arch/risc-v: fix timer initialization for SMP using mtimer

Correct timer initialization issue in SMP mode using mtimer to ensure
  per-hart timers are properly set up during boot.

Signed-off-by: Chengdong Wang <wangchengdong@lixiang.com>
This commit is contained in:
wangchengdong 2026-01-27 15:39:48 +08:00 committed by Xiang Xiao
parent c52d54d500
commit d9a0cf46ac
3 changed files with 34 additions and 4 deletions

View file

@ -123,6 +123,8 @@ void riscv_cpu_boot(int cpu)
sched_note_cpu_started(this_task());
#endif
riscv_timer_secondary_init();
up_irq_enable();
/* Then transfer control to the IDLE task */

View file

@ -365,6 +365,7 @@ void riscv_color_intstack(void);
#ifdef CONFIG_SMP
void riscv_cpu_boot(int cpu);
int riscv_smp_call_handler(int irq, void *c, void *arg);
void riscv_timer_secondary_init(void);
#endif
#ifdef CONFIG_ARCH_RV_CPUID_MAP

View file

@ -41,6 +41,7 @@
struct riscv_mtimer_lowerhalf_s
{
struct oneshot_lowerhalf_s lower;
int irq;
uintreg_t mtime;
uintreg_t mtimecmp;
};
@ -87,7 +88,7 @@ static uint64_t riscv_mtimer_get_mtime(struct riscv_mtimer_lowerhalf_s *priv)
static void riscv_mtimer_set_mtimecmp(struct riscv_mtimer_lowerhalf_s *priv,
uint64_t value)
{
riscv_mtimer_set(priv->mtime, priv->mtimecmp, value);
riscv_mtimer_set(priv->mtime, priv->mtimecmp + 8 * up_cpu_index(), value);
}
static clkcnt_t riscv_mtime_max_delay(struct oneshot_lowerhalf_s *lower)
@ -141,6 +142,25 @@ static int riscv_mtimer_interrupt(int irq, void *context, void *arg)
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: riscv_mtimer_oneshot_initialize_per_cpu
*
* Description:
* Initialize the riscv mtimer for secondary CPUs.
*
* Returned Value:
* None
*
****************************************************************************/
static void riscv_mtimer_oneshot_initialize_per_cpu(void)
{
struct riscv_mtimer_lowerhalf_s *priv = &g_riscv_mtime_lowerhalf;
riscv_mtimer_set_mtimecmp(priv, UINT64_MAX);
up_enable_irq(priv->irq);
}
struct oneshot_lowerhalf_s *
riscv_mtimer_initialize(uintreg_t mtime, uintreg_t mtimecmp,
int irq, uint64_t freq)
@ -148,13 +168,20 @@ riscv_mtimer_initialize(uintreg_t mtime, uintreg_t mtimecmp,
struct riscv_mtimer_lowerhalf_s *priv = &g_riscv_mtime_lowerhalf;
priv->mtime = mtime;
priv->irq = irq;
priv->mtimecmp = mtimecmp;
oneshot_count_init(&priv->lower, freq);
riscv_mtimer_set_mtimecmp(priv, UINT64_MAX);
irq_attach(irq, riscv_mtimer_interrupt, priv);
up_enable_irq(irq);
irq_attach(priv->irq, riscv_mtimer_interrupt, priv);
riscv_mtimer_oneshot_initialize_per_cpu();
return &priv->lower;
}
#ifdef CONFIG_SMP
void riscv_timer_secondary_init(void)
{
riscv_mtimer_oneshot_initialize_per_cpu();
}
#endif