Always check current HPET counter value after comparator programming to

avoid lost timer interrupts. Previous optimization attempt doing it only
for intervals less then 5000 ticks (~300us) reported to be unreliable by
some people. Probably because of some heavy SMI code on their boards.
Introduce additional safety interval of 128 counter ticks (~9us) between
programmed comparator and counter values to cover different cases of
delayed write found on some chipsets.

Approved by:	re (kib)
This commit is contained in:
Alexander Motin 2011-08-16 21:51:29 +00:00
parent 3900c0936f
commit 9839387616
2 changed files with 8 additions and 8 deletions

View File

@ -190,13 +190,10 @@ hpet_start(struct eventtimer *et,
bus_write_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num),
t->next);
}
if (fdiv < 5000) {
bus_read_4(sc->mem_res, HPET_TIMER_COMPARATOR(t->num));
now = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER);
if ((int32_t)(now - t->next) >= 0) {
fdiv *= 2;
goto restart;
}
now = bus_read_4(sc->mem_res, HPET_MAIN_COUNTER);
if ((int32_t)(now - t->next + HPET_MIN_CYCLES) >= 0) {
fdiv *= 2;
goto restart;
}
return (0);
}
@ -679,7 +676,8 @@ hpet_attach(device_t dev)
t->et.et_quality -= 10;
t->et.et_frequency = sc->freq;
t->et.et_min_period.sec = 0;
t->et.et_min_period.frac = 0x00008000LLU << 32;
t->et.et_min_period.frac =
(((uint64_t)(HPET_MIN_CYCLES * 2) << 32) / sc->freq) << 32;
t->et.et_max_period.sec = 0xfffffffeLLU / sc->freq;
t->et.et_max_period.frac =
((0xfffffffeLLU << 32) / sc->freq) << 32;

View File

@ -62,4 +62,6 @@
#define HPET_TIMER_FSB_VAL(x) ((x) * 0x20 + 0x110)
#define HPET_TIMER_FSB_ADDR(x) ((x) * 0x20 + 0x114)
#define HPET_MIN_CYCLES 128 /* Period considered reliable. */
#endif /* !__ACPI_HPET_H__ */