try to boot second core

This commit is contained in:
Aurel Feer 2022-04-25 15:55:00 +02:00
parent 1e225bac85
commit fc44e3efc6
2 changed files with 119 additions and 21 deletions

View File

@ -206,6 +206,11 @@ errval_t coreboot(coreid_t mpid,
if (err_is_fail(err)) return err;
err = cap_retype(kcb_cap, kcb_ram_cap, 0, ObjType_KernelControlBlock, OBJSIZE_KCB, 1);
if (err_is_fail(err)) return err;
struct frame_identity kcb_id;
err = invoke_kcb_identify(kcb_cap, &kcb_id);
if(err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_IDENTIFY);
// TODO rueegges: does freeing the capability slot work?
// err = cap_delete(kcb_ram_cap);
// if (err_is_fail(err)) return err_push(err, LIB_ERR_CAP_DELETE);
@ -217,13 +222,102 @@ errval_t coreboot(coreid_t mpid,
struct mem_region * cpudriver_module = multiboot_find_module(bi, cpu_driver);
if (cpudriver_module == NULL) return LIB_ERR_COREBOOT_FIND_MODULE;
struct mem_region * init_module = multiboot_find_module(bi, init);
if (init_module == NULL) return LIB_ERR_COREBOOT_FIND_MODULE;
struct capref init_elf_frame = {
.cnode = cnode_module,
.slot = init_module->mrmod_slot,
};
struct frame_identity init_elf_frame_id;
err = frame_identify(init_elf_frame, &init_elf_frame_id);
if(err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_IDENTIFY);
// - Load the ELF binary
// afeer: do we need to copy paste code from spawn.c here?
struct capref bootdriver_elf_frame = {
.cnode = cnode_module,
.slot = bootdriver_module->mrmod_slot,
};
struct frame_identity bootdriver_elf_frame_id;
err = frame_identify(bootdriver_elf_frame, &bootdriver_elf_frame_id);
if(err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_IDENTIFY);
struct capref remote_bootdriver_elf_frame;
err = frame_alloc(&remote_bootdriver_elf_frame, bootdriver_elf_frame_id.bytes, NULL);
if(err_is_fail(err)) return err;
struct frame_identity remote_bootdriver_elf_frame_id;
err = frame_identify(remote_bootdriver_elf_frame, &remote_bootdriver_elf_frame_id);
if(err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_IDENTIFY);
char * bootdriver_elf_addr;
err = paging_map_frame_attr(get_current_paging_state(), (void **) &bootdriver_elf_addr, bootdriver_elf_frame_id.bytes, bootdriver_elf_frame, VREGION_FLAGS_READ);
if(err_is_fail(err)) return err;
char * remote_bootdriver_elf_addr;
err = paging_map_frame(get_current_paging_state(), (void **) &remote_bootdriver_elf_addr, bootdriver_elf_frame_id.bytes, remote_bootdriver_elf_frame);
if(err_is_fail(err)) return err;
struct capref cpudriver_elf_frame = {
.cnode = cnode_module,
.slot = cpudriver_module->mrmod_slot,
};
struct frame_identity cpudriver_elf_frame_id;
err = frame_identify(cpudriver_elf_frame, &cpudriver_elf_frame_id);
if(err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_IDENTIFY);
struct capref remote_cpudriver_elf_frame;
err = frame_alloc(&remote_cpudriver_elf_frame, cpudriver_elf_frame_id.bytes, NULL);
if(err_is_fail(err)) return err;
struct frame_identity remote_cpudriver_elf_frame_id;
err = frame_identify(remote_cpudriver_elf_frame, &remote_cpudriver_elf_frame_id);
if(err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_IDENTIFY);
char * cpudriver_elf_addr;
err = paging_map_frame_attr(get_current_paging_state(), (void **) &cpudriver_elf_addr, cpudriver_elf_frame_id.bytes, cpudriver_elf_frame, VREGION_FLAGS_READ);
if(err_is_fail(err)) return err;
char * remote_cpudriver_elf_addr;
err = paging_map_frame(get_current_paging_state(), (void **) &remote_cpudriver_elf_addr, cpudriver_elf_frame_id.bytes, remote_cpudriver_elf_frame);
if(err_is_fail(err)) return err;
// - Find the boot driver entry point. Look for the symbol "boot_entry_psci"
struct mem_info bootdriver_mem_info = {
.size = remote_bootdriver_elf_frame_id.bytes,
.buf = remote_bootdriver_elf_addr,
.phys_base = remote_bootdriver_elf_frame_id.base,
};
struct Elf64_Sym * boot_entry_psci_sym = elf64_find_symbol_by_name((genvaddr_t) bootdriver_elf_addr, bootdriver_elf_frame_id.bytes, "boot_entry_psci", false, STT_FUNC, 0);
genvaddr_t reloc_bootdriver_entry;
err = load_elf_binary((genvaddr_t) bootdriver_elf_addr, &bootdriver_mem_info, boot_entry_psci_sym->st_value, &reloc_bootdriver_entry);
if(err_is_fail(err)) return err;
// - Find the CPU driver entry point. Look for the symbol "arch_init". Put
// the address in the core data struct.
struct mem_info cpudriver_mem_info = {
.size = remote_cpudriver_elf_frame_id.bytes,
.buf = remote_cpudriver_elf_addr,
.phys_base = remote_cpudriver_elf_frame_id.base,
};
struct Elf64_Sym * arch_init_sym = elf64_find_symbol_by_name((genvaddr_t) cpudriver_elf_addr, cpudriver_elf_frame_id.bytes, "arch_init", false, STT_FUNC, 0);
genvaddr_t reloc_cpudriver_entry;
err = load_elf_binary((genvaddr_t) cpudriver_elf_addr, &cpudriver_mem_info, arch_init_sym->st_value, &reloc_cpudriver_entry);
if(err_is_fail(err)) return err;
// - Relocate the boot and CPU driver. The boot driver runs with a 1:1
// VA->PA mapping. The CPU driver is expected to be loaded at the
// high virtual address space, at offset ARMV8_KERNEL_OFFSET.
err = relocate_elf((genvaddr_t) bootdriver_elf_addr, &bootdriver_mem_info, remote_bootdriver_elf_frame_id.base);
if(err_is_fail(err)) return err;
err = relocate_elf((genvaddr_t) cpudriver_elf_addr, &cpudriver_mem_info, ARMv8_KERNEL_OFFSET);
if(err_is_fail(err)) return err;
// - Allocate a page for the core data struct
@ -245,7 +339,7 @@ errval_t coreboot(coreid_t mpid,
// Space to load the init process. This should be at least space for init
// plus ARMV8_CORE_DATA_PAGES × BASE_PAGE_SIZE bytes.
struct capref init_process_frame;
err = frame_alloc(&init_process_frame, init_process_space + ARMV8_CORE_DATA_PAGES * BASE_PAGE_SIZE, NULL);
err = frame_alloc(&init_process_frame, init_module->mrmod_size + ARMV8_CORE_DATA_PAGES * BASE_PAGE_SIZE, NULL);
if(err_is_fail(err)) return err_push(err, LIB_ERR_FRAME_ALLOC);
struct frame_identity init_process_frame_id;
err = frame_identify(init_process_frame, &init_process_frame_id);
@ -254,13 +348,13 @@ errval_t coreboot(coreid_t mpid,
// - Fill in the core data struct, for a description, see the definition
// in include/target/aarch64/barrelfish_kpi/arm_core_data.h
struct armv8_core_data *core_data;
paging_map_frame(get_current_paging_state(), &core_data, PAGE_SIZE, core_data_frame);
paging_map_frame(get_current_paging_state(), (void**) &core_data, PAGE_SIZE, core_data_frame);
core_data->boot_magic = ARMV8_BOOTMAGIC_PSCI;
core_data->cpu_driver_stack = cpu_driver_stack_frame_id.base + 16 * BASE_PAGE_SIZE;
core_data->cpu_driver_stack_limit = cpu_driver_stack_frame_id.base;
core_data->cpu_driver_cmdline = ?;
strncpy(core_data->cpu_driver_cmdline, multiboot_module_opts(cpudriver_module), 128);
core_data->memory.base = init_process_frame_id.base;
core_data->memory.length = init_process_frame_id.bytes;
@ -268,40 +362,44 @@ errval_t coreboot(coreid_t mpid,
core_data->urpc_frame.base = urpc_frame_id.base;
core_data->urpc_frame.length = urpc_frame_id.bytes;
core_data->monitor_binary.base = ?;
core_data->monitor_binary.length = ?;
core_data->monitor_binary.base = init_elf_frame_id.base;
core_data->monitor_binary.length = init_elf_frame_id.bytes;
core_data->kcb = ?;
core_data->kcb = kcb_id.base;
core_data->src_core_id = disp_get_core_id();
core_data->dst_core_id = mpid;
core_data->src_arch_id = disp_get_core_id();
core_data->dst_arch_id = mpid;
// find boot entry point
genpaddr_t boot_driver_entry = ?;
// find cpu driver entry point
core_data->cpu_driver_entry = ?;
// - Find the CPU driver entry point. Look for the symbol "arch_init". Put
// the address in the core data struct.
// Elf64_Sym * arch_init_sym = elf64_find_symbol_by_name();
// - Find the boot driver entry point. Look for the symbol "boot_entry_psci"
core_data->cpu_driver_entry = reloc_cpudriver_entry + ARMv8_KERNEL_OFFSET;
// - Flush the cache.
// TODO: add barriers
//memory barrier
__asm volatile (
"dmb sy\n"
);
//clean and invalidate cache
cpu_idcache_wbinv_range(0, VADDR_SIZE);
// - Call the invoke_monitor_spawn_core with the entry point
// of the boot driver and pass the (physical, of course) address of the
// boot struct as argument
err = invoke_monitor_spawn_core(mpid, CPU_ARM8, boot_driver_entry, core_data_frame_id.base, 0 /*ignored in aos*/);
err = invoke_monitor_spawn_core(mpid, CPU_ARM8, reloc_bootdriver_entry, core_data_frame_id.base, 0 /*ignored in aos*/);
if (err_is_fail(err)) return err_push(err, MON_ERR_SPAWN_CORE);
// unmap stuff
paging_unmap(get_current_paging_state(), core_data);
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
paging_unmap(get_current_paging_state(), bootdriver_elf_addr);
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
paging_unmap(get_current_paging_state(), remote_bootdriver_elf_addr);
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
paging_unmap(get_current_paging_state(), cpudriver_elf_addr);
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
paging_unmap(get_current_paging_state(), remote_cpudriver_elf_addr);
if (err_is_fail(err)) return err_push(err, LIB_ERR_PMAP_UNMAP);
return SYS_ERR_OK;

View File

@ -40,8 +40,8 @@ void
grading_test_early(void) {
// do_test_spawn();
// do_test_ipc();
do_test_threads();
do_test_stackoverflow();
// do_test_threads();
// do_test_stackoverflow();
}
void