/* * Get current value, request timeout in the future for main thread, check * notified correctly. */ static void test01(void) { uint32_t cur_value; L4_Word_t result; L4_Word_t notifybits = 0x1; L4_MsgTag_t tag; L4_Word_t mask; printf("%s: ", __func__); result = counter_current_value(&cur_value); if (result == 0) { FAILED(); return; } result = counter_request(cur_value + 10, main_tid, notifybits); if (result == 0) { FAILED(); return; } L4_Set_NotifyMask(notifybits); L4_Accept(L4_NotifyMsgAcceptor); tag = L4_WaitNotify(&mask); if (L4_IpcFailed(tag)) { FAILED(); return; } PASSED(); }
static void waiting_notify_thread(void *arg) { L4_Word_t notifybits; L4_MsgTag_t tag; L4_Word_t mask; tag = L4_Receive(main_tid); notifybits = L4_Label(tag); L4_Set_NotifyMask(notifybits); L4_Accept(L4_NotifyMsgAcceptor); L4_LoadMR(0, 0); L4_Send(main_tid); tag = L4_WaitNotify(&mask); if (L4_IpcFailed(tag)) { FAILED(); return; } L4_Set_Label(&tag, notifybits); L4_Set_MsgTag(tag); L4_Call(main_tid); while (1) { } }
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; }
void thread_block(void) { L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgTag_t tag = L4_Receive(L4_Myself()); if (L4_IpcFailed(tag)) { printf("!!! thread_block: failed, tag=%lx\n", tag.raw); } }
/* * The medium thread tries to acquire a mutex, releases it once acquired and then * receives from highest priority thread in scenario 1. It increments 2 counters * on success, one for each operation. * It acquires a mutex at initialisation time and waits for any thread before * releasing the mutex in scenario 2. It increments 2 counters on success, * one for each operation. */ void mixed_pi_medium(int argc, char **argv) { L4_ThreadId_t any_thread, tid; L4_MsgTag_t tag; int counter = 10000; while (!libs_ready) ; while (L4_IsNilThread(medium1_prio_thread)) ; tid = medium1_prio_thread; //printf("Middle thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { // Initialisation if (scenario2) { //printf("Middle thread %lx/%lx acquires mutex for resource\n", me, pi_main.raw); okl4_libmutex_count_lock(resource_mutex); cnt_m1++; } //printf("(Initialisation) Medium thread %lx/%lx blocks open receiving\n", me, pi_main.raw); L4_Wait(&any_thread); //printf("(Initialisation) Medium thread %lx/%lx received from 0x%lx\n", me, pi_main.raw, any_thread.raw); L4_LoadMR(0, 0); L4_Send(tid); L4_Yield(); /*** Start test ***/ while (stop_spinning) ; wait_a_bit(counter); if (scenario1) { okl4_libmutex_count_lock(resource_mutex); cnt_m1++; wait_a_bit(counter); } else if (scenario2) { //printf("Middle thread %lx/%lx blocks open receiving\n", me, pi_main.raw); tag = L4_Wait(&any_thread); if (L4_IpcSucceeded(tag) && (any_thread.raw == low_prio_thread.raw)) cnt_m2++; wait_a_bit(counter); } okl4_libmutex_count_unlock(resource_mutex); if (!flag1 && (counter < LIMIT)) { counter *= 2; } if (scenario1) { cnt_m2++; tag = L4_Receive(high_prio_thread); if (L4_IpcFailed(tag)) cnt_m2--; } L4_Yield(); tid = pi_main; } }
// Block a thread forever static void thread_block(void) { L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgTag_t tag = L4_Receive(L4_Myself()); if (L4_IpcFailed(tag)) { printf("blocking thread failed: %lx\n", tag.raw); *(char *) 0 = 0; } }
void sos_debug_flush(void) { // Send a syscall to the root thread, which unmaps the user address space. L4_Msg_t msg; L4_MsgClear(&msg); L4_Set_MsgLabel(&msg, MAKETAG_SYSLAB(SOS_SYSCALL_UNMAP_USER_ADDRESS_SPACE)); L4_MsgLoad(&msg); L4_MsgTag_t tag = L4_Send(sSystemId); if (L4_IpcFailed(tag)) { printf("Error sending unmap address space syscall."); } }
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); } }
size_t sos_write(const void *vData, long int position, size_t count, void *handle) { size_t i; const char *realdata = vData; // send over serial for (i = 0; i < count; i++) L4_KDB_PrintChar(realdata[i]); // send to syscall in chunks of 5 words // so that we use all 6 ARM registers //for (i = position; i < count;) // well looks like this is not what position is for. for (i = 0; i < count;) // i incremented in the loop { L4_Msg_t msg; L4_MsgClear(&msg); L4_Set_MsgLabel(&msg, MAKETAG_SYSLAB(SOS_SYSCALL_SERIAL_SEND)); // add the words to the message for (int j = 0; j < WORDS_SENT_PER_IPC && i < count; j++) { // initialize to 0 so we send 0-chars if the message // is not word-padded L4_Word_t word = 0; // add bytes one by one char* writeTo = (char*) &word; for (int k = 0; k < sizeof(L4_Word_t) && i < count; k++) { *(writeTo++) = realdata[i++]; } L4_MsgAppendWord(&msg, word); } L4_MsgLoad(&msg); L4_MsgTag_t tag = L4_Send(sSystemId); if (L4_IpcFailed(tag)) { // FIXME: actually useful debug message L4_KDB_PrintChar('E'); L4_KDB_PrintChar('S'); L4_KDB_PrintChar('M'); break; } } return i; }
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; }
/* * The lowest priority thread acquires a mutex at initialisation time, releases * it the next it is run in scenario 1. It increments a counter on success. * It sends IPC to medium thread in scenario 2. It increments a counter on success. */ void mixed_pi_low(int argc, char **argv) { L4_ThreadId_t tid; L4_MsgTag_t tag; int counter = 10000; while (!libs_ready) ; while (L4_IsNilThread(medium3_prio_thread)) ; tid = medium3_prio_thread; //printf("Low thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { // Initalisation if (scenario1) { //printf("Low thread %lx/%lx acquires mutex for resource\n", me, pi_main.raw); okl4_libmutex_count_lock(resource_mutex); cnt_l++; } //printf("(Initialisation) Low thread %lx/%lx blocks sending to Medium thread\n", me, pi_main.raw); L4_LoadMR(0, 0); L4_Send(tid); //printf("(Initialisation) Low thread %lx/%lx sent to Medium thread\n", me, pi_main.raw); L4_Yield(); /*** Start test ***/ while (stop_spinning) ; wait_a_bit(counter); if (!flag1 && (counter < LIMIT)) { counter *= 2; } if (scenario1) { okl4_libmutex_count_unlock(resource_mutex); } else if (scenario2) { cnt_l++; //printf("Low thread %lx/%lx blocks sending to Medium thread\n", me, pi_main.raw); L4_LoadMR(0, 0); tag = L4_Send(medium2_prio_thread); if (L4_IpcFailed(tag)) cnt_l--; } L4_Yield(); tid = medium2_prio_thread; } }
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"); } }
/* poke/peek thread. obeys POKE, PEEK, and QUIT. */ static void poke_peek_fn(void *param_ptr) { #if 0 diag("%s: started as %lu:%lu. pager is %#lx", __func__, L4_ThreadNo(L4_MyGlobalId()), L4_Version(L4_MyGlobalId()), L4_Pager()); #endif for(;;) { L4_ThreadId_t from; L4_MsgTag_t tag = L4_Wait(&from); for(;;) { if(L4_IpcFailed(tag)) break; if(tag.X.label == QUIT_LABEL) { // diag("%s: quitting", __func__); return; } else if(tag.X.label == PEEK_LABEL) { L4_Word_t addr; L4_StoreMR(1, &addr); L4_LoadMR(0, (L4_MsgTag_t){ .X.u = 1 }.raw); L4_LoadMR(1, *(uint8_t *)addr); } else if(tag.X.label == POKE_LABEL) {
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; }