From 02f00a999c6dcfa4c9ddb5b23e5ff11194976635 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Thu, 12 Aug 2021 16:39:52 +0200 Subject: [PATCH] base-hw: global IRQ controller as Main member Let the kernel's driver for the global IRQ controller be a member of the one Kernel::Main object instead of having it as static variables in the drivers for the local IRQ controllers. Note that this commit spares out renaming 'Pic' to 'Local_interrupt_controller' which would be more sensible now with the new 'Global_interrupt_controller' class. Furthermore, on ARM boards the commit doesn't move 'Distributer' stuff to the new global IRQ controller class as they don't have real data members (only MMIO) and can be instanciated for each CPU anew. However, the right way would be to instanciate them only once in Main as well. Ref #4217 --- .../src/core/board/imx6q_sabrelite/board.h | 3 +- .../base-hw/src/core/board/nit6_solox/board.h | 3 +- repos/base-hw/src/core/board/pbxa9/board.h | 3 +- repos/base-hw/src/core/board/pc/board.h | 2 + .../base-hw/src/core/board/wand_quad/board.h | 3 +- .../base-hw/src/core/board/zynq_qemu/board.h | 3 +- repos/base-hw/src/core/kernel/cpu.cc | 21 +++--- repos/base-hw/src/core/kernel/cpu.h | 20 +++--- repos/base-hw/src/core/kernel/main.cc | 4 +- .../base-hw/src/core/spec/arm/bcm2835_pic.cc | 17 ++--- repos/base-hw/src/core/spec/arm/bcm2835_pic.h | 28 ++++++-- .../base-hw/src/core/spec/arm/bcm2837_pic.cc | 2 +- repos/base-hw/src/core/spec/arm/bcm2837_pic.h | 8 ++- .../src/core/spec/arm/trustzone_board.h | 3 +- .../src/core/spec/arm/virtualization/gicv2.h | 8 ++- .../src/core/spec/arm/virtualization/gicv3.h | 8 ++- repos/base-hw/src/core/spec/riscv/pic.cc | 3 +- repos/base-hw/src/core/spec/riscv/pic.h | 8 ++- repos/base-hw/src/core/spec/x86_64/pic.cc | 72 ++++++++++++------- repos/base-hw/src/core/spec/x86_64/pic.h | 65 +++++++++-------- 20 files changed, 181 insertions(+), 103 deletions(-) diff --git a/repos/base-hw/src/core/board/imx6q_sabrelite/board.h b/repos/base-hw/src/core/board/imx6q_sabrelite/board.h index fe2aebc2b3..3646a09479 100644 --- a/repos/base-hw/src/core/board/imx6q_sabrelite/board.h +++ b/repos/base-hw/src/core/board/imx6q_sabrelite/board.h @@ -26,7 +26,8 @@ namespace Board { using namespace Hw::Imx6q_sabrelite_board; - class Pic : public Hw::Gicv2 { }; + class Global_interrupt_controller { }; + class Pic : public Hw::Gicv2 { public: Pic(Global_interrupt_controller &) { } }; using L2_cache = Hw::Pl310; diff --git a/repos/base-hw/src/core/board/nit6_solox/board.h b/repos/base-hw/src/core/board/nit6_solox/board.h index 3a7704c613..7a5d2ea120 100644 --- a/repos/base-hw/src/core/board/nit6_solox/board.h +++ b/repos/base-hw/src/core/board/nit6_solox/board.h @@ -26,7 +26,8 @@ namespace Board { using namespace Hw::Nit6_solox_board; - class Pic : public Hw::Gicv2 { }; + class Global_interrupt_controller { }; + class Pic : public Hw::Gicv2 { public: Pic(Global_interrupt_controller &) { } }; using L2_cache = Hw::Pl310; diff --git a/repos/base-hw/src/core/board/pbxa9/board.h b/repos/base-hw/src/core/board/pbxa9/board.h index 5b3f42edbf..7e6506cc7e 100644 --- a/repos/base-hw/src/core/board/pbxa9/board.h +++ b/repos/base-hw/src/core/board/pbxa9/board.h @@ -26,7 +26,8 @@ namespace Board { using namespace Hw::Pbxa9_board; - class Pic : public Hw::Gicv2 { }; + class Global_interrupt_controller { }; + class Pic : public Hw::Gicv2 { public: Pic(Global_interrupt_controller &) { } }; L2_cache & l2_cache(); } diff --git a/repos/base-hw/src/core/board/pc/board.h b/repos/base-hw/src/core/board/pc/board.h index 4f0d51ad13..389a519293 100644 --- a/repos/base-hw/src/core/board/pc/board.h +++ b/repos/base-hw/src/core/board/pc/board.h @@ -26,6 +26,8 @@ namespace Board { using namespace Hw::Pc_board; + class Pic : public Local_interrupt_controller { }; + enum { VECTOR_REMAP_BASE = 48, TIMER_VECTOR_KERNEL = 32, diff --git a/repos/base-hw/src/core/board/wand_quad/board.h b/repos/base-hw/src/core/board/wand_quad/board.h index 2cfc859447..83f90aa83c 100644 --- a/repos/base-hw/src/core/board/wand_quad/board.h +++ b/repos/base-hw/src/core/board/wand_quad/board.h @@ -29,7 +29,8 @@ namespace Board { using L2_cache = Hw::Pl310; - class Pic : public Hw::Gicv2 { }; + class Global_interrupt_controller { }; + class Pic : public Hw::Gicv2 { public: Pic(Global_interrupt_controller &) { } }; L2_cache & l2_cache(); diff --git a/repos/base-hw/src/core/board/zynq_qemu/board.h b/repos/base-hw/src/core/board/zynq_qemu/board.h index 9597a305e8..81e70fe96f 100644 --- a/repos/base-hw/src/core/board/zynq_qemu/board.h +++ b/repos/base-hw/src/core/board/zynq_qemu/board.h @@ -28,7 +28,8 @@ namespace Board { using namespace Hw::Zynq_qemu_board; - class Pic : public Hw::Gicv2 { }; + class Global_interrupt_controller { }; + class Pic : public Hw::Gicv2 { public: Pic(Global_interrupt_controller &) { } }; L2_cache & l2_cache(); } diff --git a/repos/base-hw/src/core/kernel/cpu.cc b/repos/base-hw/src/core/kernel/cpu.cc index 402e35bbeb..7840d39acb 100644 --- a/repos/base-hw/src/core/kernel/cpu.cc +++ b/repos/base-hw/src/core/kernel/cpu.cc @@ -174,13 +174,15 @@ addr_t Cpu::stack_start() } -Cpu::Cpu(unsigned const id, - Board::Address_space_id_allocator &addr_space_id_alloc, - Irq::Pool &user_irq_pool, - Cpu_pool &cpu_pool, - Pd &core_pd) +Cpu::Cpu(unsigned const id, + Board::Address_space_id_allocator &addr_space_id_alloc, + Irq::Pool &user_irq_pool, + Cpu_pool &cpu_pool, + Pd &core_pd, + Board::Global_interrupt_controller &global_irq_ctrl) : _id { id }, + _pic { global_irq_ctrl }, _timer { *this }, _scheduler { _idle, _quota(), _fill() }, _idle { addr_space_id_alloc, user_irq_pool, cpu_pool, *this, @@ -198,13 +200,14 @@ Cpu::Cpu(unsigned const id, void Cpu_pool:: -initialize_executing_cpu(Board::Address_space_id_allocator &addr_space_id_alloc, - Irq::Pool &user_irq_pool, - Pd &core_pd) +initialize_executing_cpu(Board::Address_space_id_allocator &addr_space_id_alloc, + Irq::Pool &user_irq_pool, + Pd &core_pd, + Board::Global_interrupt_controller &global_irq_ctrl) { unsigned id = Cpu::executing_id(); _cpus[id].construct( - id, addr_space_id_alloc, user_irq_pool, *this, core_pd); + id, addr_space_id_alloc, user_irq_pool, *this, core_pd, global_irq_ctrl); } diff --git a/repos/base-hw/src/core/kernel/cpu.h b/repos/base-hw/src/core/kernel/cpu.h index 55ec3275f7..e9c412b916 100644 --- a/repos/base-hw/src/core/kernel/cpu.h +++ b/repos/base-hw/src/core/kernel/cpu.h @@ -111,7 +111,7 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout unsigned const _id; - Board::Pic _pic {}; + Board::Pic _pic; Timer _timer; Cpu_scheduler _scheduler; Idle_thread _idle; @@ -131,11 +131,12 @@ class Kernel::Cpu : public Genode::Cpu, private Irq::Pool, private Timeout /** * Construct object for CPU 'id' */ - Cpu(unsigned const id, - Board::Address_space_id_allocator &addr_space_id_alloc, - Irq::Pool &user_irq_pool, - Cpu_pool &cpu_pool, - Pd &core_pd); + Cpu(unsigned const id, + Board::Address_space_id_allocator &addr_space_id_alloc, + Irq::Pool &user_irq_pool, + Cpu_pool &cpu_pool, + Pd &core_pd, + Board::Global_interrupt_controller &global_irq_ctrl); static inline unsigned primary_id() { return 0; } @@ -207,9 +208,10 @@ class Kernel::Cpu_pool Cpu_pool(unsigned nr_of_cpus); void - initialize_executing_cpu(Board::Address_space_id_allocator &addr_space_id_alloc, - Irq::Pool &user_irq_pool, - Pd &core_pd); + initialize_executing_cpu(Board::Address_space_id_allocator &addr_space_id_alloc, + Irq::Pool &user_irq_pool, + Pd &core_pd, + Board::Global_interrupt_controller &global_irq_ctrl); /** * Return object of CPU 'id' diff --git a/repos/base-hw/src/core/kernel/main.cc b/repos/base-hw/src/core/kernel/main.cc index 6b4200de25..ed753cf56a 100644 --- a/repos/base-hw/src/core/kernel/main.cc +++ b/repos/base-hw/src/core/kernel/main.cc @@ -51,6 +51,7 @@ class Kernel::Main Board::Address_space_id_allocator _addr_space_id_alloc { }; Genode::Core_platform_pd _core_platform_pd { _addr_space_id_alloc }; Genode::Constructible _core_main_thread { }; + Board::Global_interrupt_controller _global_irq_ctrl { }; void _handle_kernel_entry(); @@ -137,7 +138,8 @@ void Kernel::main_initialize_and_handle_kernel_entry() Main::_instance->_cpu_pool.initialize_executing_cpu( Main::_instance->_addr_space_id_alloc, Main::_instance->_user_irq_pool, - Main::_instance->_core_platform_pd.kernel_pd()); + Main::_instance->_core_platform_pd.kernel_pd(), + Main::_instance->_global_irq_ctrl); nr_of_initialized_cpus++; }; diff --git a/repos/base-hw/src/core/spec/arm/bcm2835_pic.cc b/repos/base-hw/src/core/spec/arm/bcm2835_pic.cc index fbedcf214c..6462eda7a5 100644 --- a/repos/base-hw/src/core/spec/arm/bcm2835_pic.cc +++ b/repos/base-hw/src/core/spec/arm/bcm2835_pic.cc @@ -37,9 +37,11 @@ bool Board::Pic::Usb_dwc_otg::_need_trigger_sof(uint32_t host_frame, } -Board::Pic::Usb_dwc_otg::Usb_dwc_otg() +Board::Pic:: +Usb_dwc_otg::Usb_dwc_otg(Global_interrupt_controller &global_irq_ctrl) : - Mmio(Platform::mmio_to_virt(Board::USB_DWC_OTG_BASE)) + Mmio { Platform::mmio_to_virt(Board::USB_DWC_OTG_BASE) }, + _global_irq_ctrl { global_irq_ctrl } { write(0); write(false); @@ -52,10 +54,8 @@ bool Board::Pic::Usb_dwc_otg::handle_sof() if (!_is_sof()) return false; - static int cnt = 0; - - if (++cnt == 8*20) { - cnt = 0; + if (_global_irq_ctrl.increment_and_return_sof_cnt() == 8*20) { + _global_irq_ctrl.reset_sof_cnt(); return false; } @@ -72,9 +72,10 @@ bool Board::Pic::Usb_dwc_otg::handle_sof() } -Board::Pic::Pic() +Board::Pic::Pic(Global_interrupt_controller &global_irq_ctrl) : - Mmio(Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE)) + Mmio { Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE) }, + _usb { global_irq_ctrl } { mask(); } diff --git a/repos/base-hw/src/core/spec/arm/bcm2835_pic.h b/repos/base-hw/src/core/spec/arm/bcm2835_pic.h index f356a02108..26dfed467b 100644 --- a/repos/base-hw/src/core/spec/arm/bcm2835_pic.h +++ b/repos/base-hw/src/core/spec/arm/bcm2835_pic.h @@ -17,7 +17,25 @@ /* Genode includes */ #include -namespace Board { class Pic; } +namespace Board { + + class Global_interrupt_controller; + class Pic; +} + + +class Board::Global_interrupt_controller +{ + private: + + int _sof_cnt { 0 }; + + public: + + int increment_and_return_sof_cnt() { return ++_sof_cnt; } + + void reset_sof_cnt() { _sof_cnt = 0; } +}; class Board::Pic : Genode::Mmio @@ -80,6 +98,8 @@ class Board::Pic : Genode::Mmio struct Num : Bitfield<0, 14> { }; }; + Global_interrupt_controller &_global_irq_ctrl; + bool _is_sof() const { return read(); @@ -90,12 +110,12 @@ class Board::Pic : Genode::Mmio public: - Usb_dwc_otg(); + Usb_dwc_otg(Global_interrupt_controller &global_irq_ctrl); bool handle_sof(); }; - Usb_dwc_otg _usb { }; + Usb_dwc_otg _usb; /** * Return true if specified interrupt is pending @@ -108,7 +128,7 @@ class Board::Pic : Genode::Mmio public: - Pic(); + Pic(Global_interrupt_controller &global_irq_ctrl); bool take_request(unsigned &irq); void finish_request() { } diff --git a/repos/base-hw/src/core/spec/arm/bcm2837_pic.cc b/repos/base-hw/src/core/spec/arm/bcm2837_pic.cc index a013f42263..81841b0902 100644 --- a/repos/base-hw/src/core/spec/arm/bcm2837_pic.cc +++ b/repos/base-hw/src/core/spec/arm/bcm2837_pic.cc @@ -16,7 +16,7 @@ #include -Board::Pic::Pic() +Board::Pic::Pic(Global_interrupt_controller &) : Genode::Mmio(Genode::Platform::mmio_to_virt(Board::LOCAL_IRQ_CONTROLLER_BASE)) { } diff --git a/repos/base-hw/src/core/spec/arm/bcm2837_pic.h b/repos/base-hw/src/core/spec/arm/bcm2837_pic.h index 3454aa2ba5..3bdb3838e4 100644 --- a/repos/base-hw/src/core/spec/arm/bcm2837_pic.h +++ b/repos/base-hw/src/core/spec/arm/bcm2837_pic.h @@ -16,7 +16,11 @@ #include -namespace Board { class Pic; } +namespace Board { + + class Global_interrupt_controller { }; + class Pic; +} class Board::Pic : Genode::Mmio @@ -54,7 +58,7 @@ class Board::Pic : Genode::Mmio public: - Pic(); + Pic(Global_interrupt_controller &); bool take_request(unsigned &irq); void finish_request() { } diff --git a/repos/base-hw/src/core/spec/arm/trustzone_board.h b/repos/base-hw/src/core/spec/arm/trustzone_board.h index 59f5bf595c..28f7a616e0 100644 --- a/repos/base-hw/src/core/spec/arm/trustzone_board.h +++ b/repos/base-hw/src/core/spec/arm/trustzone_board.h @@ -27,7 +27,8 @@ namespace Board { struct Vm_page_table {}; struct Vm_page_table_array {}; - struct Pic : Hw::Pic { struct Virtual_context {}; }; + class Global_interrupt_controller { }; + struct Pic : Hw::Pic { struct Virtual_context {}; Pic(Global_interrupt_controller &) { } }; struct Vcpu_context { Vcpu_context(Kernel::Cpu &) {} }; } diff --git a/repos/base-hw/src/core/spec/arm/virtualization/gicv2.h b/repos/base-hw/src/core/spec/arm/virtualization/gicv2.h index c1bfb78420..e8500dadb1 100644 --- a/repos/base-hw/src/core/spec/arm/virtualization/gicv2.h +++ b/repos/base-hw/src/core/spec/arm/virtualization/gicv2.h @@ -16,7 +16,11 @@ #include -namespace Board { struct Pic; }; +namespace Board { + + class Global_interrupt_controller { }; + class Pic; +}; class Board::Pic : public Hw::Gicv2 @@ -50,6 +54,8 @@ class Board::Pic : public Hw::Gicv2 bool ack_virtual_irq(Virtual_context & c); void insert_virtual_irq(Virtual_context & c, unsigned irq); + + Pic(Global_interrupt_controller &) { } }; #endif /* _CORE__SPEC__ARM__VIRTUALIZATION__GICV2_H_ */ diff --git a/repos/base-hw/src/core/spec/arm/virtualization/gicv3.h b/repos/base-hw/src/core/spec/arm/virtualization/gicv3.h index 9b6e84ead3..c79ce3ba8b 100644 --- a/repos/base-hw/src/core/spec/arm/virtualization/gicv3.h +++ b/repos/base-hw/src/core/spec/arm/virtualization/gicv3.h @@ -16,7 +16,11 @@ #include -namespace Board { class Pic; }; +namespace Board { + + class Global_interrupt_controller { }; + class Pic; +}; class Board::Pic : public Hw::Pic @@ -51,6 +55,8 @@ class Board::Pic : public Hw::Pic c.lr = irq | 1ULL << 41 | 1ULL << 60 | 1ULL << 62; } + + Pic(Global_interrupt_controller &) { } }; #endif /* _CORE__SPEC__ARM__VIRTUALIZATION__GICV3_H_ */ diff --git a/repos/base-hw/src/core/spec/riscv/pic.cc b/repos/base-hw/src/core/spec/riscv/pic.cc index 9689f33423..a08b09daf4 100644 --- a/repos/base-hw/src/core/spec/riscv/pic.cc +++ b/repos/base-hw/src/core/spec/riscv/pic.cc @@ -16,7 +16,8 @@ #include #include -Board::Pic::Pic() : +Board::Pic::Pic(Global_interrupt_controller &) +: _plic(Genode::Platform::mmio_to_virt(Board::PLIC_BASE)) { /* enable external interrupts */ diff --git a/repos/base-hw/src/core/spec/riscv/pic.h b/repos/base-hw/src/core/spec/riscv/pic.h index f76e5d620c..d85ec9751f 100644 --- a/repos/base-hw/src/core/spec/riscv/pic.h +++ b/repos/base-hw/src/core/spec/riscv/pic.h @@ -20,7 +20,11 @@ #include #include -namespace Board { class Pic; } +namespace Board { + + class Global_interrupt_controller { }; + class Pic; +} /** @@ -44,7 +48,7 @@ class Board::Pic NR_OF_IRQ = Plic::NR_OF_IRQ, }; - Pic(); + Pic(Global_interrupt_controller &); bool take_request(unsigned & irq) { 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 4d011de116..d238774414 100644 --- a/repos/base-hw/src/core/spec/x86_64/pic.cc +++ b/repos/base-hw/src/core/spec/x86_64/pic.cc @@ -24,11 +24,8 @@ using namespace Genode; using namespace Board; - -uint8_t Pic::lapic_ids[NR_OF_CPUS]; - - enum { + REMAP_BASE = Board::VECTOR_REMAP_BASE, PIC_CMD_MASTER = 0x20, PIC_CMD_SLAVE = 0xa0, PIC_DATA_MASTER = 0x21, @@ -36,9 +33,15 @@ enum { }; -Pic::Pic() +/*************************************** + ** Board::Local_interrupt_controller ** + ***************************************/ + +Local_interrupt_controller:: +Local_interrupt_controller(Global_interrupt_controller &global_irq_ctrl) : - Mmio(Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base())) + Mmio { Platform::mmio_to_virt(Hw::Cpu_memory_map::lapic_phys_base()) }, + _global_irq_ctrl { global_irq_ctrl } { /* Start initialization sequence in cascade mode */ outb(PIC_CMD_MASTER, 0x11); @@ -68,7 +71,7 @@ Pic::Pic() } -bool Pic::take_request(unsigned &irq) +bool Local_interrupt_controller::take_request(unsigned &irq) { irq = get_lowest_bit(); if (!irq) { @@ -80,32 +83,33 @@ bool Pic::take_request(unsigned &irq) } -void Pic::finish_request() +void Local_interrupt_controller::finish_request() { write(0); } -void Pic::unmask(unsigned const i, unsigned) +void Local_interrupt_controller::unmask(unsigned const i, unsigned) { - ioapic.toggle_mask(i, false); + _global_irq_ctrl.toggle_mask(i, false); } -void Pic::mask(unsigned const i) +void Local_interrupt_controller::mask(unsigned const i) { - ioapic.toggle_mask(i, true); + _global_irq_ctrl.toggle_mask(i, true); } -void Pic::irq_mode(unsigned irq_number, unsigned trigger, - unsigned polarity) +void Local_interrupt_controller::irq_mode(unsigned irq_number, + unsigned trigger, + unsigned polarity) { - ioapic.irq_mode(irq_number, trigger, polarity); + _global_irq_ctrl.irq_mode(irq_number, trigger, polarity); } -inline unsigned Pic::get_lowest_bit(void) +inline unsigned Local_interrupt_controller::get_lowest_bit() { unsigned bit, vec_base = 0; @@ -120,7 +124,7 @@ inline unsigned Pic::get_lowest_bit(void) } -void Pic::send_ipi(unsigned const cpu_id) +void Local_interrupt_controller::send_ipi(unsigned const cpu_id) { while (read()) asm volatile("pause" : : : "memory"); @@ -128,9 +132,9 @@ void Pic::send_ipi(unsigned const cpu_id) Icr_high::access_t icr_high = 0; Icr_low::access_t icr_low = 0; - Icr_high::Destination::set(icr_high, lapic_ids[cpu_id]); + Icr_high::Destination::set(icr_high, _global_irq_ctrl.lapic_id(cpu_id)); - Icr_low::Vector::set(icr_low, Pic::IPI); + Icr_low::Vector::set(icr_low, Local_interrupt_controller::IPI); Icr_low::Level_assert::set(icr_low); /* program */ @@ -139,14 +143,26 @@ void Pic::send_ipi(unsigned const cpu_id) } -Ioapic::Irq_mode Ioapic::_irq_mode[IRQ_COUNT]; +/**************************************** + ** Board::Global_interrupt_controller ** + ****************************************/ + +uint8_t Global_interrupt_controller::lapic_id(unsigned cpu_id) const +{ + return _lapic_id[cpu_id]; +} -enum { REMAP_BASE = Board::VECTOR_REMAP_BASE }; +void Global_interrupt_controller::lapic_id(unsigned cpu_id, + uint8_t lapic_id) +{ + _lapic_id[cpu_id] = lapic_id; +} -void Ioapic::irq_mode(unsigned irq_number, unsigned trigger, - unsigned polarity) +void Global_interrupt_controller::irq_mode(unsigned irq_number, + unsigned trigger, + unsigned polarity) { const unsigned irq_nr = irq_number - REMAP_BASE; bool needs_sync = false; @@ -185,7 +201,7 @@ void Ioapic::irq_mode(unsigned irq_number, unsigned trigger, } -void Ioapic::_update_irt_entry(unsigned irq) +void Global_interrupt_controller::_update_irt_entry(unsigned irq) { Irte::access_t irte; @@ -200,7 +216,8 @@ void Ioapic::_update_irt_entry(unsigned irq) } -Irte::access_t Ioapic::_create_irt_entry(unsigned const irq) +Irte::access_t +Global_interrupt_controller::_create_irt_entry(unsigned const irq) { Irte::access_t irte = REMAP_BASE + irq; Irte::Mask::set(irte, 1); @@ -212,7 +229,7 @@ Irte::access_t Ioapic::_create_irt_entry(unsigned const irq) } -Ioapic::Ioapic() +Global_interrupt_controller::Global_interrupt_controller() : Mmio(Platform::mmio_to_virt(Hw::Cpu_memory_map::MMIO_IOAPIC_BASE)) { @@ -242,7 +259,8 @@ Ioapic::Ioapic() }; -void Ioapic::toggle_mask(unsigned const vector, bool const set) +void Global_interrupt_controller::toggle_mask(unsigned const vector, + bool const set) { /* * Ignore toggle requests for vectors not handled by the I/O APIC. 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 c3eb7d1ec2..eee97a058e 100644 --- a/repos/base-hw/src/core/spec/x86_64/pic.h +++ b/repos/base-hw/src/core/spec/x86_64/pic.h @@ -18,9 +18,6 @@ /* Genode includes */ #include -/* core includes */ -#include - namespace Board { /* @@ -31,12 +28,12 @@ namespace Board { /** * IO advanced programmable interrupt controller */ - class Ioapic; + class Global_interrupt_controller; /** * Programmable interrupt controller for core */ - class Pic; + class Local_interrupt_controller; enum { IRQ_COUNT = 256 }; } @@ -50,13 +47,10 @@ struct Board::Irte : Genode::Register<64> }; -class Board::Ioapic : public Genode::Mmio +class Board::Global_interrupt_controller : public Genode::Mmio { private: - /* Number of Redirection Table entries */ - unsigned _irte_count = 0; - enum { /* Register selectors */ IOAPICVER = 0x01, @@ -78,7 +72,19 @@ class Board::Ioapic : public Genode::Mmio unsigned polarity; }; - static Irq_mode _irq_mode[IRQ_COUNT]; + /* + * Registers + */ + + struct Ioregsel : Register<0x00, 32> { }; + struct Iowin : Register<0x10, 32> + { + struct Maximum_redirection_entry : Bitfield<16, 8> { }; + }; + + unsigned _irte_count = 0; /* number of redirection table entries */ + Genode::uint8_t _lapic_id[NR_OF_CPUS]; /* unique name of the LAPIC of each CPU */ + Irq_mode _irq_mode[IRQ_COUNT]; /** * Return whether 'irq' is an edge-triggered interrupt @@ -104,7 +110,7 @@ class Board::Ioapic : public Genode::Mmio public: - Ioapic(); + Global_interrupt_controller(); /** * Set/unset mask bit of IRTE for given vector @@ -112,7 +118,8 @@ class Board::Ioapic : public Genode::Mmio * \param vector targeted vector * \param set whether to set or to unset the mask bit */ - void toggle_mask(unsigned const vector, bool const set); + void toggle_mask(unsigned const vector, + bool const set); /** * Setup mode of an IRQ to specified trigger mode and polarity @@ -121,22 +128,23 @@ class Board::Ioapic : public Genode::Mmio * \param trigger new interrupt trigger mode * \param polarity new interrupt polarity setting */ - void irq_mode(unsigned irq_number, unsigned trigger, + void irq_mode(unsigned irq_number, + unsigned trigger, unsigned polarity); - /* - * Registers - */ - struct Ioregsel : Register<0x00, 32> { }; - struct Iowin : Register<0x10, 32> - { - struct Maximum_redirection_entry : Bitfield<16, 8> { }; - }; + /*************** + ** Accessors ** + ***************/ + + void lapic_id(unsigned cpu_id, + Genode::uint8_t lapic_id); + + Genode::uint8_t lapic_id(unsigned cpu_id) const; }; -class Board::Pic : public Genode::Mmio +class Board::Local_interrupt_controller : public Genode::Mmio { private: @@ -173,6 +181,8 @@ class Board::Pic : public Genode::Mmio struct Destination : Bitfield<24, 8> { }; }; + Global_interrupt_controller &_global_irq_ctrl; + /** * Determine lowest pending interrupt in ISR register * @@ -181,11 +191,6 @@ class Board::Pic : public Genode::Mmio */ inline unsigned get_lowest_bit(void); - /** - * Mapping of our logical boot CPUs to the local APIC IDs - */ - static Genode::uint8_t lapic_ids[NR_OF_CPUS]; - public: enum { @@ -201,9 +206,7 @@ class Board::Pic : public Genode::Mmio /** * Constructor */ - Pic(); - - Ioapic ioapic { }; + Local_interrupt_controller(Global_interrupt_controller &global_irq_ctrl); bool take_request(unsigned &irq); @@ -219,7 +222,7 @@ class Board::Pic : public Genode::Mmio { if (cpu_id < NR_OF_CPUS) { Id::access_t const lapic_id = read(); - lapic_ids[cpu_id] = (lapic_id >> 24) & 0xff; + _global_irq_ctrl.lapic_id(cpu_id, (lapic_id >> 24) & 0xff); } }