static struct dcb *spawn_init_common(const char *name, int argc, const char *argv[], lpaddr_t bootinfo_phys, alloc_phys_func alloc_phys, alloc_phys_aligned_func alloc_phys_aligned) { struct dispatcher_shared_generic *disp; struct dispatcher_shared_aarch64 *disp_aarch64; MSG("spawn_init_common %s\n", name); lvaddr_t paramaddr; struct dcb *init_dcb = spawn_module(&spawn_state, name, argc, argv, bootinfo_phys, INIT_ARGS_VBASE, alloc_phys, alloc_phys_aligned, ¶maddr); /* initialize page tables */ init_page_tables(); init_dcb->vspace = mem_to_local_phys((lvaddr_t)init_l0); spawn_init_map(init_l3, ARMV8_INIT_VBASE, INIT_ARGS_VBASE, spawn_state.args_page, ARGS_SIZE, INIT_PERM_RW); /* Map dispatcher */ spawn_init_map(init_l3, ARMV8_INIT_VBASE, INIT_DISPATCHER_VBASE, mem_to_local_phys(init_dcb->disp), DISPATCHER_SIZE, INIT_PERM_RW); disp = get_dispatcher_shared_generic(init_dcb->disp); disp_aarch64 = get_dispatcher_shared_aarch64(init_dcb->disp); /* Initialize dispatcher */ disp->disabled = true; strncpy(disp->name, argv[0], DISP_NAME_LEN); /* Tell init the vspace addr of its dispatcher. */ disp->udisp = INIT_DISPATCHER_VBASE; /* TODO: write the contet ID for init */ /* Set the thread ID register to point to the shared structure. */ disp_aarch64->enabled_save_area.named.x0 = paramaddr; disp_aarch64->enabled_save_area.named.spsr = AARCH64_MODE_USR | CPSR_I_MASK; sysreg_write_tpidrro_el0((uint64_t)disp->udisp); dump_dispatcher(disp); return init_dcb; }
static struct dcb *spawn_init_common(const char *name, int argc, const char *argv[], lpaddr_t bootinfo_phys, alloc_phys_func alloc_phys) { printf("spawn_init_common %s\n", name); lvaddr_t paramaddr; struct dcb *init_dcb = spawn_module(&spawn_state, name, argc, argv, bootinfo_phys, INIT_ARGS_VBASE, alloc_phys, ¶maddr); init_page_tables(); printf("about to call mem_to_local_phys with lvaddr=%"PRIxLVADDR"\n", init_l1); init_dcb->vspace = mem_to_local_phys((lvaddr_t)init_l1); spawn_init_map(init_l2, INIT_VBASE, INIT_ARGS_VBASE, spawn_state.args_page, ARGS_SIZE, INIT_PERM_RW); // Map dispatcher spawn_init_map(init_l2, INIT_VBASE, INIT_DISPATCHER_VBASE, mem_to_local_phys(init_dcb->disp), DISPATCHER_SIZE, INIT_PERM_RW); /* * we create the capability to the devices at this stage and store it * in the TASKCN_SLOT_IO, where on x86 the IO capability is stored for * device access on PCI. PCI is not available on the pandaboard so this * should not be a problem. */ struct cte *iocap = caps_locate_slot(CNODE(spawn_state.taskcn), TASKCN_SLOT_IO); errval_t err = caps_create_new(ObjType_DevFrame, 0x40000000, 30, 30, iocap); assert(err_is_ok(err)); struct dispatcher_shared_generic *disp = get_dispatcher_shared_generic(init_dcb->disp); struct dispatcher_shared_arm *disp_arm = get_dispatcher_shared_arm(init_dcb->disp); /* Initialize dispatcher */ disp->disabled = true; strncpy(disp->name, argv[0], DISP_NAME_LEN); /* tell init the vspace addr of its dispatcher */ disp->udisp = INIT_DISPATCHER_VBASE; disp_arm->enabled_save_area.named.r0 = paramaddr; #ifndef __ARM_ARCH_7M__ //the armv7-m profile does not have such a mode field disp_arm->enabled_save_area.named.cpsr = ARM_MODE_USR | CPSR_F_MASK; #endif disp_arm->enabled_save_area.named.rtls = INIT_DISPATCHER_VBASE; disp_arm->disabled_save_area.named.rtls = INIT_DISPATCHER_VBASE; printf("spawn_init_common: starting from=%"PRIxLVADDR"\n"); return init_dcb; }
static void initial_page_table(ac_uptr ptr, ac_uint word) { // BIOS Data Area (BDA) is at 0x400 and at 0x40E // maybe the Extended BIOS Data Area (EBDA) ac_u16* bda = (ac_u16*)0x0400; for (ac_uint i = 0; i < 9; i++) { ac_printf("bda[%d]=0x%x\n", i, bda[i]); } ac_u64 ebda = bda[7] << 4; ac_printf("EBDA=0x%x\n", ebda); if (word == 0x36d76289) { /** Mulitboot header **/ ac_u32 total_size = *(ac_u32*)ptr; ac_u32 reserved = *(ac_u32*)(ptr + 4); struct multiboot2_header_tag* mb_end = (struct multiboot2_header_tag*)(ptr + total_size); struct multiboot2_header_tag* tag = (struct multiboot2_header_tag*)(ptr + 8); ac_printf("mb_info: 0x%p\n", ptr); ac_printf(" total_size=%d\n", total_size); ac_printf(" reserved=0x%x\n", reserved); ac_printf(" mb_end=0x%p\n", mb_end); while ((tag != AC_NULL) && (tag < mb_end) && (tag->type != 0) && (tag->size != 8)) { print_multiboot2_tag(tag); switch (tag->type) { case 1: { char* cmdline = (char*)tag + 8; ac_printf(" cmd_line=%s\n", cmdline); break; } case 2: { char* blname = (char*)tag + 8; ac_printf(" boot loader name=%s\n", blname); break; } case 3: { ac_printf(" Modules\n"); break; } case 4: { struct multiboot2_basic_memory_tag* bm = (struct multiboot2_basic_memory_tag*)tag; ac_printf(" basic memory info:\n"); ac_printf(" mem_lower=%dK(0x%x)\n", bm->mem_lower, bm->mem_lower * 1024); ac_printf(" mem_upper=%dK(0x%x)\n", bm->mem_upper, bm->mem_upper * 1024); break; } case 5: { ac_printf(" bios boot device\n"); break; } case 6: { struct multiboot2_memory_map_tag* mm = (struct multiboot2_memory_map_tag*)tag; ac_printf(" memory map:\n"); ac_printf(" entry_size=%d\n", mm->entry_size); ac_printf(" entry_version=%d\n", mm->entry_version); if (mm->entry_version != 0) { ac_printf("ABORTING: file ac_init; Unknown multiboot2 entry_version" " %d, expecting 0\n", mm->entry_version); reset_x86(); } // Sort the enteries and create the initial a page_table ac_uint count = (mm->header.size - sizeof(mm->header)) / mm->entry_size; ac_sort_by_idx(mm->entries, count, compare_mmap_entires, swap_mmap_entires); init_page_tables(mm, count); // Map the possible ebda page so we can search it, I'm // assuming its part of a reserved type 2 memory and // wasn't mapped above ac_u64 ebda_page_addr = ebda & ~AC_BIT_MASK(ac_u64, 12); ac_printf("ebda_page_addr=0x%p\n", ebda_page_addr); page_table_map_lin_to_phy(get_page_table_linear_addr(), (void*)ebda_page_addr, ebda_page_addr, FOUR_K_PAGE_SIZE, PAGE_CACHING_WRITE_BACK); // Display the types and while doing so search for // the MP Floaing Point structure from the Intel // MultiProcessor Specification v1.4. ac_uint total_length = 0; for (ac_uint i = 0; i < count; i++) { if (mm->entries[i].type == 1) { total_length += mm->entries[i].length; } ac_printf(" %d: base_addr=0x%p length=0x%x type=%d reserved=%x\n", i, mm->entries[i].base_addr, mm->entries[i].length, mm->entries[i].type, mm->entries[i].reserved); // Search for _MP_ in EBDA if ((mm->entries[i].type == 1) || ((mm->entries[i].type == 2) && (mm->entries[i].base_addr == ebda))) { // RAM or Probable ebda ac_printf(" Look for MP Floating Point Structure\n"); ac_u8* p = (ac_u8*)mm->entries[i].base_addr; //char* nl = ""; for(ac_uint j = 0; j < 1024; j++) { //if ((j % 8) == 0) ac_printf("%s0x%p:", nl, &p[j]); //nl = "\n"; //ac_printf(" %x", p[j]); if (ac_strncmp((char*)&p[j], "_MP_", 4) == 0) { ac_printf("\nFound _MP_ at &mp[%d]=0x%p\n", j, &p[j]); } } ac_printf("\n"); } } ac_printf(" total_length=%d(0x%x)\n", total_length, total_length); break; } case 7: { ac_printf(" VBE info\n"); break; } case 8: { ac_printf(" Framebuffer info\n"); break; } case 9: { ac_printf(" Elf symbols\n"); break; } case 10: { ac_printf(" APM table\n"); break; } default: { break; } } tag = multiboot2_next_tag(tag); } } else { /** reset */ ac_printf("ABORTING: file ac_init; Unknown parameter" " ptr=%p, word=0x%x\n", ptr, word); reset_x86(); } }
static struct dcb *spawn_init_common(struct spawn_state *st, const char *name, int argc, const char *argv[], lpaddr_t bootinfo_phys, alloc_phys_func alloc_phys) { errval_t err; /* Perform arch-independent spawn */ lvaddr_t paramaddr; struct dcb *init_dcb = spawn_module(st, name, argc, argv, bootinfo_phys, ARGS_BASE, alloc_phys, ¶maddr); /* Init page tables */ init_page_tables(st, alloc_phys); /* Map dispatcher R/W into VSpace starting at vaddr 0x204000 * (Starting after Bootinfo pages)*/ #ifdef CONFIG_PAE paging_x86_32_map_pdpte(&init_pdpte[X86_32_PDPTE_BASE(DISPATCHER_BASE)], mem_to_local_phys((lvaddr_t)init_pdir)); #endif paging_x86_32_map_table(&init_pdir[X86_32_PDIR_BASE(DISPATCHER_BASE)], mem_to_local_phys((lvaddr_t)init_ptable)); for (int i = 0; i < DISPATCHER_SIZE / BASE_PAGE_SIZE; i++) { paging_x86_32_map(&init_ptable[X86_32_PTABLE_BASE(DISPATCHER_BASE) + i], mem_to_local_phys(init_dcb->disp) + i * BASE_PAGE_SIZE, INIT_PAGE_BITMAP | paging_elf_to_page_flags(PF_R | PF_W)); } struct dispatcher_shared_generic *init_disp = get_dispatcher_shared_generic(init_dcb->disp); struct dispatcher_shared_x86_32 *init_disp_x86_32 = get_dispatcher_shared_x86_32(init_dcb->disp); registers_set_param(&init_disp_x86_32->enabled_save_area, paramaddr); // Map IO cap in task cnode struct cte *iocap = caps_locate_slot(CNODE(st->taskcn), TASKCN_SLOT_IO); err = caps_create_new(ObjType_IO, 0, 0, 0, my_core_id, iocap); assert(err_is_ok(err)); /* Set fields in DCB */ // Set Vspace #ifdef CONFIG_PAE init_dcb->vspace = mem_to_local_phys((lvaddr_t)init_pdpte); #else init_dcb->vspace = mem_to_local_phys((lvaddr_t)init_pdir); #endif /* Initialize dispatcher */ init_disp->disabled = true; strncpy(init_disp->name, argv[0], DISP_NAME_LEN); /* tell init the vspace addr of its dispatcher */ init_disp->udisp = DISPATCHER_BASE; init_disp_x86_32->disabled_save_area.edi = DISPATCHER_BASE; init_disp_x86_32->disabled_save_area.fs = 0; init_disp_x86_32->disabled_save_area.gs = 0; init_disp_x86_32->disabled_save_area.cs = USER_CS; init_disp_x86_32->disabled_save_area.ss = USER_SS; init_disp_x86_32->disabled_save_area.eflags = USER_EFLAGS; return init_dcb; }