^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * arch/xtensa/kernel/vectors.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * This file contains all exception vectors (user, kernel, and double),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * as well as the window vectors (overflow and underflow), and the debug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * vector. These are the primary vectors executed by the processor if an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * exception occurs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This file is subject to the terms and conditions of the GNU General
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Public License. See the file "COPYING" in the main directory of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * this archive for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (C) 2005 - 2008 Tensilica, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Chris Zankel <chris@zankel.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * We use a two-level table approach. The user and kernel exception vectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * use a first-level dispatch table to dispatch the exception to a registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * fast handler or the default handler, if no fast handler was registered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * The default handler sets up a C-stack and dispatches the exception to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * registerd C handler in the second-level dispatch table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Fast handler entry condition:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * a0: trashed, original value saved on stack (PT_AREG0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * a1: a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * a2: new stack pointer, original value in depc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * a3: dispatch table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * depc: a2, original value saved on stack (PT_DEPC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * excsave_1: a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * The value for PT_DEPC saved to stack also functions as a boolean to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * indicate that the exception is either a double or a regular exception:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * PT_DEPC >= VALID_DOUBLE_EXCEPTION_ADDRESS: double exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * < VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Note: Neither the kernel nor the user exception handler generate literals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <asm/asmmacro.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <asm/current.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <asm/vectors.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define WINDOW_VECTORS_SIZE 0x180
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * User exception vector. (Exceptions with PS.UM == 1, PS.EXCM == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * We get here when an exception occurred while we were in userland.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * We switch to the kernel stack and jump to the first level handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * associated to the exception cause.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Note: the saved kernel stack pointer (EXC_TABLE_KSTK) is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * decremented by PT_USER_SIZE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .section .UserExceptionVector.text, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) ENTRY(_UserExceptionVector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) xsr a3, excsave1 # save a3 and get dispatch table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) wsr a2, depc # save a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) l32i a2, a3, EXC_TABLE_KSTK # load kernel stack to a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) s32i a0, a2, PT_AREG0 # save a0 to ESF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) rsr a0, exccause # retrieve exception cause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) s32i a0, a2, PT_DEPC # mark it as a regular exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) addx4 a0, a0, a3 # find entry in table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) l32i a0, a0, EXC_TABLE_FAST_USER # load handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) xsr a3, excsave1 # restore a3 and dispatch table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) jx a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ENDPROC(_UserExceptionVector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * We get this exception when we were already in kernel space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * We decrement the current stack pointer (kernel) by PT_SIZE and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * jump to the first-level handler associated with the exception cause.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * Note: we need to preserve space for the spill region.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .section .KernelExceptionVector.text, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ENTRY(_KernelExceptionVector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) xsr a3, excsave1 # save a3, and get dispatch table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) wsr a2, depc # save a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) addi a2, a1, -16-PT_SIZE # adjust stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) s32i a0, a2, PT_AREG0 # save a0 to ESF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) rsr a0, exccause # retrieve exception cause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) s32i a0, a2, PT_DEPC # mark it as a regular exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) addx4 a0, a0, a3 # find entry in table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) xsr a3, excsave1 # restore a3 and dispatch table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) jx a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ENDPROC(_KernelExceptionVector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Double exception vector (Exceptions with PS.EXCM == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * We get this exception when another exception occurs while were are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * already in an exception, such as window overflow/underflow exception,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * or 'expected' exceptions, for example memory exception when we were trying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * to read data from an invalid address in user space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * Note that this vector is never invoked for level-1 interrupts, because such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * interrupts are disabled (masked) when PS.EXCM is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * We decode the exception and take the appropriate action. However, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * double exception vector is much more careful, because a lot more error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * cases go through the double exception vector than through the user and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * kernel exception vectors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Occasionally, the kernel expects a double exception to occur. This usually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * happens when accessing user-space memory with the user's permissions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * (l32e/s32e instructions). The kernel state, though, is not always suitable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * for immediate transfer of control to handle_double, where "normal" exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * processing occurs. Also in kernel mode, TLB misses can occur if accessing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * vmalloc memory, possibly requiring repair in a double exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * The variable at TABLE_FIXUP offset from the pointer in EXCSAVE_1 doubles as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * a boolean variable and a pointer to a fixup routine. If the variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * EXC_TABLE_FIXUP is non-zero, this handler jumps to that address. A value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * zero indicates to use the default kernel/user exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * There is only one exception, when the value is identical to the exc_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * label, the kernel is in trouble. This mechanism is used to protect critical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * sections, mainly when the handler writes to the stack to assert the stack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * pointer is valid. Once the fixup/default handler leaves that area, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * EXC_TABLE_FIXUP variable is reset to the fixup handler or zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * Procedures wishing to use this mechanism should set EXC_TABLE_FIXUP to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * nonzero address of a fixup routine before it could cause a double exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * and reset it before it returns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * Some other things to take care of when a fast exception handler doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * specify a particular fixup handler but wants to use the default handlers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * - The original stack pointer (in a1) must not be modified. The fast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * exception handler should only use a2 as the stack pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * - If the fast handler manipulates the stack pointer (in a2), it has to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) * register a valid fixup handler and cannot use the default handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * - The handler can use any other generic register from a3 to a15, but it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * must save the content of these registers to stack (PT_AREG3...PT_AREGx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * - These registers must be saved before a double exception can occur.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * - If we ever implement handling signals while in double exceptions, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * number of registers a fast handler has saved (excluding a0 and a1) must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * be written to PT_AREG1. (1 if only a3 is used, 2 for a3 and a4, etc. )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * The fixup handlers are special handlers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * - Fixup entry conditions differ from regular exceptions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * a0: DEPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * a1: a1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * a3: exctable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * depc: a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * excsave_1: a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * - When the kernel enters the fixup handler, it still assumes it is in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * critical section, so EXC_TABLE_FIXUP variable is set to exc_table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) * The fixup handler, therefore, has to re-register itself as the fixup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) * handler before it returns from the double exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * - Fixup handler can share the same exception frame with the fast handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * The kernel stack pointer is not changed when entering the fixup handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * - Fixup handlers can jump to the default kernel and user exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * handlers. Before it jumps, though, it has to setup a exception frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * on stack. Because the default handler resets the register fixup handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * the fixup handler must make sure that the default handler returns to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * it instead of the exception address, so it can re-register itself as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * the fixup handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * In case of a critical condition where the kernel cannot recover, we jump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * to unrecoverable_exception with the following entry conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * All registers a0...a15 are unchanged from the last exception, except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * a0: last address before we jumped to the unrecoverable_exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * excsave_1: a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * See the handle_alloca_user and spill_registers routines for example clients.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * FIXME: Note: we currently don't allow signal handling coming from a double
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * exception, so the item markt with (*) is not required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) .section .DoubleExceptionVector.text, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ENTRY(_DoubleExceptionVector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) s32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* Check for kernel double exception (usually fatal). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) rsr a2, ps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) _bbsi.l a2, PS_UM_BIT, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) j .Lksp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .literal_position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* Check if we are currently handling a window exception. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* Note: We don't need to indicate that we enter a critical section. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) xsr a0, depc # get DEPC, save a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) movi a2, WINDOW_VECTORS_VADDR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) _bltu a0, a2, .Lfixup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) addi a2, a2, WINDOW_VECTORS_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) _bgeu a0, a2, .Lfixup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /* Window overflow/underflow exception. Get stack pointer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) l32i a2, a3, EXC_TABLE_KSTK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Check for overflow/underflow exception, jump if overflow. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) bbci.l a0, 6, _DoubleExceptionVector_WindowOverflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * Restart window underflow exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * Currently:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * depc = orig a0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * a0 = orig DEPC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * a2 = new sp based on KSTK from exc_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * a3 = excsave_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * excsave_1 = orig a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * We return to the instruction in user space that caused the window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * underflow exception. Therefore, we change window base to the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * before we entered the window underflow exception and prepare the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * registers to return as if we were coming from a regular exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * by changing depc (in a0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * Note: We can trash the current window frame (a0...a3) and depc!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) _DoubleExceptionVector_WindowUnderflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) wsr a2, depc # save stack pointer temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) rsr a0, ps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) extui a0, a0, PS_OWB_SHIFT, PS_OWB_WIDTH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) wsr a0, windowbase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) rsync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* We are now in the previous window frame. Save registers again. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) xsr a2, depc # save a2 and get stack pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) s32i a0, a2, PT_AREG0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) rsr a0, exccause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) s32i a0, a2, PT_DEPC # mark it as a regular exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) addx4 a0, a0, a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) l32i a0, a0, EXC_TABLE_FAST_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) jx a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * We only allow the ITLB miss exception if we are in kernel space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * All other exceptions are unexpected and thus unrecoverable!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #ifdef CONFIG_MMU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .extern fast_second_level_miss_double_kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .Lksp: /* a0: a0, a1: a1, a2: a2, a3: trashed, depc: depc, excsave: a3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) rsr a3, exccause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) beqi a3, EXCCAUSE_ITLB_MISS, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) addi a3, a3, -EXCCAUSE_DTLB_MISS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) bnez a3, .Lunrecoverable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 1: movi a3, fast_second_level_miss_double_kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) jx a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .equ .Lksp, .Lunrecoverable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* Critical! We can't handle this situation. PANIC! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .extern unrecoverable_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .Lunrecoverable_fixup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) xsr a0, depc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .Lunrecoverable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) rsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) wsr a0, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) call0 unrecoverable_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .Lfixup:/* Check for a fixup handler or if we were in a critical section. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* a0: depc, a1: a1, a2: trash, a3: exctable, depc: a0, excsave1: a3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /* Enter critical section. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) l32i a2, a3, EXC_TABLE_FIXUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) s32i a3, a3, EXC_TABLE_FIXUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) beq a2, a3, .Lunrecoverable_fixup # critical section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) beqz a2, .Ldflt # no handler was registered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* a0: depc, a1: a1, a2: trash, a3: exctable, depc: a0, excsave: a3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) jx a2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .Ldflt: /* Get stack pointer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) addi a2, a2, -PT_USER_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* a0: depc, a1: a1, a2: kstk, a3: exctable, depc: a0, excsave: a3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) s32i a0, a2, PT_DEPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) l32i a0, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) xsr a0, depc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) s32i a0, a2, PT_AREG0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* a0: avail, a1: a1, a2: kstk, a3: exctable, depc: a2, excsave: a3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rsr a0, exccause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) addx4 a0, a0, a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) l32i a0, a0, EXC_TABLE_FAST_USER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) jx a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * Restart window OVERFLOW exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * Currently:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * depc = orig a0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) * a0 = orig DEPC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * a2 = new sp based on KSTK from exc_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) * a3 = EXCSAVE_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * excsave_1 = orig a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * We return to the instruction in user space that caused the window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * overflow exception. Therefore, we change window base to the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * before we entered the window overflow exception and prepare the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * registers to return as if we were coming from a regular exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * by changing DEPC (in a0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * NOTE: We CANNOT trash the current window frame (a0...a3), but we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * can clobber depc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * The tricky part here is that overflow8 and overflow12 handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * save a0, then clobber a0. To restart the handler, we have to restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * a0 if the double exception was past the point where a0 was clobbered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * To keep things simple, we take advantage of the fact all overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * handlers save a0 in their very first instruction. If DEPC was past
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * that instruction, we can safely restore a0 from where it was saved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * on the stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * a0: depc, a1: a1, a2: kstk, a3: exc_table, depc: a0, excsave1: a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) _DoubleExceptionVector_WindowOverflow:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) extui a2, a0, 0, 6 # get offset into 64-byte vector handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) beqz a2, 1f # if at start of vector, don't restore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) addi a0, a0, -128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) bbsi.l a0, 8, 1f # don't restore except for overflow 8 and 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * This fixup handler is for the extremely unlikely case where the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * overflow handler's reference thru a0 gets a hardware TLB refill
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * that bumps out the (distinct, aliasing) TLB entry that mapped its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * prior references thru a9/a13, and where our reference now thru
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * a9/a13 gets a 2nd-level miss exception (not hardware TLB refill).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) movi a2, window_overflow_restore_a0_fixup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) s32i a2, a3, EXC_TABLE_FIXUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) bbsi.l a0, 7, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * Restore a0 as saved by _WindowOverflow8().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) l32e a0, a9, -16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) wsr a0, depc # replace the saved a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) j 3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * Restore a0 as saved by _WindowOverflow12().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) l32e a0, a13, -16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) wsr a0, depc # replace the saved a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) movi a0, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) s32i a0, a3, EXC_TABLE_FIXUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) s32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * Restore WindowBase while leaving all address registers restored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * We have to use ROTW for this, because WSR.WINDOWBASE requires
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * an address register (which would prevent restore).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * Window Base goes from 0 ... 7 (Module 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * Window Start is 8 bits; Ex: (0b1010 1010):0x55 from series of call4s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) rsr a0, ps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) extui a0, a0, PS_OWB_SHIFT, PS_OWB_WIDTH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) rsr a2, windowbase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) sub a0, a2, a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) extui a0, a0, 0, 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) beqi a0, 1, .L1pane
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) beqi a0, 3, .L3pane
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) rsr a0, depc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) rotw -2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * We are now in the user code's original window frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * Process the exception as a user exception as if it was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * taken by the user code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * This is similar to the user exception vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * except that PT_DEPC isn't set to EXCCAUSE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) wsr a2, depc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) l32i a2, a3, EXC_TABLE_KSTK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) s32i a0, a2, PT_AREG0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) rsr a0, exccause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) s32i a0, a2, PT_DEPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) _DoubleExceptionVector_handle_exception:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) addi a0, a0, -EXCCAUSE_UNALIGNED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) beqz a0, 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) addx4 a0, a0, a3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) l32i a0, a0, EXC_TABLE_FAST_USER + 4 * EXCCAUSE_UNALIGNED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) jx a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) movi a0, user_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) jx a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .L1pane:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) rsr a0, depc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) rotw -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) j 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .L3pane:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) rsr a0, depc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) rotw -3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) j 1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ENDPROC(_DoubleExceptionVector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * Fixup handler for TLB miss in double exception handler for window owerflow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * We get here with windowbase set to the window that was being spilled and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * a0 trashed. a0 bit 7 determines if this is a call8 (bit clear) or call12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * (bit set) window.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * We do the following here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * - go to the original window retaining a0 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * - set up exception stack to return back to appropriate a0 restore code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * (we'll need to rotate window back and there's no place to save this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * information, use different return address for that);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * - handle the exception;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * - go to the window that was being spilled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * - set up window_overflow_restore_a0_fixup as a fixup routine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * - reload a0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * - restore the original window;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * - reset the default fixup routine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) * - return to user. By the time we get to this fixup handler all information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * about the conditions of the original double exception that happened in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * the window overflow handler is lost, so we just return to userspace to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * retry overflow from start.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * a0: value of depc, original value in depc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * a3: exctable, original value in excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) __XTENSA_HANDLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) .literal_position
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ENTRY(window_overflow_restore_a0_fixup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) rsr a0, ps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) extui a0, a0, PS_OWB_SHIFT, PS_OWB_WIDTH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) rsr a2, windowbase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) sub a0, a2, a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) extui a0, a0, 0, 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) _beqi a0, 1, .Lhandle_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) _beqi a0, 3, .Lhandle_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) .macro overflow_fixup_handle_exception_pane n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) rsr a0, depc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) rotw -\n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) wsr a2, depc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) l32i a2, a3, EXC_TABLE_KSTK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) s32i a0, a2, PT_AREG0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) movi a0, .Lrestore_\n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) s32i a0, a2, PT_DEPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) rsr a0, exccause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) j _DoubleExceptionVector_handle_exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) overflow_fixup_handle_exception_pane 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .Lhandle_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) overflow_fixup_handle_exception_pane 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) .Lhandle_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) overflow_fixup_handle_exception_pane 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .macro overflow_fixup_restore_a0_pane n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) rotw \n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* Need to preserve a0 value here to be able to handle exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * that may occur on a0 reload from stack. It may occur because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * TLB miss handler may not be atomic and pointer to page table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * may be lost before we get here. There are no free registers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * so we need to use EXC_TABLE_DOUBLE_SAVE area.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) s32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) movi a2, window_overflow_restore_a0_fixup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) s32i a2, a3, EXC_TABLE_FIXUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) bbsi.l a0, 7, 1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) l32e a0, a9, -16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) j 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) l32e a0, a13, -16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) rotw -\n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .Lrestore_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) overflow_fixup_restore_a0_pane 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .Lset_default_fixup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) s32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) movi a2, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) s32i a2, a3, EXC_TABLE_FIXUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) xsr a3, excsave1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) rfe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .Lrestore_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) overflow_fixup_restore_a0_pane 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) j .Lset_default_fixup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) .Lrestore_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) overflow_fixup_restore_a0_pane 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) j .Lset_default_fixup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ENDPROC(window_overflow_restore_a0_fixup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * Debug interrupt vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * There is not much space here, so simply jump to another handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * EXCSAVE[DEBUGLEVEL] has been set to that handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) .section .DebugInterruptVector.text, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ENTRY(_DebugInterruptVector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) xsr a3, SREG_EXCSAVE + XCHAL_DEBUGLEVEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) s32i a0, a3, DT_DEBUG_SAVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) l32i a0, a3, DT_DEBUG_EXCEPTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) jx a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ENDPROC(_DebugInterruptVector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * Medium priority level interrupt vectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * Each takes less than 16 (0x10) bytes, no literals, by placing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * the extra 8 bytes that would otherwise be required in the window
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * vectors area where there is space. With relocatable vectors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * all vectors are within ~ 4 kB range of each other, so we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * simply jump (J) to another vector without having to use JX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * common_exception code gets current IRQ level in PS.INTLEVEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * and preserves it for the IRQ handling time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) .macro irq_entry_level level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .if XCHAL_EXCM_LEVEL >= \level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) .section .Level\level\()InterruptVector.text, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ENTRY(_Level\level\()InterruptVector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) wsr a0, excsave2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) rsr a0, epc\level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) wsr a0, epc1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) .if \level <= LOCKLEVEL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) movi a0, EXCCAUSE_LEVEL1_INTERRUPT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) .else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) movi a0, EXCCAUSE_MAPPED_NMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) .endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) wsr a0, exccause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) rsr a0, eps\level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) # branch to user or kernel vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) j _SimulateUserKernelVectorException
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) irq_entry_level 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) irq_entry_level 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) irq_entry_level 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) irq_entry_level 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) irq_entry_level 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /* Window overflow and underflow handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * The handlers must be 64 bytes apart, first starting with the underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * handlers underflow-4 to underflow-12, then the overflow handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * overflow-4 to overflow-12.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * Note: We rerun the underflow handlers if we hit an exception, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * we try to access any page that would cause a page fault early.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) #define ENTRY_ALIGN64(name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) .globl name; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) .align 64; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .section .WindowVectors.text, "ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /* 4-Register Window Overflow Vector (Handler) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ENTRY_ALIGN64(_WindowOverflow4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) s32e a0, a5, -16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) s32e a1, a5, -12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) s32e a2, a5, -8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) s32e a3, a5, -4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) rfwo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) ENDPROC(_WindowOverflow4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) #if XCHAL_EXCM_LEVEL >= 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /* Not a window vector - but a convenient location
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * (where we know there's space) for continuation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * medium priority interrupt dispatch code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * On entry here, a0 contains PS, and EPC2 contains saved a0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) .align 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) _SimulateUserKernelVectorException:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) addi a0, a0, (1 << PS_EXCM_BIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) #if !XTENSA_FAKE_NMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) wsr a0, ps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) bbsi.l a0, PS_UM_BIT, 1f # branch if user mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) xsr a0, excsave2 # restore a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) j _KernelExceptionVector # simulate kernel vector exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 1: xsr a0, excsave2 # restore a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) j _UserExceptionVector # simulate user vector exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) /* 4-Register Window Underflow Vector (Handler) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ENTRY_ALIGN64(_WindowUnderflow4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) l32e a0, a5, -16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) l32e a1, a5, -12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) l32e a2, a5, -8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) l32e a3, a5, -4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) rfwu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) ENDPROC(_WindowUnderflow4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /* 8-Register Window Overflow Vector (Handler) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) ENTRY_ALIGN64(_WindowOverflow8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) s32e a0, a9, -16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) l32e a0, a1, -12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) s32e a2, a9, -8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) s32e a1, a9, -12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) s32e a3, a9, -4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) s32e a4, a0, -32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) s32e a5, a0, -28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) s32e a6, a0, -24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) s32e a7, a0, -20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) rfwo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) ENDPROC(_WindowOverflow8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* 8-Register Window Underflow Vector (Handler) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) ENTRY_ALIGN64(_WindowUnderflow8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) l32e a1, a9, -12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) l32e a0, a9, -16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) l32e a7, a1, -12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) l32e a2, a9, -8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) l32e a4, a7, -32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) l32e a3, a9, -4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) l32e a5, a7, -28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) l32e a6, a7, -24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) l32e a7, a7, -20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) rfwu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) ENDPROC(_WindowUnderflow8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) /* 12-Register Window Overflow Vector (Handler) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) ENTRY_ALIGN64(_WindowOverflow12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) s32e a0, a13, -16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) l32e a0, a1, -12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) s32e a1, a13, -12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) s32e a2, a13, -8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) s32e a3, a13, -4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) s32e a4, a0, -48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) s32e a5, a0, -44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) s32e a6, a0, -40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) s32e a7, a0, -36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) s32e a8, a0, -32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) s32e a9, a0, -28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) s32e a10, a0, -24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) s32e a11, a0, -20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) rfwo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ENDPROC(_WindowOverflow12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* 12-Register Window Underflow Vector (Handler) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) ENTRY_ALIGN64(_WindowUnderflow12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) l32e a1, a13, -12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) l32e a0, a13, -16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) l32e a11, a1, -12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) l32e a2, a13, -8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) l32e a4, a11, -48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) l32e a8, a11, -32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) l32e a3, a13, -4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) l32e a5, a11, -44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) l32e a6, a11, -40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) l32e a7, a11, -36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) l32e a9, a11, -28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) l32e a10, a11, -24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) l32e a11, a11, -20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) rfwu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) ENDPROC(_WindowUnderflow12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) .text