static int print_init(void) { static int first = 1; char *addr, *start; unsigned long i, sz; if (!first) return 0; first = 0; sz = cos_trans_cntl(COS_TRANS_MAP_SZ, 0, 0, 0); if (sz > (8*1024*1024)) return -1; addr = start = cos_get_vas_page(); if (!start) return -2; for (i = PAGE_SIZE ; i < sz ; i += PAGE_SIZE) { char *next_addr = cos_get_vas_page(); if ((((unsigned long)next_addr) - (unsigned long)addr) != PAGE_SIZE) return -3; addr = next_addr; } for (i = 0, addr = start ; i < sz ; i += PAGE_SIZE, addr += PAGE_SIZE) { if (cos_trans_cntl(COS_TRANS_MAP, COS_TRANS_SERVICE_PRINT, (unsigned long)addr, i)) return -4; } cringbuf_init(&sharedbuf, start, sz); return 0; }
vaddr_t mm_test3() { vaddr_t addr; addr = (vaddr_t)cos_get_vas_page(); if (!addr) BUG(); return addr; }
static int boot_spd_map_memory(struct cobj_header *h, spdid_t spdid, vaddr_t comp_info) { unsigned int i; vaddr_t dest_daddr; local_md[spdid].spdid = spdid; local_md[spdid].h = h; local_md[spdid].page_start = cos_get_heap_ptr(); local_md[spdid].comp_info = comp_info; for (i = 0 ; i < h->nsect ; i++) { struct cobj_sect *sect; char *dsrc; int left; sect = cobj_sect_get(h, i); dest_daddr = sect->vaddr; left = cobj_sect_size(h, i); while (left > 0) { dsrc = cos_get_vas_page(); if ((vaddr_t)dsrc != mman_get_page(cos_spd_id(), (vaddr_t)dsrc, 0)) BUG(); if (dest_daddr != (mman_alias_page(cos_spd_id(), (vaddr_t)dsrc, spdid, dest_daddr))) BUG(); dest_daddr += PAGE_SIZE; left -= PAGE_SIZE; } } local_md[spdid].page_end = (void*)dest_daddr; return 0; }
static inline void * __page_get(void) { void *hp = cos_get_vas_page(); struct frame *f = frame_alloc(); assert(hp && f); frame_ref(f); if (cos_mmap_cntl(COS_MMAP_GRANT, 0, cos_spd_id(), (vaddr_t)hp, frame_index(f))) { BUG(); } return hp; }
static unsigned long * map_stack(spdid_t spdid, vaddr_t extern_stk) { static unsigned long *stack = 0; vaddr_t extern_addr; if (!stack) stack = cos_get_vas_page(); extern_addr = round_to_page(extern_stk); if (stkmgr_stack_introspect(cos_spd_id(), (vaddr_t)stack, spdid, extern_addr)) BUG(); return stack; }
void *valloc_alloc(spdid_t spdid, spdid_t dest, unsigned long npages) { /* JWW print out a few things : spdid, heap ptr, make sure the heap ptr is sane */ void *ret = NULL; struct spd_vas_tracker *trac; struct spd_vas_occupied *occ; long off; /*JWW REMOVE THIS */ struct cos_component_information *ci; unsigned long page_off; void *hp; /* /JWW */ LOCK(); /*JWW REMOVE THIS */ ci = cos_get_vas_page(); if (cinfo_map(cos_spd_id(), (vaddr_t)ci, spdid)) { // error cos_release_vas_page(ci); printc("CINFO_MAP ERROR\n"); } hp = (void*)ci->cos_heap_ptr; // now print some things out. // printc("valloc alloc heap_ptr: %x, ucap_tbl: %x, npages: %ul \n", (unsigned int) hp, (unsigned int) ci->cos_user_caps, npages); /* /JWW */ page_off = ((unsigned long)hp - (unsigned long)round_to_pgd_page(hp))/PAGE_SIZE; trac = cos_vect_lookup(&spd_vect, dest); if (!trac) { printc("valloc init being called\n"); if (__valloc_init(dest) || !(trac = cos_vect_lookup(&spd_vect, dest))) goto done; } // printc("valloc alloc past init\n"); occ = trac->map; assert(occ); // off = bitmap_extent_find_set(&occ->pgd_occupied[0], page_off, npages, MAP_MAX); off = bitmap_extent_find_set(&occ->pgd_occupied[0], 0, npages, MAP_MAX); if (off < 0) goto done; ret = ((char *)trac->extents[0].start) + (off * PAGE_SIZE); done: // printc("valloc alloc returning %x\n", (unsigned int) ret); UNLOCK(); return ret; }
static inline void * __page_get(void) { void *hp = cos_get_vas_page(); struct frame *f = frame_alloc(); assert(hp && f); frame_ref(f); f->nmaps = -1; /* belongs to us... */ f->c.addr = (vaddr_t)hp; /* ...at this address */ if (cos_mmap_cntl(COS_MMAP_GRANT, MAPPING_RW, cos_spd_id(), (vaddr_t)hp, frame_index(f))) { printc("grant @ %p for frame %d\n", hp, frame_index(f)); BUG(); } return hp; }
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 void get_test() { int i; printc("\n<<< GET TEST BEGIN! >>>\n"); for (i = 0; i<PAGE_NUM; i++) { s_addr[i] = (vaddr_t)cos_get_vas_page(); if (unlikely(!s_addr[i])) { printc("Cannot get vas for comp %ld!\n", cos_spd_id()); BUG(); } /* printc("s_addr %p\n", s_addr[i]); */ /* rdtscll(start); */ if (s_addr[i]!= mman_get_page(cos_spd_id(), s_addr[i], 0)) BUG(); /* rdtscll(end); */ /* printc("cost %llu\n", end - start); */ } printc("<<< GET TEST END! >>>\n\n"); return; }
static void all_in_one() { int i; for (i = 0; i<PAGE_NUM; i++) { s_addr[i] = (vaddr_t)cos_get_vas_page(); d_addr[i] = mm_test2(); } for (i = 0; i<PAGE_NUM; i++) { /* rdtscll(start); */ mman_get_page(cos_spd_id(), s_addr[i], 0); mman_alias_page(cos_spd_id(), s_addr[i], cos_spd_id()+1, d_addr[i]); mman_revoke_page(cos_spd_id(), s_addr[i], 0); /* rdtscll(end); */ /* printc("grant-alias-revoke cost %llu\n", end - start); */ /* mman_release_page(cos_spd_id(), s_addr[i], 0); */ } return; }
static inline struct mem_cell * find_unused(void) { int i; /* If we care about scaling, this should, of course use freelist */ for (i = 0 ; i < COS_MAX_MEMORY ; i++) { cells[i].map[0].flags = 0; if (cells[i].map[0].owner_spd != 0) continue; if (!cells[i].local_addr) { char *hp = cos_get_vas_page(); if (!parent_mman_get_page(cos_spd_id(), (vaddr_t)hp, 0)) { return NULL; } cells[i].local_addr = hp; } return &cells[i]; } return NULL; }
/** * maps the compoenents spdid info page on startup * I do it this way since not every component may require stacks or * what spdid's I even have access too. * I am not sure if this is the best way to handle this, but it * should work for now. */ static inline void get_cos_info_page(spdid_t spdid) { spdid_t s; int i; int found = 0; void *hp; if(spdid > MAX_NUM_SPDS){ BUG(); } for (i = 0; i < MAX_NUM_SPDS; i++) { s = cinfo_get_spdid(i); if(!s) { printc("Unable to map compoents cinfo page!\n"); BUG(); } if (s == spdid) { found = 1; break; } } if(!found){ DOUT("Could not find cinfo for spdid: %d\n", spdid); BUG(); } hp = cos_get_vas_page(); if(cinfo_map(cos_spd_id(), (vaddr_t)hp, s)){ DOUT("Could not map cinfo page for %d\n", spdid); BUG(); } spd_stk_info_list[spdid].ci = hp; DOUT("mapped -- id: %ld, hp:%x, sp:%x\n", spd_stk_info_list[spdid].ci->cos_this_spd_id, (unsigned int)spd_stk_info_list[spdid].ci->cos_heap_ptr, (unsigned int)spd_stk_info_list[spdid].ci->cos_stacks.freelists[0].freelist); }
/** * cos_init */ void cos_init(void *arg){ int i; struct cos_stk_item *stk_item; DOUT("<stkmgr>: STACK in cos_init\n"); memset(spd_stk_info_list, 0, sizeof(struct spd_stk_info) * MAX_NUM_SPDS); for(i = 0; i < MAX_NUM_SPDS; i++){ spd_stk_info_list[i].spdid = i; INIT_LIST(&spd_stk_info_list[i].stk_list, next, prev); INIT_LIST(&spd_stk_info_list[i].bthd_list, next, prev); } // Initialize our free stack list for(i = 0; i < MAX_NUM_STACKS; i++){ // put stk list is some known state stk_item = &(all_stk_list[i]); stk_item->stk = NULL; INIT_LIST(stk_item, next, prev); // allocate a page stk_item->hptr = alloc_page(); if (stk_item->hptr == NULL){ DOUT("<stk_mgr>: ERROR, could not allocate stack\n"); } else { // figure out or location of the top of the stack stk_item->stk = (struct cos_stk *)D_COS_STK_ADDR((char *)stk_item->hptr); freelist_add(stk_item); } } stacks_allocated = 0; // Map all of the spds we can into this component for (i = 0 ; i < MAX_NUM_SPDS ; i++) { spdid_t spdid; void *hp; hp = cos_get_vas_page(); spdid = cinfo_get_spdid(i); if (!spdid) break; if(cinfo_map(cos_spd_id(), (vaddr_t)hp, spdid)){ DOUT("Could not map cinfo page for %d\n", spdid); BUG(); } spd_stk_info_list[spdid].ci = hp; DOUT("mapped -- id: %ld, hp:%x, sp:%x\n", spd_stk_info_list[spdid].ci->cos_this_spd_id, (unsigned int)spd_stk_info_list[spdid].ci->cos_heap_ptr, (unsigned int)spd_stk_info_list[spdid].ci->cos_stacks.freelists[0].freelist); stacks_target += DEFAULT_TARGET_ALLOC; spd_stk_info_list[spdid].num_allocated = 0; spd_stk_info_list[spdid].num_desired = DEFAULT_TARGET_ALLOC; } LOCK_INIT(); DOUT("Done mapping components information pages!\n"); DOUT("<stkmgr>: init finished\n"); return; }