platform(x86): report features via platform_info

Report via platform_info the capabilities of the kernel, e.g. ACPI and MSI.

With the commit the try-catch pattern on IRQ session creation by the platform
driver is avoided.

Issue #4016
This commit is contained in:
Alexander Boettcher 2021-05-25 08:12:53 +02:00 committed by Christian Helmuth
parent e1abd2db4e
commit 509e5aa776
6 changed files with 51 additions and 34 deletions

View File

@ -493,7 +493,11 @@ Platform::Platform()
pages << get_page_size_log2(), pages << get_page_size_log2(),
"platform_info", [&] () "platform_info", [&] ()
{ {
xml.node("kernel", [&] () { xml.attribute("name", "foc"); }); xml.node("kernel", [&] () {
xml.attribute("name", "foc");
xml.attribute("acpi", true);
xml.attribute("msi" , true);
});
xml.node("hardware", [&] () { xml.node("hardware", [&] () {
_setup_platform_info(xml, sigma0_map_kip()); }); _setup_platform_info(xml, sigma0_map_kip()); });

View File

@ -132,7 +132,10 @@ void Platform::_init_platform_info()
Genode::Xml_generator xml(reinterpret_cast<char *>(virt_addr), Genode::Xml_generator xml(reinterpret_cast<char *>(virt_addr),
rom_size, rom_name, [&] () rom_size, rom_name, [&] ()
{ {
xml.node("kernel", [&] () { xml.attribute("name", "hw"); }); xml.node("kernel", [&] () {
xml.attribute("name", "hw");
xml.attribute("acpi", true);
});
_init_additional_platform_info(xml); _init_additional_platform_info(xml);
xml.node("affinity-space", [&] () { xml.node("affinity-space", [&] () {
xml.attribute("width", affinity_space().width()); xml.attribute("width", affinity_space().width());

View File

@ -680,7 +680,11 @@ Platform::Platform()
pages << get_page_size_log2(), pages << get_page_size_log2(),
"platform_info", [&] () "platform_info", [&] ()
{ {
xml.node("kernel", [&] () { xml.attribute("name", "nova"); }); xml.node("kernel", [&] () {
xml.attribute("name", "nova");
xml.attribute("acpi", true);
xml.attribute("msi" , true);
});
if (efi_sys_tab_phy) { if (efi_sys_tab_phy) {
xml.node("efi-system-table", [&] () { xml.node("efi-system-table", [&] () {
xml.attribute("address", String<32>(Hex(efi_sys_tab_phy))); xml.attribute("address", String<32>(Hex(efi_sys_tab_phy)));

View File

@ -404,7 +404,10 @@ void Platform::_init_rom_modules()
tsc_freq const * boot_freq = reinterpret_cast<tsc_freq const *>(reinterpret_cast<addr_t>(element) + sizeof(* element)); tsc_freq const * boot_freq = reinterpret_cast<tsc_freq const *>(reinterpret_cast<addr_t>(element) + sizeof(* element));
xml.node("kernel", [&] () { xml.attribute("name", "sel4"); }); xml.node("kernel", [&] () {
xml.attribute("name", "sel4");
xml.attribute("acpi", true);
});
xml.node("hardware", [&] () { xml.node("hardware", [&] () {
xml.node("features", [&] () { xml.node("features", [&] () {
#ifdef CONFIG_VTX #ifdef CONFIG_VTX

View File

@ -50,7 +50,6 @@ struct Platform::Main
Capability<Typed_root<Platform::Session_component> > root_cap { }; Capability<Typed_root<Platform::Session_component> > root_cap { };
bool const _acpi_platform;
bool _acpi_ready = false; bool _acpi_ready = false;
void _attempt_acpi_reset(); void _attempt_acpi_reset();
@ -63,8 +62,20 @@ struct Platform::Main
if (!acpi_rom->valid()) if (!acpi_rom->valid())
return; return;
bool msi_platform = false;
bool acpi_platform = false;
try {
Attached_rom_dataspace info { _env, "platform_info" };
info.xml().with_sub_node("kernel", [&] (Xml_node const &node) {
acpi_platform = node.attribute_value("acpi", acpi_platform);
msi_platform = node.attribute_value("msi" , msi_platform);
});
} catch (...) { }
root.construct(_env, sliced_heap, _config, root.construct(_env, sliced_heap, _config,
acpi_rom->local_addr<const char>(), _acpi_platform); acpi_rom->local_addr<const char>(), acpi_platform,
msi_platform);
} }
if (root_cap.valid()) if (root_cap.valid())
@ -134,25 +145,7 @@ struct Platform::Main
} }
} }
static bool acpi_platform(Env & env) Main(Env &env) : _env(env)
{
using Name = String<32>;
try {
Attached_rom_dataspace info { env, "platform_info" };
Name kernel =
info.xml().sub_node("kernel").attribute_value("name", Name());
if (kernel == "hw" ||
kernel == "nova" ||
kernel == "foc" ||
kernel == "sel4") { return true; }
} catch (...) {}
return false;
}
Main(Env &env)
:
_env(env),
_acpi_platform(acpi_platform(env))
{ {
_config.sigh(_config_handler); _config.sigh(_config_handler);

View File

@ -220,7 +220,8 @@ class Platform::Session_component : public Rpc_object<Session>
Heap &_global_heap; Heap &_global_heap;
Pci::Config::Delayer &_delayer; Pci::Config::Delayer &_delayer;
Device_bars_pool &_devices_bars; Device_bars_pool &_devices_bars;
bool _iommu; bool const _iommu;
bool const _msi_avail;
bool _msi_usage { true }; bool _msi_usage { true };
bool _msix_usage { true }; bool _msix_usage { true };
@ -474,7 +475,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,
char const *args, char const *args,
bool const iommu) bool const iommu,
bool const msi)
: :
_env(env), _env(env),
_config(config), _config(config),
@ -488,7 +490,8 @@ class Platform::Session_component : public Rpc_object<Session>
_global_heap(global_heap), _global_heap(global_heap),
_delayer(delayer), _delayer(delayer),
_devices_bars(devices_bars), _devices_bars(devices_bars),
_iommu(iommu) _iommu(iommu),
_msi_avail(msi)
{ {
/* subtract the RPC session and session dataspace capabilities */ /* subtract the RPC session and session dataspace capabilities */
_cap_guard.withdraw(Cap_quota{2}); _cap_guard.withdraw(Cap_quota{2});
@ -500,9 +503,12 @@ class Platform::Session_component : public Rpc_object<Session>
{ {
Session_policy const policy { _label, _config.xml() }; Session_policy const policy { _label, _config.xml() };
if (_msi_avail) {
_msi_usage = policy.attribute_value("msi", _msi_usage); _msi_usage = policy.attribute_value("msi", _msi_usage);
_msix_usage = _msi_usage && _msix_usage = _msi_usage &&
policy.attribute_value("msix", _msix_usage); policy.attribute_value("msix", _msix_usage);
} else
_msi_usage = _msix_usage = false;
/* 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) {
@ -875,6 +881,7 @@ class Platform::Root : public Root_component<Session_component>
bool _iommu { false }; bool _iommu { false };
bool _pci_reported { false }; bool _pci_reported { false };
bool _msi_platform;
struct Timer_delayer : Pci::Config::Delayer, Timer::Connection struct Timer_delayer : Pci::Config::Delayer, Timer::Connection
{ {
@ -1074,7 +1081,8 @@ class Platform::Root : public Root_component<Session_component>
*_pci_confspace, *_pci_confspace,
_pci_confspace_base, _pci_confspace_base,
*_buses, _heap, _delayer, *_buses, _heap, _delayer,
_devices_bars, args, _iommu); _devices_bars, args, _iommu,
_msi_platform);
} }
catch (Session_policy::No_policy_defined) { catch (Session_policy::No_policy_defined) {
error("Invalid session request, no matching policy for ", error("Invalid session request, no matching policy for ",
@ -1097,10 +1105,12 @@ class Platform::Root : public Root_component<Session_component>
* components and PCI-device components * components and PCI-device components
*/ */
Root(Env &env, Allocator &md_alloc, Attached_rom_dataspace &config, Root(Env &env, Allocator &md_alloc, Attached_rom_dataspace &config,
char const *acpi_rom, bool acpi_platform) char const *acpi_rom, bool acpi_platform, bool msi_platform)
: :
Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc), Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc),
_env(env), _config(config) _env(env),
_config(config),
_msi_platform(msi_platform)
{ {
try { try {
_parse_report_rom(env, acpi_rom, acpi_platform); _parse_report_rom(env, acpi_rom, acpi_platform);