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
This commit is contained in:
Alexander Boettcher 2018-05-08 16:00:11 +02:00 committed by Christian Helmuth
parent 24e6b677bd
commit 501d82b99f
3 changed files with 57 additions and 6 deletions

View File

@ -177,6 +177,10 @@ struct Device_scope : Genode::Mmio
};
unsigned count() const {
unsigned const length = read<Length>();
if (length < 6)
return 0;
unsigned paths = (read<Length>() - 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 <typename FUNC>
void apply(FUNC const &func = [] () { } )
{
addr_t addr = base() + 16;
do {
Device_scope scope(addr);
func(scope);
addr = scope.base() + scope.read<Device_scope::Length>();
} while (addr < base() + read<Length>());
}
};
/* 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<Device_scope::Bus>());
xml.attribute("type", scope.read<Device_scope::Type>());
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>() == Dmar_common::Type::DRHD) {
Dmar_drhd drhd(dmar.base());
xml.node("drhd", [&] () {
attribute_hex(xml, "phys", drhd.read<Dmar_drhd::Phys>());
attribute_hex(xml, "flags", drhd.read<Dmar_drhd::Flags>());
attribute_hex(xml, "segment", drhd.read<Dmar_drhd::Segment>());
drhd.apply(func_scope);
});
}
if (dmar.read<Dmar_common::Type>() != Dmar_common::Type::RMRR)
return;

View File

@ -219,7 +219,7 @@ class Platform::Session_component : public Genode::Rpc_object<Session>
Genode::List<Device_component> _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<Session>
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<Session>
_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<Session>
{
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<Session_component>
Genode::Constructible<Platform::Pci_buses> _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<Session_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<Session_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 ",

View File

@ -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 "<acpi><bdf start=\"0\" count=\"16384\" base=\"0xf8000000\"/></acpi>"
puts $fh "<acpi><bdf start=\"0\" count=\"16384\" base=\"0xf8000000\"/><drhd/></acpi>"
close $fh
}