diff --git a/repos/demo/include/launchpad/launchpad.h b/repos/demo/include/launchpad/launchpad.h index 77c128c9d..12268fcc7 100644 --- a/repos/demo/include/launchpad/launchpad.h +++ b/repos/demo/include/launchpad/launchpad.h @@ -26,65 +26,138 @@ #include #include #include - #include -class Launchpad_child_policy : public Genode::Child_policy, - public Genode::Client +class Launchpad; + + +class Launchpad_child : public Genode::Child_policy, + public Genode::List::Element, + public Genode::Child_service::Wakeup { + public: + + typedef Genode::Child_policy::Name Name; + + typedef Genode::Registered Child_service; + typedef Genode::Registered Parent_service; + + typedef Genode::Registry Child_services; + typedef Genode::Registry Parent_services; + private: - typedef Genode::String<64> Name; Name const _name; - Genode::Server *_server; - Genode::Service_registry *_parent_services; - Genode::Service_registry *_child_services; - Genode::Dataspace_capability _config_ds; - Genode::Rpc_entrypoint *_parent_entrypoint; - Init::Child_policy_enforce_labeling _labeling_policy; - Init::Child_policy_provide_rom_file _config_policy; - Init::Child_policy_provide_rom_file _binary_policy; + Genode::Env &_env; + + Genode::Ram_session_capability _ref_ram_cap; + Genode::Ram_session_client _ref_ram { _ref_ram_cap }; + Genode::size_t const _ram_quota; + + Parent_services &_parent_services; + Child_services &_child_services; + + Genode::Dataspace_capability _config_ds; + + Genode::Session_requester _session_requester; + + Init::Child_policy_enforce_labeling _labeling_policy { _name.string() }; + Init::Child_policy_provide_rom_file _config_policy; + + Genode::Child _child; + + /** + * Child_service::Wakeup callback + */ + void wakeup_child_service() override + { + _session_requester.trigger_update(); + } + + template + static Genode::Service *_find_service(Genode::Registry &services, + Genode::Service::Name const &name) + { + Genode::Service *service = nullptr; + services.for_each([&] (T &s) { + if (!service && (s.name() == name)) + service = &s; }); + return service; + } public: - Launchpad_child_policy(const char *name, - Genode::Server *server, - Genode::Service_registry *parent_services, - Genode::Service_registry *child_services, - Genode::Dataspace_capability config_ds, - Genode::Dataspace_capability binary_ds, - Genode::Rpc_entrypoint *parent_entrypoint) + Launchpad_child(Genode::Env &env, + Genode::Session_label const &label, + Name const &elf_name, + Genode::size_t ram_quota, + Parent_services &parent_services, + Child_services &child_services, + Genode::Dataspace_capability config_ds) : - _name(name), - _server(server), + _name(label), + _env(env), _ref_ram_cap(env.ram_session_cap()), _ram_quota(ram_quota), _parent_services(parent_services), _child_services(child_services), - _config_ds(config_ds), - _parent_entrypoint(parent_entrypoint), - _labeling_policy(_name.string()), - _config_policy("config", config_ds, _parent_entrypoint), - _binary_policy("binary", binary_ds, _parent_entrypoint) + _session_requester(env.ep().rpc_ep(), _env.ram(), _env.rm()), + _config_policy("config", config_ds, &_env.ep().rpc_ep()), + _child(_env.rm(), _env.ep().rpc_ep(), *this) { } - const char *name() const { return _name.string(); } - - Genode::Service *resolve_session_request(const char *service_name, - const char *args) + ~Launchpad_child() { - Genode::Service *service; + using namespace Genode; + + /* unregister services */ + _child_services.for_each( + [&] (Child_service &service) { + if (service.has_id_space(_session_requester.id_space())) + Genode::destroy(_child.heap(), &service); }); + } + + Genode::Allocator &heap() { return _child.heap(); } + + + /**************************** + ** Child_policy interface ** + ****************************/ + + Name name() const override { return _name; } + + Genode::Ram_session &ref_ram() override { return _ref_ram; } + + Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; } + + void init(Genode::Ram_session &session, + Genode::Ram_session_capability cap) override + { + session.ref_account(_ref_ram_cap); + _ref_ram.transfer_quota(cap, _ram_quota); + } + + Genode::Id_space &server_id_space() override { + return _session_requester.id_space(); } + + Genode::Service &resolve_session_request(Genode::Service::Name const &service_name, + Genode::Session_state::Args const &args) override + { + Genode::Service *service = nullptr; /* check for config file request */ - if ((service = _config_policy.resolve_session_request(service_name, args))) - return service; + if ((service = _config_policy + .resolve_session_request(service_name.string(), args.string()))) + return *service; - /* check for binary file request */ - if ((service = _binary_policy.resolve_session_request(service_name, args))) - return service; + /* check for "session_requests" ROM request */ + Genode::Session_label const label(Genode::label_from_args(args.string())); + if (service_name == Genode::Rom_session::service_name() + && label.last_element() == Genode::Session_requester::rom_name()) + return _session_requester.service(); /* if service is provided by one of our children, use it */ - if ((service = _child_services->find(service_name))) - return service; + if ((service = _find_service(_child_services, service_name))) + return *service; /* * Handle special case of the demo scenario when the user uses @@ -100,130 +173,33 @@ class Launchpad_child_policy : public Genode::Child_policy, * interacted, however, would block at the parent interface * until this condition gets satisfied. */ - if (Genode::strcmp(service_name, "Input") != 0 - && Genode::strcmp(service_name, "Framebuffer") != 0 - && (service = _parent_services->find(service_name))) - return service; + if (service_name != "Input" + && service_name != "Framebuffer" + && ((service = _find_service(_parent_services, service_name)))) + return *service; - /* wait for the service to become available */ - Genode::Client client; - return _child_services->wait_for_service(service_name, - &client, name()); + Genode::warning(name(), ": service ", service_name, " not available"); + throw Genode::Parent::Service_denied(); } - void filter_session_args(const char *service, char *args, - Genode::size_t args_len) + void filter_session_args(Genode::Service::Name const &service, + char *args, Genode::size_t args_len) override { - _labeling_policy.filter_session_args(service, args, args_len); + _labeling_policy.filter_session_args(service.string(), args, args_len); } - bool announce_service(const char *service_name, - Genode::Root_capability root, - Genode::Allocator *alloc, - Genode::Server * /*server*/) + void announce_service(Genode::Service::Name const &service_name) override { - if (_child_services->find(service_name)) { - PWRN("%s: service %s is already registered", - name(), service_name); - return false; + if (_find_service(_child_services, service_name)) { + Genode::warning(name(), ": service ", service_name, " is already registered"); + return; } - /* XXX remove potential race between checking for and inserting service */ - - _child_services->insert(new (alloc) - Genode::Child_service(service_name, root, _server)); - Genode::printf("%s registered service %s\n", name(), service_name); - return true; + new (_child.heap()) + Child_service(_child_services, _session_requester.id_space(), + _child.session_factory(), service_name, + _child.ram_session_cap(), *this); } - - void unregister_services() - { - Genode::Service *rs; - while ((rs = _child_services->find_by_server(_server))) - _child_services->remove(rs); - } -}; - - -class Launchpad; - - -class Launchpad_child : public Genode::List::Element -{ - private: - - static Genode::Dataspace_capability _ldso_ds(); - - Launchpad *_launchpad; - - /* - * Entry point used for serving the parent interface and the - * locally provided ROM sessions for the 'config' and 'binary' - * files. - */ - enum { ENTRYPOINT_STACK_SIZE = 12*1024 }; - Genode::Rpc_entrypoint _entrypoint; - - Genode::Region_map_client _address_space; - - Genode::Rom_session_client _rom; - Genode::Pd_session_client _pd; - Genode::Ram_session_client _ram; - Genode::Cpu_session_client _cpu; - - Genode::Child::Initial_thread _initial_thread; - - Genode::Server _server; - - Launchpad_child_policy _policy; - Genode::Child _child; - - public: - - Launchpad_child(const char *name, - Genode::Dataspace_capability elf_ds, - Genode::Pd_session_capability pd, - Genode::Ram_session_capability ram, - Genode::Cpu_session_capability cpu, - Genode::Rom_session_capability rom, - Genode::Cap_session *cap_session, - Genode::Service_registry *parent_services, - Genode::Service_registry *child_services, - Genode::Dataspace_capability config_ds, - Launchpad *launchpad) - : - _launchpad(launchpad), - _entrypoint(cap_session, ENTRYPOINT_STACK_SIZE, name, false), - _address_space(Genode::Pd_session_client(pd).address_space()), - _rom(rom), _pd(pd), _ram(ram), _cpu(cpu), - _initial_thread(_cpu, _pd, name), _server(_ram), - _policy(name, &_server, parent_services, child_services, - config_ds, elf_ds, &_entrypoint), - _child(elf_ds, _ldso_ds(), _pd, _pd, _ram, _ram, _cpu, - _initial_thread, *Genode::env()->rm_session(), - _address_space, _entrypoint, _policy) - { - _entrypoint.activate(); - } - - /** - * Required to forcefully kill client which blocks on a session - * opening quest where the service is not up yet. - */ - void cancel_blocking() { _entrypoint.cancel_blocking(); } - - Genode::Rom_session_capability rom_session_cap() { return _rom; } - Genode::Ram_session_capability ram_session_cap() { return _ram; } - Genode::Cpu_session_capability cpu_session_cap() { return _cpu; } - - const char *name() const { return _policy.name(); } - - const Genode::Server *server() const { return &_server; } - - Genode::Allocator *heap() { return _child.heap(); } - - void revoke_server(const Genode::Server *server) { - _child.revoke_server(server); } }; @@ -231,31 +207,31 @@ class Launchpad { private: + Genode::Env &_env; + + Genode::Heap _heap { _env.ram(), _env.rm() }; + unsigned long _initial_quota; - Genode::Service_registry _parent_services; - Genode::Service_registry _child_services; + Launchpad_child::Parent_services _parent_services; + Launchpad_child::Child_services _child_services; Genode::Lock _children_lock; Genode::List _children; - bool _child_name_exists(const char *name); - void _get_unique_child_name(const char *filename, char *dst, int dst_len); + bool _child_name_exists(Launchpad_child::Name const &); + + Launchpad_child::Name _get_unique_child_name(Launchpad_child::Name const &); Genode::Sliced_heap _sliced_heap; - /* cap session for allocating capabilities for parent interfaces */ - Genode::Cap_connection _cap_session; - protected: int _ypos; public: - Genode::Lock gui_lock; - - Launchpad(unsigned long initial_quota); + Launchpad(Genode::Env &env, unsigned long initial_quota); unsigned long initial_quota() { return _initial_quota; } @@ -273,36 +249,26 @@ class Launchpad virtual void quota(unsigned long quota) { } - virtual void add_launcher(const char *filename, + virtual void add_launcher(Launchpad_child::Name const &binary_name, unsigned long default_quota, Genode::Dataspace_capability config_ds) { } - virtual void add_child(const char *unique_name, + virtual void add_child(Launchpad_child::Name const &, unsigned long quota, - Launchpad_child *launchpad_child, - Genode::Allocator *alloc) { } + Launchpad_child &, + Genode::Allocator &) { } - virtual void remove_child(const char *name, - Genode::Allocator *alloc) { } + virtual void remove_child(Launchpad_child::Name const &, + Genode::Allocator &) { } - Launchpad_child *start_child(const char *prg_name, unsigned long quota, + Launchpad_child *start_child(Launchpad_child::Name const &binary_name, + unsigned long quota, Genode::Dataspace_capability config_ds); /** * Exit child and close all its sessions - * - * \param timer Timer session to use for watchdog - * mechanism. When using the default - * value, a new timer session gets - * created during the 'exit_child' - * call. - * \param session_close_timeout_ms Timeout in milliseconds until a an - * unresponsive service->close call - * gets canceled. */ - void exit_child(Launchpad_child *child, - Timer::Session *timer = 0, - int session_close_timeout_ms = 2000); + void exit_child(Launchpad_child &child); }; #endif /* _INCLUDE__LAUNCHPAD__LAUNCHPAD_H_ */ diff --git a/repos/demo/include/scout/element.h b/repos/demo/include/scout/element.h index 012796caa..4677983be 100644 --- a/repos/demo/include/scout/element.h +++ b/repos/demo/include/scout/element.h @@ -181,7 +181,7 @@ class Scout::Element /** * Handle user input or timer event */ - void handle_event(Event &ev) { if (_evh) _evh->handle(ev); } + void handle_event(Event const &ev) { if (_evh) _evh->handle_event(ev); } /** * Request the chapter in which the element lives diff --git a/repos/demo/include/scout/event.h b/repos/demo/include/scout/event.h index b94fc0fe5..3c8899bc7 100644 --- a/repos/demo/include/scout/event.h +++ b/repos/demo/include/scout/event.h @@ -76,7 +76,7 @@ class Scout::Event_handler /** * Handle event */ - virtual void handle(Event &e) = 0; + virtual void handle_event(Event const &e) = 0; }; #endif /* _INCLUDE__SCOUT__EVENT_H_ */ diff --git a/repos/demo/include/scout/platform.h b/repos/demo/include/scout/platform.h index 89dfdea59..c6c7fe1b2 100644 --- a/repos/demo/include/scout/platform.h +++ b/repos/demo/include/scout/platform.h @@ -17,6 +17,7 @@ #define _INCLUDE__SCOUT__PLATFORM_H_ #include +#include #include #include #include @@ -51,150 +52,108 @@ class Scout::Platform { private: - /***************** - ** Event queue ** - *****************/ - - class Event_queue + Genode::Env &_env; + Event_handler *_event_handler = nullptr; + + int _mx = 0, _my = 0; + + void _handle_event(Event const &ev) { - private: + if (_event_handler) + _event_handler->handle_event(ev); + } - static const int queue_size = 1024; - int _head; - int _tail; - Genode::Semaphore _sem; - Genode::Lock _head_lock; /* synchronize add */ + /**************************** + ** Timer event processing ** + ****************************/ - Event _queue[queue_size]; + Timer::Connection _timer { _env }; - public: + unsigned long _ticks = 0; - /** - * Constructor - */ - Event_queue(): _head(0), _tail(0) - { - Genode::memset(_queue, 0, sizeof(_queue)); - } - - void add(Event ev) - { - Genode::Lock::Guard lock_guard(_head_lock); - - if ((_head + 1)%queue_size != _tail) { - - _queue[_head] = ev; - _head = (_head + 1)%queue_size; - _sem.up(); - } - } - - Event get() - { - _sem.down(); - Event ev = _queue[_tail]; - _tail = (_tail + 1)%queue_size; - return ev; - } - - int pending() const { return _head != _tail; } - - } _event_queue; - - /****************** - ** Timer thread ** - ******************/ - - class Timer_thread : public Genode::Thread_deprecated<4096> + void _handle_timer() { - private: + _ticks = _timer.elapsed_ms(); - Timer::Connection _timer; - Input::Session &_input; - Input::Event *_ev_buf = { Genode::env()->rm_session()->attach(_input.dataspace()) }; - Event_queue &_event_queue; - int _mx, _my; - unsigned long _ticks = { 0 }; + Event ev; + ev.assign(Event::TIMER, _mx, _my, 0); - void _import_events() - { - if (_input.pending() == false) return; + _handle_event(ev); + } - for (int i = 0, num = _input.flush(); i < num; i++) - { - Event ev; - Input::Event e = _ev_buf[i]; + Genode::Signal_handler _timer_handler { + _env.ep(), *this, &Platform::_handle_timer }; - if (e.type() == Input::Event::RELEASE - || e.type() == Input::Event::PRESS) { - _mx = e.ax(); - _my = e.ay(); - ev.assign(e.type() == Input::Event::PRESS ? Event::PRESS : Event::RELEASE, - e.ax(), e.ay(), e.code()); - _event_queue.add(ev); - } - if (e.type() == Input::Event::MOTION) { - _mx = e.ax(); - _my = e.ay(); - ev.assign(Event::MOTION, e.ax(), e.ay(), e.code()); - _event_queue.add(ev); - } - } + /**************************** + ** Input event processing ** + ****************************/ + + Input::Session &_input; + + Genode::Attached_dataspace _input_ds { _env.rm(), _input.dataspace() }; + + Input::Event * const _ev_buf = _input_ds.local_addr(); + + bool _event_pending = 0; + + void _handle_input() + { + if (_input.pending() == false) return; + + for (int i = 0, num = _input.flush(); i < num; i++) + { + Event ev; + Input::Event e = _ev_buf[i]; + + _event_pending = i + 1 < num; + + if (e.type() == Input::Event::RELEASE + || e.type() == Input::Event::PRESS) { + _mx = e.ax(); + _my = e.ay(); + ev.assign(e.type() == Input::Event::PRESS ? Event::PRESS : Event::RELEASE, + e.ax(), e.ay(), e.code()); + _handle_event(ev); } - public: - - /** - * Constructor - * - * Start thread immediately on construction. - */ - Timer_thread(Input::Session &input, Event_queue &event_queue) - : Thread_deprecated("timer"), _input(input), _event_queue(event_queue) - { start(); } - - void entry() - { - while (1) { - Event ev; - ev.assign(Event::TIMER, _mx, _my, 0); - _event_queue.add(ev); - - _import_events(); - - _timer.msleep(10); - _ticks += 10; - } + if (e.type() == Input::Event::MOTION) { + _mx = e.ax(); + _my = e.ay(); + ev.assign(Event::MOTION, e.ax(), e.ay(), e.code()); + _handle_event(ev); } + } + } - unsigned long ticks() const { return _ticks; } - } _timer_thread; + Genode::Signal_handler _input_handler { + _env.ep(), *this, &Platform::_handle_input}; public: - Platform(Input::Session &input) : _timer_thread(input, _event_queue) { } + Platform(Genode::Env &env, Input::Session &input) + : _env(env), _input(input) { } /** * Get timer ticks in miilliseconds */ - unsigned long timer_ticks() const { return _timer_thread.ticks(); } + unsigned long timer_ticks() const { return _ticks; } /** - * Return true if an event is pending + * Register event handler */ - bool event_pending() const { return _event_queue.pending(); } + void event_handler(Event_handler &handler) + { + _event_handler = &handler; - /** - * Request event - * - * \param e destination where to store event information. - * - * If there is no event pending, this function blocks - * until there is an event to deliver. - */ - Event get_event() { return _event_queue.get(); } + _timer.sigh(_timer_handler); + _timer.trigger_periodic(40*1000); + + _input.sigh(_input_handler); + } + + bool event_pending() const { return _event_pending; } }; #endif /* _INCLUDE__SCOUT__PLATFORM_H_ */ diff --git a/repos/demo/include/scout/user_state.h b/repos/demo/include/scout/user_state.h index 5bc2ead9f..5d86b7515 100644 --- a/repos/demo/include/scout/user_state.h +++ b/repos/demo/include/scout/user_state.h @@ -78,7 +78,7 @@ class Scout::User_state : public Parent_element /** * Apply input event to mouse focus state */ - void handle_event(Event &ev) + void handle_event(Event const &ev) { _key_cnt += ev.type == Event::PRESS ? 1 : 0; _key_cnt -= ev.type == Event::RELEASE ? 1 : 0; diff --git a/repos/demo/include/scout/window.h b/repos/demo/include/scout/window.h index 23d49dfdd..619d2c4f1 100644 --- a/repos/demo/include/scout/window.h +++ b/repos/demo/include/scout/window.h @@ -34,21 +34,34 @@ class Scout::Window : public Parent_element Graphics_backend &_gfx_backend; Rect _dirty; Area _max_size; - Point _view_position; int _request_cnt; /* nb of requests since last process */ bool const _scout_quirk; /* enable redraw quirk for scout */ + /* + * We limit the rate of (expensive) view-position updates to the rate + * of 'process_redraw' calls instead of eagerly responding to + * individual input events (which trigger calls of 'vpos'). + */ + Point _view_position, _next_view_position = _view_position; + + void _update_view_position() + { + if (_view_position == _next_view_position) return; + + _view_position = _next_view_position; + _gfx_backend.position(_view_position); + } + public: Window(Graphics_backend &gfx_backend, Point position, Area size, Area max_size, bool scout_quirk) : _gfx_backend(gfx_backend), _max_size(max_size), _request_cnt(0), - _scout_quirk(scout_quirk) + _scout_quirk(scout_quirk), _view_position(position) { /* init element attributes */ - _view_position = position; - _size = size; + _size = size; } virtual ~Window() { } @@ -56,8 +69,8 @@ class Scout::Window : public Parent_element /** * Return current window position */ - int view_x() const { return _view_position.x(); } - int view_y() const { return _view_position.y(); } + int view_x() const { return _next_view_position.x(); } + int view_y() const { return _next_view_position.y(); } int view_w() const { return _size.w(); } int view_h() const { return _size.h(); } @@ -71,11 +84,7 @@ class Scout::Window : public Parent_element /** * Move window to new position */ - virtual void vpos(int x, int y) - { - _view_position = Point(x, y); - _gfx_backend.position(_view_position); - } + virtual void vpos(int x, int y) { _next_view_position = Point(x, y); } /** * Define vertical scroll offset @@ -133,6 +142,8 @@ class Scout::Window : public Parent_element */ void process_redraw() { + _update_view_position(); + if (_request_cnt == 0) return; /* get actual drawing area (clipped against canvas dimensions) */ @@ -198,7 +209,7 @@ class Scout::Drag_event_handler : public Event_handler /** * Event handler interface */ - void handle(Event &ev) + void handle_event(Event const &ev) override { if (ev.type == Event::PRESS) _key_cnt++; if (ev.type == Event::RELEASE) _key_cnt--; diff --git a/repos/demo/src/app/launchpad/child_entry.h b/repos/demo/src/app/launchpad/child_entry.h index 27256bf84..cbd60d461 100644 --- a/repos/demo/src/app/launchpad/child_entry.h +++ b/repos/demo/src/app/launchpad/child_entry.h @@ -32,18 +32,18 @@ class Kill_event_handler : public Scout::Event_handler { private: - Launchpad *_launchpad; - Launchpad_child *_launchpad_child; + Launchpad &_launchpad; + Launchpad_child &_launchpad_child; public: - Kill_event_handler(Launchpad *launchpad, Launchpad_child *launchpad_child): + Kill_event_handler(Launchpad &launchpad, Launchpad_child &launchpad_child): _launchpad(launchpad), _launchpad_child(launchpad_child) { } /** * Event handler interface */ - void handle(Scout::Event &ev) + void handle_event(Scout::Event const &ev) override { static int key_cnt; @@ -53,7 +53,7 @@ class Kill_event_handler : public Scout::Event_handler if (ev.type == Event::RELEASE) key_cnt--; if (ev.type == Event::RELEASE && key_cnt == 0) - _launchpad->exit_child(_launchpad_child); + _launchpad.exit_child(_launchpad_child); } }; @@ -73,7 +73,7 @@ class Child_entry : public Scout::Parent_element, Scout::Block _block; Kbyte_loadbar _loadbar; - char _name[_NAME_LEN]; + Launchpad_child::Name const _name; Scout::Fade_icon _kill_icon; Scout::Fade_icon _fold_icon; @@ -85,14 +85,14 @@ class Child_entry : public Scout::Parent_element, /** * Constructor */ - Child_entry(const char *name, int quota_kb, int max_quota_kb, - Launchpad *launchpad, Launchpad_child *launchpad_child) + Child_entry(Launchpad_child::Name const &name, int quota_kb, int max_quota_kb, + Launchpad &launchpad, Launchpad_child &launchpad_child) : _block(Scout::Block::RIGHT), _loadbar(0, &Scout::label_font), + _name(name), _kill_event_handler(launchpad, launchpad_child) { - Genode::strncpy(_name, name, sizeof(_name)); - _block.append_plaintext(_name, &Scout::plain_style); + _block.append_plaintext(_name.string(), &Scout::plain_style); _loadbar.max_value(max_quota_kb); _loadbar.value(quota_kb); @@ -118,7 +118,7 @@ class Child_entry : public Scout::Parent_element, /** * Accessors */ - const char *name() { return _name; } + Launchpad_child::Name name() { return _name; } /****************************** diff --git a/repos/demo/src/app/launchpad/launch_entry.h b/repos/demo/src/app/launchpad/launch_entry.h index 94f8cd572..cd745f19c 100644 --- a/repos/demo/src/app/launchpad/launch_entry.h +++ b/repos/demo/src/app/launchpad/launch_entry.h @@ -22,6 +22,7 @@ class Launch_entry : public Scout::Parent_element, public Loadbar_listener { private: + Scout::Launcher::Name _prg_name; Scout::Block _block; Kbyte_loadbar _loadbar; Scout::Launcher_config _config; @@ -37,15 +38,16 @@ class Launch_entry : public Scout::Parent_element, public Loadbar_listener /** * Constructor */ - Launch_entry(const char *prg_name, unsigned long initial_quota, + Launch_entry(Scout::Launcher::Name const &prg_name, unsigned long initial_quota, unsigned long max_quota, Launchpad *launchpad, Genode::Dataspace_capability config_ds) : + _prg_name(prg_name), _block(Scout::Block::RIGHT), _loadbar(this, &Scout::label_font), _config(config_ds), _launcher(prg_name, launchpad, initial_quota * 1024UL, &_config) { - _block.append_launchertext(prg_name, &Scout::link_style, &_launcher); + _block.append_launchertext(_prg_name.string(), &Scout::link_style, &_launcher); _loadbar.max_value(max_quota); _loadbar.value(initial_quota); diff --git a/repos/demo/src/app/launchpad/launchpad_window.cc b/repos/demo/src/app/launchpad/launchpad_window.cc index ed4b25808..07095a77f 100644 --- a/repos/demo/src/app/launchpad/launchpad_window.cc +++ b/repos/demo/src/app/launchpad/launchpad_window.cc @@ -35,11 +35,12 @@ extern unsigned char TITLEBAR_RGBA[]; ********************************/ template -Launchpad_window::Launchpad_window(Graphics_backend &gfx_backend, +Launchpad_window::Launchpad_window(Genode::Env &env, + Graphics_backend &gfx_backend, Point position, Area size, Area max_size, unsigned long initial_quota) : - Launchpad(initial_quota), + Launchpad(env, initial_quota), Window(gfx_backend, position, size, max_size, false), _docview(0), _spacer(1, _TH), diff --git a/repos/demo/src/app/launchpad/launchpad_window.h b/repos/demo/src/app/launchpad/launchpad_window.h index b59ee8c41..bd980bb63 100644 --- a/repos/demo/src/app/launchpad/launchpad_window.h +++ b/repos/demo/src/app/launchpad/launchpad_window.h @@ -14,6 +14,9 @@ #ifndef _LAUNCHPAD_WINDOW_H_ #define _LAUNCHPAD_WINDOW_H_ +#include +#include + #include #include @@ -73,7 +76,8 @@ class Launchpad_window : public Scout::Scrollbar_listener, * * \param initial_quota maximum value of quota displays */ - Launchpad_window(Scout::Graphics_backend &gfx_backend, + Launchpad_window(Genode::Env &env, + Scout::Graphics_backend &gfx_backend, Scout::Point position, Scout::Area size, Scout::Area max_size, unsigned long inital_quota); @@ -123,39 +127,40 @@ class Launchpad_window : public Scout::Scrollbar_listener, _status_entry.refresh(); } - void add_launcher(const char *filename, + void add_launcher(Launchpad_child::Name const &name, unsigned long default_quota, - Genode::Dataspace_capability config_ds = Genode::Dataspace_capability()) + Genode::Dataspace_capability config_ds = Genode::Dataspace_capability()) override { Launch_entry *le; - le = new Launch_entry(filename, default_quota / 1024, + le = new Launch_entry(name, default_quota / 1024, initial_quota() / 1024, this, config_ds); _launch_section.append(le); refresh(); } - void add_child(const char *unique_name, + void add_child(Launchpad_child::Name const &name, unsigned long quota, - Launchpad_child *launchpad_child, - Genode::Allocator *alloc) + Launchpad_child &launchpad_child, + Genode::Allocator &alloc) override { Child_entry *ce; - ce = new (alloc) Child_entry(unique_name, quota / 1024, + ce = new (alloc) Child_entry(name, quota / 1024, initial_quota() / 1024, - this, launchpad_child); + *this, launchpad_child); _child_entry_list.insert(ce); _kiddy_section.append(ce); format(_size); refresh(); } - void remove_child(const char *name, Genode::Allocator *alloc) + void remove_child(Launchpad_child::Name const &name, + Genode::Allocator &alloc) override { /* lookup child entry by its name */ Child_entry *ce = _child_entry_list.first(); for ( ; ce; ce = ce->Genode::List >::Element::next()) - if (Genode::strcmp(ce->name(), name) == 0) + if (name == ce->name()) break; if (!ce) { diff --git a/repos/demo/src/app/launchpad/loadbar.h b/repos/demo/src/app/launchpad/loadbar.h index ec3c5a4ca..6b3f055a4 100644 --- a/repos/demo/src/app/launchpad/loadbar.h +++ b/repos/demo/src/app/launchpad/loadbar.h @@ -53,7 +53,7 @@ class Loadbar_event_handler : public Scout::Event_handler /** * Event handler interface */ - void handle(Scout::Event &ev) + void handle_event(Scout::Event const &ev) override { static int key_cnt; using Scout::Event; diff --git a/repos/demo/src/app/launchpad/main.cc b/repos/demo/src/app/launchpad/main.cc index 80aa07f8e..8411d1bb9 100644 --- a/repos/demo/src/app/launchpad/main.cc +++ b/repos/demo/src/app/launchpad/main.cc @@ -11,6 +11,8 @@ * under the terms of the GNU General Public License version 2. */ +#include + #include #include #include @@ -85,15 +87,52 @@ static long read_int_attr_from_config(const char *attr, long default_value) } -/** - * Main program - */ -int main(int argc, char **argv) +struct Main : Scout::Event_handler +{ + Scout::Platform &_pf; + Scout::Window &_launchpad; + Scout::User_state &_user_state; + + unsigned long _old_time = _pf.timer_ticks(); + + Main(Scout::Platform &pf, Scout::Window &launchpad, Scout::User_state &user_state) + : _pf(pf), _launchpad(launchpad), _user_state(user_state) { } + + void handle_event(Scout::Event const &event) override + { + using namespace Scout; + + Event ev = event; + + if (ev.type != Event::WHEEL) + ev.mouse_position = ev.mouse_position - _user_state.view_position(); + + _user_state.handle_event(ev); + + if (ev.type == Event::TIMER) + Tick::handle(_pf.timer_ticks()); + + /* perform periodic redraw */ + unsigned long const curr_time = _pf.timer_ticks(); + if (!_pf.event_pending() && ((curr_time - _old_time > 20) + || (curr_time < _old_time))) { + _old_time = curr_time; + _launchpad.process_redraw(); + } + } +}; + + +/*************** + ** Component ** + ***************/ + +void Component::construct(Genode::Env &env) { using namespace Scout; - static Nitpicker::Connection nitpicker; - static Platform pf(*nitpicker.input()); + static Nitpicker::Connection nitpicker(env); + static Platform pf(env, *nitpicker.input()); long initial_x = read_int_attr_from_config("xpos", 550); long initial_y = read_int_attr_from_config("ypos", 150); @@ -109,17 +148,13 @@ int main(int argc, char **argv) /* create instance of launchpad window */ static Launchpad_window - launchpad( - graphics_backend, initial_position, initial_size, max_size, - Genode::env()->ram_session()->avail() - ); + launchpad(env, graphics_backend, initial_position, initial_size, + max_size, env.ram().avail()); /* request config file from ROM service */ - try { - launchpad.process_config(); - } catch (...) { } + try { launchpad.process_config(); } catch (...) { } - Avail_quota_update avail_quota_update(&launchpad); + static Avail_quota_update avail_quota_update(&launchpad); /* create user state manager */ static User_state user_state(&launchpad, &launchpad, @@ -129,36 +164,6 @@ int main(int argc, char **argv) launchpad.format(initial_size); launchpad.ypos(0); - Genode::printf("--- entering main loop ---\n"); - - /* enter main loop */ - unsigned long curr_time, old_time; - curr_time = old_time = pf.timer_ticks(); - for (;;) { - Event ev = pf.get_event(); - - launchpad.gui_lock.lock(); - - if (ev.type != Event::WHEEL) - ev.mouse_position = ev.mouse_position - user_state.view_position(); - - user_state.handle_event(ev); - - if (ev.type == Event::TIMER) - Tick::handle(pf.timer_ticks()); - - /* perform periodic redraw */ - curr_time = pf.timer_ticks(); - if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) { - old_time = curr_time; - launchpad.process_redraw(); - } - - launchpad.gui_lock.unlock(); - - if (ev.type == Event::QUIT) - break; - } - - return 0; + static Main main(pf, launchpad, user_state); + pf.event_handler(main); } diff --git a/repos/demo/src/app/scout/browser_window.cc b/repos/demo/src/app/scout/browser_window.cc index 5b838aeda..c30c036dd 100644 --- a/repos/demo/src/app/scout/browser_window.cc +++ b/repos/demo/src/app/scout/browser_window.cc @@ -136,7 +136,7 @@ class Iconbar_event_handler : public Scout::Event_handler /** * Event handler interface */ - void handle(Event &ev) + void handle_event(Event const &ev) override { static int key_cnt; diff --git a/repos/demo/src/app/scout/elements.cc b/repos/demo/src/app/scout/elements.cc index 4ca96f653..c853a642f 100644 --- a/repos/demo/src/app/scout/elements.cc +++ b/repos/demo/src/app/scout/elements.cc @@ -426,7 +426,7 @@ void Verbatim::format_fixed_width(int w) ** Link_token ** ****************/ -void Link_token::handle(Event &e) +void Link_token::handle_event(Event const &e) { if (e.type != Event::PRESS) return; @@ -444,7 +444,7 @@ void Link_token::handle(Event &e) ** Launcher_link_token ** *************************/ -void Launcher_link_token::handle(Event &e) +void Launcher_link_token::handle_event(Event const &e) { if (e.type != Event::PRESS) return; diff --git a/repos/demo/src/app/scout/elements.h b/repos/demo/src/app/scout/elements.h index 6bff0e1dd..761959159 100644 --- a/repos/demo/src/app/scout/elements.h +++ b/repos/demo/src/app/scout/elements.h @@ -200,7 +200,7 @@ class Scout::Link_token : public Token, public Link, public Event_handler, /** * Event handler interface */ - void handle(Event &e); + void handle_event(Event const &) override; /** * Tick interface @@ -221,9 +221,13 @@ class Launchpad; class Scout::Launcher : public Anchor { + public: + + typedef Genode::String<64> Name; + private: - const char *_prg_name; /* null-terminated name of the program */ + Name _prg_name; int _active; int _exec_once; Launchpad *_launchpad; @@ -232,22 +236,24 @@ class Scout::Launcher : public Anchor public: + static void init(Genode::Env &); + /** * Constructors */ - Launcher(const char *prg_name, int exec_once = 0, + Launcher(Name const &prg_name, int exec_once = 0, unsigned long quota = 0, Launcher_config *config = 0) : _prg_name(prg_name), _active(1), _exec_once(exec_once), _quota(quota), _config(config) { } - Launcher(const char *prg_name, Launchpad *launchpad, + Launcher(Name const &prg_name, Launchpad *launchpad, unsigned long quota, Launcher_config *config = 0) : _prg_name(prg_name), _launchpad(launchpad), _quota(quota), _config(config) { } int active() { return _active; } - const char *prg_name() { return _prg_name; } + Name prg_name() { return _prg_name; } void quota(unsigned long quota) { _quota = quota; } @@ -280,7 +286,7 @@ class Scout::Launcher_link_token : public Link_token /** * Event handler interface */ - void handle(Event &e); + void handle_event(Event const &) override; }; diff --git a/repos/demo/src/app/scout/launcher.cc b/repos/demo/src/app/scout/launcher.cc index 01b204ecd..0a95b2774 100644 --- a/repos/demo/src/app/scout/launcher.cc +++ b/repos/demo/src/app/scout/launcher.cc @@ -18,9 +18,6 @@ #include #include "elements.h" -static Launchpad launchpad(Genode::env()->ram_session()->quota()); - - using namespace Genode; using namespace Scout; @@ -94,10 +91,32 @@ Dataspace_capability Config_registry::config(char const *name) ** Launcher interface ** ************************/ + +static Launchpad *launchpad_ptr; + + +static Launchpad &launchpad() +{ + if (!launchpad_ptr) { + class Missing_launchpad_init_call { }; + throw Missing_launchpad_init_call(); + } + + return *launchpad_ptr; +} + + +void Launcher::init(Genode::Env &env) +{ + static Launchpad launchpad(env, env.ram().avail()); + launchpad_ptr = &launchpad; +} + + void Launcher::launch() { static Config_registry config_registry; - launchpad.start_child(prg_name(), quota(), - config_registry.config(prg_name())); + launchpad().start_child(prg_name(), quota(), + config_registry.config(prg_name().string())); } diff --git a/repos/demo/src/app/scout/main.cc b/repos/demo/src/app/scout/main.cc index aa26dab9f..3d5894f99 100644 --- a/repos/demo/src/app/scout/main.cc +++ b/repos/demo/src/app/scout/main.cc @@ -11,6 +11,8 @@ * under the terms of the GNU General Public License version 2. */ +#include + #include #include #include @@ -45,20 +47,86 @@ extern unsigned char NAV_PREV_RGBA[]; static unsigned char *navicons_rgba[] = { NAV_NEXT_RGBA, NAV_PREV_RGBA }; static Scout::Generic_icon **navicons[] = { &Scout::Navbar::next_icon, - &Scout::Navbar::prev_icon }; + &Scout::Navbar::prev_icon }; extern int native_startup(int, char **); -/** - * Main program - */ -int main(int argc, char **argv) +namespace Scout { struct Main; } + + +struct Scout::Main : Scout::Event_handler +{ + Scout::Platform &_pf; + Scout::Window &_browser; + Scout::User_state &_user_state; + Scout::Element &_mcursor; + + Scout::Point _mouse_position; + + unsigned long _old_time = _pf.timer_ticks(); + + Main(Scout::Platform &pf, Scout::Window &browser, + Scout::User_state &user_state, Scout::Element &mcursor) + : + _pf(pf), _browser(browser), _user_state(user_state), _mcursor(mcursor) + { } + + void handle_event(Scout::Event const &event) override + { + using namespace Scout; + + Event ev = event; + + if (event.type != Event::WHEEL) { + + ev.mouse_position = ev.mouse_position - _user_state.view_position(); + + /* update mouse cursor */ + if (Config::mouse_cursor && (ev.mouse_position.x() != _mouse_position.x() + || ev.mouse_position.y() != _mouse_position.y())) { + int x1 = min(ev.mouse_position.x(), _mouse_position.x()); + int y1 = min(ev.mouse_position.y(), _mouse_position.y()); + int x2 = max(ev.mouse_position.x() + _mcursor.size().w() - 1, + _mouse_position.x() + _mcursor.size().w() - 1); + int y2 = max(ev.mouse_position.y() + _mcursor.size().h() - 1, + _mouse_position.y() + _mcursor.size().h() - 1); + + _mcursor.geometry(Rect(ev.mouse_position, _mcursor.size())); + _browser.redraw_area(x1, y1, x2 - x1 + 1, y2 - y1 + 1); + + _mouse_position = ev.mouse_position; + } + } + + _user_state.handle_event(ev); + + if (event.type == Event::TIMER) + Tick::handle(_pf.timer_ticks()); + + /* perform periodic redraw */ + unsigned long curr_time = _pf.timer_ticks(); + if (!_pf.event_pending() && ((curr_time - _old_time > 20) + || (curr_time < _old_time))) { + _old_time = curr_time; + _browser.process_redraw(); + } + } +}; + + +/*************** + ** Component ** + ***************/ + +void Component::construct(Genode::Env &env) { using namespace Scout; + Launcher::init(env); + static Nitpicker::Connection nitpicker; - static Platform pf(*nitpicker.input()); + static Platform pf(env, *nitpicker.input()); Area const max_size(530, 620); Point const initial_position(256, 80); @@ -92,10 +160,9 @@ int main(int argc, char **argv) ); /* initialize mouse cursor */ - Point mouse_position; static Icon mcursor; if (Config::mouse_cursor) { - mcursor.geometry(Rect(mouse_position, Area(32, 32))); + mcursor.geometry(Rect(Point(0, 0), Area(32, 32))); mcursor.rgba(POINTER_RGBA); mcursor.alpha(255); mcursor.findable(0); @@ -107,47 +174,7 @@ int main(int argc, char **argv) initial_position.x(), initial_position.y()); browser.ypos(0); - /* enter main loop */ - unsigned long curr_time, old_time; - curr_time = old_time = pf.timer_ticks(); - for (;;) { - Event ev = pf.get_event(); + static Main main(pf, browser, user_state, mcursor); + pf.event_handler(main); - if (ev.type != Event::WHEEL) { - ev.mouse_position = ev.mouse_position - user_state.view_position(); - - /* update mouse cursor */ - if (Config::mouse_cursor && (ev.mouse_position.x() != mouse_position.x() - || ev.mouse_position.y() != mouse_position.y())) { - int x1 = min(ev.mouse_position.x(), mouse_position.x()); - int y1 = min(ev.mouse_position.y(), mouse_position.y()); - int x2 = max(ev.mouse_position.x() + mcursor.size().w() - 1, - mouse_position.x() + mcursor.size().w() - 1); - int y2 = max(ev.mouse_position.y() + mcursor.size().h() - 1, - mouse_position.y() + mcursor.size().h() - 1); - - mcursor.geometry(Rect(ev.mouse_position, mcursor.size())); - browser.redraw_area(x1, y1, x2 - x1 + 1, y2 - y1 + 1); - - mouse_position = ev.mouse_position; - } - } - - user_state.handle_event(ev); - - if (ev.type == Event::TIMER) - Tick::handle(pf.timer_ticks()); - - /* perform periodic redraw */ - curr_time = pf.timer_ticks(); - if (!pf.event_pending() && ((curr_time - old_time > 20) || (curr_time < old_time))) { - old_time = curr_time; - browser.process_redraw(); - } - - if (ev.type == Event::QUIT) - break; - } - - return 0; } diff --git a/repos/demo/src/app/scout/navbar.cc b/repos/demo/src/app/scout/navbar.cc index 5b247dd2a..4fe222b5a 100644 --- a/repos/demo/src/app/scout/navbar.cc +++ b/repos/demo/src/app/scout/navbar.cc @@ -58,7 +58,7 @@ class Linkicon_event_handler : public Event_handler /** * Event handler interface */ - void handle(Event &ev) + void handle_event(Event const &ev) override { if (ev.type != Event::PRESS || !_navbar) return; diff --git a/repos/demo/src/app/scout/scrollbar.cc b/repos/demo/src/app/scout/scrollbar.cc index d04a7a5fd..133e81a75 100644 --- a/repos/demo/src/app/scout/scrollbar.cc +++ b/repos/demo/src/app/scout/scrollbar.cc @@ -69,7 +69,7 @@ class Arrow_event_handler : public Event_handler, public Tick /** * Event handler interface */ - void handle(Event &ev) + void handle_event(Event const &ev) override { static int key_cnt; @@ -166,7 +166,7 @@ class Slider_event_handler : public Event_handler /** * Event handler interface */ - void handle(Event &ev) + void handle_event(Event const &ev) override { static int key_cnt; static int curr_my, orig_my; diff --git a/repos/demo/src/lib/launchpad/launchpad.cc b/repos/demo/src/lib/launchpad/launchpad.cc index e8b588fc2..8ff58f907 100644 --- a/repos/demo/src/lib/launchpad/launchpad.cc +++ b/repos/demo/src/lib/launchpad/launchpad.cc @@ -14,16 +14,10 @@ */ #include -#include -#include #include #include -#include -#include -#include -#include +#include #include -#include #include using namespace Genode; @@ -33,10 +27,11 @@ using namespace Genode; ** Launchpad ** ***************/ -Launchpad::Launchpad(unsigned long initial_quota) +Launchpad::Launchpad(Env &env, unsigned long initial_quota) : + _env(env), _initial_quota(initial_quota), - _sliced_heap(env()->ram_session(), env()->rm_session()) + _sliced_heap(_env.ram(), _env.rm()) { /* names of services provided by the parent */ static const char *names[] = { @@ -45,25 +40,24 @@ Launchpad::Launchpad(unsigned long initial_quota) "RAM", "RM", "PD", "CPU", "IO_MEM", "IO_PORT", "IRQ", "ROM", "LOG", /* services expected to got started by init */ - "Nitpicker", "Init", "Timer", "PCI", "Block", "Nic", "Rtc", + "Nitpicker", "Init", "Timer", "Block", "Nic", "Rtc", 0 /* null-termination */ }; for (unsigned i = 0; names[i]; i++) - _parent_services.insert(new (env()->heap()) - Parent_service(names[i])); + new (_heap) Launchpad_child::Parent_service(_parent_services, names[i]); } /** * Check if a program with the specified name already exists */ -bool Launchpad::_child_name_exists(const char *name) +bool Launchpad::_child_name_exists(Launchpad_child::Name const &name) { Launchpad_child *c = _children.first(); for ( ; c; c = c->List::Element::next()) - if (strcmp(c->name(), name) == 0) + if (c->name() == name) return true; return false; @@ -73,30 +67,23 @@ bool Launchpad::_child_name_exists(const char *name) /** * Create a unique name based on the filename * - * If a program with the filename as name already exists, we - * add a counting number as suffix. + * If a program with the filename as name already exists, we add a counting + * number as suffix. */ -void Launchpad::_get_unique_child_name(const char *filename, char *dst, int dst_len) +Launchpad_child::Name +Launchpad::_get_unique_child_name(Launchpad_child::Name const &binary_name) { Lock::Guard lock_guard(_children_lock); - char buf[64]; - char suffix[8]; - suffix[0] = 0; + if (!_child_name_exists(binary_name)) + return binary_name; - for (int cnt = 1; true; cnt++) { - - /* build program name composed of filename and numeric suffix */ - snprintf(buf, sizeof(buf), "%s%s", filename, suffix); + for (unsigned cnt = 1; ; cnt++) { /* if such a program name does not exist yet, we are happy */ - if (!_child_name_exists(buf)) { - strncpy(dst, buf, dst_len); - return; - } - - /* increase number of suffix */ - snprintf(suffix, sizeof(suffix), ".%d", cnt + 1); + Launchpad_child::Name const unique(binary_name, ".", cnt); + if (!_child_name_exists(unique)) + return unique; } } @@ -114,370 +101,98 @@ void Launchpad::process_config() * Iterate through all entries of the config file and create * launchpad entries as specified. */ - int launcher_cnt = 0; - for (unsigned i = 0; i < config_node.num_sub_nodes(); i++) { - Xml_node node = config_node.sub_node(i); - if (node.has_type("launcher")) + config_node.for_each_sub_node("launcher", [&] (Xml_node node) { - /* catch XML syntax errors within launcher node */ - try { - /* read file name and default quote from launcher node */ - Xml_node::Attribute filename_attr = node.attribute("name"); + typedef Launchpad_child::Name Name; + Name *name = new (_heap) Name(node.attribute_value("name", Name())); - enum { MAX_NAME_LEN = 128 }; - char *filename = (char *)env()->heap()->alloc(MAX_NAME_LEN); - if (!filename) { - Genode::error("out of memory while processing configuration"); - return; - } - filename_attr.value(filename, MAX_NAME_LEN); - Xml_node::Attribute ram_quota_attr = node.attribute("ram_quota"); - Number_of_bytes default_ram_quota = 0; - ram_quota_attr.value(&default_ram_quota); + Number_of_bytes default_ram_quota = + node.attribute_value("ram_quota", Number_of_bytes(0)); - /* - * Obtain configuration for the child - */ - Dataspace_capability config_ds; + /* + * Obtain configuration for the child + */ + Dataspace_capability config_ds; - if (node.has_sub_node("configfile") - && node.sub_node("configfile").has_attribute("name")) { + typedef String<128> Rom_name; - char name[128]; - node.sub_node("configfile").attribute("name").value(name, sizeof(name)); + if (node.has_sub_node("configfile")) { - Rom_connection config_rom(name); - config_rom.on_destruction(Rom_connection::KEEP_OPEN); + Rom_name const name = + node.sub_node("configfile").attribute_value("name", Rom_name()); - config_ds = config_rom.dataspace(); - } + Rom_connection &config_rom = *new (_heap) Rom_connection(name.string()); - if (node.has_sub_node("config")) { - - Xml_node config_node = node.sub_node("config"); - - /* allocate dataspace for config */ - size_t const config_size = config_node.size(); - config_ds = env()->ram_session()->alloc(config_size); - - /* copy configuration into new dataspace */ - char * const ptr = env()->rm_session()->attach(config_ds); - Genode::memcpy(ptr, config_node.addr(), config_size); - env()->rm_session()->detach(ptr); - } - - /* add launchpad entry */ - add_launcher(filename, default_ram_quota, config_ds); - launcher_cnt++; - - } catch (...) { - Genode::warning("launcher entry ", launcher_cnt + 1, " is malformed"); - } - else { - char buf[32]; - node.type_name(buf, sizeof(buf)); - Genode::warning("ignoring unsupported tag <", Genode::Cstring(buf), ">"); + config_ds = config_rom.dataspace(); } - } + + if (node.has_sub_node("config")) { + + Xml_node config_node = node.sub_node("config"); + + /* allocate dataspace for config */ + size_t const size = config_node.size(); + config_ds = env()->ram_session()->alloc(size); + + /* copy configuration into new dataspace */ + Attached_dataspace attached(config_ds); + memcpy(attached.local_addr(), config_node.addr(), size); + } + + /* add launchpad entry */ + add_launcher(*name, default_ram_quota, config_ds); + }); } -Launchpad_child *Launchpad::start_child(const char *filename, +Launchpad_child *Launchpad::start_child(Launchpad_child::Name const &binary_name, unsigned long ram_quota, - Genode::Dataspace_capability config_ds) + Dataspace_capability config_ds) { - Genode::log("starting ", filename, " with quota ", ram_quota); + log("starting ", binary_name, " with quota ", ram_quota); /* find unique name for new child */ - char unique_name[64]; - _get_unique_child_name(filename, unique_name, sizeof(unique_name)); - Genode::log("using unique child name \"", Cstring(unique_name), "\""); + Launchpad_child::Name const unique_name = _get_unique_child_name(binary_name); + log("using unique child name \"", unique_name, "\""); if (ram_quota > env()->ram_session()->avail()) { - Genode::error("child's ram quota is higher than our available quota, using available quota"); + error("child's ram quota is higher than our available quota, using available quota"); ram_quota = env()->ram_session()->avail() - 256*1000; } size_t metadata_size = 4096*16 + sizeof(Launchpad_child); if (metadata_size > ram_quota) { - Genode::error("too low ram_quota to hold child metadata"); + error("too low ram_quota to hold child metadata"); return 0; } ram_quota -= metadata_size; - /* lookup executable elf binary */ - Dataspace_capability file_cap; - Rom_session_capability rom_cap; - try { - /* - * When creating a ROM connection for a non-existing file, the - * constructor of 'Rom_connection' throws a 'Parent::Service_denied' - * exception. - */ - Rom_connection rom(prefixed_label(Session_label(Cstring(unique_name)), - Session_label(filename)).string()); - rom.on_destruction(Rom_connection::KEEP_OPEN); - rom_cap = rom.cap(); - file_cap = rom.dataspace(); - } catch (...) { - Genode::error("could not access ROM module \"", filename, "\""); - return 0; - } - - /* create ram session for child with some of our own quota */ - Ram_connection ram; - ram.on_destruction(Ram_connection::KEEP_OPEN); - ram.ref_account(env()->ram_session_cap()); - env()->ram_session()->transfer_quota(ram.cap(), ram_quota); - - /* create cpu session for child */ - Cpu_connection cpu(unique_name); - cpu.on_destruction(Cpu_connection::KEEP_OPEN); - - if (!ram.cap().valid() || !cpu.cap().valid()) { - if (ram.cap().valid()) { - Genode::warning("failed to create CPU session"); - env()->parent()->close(ram.cap()); - } - if (cpu.cap().valid()) { - Genode::warning("failed to create RAM session"); - env()->parent()->close(cpu.cap()); - } - env()->parent()->close(rom_cap); - Genode::log("our quota is ", env()->ram_session()->quota()); - return 0; - } - - Pd_connection pd; - pd.on_destruction(Pd_connection::KEEP_OPEN); - if (!pd.cap().valid()) { - Genode::warning("failed to create PD session"); - env()->parent()->close(ram.cap()); - env()->parent()->close(cpu.cap()); - env()->parent()->close(rom_cap); - return 0; - } - try { Launchpad_child *c = new (&_sliced_heap) - Launchpad_child(unique_name, file_cap, pd.cap(), ram.cap(), - cpu.cap(), rom_cap, - &_cap_session, &_parent_services, &_child_services, - config_ds, this); + Launchpad_child(_env, unique_name, binary_name, ram_quota, + _parent_services, _child_services, config_ds); Lock::Guard lock_guard(_children_lock); _children.insert(c); - add_child(unique_name, ram_quota, c, c->heap()); - + add_child(unique_name, ram_quota, *c, c->heap()); return c; - } catch (Cpu_session::Thread_creation_failed) { - Genode::warning("failed to create child - Cpu_session::Thread_creation_failed"); - } catch (...) { - Genode::warning("failed to create child - unknown reason"); - } - env()->parent()->close(ram.cap()); - env()->parent()->close(cpu.cap()); - env()->parent()->close(rom_cap); + } catch (...) { + warning("failed to create child - unknown reason"); } return 0; } -/** - * Watchdog-guarded child destruction mechanism - * - * During the destruction of a child, all sessions of the child are getting - * closed. A server, however, may refuse to answer a close call. We detect - * this case using a watchdog mechanism, unblock the 'close' call, and - * proceed with the closing the other remaining sessions. - */ -class Child_destructor_thread : Thread_deprecated<2*4096> +void Launchpad::exit_child(Launchpad_child &child) { - private: - - Launchpad_child *_curr_child; /* currently destructed child */ - Allocator *_curr_alloc; /* child object'sallocator */ - Lock _submit_lock; /* only one submission at a time */ - Lock _activate_lock; /* submission protocol */ - bool _ready; /* set if submission is completed */ - int _watchdog_cnt; /* watchdog counter in milliseconds */ - - /** - * Thread entry function - */ - void entry() { - while (true) { - - /* wait for next submission */ - _activate_lock.lock(); - - /* - * Eventually long-taking operation that involves the - * closing of all session of the child. This procedure - * may need blocking cancellation to proceed in the - * case servers are unresponsive. - */ - try { - destroy(_curr_alloc, _curr_child); - } catch (Blocking_canceled) { - Genode::error("suspicious cancellation"); - } - - _ready = true; - } - } - - public: - - /* - * Watchdog timer granularity in milliseconds. This value defined - * after how many milliseconds the watchdog is activated. - */ - enum { WATCHDOG_GRANULARITY_MS = 10 }; - - /** - * Constructor - */ - Child_destructor_thread() : - Thread_deprecated("child_destructor"), - _curr_child(0), _curr_alloc(0), - _activate_lock(Lock::LOCKED), - _ready(true) - { - start(); - } - - /** - * Destruct child, coping with unresponsive servers - * - * \param alloc Child object's allocator - * \param child Child to destruct - * \param timeout_ms Maximum destruction time until the destructing - * thread gets waken up to give up the close call to - * an unreponsive server. - */ - void submit_for_destruction(Allocator *alloc, Launchpad_child *child, - Timer::Session *timer, int timeout_ms) - { - /* block until destructor thread is ready for new submission */ - Lock::Guard _lock_guard(_submit_lock); - - /* register submission values */ - _curr_child = child; - _curr_alloc = alloc; - _ready = false; - _watchdog_cnt = 0; - - /* wake up the destruction thread */ - _activate_lock.unlock(); - - /* - * Now, the destruction thread attempts to close all the - * child's sessions. Check '_ready' flag periodically. - */ - while (!_ready) { - - /* give the destruction thread some time to proceed */ - timer->msleep(WATCHDOG_GRANULARITY_MS); - _watchdog_cnt += WATCHDOG_GRANULARITY_MS; - - /* check if we reached the timeout */ - if (_watchdog_cnt > timeout_ms) { - - /* - * The destruction seems to got stuck, let's shake it a - * bit to proceed and reset the watchdog counter to give - * the next blocking operation a chance to execute. - */ - child->cancel_blocking(); - _watchdog_cnt = 0; - } - } - } -}; - - -/** - * Construct a timer session for the watchdog timer on demand - */ -static Timer::Session *timer_session() -{ - static Timer::Connection timer; - return &timer; -} - - -Dataspace_capability Launchpad_child::_ldso_ds() -{ - static bool first_attempt_failed = false; - - if (!first_attempt_failed) { - try { - static Rom_connection rom("ld.lib.so"); - static Dataspace_capability ds = rom.dataspace(); - return ds; - } catch (...) { } - } - - first_attempt_failed = true; - return Dataspace_capability(); -} - - -/* construct child-destructor thread early - in case we run out of threads */ -static Child_destructor_thread child_destructor; - -/** - * Destruct Launchpad_child, cope with infinitely blocking server->close calls - * - * The arguments correspond to the 'Child_destructor_thread::submit_for_destruction' - * function. - */ -static void destruct_child(Allocator *alloc, Launchpad_child *child, - Timer::Session *timer, int timeout) -{ - /* if no timer session was provided by our caller, we have create one */ - if (!timer) - timer = timer_session(); - - child_destructor.submit_for_destruction(alloc, child, timer, timeout); -} - - -void Launchpad::exit_child(Launchpad_child *child, - Timer::Session *timer, - int session_close_timeout_ms) -{ - remove_child(child->name(), child->heap()); + remove_child(child.name(), child.heap()); Lock::Guard lock_guard(_children_lock); - _children.remove(child); + _children.remove(&child); - Ram_session_capability ram_session_cap = child->ram_session_cap(); - Cpu_session_capability cpu_session_cap = child->cpu_session_cap(); - Rom_session_capability rom_session_cap = child->rom_session_cap(); - - const Genode::Server *server = child->server(); - destruct_child(&_sliced_heap, child, timer, session_close_timeout_ms); - - env()->parent()->close(cpu_session_cap); - env()->parent()->close(rom_session_cap); - env()->parent()->close(ram_session_cap); - - /* - * The killed child may have provided services to other children. - * Since the server is dead by now, we cannot close its sessions - * in the cooperative way. Instead, we need to instruct each - * other child to forget about session associated with the dead - * server. Note that the 'child' pointer points a a no-more - * existing object. It is only used to identify the corresponding - * session. It must never by de-referenced! - */ - Launchpad_child *c = _children.first(); - for ( ; c; c = c->Genode::List::Element::next()) - c->revoke_server(server); + destroy(_sliced_heap, &child); } diff --git a/repos/demo/src/server/liquid_framebuffer/main.cc b/repos/demo/src/server/liquid_framebuffer/main.cc index 954fad1e9..70ebd9dfd 100644 --- a/repos/demo/src/server/liquid_framebuffer/main.cc +++ b/repos/demo/src/server/liquid_framebuffer/main.cc @@ -11,10 +11,9 @@ * under the terms of the GNU General Public License version 2. */ +#include #include -#include -#include -#include +#include #include #include @@ -101,12 +100,10 @@ static bool config_decoration = true; /** * Parse configuration */ -static void read_config() +static void read_config(Genode::Xml_node config_node) { using namespace Genode; - Xml_node config_node = config()->xml_node(); - try { char buf[16]; config_node.attribute("animate").value(buf, sizeof(buf)); @@ -169,42 +166,71 @@ static void read_config() struct Input_handler { - GENODE_RPC(Rpc_handle_input, void, handle, Scout::Event&); + GENODE_RPC(Rpc_handle_input, void, handle_input, Scout::Event const &); GENODE_RPC_INTERFACE(Rpc_handle_input); }; -class Input_handler_component : public Genode::Rpc_object +class Main : public Scout::Event_handler { - private: Scout::Platform &_pf; Scout::User_state &_user_state; Framebuffer_window &_fb_win; - Genode::Signal_receiver &_sig_rec; + Genode::Attached_rom_dataspace &_config; unsigned long _curr_time, _old_time; + void _handle_config() + { + _config.update(); + + /* keep the current values by default */ + config_fb_x = _fb_win.view_x(); + config_fb_y = _fb_win.view_y(); + config_fb_width = _fb_win.view_w(); + config_fb_height = _fb_win.view_h(); + + try { read_config(_config.xml()); } catch (...) { } + + _fb_win.name(config_title); + _fb_win.config_alpha(config_alpha); + _fb_win.config_resize_handle(config_resize_handle); + _fb_win.config_decoration(config_decoration); + + /* must get called after 'config_decoration()' */ + _fb_win.content_geometry(config_fb_x, config_fb_y, + config_fb_width, config_fb_height); + _user_state.update_view_offset(); + } + + Genode::Signal_handler
_config_handler; + public: - Input_handler_component(Scout::Platform &pf, - Scout::User_state &user_state, - Framebuffer_window &fb_win, - Genode::Signal_receiver &sig_rec) + Main(Scout::Platform &pf, + Scout::User_state &user_state, + Framebuffer_window &fb_win, + Genode::Entrypoint &ep, + Genode::Attached_rom_dataspace &config) : _pf(pf), _user_state(user_state), _fb_win(fb_win), - _sig_rec(sig_rec) + _config(config), + _config_handler(ep, *this, &Main::_handle_config) { _curr_time = _old_time = _pf.timer_ticks(); + + config.sigh(_config_handler); } - void handle(Scout::Event &ev) + void handle_event(Scout::Event const &event) override { using Scout::Event; + Event ev = event; + if (ev.type != Event::WHEEL) ev.mouse_position = ev.mouse_position - _user_state.view_position(); @@ -217,30 +243,11 @@ class Input_handler_component : public Genode::Rpc_objectreload(); - /* keep the current values by default */ - config_fb_x = _fb_win.view_x(); - config_fb_y = _fb_win.view_y(); - config_fb_width = _fb_win.view_w(); - config_fb_height = _fb_win.view_h(); - try { read_config(); } catch (...) { } - _fb_win.name(config_title); - _fb_win.config_alpha(config_alpha); - _fb_win.config_resize_handle(config_resize_handle); - _fb_win.config_decoration(config_decoration); - /* must get called after 'config_decoration()' */ - _fb_win.content_geometry(config_fb_x, config_fb_y, - config_fb_width, config_fb_height); - _user_state.update_view_offset(); - } } /* perform periodic redraw */ _curr_time = _pf.timer_ticks(); - if (!_pf.event_pending() && ((_curr_time - _old_time > 20) || (_curr_time < _old_time))) { + if ((_curr_time - _old_time > 20) || (_curr_time < _old_time)) { _old_time = _curr_time; _fb_win.process_redraw(); } @@ -248,29 +255,24 @@ class Input_handler_component : public Genode::Rpc_objectsigh(sig_rec.manage(&sig_ctx)); } catch (...) { } + try { read_config(config.xml()); } catch (...) { } /* heuristic for allocating the double-buffer backing store */ enum { WINBORDER_WIDTH = 10, WINBORDER_HEIGHT = 40 }; /* init platform */ - static Nitpicker::Connection nitpicker; - static Platform pf(*nitpicker.input()); + static Nitpicker::Connection nitpicker(env); + static Platform pf(env, *nitpicker.input()); Area const max_size(config_fb_width + WINBORDER_WIDTH, config_fb_height + WINBORDER_HEIGHT); @@ -301,27 +303,9 @@ int main(int argc, char **argv) fb_win.content_geometry(config_fb_x, config_fb_y, config_fb_width, config_fb_height); - /* initialize server entry point */ - enum { STACK_SIZE = 2*1024*sizeof(Genode::addr_t) }; - static Genode::Cap_connection cap; - static Genode::Rpc_entrypoint ep(&cap, STACK_SIZE, "liquid_fb_ep"); - /* initialize public services */ - init_services(ep); + init_services(env.ep().rpc_ep()); - /* create local input handler service */ - static Input_handler_component input_handler(pf, user_state, fb_win, - sig_rec); - Genode::Capability input_handler_cap = ep.manage(&input_handler); - - /* enter main loop */ - for (;;) { - Event ev = pf.get_event(); - input_handler_cap.call(ev); - - if (ev.type == Event::QUIT) - break; - } - - return 0; + static Main main(pf, user_state, fb_win, env.ep(), config); + pf.event_handler(main); } diff --git a/repos/demo/src/server/liquid_framebuffer/services.cc b/repos/demo/src/server/liquid_framebuffer/services.cc index b84444713..bd2e00f02 100644 --- a/repos/demo/src/server/liquid_framebuffer/services.cc +++ b/repos/demo/src/server/liquid_framebuffer/services.cc @@ -58,7 +58,7 @@ class Window_content : public Scout::Element : _input_session(input_session),_element(element) { } - void handle(Scout::Event &ev) + void handle_event(Scout::Event const &ev) override { using namespace Scout; diff --git a/repos/demo/src/server/nitlog/main.cc b/repos/demo/src/server/nitlog/main.cc index fcd930bdb..c247da5bd 100644 --- a/repos/demo/src/server/nitlog/main.cc +++ b/repos/demo/src/server/nitlog/main.cc @@ -401,7 +401,7 @@ int main(int argc, char **argv) Framebuffer::Mode::RGB565), false); /* initialize entry point that serves the root interface */ - enum { STACK_SIZE = 4096 }; + enum { STACK_SIZE = 4096*sizeof(long) }; static Cap_connection cap; static Rpc_entrypoint ep(&cap, STACK_SIZE, "nitlog_ep"); diff --git a/repos/gems/include/gems/report_rom_slave.h b/repos/gems/include/gems/report_rom_slave.h index da18a99f0..bacb043f8 100644 --- a/repos/gems/include/gems/report_rom_slave.h +++ b/repos/gems/include/gems/report_rom_slave.h @@ -17,85 +17,53 @@ /* Genode includes */ #include #include -#include -#include -#include +#include +#include class Report_rom_slave : public Genode::Noncopyable { private: - class Policy : public Genode::Slave_policy + class Policy : public Genode::Slave::Policy { private: Genode::Root_capability _report_root_cap; Genode::Root_capability _rom_root_cap; bool _announced; - Genode::Lock mutable _lock; /* used to wait for announcement */ protected: char const **_permitted_services() const { static char const *permitted_services[] = { - "LOG", "RM", 0 }; + "CPU", "PD", "RAM", "LOG", 0 }; return permitted_services; }; + static Name _name() { return "report_rom"; } + static Genode::size_t _quota() { return 1024*1024; } + public: - Policy(Genode::Rpc_entrypoint &entrypoint, - Genode::Ram_session &ram, - const char *config) + Policy(Genode::Rpc_entrypoint &ep, + Genode::Region_map &rm, + Genode::Ram_session_capability ram, + const char *config) : - Slave_policy("report_rom", entrypoint, &ram), - _lock(Genode::Lock::LOCKED) + Genode::Slave::Policy(_name(), _name(), ep, rm, ram, _quota()) { if (config) configure(config); } - - bool announce_service(const char *service_name, - Genode::Root_capability root, - Genode::Allocator *, - Genode::Server *) - { - if (Genode::strcmp(service_name, "ROM") == 0) - _rom_root_cap = root; - else if (Genode::strcmp(service_name, "Report") == 0) - _report_root_cap = root; - else - return false; - - if (_rom_root_cap.valid() && _report_root_cap.valid()) - _lock.unlock(); - - return true; - } - - Genode::Root_capability report_root() const - { - Genode::Lock::Guard guard(_lock); - return _report_root_cap; - } - - Genode::Root_capability rom_root() const - { - Genode::Lock::Guard guard(_lock); - return _rom_root_cap; - } }; Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t); Genode::Rpc_entrypoint _ep; Policy _policy; - Genode::size_t const _quota = 1024*1024; - Genode::Slave _slave; - Genode::Root_client _rom_root; - Genode::Root_client _report_root; + Genode::Child _child; public: @@ -106,64 +74,17 @@ class Report_rom_slave : public Genode::Noncopyable * \param ram RAM session used to allocate the configuration * dataspace */ - Report_rom_slave(Genode::Cap_session &cap, Genode::Ram_session &ram, - char const *config) + Report_rom_slave(Genode::Pd_session &pd, + Genode::Region_map &rm, + Genode::Ram_session_capability ram, + char const *config) : - _ep(&cap, _ep_stack_size, "report_rom"), - _policy(_ep, ram, config), - _slave(_ep, _policy, _quota), - _rom_root(_policy.rom_root()), - _report_root(_policy.report_root()) + _ep(&pd, _ep_stack_size, "report_rom"), + _policy(_ep, rm, ram, config), + _child(rm, _ep, _policy) { } - Genode::Rom_session_capability rom_session(char const *label) - { - using namespace Genode; - - enum { ARGBUF_SIZE = 128 }; - char argbuf[ARGBUF_SIZE]; - argbuf[0] = 0; - - /* - * Declare ram-quota donation - */ - enum { SESSION_METADATA = 4*1024 }; - Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA); - - /* - * Set session label - */ - Arg_string::set_arg_string(argbuf, sizeof(argbuf), "label", label); - - Session_capability session_cap = _rom_root.session(argbuf, Affinity()); - - return static_cap_cast(session_cap); - } - - Genode::Capability report_session(char const *label) - { - using namespace Genode; - - enum { ARGBUF_SIZE = 128 }; - char argbuf[ARGBUF_SIZE]; - argbuf[0] = 0; - - /* - * Declare ram-quota donation - */ - enum { BUFFER_SIZE = 4096, SESSION_METADATA = BUFFER_SIZE + 8*1024 }; - Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA); - Arg_string::set_arg(argbuf, sizeof(argbuf), "buffer_size", BUFFER_SIZE); - - /* - * Set session label - */ - Arg_string::set_arg_string(argbuf, sizeof(argbuf), "label", label); - - Session_capability session_cap = _report_root.session(argbuf, Affinity()); - - return static_cap_cast(session_cap); - } + Genode::Slave::Policy &policy() { return _policy; } }; #endif /* _INCLUDE__GEMS__REPORT_ROM_SLAVE_H_ */ diff --git a/repos/gems/include/gems/single_session_service.h b/repos/gems/include/gems/single_session_service.h deleted file mode 100644 index 8cf747674..000000000 --- a/repos/gems/include/gems/single_session_service.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * \brief Utility for implementing a local service with a single session - * \author Norman Feske - * \date 2014-02-14 - */ - -/* - * Copyright (C) 2014 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _INCLUDE__GEMS__SINGLE_SESSION_SERVICE_H_ -#define _INCLUDE__GEMS__SINGLE_SESSION_SERVICE_H_ - -#include - -struct Single_session_service : Genode::Service -{ - Genode::Session_capability session_cap; - - Single_session_service(char const *service_name, - Genode::Session_capability session_cap) - : - Service(service_name), session_cap(session_cap) - { } - - Genode::Session_capability - session(const char *, Genode::Affinity const &) override - { - return session_cap; - } - - void upgrade(Genode::Session_capability, const char *) override { } - void close(Genode::Session_capability) override { } -}; - -#endif /* _INCLUDE__GEMS__SINGLE_SESSION_SERVICE_H_ */ diff --git a/repos/gems/src/app/launcher/context_dialog.h b/repos/gems/src/app/launcher/context_dialog.h index ee6a00a37..7cd8adab9 100644 --- a/repos/gems/src/app/launcher/context_dialog.h +++ b/repos/gems/src/app/launcher/context_dialog.h @@ -105,12 +105,11 @@ class Launcher::Context_dialog : Input_event_handler, Dialog_generator, public: - Context_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram, - Dataspace_capability ldso_ds, + Context_dialog(Env &env, Report_rom_slave &report_rom_slave, Response_handler &response_handler) : - _dialog(ep, cap, ram, ldso_ds, report_rom_slave, + _dialog(env, report_rom_slave, "context_dialog", "context_hover", *this, *this, *this, *this, Fading_dialog::Position(364, 64)), diff --git a/repos/gems/src/app/launcher/dialog_nitpicker.h b/repos/gems/src/app/launcher/dialog_nitpicker.h index 68ee59249..b01a46c87 100644 --- a/repos/gems/src/app/launcher/dialog_nitpicker.h +++ b/repos/gems/src/app/launcher/dialog_nitpicker.h @@ -20,6 +20,7 @@ /* Genode includes */ #include +#include #include #include #include @@ -54,7 +55,7 @@ struct Launcher::Dialog_nitpicker_session : Wrapped_nitpicker_session Input_event_handler &_input_event_handler; - Server::Entrypoint &_ep; + Rpc_entrypoint &_session_ep; Nitpicker::Session &_nitpicker_session; @@ -62,36 +63,43 @@ struct Launcher::Dialog_nitpicker_session : Wrapped_nitpicker_session Attached_dataspace _nitpicker_input_ds { _nitpicker_input.dataspace() }; - Signal_rpc_member - _input_dispatcher { _ep, *this, &Dialog_nitpicker_session::_input_handler }; + Signal_handler _input_handler; Input::Session_component _input_session; - Capability _input_session_cap { _ep.manage(_input_session) }; - /** * Constructor + * + * \param input_sigh_ep entrypoint where the input signal handler is + * installed ('env.ep') + * \param service_ep entrypoint providing the nitpicker session + * (slave-specific ep) */ - Dialog_nitpicker_session(Nitpicker::Session &nitpicker_session, - Server::Entrypoint &ep, + Dialog_nitpicker_session(Nitpicker::Session &nitpicker_session, + Entrypoint &input_sigh_ep, + Rpc_entrypoint &session_ep, Input_event_handler &input_event_handler) : Wrapped_nitpicker_session(nitpicker_session), _input_event_handler(input_event_handler), - _ep(ep), - _nitpicker_session(nitpicker_session) + _session_ep(session_ep), + _nitpicker_session(nitpicker_session), + _input_handler(input_sigh_ep, *this, &Dialog_nitpicker_session::_handle_input) { - _nitpicker_input.sigh(_input_dispatcher); + _session_ep.manage(this); + _session_ep.manage(&_input_session); + _nitpicker_input.sigh(_input_handler); _input_session.event_queue().enabled(true); } ~Dialog_nitpicker_session() { - _ep.dissolve(_input_session); + _session_ep.dissolve(&_input_session); + _session_ep.dissolve(this); } - void _input_handler(unsigned) + void _handle_input() { Input::Event const * const events = _nitpicker_input_ds.local_addr(); @@ -116,7 +124,7 @@ struct Launcher::Dialog_nitpicker_session : Wrapped_nitpicker_session Input::Session_capability input_session() override { - return _input_session_cap; + return _input_session.cap(); } }; diff --git a/repos/gems/src/app/launcher/fading_dialog.h b/repos/gems/src/app/launcher/fading_dialog.h index 76967fb76..a3cf66f1e 100644 --- a/repos/gems/src/app/launcher/fading_dialog.h +++ b/repos/gems/src/app/launcher/fading_dialog.h @@ -54,17 +54,17 @@ class Launcher::Fading_dialog : private Input_event_handler { private: - Rom_session_capability _dialog_rom; + Slave::Connection _dialog_rom; /* dialog reported locally */ - Capability _dialog_report; + Slave::Connection _dialog_report; - Rom_session_client _hover_rom; + Slave::Connection _hover_rom; Lazy_volatile_object _hover_ds; /* hovered element reported by menu view */ - Capability _hover_report; + Slave::Connection _hover_report; Local_reporter _dialog_reporter { "dialog", _dialog_report }; @@ -100,7 +100,7 @@ class Launcher::Fading_dialog : private Input_event_handler return forward_event; } - void _handle_hover_update(unsigned) + void _handle_hover_update() { try { if (!_hover_ds.constructed() || _hover_rom.update() == false) { @@ -129,52 +129,10 @@ class Launcher::Fading_dialog : private Input_event_handler } } - Signal_rpc_member _hover_update_dispatcher; + Signal_handler _hover_update_handler; private: - /** - * Local nitpicker service to be handed out to the menu view slave - */ - struct Nitpicker_service : Genode::Service - { - Server::Entrypoint &ep; - Rpc_entrypoint &child_ep; - - /* connection to real nitpicker */ - Nitpicker::Connection connection { "menu" }; - - Dialog_nitpicker_session wrapper_session; - - Capability session_cap { child_ep.manage(&wrapper_session) }; - - Nitpicker_service(Server::Entrypoint &ep, - Rpc_entrypoint &child_ep, - Dialog_nitpicker_session::Input_event_handler &ev_handler) - : - Genode::Service(Nitpicker::Session::service_name()), - ep(ep), child_ep(child_ep), - wrapper_session(connection, ep, ev_handler) - { } - - /******************************* - ** Genode::Service interface ** - *******************************/ - - Genode::Session_capability - session(const char *, Genode::Affinity const &) override - { - return session_cap; - } - - void upgrade(Genode::Session_capability, const char *args) override - { - Genode::log("upgrade called args: '", args, "'"); - } - - void close(Genode::Session_capability) override { } - }; - /* * Entrypoint for the fader slave * @@ -188,9 +146,21 @@ class Launcher::Fading_dialog : private Input_event_handler size_t const _fader_slave_ep_stack_size = 4*1024*sizeof(addr_t); Rpc_entrypoint _fader_slave_ep; - Nitpicker_service _nitpicker_service; - Nit_fader_slave _nit_fader_slave; - Menu_view_slave _menu_view_slave; + /* + * Provide wrapped nitpicker connection as a service handed out to + * the menu-view slave + */ + typedef Genode::Local_service Nitpicker_service; + typedef Nitpicker_service::Single_session_factory Nitpicker_factory; + + Nitpicker::Connection _nitpicker_connection; + Dialog_nitpicker_session _nitpicker_session; + Nitpicker_factory _nitpicker_factory { _nitpicker_session }; + Nitpicker_service _nitpicker_service { _nitpicker_factory }; + + Nit_fader_slave _nit_fader_slave; + Slave::Connection _nit_fader_connection; + Menu_view_slave _menu_view_slave; bool _visible = false; @@ -198,47 +168,38 @@ class Launcher::Fading_dialog : private Input_event_handler typedef Menu_view_slave::Position Position; - /** - * Constructor - * - * \param ep main entrypoint, used for managing the local input - * session provided (indirectly through the wrapped - * nitpicker session) to the menu view - * \param cap capability session to be used for creating the - * slave entrypoints - * \param ram RAM session where to draw the memory for providing - * configuration data to the slave processes - */ - Fading_dialog(Server::Entrypoint &ep, - Cap_session &cap, - Ram_session &ram, - Dataspace_capability ldso_ds, - Report_rom_slave &report_rom_slave, - char const *dialog_name, - char const *hover_name, - Input_event_handler &input_event_handler, - Hover_handler &hover_handler, - Dialog_generator &dialog_generator, - Dialog_model &dialog_model, - Position initial_position) + Fading_dialog(Env &env, + Report_rom_slave &report_rom_slave, + char const *dialog_name, + char const *hover_name, + Input_event_handler &input_event_handler, + Hover_handler &hover_handler, + Dialog_generator &dialog_generator, + Dialog_model &dialog_model, + Position initial_position) : - _dialog_rom(report_rom_slave.rom_session(dialog_name)), - _dialog_report(report_rom_slave.report_session(dialog_name)), - _hover_rom(report_rom_slave.rom_session(hover_name)), - _hover_report(report_rom_slave.report_session(hover_name)), + _dialog_rom(report_rom_slave.policy(), Slave::Args("label=", dialog_name)), + _dialog_report(report_rom_slave.policy(), + Slave::Args("label=", dialog_name, ", buffer_size=4096")), + _hover_rom(report_rom_slave.policy(), Slave::Args("label=", hover_name)), + _hover_report(report_rom_slave.policy(), + Slave::Args("label=", hover_name, ", buffer_size=4096")), _dialog_input_event_handler(input_event_handler), _hover_handler(hover_handler), _dialog_generator(dialog_generator), _dialog_model(dialog_model), - _hover_update_dispatcher(ep, *this, &Fading_dialog::_handle_hover_update), - _fader_slave_ep(&cap, _fader_slave_ep_stack_size, "nit_fader"), - _nitpicker_service(ep, _fader_slave_ep, *this), - _nit_fader_slave(_fader_slave_ep, ram, _nitpicker_service, ldso_ds), - _menu_view_slave(cap, ram, ldso_ds, - _nit_fader_slave.nitpicker_session("menu"), + _hover_update_handler(env.ep(), *this, &Fading_dialog::_handle_hover_update), + _fader_slave_ep(&env.pd(), _fader_slave_ep_stack_size, "nit_fader"), + _nitpicker_connection(env, "menu"), + _nitpicker_session(_nitpicker_connection, env.ep(), _fader_slave_ep, *this), + _nit_fader_slave(_fader_slave_ep, env.rm(), env.ram_session_cap(), + _nitpicker_service), + _nit_fader_connection(_nit_fader_slave.policy(), Slave::Args("label=menu")), + _menu_view_slave(env.pd(), env.rm(), env.ram_session_cap(), + _nit_fader_connection, _dialog_rom, _hover_report, initial_position) { - Rom_session_client(_hover_rom).sigh(_hover_update_dispatcher); + Rom_session_client(_hover_rom).sigh(_hover_update_handler); } void update() diff --git a/repos/gems/src/app/launcher/main.cc b/repos/gems/src/app/launcher/main.cc index a92b74544..2543f6bf1 100644 --- a/repos/gems/src/app/launcher/main.cc +++ b/repos/gems/src/app/launcher/main.cc @@ -12,9 +12,7 @@ */ /* Genode includes */ -#include -#include -#include +#include #include #include #include @@ -23,25 +21,16 @@ /* local includes */ #include +namespace Launcher { + + using namespace Genode; + struct Main; +} -namespace Launcher { struct Main; } struct Launcher::Main { - Server::Entrypoint &_ep; - - Genode::Dataspace_capability _request_ldso_ds() - { - try { - static Genode::Rom_connection rom("ld.lib.so"); - return rom.dataspace(); - } catch (...) { } - return Genode::Dataspace_capability(); - } - - Genode::Dataspace_capability _ldso_ds = _request_ldso_ds(); - - Genode::Cap_connection _cap; + Env &_env; char const *_report_rom_config = "" @@ -53,35 +42,54 @@ struct Launcher::Main " " ""; - Report_rom_slave _report_rom_slave = { _cap, *env()->ram_session(), _report_rom_config }; + Report_rom_slave _report_rom_slave { + _env.pd(), _env.rm(), _env.ram_session_cap(), _report_rom_config }; /** * Nitpicker session used to perform session-control operations on the * subsystem's nitpicker sessions and to receive global keyboard * shortcuts. */ - Nitpicker::Connection _nitpicker; + Nitpicker::Connection _nitpicker { _env }; - Genode::Signal_rpc_member
_input_dispatcher = - { _ep, *this, &Main::_handle_input }; + Signal_handler
_input_handler = + { _env.ep(), *this, &Main::_handle_input }; - void _handle_input(unsigned); + void _handle_input(); unsigned _key_cnt = 0; - Genode::Signal_rpc_member
_exited_child_dispatcher = - { _ep, *this, &Main::_handle_exited_child }; + Signal_handler
_exited_child_handler = + { _env.ep(), *this, &Main::_handle_exited_child }; - Subsystem_manager _subsystem_manager { _ep, _cap, _exited_child_dispatcher, - _ldso_ds }; + Attached_rom_dataspace _config { _env, "config" }; - Panel_dialog _panel_dialog { _ep, _cap, *env()->ram_session(), _ldso_ds, - *env()->heap(), - _report_rom_slave, _subsystem_manager, _nitpicker }; + static size_t _ram_preservation(Xml_node config) + { + char const * const node_name = "preservation"; - void _handle_config(unsigned); + if (config.has_sub_node(node_name)) { - void _handle_exited_child(unsigned) + Xml_node const node = config.sub_node(node_name); + if (node.attribute_value("name", Genode::String<16>()) == "RAM") + return node.attribute_value("quantum", Genode::Number_of_bytes()); + } + + return 0; + } + + Subsystem_manager _subsystem_manager { _env.ep(), _env.pd(), + _ram_preservation(_config.xml()), + _exited_child_handler }; + + Heap _heap { _env.ram(), _env.rm() }; + + Panel_dialog _panel_dialog { _env, _heap, _report_rom_slave, + _subsystem_manager, _nitpicker }; + + void _handle_config(); + + void _handle_exited_child() { auto kill_child_fn = [&] (Label const &label) { _panel_dialog.kill(label); }; @@ -92,37 +100,40 @@ struct Launcher::Main Genode::Attached_rom_dataspace _focus_rom { "focus" }; - void _handle_focus_update(unsigned); + void _handle_focus_update(); - Genode::Signal_rpc_member
_focus_update_dispatcher = - { _ep, *this, &Main::_handle_focus_update }; + Signal_handler
_focus_update_handler = + { _env.ep(), *this, &Main::_handle_focus_update }; /** * Constructor */ - Main(Server::Entrypoint &ep) : _ep(ep) + Main(Env &env) : _env(env) { - _nitpicker.input()->sigh(_input_dispatcher); - _focus_rom.sigh(_focus_update_dispatcher); + _nitpicker.input()->sigh(_input_handler); + _focus_rom.sigh(_focus_update_handler); - _handle_config(0); + _handle_config(); _panel_dialog.visible(true); } }; -void Launcher::Main::_handle_config(unsigned) +void Launcher::Main::_handle_config() { - config()->reload(); + _config.update(); - _focus_prefix = config()->xml_node().attribute_value("focus_prefix", Label()); + _focus_prefix = _config.xml().attribute_value("focus_prefix", Label()); - _panel_dialog.update(config()->xml_node()); + try { + _panel_dialog.update(_config.xml()); } + catch (Allocator::Out_of_memory) { + error("out of memory while applying configuration"); } } -void Launcher::Main::_handle_input(unsigned) +void Launcher::Main::_handle_input() { _nitpicker.input()->for_each_event([&] (Input::Event const &e) { if (e.type() == Input::Event::PRESS) _key_cnt++; @@ -143,7 +154,7 @@ void Launcher::Main::_handle_input(unsigned) } -void Launcher::Main::_handle_focus_update(unsigned) +void Launcher::Main::_handle_focus_update() { try { _focus_rom.update(); @@ -176,18 +187,4 @@ void Launcher::Main::_handle_focus_update(unsigned) } -/************ - ** Server ** - ************/ - -namespace Server { - - char const *name() { return "desktop_ep"; } - - size_t stack_size() { return 4*1024*sizeof(long); } - - void construct(Entrypoint &ep) - { - static Launcher::Main desktop(ep); - } -} +void Component::construct(Genode::Env &env) { static Launcher::Main main(env); } diff --git a/repos/gems/src/app/launcher/menu_dialog.h b/repos/gems/src/app/launcher/menu_dialog.h index 718b949fb..f0595d351 100644 --- a/repos/gems/src/app/launcher/menu_dialog.h +++ b/repos/gems/src/app/launcher/menu_dialog.h @@ -103,18 +103,14 @@ class Launcher::Menu_dialog : Input_event_handler, Dialog_generator, public: - Menu_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram, - Dataspace_capability ldso_ds, + Menu_dialog(Env &env, Report_rom_slave &report_rom_slave, Response_handler &response_handler) : _response_handler(response_handler), - _dialog(ep, cap, ram, ldso_ds, report_rom_slave, - "menu_dialog", "menu_hover", - *this, *this, *this, *this, - _position) - { - } + _dialog(env, report_rom_slave, "menu_dialog", "menu_hover", + *this, *this, *this, *this, _position) + { } /** * Dialog_generator interface diff --git a/repos/gems/src/app/launcher/menu_view_slave.h b/repos/gems/src/app/launcher/menu_view_slave.h index 2ef836ea8..614a636be 100644 --- a/repos/gems/src/app/launcher/menu_view_slave.h +++ b/repos/gems/src/app/launcher/menu_view_slave.h @@ -19,7 +19,7 @@ #include /* gems includes */ -#include +#include /* local includes */ #include @@ -35,16 +35,13 @@ class Launcher::Menu_view_slave private: - class Policy : public Genode::Slave_policy + class Policy : public Genode::Slave::Policy { private: - Lock mutable _nitpicker_root_lock { Lock::LOCKED }; - Capability _nitpicker_root_cap; - - Single_session_service _nitpicker_service; - Single_session_service _dialog_rom_service; - Single_session_service _hover_report_service; + Genode::Single_session_service _nitpicker; + Genode::Single_session_service _dialog_rom; + Genode::Single_session_service _hover_report; Position _position; @@ -53,7 +50,7 @@ class Launcher::Menu_view_slave char const **_permitted_services() const { static char const *permitted_services[] = { - "ROM", "LOG", "RM", "Timer", 0 }; + "CPU", "PD", "RAM", "ROM", "LOG", "Timer", 0 }; return permitted_services; }; @@ -78,82 +75,70 @@ class Launcher::Menu_view_slave configure(config); } + static Name _name() { return "menu_view"; } + static Genode::size_t _quota() { return 6*1024*1024; } + public: - Policy(Genode::Rpc_entrypoint &entrypoint, - Genode::Ram_session &ram, + Policy(Genode::Rpc_entrypoint &ep, + Genode::Region_map &rm, + Genode::Ram_session_capability ram, Capability nitpicker_session, Capability dialog_rom_session, Capability hover_report_session, Position position) : - Slave_policy("menu_view", entrypoint, &ram), - _nitpicker_service(Nitpicker::Session::service_name(), nitpicker_session), - _dialog_rom_service(Rom_session::service_name(), dialog_rom_session), - _hover_report_service(Report::Session::service_name(), hover_report_session), + Genode::Slave::Policy(_name(), _name(), ep, rm, ram, _quota()), + _nitpicker(nitpicker_session), + _dialog_rom(dialog_rom_session), + _hover_report(hover_report_session), _position(position) { _configure(position); } - void position(Position pos) + void position(Position pos) { _configure(pos); } + + Genode::Service &resolve_session_request(Genode::Service::Name const &service, + Genode::Session_state::Args const &args) override { - _configure(pos); - } + if (service == "Nitpicker") + return _nitpicker.service(); - Genode::Service *resolve_session_request(const char *service_name, - const char *args) override - { - using Genode::strcmp; + Genode::Session_label const label(label_from_args(args.string())); - if (strcmp(service_name, "Nitpicker") == 0) - return &_nitpicker_service; + if ((service == "ROM") && (label == "menu_view -> dialog")) + return _dialog_rom.service(); - char label[128]; - Arg_string::find_arg(args, "label").string(label, sizeof(label), ""); + if ((service == "Report") && (label == "menu_view -> hover")) + return _hover_report.service(); - if (strcmp(service_name, "ROM") == 0) { - - if (strcmp(label, "menu_view -> dialog") == 0) - return &_dialog_rom_service; - } - - if (strcmp(service_name, "Report") == 0) { - - if (strcmp(label, "menu_view -> hover") == 0) - return &_hover_report_service; - } - - return Genode::Slave_policy::resolve_session_request(service_name, args); + return Genode::Slave::Policy::resolve_session_request(service, args); } }; Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t); Genode::Rpc_entrypoint _ep; Policy _policy; - Genode::size_t const _quota = 6*1024*1024; - Genode::Slave _slave; + Genode::Child _child; public: /** * Constructor - * - * \param ep entrypoint used for child thread - * \param ram RAM session used to allocate the configuration - * dataspace */ - Menu_view_slave(Genode::Cap_session &cap, Genode::Ram_session &ram, - Genode::Dataspace_capability ldso_ds, + Menu_view_slave(Genode::Pd_session &pd, + Genode::Region_map &rm, + Genode::Ram_session_capability ram, Capability nitpicker_session, Capability dialog_rom_session, Capability hover_report_session, Position initial_position) : - _ep(&cap, _ep_stack_size, "nit_fader"), - _policy(_ep, ram, nitpicker_session, dialog_rom_session, + _ep(&pd, _ep_stack_size, "nit_fader"), + _policy(_ep, rm, ram, nitpicker_session, dialog_rom_session, hover_report_session, initial_position), - _slave(_ep, _policy, _quota, env()->ram_session_cap(), ldso_ds) + _child(rm, _ep, _policy) { } void position(Position position) { _policy.position(position); } diff --git a/repos/gems/src/app/launcher/nit_fader_slave.h b/repos/gems/src/app/launcher/nit_fader_slave.h index a32b32a43..b24857273 100644 --- a/repos/gems/src/app/launcher/nit_fader_slave.h +++ b/repos/gems/src/app/launcher/nit_fader_slave.h @@ -28,31 +28,33 @@ class Launcher::Nit_fader_slave { private: - class Policy : public Slave_policy + class Policy : public Slave::Policy { private: Genode::Service &_nitpicker_service; - Lock mutable _nitpicker_root_lock { Lock::LOCKED }; - Capability _nitpicker_root_cap; protected: char const **_permitted_services() const { static char const *permitted_services[] = { - "LOG", "RM", "Timer", 0 }; + "RAM", "CPU", "PD", "LOG", "Timer", 0 }; return permitted_services; }; + static Name _name() { return "nit_fader"; } + static size_t _quota() { return 2*1024*1024; } + public: - Policy(Rpc_entrypoint &entrypoint, - Ram_session &ram, - Genode::Service &nitpicker_service) + Policy(Rpc_entrypoint &ep, + Region_map &rm, + Ram_session_capability ram, + Genode::Service &nitpicker_service) : - Slave_policy("nit_fader", entrypoint, &ram), + Genode::Slave::Policy(_name(), _name(), ep, rm, ram, _quota()), _nitpicker_service(nitpicker_service) { visible(false); @@ -66,42 +68,18 @@ class Launcher::Nit_fader_slave configure(config, strlen(config) + 1); } - bool announce_service(const char *service_name, - Root_capability root, - Allocator *, - Genode::Server *) + Genode::Service &resolve_session_request(Genode::Service::Name const &service, + Genode::Session_state::Args const &args) override { - if (strcmp(service_name, "Nitpicker") == 0) - _nitpicker_root_cap = root; - else - return false; + if (service == Nitpicker::Session::service_name()) + return _nitpicker_service; - if (_nitpicker_root_cap.valid()) - _nitpicker_root_lock.unlock(); - - return true; - } - - Genode::Service *resolve_session_request(const char *service_name, - const char *args) override - { - if (Genode::strcmp(service_name, "Nitpicker") == 0) - return &_nitpicker_service; - - return Genode::Slave_policy::resolve_session_request(service_name, args); - } - - Root_capability nitpicker_root() const - { - Lock::Guard guard(_nitpicker_root_lock); - return _nitpicker_root_cap; + return Genode::Slave::Policy::resolve_session_request(service, args); } }; - Policy _policy; - size_t const _quota = 2*1024*1024; - Slave _slave; - Root_client _nitpicker_root; + Policy _policy; + Child _child; public: @@ -112,38 +90,18 @@ class Launcher::Nit_fader_slave * \param ram RAM session used to allocate the configuration * dataspace */ - Nit_fader_slave(Rpc_entrypoint &ep, Ram_session &ram, - Genode::Service &nitpicker_service, - Genode::Dataspace_capability ldso_ds) + Nit_fader_slave(Rpc_entrypoint &ep, + Genode::Region_map &rm, + Ram_session_capability ram, + Genode::Service &nitpicker_service) : - _policy(ep, ram, nitpicker_service), - _slave(ep, _policy, _quota, env()->ram_session_cap(), ldso_ds), - _nitpicker_root(_policy.nitpicker_root()) + _policy(ep, rm, ram, nitpicker_service), + _child(rm, ep, _policy) { visible(false); } - Capability nitpicker_session(char const *label) - { - enum { ARGBUF_SIZE = 128 }; - char argbuf[ARGBUF_SIZE]; - argbuf[0] = 0; - - /* - * Declare ram-quota donation - */ - enum { SESSION_METADATA = 8*1024 }; - Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", SESSION_METADATA); - - /* - * Set session label - */ - Arg_string::set_arg_string(argbuf, sizeof(argbuf), "label", label); - - Session_capability session_cap = _nitpicker_root.session(argbuf, Affinity()); - - return static_cap_cast(session_cap); - } + Genode::Slave::Policy &policy() { return _policy; } void visible(bool visible) { diff --git a/repos/gems/src/app/launcher/panel_dialog.h b/repos/gems/src/app/launcher/panel_dialog.h index 0e9d9ec94..1f62763d7 100644 --- a/repos/gems/src/app/launcher/panel_dialog.h +++ b/repos/gems/src/app/launcher/panel_dialog.h @@ -50,6 +50,39 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator, Genode::Allocator &_alloc; + struct Buffered_xml + { + Allocator &_alloc; + char const * const _ptr; /* pointer to dynamically allocated buffer */ + Xml_node const _xml; /* referring to buffer of '_ptr' */ + + /** + * \throw Allocator::Out_of_memory + */ + static char const *_init_ptr(Allocator &alloc, Xml_node node) + { + char *ptr = (char *)alloc.alloc(node.size()); + Genode::memcpy(ptr, node.addr(), node.size()); + return ptr; + } + + /** + * Constructor + * + * \throw Allocator::Out_of_memory + */ + Buffered_xml(Allocator &alloc, Xml_node node) + : + _alloc(alloc), _ptr(_init_ptr(alloc, node)), _xml(_ptr, node.size()) + { } + + ~Buffered_xml() { _alloc.free(const_cast(_ptr), _xml.size()); } + + Xml_node xml() const { return _xml; } + }; + + Lazy_volatile_object _config; + List _elements; Label _focus; @@ -135,7 +168,7 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator, Element *_clicked = nullptr; bool _click_in_progress = false; - Signal_rpc_member _timer_dispatcher; + Signal_handler _timer_handler; Label _context_subsystem; Context_dialog _context_dialog; @@ -165,9 +198,13 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator, void _start(Label const &label) { + if (!_config.constructed()) { + warning("attempt to start subsystem without prior configuration"); + return; + } + try { - Xml_node subsystem = _subsystem(config()->xml_node(), - label.string()); + Xml_node subsystem = _subsystem(_config->xml(), label.string()); _subsystem_manager.start(subsystem); Title const title = subsystem.attribute_value("title", Title()); @@ -232,7 +269,7 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator, _context_dialog.visible(true); } - void _handle_timer(unsigned) + void _handle_timer() { if (_click_in_progress && _clicked && _hovered() == _clicked) { _open_context_dialog(_clicked->label); @@ -250,26 +287,23 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator, public: - Panel_dialog(Server::Entrypoint &ep, Cap_session &cap, Ram_session &ram, - Dataspace_capability ldso_ds, - Genode::Allocator &alloc, - Report_rom_slave &report_rom_slave, - Subsystem_manager &subsystem_manager, + Panel_dialog(Env &env, + Genode::Allocator &alloc, + Report_rom_slave &report_rom_slave, + Subsystem_manager &subsystem_manager, Nitpicker::Session &nitpicker) : _alloc(alloc), _subsystem_manager(subsystem_manager), _nitpicker(nitpicker), - _dialog(ep, cap, ram, ldso_ds, report_rom_slave, - "panel_dialog", "panel_hover", - *this, *this, *this, *this, - _position), - _timer_dispatcher(ep, *this, &Panel_dialog::_handle_timer), - _context_dialog(ep, cap, ram, ldso_ds, report_rom_slave, *this), - _menu_dialog(ep, cap, ram, ldso_ds, report_rom_slave, *this) + _dialog(env, report_rom_slave, "panel_dialog", "panel_hover", + *this, *this, *this, *this, _position), + _timer_handler(env.ep(), *this, &Panel_dialog::_handle_timer), + _context_dialog(env, report_rom_slave, *this), + _menu_dialog(env, report_rom_slave, *this) { _elements.insert(&_menu_button); - _timer.sigh(_timer_dispatcher); + _timer.sigh(_timer_handler); } /** @@ -514,13 +548,17 @@ class Launcher::Panel_dialog : Input_event_handler, Dialog_generator, _kill(label); } + /** + * \throw Allocator::Out_of_memory + */ void update(Xml_node config) { + _config.construct(_alloc, config); + /* populate menu dialog with one item per subsystem */ - _menu_dialog.update(config); + _menu_dialog.update(_config->xml()); /* evaluate configuration */ - _dialog.update(); } diff --git a/repos/gems/src/app/launcher/subsystem_manager.h b/repos/gems/src/app/launcher/subsystem_manager.h index 765e9d158..5bf7af7b5 100644 --- a/repos/gems/src/app/launcher/subsystem_manager.h +++ b/repos/gems/src/app/launcher/subsystem_manager.h @@ -25,28 +25,7 @@ namespace Launcher { class Subsystem_manager; using Decorator::string_attribute; -} - - -/*************** - ** Utilities ** - ***************/ - -/* - * XXX copied from 'cli_monitor/main.cc' - */ -static Genode::size_t ram_preservation_from_config() -{ - Genode::Number_of_bytes ram_preservation = 0; - try { - Genode::Xml_node node = - Genode::config()->xml_node().sub_node("preservation"); - - if (node.attribute("name").has_value("RAM")) - node.attribute("quantum").value(&ram_preservation); - } catch (...) { } - - return ram_preservation; + using namespace Genode; } @@ -61,34 +40,15 @@ class Launcher::Subsystem_manager private: - Server::Entrypoint &_ep; - Cap_session &_cap; - Dataspace_capability _ldso_ds; + Entrypoint &_ep; + Pd_session &_pd; + + size_t const _ram_preservation; struct Child : Child_base, List::Element { - typedef String<128> Binary_name; - - Child(Ram &ram, - Label const &label, - Binary_name const &binary, - Cap_session &cap_session, - size_t ram_quota, - size_t ram_limit, - Signal_context_capability yield_response_sig_cap, - Signal_context_capability exit_sig_cap, - Dataspace_capability ldso_ds) - : - Child_base(ram, - label.string(), - binary.string(), - cap_session, - ram_quota, - ram_limit, - yield_response_sig_cap, - exit_sig_cap, - ldso_ds) - { } + template + Child(ARGS &&... args) : Child_base(args...) { } }; List _children; @@ -99,10 +59,10 @@ class Launcher::Subsystem_manager child->try_response_to_resource_request(); } - Genode::Signal_rpc_member _yield_broadcast_dispatcher = + Signal_handler _yield_broadcast_handler = { _ep, *this, &Subsystem_manager::_handle_yield_broadcast }; - void _handle_yield_broadcast(unsigned) + void _handle_yield_broadcast() { _try_response_to_resource_request(); @@ -129,27 +89,27 @@ class Launcher::Subsystem_manager child->yield(amount, true); } - Genode::Signal_rpc_member _resource_avail_dispatcher = + Signal_handler _resource_avail_handler = { _ep, *this, &Subsystem_manager::_handle_resource_avail }; - void _handle_resource_avail(unsigned) + void _handle_resource_avail() { _try_response_to_resource_request(); } - Genode::Signal_rpc_member _yield_response_dispatcher = + Signal_handler _yield_response_handler = { _ep, *this, &Subsystem_manager::_handle_yield_response }; - void _handle_yield_response(unsigned) + void _handle_yield_response() { _try_response_to_resource_request(); } Genode::Signal_context_capability _exited_child_sig_cap; - Ram _ram { ram_preservation_from_config(), - _yield_broadcast_dispatcher, - _resource_avail_dispatcher }; + Ram _ram { _ram_preservation, + _yield_broadcast_handler, + _resource_avail_handler }; static Child::Binary_name _binary_name(Xml_node subsystem) { @@ -187,11 +147,11 @@ class Launcher::Subsystem_manager public: - Subsystem_manager(Server::Entrypoint &ep, Cap_session &cap, - Genode::Signal_context_capability exited_child_sig_cap, - Dataspace_capability ldso_ds) + Subsystem_manager(Genode::Entrypoint &ep, Pd_session &pd, + size_t ram_preservation, + Genode::Signal_context_capability exited_child_sig_cap) : - _ep(ep), _cap(cap), _ldso_ds(ldso_ds), + _ep(ep), _pd(pd), _ram_preservation(ram_preservation), _exited_child_sig_cap(exited_child_sig_cap) { } @@ -213,10 +173,14 @@ class Launcher::Subsystem_manager try { Child *child = new (env()->heap()) - Child(_ram, label, binary_name.string(), _cap, + Child(_ram, label, binary_name.string(), + *Genode::env()->pd_session(), + *Genode::env()->ram_session(), + Genode::env()->ram_session_cap(), + *Genode::env()->rm_session(), ram_config.quantum, ram_config.limit, - _yield_broadcast_dispatcher, - _exited_child_sig_cap, _ldso_ds); + _yield_broadcast_handler, + _exited_child_sig_cap); /* configure child */ try { @@ -228,8 +192,8 @@ class Launcher::Subsystem_manager child->start(); - } catch (Rom_connection::Rom_connection_failed) { - Genode::error("binary \"", binary_name, "\" is missing"); + } catch (Parent::Service_denied) { + Genode::error("failed to start ", binary_name); throw Invalid_config(); } } diff --git a/repos/gems/src/app/launcher/target.mk b/repos/gems/src/app/launcher/target.mk index a1a5d82d9..b9cdf0a44 100644 --- a/repos/gems/src/app/launcher/target.mk +++ b/repos/gems/src/app/launcher/target.mk @@ -1,4 +1,4 @@ TARGET = launcher SRC_CC = main.cc -LIBS = base server config +LIBS = base INC_DIR += $(PRG_DIR) diff --git a/repos/gems/src/app/themed_decorator/main.cc b/repos/gems/src/app/themed_decorator/main.cc index 0bdfbb30a..65cf62192 100644 --- a/repos/gems/src/app/themed_decorator/main.cc +++ b/repos/gems/src/app/themed_decorator/main.cc @@ -118,7 +118,7 @@ struct Decorator::Main : Window_factory_base * and view_handle operations. Currently, these exceptions will * abort the decorator. */ - Genode::env()->parent()->upgrade(nitpicker, "ram_quota=256K"); + nitpicker.upgrade_ram(256*1024); Genode::config()->sigh(config_dispatcher); handle_config(0); diff --git a/repos/gems/src/server/terminal/main.cc b/repos/gems/src/server/terminal/main.cc index 4505c62ed..a43761c53 100644 --- a/repos/gems/src/server/terminal/main.cc +++ b/repos/gems/src/server/terminal/main.cc @@ -499,15 +499,11 @@ namespace Terminal { } -extern "C" void wait_for_continue(); - - int main(int, char **) { using namespace Genode; log("--- terminal service started ---"); - wait_for_continue(); static Framebuffer::Connection framebuffer; static Input::Connection input; diff --git a/repos/gems/src/server/terminal_mux/main.cc b/repos/gems/src/server/terminal_mux/main.cc index 2298b7af1..bfdf56942 100644 --- a/repos/gems/src/server/terminal_mux/main.cc +++ b/repos/gems/src/server/terminal_mux/main.cc @@ -737,7 +737,7 @@ int main(int, char **) static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session()); - static Registry registry; + static ::Registry registry; static Ncurses ncurses; static Status_window status_window(ncurses); static Menu menu(ncurses, registry, status_window); diff --git a/repos/gems/src/server/wm/decorator_nitpicker.h b/repos/gems/src/server/wm/decorator_nitpicker.h index 23dcffb10..62d078209 100644 --- a/repos/gems/src/server/wm/decorator_nitpicker.h +++ b/repos/gems/src/server/wm/decorator_nitpicker.h @@ -352,7 +352,8 @@ struct Wm::Decorator_nitpicker_session : Genode::Rpc_object, void upgrade(const char *args) { - Genode::env()->parent()->upgrade(_nitpicker_session, args); + size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); + _nitpicker_session.upgrade_ram(ram_quota); } diff --git a/repos/gems/src/server/wm/direct_nitpicker.h b/repos/gems/src/server/wm/direct_nitpicker.h index 963567ef3..d03f5afcf 100644 --- a/repos/gems/src/server/wm/direct_nitpicker.h +++ b/repos/gems/src/server/wm/direct_nitpicker.h @@ -40,7 +40,8 @@ class Wm::Direct_nitpicker_session : public Genode::Rpc_objectparent()->upgrade(_session, args); + size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); + _session.upgrade_ram(ram_quota); } diff --git a/repos/gems/src/server/wm/nitpicker.h b/repos/gems/src/server/wm/nitpicker.h index 0373f21b8..96b5c2d46 100644 --- a/repos/gems/src/server/wm/nitpicker.h +++ b/repos/gems/src/server/wm/nitpicker.h @@ -737,7 +737,8 @@ class Wm::Nitpicker::Session_component : public Rpc_object, void upgrade(char const *args) { - Genode::env()->parent()->upgrade(_session, args); + size_t const ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0); + _session.upgrade_ram(ram_quota); } void try_to_init_real_child_views() diff --git a/repos/libports/include/acpica/acpica.h b/repos/libports/include/acpica/acpica.h new file mode 100644 index 000000000..a43aa1244 --- /dev/null +++ b/repos/libports/include/acpica/acpica.h @@ -0,0 +1,24 @@ +/* + * \brief Port of ACPICA library + * \author Alexander Boettcher + * \date 2016-11-14 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__ACPICA__ACPICA_H_ +#define _INCLUDE__ACPICA__ACPICA_H_ + +namespace Genode { + struct Env; + struct Allocator; +} + +namespace Acpica { void init(Genode::Env &env, Genode::Allocator &heap); } + +#endif /* _INCLUDE__ACPICA__ACPICA_H_ */ diff --git a/repos/libports/lib/import/import-acpica.mk b/repos/libports/lib/import/import-acpica.mk new file mode 100644 index 000000000..939e30492 --- /dev/null +++ b/repos/libports/lib/import/import-acpica.mk @@ -0,0 +1,2 @@ +INC_DIR += $(call select_from_ports,acpica)/src/lib/acpica/source/include +CC_OPT += -DACPI_INLINE=inline -Wno-unused-variable diff --git a/repos/libports/lib/mk/acpica.mk b/repos/libports/lib/mk/acpica.mk index aed6065cd..d47e2c2d3 100644 --- a/repos/libports/lib/mk/acpica.mk +++ b/repos/libports/lib/mk/acpica.mk @@ -3,8 +3,6 @@ REQUIRES := x86 ACPICA_DIR := $(call select_from_ports,acpica)/src/lib/acpica ACPICA_COMP := $(ACPICA_DIR)/source/components -INC_DIR += $(ACPICA_DIR)/source/include - SRC_C += debugger/dbdisply.c debugger/dbobject.c debugger/dbxface.c SRC_C += $(addprefix disassembler/, $(notdir $(wildcard $(ACPICA_COMP)/disassembler/*.c))) SRC_C += $(addprefix dispatcher/, $(notdir $(wildcard $(ACPICA_COMP)/dispatcher/*.c))) @@ -17,10 +15,10 @@ SRC_C += $(addprefix resources/, $(notdir $(wildcard $(ACPICA_COMP)/resources/*. SRC_C += $(addprefix tables/, $(notdir $(wildcard $(ACPICA_COMP)/tables/*.c))) SRC_C += $(addprefix utilities/, $(notdir $(wildcard $(ACPICA_COMP)/utilities/*.c))) -SRC_CC += osl.cc iomem.cc pci.cc -SRC_CC += scan_root.cc +SRC_CC += osl.cc iomem.cc pci.cc scan_root.cc env.cc + +include $(REP_DIR)/lib/import/import-acpica.mk -CC_OPT += -Wno-unused-function -Wno-unused-variable CC_C_OPT += -DACPI_LIBRARY vpath %.c $(ACPICA_COMP) diff --git a/repos/libports/ports/acpica.hash b/repos/libports/ports/acpica.hash index 3f2cc1f6e..ed37699c6 100644 --- a/repos/libports/ports/acpica.hash +++ b/repos/libports/ports/acpica.hash @@ -1 +1 @@ -a3d820f28b860fdd9fd8c855f0fa2ec0b4beb859 +cd8c5b5513ba384e52be2cfc54ee4435439b57d2 diff --git a/repos/libports/run/lwip.run b/repos/libports/run/lwip.run index ee88787c6..cfcd0be68 100644 --- a/repos/libports/run/lwip.run +++ b/repos/libports/run/lwip.run @@ -103,7 +103,7 @@ append_platform_drv_config append_if $use_nic_driver config { - + } diff --git a/repos/libports/run/qt5_drivers.inc b/repos/libports/run/qt5_drivers.inc index e2d3754fc..3aefdf9c8 100644 --- a/repos/libports/run/qt5_drivers.inc +++ b/repos/libports/run/qt5_drivers.inc @@ -145,8 +145,9 @@ proc drivers_start_nodes { feature_arg } { append_if [use_audio_drv feature] start_nodes { - + + } @@ -177,7 +178,7 @@ proc drivers_start_nodes { feature_arg } { append_if [use_nic_drv feature] start_nodes { - + } diff --git a/repos/libports/src/app/acpica/os.cc b/repos/libports/src/app/acpica/os.cc index a398a9af2..8f4d0b26f 100644 --- a/repos/libports/src/app/acpica/os.cc +++ b/repos/libports/src/app/acpica/os.cc @@ -14,16 +14,19 @@ #include #include #include +#include #include #include #include -#include #include #include #include +#include + + extern "C" { #include "acpi.h" #include "accommon.h" @@ -46,7 +49,149 @@ namespace Acpica { #include "ec.h" -static void init_acpica(Acpica::Reportstate *report) { +struct Acpica::Statechange +{ + Genode::Signal_handler _dispatcher; + Genode::Attached_rom_dataspace _system_state; + bool _enable_reset; + bool _enable_poweroff; + + Statechange(Genode::Entrypoint &ep, bool reset, bool poweroff) + : + _dispatcher(ep, *this, &Statechange::state_changed), + _system_state("system"), + _enable_reset(reset), _enable_poweroff(poweroff) + { + _system_state.sigh(_dispatcher); + + state_changed(); + } + + void state_changed() { + + _system_state.update(); + + if (!_system_state.is_valid()) return; + + Genode::Xml_node system(_system_state.local_addr(), + _system_state.size()); + + Genode::String<32> state; + system.attribute("state").value<32>(&state); + + if (_enable_poweroff && state == "poweroff") { + ACPI_STATUS res0 = AcpiEnterSleepStatePrep(5); + ACPI_STATUS res1 = AcpiEnterSleepState(5); + Genode::error("system poweroff failed - " + "res=", Genode::Hex(res0), ",", Genode::Hex(res1)); + return; + } + + if (_enable_reset && state == "reset") { + ACPI_STATUS res = AE_OK; + try { + res = AcpiReset(); + } catch (...) { } + + Genode::uint64_t const space_addr = AcpiGbl_FADT.ResetRegister.Address; + Genode::error("system reset failed - " + "err=", res, " " + "reset=", !!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER), " " + "spaceid=", Genode::Hex(AcpiGbl_FADT.ResetRegister.SpaceId), " " + "addr=", Genode::Hex(space_addr)); + } + } +}; + +struct Acpica::Main +{ + Genode::Env &env; + Genode::Heap heap { env.ram(), env.rm() }; + + Genode::Attached_rom_dataspace config { env, "config" }; + + Genode::Signal_handler sci_irq; + Genode::Lazy_volatile_object sci_conn; + + Acpica::Reportstate * report = nullptr; + + static struct Irq_handler { + UINT32 irq; + ACPI_OSD_HANDLER handler; + void *context; + } irq_handler; + + void init_acpica(); + + Main(Genode::Env &env) + : + env(env), + sci_irq(env.ep(), *this, &Main::acpi_irq) + { + bool const enable_reset = config.xml().attribute_value("reset", false); + bool const enable_poweroff = config.xml().attribute_value("poweroff", false); + bool const enable_report = config.xml().attribute_value("report", false); + bool const enable_ready = config.xml().attribute_value("acpi_ready", false); + + if (enable_report) + report = new (heap) Acpica::Reportstate(); + + init_acpica(); + + if (enable_report) + report->enable(); + + if (enable_reset || enable_poweroff) + new (heap) Acpica::Statechange(env.ep(), enable_reset, + enable_poweroff); + + /* setup IRQ */ + if (!irq_handler.handler) { + Genode::warning("no IRQ handling available"); + return; + } + + sci_conn.construct(irq_handler.irq); + + Genode::log("SCI IRQ: ", irq_handler.irq); + + sci_conn->sigh(sci_irq); + sci_conn->ack_irq(); + + if (!enable_ready) + return; + + /* we are ready - signal it via changing system state */ + static Genode::Reporter _system_rom { "system", "acpi_ready" }; + _system_rom.enabled(true); + Genode::Reporter::Xml_generator xml(_system_rom, [&] () { + xml.attribute("state", "acpi_ready"); + }); + } + + void acpi_irq() + { + if (!irq_handler.handler) + return; + + UINT32 res = irq_handler.handler(irq_handler.context); + + sci_conn->ack_irq(); + + AcpiOsWaitEventsComplete(); + + if (report) + report->generate_report(); + + if (res == ACPI_INTERRUPT_HANDLED) + return; + } +}; + + +void Acpica::Main::init_acpica() +{ + Acpica::init(env, heap); /* enable debugging: */ /* AcpiDbgLevel |= ACPI_LV_IO | ACPI_LV_INTERRUPTS | ACPI_LV_INIT_NAMES; */ @@ -107,7 +252,7 @@ static void init_acpica(Acpica::Reportstate *report) { } /* note: ACPI_EVENT_PMTIMER claimed by nova kernel - not usable by us */ - Fixed * acpi_fixed = new (Genode::env()->heap()) Fixed(report); + Fixed * acpi_fixed = new (heap) Fixed(report); status = AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON, Fixed::handle_power_button, @@ -144,138 +289,6 @@ static void init_acpica(Acpica::Reportstate *report) { } } -struct Acpica::Statechange -{ - Genode::Signal_handler _dispatcher; - Genode::Attached_rom_dataspace _system_state; - bool _enable_reset; - bool _enable_poweroff; - - Statechange(Genode::Entrypoint &ep, bool reset, bool poweroff) - : - _dispatcher(ep, *this, &Statechange::state_changed), - _system_state("system"), - _enable_reset(reset), _enable_poweroff(poweroff) - { - _system_state.sigh(_dispatcher); - - state_changed(); - } - - void state_changed() { - - _system_state.update(); - - if (!_system_state.is_valid()) return; - - Genode::Xml_node system(_system_state.local_addr(), - _system_state.size()); - - Genode::String<32> state; - system.attribute("state").value<32>(&state); - - if (_enable_poweroff && state == "poweroff") { - ACPI_STATUS res0 = AcpiEnterSleepStatePrep(5); - ACPI_STATUS res1 = AcpiEnterSleepState(5); - Genode::error("system poweroff failed - " - "res=", Genode::Hex(res0), ",", Genode::Hex(res1)); - return; - } - - if (_enable_reset && state == "reset") { - ACPI_STATUS res = AE_OK; - try { - res = AcpiReset(); - } catch (...) { } - - Genode::uint64_t const space_addr = AcpiGbl_FADT.ResetRegister.Address; - Genode::error("system reset failed - " - "err=", res, " " - "reset=", !!(AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER), " " - "spaceid=", Genode::Hex(AcpiGbl_FADT.ResetRegister.SpaceId), " " - "addr=", Genode::Hex(space_addr)); - } - } -}; - -struct Acpica::Main { - - Genode::Signal_handler _sci_irq; - Genode::Lazy_volatile_object _sci_conn; - - Acpica::Reportstate * _report = nullptr; - - static struct Irq_handler { - UINT32 irq; - ACPI_OSD_HANDLER handler; - void *context; - } irq_handler; - - Main(Genode::Env &env) - : - _sci_irq(env.ep(), *this, &Main::acpi_irq) - { - bool enable_reset = Genode::config()->xml_node().attribute_value("reset", false); - bool enable_poweroff = Genode::config()->xml_node().attribute_value("poweroff", false); - bool enable_report = Genode::config()->xml_node().attribute_value("report", false); - bool enable_ready = Genode::config()->xml_node().attribute_value("acpi_ready", false); - - if (enable_report) - _report = new (Genode::env()->heap()) Acpica::Reportstate(); - - init_acpica(_report); - - if (enable_report) - _report->enable(); - - if (enable_reset || enable_poweroff) - new (Genode::env()->heap()) Acpica::Statechange(env.ep(), enable_reset, - enable_poweroff); - - /* setup IRQ */ - if (!irq_handler.handler) { - Genode::warning("no IRQ handling available"); - return; - } - - _sci_conn.construct(irq_handler.irq); - - Genode::log("SCI IRQ: ", irq_handler.irq); - - _sci_conn->sigh(_sci_irq); - _sci_conn->ack_irq(); - - if (!enable_ready) - return; - - /* we are ready - signal it via changing system state */ - const char * system_file = "system"; - - static Genode::Reporter _system_rom { "system", "acpi_ready" }; - _system_rom.enabled(true); - Genode::Reporter::Xml_generator xml(_system_rom, [&] () { - xml.attribute("state", "acpi_ready"); - }); - } - - void acpi_irq() - { - if (!irq_handler.handler) - return; - - UINT32 res = irq_handler.handler(irq_handler.context); - - _sci_conn->ack_irq(); - - AcpiOsWaitEventsComplete(); - - if (_report) - _report->generate_report(); - - if (res == ACPI_INTERRUPT_HANDLED) - return; - } -}; struct Acpica::Main::Irq_handler Acpica::Main::irq_handler; diff --git a/repos/libports/src/app/acpica/target.inc b/repos/libports/src/app/acpica/target.inc index 0abca8b5b..20668181e 100644 --- a/repos/libports/src/app/acpica/target.inc +++ b/repos/libports/src/app/acpica/target.inc @@ -1,8 +1,3 @@ REQUIRES := x86 -LIBS += base acpica config - -CC_OPT += -Wno-unused-function -Wno-unused-variable -CC_C_OPT += -DACPI_LIBRARY - -INC_DIR += $(call select_from_ports,acpica)/src/lib/acpica/source/include +LIBS += base acpica diff --git a/repos/libports/src/app/qt5/qt_avplay/avplay_policy.h b/repos/libports/src/app/qt5/qt_avplay/avplay_policy.h deleted file mode 100644 index d9f1a93d3..000000000 --- a/repos/libports/src/app/qt5/qt_avplay/avplay_policy.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * \brief Avplay policy - * \author Christian Prochaska - * \date 2012-04-05 - */ - -/* - * Copyright (C) 2012-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _AVPLAY_POLICY_H_ -#define _AVPLAY_POLICY_H_ - -/* Qt includes */ -#include -#include -#include -#include -#include - -/* Genode includes */ -#include - - -class Avplay_policy : public QObject, public Genode::Slave_policy -{ - Q_OBJECT - - private: - - Genode::Service_registry &_input_in; - Genode::Service_registry &_framebuffer_in; - - const char *_mediafile; - int _sdl_audio_volume; - QByteArray _config_byte_array; - - - const char *_config() - { - QDomDocument config_doc; - - QDomElement config_node = config_doc.createElement("config"); - config_doc.appendChild(config_node); - - QDomElement arg0_node = config_doc.createElement("arg"); - arg0_node.setAttribute("value", "avplay"); - config_node.appendChild(arg0_node); - - QDomElement arg1_node = config_doc.createElement("arg"); - arg1_node.setAttribute("value", _mediafile); - config_node.appendChild(arg1_node); - - /* - * Configure libc of avplay to direct output to LOG and to obtain - * the mediafile from ROM. - */ - QDomElement libc_node = config_doc.createElement("libc"); - libc_node.setAttribute("stdout", "/dev/log"); - libc_node.setAttribute("stderr", "/dev/log"); - QDomElement libc_vfs_node = config_doc.createElement("vfs"); - QDomElement libc_vfs_dev_node = config_doc.createElement("dir"); - libc_vfs_dev_node.setAttribute("name", "dev"); - QDomElement libc_vfs_dev_log_node = config_doc.createElement("log"); - libc_vfs_dev_node.appendChild(libc_vfs_dev_log_node); - libc_vfs_node.appendChild(libc_vfs_dev_node); - QDomElement libc_vfs_mediafile_node = config_doc.createElement("rom"); - libc_vfs_mediafile_node.setAttribute("name", "mediafile"); - libc_vfs_node.appendChild(libc_vfs_mediafile_node); - libc_node.appendChild(libc_vfs_node); - config_node.appendChild(libc_node); - - QDomElement sdl_audio_volume_node = config_doc.createElement("sdl_audio_volume"); - sdl_audio_volume_node.setAttribute("value", QString::number(_sdl_audio_volume)); - config_node.appendChild(sdl_audio_volume_node); - - _config_byte_array = config_doc.toByteArray(4); - - return _config_byte_array.constData(); - } - - protected: - - const char **_permitted_services() const - { - static const char *permitted_services[] = { - "LOG", "RM", "ROM", "Timer", "Audio_out", 0 }; - - return permitted_services; - }; - - public: - - Avplay_policy(Genode::Rpc_entrypoint &entrypoint, - Genode::Service_registry &input_in, - Genode::Service_registry &framebuffer_in, - const char *mediafile) - : Genode::Slave_policy("avplay", entrypoint, Genode::env()->ram_session()), - _input_in(input_in), - _framebuffer_in(framebuffer_in), - _mediafile(mediafile), - _sdl_audio_volume(100) - { - configure(_config()); - } - - Genode::Service *resolve_session_request(const char *service_name, - const char *args) - { - if (strcmp(service_name, "Input") == 0) - return _input_in.find(service_name); - - if (strcmp(service_name, "Framebuffer") == 0) { - Genode::Client client; - return _framebuffer_in.wait_for_service(service_name, &client, name()); - } - - return Slave_policy::resolve_session_request(service_name, args); - } - - public Q_SLOTS: - - void volume_changed(int value) - { - _sdl_audio_volume = value; - configure(_config()); - } -}; - -#endif /* _AVPLAY_POLICY_H_ */ diff --git a/repos/libports/src/app/qt5/qt_avplay/avplay_slave.h b/repos/libports/src/app/qt5/qt_avplay/avplay_slave.h new file mode 100644 index 000000000..e00388b23 --- /dev/null +++ b/repos/libports/src/app/qt5/qt_avplay/avplay_slave.h @@ -0,0 +1,175 @@ +/* + * \brief Avplay slave + * \author Christian Prochaska + * \date 2012-04-05 + */ + +/* + * Copyright (C) 2012-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _AVPLAY_SLAVE_H_ +#define _AVPLAY_SLAVE_H_ + +/* Qt includes */ +#include +#include +#include +#include +#include + +/* Genode includes */ +#include +#include + +/* local includes */ +#include "framebuffer_service_factory.h" + +typedef Genode::Local_service Input_service; + +class Avplay_slave : public QObject +{ + Q_OBJECT + + private: + + class Policy : public Genode::Slave::Policy + { + private: + + Input_service &_input_service; + Framebuffer_service_factory &_framebuffer_service_factory; + + const char *_mediafile; + int _sdl_audio_volume; + QByteArray _config_byte_array; + + + const char *_config() + { + QDomDocument config_doc; + + QDomElement config_node = config_doc.createElement("config"); + config_doc.appendChild(config_node); + + QDomElement arg0_node = config_doc.createElement("arg"); + arg0_node.setAttribute("value", "avplay"); + config_node.appendChild(arg0_node); + + QDomElement arg1_node = config_doc.createElement("arg"); + arg1_node.setAttribute("value", _mediafile); + config_node.appendChild(arg1_node); + + /* + * Configure libc of avplay to direct output to LOG and to obtain + * the mediafile from ROM. + */ + QDomElement libc_node = config_doc.createElement("libc"); + libc_node.setAttribute("stdout", "/dev/log"); + libc_node.setAttribute("stderr", "/dev/log"); + QDomElement libc_vfs_node = config_doc.createElement("vfs"); + QDomElement libc_vfs_dev_node = config_doc.createElement("dir"); + libc_vfs_dev_node.setAttribute("name", "dev"); + QDomElement libc_vfs_dev_log_node = config_doc.createElement("log"); + libc_vfs_dev_node.appendChild(libc_vfs_dev_log_node); + libc_vfs_node.appendChild(libc_vfs_dev_node); + QDomElement libc_vfs_mediafile_node = config_doc.createElement("rom"); + libc_vfs_mediafile_node.setAttribute("name", "mediafile"); + libc_vfs_node.appendChild(libc_vfs_mediafile_node); + libc_node.appendChild(libc_vfs_node); + config_node.appendChild(libc_node); + + QDomElement sdl_audio_volume_node = config_doc.createElement("sdl_audio_volume"); + sdl_audio_volume_node.setAttribute("value", QString::number(_sdl_audio_volume)); + config_node.appendChild(sdl_audio_volume_node); + + _config_byte_array = config_doc.toByteArray(4); + + return _config_byte_array.constData(); + } + + static Genode::size_t _quota() { return 32*1024*1024; } + static Name _name() { return "avplay"; } + + protected: + + const char **_permitted_services() const override + { + static const char *permitted_services[] = { + "CPU", "LOG", "PD", "RAM", "RM", "ROM", "Timer", "Audio_out", 0 }; + + return permitted_services; + }; + + public: + + Policy(Genode::Rpc_entrypoint &entrypoint, + Genode::Region_map &rm, + Genode::Ram_session_capability ram, + Input_service &input_service, + Framebuffer_service_factory &framebuffer_service_factory, + char const *mediafile) + : Genode::Slave::Policy(_name(), _name(), entrypoint, rm, ram, + _quota()), + _input_service(input_service), + _framebuffer_service_factory(framebuffer_service_factory), + _mediafile(mediafile), + _sdl_audio_volume(100) + { + configure(_config()); + } + + Genode::Service &resolve_session_request(Genode::Service::Name const &service_name, + Genode::Session_state::Args const &args) override + { + if (service_name == "Input") + return _input_service; + + if (service_name == "Framebuffer") + return _framebuffer_service_factory.create(args); + + return Genode::Slave::Policy::resolve_session_request(service_name, args); + } + + void volume_changed(int value) + { + _sdl_audio_volume = value; + configure(_config()); + } + + }; + + Genode::size_t const _ep_stack_size = 4*1024*sizeof(Genode::addr_t); + Genode::Rpc_entrypoint _ep; + Policy _policy; + Genode::Child _child; + + public: + + /** + * Constructor + */ + Avplay_slave(Genode::Pd_session &pd, + Genode::Region_map &rm, + Genode::Ram_session_capability ram, + Input_service &input_service, + Framebuffer_service_factory &framebuffer_service_factory, + char const *mediafile) + : + _ep(&pd, _ep_stack_size, "avplay_ep"), + _policy(_ep, rm, ram, input_service, framebuffer_service_factory, mediafile), + _child(rm, _ep, _policy) + { } + + public Q_SLOTS: + + void volume_changed(int value) + { + _policy.volume_changed(value); + } +}; + +#endif /* _AVPLAY_SLAVE_H_ */ diff --git a/repos/libports/src/app/qt5/qt_avplay/control_bar.cpp b/repos/libports/src/app/qt5/qt_avplay/control_bar.cpp index d40eff97c..ce6ddcea8 100644 --- a/repos/libports/src/app/qt5/qt_avplay/control_bar.cpp +++ b/repos/libports/src/app/qt5/qt_avplay/control_bar.cpp @@ -24,15 +24,15 @@ void Control_bar::_rewind() { /* mouse click at horizontal position 0 */ - _event_queue.add(Input::Event(Input::Event::PRESS, Input::BTN_LEFT, 0, 0, 0, 0)); - _event_queue.add(Input::Event(Input::Event::RELEASE, Input::BTN_LEFT, 0, 0, 0, 0)); + _input.submit(Input::Event(Input::Event::PRESS, Input::BTN_LEFT, 0, 0, 0, 0)); + _input.submit(Input::Event(Input::Event::RELEASE, Input::BTN_LEFT, 0, 0, 0, 0)); } void Control_bar::_pause_resume() { - _event_queue.add(Input::Event(Input::Event::PRESS, Input::KEY_SPACE, 0, 0, 0, 0)); - _event_queue.add(Input::Event(Input::Event::RELEASE, Input::KEY_SPACE, 0, 0, 0, 0)); + _input.submit(Input::Event(Input::Event::PRESS, Input::KEY_SPACE, 0, 0, 0, 0)); + _input.submit(Input::Event(Input::Event::RELEASE, Input::KEY_SPACE, 0, 0, 0, 0)); _playing = !_playing; if (_playing) @@ -51,9 +51,9 @@ void Control_bar::_stop() } -Control_bar::Control_bar(Input::Event_queue &event_queue) +Control_bar::Control_bar(Input::Session_component &input) : - _event_queue(event_queue), _playing(true) + _input(input), _playing(true) { update_style_id(_play_pause_button, "play"); diff --git a/repos/libports/src/app/qt5/qt_avplay/control_bar.h b/repos/libports/src/app/qt5/qt_avplay/control_bar.h index 7a88ddf4f..f21627d65 100644 --- a/repos/libports/src/app/qt5/qt_avplay/control_bar.h +++ b/repos/libports/src/app/qt5/qt_avplay/control_bar.h @@ -23,7 +23,7 @@ #include /* Genode includes */ -#include +#include struct Play_pause_button : QPushButton { Q_OBJECT }; struct Stop_button : QPushButton { Q_OBJECT }; @@ -36,7 +36,7 @@ class Control_bar : public Compound_widget private: - Input::Event_queue &_event_queue; + Input::Session_component &_input; QMember _play_pause_button; QMember _stop_button; @@ -54,7 +54,7 @@ class Control_bar : public Compound_widget public: - Control_bar(Input::Event_queue &event_queue); + Control_bar(Input::Session_component &input); Q_SIGNALS: diff --git a/repos/libports/src/app/qt5/qt_avplay/filter_framebuffer_policy.h b/repos/libports/src/app/qt5/qt_avplay/filter_framebuffer_policy.h deleted file mode 100644 index e48e1e4e1..000000000 --- a/repos/libports/src/app/qt5/qt_avplay/filter_framebuffer_policy.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * \brief Filter framebuffer policy - * \author Christian Prochaska - * \date 2012-04-11 - */ - -/* - * Copyright (C) 2012-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _FILTER_FRAMEBUFFER_POLICY_H_ -#define _FILTER_FRAMEBUFFER_POLICY_H_ - -/* Genode includes */ -#include -#include - - -class Filter_framebuffer_policy : public Genode::Slave_policy -{ - private: - - Genode::Service_registry &_framebuffer_in; - Genode::Service_registry &_framebuffer_out; - - protected: - - const char **_permitted_services() const - { - static const char *permitted_services[] = { - "LOG", "RM", "ROM", "Timer", 0 }; - - return permitted_services; - }; - - public: - - Filter_framebuffer_policy(const char *name, - Genode::Rpc_entrypoint &entrypoint, - Genode::Service_registry &framebuffer_in, - Genode::Service_registry &framebuffer_out) - : Genode::Slave_policy(name, entrypoint, Genode::env()->ram_session()), - _framebuffer_in(framebuffer_in), - _framebuffer_out(framebuffer_out) { } - - Genode::Service *resolve_session_request(const char *service_name, - const char *args) - { - if (strcmp(service_name, "Framebuffer") == 0) { - Genode::Client client; - return _framebuffer_in.wait_for_service(service_name, &client, name()); - } - - return Slave_policy::resolve_session_request(service_name, args); - } - - bool announce_service(const char *name, - Genode::Root_capability root, - Genode::Allocator *alloc, - Genode::Server *server) - { - if (strcmp(name, "Framebuffer") == 0) { - _framebuffer_out.insert(new (alloc) Genode::Child_service(name, root, server)); - return true; - } - - return Slave_policy::announce_service(name, root, alloc, server); - } - - -}; - -#endif /* _FILTER_FRAMEBUFFER_POLICY_H_ */ diff --git a/repos/libports/src/app/qt5/qt_avplay/filter_framebuffer_slave.h b/repos/libports/src/app/qt5/qt_avplay/filter_framebuffer_slave.h new file mode 100644 index 000000000..584acfe2e --- /dev/null +++ b/repos/libports/src/app/qt5/qt_avplay/filter_framebuffer_slave.h @@ -0,0 +1,91 @@ +/* + * \brief Filter framebuffer policy + * \author Christian Prochaska + * \date 2012-04-11 + */ + +/* + * Copyright (C) 2012-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _FILTER_FRAMEBUFFER_SLAVE_H_ +#define _FILTER_FRAMEBUFFER_SLAVE_H_ + +/* Genode includes */ +#include +#include + +/* local includes */ +#include "framebuffer_service_factory.h" + + +class Filter_framebuffer_slave +{ + private: + + class Policy : public Genode::Slave::Policy + { + private: + + Framebuffer_service_factory &_framebuffer_service_factory; + + protected: + + const char **_permitted_services() const + { + static const char *permitted_services[] = { + "CPU", "LOG", "PD", "RAM", "RM", "ROM", "Timer", 0 }; + + return permitted_services; + }; + + public: + + Policy(Genode::Rpc_entrypoint &entrypoint, + Genode::Region_map &rm, + Genode::Ram_session_capability ram, + Name const &name, + size_t quota, + Framebuffer_service_factory &framebuffer_service_factory) + : Genode::Slave::Policy(name, name, entrypoint, rm, ram, quota), + _framebuffer_service_factory(framebuffer_service_factory) { } + + Genode::Service &resolve_session_request(Genode::Service::Name const &service_name, + Genode::Session_state::Args const &args) override + { + if (service_name == "Framebuffer") + return _framebuffer_service_factory.create(args); + + return Genode::Slave::Policy::resolve_session_request(service_name, args); + } + }; + + Genode::size_t const _ep_stack_size = 2*1024*sizeof(Genode::addr_t); + Genode::Rpc_entrypoint _ep; + Policy _policy; + Genode::Child _child; + + public: + + /** + * Constructor + */ + Filter_framebuffer_slave(Genode::Pd_session &pd, + Genode::Region_map &rm, + Genode::Ram_session_capability ram, + Genode::Slave::Policy::Name const &name, + size_t quota, + Framebuffer_service_factory &framebuffer_service_factory) + : + _ep(&pd, _ep_stack_size, "filter_framebuffer_ep"), + _policy(_ep, rm, ram, name, quota, framebuffer_service_factory), + _child(rm, _ep, _policy) + { } + + Genode::Slave::Policy &policy() { return _policy; } +}; + +#endif /* _FILTER_FRAMEBUFFER_SLAVE_H_ */ diff --git a/repos/libports/src/app/qt5/qt_avplay/framebuffer_root.h b/repos/libports/src/app/qt5/qt_avplay/framebuffer_root.h deleted file mode 100644 index ad46f893a..000000000 --- a/repos/libports/src/app/qt5/qt_avplay/framebuffer_root.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * \brief Framebuffer root - * \author Christian Prochaska - * \date 2012-04-02 - */ - -/* - * Copyright (C) 2012-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - - -#ifndef _FRAMEBUFFER_ROOT_H_ -#define _FRAMEBUFFER_ROOT_H_ - -/* Genode includes */ -#include - -#include "framebuffer_session_component.h" - -namespace Framebuffer { - - /** - * Shortcut for single-client root component - */ - typedef Genode::Root_component Root_component; - - - class Root : public Root_component - { - private: - - QNitpickerViewWidget &_nitpicker_view_widget; - int _max_width; - int _max_height; - - protected: - - Session_component *_create_session(const char *args) - { - return new (md_alloc()) - Session_component(args, _nitpicker_view_widget, - _max_width, _max_height); - } - - public: - - Root(Genode::Rpc_entrypoint *session_ep, - Genode::Allocator *md_alloc, - QNitpickerViewWidget &nitpicker_view_widget, - int max_width = 0, - int max_height = 0) - : Root_component(session_ep, md_alloc), - _nitpicker_view_widget(nitpicker_view_widget), - _max_width(max_width), - _max_height(max_height) { } - - }; - -} - -#endif /* _FRAMEBUFFER_ROOT_H_ */ diff --git a/repos/libports/src/app/qt5/qt_avplay/framebuffer_service_factory.h b/repos/libports/src/app/qt5/qt_avplay/framebuffer_service_factory.h new file mode 100644 index 000000000..8e65366c0 --- /dev/null +++ b/repos/libports/src/app/qt5/qt_avplay/framebuffer_service_factory.h @@ -0,0 +1,141 @@ +/* + * \brief Framebuffer service factory + * \author Christian Prochaska + * \date 2016-11-24 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _FRAMEBUFFER_SERVICE_FACTORY_H_ +#define _FRAMEBUFFER_SERVICE_FACTORY_H_ + +/* Genode includes */ +#include +#include +#include +#include +#include + +/* Qt includes */ +#include +#include + + +struct Framebuffer_service_factory +{ + virtual Genode::Service &create(Genode::Session_state::Args const &args) = 0; + + typedef Genode::Single_session_service Session_service; +}; + + +class Nitpicker_framebuffer_service_factory : public Framebuffer_service_factory +{ + private: + + Nitpicker::Connection _nitpicker; + + Session_service _service; + + QNitpickerViewWidget &_nitpicker_view_widget; + int _max_width; + int _max_height; + + int _limited_size(int requested_size, int max_size) + { + if (requested_size == 0) + return max_size; + else + return (max_size > 0) ? Genode::min(requested_size, max_size) : requested_size; + } + + static inline long _session_arg(Genode::Session_state::Args const &args, const char *key) + { + return Genode::Arg_string::find_arg(args.string(), key).long_value(0); + } + + public: + + Nitpicker_framebuffer_service_factory(Genode::Env &env, + QNitpickerViewWidget &nitpicker_view_widget, + int max_width = 0, + int max_height = 0) + : _nitpicker(env), + _service(_nitpicker.framebuffer_session()), + _nitpicker_view_widget(nitpicker_view_widget), + _max_width(max_width), _max_height(max_height) + { } + + Genode::Service &create(Genode::Session_state::Args const &args) + { + Framebuffer::Mode const + mode(_limited_size(_session_arg(args, "fb_width"), _max_width), + _limited_size(_session_arg(args, "fb_height"), _max_height), + _nitpicker.mode().format()); + _nitpicker.buffer(mode, false); + + QNitpickerPlatformWindow *platform_window = + dynamic_cast(_nitpicker_view_widget + .window()->windowHandle()->handle()); + + Nitpicker::Session::View_handle parent_view_handle = + _nitpicker.view_handle(platform_window->view_cap()); + + Nitpicker::Session::View_handle nitpicker_view_handle = + _nitpicker.create_view(parent_view_handle); + + _nitpicker.release_view_handle(parent_view_handle); + + Framebuffer::Session_client framebuffer(_nitpicker.framebuffer_session()); + + Framebuffer::Mode framebuffer_mode = framebuffer.mode(); + _nitpicker_view_widget.setNitpickerView(&_nitpicker, + nitpicker_view_handle, + 0, 0, + framebuffer_mode.width(), + framebuffer_mode.height()); + return _service.service(); + } +}; + + +class Filter_framebuffer_service_factory : public Framebuffer_service_factory +{ + private: + + typedef Genode::Slave::Connection Framebuffer_connection; + + Genode::Slave::Policy &_policy; + + Framebuffer_connection *_slave_connection { nullptr }; + Session_service *_service { nullptr }; + + public: + + Filter_framebuffer_service_factory(Genode::Slave::Policy &policy) + : _policy(policy) + { } + + ~Filter_framebuffer_service_factory() + { + delete _service; + delete _slave_connection; + } + + Genode::Service &create(Genode::Session_state::Args const &args) + { + _slave_connection = new Framebuffer_connection(_policy, args); + + _service = new Session_service(*_slave_connection); + + return _service->service(); + } +}; + + +#endif /* _FRAMEBUFFER_SERVICE_FACTORY_H_ */ diff --git a/repos/libports/src/app/qt5/qt_avplay/framebuffer_session_component.cc b/repos/libports/src/app/qt5/qt_avplay/framebuffer_session_component.cc deleted file mode 100644 index 1f4eb4861..000000000 --- a/repos/libports/src/app/qt5/qt_avplay/framebuffer_session_component.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * \brief Framebuffer session component - * \author Christian Prochaska - * \date 2012-04-02 - */ - -/* - * Copyright (C) 2012-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* Genode includes */ -#include -#include -#include -#include - -#include "framebuffer_session_component.h" -#include - -namespace Framebuffer { - - - int Session_component::_limited_size(int requested_size, int max_size) - { - if (requested_size == 0) - return max_size; - else - return (max_size > 0) ? Genode::min(requested_size, max_size) : requested_size; - } - - - static inline long session_arg(const char *arg, const char *key) - { - return Genode::Arg_string::find_arg(arg, key).long_value(0); - } - - - Session_component::Session_component(const char *args, - QNitpickerViewWidget &nitpicker_view_widget, - int max_width, - int max_height) - : - _framebuffer(_nitpicker.framebuffer_session()) - { - Framebuffer::Mode const - mode(_limited_size(session_arg(args, "fb_width"), max_width), - _limited_size(session_arg(args, "fb_height"), max_height), - _nitpicker.mode().format()); - _nitpicker.buffer(mode, false); - - QNitpickerPlatformWindow *platform_window = - dynamic_cast(nitpicker_view_widget - .window()->windowHandle()->handle()); - - Nitpicker::Session::View_handle parent_view_handle = - _nitpicker.view_handle(platform_window->view_cap()); - - Nitpicker::Session::View_handle nitpicker_view_handle = - _nitpicker.create_view(parent_view_handle); - - _nitpicker.release_view_handle(parent_view_handle); - - Mode _mode = _framebuffer.mode(); - nitpicker_view_widget.setNitpickerView(&_nitpicker, - nitpicker_view_handle, - 0, 0, - _mode.width(), - _mode.height()); - } - - - Genode::Dataspace_capability Session_component::dataspace() - { - return _framebuffer.dataspace(); - } - - - Mode Session_component::mode() const - { - return _framebuffer.mode(); - } - - - void Session_component::mode_sigh(Genode::Signal_context_capability sigh_cap) - { - _framebuffer.mode_sigh(sigh_cap); - } - - - void Session_component::sync_sigh(Genode::Signal_context_capability sigh_cap) - { - _framebuffer.sync_sigh(sigh_cap); - } - - void Session_component::refresh(int x, int y, int w, int h) - { - _framebuffer.refresh(x, y, w, h); - } -} diff --git a/repos/libports/src/app/qt5/qt_avplay/framebuffer_session_component.h b/repos/libports/src/app/qt5/qt_avplay/framebuffer_session_component.h deleted file mode 100644 index 4bd630c59..000000000 --- a/repos/libports/src/app/qt5/qt_avplay/framebuffer_session_component.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * \brief Framebuffer session component - * \author Christian Prochaska - * \date 2012-04-02 - */ - -/* - * Copyright (C) 2012-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - - -#ifndef _FRAMEBUFFER_SESSION_COMPONENT_H_ -#define _FRAMEBUFFER_SESSION_COMPONENT_H_ - -/* Genode includes */ -#include -#include -#include - -/* Qt includes */ -#include - - -namespace Framebuffer { - - class Session_component : public Genode::Rpc_object - { - private: - - Nitpicker::Connection _nitpicker; - Session_client _framebuffer; - - int _limited_size(int requested_size, int max_size); - - public: - - /** - * Constructor - */ - Session_component(const char *args, - QNitpickerViewWidget &nitpicker_view_widget, - int max_width = 0, - int max_height = 0); - - Genode::Dataspace_capability dataspace() override; - Mode mode() const override; - void mode_sigh(Genode::Signal_context_capability) override; - void sync_sigh(Genode::Signal_context_capability) override; - void refresh(int, int, int, int) override; - }; - -} - -#endif /* _FRAMEBUFFER_SESSION_COMPONENT_H_ */ diff --git a/repos/libports/src/app/qt5/qt_avplay/main.cpp b/repos/libports/src/app/qt5/qt_avplay/main.cpp index 997b333af..98ccb808c 100644 --- a/repos/libports/src/app/qt5/qt_avplay/main.cpp +++ b/repos/libports/src/app/qt5/qt_avplay/main.cpp @@ -18,7 +18,7 @@ #include "main_window.h" /* Genode includes */ -#include +#include #include @@ -35,15 +35,18 @@ static inline void load_stylesheet() } -int main(int argc, char *argv[]) +extern int genode_argc; +extern char **genode_argv; + +void Component::construct(Genode::Env &env) { - QApplication app(argc, argv); + QApplication app(genode_argc, genode_argv); load_stylesheet(); - QMember main_window; + QMember main_window(env); main_window->show(); - return app.exec(); + app.exec(); } diff --git a/repos/libports/src/app/qt5/qt_avplay/main_window.cpp b/repos/libports/src/app/qt5/qt_avplay/main_window.cpp index fe24461ab..40b253e67 100644 --- a/repos/libports/src/app/qt5/qt_avplay/main_window.cpp +++ b/repos/libports/src/app/qt5/qt_avplay/main_window.cpp @@ -12,9 +12,7 @@ */ /* qt_avplay includes */ -#include "avplay_policy.h" -#include "filter_framebuffer_policy.h" -#include "framebuffer_root.h" +#include "filter_framebuffer_slave.h" #include "main_window.h" @@ -24,22 +22,19 @@ using namespace Genode; struct Framebuffer_filter { enum { MAX_FILTER_NAME_SIZE = 32 }; - char name[MAX_FILTER_NAME_SIZE]; - Genode::Number_of_bytes ram_quota; - - Service_registry *framebuffer_out_registry; - Rpc_entrypoint *ep; - Filter_framebuffer_policy *policy; - Slave *slave; + char name[MAX_FILTER_NAME_SIZE]; + Genode::Number_of_bytes ram_quota; + Filter_framebuffer_slave *slave; }; -Main_window::Main_window() +Main_window::Main_window(Genode::Env &env) : - _control_bar(_input_session.event_queue()) + _env(env), + _control_bar(_input_session_component) { - _input_registry.insert(&_input_service); - _ep.manage(&_input_root); + _input_session_component.event_queue().enabled(true); + _ep.manage(&_input_session_component); /* find out which filtering framebuffer services to start and sort them in reverse order */ @@ -55,49 +50,33 @@ Main_window::Main_window() } } catch (Xml_node::Nonexistent_sub_node) { } + Framebuffer_service_factory *framebuffer_service_factory = + &_nitpicker_framebuffer_service_factory; + /* start the filtering framebuffer services */ - Service_registry *framebuffer_in_registry = &_nitpicker_framebuffer_registry; - Q_FOREACH(Framebuffer_filter *framebuffer_filter, framebuffer_filters) { - framebuffer_filter->framebuffer_out_registry = new Service_registry; - framebuffer_filter->ep = new Rpc_entrypoint(&_cap, STACK_SIZE, "filter_fb_ep"); - framebuffer_filter->policy = new Filter_framebuffer_policy(framebuffer_filter->name, - *framebuffer_filter->ep, - *framebuffer_in_registry, - *framebuffer_filter->framebuffer_out_registry); - framebuffer_filter->slave = new Slave(*framebuffer_filter->ep, - *framebuffer_filter->policy, - framebuffer_filter->ram_quota); - framebuffer_in_registry = framebuffer_filter->framebuffer_out_registry; + framebuffer_filter->slave = new Filter_framebuffer_slave(_env.pd(), _env.rm(), + _env.ram_session_cap(), + framebuffer_filter->name, + framebuffer_filter->ram_quota, + *framebuffer_service_factory); + framebuffer_service_factory = + new Filter_framebuffer_service_factory(framebuffer_filter->slave->policy()); } - Rpc_entrypoint *local_framebuffer_ep = framebuffer_filters.isEmpty() ? - &_ep : - framebuffer_filters.at(0)->ep; - - static Framebuffer::Root framebuffer_root(local_framebuffer_ep, env()->heap(), *_avplay_widget, 640, 480); - static Local_service framebuffer_service(Framebuffer::Session::service_name(), &framebuffer_root); - _nitpicker_framebuffer_registry.insert(&framebuffer_service); - - /* obtain dynamic linker */ - - Dataspace_capability ldso_ds; - try { - static Rom_connection rom("ld.lib.so"); - ldso_ds = rom.dataspace(); - } catch (...) { } - - /* start avplay */ - - static Avplay_policy avplay_policy(_ep, _input_registry, *framebuffer_in_registry, _mediafile_name.buf); - static Genode::Slave avplay_slave(_ep, avplay_policy, 32*1024*1024, - env()->ram_session_cap(), ldso_ds); - /* add widgets to layout */ _layout->addWidget(_avplay_widget); _layout->addWidget(_control_bar); - connect(_control_bar, SIGNAL(volume_changed(int)), &avplay_policy, SLOT(volume_changed(int))); + /* start avplay */ + + Avplay_slave *avplay_slave = new Avplay_slave(_env.pd(), _env.rm(), + _env.ram_session_cap(), + _input_service, + *framebuffer_service_factory, + _mediafile_name.buf); + + connect(_control_bar, SIGNAL(volume_changed(int)), avplay_slave, SLOT(volume_changed(int))); } diff --git a/repos/libports/src/app/qt5/qt_avplay/main_window.h b/repos/libports/src/app/qt5/qt_avplay/main_window.h index bc256fc2e..2502eaacc 100644 --- a/repos/libports/src/app/qt5/qt_avplay/main_window.h +++ b/repos/libports/src/app/qt5/qt_avplay/main_window.h @@ -31,8 +31,9 @@ #include /* local includes */ +#include "avplay_slave.h" #include "control_bar.h" - +#include "framebuffer_service_factory.h" class Main_window : public Compound_widget { @@ -56,25 +57,29 @@ class Main_window : public Compound_widget Genode::warning("no config node found, using \"mediafile\""); } } - } _mediafile_name; + }; - enum { STACK_SIZE = 2*sizeof(Genode::addr_t)*1024 }; - Genode::Cap_connection _cap; - Genode::Rpc_entrypoint _ep { &_cap, STACK_SIZE, "avplay_ep" }; - Genode::Service_registry _input_registry; - Genode::Service_registry _nitpicker_framebuffer_registry; + Genode::Env &_env; - Input::Session_component _input_session; - Input::Root_component _input_root { _ep, _input_session }; + Mediafile_name _mediafile_name; - Genode::Local_service _input_service { Input::Session::service_name(), &_input_root }; + QMember _avplay_widget; + QMember _control_bar; - QMember _avplay_widget; - QMember _control_bar; + Genode::size_t const _ep_stack_size { 2*sizeof(Genode::addr_t)*1024 }; + Genode::Rpc_entrypoint _ep { &_env.pd(), _ep_stack_size, "avplay_ep" }; + + Nitpicker_framebuffer_service_factory _nitpicker_framebuffer_service_factory { _env, + *_avplay_widget, + 640, 480 }; + + Input::Session_component _input_session_component { _env, _env.ram() }; + Input_service::Single_session_factory _input_factory { _input_session_component }; + Input_service _input_service { _input_factory }; public: - Main_window(); + Main_window(Genode::Env &env); }; #endif /* _MAIN_WINDOW_H_ */ diff --git a/repos/libports/src/app/qt5/qt_avplay/qt_avplay.pro b/repos/libports/src/app/qt5/qt_avplay/qt_avplay.pro index 5c2c7d9d1..36f04b436 100644 --- a/repos/libports/src/app/qt5/qt_avplay/qt_avplay.pro +++ b/repos/libports/src/app/qt5/qt_avplay/qt_avplay.pro @@ -1,11 +1,10 @@ TEMPLATE = app TARGET = qt_avplay QT = core gui xml -HEADERS = avplay_policy.h \ +HEADERS = avplay_slave.h \ control_bar.h \ main_window.h SOURCES = control_bar.cpp \ - framebuffer_session_component.cc \ main.cpp \ main_window.cpp RESOURCES = style.qrc diff --git a/repos/libports/src/app/qt5/qt_launchpad/child_entry.cpp b/repos/libports/src/app/qt5/qt_launchpad/child_entry.cpp index 637e1352c..abf45ba99 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/child_entry.cpp +++ b/repos/libports/src/app/qt5/qt_launchpad/child_entry.cpp @@ -6,14 +6,15 @@ #include "child_entry.h" -Child_entry::Child_entry(const char *name, int quota_kb, int max_quota_kb, - Launchpad *launchpad, Launchpad_child *launchpad_child, +Child_entry::Child_entry(Launchpad_child::Name const &name, int quota_kb, + int max_quota_kb, Launchpad &launchpad, + Launchpad_child &launchpad_child, QWidget *parent) : QWidget(parent), _launchpad(launchpad), _launchpad_child(launchpad_child) { ui.setupUi(this); - ui.nameLabel->setText(name); + ui.nameLabel->setText(name.string()); ui.quotaBar->setMaximum(max_quota_kb); ui.quotaBar->setValue(quota_kb); } @@ -21,5 +22,5 @@ Child_entry::Child_entry(const char *name, int quota_kb, int max_quota_kb, void Child_entry::on_exitButton_clicked() { - _launchpad->exit_child(_launchpad_child); + _launchpad.exit_child(_launchpad_child); } diff --git a/repos/libports/src/app/qt5/qt_launchpad/child_entry.h b/repos/libports/src/app/qt5/qt_launchpad/child_entry.h index 1b046e971..df6ede98d 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/child_entry.h +++ b/repos/libports/src/app/qt5/qt_launchpad/child_entry.h @@ -28,8 +28,8 @@ class Child_entry : public QWidget Ui::Child_entryClass ui; - Launchpad *_launchpad; - Launchpad_child *_launchpad_child; + Launchpad &_launchpad; + Launchpad_child &_launchpad_child; private slots: @@ -37,8 +37,9 @@ class Child_entry : public QWidget public: - Child_entry(const char *name, int quota_kb, int max_quota_kb, - Launchpad *launchpad, Launchpad_child *launchpad_child, + Child_entry(Launchpad_child::Name const &name, int quota_kb, + int max_quota_kb, Launchpad &launchpad, + Launchpad_child &launchpad_child, QWidget *parent = 0); }; diff --git a/repos/libports/src/app/qt5/qt_launchpad/launch_entry.cpp b/repos/libports/src/app/qt5/qt_launchpad/launch_entry.cpp index a044b1a24..fc4ac2467 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/launch_entry.cpp +++ b/repos/libports/src/app/qt5/qt_launchpad/launch_entry.cpp @@ -6,19 +6,20 @@ #include "launch_entry.h" -Launch_entry::Launch_entry(const char *filename, unsigned long default_quota, +Launch_entry::Launch_entry(Launchpad_child::Name const &prg_name, + unsigned long default_quota, unsigned long max_quota, - Genode::Dataspace_capability config_ds, Launchpad *launchpad, + Genode::Dataspace_capability config_ds, QWidget *parent) : QWidget(parent), - _filename(filename), - _config_ds(config_ds), - _launchpad(launchpad) + _prg_name(prg_name), + _launchpad(launchpad), + _config_ds(config_ds) { ui.setupUi(this); - ui.launchButton->setText(filename); + ui.launchButton->setText(prg_name.string()); ui.quotaDial->setMaximum(max_quota); ui.quotaDial->setSingleStep(max_quota / 100); @@ -28,7 +29,7 @@ Launch_entry::Launch_entry(const char *filename, unsigned long default_quota, void Launch_entry::on_launchButton_clicked() { - _launchpad->start_child(_filename, + _launchpad->start_child(_prg_name, 1024 * ui.quotaDial->value(), _config_ds); } diff --git a/repos/libports/src/app/qt5/qt_launchpad/launch_entry.h b/repos/libports/src/app/qt5/qt_launchpad/launch_entry.h index 784a05255..8b410f7d0 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/launch_entry.h +++ b/repos/libports/src/app/qt5/qt_launchpad/launch_entry.h @@ -28,9 +28,9 @@ class Launch_entry : public QWidget Ui::Launch_entryClass ui; - const char *_filename; - Genode::Dataspace_capability _config_ds; - Launchpad *_launchpad; + Launchpad_child::Name const &_prg_name; + Launchpad *_launchpad; + Genode::Dataspace_capability _config_ds; private slots: @@ -38,11 +38,11 @@ class Launch_entry : public QWidget public: - Launch_entry(const char *filename, + Launch_entry(Launchpad_child::Name const &prg_name, unsigned long default_quota, unsigned long max_quota, - Genode::Dataspace_capability config_ds, Launchpad *launchpad, + Genode::Dataspace_capability config_ds, QWidget *parent = 0); }; diff --git a/repos/libports/src/app/qt5/qt_launchpad/main.cpp b/repos/libports/src/app/qt5/qt_launchpad/main.cpp index e1b204a61..199afc36b 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/main.cpp +++ b/repos/libports/src/app/qt5/qt_launchpad/main.cpp @@ -12,14 +12,57 @@ #include /* Genode includes */ +#include #include -#include -int main(int argc, char *argv[]) +extern int genode_argc; +extern char **genode_argv; + +namespace Qt_launchpad_namespace { + struct Local_env; + using namespace Genode; +} + +struct Qt_launchpad_namespace::Local_env : Genode::Env { - static QApplication a(argc, argv); + Genode::Env &genode_env; - static Qt_launchpad launchpad(Genode::env()->ram_session()->quota()); + Genode::Entrypoint local_ep { genode_env, + 2*1024*sizeof(addr_t), + "qt_launchpad_ep" }; + + Local_env(Env &genode_env) : genode_env(genode_env) { } + + Parent &parent() { return genode_env.parent(); } + Ram_session &ram() { return genode_env.ram(); } + Cpu_session &cpu() { return genode_env.cpu(); } + Region_map &rm() { return genode_env.rm(); } + Pd_session &pd() { return genode_env.pd(); } + Entrypoint &ep() { return local_ep; } + Ram_session_capability ram_session_cap() { return genode_env.ram_session_cap(); } + Cpu_session_capability cpu_session_cap() { return genode_env.cpu_session_cap(); } + Pd_session_capability pd_session_cap() { return genode_env.pd_session_cap(); } + Id_space &id_space() { return genode_env.id_space(); } + + Session_capability session(Parent::Service_name const &service_name, + Parent::Client::Id id, + Parent::Session_args const &session_args, + Affinity const &affinity) + { return genode_env.session(service_name, id, session_args, affinity); } + + void upgrade(Parent::Client::Id id, Parent::Upgrade_args const &args) + { return genode_env.upgrade(id, args); } + + void close(Parent::Client::Id id) { return genode_env.close(id); } +}; + +void Component::construct(Genode::Env &env) +{ + static Qt_launchpad_namespace::Local_env local_env(env); + + static QApplication a(genode_argc, genode_argv); + + static Qt_launchpad launchpad(local_env, env.ram().avail()); try { launchpad.process_config(); @@ -30,7 +73,5 @@ int main(int argc, char *argv[]) a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit())); - int const result = a.exec(); - - return result; + a.exec(); } diff --git a/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.cpp b/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.cpp index 580250e54..ef0f5e7cb 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.cpp +++ b/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.cpp @@ -11,8 +11,9 @@ #include "launch_entry.h" #include "child_entry.h" -Qt_launchpad::Qt_launchpad(unsigned long initial_quota, QWidget *parent) -: QMainWindow(parent), Launchpad(initial_quota) +Qt_launchpad::Qt_launchpad(Genode::Env &env, unsigned long initial_quota, + QWidget *parent) +: QMainWindow(parent), Launchpad(env, initial_quota) { setupUi(this); @@ -72,40 +73,40 @@ void Qt_launchpad::quota(unsigned long quota) } -void Qt_launchpad::add_launcher(const char *filename, +void Qt_launchpad::add_launcher(Launchpad_child::Name const &binary_name, unsigned long default_quota, Genode::Dataspace_capability config_ds) { - Launch_entry *launch_entry = new Launch_entry(filename, + Launch_entry *launch_entry = new Launch_entry(binary_name, default_quota / 1024, initial_quota() / 1024, - config_ds, - this); + this, + config_ds); launcherDockWidgetContents->layout()->addWidget(launch_entry); launch_entry->show(); launcherDockWidgetContents->adjustSize(); } -void Qt_launchpad::add_child(const char *unique_name, +void Qt_launchpad::add_child(Launchpad_child::Name const &name, unsigned long quota, - Launchpad_child *launchpad_child, - Genode::Allocator *alloc) + Launchpad_child &launchpad_child, + Genode::Allocator &alloc) { - Child_entry *child_entry = new Child_entry(unique_name, quota / 1024, + Child_entry *child_entry = new Child_entry(name, quota / 1024, initial_quota() / 1024, - this, launchpad_child); - child_entry->setObjectName(QString(unique_name) + "_child_entry"); + *this, launchpad_child); + child_entry->setObjectName(QString(name.string()) + "_child_entry"); childrenDockWidgetContents->layout()->addWidget(child_entry); child_entry->show(); childrenDockWidgetContents->adjustSize(); } -void Qt_launchpad::remove_child(const char *name, Genode::Allocator *alloc) +void Qt_launchpad::remove_child(Launchpad_child::Name const &name, Genode::Allocator &alloc) { Child_entry *child_entry = - childrenDockWidgetContents->findChild(QString(name) + "_child_entry"); + childrenDockWidgetContents->findChild(QString(name.string()) + "_child_entry"); if (!child_entry) { PWRN("child entry lookup failed"); diff --git a/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.h b/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.h index 479e1ac7a..4bb3ffb70 100644 --- a/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.h +++ b/repos/libports/src/app/qt5/qt_launchpad/qt_launchpad.h @@ -29,20 +29,22 @@ class Qt_launchpad : public QMainWindow, public Launchpad, private Ui::Qt_launch public: - Qt_launchpad(unsigned long initial_quota, QWidget *parent = 0); + Qt_launchpad(Genode::Env &env, unsigned long initial_quota, + QWidget *parent = 0); virtual void quota(unsigned long quota) override; - virtual void add_launcher(const char *filename, + virtual void add_launcher(Launchpad_child::Name const &binary_name, unsigned long default_quota, Genode::Dataspace_capability config_ds) override; - virtual void add_child(const char *unique_name, + virtual void add_child(Launchpad_child::Name const &name, unsigned long quota, - Launchpad_child *launchpad_child, - Genode::Allocator *alloc) override; + Launchpad_child &launchpad_child, + Genode::Allocator &alloc) override; - virtual void remove_child(const char *name, Genode::Allocator *alloc) override; + virtual void remove_child(Launchpad_child::Name const &name, + Genode::Allocator &alloc) override; }; #endif /* QT_LAUNCHPAD_H */ diff --git a/repos/libports/src/lib/acpica/acpica.patch b/repos/libports/src/lib/acpica/acpica.patch index e0fb454a9..1e3a3c1fe 100644 --- a/repos/libports/src/lib/acpica/acpica.patch +++ b/repos/libports/src/lib/acpica/acpica.patch @@ -74,3 +74,14 @@ /* * Make sure that a handler exists. If not, report an error ++++ src/lib/acpica/source/include/platform/acgcc.h +@@ -44,7 +44,9 @@ + #ifndef __ACGCC_H__ + #define __ACGCC_H__ + ++#ifndef ACPI_INLINE + #define ACPI_INLINE __inline__ ++#endif + + /* Function name is used for debug output. Non-ANSI, compiler-dependent */ + diff --git a/repos/libports/src/lib/acpica/env.cc b/repos/libports/src/lib/acpica/env.cc new file mode 100644 index 000000000..391bd4d4b --- /dev/null +++ b/repos/libports/src/lib/acpica/env.cc @@ -0,0 +1,60 @@ +/* + * \brief Genode environment for ACPICA library + * \author Christian Helmuth + * \date 2016-11-14 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* Genode includes */ +#include +#include +#include + +#include "env.h" + + +namespace Acpica { struct Env; } + + +struct Acpica::Env +{ + Genode::Env &env; + Genode::Allocator &heap; + + Genode::Parent::Service_name announce_for_acpica { "Acpi" }; + + Genode::Parent::Client parent_client; + + Genode::Id_space::Element id_space_element { + parent_client, env.id_space() }; + + Genode::Capability cap { + Genode::reinterpret_cap_cast( + env.session(announce_for_acpica, + id_space_element.id(), + "ram_quota=24K", Genode::Affinity())) }; + + Platform::Client platform { cap }; + + Env(Genode::Env &env, Genode::Allocator &heap) + : env(env), heap(heap) { } +}; + +static Genode::Lazy_volatile_object instance; + + +Genode::Allocator & Acpica::heap() { return instance->heap; } +Genode::Env & Acpica::env() { return instance->env; } +Platform::Client & Acpica::platform() { return instance->platform; } + + +void Acpica::init(Genode::Env &env, Genode::Allocator &heap) +{ + instance.construct(env, heap); +} diff --git a/repos/libports/src/lib/acpica/env.h b/repos/libports/src/lib/acpica/env.h new file mode 100644 index 000000000..71456127b --- /dev/null +++ b/repos/libports/src/lib/acpica/env.h @@ -0,0 +1,27 @@ +/* + * \brief Genode environment for ACPICA library + * \author Christian Helmuth + * \date 2016-11-14 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _ACPICA__ENV_H_ +#define _ACPICA__ENV_H_ + +#include +#include +#include + +namespace Acpica { + Genode::Env & env(); + Genode::Allocator & heap(); + Platform::Client & platform(); +} + +#endif /* _ACPICA__ENV_H_ */ diff --git a/repos/libports/src/lib/acpica/iomem.cc b/repos/libports/src/lib/acpica/iomem.cc index 97c30d553..bdb5a2385 100644 --- a/repos/libports/src/lib/acpica/iomem.cc +++ b/repos/libports/src/lib/acpica/iomem.cc @@ -1,7 +1,7 @@ /* * \brief I/O memory backend for ACPICA library * \author Alexander Boettcher - * + * \date 2016-11-14 */ /* @@ -12,12 +12,13 @@ */ #include -#include #include #include #include +#include "env.h" + extern "C" { #include "acpi.h" #include "acpiosxf.h" @@ -31,9 +32,7 @@ extern "C" { return retval; \ } -namespace Acpica { -class Io_mem; -}; +namespace Acpica { class Io_mem; }; class Acpica::Io_mem { @@ -77,7 +76,7 @@ class Acpica::Io_mem void invalidate(ACPI_SIZE s) { if (_io_mem && refs()) - Genode::destroy(Genode::env()->heap(), _io_mem); + Genode::destroy(Acpica::heap(), _io_mem); ACPI_PHYSICAL_ADDRESS const p = _phys; @@ -139,7 +138,7 @@ class Acpica::Io_mem io_mem._ref = r; io_mem._virt = 0; - io_mem._io_mem = new (Genode::env()->heap()) + io_mem._io_mem = new (Acpica::heap()) Genode::Io_mem_connection(io_mem._phys, io_mem._size); return &io_mem; @@ -152,7 +151,8 @@ class Acpica::Io_mem if (!io_mem) return 0UL; - io_mem->_virt = Genode::env()->rm_session()->attach(io_mem->_io_mem->dataspace(), io_mem->_size); + io_mem->_virt = Acpica::env().rm().attach(io_mem->_io_mem->dataspace(), + io_mem->_size); return reinterpret_cast(io_mem->_virt); } @@ -160,7 +160,7 @@ class Acpica::Io_mem Genode::addr_t pre_expand(ACPI_PHYSICAL_ADDRESS p, ACPI_SIZE s) { if (_io_mem) - Genode::destroy(Genode::env()->heap(), _io_mem); + Genode::destroy(Acpica::heap(), _io_mem); _io_mem = nullptr; @@ -174,7 +174,7 @@ class Acpica::Io_mem Genode::addr_t post_expand(ACPI_PHYSICAL_ADDRESS p, ACPI_SIZE s) { if (_io_mem) - Genode::destroy(Genode::env()->heap(), _io_mem); + Genode::destroy(Acpica::heap(), _io_mem); ACPI_SIZE xsize = p + s - _phys; if (!allocate(_phys, xsize, _ref)) @@ -211,8 +211,7 @@ class Acpica::Io_mem io2._io_mem = io_mem._io_mem; Genode::addr_t virt = reinterpret_cast(io2._virt); - Genode::env()->rm_session()->attach_at(io_ds, virt, - io2._size, off_phys); + Acpica::env().rm().attach_at(io_ds, virt, io2._size, off_phys); }); /** @@ -227,7 +226,7 @@ class Acpica::Io_mem FAIL(0UL); /* attach whole memory */ - io_mem._virt = Genode::env()->rm_session()->attach(io_ds); + io_mem._virt = Acpica::env().rm().attach(io_ds); return io_mem.to_virt(p); }); diff --git a/repos/libports/src/lib/acpica/osl.cc b/repos/libports/src/lib/acpica/osl.cc index 40a047496..6b5711c12 100644 --- a/repos/libports/src/lib/acpica/osl.cc +++ b/repos/libports/src/lib/acpica/osl.cc @@ -1,7 +1,7 @@ /* * \brief OS specific backend for ACPICA library * \author Alexander Boettcher - * + * \date 2016-11-14 */ /* @@ -12,17 +12,21 @@ */ #include -#include #include #include #include +#include + +#include "env.h" + extern "C" { #include "acpi.h" #include "acpiosxf.h" } + #define FAIL(retval) \ { \ Genode::error(__func__, ":", __LINE__, " called - dead"); \ @@ -39,21 +43,20 @@ ACPI_STATUS AcpiOsPredefinedOverride (const ACPI_PREDEFINED_NAMES *pre, } -void * AcpiOsAllocate (ACPI_SIZE size) { - return Genode::env()->heap()->alloc(size); } +void * AcpiOsAllocate (ACPI_SIZE size) { return Acpica::heap().alloc(size); } void AcpiOsFree (void *ptr) { - if (Genode::env()->heap()->need_size_for_free()) + if (Acpica::heap().need_size_for_free()) Genode::warning(__func__, " called - warning - ptr=", ptr); - Genode::env()->heap()->free(ptr, 0); + Acpica::heap().free(ptr, 0); } ACPI_STATUS AcpiOsCreateLock (ACPI_SPINLOCK *spin_lock) { - *spin_lock = new (Genode::env()->heap()) Genode::Lock(); + *spin_lock = new (Acpica::heap()) Genode::Lock(); return AE_OK; } @@ -80,7 +83,7 @@ void AcpiOsReleaseLock (ACPI_SPINLOCK h, ACPI_CPU_FLAGS flags) ACPI_STATUS AcpiOsCreateSemaphore (UINT32 max, UINT32 initial, ACPI_SEMAPHORE *sem) { - *sem = new (Genode::env()->heap()) Genode::Semaphore(initial); + *sem = new (Acpica::heap()) Genode::Semaphore(initial); return AE_OK; } @@ -200,7 +203,8 @@ ACPI_STATUS AcpiOsWritePort (ACPI_IO_ADDRESS port, UINT32 value, UINT32 width) return AE_OK; } -static struct { +static struct +{ ACPI_EXECUTE_TYPE type; ACPI_OSD_EXEC_CALLBACK func; void *context; diff --git a/repos/libports/src/lib/acpica/pci.cc b/repos/libports/src/lib/acpica/pci.cc index bff08e3d7..81354e73d 100644 --- a/repos/libports/src/lib/acpica/pci.cc +++ b/repos/libports/src/lib/acpica/pci.cc @@ -1,7 +1,7 @@ /* * \brief PCI specific backend for ACPICA library * \author Alexander Boettcher - * + * \date 2016-11-14 */ /* @@ -12,9 +12,8 @@ */ #include -#include -#include -#include + +#include "env.h" extern "C" { #include "acpi.h" @@ -42,44 +41,12 @@ struct Bdf }; -static Platform::Client & platform() -{ - static bool connected = false; - - typedef Genode::Capability Platform_session_capability; - Platform_session_capability platform_cap; - - if (!connected) { - Genode::Parent::Service_name announce_for_acpica("Acpi"); - Genode::Native_capability cap = Genode::env()->parent()->session(announce_for_acpica, "ram_quota=20K"); - - platform_cap = Genode::reinterpret_cap_cast(cap); - connected = true; - } - - static Platform::Client conn(platform_cap); - return conn; -} - -ACPI_STATUS AcpiOsInitialize (void) -{ - /* acpi_drv uses IOMEM concurrently to us - wait until it is done */ - Genode::log("wait for platform drv"); - try { - platform(); - } catch (...) { - Genode::error("did not get Platform connection"); - Genode::Lock lock(Genode::Lock::LOCKED); - lock.lock(); - } - Genode::log("wait for platform drv - done"); - return AE_OK; -} +ACPI_STATUS AcpiOsInitialize (void) { return AE_OK; } ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, UINT64 *value, UINT32 width) { - Platform::Device_capability cap = platform().first_device(); + Platform::Device_capability cap = Acpica::platform().first_device(); while (cap.valid()) { Platform::Device_client client(cap); @@ -103,7 +70,7 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, break; default: Genode::error(__func__, " : unsupported access size ", width); - platform().release_device(client); + Acpica::platform().release_device(client); return AE_ERROR; }; @@ -114,13 +81,13 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, "width=", width, " -> " "value=", Genode::Hex(*value)); - platform().release_device(client); + Acpica::platform().release_device(client); return AE_OK; } - cap = platform().next_device(cap); + cap = Acpica::platform().next_device(cap); - platform().release_device(client); + Acpica::platform().release_device(client); } Genode::error(__func__, " unknown device - segment=", pcidev->Segment, " " @@ -134,7 +101,7 @@ ACPI_STATUS AcpiOsReadPciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, UINT64 value, UINT32 width) { - Platform::Device_capability cap = platform().first_device(); + Platform::Device_capability cap = Acpica::platform().first_device(); while (cap.valid()) { Platform::Device_client client(cap); @@ -158,7 +125,7 @@ ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, break; default: Genode::error(__func__, " : unsupported access size ", width); - platform().release_device(client); + Acpica::platform().release_device(client); return AE_ERROR; }; @@ -169,13 +136,13 @@ ACPI_STATUS AcpiOsWritePciConfiguration (ACPI_PCI_ID *pcidev, UINT32 reg, "width=", width, " " "value=", Genode::Hex(value)); - platform().release_device(client); + Acpica::platform().release_device(client); return AE_OK; } - cap = platform().next_device(cap); + cap = Acpica::platform().next_device(cap); - platform().release_device(client); + Acpica::platform().release_device(client); } Genode::error(__func__, " unknown device - segment=", pcidev->Segment, " ", diff --git a/repos/libports/src/lib/acpica/scan_root.cc b/repos/libports/src/lib/acpica/scan_root.cc index fd7627f08..b41bd7ebb 100644 --- a/repos/libports/src/lib/acpica/scan_root.cc +++ b/repos/libports/src/lib/acpica/scan_root.cc @@ -1,6 +1,7 @@ /* * \brief Lookup code for initial ACPI RSDP pointer * \author Alexander Boettcher + * \date 2016-11-14 */ /* @@ -13,6 +14,8 @@ #include #include +#include "env.h" + extern "C" { #include "acpi.h" } @@ -48,9 +51,11 @@ class Genode::Acpi_table { uint8_t * local = 0; + Genode::Env &env = Acpica::env(); + /* try BIOS area */ { - Genode::Attached_io_mem_dataspace io_mem(BIOS_BASE, BIOS_SIZE); + Genode::Attached_io_mem_dataspace io_mem(env, BIOS_BASE, BIOS_SIZE); local = _search_rsdp(io_mem.local_addr()); if (local) return BIOS_BASE + (local - io_mem.local_addr()); @@ -60,7 +65,7 @@ class Genode::Acpi_table try { unsigned short base = 0; { - Genode::Attached_io_mem_dataspace io_mem(0, 0x1000); + Genode::Attached_io_mem_dataspace io_mem(env, 0, 0x1000); local = io_mem.local_addr(); if (local) base = (*reinterpret_cast(local + 0x40e)) << 4; @@ -69,7 +74,7 @@ class Genode::Acpi_table if (!base) return 0; - Genode::Attached_io_mem_dataspace io_mem(base, 1024); + Genode::Attached_io_mem_dataspace io_mem(env, base, 1024); local = _search_rsdp(io_mem.local_addr()); if (local) diff --git a/repos/libports/src/lib/qt5/qpluginwidget/qpluginwidget.cpp b/repos/libports/src/lib/qt5/qpluginwidget/qpluginwidget.cpp index 8f6e6c891..a3f0eaf7b 100644 --- a/repos/libports/src/lib/qt5/qpluginwidget/qpluginwidget.cpp +++ b/repos/libports/src/lib/qt5/qpluginwidget/qpluginwidget.cpp @@ -50,8 +50,7 @@ const char *config = " \ \ \ \ - \ - \ + \ \ \ \ diff --git a/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerscreen.h b/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerscreen.h index 921f07667..912ab5089 100644 --- a/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerscreen.h +++ b/repos/libports/src/lib/qt5/qtbase/src/plugins/platforms/nitpicker/qnitpickerscreen.h @@ -28,13 +28,14 @@ class QNitpickerScreen : public QPlatformScreen { private: - Nitpicker::Connection _nitpicker; QRect _geometry; public: QNitpickerScreen() { + Nitpicker::Connection _nitpicker; + Framebuffer::Mode const scr_mode = _nitpicker.mode(); if (scr_mode.format() != Framebuffer::Mode::RGB565) @@ -42,8 +43,6 @@ class QNitpickerScreen : public QPlatformScreen _geometry.setRect(0, 0, scr_mode.width(), scr_mode.height()); - - Genode::env()->parent()->close(_nitpicker.cap()); } QRect geometry() const { return _geometry; } diff --git a/repos/os/include/cli_monitor/child.h b/repos/os/include/cli_monitor/child.h index 2a1136e3c..1e2ff80cd 100644 --- a/repos/os/include/cli_monitor/child.h +++ b/repos/os/include/cli_monitor/child.h @@ -260,7 +260,8 @@ class Child_base : public Genode::Child_policy ** Child_policy interface ** ****************************/ - Name name() const override { return _label.string(); } + Name name() const override { return _label; } + Binary_name binary_name() const override { return _binary_name; } Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; } Genode::Ram_session &ref_ram() override { return _ref_ram; } diff --git a/repos/os/include/framebuffer_session/connection.h b/repos/os/include/framebuffer_session/connection.h index 92b25f0c7..fd8668401 100644 --- a/repos/os/include/framebuffer_session/connection.h +++ b/repos/os/include/framebuffer_session/connection.h @@ -24,6 +24,10 @@ namespace Framebuffer { class Connection; } class Framebuffer::Connection : public Genode::Connection, public Session_client { + public: + + enum { RAM_QUOTA = 8*1024UL }; + private: /** @@ -39,7 +43,7 @@ class Framebuffer::Connection : public Genode::Connection, char argbuf[ARGBUF_SIZE]; /* donate ram quota for storing server-side meta data */ - Genode::strncpy(argbuf, "ram_quota=8K", sizeof(argbuf)); + Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", RAM_QUOTA); /* set optional session-constructor arguments */ if (width) diff --git a/repos/os/include/framebuffer_session/framebuffer_session.h b/repos/os/include/framebuffer_session/framebuffer_session.h index aebf30930..50175e106 100644 --- a/repos/os/include/framebuffer_session/framebuffer_session.h +++ b/repos/os/include/framebuffer_session/framebuffer_session.h @@ -23,6 +23,7 @@ namespace Framebuffer { struct Mode; struct Session; + struct Session_client; } @@ -81,6 +82,8 @@ struct Framebuffer::Session : Genode::Session { static const char *service_name() { return "Framebuffer"; } + typedef Session_client Client; + virtual ~Session() { } /** diff --git a/repos/os/include/nitpicker_session/connection.h b/repos/os/include/nitpicker_session/connection.h index 11d3ae284..ed20cff27 100644 --- a/repos/os/include/nitpicker_session/connection.h +++ b/repos/os/include/nitpicker_session/connection.h @@ -28,7 +28,7 @@ class Nitpicker::Connection : public Genode::Connection, { public: - enum { RAM_QUOTA = 36*1024UL }; + enum { RAM_QUOTA = 36*1024UL }; private: diff --git a/repos/os/include/os/single_session_service.h b/repos/os/include/os/single_session_service.h new file mode 100644 index 000000000..127163308 --- /dev/null +++ b/repos/os/include/os/single_session_service.h @@ -0,0 +1,61 @@ +/* + * \brief Utility for implementing a local service with a single session + * \author Norman Feske + * \date 2014-02-14 + */ + +/* + * Copyright (C) 2014 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _INCLUDE__OS__SINGLE_SESSION_SERVICE_H_ +#define _INCLUDE__OS__SINGLE_SESSION_SERVICE_H_ + +/* Genode includes */ +#include + + +namespace Genode { template class Single_session_service; } + + +template +class Genode::Single_session_service +{ + public: + + typedef Capability Session_capability; + + private: + + /* + * Wrap client object to be compabile with 'Rpc_object::cap' calls + * + * We hand out the capability via 'cap' method to be compatible with + * the interface normally provided by server-side component objects. + * The 'Single_session_factory' requests the capability via this + * method. + */ + struct Client : SESSION::Client + { + Client(Session_capability cap) : SESSION::Client(cap) { } + Session_capability cap() const { return *this; } + }; + + typedef Local_service Service; + typedef typename Service::Single_session_factory Factory; + + Client _client; + Factory _factory { _client }; + Service _service { _factory }; + + public: + + Single_session_service(Session_capability cap) : _client(cap) { } + + Service &service() { return _service; } +}; + +#endif /* _INCLUDE__OS__SINGLE_SESSION_SERVICE_H_ */ diff --git a/repos/os/src/app/cli_monitor/child.h b/repos/os/src/app/cli_monitor/child.h index 947003bbe..a4f1d6ea3 100644 --- a/repos/os/src/app/cli_monitor/child.h +++ b/repos/os/src/app/cli_monitor/child.h @@ -25,25 +25,29 @@ struct Child : Child_base, List::Element Argument argument; Child(Ram &ram, - char const *label, - char const *binary, - Genode::Cap_session &cap_session, + Name const &label, + Binary_name const &binary, + Genode::Pd_session &pd_session, + Genode::Ram_session &ref_ram, + Genode::Ram_session_capability ref_ram_cap, + Genode::Region_map &local_rm, Genode::size_t ram_quota, Genode::size_t ram_limit, Genode::Signal_context_capability yield_response_sig_cap, - Genode::Signal_context_capability exit_sig_cap, - Genode::Dataspace_capability ldso_ds) + Genode::Signal_context_capability exit_sig_cap) : Child_base(ram, label, binary, - cap_session, + pd_session, + ref_ram, + ref_ram_cap, + local_rm, ram_quota, ram_limit, yield_response_sig_cap, - exit_sig_cap, - ldso_ds), - argument(label, "subsystem") + exit_sig_cap), + argument(label.string(), "subsystem") { } }; diff --git a/repos/os/src/app/cli_monitor/child_registry.h b/repos/os/src/app/cli_monitor/child_registry.h index d52327087..ffc7623f9 100644 --- a/repos/os/src/app/cli_monitor/child_registry.h +++ b/repos/os/src/app/cli_monitor/child_registry.h @@ -30,7 +30,7 @@ class Child_registry : public List bool _child_name_exists(const char *label) { for (Child *child = first() ; child; child = child->next()) - if (strcmp(child->name(), label) == 0) + if (child->name() == label) return true; return false; } diff --git a/repos/os/src/app/cli_monitor/kill_command.h b/repos/os/src/app/cli_monitor/kill_command.h index 7d9b5b1d8..d54cc0df5 100644 --- a/repos/os/src/app/cli_monitor/kill_command.h +++ b/repos/os/src/app/cli_monitor/kill_command.h @@ -23,7 +23,7 @@ struct Kill_command : Command void _destroy_child(Child *child, Terminal::Session &terminal) { - tprintf(terminal, "destroying subsystem '%s'\n", child->name()); + tprintf(terminal, "destroying subsystem '%s'\n", child->name().string()); _children.remove(child); Genode::destroy(Genode::env()->heap(), child); } @@ -38,8 +38,8 @@ struct Kill_command : Command void _for_each_argument(Argument_fn const &fn) const override { - auto child_name_fn = [&] (char const *child_name) { - Argument arg(child_name, ""); + auto child_name_fn = [&] (Child_base::Name const &child_name) { + Argument arg(child_name.string(), ""); fn(arg); }; @@ -65,7 +65,7 @@ struct Kill_command : Command /* lookup child by its unique name */ for (Child *child = _children.first(); child; child = child->next()) { - if (strcmp(child->name(), label) == 0) { + if (child->name() == label) { _destroy_child(child, terminal); return; } diff --git a/repos/os/src/app/cli_monitor/main.cc b/repos/os/src/app/cli_monitor/main.cc index d7df1cfc7..8052965f1 100644 --- a/repos/os/src/app/cli_monitor/main.cc +++ b/repos/os/src/app/cli_monitor/main.cc @@ -132,11 +132,12 @@ void Component::construct(Genode::Env &env) commands.insert(new Help_command); Kill_command kill_command(children); commands.insert(&kill_command); - commands.insert(new Start_command(ram, cap, children, + commands.insert(new Start_command(ram, env.pd(), + env.ram(), env.ram_session_cap(), + env.rm(), children, subsystem_config_registry, yield_response_sig_cap, - exited_child_sig_cap, - ldso_ds)); + exited_child_sig_cap)); commands.insert(new Status_command(ram, children)); commands.insert(new Yield_command(children)); commands.insert(new Ram_command(children)); diff --git a/repos/os/src/app/cli_monitor/ram_command.h b/repos/os/src/app/cli_monitor/ram_command.h index 7d3c471c5..395fd04b9 100644 --- a/repos/os/src/app/cli_monitor/ram_command.h +++ b/repos/os/src/app/cli_monitor/ram_command.h @@ -40,13 +40,13 @@ struct Ram_command : Command size_t const avail = Genode::env()->ram_session()->avail(); if (amount > avail) { tprintf(terminal, "upgrade of '%s' exceeds available quota of ", - child.name()); + child.name().string()); tprint_bytes(terminal, avail); tprintf(terminal, "\n"); amount = avail; } - tprintf(terminal, "upgrading quota of '%s' to ", child.name()); + tprintf(terminal, "upgrading quota of '%s' to ", child.name().string()); tprint_bytes(terminal, old_quota + amount); tprintf(terminal, "\n"); @@ -69,7 +69,7 @@ struct Ram_command : Command amount = avail; } - tprintf(terminal, "depleting quota of '%s' to ", child.name()); + tprintf(terminal, "depleting quota of '%s' to ", child.name().string()); tprint_bytes(terminal, old_quota - amount); tprintf(terminal, "\n"); @@ -82,8 +82,8 @@ struct Ram_command : Command void _for_each_argument(Argument_fn const &fn) const override { - auto child_name_fn = [&] (char const *child_name) { - Argument arg(child_name, ""); + auto child_name_fn = [&] (Child_base::Name const &child_name) { + Argument arg(child_name.string(), ""); fn(arg); }; @@ -102,7 +102,7 @@ struct Ram_command : Command /* lookup child by its unique name */ Child *child = _children.first(); for (; child; child = child->next()) - if (strcmp(child->name(), label) == 0) + if (child->name() == label) break; if (!child) { diff --git a/repos/os/src/app/cli_monitor/start_command.h b/repos/os/src/app/cli_monitor/start_command.h index 4c1c8b5ac..610349c35 100644 --- a/repos/os/src/app/cli_monitor/start_command.h +++ b/repos/os/src/app/cli_monitor/start_command.h @@ -28,14 +28,16 @@ class Start_command : public Command typedef Genode::Signal_context_capability Signal_context_capability; typedef Genode::Dataspace_capability Dataspace_capability; - Ram &_ram; - Child_registry &_children; - Genode::Cap_session &_cap; - Subsystem_config_registry &_subsystem_configs; - List _arguments; - Signal_context_capability _yield_response_sigh_cap; - Signal_context_capability _exit_sig_cap; - Dataspace_capability _ldso_ds; + Ram &_ram; + Child_registry &_children; + Genode::Pd_session &_pd; + Genode::Ram_session &_ref_ram; + Genode::Ram_session_capability _ref_ram_cap; + Genode::Region_map &_local_rm; + Subsystem_config_registry &_subsystem_configs; + List _arguments; + Signal_context_capability _yield_response_sigh_cap; + Signal_context_capability _exit_sig_cap; void _execute_subsystem(char const *name, Command_line &cmd, Terminal::Session &terminal, @@ -107,11 +109,12 @@ class Start_command : public Command Child *child = 0; try { child = new (Genode::env()->heap()) - Child(_ram, label, binary_name, _cap, ram, ram_limit, - _yield_response_sigh_cap, _exit_sig_cap, _ldso_ds); + Child(_ram, label, binary_name, _pd, _ref_ram, _ref_ram_cap, + _local_rm, ram, ram_limit, + _yield_response_sigh_cap, _exit_sig_cap); } - catch (Genode::Rom_connection::Rom_connection_failed) { - tprintf(terminal, "Error: could not obtain ROM module \"%s\"\n", + catch (Genode::Parent::Service_denied) { + tprintf(terminal, "Error: could not start child \"%s\"\n", binary_name); return; } @@ -146,18 +149,22 @@ class Start_command : public Command public: - Start_command(Ram &ram, Genode::Cap_session &cap, Child_registry &children, - Subsystem_config_registry &subsustem_configs, - Signal_context_capability yield_response_sigh_cap, - Signal_context_capability exit_sig_cap, - Dataspace_capability ldso_ds) + Start_command(Ram &ram, + Genode::Pd_session &pd, + Genode::Ram_session &ref_ram, + Genode::Ram_session_capability ref_ram_cap, + Genode::Region_map &local_rm, + Child_registry &children, + Subsystem_config_registry &subsustem_configs, + Signal_context_capability yield_response_sigh_cap, + Signal_context_capability exit_sig_cap) : Command("start", "create new subsystem"), - _ram(ram), _children(children), _cap(cap), + _ram(ram), _children(children), _pd(pd), + _ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap), _local_rm(local_rm), _subsystem_configs(subsustem_configs), _yield_response_sigh_cap(yield_response_sigh_cap), - _exit_sig_cap(exit_sig_cap), - _ldso_ds(ldso_ds) + _exit_sig_cap(exit_sig_cap) { add_parameter(new Parameter("--count", Parameter::NUMBER, "number of instances")); add_parameter(new Parameter("--ram", Parameter::NUMBER, "initial RAM quota")); diff --git a/repos/os/src/app/cli_monitor/status_command.h b/repos/os/src/app/cli_monitor/status_command.h index 7b46db586..21a5bc719 100644 --- a/repos/os/src/app/cli_monitor/status_command.h +++ b/repos/os/src/app/cli_monitor/status_command.h @@ -139,7 +139,7 @@ struct Status_command : Command Child_info child_info[num_children]; unsigned i = 0; for (Child *c = _children.first(); c && i < num_children; c = c->next(), i++) - child_info[i] = Child_info(c->name(), c->ram_status()); + child_info[i] = Child_info(c->name().string(), c->ram_status()); /* * Print table diff --git a/repos/os/src/app/cli_monitor/yield_command.h b/repos/os/src/app/cli_monitor/yield_command.h index 24159e56e..a1c6c94ce 100644 --- a/repos/os/src/app/cli_monitor/yield_command.h +++ b/repos/os/src/app/cli_monitor/yield_command.h @@ -32,8 +32,8 @@ struct Yield_command : Command void _for_each_argument(Argument_fn const &fn) const override { - auto child_name_fn = [&] (char const *child_name) { - Argument arg(child_name, ""); + auto child_name_fn = [&] (Child_base::Name const &child_name) { + Argument arg(child_name.string(), ""); fn(arg); }; @@ -57,7 +57,7 @@ struct Yield_command : Command /* lookup child by its unique name */ Child *child = _children.first(); for (; child; child = child->next()) - if (strcmp(child->name(), label) == 0) + if (child->name() == label) break; if (!child) { @@ -67,7 +67,7 @@ struct Yield_command : Command child->yield(ram, greedy); - tprintf(terminal, "requesting '%s' to yield ", child->name()); + tprintf(terminal, "requesting '%s' to yield ", child->name().string()); tprint_bytes(terminal, ram); tprintf(terminal, "\n"); } diff --git a/repos/ports-foc/src/lib/l4lx/include/dataspace.h b/repos/ports-foc/src/lib/l4lx/include/dataspace.h index 495308fe4..bc178b65c 100644 --- a/repos/ports-foc/src/lib/l4lx/include/dataspace.h +++ b/repos/ports-foc/src/lib/l4lx/include/dataspace.h @@ -115,9 +115,7 @@ namespace L4lx { use_local_addr, local_addr, executable); }, - [&] () { - Genode::env()->parent()->upgrade(Rm_connection::cap(), "ram_quota=8K"); - }); + [&] () { Rm_connection::upgrade_ram(8*1024); }); } }; diff --git a/repos/ports-foc/src/lib/l4lx/include/platform_env.h b/repos/ports-foc/src/lib/l4lx/include/platform_env.h index ba750f9d3..b6cd49d30 100644 --- a/repos/ports-foc/src/lib/l4lx/include/platform_env.h +++ b/repos/ports-foc/src/lib/l4lx/include/platform_env.h @@ -56,30 +56,4 @@ auto retry(FUNC func, HANDLER handler, unsigned attempts = ~0U) -> decltype(func throw EXC(); } - -/** - * Client object for a session that may get its session quota upgraded - */ -template -struct Upgradeable_client : CLIENT -{ - typedef Genode::Capability Capability; - - Capability _cap; - - Upgradeable_client(Capability cap) : CLIENT(cap), _cap(cap) { } - - void upgrade_ram(Genode::size_t quota) - { - Genode::log("upgrading quota donation for " - "Env::", CLIENT::Rpc_interface::service_name(), " " - "(", quota, " bytes)"); - - char buf[128]; - Genode::snprintf(buf, sizeof(buf), "ram_quota=%ld", quota); - - Genode::env()->parent()->upgrade(_cap, buf); - } -}; - #endif /* _PLATFORM_ENV_H_ */ diff --git a/repos/ports-foc/src/lib/l4lx/startup.cc b/repos/ports-foc/src/lib/l4lx/startup.cc index 564d2e3a4..167515ac9 100644 --- a/repos/ports-foc/src/lib/l4lx/startup.cc +++ b/repos/ports-foc/src/lib/l4lx/startup.cc @@ -83,7 +83,7 @@ static void map_kip() using namespace Genode; /* Open the KIP special file and keep it open */ - static Genode::Rom_connection kip_rom("kip"); + static Genode::Rom_connection kip_rom("l4v2_kip"); /* Attach and register dataspace */ l4lx_kinfo = L4lx::Env::env()->rm()->attach(kip_rom.dataspace(), "KIP"); diff --git a/repos/ports/include/noux_session/connection.h b/repos/ports/include/noux_session/connection.h index 27ab62338..e0985c940 100644 --- a/repos/ports/include/noux_session/connection.h +++ b/repos/ports/include/noux_session/connection.h @@ -40,6 +40,18 @@ struct Noux::Connection : Genode::Connection, Session_client */ Connection() : Genode::Connection(session("")), Session_client(cap()) { } + + /** + * Remove session ID of the noux session from the ID space. + * + * This must by done before reinitializing the noux connection in a + * freshly forked process. Otherwise, an overwritten 'Noux::Connection' + * object would still be referenced by the AVL tree of the the ID space. + */ + void discard_session_id() + { + _id_space_element.~Element(); + } }; #endif /* _INCLUDE__NOUX_SESSION__CONNECTION_H_ */ diff --git a/repos/ports/include/vmm/vcpu_dispatcher.h b/repos/ports/include/vmm/vcpu_dispatcher.h index 823e84b14..336536a06 100644 --- a/repos/ports/include/vmm/vcpu_dispatcher.h +++ b/repos/ports/include/vmm/vcpu_dispatcher.h @@ -38,8 +38,8 @@ class Vmm::Vcpu_dispatcher : public T enum { WEIGHT = Genode::Cpu_session::Weight::DEFAULT_WEIGHT }; - Pd_session &_pd; - Nova_native_pd_client _native_pd { _pd.native_pd() }; + Env &_env; + Nova_native_pd_client _native_pd { _env.pd().native_pd() }; /** * Portal entry point entered on virtualization events @@ -69,12 +69,12 @@ class Vmm::Vcpu_dispatcher : public T unsigned int exit_reason = 0; - Vcpu_dispatcher(Genode::size_t stack_size, Pd_session &pd, + Vcpu_dispatcher(Genode::Env &env, Genode::size_t stack_size, Cpu_session * cpu_session, Genode::Affinity::Location location, const char * name = "vCPU dispatcher") : - T(WEIGHT, name, stack_size, location), _pd(pd) + T(WEIGHT, name, stack_size, location), _env(env) { using namespace Genode; @@ -85,13 +85,13 @@ class Vmm::Vcpu_dispatcher : public T } template - Vcpu_dispatcher(Genode::size_t stack_size, Pd_session &pd, + Vcpu_dispatcher(Genode::Env &env, Genode::size_t stack_size, Cpu_session * cpu_session, Genode::Affinity::Location location, X attr, void *(*start_routine) (void *), void *arg, const char * name = "vCPU dispatcher") : T(attr, start_routine, arg, stack_size, name, nullptr, location), - _pd(pd) + _env(env) { using namespace Genode; @@ -125,11 +125,7 @@ class Vmm::Vcpu_dispatcher : public T }, [&] () { Thread::myself()->native_thread().reset_client_rcv_sel(); - Pd_session_client *client = - dynamic_cast(&_pd); - - if (client) - env()->parent()->upgrade(*client, "ram_quota=16K"); + _env.parent().upgrade(Parent::Env::pd(), "ram_quota=16K"); }); /* revert selector allocation to automatic mode of operation */ diff --git a/repos/ports/run/arora.run b/repos/ports/run/arora.run index 869e88089..9073812dd 100644 --- a/repos/ports/run/arora.run +++ b/repos/ports/run/arora.run @@ -64,6 +64,22 @@ append config { + + + + + + + + + + + + + + + + diff --git a/repos/ports/run/noux_net_netcat.run b/repos/ports/run/noux_net_netcat.run index 31badaaee..808734a38 100644 --- a/repos/ports/run/noux_net_netcat.run +++ b/repos/ports/run/noux_net_netcat.run @@ -104,7 +104,7 @@ append config { append_if $use_nic_driver config { - + } diff --git a/repos/ports/run/seoul.inc b/repos/ports/run/seoul.inc index 928e0dc76..fc9021d1b 100644 --- a/repos/ports/run/seoul.inc +++ b/repos/ports/run/seoul.inc @@ -212,7 +212,7 @@ append_platform_drv_config append_if $use_nic_session config { - + diff --git a/repos/ports/run/vmm_utils.run b/repos/ports/run/vmm_utils.run index 8883a1d56..e53c75b53 100644 --- a/repos/ports/run/vmm_utils.run +++ b/repos/ports/run/vmm_utils.run @@ -34,6 +34,7 @@ append qemu_args " -m 512 " append qemu_args " -cpu phenom " append qemu_args " -nographic " -run_genode_until {.*VMM: _svm_startup called} 30 +run_genode_until {.*VMM: vcpu1 _svm_startup called.*\n} 30 +run_genode_until {.*VMM: vcpu2 _svm_startup called.*\n} 10 [output_spawn_id] puts "Test succeeded" diff --git a/repos/ports/src/app/arora/demo/nitpicker_plugin/config.plugin b/repos/ports/src/app/arora/demo/nitpicker_plugin/config.plugin index 0251d7ff8..7645b1587 100644 --- a/repos/ports/src/app/arora/demo/nitpicker_plugin/config.plugin +++ b/repos/ports/src/app/arora/demo/nitpicker_plugin/config.plugin @@ -24,12 +24,10 @@ - - - - - - + + + + diff --git a/repos/ports/src/app/gdb_monitor/app_child.h b/repos/ports/src/app/gdb_monitor/app_child.h index dcbbcb41b..2b40cc4a5 100644 --- a/repos/ports/src/app/gdb_monitor/app_child.h +++ b/repos/ports/src/app/gdb_monitor/app_child.h @@ -25,73 +25,68 @@ #include -#include "cpu_root.h" #include "genode_child_resources.h" +#include "cpu_session_component.h" #include "pd_session_component.h" -#include "ram_root.h" #include "rom.h" namespace Gdb_monitor { class App_child; } -class Gdb_monitor::App_child : public Child_policy, - public Init::Child_policy_enforce_labeling +class Gdb_monitor::App_child : public Child_policy { + public: + + typedef Genode::Registered Parent_service; + typedef Genode::Registry Parent_services; + private: enum { STACK_SIZE = 4*1024*sizeof(long) }; - const char *_unique_name; + Init::Child_policy_enforce_labeling _labeling_policy; - Genode::Dataspace_capability _elf_ds; - Genode::Dataspace_capability _ldso_ds; + Genode::Env &_env; - Rpc_entrypoint _entrypoint; + Genode::Ram_session_capability _ref_ram_cap { _env.ram_session_cap() }; + Genode::Ram_session_client _ref_ram { _ref_ram_cap }; - Service_registry *_parent_services; - Service_registry _local_services; + const char *_unique_name; - Genode::Rpc_entrypoint *_root_ep; + Genode::Dataspace_capability _elf_ds; - Init::Child_config _child_config; + Genode::Region_map &_rm; + + Genode::size_t _ram_quota; + + Rpc_entrypoint _entrypoint; + + Parent_services _parent_services; + + Init::Child_config _child_config; - Init::Child_policy_provide_rom_file _binary_policy; Init::Child_policy_provide_rom_file _config_policy; - Genode_child_resources _genode_child_resources; + Genode_child_resources _genode_child_resources; - Signal_dispatcher _unresolved_page_fault_dispatcher; + Signal_dispatcher _unresolved_page_fault_dispatcher; - Dataspace_pool _managed_ds_map; + Dataspace_pool _managed_ds_map; - Pd_session_component _pd {_unique_name, _entrypoint, _managed_ds_map}; + Pd_session_component _pd {_unique_name, _entrypoint, _managed_ds_map}; + Pd_service::Single_session_factory _pd_factory { _pd }; + Pd_service _pd_service { _pd_factory }; - Cpu_root _cpu_root; - Cpu_session_client _cpu_session; + Local_cpu_factory _cpu_factory; + Cpu_service _cpu_service { _cpu_factory }; - Ram_session_client _ram_session; + Local_rom_factory _rom_factory; + Rom_service _rom_service { _rom_factory }; - Region_map_client _address_space { _pd.address_space() }; - - Child::Initial_thread _initial_thread; - - Parent_service _parent_pd_service { "" }; - Parent_service _parent_ram_service { "" }; - Parent_service _parent_cpu_service { "" }; - - Child *_child; - - Rom_service _rom_service; - - - Cpu_session_capability _get_cpu_session_cap() - { - _entrypoint.manage(&_cpu_root); - char args[64]; - Genode::snprintf(args, sizeof(args), "ram_quota=64K, label=\"%s\"", _unique_name); - return static_cap_cast(_cpu_root.session(args, Affinity())); - } + Child *_child; + /* FIXME */ +#if 0 /** * Proxy for a service provided by the child */ @@ -229,12 +224,23 @@ class Gdb_monitor::App_child : public Child_policy, child_ram.transfer_quota(env()->ram_session_cap(), ram_quota); } }; - +#endif void _dispatch_unresolved_page_fault(unsigned) { _genode_child_resources.cpu_session_component()->handle_unresolved_page_fault(); } + template + static Genode::Service *_find_service(Genode::Registry &services, + Genode::Service::Name const &name) + { + Genode::Service *service = nullptr; + services.for_each([&] (T &s) { + if (!service && (s.name() == name)) + service = &s; }); + return service; + } + public: /** @@ -244,38 +250,30 @@ class Gdb_monitor::App_child : public Child_policy, * services provided by the child and announced * towards the parent of GDB monitor */ - App_child(const char *unique_name, - Genode::Dataspace_capability elf_ds, - Genode::Dataspace_capability ldso_ds, - Genode::Ram_session_capability ram_session, - Genode::Cap_session *cap_session, - Service_registry *parent_services, - Genode::Rpc_entrypoint *root_ep, + App_child(Genode::Env &env, + const char *unique_name, + Genode::Pd_session &pd, + Genode::Region_map &rm, + Genode::size_t ram_quota, Signal_receiver *signal_receiver, Xml_node target_node) - : Init::Child_policy_enforce_labeling(unique_name), + : _labeling_policy(unique_name), + _env(env), _unique_name(unique_name), - _elf_ds(elf_ds), - _ldso_ds(ldso_ds), - _entrypoint(cap_session, STACK_SIZE, "GDB monitor entrypoint name"), - _parent_services(parent_services), - _root_ep(root_ep), - _child_config(ram_session, target_node), - _binary_policy("binary", elf_ds, &_entrypoint), + _rm(rm), + _ram_quota(ram_quota), + _entrypoint(&pd, STACK_SIZE, "GDB monitor entrypoint"), + _child_config(env.ram(), rm, target_node), _config_policy("config", _child_config.dataspace(), &_entrypoint), _unresolved_page_fault_dispatcher(*signal_receiver, *this, &App_child::_dispatch_unresolved_page_fault), - _cpu_root(&_entrypoint, &_entrypoint, env()->heap(), _pd.core_pd_cap(), - signal_receiver, &_genode_child_resources), - _cpu_session(_get_cpu_session_cap()), - _ram_session(ram_session), - _initial_thread(_cpu_session, _pd.cap(), unique_name), - _rom_service(&_entrypoint, env()->heap()) + _cpu_factory(_env, _entrypoint, Genode::env()->heap(), _pd.core_pd_cap(), + signal_receiver, &_genode_child_resources), + _rom_factory(env, _entrypoint) { _genode_child_resources.region_map_component(&_pd.region_map()); _pd.region_map().fault_handler(_unresolved_page_fault_dispatcher); - _local_services.insert(&_rom_service); } ~App_child() @@ -290,68 +288,72 @@ class Gdb_monitor::App_child : public Child_policy, void start() { - _child = new (env()->heap()) Child(_elf_ds, - _ldso_ds, - _pd.cap(), - _pd, - _ram_session, - _ram_session, - _cpu_session, - _initial_thread, - *Genode::env()->rm_session(), - _address_space, - _entrypoint, - *this); + _child = new (env()->heap()) Child(_rm, _entrypoint, *this); } /**************************** ** Child-policy interface ** ****************************/ - const char *name() const { return _unique_name; } + Name name() const override { return _unique_name; } - void filter_session_args(const char *, char *args, Genode::size_t args_len) + Genode::Ram_session &ref_ram() override { return _ref_ram; } + + Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; } + + void init(Genode::Ram_session &session, + Genode::Ram_session_capability cap) override { - Init::Child_policy_enforce_labeling::filter_session_args(0, args, args_len); + session.ref_account(_ref_ram_cap); + _ref_ram.transfer_quota(cap, _ram_quota); } - Service *resolve_session_request(const char *service_name, - const char *args) + void filter_session_args(Service::Name const&, char *args, Genode::size_t args_len) override { - Service *service = 0; + _labeling_policy.filter_session_args(0, args, args_len); + } - /* check for binary file request */ - if ((service = _binary_policy.resolve_session_request(service_name, args))) - return service; + Service &resolve_session_request(Genode::Service::Name const &service_name, + Genode::Session_state::Args const &args) override + { + Service *service = nullptr; /* check for config file request */ - if ((service = _config_policy.resolve_session_request(service_name, args))) - return service; + if ((service = _config_policy.resolve_session_request(service_name.string(), args.string()))) + return *service; - service = _local_services.find(service_name); - if (service) - return service; + if (service_name == "CPU") + return _cpu_service; - service = _parent_services->find(service_name); - if (!service) { - service = new (env()->heap()) Parent_service(service_name); - _parent_services->insert(service); - } + if (service_name == "PD") + return _pd_service; - return service; + if (service_name == "ROM") + return _rom_service; + + service = _find_service(_parent_services, service_name); + if (!service) + service = new (env()->heap()) Parent_service(_parent_services, _env, service_name); + + if (!service) + throw Parent::Service_denied(); + + return *service; } - bool announce_service(const char *name, - Root_capability root, - Allocator *alloc, - Server *server) + // XXX adjust to API change, need to serve a "session_requests" rom + // to the child + void announce_service(Service::Name const &name) override { + /* FIXME */ +#if 0 /* create and announce proxy for the child's root interface */ Child_service_root *r = new (alloc) Child_service_root(_ram_session, root); - Genode::env()->parent()->announce(name, _root_ep->manage(r)); - return true; +#else + Genode::warning(__PRETTY_FUNCTION__, ": not implemented"); +#endif } }; diff --git a/repos/ports/src/app/gdb_monitor/cpu_root.h b/repos/ports/src/app/gdb_monitor/cpu_root.h deleted file mode 100644 index e80cfc842..000000000 --- a/repos/ports/src/app/gdb_monitor/cpu_root.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * \brief CPU root interface - * \author Christian Helmuth - * \date 2006-07-17 - */ - -/* - * Copyright (C) 2006-2016 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _CPU_ROOT_H_ -#define _CPU_ROOT_H_ - -/* Genode includes */ -#include - -/* core includes */ -#include - -/* GDB monitor includes */ -#include "genode_child_resources.h" - -namespace Gdb_monitor { class Cpu_root; } - -class Gdb_monitor::Cpu_root : public Root_component -{ - private: - - Rpc_entrypoint *_thread_ep; - Allocator *_md_alloc; - Pd_session_capability _core_pd; - Genode::Signal_receiver *_signal_receiver; - Genode_child_resources *_genode_child_resources; - - protected: - - Cpu_session_component *_create_session(const char *args) - { - Cpu_session_component *cpu_session_component = - new (md_alloc()) - Cpu_session_component(_thread_ep, - _md_alloc, - _core_pd, - _signal_receiver, - args); - _genode_child_resources->cpu_session_component(cpu_session_component); - return cpu_session_component; - } - - public: - - /** - * Constructor - * - * \param session_ep entry point for managing cpu session objects - * \param thread_ep entry point for managing threads - * \param md_alloc meta data allocator to be used by root component - */ - Cpu_root(Rpc_entrypoint *session_ep, - Rpc_entrypoint *thread_ep, - Allocator *md_alloc, - Pd_session_capability core_pd, - Genode::Signal_receiver *signal_receiver, - Genode_child_resources *genode_child_resources) - : - Root_component(session_ep, md_alloc), - _thread_ep(thread_ep), - _md_alloc(md_alloc), - _core_pd(core_pd), - _signal_receiver(signal_receiver), - _genode_child_resources(genode_child_resources) - { } -}; - -#endif /* _CPU_ROOT_H_ */ diff --git a/repos/ports/src/app/gdb_monitor/cpu_session_component.cc b/repos/ports/src/app/gdb_monitor/cpu_session_component.cc index c7fc190cb..a6a5d32fc 100644 --- a/repos/ports/src/app/gdb_monitor/cpu_session_component.cc +++ b/repos/ports/src/app/gdb_monitor/cpu_session_component.cc @@ -36,7 +36,7 @@ Cpu_session &Cpu_session_component::parent_cpu_session() Rpc_entrypoint &Cpu_session_component::thread_ep() { - return *_thread_ep; + return _ep; } @@ -299,18 +299,22 @@ Capability Cpu_session_component::native_cpu() } -Cpu_session_component::Cpu_session_component(Rpc_entrypoint *thread_ep, +Cpu_session_component::Cpu_session_component(Genode::Env &env, + Rpc_entrypoint &ep, Allocator *md_alloc, Pd_session_capability core_pd, Signal_receiver *exception_signal_receiver, - const char *args) -: _thread_ep(thread_ep), + const char *args, + Affinity const &affinity) +: _env(env), + _ep(ep), _md_alloc(md_alloc), _core_pd(core_pd), - _parent_cpu_session(env()->parent()->session(args)), + _parent_cpu_session(env.session(_id_space_element.id(), args, affinity)), _exception_signal_receiver(exception_signal_receiver), _native_cpu_cap(_setup_native_cpu()) { + _ep.manage(this); } @@ -323,6 +327,8 @@ Cpu_session_component::~Cpu_session_component() } _cleanup_native_cpu(); + + _ep.dissolve(this); } diff --git a/repos/ports/src/app/gdb_monitor/cpu_session_component.h b/repos/ports/src/app/gdb_monitor/cpu_session_component.h index 04b2b7ee1..11ec57fe2 100644 --- a/repos/ports/src/app/gdb_monitor/cpu_session_component.h +++ b/repos/ports/src/app/gdb_monitor/cpu_session_component.h @@ -16,43 +16,59 @@ /* Genode includes */ #include +#include #include +#include #include #include #include +#include #include /* GDB monitor includes */ #include "append_list.h" +#include "genode_child_resources.h" namespace Gdb_monitor { class Cpu_session_component; class Cpu_thread_component; + class Local_cpu_factory; + + typedef Genode::Local_service Cpu_service; + using namespace Genode; } + class Gdb_monitor::Cpu_session_component : public Rpc_object { private: - Rpc_entrypoint *_thread_ep; - Allocator *_md_alloc; + Genode::Env &_env; - Pd_session_capability _core_pd; + Genode::Parent::Client _parent_client; + + Id_space::Element const _id_space_element + { _parent_client, _env.id_space() }; - Cpu_session_client _parent_cpu_session; - Signal_receiver *_exception_signal_receiver; + Rpc_entrypoint &_ep; + Allocator *_md_alloc; - Append_list _thread_list; + Pd_session_capability _core_pd; - bool _stop_new_threads = true; - Lock _stop_new_threads_lock; + Cpu_session_client _parent_cpu_session; + Signal_receiver *_exception_signal_receiver; - Capability _native_cpu_cap; + Append_list _thread_list; - Capability _setup_native_cpu(); + bool _stop_new_threads = true; + Lock _stop_new_threads_lock; + + Capability _native_cpu_cap; + + Capability _setup_native_cpu(); void _cleanup_native_cpu(); public: @@ -60,11 +76,13 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object /** * Constructor */ - Cpu_session_component(Rpc_entrypoint *thread_ep, - Allocator *md_alloc, - Pd_session_capability core_pd, - Signal_receiver *exception_signal_receiver, - const char *args); + Cpu_session_component(Genode::Env &env, + Rpc_entrypoint &ep, + Allocator *md_alloc, + Pd_session_capability core_pd, + Signal_receiver *exception_signal_receiver, + const char *args, + Affinity const &affinity); /** * Destructor @@ -109,4 +127,59 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object Capability native_cpu() override; }; + +class Gdb_monitor::Local_cpu_factory : public Cpu_service::Factory +{ + private: + + Genode::Env &_env; + Genode::Rpc_entrypoint &_ep; + + Allocator *_md_alloc; + Pd_session_capability _core_pd; + Genode::Signal_receiver *_signal_receiver; + Genode_child_resources *_genode_child_resources; + + + public: + + Local_cpu_factory(Genode::Env &env, Genode::Rpc_entrypoint &ep, + Allocator *md_alloc, + Pd_session_capability core_pd, + Genode::Signal_receiver *signal_receiver, + Genode_child_resources *genode_child_resources) + : _env(env), _ep(ep), + _md_alloc(md_alloc), + _core_pd(core_pd), + _signal_receiver(signal_receiver), + _genode_child_resources(genode_child_resources) + { } + + /*********************** + ** Factory interface ** + ***********************/ + + Cpu_session_component &create(Args const &args, Affinity affinity) override + { + Cpu_session_component *cpu_session_component = + new (_md_alloc) + Cpu_session_component(_env, + _ep, + _md_alloc, + _core_pd, + _signal_receiver, + args.string(), + affinity); + _genode_child_resources->cpu_session_component(cpu_session_component); + return *cpu_session_component; + } + + void upgrade(Cpu_session_component &, Args const &) override { } + + void destroy(Cpu_session_component &session) override + { + Genode::destroy(env()->heap(), &session); + } +}; + #endif /* _CPU_SESSION_COMPONENT_H_ */ diff --git a/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc b/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc index 3d4eee726..bb539f285 100644 --- a/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc +++ b/repos/ports/src/app/gdb_monitor/gdbserver/genode-low.cc @@ -46,6 +46,8 @@ int linux_detach_one_lwp (struct inferior_list_entry *entry, void *args); static bool verbose = false; +Genode::Env *genode_env; + static int _new_thread_pipe[2]; /* @@ -273,16 +275,6 @@ extern "C" int fork() return -1; } - /* look for dynamic linker */ - - Dataspace_capability ldso_cap; - try { - Rom_connection ldso_rom("ld.lib.so"); - ldso_cap = clone_rom(ldso_rom.dataspace()); - } catch (...) { - warning("ld.lib.so not found"); - } - /* extract target filename from config file */ static char filename[32] = ""; @@ -319,34 +311,6 @@ extern "C" int fork() Number_of_bytes ram_quota = env()->ram_session()->avail() - preserved_ram_quota; /* start the application */ - char *unique_name = filename; - Capability file_cap; - try { - static Rom_connection rom(prefixed_label(Session_label(Cstring(unique_name)), - Session_label(Cstring(filename))).string()); - file_cap = rom.dataspace(); - } catch (Rom_connection::Rom_connection_failed) { - error("could not access ROM module \"", Cstring(filename), "\""); - return -1; - } - - /* copy ELF image to writable dataspace */ - Genode::size_t elf_size = Dataspace_client(file_cap).size(); - Dataspace_capability elf_cap = clone_rom(file_cap); - - /* create ram session for child with some of our own quota */ - static Ram_connection ram; - ram.ref_account(env()->ram_session_cap()); - env()->ram_session()->transfer_quota(ram.cap(), (Genode::size_t)ram_quota - elf_size); - - /* cap session for allocating capabilities for parent interfaces */ - static Cap_connection cap_session; - - static Service_registry parent_services; - - enum { CHILD_ROOT_EP_STACK = 1024*sizeof(addr_t) }; - static Rpc_entrypoint child_root_ep(&cap_session, CHILD_ROOT_EP_STACK, - "child_root_ep"); static Signal_receiver signal_receiver; @@ -354,19 +318,22 @@ extern "C" int fork() signal_handler_thread(&signal_receiver); signal_handler_thread.start(); - App_child *child = new (env()->heap()) App_child(unique_name, - elf_cap, - ldso_cap, - ram.cap(), - &cap_session, - &parent_services, - &child_root_ep, + App_child *child = new (env()->heap()) App_child(*genode_env, + filename, + genode_env->pd(), + genode_env->rm(), + ram_quota, &signal_receiver, target_node); _genode_child_resources = child->genode_child_resources(); - child->start(); + try { + child->start(); + } catch (...) { + Genode::error("Could not start child process"); + return -1; + } return GENODE_MAIN_LWPID; } diff --git a/repos/ports/src/app/gdb_monitor/genode_child_resources.h b/repos/ports/src/app/gdb_monitor/genode_child_resources.h index a0da1c84e..444b19450 100644 --- a/repos/ports/src/app/gdb_monitor/genode_child_resources.h +++ b/repos/ports/src/app/gdb_monitor/genode_child_resources.h @@ -14,10 +14,12 @@ #ifndef _GENODE_CHILD_RESOURCES_H_ #define _GENODE_CHILD_RESOURCES_H_ -#include "cpu_session_component.h" #include "region_map_component.h" -namespace Gdb_monitor { class Genode_child_resources; } +namespace Gdb_monitor { + class Cpu_session_component; + class Genode_child_resources; +} class Gdb_monitor::Genode_child_resources { diff --git a/repos/ports/src/app/gdb_monitor/main.cc b/repos/ports/src/app/gdb_monitor/main.cc index e6bc869c1..17a972bb7 100644 --- a/repos/ports/src/app/gdb_monitor/main.cc +++ b/repos/ports/src/app/gdb_monitor/main.cc @@ -11,6 +11,7 @@ * under the terms of the GNU General Public License version 2. */ +#include /* * Suppress messages of libc dummy functions @@ -30,10 +31,14 @@ extern "C" const char host_name[] = ""; extern "C" int gdbserver_main(int argc, const char *argv[]); -int main() +extern Genode::Env *genode_env; + +void Component::construct(Genode::Env &env) { + genode_env = &env; + int argc = 3; const char *argv[] = { "gdbserver", "/dev/terminal", "target", 0 }; - return gdbserver_main(argc, argv); + gdbserver_main(argc, argv); } 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 d62ecc218..88a2fe7b7 100644 --- a/repos/ports/src/app/gdb_monitor/pd_session_component.h +++ b/repos/ports/src/app/gdb_monitor/pd_session_component.h @@ -23,6 +23,7 @@ namespace Gdb_monitor { class Pd_session_component; + typedef Genode::Local_service Pd_service; using namespace Genode; } diff --git a/repos/ports/src/app/gdb_monitor/ram_root.h b/repos/ports/src/app/gdb_monitor/ram_root.h deleted file mode 100644 index 2478767a1..000000000 --- a/repos/ports/src/app/gdb_monitor/ram_root.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * \brief RAM root interface - * \author Norman Feske - * \date 2006-05-30 - */ - -/* - * Copyright (C) 2006-2016 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _RAM_ROOT_H_ -#define _RAM_ROOT_H_ - -#include - -#include "ram_session_component.h" - -namespace Gdb_monitor { class Ram_root; } - -class Gdb_monitor::Ram_root : public Root_component -{ - protected: - - Ram_session_component *_create_session(const char *args) - { - return new (md_alloc()) - Ram_session_component(args); - } - - public: - - /** - * Constructor - * - * \param session_ep entry point for managing ram session objects - * \param md_alloc meta-data allocator to be used by root component - */ - Ram_root(Rpc_entrypoint *session_ep, - Allocator *md_alloc) - : Root_component(session_ep, md_alloc) - { } -}; - -#endif /* _RAM_ROOT_H_ */ diff --git a/repos/ports/src/app/gdb_monitor/ram_session_component.cc b/repos/ports/src/app/gdb_monitor/ram_session_component.cc index d5c18ab76..fc0f880cf 100644 --- a/repos/ports/src/app/gdb_monitor/ram_session_component.cc +++ b/repos/ports/src/app/gdb_monitor/ram_session_component.cc @@ -20,8 +20,10 @@ using namespace Genode; using namespace Gdb_monitor; -Ram_session_component::Ram_session_component(const char *args) -: _parent_ram_session(env()->parent()->session(args)) +Ram_session_component::Ram_session_component(Genode::Env &env, const char *args, + Affinity const &affinity) +: _env(env), + _parent_ram_session(_env.session(_id_space_element.id(), args, affinity)) { } diff --git a/repos/ports/src/app/gdb_monitor/ram_session_component.h b/repos/ports/src/app/gdb_monitor/ram_session_component.h index 69fc7002c..ebdd335a0 100644 --- a/repos/ports/src/app/gdb_monitor/ram_session_component.h +++ b/repos/ports/src/app/gdb_monitor/ram_session_component.h @@ -28,6 +28,13 @@ class Gdb_monitor::Ram_session_component : public Rpc_object { private: + Genode::Env &_env; + + Genode::Parent::Client _parent_client; + + Id_space::Element const _id_space_element + { _parent_client, _env.id_space() }; + Genode::Ram_session_client _parent_ram_session; public: @@ -35,7 +42,8 @@ class Gdb_monitor::Ram_session_component : public Rpc_object /** * Constructor */ - Ram_session_component(const char *args); + Ram_session_component(Genode::Env &env, const char *args, + Affinity const &affinity); /** * Destructor diff --git a/repos/ports/src/app/gdb_monitor/rom.h b/repos/ports/src/app/gdb_monitor/rom.h index 758a21b16..e35a80d5f 100644 --- a/repos/ports/src/app/gdb_monitor/rom.h +++ b/repos/ports/src/app/gdb_monitor/rom.h @@ -25,8 +25,9 @@ namespace Gdb_monitor { class Rom_session_component; - class Rom_root; - class Rom_service; + class Local_rom_factory; + typedef Genode::Local_service Rom_service; + using namespace Genode; } @@ -65,68 +66,68 @@ class Gdb_monitor::Rom_session_component : public Rpc_object { private: + Genode::Rpc_entrypoint &_ep; + Capability _clone_cap; public: - Rom_session_component(char const *filename) - : _clone_cap(clone_rom(Rom_connection(filename).dataspace())) - { } + Rom_session_component(Genode::Rpc_entrypoint &ep, char const *filename) + : _ep(ep), + _clone_cap(clone_rom(Rom_connection(filename).dataspace())) + { _ep.manage(this); } - ~Rom_session_component() { env()->ram_session()->free(_clone_cap); } + ~Rom_session_component() + { + env()->ram_session()->free(_clone_cap); + _ep.dissolve(this); + } - Capability dataspace() + /*************************** + ** ROM session interface ** + ***************************/ + + Rom_dataspace_capability dataspace() override { return static_cap_cast( static_cap_cast(_clone_cap)); } - void release() { } - - void sigh(Genode::Signal_context_capability) { } + void sigh(Genode::Signal_context_capability) override { } }; -class Gdb_monitor::Rom_root : public Root_component -{ - protected: - - Rom_session_component *_create_session(char const *args) - { - Session_label const label = label_from_args(args); - - return new (md_alloc()) - Rom_session_component(label.last_element().string()); - } - - public: - - Rom_root(Rpc_entrypoint *session_ep, - Allocator *md_alloc) - : Root_component(session_ep, md_alloc) - { } -}; - - -class Gdb_monitor::Rom_service : public Service +class Gdb_monitor::Local_rom_factory : public Rom_service::Factory { private: - Rom_root _root; + Genode::Env &_env; + Genode::Rpc_entrypoint &_ep; public: - Rom_service(Rpc_entrypoint *entrypoint, - Allocator *md_alloc) - : Service("ROM"), _root(entrypoint, md_alloc) - { } + Local_rom_factory(Genode::Env &env, Genode::Rpc_entrypoint &ep) + : _env(env), _ep(ep) { } - Capability session(char const *args, Affinity const &affinity) { - return _root.session(args, affinity); } + /*********************** + ** Factory interface ** + ***********************/ - void upgrade(Capability, char const *) { } + Rom_session_component &create(Args const &args, Affinity) override + { + Session_label const label = label_from_args(args.string()); - void close(Capability cap) { _root.close(cap); } + return *new (env()->heap()) + Rom_session_component(_ep, label.last_element().string()); + } + + void upgrade(Rom_session_component &, Args const &) override { } + + void destroy(Rom_session_component &session) override + { + Genode::destroy(env()->heap(), &session); + } }; + #endif /* _ROM_H_ */ diff --git a/repos/ports/src/app/seoul/main.cc b/repos/ports/src/app/seoul/main.cc index 56bcda80a..353b700f6 100644 --- a/repos/ports/src/app/seoul/main.cc +++ b/repos/ports/src/app/seoul/main.cc @@ -32,8 +32,8 @@ */ /* Genode includes */ +#include #include -#include #include #include #include @@ -699,7 +699,7 @@ class Vcpu_dispatcher : public Vcpu_handler, Vcpu_dispatcher(Genode::Lock &vcpu_lock, - Genode::Cap_connection &cap_connection, + Genode::Env &env, VCpu *unsynchronized_vcpu, Guest_memory &guest_memory, Synced_motherboard &motherboard, @@ -709,7 +709,7 @@ class Vcpu_dispatcher : public Vcpu_handler, Genode::Cpu_session *cpu_session, Genode::Affinity::Location &location) : - Vcpu_handler(STACK_SIZE, cap_connection, cpu_session, location), + Vcpu_handler(env, STACK_SIZE, cpu_session, location), _vcpu(vcpu_lock, unsynchronized_vcpu), _vcpu_thread(vcpu_thread), _guest_memory(guest_memory), @@ -849,9 +849,9 @@ class Machine : public StaticReceiver { private: + Genode::Env &_env;; Genode::Rom_connection _hip_rom; Hip * const _hip; - Genode::Cap_connection _cap; Clock _clock; Genode::Lock _motherboard_lock; Motherboard _unsynchronized_motherboard; @@ -955,7 +955,7 @@ class Machine : public StaticReceiver Vcpu_dispatcher *vcpu_dispatcher = new Vcpu_dispatcher(_motherboard_lock, - _cap, + _env, msg.vcpu, _guest_memory, _motherboard, @@ -1246,10 +1246,11 @@ class Machine : public StaticReceiver /** * Constructor */ - Machine(Boot_module_provider &boot_modules, Guest_memory &guest_memory, - bool colocate) + Machine(Genode::Env &env, Boot_module_provider &boot_modules, + Guest_memory &guest_memory, bool colocate) : - _hip_rom("hypervisor_info_page"), + _env(env), + _hip_rom(_env, "hypervisor_info_page"), _hip(Genode::env()->rm_session()->attach(_hip_rom.dataspace())), _clock(_hip->tsc_freq*1000), _motherboard_lock(Genode::Lock::LOCKED), @@ -1403,7 +1404,7 @@ extern unsigned long _prog_img_beg; /* begin of program image (link address) */ extern unsigned long _prog_img_end; /* end of program image */ -int main(int argc, char **argv) +void Component::construct(Genode::Env &env) { Genode::addr_t fb_size = 4*1024*1024; Genode::addr_t vm_size; @@ -1434,7 +1435,7 @@ int main(int argc, char **argv) Genode::Xml_node node = Genode::config()->xml_node().sub_node("machine").sub_node("vga"); Genode::Xml_node::Attribute arg = node.attribute("fb_size"); - unsigned long val; + unsigned long val = 0; arg.value(&val); fb_size = val*1024; } catch (...) { } @@ -1484,7 +1485,8 @@ int main(int argc, char **argv) !guest_memory.backing_store_fb_local_base()) { PERR("Not enough space left for %s - exit", guest_memory.backing_store_local_base() ? "framebuffer" : "VMM"); - return 1; + env.parent().exit(-1); + return; } Genode::printf("\n--- Setup VM ---\n"); @@ -1493,17 +1495,17 @@ int main(int argc, char **argv) boot_modules(Genode::config()->xml_node().sub_node("multiboot")); /* create the PC machine based on the configuration given */ - static Machine machine(boot_modules, guest_memory, colocate); + static Machine machine(env, boot_modules, guest_memory, colocate); /* create console thread */ - Vancouver_console vcon(machine.motherboard(), fb_size, guest_memory.fb_ds()); + static Vancouver_console vcon(machine.motherboard(), fb_size, guest_memory.fb_ds()); vcon.register_host_operations(machine.unsynchronized_motherboard()); /* create disk thread */ - Vancouver_disk vdisk(machine.motherboard(), - guest_memory.backing_store_local_base(), - guest_memory.backing_store_size()); + static Vancouver_disk vdisk(machine.motherboard(), + guest_memory.backing_store_local_base(), + guest_memory.backing_store_size()); vdisk.register_host_operations(machine.unsynchronized_motherboard()); @@ -1512,7 +1514,4 @@ int main(int argc, char **argv) Genode::printf("\n--- Booting VM ---\n"); machine.boot(); - - Genode::sleep_forever(); - return 0; } diff --git a/repos/ports/src/lib/gdbserver_platform/spec/foc/native_cpu.cc b/repos/ports/src/lib/gdbserver_platform/spec/foc/native_cpu.cc index fb512ee01..1e32a0c32 100644 --- a/repos/ports/src/lib/gdbserver_platform/spec/foc/native_cpu.cc +++ b/repos/ports/src/lib/gdbserver_platform/spec/foc/native_cpu.cc @@ -82,7 +82,7 @@ Gdb_monitor::Cpu_session_component::_setup_native_cpu() void Gdb_monitor::Cpu_session_component::_cleanup_native_cpu() { Native_cpu_component *native_cpu_component = nullptr; - _thread_ep->apply(_native_cpu_cap, [&] (Native_cpu_component *c) { native_cpu_component = c; }); + _ep.apply(_native_cpu_cap, [&] (Native_cpu_component *c) { native_cpu_component = c; }); if (!native_cpu_component) return; diff --git a/repos/ports/src/lib/gdbserver_platform/spec/nova/native_cpu.cc b/repos/ports/src/lib/gdbserver_platform/spec/nova/native_cpu.cc index d5caf0d7b..1ab8c0a6d 100644 --- a/repos/ports/src/lib/gdbserver_platform/spec/nova/native_cpu.cc +++ b/repos/ports/src/lib/gdbserver_platform/spec/nova/native_cpu.cc @@ -71,7 +71,7 @@ Gdb_monitor::Cpu_session_component::_setup_native_cpu() void Gdb_monitor::Cpu_session_component::_cleanup_native_cpu() { Native_cpu_component *native_cpu_component = nullptr; - _thread_ep->apply(_native_cpu_cap, [&] (Native_cpu_component *c) { native_cpu_component = c; }); + _ep.apply(_native_cpu_cap, [&] (Native_cpu_component *c) { native_cpu_component = c; }); if (!native_cpu_component) return; diff --git a/repos/ports/src/lib/libc_noux/plugin.cc b/repos/ports/src/lib/libc_noux/plugin.cc index 0df340594..7fd095eeb 100644 --- a/repos/ports/src/lib/libc_noux/plugin.cc +++ b/repos/ports/src/lib/libc_noux/plugin.cc @@ -16,8 +16,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -89,17 +88,11 @@ class Noux_connection private: Noux::Connection _connection; - Noux::Sysio *_sysio; - Noux::Sysio *_obtain_sysio() - { - return Genode::env()->rm_session()->attach(_connection.sysio_dataspace()); - } + Genode::Attached_dataspace _sysio_ds { _connection.sysio_dataspace() }; public: - Noux_connection() : _sysio(_obtain_sysio()) { } - /** * Return the capability of the local stack-area region map * @@ -111,7 +104,26 @@ class Noux_connection } Noux::Session *session() { return &_connection; } - Noux::Sysio *sysio() { return _sysio; } + Noux::Sysio *sysio() { return _sysio_ds.local_addr(); } + + void reconnect() + { + using namespace Genode; + + /* + * Release Id_space::Element of the local ID space. + */ + _connection.discard_session_id(); + + /* + * Obtain new noux connection. Note that we cannot reconstruct + * the connection via a 'Volatile_object' because this would + * result in an inconsistent referernce count when attempting + * to destruct the session capability in the just-cleared + * capability space. + */ + construct_at(this); + } }; @@ -532,12 +544,8 @@ extern "C" void fork_trampoline() /* reinitialize standard-output connection */ stdout_reconnect(); - /* reinitialize config */ - Genode::Config *config = Genode::config(); - construct_at(config); - /* reinitialize noux connection */ - construct_at(noux_connection()); + noux_connection()->reconnect(); /* reinitialize main-thread object which implies reinit of stack area */ auto stack_area_rm = noux_connection()->stack_area_region_map(in_stack_area); @@ -2229,14 +2237,14 @@ void init_libc_noux(void) sigemptyset(&signal_mask); /* copy command-line arguments from 'args' ROM dataspace */ - Genode::Rom_connection args_rom("args"); - char *args = (char *)Genode::env()->rm_session()-> - attach(args_rom.dataspace()); - - enum { MAX_ARGS = 256, ARG_BUF_SIZE = 4096 }; + enum { MAX_ARGS = 256, ARG_BUF_SIZE = 4096UL }; static char *argv[MAX_ARGS]; static char arg_buf[ARG_BUF_SIZE]; - Genode::memcpy(arg_buf, args, ARG_BUF_SIZE); + { + Genode::Attached_rom_dataspace ds("args"); + Genode::memcpy(arg_buf, ds.local_addr(), + Genode::min((size_t)ARG_BUF_SIZE, ds.size())); + } int argc = 0; for (unsigned i = 0; arg_buf[i] && (i < ARG_BUF_SIZE - 2); ) { @@ -2252,7 +2260,7 @@ void init_libc_noux(void) } argv[argc] = &arg_buf[i]; - i += Genode::strlen(&args[i]) + 1; /* skip null-termination */ + i += Genode::strlen(&arg_buf[i]) + 1; /* skip null-termination */ argc++; } @@ -2264,12 +2272,15 @@ void init_libc_noux(void) * Make environment variables from 'env' ROM dataspace available to libc's * 'environ'. */ - Genode::Rom_connection env_rom("env"); - Genode::Dataspace_capability env_ds = env_rom.dataspace(); - char *env_string = (char *)Genode::env()->rm_session()->attach(env_ds); - - enum { ENV_MAX_ENTRIES = 128 }; + enum { ENV_MAX_ENTRIES = 128, ENV_BUF_SIZE = 8*1024 }; static char *env_array[ENV_MAX_ENTRIES]; + static char env_buf[ENV_BUF_SIZE]; + { + Genode::Attached_rom_dataspace ds("env"); + Genode::memcpy(env_buf, ds.local_addr(), + Genode::min((size_t)ENV_BUF_SIZE, ds.size())); + } + char *env_string = &env_buf[0]; unsigned num_entries = 0; /* index within 'env_array' */ diff --git a/repos/ports/src/noux/child.h b/repos/ports/src/noux/child.h index 5d0df81d3..0a511fbb9 100644 --- a/repos/ports/src/noux/child.h +++ b/repos/ports/src/noux/child.h @@ -38,8 +38,6 @@ #include #include #include -#include -#include #include namespace Noux { @@ -87,11 +85,6 @@ namespace Noux { */ Io_receptor_registry *io_receptor_registry(); - /** - * Return ELF binary of dynamic linker - */ - Dataspace_capability ldso_ds_cap(); - /* * Return lock for protecting the signal queue */ @@ -135,67 +128,77 @@ namespace Noux { { private: + Child_policy::Name const _name; + Parent_exit *_parent_exit; Kill_broadcaster &_kill_broadcaster; Parent_execve &_parent_execve; - Signal_receiver *_sig_rec; + Signal_receiver &_sig_rec; + + Vfs::Dir_file_system &_root_dir; - Allocator *_alloc; Destruct_queue &_destruct_queue; - Destruct_dispatcher _destruct_dispatcher; - Signal_context_capability _destruct_context_cap; + Destruct_dispatcher _destruct_dispatcher { _destruct_queue, this }; + Signal_context_capability _destruct_context_cap = + _sig_rec.manage(&_destruct_dispatcher); - Cap_session * const _cap_session; + Pd_session &_env_pd_session; /* used for creating 'Rpc_entrypoint' */ - enum { STACK_SIZE = 5*1024*sizeof(long) }; - Rpc_entrypoint _entrypoint; + /** + * Entrypoint used to serve the RPC interfaces of the + * locally-provided services + */ + enum { STACK_SIZE = 8*1024*sizeof(long) }; + Rpc_entrypoint _ep { &_env_pd_session, STACK_SIZE, "noux_process", false }; + + Ram_session &_ref_ram; + Ram_session_capability const _ref_ram_cap; /** * Registry of dataspaces owned by the Noux process */ Dataspace_registry _ds_registry; - Pd_session_component _pd; + /** + * Locally-provided PD service + */ + typedef Local_service Pd_service; + Pd_session_component _pd { _ep, _name, _ds_registry }; + Pd_service::Single_session_factory _pd_factory { _pd }; + Pd_service _pd_service { _pd_factory }; /** - * Resources assigned to the child + * Locally-provided RAM service */ - struct Resources - { - /** - * Entrypoint used to serve the RPC interfaces of the - * locally-provided services - */ - Rpc_entrypoint &ep; + typedef Local_service Ram_service; + Ram_session_component _ram { _ep, _ds_registry }; + Ram_service::Single_session_factory _ram_factory { _ram }; + Ram_service _ram_service { _ram_factory }; - /** - * Locally-provided services for accessing platform resources - */ - Ram_session_component ram; - Cpu_session_component cpu; + /** + * Locally-provided CPU service + */ + typedef Local_service Cpu_service; + Cpu_session_component _cpu { _ep, _name, false }; + Cpu_service::Single_session_factory _cpu_factory { _cpu }; + Cpu_service _cpu_service { _cpu_factory }; - Resources(char const *label, Rpc_entrypoint &ep, - Dataspace_registry &ds_registry, - Pd_session_capability core_pd_cap, bool forked) - : - ep(ep), ram(ds_registry), cpu(label, core_pd_cap, forked) - { - ep.manage(&ram); - ep.manage(&cpu); - } + /* + * Locally-provided Noux service + */ + Session_capability const _noux_session_cap = + Session_capability(_ep.manage(this)); - ~Resources() - { - ep.dissolve(&ram); - ep.dissolve(&cpu); - } + typedef Local_service > Noux_service; + Noux_service::Single_session_factory _noux_factory { *this }; + Noux_service _noux_service { _noux_factory }; - } _resources; - - Genode::Child::Initial_thread _initial_thread; - - Region_map_client _address_space { _pd.address_space() }; + /* + * Locally-provided ROM service + */ + Local_rom_factory _rom_factory { _ep, _root_dir, _ds_registry }; + Local_rom_service _rom_service { _rom_factory }; /** * Command line arguments @@ -210,61 +213,26 @@ namespace Noux { /* * Child configuration */ - Child_config _config; - - /** - * ELF binary handling - */ - struct Elf - { - enum { NAME_MAX_LEN = 128 }; - char _name[NAME_MAX_LEN]; - - Vfs::Dir_file_system * const _root_dir; - Dataspace_capability const _binary_ds; - - Elf(char const * const binary_name, Vfs::Dir_file_system * root_dir, - Dataspace_capability binary_ds) - : - _root_dir(root_dir), _binary_ds(binary_ds) - { - strncpy(_name, binary_name, sizeof(_name)); - _name[NAME_MAX_LEN - 1] = 0; - } - - ~Elf() { _root_dir->release(_name, _binary_ds); } - } _elf; + Child_config _config { *env()->ram_session() }; enum { PAGE_SIZE = 4096, PAGE_MASK = ~(PAGE_SIZE - 1) }; enum { SYSIO_DS_SIZE = PAGE_MASK & (sizeof(Sysio) + PAGE_SIZE - 1) }; - Attached_ram_dataspace _sysio_ds; - Sysio * const _sysio; + Attached_ram_dataspace _sysio_ds { env()->ram_session(), SYSIO_DS_SIZE }; + Sysio &_sysio = *_sysio_ds.local_addr(); typedef Ring_buffer Signal_queue; Signal_queue _pending_signals; - Session_capability const _noux_session_cap; + Parent_services &_parent_services; - Local_noux_service _local_noux_service; - Parent_service _parent_ram_service; - Parent_service _parent_pd_service; - Local_cpu_service _local_cpu_service; - Local_pd_service _local_pd_service; - Local_rom_service _local_rom_service; - Service_registry &_parent_services; - - Static_dataspace_info _binary_ds_info; Static_dataspace_info _sysio_ds_info; - Static_dataspace_info _ldso_ds_info; Static_dataspace_info _args_ds_info; Static_dataspace_info _env_ds_info; Static_dataspace_info _config_ds_info; - Dataspace_capability _ldso_ds; - - Child_policy _child_policy; + Child_policy _child_policy; Genode::Child _child; @@ -326,19 +294,16 @@ namespace Noux { io->unregister_wake_up_notifier(¬ifier); } - Vfs::Dir_file_system * const root_dir() { return _elf._root_dir; } - /** * Method for handling noux network related system calls */ - bool _syscall_net(Syscall sc); void _destruct() { - _sig_rec->dissolve(&_destruct_dispatcher); + _sig_rec.dissolve(&_destruct_dispatcher); - _entrypoint.dissolve(this); + _ep.dissolve(this); if (init_process(this)) init_process_exited(_child_policy.exit_value()); @@ -364,82 +329,56 @@ namespace Noux { * \throw Insufficent_memory if the child could not be started by * the parent */ - Child(char const *binary_name, - Dataspace_capability ldso_ds, - Parent_exit *parent_exit, - Kill_broadcaster &kill_broadcaster, - Parent_execve &parent_execve, - int pid, - Signal_receiver *sig_rec, - Vfs::Dir_file_system *root_dir, - Args const &args, - Sysio::Env const &env, - Cap_session *cap_session, - Service_registry &parent_services, - Rpc_entrypoint &resources_ep, - bool forked, - Allocator *destruct_alloc, - Destruct_queue &destruct_queue, - bool verbose) + Child(Child_policy::Name const &name, + Parent_exit *parent_exit, + Kill_broadcaster &kill_broadcaster, + Parent_execve &parent_execve, + int pid, + Signal_receiver &sig_rec, + Vfs::Dir_file_system &root_dir, + Args const &args, + Sysio::Env const &env, + Pd_session &env_pd_session, + Ram_session &ref_ram, + Ram_session_capability ref_ram_cap, + Parent_services &parent_services, + Rpc_entrypoint &resources_ep, + bool forked, + Allocator &destruct_alloc, + Destruct_queue &destruct_queue, + bool verbose) : Family_member(pid), - Destruct_queue::Element(destruct_alloc), + Destruct_queue::Element(&destruct_alloc), + _name(name), _parent_exit(parent_exit), _kill_broadcaster(kill_broadcaster), _parent_execve(parent_execve), _sig_rec(sig_rec), + _root_dir(root_dir), _destruct_queue(destruct_queue), - _destruct_dispatcher(_destruct_queue, this), - _destruct_context_cap(sig_rec->manage(&_destruct_dispatcher)), - _cap_session(cap_session), - _entrypoint(cap_session, STACK_SIZE, "noux_process", false), - _pd(binary_name, resources_ep, _ds_registry), - _resources(binary_name, resources_ep, _ds_registry, _pd.core_pd_cap(), false), - _initial_thread(_resources.cpu, _pd.cap(), binary_name), + _env_pd_session(env_pd_session), + _ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap), _args(ARGS_DS_SIZE, args), _env(env), - _config(*Genode::env()->ram_session()), - _elf(binary_name, root_dir, root_dir->dataspace(binary_name)), - _sysio_ds(Genode::env()->ram_session(), SYSIO_DS_SIZE), - _sysio(_sysio_ds.local_addr()), - _noux_session_cap(Session_capability(_entrypoint.manage(this))), - _local_noux_service(_noux_session_cap), - _parent_ram_service(""), - _parent_pd_service(""), - _local_cpu_service(_entrypoint, _resources.cpu.cpu_cap()), - _local_pd_service(_entrypoint, _pd.core_pd_cap()), - _local_rom_service(_entrypoint, _ds_registry), _parent_services(parent_services), - _binary_ds_info(_ds_registry, _elf._binary_ds), _sysio_ds_info(_ds_registry, _sysio_ds.cap()), - _ldso_ds_info(_ds_registry, ldso_ds_cap()), _args_ds_info(_ds_registry, _args.cap()), _env_ds_info(_ds_registry, _env.cap()), _config_ds_info(_ds_registry, _config.cap()), - _ldso_ds(ldso_ds), - _child_policy(_elf._name, _elf._binary_ds, _args.cap(), - _env.cap(), _config.cap(), - _entrypoint, _local_noux_service, - _local_rom_service, _parent_services, + _child_policy(name, + forked ? Rom_session_component::forked_magic_binary_name() + : name, + _args.cap(), _env.cap(), _config.cap(), + _ep, _pd_service, _ram_service, _cpu_service, + _noux_service, _rom_service, _parent_services, *this, parent_exit, *this, _destruct_context_cap, - _resources.ram, verbose), - _child(forked ? Dataspace_capability() : _elf._binary_ds, - _ldso_ds, _pd.cap(), _pd, - _resources.ram.cap(), _resources.ram, - _resources.cpu.cap(), _initial_thread, - *Genode::env()->rm_session(), _address_space, - _entrypoint, _child_policy, _local_pd_service, - _parent_ram_service, _local_cpu_service) + ref_ram, ref_ram_cap, verbose), + _child(*Genode::env()->rm_session(), _ep, _child_policy) { if (verbose) _args.dump(); - if (!forked && !_elf._binary_ds.valid()) { - error("lookup of executable \"", binary_name, "\" failed"); - - _destruct(); - throw Binary_does_not_exist(); - } if (!_child.main_thread_cap().valid()) { _destruct(); throw Insufficient_memory(); @@ -448,7 +387,7 @@ namespace Noux { ~Child() { _destruct(); } - void start() { _entrypoint.activate(); } + void start() { _ep.activate(); } void start_forked_main_thread(addr_t ip, addr_t sp, addr_t parent_cap_addr) { @@ -458,7 +397,7 @@ namespace Noux { _pd.poke(parent_cap_addr, &raw, sizeof(raw)); /* start execution of new main thread at supplied trampoline */ - _resources.cpu.start_main_thread(ip, sp); + _cpu.start_main_thread(ip, sp); } void submit_exit_signal() @@ -473,8 +412,9 @@ namespace Noux { } } - Ram_session_capability ram() const { return _resources.ram.cap(); } - Pd_session_capability pd() const { return _pd.cap(); } + Ram_session_component &ram() { return _ram; } + Pd_session_component &pd() { return _pd; } + Dataspace_registry &ds_registry() { return _ds_registry; } @@ -587,22 +527,22 @@ namespace Noux { Lock::Guard signal_lock_guard(signal_lock()); Child *child = new Child(filename, - _ldso_ds, - _parent_exit, - _kill_broadcaster, - _parent_execve, - pid(), - _sig_rec, - root_dir(), - args, - env, - _cap_session, - _parent_services, - _resources.ep, - false, - Genode::env()->heap(), - _destruct_queue, - verbose); + _parent_exit, + _kill_broadcaster, + _parent_execve, + pid(), + _sig_rec, + _root_dir, + args, + env, + _env_pd_session, + _ref_ram, _ref_ram_cap, + _parent_services, + _ep, + false, + *Genode::env()->heap(), + _destruct_queue, + verbose); _assign_io_channels_to(child); diff --git a/repos/ports/src/noux/child_policy.h b/repos/ports/src/noux/child_policy.h index 2aae90c36..01e886cbd 100644 --- a/repos/ports/src/noux/child_policy.h +++ b/repos/ports/src/noux/child_policy.h @@ -21,64 +21,90 @@ #include #include #include -#include #include namespace Noux { + typedef Registered Parent_service; + typedef Registry Parent_services; + + typedef Local_service Pd_service; + typedef Local_service Ram_service; + typedef Local_service Cpu_service; + typedef Local_service > Noux_service; + class Child_policy : public Genode::Child_policy { private: - char const *_name; + Name const _name; + Binary_name const _binary_name; Init::Child_policy_enforce_labeling _labeling_policy; - Init::Child_policy_provide_rom_file _binary_policy; Init::Child_policy_provide_rom_file _args_policy; Init::Child_policy_provide_rom_file _env_policy; Init::Child_policy_provide_rom_file _config_policy; - Local_noux_service &_local_noux_service; - Local_rom_service &_local_rom_service; - Service_registry &_parent_services; + Pd_service &_pd_service; + Ram_service &_ram_service; + Cpu_service &_cpu_service; + Noux_service &_noux_service; + Local_rom_service &_rom_service; + Parent_services &_parent_services; Family_member &_family_member; Parent_exit *_parent_exit; File_descriptor_registry &_file_descriptor_registry; Signal_context_capability _destruct_context_cap; - Ram_session &_ref_ram_session; + Ram_session &_ref_ram; + Ram_session_capability _ref_ram_cap; int _exit_value; bool _verbose; + template + static Genode::Service *_find_service(Genode::Registry &services, + Genode::Service::Name const &name) + { + Genode::Service *service = nullptr; + services.for_each([&] (T &s) { + if (!service && (s.name() == name)) + service = &s; }); + return service; + } + public: - Child_policy(char const *name, - Dataspace_capability binary_ds, + Child_policy(Name const &name, + Binary_name const &binary_name, Dataspace_capability args_ds, Dataspace_capability env_ds, Dataspace_capability config_ds, Rpc_entrypoint &entrypoint, - Local_noux_service &local_noux_service, - Local_rom_service &local_rom_service, - Service_registry &parent_services, + Pd_service &pd_service, + Ram_service &ram_service, + Cpu_service &cpu_service, + Noux_service &noux_service, + Local_rom_service &rom_service, + Parent_services &parent_services, Family_member &family_member, Parent_exit *parent_exit, File_descriptor_registry &file_descriptor_registry, Signal_context_capability destruct_context_cap, - Ram_session &ref_ram_session, + Ram_session &ref_ram, + Ram_session_capability ref_ram_cap, bool verbose) : _name(name), - _labeling_policy(_name), - _binary_policy("binary", binary_ds, &entrypoint), + _binary_name(binary_name), + _labeling_policy(_name.string()), _args_policy( "args", args_ds, &entrypoint), _env_policy( "env", env_ds, &entrypoint), _config_policy("config", config_ds, &entrypoint), - _local_noux_service(local_noux_service), - _local_rom_service(local_rom_service), - _parent_services(parent_services), + _pd_service(pd_service), _ram_service(ram_service), + _cpu_service(cpu_service), _noux_service(noux_service), + _rom_service(rom_service), _parent_services(parent_services), _family_member(family_member), _parent_exit(parent_exit), _file_descriptor_registry(file_descriptor_registry), _destruct_context_cap(destruct_context_cap), - _ref_ram_session(ref_ram_session), + _ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap), _exit_value(~0), _verbose(verbose) { } @@ -89,40 +115,58 @@ namespace Noux { ** Child policy interface ** ****************************/ - const char *name() const { return _name; } + Name name() const override { return _name; } + Binary_name binary_name() const override { return _binary_name; } - Service *resolve_session_request(const char *service_name, - const char *args) + Ram_session &ref_ram() override { return _ref_ram; } + + Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; } + + void init(Ram_session &session, Ram_session_capability cap) override { - Service *service = 0; - - /* check for local ROM file requests */ - if ((service = _args_policy.resolve_session_request(service_name, args)) - || (service = _env_policy.resolve_session_request(service_name, args)) - || (service = _config_policy.resolve_session_request(service_name, args)) - || (service = _binary_policy.resolve_session_request(service_name, args))) - return service; - - /* check for locally implemented noux service */ - if (strcmp(service_name, Session::service_name()) == 0) - return &_local_noux_service; - - /* - * Check for local ROM service - */ - if (strcmp(service_name, Rom_session::service_name()) == 0) - return &_local_rom_service; - - return _parent_services.find(service_name); + session.ref_account(_ref_ram_cap); } - void filter_session_args(const char *service, - char *args, size_t args_len) + Service &resolve_session_request(Service::Name const &service_name, + Session_state::Args const &args) override { - _labeling_policy.filter_session_args(service, args, args_len); + Session_label const label(Genode::label_from_args(args.string())); + + /* route initial ROM requests (binary and linker) to the parent */ + if (service_name == Genode::Rom_session::service_name()) { + if (label.last_element() == binary_name()) return _rom_service; + if (label.last_element() == linker_name()) return _rom_service; + } + + Genode::Service *service = nullptr; + + /* check for local ROM requests */ + if ((service = _args_policy .resolve_session_request(service_name.string(), args.string())) + || (service = _env_policy .resolve_session_request(service_name.string(), args.string())) + || (service = _config_policy.resolve_session_request(service_name.string(), args.string()))) + return *service; + + /* check for local services */ + if (service_name == Genode::Ram_session::service_name()) return _ram_service; + if (service_name == Genode::Cpu_session::service_name()) return _cpu_service; + if (service_name == Genode::Rom_session::service_name()) return _rom_service; + if (service_name == Genode::Pd_session::service_name()) return _pd_service; + if (service_name == Noux::Session::service_name()) return _noux_service; + + /* check for parent services */ + if ((service = _find_service(_parent_services, service_name))) + return *service; + + throw Parent::Service_denied(); } - void exit(int exit_value) + void filter_session_args(Genode::Service::Name const &service, + char *args, Genode::size_t args_len) override + { + _labeling_policy.filter_session_args(service.string(), args, args_len); + } + + void exit(int exit_value) override { _exit_value = exit_value; @@ -147,12 +191,11 @@ namespace Noux { } } - Ram_session *ref_ram_session() + Region_map *address_space(Pd_session &pd) override { - return &_ref_ram_session; + return &static_cast(pd).address_space_region_map(); } }; } #endif /* _NOUX__CHILD_POLICY_H_ */ - diff --git a/repos/ports/src/noux/cpu_session_component.h b/repos/ports/src/noux/cpu_session_component.h index 203e0d912..64d0046aa 100644 --- a/repos/ports/src/noux/cpu_session_component.h +++ b/repos/ports/src/noux/cpu_session_component.h @@ -25,10 +25,14 @@ #define _NOUX__CPU_SESSION_COMPONENT_H_ /* Genode includes */ +#include #include #include #include +/* Noux includes */ +#include + namespace Noux { using namespace Genode; @@ -37,9 +41,9 @@ namespace Noux { { private: - Pd_session_capability _core_pd; - bool const _forked; - Cpu_connection _cpu; + Rpc_entrypoint &_ep; + bool const _forked; + Cpu_connection _cpu; enum { MAX_THREADS = 8, MAIN_THREAD_IDX = 0 }; @@ -50,8 +54,6 @@ namespace Noux { /** * Constructor * - * \param core_pd capability of PD session at core to be used - * as argument of 'create_thread' * \param forked false if the CPU session belongs to a child * created via execve or to the init process, or * true if the CPU session belongs to a newly @@ -60,9 +62,12 @@ namespace Noux { * The 'forked' parameter controls the policy applied to the * startup of the main thread. */ - Cpu_session_component(char const *label, - Pd_session_capability core_pd, bool forked) - : _core_pd(core_pd), _forked(forked), _cpu(label) { } + Cpu_session_component(Rpc_entrypoint &ep, Child_policy::Name const &label, + bool forked) + : _ep(ep), _forked(forked), _cpu(label.string()) + { _ep.manage(this); } + + ~Cpu_session_component() { _ep.dissolve(this); } /** * Explicitly start main thread, only meaningful when @@ -81,7 +86,7 @@ namespace Noux { ** Cpu_session interface ** ***************************/ - Thread_capability create_thread(Capability, + Thread_capability create_thread(Capability pd_cap, Name const &name, Affinity::Location affinity, Weight weight, @@ -92,14 +97,16 @@ namespace Noux { if (_threads[i].valid()) continue; - /* - * Note that we don't use the PD-capability argument (which - * refers to our virtualized PD session) but the physical - * core PD. - */ - Thread_capability cap = - _cpu.create_thread(_core_pd, name, affinity, weight, utcb); + auto lambda = [&] (Pd_session_component *pd) + { + if (!pd) + throw Thread_creation_failed(); + return _cpu.create_thread(pd->core_pd_cap(), name, + affinity, weight, utcb); + }; + + Thread_capability cap = _ep.apply(pd_cap, lambda); _threads[i] = cap; return cap; } diff --git a/repos/ports/src/noux/dataspace_registry.h b/repos/ports/src/noux/dataspace_registry.h index e90efd47f..cda9fab6f 100644 --- a/repos/ports/src/noux/dataspace_registry.h +++ b/repos/ports/src/noux/dataspace_registry.h @@ -92,9 +92,9 @@ namespace Noux { * RM session) * \return capability for the new dataspace */ - virtual Dataspace_capability fork(Ram_session_capability ram, - Dataspace_registry &ds_registry, - Rpc_entrypoint &ep) = 0; + virtual Dataspace_capability fork(Ram_session &ram, + Dataspace_registry &ds_registry, + Rpc_entrypoint &ep) = 0; /** * Write raw byte sequence into dataspace @@ -164,9 +164,9 @@ namespace Noux { _ds_registry.apply(ds_cap(), lambda); } - Dataspace_capability fork(Ram_session_capability, + Dataspace_capability fork(Ram_session &, Dataspace_registry &, - Rpc_entrypoint &) + Rpc_entrypoint &) { return ds_cap(); } diff --git a/repos/ports/src/noux/local_cpu_service.h b/repos/ports/src/noux/local_cpu_service.h deleted file mode 100644 index 725adbc69..000000000 --- a/repos/ports/src/noux/local_cpu_service.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * \brief CPU service provided to Noux processes - * \author Josef Soentgen - * \date 2013-04-16 - */ - -/* - * Copyright (C) 2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _NOUX__LOCAL_CPU_SERVICE_H_ -#define _NOUX__LOCAL_CPU_SERVICE_H_ - -/* Genode includes */ -#include - -/* Noux includes */ -#include - -namespace Noux { - - class Local_cpu_service : public Service - { - private: - - Rpc_entrypoint &_ep; - Cpu_session_capability _cap; - - public: - - Local_cpu_service(Rpc_entrypoint &ep, Cpu_session_capability cap) - : - Service(Cpu_session::service_name()), _ep(ep), - _cap(cap) - { } - - Genode::Session_capability session(const char *args, Affinity const &) - { - Genode::warning(__func__, ": implement me!"); - return Genode::Session_capability(); - } - - void upgrade(Genode::Session_capability, const char *args) - { - env()->parent()->upgrade(_cap, args); - } - - void close(Genode::Session_capability session) - { - Genode::warning(__func__, ": implement me!"); - } - }; -} - -#endif /* _NOUX__LOCAL_CPU_SERVICE_H_ */ diff --git a/repos/ports/src/noux/local_noux_service.h b/repos/ports/src/noux/local_noux_service.h deleted file mode 100644 index 31c799d2e..000000000 --- a/repos/ports/src/noux/local_noux_service.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * \brief Locally-provided Noux service - * \author Norman Feske - * \date 2011-02-17 - */ - -/* - * Copyright (C) 2012-2013 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _NOUX__LOCAL_NOUX_SERVICE_H_ -#define _NOUX__LOCAL_NOUX_SERVICE_H_ - -/* Genode includes */ -#include - -namespace Noux { - - using namespace Genode; - - struct Local_noux_service : public Service - { - Genode::Session_capability _cap; - - /** - * Constructor - * - * \param cap capability to return on session requests - */ - Local_noux_service(Genode::Session_capability cap) - : Service(Session::service_name()), _cap(cap) { } - - Genode::Session_capability session(const char *args, Affinity const &) - { - return _cap; - } - - void upgrade(Genode::Session_capability, const char *args) { } - void close(Genode::Session_capability) { } - }; -} - -#endif /* _NOUX__LOCAL_NOUX_SERVICE_H_ */ diff --git a/repos/ports/src/noux/local_pd_service.h b/repos/ports/src/noux/local_pd_service.h deleted file mode 100644 index 7ec1b138d..000000000 --- a/repos/ports/src/noux/local_pd_service.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * \brief PD service provided to Noux processes - * \author Christian Prochaska - * \date 2016-05-23 - */ - -/* - * Copyright (C) 2016 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#ifndef _NOUX__LOCAL_PD_SERVICE_H_ -#define _NOUX__LOCAL_PD_SERVICE_H_ - -/* Genode includes */ -#include - -/* Noux includes */ -#include - -namespace Noux { - - class Local_pd_service : public Service - { - private: - - Rpc_entrypoint &_ep; - Pd_session_capability _cap; - - public: - - Local_pd_service(Rpc_entrypoint &ep, Pd_session_capability cap) - : - Service(Pd_session::service_name()), _ep(ep), - _cap(cap) - { } - - Genode::Session_capability session(const char *args, Affinity const &) override - { - warning(__func__, " not implemented"); - return Genode::Session_capability(); - } - - void upgrade(Genode::Session_capability, const char *args) override - { - env()->parent()->upgrade(_cap, args); - } - - void close(Genode::Session_capability session) override - { - warning(__func__, " not implemented"); - } - }; -} - -#endif /* _NOUX__LOCAL_PD_SERVICE_H_ */ diff --git a/repos/ports/src/noux/local_rom_service.h b/repos/ports/src/noux/local_rom_service.h index 45efcc91a..c02d23289 100644 --- a/repos/ports/src/noux/local_rom_service.h +++ b/repos/ports/src/noux/local_rom_service.h @@ -27,57 +27,45 @@ namespace Noux { - class Local_rom_service : public Service - { - private: - - Rpc_entrypoint &_ep; - Dataspace_registry &_ds_registry; - - public: - - Local_rom_service(Rpc_entrypoint &ep, Dataspace_registry &ds_registry) - : - Service(Rom_session::service_name()), _ep(ep), - _ds_registry(ds_registry) - { } - - Genode::Session_capability session(const char *args, Affinity const &) - { - Session_label const label = label_from_args(args); - - try { - Genode::Session_label const module_name = label.last_element(); - Rom_session_component *rom = new (env()->heap()) - Rom_session_component(_ds_registry, module_name.string()); - - return _ep.manage(rom); - } catch (Rom_connection::Rom_connection_failed) { - throw Service::Unavailable(); - } - } - - void upgrade(Genode::Session_capability, const char *args) { } - - void close(Genode::Session_capability session) - { - /* acquire locked session object */ - Rom_session_component *rom_session; - - _ep.apply(session, [&] (Rom_session_component *rsc) { - rom_session = rsc; - - if (!rom_session) { - PWRN("Unexpected call of close with non-ROM-session argument"); - return; - } - - _ep.dissolve(rom_session); - }); - - destroy(env()->heap(), rom_session); - } - }; + typedef Local_service Local_rom_service; + class Local_rom_factory; } + +class Noux::Local_rom_factory : public Local_rom_service::Factory +{ + private: + + Rpc_entrypoint &_ep; + Vfs::Dir_file_system &_root_dir; + Dataspace_registry &_registry; + + public: + + Local_rom_factory(Rpc_entrypoint &ep, Vfs::Dir_file_system &root_dir, + Dataspace_registry ®istry) + : + _ep(ep), _root_dir(root_dir), _registry(registry) + { } + + Rom_session_component &create(Args const &args, Affinity) override + { + try { + Rom_session_component::Name const rom_name = + label_from_args(args.string()).last_element(); + + return *new (env()->heap()) + Rom_session_component(_ep, _root_dir, _registry, rom_name); + } + catch (Rom_connection::Rom_connection_failed) { throw Denied(); } + } + + void upgrade(Rom_session_component &, Args const &) override { } + + void destroy(Rom_session_component &session) override + { + Genode::destroy(env()->heap(), &session); + } +}; + #endif /* _NOUX__LOCAL_ROM_SERVICE_H_ */ diff --git a/repos/ports/src/noux/main.cc b/repos/ports/src/noux/main.cc index 114ac24a1..045b54937 100644 --- a/repos/ports/src/noux/main.cc +++ b/repos/ports/src/noux/main.cc @@ -158,11 +158,11 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) case SYSCALL_WRITE: { - size_t const count_in = _sysio->write_in.count; + size_t const count_in = _sysio.write_in.count; for (size_t offset = 0; offset != count_in; ) { - Shared_pointer io = _lookup_channel(_sysio->write_in.fd); + Shared_pointer io = _lookup_channel(_sysio.write_in.fd); if (!io->nonblocking()) _block_for_io_channel(io, false, true, false); @@ -170,15 +170,15 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) if (io->check_unblock(false, true, false)) { /* * 'io->write' is expected to update - * '_sysio->write_out.count' and 'offset' + * '_sysio.write_out.count' and 'offset' */ - result = io->write(_sysio, offset); + result = io->write(&_sysio, offset); if (result == false) break; } else { if (result == false) { /* nothing was written yet */ - _sysio->error.write = Vfs::File_io_service::WRITE_ERR_INTERRUPT; + _sysio.error.write = Vfs::File_io_service::WRITE_ERR_INTERRUPT; } break; } @@ -188,29 +188,29 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) case SYSCALL_READ: { - Shared_pointer io = _lookup_channel(_sysio->read_in.fd); + Shared_pointer io = _lookup_channel(_sysio.read_in.fd); if (!io->nonblocking()) _block_for_io_channel(io, true, false, false); if (io->check_unblock(true, false, false)) - result = io->read(_sysio); + result = io->read(&_sysio); else - _sysio->error.read = Vfs::File_io_service::READ_ERR_INTERRUPT; + _sysio.error.read = Vfs::File_io_service::READ_ERR_INTERRUPT; break; } case SYSCALL_FTRUNCATE: { - Shared_pointer io = _lookup_channel(_sysio->ftruncate_in.fd); + Shared_pointer io = _lookup_channel(_sysio.ftruncate_in.fd); _block_for_io_channel(io, false, true, false); if (io->check_unblock(false, true, false)) - result = io->ftruncate(_sysio); + result = io->ftruncate(&_sysio); else - _sysio->error.ftruncate = Vfs::File_io_service::FTRUNCATE_ERR_INTERRUPT; + _sysio.error.ftruncate = Vfs::File_io_service::FTRUNCATE_ERR_INTERRUPT; break; } @@ -222,13 +222,13 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * We calculate the inode by hashing the path because there is * no inode registry in noux. */ - size_t path_len = strlen(_sysio->stat_in.path); - uint32_t path_hash = hash_path(_sysio->stat_in.path, path_len); + size_t path_len = strlen(_sysio.stat_in.path); + uint32_t path_hash = hash_path(_sysio.stat_in.path, path_len); Vfs::Directory_service::Stat stat_out; - _sysio->error.stat = root_dir()->stat(_sysio->stat_in.path, stat_out); + _sysio.error.stat = _root_dir.stat(_sysio.stat_in.path, stat_out); - result = (_sysio->error.stat == Vfs::Directory_service::STAT_OK); + result = (_sysio.error.stat == Vfs::Directory_service::STAT_OK); /* * Instead of using the uid/gid given by the actual file system @@ -241,16 +241,16 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) stat_out.inode = path_hash; } - _sysio->stat_out.st = stat_out; + _sysio.stat_out.st = stat_out; break; } case SYSCALL_FSTAT: { - Shared_pointer io = _lookup_channel(_sysio->fstat_in.fd); + Shared_pointer io = _lookup_channel(_sysio.fstat_in.fd); - result = io->fstat(_sysio); + result = io->fstat(&_sysio); if (result) { Sysio::Path path; @@ -262,7 +262,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) size_t path_len = strlen(path); uint32_t path_hash = hash_path(path, path_len); - _sysio->stat_out.st.inode = path_hash; + _sysio.stat_out.st.inode = path_hash; } } @@ -271,29 +271,29 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) case SYSCALL_FCNTL: - if (_sysio->fcntl_in.cmd == Sysio::FCNTL_CMD_SET_FD_FLAGS) { + if (_sysio.fcntl_in.cmd == Sysio::FCNTL_CMD_SET_FD_FLAGS) { /* we assume that there is only the close-on-execve flag */ - _lookup_channel(_sysio->fcntl_in.fd)->close_on_execve = - !!_sysio->fcntl_in.long_arg; + _lookup_channel(_sysio.fcntl_in.fd)->close_on_execve = + !!_sysio.fcntl_in.long_arg; result = true; break; } - result = _lookup_channel(_sysio->fcntl_in.fd)->fcntl(_sysio); + result = _lookup_channel(_sysio.fcntl_in.fd)->fcntl(&_sysio); break; case SYSCALL_OPEN: { Vfs::Vfs_handle *vfs_handle = 0; - _sysio->error.open = root_dir()->open(_sysio->open_in.path, - _sysio->open_in.mode, - &vfs_handle, - *Genode::env()->heap()); + _sysio.error.open = _root_dir.open(_sysio.open_in.path, + _sysio.open_in.mode, + &vfs_handle, + *Genode::env()->heap()); if (!vfs_handle) break; - char const *leaf_path = root_dir()->leaf_path(_sysio->open_in.path); + char const *leaf_path = _root_dir.leaf_path(_sysio.open_in.path); /* * File descriptors of opened directories are handled by @@ -301,40 +301,40 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * path because path operations always refer to the global * root. */ - if (&vfs_handle->ds() == root_dir()) - leaf_path = _sysio->open_in.path; + if (&vfs_handle->ds() == &_root_dir) + leaf_path = _sysio.open_in.path; Shared_pointer - channel(new Vfs_io_channel(_sysio->open_in.path, - leaf_path, root_dir(), - vfs_handle, *_sig_rec), + channel(new Vfs_io_channel(_sysio.open_in.path, + leaf_path, &_root_dir, + vfs_handle, _sig_rec), Genode::env()->heap()); - _sysio->open_out.fd = add_io_channel(channel); + _sysio.open_out.fd = add_io_channel(channel); result = true; break; } case SYSCALL_CLOSE: { - remove_io_channel(_sysio->close_in.fd); + remove_io_channel(_sysio.close_in.fd); result = true; break; } case SYSCALL_IOCTL: - result = _lookup_channel(_sysio->ioctl_in.fd)->ioctl(_sysio); + result = _lookup_channel(_sysio.ioctl_in.fd)->ioctl(&_sysio); break; case SYSCALL_LSEEK: - result = _lookup_channel(_sysio->lseek_in.fd)->lseek(_sysio); + result = _lookup_channel(_sysio.lseek_in.fd)->lseek(&_sysio); break; case SYSCALL_DIRENT: - result = _lookup_channel(_sysio->dirent_in.fd)->dirent(_sysio); + result = _lookup_channel(_sysio.dirent_in.fd)->dirent(&_sysio); break; case SYSCALL_EXECVE: @@ -345,27 +345,27 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * does not exist. */ Dataspace_capability binary_ds = - root_dir()->dataspace(_sysio->execve_in.filename); + _root_dir.dataspace(_sysio.execve_in.filename); if (!binary_ds.valid()) { - _sysio->error.execve = Sysio::EXECVE_NONEXISTENT; + _sysio.error.execve = Sysio::EXECVE_NONEXISTENT; break; } - Child_envexecve_in.args)> - child_env(_sysio->execve_in.filename, binary_ds, - _sysio->execve_in.args, _sysio->execve_in.env); + Child_env + child_env(_sysio.execve_in.filename, binary_ds, + _sysio.execve_in.args, _sysio.execve_in.env); - root_dir()->release(_sysio->execve_in.filename, binary_ds); + _root_dir.release(_sysio.execve_in.filename, binary_ds); - binary_ds = root_dir()->dataspace(child_env.binary_name()); + binary_ds = _root_dir.dataspace(child_env.binary_name()); if (!binary_ds.valid()) { - _sysio->error.execve = Sysio::EXECVE_NONEXISTENT; + _sysio.error.execve = Sysio::EXECVE_NONEXISTENT; break; } - root_dir()->release(child_env.binary_name(), binary_ds); + _root_dir.release(child_env.binary_name(), binary_ds); try { _parent_execve.execve_child(*this, @@ -381,28 +381,28 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) return true; } catch (Child::Binary_does_not_exist) { - _sysio->error.execve = Sysio::EXECVE_NONEXISTENT; } + _sysio.error.execve = Sysio::EXECVE_NONEXISTENT; } catch (Child::Insufficient_memory) { - _sysio->error.execve = Sysio::EXECVE_NOMEM; } + _sysio.error.execve = Sysio::EXECVE_NOMEM; } break; } case SYSCALL_SELECT: { - size_t in_fds_total = _sysio->select_in.fds.total_fds(); + size_t in_fds_total = _sysio.select_in.fds.total_fds(); Sysio::Select_fds in_fds; for (Genode::size_t i = 0; i < in_fds_total; i++) - in_fds.array[i] = _sysio->select_in.fds.array[i]; - in_fds.num_rd = _sysio->select_in.fds.num_rd; - in_fds.num_wr = _sysio->select_in.fds.num_wr; - in_fds.num_ex = _sysio->select_in.fds.num_ex; + in_fds.array[i] = _sysio.select_in.fds.array[i]; + in_fds.num_rd = _sysio.select_in.fds.num_rd; + in_fds.num_wr = _sysio.select_in.fds.num_wr; + in_fds.num_ex = _sysio.select_in.fds.num_ex; int _rd_array[in_fds_total]; int _wr_array[in_fds_total]; - long timeout_sec = _sysio->select_in.timeout.sec; - long timeout_usec = _sysio->select_in.timeout.usec; + long timeout_sec = _sysio.select_in.timeout.sec; + long timeout_usec = _sysio.select_in.timeout.usec; bool timeout_reached = false; /* reset the blocker lock to the 'locked' state */ @@ -486,18 +486,18 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * Merge the fd arrays in one output array */ for (size_t i = 0; i < unblock_rd; i++) { - _sysio->select_out.fds.array[i] = _rd_array[i]; + _sysio.select_out.fds.array[i] = _rd_array[i]; } - _sysio->select_out.fds.num_rd = unblock_rd; + _sysio.select_out.fds.num_rd = unblock_rd; /* XXX could use a pointer to select_out.fds.array instead */ for (size_t j = unblock_rd, i = 0; i < unblock_wr; i++, j++) { - _sysio->select_out.fds.array[j] = _wr_array[i]; + _sysio.select_out.fds.array[j] = _wr_array[i]; } - _sysio->select_out.fds.num_wr = unblock_wr; + _sysio.select_out.fds.num_wr = unblock_wr; /* exception fds are currently not considered */ - _sysio->select_out.fds.num_ex = unblock_ex; + _sysio.select_out.fds.num_ex = unblock_ex; result = true; break; @@ -507,14 +507,14 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * Return if timeout is zero or timeout exceeded */ - if (_sysio->select_in.timeout.zero() || timeout_reached) { + if (_sysio.select_in.timeout.zero() || timeout_reached) { /* if (timeout_reached) log("timeout_reached"); else log("timeout.zero()"); */ - _sysio->select_out.fds.num_rd = 0; - _sysio->select_out.fds.num_wr = 0; - _sysio->select_out.fds.num_ex = 0; + _sysio.select_out.fds.num_rd = 0; + _sysio.select_out.fds.num_wr = 0; + _sysio.select_out.fds.num_ex = 0; result = true; break; @@ -525,7 +525,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) */ if (!_pending_signals.empty()) { - _sysio->error.select = Sysio::SELECT_ERR_INTERRUPT; + _sysio.error.select = Sysio::SELECT_ERR_INTERRUPT; break; } @@ -533,7 +533,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * Block at barrier except when reaching the timeout */ - if (!_sysio->select_in.timeout.infinite()) { + if (!_sysio.select_in.timeout.infinite()) { unsigned long to_msec = (timeout_sec * 1000) + (timeout_usec / 1000); Timeout_state ts; Timeout_alarm ta(&ts, &_blocker, Noux::timeout_scheduler(), to_msec); @@ -580,9 +580,9 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) case SYSCALL_FORK: { - Genode::addr_t ip = _sysio->fork_in.ip; - Genode::addr_t sp = _sysio->fork_in.sp; - Genode::addr_t parent_cap_addr = _sysio->fork_in.parent_cap_addr; + Genode::addr_t ip = _sysio.fork_in.ip; + Genode::addr_t sp = _sysio.fork_in.sp; + Genode::addr_t parent_cap_addr = _sysio.fork_in.parent_cap_addr; int const new_pid = pid_allocator()->alloc(); Child * child = nullptr; @@ -594,24 +594,24 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * reusing the name of the parent. */ child = new Child(_child_policy.name(), - _ldso_ds, this, _kill_broadcaster, *this, new_pid, _sig_rec, - root_dir(), + _root_dir, _args, _env.env(), - _cap_session, + _env_pd_session, + _ref_ram, _ref_ram_cap, _parent_services, - _resources.ep, + _ep, true, - env()->heap(), + *env()->heap(), _destruct_queue, verbose); } catch (Child::Insufficient_memory) { - _sysio->error.fork = Sysio::FORK_NOMEM; + _sysio.error.fork = Sysio::FORK_NOMEM; break; } @@ -620,34 +620,39 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) _assign_io_channels_to(child); /* copy our address space into the new child */ - _pd.replay(child->ram(), child->pd(), - child->ds_registry(), _resources.ep); + try { + _pd.replay(child->ram(), child->pd(), + child->ds_registry(), _ep); - /* start executing the main thread of the new process */ - child->start_forked_main_thread(ip, sp, parent_cap_addr); + /* start executing the main thread of the new process */ + child->start_forked_main_thread(ip, sp, parent_cap_addr); - /* activate child entrypoint, thereby starting the new process */ - child->start(); + /* activate child entrypoint, thereby starting the new process */ + child->start(); - _sysio->fork_out.pid = new_pid; + _sysio.fork_out.pid = new_pid; + + result = true; + } + catch (Region_map::Region_conflict) { + error("region conflict while replaying the address space"); } - result = true; break; } case SYSCALL_GETPID: { - _sysio->getpid_out.pid = pid(); + _sysio.getpid_out.pid = pid(); return true; } case SYSCALL_WAIT4: { - Family_member *exited = _sysio->wait4_in.nohang ? poll4() : wait4(); + Family_member *exited = _sysio.wait4_in.nohang ? poll4() : wait4(); if (exited) { - _sysio->wait4_out.pid = exited->pid(); - _sysio->wait4_out.status = exited->exit_status(); + _sysio.wait4_out.pid = exited->pid(); + _sysio.wait4_out.status = exited->exit_status(); Family_member::remove(exited); if (verbose) @@ -655,11 +660,11 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) static_cast(exited)->submit_exit_signal(); } else { - if (_sysio->wait4_in.nohang) { - _sysio->wait4_out.pid = 0; - _sysio->wait4_out.status = 0; + if (_sysio.wait4_in.nohang) { + _sysio.wait4_out.pid = 0; + _sysio.wait4_out.status = 0; } else { - _sysio->error.wait4 = Sysio::WAIT4_ERR_INTERRUPT; + _sysio.error.wait4 = Sysio::WAIT4_ERR_INTERRUPT; break; } } @@ -671,13 +676,13 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) { Shared_pointer pipe(new Pipe, Genode::env()->heap()); - Shared_pointer pipe_sink(new Pipe_sink_io_channel(pipe, *_sig_rec), + Shared_pointer pipe_sink(new Pipe_sink_io_channel(pipe, _sig_rec), Genode::env()->heap()); - Shared_pointer pipe_source(new Pipe_source_io_channel(pipe, *_sig_rec), + Shared_pointer pipe_source(new Pipe_source_io_channel(pipe, _sig_rec), Genode::env()->heap()); - _sysio->pipe_out.fd[0] = add_io_channel(pipe_source); - _sysio->pipe_out.fd[1] = add_io_channel(pipe_sink); + _sysio.pipe_out.fd[0] = add_io_channel(pipe_source); + _sysio.pipe_out.fd[1] = add_io_channel(pipe_sink); result = true; break; @@ -685,10 +690,10 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) case SYSCALL_DUP2: { - int fd = add_io_channel(io_channel_by_fd(_sysio->dup2_in.fd), - _sysio->dup2_in.to_fd); + int fd = add_io_channel(io_channel_by_fd(_sysio.dup2_in.fd), + _sysio.dup2_in.to_fd); - _sysio->dup2_out.fd = fd; + _sysio.dup2_out.fd = fd; result = true; break; @@ -696,56 +701,57 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) case SYSCALL_UNLINK: - _sysio->error.unlink = root_dir()->unlink(_sysio->unlink_in.path); + _sysio.error.unlink = _root_dir.unlink(_sysio.unlink_in.path); - result = (_sysio->error.unlink == Vfs::Directory_service::UNLINK_OK); + result = (_sysio.error.unlink == Vfs::Directory_service::UNLINK_OK); break; case SYSCALL_READLINK: { Vfs::file_size out_count = 0; - _sysio->error.readlink = root_dir()->readlink(_sysio->readlink_in.path, - _sysio->readlink_out.chunk, - min(_sysio->readlink_in.bufsiz, - sizeof(_sysio->readlink_out.chunk)), - out_count); + _sysio.error.readlink = + _root_dir.readlink(_sysio.readlink_in.path, + _sysio.readlink_out.chunk, + min(_sysio.readlink_in.bufsiz, + sizeof(_sysio.readlink_out.chunk)), + out_count); - _sysio->readlink_out.count = out_count; + _sysio.readlink_out.count = out_count; - result = (_sysio->error.readlink == Vfs::Directory_service::READLINK_OK); + result = (_sysio.error.readlink == Vfs::Directory_service::READLINK_OK); break; } case SYSCALL_RENAME: - _sysio->error.rename = root_dir()->rename(_sysio->rename_in.from_path, - _sysio->rename_in.to_path); + _sysio.error.rename = _root_dir.rename(_sysio.rename_in.from_path, + _sysio.rename_in.to_path); - result = (_sysio->error.rename == Vfs::Directory_service::RENAME_OK); + result = (_sysio.error.rename == Vfs::Directory_service::RENAME_OK); break; case SYSCALL_MKDIR: - _sysio->error.mkdir = root_dir()->mkdir(_sysio->mkdir_in.path, 0); + _sysio.error.mkdir = _root_dir.mkdir(_sysio.mkdir_in.path, 0); - result = (_sysio->error.mkdir == Vfs::Directory_service::MKDIR_OK); + result = (_sysio.error.mkdir == Vfs::Directory_service::MKDIR_OK); break; case SYSCALL_SYMLINK: - _sysio->error.symlink = root_dir()->symlink(_sysio->symlink_in.oldpath, - _sysio->symlink_in.newpath); + _sysio.error.symlink = _root_dir.symlink(_sysio.symlink_in.oldpath, + _sysio.symlink_in.newpath); - result = (_sysio->error.symlink == Vfs::Directory_service::SYMLINK_OK); + result = (_sysio.error.symlink == Vfs::Directory_service::SYMLINK_OK); break; case SYSCALL_USERINFO: { - if (_sysio->userinfo_in.request == Sysio::USERINFO_GET_UID - || _sysio->userinfo_in.request == Sysio::USERINFO_GET_GID) { - _sysio->userinfo_out.uid = Noux::user_info()->uid; - _sysio->userinfo_out.gid = Noux::user_info()->gid; + if (_sysio.userinfo_in.request == Sysio::USERINFO_GET_UID + || _sysio.userinfo_in.request == Sysio::USERINFO_GET_GID) { + _sysio.userinfo_out.uid = Noux::user_info()->uid; + _sysio.userinfo_out.gid = Noux::user_info()->gid; result = true; break; @@ -755,21 +761,21 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) * Since NOUX supports exactly one user, return false if we * got a unknown uid. */ - if (_sysio->userinfo_in.uid != Noux::user_info()->uid) + if (_sysio.userinfo_in.uid != Noux::user_info()->uid) break; - Genode::memcpy(_sysio->userinfo_out.name, + Genode::memcpy(_sysio.userinfo_out.name, Noux::user_info()->name, sizeof(Noux::user_info()->name)); - Genode::memcpy(_sysio->userinfo_out.shell, + Genode::memcpy(_sysio.userinfo_out.shell, Noux::user_info()->shell, sizeof(Noux::user_info()->shell)); - Genode::memcpy(_sysio->userinfo_out.home, + Genode::memcpy(_sysio.userinfo_out.home, Noux::user_info()->home, sizeof(Noux::user_info()->home)); - _sysio->userinfo_out.uid = user_info()->uid; - _sysio->userinfo_out.gid = user_info()->gid; + _sysio.userinfo_out.uid = user_info()->uid; + _sysio.userinfo_out.gid = user_info()->gid; result = true; break; @@ -788,8 +794,8 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) */ unsigned long time = Noux::timeout_scheduler()->curr_time(); - _sysio->gettimeofday_out.sec = (time / 1000); - _sysio->gettimeofday_out.usec = (time % 1000) * 1000; + _sysio.gettimeofday_out.sec = (time / 1000); + _sysio.gettimeofday_out.usec = (time % 1000) * 1000; result = true; break; @@ -802,13 +808,13 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) */ unsigned long time = Noux::timeout_scheduler()->curr_time(); - switch (_sysio->clock_gettime_in.clock_id) { + switch (_sysio.clock_gettime_in.clock_id) { /* CLOCK_SECOND is used by time(3) in the libc. */ case Sysio::CLOCK_ID_SECOND: { - _sysio->clock_gettime_out.sec = (time / 1000); - _sysio->clock_gettime_out.nsec = 0; + _sysio.clock_gettime_out.sec = (time / 1000); + _sysio.clock_gettime_out.nsec = 0; result = true; break; @@ -816,9 +822,9 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) default: { - _sysio->clock_gettime_out.sec = 0; - _sysio->clock_gettime_out.nsec = 0; - _sysio->error.clock = Sysio::CLOCK_ERR_INVALID; + _sysio.clock_gettime_out.sec = 0; + _sysio.clock_gettime_out.nsec = 0; + _sysio.error.clock = Sysio::CLOCK_ERR_INVALID; break; } @@ -844,25 +850,25 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) case SYSCALL_SYNC: { - root_dir()->sync("/"); + _root_dir.sync("/"); result = true; break; } case SYSCALL_KILL: { - if (_kill_broadcaster.kill(_sysio->kill_in.pid, - _sysio->kill_in.sig)) + if (_kill_broadcaster.kill(_sysio.kill_in.pid, + _sysio.kill_in.sig)) result = true; else - _sysio->error.kill = Sysio::KILL_ERR_SRCH; + _sysio.error.kill = Sysio::KILL_ERR_SRCH; break; } case SYSCALL_GETDTABLESIZE: { - _sysio->getdtablesize_out.n = + _sysio.getdtablesize_out.n = Noux::File_descriptor_registry::MAX_FILE_DESCRIPTORS; result = true; break; @@ -890,15 +896,15 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) } catch (Invalid_fd) { - _sysio->error.general = Vfs::Directory_service::ERR_FD_INVALID; + _sysio.error.general = Vfs::Directory_service::ERR_FD_INVALID; error("invalid file descriptor"); } catch (...) { error("unexpected exception"); } /* handle signals which might have occured */ while (!_pending_signals.empty() && - (_sysio->pending_signals.avail_capacity() > 0)) { - _sysio->pending_signals.add(_pending_signals.get()); + (_sysio.pending_signals.avail_capacity() > 0)) { + _sysio.pending_signals.add(_pending_signals.get()); } return result; @@ -908,7 +914,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc) /** * Return name of init process as specified in the config */ -static char *name_of_init_process() +static char const *name_of_init_process() { enum { INIT_NAME_LEN = 128 }; static char buf[INIT_NAME_LEN]; @@ -1070,18 +1076,6 @@ static Noux::Io_channel *connect_stdio(Vfs::Dir_file_system &root, } -Genode::Dataspace_capability Noux::ldso_ds_cap() -{ - try { - static Genode::Rom_connection rom("ld.lib.so"); - static Genode::Dataspace_capability ldso_ds = rom.dataspace(); - return ldso_ds; - } catch (...) { } - - return Genode::Dataspace_capability(); -} - - /* * This lock is needed to delay the insertion of signals into a child object. * This is necessary during an 'execve()' syscall, when signals get copied from @@ -1138,12 +1132,10 @@ void Component::construct(Genode::Env &env) log("--- noux started ---"); /* whitelist of service requests to be routed to the parent */ - static Genode::Service_registry parent_services; + static Noux::Parent_services parent_services; char const *service_names[] = { "LOG", "ROM", "Timer", 0 }; for (unsigned i = 0; service_names[i]; i++) - parent_services.insert(new Genode::Parent_service(service_names[i])); - - static Genode::Cap_connection cap; + new Noux::Parent_service(parent_services, service_names[i]); /* obtain global configuration */ trace_syscalls = config()->xml_node().attribute_value("trace_syscalls", trace_syscalls); @@ -1176,7 +1168,8 @@ void Component::construct(Genode::Env &env) * Entrypoint used to virtualize child resources such as RAM, RM */ enum { STACK_SIZE = 2*1024*sizeof(long) }; - static Genode::Rpc_entrypoint resources_ep(&cap, STACK_SIZE, "noux_rsc_ep"); + static Genode::Rpc_entrypoint + resources_ep(Genode::env()->pd_session(), STACK_SIZE, "noux_rsc_ep"); /* create init process */ static Genode::Signal_receiver sig_rec; @@ -1184,7 +1177,7 @@ void Component::construct(Genode::Env &env) struct Kill_broadcaster_implementation : Kill_broadcaster { - Family_member *init_process; + Family_member *init_process = nullptr; bool kill(int pid, Noux::Sysio::Signal sig) { @@ -1192,23 +1185,27 @@ void Component::construct(Genode::Env &env) } }; + static Dataspace_registry ref_ram_ds_registry; + static Ram_session_component ref_ram(resources_ep, ref_ram_ds_registry); + static Kill_broadcaster_implementation kill_broadcaster; init_child = new Noux::Child(name_of_init_process(), - ldso_ds_cap(), 0, kill_broadcaster, *init_child, pid_allocator()->alloc(), - &sig_rec, - &root_dir, + sig_rec, + root_dir, args_of_init_process(), env_string_of_init_process(), - &cap, + *Genode::env()->pd_session(), + ref_ram, + Ram_session_capability(), parent_services, resources_ep, false, - Genode::env()->heap(), + *Genode::env()->heap(), destruct_queue, verbose); diff --git a/repos/ports/src/noux/net/net.cc b/repos/ports/src/noux/net/net.cc index 36e31a932..78b33a052 100644 --- a/repos/ports/src/noux/net/net.cc +++ b/repos/ports/src/noux/net/net.cc @@ -121,121 +121,121 @@ bool Noux::Child::_syscall_net(Noux::Session::Syscall sc) GET_SOCKET_IO_CHANNEL_BACKEND(socket_io_channel->backend(), backend); - if (!backend->socket(_sysio)) { + if (!backend->socket(&_sysio)) { delete socket_io_channel; return false; } Shared_pointer io_channel(socket_io_channel, Genode::env()->heap()); - _sysio->socket_out.fd = add_io_channel(io_channel); + _sysio.socket_out.fd = add_io_channel(io_channel); return true; } case SYSCALL_GETSOCKOPT: { - Shared_pointer io = _lookup_channel(_sysio->getsockopt_in.fd); + Shared_pointer io = _lookup_channel(_sysio.getsockopt_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return backend->getsockopt(_sysio); + return backend->getsockopt(&_sysio); } case SYSCALL_SETSOCKOPT: { - Shared_pointer io = _lookup_channel(_sysio->setsockopt_in.fd); + Shared_pointer io = _lookup_channel(_sysio.setsockopt_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return backend->setsockopt(_sysio); + return backend->setsockopt(&_sysio); } case SYSCALL_ACCEPT: { - Shared_pointer io = _lookup_channel(_sysio->accept_in.fd); + Shared_pointer io = _lookup_channel(_sysio.accept_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - int socket = backend->accept(_sysio); + int socket = backend->accept(&_sysio); if (socket == -1) return false; Socket_io_channel *socket_io_channel = new Socket_io_channel(socket); Shared_pointer io_channel(socket_io_channel, Genode::env()->heap()); - _sysio->accept_out.fd = add_io_channel(io_channel); + _sysio.accept_out.fd = add_io_channel(io_channel); return true; } case SYSCALL_BIND: { - Shared_pointer io = _lookup_channel(_sysio->bind_in.fd); + Shared_pointer io = _lookup_channel(_sysio.bind_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return (backend->bind(_sysio) == -1) ? false : true; + return (backend->bind(&_sysio) == -1) ? false : true; } case SYSCALL_LISTEN: { - Shared_pointer io = _lookup_channel(_sysio->listen_in.fd); + Shared_pointer io = _lookup_channel(_sysio.listen_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return (backend->listen(_sysio) == -1) ? false : true; + return (backend->listen(&_sysio) == -1) ? false : true; } case SYSCALL_SEND: { - Shared_pointer io = _lookup_channel(_sysio->send_in.fd); + Shared_pointer io = _lookup_channel(_sysio.send_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return (backend->send(_sysio) == -1) ? false : true; + return (backend->send(&_sysio) == -1) ? false : true; } case SYSCALL_SENDTO: { - Shared_pointer io = _lookup_channel(_sysio->sendto_in.fd); + Shared_pointer io = _lookup_channel(_sysio.sendto_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return (backend->sendto(_sysio) == -1) ? false : true; + return (backend->sendto(&_sysio) == -1) ? false : true; } case SYSCALL_RECV: { - Shared_pointer io = _lookup_channel(_sysio->recv_in.fd); + Shared_pointer io = _lookup_channel(_sysio.recv_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return (backend->recv(_sysio) == -1) ? false : true; + return (backend->recv(&_sysio) == -1) ? false : true; } case SYSCALL_RECVFROM: { - Shared_pointer io = _lookup_channel(_sysio->recvfrom_in.fd); + Shared_pointer io = _lookup_channel(_sysio.recvfrom_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return (backend->recvfrom(_sysio) == -1) ? false : true; + return (backend->recvfrom(&_sysio) == -1) ? false : true; } case SYSCALL_GETPEERNAME: { - Shared_pointer io = _lookup_channel(_sysio->getpeername_in.fd); + Shared_pointer io = _lookup_channel(_sysio.getpeername_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return (backend->getpeername(_sysio) == -1) ? false : true; + return (backend->getpeername(&_sysio) == -1) ? false : true; } case SYSCALL_SHUTDOWN: { - Shared_pointer io = _lookup_channel(_sysio->shutdown_in.fd); + Shared_pointer io = _lookup_channel(_sysio.shutdown_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return (backend->shutdown(_sysio) == -1) ? false : true; + return (backend->shutdown(&_sysio) == -1) ? false : true; } case SYSCALL_CONNECT: { - Shared_pointer io = _lookup_channel(_sysio->connect_in.fd); + Shared_pointer io = _lookup_channel(_sysio.connect_in.fd); GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend); - return (backend->connect(_sysio) == -1) ? false : true; + return (backend->connect(&_sysio) == -1) ? false : true; } } diff --git a/repos/ports/src/noux/pd_session_component.h b/repos/ports/src/noux/pd_session_component.h index 96b1579fc..2f4a5e1e7 100644 --- a/repos/ports/src/noux/pd_session_component.h +++ b/repos/ports/src/noux/pd_session_component.h @@ -42,10 +42,10 @@ class Noux::Pd_session_component : public Rpc_object /** * Constructor */ - Pd_session_component(char const *binary_name, - Rpc_entrypoint &ep, Dataspace_registry &ds_registry) + Pd_session_component(Rpc_entrypoint &ep, Child_policy::Name const &name, + Dataspace_registry &ds_registry) : - _ep(ep), _pd(binary_name), + _ep(ep), _pd(name.string()), _address_space(_ep, ds_registry, _pd, _pd.address_space()), _stack_area (_ep, ds_registry, _pd, _pd.stack_area()), _linker_area (_ep, ds_registry, _pd, _pd.linker_area()) @@ -70,29 +70,31 @@ class Noux::Pd_session_component : public Rpc_object return _address_space.lookup_region_map(addr); } - void replay(Ram_session_capability dst_ram, - Capability dst_pd_cap, - Dataspace_registry &ds_registry, - Rpc_entrypoint &ep) + Region_map &address_space_region_map() { return _address_space; } + Region_map &linker_area_region_map() { return _linker_area; } + Region_map &stack_area_region_map() { return _stack_area; } + + void replay(Ram_session &dst_ram, + Pd_session_component &dst_pd, + Dataspace_registry &ds_registry, + Rpc_entrypoint &ep) { - Pd_session_client dst_pd(dst_pd_cap); - /* replay region map into new protection domain */ - _stack_area .replay(dst_ram, dst_pd.stack_area(), ds_registry, ep); - _linker_area .replay(dst_ram, dst_pd.linker_area(), ds_registry, ep); - _address_space.replay(dst_ram, dst_pd.address_space(), ds_registry, ep); + _stack_area .replay(dst_ram, dst_pd.stack_area_region_map(), ds_registry, ep); + _linker_area .replay(dst_ram, dst_pd.linker_area_region_map(), ds_registry, ep); + _address_space.replay(dst_ram, dst_pd.address_space_region_map(), ds_registry, ep); - Region_map_client dst_address_space(dst_pd.address_space()); + Region_map &dst_address_space = dst_pd.address_space_region_map(); + Region_map &dst_stack_area = dst_pd.stack_area_region_map(); + Region_map &dst_linker_area = dst_pd.linker_area_region_map(); /* attach stack area */ - Region_map_client dst_stack_area(dst_pd.stack_area()); dst_address_space.attach(dst_stack_area.dataspace(), Dataspace_client(dst_stack_area.dataspace()).size(), 0, true, _address_space.lookup_region_base(_stack_area.dataspace())); /* attach linker area */ - Region_map_client dst_linker_area(dst_pd.linker_area()); dst_address_space.attach(dst_linker_area.dataspace(), Dataspace_client(dst_linker_area.dataspace()).size(), 0, true, diff --git a/repos/ports/src/noux/ram_session_component.h b/repos/ports/src/noux/ram_session_component.h index 819725cc7..0ca3b0458 100644 --- a/repos/ports/src/noux/ram_session_component.h +++ b/repos/ports/src/noux/ram_session_component.h @@ -39,19 +39,16 @@ namespace Noux { Ram_dataspace_info(Ram_dataspace_capability ds_cap) : Dataspace_info(ds_cap) { } - Dataspace_capability fork(Ram_session_capability ram, - Dataspace_registry &, - Rpc_entrypoint &) + Dataspace_capability fork(Ram_session &ram, + Dataspace_registry &ds_registry, + Rpc_entrypoint &) override { size_t const size = Dataspace_client(ds_cap()).size(); Ram_dataspace_capability dst_ds; - try { - dst_ds = Ram_session_client(ram).alloc(size); - } catch (...) { - return Dataspace_capability(); - } + try { dst_ds = ram.alloc(size); } + catch (...) { return Dataspace_capability(); } void *src = 0; try { @@ -70,10 +67,12 @@ namespace Noux { if (dst) env()->rm_session()->detach(dst); if (!src || !dst) { - Ram_session_client(ram).free(dst_ds); + ram.free(dst_ds); return Dataspace_capability(); } + ds_registry.insert(new (env()->heap()) Ram_dataspace_info(dst_ds)); + return dst_ds; } @@ -101,6 +100,8 @@ namespace Noux { { private: + Rpc_entrypoint &_ep; + List _list; /* @@ -117,14 +118,15 @@ namespace Noux { /** * Constructor */ - Ram_session_component(Dataspace_registry ®istry) - : _used_quota(0), _registry(registry) { } + Ram_session_component(Rpc_entrypoint &ep, Dataspace_registry ®istry) + : _ep(ep), _used_quota(0), _registry(registry) { _ep.manage(this); } /** * Destructor */ ~Ram_session_component() { + _ep.dissolve(this); Ram_dataspace_info *info = 0; while ((info = _list.first())) free(static_cap_cast(info->ds_cap())); diff --git a/repos/ports/src/noux/region_map_component.h b/repos/ports/src/noux/region_map_component.h index cd961b547..45a728514 100644 --- a/repos/ports/src/noux/region_map_component.h +++ b/repos/ports/src/noux/region_map_component.h @@ -91,7 +91,7 @@ class Noux::Region_map_component : public Rpc_object, */ Region_map_client _rm; - Pd_session_capability _pd; + Pd_connection &_pd; Dataspace_registry &_ds_registry; @@ -106,7 +106,7 @@ class Noux::Region_map_component : public Rpc_object, */ Region_map_component(Rpc_entrypoint &ep, Dataspace_registry &ds_registry, - Pd_session_capability pd, + Pd_connection &pd, Capability rm) : Dataspace_info(Region_map_client(rm).dataspace()), @@ -157,10 +157,10 @@ class Noux::Region_map_component : public Rpc_object, * \param ep entrypoint used to serve the RPC interface * of forked managed dataspaces */ - void replay(Ram_session_capability dst_ram, - Capability dst_rm, - Dataspace_registry &ds_registry, - Rpc_entrypoint &ep) + void replay(Ram_session &dst_ram, + Region_map &dst_rm, + Dataspace_registry &ds_registry, + Rpc_entrypoint &ep) { Lock::Guard guard(_region_lock); for (Region *curr = _regions.first(); curr; curr = curr->next_region()) { @@ -210,10 +210,7 @@ class Noux::Region_map_component : public Rpc_object, return; } - Region_map_client(dst_rm).attach(ds, curr->size, - curr->offset, - true, - curr->local_addr); + dst_rm.attach(ds, curr->size, curr->offset, true, curr->local_addr); }; _ds_registry.apply(curr->ds, lambda); }; @@ -241,7 +238,7 @@ class Noux::Region_map_component : public Rpc_object, local_addr, executable); break; } catch (Region_map::Out_of_metadata) { - Genode::env()->parent()->upgrade(_pd, "ram_quota=8096"); + _pd.upgrade_ram(8*1024); } } @@ -325,9 +322,9 @@ class Noux::Region_map_component : public Rpc_object, ** Dataspace_info interface ** ******************************/ - Dataspace_capability fork(Ram_session_capability ram, - Dataspace_registry &ds_registry, - Rpc_entrypoint &ep) override + Dataspace_capability fork(Ram_session &, + Dataspace_registry &, + Rpc_entrypoint &) override { return Dataspace_capability(); } diff --git a/repos/ports/src/noux/rom_session_component.h b/repos/ports/src/noux/rom_session_component.h index 72cde48fa..9395fd9f9 100644 --- a/repos/ports/src/noux/rom_session_component.h +++ b/repos/ports/src/noux/rom_session_component.h @@ -20,80 +20,147 @@ namespace Noux { - struct Rom_dataspace_info : Dataspace_info - { - Rom_dataspace_info(Dataspace_capability ds) : Dataspace_info(ds) { } - - ~Rom_dataspace_info() { } - - Dataspace_capability fork(Ram_session_capability, - Dataspace_registry &ds_registry, - Rpc_entrypoint &) - { - return ds_cap(); - } - - void poke(addr_t dst_offset, void const *src, size_t len) - { - error("attempt to poke onto a ROM dataspace"); - } - }; - - - class Rom_session_component : public Rpc_object - { - private: - - /** - * Wrapped ROM session at core - */ - Rom_connection _rom; - - Dataspace_registry &_ds_registry; - - Rom_dataspace_info _ds_info; - - public: - - Rom_session_component(Dataspace_registry &ds_registry, - char const *name) - : - _rom(name), _ds_registry(ds_registry), _ds_info(_rom.dataspace()) - { - _ds_registry.insert(&_ds_info); - } - - ~Rom_session_component() - { - /* - * Lookup and lock ds info instead of directly accessing - * the '_ds_info' member. - */ - _ds_registry.apply(_ds_info.ds_cap(), [this] (Dataspace_info *info) { - - if (!info) { - error("~Rom_session_component: unexpected !info"); - return; - } - - _ds_registry.remove(&_ds_info); - - info->dissolve_users(); - }); - } - - - /*************************** - ** ROM session interface ** - ***************************/ - - Rom_dataspace_capability dataspace() - { - return static_cap_cast(_ds_info.ds_cap()); - } - - void sigh(Signal_context_capability) { } - }; + struct Rom_dataspace_info; + class Rom_session_component; } + +struct Noux::Rom_dataspace_info : Dataspace_info +{ + Rom_dataspace_info(Dataspace_capability ds) : Dataspace_info(ds) { } + + ~Rom_dataspace_info() { } + + Dataspace_capability fork(Ram_session &, + Dataspace_registry &ds_registry, + Rpc_entrypoint &) override + { + ds_registry.insert(new (env()->heap()) Rom_dataspace_info(ds_cap())); + return ds_cap(); + } + + void poke(addr_t dst_offset, void const *src, size_t len) + { + error("attempt to poke onto a ROM dataspace"); + } +}; + + +/** + * Local ROM service + * + * Depending on the ROM name, the data is provided by the VFS (if the name + * starts with a '/' or the parent's ROM service. If the name empty, an + * invalid dataspace capability is returned (this is used for the binary + * ROM session of a forked process). + */ +class Noux::Rom_session_component : public Rpc_object +{ + public: + + typedef Child_policy::Name Name; + + /** + * Label of ROM session requested for the binary of a forked process + * + * In this case, the loading of the binary must be omitted because the + * address space is replayed by the fork operation. Hence, requests for + * such ROM modules are answered by an invalid dataspace, which is + * handled in 'Child::Process'. + */ + static Name forked_magic_binary_name() { return "(forked)"; } + + private: + + Rpc_entrypoint &_ep; + Vfs::Dir_file_system &_root_dir; + Dataspace_registry &_ds_registry; + + /** + * Dataspace obtained from the VFS + */ + struct Vfs_dataspace + { + Vfs::Dir_file_system &root_dir; + + Name const name; + Dataspace_capability const ds; + + Vfs_dataspace(Vfs::Dir_file_system &root_dir, Name const &name) + : + root_dir(root_dir), name(name), ds(root_dir.dataspace(name.string())) + { } + + ~Vfs_dataspace() { root_dir.release(name.string(), ds); } + }; + + Lazy_volatile_object _rom_from_vfs; + + /** + * Wrapped ROM session at core + */ + Lazy_volatile_object _rom_from_parent; + + Dataspace_capability _init_ds_cap(Name const &name) + { + if (name.string()[0] == '/') { + _rom_from_vfs.construct(_root_dir, name); + return _rom_from_vfs->ds; + } + + if (name == forked_magic_binary_name()) + return Dataspace_capability(); + + _rom_from_parent.construct(name.string()); + Dataspace_capability ds = _rom_from_parent->dataspace(); + return ds; + } + + Dataspace_capability const _ds_cap; + + public: + + Rom_session_component(Rpc_entrypoint &ep, Vfs::Dir_file_system &root_dir, + Dataspace_registry &ds_registry, Name const &name) + : + _ep(ep), _root_dir(root_dir), _ds_registry(ds_registry), + _ds_cap(_init_ds_cap(name)) + { + _ep.manage(this); + _ds_registry.insert(new (env()->heap()) Rom_dataspace_info(_ds_cap)); + } + + ~Rom_session_component() + { + /* + * Lookup and lock ds info instead of directly accessing + * the '_ds_info' member. + */ + _ds_registry.apply(_ds_cap, [this] (Dataspace_info *info) { + + if (!info) { + error("~Rom_session_component: unexpected !info"); + return; + } + + _ds_registry.remove(info); + + info->dissolve_users(); + }); + _ep.dissolve(this); + } + + + /*************************** + ** ROM session interface ** + ***************************/ + + Rom_dataspace_capability dataspace() + { + return static_cap_cast(_ds_cap); + } + + void sigh(Signal_context_capability) { } +}; + #endif /* _NOUX__ROM_SESSION_COMPONENT_H_ */ diff --git a/repos/ports/src/test/vmm_utils/main.cc b/repos/ports/src/test/vmm_utils/main.cc index ad0927905..f73f22b10 100644 --- a/repos/ports/src/test/vmm_utils/main.cc +++ b/repos/ports/src/test/vmm_utils/main.cc @@ -12,24 +12,22 @@ */ /* Genode includes */ -#include +#include /* VMM utility includes */ #include #include #include -using Genode::Cap_connection; -using Genode::sleep_forever; - +template class Vcpu_dispatcher : public Vmm::Vcpu_dispatcher { private: typedef Vcpu_dispatcher This; - Vmm::Vcpu_same_pd _vcpu_thread; + T _vcpu_thread; /** * Shortcut for calling 'Vmm::Vcpu_dispatcher::register_handler' @@ -50,17 +48,19 @@ class Vcpu_dispatcher : public Vmm::Vcpu_dispatcher void _svm_startup() { - Vmm::log("_svm_startup called"); + Vmm::log(name(), " _svm_startup called"); } public: enum Type { SVM, VTX }; - Vcpu_dispatcher(Cap_connection &cap, Type type) + Vcpu_dispatcher(Genode::Env &env, Type type, char const * name) : - Vmm::Vcpu_dispatcher(STACK_SIZE, cap, Genode::env()->cpu_session(), Genode::Affinity::Location()), - _vcpu_thread(STACK_SIZE, Genode::env()->cpu_session(), Genode::Affinity::Location()) + Vmm::Vcpu_dispatcher(env, STACK_SIZE, &env.cpu(), + Genode::Affinity::Location(), + name), + _vcpu_thread(STACK_SIZE, &env.cpu(), Genode::Affinity::Location()) { using namespace Nova; @@ -83,14 +83,10 @@ class Vcpu_dispatcher : public Vmm::Vcpu_dispatcher }; -int main(int argc, char **argv) +void Component::construct(Genode::Env &env) { - Genode::log("--- VBox started ---"); + typedef Vcpu_dispatcher Vcpu; - static Cap_connection cap; - static Vcpu_dispatcher vcpu_dispatcher(cap, Vcpu_dispatcher::SVM); - - Genode::log("going to sleep forever..."); - sleep_forever(); - return 0; + static Vcpu vcpu(env, Vcpu::SVM, "vcpu1"); + static Vcpu vcpu2(env, Vcpu::SVM, "vcpu2"); } diff --git a/repos/ports/src/virtualbox/frontend/main.cc b/repos/ports/src/virtualbox/frontend/main.cc index f3c05d7a4..ec3db6b24 100644 --- a/repos/ports/src/virtualbox/frontend/main.cc +++ b/repos/ports/src/virtualbox/frontend/main.cc @@ -15,6 +15,7 @@ /* Genode includes */ #include +#include #include /* Virtualbox includes */ @@ -193,8 +194,24 @@ HRESULT setupmachine() } -int main(int argc, char **argv) +static Genode::Env *genode_env_ptr; + + +Genode::Env &genode_env() { + struct Genode_env_ptr_uninitialized : Genode::Exception { }; + if (!genode_env_ptr) + throw Genode_env_ptr_uninitialized(); + + return *genode_env_ptr; +} + + +void Component::construct(Genode::Env &env) +{ + /* make Genode environment accessible via the global 'genode_env()' */ + genode_env_ptr = &env; + try { using namespace Genode; @@ -212,17 +229,19 @@ int main(int argc, char **argv) /* enable stdout/stderr for VBox Log infrastructure */ init_libc_vbox_logger(); - int rc = RTR3InitExe(argc, &argv, 0); + static char argv0[] = { '_', 'm', 'a', 'i', 'n', 0}; + static char *argv[1] = { argv0 }; + char **dummy_argv = argv; + + int rc = RTR3InitExe(1, &dummy_argv, 0); if (RT_FAILURE(rc)) - return -1; + throw -1; HRESULT hrc = setupmachine(); if (FAILED(hrc)) { Genode::error("startup of VMM failed - reason ", hrc, " - exiting ..."); - return -2; + throw -2; } Genode::error("VMM exiting ..."); - - return 0; } diff --git a/repos/ports/src/virtualbox/mm.h b/repos/ports/src/virtualbox/mm.h index 5986df40a..f2bcd5533 100644 --- a/repos/ports/src/virtualbox/mm.h +++ b/repos/ports/src/virtualbox/mm.h @@ -54,10 +54,7 @@ class Sub_rm_connection : private Genode::Rm_connection, use_local_addr, local_addr, executable); }, - [&] () { - char quota[] = "ram_quota=8192"; - Genode::env()->parent()->upgrade(this->cap(), quota); - }); + [&] () { upgrade_ram(8192); }); Genode::addr_t new_addr = addr; new_addr += _offset; diff --git a/repos/ports/src/virtualbox/spec/nova/sup.cc b/repos/ports/src/virtualbox/spec/nova/sup.cc index 0a4e0a2f3..b23f4be8a 100644 --- a/repos/ports/src/virtualbox/spec/nova/sup.cc +++ b/repos/ports/src/virtualbox/spec/nova/sup.cc @@ -302,12 +302,14 @@ bool create_emt_vcpu(pthread_t * pthread, size_t stack, Vcpu_handler *vcpu_handler = 0; if (hip->has_feature_vmx()) - vcpu_handler = new (0x10) Vcpu_handler_vmx(stack, attr, start_routine, + vcpu_handler = new (0x10) Vcpu_handler_vmx(genode_env(), + stack, attr, start_routine, arg, cpu_session, location, cpu_id, name); if (hip->has_feature_svm()) - vcpu_handler = new (0x10) Vcpu_handler_svm(stack, attr, start_routine, + vcpu_handler = new (0x10) Vcpu_handler_svm(genode_env(), + stack, attr, start_routine, arg, cpu_session, location, cpu_id, name); diff --git a/repos/ports/src/virtualbox/spec/nova/vcpu.h b/repos/ports/src/virtualbox/spec/nova/vcpu.h index 4f85c81e9..5b7cc0a46 100644 --- a/repos/ports/src/virtualbox/spec/nova/vcpu.h +++ b/repos/ports/src/virtualbox/spec/nova/vcpu.h @@ -758,14 +758,13 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher, }; - Vcpu_handler(size_t stack_size, const pthread_attr_t *attr, + Vcpu_handler(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg, Genode::Cpu_session * cpu_session, Genode::Affinity::Location location, unsigned int cpu_id, const char * name) : - Vmm::Vcpu_dispatcher(stack_size, *Genode::env()->pd_session(), - cpu_session, location, + Vmm::Vcpu_dispatcher(env, stack_size, cpu_session, location, attr ? *attr : 0, start_routine, arg, name), _vcpu(cpu_session, location), diff --git a/repos/ports/src/virtualbox/spec/nova/vcpu_svm.h b/repos/ports/src/virtualbox/spec/nova/vcpu_svm.h index 298561e58..3029f9f33 100644 --- a/repos/ports/src/virtualbox/spec/nova/vcpu_svm.h +++ b/repos/ports/src/virtualbox/spec/nova/vcpu_svm.h @@ -84,13 +84,13 @@ class Vcpu_handler_svm : public Vcpu_handler public: - Vcpu_handler_svm(size_t stack_size, const pthread_attr_t *attr, + Vcpu_handler_svm(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg, Genode::Cpu_session * cpu_session, Genode::Affinity::Location location, unsigned int cpu_id, const char * name) : - Vcpu_handler(stack_size, attr, start_routine, arg, cpu_session, + Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session, location, cpu_id, name) { using namespace Nova; diff --git a/repos/ports/src/virtualbox/spec/nova/vcpu_vmx.h b/repos/ports/src/virtualbox/spec/nova/vcpu_vmx.h index 112eb22b0..f32314637 100644 --- a/repos/ports/src/virtualbox/spec/nova/vcpu_vmx.h +++ b/repos/ports/src/virtualbox/spec/nova/vcpu_vmx.h @@ -158,13 +158,13 @@ class Vcpu_handler_vmx : public Vcpu_handler public: - Vcpu_handler_vmx(size_t stack_size, const pthread_attr_t *attr, + Vcpu_handler_vmx(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg, Genode::Cpu_session * cpu_session, Genode::Affinity::Location location, unsigned int cpu_id, const char * name) : - Vcpu_handler(stack_size, attr, start_routine, arg, cpu_session, + Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session, location, cpu_id, name) { using namespace Nova; diff --git a/repos/ports/src/virtualbox/sup.h b/repos/ports/src/virtualbox/sup.h index b6272a81a..5c5ae7340 100644 --- a/repos/ports/src/virtualbox/sup.h +++ b/repos/ports/src/virtualbox/sup.h @@ -15,7 +15,7 @@ #define _SUP_H_ /* Genode includes */ -#include +#include /* VirtualBox includes */ #include @@ -48,6 +48,8 @@ void genode_update_tsc(void (*update_func)(void), unsigned long update_us); Genode::Cpu_session * get_vcpu_cpu_session(); +Genode::Env &genode_env(); + void genode_VMMR0_DO_GVMM_CREATE_VM(PSUPVMMR0REQHDR pReqHdr); void genode_VMMR0_DO_GVMM_REGISTER_VMCPU(PVMR0 pVMR0, VMCPUID idCpu); diff --git a/repos/ports/src/virtualbox/thread.cc b/repos/ports/src/virtualbox/thread.cc index c8b10a27c..b745f624b 100644 --- a/repos/ports/src/virtualbox/thread.cc +++ b/repos/ports/src/virtualbox/thread.cc @@ -131,8 +131,7 @@ extern "C" int pthread_create(pthread_t *thread, const pthread_attr_t *attr, } catch (Cpu_session::Out_of_metadata) { log("Upgrading memory for creation of " "thread '", Cstring(rtthread->szName), "'"); - env()->parent()->upgrade(cpu_connection(rtthread->enmType)->cap(), - "ram_quota=4096"); + cpu_connection(rtthread->enmType)->upgrade_ram(4096); } catch (...) { break; } } diff --git a/repos/ports/src/virtualbox5/frontend/main.cc b/repos/ports/src/virtualbox5/frontend/main.cc index c6b2ef853..f7ebc4ff5 100644 --- a/repos/ports/src/virtualbox5/frontend/main.cc +++ b/repos/ports/src/virtualbox5/frontend/main.cc @@ -15,6 +15,7 @@ /* Genode includes */ #include +#include #include /* Virtualbox includes */ @@ -224,8 +225,24 @@ HRESULT setupmachine() } -int main(int argc, char **argv) +static Genode::Env *genode_env_ptr; + + +Genode::Env &genode_env() { + struct Genode_env_ptr_uninitialized : Genode::Exception { }; + if (!genode_env_ptr) + throw Genode_env_ptr_uninitialized(); + + return *genode_env_ptr; +} + + +void Component::construct(Genode::Env &env) +{ + /* make Genode environment accessible via the global 'genode_env()' */ + genode_env_ptr = &env; + try { using namespace Genode; @@ -243,18 +260,20 @@ int main(int argc, char **argv) /* enable stdout/stderr for VBox Log infrastructure */ init_libc_vbox_logger(); - int rc = RTR3InitExe(argc, &argv, 0); + static char argv0[] = { '_', 'm', 'a', 'i', 'n', 0}; + static char *argv[1] = { argv0 }; + char **dummy_argv = argv; + + int rc = RTR3InitExe(1, &dummy_argv, 0); if (RT_FAILURE(rc)) - return -1; + throw -1; HRESULT hrc = setupmachine(); if (FAILED(hrc)) { Genode::error("startup of VMM failed - reason ", hrc, " '", RTErrCOMGet(hrc)->pszMsgFull, "' - exiting ..."); - return -2; + throw -2; } Genode::error("VMM exiting ..."); - - return 0; } diff --git a/repos/ports/src/virtualbox5/spec/nova/sup.cc b/repos/ports/src/virtualbox5/spec/nova/sup.cc index 87b8aad90..6d644283e 100644 --- a/repos/ports/src/virtualbox5/spec/nova/sup.cc +++ b/repos/ports/src/virtualbox5/spec/nova/sup.cc @@ -563,12 +563,14 @@ bool create_emt_vcpu(pthread_t * pthread, ::size_t stack, Vcpu_handler *vcpu_handler = 0; if (hip->has_feature_vmx()) - vcpu_handler = new (0x10) Vcpu_handler_vmx(stack, attr, start_routine, + vcpu_handler = new (0x10) Vcpu_handler_vmx(genode_env(), + stack, attr, start_routine, arg, cpu_session, location, cpu_id, name); if (hip->has_feature_svm()) - vcpu_handler = new (0x10) Vcpu_handler_svm(stack, attr, start_routine, + vcpu_handler = new (0x10) Vcpu_handler_svm(genode_env(), + stack, attr, start_routine, arg, cpu_session, location, cpu_id, name); diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu.h b/repos/ports/src/virtualbox5/spec/nova/vcpu.h index 90f31721b..c6232f358 100644 --- a/repos/ports/src/virtualbox5/spec/nova/vcpu.h +++ b/repos/ports/src/virtualbox5/spec/nova/vcpu.h @@ -761,16 +761,15 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher, }; - Vcpu_handler(size_t stack_size, const pthread_attr_t *attr, + Vcpu_handler(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg, Genode::Cpu_session * cpu_session, Genode::Affinity::Location location, unsigned int cpu_id, const char * name) : - Vmm::Vcpu_dispatcher(stack_size, *Genode::env()->pd_session(), - cpu_session, location, - attr ? *attr : 0, start_routine, - arg, name), + Vmm::Vcpu_dispatcher(env, stack_size, cpu_session, location, + attr ? *attr : 0, start_routine, arg, + name), _vcpu(cpu_session, location), _ec_sel(Genode::cap_map()->insert()), _irq_win(false), diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h b/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h index 43c784854..4411881f9 100644 --- a/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h +++ b/repos/ports/src/virtualbox5/spec/nova/vcpu_svm.h @@ -84,13 +84,13 @@ class Vcpu_handler_svm : public Vcpu_handler public: - Vcpu_handler_svm(size_t stack_size, const pthread_attr_t *attr, + Vcpu_handler_svm(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg, Genode::Cpu_session * cpu_session, Genode::Affinity::Location location, unsigned int cpu_id, const char * name) : - Vcpu_handler(stack_size, attr, start_routine, arg, cpu_session, + Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session, location, cpu_id, name) { using namespace Nova; diff --git a/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h b/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h index e09629615..a06baf371 100644 --- a/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h +++ b/repos/ports/src/virtualbox5/spec/nova/vcpu_vmx.h @@ -166,13 +166,13 @@ class Vcpu_handler_vmx : public Vcpu_handler public: - Vcpu_handler_vmx(size_t stack_size, const pthread_attr_t *attr, + Vcpu_handler_vmx(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg, Genode::Cpu_session * cpu_session, Genode::Affinity::Location location, unsigned int cpu_id, const char * name) : - Vcpu_handler(stack_size, attr, start_routine, arg, cpu_session, + Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session, location, cpu_id, name) { using namespace Nova;