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 9367f3ec28021..09d7e5b1783d2 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 afdf5615520b3..62425feddbfb1 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 3f1d23e2b97e6..fef41b769af59 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 12470257a6941..3c404d13666eb 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 ab8ec421c5d5b..9214c439eaf3a 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 62962399c5d5c..6f49b40a2aaee 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 f82101e35238d..78322f911e4a8 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 4e5760695337f..75913b445af6a 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)