From 1bb1ebe2aec62fb6da9b55ad2d3a8e2b8446ebe5 Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Fri, 29 Sep 2023 11:46:50 +0200 Subject: [PATCH] sculpt: use debug monitor as runtime init Fixes #5012 --- repos/gems/recipes/pkg/sculpt/archives | 2 + repos/gems/run/sculpt.run | 11 +- repos/gems/src/app/depot_deploy/child.h | 42 ++++++- repos/gems/src/app/depot_deploy/children.h | 6 + repos/gems/src/app/sculpt_manager/deploy.cc | 5 +- repos/gems/src/app/sculpt_manager/main.cc | 1 + .../src/app/sculpt_manager/model/component.h | 13 +++ .../app/sculpt_manager/model/runtime_config.h | 3 +- .../app/sculpt_manager/model/runtime_state.h | 2 + .../app/sculpt_manager/view/debug_dialog.h | 109 ++++++++++++++++++ .../app/sculpt_manager/view/popup_dialog.cc | 39 ++++++- .../app/sculpt_manager/view/popup_dialog.h | 20 +++- 12 files changed, 245 insertions(+), 8 deletions(-) create mode 100644 repos/gems/src/app/sculpt_manager/view/debug_dialog.h diff --git a/repos/gems/recipes/pkg/sculpt/archives b/repos/gems/recipes/pkg/sculpt/archives index b0b25774c8..984ed896e4 100644 --- a/repos/gems/recipes/pkg/sculpt/archives +++ b/repos/gems/recipes/pkg/sculpt/archives @@ -4,6 +4,8 @@ _/pkg/backdrop _/src/report_rom _/src/clipboard _/src/init +_/src/monitor +_/src/terminal_crosslink _/src/fs_rom _/src/cached_fs_rom _/src/fs_report diff --git a/repos/gems/run/sculpt.run b/repos/gems/run/sculpt.run index 3acf1267d4..00162758fa 100644 --- a/repos/gems/run/sculpt.run +++ b/repos/gems/run/sculpt.run @@ -598,8 +598,16 @@ install_config { + + + + + + + + - + @@ -655,6 +663,7 @@ install_config { + diff --git a/repos/gems/src/app/depot_deploy/child.h b/repos/gems/src/app/depot_deploy/child.h index 5cc46f2e29..26bacfd4e3 100644 --- a/repos/gems/src/app/depot_deploy/child.h +++ b/repos/gems/src/app/depot_deploy/child.h @@ -353,6 +353,8 @@ class Depot_deploy::Child : public List_model::Element Depot_rom_server const &cached_depot_rom, Depot_rom_server const &uncached_depot_rom) const; + inline void gen_monitor_policy_node(Xml_generator&) const; + template void with_missing_pkg_path(FN const &fn) const { @@ -562,11 +564,49 @@ void Depot_deploy::Child::gen_start_node(Xml_generator &xml, } xml.node("route", [&] () { - _gen_routes(xml, common, cached_depot_rom, uncached_depot_rom); }); + + if (start_xml.has_sub_node("monitor")) { + xml.node("service", [&] () { + xml.attribute("name", "PD"); + xml.node("local"); + }); + xml.node("service", [&] () { + xml.attribute("name", "CPU"); + xml.node("local"); + }); + } + + _gen_routes(xml, common, cached_depot_rom, uncached_depot_rom); + }); }); } +void Depot_deploy::Child::gen_monitor_policy_node(Xml_generator &xml) const +{ + if (!_configured() || _condition == UNSATISFIED) + return; + + if (_defined_by_launcher() && !_launcher_xml.constructed()) + return; + + if (!_pkg_xml->xml().has_sub_node("runtime")) { + return; + } + + Xml_node const start_xml = _start_xml->xml(); + + if (start_xml.has_sub_node("monitor")) { + Xml_node const monitor = start_xml.sub_node("monitor"); + xml.node("policy", [&] () { + xml.attribute("label", _name); + xml.attribute("wait", monitor.attribute_value("wait", false)); + xml.attribute("wx", monitor.attribute_value("wx", false)); + }); + } +} + + void Depot_deploy::Child::_gen_routes(Xml_generator &xml, Xml_node common, Depot_rom_server const &cached_depot_rom, Depot_rom_server const &uncached_depot_rom) const diff --git a/repos/gems/src/app/depot_deploy/children.h b/repos/gems/src/app/depot_deploy/children.h index b22c582995..6f64593247 100644 --- a/repos/gems/src/app/depot_deploy/children.h +++ b/repos/gems/src/app/depot_deploy/children.h @@ -159,6 +159,12 @@ class Depot_deploy::Children cached_depot_rom, uncached_depot_rom); }); } + void gen_monitor_policy_nodes(Xml_generator &xml) const + { + _children.for_each([&] (Child const &child) { + child.gen_monitor_policy_node(xml); }); + } + void gen_queries(Xml_generator &xml) const { _children.for_each([&] (Child const &child) { diff --git a/repos/gems/src/app/sculpt_manager/deploy.cc b/repos/gems/src/app/sculpt_manager/deploy.cc index d520983cd0..6b3a2836b7 100644 --- a/repos/gems/src/app/sculpt_manager/deploy.cc +++ b/repos/gems/src/app/sculpt_manager/deploy.cc @@ -194,8 +194,11 @@ void Sculpt::Deploy::gen_runtime_start_nodes(Xml_generator &xml, } /* generate start nodes for deployed packages */ - if (managed_deploy.has_sub_node("common_routes")) + if (managed_deploy.has_sub_node("common_routes")) { _children.gen_start_nodes(xml, managed_deploy.sub_node("common_routes"), prio_levels, affinity_space, "depot_rom", "dynamic_depot_rom"); + xml.node("monitor", [&] () { + _children.gen_monitor_policy_nodes(xml);}); + } } diff --git a/repos/gems/src/app/sculpt_manager/main.cc b/repos/gems/src/app/sculpt_manager/main.cc index a0ad5c1336..90c299b49d 100644 --- a/repos/gems/src/app/sculpt_manager/main.cc +++ b/repos/gems/src/app/sculpt_manager/main.cc @@ -2086,6 +2086,7 @@ void Sculpt::Main::_generate_runtime_config(Xml_generator &xml) const gen_parent_service(xml); gen_parent_service(xml); gen_parent_service(xml); + gen_parent_service(xml); }); xml.node("affinity-space", [&] () { diff --git a/repos/gems/src/app/sculpt_manager/model/component.h b/repos/gems/src/app/sculpt_manager/model/component.h index 53e7b1bcb8..401d171553 100644 --- a/repos/gems/src/app/sculpt_manager/model/component.h +++ b/repos/gems/src/app/sculpt_manager/model/component.h @@ -48,6 +48,10 @@ struct Sculpt::Component : Noncopyable affinity_space.height() }; Priority priority = Priority::DEFAULT; + bool monitor { false }; + bool wait { false }; + bool wx { false }; + struct Blueprint_info { bool known; @@ -188,6 +192,15 @@ struct Sculpt::Component : Noncopyable }); } + void gen_monitor(Xml_generator &xml) const + { + if (monitor) + xml.node("monitor", [&] () { + xml.attribute("wait", wait ? "yes" : "no"); + xml.attribute("wx", wx ? "yes" : "no"); + }); + } + void gen_pd_cpu_route(Xml_generator &xml) const { /* by default pd route goes to parent if nothing is specified */ diff --git a/repos/gems/src/app/sculpt_manager/model/runtime_config.h b/repos/gems/src/app/sculpt_manager/model/runtime_config.h index f1d517927e..29e5998b1a 100644 --- a/repos/gems/src/app/sculpt_manager/model/runtime_config.h +++ b/repos/gems/src/app/sculpt_manager/model/runtime_config.h @@ -320,7 +320,8 @@ class Sculpt::Runtime_config _pin_ctrl { _r, Type::PIN_CONTROL, "GPIO pin control" }, _trace { _r, Type::TRACE, "system-global tracing" }, _vm { _r, Type::VM, "virtualization hardware" }, - _pd { _r, Type::PD, "system PD service" }; + _pd { _r, Type::PD, "system PD service" }, + _monitor { _r, Type::TERMINAL, "debug monitor" }; template void for_each(FN const &fn) const { _r.for_each(fn); } diff --git a/repos/gems/src/app/sculpt_manager/model/runtime_state.h b/repos/gems/src/app/sculpt_manager/model/runtime_state.h index 7392d69e54..c10254bf2f 100644 --- a/repos/gems/src/app/sculpt_manager/model/runtime_state.h +++ b/repos/gems/src/app/sculpt_manager/model/runtime_state.h @@ -185,6 +185,8 @@ class Sculpt::Runtime_state : public Runtime_info construction->gen_priority(xml); construction->gen_affinity(xml); + construction->gen_monitor(xml); + xml.node("route", [&] () { construction->gen_pd_cpu_route(xml); diff --git a/repos/gems/src/app/sculpt_manager/view/debug_dialog.h b/repos/gems/src/app/sculpt_manager/view/debug_dialog.h new file mode 100644 index 0000000000..7b7c7dce69 --- /dev/null +++ b/repos/gems/src/app/sculpt_manager/view/debug_dialog.h @@ -0,0 +1,109 @@ +/* + * \brief Debug options dialog + * \author Christian Prochaska + * \date 2022-09-06 + */ + +/* + * Copyright (C) 2023 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 _VIEW__DEBUG_DIALOG_H_ +#define _VIEW__DEBUG_DIALOG_H_ + +/* local includes */ +#include +#include +#include + +namespace Sculpt { struct Debug_dialog; } + + +struct Sculpt::Debug_dialog : Noncopyable, Deprecated_dialog +{ + bool _monitor; + bool _wait; + bool _wx; + + Hoverable_item _item { }; + + Debug_dialog(bool monitor, bool wait, bool wx) + : _monitor(monitor), _wait(wait), _wx(wx) { } + + Hover_result hover(Xml_node hover) override + { + return Deprecated_dialog::any_hover_changed( + _item.match(hover, "vbox", "hbox", "name")); + } + + void click(Component &component) + { + Hoverable_item::Id const clicked = _item._hovered; + + if (!clicked.valid()) + return; + + if (clicked == "monitor") + _monitor = component.monitor = !component.monitor; + else if (clicked == "wait") { + _wait = component.wait = !component.wait; + /* wait depends on wx */ + if (_wait) + _wx = component.wx = true; + } else if (clicked == "wx") { + _wx = component.wx = !component.wx; + /* wait depends on wx */ + if (!_wx) + _wait = component.wait = false; + } + } + + void _gen_menu_entry(Xml_generator &xml, Start_name const &name, + Component::Info const &text, bool selected, + char const *style = "radio") const + { + gen_named_node(xml, "hbox", name, [&] () { + + gen_named_node(xml, "float", "left", [&] () { + xml.attribute("west", "yes"); + + xml.node("hbox", [&] () { + gen_named_node(xml, "button", "button", [&] () { + + if (selected) + xml.attribute("selected", "yes"); + + xml.attribute("style", style); + _item.gen_hovered_attr(xml, name); + xml.node("hbox", [&] () { }); + }); + gen_named_node(xml, "label", "name", [&] () { + xml.attribute("text", Path(" ", text)); }); + }); + }); + + gen_named_node(xml, "hbox", "right", [&] () { }); + }); + } + + void generate(Xml_generator &xml) const override + { + xml.node("vbox", [&] () { + _gen_menu_entry(xml, "monitor", "monitor this component", _monitor, "checkbox"); + if (_monitor) { + _gen_menu_entry(xml, "wait", " wait for GDB", _wait, "checkbox"); + _gen_menu_entry(xml, "wx", " map executable segments writeable", _wx, "checkbox"); + } + }); + } + + void reset() override + { + _item._hovered = Hoverable_item::Id(); + } +}; + +#endif /* _VIEW__DEBUG_DIALOG_H_ */ diff --git a/repos/gems/src/app/sculpt_manager/view/popup_dialog.cc b/repos/gems/src/app/sculpt_manager/view/popup_dialog.cc index 3345546dbe..06dca022ca 100644 --- a/repos/gems/src/app/sculpt_manager/view/popup_dialog.cc +++ b/repos/gems/src/app/sculpt_manager/view/popup_dialog.cc @@ -88,8 +88,7 @@ void Popup_dialog::_gen_pkg_elements(Xml_generator &xml, _pd_route.generate(xml); if (_resources.constructed()) { - - xml.node("frame", [&] { + gen_named_node(xml, "frame", "resources", [&] { xml.node("vbox", [&] () { bool const selected = _route_selected("resources"); @@ -108,6 +107,26 @@ void Popup_dialog::_gen_pkg_elements(Xml_generator &xml, }); } + if (_debug.constructed()) { + gen_named_node(xml, "frame", "debug", [&] { + xml.node("vbox", [&] () { + + bool const selected = _route_selected("debug"); + + if (!selected) + _gen_route_entry(xml, "debug", + "Debug options ...", false, "enter"); + + if (selected) { + _gen_route_entry(xml, "back", "Debug options ...", + true, "back"); + + _debug->generate(xml); + } + }); + }); + } + /* * Display "Add component" button once all routes are defined */ @@ -476,6 +495,22 @@ void Popup_dialog::click(Action &action) _resources->click(component); }); } + } else if (_debug_dialog_selected()) { + + bool const clicked_on_different_route = clicked_route.valid() + && (clicked_route != ""); + if (clicked_on_different_route) { + + /* close debug options dialog */ + _selected_route.construct(clicked_route); + + } else { + + if (_debug.constructed()) + action.apply_to_construction([&] (Component &component) { + _debug->click(component); }); + } + } else { bool clicked_on_selected_route = false; diff --git a/repos/gems/src/app/sculpt_manager/view/popup_dialog.h b/repos/gems/src/app/sculpt_manager/view/popup_dialog.h index c303fe3fab..42ffe7387e 100644 --- a/repos/gems/src/app/sculpt_manager/view/popup_dialog.h +++ b/repos/gems/src/app/sculpt_manager/view/popup_dialog.h @@ -33,6 +33,7 @@ #include #include +#include namespace Sculpt { struct Popup_dialog; } @@ -123,6 +124,7 @@ struct Sculpt::Popup_dialog : Deprecated_dialog Pd_route_dialog _pd_route { _runtime_config }; Constructible _resources { }; + Constructible _debug { }; enum State { TOP_LEVEL, DEPOT_REQUESTED, DEPOT_SHOWN, DEPOT_SELECTION, INDEX_REQUESTED, INDEX_SHOWN, @@ -149,6 +151,11 @@ struct Sculpt::Popup_dialog : Deprecated_dialog return _route_selected("resources"); } + bool _debug_dialog_selected() const + { + return _route_selected("debug"); + } + template void _apply_to_selected_route(Action &action, FN const &fn) { @@ -163,7 +170,7 @@ struct Sculpt::Popup_dialog : Deprecated_dialog Hover_result hover(Xml_node hover) override { - Deprecated_dialog::Hover_result const hover_result = Deprecated_dialog::any_hover_changed( + Deprecated_dialog::Hover_result hover_result = Deprecated_dialog::any_hover_changed( _item .match(hover, "frame", "vbox", "hbox", "name"), _action_item .match(hover, "frame", "vbox", "button", "name"), _install_item.match(hover, "frame", "vbox", "float", "vbox", "float", "button", "name"), @@ -173,7 +180,11 @@ struct Sculpt::Popup_dialog : Deprecated_dialog if (_resources.constructed() && hover_result == Deprecated_dialog::Hover_result::UNMODIFIED) - return _resources->match_sub_dialog(hover, "frame", "vbox", "frame", "vbox"); + hover_result = _resources->match_sub_dialog(hover, "frame", "vbox", "frame", "vbox"); + + if (_debug.constructed() && + hover_result == Deprecated_dialog::Hover_result::UNMODIFIED) + hover_result = _debug->match_sub_dialog(hover, "frame", "vbox", "frame", "vbox"); return hover_result; } @@ -361,6 +372,7 @@ struct Sculpt::Popup_dialog : Deprecated_dialog _selected_route.destruct(); _menu._level = 0; _resources.destruct(); + _debug.destruct(); _pd_route.reset(); } @@ -415,6 +427,10 @@ struct Sculpt::Popup_dialog : Deprecated_dialog construction.affinity_location, construction.priority); + _debug.construct(construction.monitor, + construction.wait, + construction.wx); + construction.try_apply_blueprint(blueprint); _blueprint_info = construction.blueprint_info;