mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 18:06:50 +00:00
hw lapic: find best frequency dynamically
Some x86 machines do have a LAPIC speed < 1000 ticks per millisecond when configured to use the maximum divider (as it was always the case). But we need microseconds precision for the timeout framework. Thus, reduce the divider dynamically until the frequency fullfills our requirements. Ref #2400
This commit is contained in:
parent
d9073a1848
commit
7f29eff75a
@ -56,18 +56,25 @@ uint32_t Timer_driver::pit_calc_timer_freq(void)
|
||||
Timer_driver::Timer_driver(unsigned)
|
||||
: Mmio(Platform::mmio_to_virt(Hw::Cpu_memory_map::MMIO_LAPIC_BASE))
|
||||
{
|
||||
write<Divide_configuration::Divide_value>(
|
||||
Divide_configuration::Divide_value::MAX);
|
||||
|
||||
/* Enable LAPIC timer in one-shot mode */
|
||||
write<Tmr_lvt::Vector>(Board::TIMER_VECTOR_KERNEL);
|
||||
write<Tmr_lvt::Delivery>(0);
|
||||
write<Tmr_lvt::Mask>(0);
|
||||
write<Tmr_lvt::Timer_mode>(0);
|
||||
|
||||
/* calibrate LAPIC frequency to fullfill our requirements */
|
||||
for (Divide_configuration::access_t div = Divide_configuration::Divide_value::MAX;
|
||||
div && ticks_per_ms < TIMER_MIN_TICKS_PER_MS; div--)
|
||||
{
|
||||
if (!div){
|
||||
error("Failed to calibrate timer frequency");
|
||||
throw Calibration_failed();
|
||||
}
|
||||
write<Divide_configuration::Divide_value>(div);
|
||||
|
||||
/* Calculate timer frequency */
|
||||
ticks_per_ms = pit_calc_timer_freq();
|
||||
assert(ticks_per_ms >= TIMER_MIN_TICKS_PER_MS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,6 +63,8 @@ struct Kernel::Timer_driver : Genode::Mmio
|
||||
};
|
||||
};
|
||||
|
||||
struct Calibration_failed : Genode::Exception { };
|
||||
|
||||
Genode::uint32_t ticks_per_ms = 0;
|
||||
|
||||
/* Measure LAPIC timer frequency using PIT channel 2 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user