From 501d82b99f2e35d91a6bdc23cead26b0b60b84b7 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Tue, 8 May 2018 16:00:11 +0200 Subject: [PATCH] platform_drv: skip assign device if iommu missing Avoid red messages in the log on machines with no IOMMU, which recurring confuse people. Issue #2801 --- repos/os/src/drivers/acpi/acpi.cc | 42 +++++++++++++++++++ .../platform/spec/x86/pci_session_component.h | 19 ++++++--- tool/run/boot_dir/hw | 2 +- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/repos/os/src/drivers/acpi/acpi.cc b/repos/os/src/drivers/acpi/acpi.cc index cef6f0fd77..57f3f24fdc 100644 --- a/repos/os/src/drivers/acpi/acpi.cc +++ b/repos/os/src/drivers/acpi/acpi.cc @@ -177,6 +177,10 @@ struct Device_scope : Genode::Mmio }; unsigned count() const { + unsigned const length = read(); + if (length < 6) + return 0; + unsigned paths = (read() - 6) / 2; if (paths > MAX_PATHS) { Genode::error("Device_scope: more paths (", paths, ") than" @@ -187,6 +191,29 @@ struct Device_scope : Genode::Mmio } }; +/* DMA Remapping Hardware Definition - Intel VT-d IO Spec - 8.3. */ +struct Dmar_drhd : Genode::Mmio +{ + struct Length : Register<0x2, 16> { }; + struct Flags : Register<0x4, 8> { }; + struct Segment : Register<0x6, 16> { }; + struct Phys : Register<0x8, 64> { }; + + Dmar_drhd(addr_t a) : Genode::Mmio(a) { } + + template + void apply(FUNC const &func = [] () { } ) + { + addr_t addr = base() + 16; + do { + Device_scope scope(addr); + + func(scope); + + addr = scope.base() + scope.read(); + } while (addr < base() + read()); + } +}; /* DMA Remapping Reporting structure - Intel VT-d IO Spec - 8.3. */ struct Dmar_rmrr : Genode::Mmio @@ -1366,8 +1393,12 @@ void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc) /* lambda definition for scope evaluation in rmrr */ auto func_scope = [&] (Device_scope const &scope) { + if (!scope.count()) + return; + xml.node("scope", [&] () { xml.attribute("bus_start", scope.read()); + xml.attribute("type", scope.read()); for (unsigned j = 0 ; j < scope.count(); j++) { xml.node("path", [&] () { attribute_hex(xml, "dev", @@ -1383,6 +1414,17 @@ void Acpi::generate_report(Genode::Env &env, Genode::Allocator &alloc) entry; entry = entry->next()) { entry->apply([&] (Dmar_common const &dmar) { + if (dmar.read() == Dmar_common::Type::DRHD) { + Dmar_drhd drhd(dmar.base()); + + xml.node("drhd", [&] () { + attribute_hex(xml, "phys", drhd.read()); + attribute_hex(xml, "flags", drhd.read()); + attribute_hex(xml, "segment", drhd.read()); + drhd.apply(func_scope); + }); + } + if (dmar.read() != Dmar_common::Type::RMRR) return; diff --git a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h index 71435a7739..524d4324aa 100644 --- a/repos/os/src/drivers/platform/spec/x86/pci_session_component.h +++ b/repos/os/src/drivers/platform/spec/x86/pci_session_component.h @@ -219,7 +219,7 @@ class Platform::Session_component : public Genode::Rpc_object Genode::List _device_list { }; Platform::Pci_buses &_pci_bus; Genode::Heap &_global_heap; - bool _no_device_pd = false; + bool _iommu; /** * Registry of RAM dataspaces allocated by the session @@ -463,7 +463,8 @@ class Platform::Session_component : public Genode::Rpc_object Genode::Attached_io_mem_dataspace &pciconf, Platform::Pci_buses &buses, Genode::Heap &global_heap, - char const *args) + char const *args, + bool const iommu) : _env(env), _config(config), @@ -472,7 +473,7 @@ class Platform::Session_component : public Genode::Rpc_object _cap_guard(Genode::cap_quota_from_args(args)), _md_alloc(_env_ram, env.rm()), _label(Genode::label_from_args(args)), - _pci_bus(buses), _global_heap(global_heap) + _pci_bus(buses), _global_heap(global_heap), _iommu(iommu) { /* subtract the RPC session and session dataspace capabilities */ _cap_guard.withdraw(Genode::Cap_quota{2}); @@ -763,7 +764,7 @@ class Platform::Session_component : public Genode::Rpc_object { using namespace Genode; - if (!device || device->config_space() == ~0UL) + if (!device || device->config_space() == ~0UL || !_iommu) return; try { @@ -840,6 +841,8 @@ class Platform::Root : public Genode::Root_component Genode::Constructible _buses { }; + bool _iommu { false }; + void _parse_report_rom(Genode::Env &env, const char * acpi_rom, bool acpi_platform) { @@ -914,6 +917,11 @@ class Platform::Root : public Genode::Root_component continue; } + if (node.has_type("drhd")) { + _iommu = true; + continue; + } + if (node.has_type("rmrr")) { uint64_t mem_start = 0, mem_end = 0; node.attribute("start").value(&mem_start); @@ -1029,7 +1037,8 @@ class Platform::Root : public Genode::Root_component { try { return new (md_alloc()) - Session_component(_env, _config, *_pci_confspace, *_buses, _heap, args); + Session_component(_env, _config, *_pci_confspace, *_buses, + _heap, args, _iommu); } catch (Genode::Session_policy::No_policy_defined) { Genode::error("Invalid session request, no matching policy for ", diff --git a/tool/run/boot_dir/hw b/tool/run/boot_dir/hw index 235f792a6a..c637881d75 100644 --- a/tool/run/boot_dir/hw +++ b/tool/run/boot_dir/hw @@ -37,7 +37,7 @@ proc run_boot_dir {binaries} { # generate static ACPI report for platform driver on Muen if {[have_spec "muen"]} { set fh [open "bin/acpi" "WRONLY CREAT TRUNC"] - puts $fh "" + puts $fh "" close $fh }