From ea92f78fca8af79cf2d7c7a2ca84591e62ea7456 Mon Sep 17 00:00:00 2001 From: Aurel Feer Date: Sun, 24 Apr 2022 18:31:00 +0200 Subject: [PATCH] start on booting second core --- errors/errno.fugu | 2 ++ lib/aos/coreboot.c | 48 +++++++++++++++++++++++++++++++++++++++++++++- lib/spawn/spawn.c | 6 ------ 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/errors/errno.fugu b/errors/errno.fugu index 9b14e71..be26d1e 100755 --- a/errors/errno.fugu +++ b/errors/errno.fugu @@ -441,6 +441,8 @@ errors libaos LIB_ERR_ { // Process management client library failure PROC_MGMT_CLIENT_ACCEPT "Error in proc_mgmt_client_lmp_accept()", + + failure COREBOOT_FIND_MODULE "Didn't find module to be spawned", }; // errors in Flounder-generated bindings diff --git a/lib/aos/coreboot.c b/lib/aos/coreboot.c index 89b6f9a..46d0687 100644 --- a/lib/aos/coreboot.c +++ b/lib/aos/coreboot.c @@ -191,26 +191,72 @@ errval_t coreboot(coreid_t mpid, const char *init, struct frame_identity urpc_frame_id) { + errval_t err; // Implement me! // - Get a new KCB by retyping a RAM cap to ObjType_KernelControlBlock. // Note that it should at least OBJSIZE_KCB, and it should also be aligned // to a multiple of 16k. + struct capref kcb_ram_cap; + err = ram_alloc_aligned(&kcb_ram_cap, OBJSIZE_KCB, 4 * BASE_PAGE_SIZE); + if (err_is_fail(err)) return err; + + struct capref kcb_cap; + err = slot_alloc(&kcb_cap); + 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; + // - Get and load the CPU and boot driver binary. + struct mem_region * bootdriver_module = multiboot_find_module(bi, "boot_armv8_generic"); + if (bootdriver_module == NULL) return LIB_ERR_COREBOOT_FIND_MODULE; + + //afeer: toradex board: + struct mem_region * cpudriver_module = multiboot_find_module(bi, "cpu_imx8x"); + //afeer: qemu: + // struct mem_region *cpudriver_module = multiboot_find_module(bi, "cpu_a57_qemu"); + if (cpudriver_module == NULL) return LIB_ERR_COREBOOT_FIND_MODULE; + + // - Load the ELF binary + // afeer: do we need to copy paste code from spawn.c here? + + // - 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. + + // - Allocate a page for the core data struct + struct armv8_core_data * core_data = malloc(BASE_PAGE_SIZE); + // TODO: free + // - Allocate stack memory for the new cpu driver (at least 16 pages) + char * cpu_driver_stack = paging_malloc(17 * BASE_PAGE_SIZE, NULL, BASE_PAGE_SIZE); + // TODO: free + // - Fill in the core data struct, for a description, see the definition // in include/target/aarch64/barrelfish_kpi/arm_core_data.h + core_data->cpu_driver_stack = mem_to_local_phys((lvaddr_t) cpu_driver_stack + 17 * BASE_PAGE_SIZE); + core_data->cpu_driver_stack_limit = mem_to_local_phys((lvaddr_t) cpu_driver_stack + BASE_PAGE_SIZE); + // - 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" + + // - Flush the cache. + // TODO: add barriers + 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. + // boot struct as argument + //TODO afeer: insert arguments + err = invoke_monitor_spawn_core(1, CPU_ARM8, 0, 0, 0); + if (err_is_fail(err)) return err; return SYS_ERR_OK; diff --git a/lib/spawn/spawn.c b/lib/spawn/spawn.c index 46320e1..9162f6b 100644 --- a/lib/spawn/spawn.c +++ b/lib/spawn/spawn.c @@ -596,12 +596,6 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si, // so we don't use it after serializing child_paging_state = NULL; - // afeer: TODO: what do i put here? do we need to set these fields to some value? - // domain_params->tls_init_base = NULL; - // domain_params->tls_init_len = 0; - // domain_params->tls_total_len = 0; - // domain_params->pagesize = BASE_PAGE_SIZE; - domain_params->argc = argc; size_t offset = sizeof(struct spawn_domain_params); for (int i = 0; i < argc; ++i) {