driver/platform: re-configure bridges on resume

Fixes #5241
This commit is contained in:
Alexander Boettcher 2024-06-06 11:40:01 +02:00 committed by Norman Feske
parent 3216733a05
commit 8b0a16d750
3 changed files with 49 additions and 0 deletions

View File

@ -91,6 +91,14 @@ struct Config_helper
Config::Command::Io_space_enable::set(cmd, 1);
});
/* enable i/o space for bridges when I/O base/limit are defined */
if (_config.bridge() && (_cfg.io_base_limit || _cfg.io_base_limit_upper))
Config::Command::Io_space_enable::set(cmd, 1);
/* enable memory space for bridges when I/O mem limit is defined */
if (_config.bridge() && _cfg.memory_limit)
Config::Command::Memory_space_enable::set(cmd, 1);
_config.write<Config::Command>(cmd);
}
@ -296,3 +304,39 @@ void Driver::pci_device_specific_info(Device const & dev,
Driver::pci_virtio_info(dev, cfg, env, xml);
});
}
void Driver::pci_resume_bridges(Env & env, Device_model & devices)
{
devices.for_each([&](Device & device) {
device.for_pci_config([&](Device::Pci_config const & pc) {
if (!pc.bridge)
return;
try {
Config_helper config(env, device, pc);
Config_type1 bridge(config._config.range());
using C1 = Config_type1;
bridge.write<C1::Io_base_limit>(pc.io_base_limit);
bridge.write<C1::Memory_base> (pc.memory_base);
bridge.write<C1::Memory_limit> (pc.memory_limit);
bridge.write<C1::Prefetchable_memory_base> (pc.prefetch_memory_base);
bridge.write<C1::Prefetchable_memory_base_upper> (pc.prefetch_memory_base_upper);
bridge.write<C1::Prefetchable_memory_limit_upper>(pc.prefetch_memory_limit_upper);
bridge.write<C1::Io_base_limit_upper> (pc.io_base_limit_upper);
bridge.write<C1::Expansion_rom_base_addr> (pc.expansion_rom_base);
bridge.write<C1::Bridge_control> (pc.bridge_control);
config.enable();
} catch (Genode::Service_denied) {
Bdf bdf(pc.bus_num, pc.dev_num, pc.func_num);
error("resuming bridge ", bdf, " failed");
}
});
});
}

View File

@ -41,6 +41,7 @@ namespace Driver {
Env & env,
Device_model & model,
Xml_generator & xml);
void pci_resume_bridges(Env &, Device_model &);
}
#endif /* _SRC__DRIVERS__PLATFORM__PCI_H_ */

View File

@ -14,6 +14,7 @@
#include <base/component.h>
#include <common.h>
#include <pci.h>
#include <intel/io_mmu.h>
namespace Driver { struct Main; };
@ -111,6 +112,9 @@ void Driver::Main::_system_update()
_common.io_mmu_devices().for_each([&] (Driver::Io_mmu & io_mmu) {
io_mmu.resume();
});
Driver::pci_resume_bridges(_env, _common.devices());
/* report independent of result */
_common.report_resume();
}