From 733c11b11b423eecfd2e1abe3ee3d1ca8ec9fcbb Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Wed, 3 Jul 2019 23:43:31 +0800 Subject: [PATCH] arch: arc: use IRQ_ACT to check nest interrupt * use IRQ_ACT to check nest interrupt * implement an asm macro for nest interrupt check * no need to use exc_nest_count, remove it Signed-off-by: Wayne Ren --- arch/arc/core/fast_irq.S | 27 ++++++--------------------- arch/arc/core/fault_s.S | 21 ++++++++------------- arch/arc/core/isr_wrapper.S | 6 ------ arch/arc/core/regular_irq.S | 33 ++++++--------------------------- arch/arc/include/swap_macros.h | 11 +++++++++++ 5 files changed, 31 insertions(+), 67 deletions(-) diff --git a/arch/arc/core/fast_irq.S b/arch/arc/core/fast_irq.S index df19ab4e9dd..0011bbf6754 100644 --- a/arch/arc/core/fast_irq.S +++ b/arch/arc/core/fast_irq.S @@ -22,9 +22,6 @@ GTEXT(_firq_enter) GTEXT(_firq_exit) -GDATA(exc_nest_count) - - /** * * @brief Work to be done before handing control to a FIRQ ISR @@ -81,12 +78,9 @@ SECTION_FUNC(TEXT, _firq_enter) lr r25, [_ARC_V2_LP_END] #endif - ld r1, [exc_nest_count] - add r0, r1, 1 - st r0, [exc_nest_count] - cmp r1, 0 + _check_nest_int_by_irq_act r0, r1 - bgt.d firq_nest + bne.d firq_nest mov r0, sp mov r1, _kernel @@ -147,19 +141,10 @@ SECTION_FUNC(TEXT, _firq_exit) sr r24, [_ARC_V2_LP_START] sr r25, [_ARC_V2_LP_END] #endif - /* check if we're a nested interrupt: if so, let the interrupted - * interrupt handle the reschedule */ - mov r1, exc_nest_count - ld r0, [r1] - sub r0, r0, 1 - st r0, [r1] -/* see comments in _rirq_exit */ - lr r0, [_ARC_V2_AUX_IRQ_ACT] - and r0, r0, 0xffff - ffs r1, r0 - fls r2, r0 - cmp r1, r2 - jne _firq_no_reschedule + + _check_nest_int_by_irq_act r0, r1 + + jne _firq_no_reschedule #ifdef CONFIG_STACK_SENTINEL bl z_check_stack_sentinel diff --git a/arch/arc/core/fault_s.S b/arch/arc/core/fault_s.S index bc1b1dea3ea..2c893ec633f 100644 --- a/arch/arc/core/fault_s.S +++ b/arch/arc/core/fault_s.S @@ -38,8 +38,6 @@ GTEXT(__ev_maligned) GTEXT(z_irq_do_offload); #endif -GDATA(exc_nest_count) - /* the necessary stack size for exception handling */ #define EXCEPTION_STACK_SIZE 384 @@ -203,12 +201,11 @@ _do_non_syscall_trap: lr r0,[_ARC_V2_ERET] st_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */ - ld r1, [exc_nest_count] - add r0, r1, 1 - st r0, [exc_nest_count] - cmp r1, 0 - bgt.d exc_nest_handle + lr r0, [_ARC_V2_AUX_IRQ_ACT] + and r0, r0, 0xffff + cmp r0, 0 + bne.d exc_nest_handle mov r0, sp mov r1, _kernel @@ -220,12 +217,10 @@ exc_nest_handle: pop sp - mov r1, exc_nest_count - ld r0, [r1] - sub r0, r0, 1 - cmp r0, 0 - bne.d _exc_return_from_exc - st r0, [r1] + lr r0, [_ARC_V2_AUX_IRQ_ACT] + and r0, r0, 0xffff + cmp r0, 0 + bne _exc_return_from_exc #ifdef CONFIG_PREEMPT_ENABLED mov_s r1, _kernel diff --git a/arch/arc/core/isr_wrapper.S b/arch/arc/core/isr_wrapper.S index 8a1bc402147..a5d46c72e49 100644 --- a/arch/arc/core/isr_wrapper.S +++ b/arch/arc/core/isr_wrapper.S @@ -24,12 +24,6 @@ GTEXT(_isr_wrapper) GTEXT(_isr_demux) -GDATA(exc_nest_count) -SECTION_VAR(BSS, exc_nest_count) - .balign 4 - .word 0 - - #if defined(CONFIG_SYS_POWER_MANAGEMENT) GTEXT(z_sys_power_save_idle_exit) #endif diff --git a/arch/arc/core/regular_irq.S b/arch/arc/core/regular_irq.S index abd3c0a2228..d28e6794334 100644 --- a/arch/arc/core/regular_irq.S +++ b/arch/arc/core/regular_irq.S @@ -23,7 +23,6 @@ GTEXT(_rirq_enter) GTEXT(_rirq_exit) GTEXT(_rirq_common_interrupt_swap) -GDATA(exc_nest_count) #if 0 /* TODO: when FIRQ is not present, all would be regular */ #define NUM_REGULAR_IRQ_PRIO_LEVELS CONFIG_NUM_IRQ_PRIO_LEVELS @@ -67,12 +66,10 @@ SECTION_FUNC(TEXT, _rirq_enter) #endif #endif clri - ld r1, [exc_nest_count] - add r0, r1, 1 - st r0, [exc_nest_count] - cmp r1, 0 - bgt.d rirq_nest + _check_nest_int_by_irq_act r0, r1 + + bne.d rirq_nest mov r0, sp mov r1, _kernel @@ -96,27 +93,9 @@ SECTION_FUNC(TEXT, _rirq_exit) pop sp - mov r1, exc_nest_count - ld r0, [r1] - sub r0, r0, 1 - st r0, [r1] - /* - * using exc_nest_count to decide whether is nest int is not reliable. - * a better option is to use IRQ_ACT - * A case is: a high priority int preempts a low priority int before - * rirq_enter/firq_enter, then in _rirq_exit/_firq_exit, it will see - * exc_nest_cout is 0, this will lead to possible thread switch, but - * a low priority int is still pending. - * - * If multi bits in IRQ_ACT are set, i.e. last bit != fist bit, it's - * in nest interrupt - */ - lr r0, [_ARC_V2_AUX_IRQ_ACT] - and r0, r0, 0xffff - ffs r1, r0 - fls r2, r0 - cmp r1, r2 - jne _rirq_return_from_rirq + _check_nest_int_by_irq_act r0, r1 + + jne _rirq_return_from_rirq #ifdef CONFIG_STACK_SENTINEL bl z_check_stack_sentinel diff --git a/arch/arc/include/swap_macros.h b/arch/arc/include/swap_macros.h index 6f4aba9214b..c1e59aa3174 100644 --- a/arch/arc/include/swap_macros.h +++ b/arch/arc/include/swap_macros.h @@ -272,6 +272,17 @@ extern "C" { #endif /* CONFIG_ARC_HAS_SECURE */ .endm +/* 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 + */ +.macro _check_nest_int_by_irq_act reg1, reg2 + lr \reg1, [_ARC_V2_AUX_IRQ_ACT] + and \reg1, \reg1, 0xffff + ffs \reg2, \reg1 + fls \reg1, \reg1 + cmp \reg1, \reg2 +.endm + #endif /* _ASMLANGUAGE */ #ifdef __cplusplus