From 1e49cb4828f3cdb26252eab3e68f7ca9962bc8ba Mon Sep 17 00:00:00 2001 From: hujun5 Date: Thu, 5 Dec 2024 16:58:17 +0800 Subject: [PATCH] armv7-a/armv7-r/armv8-r: percpu reg store this_task This is continue work of https://github.com/apache/nuttx/pull/13726 We can utilize percpu storage to hold information about the current running task. If we intend to implement this feature, we would need to define two macros that help us manage this percpu information effectively. up_this_task: This macro is designed to read the contents of the percpu register to retrieve information about the current running task.This allows us to quickly access task-specific data without having to disable interrupts, access global variables and obtain the current cpu index. up_update_task: This macro is responsible for updating the contents of the percpu register.It is typically called during initialization or when a context switch occurs to ensure that the percpu register reflects the information of the newly running task. Signed-off-by: hujun5 --- arch/arm/include/armv7-a/cp15.h | 2 ++ arch/arm/include/armv7-a/irq.h | 12 +++++------- arch/arm/include/armv7-r/cp15.h | 2 ++ arch/arm/include/armv7-r/irq.h | 12 +++++------- arch/arm/include/armv8-r/cp15.h | 2 ++ arch/arm/include/armv8-r/irq.h | 12 +++++------- arch/arm/src/armv7-a/arm_scu.c | 9 +++++++++ arch/arm/src/armv7-r/arm_scu.c | 9 +++++++++ 8 files changed, 39 insertions(+), 21 deletions(-) diff --git a/arch/arm/include/armv7-a/cp15.h b/arch/arm/include/armv7-a/cp15.h index 9367f3ec28..09d7e5b178 100644 --- a/arch/arm/include/armv7-a/cp15.h +++ b/arch/arm/include/armv7-a/cp15.h @@ -275,4 +275,6 @@ value; \ }) \ +#define CP15_MODIFY(v,m,a) CP15_SET(a, ((CP15_GET(a) & ~(m)) | ((uintptr_t)(v) & (m)))) + #endif /* __ARCH_ARM_SRC_ARMV7_A_CP15_H */ diff --git a/arch/arm/include/armv7-a/irq.h b/arch/arm/include/armv7-a/irq.h index afdf561552..62425feddb 100644 --- a/arch/arm/include/armv7-a/irq.h +++ b/arch/arm/include/armv7-a/irq.h @@ -472,18 +472,16 @@ static inline_function uint32_t up_getsp(void) return sp; } -noinstrument_function -static inline_function bool up_interrupt_context(void) -{ - return (bool)CP15_GET(TPIDRPRW); -} - noinstrument_function static inline_function void up_set_interrupt_context(bool flag) { - CP15_SET(TPIDRPRW, flag); + CP15_MODIFY(flag, 1ul, TPIDRPRW); } +#define up_this_task() ((struct tcb_s *)(CP15_GET(TPIDRPRW) & ~1ul)) +#define up_update_task(t) CP15_MODIFY(t, ~1ul, TPIDRPRW) +#define up_interrupt_context() (CP15_GET(TPIDRPRW) & 1) + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/arch/arm/include/armv7-r/cp15.h b/arch/arm/include/armv7-r/cp15.h index 3f1d23e2b9..fef41b769a 100644 --- a/arch/arm/include/armv7-r/cp15.h +++ b/arch/arm/include/armv7-r/cp15.h @@ -218,4 +218,6 @@ value; \ }) \ +#define CP15_MODIFY(v,m,a) CP15_SET(a, ((CP15_GET(a) & ~(m)) | ((uintptr_t)(v) & (m)))) + #endif /* __ARCH_ARM_SRC_ARMV7_R_CP15_H */ diff --git a/arch/arm/include/armv7-r/irq.h b/arch/arm/include/armv7-r/irq.h index 12470257a6..3c404d1366 100644 --- a/arch/arm/include/armv7-r/irq.h +++ b/arch/arm/include/armv7-r/irq.h @@ -467,18 +467,16 @@ static inline_function uint32_t up_getsp(void) return sp; } -noinstrument_function -static inline_function bool up_interrupt_context(void) -{ - return (bool)CP15_GET(TPIDRPRW); -} - noinstrument_function static inline_function void up_set_interrupt_context(bool flag) { - CP15_SET(TPIDRPRW, flag); + CP15_MODIFY(flag, 1ul, TPIDRPRW); } +#define up_this_task() ((struct tcb_s *)(CP15_GET(TPIDRPRW) & ~1ul)) +#define up_update_task(t) CP15_MODIFY(t, ~1ul, TPIDRPRW) +#define up_interrupt_context() (CP15_GET(TPIDRPRW) & 1) + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/arch/arm/include/armv8-r/cp15.h b/arch/arm/include/armv8-r/cp15.h index ab8ec421c5..9214c439ea 100644 --- a/arch/arm/include/armv8-r/cp15.h +++ b/arch/arm/include/armv8-r/cp15.h @@ -237,4 +237,6 @@ _value; \ }) \ +#define CP15_MODIFY(v,m,a) CP15_SET(a, ((CP15_GET(a) & ~(m)) | ((uintptr_t)(v) & (m)))) + #endif /* __ARCH_ARM_SRC_ARMV8_R_CP15_H */ diff --git a/arch/arm/include/armv8-r/irq.h b/arch/arm/include/armv8-r/irq.h index 62962399c5..6f49b40a2a 100644 --- a/arch/arm/include/armv8-r/irq.h +++ b/arch/arm/include/armv8-r/irq.h @@ -467,18 +467,16 @@ static inline_function uint32_t up_getsp(void) return sp; } -noinstrument_function -static inline_function bool up_interrupt_context(void) -{ - return (bool)CP15_GET(TPIDRPRW); -} - noinstrument_function static inline_function void up_set_interrupt_context(bool flag) { - CP15_SET(TPIDRPRW, flag); + CP15_MODIFY(flag, 1ul, TPIDRPRW); } +#define up_this_task() ((struct tcb_s *)(CP15_GET(TPIDRPRW) & ~1ul)) +#define up_update_task(t) CP15_MODIFY(t, ~1ul, TPIDRPRW) +#define up_interrupt_context() (CP15_GET(TPIDRPRW) & 1) + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/arch/arm/src/armv7-a/arm_scu.c b/arch/arm/src/armv7-a/arm_scu.c index f82101e352..78322f911e 100644 --- a/arch/arm/src/armv7-a/arm_scu.c +++ b/arch/arm/src/armv7-a/arm_scu.c @@ -29,6 +29,7 @@ #include #include +#include #include "arm_internal.h" #include "cp15_cacheops.h" @@ -57,6 +58,14 @@ void arm_enable_smp(int cpu) { uint32_t regval; + /* We need to confirm that current_task has been initialized. */ + + while (!current_task(this_cpu())); + + /* Init idle task to percpu reg */ + + up_update_task(current_task(cpu)); + /* Handle actions unique to CPU0 which comes up first */ if (cpu == 0) diff --git a/arch/arm/src/armv7-r/arm_scu.c b/arch/arm/src/armv7-r/arm_scu.c index 4e57606953..75913b445a 100644 --- a/arch/arm/src/armv7-r/arm_scu.c +++ b/arch/arm/src/armv7-r/arm_scu.c @@ -29,6 +29,7 @@ #include #include +#include #include "arm_internal.h" #include "cp15_cacheops.h" @@ -57,6 +58,14 @@ void arm_enable_smp(int cpu) { uint32_t regval; + /* We need to confirm that current_task has been initialized. */ + + while (!current_task(this_cpu())); + + /* Init idle task to percpu reg */ + + up_update_task(current_task(cpu)); + /* Handle actions unique to CPU0 which comes up first */ if (cpu == 0)