sculpt: host MMC driver in runtime

Issue #5150
This commit is contained in:
Norman Feske 2024-03-25 14:52:36 +01:00 committed by Christian Helmuth
parent d13b8e1937
commit d8acc3a9f4
14 changed files with 285 additions and 51 deletions

View File

@ -180,6 +180,8 @@ proc driver_routes { } {
<service name="ROM" label="wifi_firmware.tar"> <parent label="a64_wifi_firmware.tar"/> </service>
<service name="ROM" label="usb_drv"> <parent label="a64_usb_host_drv"/> </service>
<service name="ROM" label="usb_drv.dtb"> <parent label="usb-pinephone.dtb"/> </service>
<service name="ROM" label="mmc_drv"> <parent label="a64_sd_card_drv"/> </service>
<service name="ROM" label="mmc_drv.dtb"> <parent label="sd_card-pinephone.dtb"/> </service>
<service name="ROM" label="fb_drv"> <parent label="de_fb_drv"/> </service>
<service name="ROM" label="fb_drv.dtb"> <parent label="de-pinephone.dtb"/> </service>
<service name="ROM" label="touch_drv"> <parent label="goodix_touch_drv"/> </service>

View File

@ -40,6 +40,7 @@
#include <fb_driver.h>
#include <touch_driver.h>
#include <usb_driver.h>
#include <mmc_driver.h>
#include <gui.h>
#include <storage.h>
#include <network.h>
@ -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());
_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<Main> _gui_mode_handler {
_env.ep(), *this, &Main::_handle_gui_mode };
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<Main> _gui_mode_handler {
_env.ep(), *this, &Main::_handle_gui_mode };
void _handle_gui_mode();
bool _verbose_modem = false;
@ -326,12 +328,15 @@ struct Sculpt::Main : Input_event_handler,
{
_block_devices_rom.update();
_usb_driver.with_devices([&] (Xml_node const &usb_devices) {
_mmc_driver.with_devices([&] (Xml_node const &mmc_devices) {
_storage.update(usb_devices,
Xml_node { "<empty/> " }, /* ahci */
Xml_node { "<empty/> " }, /* nvme */
mmc_devices,
_block_devices_rom.xml(),
_block_devices_handler);
});
});
/* update USB policies for storage devices */
_update_usb_drivers();
@ -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<Frame>
{
Hosted<Frame, Block_devices_widget> _block_devices;
Hosted<Frame, Mmc_devices_widget> _mmc_devices;
template <typename... ARGS>
Storage_widget(ARGS &&... args) : _block_devices(Id { "devices" }, args...) { }
Storage_widget(ARGS &&... args) : _mmc_devices(Id { "devices" }, args...) { }
void view(Scope<Frame> &s) const { s.widget(_block_devices); }
void view(Scope<Frame> &s) const { s.widget(_mmc_devices); }
template <typename... ARGS>
void click(ARGS &&... args) { _block_devices.propagate(args...); }
void click(ARGS &&... args) { _mmc_devices.propagate(args...); }
template <typename... ARGS>
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> _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);

View File

@ -124,6 +124,10 @@ void Graph::_view_selected_node_content(Scope<Depgraph, Frame, Vbox> &s,
if (name == "nvme")
s.sub_scope<Frame>([&] (Scope<Depgraph, Frame, Vbox, Frame> &s) {
s.widget(_nvme_devices_widget); });
if (name == "mmc")
s.sub_scope<Frame>([&] (Scope<Depgraph, Frame, Vbox, Frame> &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, [&] {

View File

@ -66,6 +66,10 @@ struct Sculpt::Graph : Widget<Depgraph>
_nvme_devices_widget { Id { "nvme_devices" },
_storage_devices, _sculpt_partition };
Hosted<Depgraph, Frame, Vbox, Frame, Mmc_devices_widget>
_mmc_devices_widget { Id { "mmc_devices" },
_storage_devices, _sculpt_partition };
Hosted<Depgraph, Frame, Vbox, Frame, Usb_devices_widget>
_usb_devices_widget { Id { "usb_devices" },
_storage_devices, _sculpt_partition };
@ -109,6 +113,7 @@ struct Sculpt::Graph : Widget<Depgraph>
_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();
}
};

View File

@ -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 { "<empty/> " }, /* mmc */
_block_devices_rom.xml(),
_block_devices_handler);
});

View File

@ -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 <block_session/block_session.h>
/* local includes */
#include <model/child_exit_state.h>
#include <model/board_info.h>
#include <runtime.h>
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<Child_state> _mmc { };
Attached_rom_dataspace _devices { _env, "report -> runtime/mmc/block_devices" };
Signal_handler<Mmc_driver> _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<Block::Session>(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<Platform::Session>(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<Cpu_session> (xml);
gen_parent_route<Pd_session> (xml);
gen_parent_route<Log_session> (xml);
gen_parent_route<Timer::Session> (xml);
gen_parent_route<Report::Session> (xml);
});
});
};
void update(Registry<Child_state> &registry, 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_ */

View File

@ -29,6 +29,7 @@ struct Sculpt::Board_info
soc_fb_present,
nvme_present,
ahci_present,
mmc_present,
usb_present,
ps2_present,
soc_touch_present;

View File

@ -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 <model/storage_device.h>
namespace Sculpt {
struct Mmc_device;
using Mmc_devices = List_model<Mmc_device>;
};
struct Sculpt::Mmc_device : List_model<Mmc_device>::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_ */

View File

@ -18,6 +18,7 @@
#include <model/block_device.h>
#include <model/ahci_device.h>
#include <model/nvme_device.h>
#include <model/mmc_device.h>
#include <model/usb_storage_device.h>
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 <typename FN>
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 <typename FN>
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); });
}
};

View File

@ -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())

View File

@ -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);

View File

@ -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);
/*

View File

@ -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<Platform::Session> (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<Pin_control::Session>(xml);
gen_parent_route<Irq_session> (xml);
gen_parent_route<Rom_session> (xml);
gen_parent_route<Cpu_session> (xml);
gen_parent_route<Pd_session> (xml);
gen_parent_route<Log_session> (xml);

View File

@ -117,6 +117,7 @@ struct Sculpt::Storage_device_button : Widget<Button>
s.sub_scope<Left_floating_hbox>(
[&] (Scope<Button, Hbox, Left_floating_hbox> &s) {
s.sub_scope<Label>(dev.name());
if (model.length() > 1)
s.sub_scope<Label>(String<80>(" (", model, ") "));
if (used_target.device_and_port() == dev.name())
s.sub_scope<Label>("* ");
@ -211,6 +212,33 @@ struct Sculpt::Nvme_devices_widget : Storage_devices_widget_base
};
namespace Sculpt { struct Mmc_devices_widget; }
struct Sculpt::Mmc_devices_widget : Storage_devices_widget_base
{
using Storage_devices_widget_base::Storage_devices_widget_base;
void view(Scope<Vbox> &s) const
{
s.sub_scope<Min_ex>(35);
_storage_devices.mmc_devices.for_each([&] (Mmc_device const &dev) {
Hosted<Vbox, Storage_device_button> button { Id { dev.name() }, dev.model };
_view_device(s, dev, button);
});
}
void click(Clicked_at const &at, Storage_device_widget::Action &action)
{
_click_device<Storage_device_button>(at, action);
}
void clack(Clacked_at const &at, Storage_device_widget::Action &action)
{
_clack_device(at, action);
}
};
namespace Sculpt { struct Usb_storage_device_button; }
struct Sculpt::Usb_storage_device_button : Widget<Button>