From 3350c6bf5323b74f2f4387fd7d2395691f08e9ac Mon Sep 17 00:00:00 2001 From: Reto Buerki Date: Tue, 16 Feb 2016 16:51:50 +0100 Subject: [PATCH] hw: Introduce platform-specifc MSI function The platform-specific get_msi_params function returns MSI parameters for a device identified by PCI config space address. The function returns false if either the platform or the device does not support MSI mode of operation. --- repos/base-hw/src/core/include/platform.h | 13 +++++++++++++ repos/base-hw/src/core/irq_session_component.cc | 12 +++++++++--- repos/base-hw/src/core/spec/arm/platform_support.cc | 7 +++++++ .../base-hw/src/core/spec/riscv/platform_support.cc | 6 ++++++ .../src/core/spec/x86_64/muen/platform_support.cc | 8 ++++++++ .../src/core/spec/x86_64/platform_support.cc | 7 +++++++ 6 files changed, 50 insertions(+), 3 deletions(-) diff --git a/repos/base-hw/src/core/include/platform.h b/repos/base-hw/src/core/include/platform.h index 55a206d6d..cf0482f58 100644 --- a/repos/base-hw/src/core/include/platform.h +++ b/repos/base-hw/src/core/include/platform.h @@ -121,6 +121,19 @@ namespace Genode { static void setup_irq_mode(unsigned irq_number, unsigned trigger, unsigned polarity); + /** + * Get MSI-related parameters from device PCI config space + * + * \param mmconf PCI config space address of device + * \param address MSI address register value to use + * \param data MSI data register value to use + * \param irq_number IRQ to use + * + * \return true if the device is MSI-capable, false if not + */ + static bool get_msi_params(const addr_t mmconf, + addr_t &address, addr_t &data, + unsigned &irq_number); /** * Return address of cores translation table allocator */ diff --git a/repos/base-hw/src/core/irq_session_component.cc b/repos/base-hw/src/core/irq_session_component.cc index acdba3094..2aec0d4c3 100644 --- a/repos/base-hw/src/core/irq_session_component.cc +++ b/repos/base-hw/src/core/irq_session_component.cc @@ -69,9 +69,15 @@ Irq_session_component::Irq_session_component(Range_allocator * const irq_alloc, _irq_number(Platform::irq(_find_irq_number(args))), _irq_alloc(irq_alloc), _is_msi(false), _address(0), _value(0) { - long const msi = Arg_string::find_arg(args, "device_config_phys").long_value(0); - if (msi) - throw Root::Unavailable(); + const long mmconf = + Arg_string::find_arg(args, "device_config_phys").long_value(0); + + if (mmconf) { + _is_msi = + Platform::get_msi_params(mmconf, _address, _value, _irq_number); + if (!_is_msi) + throw Root::Unavailable(); + } /* allocate interrupt */ if (_irq_alloc->alloc_addr(1, _irq_number).is_error()) { 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 1da35be4b..2a2a39ea2 100644 --- a/repos/base-hw/src/core/spec/arm/platform_support.cc +++ b/repos/base-hw/src/core/spec/arm/platform_support.cc @@ -36,3 +36,10 @@ void Platform::_init_io_mem_alloc() long Platform::irq(long const user_irq) { return user_irq; } + + +bool Platform::get_msi_params(const addr_t mmconf, addr_t &address, + addr_t &data, unsigned &irq_number) +{ + return false; +} 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 a60d89397..6cdfc0030 100644 --- a/repos/base-hw/src/core/spec/riscv/platform_support.cc +++ b/repos/base-hw/src/core/spec/riscv/platform_support.cc @@ -37,3 +37,9 @@ void Platform::_init_io_mem_alloc() { } void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } long Platform::irq(long const user_irq) { return 0; } + +bool Platform::get_msi_params(const addr_t mmconf, addr_t &address, + addr_t &data, unsigned &irq_number) +{ + return false; +} 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 f50a6d72b..7927f674f 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 @@ -29,9 +29,17 @@ Native_region * Platform::_core_only_mmio_regions(unsigned const i) return i < sizeof(_regions)/sizeof(_regions[0]) ? &_regions[i] : 0; } + 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) +{ + return false; +} + + Native_region * Platform::_ram_regions(unsigned const i) { static Native_region _regions[] = 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 c9820e095..6529278e6 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 @@ -49,6 +49,13 @@ void Platform::setup_irq_mode(unsigned irq_number, unsigned trigger, } +bool Platform::get_msi_params(const addr_t mmconf, addr_t &address, + addr_t &data, unsigned &irq_number) +{ + return false; +} + + Native_region * Platform::_ram_regions(unsigned const i) { static Native_region _regions[16];