blob: 7810399a2dc93c3aa288fbfb6b899fd0537d8f1b [file] [log] [blame]
/*
* Copyright (c) 2019 Carlo Caione <ccaione@baylibre.com>
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _MACRO_PRIV_INC_
#define _MACRO_PRIV_INC_
#ifdef _ASMLANGUAGE
/*
* Save volatile registers, x30, SPSR_EL1 and ELR_EL1
*
* Save the volatile registers and x30 on the process stack. This is
* needed if the thread is switched out because they can be clobbered by the
* ISR and/or context switch.
*/
.macro z_arm64_enter_exc xreg0, xreg1
/* Switch to SP_EL0 */
msr spsel, #0
/*
* Two things can happen to the remaining registers:
*
* - No context-switch: in this case x19-x28 are callee-saved register
* so we can be sure they are not going to be clobbered by ISR.
* - Context-switch: the callee-saved registers are saved by
* z_arm64_context_switch() in the kernel structure.
*/
sub sp, sp, ___esf_t_SIZEOF
stp x0, x1, [sp, ___esf_t_x0_x1_OFFSET]
stp x2, x3, [sp, ___esf_t_x2_x3_OFFSET]
stp x4, x5, [sp, ___esf_t_x4_x5_OFFSET]
stp x6, x7, [sp, ___esf_t_x6_x7_OFFSET]
stp x8, x9, [sp, ___esf_t_x8_x9_OFFSET]
stp x10, x11, [sp, ___esf_t_x10_x11_OFFSET]
stp x12, x13, [sp, ___esf_t_x12_x13_OFFSET]
stp x14, x15, [sp, ___esf_t_x14_x15_OFFSET]
stp x16, x17, [sp, ___esf_t_x16_x17_OFFSET]
stp x18, x30, [sp, ___esf_t_x18_x30_OFFSET]
mrs \xreg0, spsr_el1
mrs \xreg1, elr_el1
stp \xreg0, \xreg1, [sp, ___esf_t_spsr_elr_OFFSET]
.endm
/*
* Restore volatile registers, x30, SPSR_EL1 and ELR_EL1
*
* This is the common exit point for z_arm64_sync_exc() and _isr_wrapper().
*/
.macro z_arm64_exit_exc xreg0, xreg1
ldp \xreg0, \xreg1, [sp, ___esf_t_spsr_elr_OFFSET]
msr spsr_el1, \xreg0
msr elr_el1, \xreg1
ldp x18, x30, [sp, ___esf_t_x18_x30_OFFSET]
ldp x16, x17, [sp, ___esf_t_x16_x17_OFFSET]
ldp x14, x15, [sp, ___esf_t_x14_x15_OFFSET]
ldp x12, x13, [sp, ___esf_t_x12_x13_OFFSET]
ldp x10, x11, [sp, ___esf_t_x10_x11_OFFSET]
ldp x8, x9, [sp, ___esf_t_x8_x9_OFFSET]
ldp x6, x7, [sp, ___esf_t_x6_x7_OFFSET]
ldp x4, x5, [sp, ___esf_t_x4_x5_OFFSET]
ldp x2, x3, [sp, ___esf_t_x2_x3_OFFSET]
ldp x0, x1, [sp, ___esf_t_x0_x1_OFFSET]
add sp, sp, ___esf_t_SIZEOF
/*
* In general in the ELR_EL1 register we can find:
*
* - The address of ret in z_arm64_call_svc()
* - The address of the next instruction at the time of the IRQ when the
* thread was switched out.
* - The address of z_thread_entry() for new threads (see thread.c).
*/
eret
.endm
/*
* Increment nested counter
*/
.macro inc_nest_counter xreg0, xreg1
ldr \xreg0, =_kernel
ldr \xreg1, [\xreg0, #_kernel_offset_to_nested]
add \xreg1, \xreg1, #1
str \xreg1, [\xreg0, #_kernel_offset_to_nested]
.endm
/*
* Decrement nested counter
*/
.macro dec_nest_counter xreg0, xreg1
ldr \xreg0, =_kernel
ldr \xreg1, [\xreg0, #_kernel_offset_to_nested]
sub \xreg1, \xreg1, #1
str \xreg1, [\xreg0, #_kernel_offset_to_nested]
.endm
#endif /* _ASMLANGUAGE */
#endif /* _MACRO_PRIV_INC_ */