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:
parent
0d0f168460
commit
35efb15637
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in a new issue