platform_drv/x86: support to disable MSI-X

+ disable for wifi driver MSI-X

Issue #4079
This commit is contained in:
Johannes Schlatow 2021-04-19 15:36:34 +02:00 committed by Norman Feske
parent 7b9e7361ba
commit 2db94b8438
6 changed files with 22 additions and 12 deletions

View File

@ -107,7 +107,7 @@ proc platform_drv_policy {} {
<policy label_prefix="ps2_drv"> <device name="PS2"/> </policy> <policy label_prefix="ps2_drv"> <device name="PS2"/> </policy>
<policy label_prefix="nic_drv"> <pci class="ETHERNET"/> </policy> <policy label_prefix="nic_drv"> <pci class="ETHERNET"/> </policy>
<policy label_prefix="fb_drv"> <pci class="VGA"/> </policy> <policy label_prefix="fb_drv"> <pci class="VGA"/> </policy>
<policy label_prefix="wifi_drv"> <pci class="WIFI"/> </policy> <policy label_prefix="wifi_drv" msix="false"> <pci class="WIFI"/> </policy>
<policy label_prefix="usb_drv"> <pci class="USB"/> </policy> <policy label_prefix="usb_drv"> <pci class="USB"/> </policy>
<policy label_prefix="ahci_drv"> <pci class="AHCI"/> </policy> <policy label_prefix="ahci_drv"> <pci class="AHCI"/> </policy>
<policy label_prefix="nvme_drv"> <pci class="NVME"/> </policy> <policy label_prefix="nvme_drv"> <pci class="NVME"/> </policy>

View File

@ -124,7 +124,7 @@
<pci bus="0" device="0" function="0"/> <pci bus="0" device="0" function="0"/>
<pci class="ISABRIDGE"/> <pci class="ISABRIDGE"/>
</policy> </policy>
<policy label_suffix="-> wifi"> <pci class="WIFI"/> </policy> <policy label_suffix="-> wifi" msix="false"> <pci class="WIFI"/> </policy>
<policy label_suffix="-> nic"> <pci class="ETHERNET"/> </policy> <policy label_suffix="-> nic"> <pci class="ETHERNET"/> </policy>
<policy label_suffix="-> audio"> <pci class="AUDIO"/> <pci class="HDAUDIO"/> </policy> <policy label_suffix="-> audio"> <pci class="AUDIO"/> <pci class="HDAUDIO"/> </policy>
<policy label="acpica"> </policy> <policy label="acpica"> </policy>

View File

@ -66,13 +66,15 @@ the device specified by the triple, the device will not appear during device
discovery by the client with the fuzzy pci class policy. discovery by the client with the fuzzy pci class policy.
By default the driver will try to use MSIs if the device and the used kernel By default the driver will try to use first MSI-X, then MSI and finally GSI.
supports it. This behaviour can be overwritten: However, the MSI-X/MSI feature depends on the support by the used kernel and
the PCI capabilities of the device. The MSI and MSI-X feature can be disabled
explicitly by configuration, e.g.:
!<start name="platform_drv" managing_system="yes"> !<start name="platform_drv" managing_system="yes">
! <resource name="RAM" quantum="8M"/> ! <resource name="RAM" quantum="8M"/>
! <config> ! <config>
! <policy label_prefix="nic_drv" irq_mode="nomsi"> ! <policy label_prefix="nic_drv" msi="false" msix="false">
! ... ! ...
! </policy> ! </policy>
! </config> ! </config>

View File

@ -175,10 +175,11 @@ Genode::Irq_session_capability Platform::Device_component::irq(uint8_t id)
uint16_t const msi_cap = _msi_cap(); uint16_t const msi_cap = _msi_cap();
uint16_t const msix_cap = _msix_cap(); uint16_t const msix_cap = _msix_cap();
bool const try_msi_msix = (_session.msi_usage() && msi_cap) ||
(_session.msix_usage() && msix_cap);
_irq_session = construct_at<Irq_session_component>(_mem_irq_component, _irq_session = construct_at<Irq_session_component>(_mem_irq_component,
_configure_irq(_irq_line, msi_cap, msix_cap), _configure_irq(_irq_line, msi_cap, msix_cap),
(!_session.msi_usage() || (!msi_cap && !msix_cap)) ? ~0UL : _config_space, try_msi_msix ? _config_space : ~0UL,
_env, _global_heap); _env, _global_heap);
_env.ep().rpc_ep().manage(_irq_session); _env.ep().rpc_ep().manage(_irq_session);
@ -186,7 +187,7 @@ Genode::Irq_session_capability Platform::Device_component::irq(uint8_t id)
bool msi_used = false; bool msi_used = false;
if (_irq_session->msi()) { if (_irq_session->msi()) {
if (msix_cap) if (_session.msix_usage() && msix_cap)
msix_used = _setup_msix(msix_cap); msix_used = _setup_msix(msix_cap);
if (!msix_used && msi_cap) if (!msix_used && msi_cap)
msi_used = _setup_msi(msi_cap); msi_used = _setup_msi(msi_cap);

View File

@ -221,7 +221,8 @@ class Platform::Session_component : public Rpc_object<Session>
Pci::Config::Delayer &_delayer; Pci::Config::Delayer &_delayer;
Device_bars_pool &_devices_bars; Device_bars_pool &_devices_bars;
bool _iommu; bool _iommu;
bool _msi_usage { true }; bool _msi_usage { true };
bool _msix_usage { true };
/** /**
* Registry of RAM dataspaces allocated by the session * Registry of RAM dataspaces allocated by the session
@ -499,8 +500,9 @@ class Platform::Session_component : public Rpc_object<Session>
{ {
Session_policy const policy { _label, _config.xml() }; Session_policy const policy { _label, _config.xml() };
typedef String<10> Mode; _msi_usage = policy.attribute_value("msi", _msi_usage);
_msi_usage = policy.attribute_value("irq_mode", Mode()) != "nomsi"; _msix_usage = _msi_usage &&
policy.attribute_value("msix", _msix_usage);
/* check policy for non-pci devices */ /* check policy for non-pci devices */
policy.for_each_sub_node("device", [&] (Xml_node device_node) { policy.for_each_sub_node("device", [&] (Xml_node device_node) {
@ -656,6 +658,11 @@ class Platform::Session_component : public Rpc_object<Session>
bool msi_usage() const { return _msi_usage; } bool msi_usage() const { return _msi_usage; }
/**
* Check whether msi-x usage was explicitly switched off
*/
bool msix_usage() const { return _msix_usage; }
/*************************** /***************************
** PCI session interface ** ** PCI session interface **
***************************/ ***************************/

View File

@ -180,7 +180,7 @@ source ${genode_dir}/repos/base/run/platform_drv.inc
proc platform_drv_policy {} { proc platform_drv_policy {} {
global use_wifi_driver global use_wifi_driver
if { $use_wifi_driver } { if { $use_wifi_driver } {
return {<policy label_prefix="nic_drv"> <pci class="WIFI"/> </policy>}} return {<policy label_prefix="nic_drv" msix="false"> <pci class="WIFI"/> </policy>}}
return {<policy label_prefix="usb_host_drv"> <pci class="USB"/> </policy>} return {<policy label_prefix="usb_host_drv"> <pci class="USB"/> </policy>}
} }