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); } }