diff --git a/sys/arm64/arm64/exception.S b/sys/arm64/arm64/exception.S --- a/sys/arm64/arm64/exception.S +++ b/sys/arm64/arm64/exception.S @@ -33,7 +33,12 @@ .text -.macro save_registers el +/* + * This is limited to 28 instructions as it's placed in the exception vector + * slot that is 32 instructions long. We need one for the branch, and three + * for the prolog. + */ +.macro save_registers_head el .if \el == 1 mov x18, sp sub sp, sp, #128 @@ -65,6 +70,9 @@ stp x18, lr, [sp, #(TF_SP)] mrs x18, tpidr_el1 add x29, sp, #(TF_SIZE) +.endm + +.macro save_registers el .if \el == 0 #if defined(PERTHREAD_SSP) /* Load the SSP canary to sp_el0 */ @@ -234,36 +242,40 @@ b 1b END(handle_empty_exception) -.macro vempty +.macro vector name, el .align 7 - b handle_empty_exception + save_registers_head \el + b handle_\name + dsb sy + isb + /* Break instruction to ensure we aren't executing code here. */ + brk 0x42 .endm -.macro vector name - .align 7 - b handle_\name +.macro vempty el + vector empty_exception \el .endm .align 11 .globl exception_vectors exception_vectors: - vempty /* Synchronous EL1t */ - vempty /* IRQ EL1t */ - vempty /* FIQ EL1t */ - vempty /* Error EL1t */ + vempty 1 /* Synchronous EL1t */ + vempty 1 /* IRQ EL1t */ + vempty 1 /* FIQ EL1t */ + vempty 1 /* Error EL1t */ - vector el1h_sync /* Synchronous EL1h */ - vector el1h_irq /* IRQ EL1h */ - vempty /* FIQ EL1h */ - vector serror /* Error EL1h */ + vector el1h_sync 1 /* Synchronous EL1h */ + vector el1h_irq 1 /* IRQ EL1h */ + vempty 1 /* FIQ EL1h */ + vector serror 1 /* Error EL1h */ - vector el0_sync /* Synchronous 64-bit EL0 */ - vector el0_irq /* IRQ 64-bit EL0 */ - vempty /* FIQ 64-bit EL0 */ - vector serror /* Error 64-bit EL0 */ + vector el0_sync 0 /* Synchronous 64-bit EL0 */ + vector el0_irq 0 /* IRQ 64-bit EL0 */ + vempty 0 /* FIQ 64-bit EL0 */ + vector serror 0 /* Error 64-bit EL0 */ - vector el0_sync /* Synchronous 32-bit EL0 */ - vector el0_irq /* IRQ 32-bit EL0 */ - vempty /* FIQ 32-bit EL0 */ - vector serror /* Error 32-bit EL0 */ + vector el0_sync 0 /* Synchronous 32-bit EL0 */ + vector el0_irq 0 /* IRQ 32-bit EL0 */ + vempty 0 /* FIQ 32-bit EL0 */ + vector serror 0 /* Error 32-bit EL0 */