/*
* Stack size to save general purpose registers and essential system
* registers. 8 * (30 + lr + elr_el1 + spsr_el1 + esr_el1) = 272.
- * From exceptions come from EL0, we have to save sp_el0. So the
- * TRAP_STACK_SIZE should be 272 + 8 = 280. But we enable the stack
- * alignment check, we will force align the stack for EL1 exceptions,
- * so we add a sp to save original stack pointer: 280 + 8 = 288
+ * We enable the stack alignment check, we will force align the stack for
+ * EL1 exceptions, so we add a sp to save original stack pointer: 272 + 8 = 280
+ * and then a padding of 8 bytes: 280 + 8 = 288 (288 % 16 == 0).
*
* TODO: We'd better to calculate this size automatically later.
*/
#define __TRAP_STACK_SIZE 288
#define __SP_OFFSET 272
-#define __SP_EL0_OFFSET 280
/*
* In thread context switch, we will save the callee-saved registers
/* Stack Pointer */
uint64_t sp;
- /* Stack Pointer from el0 */
- uint64_t sp_el0;
+ /* Padding to make sure this structure is 16-byte aligned */
+ __u8 pad[8];
};
/*
EXCHANGE_SP_WITH_X0
.endm
-.macro ENTER_TRAP, el
+.macro SAVE_REGS
sub sp, sp, #__TRAP_STACK_SIZE
-.if \el != 0
- /* Force align the stack, and save SP to __SP_OFFSET */
- ALIGN_STACK
-.endif
-
/* Save general purpose registers */
stp x0, x1, [sp, #16 * 0]
stp x2, x3, [sp, #16 * 1]
mrs x22, spsr_el1
mrs x23, esr_el1
stp x22, x23, [sp, #16 * 16]
-
-.if \el == 0
- /* Save stack pointer for lower level exception */
- mrs x18, sp_el0
- str x18, [sp, #__SP_EL0_OFFSET]
-.endif
-
.endm
-.macro LEAVE_TRAP, el
+.macro RESTORE_REGS
/* Mask IRQ to make sure restore would not be interrupted by IRQ */
msr daifset, #2
ldp x2, x3, [sp, #16 * 1]
ldp x0, x1, [sp, #16 * 0]
-.if \el == 0
- /* Restore stack pointer for exception from EL0 */
- ldr x18, [sp, #__SP_EL0_OFFSET]
- msr sp_el0, x18
-
- /* Restore x18, x19 */
- ldp x18, x19, [sp, #16 * 9]
-.else
/* Restore stack pointer for exception from EL1 */
ldr x18, [sp, #__SP_OFFSET]
mov x19, sp
/* Restore x18, x19 */
ldp x18, x19, [x19, #16 * 9]
-.endif
+
add sp, sp, #__TRAP_STACK_SIZE
eret
*/
.align 6
el1_sync:
- ENTER_TRAP 1
+ SAVE_REGS
mov x0, sp
mrs x1, far_el1
bl trap_el1_sync
- LEAVE_TRAP 1
+ RESTORE_REGS
.align 6
el1_irq:
- ENTER_TRAP 1
+ SAVE_REGS
msr daifclr, #(8 | 4 | 1)
mov x0, sp
bl trap_el1_irq
- LEAVE_TRAP 1
+ RESTORE_REGS
/* Bad Abort numbers */
#define BAD_SYNC 0
#define el_invalid(name, reason, el) \
.align 6; \
name##_invalid: \
- ENTER_TRAP el; \
+ SAVE_REGS; \
mov x0, sp; \
mov x1, el; \
mov x2, #(reason); \