@@ -278,17 +278,44 @@ static void test_timer_cval(struct timer_info *info)
disable_timer(info);
}
-static void test_timer_tval(struct timer_info *info)
+static void timer_do_wfi(struct timer_info *info)
{
- s32 left;
-
- info->write_tval(read_sysreg(cntfrq_el0) / 100); /* 10 ms */
local_irq_disable();
- info->write_ctl(ARCH_TIMER_CTL_ENABLE);
+ if (info->irq_received)
+ goto out;
report_info("waiting for interrupt...");
wfi();
+out:
local_irq_enable();
- left = info->read_tval();
+}
+
+static void test_timer_tval(struct timer_info *info)
+{
+ u64 time_10ms = read_sysreg(cntfrq_el0) / 100;
+ s32 left;
+ int i;
+
+ info->write_tval(time_10ms);
+ info->write_ctl(ARCH_TIMER_CTL_ENABLE);
+
+ for (;;) {
+ timer_do_wfi(info);
+ left = info->read_tval();
+ if (info->irq_received || left <= 0)
+ break;
+ }
+
+ /* Wait one second for the GIC to update the interrupt state. */
+ if (left <= 0 && !info->irq_received) {
+ for (i = 0; i < 10; i++) {
+ timer_do_wfi(info);
+ if (info->irq_received)
+ break;
+ mdelay(100);
+ }
+ left = info->read_tval();
+ }
+
report(info->irq_received, "interrupt received after TVAL/WFI");
report(left <= 0, "timer has expired");
report_info("TVAL is %d ticks", left);
The TVAL test programs the timer to fire into the future, waits for an interrupt using the WFI instruction, and when the instruction completes it checks that the timer interrupt has fired. According to ARM DDI 0487G.a there are other wake-up events that can cause the WFI to complete (listed on page D1-2520), among them interrupts routed to a higher exception level, where the hypervisor is running (if running under virtualization) or firmware (if running on baremetal). In practice, this is unlikely to have caused a false test failure, because for a GICv3 (which the author assumes is a lot more common than a GICv4+) the WFI is trapped by KVM and the VCPU thread is resumed only after the timer asserts the interrupt, as the test expects. Signed-off-by: Alexandru Elisei <alexandru.elisei@arm.com> --- arm/timer.c | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-)