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 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 */ }
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) { } }
static void c_thread(void) { again: printstr("c calling w...\n"); static char res[20], data[20] = "L4oskrnl.sys!"; L4_Call(5, 1, res, data); printstr("c got res="); printnstr(res, sizeof(res)); printstr("\n"); L4m_Pagger(2, 0, 0x60000000, 0x60000200); // ! L4m_Pagger(2, 1, 0x80000000, 0x90000000); // ! //(*(volatile int*)0x60000000) = 12; /*int x = (*(volatile int*)0x60000030); int y = (*(volatile int*)0x80000020); printstr("c got x="); printint(x); printstr(", y="); printint(y);*/ printstr("\nc got dat:\n=====\n"); static char dat[512]; memset(dat, 0, sizeof(dat)); memcpy(dat, (char*)0x60000000, sizeof(dat)); printnstr(dat, sizeof(dat)); /*memset(dat, 0, sizeof(dat)); memcpy(dat, (char*)0x60000000, sizeof(dat));*/ printstr("\n=====\n"); L4_Call1(0, 0xcafe); goto again; for (;;); panic("cc"); }
static void zone0150_thread1_routine(void) { L4_MsgTag_t result; L4_ThreadId_t thread0_tid; okl4_init_thread(); while (zone0150_children_can_run == 0) { /* spin */ } thread0_tid.raw = thread0_cap.raw; result = L4_Receive(thread0_tid); fail_unless(L4_IpcSucceeded(result) != 0, "thread1 L4_Receive() failed."); result = L4_Send(thread0_tid); fail_unless(L4_IpcSucceeded(result) != 0, "thread1 L4_Send() failed."); result = L4_Call(thread0_tid); fail_unless(L4_IpcSucceeded(result) != 0, "thread1 L4_Call() failed."); zone0150_child_thread_run++; L4_WaitForever(); }
static void run_copying_thread(L4_Word_t direction, int small_remote_buffer, int unmapped) { L4_MsgTag_t tag; memset(copying_thread_buffer, COPYING_THREAD_PATTERN, sizeof(copying_thread_buffer)); tag = L4_Niltag; L4_Set_MemoryCopy(&tag); L4_LoadMR(0, tag.raw); if (unmapped) { L4_LoadMR(1, (word_t)unmapped_address); } else { L4_LoadMR(1, (word_t)copying_thread_buffer); } if (small_remote_buffer) { L4_LoadMR(2, SMALL_BUFFER_SIZE); } else { L4_LoadMR(2, sizeof(copying_thread_buffer)); } L4_LoadMR(3, direction); tag = L4_Call(test_tid); assert(L4_IpcSucceeded(tag)); }
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 utimer_sleep(uint32_t microseconds) { utimer_entry_t entry = { L4_KDB_GetTick(), (uint32_t) US_TO_TICKS(microseconds)}; L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgAppendWord(&msg, (uintptr_t) &entry); L4_MsgLoad(&msg); L4_Call(utimer_tid); }
/* * The Philosopher thread tries to take the 2 chopsticks closest to him * (according to its number and the number of each chopstick) in order to eat. */ void philosopher(int argc, char **argv) { int left, right, first, second, mynum = 0; L4_Word_t me = L4_Myself().raw; L4_MsgTag_t tag = L4_Niltag; while (!libs_ready) ; if (argc) { mynum = atoi(argv[0]); } else { printf("(Philosopher 0x%lx) Error: Argument(s) missing!\n", me); L4_Set_MsgTag(L4_Niltag); L4_Send(dp_main); L4_Set_Label(&tag, 0xdead); L4_Set_MsgTag(tag); L4_Call(dp_main); } // Have to take chopsticks according to "my number" left = mynum; if (chopstick[mynum + 1]) { right = mynum + 1; } else { right = 0; } // This should allow to avoid deadlock when trying to grab the chopsticks. first = left < right ? left : right; second = first == left ? right : left; //printf("Philosopher %d: %lx, managed by %lx\n", mynum, me, dp_main.raw); //printf("Philosopher %d: chopsticks %d and %d\n", mynum, left, right); L4_Set_MsgTag(L4_Niltag); L4_Send(dp_main); while (meal_served == 0) ; okl4_libmutex_count_lock(chopstick[first]); //printf("Philosopher %d/%lx holds chopstick %d/%lx\n", mynum, me, first, chopstick[first]); okl4_libmutex_count_lock(chopstick[second]); //printf("Philosopher %d/%lx holds chopstick %d/%lx\n", mynum, me, second, chopstick[second]); //printf("Philosopher %d/%lx is eating\n", mynum, me); okl4_libmutex_count_unlock(chopstick[second]); okl4_libmutex_count_unlock(chopstick[first]); //printf("Philosopher %d: %lx/%lx finished eating\n", mynum, me, dp_main.raw); L4_Set_Label(&tag, 0xfed); L4_Set_MsgTag(tag); L4_Send(dp_main); L4_Send(L4_Myself()); }
void _fail_unless (int result, const char *file, int line, const char * msg, ...) { va_list ap; char buf[BUFSIZ]; /* Ensure a sane message was passed in. */ if (msg == NULL) { eprintf ("_fail_unless() called with NULL msg",__FILE__,__LINE__); msg = "(null)"; } /* If we passed the test, we need do nothing more. */ if (result) { return; } /* Unlike normal libcheck, we don't want to mark all the time, as it can * waste a lot of memory, so we only mark on failure */ send_loc_info (get_send_key(), file, line); va_start(ap,msg); vsnprintf(buf, BUFSIZ, msg, ap); va_end(ap); /* Display a failure message now, just in case we don't make it * until the end of the tests. */ printf("*** Failure: "); puts(buf); /* Send failure information to the test controller. */ send_failure_info(get_send_key(), buf); #if defined(OKL4_KERNEL_MICRO) /* Send failure message to our pager. */ if (cur_fork_status() == CK_WITHPAGER) { L4_MsgTag_t tag = L4_Niltag; /* Send a failure message to the test runner. A label of '1' indicates * failure. */ tag = L4_MsgTagAddLabel(tag, 1); L4_Set_MsgTag(tag); /* Inform the library, and wait for them to kill us. */ L4_Call(libcheck); L4_WaitForever(); } #endif }
static void synch_pong (void *arg) { L4_ThreadId_t caller; L4_MsgTag_t tag; VERBOSE_HIGH("Pong running\n"); while(pingpong_cleanup == 0) { tag = L4_Wait(&caller); pingpong_counter++; L4_LoadMR (0, 0); L4_Send(caller); } L4_Call(L4_Myself()); }
static void thread_simple_spinner_main (void) { int thrd_num = get_thread_num(L4_Myself()); clear_counters(5); thread_simple_spinner_start = 1; while(thread_simple_spinner_cleanup == 0) { if(counter[thrd_num]++ % 50000 == 0) { VERBOSE_HIGH("### %d %d\n", (int)thrd_num, (int)counter[thrd_num]); } if (counter[thrd_num] > 0x00100000) thread_simple_spinner_cleanup = 1; // done } L4_Call(L4_Myself()); }
static void thread_simple_spinner (void *arg) { int thrd_num = get_thread_num(L4_Myself()); int dummy; while(thread_simple_spinner_start == 0) ; while(thread_simple_spinner_cleanup == 0) { if(counter[thrd_num]++ % 50000 == 0) { VERBOSE_HIGH("### %d %d\n", (int)thrd_num, (int)counter[thrd_num]); } if (counter[thrd_num] > 0x00100000) dummy = 1; // done } L4_Call(L4_Myself()); }
/* * The highest priority thread blocks sending to medium thread in the * first scenario. It increments a counter on success. * It tries to acquire a mutex in the second scenario. It increments a counter on success. */ void mixed_pi_high(int argc, char **argv) { L4_MsgTag_t tag; while (!libs_ready) ; L4_Receive(pi_main); //printf("High thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { while (stop_spinning) ; if (scenario1) { L4_LoadMR(0, 0); tag = L4_Send(medium2_prio_thread); if (L4_IpcSucceeded(tag)) cnt_h++; } else if (scenario2) { //printf("High thread %lx/%lx acquiring mutex for resource, current holder: 0x%lx\n", me, pi_main.raw, resource_mutex->holder); okl4_libmutex_count_lock(resource_mutex); //printf("High thread %lx/%lx acquired mutex for resource\n", me, pi_main.raw); cnt_h++; } // If intermediate threads have run, then increment respective counter. if (flag1) cnt_i1++; if (flag3) cnt_i2++; if (scenario2) okl4_libmutex_count_unlock(resource_mutex); // Tell main thread iteration is done. L4_LoadMR(0, 0); L4_Call(pi_main); // Re-initialise. if (flag1) { L4_Receive_Nonblocking(medium1_prio_thread); flag1 = 0; } if (flag3) { L4_Receive_Nonblocking(medium3_prio_thread); flag3 = 0; } } }
static void synch_ping (void *arg) { L4_ThreadId_t partner; L4_MsgTag_t tag; VERBOSE_HIGH("Ping running\n"); /* XXX partner always thread 0 (created before us) */ partner = get_thread_id(0); while(pingpong_cleanup == 0) { L4_LoadMR (0, 0); L4_Send(partner); tag = L4_Wait(&partner); } L4_Call(L4_Myself()); }
END_TEST /* \begin{test}{MUTEX0402} \TestDescription{Verify L4_TryLock on a locked mutex} \TestFunctionalityTested{\Func{L4\_TryLock}} \TestImplementationProcess{ \begin{enumerate} \item Call \Func{L4\_CreateMutex} and check it returns successfully. \item Call \Func{L4\_Lock} and check it returns successfully. \item Create a thread. \item Thread calls L4\_TryLock on the held mutex. \item Check it returns an error. \end{enumerate} } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(MUTEX0402) { L4_ThreadId_t try_lock_thread; L4_MsgTag_t tag; L4_Word_t res; res = okl4_kmutexid_allocany(mutexid_pool, &m); fail_unless(res == OKL4_OK, "Failed to allocate any mutex id."); res = L4_CreateMutex(m); fail_unless(res == 1, "L4_CreateMutex() failed"); res = L4_Lock(m); fail_unless(res == 1, "L4_Lock() failed"); try_lock_thread = createThread(lock_mutex_thread); L4_Set_Label(&tag, 0xb); L4_Set_MsgTag(tag); L4_Call(try_lock_thread); L4_Unlock(m); L4_DeleteMutex(m); okl4_kmutexid_free(mutexid_pool, m); }
/* * Intermediate thread 1 has priority in between highest and medium thread. * Intermediate thread 2 has priority in between medium and lowest thread. * They set their flag each time they run during the PI test. */ void mixed_pi_intermediate(int argc, char **argv) { int num = 0; L4_ThreadId_t any_thread; L4_MsgTag_t tag = L4_Niltag; while (!libs_ready) ; if (argc) { num = atoi(argv[0]); } else { printf("(%s Intermediate Thread) Error: Argument(s) missing!\n", test_name); L4_Set_Label(&tag, 0xdead); L4_Set_MsgTag(tag); L4_Call(pi_main); } // Initialisation if (num == 1) { L4_Wait(&any_thread); L4_LoadMR(0, 0); L4_Send(pi_main); } else if (num == 2) { L4_Wait(&any_thread); while (L4_IsNilThread(medium2_prio_thread)) ; L4_LoadMR(0, 0); L4_Send(medium2_prio_thread); } L4_Yield(); // Thread is now ready to set the flag the next time it is run. while(1) { if (num == 1) { flag1 = 1; } else if (num == 2) { flag3 = 1; } L4_LoadMR(0, 0); L4_Send(high_prio_thread); } }
END_TEST /* \begin{test}{MUTEX0301} \TestDescription{Verify unprivileged thread can not delete mutex} \TestFunctionalityTested{\Func{L4\_DeleteMutex}} \TestImplementationProcess{ \begin{enumerate} \item Create a mutex. \item Create unprivileged thread. \item Unprivileged thread call \Func{L4\_DeleteMutex} with the created mutex. \item Checks \Func{L4\_DeleteMutex} returns an error. \end{enumerate} } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(MUTEX0301) { L4_ThreadId_t unpriv_thread; L4_MsgTag_t tag; L4_Word_t res; res = okl4_kmutexid_allocany(mutexid_pool, &m); fail_unless(res == OKL4_OK, "Failed to allocate any mutex id."); res = L4_CreateMutex(m); fail_unless(res == 1, "L4_CreateMutex() failed"); unpriv_thread = createThreadInSpace(L4_nilspace, create_delete_mutex_thread); L4_Set_Label(&tag, 0xd); L4_Set_MsgTag(tag); L4_Call(unpriv_thread); res = L4_DeleteMutex(m); fail_unless(res == 1, "L4_DeleteMutex() failed"); okl4_kmutexid_free(mutexid_pool, m); deleteThread(unpriv_thread); }
static void synch_recv (void *arg) { L4_ThreadId_t caller; L4_MsgTag_t tag; int i; int j=1000; while(pingpong_cleanup == 0) { tag = L4_Wait(&caller); pingpong_counter++; for (i=0; i < j; i++) ; j+=1000; if ((pingpong_counter % 50) == 0) { printf(" %d: %d\n", pingpong_counter, j); } } L4_Call(L4_Myself()); }
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(); }
/* * Get current value, request timeout for different threads, check all notified * correctly. */ static void test02(void) { uint32_t cur_value; L4_Word_t result, i; thread_ref_t thread1, thread2, thread3; L4_ThreadId_t tid1, tid2, tid3, any_thread; L4_Word_t notifybits1 = 0x1; L4_Word_t notifybits2 = 0x2; L4_Word_t notifybits3 = 0x3; L4_MsgTag_t tag; L4_Word_t label; printf("%s: ", __func__); thread1 = thread_create_simple(waiting_notify_thread, NULL, 99); thread2 = thread_create_simple(waiting_notify_thread, NULL, 99); thread3 = thread_create_simple(waiting_notify_thread, NULL, 99); tid1 = thread_l4tid(thread1); tid2 = thread_l4tid(thread2); tid3 = thread_l4tid(thread3); tag = L4_Make_MsgTag(notifybits1, 0); L4_Set_MsgTag(tag); tag = L4_Call(tid1); tag = L4_Make_MsgTag(notifybits2, 0); L4_Set_MsgTag(tag); tag = L4_Call(tid2); tag = L4_Make_MsgTag(notifybits3, 0); L4_Set_MsgTag(tag); tag = L4_Call(tid3); result = counter_current_value(&cur_value); if (result == 0) { FAILED(); return; } result = counter_request(cur_value + 10, tid1, notifybits1); if (result == 0) { FAILED(); return; } result = counter_request(cur_value + 12, tid2, notifybits2); if (result == 0) { FAILED(); return; } result = counter_request(cur_value + 14, tid3, notifybits3); if (result == 0) { FAILED(); return; } for (i = 0; i < 3; i++) { tag = L4_Wait(&any_thread); label = L4_Label(tag); if (((i == 0) && (label != 0x1)) || ((i == 1) && (label != 0x2)) || ((i == 2) && (label != 0x3))) { thread_delete(tid1); thread_delete(tid2); thread_delete(tid3); FAILED(); return; } } thread_delete(tid1); thread_delete(tid2); thread_delete(tid3); PASSED(); }
static void handler(void) { int i; L4_Word_t irq, control; irq = interrupt; //L4_MsgTag_t tag; L4_Call(master_tid); /* Accept interrupts */ L4_Accept(L4_NotifyMsgAcceptor); L4_Set_NotifyMask(~0UL); /* Handle interrupts */ for (i=0; i < num_iterations + 2; i++) { int k,j; struct counter **count; uint64_t cnt = 0; L4_Word_t mask; #if defined(CONFIG_CPU_ARM_XSCALE) || defined(CONFIG_CPU_ARM_ARM1136JS) || defined(CONFIG_CPU_ARM_ARM1176JZS) //Setup pmu irq L4_KDB_PMN_Write(REG_CCNT, 0xFF800000); //At least leave 0x100000 cycles L4_Word_t PMNC = L4_KDB_PMN_Read(REG_PMNC) & ~PMNC_CCNT_64DIV; L4_KDB_PMN_Write(REG_PMNC, (PMNC | PMNC_CCNT_OFL | PMNC_CCNT_ENABLE) & ~PMNC_CCNT_RESET); L4_KDB_PMN_Ofl_Write(REG_CCNT, ~0UL); #endif // ack/wait IRQ control = 0 | (3 << 6); L4_LoadMR(0, irq); (void)L4_InterruptControl(L4_nilthread, control); L4_StoreMR(1, &mask); irq = __L4_TCR_PlatformReserved(0); //tag.raw = 0x0000C000; //tag = L4_Ipc(from, thread_tid, tag, &from); //if (getTagE(tag)) // printf("ipc error %lx\n", L4_ErrorCode()); //printf("Receive irq ipc from %lx\n", from.raw); #if defined(CONFIG_CPU_ARM_XSCALE) || defined(CONFIG_CPU_ARM_ARM1136JS) || defined(CONFIG_CPU_ARM_ARM1176JZS) //Get CCNT count cnt = L4_KDB_PMN_Read(REG_CCNT); PMNC = L4_KDB_PMN_Read(REG_PMNC); assert(PMNC & ~PMNC_CCNT_OFL); //Since on ARM11, PMNC IRQ can only be deasserted when PMU is enabled, //need to clear overflow flag and disable IRQ before disable PMU. L4_KDB_PMN_Write(REG_PMNC, (PMNC | PMNC_CCNT_OFL) & ~PMNC_CCNT_ENIRQ); //Stop CCNT. L4_KDB_PMN_Write(REG_PMNC, PMNC & ~PMNC_CCNT_ENABLE); //printf("CNT is %016lld\n", cnt); #endif //Write result back. for (k = 0, count = irq_ipc_counters; *count != NULL; count++, k++) { for (j = 0; j < (*count)->get_num_counters(*count); j++) { results[k] += cnt; if ( i == 0 || i == 1) //we don't count the first 2 run, since they contain page fault and cache miss latency. results[k] -= cnt; } } } /* Tell master that we're finished */ L4_Set_MsgTag (L4_Niltag); L4_Send (master_tid); for (;;) L4_WaitForever(); /* NOTREACHED */ }
{ #if 0 diag("flushing %#lx:%#lx (dpos %d)", L4_Address(drop), L4_Size(drop), dpos); #endif L4_Set_Rights(&drop, L4_FullyAccessible); L4_FlushFpage(drop); } /* pass it on. */ L4_LoadBR(0, L4_CompleteAddressSpace.raw); L4_LoadMR(0, (L4_MsgTag_t){ .X.label = 0xffe0 | rwx, .X.u = 2 }.raw); L4_LoadMR(1, faddr); L4_LoadMR(2, fip); tag = L4_Call(L4_Pager()); if(L4_IpcFailed(tag)) { diag("drop-to-pager IPC failed, ec %lu", L4_ErrorCode()); muidl_raise_no_reply(); } else if(tag.X.t != 2 || tag.X.u != 0) { diag("drop-to-pager IPC returned weird tag %#lx", tag.raw); map->raw[0] = 0; map->raw[1] = 0; } else { /* AOK! */ L4_StoreMRs(1, 2, map->raw); } }
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; }