From 1a752e8a3542206385b017f91a92297f59749cdf Mon Sep 17 00:00:00 2001 From: Yong Cong Sin Date: Fri, 1 Nov 2024 12:12:41 +0800 Subject: [PATCH] arch: riscv: implement ARCH_HAS_CUSTOM_CURRENT_IMPL with GP Implement `arch_curr_thread()` & `arch_set_curr_thread()` with the global pointer (GP) register. Signed-off-by: Yong Cong Sin Signed-off-by: Yong Cong Sin --- arch/riscv/Kconfig | 10 ++++++++++ doc/releases/release-notes-4.1.rst | 3 +++ include/zephyr/arch/riscv/arch_inlines.h | 12 ++++++++++++ 3 files changed, 25 insertions(+) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 7314a1923e2..f62bb34d147 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -28,6 +28,16 @@ config RISCV_GP global pointer at program start or earlier than any instruction using GP relative addressing. +config RISCV_CURRENT_VIA_GP + bool "Store current thread into the global pointer (GP) register" + depends on !RISCV_GP && !USERSPACE + depends on MP_MAX_NUM_CPUS > 1 + select ARCH_HAS_CUSTOM_CURRENT_IMPL + help + Store the current thread's pointer into the global pointer (GP) register. + When is enabled, calls to `_current` & `k_sched_current_thread_query()` will + be reduced to a single register read. + config RISCV_ALWAYS_SWITCH_THROUGH_ECALL bool "Do not use mret outside a trap handler context" depends on MULTITHREADING diff --git a/doc/releases/release-notes-4.1.rst b/doc/releases/release-notes-4.1.rst index bb52564d168..256afc0392a 100644 --- a/doc/releases/release-notes-4.1.rst +++ b/doc/releases/release-notes-4.1.rst @@ -52,6 +52,9 @@ Architectures * RISC-V + * Implements :c:func:`arch_current_thread_set` & :c:func:`arch_current_thread`, which can be enabled + by :kconfig:option:`CONFIG_RISCV_CURRENT_VIA_GP` (:github:`80716`). + * Xtensa * native/POSIX diff --git a/include/zephyr/arch/riscv/arch_inlines.h b/include/zephyr/arch/riscv/arch_inlines.h index 36dc2e640f9..b779ebf3ace 100644 --- a/include/zephyr/arch/riscv/arch_inlines.h +++ b/include/zephyr/arch/riscv/arch_inlines.h @@ -11,6 +11,7 @@ #include #include "csr.h" +#include "reg.h" static ALWAYS_INLINE uint32_t arch_proc_id(void) { @@ -26,6 +27,17 @@ static ALWAYS_INLINE _cpu_t *arch_curr_cpu(void) #endif } +#ifdef CONFIG_RISCV_CURRENT_VIA_GP +register struct k_thread *__arch_current_thread __asm__("gp"); + +#define arch_current_thread() __arch_current_thread +#define arch_current_thread_set(thread) \ + { \ + _current_cpu->current = thread; \ + __arch_current_thread = (thread); \ + } +#endif /* CONFIG_RISCV_CURRENT_VIA_GP */ + static ALWAYS_INLINE unsigned int arch_num_cpus(void) { return CONFIG_MP_MAX_NUM_CPUS;