From 84cdfa271d85c5427b80457d1b104f01b1fcfd07 Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Sat, 29 Feb 2020 22:58:22 +0800 Subject: [PATCH] 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 --- arch/arc/core/fault_s.S | 56 +++++------ arch/arc/core/isr_wrapper.S | 173 ++++++++++++++++----------------- arch/arc/core/regular_irq.S | 37 +++---- arch/arc/core/switch.S | 30 ++---- arch/arc/core/userspace.S | 57 +++-------- arch/arc/include/swap_macros.h | 56 ++++++++++- 6 files changed, 196 insertions(+), 213 deletions(-) diff --git a/arch/arc/core/fault_s.S b/arch/arc/core/fault_s.S index 6b60498480f..f76219bf516 100644 --- a/arch/arc/core/fault_s.S +++ b/arch/arc/core/fault_s.S @@ -19,7 +19,6 @@ #include GTEXT(_Fault) -GTEXT(z_do_kernel_oops) GTEXT(__reset) GTEXT(__memory_error) GTEXT(__instruction_error) @@ -38,6 +37,17 @@ GTEXT(__ev_maligned) GTEXT(z_irq_do_offload); #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 @@ -89,15 +99,7 @@ _exc_entry: */ _create_irq_stack_frame -#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_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 */ + _save_exc_regs_into_stack /* sp is parameter of _Fault */ mov_s r0, sp @@ -174,10 +176,13 @@ _exc_return: mov r2, ilink #endif - /* Assumption: r2 has next thread */ + /* Assumption: r2 has next thread */ b _rirq_newthread_switch _exc_return_from_exc: + /* exception handler may change return address. + * reload it + */ ld_s r0, [sp, ___isf_t_pc_OFFSET] sr r0, [_ARC_V2_ERET] @@ -185,7 +190,7 @@ _exc_return_from_exc: mov_s sp, ilink rtie - +/* separated entry for trap which may be used by irq_offload, USERPSACE */ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_trap) /* get the id of trap_s */ lr ilink, [_ARC_V2_ECR] @@ -208,15 +213,12 @@ valid_syscall_id: */ _create_irq_stack_frame -#ifdef CONFIG_ARC_SECURE_FIRMWARE - /* 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] /* eret into pc */ - lr r0,[_ARC_V2_ERSTATUS] - st_s r0, [sp, ___isf_t_status32_OFFSET] + _save_exc_regs_into_stack + + /* exc return and do sys call in kernel mode, + * so need to clear U bit, r0 is already loaded + * with ERSTATUS in _save_exc_regs_into_stack + */ bclr r0, r0, _ARC_V2_STATUS32_U_BIT sr r0, [_ARC_V2_ERSTATUS] @@ -239,15 +241,7 @@ _do_non_syscall_trap: /* save caller saved registers */ _create_irq_stack_frame -#ifdef CONFIG_ARC_HAS_SECURE - 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 */ - + _save_exc_regs_into_stack /* check whether irq stack is used */ _check_and_inc_int_nest_counter r0, r1 @@ -266,6 +260,8 @@ exc_nest_handle: _dec_int_nest_counter r0, r1 _pop_irq_stack_frame + + /* ERSTATUS, ERET are not changed, so ok to rtie */ rtie #endif /* CONFIG_IRQ_OFFLOAD */ b _exc_entry diff --git a/arch/arc/core/isr_wrapper.S b/arch/arc/core/isr_wrapper.S index 50efbf2035b..35a1b584f6c 100644 --- a/arch/arc/core/isr_wrapper.S +++ b/arch/arc/core/isr_wrapper.S @@ -35,37 +35,35 @@ _rirq_enter/_firq_enter: they are jump points. The flow is the following: ISR -> _isr_wrapper -- + -> _rirq_enter -> _isr_demux -> ISR -> _rirq_exit - | - + -> _firq_enter -> _isr_demux -> ISR -> _firq_exit + | + + -> _firq_enter -> _isr_demux -> ISR -> _firq_exit Context switch explanation: 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: - high address + high address - status32 - pc - lp_count - lp_start - lp_end - blink - r13 - ... - sp -> r0 + status32 + pc + lp_count + lp_start + lp_end + blink + r13 + ... + sp -> r0 - low address + low address 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 - transition from outgoing thread to incoming thread + - r2 contains _kernel.current ASAP, and the incoming thread when we + transition from outgoing thread to incoming thread Not loading _kernel into r0 allows loading _kernel without stomping on the parameter in r0 in arch_switch(). @@ -100,47 +98,49 @@ done upfront, and the rest is done when needed: o RIRQ - All needed registers to run C code in the ISR are saved automatically - on the outgoing thread's stack: loop, status32, pc, and the caller- - 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 - the kernel. If a context switch is required, the callee-saved GPRs - are then saved in the thread control structure (TCS). + All needed registers to run C code in the ISR are saved automatically + on the outgoing thread's stack: loop, status32, pc, and the caller- + 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 + the kernel. If a context switch is required, the callee-saved GPRs + are then saved in the thread's stack. o FIRQ - First, a FIRQ can be interrupting a lower-priority RIRQ: if this is the case, - the FIRQ does not take a scheduling decision and leaves it the RIRQ to - handle. This limits the amount of code that has to run at interrupt-level. + First, a FIRQ can be interrupting a lower-priority RIRQ: if this is + the case, the FIRQ does not take a scheduling decision and leaves it + the RIRQ to handle. This limits the amount of code that has to run at + interrupt-level. - CONFIG_RGF_NUM_BANKS==1 case: - 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, - if the FIRQ interrupted a RIRQ, the FIRQ will return from interrupt and - let the RIRQ do the context switch. At entry, one register is needed in order - to have code to save other registers. r0 is saved first in a global called - saved_r0. + CONFIG_RGF_NUM_BANKS==1 case: + 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, + if the FIRQ interrupted a RIRQ, the FIRQ will return from interrupt + and let the RIRQ do the context switch. At entry, one register is + needed in order to have code to save other registers. r0 is saved + first in the stack and restored later - CONFIG_RGF_NUM_BANKS!=1 case: - 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. - GPRs are banked, loop registers are saved in unused callee saved regs upon - interrupt entry. If returning to a thread, loop registers are restored and the - CPU switches back to bank 0 for the GPRs. If a context switch is - needed, at this point only are all the registers saved. First, a - stack frame with the same layout as the automatic RIRQ one is created - and then the callee-saved GPRs are saved in the TCS. 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 - bank0 of registers, since that is where the registers containing the exiting - thread are saved. Care must be taken not to touch any register before saving - them: the only one usable at that point is the stack pointer. + CONFIG_RGF_NUM_BANKS!=1 case: + 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. GPRs are banked, loop registers are saved in unused callee saved + regs upon interrupt entry. If returning to a thread, loop registers are + restored and the CPU switches back to bank 0 for the GPRs. If a context + switch is needed, at this point only are all the registers saved. + First, a stack frame with the same layout as the automatic RIRQ one is + created and then the callee-saved GPRs are saved in the stack. + 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 bank0 of registers, since that is where the registers containing + the exiting thread are saved. Care must be taken not to touch any + register before saving them: the only one usable at that point is the + stack pointer. o coop - 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 - compiler has already placed them on the stack. + When a coop context switch is done, the callee-saved registers are + saved in the stack. The other GPRs do not need to be saved, since the + compiler has already placed them on the stack. For restoring the contexts, there are six cases. In all cases, the callee-saved registers of the incoming thread have to be restored. Then, there @@ -148,57 +148,56 @@ are specifics for each case: From coop: - o to coop + o to coop - Do a normal function call return. + Do a normal function call return. - o to any irq + o to any irq - The incoming interrupted thread has an IRQ stack frame containing the - caller-saved registers that has to be popped. status32 has to be restored, - then we jump to the interrupted instruction. + The incoming interrupted thread has an IRQ stack frame containing the + caller-saved registers that has to be popped. status32 has to be + restored, then we jump to the interrupted instruction. From FIRQ: - 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, - not bank1 anymore, because it had to save the outgoing context from bank0, - and now has to load the incoming one - into bank0. + 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, + not bank1 anymore, because it had to save the outgoing context from + bank0, and now has to load the incoming one into bank0. - o to coop + o to coop - The address of the returning instruction from arch_switch() is loaded - in ilink and the saved status32 in status32_p0. + The address of the returning instruction from arch_switch() is loaded + in ilink and the saved status32 in status32_p0. - o to any irq + o to any irq - The IRQ has saved the caller-saved registers in a stack frame, which must be - popped, and status32 and pc loaded in status32_p0 and ilink. + The IRQ has saved the caller-saved registers in a stack frame, which + must be popped, and status32 and pc loaded in status32_p0 and ilink. From RIRQ: - o to coop + o to coop - The interrupt return mechanism in the processor expects a stack frame, but - the outgoing context did not create one. A fake one is created here, with - only the relevant values filled in: pc, status32. + The interrupt return mechanism in the processor expects a stack frame, + but the outgoing context did not create one. A fake one is created + here, with only the relevant values filled in: pc, status32. - There is a discrepancy between the ABI from the ARCv2 docs, including the - way the processor pushes GPRs in pairs in the IRQ stack frame, and the ABI - GCC uses. r13 should be a callee-saved register, but GCC treats it as - caller-saved. This means that the processor pushes it in the stack frame - along with r12, but the compiler does not save it before entering a - function. So, it is saved as part of the callee-saved registers, and - restored there, but the processor restores it _a second time_ when popping - the IRQ stack frame. Thus, the correct value must also be put in the fake - stack frame when returning to a thread that context switched out - cooperatively. + There is a discrepancy between the ABI from the ARCv2 docs, + including the way the processor pushes GPRs in pairs in the IRQ stack + frame, and the ABI GCC uses. r13 should be a callee-saved register, + but GCC treats it as caller-saved. This means that the processor pushes + it in the stack frame along with r12, but the compiler does not save it + before entering a function. So, it is saved as part of the callee-saved + registers, and restored there, but the processor restores it _a second + time_ when popping the IRQ stack frame. Thus, the correct value must + also be put in the fake stack frame when returning to a thread that + context switched out cooperatively. - o to any irq + o to any irq - Both types of IRQs already have an IRQ stack frame: simply return from - interrupt. + Both types of IRQs already have an IRQ stack frame: simply return from + interrupt. */ SECTION_FUNC(TEXT, _isr_wrapper) @@ -251,8 +250,6 @@ GTEXT(sys_trace_isr_enter) #if defined(CONFIG_SYS_POWER_MANAGEMENT) .macro exit_tickless_idle clri r0 /* do not interrupt exiting tickless idle operations */ - push_s r1 - push_s r0 mov_s r1, _kernel ld_s r0, [r1, _kernel_offset_to_idle] /* requested idle duration */ breq r0, 0, _skip_sys_power_save_idle_exit @@ -263,8 +260,6 @@ GTEXT(sys_trace_isr_enter) pop_s blink _skip_sys_power_save_idle_exit: - pop_s r0 - pop_s r1 seti r0 .endm #else diff --git a/arch/arc/core/regular_irq.S b/arch/arc/core/regular_irq.S index 724edbbc600..709282801c9 100644 --- a/arch/arc/core/regular_irq.S +++ b/arch/arc/core/regular_irq.S @@ -25,17 +25,6 @@ GTEXT(_rirq_enter) GTEXT(_rirq_exit) 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) - -#ifdef CONFIG_ARC_STACK_CHECKING -#ifdef CONFIG_ARC_SECURE_FIRMWARE - lr r2, [_ARC_V2_SEC_STAT] - bclr r2, r2, _ARC_V2_SEC_STAT_SSC_BIT - sflag r2 - -#else - /* disable stack checking */ - lr r2, [_ARC_V2_STATUS32] - bclr r2, r2, _ARC_V2_STATUS32_SC_BIT - kflag r2 -#endif -#endif +/* the ISR will be handled in separate interrupt stack, + * so stack checking must be diabled, or exception will + * be caused + */ + _disable_stack_checking r2 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 bne.d rirq_nest @@ -302,6 +284,9 @@ _rirq_newthread_switch: .balign 4 _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 /* diff --git a/arch/arc/core/switch.S b/arch/arc/core/switch.S index f6979164d42..07fede25159 100644 --- a/arch/arc/core/switch.S +++ b/arch/arc/core/switch.S @@ -96,18 +96,10 @@ SECTION_FUNC(TEXT, arch_switch) _store_old_thread_callee_regs -#ifdef CONFIG_ARC_STACK_CHECKING /* disable stack checking here, as sp will be changed to target * thread'sp */ -#if defined(CONFIG_ARC_HAS_SECURE) && defined(CONFIG_ARC_SECURE_FIRMWARE) - bclr r3, r3, _ARC_V2_SEC_STAT_SSC_BIT - sflag r3 -#else - bclr r3, r3, _ARC_V2_STATUS32_SC_BIT - kflag r3 -#endif -#endif + _disable_stack_checking r3 mov_s r2, r0 @@ -134,9 +126,12 @@ _switch_return_from_coop: kflag r3 /* write status32 */ #ifdef CONFIG_EXECUTION_BENCHMARKING - b _capture_value_for_benchmarking -#endif -return_loc: + push_s blink + + bl read_timer_end_of_swap + + pop_s blink +#endif /* CONFIG_EXECUTION_BENCHMARKING */ j_s [blink] @@ -167,14 +162,3 @@ _switch_return_from_firq: sr r3, [_ARC_V2_AUX_IRQ_ACT] #endif 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 */ diff --git a/arch/arc/core/userspace.S b/arch/arc/core/userspace.S index 20169536708..03e4ffaf694 100644 --- a/arch/arc/core/userspace.S +++ b/arch/arc/core/userspace.S @@ -93,22 +93,13 @@ SECTION_FUNC(TEXT, z_arc_userspace_enter) /* * 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 */ -#ifdef CONFIG_ARC_SECURE_FIRMWARE - 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 + _disable_stack_checking blink + /* the end of user stack in r5 */ add r5, r4, r5 /* 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 push_s r0 @@ -118,6 +109,9 @@ SECTION_FUNC(TEXT, z_arc_userspace_enter) 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 mov_s r0, 0xaaaaaaaa #else @@ -128,23 +122,22 @@ _clear_user_stack: cmp r4, r5 jlt _clear_user_stack +/* reload the stack checking regs as the original kernel stack + * becomess user stack + */ #ifdef CONFIG_ARC_STACK_CHECKING mov_s r1, _kernel ld_s r2, [r1, _kernel_offset_to_current] _load_stack_check_regs -#ifdef CONFIG_ARC_SECURE_FIRMWARE - 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 + _enable_stack_checking r0 #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: lr r0, [_ARC_V2_STATUS32] bset r0, r0, _ARC_V2_STATUS32_U_BIT @@ -185,9 +178,8 @@ _arc_go_to_user_space: mov_s blink, 0 #ifdef CONFIG_EXECUTION_BENCHMARKING - b _capture_value_for_benchmarking_userspace -return_loc_userspace_enter: -#endif /* CONFIG_EXECUTION_BENCHMARKING */ + bl read_timer_end_of_userspace_enter +#endif rtie @@ -298,20 +290,3 @@ inc_len: /* increment length measurement, loop again */ add_s r0, r0, 1 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 diff --git a/arch/arc/include/swap_macros.h b/arch/arc/include/swap_macros.h index e990bc26f36..ca83f3303f0 100644 --- a/arch/arc/include/swap_macros.h +++ b/arch/arc/include/swap_macros.h @@ -16,7 +16,7 @@ #ifdef _ASMLANGUAGE -/* entering this macro, current is in r2 */ +/* save callee regs of current thread in r2 */ .macro _save_callee_saved_regs sub_s sp, sp, ___callee_saved_stack_t_SIZEOF @@ -89,7 +89,7 @@ st sp, [r2, _thread_offset_to_sp] .endm -/* entering this macro, current is in r2 */ +/* load the callee regs of thread (in r2)*/ .macro _load_callee_saved_regs /* restore stack pointer from struct k_thread */ ld sp, [r2, _thread_offset_to_sp] @@ -162,6 +162,7 @@ .endm +/* discard callee regs */ .macro _discard_callee_saved_regs add_s sp, sp, ___callee_saved_stack_t_SIZEOF .endm @@ -265,7 +266,7 @@ .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. */ .macro _load_stack_check_regs @@ -297,6 +298,7 @@ /* check and increase the interrupt nest counter * after increase, check whether nest counter == 1 * the result will be EQ bit of status32 + * two temp regs are needed */ .macro _check_and_inc_int_nest_counter reg1 reg2 #ifdef CONFIG_SMP @@ -316,7 +318,10 @@ cmp \reg2, 1 .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 #ifdef CONFIG_SMP _get_cpu_id \reg1 @@ -336,6 +341,7 @@ /* 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 + * need two temp reg to do this */ .macro _check_nest_int_by_irq_act reg1, reg2 lr \reg1, [_ARC_V2_AUX_IRQ_ACT] @@ -349,11 +355,18 @@ cmp \reg1, \reg2 .endm + +/* macro to get id of current cpu + * the result will be in reg (a reg) + */ .macro _get_cpu_id reg lr \reg, [_ARC_V2_IDENTITY] xbfu \reg, \reg, 0xe8 .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 #ifdef CONFIG_SMP _get_cpu_id \irq_sp @@ -478,6 +491,41 @@ pop_s r2 .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 /* ZEPHYR_ARCH_ARC_INCLUDE_SWAP_MACROS_H_ */