From d8acc3a9f48929b4623860d6fd7fe52fec2b8871 Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Mon, 25 Mar 2024 14:52:36 +0100 Subject: [PATCH] sculpt: host MMC driver in runtime Issue #5150 --- repos/gems/run/sculpt.run | 2 + repos/gems/src/app/phone_manager/main.cc | 53 ++++++---- repos/gems/src/app/sculpt_manager/graph.cc | 6 ++ repos/gems/src/app/sculpt_manager/graph.h | 5 + repos/gems/src/app/sculpt_manager/main.cc | 1 + .../gems/src/app/sculpt_manager/mmc_driver.h | 96 +++++++++++++++++++ .../src/app/sculpt_manager/model/board_info.h | 1 + .../src/app/sculpt_manager/model/mmc_device.h | 57 +++++++++++ .../sculpt_manager/model/storage_devices.h | 64 ++++++++----- .../app/sculpt_manager/model/storage_target.h | 3 +- repos/gems/src/app/sculpt_manager/storage.cc | 10 ++ repos/gems/src/app/sculpt_manager/storage.h | 3 +- .../src/app/sculpt_manager/touch_driver.h | 5 +- .../app/sculpt_manager/view/storage_widget.h | 30 +++++- 14 files changed, 285 insertions(+), 51 deletions(-) create mode 100644 repos/gems/src/app/sculpt_manager/mmc_driver.h create mode 100644 repos/gems/src/app/sculpt_manager/model/mmc_device.h diff --git a/repos/gems/run/sculpt.run b/repos/gems/run/sculpt.run index 3bd2d03bd0..8468a73a78 100644 --- a/repos/gems/run/sculpt.run +++ b/repos/gems/run/sculpt.run @@ -180,6 +180,8 @@ proc driver_routes { } { + + diff --git a/repos/gems/src/app/phone_manager/main.cc b/repos/gems/src/app/phone_manager/main.cc index f300e2d26b..72a1842295 100644 --- a/repos/gems/src/app/phone_manager/main.cc +++ b/repos/gems/src/app/phone_manager/main.cc @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -88,7 +89,8 @@ struct Sculpt::Main : Input_event_handler, Software_update_widget::Action, Software_add_widget::Action, Screensaver::Action, - Usb_driver::Action + Usb_driver::Action, + Mmc_driver::Action { Env &_env; @@ -152,8 +154,6 @@ struct Sculpt::Main : Input_event_handler, void generate(Xml_generator &xml, Screensaver const &screensaver) const { - if (storage) xml.attribute("storage", "yes"); - if (state.length() > 1) xml.attribute("state", state); @@ -208,11 +208,13 @@ struct Sculpt::Main : Input_event_handler, _board_info.wifi_present = true; _board_info.usb_present = true; + _board_info.mmc_present = true; _board_info.soc_fb_present = true; _board_info.soc_touch_present = true; - _fb_driver.update(_child_states, _board_info, _platform.xml()); + _fb_driver .update(_child_states, _board_info, _platform.xml()); _touch_driver.update(_child_states, _board_info); + _mmc_driver .update(_child_states, _board_info); _update_usb_drivers(); update_network_dialog(); @@ -239,11 +241,8 @@ struct Sculpt::Main : Input_event_handler, Fb_driver _fb_driver { }; Touch_driver _touch_driver { }; - - Signal_handler
_gui_mode_handler { - _env.ep(), *this, &Main::_handle_gui_mode }; - - Usb_driver _usb_driver { _env, *this }; + Usb_driver _usb_driver { _env, *this }; + Mmc_driver _mmc_driver { _env, *this }; void _update_usb_drivers() { @@ -253,6 +252,9 @@ struct Sculpt::Main : Input_event_handler, }); } + Signal_handler
_gui_mode_handler { + _env.ep(), *this, &Main::_handle_gui_mode }; + void _handle_gui_mode(); bool _verbose_modem = false; @@ -326,11 +328,14 @@ struct Sculpt::Main : Input_event_handler, { _block_devices_rom.update(); _usb_driver.with_devices([&] (Xml_node const &usb_devices) { - _storage.update(usb_devices, - Xml_node { " " }, /* ahci */ - Xml_node { " " }, /* nvme */ - _block_devices_rom.xml(), - _block_devices_handler); + _mmc_driver.with_devices([&] (Xml_node const &mmc_devices) { + _storage.update(usb_devices, + Xml_node { " " }, /* ahci */ + Xml_node { " " }, /* nvme */ + mmc_devices, + _block_devices_rom.xml(), + _block_devices_handler); + }); }); /* update USB policies for storage devices */ @@ -352,6 +357,11 @@ struct Sculpt::Main : Input_event_handler, _storage.gen_usb_storage_policies(xml); } + /** + * Mmc_driver::Action + */ + void handle_mmc_discovered() override { _handle_block_devices(); } + /** * Storage::Action interface */ @@ -791,20 +801,20 @@ struct Sculpt::Main : Input_event_handler, struct Storage_widget : Widget { - Hosted _block_devices; + Hosted _mmc_devices; template - Storage_widget(ARGS &&... args) : _block_devices(Id { "devices" }, args...) { } + Storage_widget(ARGS &&... args) : _mmc_devices(Id { "devices" }, args...) { } - void view(Scope &s) const { s.widget(_block_devices); } + void view(Scope &s) const { s.widget(_mmc_devices); } template - void click(ARGS &&... args) { _block_devices.propagate(args...); } + void click(ARGS &&... args) { _mmc_devices.propagate(args...); } template - void clack(ARGS &&... args) { _block_devices.propagate(args...); } + void clack(ARGS &&... args) { _mmc_devices.propagate(args...); } - void reset_operation() { _block_devices.reset_operation(); } + void reset_operation() { _mmc_devices.reset_operation(); } }; Conditional_widget _storage_widget { @@ -2463,6 +2473,9 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const _touch_driver.gen_start_node (xml); } + if (_system.storage) + _mmc_driver.gen_start_node(xml); + if (_network._nic_target.type() == Nic_target::Type::MODEM) _usb_driver.gen_start_nodes(xml); diff --git a/repos/gems/src/app/sculpt_manager/graph.cc b/repos/gems/src/app/sculpt_manager/graph.cc index 27b64c2e21..c5e47d2bdf 100644 --- a/repos/gems/src/app/sculpt_manager/graph.cc +++ b/repos/gems/src/app/sculpt_manager/graph.cc @@ -124,6 +124,10 @@ void Graph::_view_selected_node_content(Scope &s, if (name == "nvme") s.sub_scope([&] (Scope &s) { s.widget(_nvme_devices_widget); }); + + if (name == "mmc") + s.sub_scope([&] (Scope &s) { + s.widget(_mmc_devices_widget); }); } @@ -296,6 +300,7 @@ void Graph::click(Clicked_at const &at, Action &action) _block_devices_widget.propagate(at, action); _ahci_devices_widget .propagate(at, action); _nvme_devices_widget .propagate(at, action); + _mmc_devices_widget .propagate(at, action); _usb_devices_widget .propagate(at, action); _remove .propagate(at); @@ -309,6 +314,7 @@ void Graph::clack(Clacked_at const &at, Action &action, Ram_fs_widget::Action &r _block_devices_widget.propagate(at, action); _ahci_devices_widget .propagate(at, action); _nvme_devices_widget .propagate(at, action); + _mmc_devices_widget .propagate(at, action); _usb_devices_widget .propagate(at, action); _remove.propagate(at, [&] { diff --git a/repos/gems/src/app/sculpt_manager/graph.h b/repos/gems/src/app/sculpt_manager/graph.h index cc4fc685b8..8ced28932b 100644 --- a/repos/gems/src/app/sculpt_manager/graph.h +++ b/repos/gems/src/app/sculpt_manager/graph.h @@ -66,6 +66,10 @@ struct Sculpt::Graph : Widget _nvme_devices_widget { Id { "nvme_devices" }, _storage_devices, _sculpt_partition }; + Hosted + _mmc_devices_widget { Id { "mmc_devices" }, + _storage_devices, _sculpt_partition }; + Hosted _usb_devices_widget { Id { "usb_devices" }, _storage_devices, _sculpt_partition }; @@ -109,6 +113,7 @@ struct Sculpt::Graph : Widget _block_devices_widget.reset_operation(); _ahci_devices_widget.reset_operation(); _nvme_devices_widget.reset_operation(); + _mmc_devices_widget.reset_operation(); _usb_devices_widget.reset_operation(); } }; diff --git a/repos/gems/src/app/sculpt_manager/main.cc b/repos/gems/src/app/sculpt_manager/main.cc index b704a6ae0c..30dc00b0ae 100644 --- a/repos/gems/src/app/sculpt_manager/main.cc +++ b/repos/gems/src/app/sculpt_manager/main.cc @@ -281,6 +281,7 @@ struct Sculpt::Main : Input_event_handler, _ahci_driver.with_ahci_ports([&] (Xml_node const &ahci_ports) { _nvme_driver.with_nvme_namespaces([&] (Xml_node const &nvme_namespaces) { _storage.update(usb_devices, ahci_ports, nvme_namespaces, + Xml_node { " " }, /* mmc */ _block_devices_rom.xml(), _block_devices_handler); }); diff --git a/repos/gems/src/app/sculpt_manager/mmc_driver.h b/repos/gems/src/app/sculpt_manager/mmc_driver.h new file mode 100644 index 0000000000..70c11f9ac7 --- /dev/null +++ b/repos/gems/src/app/sculpt_manager/mmc_driver.h @@ -0,0 +1,96 @@ +/* + * \brief Sculpt MMC-driver management + * \author Norman Feske + * \date 2024-03-25 + */ + +/* + * Copyright (C) 2024 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. + */ + +#ifndef _MMC_DRIVER_H_ +#define _MMC_DRIVER_H_ + +/* Genode includes */ +#include + +/* local includes */ +#include +#include +#include + +namespace Sculpt { struct Mmc_driver; } + + +struct Sculpt::Mmc_driver : private Noncopyable +{ + struct Action : Interface + { + virtual void handle_mmc_discovered() = 0; + }; + + Env &_env; + Action &_action; + + Constructible _mmc { }; + + Attached_rom_dataspace _devices { _env, "report -> runtime/mmc/block_devices" }; + + Signal_handler _devices_handler { + _env.ep(), *this, &Mmc_driver::_handle_devices }; + + void _handle_devices() + { + _devices.update(); + _action.handle_mmc_discovered(); + } + + Mmc_driver(Env &env, Action &action) : _env(env), _action(action) + { + _devices.sigh(_devices_handler); + _devices_handler.local_submit(); + } + + void gen_start_node(Xml_generator &xml) const + { + if (!_mmc.constructed()) + return; + + xml.node("start", [&] { + _mmc->gen_start_node_content(xml); + gen_named_node(xml, "binary", "mmc_drv"); + gen_provides(xml); + xml.node("config", [&] { + xml.attribute("report", "yes"); + xml.node("default-policy", [&] { + xml.attribute("device", "mmcblk0"); + xml.attribute("writeable", "yes"); }); + }); + xml.node("route", [&] { + gen_parent_route(xml); + gen_parent_rom_route(xml, "dtb", "mmc_drv.dtb"); + gen_parent_rom_route(xml, "ld.lib.so"); + gen_parent_rom_route(xml, "mmc_drv"); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + gen_parent_route (xml); + }); + }); + }; + + void update(Registry ®istry, Board_info const &board_info) + { + _mmc.conditional(board_info.mmc_present, + registry, "mmc", Priority::DEFAULT, + Ram_quota { 16*1024*1024 }, Cap_quota { 500 }); + } + + void with_devices(auto const &fn) const { fn(_devices.xml()); } +}; + +#endif /* _MMC_DRIVER_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/model/board_info.h b/repos/gems/src/app/sculpt_manager/model/board_info.h index f6399c8c89..2514c41996 100644 --- a/repos/gems/src/app/sculpt_manager/model/board_info.h +++ b/repos/gems/src/app/sculpt_manager/model/board_info.h @@ -29,6 +29,7 @@ struct Sculpt::Board_info soc_fb_present, nvme_present, ahci_present, + mmc_present, usb_present, ps2_present, soc_touch_present; diff --git a/repos/gems/src/app/sculpt_manager/model/mmc_device.h b/repos/gems/src/app/sculpt_manager/model/mmc_device.h new file mode 100644 index 0000000000..434e7ccdd5 --- /dev/null +++ b/repos/gems/src/app/sculpt_manager/model/mmc_device.h @@ -0,0 +1,57 @@ +/* + * \brief Representation of MMC devices + * \author Norman Feske + * \date 2024-03-25 + */ + +/* + * Copyright (C) 2024 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. + */ + +#ifndef _MODEL__MMC_DEVICE_H_ +#define _MODEL__MMC_DEVICE_H_ + +#include + +namespace Sculpt { + + struct Mmc_device; + + using Mmc_devices = List_model; +}; + + +struct Sculpt::Mmc_device : List_model::Element, Storage_device +{ + using Model = String<16>; + + Model const model; + + static Port _port(Xml_node const &node) + { + return node.attribute_value("label", Port()); + } + + static Capacity _capacity(Xml_node const &node) + { + return { node.attribute_value("block_size", 0ULL) + * node.attribute_value("block_count", 0ULL) }; + } + + Mmc_device(Env &env, Allocator &alloc, Signal_context_capability sigh, + Xml_node const &node) + : + Storage_device(env, alloc, Storage_device::Provider::RUNTIME, + "mmc", _port(node), _capacity(node), sigh), + model(node.attribute_value("model", Model())) + { } + + bool matches(Xml_node const &node) const { return _port(node) == port; } + + static bool type_matches(Xml_node const &) { return true; } +}; + +#endif /* _MODEL__MMC_DEVICE_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/model/storage_devices.h b/repos/gems/src/app/sculpt_manager/model/storage_devices.h index ce3da2fdd3..62293205b8 100644 --- a/repos/gems/src/app/sculpt_manager/model/storage_devices.h +++ b/repos/gems/src/app/sculpt_manager/model/storage_devices.h @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace Sculpt { struct Storage_devices; } @@ -28,6 +29,7 @@ struct Sculpt::Storage_devices Block_devices block_devices { }; Ahci_devices ahci_devices { }; Nvme_devices nvme_devices { }; + Mmc_devices mmc_devices { }; Usb_storage_devices usb_storage_devices { }; bool _block_devices_report_valid = false; @@ -114,6 +116,30 @@ struct Sculpt::Storage_devices return progress; } + bool update_mmc_devices_from_xml(Env &env, Allocator &alloc, Xml_node node, + Signal_context_capability sigh) + { + bool progress = false; + mmc_devices.update_from_xml(node, + + /* create */ + [&] (Xml_node const &node) -> Mmc_device & { + progress = true; + return *new (alloc) Mmc_device(env, alloc, sigh, node); + }, + + /* destroy */ + [&] (Mmc_device &d) { + destroy(alloc, &d); + progress = true; + }, + + /* update */ + [&] (Mmc_device &, Xml_node const &) { } + ); + return progress; + } + /** * Update 'usb_storage_devices' from USB devices report * @@ -173,36 +199,22 @@ struct Sculpt::Storage_devices return _block_devices_report_valid && _usb_active_config_valid; } - template - void for_each(FN const &fn) const + void for_each(auto const &fn) const { - block_devices.for_each([&] (Block_device const &dev) { - fn(dev); }); - - ahci_devices.for_each([&] (Ahci_device const &dev) { - fn(dev); }); - - nvme_devices.for_each([&] (Nvme_device const &dev) { - fn(dev); }); - - usb_storage_devices.for_each([&] (Usb_storage_device const &dev) { - fn(dev); }); + block_devices .for_each([&] (Storage_device const &dev) { fn(dev); }); + ahci_devices .for_each([&] (Storage_device const &dev) { fn(dev); }); + nvme_devices .for_each([&] (Storage_device const &dev) { fn(dev); }); + mmc_devices .for_each([&] (Storage_device const &dev) { fn(dev); }); + usb_storage_devices.for_each([&] (Storage_device const &dev) { fn(dev); }); } - template - void for_each(FN const &fn) + void for_each(auto const &fn) { - block_devices.for_each([&] (Block_device &dev) { - fn(dev); }); - - ahci_devices.for_each([&] (Ahci_device &dev) { - fn(dev); }); - - nvme_devices.for_each([&] (Nvme_device &dev) { - fn(dev); }); - - usb_storage_devices.for_each([&] (Usb_storage_device &dev) { - fn(dev); }); + block_devices .for_each([&] (Storage_device &dev) { fn(dev); }); + ahci_devices .for_each([&] (Storage_device &dev) { fn(dev); }); + nvme_devices .for_each([&] (Storage_device &dev) { fn(dev); }); + mmc_devices .for_each([&] (Storage_device &dev) { fn(dev); }); + usb_storage_devices.for_each([&] (Storage_device &dev) { fn(dev); }); } }; diff --git a/repos/gems/src/app/sculpt_manager/model/storage_target.h b/repos/gems/src/app/sculpt_manager/model/storage_target.h index 03dd2c5eba..e4144b452d 100644 --- a/repos/gems/src/app/sculpt_manager/model/storage_target.h +++ b/repos/gems/src/app/sculpt_manager/model/storage_target.h @@ -62,6 +62,7 @@ struct Sculpt::Storage_target bool const usb = (Label(Cstring(device.string(), 3)) == "usb"); bool const ahci = (Label(Cstring(device.string(), 4)) == "ahci"); bool const nvme = (Label(Cstring(device.string(), 4)) == "nvme"); + bool const mmc = (Label(Cstring(device.string(), 3)) == "mmc"); bool const whole_device = !partition.valid(); @@ -70,7 +71,7 @@ struct Sculpt::Storage_target if (whole_device) { - if (usb || ahci || nvme) + if (usb || ahci || nvme || mmc) xml.node("child", [&] () { xml.attribute("name", device); if (port.valid()) diff --git a/repos/gems/src/app/sculpt_manager/storage.cc b/repos/gems/src/app/sculpt_manager/storage.cc index 1fa1cb0b54..60a7f84fba 100644 --- a/repos/gems/src/app/sculpt_manager/storage.cc +++ b/repos/gems/src/app/sculpt_manager/storage.cc @@ -18,6 +18,7 @@ void Sculpt::Storage::update(Xml_node const &usb_devices, Xml_node const &ahci_ports, Xml_node const &nvme_namespaces, + Xml_node const &mmc_devices, Xml_node const &block_devices, Signal_context_capability sigh) { @@ -52,6 +53,15 @@ void Sculpt::Storage::update(Xml_node const &usb_devices, process_part_block_report(dev); }); } + { + reconfigure_runtime |= + _storage_devices.update_mmc_devices_from_xml(_env, _alloc, mmc_devices, + sigh); + + _storage_devices.mmc_devices.for_each([&] (Mmc_device &dev) { + process_part_block_report(dev); }); + } + { _storage_devices.update_block_devices_from_xml(_env, _alloc, block_devices, sigh); diff --git a/repos/gems/src/app/sculpt_manager/storage.h b/repos/gems/src/app/sculpt_manager/storage.h index 43288b392d..d9b32b51e8 100644 --- a/repos/gems/src/app/sculpt_manager/storage.h +++ b/repos/gems/src/app/sculpt_manager/storage.h @@ -54,7 +54,8 @@ struct Sculpt::Storage : Storage_device_widget::Action, Ram_fs_widget::Action Inspect_view_version _inspect_view_version { 0 }; void update(Xml_node const &usb_devices, Xml_node const &ahci_ports, - Xml_node const &nvme_namespaces, Xml_node const &block_devices, + Xml_node const &nvme_namespaces, Xml_node const &mmc_devices, + Xml_node const &block_devices, Signal_context_capability sigh); /* diff --git a/repos/gems/src/app/sculpt_manager/touch_driver.h b/repos/gems/src/app/sculpt_manager/touch_driver.h index 5d3878fe2c..f2f09469c9 100644 --- a/repos/gems/src/app/sculpt_manager/touch_driver.h +++ b/repos/gems/src/app/sculpt_manager/touch_driver.h @@ -36,11 +36,12 @@ struct Sculpt::Touch_driver : private Noncopyable gen_named_node(xml, "binary", "touch_drv"); xml.node("config", [&] { }); xml.node("route", [&] { - gen_parent_rom_route(xml, "dtb", "touch_drv.dtb"); gen_parent_route (xml); + gen_parent_rom_route(xml, "dtb", "touch_drv.dtb"); + gen_parent_rom_route(xml, "ld.lib.so"); + gen_parent_rom_route(xml, "touch_drv"); gen_parent_route(xml); gen_parent_route (xml); - gen_parent_route (xml); gen_parent_route (xml); gen_parent_route (xml); gen_parent_route (xml); diff --git a/repos/gems/src/app/sculpt_manager/view/storage_widget.h b/repos/gems/src/app/sculpt_manager/view/storage_widget.h index d5e09675f7..f58a250d97 100644 --- a/repos/gems/src/app/sculpt_manager/view/storage_widget.h +++ b/repos/gems/src/app/sculpt_manager/view/storage_widget.h @@ -117,7 +117,8 @@ struct Sculpt::Storage_device_button : Widget