diff --git a/repos/os/src/app/pci_decode/main.cc b/repos/os/src/app/pci_decode/main.cc index c97853ef39..afdbb64b97 100644 --- a/repos/os/src/app/pci_decode/main.cc +++ b/repos/os/src/app/pci_decode/main.cc @@ -19,6 +19,7 @@ #include #include +#include #include using namespace Genode; @@ -43,6 +44,7 @@ struct Main List_model irq_routing_list {}; List_model irq_override_list {}; + List_model reserved_memory_list {}; Constructible pci_config_ds {}; @@ -168,6 +170,15 @@ void Main::parse_pci_function(Bdf bdf, gen.attribute("number", irq); }); + + reserved_memory_list.for_each([&] (Rmrr & rmrr) { + if (rmrr.bdf == bdf) + gen.node("reserved_memory", [&] + { + gen.attribute("address", rmrr.addr); + gen.attribute("size", rmrr.size); + }); + }); }); } @@ -259,6 +270,11 @@ void Main::sys_rom_update() irq_routing_list.update_from_xml(policy, xml); } + { + Rmrr_policy policy(heap); + reserved_memory_list.update_from_xml(policy, xml); + } + parse_pci_config_spaces(xml); } diff --git a/repos/os/src/app/pci_decode/rmrr.h b/repos/os/src/app/pci_decode/rmrr.h new file mode 100644 index 0000000000..2576c152f7 --- /dev/null +++ b/repos/os/src/app/pci_decode/rmrr.h @@ -0,0 +1,75 @@ +/* + * \brief Reserved memory region reporting from ACPI information in list models + * \author Stefan Kalkowski + * \date 2022-09-12 + */ + +/* + * Copyright (C) 2022 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU Affero General Public License version 3. + */ + + +#include +#include +#include + +using namespace Genode; +using namespace Pci; + + +struct Rmrr : List_model::Element +{ + Bdf bdf; + addr_t addr; + size_t size; + + Rmrr(Bdf bdf, addr_t addr, size_t size) + : bdf(bdf), addr(addr), size(size) {} +}; + + +struct Rmrr_policy : List_model::Update_policy +{ + Heap & heap; + + void destroy_element(Rmrr & rmrr) { + destroy(heap, &rmrr); } + + Rmrr & create_element(Xml_node node) + { + bus_t bus = 0; + dev_t dev = 0; + func_t fn = 0; + addr_t start = node.attribute_value("start", 0UL); + addr_t end = node.attribute_value("end", 0UL); + + node.with_optional_sub_node("scope", [&] (Xml_node node) { + bus = node.attribute_value("bus_start", 0U); + node.with_optional_sub_node("path", [&] (Xml_node node) { + dev = node.attribute_value("dev", 0); + fn = node.attribute_value("func", 0); + }); + }); + + return *(new (heap) Rmrr({bus, dev, fn}, start, (end-start+1))); + } + + void update_element(Rmrr &, Xml_node) {} + + static bool element_matches_xml_node(Rmrr const & rmrr, + Genode::Xml_node node) + { + addr_t start = node.attribute_value("start", 0UL); + addr_t end = node.attribute_value("end", 0UL); + return rmrr.addr == start && + rmrr.size == (end-start+1); + } + + static bool node_is_element(Genode::Xml_node node) { + return node.has_type("rmrr"); } + + Rmrr_policy(Heap & heap) : heap(heap) {} +};