mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-09 04:15:52 +00:00
parent
1f29055927
commit
a02ec07e49
@ -44,7 +44,8 @@ struct Sculpt::Component : Noncopyable
|
||||
|
||||
bool blueprint_known = false;
|
||||
|
||||
List_model<Route> routes { };
|
||||
List_model<Route> routes { };
|
||||
Route pd_route { "<pd/>" };
|
||||
|
||||
Component(Allocator &alloc, Path const &path, Info const &info,
|
||||
Affinity::Space const space)
|
||||
@ -92,6 +93,22 @@ struct Sculpt::Component : Noncopyable
|
||||
});
|
||||
}
|
||||
|
||||
void gen_pd_cpu_route(Xml_generator &xml) const
|
||||
{
|
||||
/* by default pd route goes to parent if nothing is specified */
|
||||
if (!pd_route.selected_service.constructed())
|
||||
return;
|
||||
|
||||
/*
|
||||
* Until PD & CPU gets merged, enforce on Sculpt that PD and CPU routes
|
||||
* go to the same server.
|
||||
*/
|
||||
gen_named_node(xml, "service", Sculpt::Service::name_attr(pd_route.required), [&] () {
|
||||
pd_route.selected_service->gen_xml(xml); });
|
||||
gen_named_node(xml, "service", "CPU", [&] () {
|
||||
pd_route.selected_service->gen_xml(xml); });
|
||||
}
|
||||
|
||||
bool all_routes_defined() const
|
||||
{
|
||||
bool result = true;
|
||||
|
@ -46,6 +46,7 @@ struct Sculpt::Route : List_model<Route>::Element
|
||||
case Service::Type::RTC: return "rtc";
|
||||
case Service::Type::PLATFORM: return "platform";
|
||||
case Service::Type::VM: return "vm";
|
||||
case Service::Type::PD: return "pd";
|
||||
case Service::Type::UNDEFINED: break;
|
||||
}
|
||||
return "undefined";
|
||||
@ -72,6 +73,7 @@ struct Sculpt::Route : List_model<Route>::Element
|
||||
case Service::Type::RTC: return "Real-time clock";
|
||||
case Service::Type::PLATFORM: return "Device access";
|
||||
case Service::Type::VM: return "Hardware-based virtualization";
|
||||
case Service::Type::PD: return "Protection domain";
|
||||
case Service::Type::UNDEFINED: break;
|
||||
}
|
||||
return "<undefined>";
|
||||
|
@ -350,7 +350,8 @@ class Sculpt::Runtime_config
|
||||
_pci_audio { _r, Type::PLATFORM, "audio hardware", "audio" },
|
||||
_pci_acpi { _r, Type::PLATFORM, "ACPI", "acpica" },
|
||||
_trace { _r, Type::TRACE, "system-global tracing" },
|
||||
_vm { _r, Type::VM, "virtualization hardware" };
|
||||
_vm { _r, Type::VM, "virtualization hardware" },
|
||||
_pd { _r, Type::PD, "system PD service" };
|
||||
|
||||
template <typename FN>
|
||||
void for_each(FN const &fn) const { _r.for_each(fn); }
|
||||
|
@ -157,6 +157,8 @@ class Sculpt::Runtime_state : public Runtime_info
|
||||
construction->gen_affinity_xml(xml);
|
||||
|
||||
xml.node("route", [&] () {
|
||||
construction->gen_pd_cpu_route(xml);
|
||||
|
||||
construction->routes.for_each([&] (Route const &route) {
|
||||
route.gen_xml(xml); }); });
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ struct Sculpt::Service
|
||||
enum class Type {
|
||||
AUDIO_IN, AUDIO_OUT, BLOCK, FILE_SYSTEM, NIC, GUI,
|
||||
RM, IO_MEM, IO_PORT, IRQ, REPORT, ROM, TERMINAL, TRACE,
|
||||
USB, RTC, PLATFORM, VM, UNDEFINED };
|
||||
USB, RTC, PLATFORM, VM, PD, UNDEFINED };
|
||||
|
||||
enum class Match_label { EXACT, LAST };
|
||||
|
||||
@ -61,6 +61,7 @@ struct Sculpt::Service
|
||||
case Type::RTC: return "Rtc";
|
||||
case Type::PLATFORM: return "Platform";
|
||||
case Type::VM: return "VM";
|
||||
case Type::PD: return "PD";
|
||||
case Type::UNDEFINED: break;
|
||||
}
|
||||
return "undefined";
|
||||
|
107
repos/gems/src/app/sculpt_manager/view/pd_route_dialog.cc
Normal file
107
repos/gems/src/app/sculpt_manager/view/pd_route_dialog.cc
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* \brief PD/CPU route assignment dialog
|
||||
* \author Alexander Boettcher
|
||||
* \date 2021-02-26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 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 <view/pd_route_dialog.h>
|
||||
|
||||
using namespace Sculpt;
|
||||
|
||||
void Pd_route_dialog::generate(Xml_generator &xml) const
|
||||
{
|
||||
/* find out number of available PD services */
|
||||
unsigned count_pd_services = 0;
|
||||
_runtime_config.for_each_service([&] (Service const &service) {
|
||||
|
||||
if (service.type == Service::Type::PD)
|
||||
count_pd_services ++;
|
||||
});
|
||||
|
||||
/* don't show the PD menu if just the system PD service is available */
|
||||
if (count_pd_services <= 1)
|
||||
return;
|
||||
|
||||
{
|
||||
Route::Id const pd_id("pd_route");
|
||||
|
||||
gen_named_node(xml, "frame", pd_id, [&] () {
|
||||
|
||||
xml.node("vbox", [&] () {
|
||||
|
||||
bool const defined = _route.selected_service.constructed();
|
||||
|
||||
if (!_menu_selected) {
|
||||
_gen_route_entry(xml, pd_id,
|
||||
defined ? Component::Info(_route.selected_service->info)
|
||||
: Component::Info(_route),
|
||||
defined);
|
||||
}
|
||||
|
||||
/*
|
||||
* List of routing options
|
||||
*/
|
||||
if (_menu_selected) {
|
||||
_gen_route_entry(xml, "back", Component::Info(_route), true, "back");
|
||||
|
||||
unsigned cnt = 0;
|
||||
_runtime_config.for_each_service([&] (Service const &service) {
|
||||
|
||||
Hoverable_item::Id const id("service.", cnt++);
|
||||
|
||||
bool const service_selected =
|
||||
_route.selected_service.constructed() &&
|
||||
id == _route.selected_service_id;
|
||||
|
||||
if (service.type == _route.required)
|
||||
_gen_route_entry(xml, id, service.info, service_selected);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Pd_route_dialog::click(Component &component)
|
||||
{
|
||||
if (_route_item.hovered("pd_route")) {
|
||||
_menu_selected = true;
|
||||
}
|
||||
|
||||
if (!_menu_selected)
|
||||
return;
|
||||
|
||||
unsigned cnt = 0;
|
||||
_runtime_config.for_each_service([&] (Service const &service) {
|
||||
|
||||
Hoverable_item::Id const id("service.", cnt++);
|
||||
|
||||
if (!_route_item.hovered(id))
|
||||
return;
|
||||
|
||||
if (_route.selected_service.constructed()) {
|
||||
if (component.pd_route.selected_service.constructed())
|
||||
component.pd_route.selected_service.destruct();
|
||||
|
||||
_route.selected_service.destruct();
|
||||
if (_route_item.hovered(_route.selected_service_id)) {
|
||||
_route.selected_service_id = Hoverable_item::Id();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
component.pd_route.selected_service.construct(service);
|
||||
|
||||
_route.selected_service.construct(service);
|
||||
_route.selected_service_id = id;
|
||||
|
||||
_menu_selected = false;
|
||||
});
|
||||
}
|
107
repos/gems/src/app/sculpt_manager/view/pd_route_dialog.h
Normal file
107
repos/gems/src/app/sculpt_manager/view/pd_route_dialog.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* \brief PD/CPU route assignment dialog
|
||||
* \author Alexander Boettcher
|
||||
* \date 2021-02-26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 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__PD_ROUTE_DIALOG_H_
|
||||
#define _VIEW__PD_ROUTE_DIALOG_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <os/reporter.h>
|
||||
#include <depot/archive.h>
|
||||
|
||||
/* local includes */
|
||||
#include <xml.h>
|
||||
#include <model/component.h>
|
||||
#include <model/runtime_config.h>
|
||||
#include <view/dialog.h>
|
||||
|
||||
namespace Sculpt { struct Pd_route_dialog; }
|
||||
|
||||
|
||||
struct Sculpt::Pd_route_dialog : Noncopyable, Dialog
|
||||
{
|
||||
Route _route { "<pd/>" };
|
||||
Hoverable_item _route_item { };
|
||||
bool _menu_selected { false };
|
||||
|
||||
Runtime_config const &_runtime_config;
|
||||
|
||||
Pd_route_dialog(Runtime_config const &runtime_config)
|
||||
:
|
||||
_runtime_config(runtime_config)
|
||||
{ }
|
||||
|
||||
Hover_result hover(Xml_node hover_node) override
|
||||
{
|
||||
Dialog::Hover_result const hover_result = hover(hover_node);
|
||||
return hover_result;
|
||||
}
|
||||
|
||||
template <typename... ARGS>
|
||||
Hover_result hover(Xml_node hover, ARGS &&... args)
|
||||
{
|
||||
Dialog::Hover_result const hover_result = Dialog::any_hover_changed(
|
||||
_route_item.match(hover, args...));
|
||||
|
||||
return hover_result;
|
||||
}
|
||||
|
||||
void click(Component &);
|
||||
|
||||
void generate(Xml_generator &xml) const override;
|
||||
|
||||
void reset() override
|
||||
{
|
||||
if (_route.selected_service.constructed())
|
||||
_route.selected_service.destruct();
|
||||
_route_item._hovered = Hoverable_item::Id();
|
||||
_menu_selected = false;
|
||||
}
|
||||
|
||||
void click()
|
||||
{
|
||||
if (_route_item.hovered("pd_route"))
|
||||
_menu_selected = true;
|
||||
}
|
||||
|
||||
void _gen_route_entry(Xml_generator &xml,
|
||||
Start_name const &name,
|
||||
Start_name 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);
|
||||
_route_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", [&] () { });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _VIEW__PD_ROUTE_DIALOG_H_ */
|
@ -85,6 +85,8 @@ void Popup_dialog::_gen_pkg_elements(Xml_generator &xml,
|
||||
});
|
||||
});
|
||||
|
||||
_pd_route.generate(xml);
|
||||
|
||||
if (_resources.constructed() && component.affinity_space.total() > 1) {
|
||||
xml.node("frame", [&] {
|
||||
xml.node("vbox", [&] () {
|
||||
@ -302,6 +304,7 @@ void Popup_dialog::click(Action &action)
|
||||
|
||||
_action_item .propose_activation_on_click();
|
||||
_install_item.propose_activation_on_click();
|
||||
_pd_route.click();
|
||||
|
||||
Route::Id const clicked_route = _route_item._hovered;
|
||||
|
||||
@ -440,7 +443,7 @@ void Popup_dialog::click(Action &action)
|
||||
if (clicked_route == "back") {
|
||||
_state = PKG_SHOWN;
|
||||
_selected_route.destruct();
|
||||
|
||||
_pd_route.reset();
|
||||
} else {
|
||||
|
||||
bool clicked_on_selected_route = false;
|
||||
@ -490,6 +493,10 @@ void Popup_dialog::click(Action &action)
|
||||
_resources->click(component);
|
||||
});
|
||||
}
|
||||
|
||||
action.apply_to_construction([&] (Component &component) {
|
||||
_pd_route.click(component);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <view/activatable_item.h>
|
||||
#include <depot_query.h>
|
||||
|
||||
#include <view/pd_route_dialog.h>
|
||||
#include <view/resource_dialog.h>
|
||||
|
||||
namespace Sculpt { struct Popup_dialog; }
|
||||
@ -114,6 +115,7 @@ struct Sculpt::Popup_dialog : Dialog
|
||||
Activatable_item _action_item { };
|
||||
Activatable_item _install_item { };
|
||||
Hoverable_item _route_item { };
|
||||
Pd_route_dialog _pd_route { _runtime_config };
|
||||
|
||||
Constructible<Resource_dialog> _resources { };
|
||||
|
||||
@ -198,6 +200,8 @@ struct Sculpt::Popup_dialog : Dialog
|
||||
_install_item.match(hover, "frame", "vbox", "float", "vbox", "float", "button", "name"),
|
||||
_route_item .match(hover, "frame", "vbox", "frame", "vbox", "hbox", "name"));
|
||||
|
||||
_pd_route.hover(hover, "frame", "vbox", "frame", "vbox", "hbox", "name");
|
||||
|
||||
if (_resources.constructed() &&
|
||||
hover_result == Dialog::Hover_result::UNMODIFIED)
|
||||
return _resources->hover(hover, "frame", "vbox", "frame", "vbox");
|
||||
@ -407,6 +411,7 @@ struct Sculpt::Popup_dialog : Dialog
|
||||
_selected_route.destruct();
|
||||
_menu._level = 0;
|
||||
_resources.destruct();
|
||||
_pd_route.reset();
|
||||
}
|
||||
|
||||
Popup_dialog(Env &env, Refresh &refresh,
|
||||
|
Loading…
x
Reference in New Issue
Block a user