arch: arm: timer: mask interrupt in ISR

As timer interrupt is level triggered, we need to mask it before leaving
ISR or it will be delivered again.

Also, Xen automatically masks timer interrupt when it injects IRQ to
a guest, so we need to unmask it again, when setting new timeout.

Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
This commit is contained in:
Volodymyr Babchuk 2020-11-19 22:48:46 +02:00 committed by Anas Nashif
parent 0d0f168460
commit 35efb15637
2 changed files with 26 additions and 2 deletions

View file

@ -36,6 +36,9 @@ static void arm_arch_timer_compare_isr(const void *arg)
next_cycle += CYC_PER_TICK;
}
arm_arch_timer_set_compare(next_cycle);
arm_arch_timer_set_irq_mask(false);
} else {
arm_arch_timer_set_irq_mask(true);
}
k_spin_unlock(&lock, key);
@ -52,6 +55,7 @@ int z_clock_driver_init(const struct device *device)
arm_arch_timer_set_compare(arm_arch_timer_count() + CYC_PER_TICK);
arm_arch_timer_enable(true);
irq_enable(ARM_ARCH_TIMER_IRQ);
arm_arch_timer_set_irq_mask(false);
return 0;
}
@ -83,6 +87,7 @@ void z_clock_set_timeout(int32_t ticks, bool idle)
}
arm_arch_timer_set_compare(req_cycle + last_cycle);
arm_arch_timer_set_irq_mask(false);
k_spin_unlock(&lock, key);
#endif

View file

@ -21,6 +21,7 @@ extern "C" {
#define ARM_ARCH_TIMER_FLAGS ARM_TIMER_VIRTUAL_FLAGS
#define CNTV_CTL_ENABLE ((1) << 0)
#define CNTV_CTL_IMASK ((1) << 1)
static ALWAYS_INLINE void arm_arch_timer_set_compare(uint64_t val)
@ -36,10 +37,28 @@ static ALWAYS_INLINE void arm_arch_timer_enable(unsigned char enable)
__asm__ volatile("mrs %0, cntv_ctl_el0\n\t"
: "=r" (cntv_ctl) : : "memory");
if (enable)
if (enable) {
cntv_ctl |= CNTV_CTL_ENABLE;
else
} else {
cntv_ctl &= ~CNTV_CTL_ENABLE;
}
__asm__ volatile("msr cntv_ctl_el0, %0\n\t"
: : "r" (cntv_ctl) : "memory");
}
static ALWAYS_INLINE void arm_arch_timer_set_irq_mask(bool mask)
{
uint32_t cntv_ctl;
__asm__ volatile("mrs %0, cntv_ctl_el0\n\t"
: "=r" (cntv_ctl) : : "memory");
if (mask) {
cntv_ctl |= CNTV_CTL_IMASK;
} else {
cntv_ctl &= ~CNTV_CTL_IMASK;
}
__asm__ volatile("msr cntv_ctl_el0, %0\n\t"
: : "r" (cntv_ctl) : "memory");