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 <ycsin@meta.com>
Signed-off-by: Yong Cong Sin <yongcong.sin@gmail.com>
This commit is contained in:
Yong Cong Sin 2024-11-01 12:12:41 +08:00 committed by Anas Nashif
commit 1a752e8a35
3 changed files with 25 additions and 0 deletions

View file

@ -28,6 +28,16 @@ config RISCV_GP
global pointer at program start or earlier than any instruction global pointer at program start or earlier than any instruction
using GP relative addressing. 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 config RISCV_ALWAYS_SWITCH_THROUGH_ECALL
bool "Do not use mret outside a trap handler context" bool "Do not use mret outside a trap handler context"
depends on MULTITHREADING depends on MULTITHREADING

View file

@ -52,6 +52,9 @@ Architectures
* RISC-V * 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 * Xtensa
* native/POSIX * native/POSIX

View file

@ -11,6 +11,7 @@
#include <zephyr/kernel_structs.h> #include <zephyr/kernel_structs.h>
#include "csr.h" #include "csr.h"
#include "reg.h"
static ALWAYS_INLINE uint32_t arch_proc_id(void) static ALWAYS_INLINE uint32_t arch_proc_id(void)
{ {
@ -26,6 +27,17 @@ static ALWAYS_INLINE _cpu_t *arch_curr_cpu(void)
#endif #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) static ALWAYS_INLINE unsigned int arch_num_cpus(void)
{ {
return CONFIG_MP_MAX_NUM_CPUS; return CONFIG_MP_MAX_NUM_CPUS;