diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc b/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc index 7c1798df62..5dcc44a2bd 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc @@ -22,6 +22,10 @@ void Kernel::Cpu::_arch_init() Idt::init(); Tss::init(); + _pic.init(); + _timer.init(); + _ipi_irq.init(); + /* enable timer interrupt */ _pic.store_apic_id(id()); _pic.unmask(_timer.interrupt_id(), id()); diff --git a/repos/base-hw/src/core/spec/x86_64/pic.cc b/repos/base-hw/src/core/spec/x86_64/pic.cc index e3a85aa2d5..a151b1482a 100644 --- a/repos/base-hw/src/core/spec/x86_64/pic.cc +++ b/repos/base-hw/src/core/spec/x86_64/pic.cc @@ -42,6 +42,11 @@ Local_interrupt_controller(Global_interrupt_controller &global_irq_ctrl) : Mmio { Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base()) }, _global_irq_ctrl { global_irq_ctrl } +{ + init(); +} + +void Local_interrupt_controller::init() { /* Start initialization sequence in cascade mode */ outb(PIC_CMD_MASTER, 0x11); diff --git a/repos/base-hw/src/core/spec/x86_64/pic.h b/repos/base-hw/src/core/spec/x86_64/pic.h index 37620200dd..d8243e9aca 100644 --- a/repos/base-hw/src/core/spec/x86_64/pic.h +++ b/repos/base-hw/src/core/spec/x86_64/pic.h @@ -230,6 +230,8 @@ class Board::Local_interrupt_controller : public Genode::Mmio } void send_ipi(unsigned const); + + void init(); }; #endif /* _CORE__SPEC__X86_64__PIC_H_ */ diff --git a/repos/base-hw/src/core/spec/x86_64/pit.cc b/repos/base-hw/src/core/spec/x86_64/pit.cc index 119c4930a1..bb07ae6f77 100644 --- a/repos/base-hw/src/core/spec/x86_64/pit.cc +++ b/repos/base-hw/src/core/spec/x86_64/pit.cc @@ -69,6 +69,12 @@ void Board::Timer::init() write(0); write(0); + /* use very same divider after ACPI resume as used during initial boot */ + if (divider) { + write((uint8_t)divider); + return; + } + /* 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--) @@ -81,6 +87,7 @@ void Board::Timer::init() /* Calculate timer frequency */ ticks_per_ms = pit_calc_timer_freq(); + divider = div; } /** diff --git a/repos/base-hw/src/core/spec/x86_64/pit.h b/repos/base-hw/src/core/spec/x86_64/pit.h index 562a63533c..0d6bad1785 100644 --- a/repos/base-hw/src/core/spec/x86_64/pit.h +++ b/repos/base-hw/src/core/spec/x86_64/pit.h @@ -66,7 +66,8 @@ struct Board::Timer: Genode::Mmio struct Calibration_failed : Genode::Exception { }; - Genode::uint32_t ticks_per_ms = 0; + Divide_configuration::access_t divider = 0; + Genode::uint32_t ticks_per_ms = 0; /* Measure LAPIC timer frequency using PIT channel 2 */ Genode::uint32_t pit_calc_timer_freq(void);