/usr/init/setup.c
C | 263 lines | 173 code | 52 blank | 38 comment | 27 complexity | 13c064c3815a2bc2c6592731395e9b48 MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause
- /**
- * Group C
- */
- #include "setup.h"
- #include "mem_alloc.h"
- #include "bootstrap.h"
- #include <aos/connect/ump.h>
- #include <aos_rpc_server/aos_rpc_server_monitor.h>
- #include <aos_rpc_server/aos_rpc_server_intermon.h>
- errval_t parse_arguments(char *init_args) {
- char *current_argument = strtok(init_args, " ");
- while (current_argument) {
- if (!strcmp("init_args_test", current_argument)) {
- debug_printf("Arguments passing test\n");
- debug_printf("Received arguments: %s\n", strtok(NULL, ""));
- while (true);
- break;
- }
- // TODO jmeier: add handling for other arguments to init
- current_argument = strtok(NULL, " ");
- }
- return SYS_ERR_OK;
- }
- /** \brief creates the bootinfo and puts it in the well known location
- * for APP cores only
- * additionally it maps the frame to the global bootinfo pointer
- *
- * \param bootinfo_base kernel virtual address of bootinfo
- * \param bootinfo_size size of bootinfo frame
- */
- static errval_t setup_bootinfo(genpaddr_t bootinfo_base, gensize_t bootinfo_size) {
- assert(bootinfo_base);
- errval_t err = frame_forge(cap_bootinfo, bootinfo_base, bootinfo_size, disp_get_core_id());
- if (err_is_fail(err)) {
- debug_printf("frame forge failedin setup_bootinfo\n");
- return err;
- }
- err = paging_map_frame_attr(get_current_paging_state(), (void *) &bi, bootinfo_size, cap_bootinfo, VREGION_FLAGS_READ, NULL, NULL);
- if (err_is_fail(err)) {
- debug_printf("bootinfo mapping failed\n");
- return err;
- }
- return SYS_ERR_OK;
- }
- /** \brief forges the mmstringsraw module capability from
- * urpc_init_msg and creates the other modules
- * capabilities from the bootinfo
- */
- static errval_t setup_modules_caps(genpaddr_t mmstrings_base, gensize_t mmstrings_size) {
- assert(bi);
- genpaddr_t base;
- gensize_t size;
- errval_t err = cnode_create_foreign_l2(cap_root, ROOTCN_SLOT_MODULECN, NULL);
- if (err_is_fail(err)) {
- debug_printf("cnode_create_l2 failed for mmstrings\n");
- return err;
- }
- /* Map in multiboot module strings area */
- struct capref module_cap = {
- .cnode = cnode_module,
- .slot = 0
- };
- coreid_t core_id = disp_get_core_id();
- err = frame_forge(module_cap, mmstrings_base, mmstrings_size, core_id);
- if (err_is_fail(err)) {
- debug_printf("frame forge failed for mmstrings\n");
- return err;
- }
- void *buf;
- err = paging_map_frame_attr(get_current_paging_state(), &buf, mmstrings_size, module_cap, VREGION_FLAGS_READ, NULL, NULL);
- int i = 0;
- while(i < bi->regions_length) {
- if (bi->regions[i].mr_type == RegionType_Module) {
- base = bi->regions[i].mr_base;
- size = bi->regions[i].mrmod_size;
- module_cap.slot = bi->regions[i].mrmod_slot;
- err = frame_forge(module_cap, base, size, core_id);
- if (err_is_fail(err)) {
- debug_printf("frame_forge failed for module\n");
- return err;
- }
- }
- i++;
- }
- return SYS_ERR_OK;
- }
- struct bootstrap_state {
- bool done;
- struct aos_urpc_chan *urpc_chan;
- };
- void setup_init_bsp(enum rpc_services_mode mode) {
- assert(disp_get_core_id() == 0);
- debug_printf("address of bootinfo: %p\n", bi);
- debug_printf("bootinfo region length: %u\n", bi->regions_length);
- // Initialize physical memory management for boot core
- errval_t err = initialize_ram_alloc_bsp(mode);
- if (err_is_fail(err)) {
- DEBUG_ERR(err, "initialize_ram_alloc_bsp failed.\n");
- abort();
- }
- }
- void setup_init_app(routing_info_t intermon_routing) {
- assert(0 < disp_get_core_id());
- // set local monitor channel
- struct aos_rpc *monitor_rpc = malloc(sizeof(*monitor_rpc));
- if (!monitor_rpc) {
- USER_PANIC_ERR(LIB_ERR_MALLOC_FAIL, "could not initialize local init channel\n");
- }
- init_local_channel(monitor_rpc, AOS_RPC_INTERFACE_MONITOR, &aos_rpc_monitor_local_vtable);
- set_init_rpc(monitor_rpc);
- // map the urpc frame from well known urpc cap and establish a full bidirectional
- // connection with the bsp core (both offering server and client functionalities)
- void *ump_buffer;
- errval_t err = paging_map_frame_attr(get_current_paging_state(), &ump_buffer, MON_URPC_SIZE, cap_urpc, VREGION_FLAGS_READ_WRITE, NULL, NULL);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "urpc mapping failed\n");
- }
- // note: *NO* clean and in particular *NO* invalidate (which goes to poc) here
- // again, first is what is done first, i.e. on core 1: client, then server connection
- // note: on core 0, the order is reversed, of course
- // also: the ump_chan_init() including handshakes need to be established before
- // the actual RPC chan can be established
- size_t half = MON_URPC_SIZE >> 1;
- void *first = ump_buffer;
- void *second = ((char *)ump_buffer) + half;
- // again, first is what is done first, i.e. on core 1: client, then server connection
- // note: on core 0, the order is reversed, of course
- struct aos_rpc *intermon_client;
- err = setup_ump_client_from_buffer(first, half,
- AOS_RPC_INTERFACE_INTERMON, &aos_rpc_intermon_remote_vtable,
- intermon_routing, &intermon_client);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "setup_ump_client failed\n");
- }
- set_intermon_rpc(AOS_RPC_ROUTING_SERVER_CORE_ID(intermon_routing), intermon_client);
- struct ump_service_create_data data;
- err = setup_ump_service_part1_from_buffer(second, half, &data);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "setup_ump_service_part1 failed\n");
- }
- // NOTE: deliberately, the monitor handler is used here (which can also handle intermon)
- err = setup_ump_service_part2(&data, MKCLOSURE(aos_rpc_monitor_event_handler, NULL));
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "setup_ump_service_part2 failed\n");
- }
- debug_printf("intermon handshakes completed\n");
- //--- get bootstrap info
- struct aos_rpc *irpc = aos_rpc_get_intermon_channel(BSP_CORE_ID);
- struct aos_intermon_bootstrap_res bootstrap_info;
- err = aos_rpc_intermon_request_bootstrap_info(irpc, disp_get_core_id(), &bootstrap_info);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "could not get bootinfo from BSP core\n");
- }
- err = setup_bootinfo(bootstrap_info.bootinfo_base, bootstrap_info.bootinfo_size);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "could not set up bootinfo for APP core\n");
- }
- debug_printf("bootinfo received\n");
- //--- name service
- struct capref name_cap;
- err = slot_alloc(&name_cap);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "Cannot allocate slot for frame forgery.\n");
- }
- // doing some forgery...... psssssst, don't tell anyone
- err = frame_forge(name_cap, bootstrap_info.name_base, bootstrap_info.name_size, disp_get_core_id());
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "Cannot forge frame\n");
- }
- struct aos_rpc *name_rpc;
- err = aos_rpc_connect_with_service(name_cap, AOS_RPC_INTERFACE_NAME, AOS_RPC_CHAN_DRIVER_UMP,
- intermon_routing, &name_rpc, NULL);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "Cannot connect with name service\n");
- }
- set_name_rpc(name_rpc);
- debug_printf("Connected with name service\n");
- //--- memory service, including switch of default RAM allocator to Dionysos
- // using name service and late binding
- struct aos_rpc *mem_rpc = aos_rpc_get_memory_channel();
- if (!mem_rpc) {
- USER_PANIC_ERR(err, "Cannot connect with Memory service on core 0.\n");
- }
- debug_printf("mem_rpc here\n");
- // note: no late switching for monitors because they need
- // different RAM sizes early on. Thus: better check & test here that all works
- err = ram_alloc_set(NULL);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "Cannot set ram_allocator.\n");
- }
- debug_printf("Connected with memory service\n");
- // test memory system
- debug_printf("Testing memory service\n");
- void *test = calloc(1, 8000);
- if (!test) {
- USER_PANIC_ERR(LIB_ERR_MALLOC_FAIL, "memory system not fully working\n");
- }
- free(test);
- debug_printf("Memory service tested\n");
- // initialize all module capabilities on order to spawn on second core
- err = setup_modules_caps(bootstrap_info.mmstrings_base, bootstrap_info.mmstrings_size);
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "could not initialize module capabilities on APP core\n");
- }
- // register after setup is complete (function defined in bootstrap.c)
- err = register_monitor();
- if (err_is_fail(err)) {
- USER_PANIC_ERR(err, "Cannot register to name service\n");
- }
- debug_printf("setup & registration complete\n");
- }