From e8556382661aa469335a1458d607335493218c7d Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Thu, 15 Aug 2019 14:41:09 +0200 Subject: [PATCH] hw: add system call for irq mode setting Core is not allowd to access the kernel's Pic implementation directly. fixes #3474 --- repos/base-hw/src/core/irq_session_component.cc | 2 +- repos/base-hw/src/core/kernel/core_interface.h | 12 ++++++++++++ repos/base-hw/src/core/kernel/thread.cc | 7 +++++++ repos/base-hw/src/core/kernel/thread.h | 1 + repos/base-hw/src/core/platform.h | 10 ---------- repos/base-hw/src/core/spec/arm/bcm2835_pic.cc | 3 +++ repos/base-hw/src/core/spec/arm/bcm2835_pic.h | 1 + repos/base-hw/src/core/spec/arm/bcm2837_pic.cc | 3 +++ repos/base-hw/src/core/spec/arm/bcm2837_pic.h | 1 + repos/base-hw/src/core/spec/arm/platform_support.cc | 2 -- repos/base-hw/src/core/spec/riscv/pic.h | 1 + .../base-hw/src/core/spec/riscv/platform_support.cc | 2 -- repos/base-hw/src/core/spec/x86_64/muen/pic.h | 1 + .../src/core/spec/x86_64/muen/platform_support.cc | 3 --- repos/base-hw/src/core/spec/x86_64/pic.cc | 10 ++++++++-- repos/base-hw/src/core/spec/x86_64/pic.h | 6 ++++-- .../base-hw/src/core/spec/x86_64/platform_support.cc | 9 --------- repos/base-hw/src/include/hw/spec/arm/gicv2.h | 5 +++++ repos/base-hw/src/include/hw/spec/arm/gicv3.h | 2 ++ repos/base-hw/src/include/hw/spec/arm/imx_tzic.h | 2 ++ 20 files changed, 52 insertions(+), 31 deletions(-) diff --git a/repos/base-hw/src/core/irq_session_component.cc b/repos/base-hw/src/core/irq_session_component.cc index 333241ef74..0fadd987c6 100644 --- a/repos/base-hw/src/core/irq_session_component.cc +++ b/repos/base-hw/src/core/irq_session_component.cc @@ -92,5 +92,5 @@ Irq_session_component::Irq_session_component(Range_allocator &irq_alloc, Irq_args const irq_args(args); - Platform::setup_irq_mode(_irq_number, irq_args.trigger(), irq_args.polarity()); + Kernel::irq_mode(_irq_number, irq_args.trigger(), irq_args.polarity()); } diff --git a/repos/base-hw/src/core/kernel/core_interface.h b/repos/base-hw/src/core/kernel/core_interface.h index 81848c5d48..8620df663f 100644 --- a/repos/base-hw/src/core/kernel/core_interface.h +++ b/repos/base-hw/src/core/kernel/core_interface.h @@ -60,6 +60,7 @@ namespace Kernel constexpr Call_arg call_id_delete_obj() { return 122; } constexpr Call_arg call_id_cancel_thread_blocking() { return 123; } constexpr Call_arg call_id_new_core_thread() { return 124; } + constexpr Call_arg call_id_irq_mode() { return 125; } /** * Invalidate TLB entries for the `pd` in region `addr`, `sz` @@ -207,6 +208,17 @@ namespace Kernel return call(call_id_new_irq(), (Call_arg) p, irq_nr, signal_context_id); } + /** + * Set trigger/polaruty of IRQ + * \param irq_nr interrupt number + * \param trigger low or edge + * \param polarity low or high + */ + inline void irq_mode(unsigned irq_nr, unsigned trigger, unsigned polarity) + { + call(call_id_irq_mode(), irq_nr, trigger, polarity); + } + /** * Acknowledge interrupt * diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index 68e4c97533..8e86e0b4e7 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -577,6 +577,12 @@ void Thread::_call_new_irq() user_arg_0(0); } +void Thread::_call_irq_mode() +{ + cpu_pool().executing_cpu().pic().irq_mode(user_arg_1(), user_arg_2(), + user_arg_3()); +} + void Thread::_call_ack_irq() { reinterpret_cast(user_arg_1())->enable(); } @@ -706,6 +712,7 @@ void Thread::_call() case call_id_pause_vm(): _call_pause_vm(); return; case call_id_pause_thread(): _call_pause_thread(); return; case call_id_new_irq(): _call_new_irq(); return; + case call_id_irq_mode(): _call_irq_mode(); return; case call_id_delete_irq(): _call_delete(); return; case call_id_ack_irq(): _call_ack_irq(); return; case call_id_new_obj(): _call_new_obj(); return; diff --git a/repos/base-hw/src/core/kernel/thread.h b/repos/base-hw/src/core/kernel/thread.h index 7fa857eedd..1a384fd3c9 100644 --- a/repos/base-hw/src/core/kernel/thread.h +++ b/repos/base-hw/src/core/kernel/thread.h @@ -228,6 +228,7 @@ class Kernel::Thread void _call_pause_vm(); void _call_pager(); void _call_new_irq(); + void _call_irq_mode(); void _call_ack_irq(); void _call_new_obj(); void _call_delete_obj(); diff --git a/repos/base-hw/src/core/platform.h b/repos/base-hw/src/core/platform.h index e96f898165..4a8288f931 100644 --- a/repos/base-hw/src/core/platform.h +++ b/repos/base-hw/src/core/platform.h @@ -94,16 +94,6 @@ class Genode::Platform : public Genode::Platform_generic */ static long irq(long const user_irq); - /** - * Setup mode of an IRQ to specified trigger mode and polarity - * - * \param irq_number ID of targeted interrupt - * \param trigger new interrupt trigger mode - * \param polarity new interrupt polarity setting - */ - static void setup_irq_mode(unsigned irq_number, unsigned trigger, - unsigned polarity); - /** * Get MSI-related parameters from device PCI config space * 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 bfb3cba525..c014a77126 100644 --- a/repos/base-hw/src/core/spec/arm/bcm2835_pic.cc +++ b/repos/base-hw/src/core/spec/arm/bcm2835_pic.cc @@ -136,3 +136,6 @@ void Board::Pic::mask(unsigned const i) else write(1 << (i - 8 - 32)); } + + +void Board::Pic::irq_mode(unsigned, unsigned, unsigned) { } 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 8f8ea420d5..f356a02108 100644 --- a/repos/base-hw/src/core/spec/arm/bcm2835_pic.h +++ b/repos/base-hw/src/core/spec/arm/bcm2835_pic.h @@ -115,6 +115,7 @@ class Board::Pic : Genode::Mmio void mask(); void unmask(unsigned const i, unsigned); void mask(unsigned const i); + void irq_mode(unsigned, unsigned, unsigned); static constexpr bool fast_interrupts() { return false; } }; 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 6de4699bec..85894c6257 100644 --- a/repos/base-hw/src/core/spec/arm/bcm2837_pic.cc +++ b/repos/base-hw/src/core/spec/arm/bcm2837_pic.cc @@ -56,3 +56,6 @@ void Board::Pic::mask(unsigned const i) Genode::raw("irq of peripherals != timer not implemented yet!"); } + + +void Board::Pic::irq_mode(unsigned, unsigned, unsigned) { } 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 4f2eabb853..f5f65998fc 100644 --- a/repos/base-hw/src/core/spec/arm/bcm2837_pic.h +++ b/repos/base-hw/src/core/spec/arm/bcm2837_pic.h @@ -59,6 +59,7 @@ class Board::Pic : Genode::Mmio void mask(); void unmask(unsigned const i, unsigned); void mask(unsigned const i); + void irq_mode(unsigned, unsigned, unsigned); static constexpr bool fast_interrupts() { return false; } }; diff --git a/repos/base-hw/src/core/spec/arm/platform_support.cc b/repos/base-hw/src/core/spec/arm/platform_support.cc index 08cb0c40d0..495814e91c 100644 --- a/repos/base-hw/src/core/spec/arm/platform_support.cc +++ b/repos/base-hw/src/core/spec/arm/platform_support.cc @@ -20,8 +20,6 @@ void Platform::_init_io_port_alloc() { }; void Platform::_init_additional_platform_info(Genode::Xml_generator&) { } -void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } - long Platform::irq(long const user_irq) { return user_irq; } bool Platform::get_msi_params(const addr_t /* mmconf */, addr_t & /* address */, diff --git a/repos/base-hw/src/core/spec/riscv/pic.h b/repos/base-hw/src/core/spec/riscv/pic.h index db66fb01ec..4d3497f7e4 100644 --- a/repos/base-hw/src/core/spec/riscv/pic.h +++ b/repos/base-hw/src/core/spec/riscv/pic.h @@ -39,6 +39,7 @@ class Board::Pic void unmask(unsigned, unsigned) { } void mask(unsigned) { } void finish_request() { } + void irq_mode(unsigned, unsigned, unsigned) { } }; #endif /* _CORE__SPEC__RISCV__PIC_H_ */ diff --git a/repos/base-hw/src/core/spec/riscv/platform_support.cc b/repos/base-hw/src/core/spec/riscv/platform_support.cc index 7cf502ae7d..b64d2d97b0 100644 --- a/repos/base-hw/src/core/spec/riscv/platform_support.cc +++ b/repos/base-hw/src/core/spec/riscv/platform_support.cc @@ -25,8 +25,6 @@ void Platform::_init_io_port_alloc() { } void Platform::_init_additional_platform_info(Genode::Xml_generator&) { } -void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } - long Platform::irq(long const /* user_irq */) { return 0; } bool Platform::get_msi_params(addr_t /* mmconf */, addr_t & /* address */, diff --git a/repos/base-hw/src/core/spec/x86_64/muen/pic.h b/repos/base-hw/src/core/spec/x86_64/muen/pic.h index 0d3161a149..ef28aee6a9 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/pic.h +++ b/repos/base-hw/src/core/spec/x86_64/muen/pic.h @@ -62,6 +62,7 @@ class Board::Pic void mask(unsigned const) { } bool is_ip_interrupt(unsigned, unsigned) { return false; } void store_apic_id(unsigned const) { } + void irq_mode(unsigned, unsigned, unsigned) { } private: diff --git a/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc b/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc index fe565093c1..e5933c00d6 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc +++ b/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc @@ -59,9 +59,6 @@ struct Msi_address : Register<32> }; -void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } - - bool Platform::get_msi_params(const addr_t mmconf, addr_t &address, addr_t &data, unsigned &irq_number) { 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 58a4d98935..9affd139fa 100644 --- a/repos/base-hw/src/core/spec/x86_64/pic.cc +++ b/repos/base-hw/src/core/spec/x86_64/pic.cc @@ -88,6 +88,12 @@ void Pic::mask(unsigned const i) ioapic.toggle_mask(i, true); } +void Pic::irq_mode(unsigned irq_number, unsigned trigger, + unsigned polarity) +{ + ioapic.irq_mode(irq_number, trigger, polarity); +} + inline unsigned Pic::get_lowest_bit(void) { unsigned bit, vec_base = 0; @@ -125,8 +131,8 @@ Ioapic::Irq_mode Ioapic::_irq_mode[IRQ_COUNT]; enum { REMAP_BASE = Board::VECTOR_REMAP_BASE }; -void Ioapic::setup_irq_mode(unsigned irq_number, unsigned trigger, - unsigned polarity) +void Ioapic::irq_mode(unsigned irq_number, unsigned trigger, + unsigned polarity) { const unsigned irq_nr = irq_number - REMAP_BASE; bool needs_sync = false; 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 6f6d896de2..7af7a95145 100644 --- a/repos/base-hw/src/core/spec/x86_64/pic.h +++ b/repos/base-hw/src/core/spec/x86_64/pic.h @@ -119,8 +119,8 @@ class Board::Ioapic : public Genode::Mmio * \param trigger new interrupt trigger mode * \param polarity new interrupt polarity setting */ - void setup_irq_mode(unsigned irq_number, unsigned trigger, - unsigned polarity); + void irq_mode(unsigned irq_number, unsigned trigger, + unsigned polarity); /* * Registers @@ -207,6 +207,8 @@ class Board::Pic : public Genode::Mmio void mask(unsigned const i); + void irq_mode(unsigned irq, unsigned trigger, unsigned polarity); + void store_apic_id(unsigned const cpu_id) { Id::access_t const lapic_id = read(); lapic_ids[cpu_id] = (lapic_id >> 24) & 0xff; diff --git a/repos/base-hw/src/core/spec/x86_64/platform_support.cc b/repos/base-hw/src/core/spec/x86_64/platform_support.cc index 2637f68972..7f5e805c26 100644 --- a/repos/base-hw/src/core/spec/x86_64/platform_support.cc +++ b/repos/base-hw/src/core/spec/x86_64/platform_support.cc @@ -59,15 +59,6 @@ void Platform::_init_additional_platform_info(Xml_generator &xml) } -void Platform::setup_irq_mode(unsigned irq_number, unsigned trigger, - unsigned polarity) -{ - Kernel::cpu_pool().executing_cpu().pic().ioapic.setup_irq_mode(irq_number, - trigger, - polarity); -} - - bool Platform::get_msi_params(addr_t, addr_t &, addr_t &, unsigned &) { return false; } diff --git a/repos/base-hw/src/include/hw/spec/arm/gicv2.h b/repos/base-hw/src/include/hw/spec/arm/gicv2.h index 501520e48d..c98065f560 100644 --- a/repos/base-hw/src/include/hw/spec/arm/gicv2.h +++ b/repos/base-hw/src/include/hw/spec/arm/gicv2.h @@ -220,6 +220,11 @@ class Hw::Gicv2 void mask(unsigned const irq_id) { _distr.write(1, irq_id); } + /** + * Set trigger and polarity + */ + void irq_mode(unsigned, unsigned, unsigned) { } + /** * Raise inter-processor IRQ of the CPU with kernel name 'cpu_id' */ diff --git a/repos/base-hw/src/include/hw/spec/arm/gicv3.h b/repos/base-hw/src/include/hw/spec/arm/gicv3.h index d5e113b082..7da0c2adb9 100644 --- a/repos/base-hw/src/include/hw/spec/arm/gicv3.h +++ b/repos/base-hw/src/include/hw/spec/arm/gicv3.h @@ -255,6 +255,8 @@ class Hw::Pic _distr.write(1, irq_id); } } + + void irq_mode(unsigned, unsigned, unsigned) { } }; #undef SYSTEM_REGISTER diff --git a/repos/base-hw/src/include/hw/spec/arm/imx_tzic.h b/repos/base-hw/src/include/hw/spec/arm/imx_tzic.h index 0777fa3b32..77c1a3d947 100644 --- a/repos/base-hw/src/include/hw/spec/arm/imx_tzic.h +++ b/repos/base-hw/src/include/hw/spec/arm/imx_tzic.h @@ -104,6 +104,8 @@ class Hw::Pic : public Genode::Mmio void finish_request() { } + void irq_mode(unsigned, unsigned, unsigned) { } + /** * Unmask interrupt 'i' */