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 <keithp@keithp.com>
This commit is contained in:
Keith Packard 2022-04-19 17:33:03 -07:00 committed by Stephanos Ioannidis
commit f623571a73
6 changed files with 13 additions and 0 deletions

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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)) {

View file

@ -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