void cos_init(void *arg) { struct cobj_header *h; int num_cobj; LOCK(); cos_vect_init_static(&spd_info_addresses); h = (struct cobj_header *)cos_comp_info.cos_poly[0]; num_cobj = (int)cos_comp_info.cos_poly[1]; boot_find_cobjs(h, num_cobj); /* This component really might need more vas */ if (cos_vas_cntl(COS_VAS_SPD_EXPAND, cos_spd_id(), round_up_to_pgd_page((unsigned long)&num_cobj), round_up_to_pgd_page(1))) { printc("Could not expand boot component to %p:%x\n", (void *)round_up_to_pgd_page((unsigned long)&num_cobj), (unsigned int)round_up_to_pgd_page(1)); BUG(); } printc("h @ %p, heap ptr @ %p\n", h, cos_get_heap_ptr()); printc("header %p, size %d, num comps %d, new heap %p\n", h, h->size, num_cobj, cos_get_heap_ptr()); /* Assumes that hs have been setup with boot_find_cobjs */ boot_create_system(); UNLOCK(); return; }
int kern_setup_image(void) { unsigned long i, j; paddr_t kern_pa_start, kern_pa_end; printk("\tSetting up initial page directory.\n"); kern_pa_start = round_to_pgd_page(chal_va2pa(mem_kern_start())); /* likely 0 */ kern_pa_end = chal_va2pa(mem_kmem_end()); /* ASSUMPTION: The static layout of boot_comp_pgd is identical to a pgd post-pgtbl_alloc */ /* FIXME: should use pgtbl_extend instead of directly accessing the pgd array... */ for (i = kern_pa_start, j = COS_MEM_KERN_START_VA/PGD_RANGE ; i < (unsigned long)round_up_to_pgd_page(kern_pa_end) ; i += PGD_RANGE, j++) { assert(j != KERN_INIT_PGD_IDX || ((boot_comp_pgd[j] | PGTBL_GLOBAL) & ~(PGTBL_MODIFIED | PGTBL_ACCESSED)) == (i | PGTBL_PRESENT | PGTBL_WRITABLE | PGTBL_SUPER | PGTBL_GLOBAL)); boot_comp_pgd[j] = i | PGTBL_PRESENT | PGTBL_WRITABLE | PGTBL_SUPER | PGTBL_GLOBAL; boot_comp_pgd[i/PGD_RANGE] = 0; /* unmap lower addresses */ } /* FIXME: Ugly hack to get the physical page with the ACPI RSDT mapped */ printk("ACPI initialization\n"); void *rsdt = acpi_find_rsdt(); if (rsdt) { u32_t page = round_up_to_pgd_page(rsdt) - (1 << 22); boot_comp_pgd[j] = page | PGTBL_PRESENT | PGTBL_WRITABLE | PGTBL_SUPER | PGTBL_GLOBAL; acpi_set_rsdt_page(j); j++; u64_t hpet = timer_find_hpet(acpi_find_timer()); if (hpet) { page = round_up_to_pgd_page(hpet & 0xffffffff) - (1 << 22); boot_comp_pgd[j] = page | PGTBL_PRESENT | PGTBL_WRITABLE | PGTBL_SUPER | PGTBL_GLOBAL; timer_set_hpet_page(j); j++; } } for ( ; j < PAGE_SIZE/sizeof(unsigned int) ; i += PGD_RANGE, j++) { boot_comp_pgd[j] = boot_comp_pgd[i/PGD_RANGE] = 0; } chal_cpu_init(); chal_cpu_pgtbl_activate((pgtbl_t)chal_va2pa(boot_comp_pgd)); kern_retype_initial(); return 0; }
static inline void mm_init(void) { printc("core %ld: mm init as thread %d\n", cos_cpuid(), cos_get_thd_id()); /* Expanding VAS. */ printc("mm expanding %lu MBs @ %p\n", (NREGIONS-1) * round_up_to_pgd_page(1) / 1024 / 1024, (void *)round_up_to_pgd_page((unsigned long)&cos_comp_info.cos_poly[1])); if (cos_vas_cntl(COS_VAS_SPD_EXPAND, cos_spd_id(), round_up_to_pgd_page((unsigned long)&cos_comp_info.cos_poly[1]), (NREGIONS-1) * round_up_to_pgd_page(1))) { printc("MM could not expand VAS\n"); BUG(); } frame_init(); printc("core %ld: mm init done\n", cos_cpuid()); }
int valloc_alloc_at(spdid_t spdid, spdid_t dest, void *addr, unsigned long npages) { int ret = -1, i = 0; struct spd_vas_tracker *trac; struct spd_vas_occupied *occ; unsigned long off, ext_size; LOCK(); trac = cos_vect_lookup(&spd_vect, dest); if (!trac) { if (__valloc_init(dest) || !(trac = cos_vect_lookup(&spd_vect, dest))) goto done; } if (unlikely(npages > MAP_MAX * sizeof(u32_t))) { printc("valloc: cannot alloc more than %u bytes in one time!\n", 32 * WORDS_PER_PAGE * PAGE_SIZE); goto done; } while (trac->extents[i].map) { if (addr < trac->extents[i].start || addr > trac->extents[i].end) { if (++i == MAX_SPD_VAS_LOCATIONS) goto done; continue; } /* the address is in the range of an existing extent */ occ = trac->extents[i].map; off = ((char*)addr - (char*)trac->extents[i].start) / PAGE_SIZE; assert(off + npages < MAP_MAX * sizeof(u32_t)); ret = bitmap_extent_set_at(&occ->pgd_occupied[0], off, npages, MAP_MAX); goto done; } ext_size = round_up_to_pgd_page(npages * PAGE_SIZE); trac->extents[i].map = alloc_page(); occ = trac->extents[i].map; assert(occ); if (vas_mgr_take(spdid, dest, (vaddr_t)addr, ext_size) == 0) goto free; trac->extents[i].start = addr; trac->extents[i].end = (void *)((uintptr_t)addr + ext_size); bitmap_set_contig(&occ->pgd_occupied[0], 0, ext_size / PAGE_SIZE, 1); bitmap_set_contig(&occ->pgd_occupied[0], 0, npages, 0); ret = 0; done: UNLOCK(); return ret; free: free_page(trac->extents[i].map); goto done; }
void *valloc_alloc(spdid_t spdid, spdid_t dest, unsigned long npages) { void *ret = NULL; struct spd_vas_tracker *trac; struct spd_vas_occupied *occ; unsigned long ext_size; long off, i = 0; LOCK(); trac = cos_vect_lookup(&spd_vect, dest); if (!trac) { if (__valloc_init(dest) || !(trac = cos_vect_lookup(&spd_vect, dest))) goto done; } if (unlikely(npages > MAP_MAX * sizeof(u32_t))) { printc("valloc: cannot alloc more than %u bytes in one time!\n", 32 * WORDS_PER_PAGE * PAGE_SIZE); goto done; } while (trac->extents[i].map) { occ = trac->extents[i].map; off = bitmap_extent_find_set(&occ->pgd_occupied[0], 0, npages, MAP_MAX); if (off < 0) { if (++i == MAX_SPD_VAS_LOCATIONS) goto done; continue; } ret = (void *)((char *)trac->extents[i].start + off * PAGE_SIZE); goto done; } ext_size = round_up_to_pgd_page(npages * PAGE_SIZE); trac->extents[i].map = alloc_page(); occ = trac->extents[i].map; assert(occ); trac->extents[i].start = (void*)vas_mgr_expand(spdid, dest, ext_size); trac->extents[i].end = (void *)(trac->extents[i].start + ext_size); bitmap_set_contig(&occ->pgd_occupied[0], 0, ext_size / PAGE_SIZE, 1); bitmap_set_contig(&occ->pgd_occupied[0], 0, npages, 0); ret = trac->extents[i].start; done: UNLOCK(); return ret; }
void kern_paging_map_init(void *pa) { unsigned long i, j; paddr_t kern_pa_start = 0, kern_pa_end = (paddr_t)pa; for (i = kern_pa_start, j = COS_MEM_KERN_START_VA/PGD_RANGE ; i < (unsigned long)round_up_to_pgd_page(kern_pa_end) ; i += PGD_RANGE, j++) { assert(j != KERN_INIT_PGD_IDX || ((boot_comp_pgd[j] | PGTBL_GLOBAL) & ~(PGTBL_MODIFIED | PGTBL_ACCESSED)) == (i | PGTBL_PRESENT | PGTBL_WRITABLE | PGTBL_SUPER | PGTBL_GLOBAL)); /* lower mapping */ boot_comp_pgd[i/PGD_RANGE] = i | PGTBL_PRESENT | PGTBL_WRITABLE | PGTBL_SUPER | PGTBL_GLOBAL; /* higher mapping */ boot_comp_pgd[j] = i | PGTBL_PRESENT | PGTBL_WRITABLE | PGTBL_SUPER | PGTBL_GLOBAL; } }
static int __valloc_init(spdid_t spdid) { int ret = -1; struct spd_vas_tracker *trac; struct spd_vas_occupied *occ; struct cos_component_information *ci; unsigned long page_off; void *hp; if (cos_vect_lookup(&spd_vect, spdid)) goto success; trac = malloc(sizeof(struct spd_vas_tracker)); if (!trac) goto done; occ = alloc_page(); if (!occ) goto err_free1; ci = cos_get_vas_page(); if (cinfo_map(cos_spd_id(), (vaddr_t)ci, spdid)) goto err_free2; hp = (void*)ci->cos_heap_ptr; // printc("valloc init heap_ptr: %x\n", (unsigned int) hp); trac->spdid = spdid; trac->ci = ci; trac->map = occ; trac->extents[0].start = (void*)round_to_pgd_page(hp); trac->extents[0].end = (void*)round_up_to_pgd_page(hp); page_off = ((unsigned long)hp - (unsigned long)round_to_pgd_page(hp))/PAGE_SIZE; bitmap_set_contig(&occ->pgd_occupied[0], page_off, (PGD_SIZE/PAGE_SIZE)-page_off, 1); cos_vect_add_id(&spd_vect, trac, spdid); assert(cos_vect_lookup(&spd_vect, spdid)); success: // printc("valloc init success\n"); ret = 0; done: return ret; err_free2: cos_release_vas_page(ci); free_page(occ); err_free1: free(trac); goto done; }
static int __valloc_init(spdid_t spdid) { int ret = -1; struct spd_vas_tracker *trac; struct spd_vas_occupied *occ; unsigned long page_off; void *hp; if (cos_vect_lookup(&spd_vect, spdid)) goto success; trac = malloc(sizeof(struct spd_vas_tracker)); if (!trac) goto done; occ = alloc_page(); if (!occ) goto err_free1; hp = cinfo_get_heap_pointer(cos_spd_id(), spdid); if (!hp) goto err_free2; trac->spdid = spdid; trac->map = occ; trac->extents[0].start = (void*)round_to_pgd_page(hp); trac->extents[0].end = (void*)round_up_to_pgd_page(hp); trac->extents[0].map = occ; page_off = ((unsigned long)hp - (unsigned long)round_to_pgd_page(hp))/PAGE_SIZE; bitmap_set_contig(&occ->pgd_occupied[0], page_off, (PGD_SIZE/PAGE_SIZE)-page_off, 1); bitmap_set_contig(&occ->pgd_occupied[0], 0, page_off, 0); cos_vect_add_id(&spd_vect, trac, spdid); assert(cos_vect_lookup(&spd_vect, spdid)); success: ret = 0; done: return ret; err_free2: free_page(occ); err_free1: free(trac); goto done; }