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.
This commit is contained in:
Reto Buerki 2016-02-16 16:51:50 +01:00 committed by Christian Helmuth
parent 11ee72eaa6
commit 3350c6bf53
6 changed files with 50 additions and 3 deletions

View File

@ -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
*/

View File

@ -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()) {

View File

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

View File

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

View File

@ -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[] =

View File

@ -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];