struct dcb *spawn_bsp_init(const char *name) { MSG("spawning '%s' on BSP core\n", name); /* Only the first core can run this code */ assert(cpu_is_bsp()); /* Allocate bootinfo */ lpaddr_t bootinfo_phys = bsp_alloc_phys_aligned(BOOTINFO_SIZE, BASE_PAGE_SIZE); memset((void *)local_phys_to_mem(bootinfo_phys), 0, BOOTINFO_SIZE); /* store pointer to bootinfo in kernel virtual memory */ bootinfo = (struct bootinfo *) local_phys_to_mem(bootinfo_phys); /* Construct cmdline args */ char bootinfochar[16]; snprintf(bootinfochar, sizeof(bootinfochar), "%u", INIT_BOOTINFO_VBASE); const char *argv[] = { "init", bootinfochar }; int argc = 2; /* perform common spawning of init domain */ struct dcb *init_dcb = spawn_init_common(name, argc, argv,bootinfo_phys, bsp_alloc_phys, bsp_alloc_phys_aligned); /* map boot info into init's VSPACE */ spawn_init_map(init_l3, ARMV8_INIT_VBASE, INIT_BOOTINFO_VBASE, bootinfo_phys, BOOTINFO_SIZE, INIT_PERM_RW); /* load the image */ genvaddr_t init_ep, got_base; struct startup_l3_info l3_info = { init_l3, ARMV8_INIT_VBASE }; load_init_image(&l3_info, BSP_INIT_MODULE_NAME, &init_ep, &got_base); MSG("init loaded with entry=0x%" PRIxGENVADDR " and GOT=0x%" PRIxGENVADDR "\n", init_ep, got_base); struct dispatcher_shared_aarch64 *disp_aarch64 = get_dispatcher_shared_aarch64(init_dcb->disp); /* setting GOT pointers */ disp_aarch64->got_base = got_base; /* XXX - Why does the kernel do this? -DC */ disp_aarch64->enabled_save_area.named.x10 = got_base; disp_aarch64->disabled_save_area.named.x10 = got_base; /* setting entry points */ disp_aarch64->disabled_save_area.named.pc = init_ep; disp_aarch64->disabled_save_area.named.spsr = AARCH64_MODE_USR | CPSR_F_MASK; /* Create caps for init to use */ create_module_caps(&spawn_state); lpaddr_t init_alloc_end = bsp_alloc_phys(0); create_phys_caps(armv8_glbl_core_data->start_kernel_ram, init_alloc_end); /* Fill bootinfo struct */ bootinfo->mem_spawn_core = KERNEL_IMAGE_SIZE; // Size of kernel return init_dcb; }
struct dcb *spawn_bsp_init(const char *name, alloc_phys_func alloc_phys) { printf("spawn_bsp_init\n"); /* Only the first core can run this code */ assert(hal_cpu_is_bsp()); /* Allocate bootinfo */ lpaddr_t bootinfo_phys = alloc_phys(BOOTINFO_SIZE); memset((void *)local_phys_to_mem(bootinfo_phys), 0, BOOTINFO_SIZE); /* Construct cmdline args */ char bootinfochar[16]; snprintf(bootinfochar, sizeof(bootinfochar), "%u", INIT_BOOTINFO_VBASE); const char *argv[] = { "init", bootinfochar }; int argc = 2; struct dcb *init_dcb = spawn_init_common(name, argc, argv, bootinfo_phys, alloc_phys); // Map bootinfo spawn_init_map(init_l2, INIT_VBASE, INIT_BOOTINFO_VBASE, bootinfo_phys, BOOTINFO_SIZE, INIT_PERM_RW); struct startup_l2_info l2_info = { init_l2, INIT_VBASE }; genvaddr_t init_ep, got_base; load_init_image(&l2_info, BSP_INIT_MODULE_NAME, &init_ep, &got_base); struct dispatcher_shared_arm *disp_arm = get_dispatcher_shared_arm(init_dcb->disp); disp_arm->enabled_save_area.named.r10 = got_base; disp_arm->got_base = got_base; disp_arm->disabled_save_area.named.pc = init_ep; #ifndef __ARM_ARCH_7M__ //the armv7-m profile does not have such a mode field disp_arm->disabled_save_area.named.cpsr = ARM_MODE_USR | CPSR_F_MASK; #endif disp_arm->disabled_save_area.named.r10 = got_base; /* Create caps for init to use */ create_module_caps(&spawn_state); lpaddr_t init_alloc_end = alloc_phys(0); // XXX create_phys_caps(init_alloc_end); /* Fill bootinfo struct */ bootinfo->mem_spawn_core = KERNEL_IMAGE_SIZE; // Size of kernel /* // Map dispatcher spawn_init_map(init_l2, INIT_VBASE, INIT_DISPATCHER_VBASE, mem_to_local_phys(init_dcb->disp), DISPATCHER_SIZE, INIT_PERM_RW); disp_arm->disabled_save_area.named.rtls = INIT_DISPATCHER_VBASE; */ return init_dcb; }
struct dcb *spawn_app_init(struct arm_core_data *core_data, const char *name, alloc_phys_func alloc_phys) { errval_t err; /* Construct cmdline args */ // Core id of the core that booted this core char coreidchar[10]; snprintf(coreidchar, sizeof(coreidchar), "%d", core_data->src_core_id); // IPI channel id of core that booted this core char chanidchar[30]; snprintf(chanidchar, sizeof(chanidchar), "chanid=%"PRIu32, core_data->chan_id); // Arch id of the core that booted this core char archidchar[30]; snprintf(archidchar, sizeof(archidchar), "archid=%d", core_data->src_arch_id); const char *argv[5] = { name, coreidchar, chanidchar, archidchar }; int argc = 4; struct dcb *init_dcb = spawn_init_common(name, argc, argv,0, alloc_phys); // Urpc frame cap struct cte *urpc_frame_cte = caps_locate_slot(CNODE(spawn_state.taskcn), TASKCN_SLOT_MON_URPC); // XXX: Create as devframe so the memory is not zeroed out err = caps_create_new(ObjType_DevFrame, core_data->urpc_frame_base, core_data->urpc_frame_bits, core_data->urpc_frame_bits, urpc_frame_cte); assert(err_is_ok(err)); urpc_frame_cte->cap.type = ObjType_Frame; lpaddr_t urpc_ptr = gen_phys_to_local_phys(urpc_frame_cte->cap.u.frame.base); /* Map urpc frame at MON_URPC_BASE */ spawn_init_map(init_l2, INIT_VBASE, MON_URPC_VBASE, urpc_ptr, MON_URPC_SIZE, INIT_PERM_RW); struct startup_l2_info l2_info = { init_l2, INIT_VBASE }; // elf load the domain genvaddr_t entry_point, got_base=0; err = elf_load(EM_ARM, startup_alloc_init, &l2_info, local_phys_to_mem(core_data->monitor_binary), core_data->monitor_binary_size, &entry_point); if (err_is_fail(err)) { //err_print_calltrace(err); panic("ELF load of init module failed!"); } // TODO: Fix application linkage so that it's non-PIC. struct Elf32_Shdr* got_shdr = elf32_find_section_header_name(local_phys_to_mem(core_data->monitor_binary), core_data->monitor_binary_size, ".got"); if (got_shdr) { got_base = got_shdr->sh_addr; } struct dispatcher_shared_arm *disp_arm = get_dispatcher_shared_arm(init_dcb->disp); disp_arm->enabled_save_area.named.r10 = got_base; disp_arm->got_base = got_base; disp_arm->disabled_save_area.named.pc = entry_point; #ifndef __ARM_ARCH_7M__ //the armv7-m profile does not have such a mode field disp_arm->disabled_save_area.named.cpsr = ARM_MODE_USR | CPSR_F_MASK; #endif disp_arm->disabled_save_area.named.r10 = got_base; //disp_arm->disabled_save_area.named.rtls = INIT_DISPATCHER_VBASE; return init_dcb; }
struct dcb *spawn_app_init(struct armv8_core_data *core_data, const char *name) { errval_t err; MSG("spawning '%s' on APP core\n", name); /* Only the app core can run this code */ assert(!cpu_is_bsp()); /* Construct cmdline args */ // Core id of the core that booted this core char coreidchar[10]; snprintf(coreidchar, sizeof(coreidchar), "%d", core_data->src_core_id); // IPI channel id of core that booted this core char chanidchar[30]; snprintf(chanidchar, sizeof(chanidchar), "chanid=%"PRIu32, core_data->chan_id); // Arch id of the core that booted this core char archidchar[30]; snprintf(archidchar, sizeof(archidchar), "archid=%d", core_data->src_arch_id); const char *argv[5] = { name, coreidchar, chanidchar, archidchar }; int argc = 4; struct dcb *init_dcb= spawn_init_common(name, argc, argv, 0, app_alloc_phys, app_alloc_phys_aligned); MSG("creating monitor URPC frame cap\n"); // Urpc frame cap struct cte *urpc_frame_cte = caps_locate_slot(CNODE(spawn_state.taskcn), TASKCN_SLOT_MON_URPC); // XXX: Create as devframe so the memory is not zeroed out err = caps_create_new(ObjType_DevFrame, core_data->urpc_frame.base, core_data->urpc_frame.length, core_data->urpc_frame.length, my_core_id, urpc_frame_cte); assert(err_is_ok(err)); urpc_frame_cte->cap.type = ObjType_Frame; lpaddr_t urpc_ptr = gen_phys_to_local_phys(urpc_frame_cte->cap.u.frame.base); /* Map urpc frame at MON_URPC_BASE */ MSG("mapping URPC frame cap %" PRIxLPADDR" \n",urpc_ptr ); spawn_init_map(init_l3, ARMV8_INIT_VBASE, MON_URPC_VBASE, urpc_ptr, MON_URPC_SIZE, INIT_PERM_RW); struct startup_l3_info l3_info = { init_l3, ARMV8_INIT_VBASE }; // elf load the domain genvaddr_t entry_point, got_base=0; MSG("loading elf '%s' @ %" PRIxLPADDR "\n", name, local_phys_to_mem(core_data->monitor_binary.base)); err = elf_load(EM_AARCH64, startup_alloc_init, &l3_info, local_phys_to_mem(core_data->monitor_binary.base), core_data->monitor_binary.length, &entry_point); if (err_is_fail(err)) { //err_print_calltrace(err); panic("ELF load of init module failed!"); } // TODO: Fix application linkage so that it's non-PIC. struct Elf64_Shdr* got_shdr; got_shdr = elf64_find_section_header_name(local_phys_to_mem(core_data->monitor_binary.base), core_data->monitor_binary.length, ".got"); if (got_shdr) { got_base = got_shdr->sh_addr; } MSG("init loaded with entry=0x%" PRIxGENVADDR " and GOT=0x%" PRIxGENVADDR "\n", entry_point, got_base); struct dispatcher_shared_aarch64 *disp_aarch64 = get_dispatcher_shared_aarch64(init_dcb->disp); disp_aarch64->got_base = got_base; disp_aarch64->enabled_save_area.named.x10 = got_base; disp_aarch64->disabled_save_area.named.x10 = got_base; /* setting entry points */ disp_aarch64->disabled_save_area.named.pc = entry_point; disp_aarch64->disabled_save_area.named.spsr = AARCH64_MODE_USR | CPSR_F_MASK; //arch_set_thread_register(INIT_DISPATCHER_VBASE); MSG("init dcb set up\n"); return init_dcb; }
struct dcb *spawn_app_init(struct x86_core_data *core_data, const char *name, alloc_phys_func alloc_phys) { errval_t err; /* Construct cmdline args */ // Core id of the core that booted this core char coreidchar[10]; snprintf(coreidchar, sizeof(coreidchar), "%d", core_data->src_core_id); // IPI channel id of core that booted this core char chanidchar[30]; snprintf(chanidchar, sizeof(chanidchar), "chanid=%"PRIu32, core_data->chan_id); // Arch id of the core that booted this core char archidchar[30]; snprintf(archidchar, sizeof(archidchar), "archid=%d", core_data->src_arch_id); const char *argv[5] = { name, coreidchar, chanidchar, archidchar }; int argc = 4; #ifdef __scc__ char urpc_frame_base_char[30]; snprintf(urpc_frame_base_char, sizeof(urpc_frame_base_char), "frame=%" PRIuGENPADDR, core_data->urpc_frame_base); argv[argc++] = urpc_frame_base_char; #endif struct dcb *init_dcb = spawn_init_common(&spawn_state, name, argc, argv, 0, alloc_phys); // Urpc frame cap struct cte *urpc_frame_cte = caps_locate_slot(CNODE(spawn_state.taskcn), TASKCN_SLOT_MON_URPC); // XXX: Create as devframe so the memory is not zeroed out err = caps_create_new(ObjType_DevFrame, core_data->urpc_frame_base, core_data->urpc_frame_bits, core_data->urpc_frame_bits, core_data->src_core_id, urpc_frame_cte); assert(err_is_ok(err)); urpc_frame_cte->cap.type = ObjType_Frame; lpaddr_t urpc_ptr = gen_phys_to_local_phys(urpc_frame_cte->cap.u.frame.base); /* Map urpc frame at MON_URPC_BASE */ #ifdef CONFIG_PAE paging_x86_32_map_pdpte(&init_pdpte[X86_32_PDPTE_BASE(MON_URPC_BASE)], mem_to_local_phys((lvaddr_t)init_pdir)); #endif paging_x86_32_map_table(&init_pdir[X86_32_PDIR_BASE(MON_URPC_BASE)], mem_to_local_phys((lvaddr_t)init_ptable)); for (int i = 0; i < MON_URPC_SIZE / BASE_PAGE_SIZE; i++) { paging_x86_32_map(&init_ptable[X86_32_PTABLE_BASE(MON_URPC_BASE) + i], urpc_ptr + i * BASE_PAGE_SIZE, INIT_PAGE_BITMAP | paging_elf_to_page_flags(PF_R | PF_W)); } // elf load the domain genvaddr_t entry_point; err = elf_load(EM_386, startup_alloc_init, &spawn_state, local_phys_to_mem(core_data->monitor_binary), core_data->monitor_binary_size, &entry_point); if (err_is_fail(err)) { //err_print_calltrace(err); panic("ELF load of init module failed!"); } struct dispatcher_shared_x86_32 *init_disp_x86_32 = get_dispatcher_shared_x86_32(init_dcb->disp); init_disp_x86_32->disabled_save_area.eip = entry_point; return init_dcb; }
struct dcb *spawn_bsp_init(const char *name, alloc_phys_func alloc_phys) { errval_t err; /* Only the first core can run this code */ assert(apic_is_bsp()); /* Allocate bootinfo */ lpaddr_t bootinfo_phys = alloc_phys(BOOTINFO_SIZE); memset((void *)local_phys_to_mem(bootinfo_phys), 0, BOOTINFO_SIZE); /* Construct cmdline args */ char bootinfochar[16]; snprintf(bootinfochar, sizeof(bootinfochar), "%"PRIuLPADDR, BOOTINFO_BASE); const char *argv[6] = { "init", bootinfochar }; int argc = 2; #ifdef __scc__ if(glbl_core_data->urpc_frame_base != 0) { char coreidchar[10]; snprintf(coreidchar, sizeof(coreidchar), "%d", glbl_core_data->src_core_id); argv[argc++] = coreidchar; char chan_id_char[30]; snprintf(chan_id_char, sizeof(chan_id_char), "chanid=%"PRIu32, glbl_core_data->chan_id); argv[argc++] = chan_id_char; char urpc_frame_base_char[30]; snprintf(urpc_frame_base_char, sizeof(urpc_frame_base_char), "frame=%" PRIuGENPADDR, glbl_core_data->urpc_frame_base); argv[argc++] = urpc_frame_base_char; } #endif struct dcb *init_dcb = spawn_init_common(&spawn_state, name, argc, argv, bootinfo_phys, alloc_phys); /* Map bootinfo R/W into VSpace at vaddr 0x200000 (BOOTINFO_BASE) */ #ifdef CONFIG_PAE paging_x86_32_map_pdpte(&init_pdpte[0], mem_to_local_phys((lvaddr_t)init_pdir)); paging_x86_32_map_table(&init_pdir[1], mem_to_local_phys((lvaddr_t)init_ptable)); for (int i = 0; i < BOOTINFO_SIZE / BASE_PAGE_SIZE; i++) { paging_x86_32_map(&init_ptable[i], bootinfo_phys + i * BASE_PAGE_SIZE, INIT_PAGE_BITMAP | paging_elf_to_page_flags(PF_R|PF_W)); } #else paging_x86_32_map_table(&init_pdir[0], mem_to_local_phys((lvaddr_t)init_ptable)); for (int i = 0; i < BOOTINFO_SIZE / BASE_PAGE_SIZE; i++) { paging_x86_32_map(&init_ptable[i + 512], bootinfo_phys + i * BASE_PAGE_SIZE, INIT_PAGE_BITMAP | paging_elf_to_page_flags(PF_R|PF_W)); } #endif /* Load init ELF32 binary */ struct multiboot_modinfo *module = multiboot_find_module(name); if (module == NULL) { panic("Could not find init module!"); } genvaddr_t init_ep; err = elf_load(EM_386, startup_alloc_init, &spawn_state, local_phys_to_mem(module->mod_start), MULTIBOOT_MODULE_SIZE(*module), &init_ep); if (err_is_fail(err)) { //err_print_calltrace(err); panic("ELF load of init module failed!"); } struct dispatcher_shared_x86_32 *init_disp_x86_32 = get_dispatcher_shared_x86_32(init_dcb->disp); init_disp_x86_32->disabled_save_area.eip = init_ep; /* Create caps for init to use */ create_module_caps(&spawn_state); lpaddr_t init_alloc_end = alloc_phys(0); // XXX create_phys_caps(init_alloc_end); /* Fill bootinfo struct */ bootinfo->mem_spawn_core = NEEDED_KERNEL_SPACE; // Size of kernel /* for (int i = 0; i < bootinfo->regions_length; i++) { */ /* printf("%d region %d: 0x%09" PRIxPTR " - 0x%09lx (%lu MB, %u bits)\n", */ /* bootinfo->regions[i].mr_type, i, bootinfo->regions[i].mr_base, */ /* bootinfo->regions[i].mr_base + (1UL<<bootinfo->regions[i].mr_bits), */ /* bootinfo->regions[i].mr_bits >= 20 */ /* ? 1UL << (bootinfo->regions[i].mr_bits - 20) : 0, */ /* bootinfo->regions[i].mr_bits); */ /* } */ #if 0 // If app core, map (static) URPC channel if(kernel_scckernel != 0) { printf("SCC app kernel, frame at: 0x%x\n", kernel_scckernel); #define TASKCN_SLOT_MON_URPC (TASKCN_SLOTS_USER+6) ///< Frame cap for urpc comm. err = caps_create_new(ObjType_Frame, kernel_scckernel, 13, 13, caps_locate_slot(CNODE(taskcn), TASKCN_SLOT_MON_URPC)); assert(err_is_ok(err)); } #endif return init_dcb; }