Commit bab348e9 authored by Andy Ross's avatar Andy Ross Committed by Anas Nashif
Browse files

drivers/timer/hpet: Work around crazy qemu behavior



At least twice (to be fair: twice among thousands of test runs), I've
seen this device return "backwards" times in SMP, where the counter
value read from one CPU is behind the saved value already seen on the
other.  On hardware this should obviously never happen, HPET is a
single global device.

Add a simple workaround on QEMU targets so the math doesn't blow up.

Signed-off-by: default avatarAndy Ross <andrew.j.ross@intel.com>
parent d1200d21
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -38,6 +38,20 @@ static void hpet_isr(void *arg)
	ARG_UNUSED(arg);
	k_spinlock_key_t key = k_spin_lock(&lock);
	u32_t now = MAIN_COUNTER_REG;

	if (IS_ENABLED(CONFIG_SMP) &&
	    IS_ENABLED(CONFIG_QEMU_TARGET)) {
		/* Qemu in SMP mode has observed the clock going
		 * "backwards" relative to interrupts already received
		 * on the other CPU, despite the HPET being
		 * theoretically a global device.
		 */
		s32_t diff = (s32_t)(now - last_count);

		if (last_count && diff < 0) {
			now = last_count;
		}
	}
	u32_t dticks = (now - last_count) / cyc_per_tick;

	last_count += dticks * cyc_per_tick;