void sys$sigma0_map_fpage(L4_Fpage_t virt_page, L4_Fpage_t phys_page, unsigned int priv) { L4_ThreadId_t tid; L4_MsgTag_t tag; L4_Msg_t msg; L4_MapItem_t map; // Find Pager's ID tid = L4_Pager(); L4_Set_Rights(&phys_page, priv); L4_Accept(L4_MapGrantItems(virt_page)); 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); tag = L4_Call(tid); PANIC(L4_IpcFailed(tag), notice(IPC_F_FAILED "IPC failed (error %ld: %s)\n", L4_ErrorCode(), L4_ErrorCode_String(L4_ErrorCode()))); L4_MsgStore(tag, &msg); L4_MsgGetMapItem(&msg, 0, &map); if (dbg$virtual_memory == 1) { if (map.X.snd_fpage.raw == L4_Nilpage.raw) { notice(MEM_I_REJMAP "rejecting mapping\n"); notice(MEM_I_REJMAP "virtual $%016lX - $%016lX\n", L4_Address(virt_page), L4_Address(virt_page) + (L4_Size(virt_page) - 1)); notice(MEM_I_REJMAP "physical $%016lX - $%016lX\n", L4_Address(phys_page), L4_Address(phys_page) + (L4_Size(phys_page) - 1)); } else { notice(MEM_I_ACCMAP "accepting mapping\n"); notice(MEM_I_ACCMAP "virtual $%016lX - $%016lX\n", L4_Address(virt_page), L4_Address(virt_page) + (L4_Size(virt_page) - 1)); notice(MEM_I_ACCMAP "physical $%016lX - $%016lX\n", L4_Address(phys_page), L4_Address(phys_page) + (L4_Size(phys_page) - 1)); } } return; }
END_TEST /* L4_MutexControl Error codes (Create, Delete) ------------------------------------*/ /* \begin{test}{MUTEX0200} \TestDescription{Verify MutexControl does not overcreate a mutex} \TestFunctionalityTested{\Func{L4\_CreateMutex}} \TestImplementationProcess{ \begin{enumerate} \item Call \Func{L4\_CreateMutex} and check it returns successfully. \item Call \Func{L4\_CreateMutex} with the newly created mutex and check it returns an error. \end{enumerate} } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(MUTEX0200) { L4_MutexId_t mutex; L4_Word_t res; res = okl4_kmutexid_allocany(mutexid_pool, &mutex); fail_unless(res == OKL4_OK, "Failed to allocate any mutex id."); res = L4_CreateMutex(mutex); fail_unless(res == 1, "L4_CreateMutex() failed"); res = L4_CreateMutex(mutex); fail_unless(res == 0, "L4_CreateMutex() did not fail"); fail_unless(L4_ErrorCode() != L4_ErrMutexBusy, "Wrong error code"); }
END_TEST /* \begin{test}{MUTEX0201} \TestDescription{Verify MutexControl checks validity of mutex} \TestFunctionalityTested{\Func{L4\_DeleteMutex}} \TestImplementationProcess{ Call \Func{L4\_DeleteMutex} with the a non yet created mutex and checks it returns an error. } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(MUTEX0201) { L4_Word_t res; okl4_allocator_attr_t attr; L4_MutexId_t mutex; L4_Word_t id, end; okl4_kmutexid_getattribute(mutexid_pool, &attr); end = attr.base + attr.size; for (id = attr.base; id < end; id++) { mutex = L4_MutexId(id); if (!okl4_kmutexid_isallocated(mutexid_pool, mutex)) { break; } } fail_if(id == end, "No free mutex id left"); res = L4_DeleteMutex(mutex); fail_unless(res == 0, "L4_DeleteMutex() did not fail"); fail_unless(L4_ErrorCode() == L4_ErrInvalidMutex, "Wrong error code"); }
static int sync_ldt(struct task_struct *tsk, u32 entry_1, u32 entry_2, int index) { struct task_struct *p; struct mm_struct *mm; L4_Word_t dummy; p = tsk; mm = tsk->mm; do { L4_LoadMR(0, index); L4_LoadMR(1, entry_1); L4_LoadMR(2, entry_2); if (0 == L4_ExchangeRegisters( task_thread_info(p)->user_tid, L4_ExReg_Tls, 0, 0, 0, 0, L4_nilthread, &dummy, &dummy, &dummy, &dummy, &dummy)) { printk("OKLinux: ldtctrl() failed. errcode 0x%lx\n", L4_ErrorCode()); return -EINVAL; } } while ((p = next_thread(p)) != tsk); return 0; }
END_TEST /* \begin{test}{MUTEX0501} \TestDescription{Verify a non locked mutex can not be unlocked} \TestFunctionalityTested{\Func{L4\_Unlock}} \TestImplementationProcess{ Call \Func{L4\_Unlock} and check it returns an error. } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(MUTEX0501) { L4_MutexId_t mutex; L4_Word_t res; res = okl4_kmutexid_allocany(mutexid_pool, &mutex); fail_unless(res == OKL4_OK, "Failed to allocate any mutex id."); res = L4_CreateMutex(mutex); fail_unless(res == 1, "L4_CreateMutex() failed"); res = L4_Unlock(mutex); fail_unless(res == 0, "L4_Unlock() did not fail"); fail_unless(L4_ErrorCode() == L4_ErrMutexBusy, "Wrong error code"); L4_DeleteMutex(mutex); okl4_kmutexid_free(mutexid_pool, mutex); }
static void lock_mutex_thread(void) { L4_MsgTag_t tag; L4_Word_t label; L4_Word_t res; tag = L4_Receive(main_thread); while (1) { label = L4_Label(tag); if (label == 0xa) { res = L4_Lock(m); fail_unless(res == 1, "L4_Lock() failed"); L4_Unlock(m); } if (label == 0xb) { res = L4_TryLock(m); fail_unless(res == 0, "L4_TryLock() did not fail"); fail_unless(L4_ErrorCode() == L4_ErrMutexBusy, "Wrong error code"); } tag = L4_Call(main_thread); } L4_WaitForever(); }
static void ipc_teardown(struct bench_test *test, int args[]) { int r = 0; if (!fault_test) { /* Kill ping thread */ r = L4_ThreadControl (ping_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); if (r == 0) printf("thread control Error: %lx\n", L4_ErrorCode()); assert (r == 1); } if (!pagertimer) { /* Kill pong thread */ r = L4_ThreadControl (pong_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert (r == 1); } /* Delete ping space */ if (ping_space.raw != L4_nilspace.raw) { r = L4_SpaceControl(ping_space, L4_SpaceCtrl_delete, KBENCH_CLIST, L4_Nilpage, 0, NULL); assert (r == 1); okl4_kspaceid_free(spaceid_pool, ping_space); } /* Delete pong space */ if (pong_space.raw != L4_nilspace.raw) { r = L4_SpaceControl(pong_space, L4_SpaceCtrl_delete, KBENCH_CLIST, L4_Nilpage, 0, NULL); assert (r == 1); okl4_kspaceid_free(spaceid_pool, pong_space); } }
int _okl4_kspace_mapbyid(okl4_kspaceid_t kspaceid, okl4_kspace_map_attr_t *attr) { okl4_word_t pages_mapped; okl4_word_t total_pages; assert(attr != NULL); /* Calculate the number of pages we need to map. */ assert(attr->range->size % attr->page_size == 0); total_pages = attr->range->size / attr->page_size; /* Perform the mappings. */ for (pages_mapped = 0; pages_mapped < total_pages; pages_mapped++) { L4_MapItem_t map; okl4_word_t success; /* Setup the map item. */ L4_MapItem_Map(&map, attr->target->segment_id, attr->target->range.base + pages_mapped * attr->page_size, attr->range->base + pages_mapped * attr->page_size, pagesize_to_bits(attr->page_size), attr->attributes, attr->perms); /* Perform the map. */ success = L4_ProcessMapItem(kspaceid, map); if (!success) { return _okl4_convert_kernel_errno(L4_ErrorCode()); } } return OKL4_OK; }
/** * Dereferences a page. This just unmaps it in the L4 page table. * @param page */ static void dereference(page_queue_item* page) { if(L4_UnmapFpage(page->tid, L4_FpageLog2(page->virtual_address, PAGESIZE_LOG2)) == FALSE) { dprintf(0, "Can't unmap page at 0x%X (error:%d)\n", page->virtual_address, L4_ErrorCode()); } //L4_CacheFlushRange(page->tid, pager_table_lookup(page->tid, page->virtual_address)->address, pager_table_lookup(page->tid, page->virtual_address)->address+PAGESIZE); }
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; }
/** * Checks if a page has been referenced. This works by querying * the L4 pagetable. If the page is mapped in there we say it's * referenced. * @param page * @return 1 If page was referenced, 0 otherwise */ static L4_Bool_t is_referenced(page_queue_item* page) { L4_Fpage_t fpage = L4_FpageLog2(page->virtual_address, PAGESIZE_LOG2); L4_PhysDesc_t phys; if(L4_GetStatus(page->tid, &fpage, &phys) == FALSE) { dprintf(0, "Can't get status for page 0x%X (error:%d)\n", page->virtual_address, L4_ErrorCode()); } return L4_WasReferenced(fpage); }
static void create_delete_mutex_thread(void) { L4_MsgTag_t tag; L4_Word_t label; L4_Word_t res; tag = L4_Receive(main_thread); label = L4_Label(tag); if (label == 0xc) { res = L4_CreateMutex(m); fail_unless(res == 0, "L4_CreateMutex() did not fail"); fail_unless(L4_ErrorCode() == L4_ErrInvalidSpace, "Wrong error code on create"); } if (label == 0xd) { res = L4_DeleteMutex(m); fail_unless(res == 0, "L4_DeleteMutex() did not fail"); fail_unless(L4_ErrorCode() == L4_ErrInvalidSpace, "Wrong error code on delete"); } L4_Call(main_thread); L4_WaitForever(); }
static void sos_debug_flush(void) { L4_Msg_t msg; L4_MsgTag_t tag; L4_MsgClear(&msg); L4_Set_MsgLabel(&msg, TAG_SETSYSCALL(SOS_UNMAP_ALL)); L4_MsgLoad(&msg); tag = L4_Send(L4_Pager()); if (L4_IpcFailed(tag)) { L4_Word_t err = L4_ErrorCode(); printf("sos_debug_flush failed (error: %lx)\n", err); } }
__USER_TEXT void *pong_thread(void *arg) { L4_MsgTag_t tag; L4_Msg_t msg; while (1) { tag = L4_Receive_Timeout(threads[PING_THREAD], L4_TimePeriod(1000 * 1000)); L4_MsgStore(tag, &msg); if (!L4_IpcSucceeded(tag)) { printf("%p: recv ipc fails\n", L4_MyGlobalId()); printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode()); } } }
static void signal(void *unused, uintptr_t arg, struct pbuf *pbuf) { debug("Signal function called\n"); L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgLoad(&msg); L4_MsgTag_t tag = L4_Send((L4_ThreadId_t) arg); if (L4_IpcFailed(tag)) { L4_Word_t ec = L4_ErrorCode(); printf("%s: IPC error\n", __FUNCTION__); sos_print_error(ec); assert(!(ec & 1)); } call_pbuf = pbuf; }
/* * Init function to initialise the page table entries */ L4_Word_t pager_init(L4_Word_t low, L4_Word_t high) { //The frames have been used to set up page table entries as well page_table = (sos_PTE*) low; // Use a simple algaebric formula to calculate optimum size of page table for the // amount of memory available //new_low points to the memory to be used now, memory low -> new_low is the pagetable new_low = ((double)high*sizeof(sos_PTE)+PAGESIZE*(double)low)/ (double)(PAGESIZE+sizeof(sos_PTE)); // align it new_low = (new_low/PAGESIZE)*PAGESIZE + PAGESIZE; numPTE = (high-new_low)/PAGESIZE; printf("low: %lx new_low: %lx high: %lx numPTE: %d \n", low, new_low, high, numPTE); //printf("value of swap memory %p \n",swap_table); // initialize the empty page table. for (int i = 0; i < numPTE; i++) { page_table[i].tid = L4_nilthread; page_table[i].referenced = 0; page_table[i].dirty = 0; page_table[i].being_updated = 0; page_table[i].error_in_transfer = 0; page_table[i].pinned = 0; } for(int i=0;i<MAX_SWAP_ENTRIES;i++) { swap_table[i].tid = L4_nilthread; swap_table[i].offset = PTE_SENTINEL; //Initially all entries are free so each points to the next one in the table swap_table[i].next_free = i+1; } // add a guard page against stack overflows and let it map to 0 L4_Word_t guardPage = 0x7000000; L4_PhysDesc_t phys = L4_PhysDesc(0, L4_DefaultMemory); L4_Fpage_t targetFpage = L4_FpageLog2(guardPage, 12); L4_Set_Rights(&targetFpage, L4_Readable); if ( !L4_MapFpage(L4_Myself(), targetFpage, phys) ) { sos_print_error(L4_ErrorCode()); printf(" Can't map guard page\n"); } return new_low; }
__USER_TEXT void *pong_thread(void *arg) { L4_MsgTag_t tag; L4_Msg_t msg; while (1) { tag = L4_Receive_Timeout(threads[PING_THREAD], L4_TimePeriod(1000 * 1000)); L4_MsgStore(tag, &msg); if (!L4_IpcSucceeded(tag)) { printf("%p: recv ipc fails\n", L4_MyGlobalId()); printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode()); } /* FIXME: workaround solution to avoid scheduler starvation */ L4_Sleep(L4_TimePeriod(500 * 1000)); } }
__USER_TEXT void *ping_thread(void *arg) { L4_Msg_t msg; L4_MsgTag_t tag; L4_MsgClear(&msg); L4_MsgLoad(&msg); while (1) { tag = L4_Send_Timeout(threads[PONG_THREAD], L4_TimePeriod(1000 * 1000)); if (!L4_IpcSucceeded(tag)) { printf("%p: send ipc fails\n", L4_MyGlobalId()); printf("%p: ErrorCode = 0x%x\n", L4_MyGlobalId(), L4_ErrorCode()); } } }
static L4_ThreadId_t create_local_thread(char *desc, L4_KernelInterfacePage_t *kip, int idx, threadfunc_t func, L4_Word_t stack_size) { L4_Word_t utcb_size = L4_UtcbSize(kip); L4_Word_t my_utcb = L4_MyLocalId().raw; my_utcb = (my_utcb & ~(utcb_size - 1)); L4_ThreadId_t tid = L4_GlobalId(L4_ThreadNo(L4_Myself()) + idx, 1); L4_Word_t utcb_location = my_utcb + idx * utcb_size; if (FALSE == L4_ThreadControl(tid, L4_Myself(), L4_Myself(), L4_Pager(), (void *) utcb_location)) { printf("panic: can't execute %s: error code %d\n", desc, (int) L4_ErrorCode()); return L4_nilthread; } void *stack = kmalloc(stack_size); L4_Start_SpIp(tid, (L4_Word_t) stack + stack_size - 32, (L4_Word_t) func); return tid; }
int okl4_message_wait(void *recv_buff, okl4_word_t recv_buff_size, okl4_word_t *recv_bytes, okl4_kcap_t *reply_cap) { L4_MsgTag_t tag; L4_ThreadId_t from; okl4_word_t bytes_received; /* Ensure buffer is word-aligned. */ assert((okl4_word_t)recv_buff % sizeof(okl4_word_t) == 0); /* Perform the wait. */ L4_Set_NotifyMask(0); tag = L4_Wait(&from); if (!L4_IpcSucceeded(tag)) { return _okl4_message_errno(tag, L4_ErrorCode()); } /* Determine the number of words received, which is in the label. */ bytes_received = L4_Label(tag); /* Ensure that the number of bytes the message claims to contain is roughly * the same as the number of words we received. */ assert(ROUND_UP(bytes_received, sizeof(okl4_word_t)) == L4_UntypedWords(tag) * sizeof(okl4_word_t)); /* Copy to the buffer. */ _okl4_message_copy_mrs_to_buff(recv_buff, min(recv_buff_size, bytes_received)); /* Give parameters back to the caller. */ if (recv_bytes != NULL) { *recv_bytes = bytes_received; } if (reply_cap != NULL) { *reply_cap = from; } return OKL4_OK; }
static void utimer(void) { L4_KDB_SetThreadName(sos_my_tid(), "utimer"); L4_Accept(L4_UntypedWordsAcceptor); List *entryq; entryq = list_empty(); for (;;) { L4_Yield(); // Walk the timer list L4_Word_t now = L4_KDB_GetTick(); list_delete(entryq, processExpired, &now); // Wait for a new packet either blocking or non-blocking L4_MsgTag_t tag = L4_Niltag; if (list_null(entryq)) L4_Set_ReceiveBlock(&tag); else L4_Clear_ReceiveBlock(&tag); L4_ThreadId_t wait_tid = L4_nilthread; tag = L4_Ipc(L4_nilthread, L4_anythread, tag, &wait_tid); if (!L4_IpcFailed(tag)) { // Received a time out request queue it L4_Msg_t msg; L4_MsgStore(tag, &msg); // Get the message utimer_entry_t *entry = (utimer_entry_t *) L4_MsgWord(&msg, 0); entry->fTid = wait_tid; list_shift(entryq, entry); } else if (3 == L4_ErrorCode()) // Receive error # 1 continue; // no-partner - non-blocking else assert(!"Unhandled IPC error"); } }
END_TEST /* L4_Mutex Error codes (Lock, unlock) ------------------------------------------*/ /* \begin{test}{MUTEX0500} \TestDescription{Verify a non created mutex can not be locked} \TestFunctionalityTested{\Func{L4\_Lock}} \TestImplementationProcess{ Call \Func{L4\_Lock} and check it returns an error. } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(MUTEX0500) { L4_Word_t res; okl4_allocator_attr_t attr; L4_MutexId_t mutex; L4_Word_t id, end; okl4_kmutexid_getattribute(mutexid_pool, &attr); end = attr.base + attr.size; for (id = attr.base; id < end; id++) { mutex = L4_MutexId(id); if (!okl4_kmutexid_isallocated(mutexid_pool, mutex)) { break; } } fail_if(id == end, "No free mutex id left"); res = L4_Lock(mutex); fail_unless(res == 0, "L4_Lock() did not fail"); fail_unless(L4_ErrorCode() == L4_ErrInvalidMutex, "Wrong error code"); }
END_TEST /* \begin{test}{MUTEX0202} \TestDescription{Verify MutexControl handles an invalid mutex id} \TestFunctionalityTested{\Func{L4\_CreateMutex}} \TestImplementationProcess{ Call \Func{L4\_CreateMutex} with an invalid mutex id and check it returns an error. } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(MUTEX0202) { word_t res; L4_MutexId_t mutex = L4_MutexId(kernel_mutexid_base - 1); res = L4_CreateMutex(mutex); fail_unless(res == 0, "L4_CreateMutex() did not fail"); fail_unless(L4_ErrorCode() == L4_ErrInvalidMutex, "Wrong error code"); }
static void ipc_irq_setup(struct new_bench_test *test, int args[]) { int r; L4_Word_t utcb; L4_Word_t utcb_size; // L4_Word_t dummy; num_iterations = args[0]; handler_space = L4_nilspace; /* We need a maximum of two threads per task */ utcb_size = L4_GetUtcbSize(); #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb =(L4_Word_t)L4_GetUtcbBase() + utcb_size; #endif /* Create pager */ master_tid = KBENCH_SERVER; pager_tid.raw = KBENCH_SERVER.raw + 1; handler_tid.raw = KBENCH_SERVER.raw + 2; interrupt = PMU_IRQ; #if SPINNER spinner_tid = L4_GlobalId (L4_ThreadNo (master_tid) + 3, 2); #endif r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, master_tid, 0, (void*)utcb); if (r == 0 && (L4_ErrorCode() == 2)) { r = L4_ThreadControl (pager_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert(r == 1); r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, master_tid, 0, (void*)utcb); assert(r == 1); } L4_KDB_SetThreadName(pager_tid, "pager"); //L4_Schedule(pager_tid, -1, -1, 1, -1, -1, 0, &dummy, &dummy); L4_Set_Priority(pager_tid, 254); L4_Start_SpIp (pager_tid, (L4_Word_t) pager_stack + sizeof(pager_stack) - 32, START_ADDR (pager)); L4_Receive(pager_tid); #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb += utcb_size; #endif r = L4_ThreadControl(handler_tid, KBENCH_SPACE, master_tid, pager_tid, pager_tid, 0, (void *) utcb); assert(r == 1); L4_KDB_SetThreadName(handler_tid, "handler"); L4_Set_Priority(handler_tid, 100); // Startup notification, start handler thread //printf("register irq %ld, to %lx\n", interrupt, handler_tid.raw); L4_Word_t control = 0 | (0 << 6) | (31<<27); L4_LoadMR(0, interrupt); r = L4_InterruptControl(handler_tid, control); if (r == 0) { printf("Cannot register interrupt %lu\n", interrupt); } L4_Start_SpIp (handler_tid, (L4_Word_t) handler_stack + sizeof(handler_stack) - 32, START_ADDR(handler)); L4_Receive(handler_tid); #if SPINNER //Create spinner thread #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb += utcb_size; #endif r = L4_ThreadControl (spinner_tid, KBENCH_SPACE, master_tid, pager_tid, pager_tid, 0, (void*) utcb); if (r == 0) printf("create spinner failed %ld\n", L4_ErrorCode()); assert(r == 1); L4_KDB_SetThreadName(spinner_tid, "spinner"); //L4_Schedule(spinner_tid, -1, -1, 1, -1, -1, 0, &dummy, &dummy); //Set priority to the lowest. L4_Set_Priority(spinner_tid, 1); L4_Start_SpIp (spinner_tid, (L4_Word_t) spinner_stack + sizeof(spinner_stack) - 32, START_ADDR (spinner)); #endif }
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 thread_setup(struct thread *self, int _priority) { int ret = 1; int r; unsigned long r_l; struct pd *pd; unsigned long priority = 100; assert(self != NULL); pd = self->owner; /* Note: These don't allocate any resources */ #if defined(CONFIG_SESSION) session_p_list_init(&self->client_sessions); session_p_list_init(&self->server_sessions); #endif if (_priority != -1) { priority = (unsigned long)_priority; } self->magic = THREAD_MAGIC; #if defined(CONFIG_EAS) self->eas = NULL; #endif r = thread_alloc(self); /* Allocate a thread id, ALLOC #1 */ if (r != 0) { /* Can't allocate a new thread ID */ return 1; } /* Activate new thread */ { #ifdef NO_UTCB_RELOCATE self->utcb = (void *)-1UL; #endif r_l = thread_new(self, pd_l4_space(pd), self->id, IGUANA_SERVER, IGUANA_SERVER); if (r_l != 1) { if (L4_ErrorCode() == L4_ErrNoMem || L4_ErrorCode() == L4_ErrUtcbArea) { /* * L4 has run out of memory... this is probably very bad, but * we want to keep going for as long as we can */ goto thread_error_state; } else { ERROR_PRINT_L4; assert(!"This shouldn't happen"); } } else { ret = 0; } /* Set Priority */ r = L4_Set_Priority(self->id, priority); assert(r != 0); } return ret; thread_error_state: /* Here we clean up anything we have allocated */ thread_free(self->id); return 1; }
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(); }
/* * Function invoked by roottask on pagefault */ int pager(L4_ThreadId_t tid, L4_Msg_t *msgP) { send = 1; // Get the faulting address L4_Word_t addr = L4_MsgWord(msgP, 0); L4_Word_t physicalAddress = 0; L4_Word_t permission = 0; L4_MsgTag_t tag; // Alignment addr = (addr / PAGESIZE)*PAGESIZE; tag = L4_MsgMsgTag(msgP); L4_Word_t access_type = L4_Label(tag) & 0x07; //printf("pager invoked addr=%lx by %lx %lx for access 0x%lx\n", addr,L4_ThreadNo(tid),tid.raw,access_type); // Construct fpage IPC message L4_Fpage_t targetFpage = L4_FpageLog2(addr, 12); if(VIRTUAL(addr)) { if(addr >= BASE_CODE_SEGMENT_ADDRESS) { //Code segment int inPage = isInPage(tid,targetFpage); if(inPage == -1) { //It should be in page table so this should not happen printf("Panic !!! Cannot load the code segment"); } else { physicalAddress = new_low + inPage*PAGESIZE; permission = L4_FullyAccessible; } } else { //Heap and stack int inPage = isInPage(tid, targetFpage); if (inPage == -1) { //We need to check if the page is in swap inPage = isInSwap(tid,targetFpage); mapAddress(tid, targetFpage,inPage); //We dont need to map any addresses here as mapAddresses maps the addresses return send; } else { physicalAddress = new_low+inPage*PAGESIZE; targetFpage = page_table[inPage].pageNo; page_table[inPage].referenced = 1; if(access_type & L4_Writable) { //We now need to set the dirty bit and provide read write access page_table[inPage].dirty = 1; permission = L4_ReadWriteOnly; } else { permission = L4_Readable; } } } } else { // we need to map physical addresses 1:1 physicalAddress = addr; if(addr < new_low) { // This is beyond the low memory range ie the page table // and some other addresses which is below the low range permission = L4_FullyAccessible; } else { // This would be the code segment between the new_low and high permission = L4_Readable; } } L4_Set_Rights(&targetFpage,permission); L4_PhysDesc_t phys = L4_PhysDesc(physicalAddress, L4_DefaultMemory); if ( !L4_MapFpage(tid, targetFpage, phys) ) { sos_print_error(L4_ErrorCode()); printf(" Can't map page at %lx\n", addr); } return send; }
void device_server(void) { L4_ThreadId_t partner; L4_MsgTag_t msgtag; idl4_msgbuf_t msgbuf; long cnt; uintptr_t *size; partner = L4_nilthread; msgtag.raw = 0; cnt = 0; while (1) { /* * Now check async queues -- we check this everytime, which is a bit * silly, would be nice if we could detect a failed ipc to us */ size = cb_get(iguana_cb_handle, sizeof(uintptr_t)); if (size) { // uintptr_t *data = cb_get(iguana_cb_handle, *size); // DEBUG_PRINT("Got stuff: %" PRIdPTR "\n", *size); // DEBUG_PRINT("Got stuff: %" PRIxPTR " %" PRIxPTR "\n", data[0], // data[1]); } /* Wait for message */ idl4_msgbuf_sync(&msgbuf); idl4_reply_and_wait(&partner, &msgtag, &msgbuf, &cnt); if (idl4_is_error(&msgtag)) { DEBUG_PRINT("timer:device_server(%d) Error %" PRIxPTR " -- replying_to: %" PRIxPTR "\n", __LINE__, L4_ErrorCode(), partner.raw); partner = L4_nilthread; msgtag.raw = 0; cnt = 0; continue; } if (msgtag.X.label == IRQ_LABEL) { driver_interrupt(global_device, partner.global.X.thread_no); continue; } switch (magpie_get_interface_bigid(&msgbuf)) { case 37: idl4_process_request(&partner, &msgtag, &msgbuf, &cnt, device_vtable[idl4_get_function_id(&msgtag) & DEVICE_FID_MASK]); break; case 40: idl4_process_request(&partner, &msgtag, &msgbuf, &cnt, timer_server_vtable[idl4_get_function_id (&msgtag) & TIMER_SERVER_FID_MASK]); break; case 41: idl4_process_request(&partner, &msgtag, &msgbuf, &cnt, timer__vtable[idl4_get_function_id(&msgtag) & TIMER__FID_MASK]); break; default: DEBUG_PRINT("timer: device_server: Bad label! (0x%lx)\n", magpie_get_interface_bigid(&msgbuf)); partner = L4_nilthread; } } }