From a1564d1826e0f5d19c217980f4a63707bfa96ba2 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Thu, 28 Apr 2022 14:41:17 +0200 Subject: [PATCH] platform_drv: add report facility By adding a 'report' node to the platform driver's configuration one can enable either devices or config reports. The devices report contains all devices and their detailed state, as well as whether it is already in use or not. The config report contains one by one the current configuration of the platform driver. Moreover, this commit adds a README file describing the facilities of the platform driver. Fix genodelabs/genode#4386 --- repos/os/run/platform_drv.run | 48 +++++++++----- repos/os/src/drivers/platform/README | 64 +++++++++++++++++++ repos/os/src/drivers/platform/device.cc | 33 ++++++++-- repos/os/src/drivers/platform/device.h | 15 +++-- repos/os/src/drivers/platform/main.cc | 34 +++++++--- .../src/drivers/platform/session_component.cc | 2 +- repos/os/src/test/platform_drv/main.cc | 6 ++ 7 files changed, 164 insertions(+), 38 deletions(-) create mode 100644 repos/os/src/drivers/platform/README diff --git a/repos/os/run/platform_drv.run b/repos/os/run/platform_drv.run index e1c9502297..d4e08442d4 100644 --- a/repos/os/run/platform_drv.run +++ b/repos/os/run/platform_drv.run @@ -10,6 +10,7 @@ import_from_depot [depot_user]/src/[base_src] \ [depot_user]/src/fs_report \ [depot_user]/src/fs_rom \ [depot_user]/src/platform_drv \ + [depot_user]/src/report_rom \ [depot_user]/src/vfs_import \ [depot_user]/src/vfs @@ -75,12 +76,25 @@ install_config { + + + + + + + + + + + + - - + + + @@ -105,70 +119,70 @@ append qemu_args "-nographic " set good_string { [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] Error: Device 0 not valid! [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] -[init -> test-platform_drv] +[init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] [init -> test-platform_drv] @@ -177,6 +191,6 @@ set good_string { [init -> test-platform_drv] Test has ended! } -run_genode_until "No matching policy for 'test-platform_drv -> ' anymore, will close the session!.*\n" 100 +run_genode_until "Test has ended!.*\n" 100 grep_output "init -> test-platform_drv" compare_output_to $good_string diff --git a/repos/os/src/drivers/platform/README b/repos/os/src/drivers/platform/README new file mode 100644 index 0000000000..e059d4efbb --- /dev/null +++ b/repos/os/src/drivers/platform/README @@ -0,0 +1,64 @@ +This directory contains the implementation of Genode's platform driver. + +Behavior +-------- + +Per client a policy must be configured that states which client can +access certain devices to form a virtual bus per client. The client may +iterate through the virtual bus using the devices_rom() function of +the platform_session interface to discover all available devices of the virtual +bus. When identified a specific device its device capability can be obtained +via its unique name. Simple device drivers that drive exactly one device do +not need the devices ROM, but can simply obtain their device capability via +the acquire_single_device() function of the platform session interface. + +With the device capability the resources of the devices can be obtained, e.g. +io_port, io_mem and irq of the platform_device interface. + +Policy usage +------------ + +A policy may contain several nodes describing several devices. + +! +! +! ... +! +! +! +! +! +! +! ... + +The managing_system attribute is evaluated by init. If set to "yes" it +permits a component, the platform driver, to restrict the allocation of memory to +specific physical RAM ranges. The platform driver uses this feature to ensure that +the allocation of DMA capable memory consider several restrictions. For +example, some drivers, as the UHCI controller, requires a +physical memory address below 4G. Another example is that on 32bit hosts +physical to virtual identical mappings of DMA memory for the device_pd +(required when IOMMU is used) must be below the kernel memory boundary (3G). +On some systems, e.g., base-hw kernel on certain ARM platforms, it allows the +platform driver to call system management firmware via kernel syscalls. + +The 'info' attribute in a policy node describe, whether the client gets +permission to access a devices ROM containing detailed information about +the devices of its virtual bus. + +Report facilities +----------------- + +The configuration of the platform driver supports different levels of reports. +By default the platform driver does not report anything. But when adding a +report node: + +! +! + +it is possible to enable either a devices and/or config report. The first will +open up a Report session to dynamically report all accessible devices and its +state. Whereby the second report states the currently active configuration of +the platform driver. diff --git a/repos/os/src/drivers/platform/device.cc b/repos/os/src/drivers/platform/device.cc index c0adf9a25d..80446a6cfd 100644 --- a/repos/os/src/drivers/platform/device.cc +++ b/repos/os/src/drivers/platform/device.cc @@ -79,11 +79,15 @@ void Driver::Device::acquire(Session_component & sc) }); sc.update_devices_rom(); + sc.devices().update_report(); } void Driver::Device::release(Session_component & sc) { + if (!(_owner == sc)) + return; + _reset_domain_list.for_each([&] (Reset_domain & r) { sc.devices().resets().apply(r.name, [&] (Driver::Reset &reset) { @@ -102,15 +106,18 @@ void Driver::Device::release(Session_component & sc) clock.disable(); }); }); - if (_owner == sc) _owner = Owner(); + _owner = Owner(); + sc.update_devices_rom(); + sc.devices().update_report(); } -void Driver::Device::report(Xml_generator & xml, Session_component & sc) +void Driver::Device::report(Xml_generator & xml, Device_model & devices) { xml.node("device", [&] () { xml.attribute("name", name()); xml.attribute("type", type()); + xml.attribute("used", _owner.valid()); _io_mem_list.for_each([&] (Io_mem & io_mem) { xml.node("io_mem", [&] () { xml.attribute("phys_addr", String<16>(Hex(io_mem.range.start))); @@ -135,7 +142,7 @@ void Driver::Device::report(Xml_generator & xml, Session_component & sc) }); }); _clock_list.for_each([&] (Clock &c) { - sc.devices().clocks().apply(c.name, [&] (Driver::Clock &clock) { + devices.clocks().apply(c.name, [&] (Driver::Clock &clock) { xml.node("clock", [&] () { xml.attribute("rate", clock.rate().value); xml.attribute("name", c.driver_name); @@ -143,7 +150,7 @@ void Driver::Device::report(Xml_generator & xml, Session_component & sc) }); }); - _report_platform_specifics(xml, sc); + _report_platform_specifics(xml, devices); }); } @@ -157,3 +164,21 @@ Driver::Device::~Device() if (_owner.valid()) { error("Device to be destroyed, still obtained by session"); } } + + +void Driver::Device_model::update_report() +{ + if (_reporter.enabled()) { + Reporter::Xml_generator xml(_reporter, [&] () { + for_each([&] (Device & device) { + device.report(xml, *this); }); + }); + } +} + + +void Driver::Device_model::update(Xml_node const & node) +{ + _model.update_from_xml(*this, node); + update_report(); +} diff --git a/repos/os/src/drivers/platform/device.h b/repos/os/src/drivers/platform/device.h index ff0a3fa249..728ed3c329 100644 --- a/repos/os/src/drivers/platform/device.h +++ b/repos/os/src/drivers/platform/device.h @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -166,12 +167,12 @@ class Driver::Device : private List_model::Element fn(idx++, ipr.addr, ipr.size); }); } - void report(Xml_generator &, Session_component &); + void report(Xml_generator &, Device_model &); protected: virtual void _report_platform_specifics(Xml_generator &, - Session_component &) {} + Device_model &) {} friend class Driver::Device_model; friend class List_model; @@ -202,6 +203,7 @@ class Driver::Device_model : private: Heap & _heap; + Reporter & _reporter; List_model _model { }; Clocks _clocks { }; Resets _resets { }; @@ -209,12 +211,11 @@ class Driver::Device_model : public: - void update(Xml_node const & node) { - _model.update_from_xml(*this, node); - } + void update_report(); + void update(Xml_node const & node); - Device_model(Heap & heap) - : _heap(heap) { } + Device_model(Heap & heap, Reporter & reporter) + : _heap(heap), _reporter(reporter) { } ~Device_model() { _model.destroy_all_elements(*this); } diff --git a/repos/os/src/drivers/platform/main.cc b/repos/os/src/drivers/platform/main.cc index 1747cb71a0..89a3b50ab2 100644 --- a/repos/os/src/drivers/platform/main.cc +++ b/repos/os/src/drivers/platform/main.cc @@ -21,15 +21,17 @@ struct Driver::Main void update(); Env & env; - Heap heap { env.ram(), env.rm() }; - Sliced_heap sliced_heap { env.ram(), env.rm() }; - Attached_rom_dataspace config_rom { env, "config" }; - Attached_rom_dataspace devices_rom { env, "devices" }; - Device_model devices { heap }; - Signal_handler
handler { env.ep(), *this, - &Main::update }; - Driver::Root root { env, sliced_heap, - config_rom, devices }; + Heap heap { env.ram(), env.rm() }; + Sliced_heap sliced_heap { env.ram(), env.rm() }; + Attached_rom_dataspace config_rom { env, "config" }; + Attached_rom_dataspace devices_rom { env, "devices" }; + Reporter cfg_reporter { env, "config" }; + Reporter dev_reporter { env, "devices" }; + Device_model devices { heap, dev_reporter }; + Signal_handler
handler { env.ep(), *this, + &Main::update }; + Driver::Root root { env, sliced_heap, + config_rom, devices }; Main(Genode::Env & e) : env(e) @@ -46,8 +48,22 @@ void Driver::Main::update() { config_rom.update(); devices_rom.update(); + + config_rom.xml().for_each_sub_node("report", [&] (Xml_node const node) { + dev_reporter.enabled(node.attribute_value("devices", false)); + cfg_reporter.enabled(node.attribute_value("config", false)); + }); + devices.update(devices_rom.xml()); root.update_policy(); + + if (cfg_reporter.enabled()) { + Reporter::Xml_generator xml(cfg_reporter, [&] () { + config_rom.xml().with_raw_content([&] (char const *src, size_t len) { + xml.append(src, len); + }); + }); + } } void Component::construct(Genode::Env &env) { diff --git a/repos/os/src/drivers/platform/session_component.cc b/repos/os/src/drivers/platform/session_component.cc index 5831eee2a5..6af99fa901 100644 --- a/repos/os/src/drivers/platform/session_component.cc +++ b/repos/os/src/drivers/platform/session_component.cc @@ -104,7 +104,7 @@ void Session_component::produce_xml(Xml_generator &xml) xml.attribute("version", _version); _devices.for_each([&] (Device & dev) { - if (matches(dev)) dev.report(xml, *this); }); + if (matches(dev)) dev.report(xml, _devices); }); } diff --git a/repos/os/src/test/platform_drv/main.cc b/repos/os/src/test/platform_drv/main.cc index ceeefa04b8..522ea5421a 100644 --- a/repos/os/src/test/platform_drv/main.cc +++ b/repos/os/src/test/platform_drv/main.cc @@ -96,6 +96,12 @@ struct Main Reporter::Xml_generator cfg(config_reporter, [&] () { + cfg.node("report", [&] + { + cfg.attribute("devices", true); + cfg.attribute("config", true); + }); + cfg.node("policy", [&] { cfg.attribute("label", "test-platform_drv -> ");