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; }
static void pager (void) { L4_ThreadId_t tid; L4_MsgTag_t tag; L4_Msg_t msg; L4_Send(master_tid); for (;;) { tag = L4_Wait(&tid); for (;;) { L4_Word_t faddr, fip; L4_MsgStore(tag, &msg); if (L4_UntypedWords (tag) != 2 || !L4_IpcSucceeded (tag)) { printf ("Malformed pagefault IPC from %p (tag=%p)\n", (void *) tid.raw, (void *) tag.raw); L4_KDB_Enter ("malformed pf"); break; } faddr = L4_MsgWord(&msg, 0); fip = L4_MsgWord (&msg, 1); L4_MsgClear(&msg); { L4_MapItem_t map; L4_SpaceId_t space; L4_Word_t seg, offset, cache, rwx, size; int r; seg = get_seg(KBENCH_SPACE, faddr, &offset, &cache, &rwx); assert(seg != ~0UL); size = L4_GetMinPageBits(); faddr &= ~((1ul << size)-1); offset &= ~((1ul << size)-1); space.raw = __L4_TCR_SenderSpace(); L4_MapItem_Map(&map, seg, offset, faddr, size, cache, rwx); r = L4_ProcessMapItem(space, map); assert(r == 1); } L4_MsgLoad(&msg); // tag = L4_ReplyWait (tid, &tid); tag = L4_MsgTag(); L4_Set_SendBlock(&tag); L4_Set_ReceiveBlock(&tag); tag = L4_Ipc(tid, L4_anythread, tag, &tid); } } }
__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()); } } }
__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)); } }
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"); } }
static void pager (void) { L4_ThreadId_t tid; L4_MsgTag_t tag; L4_Msg_t msg; int count = 0; for (;;) { tag = L4_Wait(&tid); for (;;) { L4_Word_t faddr, fip; L4_MsgStore(tag, &msg); if (L4_Label(tag) == START_LABEL) { // Startup notification, start ping and pong thread void (*start_addr)(void); void (*pong_start_addr)(void); L4_Word_t *pong_stack_addr = pong_stack; if (pagertimer) { start_addr = ping_thread_pager; } else if (pagertimer_simulated) { start_addr = ping_thread_simulated; } else if (fass_buffer) { start_addr = ping_thread_buffer; } else if (fault_test) { count = 0; start_addr = NULL; } else if (intra_close) { start_addr = ping_thread_close; } else if (intra_open) { start_addr = ping_thread_open; } else if (intra_rpc) { start_addr = ping_thread_rpc_server; } else if (intra_ovh) { start_addr = ping_thread_ovh; } else if (intra_async) { start_addr = ping_thread_async; } else if (intra_async_ovh) { start_addr = ping_thread_async_ovh; } else { start_addr = ping_thread; } if (start_addr != NULL) { /*printf("ping_start_addr: %lx ping_stack_addr: %lx\n", START_ADDR (start_addr), (L4_Word_t) ping_stack);*/ send_startup_ipc (ping_tid, START_ADDR(start_addr), (L4_Word_t) ping_stack + sizeof (ping_stack) - 32); L4_ThreadSwitch(ping_tid); } if (fass_buffer) { pong_start_addr = pong_thread_buffer; pong_stack_addr = pong_stack_fass; } else if (fass) { pong_start_addr = pong_thread_fass; pong_stack_addr = pong_stack_fass; } else if (fault_test) { pong_stack_addr = pong_stack_fass; pong_start_addr = pong_thread_faulter; } else if (intra_close) { pong_start_addr = pong_thread_close; } else if (intra_open) { pong_start_addr = pong_thread_open; } else if (intra_rpc) { pong_start_addr = pong_thread_close; } else if (intra_ovh) { pong_start_addr = pong_thread_ovh; } else if (intra_async) { pong_start_addr = pong_thread_async; } else if (intra_async_ovh) { pong_start_addr = pong_thread_async_ovh; } else { pong_start_addr = pong_thread; } if (!pagertimer) { /*printf("pong_start_addr: %lx pong_stack_addr: %lx\n", START_ADDR (pong_start_addr), (L4_Word_t) pong_stack_addr);*/ L4_Set_Priority(ping_tid, 100); L4_Set_Priority(pong_tid, 99); send_startup_ipc (pong_tid, START_ADDR (pong_start_addr), (L4_Word_t) pong_stack_addr + sizeof (ping_stack) - 32); } break; } if (L4_UntypedWords (tag) != 2 || !L4_IpcSucceeded (tag)) { printf ("pingpong: malformed pagefault IPC from %p (tag=%p)\n", (void *) tid.raw, (void *) tag.raw); L4_KDB_Enter ("malformed pf"); break; } faddr = L4_MsgWord(&msg, 0); fip = L4_MsgWord (&msg, 1); L4_MsgClear(&msg); if (fault_test && (faddr == (uintptr_t) fault_area)) { if (count < num_iterations) { count++; } else { /* Tell master that we're finished */ L4_Set_MsgTag (L4_Niltag); L4_Send (master_tid); break; } } else { L4_MapItem_t map; L4_SpaceId_t space; L4_Word_t seg, offset, cache, rwx, size; int r; seg = get_seg(KBENCH_SPACE, faddr, &offset, &cache, &rwx); //if can not find mapping, must be page fault test, //just map any valid address, since fault address is dummy. if (seg == ~0UL) seg = get_seg(KBENCH_SPACE, (L4_Word_t) fault_area, &offset, &cache, &rwx); if (tid.raw == ping_th.raw) space = ping_space; else if (tid.raw == pong_th.raw) { if (pong_space.raw != L4_nilspace.raw) space = pong_space; else //pong_space is not created, only ping_space is used. space = ping_space; } else space = KBENCH_SPACE; size = L4_GetMinPageBits(); faddr &= ~((1ul << size)-1); offset &= ~((1ul << size)-1); L4_MapItem_Map(&map, seg, offset, faddr, size, cache, rwx); r = L4_ProcessMapItem(space, map); assert(r == 1); } L4_MsgLoad(&msg); tag = L4_ReplyWait (tid, &tid); } } }
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; }