pci_decode: use MSI enumerator as function value

Instead of using a global value to enumerate the MSIs, use a function argument
instead. Whenever the process of PCI device reporting gets started again,
due to an initially too small report buffer, the MSI enumeration value is reset
again. Formerly, we wasted MSI numbers.

Ref genodelabs/genode#4628
This commit is contained in:
Stefan Kalkowski 2022-10-05 14:57:04 +02:00 committed by Christian Helmuth
parent 08f1f94fcb
commit 243c819257

View File

@ -37,13 +37,6 @@ struct Main
Expanding_reporter pci_reporter { env, "devices", "devices" };
Registry<Bridge> bridge_registry {}; /* contains host bridges */
/*
* We count beginning from 1 not 0, because some clients (Linux drivers)
* do not ignore the pseudo MSI number announced, but interpret zero as
* invalid.
*/
unsigned msi_number { 1U };
bool apic_capable { false };
bool msi_capable { false };
@ -55,9 +48,9 @@ struct Main
void parse_pci_function(Bdf bdf, Config & cfg,
addr_t cfg_phys_base,
Xml_generator & generator);
void parse_pci_bus(bus_t bus, bus_t offset, addr_t base,
addr_t phys_base, Xml_generator & generator);
Xml_generator & generator, unsigned & msi);
void parse_pci_bus(bus_t bus, bus_t offset, addr_t base, addr_t phys_base,
Xml_generator & generator, unsigned & msi);
void parse_irq_override_rules(Xml_node & xml);
void parse_pci_config_spaces(Xml_node & xml);
@ -77,7 +70,8 @@ struct Main
void Main::parse_pci_function(Bdf bdf,
Config & cfg,
addr_t cfg_phys_base,
Xml_generator & gen)
Xml_generator & gen,
unsigned & msi_number)
{
cfg.scan();
@ -207,7 +201,8 @@ void Main::parse_pci_bus(bus_t bus,
bus_t offset,
addr_t base,
addr_t phys_base,
Xml_generator & generator)
Xml_generator & generator,
unsigned & msi_number)
{
auto per_function = [&] (addr_t config_base, addr_t config_phys_base,
dev_t dev, func_t fn) {
@ -216,7 +211,7 @@ void Main::parse_pci_bus(bus_t bus,
return true;
parse_pci_function({(bus_t)(bus+offset), dev, fn}, cfg,
config_phys_base, generator);
config_phys_base, generator, msi_number);
return !(fn == 0 && !cfg.read<Config::Header_type::Multi_function>());
};
@ -239,6 +234,12 @@ void Main::parse_pci_config_spaces(Xml_node & xml)
{
pci_reporter.generate([&] (Xml_generator & generator)
{
/*
* We count beginning from 1 not 0, because some clients (Linux drivers)
* do not ignore the pseudo MSI number announced, but interpret zero as
* invalid.
*/
unsigned msi_number = 1;
unsigned host_bridge_num = 0;
xml.for_each_sub_node("bdf", [&] (Xml_node & xml)
@ -265,7 +266,7 @@ void Main::parse_pci_config_spaces(Xml_node & xml)
do
parse_pci_bus((bus_t)bus, bus_off,
(addr_t)pci_config_ds->local_addr<void>(),
base, generator);
base, generator, msi_number);
while (bus++ < last_bus);
pci_config_ds.destruct();