hw: implement MSI support for x86

Fix genodelabs/genode#4633
This commit is contained in:
Stefan Kalkowski 2022-10-06 14:17:35 +02:00 committed by Christian Helmuth
parent 5e4e634625
commit 759ed40d98
6 changed files with 48 additions and 21 deletions

View File

@ -58,6 +58,7 @@ Irq_session_component::~Irq_session_component()
using namespace Kernel;
_irq_alloc.free((void *)(addr_t)_irq_number);
if (_is_msi) Platform::free_msi_vector(_address, _value);
}
@ -72,10 +73,10 @@ Irq_session_component::Irq_session_component(Range_allocator &irq_alloc,
Arg_string::find_arg(args, "device_config_phys").long_value(0);
if (mmconf) {
_is_msi =
Platform::get_msi_params(mmconf, _address, _value, _irq_number);
_is_msi = Platform::alloc_msi_vector(_address, _value);
if (!_is_msi)
throw Service_denied();
_irq_number = (unsigned) _value;
}
/* allocate interrupt */

View File

@ -161,6 +161,7 @@ void Platform::_init_platform_info()
xml.node("kernel", [&] () {
xml.attribute("name", "hw");
xml.attribute("acpi", true);
xml.attribute("msi", true);
});
_init_additional_platform_info(xml);
xml.node("affinity-space", [&] () {

View File

@ -97,18 +97,22 @@ class Genode::Platform : public Genode::Platform_generic
static long irq(long const user_irq);
/**
* Get MSI-related parameters from device PCI config space
* Allocate MSI exception vector entry
*
* \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
* \param address MSI address register value to use
* \param data MSI data register value to use
*
* \return true if the device is MSI-capable, false if not
* \return true if the platform is MSI-capable, false if not
*/
static bool get_msi_params(const addr_t mmconf,
addr_t &address, addr_t &data,
unsigned &irq_number);
static bool alloc_msi_vector(addr_t &address, addr_t &data);
/**
* Allocate MSI exception vector entry
*
* \param address MSI address register value to free
* \param data MSI data register value to free
*/
static void free_msi_vector(addr_t address, addr_t data);
static addr_t core_phys_addr(addr_t virt);

View File

@ -26,8 +26,7 @@ void Platform::_init_additional_platform_info(Genode::Xml_generator&) { }
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;
}
bool Platform::alloc_msi_vector(addr_t &, addr_t &) { return false; }
void Platform::free_msi_vector(addr_t, addr_t) { }

View File

@ -28,6 +28,7 @@ void Platform::_init_additional_platform_info(Genode::Xml_generator&) { }
long Platform::irq(long const user_irq ) { return user_irq; }
bool Platform::get_msi_params(addr_t /* mmconf */, addr_t & /* address */,
addr_t & /* data */, unsigned & /* irq_number */) {
return false; }
bool Platform::alloc_msi_vector(addr_t &, addr_t &) { return false; }
void Platform::free_msi_vector(addr_t, addr_t) { }

View File

@ -15,6 +15,7 @@
#include <platform.h>
#include <kernel/cpu.h>
#include <map_local.h>
#include <hw/spec/x86_64/x86_64.h>
using namespace Genode;
@ -60,8 +61,28 @@ void Platform::_init_additional_platform_info(Xml_generator &xml)
}
bool Platform::get_msi_params(addr_t, addr_t &, addr_t &, unsigned &) {
return false; }
Genode::Bit_allocator<64> & msi_allocator()
{
static Genode::Bit_allocator<64> msi_allocator;
return msi_allocator;
}
bool Platform::alloc_msi_vector(addr_t & address, addr_t & value)
{
try {
address = Hw::Cpu_memory_map::lapic_phys_base();
value = Board::Pic::IPI - 1 - msi_allocator().alloc();
return true;
} catch(...) {}
return false;
}
void Platform::free_msi_vector(addr_t, addr_t value)
{
msi_allocator().free(Board::Pic::IPI - 1 - value);
}
Board::Serial::Serial(addr_t, size_t, unsigned baudrate)