static void ping_thread_simulated (void) { volatile L4_Word_t x; /* Wait for pong thread to come up */ L4_Msg_t msg; L4_MsgTag_t tag; for (int i=0; i < num_iterations; i++) { L4_Fpage_t ppage = L4_Fpage((L4_Word_t)&fault_area[i*1024], 4096); L4_Set_Rights(&ppage, L4_FullyAccessible); /* accept fpages */ L4_Accept(L4_UntypedWordsAcceptor); /* send it to our pager */ L4_MsgClear(&msg); L4_MsgAppendWord(&msg, (L4_Word_t) ppage.raw); L4_MsgAppendWord(&msg, (L4_Word_t) 0); L4_Set_Label(&msg.tag, L4_PAGEFAULT); L4_MsgLoad(&msg); /* make the call */ tag = L4_Call(pager_tid); x = fault_area[i*1024]; } /* Tell master that we're finished */ L4_Set_MsgTag (L4_Niltag); L4_Send (master_tid); for (;;) L4_WaitForever(); /* NOTREACHED */ }
void sys$sigma0_map(vms$pointer virt_addr, vms$pointer phys_addr, vms$pointer size, unsigned int priv) { L4_Fpage_t ppage; L4_Fpage_t vpage; vms$pointer pbase; vms$pointer pend; vms$pointer vbase; vms$pointer vend; vbase = virt_addr; vend = vbase + (size - 1); pbase = phys_addr; pend = pbase + (size - 1); if (vbase < vend) { /* ???? We should map a Fpage greater than size ! vpage = vms$biggest_fpage(vbase, vbase, vend); ppage = vms$biggest_fpage(pbase, pbase, pend); */ vpage = L4_Fpage(vbase, (vend - vbase) + 1); ppage = L4_Fpage(pbase, (pend - pbase) + 1); PANIC(L4_IsNilFpage(vpage) || L4_IsNilFpage(ppage)); if (L4_Size(vpage) > L4_Size(ppage)) { vpage = L4_Fpage(vbase, L4_Size(ppage)); } else if (L4_Size(ppage) > L4_Size(vpage)) { ppage = L4_Fpage(pbase, L4_Size(vpage)); } sys$sigma0_map_fpage(vpage, ppage, L4_FullyAccessible); vbase += L4_Size(vpage); pbase += L4_Size(ppage); } return; }
void l4_map_page(mm_context_t *context, L4_Fpage_t fpage, unsigned long address, unsigned long attrib) { unsigned long dest_addr, src_addr; L4_Fpage_t vpage; L4_PhysDesc_t pdesc; int rwx; src_addr = L4_Address(fpage); #if 0 if (src_addr >= vmalloc_ms_base && src_addr <= vmalloc_ms_base + vmalloc_ms_size) { // Within the vmalloc bounds so use the new depriv mapping dest_addr = address & 0xfffff000; vpage = L4_Fpage(dest_addr, L4_Size(fpage)); pdesc = L4_PhysDesc(src_addr + vmalloc_ms_virt_to_phys_offset, attrib); rwx = L4_Rights(fpage); L4_FpageAddRightsTo(&vpage, rwx); L4_MapFpage(context->space_id, vpage, pdesc); } else { #endif eas_map(context->eas, fpage, address, attrib); // } } #endif #if defined(CONFIG_CELL) unsigned long last_vstart = -1UL; unsigned long last_vend, last_seg; int okl4_find_segment(unsigned long vaddr, unsigned long *offset, unsigned long *seg) { okl4_env_segments_t *segments = OKL4_ENV_GET_SEGMENTS("SEGMENTS"); unsigned long i; assert(segments); for (i = 0; i < segments->num_segments; i++) { if (vaddr >= segments->segments[i].virt_addr && vaddr <= (segments->segments[i].virt_addr + segments->segments[i].size - 1)) { *offset = vaddr - segments->segments[i].virt_addr; *seg = segments->segments[i].segment; /* Cache lookup */ last_vstart = segments->segments[i].virt_addr; last_vend = last_vstart + segments->segments[i].size - 1; last_seg = segments->segments[i].segment; return 1; } } return 0; }
int okl4_kspace_create(okl4_kspace_t *kspace, okl4_kspace_attr_t *attr) { okl4_word_t result; #if !defined(NO_UTCB_RELOCATE) okl4_word_t utcb_base, utcb_size; #endif L4_Fpage_t utcb_area; assert(kspace != NULL); assert(attr != NULL); /* If the attr == OKL4_WEAVED_OBJECT, we assume that the kspace object has * been weaved in and hence, we do not need to re-initialize it. */ if (attr != OKL4_WEAVED_OBJECT) { kspace->id = attr->id; kspace->kclist = attr->kclist; kspace->utcb_area = attr->utcb_area; kspace->kthread_list = NULL; kspace->next = NULL; kspace->privileged = attr->privileged; } /* * Now create the actual kernel space using SpaceControl syscall * Create a Fpage for a utcb and then pass it along */ #if !defined(NO_UTCB_RELOCATE) utcb_base = kspace->utcb_area->utcb_memory.base; utcb_size = kspace->utcb_area->utcb_memory.size; /* Fpages require that they are aligned to their size. */ assert(utcb_base % utcb_size == 0); utcb_area = L4_Fpage(utcb_base, utcb_size); #else utcb_area = L4_Nilpage; #endif result = L4_SpaceControl(kspace->id, L4_SpaceCtrl_new | (attr->privileged ? L4_SpaceCtrl_kresources_accessible : 0), kspace->kclist->id, utcb_area, 0, NULL); if (result != 1) { return _okl4_convert_kernel_errno(L4_ErrorCode()); } /* Add this kspace into the kclist's list of kspaces */ kspace->next = kspace->kclist->kspace_list; kspace->kclist->kspace_list = kspace; return OKL4_OK; }
int l4e_sigma0_map(uintptr_t virt_addr, uintptr_t phys_addr, uintptr_t size) { uintptr_t vbase = virt_addr, vend = vbase + size - 1; uintptr_t pbase = phys_addr, pend = pbase + size - 1; L4_Fpage_t vpage, ppage; while (vbase < vend) { vpage = l4e_biggest_fpage(vbase, vbase, vend); ppage = l4e_biggest_fpage(pbase, pbase, pend); if (L4_Size(vpage) > L4_Size(ppage)) vpage = L4_Fpage(vbase, L4_Size(ppage)); else if (L4_Size(ppage) > L4_Size(vpage)) ppage = L4_Fpage(pbase, L4_Size(vpage)); l4e_sigma0_map_fpage(vpage, ppage); vbase += L4_Size(vpage); pbase += L4_Size(ppage); } return 0; }
// FIXME - i386 specific (EM_386) L4_Word_t elf_load32(AddrSpace_t *space, L4_Word_t image, L4_Word_t size) { Elf32_Ehdr *eh = (Elf32_Ehdr *) image; Elf32_Phdr *ph; int i; assert(space != NULL); debug("elf_load32: loading image at %lx (size %lx) for as: %p\n", image, size, space); if ((eh->e_ident[EI_MAG0] != ELFMAG0) || (eh->e_ident[EI_MAG1] != ELFMAG1) || (eh->e_ident[EI_MAG2] != ELFMAG2) || (eh->e_ident[EI_MAG3] != ELFMAG3) || (eh->e_type != ET_EXEC) || (eh->e_machine != EM_386) || (eh->e_phoff == 0)) { debug("elf_load32: illegal ELF image at %lx\n", (L4_Word_t) image); return 0; } for (i = 0; i < eh->e_phnum; i++) { L4_Fpage_t vp, fp; L4_Word_t size; uint8_t *src, *dest; ph = (Elf32_Phdr *) (image + eh->e_phoff + i * eh->e_phentsize); if (ph->p_type != PT_LOAD) continue; assert((ph->p_offset + ph->p_filesz) < size); assert(ph->p_filesz <= ph->p_memsz); size = intlog2(ph->p_memsz); vp = L4_Fpage(ph->p_vaddr, size); fp = address_space_request_page(space, vp); if (L4_IsNilFpage(fp)) { debug("elf_load32: can't allocate memory\n"); return 0; } dest = (uint8_t *) L4_Address(fp); src = (uint8_t *) (image + ph->p_offset); memcpy(dest, src, ph->p_filesz); memset(dest + ph->p_filesz, 0, size - ph->p_filesz); } return eh->e_entry; }
static L4_Word_t thread_prepare_stack(AddrSpace_t *as, L4_Word_t sp, char *cmdline, int n, char **paths, HpfCapability *caps) { L4_Word_t size; int i; assert(as != NULL); /* nothing to do in this case */ if (cmdline == NULL) return 0; /* we need room for cmdline and for path/capability pairs */ size = strlen(cmdline) + 1 + 4 * sizeof(uint8_t *); size += n * sizeof(HpfCapability); for (i = 0; i < n; i++) { size += strlen(paths[i]) + 1; } if (size < PAGE_SIZE) size = PAGE_SIZE; size = intlog2(size); L4_Fpage_t vp = L4_Fpage(sp - size, size); L4_Fpage_t fp = address_space_request_page(as, vp); if (L4_IsNilFpage(fp)) { debug("thread_prepare_stack: can't setup stack!\n"); return 0; } uint8_t *start = (uint8_t *) L4_Address(fp); uint32_t *tmp = (uint32_t *) start; tmp[0] = L4_Address(vp) + 4 * sizeof(uint8_t *); /* pointer to cmdline */ tmp[1] = n; /* number of path/capability pairs */ tmp[2] = L4_Address(vp) + 4 * sizeof(uint8_t *) + strlen(cmdline) + 1; /* pointer to array of paths */ tmp[3] = L4_Address(vp) + size - n * sizeof(HpfCapability); /* pointer to array of caps */ strcpy(start + 4 * sizeof(uint8_t *), cmdline); memcpy(start + size - n * sizeof(HpfCapability), caps, n * sizeof(HpfCapability)); start += 4 * sizeof(uint8_t *) + strlen(cmdline) + 1; for (i = 0; i < n; i++) { char *x = paths[i]; while (*x) *start++ = *x++; *start++ = 0; } return size; }
/** * Setup a series of mappings. * * @param[in] page_size the page size to use for all the mappings * @param[in] n_pages how many pages to use in the sequence * @param[in] v the virtual address to start the sequence of mappings * @param[in] p the physical address to start the sequence of mappings * * @return 0 for success and non-zero on error */ static int map_series(L4_SpaceId_t space, L4_Word_t page_size, uintptr_t n_pages, uintptr_t v, uintptr_t p) { int i, res = 1; L4_Fpage_t f; for (i = 0; i < n_pages; i++, p += page_size) { f = L4_Fpage(v + i*page_size, page_size); f.X.rwx = L4_FullyAccessible; res = l4e_map_fpage(space, f, p, L4_DefaultMemory); if(res != 1) break; } return res; }
static L4_ThreadId_t launch(L4_BootRec_t *br) { AddrSpace_t *as = task_new(mman_tid); if (!as) { debug("launch: can't create address space for %s\n", L4_Module_Cmdline(br)); return L4_nilthread; } /* we have to explicitly grab these from sigma0 */ L4_Word_t mi; for (mi = 0; mi < L4_Module_Size(br); mi += 4096) { L4_Sigma0_GetPage(L4_nilthread, L4_Fpage(L4_Module_Start(br) + mi, 4096)); } L4_Word_t start = elf_load32(as, L4_Module_Start(br), L4_Module_Size(br)); thread_start(as->tid, start, L4_Module_Cmdline(br), n_paths, dir_paths, dir_caps); printf(" %s\n", L4_Module_Cmdline(br)); return as->tid; }
static int CreateMaxSpaces(void) { int res = 1, i = 0; int max; L4_Word_t result, end; L4_SpaceId_t space; okl4_allocator_attr_t attr; while(res == 1) { result = okl4_kspaceid_allocany(spaceid_pool, &space); fail_unless(result == OKL4_OK, "Failed to allocate any space id."); res = create_address_space(space, L4_Fpage(0xb10000, 0x1000)); if(res != 1) break; /* 2gb mapping of 512k pages*/ res = map_series(space, 0x80000, 4096, 0, 0); i++; } max = i; /* clean up */ okl4_kspaceid_getattribute(spaceid_pool, &attr); end = attr.base + attr.size; for (i = attr.base; i < end; i++) { L4_SpaceId_t id = L4_SpaceId(i); if (okl4_kspaceid_isallocated(spaceid_pool, id) && id.space_no != KTEST_SPACE.space_no) { deleteSpace(id); } } return max; }
/* * Setup L4 architecture requirements: * kip_area, utcb_area, physical memory, current, * Init user address space, ramdisk, console, early consle */ void __init setup_arch (char **command_line) { unsigned long base, area; #if defined(CONFIG_IGUANA) setup_tls(1); #endif /* Return the command line to the rest of the kernel */ boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; *command_line = boot_command_line; if (L4_UtcbIsKernelManaged()) { utcb_area = L4_Nilpage; } else { /* Currently hardcoded to 1024 L4 threads per linux * user address space */ area = L4_GetUtcbSize() * 1024; /* * Find some area to put the utcb in outside user's * area. When the KIP was present, 16 pages were * reserved for it, so keep the same spacing here * because the equation is not fully understood. */ base = PAGE_ALIGN(TASK_SIZE) + 16 * PAGE_SIZE + area; /* Round address to the 'area' boundary. */ base = (base + (area-1)) & (~(area-1)); utcb_area = L4_Fpage(base, L4_GetUtcbSize() * 1024); } /* Initialise our machine name */ setup_machine_name(); /* FIXME: (why?) */ start_phys_mem = __pa(start_phys_mem); end_phys_mem = __pa(end_phys_mem); /* Initialise paging */ paging_init(); /* Thread info setup. */ /* FIXME: remember for SMP startup */ current_tinfo(smp_processor_id()) = (unsigned long)&init_thread_union.thread_info; task_thread_info(current)->user_tid = L4_nilthread; task_thread_info(current)->user_handle = L4_nilthread; #ifdef CONFIG_EARLY_PRINTK /* early console initialisation */ enable_early_printk(); #endif /* Ramdisk setup */ #ifdef CONFIG_BLK_DEV_INITRD /* Board specific code should have set up initrd_start and initrd_end */ ROOT_DEV = Root_RAM0; /* FIXME! */ initrd_start = 0; //naming_lookup("ramdisk"); initrd_end = 0; //naming_lookup("ramdisk_end"); printk("end: %lx\n", initrd_end); initrd_below_start_ok = 1; if (initrd_start) { unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); printk("Initial ramdisk at: 0x%p (%lu bytes)\n", (void *)initrd_start, initrd_size); } #endif /* CONFIG_BLK_DEV_INITRD */ #ifdef CONFIG_VT #if defined(CONFIG_VGA_CONSOLE) __setup_vga(); conswitchp = &vga_con; #elif defined(CONFIG_DUMMY_CONSOLE) conswitchp = &dummy_con; #endif /* CONFIG_VGA_CONSOLE */ screen_info.lfb_base = 0xe000000; screen_info.lfb_size = 600*800; screen_info.lfb_height = 600; screen_info.lfb_width = 800; #endif /* CONFIG_VT */ panic_timeout = 1; #if defined(CONFIG_CELL) /* L4-specific -gl,cvs */ { extern unsigned long TIMER_BASE, SERIAL_BASE; okl4_env_lookup_address("MAIN_TIMER_MEM0", &TIMER_BASE); okl4_env_lookup_address("MAIN_SERIAL_MEM0", &SERIAL_BASE); } #if defined(CONFIG_VERSATILE) { extern unsigned long ETH_BASE, CLCD_BASE, VERSATILE_SYS_BASE, KMI0_BASE, KMI1_BASE; okl4_env_lookup_address("MAIN_ETH_MEM0", Ð_BASE); okl4_env_lookup_address("MAIN_VERSATILESYS_MEM0", &VERSATILE_SYS_BASE); okl4_env_lookup_address("MAIN_CLCD_MEM0", &CLCD_BASE); okl4_env_lookup_address("MAIN_KMI0_MEM0", &KMI0_BASE); okl4_env_lookup_address("MAIN_KMI1_MEM0", &KMI1_BASE); } #endif #if defined(CONFIG_ARCH_GUMSTIX) { extern unsigned long GPIO_BASE, DMAC_BASE; extern unsigned long PXA_CS1_PHYS, PXA_CS1_DMA; extern unsigned long PXA_CS2_PHYS, PXA_CS2_DMA; okl4_env_lookup_address("MAIN_GPIO_MEM0", &GPIO_BASE); okl4_env_lookup_address("MAIN_DMA_MEM0", &DMAC_BASE); okl4_env_lookup_address("MAIN_CS_MEM1", &PXA_CS1_PHYS); okl4_env_lookup_address("MAIN_CS_MEM2", &PXA_CS2_PHYS); PXA_CS1_DMA = *((unsigned long *)okl4_env_get("cs_mem1_physical")); PXA_CS2_DMA = *((unsigned long *)okl4_env_get("cs_mem2_physical")); } #endif #endif /*CELL*/ }
static void ipc_setup(struct bench_test *test, int args[]) { static bool setup = false; int r; L4_Word_t utcb; fass = (test == &bench_ipc_fass); pagertimer = (test == &bench_ipc_pagemap); pagertimer_simulated = (test == &bench_ipc_pagemap_simulated); inter = (test == &bench_ipc_inter); fass_buffer = ((test == &bench_ipc_fass_buffer) || (test == &bench_ipc_fass_buffer_vspace)); fault_test = (test == &bench_ipc_page_faults); intra_open = (test == &bench_ipc_intra_open); intra_close = (test == &bench_ipc_intra_close); intra_rpc = (test == &bench_ipc_intra_rpc); intra_ovh = (test == &bench_ipc_intra_ovh); intra_async = (test == &bench_ipc_intra_async); intra_async_ovh = (test == &bench_ipc_intra_async_ovh); num_iterations = args[0]; num_mrs = args[1]; ping_space = pong_space = L4_nilspace; if (! setup) { /* Find smallest supported page size. There's better at least one * bit set. */ /* Size for one UTCB */ utcb_size = L4_GetUtcbSize(); /* We need a maximum of two threads per task */ #ifdef NO_UTCB_RELOCATE no_utcb_alloc = 1; utcb_area = L4_Nilpage; if (fass) { pong_utcb_area = L4_Nilpage; } #else no_utcb_alloc = 0; utcb_area = L4_Fpage((L4_Word_t) UTCB_ADDRESS, L4_GetUtcbAreaSize() + 1); if (fass) { pong_utcb_area = L4_Fpage ((L4_Word_t) UTCB_ADDRESS, L4_GetUtcbAreaSize() + 1); } #endif /* Create pager */ master_tid.raw = KBENCH_SERVER.raw; pager_tid.raw = KBENCH_SERVER.raw + 1; ping_tid.raw = KBENCH_SERVER.raw + 2; pong_tid.raw = KBENCH_SERVER.raw + 3; /* VU: calculate UTCB address -- this has to be revised */ /** @todo FIXME: Should put into arch subdir - changhua. */ #if defined(ARCH_ARM) L4_Word_t pager_utcb = (L4_Word_t) __L4_ARM_Utcb(); #elif defined(ARCH_IA32) L4_Word_t pager_utcb = (L4_Word_t) __L4_X86_Utcb(); #elif defined(ARCH_SH) L4_Word_t pager_utcb = (L4_Word_t) L4_GetUtcbBase(); #else #error "Please define arch get_Utcb()" #endif pager_utcb = no_utcb_alloc ? ~0UL : (pager_utcb & ~(utcb_size - 1)) + utcb_size; r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, master_tid, 0, (void*)pager_utcb); if (r == 0) printf("Thread create Error: %lx\n", L4_ErrorCode()); assert(r == 1); L4_KDB_SetThreadName(pager_tid, "pager"); L4_Start_SpIp (pager_tid, (L4_Word_t) pager_stack + sizeof(pager_stack) - 32, START_ADDR (pager)); /* Find some area of memory to page to */ setup = true; } if (pagertimer) { /* Only create ping space and ping thread. */ r = okl4_kspaceid_allocany(spaceid_pool, &ping_space); assert(r == OKL4_OK); r = L4_SpaceControl(ping_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, 0, NULL); assert(r == 1); utcb = no_utcb_alloc ? ~0UL : UTCB(0); r = L4_ThreadControl(ping_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb); L4_StoreMR(0, &ping_th.raw); assert(r == 1); } else if (fault_test) { /* Only create pong space and pong thread. */ r = okl4_kspaceid_allocany(spaceid_pool, &pong_space); assert(r == OKL4_OK); r = L4_SpaceControl(pong_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, 0, NULL); assert(r == 1); utcb = no_utcb_alloc ? ~0UL : UTCB(0); r = L4_ThreadControl(pong_tid, pong_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb); L4_StoreMR(0, &pong_th.raw); assert(r == 1); } else if (pagertimer_simulated || inter || fass || fass_buffer) { /* Create both ping, pong space, and create ping, pong thread in their own space */ L4_Word_t ctrl = 0; if (test == &bench_ipc_fass_buffer_vspace) { ctrl = (1 << 16); } r = okl4_kspaceid_allocany(spaceid_pool, &ping_space); assert(r == OKL4_OK); r = L4_SpaceControl(ping_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, ctrl, NULL); if (r == 0) printf("Space control Error: 0x%lx\n", L4_ErrorCode()); assert( r == 1 ); r = okl4_kspaceid_allocany(spaceid_pool, &pong_space); assert(r == OKL4_OK); r = L4_SpaceControl(pong_space, L4_SpaceCtrl_new, KBENCH_CLIST, (fass ? pong_utcb_area : utcb_area), ctrl, NULL); assert( r == 1); utcb = no_utcb_alloc ? ~0UL : UTCB(0); r = L4_ThreadControl(ping_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb); L4_StoreMR(0, &ping_th.raw); assert( r == 1); utcb = no_utcb_alloc ? ~0UL : fass ? PONGUTCB(1) : UTCB(1); r = L4_ThreadControl(pong_tid, pong_space, master_tid, pager_tid, pager_tid, 0, (void *)utcb); L4_StoreMR(0, &pong_th.raw); } else { /* Only Create ping space, but create both ping, pong thread in that space. */ r = okl4_kspaceid_allocany(spaceid_pool, &ping_space); assert(r == OKL4_OK); r = L4_SpaceControl(ping_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, 0, NULL); assert( r == 1 ); utcb = no_utcb_alloc ? ~0UL : UTCB(0); r = L4_ThreadControl(ping_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb); L4_StoreMR(0, &ping_th.raw); assert( r == 1); utcb = no_utcb_alloc ? ~0UL : UTCB(1); r = L4_ThreadControl(pong_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb); L4_StoreMR(0, &pong_th.raw); assert( r == 1); } L4_KDB_SetThreadName(ping_tid, "ping"); if (test != &bench_ipc_pagemap) { L4_KDB_SetThreadName(pong_tid, "pong"); } }
int main(void) { int i = 0; int res = 1; L4_SpaceId_t space; okl4_allocator_attr_t attr; L4_Word_t end, result; L4_CapId_t sender; L4_MsgTag_t tag; L4_Msg_t msg; struct okl4_bitmap_allocator *spaceid_pool = okl4_env_get("MAIN_SPACE_ID_POOL"); HEAP_EXHAUSTION_CLIST = L4_ClistId(*(OKL4_ENV_GET_MAIN_CLISTID("MAIN_CLIST_ID"))); while(res == 1) { result = okl4_kspaceid_allocany(spaceid_pool, &space); if (result != OKL4_OK) { printf("Failed to allocate space id\n"); } res = create_address_space(space, L4_Fpage(0xb10000, 0x1000)); if (res != 1) { printf("SpaceControl failed, space id=%lu, Error code: %lu\n", space.space_no, L4_ErrorCode()); break; } /* 2gb mapping of 512k pages*/ res = map_series(space, 0x80000, 4096, 0, 0); i++; } printf("Created %d address spaces\n", i); if (i == 0) { okl4_kspaceid_free(spaceid_pool, space); res = 0; goto ipc_ktest; } /* clean up */ okl4_kspaceid_getattribute(spaceid_pool, &attr); end = attr.base + attr.size; for (i = attr.base; i < end; i++) { L4_SpaceId_t id = L4_SpaceId(i); if (okl4_kspaceid_isallocated(spaceid_pool, id)) { L4_SpaceControl(id, L4_SpaceCtrl_delete, HEAP_EXHAUSTION_CLIST, L4_Nilpage, 0, NULL); okl4_kspaceid_free(spaceid_pool, id); } } res = 1; ipc_ktest: tag = L4_Wait(&sender); L4_MsgClear(&msg); L4_MsgAppendWord(&msg, (L4_Word_t)res); L4_MsgLoad(&msg); L4_Reply(sender); assert(L4_IpcSucceeded(tag)); L4_WaitForever(); }
int l4e_sigma0_map_fpage(L4_Fpage_t virt_page, L4_Fpage_t phys_page) { /* * XXX: These two special cases are workarounds for broken superpage * support in pistachio. On ARM, 1M superpages are disabled by * pistachio to reduce the size of the mapping database, however due to * bugs in the mapping code, any mappings >= 1M get converted into 4K * mappings (rather than 64K). For MIPS, the tlb refill code assumes * only 4K mappings are used, even the the pagetable building code will * use superpages where possible. -- alexw */ #if defined(ARCH_ARM) uintptr_t virt_base = L4_Address(virt_page); uintptr_t phys_base = L4_Address(phys_page); uintptr_t offset = 0; uintptr_t step = L4_Size(virt_page) > 0x10000 ? 0x10000 : L4_Size(virt_page); uintptr_t limit = L4_Size(virt_page) - 1; for (virt_page = L4_Fpage(virt_base + offset, step), phys_page = L4_Fpage(phys_base + offset, step); offset < limit; offset += step, virt_page = L4_Fpage(virt_base + offset, step), phys_page = L4_Fpage(phys_base + offset, step)) #elif defined(ARCH_MIPS64) uintptr_t virt_base = L4_Address(virt_page); uintptr_t phys_base = L4_Address(phys_page); uintptr_t offset = 0; uintptr_t step = 0x1000; uintptr_t limit = L4_Size(virt_page) - 1; for (virt_page = L4_Fpage(virt_base + offset, step), phys_page = L4_Fpage(phys_base + offset, step); offset < limit; offset += step, virt_page = L4_Fpage(virt_base + offset, step), phys_page = L4_Fpage(phys_base + offset, step)) #endif { L4_ThreadId_t tid; L4_MsgTag_t tag; L4_Msg_t msg; L4_MapItem_t map; /* * find our pager's ID */ tid = L4_Pager(); L4_Set_Rights(&phys_page, L4_FullyAccessible); /* accept fpages */ L4_Accept(L4_MapGrantItems(virt_page)); /* send it to our pager */ L4_MsgClear(&msg); L4_MsgAppendWord(&msg, (L4_Word_t) phys_page.raw); L4_MsgAppendWord(&msg, (L4_Word_t) 0); L4_Set_Label(&msg.tag, SIGMA0_REQUEST_LABEL); L4_MsgLoad(&msg); /* make the call */ tag = L4_Call(tid); /* check for an error */ if (L4_IpcFailed(tag)) { return 2; } L4_MsgStore(tag, &msg); L4_MsgGetMapItem(&msg, 0, &map); /* * rejected mapping? */ if (map.X.snd_fpage.raw == L4_Nilpage.raw) { return 1; } } return 0; }
int main (void) { L4_Word_t total; printf("\n\nHasenpfeffer operating system\n"); printf("Copyright (C) 2005,2006. Senko Rasic <*****@*****.**>\n\n"); printf("Initializing root task...\n"); L4_KernelInterfacePage_t *kip = (L4_KernelInterfacePage_t *) L4_GetKernelInterface(); void *bi = (void *) L4_BootInfo(kip); // we need to preload these I/O pages // ATA L4_Sigma0_GetPage(L4_nilthread, L4_Fpage(0x0000, 4096)); // KIP L4_Sigma0_GetPage(L4_nilthread, L4_Fpage(L4_BootInfo(kip), 4096)); L4_BootRec_t *br = NULL; if (L4_BootInfo_Valid((void *) bi)) { int n = L4_BootInfo_Entries(bi); br = L4_BootInfo_FirstEntry(bi); while (--n) { /* touch roottask data from here, because sigma0 only gives pages to initial *thread* */ if (L4_BootRec_Type(br) == L4_BootInfo_SimpleExec) { L4_Word_t mi; for (mi = 0; mi < L4_Module_Size(br); mi += 4096) { L4_Sigma0_GetPage(L4_nilthread, L4_Fpage(L4_Module_Start(br) + mi, 4096)); } } br = L4_BootRec_Next(br); } } else { printf("panic: invalid bootinfo data\n"); return 0; } memory_init(); total = memory_get_free(); printf("Creating root memory manager...\n"); mman_tid = create_local_thread("root memory manager", kip, 1, memman, 4096); thread_init(mman_tid); printf("Initializing root task manager...\n"); HpfCapability full, newthread, newtask; task_manager_init(&full, &newtask, &newthread); dir_paths[0] = "/process/TaskManager"; dir_caps[0] = full; n_paths = 1; printf("Loading initial programs...\n"); int n = L4_BootInfo_Entries(bi); br = L4_BootInfo_FirstEntry(bi); int first_program = 1; while (--n) { if (L4_BootRec_Type(br) == L4_BootInfo_Module) { L4_ThreadId_t tid = launch(br); if (first_program) { first_program = 0; // this is the root directory server if (hermes_capability(tid, &(dir_caps[1]))) { // dir_paths[1] = "/process/DirectoryService"; dir_paths[1] = ""; // <- catch-all n_paths = 2; } } } br = L4_BootRec_Next(br); } printf("Init done, running...\n\n"); task_manager_main(); return 0; }
END_TEST /* \begin{test}{KMEM03} \TestDescription{Check that creating and deleting different numbers of address spaces does not leak any memory} \TestFunctionalityTested{Kernel memory allocator} \TestImplementationProcess{ \begin{enumerate} \item Create address spaces \item Delete all created spaces \item Recreate all address spaces \item Delete then create all even numbered address spaces \item Delete then create all odd numbered address spaces \item Delete and create the middle numbered address spaces \item Delete all created spaces \end{enumerate} } \TestImplementationStatus{Implemented} \TestIsFullyAutomated{Yes} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(KMEM03) { int i; int SPACES_TO_TEST; okl4_allocator_attr_t attr; okl4_kspaceid_getattribute(spaceid_pool, &attr); SPACES_TO_TEST = attr.base + attr.size - 1; /* create and delete all spaces */ for(i = attr.base; i < SPACES_TO_TEST; i++) create_address_space(L4_SpaceId(i), L4_Fpage(0xb10000, 0x1000)); for(i = attr.base; i < SPACES_TO_TEST; i++) if (i != KTEST_SPACE.space_no) { L4_SpaceControl(L4_SpaceId(i), L4_SpaceCtrl_delete, KTEST_CLIST, L4_Nilpage, 0, NULL); } /* delete and create odd and even spaces */ for(i = attr.base; i < SPACES_TO_TEST; i++) create_address_space(L4_SpaceId(i), L4_Fpage(0xb10000, 0x1000)); for(i = attr.base; i < SPACES_TO_TEST; i+=2) if (i != KTEST_SPACE.space_no) { L4_SpaceControl(L4_SpaceId(i), L4_SpaceCtrl_delete, KTEST_CLIST, L4_Nilpage, 0, NULL); } for(i = attr.base; i < SPACES_TO_TEST; i+=2) create_address_space(L4_SpaceId(i), L4_Fpage(0xb10000, 0x1000)); for(i = attr.base + 1; i < SPACES_TO_TEST; i+=2) if (i != KTEST_SPACE.space_no) { L4_SpaceControl(L4_SpaceId(i), L4_SpaceCtrl_delete, KTEST_CLIST, L4_Nilpage, 0, NULL); } for(i = attr.base + 1; i < SPACES_TO_TEST; i+=2) create_address_space(L4_SpaceId(i), L4_Fpage(0xb10000, 0x1000)); /* delete the middle range of spaces */ for(i = attr.base + 2; i < SPACES_TO_TEST-2; i++) if (i != KTEST_SPACE.space_no) { L4_SpaceControl(L4_SpaceId(i), L4_SpaceCtrl_delete, KTEST_CLIST, L4_Nilpage, 0, NULL); } for(i = attr.base + 2; i < SPACES_TO_TEST-2; i++) create_address_space(L4_SpaceId(i), L4_Fpage(0xb10000, 0x1000)); /* clean up */ for(i = attr.base; i < SPACES_TO_TEST; i++) if (i != KTEST_SPACE.space_no) { L4_SpaceControl(L4_SpaceId(i), L4_SpaceCtrl_delete, KTEST_CLIST, L4_Nilpage, 0, NULL); } }
static int CreateMaxThreads(void) { int i; int res = 1; // MIPS32 address space ends at 0x80000000 #if (defined(L4_ARCH_MIPS) && defined(L4_32BIT)) unsigned long utcb_base = 0x70000000; #else unsigned long utcb_base = 0xb0000000; #endif void * utcb = (void *)utcb_base; L4_Fpage_t utcb_area = L4_Fpage(utcb_base, 0x01000000); int max; L4_Word_t result; L4_SpaceId_t space; result = okl4_kspaceid_allocany(spaceid_pool, &space); fail_unless(result == OKL4_OK, "Failed to allocate any space id."); /* Create first thread (and address space) */ #ifdef NO_UTCB_RELOCATE utcb_area = L4_Nilpage; utcb = (void*)-1ul; #endif res = create_address_space(space, utcb_area); i = 3; // start creating threads after controlling space fail_unless(res == 1, "Failed to create controlling space\n"); /* create threads */ do { if (utcb) { utcb = (void *)(utcb_base + i * L4_GetUtcbSize()); } if (!isSystemThread(thread_offset(i))) { res = L4_ThreadControl(thread_offset(i), space, default_thread_handler, L4_nilthread, L4_nilthread, 0, (void *)utcb); } i++; } while (res == 1); max = i-3; /* delete threads */ for (; i >= 3; i--) { if (!isSystemThread(thread_offset(i))) { res = L4_ThreadControl(thread_offset(i), L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *)0); } } res = L4_SpaceControl(space, L4_SpaceCtrl_delete, KTEST_CLIST, L4_Nilpage, 0, NULL); okl4_kspaceid_free(spaceid_pool, space); return max; }
void freevms_main(void) { char *command_line; # define ROOT_DEVICE_LENGTH 80 char root_device[ROOT_DEVICE_LENGTH]; # define CONSOLE_DEVICE_LENGTH 80 char console_device[CONSOLE_DEVICE_LENGTH]; L4_BootRec_t *boot_record; L4_KernelInterfacePage_t *kip; L4_ProcDesc_t *main_proc_desc; L4_ThreadId_t root_tid; L4_ThreadId_t s0_tid; L4_Word_t api_flags; L4_Word_t boot_info; L4_Word_t i; L4_Word_t kernel_id; L4_Word_t kernel_interface; L4_Word_t num_boot_info_entries; L4_Word_t num_processors; L4_Word_t page_bits; L4_Word_t pagesize; struct vms$meminfo mem_info; vms$pd_initialized = 0; notice("\n"); notice(">>> FreeVMS %s (R)\n", FREEVMS_VERSION); notice("\n"); kip = (L4_KernelInterfacePage_t *) L4_KernelInterface(&kernel_interface, &api_flags, &kernel_id); notice(SYSBOOT_I_SYSBOOT "leaving kernel privileges\n"); notice(SYSBOOT_I_SYSBOOT "launching FreeVMS kernel with executive " "privileges\n"); root_tid = L4_Myself(); s0_tid = L4_GlobalId(kip->ThreadInfo.X.UserBase, 1); notice(SYSBOOT_I_SYSBOOT "booting main processor\n"); for(page_bits = 0; !((1 << page_bits) & L4_PageSizeMask(kip)); page_bits++); pagesize = (((vms$pointer) 1) << page_bits); notice(SYSBOOT_I_SYSBOOT "computing page size: %d bytes\n", (int) pagesize); num_processors = L4_NumProcessors((void *) kip); switch(num_processors - 1) { case 0: break; case 1: notice(SYSBOOT_I_SYSBOOT "booting %d secondary processor\n", (int) (num_processors - 1)); break; default: notice(SYSBOOT_I_SYSBOOT "booting %d secondary processors\n", (int) (num_processors - 1)); break; } for(i = 0; i < num_processors; i++) { main_proc_desc = L4_ProcDesc((void *) kip, i); notice(SYSBOOT_I_SYSBOOT "CPU%d EXTFREQ=%d MHz, INTFREQ=%d MHz\n", (int) i, (int) (main_proc_desc->X.ExternalFreq / 1000), (int) (main_proc_desc->X.InternalFreq / 1000)); } L4_Sigma0_GetPage(L4_nilthread, L4_Fpage(L4_BootInfo(kip), pagesize)); boot_info = L4_BootInfo((void *) kip); num_boot_info_entries = L4_BootInfo_Entries((void *) boot_info); boot_record = L4_BootInfo_FirstEntry((void *) boot_info); for(i = 2; i < num_boot_info_entries; i++) { PANIC(L4_BootRec_Type(boot_record) != L4_BootInfo_SimpleExec); command_line = L4_SimpleExec_Cmdline(boot_record); if ((strstr(command_line, "vmskernel.sys") != NULL) && (i == 3)) { break; } boot_record = L4_BootRec_Next(boot_record); } PANIC(L4_BootRec_Type(boot_record) != L4_BootInfo_SimpleExec); command_line = L4_SimpleExec_Cmdline(boot_record); notice(SYSBOOT_I_SYSBOOT "parsing command line: %s\n", command_line); sys$parsing(command_line, (char *) "root", root_device, ROOT_DEVICE_LENGTH); notice(SYSBOOT_I_SYSBOOT "selecting root device: %s\n", root_device); sys$parsing(command_line, (char *) "console", console_device, CONSOLE_DEVICE_LENGTH); notice(SYSBOOT_I_SYSBOOT "selecting console device: %s\n", console_device); dbg$virtual_memory = (strstr(command_line, " dbg$virtual_memory") != NULL) ? 1 : 0; dbg$sys_pagefault = (strstr(command_line, " dbg$sys_pagefault") != NULL) ? 1 : 0; dbg$vms_pagefault = (strstr(command_line, " dbg$vms_pagefault") != NULL) ? 1 : 0; // Starting virtual memory subsystem sys$mem_init(kip, &mem_info, pagesize); sys$bootstrap(&mem_info, pagesize); sys$objtable_init(); sys$utcb_init(kip); sys$pd_init(&mem_info); sys$thread_init(kip); sys$populate_init_objects(&mem_info, pagesize); dev$init(); names$init(); sys$pager(kip, &mem_info, pagesize, root_device); sys$init(kip, &mem_info, pagesize, root_device); sys$loop(); notice(">>> System halted\n"); return; }