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:
parent
3900c0936f
commit
9839387616
@ -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;
|
||||
|
@ -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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user