// vim:ft=arm64asm
#include <rt/arch/sysreg.h>
.macro sync_handler
stp x0, x1, [sp, -0x10]!
mrs x0, esr_el1
lsr w0, w0, ESR_EL1_EC_SHIFT
cmp w0, ESR_EL1_EC_SVC
bne 0f
ldp x0, x1, [sp], 0x10
b rt_svc_handler
0:
cmp w0, ESR_EL1_EC_FPSIMD
bne 0f
mrs x1, cpacr_el1
orr x1, x1, CPACR_EL1_FPEN_ENABLE
msr cpacr_el1, x1
isb
ldp x0, x1, [sp], 0x10
b vfp_init_eret
0:
ldp x0, x1, [sp], 0x10
b unhandled_exception
.endm
.section .text.vector, "ax", %progbits
.balign 2048
.global vector
vector:
// EL1t
sync_handler
.if . - vector > 128
.error "sync_handler is too large"
.endif
.balign 128
b rt_irq_handler
.balign 128
b unhandled_exception // FIQ (not enabled)
.balign 128
b unhandled_exception // SError
.balign 128
// EL1h
// SVC and FP/SIMD errors are not expected from handlers.
b unhandled_exception
.balign 128
b rt_irq_handler_nested
.balign 128
b unhandled_exception // FIQ (not enabled)
.balign 128
b unhandled_exception // SError
.balign 128
// EL0
sync_handler
.balign 128
b rt_irq_handler
.balign 128
b unhandled_exception // FIQ (not enabled)
.balign 128
b unhandled_exception // SError
.balign 128
// EL0 AArch32 (not used, AArch64-only).
b unhandled_exception
.balign 128
b unhandled_exception
.balign 128
b unhandled_exception
.balign 128
b unhandled_exception
.balign 128
.size vector, .-vector
.section .text.vfp_init_eret, "ax", %progbits
.type vfp_init_eret, %function
vfp_init_eret:
msr fpcr, xzr
msr fpsr, xzr
movi v0.2d, 0
movi v1.2d, 0
movi v2.2d, 0
movi v3.2d, 0
movi v4.2d, 0
movi v5.2d, 0
movi v6.2d, 0
movi v7.2d, 0
movi v8.2d, 0
movi v9.2d, 0
movi v10.2d, 0
movi v11.2d, 0
movi v12.2d, 0
movi v13.2d, 0
movi v14.2d, 0
movi v15.2d, 0
movi v16.2d, 0
movi v17.2d, 0
movi v18.2d, 0
movi v19.2d, 0
movi v20.2d, 0
movi v21.2d, 0
movi v22.2d, 0
movi v23.2d, 0
movi v24.2d, 0
movi v25.2d, 0
movi v26.2d, 0
movi v27.2d, 0
movi v28.2d, 0
movi v29.2d, 0
movi v30.2d, 0
movi v31.2d, 0
eret
.size vfp_init_eret, .-vfp_init_eret