From f623571a735f02d3bfd61aa6168c8e02eef9d7de Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 19 Apr 2022 17:33:03 -0700 Subject: [PATCH] riscv: Initialize TP register when starting threads Set TP in exception context so that it gets loaded into the CPU when first running the thread. Set TP for secondary cores to related idle TLS area. Signed-off-by: Keith Packard --- arch/riscv/core/fatal.c | 1 + arch/riscv/core/isr.S | 1 + arch/riscv/core/offsets/offsets.c | 2 ++ arch/riscv/core/smp.c | 3 +++ arch/riscv/core/thread.c | 5 +++++ include/zephyr/arch/riscv/exp.h | 1 + 6 files changed, 13 insertions(+) diff --git a/arch/riscv/core/fatal.c b/arch/riscv/core/fatal.c index f3283e46acc..9b02f9d9afa 100644 --- a/arch/riscv/core/fatal.c +++ b/arch/riscv/core/fatal.c @@ -42,6 +42,7 @@ FUNC_NORETURN void z_riscv_fatal_error(unsigned int reason, #ifdef CONFIG_USERSPACE LOG_ERR(" sp: " PR_REG, esf->sp); #endif + LOG_ERR(" tp: " PR_REG, esf->tp); LOG_ERR(" ra: " PR_REG, esf->ra); LOG_ERR(" mepc: " PR_REG, esf->mepc); LOG_ERR("mstatus: " PR_REG, esf->mstatus); diff --git a/arch/riscv/core/isr.S b/arch/riscv/core/isr.S index 75a6cf8e0f0..62bd429b21d 100644 --- a/arch/riscv/core/isr.S +++ b/arch/riscv/core/isr.S @@ -59,6 +59,7 @@ op a5, __z_arch_esf_t_a5_OFFSET(sp) ;\ op a6, __z_arch_esf_t_a6_OFFSET(sp) ;\ op a7, __z_arch_esf_t_a7_OFFSET(sp) ;\ + op tp, __z_arch_esf_t_tp_OFFSET(sp) ;\ op ra, __z_arch_esf_t_ra_OFFSET(sp) #ifdef CONFIG_SMP diff --git a/arch/riscv/core/offsets/offsets.c b/arch/riscv/core/offsets/offsets.c index 1cfbf9b58d1..9f14e264a51 100644 --- a/arch/riscv/core/offsets/offsets.c +++ b/arch/riscv/core/offsets/offsets.c @@ -81,6 +81,8 @@ GEN_OFFSET_SYM(z_arch_esf_t, mstatus); GEN_OFFSET_SYM(z_arch_esf_t, s0); +GEN_OFFSET_SYM(z_arch_esf_t, tp); + #ifdef CONFIG_USERSPACE GEN_OFFSET_SYM(z_arch_esf_t, sp); #endif diff --git a/arch/riscv/core/smp.c b/arch/riscv/core/smp.c index 22ed3d00fa1..dcc20b742e0 100644 --- a/arch/riscv/core/smp.c +++ b/arch/riscv/core/smp.c @@ -40,6 +40,9 @@ void z_riscv_secondary_cpu_init(int cpu_num) #endif #ifdef CONFIG_SMP irq_enable(RISCV_MACHINE_SOFT_IRQ); +#endif +#ifdef CONFIG_THREAD_LOCAL_STORAGE + __asm__("mv tp, %0" : : "r" (z_idle_threads[cpu_num].tls)); #endif riscv_cpu_init[cpu_num].fn(riscv_cpu_init[cpu_num].arg); } diff --git a/arch/riscv/core/thread.c b/arch/riscv/core/thread.c index e035935dd80..e7709a03770 100644 --- a/arch/riscv/core/thread.c +++ b/arch/riscv/core/thread.c @@ -94,6 +94,11 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, stack_init->sp = (ulong_t)(stack_init + 1); #endif /* CONFIG_USERSPACE */ +#if defined(CONFIG_THREAD_LOCAL_STORAGE) + stack_init->tp = thread->tls; + thread->callee_saved.tp = thread->tls; +#endif + /* Assign thread entry point and mstatus.MPRV mode. */ if (IS_ENABLED(CONFIG_USERSPACE) && (thread->base.user_options & K_USER)) { diff --git a/include/zephyr/arch/riscv/exp.h b/include/zephyr/arch/riscv/exp.h index 9d120b3e25a..35682f187e0 100644 --- a/include/zephyr/arch/riscv/exp.h +++ b/include/zephyr/arch/riscv/exp.h @@ -74,6 +74,7 @@ struct __esf { ulong_t s0; /* callee-saved s0 */ + ulong_t tp; /* thread pointer */ #ifdef CONFIG_USERSPACE ulong_t sp; /* preserved (user or kernel) stack pointer */ #endif