1*83d290c5STom Rini/* SPDX-License-Identifier: GPL-2.0+ */ 2c978b524SChris Zankel/* 3c978b524SChris Zankel * (C) Copyright 2008 - 2013 Tensilica Inc. 4c978b524SChris Zankel * (C) Copyright 2014 - 2016 Cadence Design Systems Inc. 5c978b524SChris Zankel */ 6c978b524SChris Zankel 7c978b524SChris Zankel#include <config.h> 8c978b524SChris Zankel#include <asm/asmmacro.h> 9c978b524SChris Zankel#include <asm/cacheasm.h> 10c978b524SChris Zankel#include <asm/regs.h> 11c978b524SChris Zankel#include <asm/arch/tie.h> 12c978b524SChris Zankel#include <asm-offsets.h> 13c978b524SChris Zankel 14c978b524SChris Zankel/* 15c978b524SChris Zankel * Offsets into the the pt_regs struture. 16c978b524SChris Zankel * Make sure these always match with the structure defined in ptrace.h! 17c978b524SChris Zankel */ 18c978b524SChris Zankel 19c978b524SChris Zankel#define PT_PC 0 20c978b524SChris Zankel#define PT_PS 4 21c978b524SChris Zankel#define PT_DEPC 8 22c978b524SChris Zankel#define PT_EXCCAUSE 12 23c978b524SChris Zankel#define PT_EXCVADDR 16 24c978b524SChris Zankel#define PT_DEBUGCAUSE 20 25c978b524SChris Zankel#define PT_WMASK 24 26c978b524SChris Zankel#define PT_LBEG 28 27c978b524SChris Zankel#define PT_LEND 32 28c978b524SChris Zankel#define PT_LCOUNT 36 29c978b524SChris Zankel#define PT_SAR 40 30c978b524SChris Zankel#define PT_WINDOWBASE 44 31c978b524SChris Zankel#define PT_WINDOWSTART 48 32c978b524SChris Zankel#define PT_SYSCALL 52 33c978b524SChris Zankel#define PT_ICOUNTLEVEL 56 34c978b524SChris Zankel#define PT_RESERVED 60 35c978b524SChris Zankel#define PT_AREG 64 36c978b524SChris Zankel#define PT_SIZE (64 + 64) 37c978b524SChris Zankel 38c978b524SChris Zankel/* 39c978b524SChris Zankel * Cache attributes are different for full MMU and region protection. 40c978b524SChris Zankel */ 41c978b524SChris Zankel 42c978b524SChris Zankel#if XCHAL_HAVE_PTP_MMU 43c978b524SChris Zankel#define CA_WRITEBACK (0x7) 44c978b524SChris Zankel#else 45c978b524SChris Zankel#define CA_WRITEBACK (0x4) 46c978b524SChris Zankel#endif 47c978b524SChris Zankel 48c978b524SChris Zankel/* 49c978b524SChris Zankel * Reset vector. 50c978b524SChris Zankel * Only a trampoline to jump to _start 51c978b524SChris Zankel * (Note that we have to mark the section writable as the section contains 52c978b524SChris Zankel * a relocatable literal) 53c978b524SChris Zankel */ 54c978b524SChris Zankel 55c978b524SChris Zankel .section .ResetVector.text, "awx" 56c978b524SChris Zankel .global _ResetVector 57c978b524SChris Zankel_ResetVector: 58c978b524SChris Zankel 59c978b524SChris Zankel j 1f 60c978b524SChris Zankel .align 4 61c978b524SChris Zankel2: .long _start 62c978b524SChris Zankel1: l32r a2, 2b 63c978b524SChris Zankel jx a2 64c978b524SChris Zankel 65c978b524SChris Zankel 66c978b524SChris Zankel/* 67c978b524SChris Zankel * Processor initialization. We still run in rom space. 68c978b524SChris Zankel * 69c978b524SChris Zankel * NOTE: Running in ROM 70c978b524SChris Zankel * For Xtensa, we currently don't allow to run some code from ROM but 71c978b524SChris Zankel * unpack the data immediately to memory. This requires, for example, 72c978b524SChris Zankel * that DDR has been set up before running U-Boot. (See also comments 73c978b524SChris Zankel * inline for ways to change it) 74c978b524SChris Zankel */ 75c978b524SChris Zankel 76c978b524SChris Zankel .section .reset.text, "ax" 77c978b524SChris Zankel .global _start 78c978b524SChris Zankel .align 4 79c978b524SChris Zankel_start: 80c978b524SChris Zankel /* Keep a0 = 0 for various initializations */ 81c978b524SChris Zankel 82c978b524SChris Zankel movi a0, 0 83c978b524SChris Zankel 84c978b524SChris Zankel /* 85c978b524SChris Zankel * For full MMU cores, put page table at unmapped virtual address. 86c978b524SChris Zankel * This ensures that accesses outside the static maps result 87c978b524SChris Zankel * in miss exceptions rather than random behaviour. 88c978b524SChris Zankel */ 89c978b524SChris Zankel 90c978b524SChris Zankel#if XCHAL_HAVE_PTP_MMU 91c978b524SChris Zankel wsr a0, PTEVADDR 92c978b524SChris Zankel#endif 93c978b524SChris Zankel 94c978b524SChris Zankel /* Disable dbreak debug exceptions */ 95c978b524SChris Zankel 96c978b524SChris Zankel#if XCHAL_HAVE_DEBUG && XCHAL_NUM_DBREAK > 0 97c978b524SChris Zankel .set _index, 0 98c978b524SChris Zankel .rept XCHAL_NUM_DBREAK 99c978b524SChris Zankel wsr a0, DBREAKC + _index 100c978b524SChris Zankel .set _index, _index + 1 101c978b524SChris Zankel .endr 102c978b524SChris Zankel#endif 103c978b524SChris Zankel 104c978b524SChris Zankel /* Reset windowbase and windowstart */ 105c978b524SChris Zankel 106c978b524SChris Zankel#if XCHAL_HAVE_WINDOWED 107c978b524SChris Zankel movi a3, 1 108c978b524SChris Zankel wsr a3, windowstart 109c978b524SChris Zankel wsr a0, windowbase 110c978b524SChris Zankel rsync 111c978b524SChris Zankel movi a0, 0 /* windowbase might have changed */ 112c978b524SChris Zankel#endif 113c978b524SChris Zankel 114c978b524SChris Zankel /* 115c978b524SChris Zankel * Vecbase in bitstream may differ from header files 116c978b524SChris Zankel * set or check it. 117c978b524SChris Zankel */ 118c978b524SChris Zankel 119c978b524SChris Zankel#if XCHAL_HAVE_VECBASE 120c978b524SChris Zankel movi a3, XCHAL_VECBASE_RESET_VADDR /* VECBASE reset value */ 121c978b524SChris Zankel wsr a3, VECBASE 122c978b524SChris Zankel#endif 123c978b524SChris Zankel 124c978b524SChris Zankel#if XCHAL_HAVE_LOOPS 125c978b524SChris Zankel /* Disable loops */ 126c978b524SChris Zankel 127c978b524SChris Zankel wsr a0, LCOUNT 128c978b524SChris Zankel#endif 129c978b524SChris Zankel 130c978b524SChris Zankel /* Set PS.WOE = 0, PS.EXCM = 0 (for loop), PS.INTLEVEL = EXCM level */ 131c978b524SChris Zankel 132c978b524SChris Zankel#if XCHAL_HAVE_XEA1 133c978b524SChris Zankel movi a2, 1 134c978b524SChris Zankel#else 135c978b524SChris Zankel movi a2, XCHAL_EXCM_LEVEL 136c978b524SChris Zankel#endif 137c978b524SChris Zankel wsr a2, PS 138c978b524SChris Zankel rsync 139c978b524SChris Zankel 140c978b524SChris Zankel /* Unlock and invalidate caches */ 141c978b524SChris Zankel 142c978b524SChris Zankel ___unlock_dcache_all a2, a3 143c978b524SChris Zankel ___invalidate_dcache_all a2, a3 144c978b524SChris Zankel ___unlock_icache_all a2, a3 145c978b524SChris Zankel ___invalidate_icache_all a2, a3 146c978b524SChris Zankel 147c978b524SChris Zankel isync 148c978b524SChris Zankel 149c978b524SChris Zankel /* Unpack data sections */ 150c978b524SChris Zankel 151c978b524SChris Zankel movi a2, __reloc_table_start 152c978b524SChris Zankel movi a3, __reloc_table_end 153c978b524SChris Zankel 154c978b524SChris Zankel1: beq a2, a3, 3f # no more entries? 155c978b524SChris Zankel l32i a4, a2, 0 # start destination (in RAM) 156c978b524SChris Zankel l32i a5, a2, 4 # end destination (in RAM) 157c978b524SChris Zankel l32i a6, a2, 8 # start source (in ROM) 158c978b524SChris Zankel addi a2, a2, 12 # next entry 159c978b524SChris Zankel beq a4, a5, 1b # skip, empty entry 160c978b524SChris Zankel beq a4, a6, 1b # skip, source and destination are the same 161c978b524SChris Zankel 162c978b524SChris Zankel /* If there's memory protection option with 512MB TLB regions and 163c978b524SChris Zankel * cache attributes in TLB entries and caching is not inhibited, 164c978b524SChris Zankel * enable data/instruction cache for relocated image. 165c978b524SChris Zankel */ 166c978b524SChris Zankel#if XCHAL_HAVE_SPANNING_WAY && \ 167c978b524SChris Zankel (!defined(CONFIG_SYS_DCACHE_OFF) || \ 168c978b524SChris Zankel !defined(CONFIG_SYS_ICACHE_OFF)) 169c978b524SChris Zankel srli a7, a4, 29 170c978b524SChris Zankel slli a7, a7, 29 171c978b524SChris Zankel addi a7, a7, XCHAL_SPANNING_WAY 172c978b524SChris Zankel#ifndef CONFIG_SYS_DCACHE_OFF 173c978b524SChris Zankel rdtlb1 a8, a7 174c978b524SChris Zankel srli a8, a8, 4 175c978b524SChris Zankel slli a8, a8, 4 176c978b524SChris Zankel addi a8, a8, CA_WRITEBACK 177c978b524SChris Zankel wdtlb a8, a7 178c978b524SChris Zankel#endif 179c978b524SChris Zankel#ifndef CONFIG_SYS_ICACHE_OFF 180c978b524SChris Zankel ritlb1 a8, a7 181c978b524SChris Zankel srli a8, a8, 4 182c978b524SChris Zankel slli a8, a8, 4 183c978b524SChris Zankel addi a8, a8, CA_WRITEBACK 184c978b524SChris Zankel witlb a8, a7 185c978b524SChris Zankel#endif 186c978b524SChris Zankel isync 187c978b524SChris Zankel#endif 188c978b524SChris Zankel 189c978b524SChris Zankel2: l32i a7, a6, 0 190c978b524SChris Zankel addi a6, a6, 4 191c978b524SChris Zankel s32i a7, a4, 0 192c978b524SChris Zankel addi a4, a4, 4 193c978b524SChris Zankel bltu a4, a5, 2b 194c978b524SChris Zankel j 1b 195c978b524SChris Zankel 196c978b524SChris Zankel3: /* All code and initalized data segments have been copied */ 197c978b524SChris Zankel 198c978b524SChris Zankel /* Setup PS, PS.WOE = 1, PS.EXCM = 0, PS.INTLEVEL = EXCM level. */ 199c978b524SChris Zankel 200c978b524SChris Zankel#if __XTENSA_CALL0_ABI__ 201c978b524SChris Zankel movi a2, XCHAL_EXCM_LEVEL 202c978b524SChris Zankel#else 203c978b524SChris Zankel movi a2, (1<<PS_WOE_BIT) | XCHAL_EXCM_LEVEL 204c978b524SChris Zankel#endif 205c978b524SChris Zankel wsr a2, PS 206c978b524SChris Zankel rsync 207c978b524SChris Zankel 208c978b524SChris Zankel /* Writeback */ 209c978b524SChris Zankel 210c978b524SChris Zankel ___flush_dcache_all a2, a3 211c978b524SChris Zankel 212c978b524SChris Zankel#ifdef __XTENSA_WINDOWED_ABI__ 213c978b524SChris Zankel /* 214c978b524SChris Zankel * In windowed ABI caller and call target need to be within the same 215c978b524SChris Zankel * gigabyte. Put the rest of the code into the text segment and jump 216c978b524SChris Zankel * there. 217c978b524SChris Zankel */ 218c978b524SChris Zankel 219c978b524SChris Zankel movi a4, .Lboard_init_code 220c978b524SChris Zankel jx a4 221c978b524SChris Zankel 222c978b524SChris Zankel .text 223c978b524SChris Zankel .align 4 224c978b524SChris Zankel.Lboard_init_code: 225c978b524SChris Zankel#endif 226c978b524SChris Zankel 227c978b524SChris Zankel movi a0, 0 22810117a29SMax Filippov movi sp, (XTENSA_SYS_TEXT_ADDR - 16) & 0xfffffff0 229c978b524SChris Zankel 230c978b524SChris Zankel#ifdef CONFIG_DEBUG_UART 231c978b524SChris Zankel movi a4, debug_uart_init 232c978b524SChris Zankel#ifdef __XTENSA_CALL0_ABI__ 233c978b524SChris Zankel callx0 a4 234c978b524SChris Zankel#else 235c978b524SChris Zankel callx4 a4 236c978b524SChris Zankel#endif 237c978b524SChris Zankel#endif 238c978b524SChris Zankel 239c978b524SChris Zankel movi a4, board_init_f_alloc_reserve 240c978b524SChris Zankel 241c978b524SChris Zankel#ifdef __XTENSA_CALL0_ABI__ 242c978b524SChris Zankel mov a2, sp 243c978b524SChris Zankel callx0 a4 244c978b524SChris Zankel mov sp, a2 245c978b524SChris Zankel#else 246c978b524SChris Zankel mov a6, sp 247c978b524SChris Zankel callx4 a4 248c978b524SChris Zankel movsp sp, a6 249c978b524SChris Zankel#endif 250c978b524SChris Zankel 251c978b524SChris Zankel movi a4, board_init_f_init_reserve 252c978b524SChris Zankel 253c978b524SChris Zankel#ifdef __XTENSA_CALL0_ABI__ 254c978b524SChris Zankel callx0 a4 255c978b524SChris Zankel#else 256c978b524SChris Zankel callx4 a4 257c978b524SChris Zankel#endif 258c978b524SChris Zankel 259c978b524SChris Zankel /* 260c978b524SChris Zankel * Call board initialization routine (never returns). 261c978b524SChris Zankel */ 262c978b524SChris Zankel 263c978b524SChris Zankel movi a4, board_init_f 264c978b524SChris Zankel 265c978b524SChris Zankel#ifdef __XTENSA_CALL0_ABI__ 266c978b524SChris Zankel movi a2, 0 267c978b524SChris Zankel callx0 a4 268c978b524SChris Zankel#else 269c978b524SChris Zankel movi a6, 0 270c978b524SChris Zankel callx4 a4 271c978b524SChris Zankel#endif 272c978b524SChris Zankel /* Never Returns */ 273c978b524SChris Zankel ill 274c978b524SChris Zankel 275c978b524SChris Zankel/* 276c978b524SChris Zankel * void relocate_code (addr_sp, gd, addr_moni) 277c978b524SChris Zankel * 278c978b524SChris Zankel * This "function" does not return, instead it continues in RAM 279c978b524SChris Zankel * after relocating the monitor code. 280c978b524SChris Zankel * 281c978b524SChris Zankel * a2 = addr_sp 282c978b524SChris Zankel * a3 = gd 283c978b524SChris Zankel * a4 = destination address 284c978b524SChris Zankel */ 285c978b524SChris Zankel .text 286c978b524SChris Zankel .globl relocate_code 287c978b524SChris Zankel .align 4 288c978b524SChris Zankelrelocate_code: 289c978b524SChris Zankel abi_entry 290c978b524SChris Zankel 291c978b524SChris Zankel#ifdef __XTENSA_CALL0_ABI__ 292c978b524SChris Zankel mov a1, a2 293c978b524SChris Zankel mov a2, a3 294c978b524SChris Zankel mov a3, a4 295c978b524SChris Zankel movi a0, board_init_r 296c978b524SChris Zankel callx0 a0 297c978b524SChris Zankel#else 298c978b524SChris Zankel /* We can't movsp here, because the chain of stack frames may cross 299c978b524SChris Zankel * the now reserved memory. We need to toss all window frames except 300c978b524SChris Zankel * the current, create new pristine stack frame and start from scratch. 301c978b524SChris Zankel */ 302c978b524SChris Zankel rsr a0, windowbase 303c978b524SChris Zankel ssl a0 304c978b524SChris Zankel movi a0, 1 305c978b524SChris Zankel sll a0, a0 306c978b524SChris Zankel wsr a0, windowstart 307c978b524SChris Zankel rsync 308c978b524SChris Zankel 309c978b524SChris Zankel movi a0, 0 310c978b524SChris Zankel 311c978b524SChris Zankel /* Reserve 16-byte save area */ 312c978b524SChris Zankel addi sp, a2, -16 313c978b524SChris Zankel mov a6, a3 314c978b524SChris Zankel mov a7, a4 315c978b524SChris Zankel movi a4, board_init_r 316c978b524SChris Zankel callx4 a4 317c978b524SChris Zankel#endif 318c978b524SChris Zankel ill 319c978b524SChris Zankel 320c978b524SChris Zankel#if XCHAL_HAVE_EXCEPTIONS 321c978b524SChris Zankel 322c978b524SChris Zankel/* 323c978b524SChris Zankel * Exception vectors. 324c978b524SChris Zankel * 325c978b524SChris Zankel * Various notes: 326c978b524SChris Zankel * - We currently don't use the user exception vector (PS.UM is always 0), 327c978b524SChris Zankel * but do define such a vector, just in case. They both jump to the 328c978b524SChris Zankel * same exception handler, though. 329c978b524SChris Zankel * - We currently only save the bare minimum number of registers: 330c978b524SChris Zankel * a0...a15, sar, loop-registers, exception register (epc1, excvaddr, 331c978b524SChris Zankel * exccause, depc) 332c978b524SChris Zankel * - WINDOWSTART is only saved to identify if registers have been spilled 333c978b524SChris Zankel * to the wrong stack (exception stack) while executing the exception 334c978b524SChris Zankel * handler. 335c978b524SChris Zankel */ 336c978b524SChris Zankel 337c978b524SChris Zankel .section .KernelExceptionVector.text, "ax" 338c978b524SChris Zankel .global _KernelExceptionVector 339c978b524SChris Zankel_KernelExceptionVector: 340c978b524SChris Zankel 341c978b524SChris Zankel wsr a2, EXCSAVE1 342c978b524SChris Zankel movi a2, ExceptionHandler 343c978b524SChris Zankel jx a2 344c978b524SChris Zankel 345c978b524SChris Zankel .section .UserExceptionVector.text, "ax" 346c978b524SChris Zankel .global _UserExceptionVector 347c978b524SChris Zankel_UserExceptionVector: 348c978b524SChris Zankel 349c978b524SChris Zankel wsr a2, EXCSAVE1 350c978b524SChris Zankel movi a2, ExceptionHandler 351c978b524SChris Zankel jx a2 352c978b524SChris Zankel 353c978b524SChris Zankel#if !XCHAL_HAVE_XEA1 354c978b524SChris Zankel .section .DoubleExceptionVector.text, "ax" 355c978b524SChris Zankel .global _DoubleExceptionVector 356c978b524SChris Zankel_DoubleExceptionVector: 357c978b524SChris Zankel 358c978b524SChris Zankel#ifdef __XTENSA_CALL0_ABI__ 359c978b524SChris Zankel wsr a0, EXCSAVE1 360c978b524SChris Zankel movi a0, hang # report and ask user to reset board 361c978b524SChris Zankel callx0 a0 362c978b524SChris Zankel#else 363c978b524SChris Zankel wsr a4, EXCSAVE1 364c978b524SChris Zankel movi a4, hang # report and ask user to reset board 365c978b524SChris Zankel callx4 a4 366c978b524SChris Zankel#endif 367c978b524SChris Zankel#endif 368c978b524SChris Zankel /* Does not return here */ 369c978b524SChris Zankel 370c978b524SChris Zankel 371c978b524SChris Zankel .text 372c978b524SChris Zankel .align 4 373c978b524SChris ZankelExceptionHandler: 374c978b524SChris Zankel 375c978b524SChris Zankel rsr a2, EXCCAUSE # find handler 376c978b524SChris Zankel 377c978b524SChris Zankel#if XCHAL_HAVE_WINDOWED 378c978b524SChris Zankel /* Special case for alloca handler */ 379c978b524SChris Zankel 380c978b524SChris Zankel bnei a2, 5, 1f # jump if not alloca exception 381c978b524SChris Zankel 382c978b524SChris Zankel addi a1, a1, -16 - 4 # create a small stack frame 383c978b524SChris Zankel s32i a3, a1, 0 # and save a3 (a2 still in excsave1) 384c978b524SChris Zankel movi a2, fast_alloca_exception 385c978b524SChris Zankel jx a2 # jump to fast_alloca_exception 386c978b524SChris Zankel#endif 387c978b524SChris Zankel /* All other exceptions go here: */ 388c978b524SChris Zankel 389c978b524SChris Zankel /* Create ptrace stack and save a0...a3 */ 390c978b524SChris Zankel 391c978b524SChris Zankel1: addi a2, a1, - PT_SIZE - 16 392c978b524SChris Zankel s32i a0, a2, PT_AREG + 0 * 4 393c978b524SChris Zankel s32i a1, a2, PT_AREG + 1 * 4 394c978b524SChris Zankel s32i a3, a2, PT_AREG + 3 * 4 395c978b524SChris Zankel rsr a3, EXCSAVE1 396c978b524SChris Zankel s32i a3, a2, PT_AREG + 2 * 4 397c978b524SChris Zankel mov a1, a2 398c978b524SChris Zankel 399c978b524SChris Zankel /* Save remaining AR registers */ 400c978b524SChris Zankel 401c978b524SChris Zankel s32i a4, a1, PT_AREG + 4 * 4 402c978b524SChris Zankel s32i a5, a1, PT_AREG + 5 * 4 403c978b524SChris Zankel s32i a6, a1, PT_AREG + 6 * 4 404c978b524SChris Zankel s32i a7, a1, PT_AREG + 7 * 4 405c978b524SChris Zankel s32i a8, a1, PT_AREG + 8 * 4 406c978b524SChris Zankel s32i a9, a1, PT_AREG + 9 * 4 407c978b524SChris Zankel s32i a10, a1, PT_AREG + 10 * 4 408c978b524SChris Zankel s32i a11, a1, PT_AREG + 11 * 4 409c978b524SChris Zankel s32i a12, a1, PT_AREG + 12 * 4 410c978b524SChris Zankel s32i a13, a1, PT_AREG + 13 * 4 411c978b524SChris Zankel s32i a14, a1, PT_AREG + 14 * 4 412c978b524SChris Zankel s32i a15, a1, PT_AREG + 15 * 4 413c978b524SChris Zankel 414c978b524SChris Zankel /* Save SRs */ 415c978b524SChris Zankel 416c978b524SChris Zankel#if XCHAL_HAVE_WINDOWED 417c978b524SChris Zankel rsr a2, WINDOWSTART 418c978b524SChris Zankel s32i a2, a1, PT_WINDOWSTART 419c978b524SChris Zankel#endif 420c978b524SChris Zankel 421c978b524SChris Zankel rsr a2, SAR 422c978b524SChris Zankel rsr a3, EPC1 423c978b524SChris Zankel rsr a4, EXCVADDR 424c978b524SChris Zankel s32i a2, a1, PT_SAR 425c978b524SChris Zankel s32i a3, a1, PT_PC 426c978b524SChris Zankel s32i a4, a1, PT_EXCVADDR 427c978b524SChris Zankel 428c978b524SChris Zankel#if XCHAL_HAVE_LOOPS 429c978b524SChris Zankel movi a2, 0 430c978b524SChris Zankel rsr a3, LBEG 431c978b524SChris Zankel xsr a2, LCOUNT 432c978b524SChris Zankel s32i a3, a1, PT_LBEG 433c978b524SChris Zankel rsr a3, LEND 434c978b524SChris Zankel s32i a2, a1, PT_LCOUNT 435c978b524SChris Zankel s32i a3, a1, PT_LEND 436c978b524SChris Zankel#endif 437c978b524SChris Zankel 438c978b524SChris Zankel /* Set up C environment and call registered handler */ 439c978b524SChris Zankel /* Setup stack, PS.WOE = 1, PS.EXCM = 0, PS.INTLEVEL = EXCM level. */ 440c978b524SChris Zankel 441c978b524SChris Zankel rsr a2, EXCCAUSE 442c978b524SChris Zankel#if XCHAL_HAVE_XEA1 443c978b524SChris Zankel movi a3, (1<<PS_WOE_BIT) | 1 444c978b524SChris Zankel#elif __XTENSA_CALL0_ABI__ 445c978b524SChris Zankel movi a3, XCHAL_EXCM_LEVEL 446c978b524SChris Zankel#else 447c978b524SChris Zankel movi a3, (1<<PS_WOE_BIT) | XCHAL_EXCM_LEVEL 448c978b524SChris Zankel#endif 449c978b524SChris Zankel xsr a3, PS 450c978b524SChris Zankel rsync 451c978b524SChris Zankel s32i a2, a1, PT_EXCCAUSE 452c978b524SChris Zankel s32i a3, a1, PT_PS 453c978b524SChris Zankel 454c978b524SChris Zankel movi a0, exc_table 455c978b524SChris Zankel addx4 a0, a2, a0 456c978b524SChris Zankel l32i a0, a0, 0 457c978b524SChris Zankel#ifdef __XTENSA_CALL0_ABI__ 458c978b524SChris Zankel mov a2, a1 # Provide stack frame as only argument 459c978b524SChris Zankel callx0 a0 460c978b524SChris Zankel l32i a3, a1, PT_PS 461c978b524SChris Zankel#else 462c978b524SChris Zankel mov a6, a1 # Provide stack frame as only argument 463c978b524SChris Zankel callx4 a0 464c978b524SChris Zankel#endif 465c978b524SChris Zankel 466c978b524SChris Zankel /* Restore PS and go to exception mode (PS.EXCM=1) */ 467c978b524SChris Zankel 468c978b524SChris Zankel wsr a3, PS 469c978b524SChris Zankel 470c978b524SChris Zankel /* Restore SR registers */ 471c978b524SChris Zankel 472c978b524SChris Zankel#if XCHAL_HAVE_LOOPS 473c978b524SChris Zankel l32i a2, a1, PT_LBEG 474c978b524SChris Zankel l32i a3, a1, PT_LEND 475c978b524SChris Zankel l32i a4, a1, PT_LCOUNT 476c978b524SChris Zankel wsr a2, LBEG 477c978b524SChris Zankel wsr a3, LEND 478c978b524SChris Zankel wsr a4, LCOUNT 479c978b524SChris Zankel#endif 480c978b524SChris Zankel 481c978b524SChris Zankel l32i a2, a1, PT_SAR 482c978b524SChris Zankel l32i a3, a1, PT_PC 483c978b524SChris Zankel wsr a2, SAR 484c978b524SChris Zankel wsr a3, EPC1 485c978b524SChris Zankel 486c978b524SChris Zankel#if XCHAL_HAVE_WINDOWED 487c978b524SChris Zankel /* Do we need to simulate a MOVSP? */ 488c978b524SChris Zankel 489c978b524SChris Zankel l32i a2, a1, PT_WINDOWSTART 490c978b524SChris Zankel addi a3, a2, -1 491c978b524SChris Zankel and a2, a2, a3 492c978b524SChris Zankel beqz a2, 1f # Skip if regs were spilled before exc. 493c978b524SChris Zankel 494c978b524SChris Zankel rsr a2, WINDOWSTART 495c978b524SChris Zankel addi a3, a2, -1 496c978b524SChris Zankel and a2, a2, a3 497c978b524SChris Zankel bnez a2, 1f # Skip if registers aren't spilled now 498c978b524SChris Zankel 499c978b524SChris Zankel addi a2, a1, -16 500c978b524SChris Zankel l32i a4, a2, 0 501c978b524SChris Zankel l32i a5, a2, 4 502c978b524SChris Zankel s32i a4, a1, PT_SIZE + 0 503c978b524SChris Zankel s32i a5, a1, PT_SIZE + 4 504c978b524SChris Zankel l32i a4, a2, 8 505c978b524SChris Zankel l32i a5, a2, 12 506c978b524SChris Zankel s32i a4, a1, PT_SIZE + 8 507c978b524SChris Zankel s32i a5, a1, PT_SIZE + 12 508c978b524SChris Zankel#endif 509c978b524SChris Zankel 510c978b524SChris Zankel /* Restore address register */ 511c978b524SChris Zankel 512c978b524SChris Zankel1: l32i a15, a1, PT_AREG + 15 * 4 513c978b524SChris Zankel l32i a14, a1, PT_AREG + 14 * 4 514c978b524SChris Zankel l32i a13, a1, PT_AREG + 13 * 4 515c978b524SChris Zankel l32i a12, a1, PT_AREG + 12 * 4 516c978b524SChris Zankel l32i a11, a1, PT_AREG + 11 * 4 517c978b524SChris Zankel l32i a10, a1, PT_AREG + 10 * 4 518c978b524SChris Zankel l32i a9, a1, PT_AREG + 9 * 4 519c978b524SChris Zankel l32i a8, a1, PT_AREG + 8 * 4 520c978b524SChris Zankel l32i a7, a1, PT_AREG + 7 * 4 521c978b524SChris Zankel l32i a6, a1, PT_AREG + 6 * 4 522c978b524SChris Zankel l32i a5, a1, PT_AREG + 5 * 4 523c978b524SChris Zankel l32i a4, a1, PT_AREG + 4 * 4 524c978b524SChris Zankel l32i a3, a1, PT_AREG + 3 * 4 525c978b524SChris Zankel l32i a2, a1, PT_AREG + 2 * 4 526c978b524SChris Zankel l32i a0, a1, PT_AREG + 0 * 4 527c978b524SChris Zankel 528c978b524SChris Zankel l32i a1, a1, PT_AREG + 1 * 4 # Remove ptrace stack frame 529c978b524SChris Zankel 530c978b524SChris Zankel rfe 531c978b524SChris Zankel 532c978b524SChris Zankel#endif /* XCHAL_HAVE_EXCEPTIONS */ 533c978b524SChris Zankel 534c978b524SChris Zankel#if XCHAL_HAVE_WINDOWED 535c978b524SChris Zankel 536c978b524SChris Zankel/* 537c978b524SChris Zankel * Window overflow and underflow handlers. 538c978b524SChris Zankel * The handlers must be 64 bytes apart, first starting with the underflow 539c978b524SChris Zankel * handlers underflow-4 to underflow-12, then the overflow handlers 540c978b524SChris Zankel * overflow-4 to overflow-12. 541c978b524SChris Zankel * 542c978b524SChris Zankel * Note: We rerun the underflow handlers if we hit an exception, so 543c978b524SChris Zankel * we try to access any page that would cause a page fault early. 544c978b524SChris Zankel */ 545c978b524SChris Zankel 546c978b524SChris Zankel .section .WindowVectors.text, "ax" 547c978b524SChris Zankel 548c978b524SChris Zankel/* 4-Register Window Overflow Vector (Handler) */ 549c978b524SChris Zankel 550c978b524SChris Zankel .align 64 551c978b524SChris Zankel.global _WindowOverflow4 552c978b524SChris Zankel_WindowOverflow4: 553c978b524SChris Zankel s32e a0, a5, -16 554c978b524SChris Zankel s32e a1, a5, -12 555c978b524SChris Zankel s32e a2, a5, -8 556c978b524SChris Zankel s32e a3, a5, -4 557c978b524SChris Zankel rfwo 558c978b524SChris Zankel 559c978b524SChris Zankel 560c978b524SChris Zankel/* 4-Register Window Underflow Vector (Handler) */ 561c978b524SChris Zankel 562c978b524SChris Zankel .align 64 563c978b524SChris Zankel.global _WindowUnderflow4 564c978b524SChris Zankel_WindowUnderflow4: 565c978b524SChris Zankel l32e a0, a5, -16 566c978b524SChris Zankel l32e a1, a5, -12 567c978b524SChris Zankel l32e a2, a5, -8 568c978b524SChris Zankel l32e a3, a5, -4 569c978b524SChris Zankel rfwu 570c978b524SChris Zankel 571c978b524SChris Zankel/* 572c978b524SChris Zankel * a0: a0 573c978b524SChris Zankel * a1: new stack pointer = a1 - 16 - 4 574c978b524SChris Zankel * a2: available, saved in excsave1 575c978b524SChris Zankel * a3: available, saved on stack *a1 576c978b524SChris Zankel */ 577c978b524SChris Zankel 578c978b524SChris Zankel/* 15*/ .byte 0xff 579c978b524SChris Zankel 580c978b524SChris Zankelfast_alloca_exception: /* must be at _WindowUnderflow4 + 16 */ 581c978b524SChris Zankel 582c978b524SChris Zankel/* 16*/ rsr a2, PS 583c978b524SChris Zankel/* 19*/ rsr a3, WINDOWBASE 584c978b524SChris Zankel/* 22*/ extui a2, a2, PS_OWB_SHIFT, PS_OWB_SHIFT 585c978b524SChris Zankel/* 25*/ xor a2, a2, a3 586c978b524SChris Zankel/* 28*/ rsr a3, PS 587c978b524SChris Zankel/* 31*/ slli a2, a2, PS_OWB_SHIFT 588c978b524SChris Zankel/* 34*/ xor a2, a3, a2 589c978b524SChris Zankel/* 37*/ wsr a2, PS 590c978b524SChris Zankel 591c978b524SChris Zankel/* 40*/ _l32i a3, a1, 0 592c978b524SChris Zankel/* 43*/ addi a1, a1, 16 + 4 593c978b524SChris Zankel/* 46*/ rsr a2, EXCSAVE1 594c978b524SChris Zankel 595c978b524SChris Zankel/* 49*/ rotw -1 596c978b524SChris Zankel/* 52*/ _bbci.l a4, 31, _WindowUnderflow4 /* 0x: call4 */ 597c978b524SChris Zankel/* 55*/ rotw -1 598c978b524SChris Zankel/* 58*/ _bbci.l a8, 30, _WindowUnderflow8 /* 10: call8 */ 599c978b524SChris Zankel/* 61*/ _j __WindowUnderflow12 /* 11: call12 */ 600c978b524SChris Zankel/* 64*/ 601c978b524SChris Zankel 602c978b524SChris Zankel/* 8-Register Window Overflow Vector (Handler) */ 603c978b524SChris Zankel 604c978b524SChris Zankel .align 64 605c978b524SChris Zankel.global _WindowOverflow8 606c978b524SChris Zankel_WindowOverflow8: 607c978b524SChris Zankel s32e a0, a9, -16 608c978b524SChris Zankel l32e a0, a1, -12 609c978b524SChris Zankel s32e a2, a9, -8 610c978b524SChris Zankel s32e a1, a9, -12 611c978b524SChris Zankel s32e a3, a9, -4 612c978b524SChris Zankel s32e a4, a0, -32 613c978b524SChris Zankel s32e a5, a0, -28 614c978b524SChris Zankel s32e a6, a0, -24 615c978b524SChris Zankel s32e a7, a0, -20 616c978b524SChris Zankel rfwo 617c978b524SChris Zankel 618c978b524SChris Zankel/* 8-Register Window Underflow Vector (Handler) */ 619c978b524SChris Zankel 620c978b524SChris Zankel .align 64 621c978b524SChris Zankel.global _WindowUnderflow8 622c978b524SChris Zankel_WindowUnderflow8: 623c978b524SChris Zankel l32e a1, a9, -12 624c978b524SChris Zankel l32e a0, a9, -16 625c978b524SChris Zankel l32e a7, a1, -12 626c978b524SChris Zankel l32e a2, a9, -8 627c978b524SChris Zankel l32e a4, a7, -32 628c978b524SChris Zankel l32e a3, a9, -4 629c978b524SChris Zankel l32e a5, a7, -28 630c978b524SChris Zankel l32e a6, a7, -24 631c978b524SChris Zankel l32e a7, a7, -20 632c978b524SChris Zankel rfwu 633c978b524SChris Zankel 634c978b524SChris Zankel/* 12-Register Window Overflow Vector (Handler) */ 635c978b524SChris Zankel 636c978b524SChris Zankel .align 64 637c978b524SChris Zankel.global _WindowOverflow12 638c978b524SChris Zankel_WindowOverflow12: 639c978b524SChris Zankel s32e a0, a13, -16 640c978b524SChris Zankel l32e a0, a1, -12 641c978b524SChris Zankel s32e a1, a13, -12 642c978b524SChris Zankel s32e a2, a13, -8 643c978b524SChris Zankel s32e a3, a13, -4 644c978b524SChris Zankel s32e a4, a0, -48 645c978b524SChris Zankel s32e a5, a0, -44 646c978b524SChris Zankel s32e a6, a0, -40 647c978b524SChris Zankel s32e a7, a0, -36 648c978b524SChris Zankel s32e a8, a0, -32 649c978b524SChris Zankel s32e a9, a0, -28 650c978b524SChris Zankel s32e a10, a0, -24 651c978b524SChris Zankel s32e a11, a0, -20 652c978b524SChris Zankel rfwo 653c978b524SChris Zankel 654c978b524SChris Zankel/* 12-Register Window Underflow Vector (Handler) */ 655c978b524SChris Zankel 656c978b524SChris Zankel .org _WindowOverflow12 + 64 - 3 657c978b524SChris Zankel__WindowUnderflow12: 658c978b524SChris Zankel rotw -1 659c978b524SChris Zankel.global _WindowUnderflow12 660c978b524SChris Zankel_WindowUnderflow12: 661c978b524SChris Zankel l32e a1, a13, -12 662c978b524SChris Zankel l32e a0, a13, -16 663c978b524SChris Zankel l32e a11, a1, -12 664c978b524SChris Zankel l32e a2, a13, -8 665c978b524SChris Zankel l32e a4, a11, -48 666c978b524SChris Zankel l32e a8, a11, -32 667c978b524SChris Zankel l32e a3, a13, -4 668c978b524SChris Zankel l32e a5, a11, -44 669c978b524SChris Zankel l32e a6, a11, -40 670c978b524SChris Zankel l32e a7, a11, -36 671c978b524SChris Zankel l32e a9, a11, -28 672c978b524SChris Zankel l32e a10, a11, -24 673c978b524SChris Zankel l32e a11, a11, -20 674c978b524SChris Zankel rfwu 675c978b524SChris Zankel 676c978b524SChris Zankel#endif /* XCHAL_HAVE_WINDOWED */ 677