\r
GCC_ASM_EXPORT(ExceptionHandlersEnd)\r
GCC_ASM_EXPORT(CommonCExceptionHandler)\r
+GCC_ASM_EXPORT(RegisterEl0Stack)\r
\r
.text\r
\r
VECTOR_BASE(ExceptionHandlersStart)\r
#endif\r
\r
- .macro ExceptionEntry, val\r
+ .macro ExceptionEntry, val, sp=SPx\r
+ //\r
+ // Our backtrace and register dump code is written in C and so it requires\r
+ // a stack. This makes it difficult to produce meaningful diagnostics when\r
+ // the stack pointer has been corrupted. So in such cases (i.e., when taking\r
+ // synchronous exceptions), this macro is expanded with \sp set to SP0, in\r
+ // which case we switch to the SP_EL0 stack pointer, which has been\r
+ // initialized to point to a buffer that has been set aside for this purpose.\r
+ //\r
+ // Since 'sp' may no longer refer to the stack frame that was active when\r
+ // the exception was taken, we may have to switch back and forth between\r
+ // SP_EL0 and SP_ELx to record the correct value for SP in the context struct.\r
+ //\r
+ .ifnc \sp, SPx\r
+ msr SPsel, xzr\r
+ .endif\r
+\r
// Move the stackpointer so we can reach our structure with the str instruction.\r
sub sp, sp, #(FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)\r
\r
- // Push some GP registers so we can record the exception context\r
+ // Push the GP registers so we can record the exception context\r
stp x0, x1, [sp, #-GP_CONTEXT_SIZE]!\r
stp x2, x3, [sp, #0x10]\r
stp x4, x5, [sp, #0x20]\r
stp x6, x7, [sp, #0x30]\r
+ stp x8, x9, [sp, #0x40]\r
+ stp x10, x11, [sp, #0x50]\r
+ stp x12, x13, [sp, #0x60]\r
+ stp x14, x15, [sp, #0x70]\r
+ stp x16, x17, [sp, #0x80]\r
+ stp x18, x19, [sp, #0x90]\r
+ stp x20, x21, [sp, #0xa0]\r
+ stp x22, x23, [sp, #0xb0]\r
+ stp x24, x25, [sp, #0xc0]\r
+ stp x26, x27, [sp, #0xd0]\r
+ stp x28, x29, [sp, #0xe0]\r
+ add x28, sp, #(GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE)\r
\r
- EL1_OR_EL2_OR_EL3(x1)\r
-1:mrs x2, elr_el1 // Exception Link Register\r
- mrs x3, spsr_el1 // Saved Processor Status Register 32bit\r
- mrs x5, esr_el1 // EL1 Exception syndrome register 32bit\r
- mrs x6, far_el1 // EL1 Fault Address Register\r
- b 4f\r
-\r
-2:mrs x2, elr_el2 // Exception Link Register\r
- mrs x3, spsr_el2 // Saved Processor Status Register 32bit\r
- mrs x5, esr_el2 // EL2 Exception syndrome register 32bit\r
- mrs x6, far_el2 // EL2 Fault Address Register\r
- b 4f\r
-\r
-3:mrs x2, elr_el3 // Exception Link Register\r
- mrs x3, spsr_el3 // Saved Processor Status Register 32bit\r
- mrs x5, esr_el3 // EL3 Exception syndrome register 32bit\r
- mrs x6, far_el3 // EL3 Fault Address Register\r
+ .ifnc \sp, SPx\r
+ msr SPsel, #1\r
+ mov x7, sp\r
+ msr SPsel, xzr\r
+ .else\r
+ mov x7, x28\r
+ .endif\r
\r
-4:mrs x4, fpsr // Floating point Status Register 32bit\r
+ stp x30, x7, [sp, #0xf0]\r
\r
// Record the type of exception that occurred.\r
mov x0, #\val\r
//\r
VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPx_SYNC)\r
ASM_PFX(SynchronousExceptionSPx):\r
- ExceptionEntry EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS\r
+ ExceptionEntry EXCEPT_AARCH64_SYNCHRONOUS_EXCEPTIONS, SP0\r
\r
VECTOR_ENTRY(ExceptionHandlersStart, ARM_VECTOR_CUR_SPx_IRQ)\r
ASM_PFX(IrqSPx):\r
\r
ASM_PFX(CommonExceptionEntry):\r
\r
- // Stack the remaining GP registers\r
- stp x8, x9, [sp, #0x40]\r
- stp x10, x11, [sp, #0x50]\r
- stp x12, x13, [sp, #0x60]\r
- stp x14, x15, [sp, #0x70]\r
- stp x16, x17, [sp, #0x80]\r
- stp x18, x19, [sp, #0x90]\r
- stp x20, x21, [sp, #0xa0]\r
- stp x22, x23, [sp, #0xb0]\r
- stp x24, x25, [sp, #0xc0]\r
- stp x26, x27, [sp, #0xd0]\r
- stp x28, x29, [sp, #0xe0]\r
- add x28, sp, #GP_CONTEXT_SIZE + FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE\r
- stp x30, x28, [sp, #0xf0]\r
+ EL1_OR_EL2_OR_EL3(x1)\r
+1:mrs x2, elr_el1 // Exception Link Register\r
+ mrs x3, spsr_el1 // Saved Processor Status Register 32bit\r
+ mrs x5, esr_el1 // EL1 Exception syndrome register 32bit\r
+ mrs x6, far_el1 // EL1 Fault Address Register\r
+ b 4f\r
+\r
+2:mrs x2, elr_el2 // Exception Link Register\r
+ mrs x3, spsr_el2 // Saved Processor Status Register 32bit\r
+ mrs x5, esr_el2 // EL2 Exception syndrome register 32bit\r
+ mrs x6, far_el2 // EL2 Fault Address Register\r
+ b 4f\r
+\r
+3:mrs x2, elr_el3 // Exception Link Register\r
+ mrs x3, spsr_el3 // Saved Processor Status Register 32bit\r
+ mrs x5, esr_el3 // EL3 Exception syndrome register 32bit\r
+ mrs x6, far_el3 // EL3 Fault Address Register\r
+\r
+4:mrs x4, fpsr // Floating point Status Register 32bit\r
\r
// Save the SYS regs\r
stp x2, x3, [x28, #-SYS_CONTEXT_SIZE]!\r
add sp, sp, #FP_CONTEXT_SIZE + SYS_CONTEXT_SIZE\r
\r
eret\r
+\r
+ASM_PFX(RegisterEl0Stack):\r
+ msr sp_el0, x0\r
+ ret\r