From 5fb0c44f38bf7ae1ddc8d446abe070b6f0513608 Mon Sep 17 00:00:00 2001 From: Jinliang Li Date: Fri, 16 Aug 2024 15:21:08 +0800 Subject: [PATCH] arm/armv8-r: optimize generic timer initialization 1. Enable timer and irq finally to make sure timer callback was already registered. When the CPU resets, the values of some generic timer registers are undefined. Enabling the timer interrupt in advance may cause the timer to trigger early while the timer callback is not yet registered. This results in the timer ISR being executed, which masks the timer interrupt. Since the timer callback is not registered at this point, the timer interrupt is not unmasked, further causing the system scheduler to hang. 2. Remove timer mask for one-shot timer and that's in isr, irq/fiq is disabled. Masking generic timer is not necessary, and it may introduce risks, otherwise, mask/unmask must be pair in all situations. Signed-off-by: Jinliang Li --- arch/arm/src/armv8-r/arm_arch_timer.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/arch/arm/src/armv8-r/arm_arch_timer.c b/arch/arm/src/armv8-r/arm_arch_timer.c index 1c558fec18..14b87464a2 100644 --- a/arch/arm/src/armv8-r/arm_arch_timer.c +++ b/arch/arm/src/armv8-r/arm_arch_timer.c @@ -139,8 +139,6 @@ static int arm_arch_timer_compare_isr(int irq, void *regs, void *arg) struct arm_oneshot_lowerhalf_s *priv = (struct arm_oneshot_lowerhalf_s *)arg; - arm_arch_timer_set_irq_mask(true); - if (priv->callback) { /* Then perform the callback */ @@ -255,6 +253,11 @@ static int arm_tick_start(struct oneshot_lowerhalf_s *lower, arm_arch_timer_set_compare(arm_arch_timer_count() + priv->cycle_per_tick * ticks); + + /* Try to unmask the timer irq in timer controller + * in case of arm_tick_cancel is called. + */ + arm_arch_timer_set_irq_mask(false); return OK; @@ -345,14 +348,6 @@ static struct oneshot_lowerhalf_s *arm_oneshot_initialize(void) irq_attach(ARM_ARCH_TIMER_IRQ, arm_arch_timer_compare_isr, priv); - /* Enable int */ - - up_enable_irq(ARM_ARCH_TIMER_IRQ); - - /* Start timer */ - - arm_arch_timer_enable(true); - tmrinfo("oneshot_initialize ok %p \n", &priv->lh); return &priv->lh; @@ -380,6 +375,8 @@ void up_timer_initialize(void) __func__, freq / 1000000, (freq / 10000) % 100); up_alarm_set_lowerhalf(arm_oneshot_initialize()); + up_enable_irq(ARM_ARCH_TIMER_IRQ); + arm_arch_timer_enable(true); } #ifdef CONFIG_SMP