From de99945af05f182aed86d67768c63c8cd88ab84a Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Wed, 21 Jun 2023 17:25:44 +0200 Subject: [PATCH] base: pass 'Platform &' to 'bootstrap_component' This eliminates the need of component.cc to pull the platform resources out of thin air (calling 'env_deprecated()'). Issue #4784 --- repos/base-fiasco/src/core/platform.cc | 18 +- repos/base-foc/src/core/platform.cc | 18 +- repos/base-linux/src/core/platform.cc | 4 +- repos/base-linux/src/lib/base/platform.cc | 10 +- .../base-linux/src/lib/lx_hybrid/lx_hybrid.cc | 6 +- repos/base-nova/src/core/pager.cc | 4 +- repos/base-nova/src/core/platform.cc | 14 +- repos/base-okl4/src/core/platform.cc | 24 +- repos/base-pistachio/src/core/platform.cc | 22 +- .../base-sel4/src/core/include/thread_sel4.h | 4 +- repos/base-sel4/src/core/platform.cc | 23 +- repos/base/src/core/main.cc | 14 +- .../base/src/include/base/internal/globals.h | 6 +- repos/base/src/lib/base/component.cc | 363 +++++++++--------- repos/base/src/lib/base/platform.cc | 9 +- repos/base/src/lib/startup/_main.cc | 9 +- 16 files changed, 285 insertions(+), 263 deletions(-) diff --git a/repos/base-fiasco/src/core/platform.cc b/repos/base-fiasco/src/core/platform.cc index 058151f246..cacb99151a 100644 --- a/repos/base-fiasco/src/core/platform.cc +++ b/repos/base-fiasco/src/core/platform.cc @@ -123,7 +123,7 @@ static void _core_pager_loop() } -Platform::Sigma0::Sigma0() +Core::Platform::Sigma0::Sigma0() : Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location(), Session_label(), @@ -133,14 +133,14 @@ Platform::Sigma0::Sigma0() } -Platform::Sigma0 &Platform::sigma0() +Core::Platform::Sigma0 &Core::Platform::sigma0() { static Sigma0 _sigma0; return _sigma0; } -Platform::Core_pager::Core_pager(Platform_pd &core_pd) +Core::Platform::Core_pager::Core_pager(Platform_pd &core_pd) : Platform_thread("core.pager"), Pager_object(Cpu_session_capability(), Thread_capability(), @@ -167,7 +167,7 @@ Platform::Core_pager::Core_pager(Platform_pd &core_pd) } -Platform::Core_pager &Platform::core_pager() +Core::Platform::Core_pager &Core::Platform::core_pager() { static Core_pager _core_pager(core_pd()); return _core_pager; @@ -249,7 +249,7 @@ static inline int sigma0_req_region(addr_t *addr, unsigned log2size) } -void Platform::_setup_mem_alloc() +void Core::Platform::_setup_mem_alloc() { /* * Completely map program image by touching all pages read-only to @@ -296,7 +296,7 @@ void Platform::_setup_mem_alloc() } -void Platform::_setup_irq_alloc() +void Core::Platform::_setup_irq_alloc() { _irq_alloc.add_range(0, 0x10); } @@ -347,7 +347,7 @@ static l4_kernel_info_t *get_kip() } -void Platform::_setup_basics() +void Core::Platform::_setup_basics() { l4_kernel_info_t * kip = get_kip(); @@ -397,7 +397,7 @@ void Platform::_setup_basics() } -Platform::Platform() +Core::Platform::Platform() : _ram_alloc(nullptr), _io_mem_alloc(&core_mem_alloc()), _io_port_alloc(&core_mem_alloc()), _irq_alloc(&core_mem_alloc()), @@ -484,7 +484,7 @@ Platform::Platform() ** Generic platform interface ** ********************************/ -void Platform::wait_for_exit() +void Core::Platform::wait_for_exit() { /* * On Fiasco, Core never exits. So let us sleep forever. diff --git a/repos/base-foc/src/core/platform.cc b/repos/base-foc/src/core/platform.cc index 657ee7a70f..bca9bd8741 100644 --- a/repos/base-foc/src/core/platform.cc +++ b/repos/base-foc/src/core/platform.cc @@ -120,7 +120,7 @@ static void _core_pager_loop() } -Platform::Sigma0::Sigma0(Cap_index* i) +Core::Platform::Sigma0::Sigma0(Cap_index* i) : Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location(), Session_label(), @@ -134,7 +134,7 @@ Platform::Sigma0::Sigma0(Cap_index* i) } -Platform::Core_pager::Core_pager(Platform_pd &core_pd, Sigma0 &sigma0) +Core::Platform::Core_pager::Core_pager(Platform_pd &core_pd, Sigma0 &sigma0) : Platform_thread("core.pager"), Pager_object(Cpu_session_capability(), Thread_capability(), @@ -161,7 +161,7 @@ Platform::Core_pager::Core_pager(Platform_pd &core_pd, Sigma0 &sigma0) } -Platform::Core_pager &Platform::core_pager() +Core::Platform::Core_pager &Core::Platform::core_pager() { static Core_pager _core_pager(core_pd(), _sigma0); return _core_pager; @@ -280,7 +280,7 @@ static Foc::l4_kernel_info_t &sigma0_map_kip() } -void Platform::_setup_mem_alloc() +void Core::Platform::_setup_mem_alloc() { /* * Completely map program image by touching all pages read-only to @@ -329,7 +329,7 @@ void Platform::_setup_mem_alloc() } -void Platform::_setup_irq_alloc() +void Core::Platform::_setup_irq_alloc() { using namespace Foc; @@ -342,7 +342,7 @@ void Platform::_setup_irq_alloc() } -void Platform::_setup_basics() +void Core::Platform::_setup_basics() { using namespace Foc; @@ -415,7 +415,7 @@ void Platform::_setup_basics() } -Platform::Platform() +Core::Platform::Platform() : _ram_alloc(nullptr), _io_mem_alloc(&core_mem_alloc()), _io_port_alloc(&core_mem_alloc()), _irq_alloc(&core_mem_alloc()), @@ -581,7 +581,7 @@ Platform::Platform() ** Generic platform interface ** ********************************/ -void Platform::wait_for_exit() +void Core::Platform::wait_for_exit() { /* * On Fiasco.OC, core never exits. So let us sleep forever. @@ -590,7 +590,7 @@ void Platform::wait_for_exit() } -Affinity::Space Platform::affinity_space() const +Affinity::Space Core::Platform::affinity_space() const { using namespace Foc; diff --git a/repos/base-linux/src/core/platform.cc b/repos/base-linux/src/core/platform.cc index 6ca52b1264..25352c972d 100644 --- a/repos/base-linux/src/core/platform.cc +++ b/repos/base-linux/src/core/platform.cc @@ -86,7 +86,7 @@ static void sigchld_handler(int) } -Platform::Platform() +Core::Platform::Platform() : _core_mem_alloc(nullptr) { @@ -118,7 +118,7 @@ Platform::Platform() } -void Platform::wait_for_exit() +void Core::Platform::wait_for_exit() { for (;;) { diff --git a/repos/base-linux/src/lib/base/platform.cc b/repos/base-linux/src/lib/base/platform.cc index 1e99133213..f5aa741822 100644 --- a/repos/base-linux/src/lib/base/platform.cc +++ b/repos/base-linux/src/lib/base/platform.cc @@ -178,16 +178,12 @@ Capability Platform::_obtain_parent_cap() void Genode::init_parent_resource_requests(Genode::Env & env) { - /** - * Catch up asynchronous resource request and notification - * mechanism construction of the expanding parent environment - */ using Parent = Expanding_parent_client; static_cast(&env.parent())->init_fallback_signal_handling(); } -void Genode::init_platform() +Platform &Genode::init_platform() { static Genode::Platform platform; @@ -197,8 +193,12 @@ void Genode::init_platform() init_thread(platform.cpu, platform.rm); init_thread_start(platform.pd.rpc_cap()); init_thread_bootstrap(platform.cpu, platform.parent.main_thread_cap()); + init_exception_handling(platform.pd, platform.rm); + init_signal_receiver(platform.pd, platform.parent); _platform_ptr = &platform; + + return platform; } diff --git a/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc b/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc index 6b26a5f707..e56d61da69 100644 --- a/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc +++ b/repos/base-linux/src/lib/lx_hybrid/lx_hybrid.cc @@ -80,7 +80,6 @@ static Genode::Env *_env_ptr; namespace Genode { - extern void bootstrap_component(); extern void call_global_static_constructors(); struct Thread_meta_data_created; @@ -131,8 +130,9 @@ Genode::size_t Component::stack_size() int main() { - Genode::init_platform(); - Genode::bootstrap_component(); + using namespace Genode; + + bootstrap_component(init_platform()); /* never reached */ } diff --git a/repos/base-nova/src/core/pager.cc b/repos/base-nova/src/core/pager.cc index 05b461e561..e484019cd6 100644 --- a/repos/base-nova/src/core/pager.cc +++ b/repos/base-nova/src/core/pager.cc @@ -66,11 +66,11 @@ struct Pager_thread: public Thread void entry() override { } }; -enum { PAGER_CPUS = Platform::MAX_SUPPORTED_CPUS }; +enum { PAGER_CPUS = Core::Platform::MAX_SUPPORTED_CPUS }; static Constructible pager_threads[PAGER_CPUS]; static Pager_thread &pager_thread(Affinity::Location location, - Platform &platform) + Core::Platform &platform) { unsigned const pager_index = platform.pager_index(location); unsigned const kernel_cpu_id = platform.kernel_cpu_id(location); diff --git a/repos/base-nova/src/core/platform.cc b/repos/base-nova/src/core/platform.cc index 89daeee485..f475168a17 100644 --- a/repos/base-nova/src/core/platform.cc +++ b/repos/base-nova/src/core/platform.cc @@ -74,8 +74,8 @@ extern unsigned _prog_img_beg, _prog_img_end; * This function uses the virtual-memory region allocator to find a region * fitting the desired mapping. Other allocators are left alone. */ -addr_t Platform::_map_pages(addr_t const phys_addr, addr_t const pages, - bool guard_page) +addr_t Core::Platform::_map_pages(addr_t const phys_addr, addr_t const pages, + bool guard_page) { addr_t const size = pages << get_page_size_log2(); @@ -301,7 +301,7 @@ static Affinity::Space setup_affinity_space(Hip const &hip) ** Platform ** **************/ -Platform::Platform() +Core::Platform::Platform() : _io_mem_alloc(&core_mem_alloc()), _io_port_alloc(&core_mem_alloc()), _irq_alloc(&core_mem_alloc()), @@ -977,13 +977,13 @@ Platform::Platform() } -addr_t Platform::_rom_module_phys(addr_t virt) +addr_t Core::Platform::_rom_module_phys(addr_t virt) { return virt - (addr_t)&_prog_img_beg + _core_phys_start; } -unsigned Platform::kernel_cpu_id(Affinity::Location location) const +unsigned Core::Platform::kernel_cpu_id(Affinity::Location location) const { unsigned const cpu_id = pager_index(location); @@ -996,7 +996,7 @@ unsigned Platform::kernel_cpu_id(Affinity::Location location) const } -unsigned Platform::pager_index(Affinity::Location location) const +unsigned Core::Platform::pager_index(Affinity::Location location) const { return (location.xpos() * _cpus.height() + location.ypos()) % (_cpus.width() * _cpus.height()); @@ -1033,5 +1033,5 @@ bool Mapped_mem_allocator::_unmap_local(addr_t virt_addr, addr_t, size_t size) ** Generic platform interface ** ********************************/ -void Platform::wait_for_exit() { sleep_forever(); } +void Core::Platform::wait_for_exit() { sleep_forever(); } diff --git a/repos/base-okl4/src/core/platform.cc b/repos/base-okl4/src/core/platform.cc index 8455b875be..19f2a9ab40 100644 --- a/repos/base-okl4/src/core/platform.cc +++ b/repos/base-okl4/src/core/platform.cc @@ -51,9 +51,9 @@ bool Mapped_mem_allocator::_unmap_local(addr_t virt_addr, addr_t, size_t size) { ** Boot-info parser ** **********************/ -int Platform::bi_init_mem(Okl4::uintptr_t virt_base, Okl4::uintptr_t virt_end, - Okl4::uintptr_t phys_base, Okl4::uintptr_t phys_end, - const Okl4::bi_user_data_t *data) +int Core::Platform::bi_init_mem(Okl4::uintptr_t virt_base, Okl4::uintptr_t virt_end, + Okl4::uintptr_t phys_base, Okl4::uintptr_t phys_end, + const Okl4::bi_user_data_t *data) { Platform &p = *(Platform *)data->user_data; p._core_mem_alloc.phys_alloc().add_range(phys_base, phys_end - phys_base + 1); @@ -62,8 +62,8 @@ int Platform::bi_init_mem(Okl4::uintptr_t virt_base, Okl4::uintptr_t virt_end, } -int Platform::bi_add_virt_mem(Okl4::bi_name_t, Okl4::uintptr_t base, - Okl4::uintptr_t end, const Okl4::bi_user_data_t *data) +int Core::Platform::bi_add_virt_mem(Okl4::bi_name_t, Okl4::uintptr_t base, + Okl4::uintptr_t end, const Okl4::bi_user_data_t *data) { /* prevent first page from being added to core memory */ if (base < get_page_size() || end < get_page_size()) @@ -75,8 +75,8 @@ int Platform::bi_add_virt_mem(Okl4::bi_name_t, Okl4::uintptr_t base, } -int Platform::bi_add_phys_mem(Okl4::bi_name_t pool, Okl4::uintptr_t base, - Okl4::uintptr_t end, const Okl4::bi_user_data_t *data) +int Core::Platform::bi_add_phys_mem(Okl4::bi_name_t pool, Okl4::uintptr_t base, + Okl4::uintptr_t end, const Okl4::bi_user_data_t *data) { if (pool == 2) { Platform &p = *(Platform *)data->user_data; @@ -90,7 +90,7 @@ static char init_slab_block_rom[get_page_size()]; static char init_slab_block_thread[get_page_size()]; -Platform::Platform() +Core::Platform::Platform() : _io_mem_alloc(&core_mem_alloc()), _io_port_alloc(&core_mem_alloc()), _irq_alloc(&core_mem_alloc()), @@ -142,9 +142,9 @@ Platform::Platform() * type. */ static Okl4::bi_callbacks_t callbacks; - callbacks.init_mem = Platform::bi_init_mem; - callbacks.add_virt_mem = Platform::bi_add_virt_mem; - callbacks.add_phys_mem = Platform::bi_add_phys_mem; + callbacks.init_mem = bi_init_mem; + callbacks.add_virt_mem = bi_add_virt_mem; + callbacks.add_phys_mem = bi_add_phys_mem; Okl4::bootinfo_parse((void *)boot_info_addr, &callbacks, this); @@ -254,7 +254,7 @@ Platform::Platform() ** Generic platform interface ** ********************************/ -void Platform::wait_for_exit() +void Core::Platform::wait_for_exit() { /* * On OKL4, core never exits. So let us sleep forever. diff --git a/repos/base-pistachio/src/core/platform.cc b/repos/base-pistachio/src/core/platform.cc index 6291fcaedc..2786b910ac 100644 --- a/repos/base-pistachio/src/core/platform.cc +++ b/repos/base-pistachio/src/core/platform.cc @@ -195,7 +195,7 @@ static void _core_pager_loop() } -Platform::Sigma0::Sigma0() +Core::Platform::Sigma0::Sigma0() : Pager_object(Cpu_session_capability(), Thread_capability(), 0, Affinity::Location(), @@ -205,14 +205,14 @@ Platform::Sigma0::Sigma0() } -Platform::Sigma0 &Platform::sigma0() +Core::Platform::Sigma0 &Core::Platform::sigma0() { static Sigma0 _sigma0; return _sigma0; } -Platform::Core_pager::Core_pager(Platform_pd &core_pd) +Core::Platform::Core_pager::Core_pager(Platform_pd &core_pd) : Platform_thread("core.pager"), Pager_object(Cpu_session_capability(), Thread_capability(), @@ -233,7 +233,7 @@ Platform::Core_pager::Core_pager(Platform_pd &core_pd) } -Platform::Core_pager &Platform::core_pager() +Core::Platform::Core_pager &Core::Platform::core_pager() { static Core_pager _core_pager(core_pd()); return _core_pager; @@ -370,7 +370,7 @@ bool sigma0_req_region(addr_t *addr, unsigned log2size) } -void Platform::_setup_mem_alloc() +void Core::Platform::_setup_mem_alloc() { Pistachio::L4_KernelInterfacePage_t *kip = Pistachio::get_kip(); @@ -452,10 +452,10 @@ void Platform::_setup_mem_alloc() } -void Platform::_setup_irq_alloc() { _irq_alloc.add_range(0, 0x10); } +void Core::Platform::_setup_irq_alloc() { _irq_alloc.add_range(0, 0x10); } -void Platform::_setup_preemption() +void Core::Platform::_setup_preemption() { /* * The roottask has the maximum priority @@ -465,7 +465,7 @@ void Platform::_setup_preemption() } -void Platform::_setup_basics() +void Core::Platform::_setup_basics() { using namespace Pistachio; @@ -555,7 +555,7 @@ void Platform::_setup_basics() } -Platform_pd &Platform::core_pd() +Platform_pd &Core::Platform::core_pd() { /* on first call, setup task object for core task */ static Platform_pd _core_pd(true); @@ -563,7 +563,7 @@ Platform_pd &Platform::core_pd() } -Platform::Platform() +Core::Platform::Platform() : _ram_alloc(nullptr), _io_mem_alloc(&core_mem_alloc()), _io_port_alloc(&core_mem_alloc()), _irq_alloc(&core_mem_alloc()), @@ -644,7 +644,7 @@ Platform::Platform() ** Generic platform interface ** ********************************/ -void Platform::wait_for_exit() +void Core::Platform::wait_for_exit() { /* * On Pistachio, core never exits. So let us sleep forever. diff --git a/repos/base-sel4/src/core/include/thread_sel4.h b/repos/base-sel4/src/core/include/thread_sel4.h index 6f2db0ca03..765c3213d7 100644 --- a/repos/base-sel4/src/core/include/thread_sel4.h +++ b/repos/base-sel4/src/core/include/thread_sel4.h @@ -88,7 +88,7 @@ void Genode::Thread_info::init(addr_t const utcb_virt_addr, unsigned const prio) { using namespace Core; - Platform &platform = platform_specific(); + Core::Platform &platform = platform_specific(); Range_allocator &phys_alloc = platform.ram_alloc(); /* create IPC buffer of one page */ @@ -151,7 +151,7 @@ void Genode::Thread_info::destruct() } if (ipc_buffer_phys) { - Platform &platform = platform_specific(); + Core::Platform &platform = platform_specific(); Range_allocator &phys_alloc = platform.ram_alloc(); Untyped_memory::convert_to_untyped_frames(ipc_buffer_phys, 4096); Untyped_memory::free_page(phys_alloc, ipc_buffer_phys); diff --git a/repos/base-sel4/src/core/platform.cc b/repos/base-sel4/src/core/platform.cc index 10990f30e1..133d0192d9 100644 --- a/repos/base-sel4/src/core/platform.cc +++ b/repos/base-sel4/src/core/platform.cc @@ -43,7 +43,7 @@ static bool const verbose_boot_info = true; * platform_specific(). May happen if meta data allocator of phys_alloc runs * out of memory. */ -static Platform * platform_in_construction = nullptr; +static Core::Platform * platform_in_construction = nullptr; /* * Memory-layout information provided by the linker script @@ -85,14 +85,14 @@ bool Mapped_mem_allocator::_unmap_local(addr_t virt_addr, addr_t phys_addr, size ** Platform interface ** ************************/ -void Platform::_init_unused_phys_alloc() +void Core::Platform::_init_unused_phys_alloc() { /* the lower physical ram is kept by the kernel and not usable to us */ _unused_phys_alloc.add_range(0x100000, 0UL - 0x100000); } -void Platform::_init_allocators() +void Core::Platform::_init_allocators() { /* interrupt allocator */ _irq_alloc.add_range(0, 256); @@ -164,7 +164,7 @@ void Platform::_init_allocators() } -void Platform::_switch_to_core_cspace() +void Core::Platform::_switch_to_core_cspace() { Cnode_base const initial_cspace(Cap_sel(seL4_CapInitThreadCNode), CONFIG_WORD_SIZE); @@ -267,13 +267,13 @@ void Platform::_switch_to_core_cspace() } -Cap_sel Platform::_init_asid_pool() +Cap_sel Core::Platform::_init_asid_pool() { return Cap_sel(seL4_CapInitThreadASIDPool); } -void Platform::_init_rom_modules() +void Core::Platform::_init_rom_modules() { seL4_BootInfo const &bi = sel4_boot_info(); @@ -528,9 +528,8 @@ void Platform::_init_rom_modules() } -Platform::Platform() +Core::Platform::Platform() : - _io_mem_alloc(&core_mem_alloc()), _io_port_alloc(&core_mem_alloc()), _irq_alloc(&core_mem_alloc()), _unused_phys_alloc(&core_mem_alloc()), @@ -631,7 +630,7 @@ Platform::Platform() } Idle_trace_source(Trace::Source_registry ®istry, - Platform &platform, Range_allocator &phys_alloc, + Core::Platform &platform, Range_allocator &phys_alloc, Affinity::Location affinity) : Trace::Control(), @@ -659,7 +658,7 @@ Platform::Platform() } -unsigned Platform::alloc_core_rcv_sel() +unsigned Core::Platform::alloc_core_rcv_sel() { Cap_sel rcv_sel = _core_sel_alloc.alloc(); @@ -670,13 +669,13 @@ unsigned Platform::alloc_core_rcv_sel() } -void Platform::reset_sel(unsigned sel) +void Core::Platform::reset_sel(unsigned sel) { _core_cnode.remove(Cap_sel(sel)); } -void Platform::wait_for_exit() +void Core::Platform::wait_for_exit() { sleep_forever(); } diff --git a/repos/base/src/core/main.cc b/repos/base/src/core/main.cc index a03b68f955..7b56385acd 100644 --- a/repos/base/src/core/main.cc +++ b/repos/base/src/core/main.cc @@ -78,7 +78,7 @@ Env_deprecated *Genode::env_deprecated() { return &core_env(); } -Platform &Core::platform_specific() +Core::Platform &Core::platform_specific() { static Platform _platform; return _platform; @@ -88,7 +88,15 @@ Platform &Core::platform_specific() Platform_generic &Core::platform() { return platform_specific(); } -void Genode::init_platform() { core_env(); } +struct Genode::Platform { }; + + +Genode::Platform &Genode::init_platform() +{ + core_env(); + static Genode::Platform platform { }; + return platform; +} /** @@ -221,7 +229,7 @@ namespace Genode { Genode::size_t Component::stack_size() { return 64*1024; } -void Genode::bootstrap_component() +void Genode::bootstrap_component(Genode::Platform &) { init_exception_handling(*core_env().pd_session(), core_env().local_rm()); diff --git a/repos/base/src/include/base/internal/globals.h b/repos/base/src/include/base/internal/globals.h index ee904dc2c3..f2b4b3e648 100644 --- a/repos/base/src/include/base/internal/globals.h +++ b/repos/base/src/include/base/internal/globals.h @@ -21,12 +21,14 @@ namespace Genode { class Region_map; class Ram_allocator; class Env; + class Platform; class Local_session_id_space; extern Region_map *env_stack_area_region_map; extern Ram_allocator *env_stack_area_ram_allocator; - void init_platform(); + Platform &init_platform(); + void init_stack_area(); void init_exception_handling(Ram_allocator &, Region_map &); void init_signal_transmitter(Env &); @@ -58,7 +60,7 @@ namespace Genode { Env &internal_env(); void prepare_init_main_thread(); - void bootstrap_component(); + void bootstrap_component(Platform &); void binary_ready_hook_for_platform(); } diff --git a/repos/base/src/lib/base/component.cc b/repos/base/src/lib/base/component.cc index 44beffc473..b1493f8e00 100644 --- a/repos/base/src/lib/base/component.cc +++ b/repos/base/src/lib/base/component.cc @@ -22,12 +22,19 @@ /* base-internal includes */ #include +#include + /* * XXX remove this pointer once 'Env_deprecated' is removed */ static Genode::Env *env_ptr = nullptr; +namespace Genode { struct Component_env; } + +using namespace Genode; + + /** * Excecute pending static constructors * @@ -37,180 +44,182 @@ static Genode::Env *env_ptr = nullptr; void Genode::exec_static_constructors() __attribute__((weak)); void Genode::exec_static_constructors() { } -namespace { - using namespace Genode; +struct Genode::Component_env : Env +{ + Platform &_platform; - struct Env : Genode::Env + Parent &_parent = _platform.parent; + Pd_session &_pd = _platform.pd; + Cpu_session &_cpu = _platform.cpu; + Region_map &_rm = _platform.rm; + + Capability _pd_cap = _platform.pd.rpc_cap(); + Capability _cpu_cap = _platform.cpu.rpc_cap(); + + Entrypoint &_ep; + + /** + * Mutex for serializing 'session' and 'close' + */ + Mutex _mutex { }; + + /** + * Utility to used block for single signal + */ + struct Blockade { - Genode::Entrypoint &_ep; + Parent &_parent; + Signal_receiver _sig_rec { }; + Signal_context _sig_ctx { }; - Genode::Parent &_parent = *env_deprecated()->parent(); - - /** - * Mutex for serializing 'session' and 'close' - */ - Genode::Mutex _mutex { }; - - /** - * Utility to used block for single signal - */ - struct Blockade + Blockade(Parent &parent) : _parent(parent) { - Parent &_parent; - Genode::Signal_receiver _sig_rec { }; - Genode::Signal_context _sig_ctx { }; - - Blockade(Parent &parent) : _parent(parent) - { - _parent.session_sigh(_sig_rec.manage(&_sig_ctx)); - } - - void block() { _sig_rec.wait_for_signal(); } - }; - - Constructible _session_blockade { }; - - Env(Genode::Entrypoint &ep) : _ep(ep) { env_ptr = this; } - - Genode::Parent &parent() override { return _parent; } - Genode::Cpu_session &cpu() override { return *Genode::env_deprecated()->cpu_session(); } - Genode::Region_map &rm() override { return *Genode::env_deprecated()->rm_session(); } - Genode::Pd_session &pd() override { return *Genode::env_deprecated()->pd_session(); } - Genode::Entrypoint &ep() override { return _ep; } - - Genode::Cpu_session_capability cpu_session_cap() override - { - return Genode::env_deprecated()->cpu_session_cap(); + _parent.session_sigh(_sig_rec.manage(&_sig_ctx)); } - Genode::Pd_session_capability pd_session_cap() override - { - return Genode::env_deprecated()->pd_session_cap(); - } - - Genode::Id_space &id_space() override - { - return Genode::env_session_id_space(); - } - - void _block_for_session() - { - /* - * Construct blockade lazily be avoid it being used in core where - * all session requests are immediately answered. - */ - if (!_session_blockade.constructed()) - _session_blockade.construct(_parent); - - _session_blockade->block(); - } - - Session_capability try_session(Parent::Service_name const &name, - Parent::Client::Id id, - Parent::Session_args const &args, - Affinity const &affinity) override - { - if (!args.valid_string()) { - warning(name.string(), " session denied because of truncated arguments"); - throw Service_denied(); - } - - Mutex::Guard guard(_mutex); - - Session_capability cap = _parent.session(id, name, args, affinity); - - if (cap.valid()) - return cap; - - _block_for_session(); - return _parent.session_cap(id); - } - - Session_capability session(Parent::Service_name const &name, - Parent::Client::Id id, - Parent::Session_args const &args, - Affinity const &affinity) override - { - /* - * Since we account for the backing store for session meta data on - * the route between client and server, the session quota provided - * by the client may become successively diminished by intermediate - * components, prompting the server to deny the session request. - */ - - /* extract session quota as specified by the 'Connection' */ - char argbuf[Parent::Session_args::MAX_SIZE]; - copy_cstring(argbuf, args.string(), sizeof(argbuf)); - - Ram_quota ram_quota = ram_quota_from_args(argbuf); - Cap_quota cap_quota = cap_quota_from_args(argbuf); - - unsigned warn_after_attempts = 2; - - for (unsigned cnt = 0;; cnt++) { - - try { - - Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", - String<32>(ram_quota).string()); - - Arg_string::set_arg(argbuf, sizeof(argbuf), "cap_quota", - String<32>(cap_quota).string()); - - return try_session(name, id, Parent::Session_args(argbuf), affinity); - } - - catch (Insufficient_ram_quota) { - ram_quota = Ram_quota { ram_quota.value + 4096 }; } - - catch (Insufficient_cap_quota) { - cap_quota = Cap_quota { cap_quota.value + 4 }; } - - catch (Out_of_ram) { - if (ram_quota.value > pd().avail_ram().value) { - Parent::Resource_args args(String<64>("ram_quota=", ram_quota)); - _parent.resource_request(args); - } - } - - catch (Out_of_caps) { - if (cap_quota.value > pd().avail_caps().value) { - Parent::Resource_args args(String<64>("cap_quota=", cap_quota)); - _parent.resource_request(args); - } - } - - if (cnt == warn_after_attempts) { - warning("re-attempted ", name.string(), " session request ", - cnt, " times (args: ", Cstring(argbuf), ")"); - warn_after_attempts *= 2; - } - } - } - - void upgrade(Parent::Client::Id id, Parent::Upgrade_args const &args) override - { - Mutex::Guard guard(_mutex); - - if (_parent.upgrade(id, args) == Parent::UPGRADE_PENDING) - _block_for_session(); - } - - void close(Parent::Client::Id id) override - { - Mutex::Guard guard(_mutex); - - if (_parent.close(id) == Parent::CLOSE_PENDING) - _block_for_session(); - } - - void exec_static_constructors() override - { - Genode::exec_static_constructors(); - } + void block() { _sig_rec.wait_for_signal(); } }; -} + + Constructible _session_blockade { }; + + Component_env(Platform &platform, Entrypoint &ep) + : + _platform(platform), _ep(ep) + { + env_ptr = this; + } + + Parent &parent() override { return _parent; } + Cpu_session &cpu() override { return _cpu; } + Region_map &rm() override { return _rm; } + Pd_session &pd() override { return _pd; } + Entrypoint &ep() override { return _ep; } + + Cpu_session_capability cpu_session_cap() override { return _cpu_cap; } + Pd_session_capability pd_session_cap() override { return _pd_cap; } + + Id_space &id_space() override + { + return env_session_id_space(); + } + + void _block_for_session() + { + /* + * Construct blockade lazily be avoid it being used in core where + * all session requests are immediately answered. + */ + if (!_session_blockade.constructed()) + _session_blockade.construct(_parent); + + _session_blockade->block(); + } + + Session_capability try_session(Parent::Service_name const &name, + Parent::Client::Id id, + Parent::Session_args const &args, + Affinity const &affinity) override + { + if (!args.valid_string()) { + warning(name.string(), " session denied because of truncated arguments"); + throw Service_denied(); + } + + Mutex::Guard guard(_mutex); + + Session_capability cap = _parent.session(id, name, args, affinity); + + if (cap.valid()) + return cap; + + _block_for_session(); + return _parent.session_cap(id); + } + + Session_capability session(Parent::Service_name const &name, + Parent::Client::Id id, + Parent::Session_args const &args, + Affinity const &affinity) override + { + /* + * Since we account for the backing store for session meta data on + * the route between client and server, the session quota provided + * by the client may become successively diminished by intermediate + * components, prompting the server to deny the session request. + */ + + /* extract session quota as specified by the 'Connection' */ + char argbuf[Parent::Session_args::MAX_SIZE]; + copy_cstring(argbuf, args.string(), sizeof(argbuf)); + + Ram_quota ram_quota = ram_quota_from_args(argbuf); + Cap_quota cap_quota = cap_quota_from_args(argbuf); + + unsigned warn_after_attempts = 2; + + for (unsigned cnt = 0;; cnt++) { + + try { + + Arg_string::set_arg(argbuf, sizeof(argbuf), "ram_quota", + String<32>(ram_quota).string()); + + Arg_string::set_arg(argbuf, sizeof(argbuf), "cap_quota", + String<32>(cap_quota).string()); + + return try_session(name, id, Parent::Session_args(argbuf), affinity); + } + + catch (Insufficient_ram_quota) { + ram_quota = Ram_quota { ram_quota.value + 4096 }; } + + catch (Insufficient_cap_quota) { + cap_quota = Cap_quota { cap_quota.value + 4 }; } + + catch (Out_of_ram) { + if (ram_quota.value > pd().avail_ram().value) { + Parent::Resource_args args(String<64>("ram_quota=", ram_quota)); + _parent.resource_request(args); + } + } + + catch (Out_of_caps) { + if (cap_quota.value > pd().avail_caps().value) { + Parent::Resource_args args(String<64>("cap_quota=", cap_quota)); + _parent.resource_request(args); + } + } + + if (cnt == warn_after_attempts) { + warning("re-attempted ", name.string(), " session request ", + cnt, " times (args: ", Cstring(argbuf), ")"); + warn_after_attempts *= 2; + } + } + } + + void upgrade(Parent::Client::Id id, Parent::Upgrade_args const &args) override + { + Mutex::Guard guard(_mutex); + + if (_parent.upgrade(id, args) == Parent::UPGRADE_PENDING) + _block_for_session(); + } + + void close(Parent::Client::Id id) override + { + Mutex::Guard guard(_mutex); + + if (_parent.close(id) == Parent::CLOSE_PENDING) + _block_for_session(); + } + + void exec_static_constructors() override + { + Genode::exec_static_constructors(); + } +}; namespace Genode { @@ -230,8 +239,8 @@ namespace Genode { } -Genode::size_t Component::stack_size() __attribute__((weak)); -Genode::size_t Component::stack_size() { return 64*1024; } +size_t Component::stack_size() __attribute__((weak)); +size_t Component::stack_size() { return 64*1024; } /** @@ -252,22 +261,28 @@ void Genode::init_ldso_phdr(Env &) { } */ struct Genode::Startup { - ::Env env { ep }; + Component_env env; - bool const ldso_phdr = (init_ldso_phdr(env), true); - bool const exception_handling = (init_exception_handling(env.pd(), env.rm()), true); - bool const signal_receiver = (init_signal_receiver(env.pd(), env.parent()), true); + /* + * 'init_ldso_phdr' must be called before 'init_exception_handling' because + * the initial exception thrown by 'init_exception_handling' involves the + * linker's 'dl_iterate_phdr' function. + */ + bool const ldso_phdr = (init_ldso_phdr(env), true); + bool const exception = (init_exception_handling(env.ram(), env.rm()), true); /* * The construction of the main entrypoint does never return. */ Entrypoint ep { env }; + + Startup(Platform &platform) : env(platform, ep) { } }; -void Genode::bootstrap_component() +void Genode::bootstrap_component(Platform &platform) { - static Startup startup; + static Startup startup { platform }; /* never reached */ } diff --git a/repos/base/src/lib/base/platform.cc b/repos/base/src/lib/base/platform.cc index 2d8e5c5499..35c01b6fe2 100644 --- a/repos/base/src/lib/base/platform.cc +++ b/repos/base/src/lib/base/platform.cc @@ -51,16 +51,12 @@ Env_deprecated *Genode::env_deprecated() void Genode::init_parent_resource_requests(Genode::Env &env) { - /** - * Catch up asynchronous resource request and notification - * mechanism construction of the expanding parent environment - */ using Parent = Expanding_parent_client; static_cast(&env.parent())->init_fallback_signal_handling(); } -void Genode::init_platform() +Platform &Genode::init_platform() { static Genode::Platform platform; @@ -70,8 +66,11 @@ void Genode::init_platform() init_thread(platform.cpu, platform.rm); init_thread_start(platform.pd.rpc_cap()); init_thread_bootstrap(platform.cpu, platform.parent.main_thread_cap()); + init_signal_receiver(platform.pd, platform.parent); _platform_ptr = &platform; + + return platform; } diff --git a/repos/base/src/lib/startup/_main.cc b/repos/base/src/lib/startup/_main.cc index 09d72a5acf..d8724f1192 100644 --- a/repos/base/src/lib/startup/_main.cc +++ b/repos/base/src/lib/startup/_main.cc @@ -27,6 +27,8 @@ using namespace Genode; addr_t init_main_thread_result; +static Platform *platform_ptr; + enum { MAIN_THREAD_STACK_SIZE = 16*1024 }; @@ -86,7 +88,7 @@ extern "C" void init_main_thread() { prepare_init_main_thread(); - init_platform(); + platform_ptr = &init_platform(); /* create a thread object for the main thread */ main_thread(); @@ -152,15 +154,12 @@ namespace Genode { void (**func)(); for (func = &_ctors_end; func != &_ctors_start; (*--func)()); } - - /* XXX move to base-internal header */ - extern void bootstrap_component(); } extern "C" int _main() { - Genode::bootstrap_component(); + Genode::bootstrap_component(*platform_ptr); /* never reached */ return 0;