127 lines · plain
1/* SPDX-License-Identifier: GPL-2.0 */2.macro save_registers3 add sp, sp, #-16 * 174 5 stp x0, x1, [sp, #16 * 0]6 stp x2, x3, [sp, #16 * 1]7 stp x4, x5, [sp, #16 * 2]8 stp x6, x7, [sp, #16 * 3]9 stp x8, x9, [sp, #16 * 4]10 stp x10, x11, [sp, #16 * 5]11 stp x12, x13, [sp, #16 * 6]12 stp x14, x15, [sp, #16 * 7]13 stp x16, x17, [sp, #16 * 8]14 stp x18, x19, [sp, #16 * 9]15 stp x20, x21, [sp, #16 * 10]16 stp x22, x23, [sp, #16 * 11]17 stp x24, x25, [sp, #16 * 12]18 stp x26, x27, [sp, #16 * 13]19 stp x28, x29, [sp, #16 * 14]20 21 /*22 * This stores sp_el1 into ex_regs.sp so exception handlers can "look"23 * at it. It will _not_ be used to restore the sp on return from the24 * exception so handlers can not update it.25 */26 add x1, sp, #16 * 1727 stp x30, x1, [sp, #16 * 15] /* x30, SP */28 29 mrs x1, elr_el130 mrs x2, spsr_el131 stp x1, x2, [sp, #16 * 16] /* PC, PSTATE */32.endm33 34.macro restore_registers35 ldp x1, x2, [sp, #16 * 16] /* PC, PSTATE */36 msr elr_el1, x137 msr spsr_el1, x238 39 /* sp is not restored */40 ldp x30, xzr, [sp, #16 * 15] /* x30, SP */41 42 ldp x28, x29, [sp, #16 * 14]43 ldp x26, x27, [sp, #16 * 13]44 ldp x24, x25, [sp, #16 * 12]45 ldp x22, x23, [sp, #16 * 11]46 ldp x20, x21, [sp, #16 * 10]47 ldp x18, x19, [sp, #16 * 9]48 ldp x16, x17, [sp, #16 * 8]49 ldp x14, x15, [sp, #16 * 7]50 ldp x12, x13, [sp, #16 * 6]51 ldp x10, x11, [sp, #16 * 5]52 ldp x8, x9, [sp, #16 * 4]53 ldp x6, x7, [sp, #16 * 3]54 ldp x4, x5, [sp, #16 * 2]55 ldp x2, x3, [sp, #16 * 1]56 ldp x0, x1, [sp, #16 * 0]57 58 add sp, sp, #16 * 1759 60 eret61.endm62 63.pushsection ".entry.text", "ax"64.balign 0x80065.global vectors66vectors:67.popsection68 69.set vector, 070 71/*72 * Build an exception handler for vector and append a jump to it into73 * vectors (while making sure that it's 0x80 aligned).74 */75.macro HANDLER, label76handler_\label:77 save_registers78 mov x0, sp79 mov x1, #vector80 bl route_exception81 restore_registers82 83.pushsection ".entry.text", "ax"84.balign 0x8085 b handler_\label86.popsection87 88.set vector, vector + 189.endm90 91.macro HANDLER_INVALID92.pushsection ".entry.text", "ax"93.balign 0x8094/* This will abort so no need to save and restore registers. */95 mov x0, #vector96 mov x1, #0 /* ec */97 mov x2, #0 /* valid_ec */98 b kvm_exit_unexpected_exception99.popsection100 101.set vector, vector + 1102.endm103 104/*105 * Caution: be sure to not add anything between the declaration of vectors106 * above and these macro calls that will build the vectors table below it.107 */108 HANDLER_INVALID // Synchronous EL1t109 HANDLER_INVALID // IRQ EL1t110 HANDLER_INVALID // FIQ EL1t111 HANDLER_INVALID // Error EL1t112 113 HANDLER el1h_sync // Synchronous EL1h114 HANDLER el1h_irq // IRQ EL1h115 HANDLER el1h_fiq // FIQ EL1h116 HANDLER el1h_error // Error EL1h117 118 HANDLER el0_sync_64 // Synchronous 64-bit EL0119 HANDLER el0_irq_64 // IRQ 64-bit EL0120 HANDLER el0_fiq_64 // FIQ 64-bit EL0121 HANDLER el0_error_64 // Error 64-bit EL0122 123 HANDLER el0_sync_32 // Synchronous 32-bit EL0124 HANDLER el0_irq_32 // IRQ 32-bit EL0125 HANDLER el0_fiq_32 // FIQ 32-bit EL0126 HANDLER el0_error_32 // Error 32-bit EL0127