summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
authorShell <[email protected]>2024-05-28 14:27:55 +0800
committerGitHub <[email protected]>2024-05-28 14:27:55 +0800
commitf17f994f8c85a0ca58d42c81a14f1134af6ada91 (patch)
tree49cb8514b38fc30884553e6b572c873a09f6935c /libcpu
parentb45fb59df2a7d938965c241431436adf77769b5b (diff)
[arm64] add hw thread self (#8942)
* [libcpu] arm64: Add hardware thread_self support This patch introduces hardware-based thread self-identification for the AArch64 architecture. It optimizes thread management by using hardware registers to store and access the current thread's pointer, reducing overhead and improving overall performance. Changes include: - Added `ARCH_USING_HW_THREAD_SELF` configuration option. - Modified `rtdef.h`, `rtsched.h` to conditionally include `critical_switch_flag` based on the new config. - Updated context management in `context_gcc.S`, `cpuport.h` to support hardware-based thread self. - Enhanced `scheduler_mp.c` and `thread.c` to leverage the new hardware thread self feature. These modifications ensure better scheduling and thread handling, particularly in multi-core environments, by minimizing the software overhead associated with thread management. Signed-off-by: Shell <[email protected]> * fixup: address suggestion * fixup: rt_current_thread as global * scheduler: add cpu object for UP scheduler Also, maintain the rt_current_thread in cpu object on UP scheduler. --------- Signed-off-by: Shell <[email protected]>
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/Kconfig6
-rw-r--r--libcpu/aarch64/common/context_gcc.S33
-rw-r--r--libcpu/aarch64/common/cpu.c18
-rw-r--r--libcpu/aarch64/common/cpuport.h42
-rw-r--r--libcpu/aarch64/cortex-a/entry_point.S12
5 files changed, 76 insertions, 35 deletions
diff --git a/libcpu/Kconfig b/libcpu/Kconfig
index 540794c43f..8c211de236 100644
--- a/libcpu/Kconfig
+++ b/libcpu/Kconfig
@@ -14,6 +14,8 @@ if ARCH_ARMV8 && ARCH_CPU_64BIT
default y
config ARCH_USING_GENERIC_CPUID
bool "Using generic cpuid implemenation"
+ select ARCH_USING_HW_THREAD_SELF
+ default y if RT_USING_OFW
default n
endmenu
endif
@@ -270,3 +272,7 @@ config ARCH_HOST_SIMULATOR
config ARCH_CPU_STACK_GROWS_UPWARD
bool
default n
+
+config ARCH_USING_HW_THREAD_SELF
+ bool
+ default n
diff --git a/libcpu/aarch64/common/context_gcc.S b/libcpu/aarch64/common/context_gcc.S
index f27144b764..9399467935 100644
--- a/libcpu/aarch64/common/context_gcc.S
+++ b/libcpu/aarch64/common/context_gcc.S
@@ -8,6 +8,7 @@
* 2021-05-18 Jesven the first version
* 2023-06-24 WangXiaoyao Support backtrace for user thread
* 2024-01-06 Shell Fix barrier on irq_disable/enable
+ * 2024-01-18 Shell fix implicit dependency of cpuid management
*/
#ifndef __ASSEMBLY__
@@ -27,15 +28,35 @@ rt_thread_switch_interrupt_flag: .zero 8
#endif
.text
-.weak rt_hw_cpu_id_set
+
+/**
+ * #ifdef RT_USING_OFW
+ * void rt_hw_cpu_id_set(long cpuid)
+ * #else
+ * void rt_hw_cpu_id_set(void)
+ * #endif
+ */
.type rt_hw_cpu_id_set, @function
rt_hw_cpu_id_set:
- mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */
+#ifdef ARCH_USING_GENERIC_CPUID
+ .globl rt_hw_cpu_id_set
+#else /* !ARCH_USING_GENERIC_CPUID */
+ .weak rt_hw_cpu_id_set
+#endif /* ARCH_USING_GENERIC_CPUID */
+
+#ifndef RT_USING_OFW
+ mrs x0, mpidr_el1 /* MPIDR_EL1: Multi-Processor Affinity Register */
#ifdef ARCH_ARM_CORTEX_A55
- lsr x0, x0, #8
-#endif
- and x0, x0, #15
- msr tpidr_el1, x0
+ lsr x0, x0, #8
+#endif /* ARCH_ARM_CORTEX_A55 */
+ and x0, x0, #15
+#endif /* !RT_USING_OFW */
+
+#ifdef ARCH_USING_HW_THREAD_SELF
+ msr tpidrro_el0, x0
+#else /* !ARCH_USING_HW_THREAD_SELF */
+ msr tpidr_el1, x0
+#endif /* ARCH_USING_HW_THREAD_SELF */
ret
/*
diff --git a/libcpu/aarch64/common/cpu.c b/libcpu/aarch64/common/cpu.c
index 72ccccac24..b9fedefdd3 100644
--- a/libcpu/aarch64/common/cpu.c
+++ b/libcpu/aarch64/common/cpu.c
@@ -232,6 +232,24 @@ int rt_hw_cpu_boot_secondary(int num_cpus, rt_uint64_t *cpu_hw_ids, struct cpu_o
#endif /*RT_USING_SMP*/
/**
+ * Generic hw-cpu-id
+ */
+#ifdef ARCH_USING_GENERIC_CPUID
+
+int rt_hw_cpu_id(void)
+{
+#if RT_CPUS_NR > 1
+ long cpuid;
+ __asm__ volatile("mrs %0, tpidrro_el0":"=r"(cpuid));
+ return cpuid;
+#else
+ return 0;
+#endif /* RT_CPUS_NR > 1 */
+}
+
+#endif /* ARCH_USING_GENERIC_CPUID */
+
+/**
* @addtogroup ARM CPU
*/
/*@{*/
diff --git a/libcpu/aarch64/common/cpuport.h b/libcpu/aarch64/common/cpuport.h
index 15500894db..217f477aaf 100644
--- a/libcpu/aarch64/common/cpuport.h
+++ b/libcpu/aarch64/common/cpuport.h
@@ -7,6 +7,7 @@
* Date Author Notes
* 2023-10-25 Shell Move ffs to cpuport, add general implementation
* by inline assembly
+ * 2024-01-18 Shell support rt_hw_thread_self to improve overall performance
*/
#ifndef CPUPORT_H__
@@ -27,31 +28,6 @@ typedef struct
rt_uint32_t value;
} rt_hw_spinlock_t;
-/**
- * Generic hw-cpu-id
- */
-#ifdef ARCH_USING_GENERIC_CPUID
-
-#if RT_CPUS_NR > 1
-
-rt_inline int rt_hw_cpu_id(void)
-{
- long cpuid;
- __asm__ volatile("mrs %0, tpidr_el1":"=r"(cpuid));
- return cpuid;
-}
-
-#else
-
-rt_inline int rt_hw_cpu_id(void)
-{
- return 0;
-}
-
-#endif /* RT_CPUS_NR > 1 */
-
-#endif /* ARCH_USING_GENERIC_CPUID */
-
#endif /* RT_USING_SMP */
#define rt_hw_barrier(cmd, ...) \
@@ -107,4 +83,20 @@ rt_inline int __rt_ffs(int value)
#endif /* RT_USING_CPU_FFS */
+#ifdef ARCH_USING_HW_THREAD_SELF
+rt_inline struct rt_thread *rt_hw_thread_self(void)
+{
+ struct rt_thread *thread;
+ __asm__ volatile ("mrs %0, tpidr_el1":"=r"(thread));
+
+ return thread;
+}
+
+rt_inline void rt_hw_thread_set_self(struct rt_thread *thread)
+{
+ __asm__ volatile ("msr tpidr_el1, %0"::"r"(thread));
+}
+
+#endif /* ARCH_USING_HW_THREAD_SELF */
+
#endif /*CPUPORT_H__*/
diff --git a/libcpu/aarch64/cortex-a/entry_point.S b/libcpu/aarch64/cortex-a/entry_point.S
index 361c9d4f67..315e331aac 100644
--- a/libcpu/aarch64/cortex-a/entry_point.S
+++ b/libcpu/aarch64/cortex-a/entry_point.S
@@ -7,6 +7,7 @@
* 2020-01-15 bigmagic the first version
* 2020-08-10 SummerGift support clang compiler
* 2023-04-29 GuEe-GUI support kernel's ARM64 boot header
+ * 2024-01-18 Shell fix implicit dependency of cpuid management
*/
#ifndef __ASSEMBLY__
@@ -95,6 +96,10 @@ _start:
/* Save cpu stack */
get_phy stack_top, .boot_cpu_stack_top
/* Save cpu id temp */
+#ifdef ARCH_USING_HW_THREAD_SELF
+ msr tpidrro_el0, xzr
+ /* Save thread self */
+#endif /* ARCH_USING_HW_THREAD_SELF */
msr tpidr_el1, xzr
bl init_cpu_el
@@ -149,11 +154,10 @@ _secondary_cpu_entry:
/* Get cpu id success */
sub x0, x2, #1
- msr tpidr_el1, x0 /* Save cpu id global */
-#else
- bl rt_hw_cpu_id_set
- mrs x0, tpidr_el1
#endif /* RT_USING_OFW */
+ /* Save cpu id global */
+ bl rt_hw_cpu_id_set
+ bl rt_hw_cpu_id
/* Set current cpu's stack top */
sub x0, x0, #1