This is an automated email from the ASF dual-hosted git repository. ligd pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 948ac9b4cc4407120b671c5237dd7ff64b37e94e Author: hujun5 <[email protected]> AuthorDate: Tue Jul 23 21:11:45 2024 +0800 arm64: add up_this_task and up_change_task macro impl Signed-off-by: hujun5 <[email protected]> --- arch/arm64/include/arch.h | 6 ++++- arch/arm64/include/irq.h | 43 ++++++------------------------ arch/arm64/src/common/arm64_cpustart.c | 6 ++++- arch/arm64/src/common/arm64_doirq.c | 15 +++++------ arch/arm64/src/common/arm64_fatal.c | 15 ++++++----- arch/arm64/src/common/arm64_registerdump.c | 1 + 6 files changed, 34 insertions(+), 52 deletions(-) diff --git a/arch/arm64/include/arch.h b/arch/arm64/include/arch.h index 157169cea9..2e39948a04 100644 --- a/arch/arm64/include/arch.h +++ b/arch/arm64/include/arch.h @@ -55,7 +55,7 @@ /**************************************************************************** * Name: - * read_/write_/zero_ sysreg + * read_/write_/zero_/modify_ sysreg * * Description: * @@ -84,6 +84,10 @@ ::: "memory"); \ }) +#define modify_sysreg(v,m,a) \ + write_sysreg((read_sysreg(a) & ~(m)) | \ + ((uintptr_t)(v) & (m)), a) + /**************************************************************************** * Inline functions ****************************************************************************/ diff --git a/arch/arm64/include/irq.h b/arch/arm64/include/irq.h index dbb8a11a20..aad83b14e9 100644 --- a/arch/arm64/include/irq.h +++ b/arch/arm64/include/irq.h @@ -387,31 +387,17 @@ static inline void up_irq_restore(irqstate_t flags) #endif /* CONFIG_ARCH_HAVE_MULTICPU */ /**************************************************************************** - * Name: - * up_current_regs/up_set_current_regs - * - * Description: - * We use the following code to manipulate the tpidr_el1 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. + * Schedule acceleration macros * + * The lsbit of tpidr_el1 stores information about whether the current + * execution is in an interrupt context, where 1 indicates being in an + * interrupt context and 0 indicates being in a thread context. ****************************************************************************/ -noinstrument_function -static inline_function uint64_t *up_current_regs(void) -{ - uint64_t *regs; - __asm__ volatile ("mrs %0, " "tpidr_el1" : "=r" (regs)); - return regs; -} - -noinstrument_function -static inline_function void up_set_current_regs(uint64_t *regs) -{ - __asm__ volatile ("msr " "tpidr_el1" ", %0" : : "r" (regs)); -} +#define up_current_regs() (this_task()->xcp.regs) +#define up_this_task() ((struct tcb_s *)(read_sysreg(tpidr_el1) & ~1ul)) +#define up_update_task(t) modify_sysreg(t, ~1ul, tpidr_el1) +#define up_interrupt_context() (read_sysreg(tpidr_el1) & 1) #define up_switch_context(tcb, rtcb) \ do { \ @@ -422,19 +408,6 @@ static inline_function void up_set_current_regs(uint64_t *regs) } \ } while (0) -/**************************************************************************** - * Name: up_interrupt_context - * - * Description: Return true is we are currently executing in - * the interrupt handler context. - * - ****************************************************************************/ - -static inline bool up_interrupt_context(void) -{ - return up_current_regs() != NULL; -} - /**************************************************************************** * Name: up_getusrpc ****************************************************************************/ diff --git a/arch/arm64/src/common/arm64_cpustart.c b/arch/arm64/src/common/arm64_cpustart.c index 46f9b72151..fcc9a41b18 100644 --- a/arch/arm64/src/common/arm64_cpustart.c +++ b/arch/arm64/src/common/arm64_cpustart.c @@ -113,7 +113,11 @@ static inline void local_delay(void) static void arm64_smp_init_top(void) { - struct tcb_s *tcb = this_task(); + struct tcb_s *tcb = current_task(this_cpu()); + + /* Init idle task to percpu reg */ + + up_update_task(tcb); #ifndef CONFIG_SUPPRESS_INTERRUPTS /* And finally, enable interrupts */ diff --git a/arch/arm64/src/common/arm64_doirq.c b/arch/arm64/src/common/arm64_doirq.c index 9806c2c41c..499b2ab3e4 100644 --- a/arch/arm64/src/common/arm64_doirq.c +++ b/arch/arm64/src/common/arm64_doirq.c @@ -61,13 +61,12 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs) /* 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 */ + + write_sysreg((uintptr_t)tcb | 1, tpidr_el1); - up_set_current_regs(regs); tcb->xcp.regs = regs; /* Deliver the IRQ */ @@ -110,11 +109,9 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs) regs = tcb->xcp.regs; } - /* Set current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ + /* Clear irq flag */ - up_set_current_regs(NULL); + write_sysreg((uintptr_t)tcb & ~1ul, tpidr_el1); return regs; } diff --git a/arch/arm64/src/common/arm64_fatal.c b/arch/arm64/src/common/arm64_fatal.c index 997fe7f675..3e779ba35a 100644 --- a/arch/arm64/src/common/arm64_fatal.c +++ b/arch/arm64/src/common/arm64_fatal.c @@ -541,13 +541,18 @@ static int arm64_exception_handler(uint64_t *regs) void arm64_fatal_handler(uint64_t *regs) { + struct tcb_s *tcb = this_task(); int ret; /* Nested exception are not supported */ - DEBUGASSERT(up_current_regs() == NULL); + DEBUGASSERT(!up_interrupt_context()); - up_set_current_regs((uint64_t *)regs); + tcb->xcp.regs = (uint64_t *)regs; + + /* Set irq flag */ + + write_sysreg((uintptr_t)tcb | 1, tpidr_el1); ret = arm64_exception_handler(regs); @@ -558,11 +563,9 @@ void arm64_fatal_handler(uint64_t *regs) PANIC_WITH_REGS("panic", regs); } - /* Set CURRENT_REGS to NULL to indicate that we are no longer in an - * Exception handler. - */ + /* Clear irq flag */ - up_set_current_regs(NULL); + write_sysreg((uintptr_t)tcb & ~1ul, tpidr_el1); } void arm64_register_debug_hook(int nr, fatal_handle_func_t fn) diff --git a/arch/arm64/src/common/arm64_registerdump.c b/arch/arm64/src/common/arm64_registerdump.c index 2b0be8d908..d19dbd704e 100644 --- a/arch/arm64/src/common/arm64_registerdump.c +++ b/arch/arm64/src/common/arm64_registerdump.c @@ -31,6 +31,7 @@ #include <nuttx/arch.h> #include <nuttx/irq.h> +#include "sched/sched.h" #include "arm64_arch.h" #include "arm64_internal.h" #include "chip.h"
