From 5587476b4e1449609159ba2dd23c4dbde0c2a2f4 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Mon, 23 Jan 2023 14:56:28 +0100 Subject: [PATCH] hw: add Timer re-init/resume support Add explicit init() to Timer infrastructure to re-initialize the hardware based on the parameters given during constructing time of the timer object. Issue #4669 --- repos/base-hw/src/core/kernel/cpu.h | 3 +++ repos/base-hw/src/core/kernel/cpu_mp.cc | 7 +++++++ repos/base-hw/src/core/kernel/timer.h | 3 +++ repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.h | 2 ++ repos/base-hw/src/core/spec/arm/generic_timer.cc | 6 ++++++ repos/base-hw/src/core/spec/arm/generic_timer.h | 2 ++ repos/base-hw/src/core/spec/arm/imx_epit.cc | 6 ++++++ repos/base-hw/src/core/spec/arm/imx_epit.h | 2 ++ repos/base-hw/src/core/spec/riscv/timer.cc | 6 ++++++ repos/base-hw/src/core/spec/riscv/timer.h | 2 ++ repos/base-hw/src/core/spec/x86_64/pit.cc | 6 ++++++ repos/base-hw/src/core/spec/x86_64/pit.h | 2 ++ 12 files changed, 47 insertions(+) diff --git a/repos/base-hw/src/core/kernel/cpu.h b/repos/base-hw/src/core/kernel/cpu.h index 833af3819d..3040aa6e2b 100644 --- a/repos/base-hw/src/core/kernel/cpu.h +++ b/repos/base-hw/src/core/kernel/cpu.h @@ -88,6 +88,9 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout Ipi(Cpu & cpu); + void init(); + + /********************* ** Irq interface ** *********************/ diff --git a/repos/base-hw/src/core/kernel/cpu_mp.cc b/repos/base-hw/src/core/kernel/cpu_mp.cc index 60889f4a81..8b2eca8fef 100644 --- a/repos/base-hw/src/core/kernel/cpu_mp.cc +++ b/repos/base-hw/src/core/kernel/cpu_mp.cc @@ -52,5 +52,12 @@ Cpu::Ipi::Ipi(Cpu & cpu) : Irq(Board::Pic::IPI, cpu, cpu.pic()), cpu(cpu) { + init(); +} + + +void Cpu::Ipi::init() +{ + pending = false; cpu.pic().unmask(Board::Pic::IPI, cpu.id()); } diff --git a/repos/base-hw/src/core/kernel/timer.h b/repos/base-hw/src/core/kernel/timer.h index 50ed898b11..920847803c 100644 --- a/repos/base-hw/src/core/kernel/timer.h +++ b/repos/base-hw/src/core/kernel/timer.h @@ -110,6 +110,9 @@ class Kernel::Timer unsigned interrupt_id() const; time_t time() const { return _time + _duration(); } + + void init() { _device.init(); } + }; #endif /* _CORE__KERNEL__TIMER_H_ */ diff --git a/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.h b/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.h index d04d4dff4c..441dac8d7f 100644 --- a/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.h +++ b/repos/base-hw/src/core/spec/arm/cortex_a9_global_timer.h @@ -61,6 +61,8 @@ struct Board::Timer : Genode::Mmio Kernel::time_t current_ticks() const; Timer(unsigned); + + void init(); }; #endif /* _SRC__CORE__SPEC__ARM__CORTEX_A9_GLOBAL_TIMER_H_ */ diff --git a/repos/base-hw/src/core/spec/arm/generic_timer.cc b/repos/base-hw/src/core/spec/arm/generic_timer.cc index 659e28b145..18695b6306 100644 --- a/repos/base-hw/src/core/spec/arm/generic_timer.cc +++ b/repos/base-hw/src/core/spec/arm/generic_timer.cc @@ -25,6 +25,12 @@ unsigned long Board::Timer::_freq() { return Genode::Cpu::Cntfrq::read(); } Board::Timer::Timer(unsigned) : ticks_per_ms((unsigned)(_freq() / 1000)) +{ + init(); +} + + +void Board::Timer::init() { Cpu::Cntp_ctl::access_t ctl = 0; Cpu::Cntp_ctl::Enable::set(ctl, 1); diff --git a/repos/base-hw/src/core/spec/arm/generic_timer.h b/repos/base-hw/src/core/spec/arm/generic_timer.h index a047670ac1..8ec27c1dc3 100644 --- a/repos/base-hw/src/core/spec/arm/generic_timer.h +++ b/repos/base-hw/src/core/spec/arm/generic_timer.h @@ -27,6 +27,8 @@ struct Board::Timer unsigned const ticks_per_ms; Timer(unsigned); + + void init(); }; #endif /* _SRC__CORE__SPEC__ARM__GENERIC_TIMER_H_ */ diff --git a/repos/base-hw/src/core/spec/arm/imx_epit.cc b/repos/base-hw/src/core/spec/arm/imx_epit.cc index aa651394b1..34e3b126ac 100644 --- a/repos/base-hw/src/core/spec/arm/imx_epit.cc +++ b/repos/base-hw/src/core/spec/arm/imx_epit.cc @@ -29,6 +29,12 @@ unsigned Timer::interrupt_id() const { return Board::EPIT_1_IRQ; } Board::Timer::Timer(unsigned) : Mmio(Platform::mmio_to_virt(Board::EPIT_1_MMIO_BASE)) +{ + init(); +} + + +void Board::Timer::init() { reset(); diff --git a/repos/base-hw/src/core/spec/arm/imx_epit.h b/repos/base-hw/src/core/spec/arm/imx_epit.h index 8a901dd29d..6b47cb4187 100644 --- a/repos/base-hw/src/core/spec/arm/imx_epit.h +++ b/repos/base-hw/src/core/spec/arm/imx_epit.h @@ -88,6 +88,8 @@ struct Board::Timer : Genode::Mmio } Timer(unsigned); + + void init(); }; #endif /* _SRC__CORE__SPEC__ARM__IMX_EPIT_H_ */ diff --git a/repos/base-hw/src/core/spec/riscv/timer.cc b/repos/base-hw/src/core/spec/riscv/timer.cc index 1747414ba5..5a8c84b6c1 100644 --- a/repos/base-hw/src/core/spec/riscv/timer.cc +++ b/repos/base-hw/src/core/spec/riscv/timer.cc @@ -21,6 +21,12 @@ using namespace Kernel; Board::Timer::Timer(unsigned) +{ + init(); +} + + +void Board::Timer::init() { /* enable timer interrupt */ enum { STIE = 0x20 }; diff --git a/repos/base-hw/src/core/spec/riscv/timer.h b/repos/base-hw/src/core/spec/riscv/timer.h index a1d30a1d90..b1d4c37aab 100644 --- a/repos/base-hw/src/core/spec/riscv/timer.h +++ b/repos/base-hw/src/core/spec/riscv/timer.h @@ -34,6 +34,8 @@ struct Board::Timer Kernel::time_t stime() const; Timer(unsigned); + + void init(); }; #endif /* _SRC__CORE__SPEC__RISCV__TIMER_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 a2f00feddd..119c4930a1 100644 --- a/repos/base-hw/src/core/spec/x86_64/pit.cc +++ b/repos/base-hw/src/core/spec/x86_64/pit.cc @@ -56,6 +56,12 @@ uint32_t Board::Timer::pit_calc_timer_freq(void) Board::Timer::Timer(unsigned) : Mmio(Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base())) +{ + init(); +} + + +void Board::Timer::init() { /* enable LAPIC timer in one-shot mode */ write(Board::TIMER_VECTOR_KERNEL); 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 8b8d6cc124..562a63533c 100644 --- a/repos/base-hw/src/core/spec/x86_64/pit.h +++ b/repos/base-hw/src/core/spec/x86_64/pit.h @@ -72,6 +72,8 @@ struct Board::Timer: Genode::Mmio Genode::uint32_t pit_calc_timer_freq(void); Timer(unsigned); + + void init(); }; #endif /* _SRC__CORE__SPEC__ARM__PIT_H_ */