#include <arch/arm/arch_cpu.h>
#include <asm_defs.h>
#include "asm_offsets.h"
#include "syscall_numbers.h"
.text
FUNCTION(_thread_exit_syscall):
svc #(SYSCALL_EXIT_THREAD)
FUNCTION_END(_thread_exit_syscall)
.macro xchg_sp xt
add sp, sp, \xt
sub \xt, sp, \xt
sub sp, sp, \xt
.endm
.macro EXCEPTION_ENTRY el
xchg_sp x19
sub x19, x19, #(IFRAME_sizeof)
stp x0, x1, [x19, #(IFRAME_x + 0 * 8)]
stp x2, x3, [x19, #(IFRAME_x + 2 * 8)]
stp x4, x5, [x19, #(IFRAME_x + 4 * 8)]
stp x6, x7, [x19, #(IFRAME_x + 6 * 8)]
stp x8, x9, [x19, #(IFRAME_x + 8 * 8)]
stp x10, x11, [x19, #(IFRAME_x + 10 * 8)]
stp x12, x13, [x19, #(IFRAME_x + 12 * 8)]
stp x14, x15, [x19, #(IFRAME_x + 14 * 8)]
stp x16, x17, [x19, #(IFRAME_x + 16 * 8)]
mov x0, sp
stp x18, x0, [x19, #(IFRAME_x + 18 * 8)]
stp x20, x21, [x19, #(IFRAME_x + 20 * 8)]
stp x22, x23, [x19, #(IFRAME_x + 22 * 8)]
stp x24, x25, [x19, #(IFRAME_x + 24 * 8)]
stp x26, x27, [x19, #(IFRAME_x + 26 * 8)]
stp x28, fp, [x19, #(IFRAME_x + 28 * 8)]
str x30, [x19, #(IFRAME_lr)]
add x0, x19, #(IFRAME_fpu)
bl _fp_save
.if \el == 0
mrs x0, SP_EL0
add x20, x19, #(IFRAME_sizeof)
.else
add x0, x19, #(IFRAME_sizeof)
.endif
mrs x1, ELR_EL1
mrs x2, SPSR_EL1
mrs x3, ESR_EL1
mrs x4, FAR_EL1
mrs x5, TPIDR_EL0
str x0, [x19, #(IFRAME_sp)]
str x1, [x19, #(IFRAME_elr)]
str x2, [x19, #(IFRAME_spsr)]
str x3, [x19, #(IFRAME_esr)]
str x4, [x19, #(IFRAME_far)]
str x5, [x19, #(IFRAME_tpidr)]
.endm
.macro EXCEPTION_RETURN el
add x0, x19, #(IFRAME_fpu)
bl _fp_restore
ldr x0, [x19, #(IFRAME_elr)]
ldr x1, [x19, #(IFRAME_spsr)]
ldr x18, [x19, #(IFRAME_sp)]
ldp x2, x3, [x19, #(IFRAME_x + 2 * 8)]
ldp x4, x5, [x19, #(IFRAME_x + 4 * 8)]
ldp x6, x7, [x19, #(IFRAME_x + 6 * 8)]
ldp x8, x9, [x19, #(IFRAME_x + 8 * 8)]
ldp x10, x11, [x19, #(IFRAME_x + 10 * 8)]
ldp x12, x13, [x19, #(IFRAME_x + 12 * 8)]
ldp x14, x15, [x19, #(IFRAME_x + 14 * 8)]
ldp x16, x17, [x19, #(IFRAME_x + 16 * 8)]
ldp x21, x22, [x19, #(IFRAME_x + 21 * 8)]
ldp x23, x24, [x19, #(IFRAME_x + 23 * 8)]
ldp x25, x26, [x19, #(IFRAME_x + 25 * 8)]
ldp x27, x28, [x19, #(IFRAME_x + 27 * 8)]
ldp x29, x30, [x19, #(IFRAME_x + 29 * 8)]
msr DAIFSet, #0xf
msr ELR_EL1, x0
msr SPSR_EL1, x1
.if \el == 0
msr SP_EL0, x18
mov sp, x20
.else
mov sp, x18
.endif
ldr x0, [x19, #(IFRAME_tpidr)]
msr TPIDR_EL0, x0
ldp x0, x1, [x19, #(IFRAME_x + 0 * 8)]
ldr x20, [x19, #(IFRAME_x + 20 * 8)]
ldp x18, x19, [x19, #(IFRAME_x + 18 * 8)]
eret
.endm
.macro EXCEPTION_HANDLER el name func
STATIC_FUNCTION(handle_\name):
EXCEPTION_ENTRY \el
and sp, x19, #0xfffffffffffffff0
mov x0, x19
mov x29, x0
bl \func
EXCEPTION_RETURN \el
FUNCTION_END(handle_\name)
.endm
.macro vector name
.align 7
b handle_\name
.endm
.macro vempty
.align 7
brk 0xfff
1: b 1b
.endm
.align 11
.globl _exception_vectors
_exception_vectors:
vempty
vempty
vempty
vempty
vector el1h_sync
vector el1h_irq
vector el1h_fiq
vector el1h_error
vector el0_sync
vector el0_irq
vector el0_fiq
vector el0_error
vempty
vempty
vempty
vempty
EXCEPTION_HANDLER 1 el1h_sync do_sync_handler
EXCEPTION_HANDLER 1 el1h_irq do_irq_handler
EXCEPTION_HANDLER 1 el1h_fiq do_fiq_handler
EXCEPTION_HANDLER 1 el1h_error do_error_handler
EXCEPTION_HANDLER 0 el0_sync do_sync_handler
EXCEPTION_HANDLER 0 el0_irq do_irq_handler
EXCEPTION_HANDLER 0 el0_fiq do_fiq_handler
EXCEPTION_HANDLER 0 el0_error do_error_handler
FUNCTION(_eret_with_iframe):
mov x19, x0
mov x20, x1
EXCEPTION_RETURN 0
FUNCTION_END(_eret_with_iframe)
FUNCTION(_fp_save):
stp q0, q1, [x0], #32
stp q2, q3, [x0], #32
stp q4, q5, [x0], #32
stp q6, q7, [x0], #32
stp q8, q9, [x0], #32
stp q10, q11, [x0], #32
stp q12, q13, [x0], #32
stp q14, q15, [x0], #32
stp q16, q17, [x0], #32
stp q18, q19, [x0], #32
stp q20, q21, [x0], #32
stp q22, q23, [x0], #32
stp q24, q25, [x0], #32
stp q26, q27, [x0], #32
stp q28, q29, [x0], #32
stp q30, q31, [x0], #32
mrs x1, FPSR
mrs x2, FPCR
str x1, [x0], #8
str x2, [x0], #8
msr FPSR, xzr
cmp x2, xzr
beq 1f
msr FPCR, xzr
1:
ret
FUNCTION_END(_fp_save)
FUNCTION(_fp_restore):
ldp q0, q1, [x0], #32
ldp q2, q3, [x0], #32
ldp q4, q5, [x0], #32
ldp q6, q7, [x0], #32
ldp q8, q9, [x0], #32
ldp q10, q11, [x0], #32
ldp q12, q13, [x0], #32
ldp q14, q15, [x0], #32
ldp q16, q17, [x0], #32
ldp q18, q19, [x0], #32
ldp q20, q21, [x0], #32
ldp q22, q23, [x0], #32
ldp q24, q25, [x0], #32
ldp q26, q27, [x0], #32
ldp q28, q29, [x0], #32
ldp q30, q31, [x0], #32
ldr x1, [x0], #8
msr FPSR, x1
ldr x2, [x0], #8
mrs x3, FPCR
cmp x3, x2
beq 1f
msr FPCR, x2
1:
ret
FUNCTION_END(_fp_restore)
FUNCTION(_arch_context_swap):
stp x19, x20, [x0], #16
stp x21, x22, [x0], #16
stp x23, x24, [x0], #16
stp x25, x26, [x0], #16
stp x27, x28, [x0], #16
stp x29, x30, [x0], #16
mov x2, sp
str x2, [x0], #8
stp d8, d9, [x0], #16
stp d10, d11, [x0], #16
stp d12, d13, [x0], #16
stp d14, d15, [x0], #16
ldp x19, x20, [x1], #16
ldp x21, x22, [x1], #16
ldp x23, x24, [x1], #16
ldp x25, x26, [x1], #16
ldp x27, x28, [x1], #16
ldp x29, x30, [x1], #16
ldr x2, [x1], #8
mov sp, x2
ldp d8, d9, [x1], #16
ldp d10, d11, [x1], #16
ldp d12, d13, [x1], #16
ldp d14, d15, [x1], #16
mov x0, x29
ret
FUNCTION_END(_arch_context_swap)
FUNCTION(arch_debug_call_with_fault_handler):
adrp x4, fault
add x4, x4, :lo12:fault
str x4, [x0, #CPU_ENT_fault_handler]
str x1, [x0, #CPU_ENT_fault_handler_stack_pointer]
mov x0, x3
br x2
fault:
mov x0, sp
mov x1, #1
b longjmp
FUNCTION_END(arch_debug_call_with_fault_handler)
FUNCTION(arm64_get_fp):
mov x0, x29
ret
FUNCTION_END(arm64_get_fp)