try to boot second core
This commit is contained in:
parent
1e225bac85
commit
fc44e3efc6
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user