Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 .macro save_registers
0003     add sp, sp, #-16 * 17
0004 
0005     stp x0, x1, [sp, #16 * 0]
0006     stp x2, x3, [sp, #16 * 1]
0007     stp x4, x5, [sp, #16 * 2]
0008     stp x6, x7, [sp, #16 * 3]
0009     stp x8, x9, [sp, #16 * 4]
0010     stp x10, x11, [sp, #16 * 5]
0011     stp x12, x13, [sp, #16 * 6]
0012     stp x14, x15, [sp, #16 * 7]
0013     stp x16, x17, [sp, #16 * 8]
0014     stp x18, x19, [sp, #16 * 9]
0015     stp x20, x21, [sp, #16 * 10]
0016     stp x22, x23, [sp, #16 * 11]
0017     stp x24, x25, [sp, #16 * 12]
0018     stp x26, x27, [sp, #16 * 13]
0019     stp x28, x29, [sp, #16 * 14]
0020 
0021     /*
0022      * This stores sp_el1 into ex_regs.sp so exception handlers can "look"
0023      * at it. It will _not_ be used to restore the sp on return from the
0024      * exception so handlers can not update it.
0025      */
0026     add x1, sp, #16 * 17
0027     stp x30, x1, [sp, #16 * 15] /* x30, SP */
0028 
0029     mrs x1, elr_el1
0030     mrs x2, spsr_el1
0031     stp x1, x2, [sp, #16 * 16] /* PC, PSTATE */
0032 .endm
0033 
0034 .macro restore_registers
0035     ldp x1, x2, [sp, #16 * 16] /* PC, PSTATE */
0036     msr elr_el1, x1
0037     msr spsr_el1, x2
0038 
0039     /* sp is not restored */
0040     ldp x30, xzr, [sp, #16 * 15] /* x30, SP */
0041 
0042     ldp x28, x29, [sp, #16 * 14]
0043     ldp x26, x27, [sp, #16 * 13]
0044     ldp x24, x25, [sp, #16 * 12]
0045     ldp x22, x23, [sp, #16 * 11]
0046     ldp x20, x21, [sp, #16 * 10]
0047     ldp x18, x19, [sp, #16 * 9]
0048     ldp x16, x17, [sp, #16 * 8]
0049     ldp x14, x15, [sp, #16 * 7]
0050     ldp x12, x13, [sp, #16 * 6]
0051     ldp x10, x11, [sp, #16 * 5]
0052     ldp x8, x9, [sp, #16 * 4]
0053     ldp x6, x7, [sp, #16 * 3]
0054     ldp x4, x5, [sp, #16 * 2]
0055     ldp x2, x3, [sp, #16 * 1]
0056     ldp x0, x1, [sp, #16 * 0]
0057 
0058     add sp, sp, #16 * 17
0059 
0060     eret
0061 .endm
0062 
0063 .pushsection ".entry.text", "ax"
0064 .balign 0x800
0065 .global vectors
0066 vectors:
0067 .popsection
0068 
0069 .set    vector, 0
0070 
0071 /*
0072  * Build an exception handler for vector and append a jump to it into
0073  * vectors (while making sure that it's 0x80 aligned).
0074  */
0075 .macro HANDLER, label
0076 handler_\label:
0077     save_registers
0078     mov x0, sp
0079     mov x1, #vector
0080     bl  route_exception
0081     restore_registers
0082 
0083 .pushsection ".entry.text", "ax"
0084 .balign 0x80
0085     b   handler_\label
0086 .popsection
0087 
0088 .set    vector, vector + 1
0089 .endm
0090 
0091 .macro HANDLER_INVALID
0092 .pushsection ".entry.text", "ax"
0093 .balign 0x80
0094 /* This will abort so no need to save and restore registers. */
0095     mov x0, #vector
0096     mov x1, #0 /* ec */
0097     mov x2, #0 /* valid_ec */
0098     b   kvm_exit_unexpected_exception
0099 .popsection
0100 
0101 .set    vector, vector + 1
0102 .endm
0103 
0104 /*
0105  * Caution: be sure to not add anything between the declaration of vectors
0106  * above and these macro calls that will build the vectors table below it.
0107  */
0108     HANDLER_INVALID                         // Synchronous EL1t
0109     HANDLER_INVALID                         // IRQ EL1t
0110     HANDLER_INVALID                         // FIQ EL1t
0111     HANDLER_INVALID                         // Error EL1t
0112 
0113     HANDLER el1h_sync                       // Synchronous EL1h
0114     HANDLER el1h_irq                        // IRQ EL1h
0115     HANDLER el1h_fiq                        // FIQ EL1h
0116     HANDLER el1h_error                      // Error EL1h
0117 
0118     HANDLER el0_sync_64                     // Synchronous 64-bit EL0
0119     HANDLER el0_irq_64                      // IRQ 64-bit EL0
0120     HANDLER el0_fiq_64                      // FIQ 64-bit EL0
0121     HANDLER el0_error_64                    // Error 64-bit EL0
0122 
0123     HANDLER el0_sync_32                     // Synchronous 32-bit EL0
0124     HANDLER el0_irq_32                      // IRQ 32-bit EL0
0125     HANDLER el0_fiq_32                      // FIQ 32-bit EL0
0126     HANDLER el0_error_32                    // Error 32-bit EL0