diff --git a/repos/base-hw/src/core/spec/arm_v8/pd_session_support.cc b/repos/base-hw/src/core/spec/arm_v8/pd_session_support.cc index dcc06a59a2..9aae4f1799 100644 --- a/repos/base-hw/src/core/spec/arm_v8/pd_session_support.cc +++ b/repos/base-hw/src/core/spec/arm_v8/pd_session_support.cc @@ -19,20 +19,47 @@ using namespace Core; using State = Genode::Pd_session::Managing_system_state; -State Pd_session_component::managing_system(State const & s) +class System_control_component : public Genode::Rpc_object, + public Core::System_control { - static constexpr addr_t SMCCC_NOT_SUPPORTED = 0xffffffffUL; + public: + State system_control(State const &) override; + + Capability control_cap(Affinity::Location const) const override; +}; + + +State System_control_component::system_control(State const &s) +{ State ret; - ret.r[0] = (_managing_system == Managing_system::DENIED) - ? SMCCC_NOT_SUPPORTED - : Hw::Psci_smc_functor::call(s.r[0], s.r[1], s.r[2], s.r[3]); + ret.r[0] = Hw::Psci_smc_functor::call(s.r[0], s.r[1], s.r[2], s.r[3]); return ret; } +static System_control_component &system_instance() +{ + static System_control_component system_component { }; + return system_component; +} + + +System_control & Core::init_system_control(Allocator &, Rpc_entrypoint &ep) +{ + ep.manage(&system_instance()); + return system_instance(); +} + + +Capability System_control_component::control_cap(Affinity::Location const) const +{ + return system_instance().cap(); +} + + /*************************** ** Dummy implementations ** ***************************/ diff --git a/repos/base-hw/src/core/spec/x86_64/pd_session_support.cc b/repos/base-hw/src/core/spec/x86_64/pd_session_support.cc index 87b9085ccc..952c80ef48 100644 --- a/repos/base-hw/src/core/spec/x86_64/pd_session_support.cc +++ b/repos/base-hw/src/core/spec/x86_64/pd_session_support.cc @@ -18,10 +18,20 @@ using namespace Core; using State = Genode::Pd_session::Managing_system_state; -State Pd_session_component::managing_system(State const &request) +class System_control_component : public Genode::Rpc_object, + public Core::System_control { - bool const suspend = (_managing_system == Managing_system::PERMITTED) && - (request.trapno == State::ACPI_SUSPEND_REQUEST); + public: + + State system_control(State const &) override; + + Capability control_cap(Affinity::Location const) const override; +}; + + +State System_control_component::system_control(State const &request) +{ + bool const suspend = (request.trapno == State::ACPI_SUSPEND_REQUEST); State respond { }; if (!suspend) { @@ -49,6 +59,26 @@ State Pd_session_component::managing_system(State const &request) } +static System_control_component &system_instance() +{ + static System_control_component system_component { }; + return system_component; +} + + +System_control & Core::init_system_control(Allocator &, Rpc_entrypoint &ep) +{ + ep.manage(&system_instance()); + return system_instance(); +} + + +Capability System_control_component::control_cap(Affinity::Location const) const +{ + return system_instance().cap(); +} + + /*************************** ** Dummy implementations ** ***************************/ @@ -57,4 +87,3 @@ bool Pd_session_component::assign_pci(addr_t, uint16_t) { return true; } void Pd_session_component::map(addr_t, addr_t) { } - diff --git a/repos/base-nova/src/core/pd_session_support.cc b/repos/base-nova/src/core/pd_session_support.cc index d74f2577cc..ffa642bab9 100644 --- a/repos/base-nova/src/core/pd_session_support.cc +++ b/repos/base-nova/src/core/pd_session_support.cc @@ -101,10 +101,41 @@ void Pd_session_component::map(addr_t virt, addr_t size) using State = Genode::Pd_session::Managing_system_state; -State Pd_session_component::managing_system(State const &request) + +class System_control_component : public Genode::Rpc_object, + public Core::System_control { - bool const suspend = (_managing_system == Managing_system::PERMITTED) && - (request.trapno == State::ACPI_SUSPEND_REQUEST); + public: + + State system_control(State const &) override; + + Capability control_cap(Affinity::Location const) const override; +}; + + +static System_control_component &system_instance() +{ + static System_control_component system_component { }; + return system_component; +} + + +System_control & Core::init_system_control(Allocator &, Rpc_entrypoint &ep) +{ + ep.manage(&system_instance()); + return system_instance(); +} + + +Capability System_control_component::control_cap(Affinity::Location const) const +{ + return system_instance().cap(); +} + + +State System_control_component::system_control(State const &request) +{ + bool const suspend = (request.trapno == State::ACPI_SUSPEND_REQUEST); State respond { }; if (!suspend) { diff --git a/repos/base/include/pd_session/client.h b/repos/base/include/pd_session/client.h index e578f192cd..bd6a9608cf 100644 --- a/repos/base/include/pd_session/client.h +++ b/repos/base/include/pd_session/client.h @@ -93,8 +93,8 @@ struct Genode::Pd_session_client : Rpc_client Capability native_pd() override { return call(); } - Managing_system_state managing_system(Managing_system_state const & state) override { - return call(state); } + Capability system_control_cap(Affinity::Location const location) override { + return call(location); } addr_t dma_addr(Ram_dataspace_capability ds) override { return call(ds); } diff --git a/repos/base/include/pd_session/pd_session.h b/repos/base/include/pd_session/pd_session.h index f824b77d3a..bb1a02d560 100644 --- a/repos/base/include/pd_session/pd_session.h +++ b/repos/base/include/pd_session/pd_session.h @@ -16,6 +16,7 @@ #define _INCLUDE__PD_SESSION__PD_SESSION_H_ #include +#include #include #include #include @@ -305,12 +306,26 @@ struct Genode::Pd_session : Session, Ram_allocator ** Access to system management interface ** *******************************************/ + struct System_control : Interface + { + using System_control_state = Cpu_state; + + virtual System_control_state system_control(System_control_state const &) = 0; + + GENODE_RPC(Rpc_system_control, System_control_state, system_control, + System_control_state const &); + + GENODE_RPC_INTERFACE(Rpc_system_control); + }; + + using Managing_system_state = Cpu_state; /** - * Call privileged system management functionality of kernel or firmware + * Call privileged system control functionality of kernel or firmware */ - virtual Managing_system_state managing_system(Managing_system_state const &) = 0; + + virtual Capability system_control_cap(Affinity::Location const) = 0; /******************************************* @@ -391,8 +406,9 @@ struct Genode::Pd_session : Session, Ram_allocator GENODE_RPC(Rpc_native_pd, Capability, native_pd); - GENODE_RPC(Rpc_managing_system, Managing_system_state, managing_system, - Managing_system_state const &); + GENODE_RPC(Rpc_system_control_cap, Capability, + system_control_cap, Affinity::Location); + GENODE_RPC(Rpc_dma_addr, addr_t, dma_addr, Ram_dataspace_capability); GENODE_RPC(Rpc_attach_dma, Attach_dma_result, attach_dma, Dataspace_capability, addr_t); @@ -405,7 +421,7 @@ struct Genode::Pd_session : Session, Ram_allocator Rpc_transfer_cap_quota, Rpc_cap_quota, Rpc_used_caps, Rpc_try_alloc, Rpc_free, Rpc_transfer_ram_quota, Rpc_ram_quota, Rpc_used_ram, - Rpc_native_pd, Rpc_managing_system, + Rpc_native_pd, Rpc_system_control_cap, Rpc_dma_addr, Rpc_attach_dma); }; diff --git a/repos/base/src/core/include/core_env.h b/repos/base/src/core/include/core_env.h index a2436f6262..fef3b37bf8 100644 --- a/repos/base/src/core/include/core_env.h +++ b/repos/base/src/core/include/core_env.h @@ -75,7 +75,8 @@ class Core::Core_env : public Noncopyable _region_map, *((Pager_entrypoint *)nullptr), "" /* args to native PD */, - platform_specific().core_mem_alloc()) + platform_specific().core_mem_alloc(), + *((Core::System_control *)nullptr)) { _pd_session.init_cap_and_ram_accounts(); } diff --git a/repos/base/src/core/include/pd_root.h b/repos/base/src/core/include/pd_root.h index 908b8ea2fa..547c4035ff 100644 --- a/repos/base/src/core/include/pd_root.h +++ b/repos/base/src/core/include/pd_root.h @@ -33,6 +33,7 @@ class Core::Pd_root : public Root_component Range_allocator &_phys_alloc; Region_map &_local_rm; Range_allocator &_core_mem; + System_control &_system_control; /** * The RAM allocations of system management components are getting @@ -91,7 +92,7 @@ class Core::Pd_root : public Root_component _virt_range_from_args(args), _managing_system(args), _local_rm, _pager_ep, args, - _core_mem); + _core_mem, _system_control); } void _upgrade_session(Pd_session_component *pd, const char *args) override @@ -111,11 +112,13 @@ class Core::Pd_root : public Root_component Range_allocator &phys_alloc, Region_map &local_rm, Allocator &md_alloc, - Range_allocator &core_mem) + Range_allocator &core_mem, + System_control &system_control) : Root_component(&ep, &md_alloc), _ep(ep), _signal_ep(signal_ep), _pager_ep(pager_ep), - _phys_alloc(phys_alloc), _local_rm(local_rm), _core_mem(core_mem) + _phys_alloc(phys_alloc), _local_rm(local_rm), _core_mem(core_mem), + _system_control(system_control) { } }; diff --git a/repos/base/src/core/include/pd_session_component.h b/repos/base/src/core/include/pd_session_component.h index fd904a0f5d..d8c2d5d06b 100644 --- a/repos/base/src/core/include/pd_session_component.h +++ b/repos/base/src/core/include/pd_session_component.h @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,7 @@ class Core::Pd_session_component : public Session_object Constructible > _ram_account { }; Rpc_entrypoint &_ep; + Core::System_control &_system_control; Constrained_ram_allocator _constrained_md_ram_alloc; Constrained_core_ram _constrained_core_ram_alloc; Sliced_heap _sliced_heap; @@ -131,10 +133,12 @@ class Core::Pd_session_component : public Session_object Region_map &local_rm, Pager_entrypoint &pager_ep, char const *args, - Range_allocator &core_mem) + Range_allocator &core_mem, + Core::System_control &system_control) : Session_object(ep, resources, label, diag), _ep(ep), + _system_control(system_control), _constrained_md_ram_alloc(*this, _ram_quota_guard(), _cap_quota_guard()), _constrained_core_ram_alloc(_ram_quota_guard(), _cap_quota_guard(), core_mem), _sliced_heap(_constrained_md_ram_alloc, local_rm), @@ -329,11 +333,17 @@ class Core::Pd_session_component : public Session_object Capability native_pd() override { return _native_pd.cap(); } - /******************************* - ** Managing system interface ** - *******************************/ + /****************************** + ** System control interface ** + ******************************/ - Managing_system_state managing_system(Managing_system_state const &) override; + Capability system_control_cap(Affinity::Location const location) override + { + if (_managing_system == Managing_system::PERMITTED) + return _system_control.control_cap(location); + + return { }; + } /******************************************* diff --git a/repos/base/src/core/include/system_control.h b/repos/base/src/core/include/system_control.h new file mode 100644 index 0000000000..f5fa0b5bcb --- /dev/null +++ b/repos/base/src/core/include/system_control.h @@ -0,0 +1,36 @@ +/* + * \brief Interface to get access to privileged system control capability + * \author Alexander Boettcher + * \date 2023-09-25 + */ + +/* + * 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 _CORE__INCLUDE__SYSTEM_CONTROL_H_ +#define _CORE__INCLUDE__SYSTEM_CONTROL_H_ + + +#include + + +namespace Core { + + class System_control; + + System_control & init_system_control(Allocator &, Rpc_entrypoint &); +} + + +class Core::System_control : Interface +{ + public: + + virtual Capability control_cap(Affinity::Location) const = 0; +}; + +#endif /* _CORE__INCLUDE__SYSTEM_CONTROL_H_ */ diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc index 7641fbcdf7..9da4ed6fd5 100644 --- a/repos/base/src/core/main.cc +++ b/repos/base/src/core/main.cc @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -255,6 +256,8 @@ void Genode::bootstrap_component(Genode::Platform &) using Trace_root = Core::Trace::Root; using Trace_session_component = Core::Trace::Session_component; + static Core::System_control &system_control = init_system_control(sliced_heap, ep); + static Rom_root rom_root (ep, ep, platform().rom_fs(), sliced_heap); static Rm_root rm_root (ep, sliced_heap, core_ram_alloc, local_rm, pager_ep); static Cpu_root cpu_root (core_ram_alloc, local_rm, ep, ep, pager_ep, @@ -262,7 +265,8 @@ void Genode::bootstrap_component(Genode::Platform &) static Pd_root pd_root (ep, core_env().signal_ep(), pager_ep, platform().ram_alloc(), local_rm, sliced_heap, - platform_specific().core_mem_alloc()); + platform_specific().core_mem_alloc(), + system_control); static Log_root log_root (ep, sliced_heap); static Io_mem_root io_mem_root (ep, ep, platform().io_mem_alloc(), platform().ram_alloc(), sliced_heap); diff --git a/repos/base/src/core/pd_session_support.cc b/repos/base/src/core/pd_session_support.cc index 6e632a1679..26ede054e2 100644 --- a/repos/base/src/core/pd_session_support.cc +++ b/repos/base/src/core/pd_session_support.cc @@ -22,6 +22,20 @@ bool Pd_session_component::assign_pci(addr_t, uint16_t) { return true; } void Pd_session_component::map(addr_t, addr_t) { } -using State = Genode::Pd_session::Managing_system_state; -State Pd_session_component::managing_system(State const &) { return State(); } +class System_control_dummy : public System_control +{ + public: + + Capability control_cap(Affinity::Location) const override + { + return { }; + } +}; + + +System_control & Core::init_system_control(Allocator &, Rpc_entrypoint &) +{ + static System_control_dummy dummy { }; + return dummy; +} diff --git a/repos/libports/src/test/suspend/component.cc b/repos/libports/src/test/suspend/component.cc index 6b7b90d5e1..e8056b3bfb 100644 --- a/repos/libports/src/test/suspend/component.cc +++ b/repos/libports/src/test/suspend/component.cc @@ -34,6 +34,17 @@ class Suspend uint8_t s3_sleep_typeb { }; bool s3_sleep_valid { }; + Capability _control_cap { _env.pd().system_control_cap(Affinity::Location()) }; + + struct Client: Genode::Rpc_client + { + explicit Client(Genode::Capability cap) + : Rpc_client(cap) { } + + Pd_session::Managing_system_state system_control(Pd_session::Managing_system_state const &state) override { + return call(state); } + } _system_control { _control_cap }; + void suspend() { /* @@ -58,7 +69,7 @@ class Suspend in.ip = s3_sleep_typea; in.sp = s3_sleep_typeb; - out = _env.pd().managing_system (in); + out = _system_control.system_control (in); if (!out.trapno) log("suspend failed"); diff --git a/repos/os/src/monitor/inferior_pd.h b/repos/os/src/monitor/inferior_pd.h index 344e4e68fb..b3d6056d5b 100644 --- a/repos/os/src/monitor/inferior_pd.h +++ b/repos/os/src/monitor/inferior_pd.h @@ -267,8 +267,8 @@ struct Monitor::Inferior_pd : Monitored_pd_session Capability native_pd() override { return _real.call(); } - Managing_system_state managing_system(Managing_system_state const & state) override { - return _real.call(state); } + Capability system_control_cap(Affinity::Location const location) override { + return _real.call(location); } addr_t dma_addr(Ram_dataspace_capability ds) override { return _real.call(ds); } diff --git a/repos/os/src/monitor/pd_intrinsics.h b/repos/os/src/monitor/pd_intrinsics.h index 022575146b..9dfaceb63a 100644 --- a/repos/os/src/monitor/pd_intrinsics.h +++ b/repos/os/src/monitor/pd_intrinsics.h @@ -39,6 +39,7 @@ struct Monitor::Pd_intrinsics : Sandbox::Pd_intrinsics using Sig_ctx_cap = Signal_context_capability; using Ram_ds_cap = Ram_dataspace_capability; using Mng_sys_state = Managing_system_state; + using Control_cap = Capability; void assign_parent(Capability) override { never_called(__func__); }; bool assign_pci(addr_t, uint16_t) override { never_called(__func__); }; @@ -61,7 +62,7 @@ struct Monitor::Pd_intrinsics : Sandbox::Pd_intrinsics Ram_quota ram_quota() const override { never_called(__func__); }; Ram_quota used_ram() const override { never_called(__func__); }; Capability native_pd() override { never_called(__func__); }; - Mng_sys_state managing_system(Mng_sys_state const &) override { never_called(__func__); }; + Control_cap system_control_cap(Affinity::Location) override { never_called(__func__); }; addr_t dma_addr(Ram_ds_cap) override { never_called(__func__); }; Attach_dma_result attach_dma(Dataspace_capability, addr_t) override { never_called(__func__); }; diff --git a/repos/ports/src/app/gdb_monitor/pd_session_component.h b/repos/ports/src/app/gdb_monitor/pd_session_component.h index ea8e3cba7e..b3ac9cebcd 100644 --- a/repos/ports/src/app/gdb_monitor/pd_session_component.h +++ b/repos/ports/src/app/gdb_monitor/pd_session_component.h @@ -145,9 +145,8 @@ class Gdb_monitor::Pd_session_component : public Rpc_object Capability native_pd() override { return _pd.native_pd(); } - Managing_system_state - managing_system(Managing_system_state const & state) override { - return _pd.managing_system(state); } + Capability system_control_cap(Affinity::Location const location) override { + return _pd.system_control_cap(location); } addr_t dma_addr(Ram_dataspace_capability ds) override { return _pd.dma_addr(ds); }