From 8e0729454d1ae4936fc58c48134ee285b8cae299 Mon Sep 17 00:00:00 2001 From: hujun5 Date: Wed, 20 Nov 2024 14:41:25 +0800 Subject: [PATCH] arm: remove up_set_current_regs/up_current_regs reason: up_set_current_regs initially had two functions: 1: To mark the entry into an interrupt state. 2: To record the context before an interrupt/exception. If we switch to a new task, we need to store the upcoming context regs by calling up_set_current_regs(regs). Currently, we record the context in other ways, so the second function is obsolete. Therefore, we need to rename up_set_current_regs to better reflect its actual meaning, which is solely to mark an interrupt. Signed-off-by: hujun5 --- arch/arm/include/arm/irq.h | 43 +++---------------- arch/arm/include/armv6-m/irq.h | 32 -------------- arch/arm/include/armv7-a/irq.h | 27 +----------- arch/arm/include/armv7-m/irq.h | 32 -------------- arch/arm/include/armv7-r/irq.h | 27 +----------- arch/arm/include/armv8-m/irq.h | 32 -------------- arch/arm/include/armv8-r/irq.h | 27 +----------- arch/arm/include/irq.h | 2 +- arch/arm/include/tlsr82/irq.h | 43 +++---------------- arch/arm/src/arm/arm_dataabort.c | 26 +++++------ arch/arm/src/arm/arm_doirq.c | 14 +++--- arch/arm/src/arm/arm_prefetchabort.c | 19 ++++---- arch/arm/src/arm/arm_syscall.c | 16 +++---- arch/arm/src/arm/arm_undefinedinsn.c | 6 ++- arch/arm/src/armv6-m/arm_doirq.c | 8 ---- arch/arm/src/armv7-a/arm_dataabort.c | 21 +++++---- arch/arm/src/armv7-a/arm_doirq.c | 14 +++--- arch/arm/src/armv7-a/arm_prefetchabort.c | 22 ++++++---- arch/arm/src/armv7-a/arm_syscall.c | 16 +++---- arch/arm/src/armv7-a/arm_undefinedinsn.c | 6 ++- arch/arm/src/armv7-m/arm_doirq.c | 8 ---- arch/arm/src/armv7-r/arm_dataabort.c | 5 ++- arch/arm/src/armv7-r/arm_doirq.c | 15 +++---- arch/arm/src/armv7-r/arm_prefetchabort.c | 5 ++- arch/arm/src/armv7-r/arm_syscall.c | 16 +++---- arch/arm/src/armv7-r/arm_undefinedinsn.c | 6 ++- arch/arm/src/armv8-m/arm_doirq.c | 8 ---- arch/arm/src/armv8-r/arm_dataabort.c | 5 ++- arch/arm/src/armv8-r/arm_doirq.c | 14 +++--- arch/arm/src/armv8-r/arm_prefetchabort.c | 5 ++- arch/arm/src/armv8-r/arm_syscall.c | 16 +++---- arch/arm/src/armv8-r/arm_undefinedinsn.c | 6 ++- arch/arm/src/common/arm_backtrace_fp.c | 4 +- arch/arm/src/common/arm_backtrace_sp.c | 2 +- arch/arm/src/common/arm_backtrace_unwind.c | 8 ++-- arch/arm/src/common/arm_initialize.c | 13 ++---- arch/arm/src/common/arm_internal.h | 24 +++++++++++ arch/arm/src/common/arm_registerdump.c | 2 +- arch/arm/src/dm320/dm320_decodeirq.c | 16 ++++--- arch/arm/src/imx1/imx_decodeirq.c | 16 ++++--- arch/arm/src/lpc214x/lpc214x_decodeirq.c | 19 ++++---- arch/arm/src/lpc2378/lpc23xx_decodeirq.c | 20 ++++----- arch/arm/src/lpc31xx/lpc31_decodeirq.c | 16 ++++--- arch/arm/src/moxart/moxart_irq.c | 12 ++++-- arch/arm/src/str71x/str71x_decodeirq.c | 20 ++++----- arch/arm/src/tlsr82/tc32/tc32_backtrace.c | 5 ++- arch/arm/src/tlsr82/tc32/tc32_doirq.c | 14 +----- arch/arm/src/tlsr82/tc32/tc32_syscall.c | 5 ++- arch/arm/src/tms570/tms570_esm.c | 7 ++- .../arm/cxd56xx/common/src/cxd56_crashdump.c | 4 +- .../arm/nrf52/nrf52840-dk/src/nrf52_highpri.c | 2 +- .../stm32/nucleo-f429zi/src/stm32_bbsram.c | 4 +- .../viewtool-stm32f107/src/stm32_highpri.c | 2 +- .../stm32f7/nucleo-f722ze/src/stm32_bbsram.c | 4 +- .../stm32f7/nucleo-f746zg/src/stm32_bbsram.c | 4 +- .../stm32f7/nucleo-f767zi/src/stm32_bbsram.c | 4 +- 56 files changed, 271 insertions(+), 498 deletions(-) diff --git a/arch/arm/include/arm/irq.h b/arch/arm/include/arm/irq.h index bb369ce96649f..b5c853e5b63af 100644 --- a/arch/arm/include/arm/irq.h +++ b/arch/arm/include/arm/irq.h @@ -156,17 +156,9 @@ struct xcptcontext * Public Data ****************************************************************************/ -/* g_current_regs[] holds a references to the current interrupt level - * register storage structure. If is non-NULL only during interrupt - * processing. Access to g_current_regs[] must be through the - * [get/set]_current_regs for portability. - */ - -/* For the case of architectures with multiple CPUs, then there must be one - * such value for each processor that can receive an interrupt. - */ +/* g_interrupt_context store irq status */ -extern volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; +extern volatile bool g_interrupt_context[CONFIG_SMP_NCPUS]; /**************************************************************************** * Inline functions @@ -239,40 +231,17 @@ static inline irqstate_t up_irq_enable(void) int up_cpu_index(void) noinstrument_function; #endif /* CONFIG_ARCH_HAVE_MULTICPU */ -noinstrument_function -static inline_function uint32_t *up_current_regs(void) -{ -#ifdef CONFIG_SMP - return (uint32_t *)g_current_regs[up_cpu_index()]; -#else - return (uint32_t *)g_current_regs[0]; -#endif -} - -noinstrument_function -static inline_function void up_set_current_regs(uint32_t *regs) -{ -#ifdef CONFIG_SMP - g_current_regs[up_cpu_index()] = regs; -#else - g_current_regs[0] = regs; -#endif -} - noinstrument_function static inline_function bool up_interrupt_context(void) { #ifdef CONFIG_SMP irqstate_t flags = up_irq_save(); -#endif - - bool ret = up_current_regs() != NULL; - -#ifdef CONFIG_SMP + bool ret = g_interrupt_context[up_cpu_index()]; up_irq_restore(flags); -#endif - return ret; +#else + return g_interrupt_context[0]; +#endif } /**************************************************************************** diff --git a/arch/arm/include/armv6-m/irq.h b/arch/arm/include/armv6-m/irq.h index 9f3d5c14a6661..d18727c6cdc20 100644 --- a/arch/arm/include/armv6-m/irq.h +++ b/arch/arm/include/armv6-m/irq.h @@ -192,18 +192,6 @@ struct xcptcontext * Public Data ****************************************************************************/ -/* g_current_regs[] holds a references to the current interrupt level - * register storage structure. If is non-NULL only during interrupt - * processing. Access to g_current_regs[] must be through the - * [get/set]_current_regs for portability. - */ - -/* For the case of architectures with multiple CPUs, then there must be one - * such value for each processor that can receive an interrupt. - */ - -extern volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; - /**************************************************************************** * Inline functions ****************************************************************************/ @@ -367,26 +355,6 @@ static inline_function uint32_t up_getsp(void) return sp; } -noinstrument_function -static inline_function uint32_t *up_current_regs(void) -{ -#ifdef CONFIG_SMP - return (uint32_t *)g_current_regs[up_cpu_index()]; -#else - return (uint32_t *)g_current_regs[0]; -#endif -} - -noinstrument_function -static inline_function void up_set_current_regs(uint32_t *regs) -{ -#ifdef CONFIG_SMP - g_current_regs[up_cpu_index()] = regs; -#else - g_current_regs[0] = regs; -#endif -} - noinstrument_function static inline_function bool up_interrupt_context(void) { diff --git a/arch/arm/include/armv7-a/irq.h b/arch/arm/include/armv7-a/irq.h index ececff0e89657..e10cdcc5b4f0b 100644 --- a/arch/arm/include/armv7-a/irq.h +++ b/arch/arm/include/armv7-a/irq.h @@ -470,35 +470,10 @@ static inline_function uint32_t up_getsp(void) return sp; } -/**************************************************************************** - * Name: - * up_current_regs/up_set_current_regs - * - * Description: - * We use the following code to manipulate the TPIDRPRW register, - * which exists uniquely for each CPU and is primarily designed to store - * current thread information. Currently, we leverage it to store interrupt - * information, with plans to further optimize its use for storing both - * thread and interrupt information in the future. - * - ****************************************************************************/ - -noinstrument_function -static inline_function uint32_t *up_current_regs(void) -{ - return (uint32_t *)CP15_GET(TPIDRPRW); -} - -noinstrument_function -static inline_function void up_set_current_regs(uint32_t *regs) -{ - CP15_SET(TPIDRPRW, regs); -} - noinstrument_function static inline_function bool up_interrupt_context(void) { - return up_current_regs() != NULL; + return (bool)CP15_GET(TPIDRPRW); } /**************************************************************************** diff --git a/arch/arm/include/armv7-m/irq.h b/arch/arm/include/armv7-m/irq.h index 4944ba6983d56..b94b3e0abad9c 100644 --- a/arch/arm/include/armv7-m/irq.h +++ b/arch/arm/include/armv7-m/irq.h @@ -254,18 +254,6 @@ struct xcptcontext * Public Data ****************************************************************************/ -/* g_current_regs[] holds a references to the current interrupt level - * register storage structure. If is non-NULL only during interrupt - * processing. Access to g_current_regs[] must be through the - * [get/set]_current_regs for portability. - */ - -/* For the case of architectures with multiple CPUs, then there must be one - * such value for each processor that can receive an interrupt. - */ - -extern volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; - /**************************************************************************** * Inline functions ****************************************************************************/ @@ -572,26 +560,6 @@ static inline_function uint32_t up_getsp(void) return sp; } -noinstrument_function -static inline_function uint32_t *up_current_regs(void) -{ -#ifdef CONFIG_SMP - return (uint32_t *)g_current_regs[up_cpu_index()]; -#else - return (uint32_t *)g_current_regs[0]; -#endif -} - -noinstrument_function -static inline_function void up_set_current_regs(uint32_t *regs) -{ -#ifdef CONFIG_SMP - g_current_regs[up_cpu_index()] = regs; -#else - g_current_regs[0] = regs; -#endif -} - noinstrument_function static inline_function bool up_interrupt_context(void) { diff --git a/arch/arm/include/armv7-r/irq.h b/arch/arm/include/armv7-r/irq.h index b50795545a6c3..d8bad2a9392df 100644 --- a/arch/arm/include/armv7-r/irq.h +++ b/arch/arm/include/armv7-r/irq.h @@ -465,35 +465,10 @@ static inline_function uint32_t up_getsp(void) return sp; } -/**************************************************************************** - * Name: - * up_current_regs/up_set_current_regs - * - * Description: - * We use the following code to manipulate the TPIDRPRW register, - * which exists uniquely for each CPU and is primarily designed to store - * current thread information. Currently, we leverage it to store interrupt - * information, with plans to further optimize its use for storing both - * thread and interrupt information in the future. - * - ****************************************************************************/ - -noinstrument_function -static inline_function uint32_t *up_current_regs(void) -{ - return (uint32_t *)CP15_GET(TPIDRPRW); -} - -noinstrument_function -static inline_function void up_set_current_regs(uint32_t *regs) -{ - CP15_SET(TPIDRPRW, regs); -} - noinstrument_function static inline_function bool up_interrupt_context(void) { - return up_current_regs() != NULL; + return (bool)CP15_GET(TPIDRPRW); } /**************************************************************************** diff --git a/arch/arm/include/armv8-m/irq.h b/arch/arm/include/armv8-m/irq.h index 32aefa0980e14..568837e43856a 100644 --- a/arch/arm/include/armv8-m/irq.h +++ b/arch/arm/include/armv8-m/irq.h @@ -265,18 +265,6 @@ struct xcptcontext * Public Data ****************************************************************************/ -/* g_current_regs[] holds a references to the current interrupt level - * register storage structure. If is non-NULL only during interrupt - * processing. Access to g_current_regs[] must be through the - * [get/set]_current_regs for portability. - */ - -/* For the case of architectures with multiple CPUs, then there must be one - * such value for each processor that can receive an interrupt. - */ - -extern volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; - /**************************************************************************** * Inline functions ****************************************************************************/ @@ -545,26 +533,6 @@ static inline_function uint32_t up_getsp(void) return sp; } -noinstrument_function -static inline_function uint32_t *up_current_regs(void) -{ -#ifdef CONFIG_SMP - return (uint32_t *)g_current_regs[up_cpu_index()]; -#else - return (uint32_t *)g_current_regs[0]; -#endif -} - -noinstrument_function -static inline_function void up_set_current_regs(uint32_t *regs) -{ -#ifdef CONFIG_SMP - g_current_regs[up_cpu_index()] = regs; -#else - g_current_regs[0] = regs; -#endif -} - noinstrument_function static inline_function bool up_interrupt_context(void) { diff --git a/arch/arm/include/armv8-r/irq.h b/arch/arm/include/armv8-r/irq.h index 91557517bd27f..a142b4bfbb058 100644 --- a/arch/arm/include/armv8-r/irq.h +++ b/arch/arm/include/armv8-r/irq.h @@ -465,35 +465,10 @@ static inline_function uint32_t up_getsp(void) return sp; } -/**************************************************************************** - * Name: - * up_current_regs/up_set_current_regs - * - * Description: - * We use the following code to manipulate the TPIDRPRW register, - * which exists uniquely for each CPU and is primarily designed to store - * current thread information. Currently, we leverage it to store interrupt - * information, with plans to further optimize its use for storing both - * thread and interrupt information in the future. - * - ****************************************************************************/ - -noinstrument_function -static inline_function uint32_t *up_current_regs(void) -{ - return (uint32_t *)CP15_GET(TPIDRPRW); -} - -noinstrument_function -static inline_function void up_set_current_regs(uint32_t *regs) -{ - CP15_SET(TPIDRPRW, regs); -} - noinstrument_function static inline_function bool up_interrupt_context(void) { - return up_current_regs() != NULL; + return (bool)CP15_GET(TPIDRPRW); } /**************************************************************************** diff --git a/arch/arm/include/irq.h b/arch/arm/include/irq.h index 066be261d8a4d..d6fd08cdddb23 100644 --- a/arch/arm/include/irq.h +++ b/arch/arm/include/irq.h @@ -105,7 +105,7 @@ extern "C" ****************************************************************************/ #define up_getusrpc(regs) \ - (((uint32_t *)((regs) ? (regs) : up_current_regs()))[REG_PC]) + (((uint32_t *)((regs) ? (regs) : running_regs()))[REG_PC]) #endif /* __ASSEMBLY__ */ diff --git a/arch/arm/include/tlsr82/irq.h b/arch/arm/include/tlsr82/irq.h index fccf441d890c6..d7a26d790466b 100644 --- a/arch/arm/include/tlsr82/irq.h +++ b/arch/arm/include/tlsr82/irq.h @@ -173,17 +173,9 @@ struct xcptcontext * Public Data ****************************************************************************/ -/* g_current_regs[] holds a references to the current interrupt level - * register storage structure. If is non-NULL only during interrupt - * processing. Access to g_current_regs[] must be through the - * [get/set]_current_regs for portability. - */ - -/* For the case of architectures with multiple CPUs, then there must be one - * such value for each processor that can receive an interrupt. - */ +/* g_interrupt_context store irq status */ -extern volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; +extern volatile bool g_interrupt_context[CONFIG_SMP_NCPUS]; /**************************************************************************** * Inline functions @@ -268,40 +260,17 @@ static inline_function uint32_t up_getsp(void) return sp; } -noinstrument_function -static inline_function uint32_t *up_current_regs(void) -{ -#ifdef CONFIG_SMP - return (uint32_t *)g_current_regs[up_cpu_index()]; -#else - return (uint32_t *)g_current_regs[0]; -#endif -} - -noinstrument_function -static inline_function void up_set_current_regs(uint32_t *regs) -{ -#ifdef CONFIG_SMP - g_current_regs[up_cpu_index()] = regs; -#else - g_current_regs[0] = regs; -#endif -} - noinstrument_function static inline_function bool up_interrupt_context(void) { #ifdef CONFIG_SMP irqstate_t flags = up_irq_save(); -#endif - - bool ret = up_current_regs() != NULL; - -#ifdef CONFIG_SMP + bool ret = g_interrupt_context[up_cpu_index()]; up_irq_restore(flags); -#endif - return ret; +#else + return g_interrupt_context[0]; +#endif } #define up_switch_context(tcb, rtcb) \ diff --git a/arch/arm/src/arm/arm_dataabort.c b/arch/arm/src/arm/arm_dataabort.c index a0951f8eb4beb..277d53d975896 100644 --- a/arch/arm/src/arm/arm_dataabort.c +++ b/arch/arm/src/arm/arm_dataabort.c @@ -70,15 +70,14 @@ void arm_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr) { struct tcb_s *tcb = this_task(); #ifdef CONFIG_LEGACY_PAGING - uint32_t *savestate; + bool savestate; + uint32_t *saveregs; - /* Save the saved processor context in current_regs where it can be - * accessed for register dumps and possibly context switching. - */ - - savestate = up_current_regs(); + savestate = up_interrupt_context(); + saveregs = tcb->xcp.regs; #endif - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); #ifdef CONFIG_LEGACY_PAGING /* In the NuttX on-demand paging implementation, only the read-only, .text @@ -133,12 +132,10 @@ void arm_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr) pg_miss(); - /* Restore the previous value of current_regs. NULL would indicate that - * we are no longer in an interrupt handler. It will be non-NULL if we - * are returning from a nested interrupt. - */ + /* Restore the previous value of irq flag. */ - up_set_current_regs(savestate); + arm_set_irq_flag(savestate); + tcb->xcp.regs = saveregs; return; segfault: @@ -153,11 +150,14 @@ void arm_dataabort(uint32_t *regs, uint32_t far, uint32_t fsr) void arm_dataabort(uint32_t *regs) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); /* Crash -- possibly showing diagnost debug information. */ diff --git a/arch/arm/src/arm/arm_doirq.c b/arch/arm/src/arm/arm_doirq.c index 55e056a8ee2ac..5a006121cbe76 100644 --- a/arch/arm/src/arm/arm_doirq.c +++ b/arch/arm/src/arm/arm_doirq.c @@ -66,13 +66,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) #else /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ + /* Set irq flag */ - up_set_current_regs(regs); + arm_set_irq_flag(true); tcb->xcp.regs = regs; /* Acknowledge the interrupt */ @@ -118,11 +116,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) regs = tcb->xcp.regs; } - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + arm_set_irq_flag(false); #endif board_autoled_off(LED_INIRQ); return regs; diff --git a/arch/arm/src/arm/arm_prefetchabort.c b/arch/arm/src/arm/arm_prefetchabort.c index 288d78495ca9f..e5177c45fb1a9 100644 --- a/arch/arm/src/arm/arm_prefetchabort.c +++ b/arch/arm/src/arm/arm_prefetchabort.c @@ -65,16 +65,17 @@ void arm_prefetchabort(uint32_t *regs) { -#ifdef CONFIG_LEGACY_PAGING - uint32_t *savestate; + struct tcb_s *tcb = this_task(); - /* Save the saved processor context in current_regs where it can be - * accessed for register dumps and possibly context switching. - */ +#ifdef CONFIG_LEGACY_PAGING + bool savestate; + uint32_t *saveregs; - savestate = up_current_regs(); + savestate = up_interrupt_context(); + saveregs = tcb->xcp.regs; #endif - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); #ifdef CONFIG_LEGACY_PAGING /* Get the (virtual) address of instruction that caused the prefetch @@ -97,7 +98,6 @@ void arm_prefetchabort(uint32_t *regs) * paging logic for both prefetch and data aborts. */ - struct tcb_s *tcb = this_task(); tcb->xcp.far = regs[REG_R15]; /* Call pg_miss() to schedule the page fill. A consequences of this @@ -119,7 +119,8 @@ void arm_prefetchabort(uint32_t *regs) * if we are returning from a nested interrupt. */ - up_set_current_regs(savestate); + arm_set_irq_flag(savestate); + tcb->xcp.regs = saveregs; } else #endif diff --git a/arch/arm/src/arm/arm_syscall.c b/arch/arm/src/arm/arm_syscall.c index a69cc31941cb5..f450a1caee92c 100644 --- a/arch/arm/src/arm/arm_syscall.c +++ b/arch/arm/src/arm/arm_syscall.c @@ -60,18 +60,16 @@ uint32_t *arm_syscall(uint32_t *regs) /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); if (*running_task != NULL) { (*running_task)->xcp.regs = regs; } - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ + /* Set irq flag */ - up_set_current_regs(regs); + arm_set_irq_flag(true); /* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */ @@ -100,7 +98,7 @@ uint32_t *arm_syscall(uint32_t *regs) */ tcb->xcp.regs = (uint32_t *)regs[REG_R1]; - DEBUGASSERT(up_current_regs()); + DEBUGASSERT(up_interrupt_context()); } break; @@ -156,11 +154,9 @@ uint32_t *arm_syscall(uint32_t *regs) restore_critical_section(tcb, this_cpu()); } - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + arm_set_irq_flag(false); /* Return the last value of curent_regs. This supports context switches * on return from the exception. That capability is only used with the diff --git a/arch/arm/src/arm/arm_undefinedinsn.c b/arch/arm/src/arm/arm_undefinedinsn.c index 0aeeb19076364..49549c90055e5 100644 --- a/arch/arm/src/arm/arm_undefinedinsn.c +++ b/arch/arm/src/arm/arm_undefinedinsn.c @@ -29,6 +29,7 @@ #include #include +#include #include "arm_internal.h" @@ -42,11 +43,14 @@ void arm_undefinedinsn(uint32_t *regs) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); if (regs[REG_PC] >= (uint32_t)_stext && regs[REG_PC] < (uint32_t)_etext) { diff --git a/arch/arm/src/armv6-m/arm_doirq.c b/arch/arm/src/armv6-m/arm_doirq.c index 125431bbcead0..fe0cb19808b2c 100644 --- a/arch/arm/src/armv6-m/arm_doirq.c +++ b/arch/arm/src/armv6-m/arm_doirq.c @@ -73,10 +73,6 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) arm_ack_irq(irq); - /* Set current regs for crash dump */ - - up_set_current_regs(regs); - if (irq == NVIC_IRQ_PENDSV) { #ifdef CONFIG_ARCH_HIPRI_INTERRUPT @@ -114,10 +110,6 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) regs = tcb->xcp.regs; #endif - /* Clear current regs */ - - up_set_current_regs(NULL); - board_autoled_off(LED_INIRQ); return regs; diff --git a/arch/arm/src/armv7-a/arm_dataabort.c b/arch/arm/src/armv7-a/arm_dataabort.c index c986ebbd8989c..8f76277a25706 100644 --- a/arch/arm/src/armv7-a/arm_dataabort.c +++ b/arch/arm/src/armv7-a/arm_dataabort.c @@ -68,14 +68,13 @@ uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) { struct tcb_s *tcb = this_task(); - uint32_t *savestate; + bool savestate; + uint32_t *saveregs; - /* Save the saved processor context in current_regs where it can be - * accessed for register dumps and possibly context switching. - */ - - savestate = up_current_regs(); - up_set_current_regs(regs); + savestate = up_interrupt_context(); + saveregs = tcb->xcp.regs; + tcb->xcp.regs = regs; + arm_set_irq_flag(true); /* In the NuttX on-demand paging implementation, only the read-only, .text * section is paged. However, the ARM compiler generated PC-relative data @@ -134,7 +133,8 @@ uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) * are returning from a nested interrupt. */ - up_set_current_regs(savestate); + arm_set_irq_flag(savestate); + tcb->xcp.regs = saveregs; return regs; segfault: @@ -148,11 +148,14 @@ uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); /* Crash -- possibly showing diagnostic debug information. */ diff --git a/arch/arm/src/armv7-a/arm_doirq.c b/arch/arm/src/armv7-a/arm_doirq.c index 97feb8b8f61f6..8e42570ccadd8 100644 --- a/arch/arm/src/armv7-a/arm_doirq.c +++ b/arch/arm/src/armv7-a/arm_doirq.c @@ -61,7 +61,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) #else /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); /* if irq == GIC_SMP_CPUSTART * We are initiating the multi-core jumping state to up_idle, @@ -75,11 +75,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) tcb->xcp.regs = regs; } - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ + /* Set irq flag */ - up_set_current_regs(regs); + arm_set_irq_flag(true); /* Deliver the IRQ */ @@ -112,11 +110,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) regs = tcb->xcp.regs; } - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + arm_set_irq_flag(false); #endif board_autoled_off(LED_INIRQ); diff --git a/arch/arm/src/armv7-a/arm_prefetchabort.c b/arch/arm/src/armv7-a/arm_prefetchabort.c index 4f4f8b8b43cc1..d948273e60238 100644 --- a/arch/arm/src/armv7-a/arm_prefetchabort.c +++ b/arch/arm/src/armv7-a/arm_prefetchabort.c @@ -54,14 +54,14 @@ uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) { - uint32_t *savestate; + struct tcb_s *tcb = this_task(); + bool savestate; + uint32_t *saveregs; - /* Save the saved processor context in current_regs where it can be - * accessed for register dumps and possibly context switching. - */ - - savestate = up_current_regs(); - up_set_current_regs(regs); + savestate = up_interrupt_context(); + saveregs = tcb->xcp.regs; + tcb->xcp.regs = regs; + arm_set_irq_flag(true); /* Get the (virtual) address of instruction that caused the prefetch * abort. When the exception occurred, this address was provided in the @@ -105,7 +105,8 @@ uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) * It will be non-NULL if we are returning from a nested interrupt. */ - up_set_current_regs(savestate); + arm_set_irq_flag(savestate); + tcb->xcp.regs = saveregs; } else { @@ -121,11 +122,14 @@ uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); /* Crash -- possibly showing diagnostic debug information. */ diff --git a/arch/arm/src/armv7-a/arm_syscall.c b/arch/arm/src/armv7-a/arm_syscall.c index dc420295ad7f0..116734083f2e5 100644 --- a/arch/arm/src/armv7-a/arm_syscall.c +++ b/arch/arm/src/armv7-a/arm_syscall.c @@ -168,18 +168,16 @@ uint32_t *arm_syscall(uint32_t *regs) /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); if (*running_task != NULL) { (*running_task)->xcp.regs = regs; } - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ + /* Set irq flag */ - up_set_current_regs(regs); + arm_set_irq_flag(true); /* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */ @@ -277,7 +275,7 @@ uint32_t *arm_syscall(uint32_t *regs) */ tcb->xcp.regs = (uint32_t *)regs[REG_R1]; - DEBUGASSERT(up_current_regs()); + DEBUGASSERT(up_interrupt_context()); } break; @@ -597,11 +595,9 @@ uint32_t *arm_syscall(uint32_t *regs) dump_syscall("Exit", cmd, regs); - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + arm_set_irq_flag(false); /* Return the last value of curent_regs. This supports context switches * on return from the exception. That capability is only used with the diff --git a/arch/arm/src/armv7-a/arm_undefinedinsn.c b/arch/arm/src/armv7-a/arm_undefinedinsn.c index 8acd6eb96dc0b..f0b58ba625ec8 100644 --- a/arch/arm/src/armv7-a/arm_undefinedinsn.c +++ b/arch/arm/src/armv7-a/arm_undefinedinsn.c @@ -29,6 +29,7 @@ #include #include +#include #include "arm_internal.h" @@ -42,11 +43,14 @@ uint32_t *arm_undefinedinsn(uint32_t *regs) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); if (regs[REG_PC] >= (uint32_t)_stext && regs[REG_PC] < (uint32_t)_etext) { diff --git a/arch/arm/src/armv7-m/arm_doirq.c b/arch/arm/src/armv7-m/arm_doirq.c index d433f83d1c82e..98c3200714335 100644 --- a/arch/arm/src/armv7-m/arm_doirq.c +++ b/arch/arm/src/armv7-m/arm_doirq.c @@ -73,10 +73,6 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) arm_ack_irq(irq); - /* Set current regs for crash dump */ - - up_set_current_regs(regs); - if (irq == NVIC_IRQ_PENDSV) { #ifdef CONFIG_ARCH_HIPRI_INTERRUPT @@ -114,10 +110,6 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) regs = tcb->xcp.regs; #endif - /* Clear current regs */ - - up_set_current_regs(NULL); - board_autoled_off(LED_INIRQ); return regs; diff --git a/arch/arm/src/armv7-r/arm_dataabort.c b/arch/arm/src/armv7-r/arm_dataabort.c index a38eb4fc8f3d7..d7d2f51c0639d 100644 --- a/arch/arm/src/armv7-r/arm_dataabort.c +++ b/arch/arm/src/armv7-r/arm_dataabort.c @@ -53,11 +53,14 @@ uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); /* Crash -- possibly showing diagnostic debug information. */ diff --git a/arch/arm/src/armv7-r/arm_doirq.c b/arch/arm/src/armv7-r/arm_doirq.c index dae25dd47e852..fd39b9b293271 100644 --- a/arch/arm/src/armv7-r/arm_doirq.c +++ b/arch/arm/src/armv7-r/arm_doirq.c @@ -50,7 +50,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) #else /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); /* if irq == GIC_SMP_CPUSTART * We are initiating the multi-core jumping state to up_idle, @@ -64,11 +64,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) tcb->xcp.regs = regs; } - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ + /* Set irq flag */ - up_set_current_regs(regs); + arm_set_irq_flag(true); /* Deliver the IRQ */ @@ -91,12 +89,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) regs = tcb->xcp.regs; } - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ - - up_set_current_regs(NULL); + /* Set irq flag */ + arm_set_irq_flag(false); board_autoled_off(LED_INIRQ); #endif return regs; diff --git a/arch/arm/src/armv7-r/arm_prefetchabort.c b/arch/arm/src/armv7-r/arm_prefetchabort.c index de5b2e35d16b0..86534b6f3a801 100644 --- a/arch/arm/src/armv7-r/arm_prefetchabort.c +++ b/arch/arm/src/armv7-r/arm_prefetchabort.c @@ -49,11 +49,14 @@ uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); /* Crash -- possibly showing diagnostic debug information. */ diff --git a/arch/arm/src/armv7-r/arm_syscall.c b/arch/arm/src/armv7-r/arm_syscall.c index b4f3a5047bfd6..a66299bbc02ca 100644 --- a/arch/arm/src/armv7-r/arm_syscall.c +++ b/arch/arm/src/armv7-r/arm_syscall.c @@ -165,18 +165,16 @@ uint32_t *arm_syscall(uint32_t *regs) /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); if (*running_task != NULL) { (*running_task)->xcp.regs = regs; } - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ + /* Set irq flag */ - up_set_current_regs(regs); + arm_set_irq_flag(true); /* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */ @@ -274,7 +272,7 @@ uint32_t *arm_syscall(uint32_t *regs) */ tcb->xcp.regs = (uint32_t *)regs[REG_R1]; - DEBUGASSERT(up_current_regs()); + DEBUGASSERT(up_interrupt_context()); } break; @@ -584,11 +582,9 @@ uint32_t *arm_syscall(uint32_t *regs) dump_syscall("Exit", cmd, regs); - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + arm_set_irq_flag(false); /* Return the last value of curent_regs. This supports context switches * on return from the exception. That capability is only used with the diff --git a/arch/arm/src/armv7-r/arm_undefinedinsn.c b/arch/arm/src/armv7-r/arm_undefinedinsn.c index a62d872f025dd..c8b9c837e15bd 100644 --- a/arch/arm/src/armv7-r/arm_undefinedinsn.c +++ b/arch/arm/src/armv7-r/arm_undefinedinsn.c @@ -29,6 +29,7 @@ #include #include +#include #include "arm_internal.h" @@ -42,11 +43,14 @@ uint32_t *arm_undefinedinsn(uint32_t *regs) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); if (regs[REG_PC] >= (uint32_t)_stext && regs[REG_PC] < (uint32_t)_etext) { diff --git a/arch/arm/src/armv8-m/arm_doirq.c b/arch/arm/src/armv8-m/arm_doirq.c index a1ca38afa427a..7e2a354460ac5 100644 --- a/arch/arm/src/armv8-m/arm_doirq.c +++ b/arch/arm/src/armv8-m/arm_doirq.c @@ -84,10 +84,6 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) arm_ack_irq(irq); - /* Set current regs for crash dump */ - - up_set_current_regs(regs); - if (irq == NVIC_IRQ_PENDSV) { #ifdef CONFIG_ARCH_HIPRI_INTERRUPT @@ -125,10 +121,6 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) regs = tcb->xcp.regs; #endif - /* Clear current regs */ - - up_set_current_regs(NULL); - board_autoled_off(LED_INIRQ); #ifdef CONFIG_ARMV8M_TRUSTZONE_HYBRID diff --git a/arch/arm/src/armv8-r/arm_dataabort.c b/arch/arm/src/armv8-r/arm_dataabort.c index 3eeae60fc8b09..9e377048e1dd6 100644 --- a/arch/arm/src/armv8-r/arm_dataabort.c +++ b/arch/arm/src/armv8-r/arm_dataabort.c @@ -53,11 +53,14 @@ uint32_t *arm_dataabort(uint32_t *regs, uint32_t dfar, uint32_t dfsr) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); /* Crash -- possibly showing diagnostic debug information. */ diff --git a/arch/arm/src/armv8-r/arm_doirq.c b/arch/arm/src/armv8-r/arm_doirq.c index af47bc641de40..3e654eda68b00 100644 --- a/arch/arm/src/armv8-r/arm_doirq.c +++ b/arch/arm/src/armv8-r/arm_doirq.c @@ -51,7 +51,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) #else /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); /* if irq == GIC_SMP_CPUSTART * We are initiating the multi-core jumping state to up_idle, @@ -65,11 +65,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) tcb->xcp.regs = regs; } - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ + /* Set irq flag */ - up_set_current_regs(regs); + arm_set_irq_flag(true); /* Deliver the IRQ */ @@ -92,11 +90,9 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) regs = tcb->xcp.regs; } - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + arm_set_irq_flag(false); board_autoled_off(LED_INIRQ); #endif diff --git a/arch/arm/src/armv8-r/arm_prefetchabort.c b/arch/arm/src/armv8-r/arm_prefetchabort.c index f5c1b5d368566..a7c6fcd7fc6c6 100644 --- a/arch/arm/src/armv8-r/arm_prefetchabort.c +++ b/arch/arm/src/armv8-r/arm_prefetchabort.c @@ -49,11 +49,14 @@ uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); /* Crash -- possibly showing diagnostic debug information. */ diff --git a/arch/arm/src/armv8-r/arm_syscall.c b/arch/arm/src/armv8-r/arm_syscall.c index ab3f6cae88fb0..58151a79ccd52 100644 --- a/arch/arm/src/armv8-r/arm_syscall.c +++ b/arch/arm/src/armv8-r/arm_syscall.c @@ -165,18 +165,16 @@ uint32_t *arm_syscall(uint32_t *regs) /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); if (*running_task != NULL) { (*running_task)->xcp.regs = regs; } - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ + /* Set irq flag */ - up_set_current_regs(regs); + arm_set_irq_flag(true); /* The SYSCALL command is in R0 on entry. Parameters follow in R1..R7 */ @@ -274,7 +272,7 @@ uint32_t *arm_syscall(uint32_t *regs) */ tcb->xcp.regs = (uint32_t *)regs[REG_R1]; - DEBUGASSERT(up_current_regs()); + DEBUGASSERT(up_interrupt_context()); } break; @@ -584,11 +582,9 @@ uint32_t *arm_syscall(uint32_t *regs) dump_syscall("Exit", cmd, regs); - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + arm_set_irq_flag(false); /* Return the last value of curent_regs. This supports context switches * on return from the exception. That capability is only used with the diff --git a/arch/arm/src/armv8-r/arm_undefinedinsn.c b/arch/arm/src/armv8-r/arm_undefinedinsn.c index 35e13306ed7b4..3d2a1ce27df4f 100644 --- a/arch/arm/src/armv8-r/arm_undefinedinsn.c +++ b/arch/arm/src/armv8-r/arm_undefinedinsn.c @@ -29,6 +29,7 @@ #include #include +#include #include "arm_internal.h" @@ -42,11 +43,14 @@ uint32_t *arm_undefinedinsn(uint32_t *regs) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); if (regs[REG_PC] >= (uint32_t)_stext && regs[REG_PC] < (uint32_t)_etext) { diff --git a/arch/arm/src/common/arm_backtrace_fp.c b/arch/arm/src/common/arm_backtrace_fp.c index c9131e3af1f00..4bf3b3fe6c050 100644 --- a/arch/arm/src/common/arm_backtrace_fp.c +++ b/arch/arm/src/common/arm_backtrace_fp.c @@ -141,8 +141,8 @@ int up_backtrace(struct tcb_s *tcb, { ret += backtrace(rtcb->stack_base_ptr, rtcb->stack_base_ptr + rtcb->adj_stack_size, - (void *)up_current_regs()[REG_FP], - (void *)up_current_regs()[REG_PC], + (void *)((uint32_t *)running_regs())[REG_FP], + (void *)((uint32_t *)running_regs())[REG_PC], &buffer[ret], size - ret, &skip); } } diff --git a/arch/arm/src/common/arm_backtrace_sp.c b/arch/arm/src/common/arm_backtrace_sp.c index 1e8c689fc9212..be96b167d5861 100644 --- a/arch/arm/src/common/arm_backtrace_sp.c +++ b/arch/arm/src/common/arm_backtrace_sp.c @@ -277,7 +277,7 @@ int up_backtrace(struct tcb_s *tcb, ret += backtrace_branch((unsigned long) rtcb->stack_base_ptr + rtcb->adj_stack_size, - up_current_regs()[REG_SP], + ((uint32_t *)running_regs())[REG_SP], &buffer[ret], size - ret, &skip); } diff --git a/arch/arm/src/common/arm_backtrace_unwind.c b/arch/arm/src/common/arm_backtrace_unwind.c index 2c9c1414540a6..e52212bf15d2e 100644 --- a/arch/arm/src/common/arm_backtrace_unwind.c +++ b/arch/arm/src/common/arm_backtrace_unwind.c @@ -743,10 +743,10 @@ int up_backtrace(struct tcb_s *tcb, ret = backtrace_unwind(&frame, buffer, size, &skip); if (ret < size) { - frame.fp = up_current_regs()[REG_FP]; - frame.sp = up_current_regs()[REG_SP]; - frame.pc = up_current_regs()[REG_PC]; - frame.lr = up_current_regs()[REG_LR]; + frame.fp = ((uint32_t *)running_regs())[REG_FP]; + frame.sp = ((uint32_t *)running_regs())[REG_SP]; + frame.pc = ((uint32_t *)running_regs())[REG_PC]; + frame.lr = ((uint32_t *)running_regs())[REG_LR]; frame.stack_base = (unsigned long)rtcb->stack_base_ptr; frame.stack_top = frame.stack_base + rtcb->adj_stack_size; ret += backtrace_unwind(&frame, &buffer[ret], diff --git a/arch/arm/src/common/arm_initialize.c b/arch/arm/src/common/arm_initialize.c index e3b6c295c600a..d7c0b5a257528 100644 --- a/arch/arm/src/common/arm_initialize.c +++ b/arch/arm/src/common/arm_initialize.c @@ -32,15 +32,10 @@ * Public Data ****************************************************************************/ -/* g_current_regs[] holds a references to the current interrupt level - * register storage structure. If is non-NULL only during interrupt - * processing. Access to g_current_regs[] must be through the - * [get/set]_current_regs for portability. - */ - -#if defined(CONFIG_ARCH_ARMV7M) || defined(CONFIG_ARCH_ARMV8M) || \ - defined(CONFIG_ARCH_ARMV6M) || defined(CONFIG_ARCH_ARM) -volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS]; +/* g_interrupt_context store irq status */ + +#if defined(CONFIG_ARCH_ARM) +volatile bool g_interrupt_context[CONFIG_SMP_NCPUS]; #endif /**************************************************************************** diff --git a/arch/arm/src/common/arm_internal.h b/arch/arm/src/common/arm_internal.h index 5b8ee49d4fa00..d0b33748fd83e 100644 --- a/arch/arm/src/common/arm_internal.h +++ b/arch/arm/src/common/arm_internal.h @@ -215,6 +215,10 @@ extern void arm_fullcontextrestore(uint32_t *restoreregs); ****************************************************************************/ #ifndef __ASSEMBLY__ +/* g_interrupt_context store irq status */ + +extern volatile bool g_interrupt_context[CONFIG_SMP_NCPUS]; + typedef void (*up_vector_t)(void); #endif @@ -406,6 +410,14 @@ uint32_t *arm_prefetchabort(uint32_t *regs, uint32_t ifar, uint32_t ifsr); uint32_t *arm_syscall(uint32_t *regs); uint32_t *arm_undefinedinsn(uint32_t *regs); +/* IRQ Flag */ + +noinstrument_function +static inline_function void arm_set_irq_flag(bool flag) +{ + CP15_SET(TPIDRPRW, flag); +} + /* Exception handling logic common to other ARM7 and ARM9 family. */ #else /* ARM7 | ARM9 */ @@ -427,6 +439,18 @@ void arm_prefetchabort(uint32_t *regs); uint32_t *arm_syscall(uint32_t *regs); void arm_undefinedinsn(uint32_t *regs); +/* IRQ Flag */ + +noinstrument_function +static inline_function void arm_set_irq_flag(bool flag) +{ +#ifdef CONFIG_SMP + g_interrupt_context[up_cpu_index()] = flag; +#else + g_interrupt_context[0] = flag; +#endif +} + #endif /* CONFIG_ARCH_ARMV[6-8]M */ void arm_vectorundefinsn(void); diff --git a/arch/arm/src/common/arm_registerdump.c b/arch/arm/src/common/arm_registerdump.c index 2bea5b407e46f..a5c69ef33a581 100644 --- a/arch/arm/src/common/arm_registerdump.c +++ b/arch/arm/src/common/arm_registerdump.c @@ -57,7 +57,7 @@ uintptr_t up_getusrsp(void *regs) void up_dump_register(void *dumpregs) { - volatile uint32_t *regs = dumpregs ? dumpregs : up_current_regs(); + volatile uint32_t *regs = dumpregs ? dumpregs : running_regs(); /* Dump the interrupt registers */ diff --git a/arch/arm/src/dm320/dm320_decodeirq.c b/arch/arm/src/dm320/dm320_decodeirq.c index 3cdec04c059b3..16436bfdd24a5 100644 --- a/arch/arm/src/dm320/dm320_decodeirq.c +++ b/arch/arm/src/dm320/dm320_decodeirq.c @@ -45,7 +45,8 @@ uint32_t *arm_decodeirq(uint32_t *regs) struct tcb_s *tcb = this_task(); #ifdef CONFIG_SUPPRESS_INTERRUPTS - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); err("ERROR: Unexpected IRQ\n"); PANIC(); return NULL; @@ -80,9 +81,12 @@ uint32_t *arm_decodeirq(uint32_t *regs) * Nested interrupts are not supported. */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); tcb->xcp.regs = regs; - up_set_current_regs(regs); + + /* Set irq flag */ + + arm_set_irq_flag(true); /* Deliver the IRQ */ @@ -109,11 +113,9 @@ uint32_t *arm_decodeirq(uint32_t *regs) } #endif - /* Set current_regs to NULL to indicate that we are no longer in - * an interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + arm_set_irq_flag(false); } } #endif diff --git a/arch/arm/src/imx1/imx_decodeirq.c b/arch/arm/src/imx1/imx_decodeirq.c index 43f7c8e1ed45b..b4c3ba116f983 100644 --- a/arch/arm/src/imx1/imx_decodeirq.c +++ b/arch/arm/src/imx1/imx_decodeirq.c @@ -60,7 +60,8 @@ uint32_t *arm_decodeirq(uint32_t *regs) struct tcb_s *tcb = this_task(); #ifdef CONFIG_SUPPRESS_INTERRUPTS - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); err("ERROR: Unexpected IRQ\n"); PANIC(); return NULL; @@ -74,8 +75,11 @@ uint32_t *arm_decodeirq(uint32_t *regs) * Nested interrupts are not supported. */ - DEBUGASSERT(up_current_regs() == NULL); - up_set_current_regs(regs); + DEBUGASSERT(!up_interrupt_context()); + + /* Set irq flag */ + + arm_set_irq_flag(true); tcb->xcp.regs = regs; /* Loop while there are pending interrupts to be processed */ @@ -127,11 +131,9 @@ uint32_t *arm_decodeirq(uint32_t *regs) } while (irq < NR_IRQS); - /* Set current_regs to NULL to indicate that we are no longer in - * an interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + arm_set_irq_flag(false); return NULL; /* Return not used in this architecture */ #endif } diff --git a/arch/arm/src/lpc214x/lpc214x_decodeirq.c b/arch/arm/src/lpc214x/lpc214x_decodeirq.c index 08662be3b5a7a..3916533207ebb 100644 --- a/arch/arm/src/lpc214x/lpc214x_decodeirq.c +++ b/arch/arm/src/lpc214x/lpc214x_decodeirq.c @@ -85,7 +85,8 @@ static uint32_t *lpc214x_decodeirq(uint32_t *regs) struct tcb_s *tcb = this_task(); #ifdef CONFIG_SUPPRESS_INTERRUPTS - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); err("ERROR: Unexpected IRQ\n"); PANIC(); return NULL; @@ -119,15 +120,12 @@ static uint32_t *lpc214x_decodeirq(uint32_t *regs) if (irq < NR_IRQS) { - uint32_t *savestate; + bool savestate; + uint32_t *saveregs; - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context - * switches. - */ - - savestate = up_current_regs(); - up_set_current_regs(regs); + savestate = up_interrupt_context(); + saveregs = tcb->xcp.regs; + arm_set_irq_flag(true); tcb->xcp.regs = regs; /* Deliver the IRQ */ @@ -139,7 +137,8 @@ static uint32_t *lpc214x_decodeirq(uint32_t *regs) * if we are returning from a nested interrupt. */ - up_set_current_regs(savestate); + arm_set_irq_flag(savestate); + tcb->xcp.regs = saveregs; } return NULL; /* Return not used in this architecture */ diff --git a/arch/arm/src/lpc2378/lpc23xx_decodeirq.c b/arch/arm/src/lpc2378/lpc23xx_decodeirq.c index 9a2d253dea86f..21ee4b9ce7379 100644 --- a/arch/arm/src/lpc2378/lpc23xx_decodeirq.c +++ b/arch/arm/src/lpc2378/lpc23xx_decodeirq.c @@ -96,7 +96,9 @@ static uint32_t *lpc23xx_decodeirq(uint32_t *regs) #ifdef CONFIG_SUPPRESS_INTERRUPTS err("ERROR: Unexpected IRQ\n"); - up_set_current_regs(regs); + + tcb->xcp.regs = regs; + arm_set_irq_flag(true); PANIC(); return NULL; #else @@ -118,15 +120,12 @@ static uint32_t *lpc23xx_decodeirq(uint32_t *regs) if (irq < NR_IRQS) /* redundant check ?? */ { - uint32_t *savestate; - - /* Current regs non-zero indicates that we are processing an - * interrupt; current_regs is also used to manage interrupt level - * context switches. - */ + bool savestate; + uint32_t *saveregs; - savestate = up_current_regs(); - up_set_current_regs(regs); + savestate = up_interrupt_context(); + saveregs = tcb->xcp.regs; + arm_set_irq_flag(true); tcb->xcp.regs = regs; /* Acknowledge the interrupt */ @@ -142,7 +141,8 @@ static uint32_t *lpc23xx_decodeirq(uint32_t *regs) * It will be non-NULL if we are returning from a nested interrupt. */ - up_set_current_regs(savestate); + arm_set_irq_flag(savestate); + tcb->xcp.regs = saveregs; } return NULL; /* Return not used in this architecture */ diff --git a/arch/arm/src/lpc31xx/lpc31_decodeirq.c b/arch/arm/src/lpc31xx/lpc31_decodeirq.c index 64e603ce3012b..569a26c328d1e 100644 --- a/arch/arm/src/lpc31xx/lpc31_decodeirq.c +++ b/arch/arm/src/lpc31xx/lpc31_decodeirq.c @@ -46,7 +46,8 @@ uint32_t *arm_decodeirq(uint32_t *regs) struct tcb_s *tcb = this_task(); #ifdef CONFIG_SUPPRESS_INTERRUPTS - up_set_current_regs(regs); + tcb->xcp.regs = regs; + arm_set_irq_flag(true); err("ERROR: Unexpected IRQ\n"); PANIC(); return NULL; @@ -84,8 +85,11 @@ uint32_t *arm_decodeirq(uint32_t *regs) * Nested interrupts are not supported. */ - DEBUGASSERT(up_current_regs() == NULL); - up_set_current_regs(regs); + DEBUGASSERT(!up_interrupt_context()); + + /* Set irq flag */ + + arm_set_irq_flag(true); tcb->xcp.regs = regs; /* Deliver the IRQ */ @@ -113,11 +117,9 @@ uint32_t *arm_decodeirq(uint32_t *regs) } #endif - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Set irq flag */ - up_set_current_regs(NULL); + arm_set_irq_flag(false); } } diff --git a/arch/arm/src/moxart/moxart_irq.c b/arch/arm/src/moxart/moxart_irq.c index 029582c0e0143..da200fed229a7 100644 --- a/arch/arm/src/moxart/moxart_irq.c +++ b/arch/arm/src/moxart/moxart_irq.c @@ -277,12 +277,18 @@ uint32_t *arm_decodeirq(uint32_t *regs) num = ffs(status) - 1; arm_ack_irq(num); - DEBUGASSERT(up_current_regs() == NULL); - up_set_current_regs(regs); + DEBUGASSERT(!up_interrupt_context()); + + /* Set irq flag */ + + arm_set_irq_flag(true); tcb->xcp.regs = regs; irq_dispatch(num, regs); - up_set_current_regs(NULL); + + /* Set irq flag */ + + arm_set_irq_flag(false); return NULL; /* Return not used in this architecture */ } diff --git a/arch/arm/src/str71x/str71x_decodeirq.c b/arch/arm/src/str71x/str71x_decodeirq.c index f3098e76b890c..6f7dd2e9f976f 100644 --- a/arch/arm/src/str71x/str71x_decodeirq.c +++ b/arch/arm/src/str71x/str71x_decodeirq.c @@ -58,7 +58,9 @@ uint32_t *arm_decodeirq(uint32_t *regs) #ifdef CONFIG_SUPPRESS_INTERRUPTS board_autoled_on(LED_INIRQ); - up_set_current_regs(regs); + + tcb->xcp.regs = regs; + arm_set_irq_flag(true); err("ERROR: Unexpected IRQ\n"); PANIC(); return NULL; @@ -76,15 +78,12 @@ uint32_t *arm_decodeirq(uint32_t *regs) if (irq < NR_IRQS) { - uint32_t *savestate; - - /* Current regs non-zero indicates that we are processing an - * interrupt; current_regs is also used to manage interrupt level - * context switches. - */ + bool savestate; + uint32_t *saveregs; - savestate = up_current_regs(); - up_set_current_regs(regs); + savestate = up_interrupt_context(); + saveregs = tcb->xcp.regs; + arm_set_irq_flag(true); tcb->xcp.regs = regs; /* Acknowledge the interrupt */ @@ -100,7 +99,8 @@ uint32_t *arm_decodeirq(uint32_t *regs) * It will be non-NULL if we are returning from a nested interrupt. */ - up_set_current_regs(savestate); + arm_set_irq_flag(savestate); + tcb->xcp.regs = saveregs; } #ifdef CONFIG_DEBUG_FEATURES else diff --git a/arch/arm/src/tlsr82/tc32/tc32_backtrace.c b/arch/arm/src/tlsr82/tc32/tc32_backtrace.c index 5971987b88fae..79f58fd89c9a6 100644 --- a/arch/arm/src/tlsr82/tc32/tc32_backtrace.c +++ b/arch/arm/src/tlsr82/tc32/tc32_backtrace.c @@ -494,10 +494,11 @@ int up_backtrace(struct tcb_s *tcb, void **buffer, int size, int skip) #endif if (ret < size) { - sp = up_current_regs()[REG_SP]; + sp = ((uint32_t *)running_regs())[REG_SP]; ret += backtrace_push(rtcb->stack_base_ptr + rtcb->adj_stack_size, &sp, - (void *)up_current_regs()[REG_PC], + (void *)((uint32_t *) + running_regs())[REG_PC], &buffer[ret], size - ret, &skip); } } diff --git a/arch/arm/src/tlsr82/tc32/tc32_doirq.c b/arch/arm/src/tlsr82/tc32/tc32_doirq.c index 8dd0abb66a2de..fb380bdb8fc1c 100644 --- a/arch/arm/src/tlsr82/tc32/tc32_doirq.c +++ b/arch/arm/src/tlsr82/tc32/tc32_doirq.c @@ -66,13 +66,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) /* Nested interrupts are not supported */ - DEBUGASSERT(up_current_regs() == NULL); - - /* Current regs non-zero indicates that we are processing an interrupt; - * current_regs is also used to manage interrupt level context switches. - */ - - up_set_current_regs(regs); + DEBUGASSERT(!up_interrupt_context()); tcb->xcp.regs = regs; @@ -82,7 +76,7 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) /* Deliver the IRQ */ - irq_dispatch(irq, up_current_regs()); + irq_dispatch(irq, regs); tcb = this_task(); /* If a context switch occurred while processing the interrupt then @@ -96,10 +90,6 @@ uint32_t *arm_doirq(int irq, uint32_t *regs) regs = tcb->xcp.regs; } - /* Update the current_regs to NULL. */ - - up_set_current_regs(NULL); - #endif board_autoled_off(LED_INIRQ); diff --git a/arch/arm/src/tlsr82/tc32/tc32_syscall.c b/arch/arm/src/tlsr82/tc32/tc32_syscall.c index 2ec10f2ae710e..e3733f6e02a53 100644 --- a/arch/arm/src/tlsr82/tc32/tc32_syscall.c +++ b/arch/arm/src/tlsr82/tc32/tc32_syscall.c @@ -51,7 +51,10 @@ void arm_syscall(uint32_t *regs) { + struct tcb_s *tcb = this_task(); + _alert("Syscall from 0x%" PRIx32 "\n", regs[REG_PC]); - up_set_current_regs(regs); + tcb->xcp.regs = regs; + PANIC(); } diff --git a/arch/arm/src/tms570/tms570_esm.c b/arch/arm/src/tms570/tms570_esm.c index 01eb1873a256c..2e7d2494fe184 100644 --- a/arch/arm/src/tms570/tms570_esm.c +++ b/arch/arm/src/tms570/tms570_esm.c @@ -146,16 +146,19 @@ int tms570_esm_initialize(void) int tms570_esm_interrupt(int irq, void *context, void *arg) { + struct tcb_s *tcb = this_task(); + /* Save the saved processor context in current_regs where it can be * accessed for register dumps and possibly context switching. */ - up_set_current_regs((uint32_t *)context); + tcb->xcp.regs = context; + arm_set_irq_flag(true); /* Crash -- possibly showing diagnostic debug information. */ _err("ERROR: ESM Interrupt. PC: %08" PRIx32 "\n", - up_current_regs()[REG_PC]); + ((uint32_t *)running_regs())[REG_PC]); PANIC(); return OK; /* To keep the compiler happy */ } diff --git a/boards/arm/cxd56xx/common/src/cxd56_crashdump.c b/boards/arm/cxd56xx/common/src/cxd56_crashdump.c index e22748a6ab11c..29a2da4be3add 100644 --- a/boards/arm/cxd56xx/common/src/cxd56_crashdump.c +++ b/boards/arm/cxd56xx/common/src/cxd56_crashdump.c @@ -147,7 +147,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, * fault. */ - pdump->info.current_regs = (uintptr_t)up_current_regs(); + pdump->info.current_regs = (uintptr_t)running_regs(); /* Save Context */ @@ -162,7 +162,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, #endif pdump->info.flags |= (REGS_PRESENT | USERSTACK_PRESENT | INTSTACK_PRESENT); - memcpy(pdump->info.regs, up_current_regs(), + memcpy(pdump->info.regs, running_regs(), sizeof(pdump->info.regs)); pdump->info.stacks.user.sp = pdump->info.regs[REG_R13]; } diff --git a/boards/arm/nrf52/nrf52840-dk/src/nrf52_highpri.c b/boards/arm/nrf52/nrf52840-dk/src/nrf52_highpri.c index 26d1b203c2312..0ca7b7c32fad8 100644 --- a/boards/arm/nrf52/nrf52840-dk/src/nrf52_highpri.c +++ b/boards/arm/nrf52/nrf52840-dk/src/nrf52_highpri.c @@ -100,7 +100,7 @@ static struct highpri_s g_highpri; static inline_function bool is_nesting_interrupt(void) { - return up_current_regs() != NULL; + return up_interrupt_context(); } /**************************************************************************** diff --git a/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c b/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c index 8406b9abab327..2d04e959365ef 100644 --- a/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c +++ b/boards/arm/stm32/nucleo-f429zi/src/stm32_bbsram.c @@ -416,7 +416,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, * fault. */ - pdump->info.current_regs = (uintptr_t)up_current_regs(); + pdump->info.current_regs = (uintptr_t)running_regs(); /* Save Context */ @@ -429,7 +429,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, pdump->info.stacks.interrupt.sp = sp; pdump->info.flags |= (REGS_PRESENT | USERSTACK_PRESENT | INTSTACK_PRESENT); - memcpy(pdump->info.regs, up_current_regs(), + memcpy(pdump->info.regs, running_regs(), sizeof(pdump->info.regs)); pdump->info.stacks.user.sp = pdump->info.regs[REG_R13]; } diff --git a/boards/arm/stm32/viewtool-stm32f107/src/stm32_highpri.c b/boards/arm/stm32/viewtool-stm32f107/src/stm32_highpri.c index d7bd9a663bc8b..c647f70e5bafe 100644 --- a/boards/arm/stm32/viewtool-stm32f107/src/stm32_highpri.c +++ b/boards/arm/stm32/viewtool-stm32f107/src/stm32_highpri.c @@ -107,7 +107,7 @@ static struct highpri_s g_highpri; static inline_function bool is_nesting_interrupt(void) { - return up_current_regs() != NULL; + return up_interrupt_context(); } /**************************************************************************** diff --git a/boards/arm/stm32f7/nucleo-f722ze/src/stm32_bbsram.c b/boards/arm/stm32f7/nucleo-f722ze/src/stm32_bbsram.c index f20520848b576..420fa994ebd06 100644 --- a/boards/arm/stm32f7/nucleo-f722ze/src/stm32_bbsram.c +++ b/boards/arm/stm32f7/nucleo-f722ze/src/stm32_bbsram.c @@ -416,7 +416,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, * fault. */ - pdump->info.current_regs = (uintptr_t)up_current_regs(); + pdump->info.current_regs = (uintptr_t)running_regs(); /* Save Context */ @@ -429,7 +429,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, pdump->info.stacks.interrupt.sp = sp; pdump->info.flags |= (REGS_PRESENT | USERSTACK_PRESENT | INTSTACK_PRESENT); - memcpy(pdump->info.regs, up_current_regs(), + memcpy(pdump->info.regs, running_regs(), sizeof(pdump->info.regs)); pdump->info.stacks.user.sp = pdump->info.regs[REG_R13]; } diff --git a/boards/arm/stm32f7/nucleo-f746zg/src/stm32_bbsram.c b/boards/arm/stm32f7/nucleo-f746zg/src/stm32_bbsram.c index 4bc556fd8b472..3802516d8fb86 100644 --- a/boards/arm/stm32f7/nucleo-f746zg/src/stm32_bbsram.c +++ b/boards/arm/stm32f7/nucleo-f746zg/src/stm32_bbsram.c @@ -416,7 +416,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, * fault. */ - pdump->info.current_regs = (uintptr_t)up_current_regs(); + pdump->info.current_regs = (uintptr_t)running_regs(); /* Save Context */ @@ -429,7 +429,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, pdump->info.stacks.interrupt.sp = sp; pdump->info.flags |= (REGS_PRESENT | USERSTACK_PRESENT | INTSTACK_PRESENT); - memcpy(pdump->info.regs, up_current_regs(), + memcpy(pdump->info.regs, running_regs(), sizeof(pdump->info.regs)); pdump->info.stacks.user.sp = pdump->info.regs[REG_R13]; } diff --git a/boards/arm/stm32f7/nucleo-f767zi/src/stm32_bbsram.c b/boards/arm/stm32f7/nucleo-f767zi/src/stm32_bbsram.c index e3e62257ecd34..4cc1143c38e8e 100644 --- a/boards/arm/stm32f7/nucleo-f767zi/src/stm32_bbsram.c +++ b/boards/arm/stm32f7/nucleo-f767zi/src/stm32_bbsram.c @@ -416,7 +416,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, * fault. */ - pdump->info.current_regs = (uintptr_t)up_current_regs(); + pdump->info.current_regs = (uintptr_t)running_regs(); /* Save Context */ @@ -429,7 +429,7 @@ void board_crashdump(uintptr_t sp, struct tcb_s *tcb, pdump->info.stacks.interrupt.sp = sp; pdump->info.flags |= (REGS_PRESENT | USERSTACK_PRESENT | INTSTACK_PRESENT); - memcpy(pdump->info.regs, up_current_regs(), + memcpy(pdump->info.regs, running_regs(), sizeof(pdump->info.regs)); pdump->info.stacks.user.sp = pdump->info.regs[REG_R13]; }