arch : arc: clean up of assembly codes

* update comments to match latest codes
* add extra comments for some assembly, macros
* use macro to replace duplcated codes
* remove unused codes, lables, symobols

Signed-off-by: Wayne Ren <wei.ren@synopsys.com>
This commit is contained in:
Wayne Ren 2020-02-29 22:58:22 +08:00 committed by Anas Nashif
commit 84cdfa271d
6 changed files with 196 additions and 213 deletions

View file

@ -19,7 +19,6 @@
#include <syscall.h> #include <syscall.h>
GTEXT(_Fault) GTEXT(_Fault)
GTEXT(z_do_kernel_oops)
GTEXT(__reset) GTEXT(__reset)
GTEXT(__memory_error) GTEXT(__memory_error)
GTEXT(__instruction_error) GTEXT(__instruction_error)
@ -38,6 +37,17 @@ GTEXT(__ev_maligned)
GTEXT(z_irq_do_offload); GTEXT(z_irq_do_offload);
#endif #endif
.macro _save_exc_regs_into_stack
#ifdef CONFIG_ARC_HAS_SECURE
/* ERSEC_STAT is IOW/RAZ in normal mode */
lr r0,[_ARC_V2_ERSEC_STAT]
st_s r0, [sp, ___isf_t_sec_stat_OFFSET]
#endif
lr r0,[_ARC_V2_ERET]
st_s r0, [sp, ___isf_t_pc_OFFSET]
lr r0,[_ARC_V2_ERSTATUS]
st_s r0, [sp, ___isf_t_status32_OFFSET]
.endm
/* /*
* The exception handling will use top part of interrupt stack to * The exception handling will use top part of interrupt stack to
@ -89,15 +99,7 @@ _exc_entry:
*/ */
_create_irq_stack_frame _create_irq_stack_frame
#ifdef CONFIG_ARC_HAS_SECURE _save_exc_regs_into_stack
/* ERSEC_STAT is IOW/RAZ in normal mode */
lr r0,[_ARC_V2_ERSEC_STAT]
st_s r0, [sp, ___isf_t_sec_stat_OFFSET]
#endif
lr r0,[_ARC_V2_ERSTATUS]
st_s r0, [sp, ___isf_t_status32_OFFSET]
lr r0,[_ARC_V2_ERET]
st_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
/* sp is parameter of _Fault */ /* sp is parameter of _Fault */
mov_s r0, sp mov_s r0, sp
@ -178,6 +180,9 @@ _exc_return:
b _rirq_newthread_switch b _rirq_newthread_switch
_exc_return_from_exc: _exc_return_from_exc:
/* exception handler may change return address.
* reload it
*/
ld_s r0, [sp, ___isf_t_pc_OFFSET] ld_s r0, [sp, ___isf_t_pc_OFFSET]
sr r0, [_ARC_V2_ERET] sr r0, [_ARC_V2_ERET]
@ -185,7 +190,7 @@ _exc_return_from_exc:
mov_s sp, ilink mov_s sp, ilink
rtie rtie
/* separated entry for trap which may be used by irq_offload, USERPSACE */
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap) SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap)
/* get the id of trap_s */ /* get the id of trap_s */
lr ilink, [_ARC_V2_ECR] lr ilink, [_ARC_V2_ECR]
@ -208,15 +213,12 @@ valid_syscall_id:
*/ */
_create_irq_stack_frame _create_irq_stack_frame
#ifdef CONFIG_ARC_SECURE_FIRMWARE _save_exc_regs_into_stack
/* ERSEC_STAT is IOW/RAZ in normal mode */
lr r0, [_ARC_V2_ERSEC_STAT] /* exc return and do sys call in kernel mode,
st_s r0, [sp, ___isf_t_sec_stat_OFFSET] * so need to clear U bit, r0 is already loaded
#endif * with ERSTATUS in _save_exc_regs_into_stack
lr r0,[_ARC_V2_ERET] */
st_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
lr r0,[_ARC_V2_ERSTATUS]
st_s r0, [sp, ___isf_t_status32_OFFSET]
bclr r0, r0, _ARC_V2_STATUS32_U_BIT bclr r0, r0, _ARC_V2_STATUS32_U_BIT
sr r0, [_ARC_V2_ERSTATUS] sr r0, [_ARC_V2_ERSTATUS]
@ -239,15 +241,7 @@ _do_non_syscall_trap:
/* save caller saved registers */ /* save caller saved registers */
_create_irq_stack_frame _create_irq_stack_frame
#ifdef CONFIG_ARC_HAS_SECURE _save_exc_regs_into_stack
lr r0,[_ARC_V2_ERSEC_STAT]
st_s r0, [sp, ___isf_t_sec_stat_OFFSET]
#endif
lr r0,[_ARC_V2_ERSTATUS]
st_s r0, [sp, ___isf_t_status32_OFFSET]
lr r0,[_ARC_V2_ERET]
st_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
/* check whether irq stack is used */ /* check whether irq stack is used */
_check_and_inc_int_nest_counter r0, r1 _check_and_inc_int_nest_counter r0, r1
@ -266,6 +260,8 @@ exc_nest_handle:
_dec_int_nest_counter r0, r1 _dec_int_nest_counter r0, r1
_pop_irq_stack_frame _pop_irq_stack_frame
/* ERSTATUS, ERET are not changed, so ok to rtie */
rtie rtie
#endif /* CONFIG_IRQ_OFFLOAD */ #endif /* CONFIG_IRQ_OFFLOAD */
b _exc_entry b _exc_entry

View file

@ -42,7 +42,7 @@ Context switch explanation:
The context switch code is spread in these files: The context switch code is spread in these files:
isr_wrapper.s, switch.s, swap_macros.s, fast_irq.s, regular_irq.s isr_wrapper.s, switch.s, swap_macros.h, fast_irq.s, regular_irq.s
IRQ stack frame layout: IRQ stack frame layout:
@ -62,8 +62,6 @@ IRQ stack frame layout:
The context switch code adopts this standard so that it is easier to follow: The context switch code adopts this standard so that it is easier to follow:
- r1 contains _kernel ASAP and is not overwritten over the lifespan of
the functions.
- r2 contains _kernel.current ASAP, and the incoming thread when we - r2 contains _kernel.current ASAP, and the incoming thread when we
transition from outgoing thread to incoming thread transition from outgoing thread to incoming thread
@ -105,41 +103,43 @@ o RIRQ
saved GPRs. That stack frame layout is pre-determined. If returning saved GPRs. That stack frame layout is pre-determined. If returning
to a thread, the stack is popped and no registers have to be saved by to a thread, the stack is popped and no registers have to be saved by
the kernel. If a context switch is required, the callee-saved GPRs the kernel. If a context switch is required, the callee-saved GPRs
are then saved in the thread control structure (TCS). are then saved in the thread's stack.
o FIRQ o FIRQ
First, a FIRQ can be interrupting a lower-priority RIRQ: if this is the case, First, a FIRQ can be interrupting a lower-priority RIRQ: if this is
the FIRQ does not take a scheduling decision and leaves it the RIRQ to the case, the FIRQ does not take a scheduling decision and leaves it
handle. This limits the amount of code that has to run at interrupt-level. the RIRQ to handle. This limits the amount of code that has to run at
interrupt-level.
CONFIG_RGF_NUM_BANKS==1 case: CONFIG_RGF_NUM_BANKS==1 case:
Registers are saved on the stack frame just as they are for RIRQ. Registers are saved on the stack frame just as they are for RIRQ.
Context switch can happen just as it does in the RIRQ case, however, Context switch can happen just as it does in the RIRQ case, however,
if the FIRQ interrupted a RIRQ, the FIRQ will return from interrupt and if the FIRQ interrupted a RIRQ, the FIRQ will return from interrupt
let the RIRQ do the context switch. At entry, one register is needed in order and let the RIRQ do the context switch. At entry, one register is
to have code to save other registers. r0 is saved first in a global called needed in order to have code to save other registers. r0 is saved
saved_r0. first in the stack and restored later
CONFIG_RGF_NUM_BANKS!=1 case: CONFIG_RGF_NUM_BANKS!=1 case:
During early initialization, the sp in the 2nd register bank is made to During early initialization, the sp in the 2nd register bank is made to
refer to _firq_stack. This allows for the FIRQ handler to use its own stack. refer to _firq_stack. This allows for the FIRQ handler to use its own
GPRs are banked, loop registers are saved in unused callee saved regs upon stack. GPRs are banked, loop registers are saved in unused callee saved
interrupt entry. If returning to a thread, loop registers are restored and the regs upon interrupt entry. If returning to a thread, loop registers are
CPU switches back to bank 0 for the GPRs. If a context switch is restored and the CPU switches back to bank 0 for the GPRs. If a context
needed, at this point only are all the registers saved. First, a switch is needed, at this point only are all the registers saved.
stack frame with the same layout as the automatic RIRQ one is created First, a stack frame with the same layout as the automatic RIRQ one is
and then the callee-saved GPRs are saved in the TCS. status32_p0 and created and then the callee-saved GPRs are saved in the stack.
ilink are saved in this case, not status32 and pc. status32_p0 and ilink are saved in this case, not status32 and pc.
To create the stack frame, the FIRQ handling code must first go back to using To create the stack frame, the FIRQ handling code must first go back to
bank0 of registers, since that is where the registers containing the exiting using bank0 of registers, since that is where the registers containing
thread are saved. Care must be taken not to touch any register before saving the exiting thread are saved. Care must be taken not to touch any
them: the only one usable at that point is the stack pointer. register before saving them: the only one usable at that point is the
stack pointer.
o coop o coop
When a coop context switch is done, the callee-saved registers are When a coop context switch is done, the callee-saved registers are
saved in the TCS. The other GPRs do not need to be saved, since the saved in the stack. The other GPRs do not need to be saved, since the
compiler has already placed them on the stack. compiler has already placed them on the stack.
For restoring the contexts, there are six cases. In all cases, the For restoring the contexts, there are six cases. In all cases, the
@ -155,16 +155,15 @@ From coop:
o to any irq o to any irq
The incoming interrupted thread has an IRQ stack frame containing the The incoming interrupted thread has an IRQ stack frame containing the
caller-saved registers that has to be popped. status32 has to be restored, caller-saved registers that has to be popped. status32 has to be
then we jump to the interrupted instruction. restored, then we jump to the interrupted instruction.
From FIRQ: From FIRQ:
When CONFIG_RGF_NUM_BANKS==1, context switch is done as it is for RIRQ. When CONFIG_RGF_NUM_BANKS==1, context switch is done as it is for RIRQ.
When CONFIG_RGF_NUM_BANKS!=1, the processor is put back to using bank0, When CONFIG_RGF_NUM_BANKS!=1, the processor is put back to using bank0,
not bank1 anymore, because it had to save the outgoing context from bank0, not bank1 anymore, because it had to save the outgoing context from
and now has to load the incoming one bank0, and now has to load the incoming one into bank0.
into bank0.
o to coop o to coop
@ -173,27 +172,27 @@ From FIRQ:
o to any irq o to any irq
The IRQ has saved the caller-saved registers in a stack frame, which must be The IRQ has saved the caller-saved registers in a stack frame, which
popped, and status32 and pc loaded in status32_p0 and ilink. must be popped, and status32 and pc loaded in status32_p0 and ilink.
From RIRQ: From RIRQ:
o to coop o to coop
The interrupt return mechanism in the processor expects a stack frame, but The interrupt return mechanism in the processor expects a stack frame,
the outgoing context did not create one. A fake one is created here, with but the outgoing context did not create one. A fake one is created
only the relevant values filled in: pc, status32. here, with only the relevant values filled in: pc, status32.
There is a discrepancy between the ABI from the ARCv2 docs, including the There is a discrepancy between the ABI from the ARCv2 docs,
way the processor pushes GPRs in pairs in the IRQ stack frame, and the ABI including the way the processor pushes GPRs in pairs in the IRQ stack
GCC uses. r13 should be a callee-saved register, but GCC treats it as frame, and the ABI GCC uses. r13 should be a callee-saved register,
caller-saved. This means that the processor pushes it in the stack frame but GCC treats it as caller-saved. This means that the processor pushes
along with r12, but the compiler does not save it before entering a it in the stack frame along with r12, but the compiler does not save it
function. So, it is saved as part of the callee-saved registers, and before entering a function. So, it is saved as part of the callee-saved
restored there, but the processor restores it _a second time_ when popping registers, and restored there, but the processor restores it _a second
the IRQ stack frame. Thus, the correct value must also be put in the fake time_ when popping the IRQ stack frame. Thus, the correct value must
stack frame when returning to a thread that context switched out also be put in the fake stack frame when returning to a thread that
cooperatively. context switched out cooperatively.
o to any irq o to any irq
@ -251,8 +250,6 @@ GTEXT(sys_trace_isr_enter)
#if defined(CONFIG_SYS_POWER_MANAGEMENT) #if defined(CONFIG_SYS_POWER_MANAGEMENT)
.macro exit_tickless_idle .macro exit_tickless_idle
clri r0 /* do not interrupt exiting tickless idle operations */ clri r0 /* do not interrupt exiting tickless idle operations */
push_s r1
push_s r0
mov_s r1, _kernel mov_s r1, _kernel
ld_s r0, [r1, _kernel_offset_to_idle] /* requested idle duration */ ld_s r0, [r1, _kernel_offset_to_idle] /* requested idle duration */
breq r0, 0, _skip_sys_power_save_idle_exit breq r0, 0, _skip_sys_power_save_idle_exit
@ -263,8 +260,6 @@ GTEXT(sys_trace_isr_enter)
pop_s blink pop_s blink
_skip_sys_power_save_idle_exit: _skip_sys_power_save_idle_exit:
pop_s r0
pop_s r1
seti r0 seti r0
.endm .endm
#else #else

View file

@ -25,17 +25,6 @@ GTEXT(_rirq_enter)
GTEXT(_rirq_exit) GTEXT(_rirq_exit)
GTEXT(_rirq_newthread_switch) GTEXT(_rirq_newthread_switch)
#if 0 /* TODO: when FIRQ is not present, all would be regular */
#define NUM_REGULAR_IRQ_PRIO_LEVELS CONFIG_NUM_IRQ_PRIO_LEVELS
#else
#define NUM_REGULAR_IRQ_PRIO_LEVELS (CONFIG_NUM_IRQ_PRIO_LEVELS-1)
#endif
/* note: the above define assumes that prio 0 IRQ is for FIRQ, and
* that all others are regular interrupts.
* TODO: Revist this if FIRQ becomes configurable.
*/
/* /*
=========================================================== ===========================================================
@ -214,23 +203,16 @@ will be corrupted.
SECTION_FUNC(TEXT, _rirq_enter) SECTION_FUNC(TEXT, _rirq_enter)
/* the ISR will be handled in separate interrupt stack,
#ifdef CONFIG_ARC_STACK_CHECKING * so stack checking must be diabled, or exception will
#ifdef CONFIG_ARC_SECURE_FIRMWARE * be caused
lr r2, [_ARC_V2_SEC_STAT] */
bclr r2, r2, _ARC_V2_SEC_STAT_SSC_BIT _disable_stack_checking r2
sflag r2
#else
/* disable stack checking */
lr r2, [_ARC_V2_STATUS32]
bclr r2, r2, _ARC_V2_STATUS32_SC_BIT
kflag r2
#endif
#endif
clri clri
/* check whether irq stack is used */ /* check whether irq stack is used, if
* not switch to isr stack
*/
_check_and_inc_int_nest_counter r0, r1 _check_and_inc_int_nest_counter r0, r1
bne.d rirq_nest bne.d rirq_nest
@ -302,6 +284,9 @@ _rirq_newthread_switch:
.balign 4 .balign 4
_rirq_switch_from_coop: _rirq_switch_from_coop:
/* for a cooperative switch, it's not in irq, so
* need to set some regs for irq return
*/
_set_misc_regs_irq_switch_from_coop _set_misc_regs_irq_switch_from_coop
/* /*

View file

@ -96,18 +96,10 @@ SECTION_FUNC(TEXT, arch_switch)
_store_old_thread_callee_regs _store_old_thread_callee_regs
#ifdef CONFIG_ARC_STACK_CHECKING
/* disable stack checking here, as sp will be changed to target /* disable stack checking here, as sp will be changed to target
* thread'sp * thread'sp
*/ */
#if defined(CONFIG_ARC_HAS_SECURE) && defined(CONFIG_ARC_SECURE_FIRMWARE) _disable_stack_checking r3
bclr r3, r3, _ARC_V2_SEC_STAT_SSC_BIT
sflag r3
#else
bclr r3, r3, _ARC_V2_STATUS32_SC_BIT
kflag r3
#endif
#endif
mov_s r2, r0 mov_s r2, r0
@ -134,9 +126,12 @@ _switch_return_from_coop:
kflag r3 /* write status32 */ kflag r3 /* write status32 */
#ifdef CONFIG_EXECUTION_BENCHMARKING #ifdef CONFIG_EXECUTION_BENCHMARKING
b _capture_value_for_benchmarking push_s blink
#endif
return_loc: bl read_timer_end_of_swap
pop_s blink
#endif /* CONFIG_EXECUTION_BENCHMARKING */
j_s [blink] j_s [blink]
@ -167,14 +162,3 @@ _switch_return_from_firq:
sr r3, [_ARC_V2_AUX_IRQ_ACT] sr r3, [_ARC_V2_AUX_IRQ_ACT]
#endif #endif
rtie rtie
#ifdef CONFIG_EXECUTION_BENCHMARKING
.balign 4
_capture_value_for_benchmarking:
push_s blink
bl read_timer_end_of_swap
pop_s blink
b return_loc
#endif /* CONFIG_EXECUTION_BENCHMARKING */

View file

@ -93,22 +93,13 @@ SECTION_FUNC(TEXT, z_arc_userspace_enter)
/* /*
* In ARCv2, the U bit can only be set through exception return * In ARCv2, the U bit can only be set through exception return
*/ */
#ifdef CONFIG_ARC_STACK_CHECKING
/* disable stack checking as the stack should be initialized */ /* disable stack checking as the stack should be initialized */
#ifdef CONFIG_ARC_SECURE_FIRMWARE _disable_stack_checking blink
lr blink, [_ARC_V2_SEC_STAT]
bclr blink, blink, _ARC_V2_SEC_STAT_SSC_BIT
sflag blink
#else
lr blink, [_ARC_V2_STATUS32]
bclr blink, blink, _ARC_V2_STATUS32_SC_BIT
kflag blink
#endif
#endif
/* the end of user stack in r5 */ /* the end of user stack in r5 */
add r5, r4, r5 add r5, r4, r5
/* start of privilege stack */ /* start of privilege stack */
add blink, r5, CONFIG_PRIVILEGED_STACK_SIZE+STACK_GUARD_SIZE add blink, r5, CONFIG_PRIVILEGED_STACK_SIZE + STACK_GUARD_SIZE
mov_s sp, r5 mov_s sp, r5
push_s r0 push_s r0
@ -118,6 +109,9 @@ SECTION_FUNC(TEXT, z_arc_userspace_enter)
mov r5, sp /* skip r0, r1, r2, r3 */ mov r5, sp /* skip r0, r1, r2, r3 */
/* to avoid the leakage of kernel info, the thread stack needs to be
* re-initialized
*/
#ifdef CONFIG_INIT_STACKS #ifdef CONFIG_INIT_STACKS
mov_s r0, 0xaaaaaaaa mov_s r0, 0xaaaaaaaa
#else #else
@ -128,23 +122,22 @@ _clear_user_stack:
cmp r4, r5 cmp r4, r5
jlt _clear_user_stack jlt _clear_user_stack
/* reload the stack checking regs as the original kernel stack
* becomess user stack
*/
#ifdef CONFIG_ARC_STACK_CHECKING #ifdef CONFIG_ARC_STACK_CHECKING
mov_s r1, _kernel mov_s r1, _kernel
ld_s r2, [r1, _kernel_offset_to_current] ld_s r2, [r1, _kernel_offset_to_current]
_load_stack_check_regs _load_stack_check_regs
#ifdef CONFIG_ARC_SECURE_FIRMWARE _enable_stack_checking r0
lr r0, [_ARC_V2_SEC_STAT]
bset r0, r0, _ARC_V2_SEC_STAT_SSC_BIT
sflag r0
#else
lr r0, [_ARC_V2_STATUS32]
bset r0, r0, _ARC_V2_STATUS32_SC_BIT
kflag r0
#endif
#endif #endif
/* the following codes are used to switch from kernel mode
* to user mode by fake exception, because U bit can only be set
* by exception
*/
_arc_go_to_user_space: _arc_go_to_user_space:
lr r0, [_ARC_V2_STATUS32] lr r0, [_ARC_V2_STATUS32]
bset r0, r0, _ARC_V2_STATUS32_U_BIT bset r0, r0, _ARC_V2_STATUS32_U_BIT
@ -185,9 +178,8 @@ _arc_go_to_user_space:
mov_s blink, 0 mov_s blink, 0
#ifdef CONFIG_EXECUTION_BENCHMARKING #ifdef CONFIG_EXECUTION_BENCHMARKING
b _capture_value_for_benchmarking_userspace bl read_timer_end_of_userspace_enter
return_loc_userspace_enter: #endif
#endif /* CONFIG_EXECUTION_BENCHMARKING */
rtie rtie
@ -298,20 +290,3 @@ inc_len:
/* increment length measurement, loop again */ /* increment length measurement, loop again */
add_s r0, r0, 1 add_s r0, r0, 1
b_s strlen_loop b_s strlen_loop
#ifdef CONFIG_EXECUTION_BENCHMARKING
.balign 4
_capture_value_for_benchmarking_userspace:
mov r1, _kernel
ld_s r2, [r1, _kernel_offset_to_current]
_save_callee_saved_regs
push_s blink
bl read_timer_end_of_userspace_enter
pop_s blink
mov r1, _kernel
ld_s r2, [r1, _kernel_offset_to_current]
_load_callee_saved_regs
b return_loc_userspace_enter
#endif

View file

@ -16,7 +16,7 @@
#ifdef _ASMLANGUAGE #ifdef _ASMLANGUAGE
/* entering this macro, current is in r2 */ /* save callee regs of current thread in r2 */
.macro _save_callee_saved_regs .macro _save_callee_saved_regs
sub_s sp, sp, ___callee_saved_stack_t_SIZEOF sub_s sp, sp, ___callee_saved_stack_t_SIZEOF
@ -89,7 +89,7 @@
st sp, [r2, _thread_offset_to_sp] st sp, [r2, _thread_offset_to_sp]
.endm .endm
/* entering this macro, current is in r2 */ /* load the callee regs of thread (in r2)*/
.macro _load_callee_saved_regs .macro _load_callee_saved_regs
/* restore stack pointer from struct k_thread */ /* restore stack pointer from struct k_thread */
ld sp, [r2, _thread_offset_to_sp] ld sp, [r2, _thread_offset_to_sp]
@ -162,6 +162,7 @@
.endm .endm
/* discard callee regs */
.macro _discard_callee_saved_regs .macro _discard_callee_saved_regs
add_s sp, sp, ___callee_saved_stack_t_SIZEOF add_s sp, sp, ___callee_saved_stack_t_SIZEOF
.endm .endm
@ -265,7 +266,7 @@
.endm .endm
/* /*
* To use this macor, r2 should have the value of thread struct pointer to * To use this macro, r2 should have the value of thread struct pointer to
* _kernel.current. r3 is a scratch reg. * _kernel.current. r3 is a scratch reg.
*/ */
.macro _load_stack_check_regs .macro _load_stack_check_regs
@ -297,6 +298,7 @@
/* check and increase the interrupt nest counter /* check and increase the interrupt nest counter
* after increase, check whether nest counter == 1 * after increase, check whether nest counter == 1
* the result will be EQ bit of status32 * the result will be EQ bit of status32
* two temp regs are needed
*/ */
.macro _check_and_inc_int_nest_counter reg1 reg2 .macro _check_and_inc_int_nest_counter reg1 reg2
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
@ -316,7 +318,10 @@
cmp \reg2, 1 cmp \reg2, 1
.endm .endm
/* decrease interrupt nest counter */ /* decrease interrupt stack nest counter
* the counter > 0, interrupt stack is used, or
* not used
*/
.macro _dec_int_nest_counter reg1 reg2 .macro _dec_int_nest_counter reg1 reg2
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
_get_cpu_id \reg1 _get_cpu_id \reg1
@ -336,6 +341,7 @@
/* If multi bits in IRQ_ACT are set, i.e. last bit != fist bit, it's /* If multi bits in IRQ_ACT are set, i.e. last bit != fist bit, it's
* in nest interrupt. The result will be EQ bit of status32 * in nest interrupt. The result will be EQ bit of status32
* need two temp reg to do this
*/ */
.macro _check_nest_int_by_irq_act reg1, reg2 .macro _check_nest_int_by_irq_act reg1, reg2
lr \reg1, [_ARC_V2_AUX_IRQ_ACT] lr \reg1, [_ARC_V2_AUX_IRQ_ACT]
@ -349,11 +355,18 @@
cmp \reg1, \reg2 cmp \reg1, \reg2
.endm .endm
/* macro to get id of current cpu
* the result will be in reg (a reg)
*/
.macro _get_cpu_id reg .macro _get_cpu_id reg
lr \reg, [_ARC_V2_IDENTITY] lr \reg, [_ARC_V2_IDENTITY]
xbfu \reg, \reg, 0xe8 xbfu \reg, \reg, 0xe8
.endm .endm
/* macro to get the interrupt stack of current cpu
* the result will be in irq_sp (a reg)
*/
.macro _get_curr_cpu_irq_stack irq_sp .macro _get_curr_cpu_irq_stack irq_sp
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
_get_cpu_id \irq_sp _get_cpu_id \irq_sp
@ -478,6 +491,41 @@
pop_s r2 pop_s r2
.endm .endm
/* macro to disable stack checking in assembly, need a GPR
* to do this
*/
.macro _disable_stack_checking reg
#ifdef CONFIG_ARC_STACK_CHECKING
#ifdef CONFIG_ARC_SECURE_FIRMWARE
lr \reg, [_ARC_V2_SEC_STAT]
bclr \reg, \reg, _ARC_V2_SEC_STAT_SSC_BIT
sflag \reg
#else
lr \reg, [_ARC_V2_STATUS32]
bclr \reg, \reg, _ARC_V2_STATUS32_SC_BIT
kflag \reg
#endif
#endif
.endm
/* macro to enable stack checking in assembly, need a GPR
* to do this
*/
.macro _enable_stack_checking reg
#ifdef CONFIG_ARC_STACK_CHECKING
#ifdef CONFIG_ARC_SECURE_FIRMWARE
lr \reg, [_ARC_V2_SEC_STAT]
bset \reg, \reg, _ARC_V2_SEC_STAT_SSC_BIT
sflag \reg
#else
lr \reg, [_ARC_V2_STATUS32]
bset \reg, \reg, _ARC_V2_STATUS32_SC_BIT
kflag \reg
#endif
#endif
.endm
#endif /* _ASMLANGUAGE */ #endif /* _ASMLANGUAGE */
#endif /* ZEPHYR_ARCH_ARC_INCLUDE_SWAP_MACROS_H_ */ #endif /* ZEPHYR_ARCH_ARC_INCLUDE_SWAP_MACROS_H_ */