Revert "drivers/timer/hpet: Extend qemu workaround"

This reverts commit 4ae44dd712.

See: https://github.com/zephyrproject-rtos/zephyr/issues/32724

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit is contained in:
Peter Bigot 2021-03-02 06:10:47 -06:00 committed by Anas Nashif
parent 6543e06914
commit 291b9b5dae

View file

@ -41,41 +41,18 @@ DEVICE_MMIO_TOPLEVEL_STATIC(hpet_regs, DT_DRV_INST(0));
#define MIN_DELAY 1000 #define MIN_DELAY 1000
/* The clock on Qemu in SMP has been observed going backwards. This
* enables a workaround that forces the clock to be monotonic.
*/
#if defined(CONFIG_SMP) && defined(CONFIG_QEMU_TARGET)
#define GLITCHY_EMU
#endif
static struct k_spinlock lock; static struct k_spinlock lock;
static unsigned int max_ticks; static unsigned int max_ticks;
static unsigned int cyc_per_tick; static unsigned int cyc_per_tick;
static unsigned int last_count; static unsigned int last_count;
#ifdef GLITCHY_EMU
volatile static int32_t last_counter;
#endif
static ALWAYS_INLINE uint32_t counter(void)
{
int32_t now = MAIN_COUNTER_REG;
#ifdef GLITCHY_EMU
if ((now - last_counter) < 0) {
now = last_counter + 1;
}
last_counter = now;
#endif
return now;
}
static void hpet_isr(const void *arg) static void hpet_isr(const void *arg)
{ {
ARG_UNUSED(arg); ARG_UNUSED(arg);
k_spinlock_key_t key = k_spin_lock(&lock); k_spinlock_key_t key = k_spin_lock(&lock);
uint32_t now = counter(); uint32_t now = MAIN_COUNTER_REG;
#if ((DT_INST_IRQ(0, sense) & IRQ_TYPE_LEVEL) == IRQ_TYPE_LEVEL) #if ((DT_INST_IRQ(0, sense) & IRQ_TYPE_LEVEL) == IRQ_TYPE_LEVEL)
/* /*
@ -86,6 +63,19 @@ static void hpet_isr(const void *arg)
INTR_STATUS_REG = TIMER0_INT_STS; INTR_STATUS_REG = TIMER0_INT_STS;
#endif #endif
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.
*/
int32_t diff = (int32_t)(now - last_count);
if (last_count && diff < 0) {
now = last_count;
}
}
uint32_t dticks = (now - last_count) / cyc_per_tick; uint32_t dticks = (now - last_count) / cyc_per_tick;
last_count += dticks * cyc_per_tick; last_count += dticks * cyc_per_tick;
@ -148,14 +138,10 @@ int z_clock_driver_init(const struct device *device)
TIMER0_CONF_REG |= TCONF_MODE32; TIMER0_CONF_REG |= TCONF_MODE32;
max_ticks = (0x7fffffff - cyc_per_tick) / cyc_per_tick; max_ticks = (0x7fffffff - cyc_per_tick) / cyc_per_tick;
last_count = counter(); last_count = MAIN_COUNTER_REG;
#ifdef GLITCHY_EMU
last_counter = last_count;
max_ticks -= 20;
#endif
TIMER0_CONF_REG |= TCONF_INT_ENABLE; TIMER0_CONF_REG |= TCONF_INT_ENABLE;
TIMER0_COMPARATOR_REG = counter() + cyc_per_tick; TIMER0_COMPARATOR_REG = MAIN_COUNTER_REG + cyc_per_tick;
return 0; return 0;
} }
@ -182,7 +168,7 @@ void z_clock_set_timeout(int32_t ticks, bool idle)
ticks = CLAMP(ticks - 1, 0, (int32_t)max_ticks); ticks = CLAMP(ticks - 1, 0, (int32_t)max_ticks);
k_spinlock_key_t key = k_spin_lock(&lock); k_spinlock_key_t key = k_spin_lock(&lock);
uint32_t now = counter(), cyc, adj; uint32_t now = MAIN_COUNTER_REG, cyc, adj;
uint32_t max_cyc = max_ticks * cyc_per_tick; uint32_t max_cyc = max_ticks * cyc_per_tick;
/* Round up to next tick boundary. */ /* Round up to next tick boundary. */
@ -212,7 +198,7 @@ uint32_t z_clock_elapsed(void)
} }
k_spinlock_key_t key = k_spin_lock(&lock); k_spinlock_key_t key = k_spin_lock(&lock);
uint32_t ret = (counter() - last_count) / cyc_per_tick; uint32_t ret = (MAIN_COUNTER_REG - last_count) / cyc_per_tick;
k_spin_unlock(&lock, key); k_spin_unlock(&lock, key);
return ret; return ret;
@ -220,15 +206,7 @@ uint32_t z_clock_elapsed(void)
uint32_t z_timer_cycle_get_32(void) uint32_t z_timer_cycle_get_32(void)
{ {
#ifdef GLITCHY_EMU return MAIN_COUNTER_REG;
k_spinlock_key_t key = k_spin_lock(&lock);
uint32_t ret = counter();
k_spin_unlock(&lock, key);
return ret;
#else
return counter();
#endif
} }
void z_clock_idle_exit(void) void z_clock_idle_exit(void)