void thread_start(L4_ThreadId_t tid, L4_Word_t ip, char *cmdline, int npaths, char **paths, HpfCapability *caps) { list_t *li; L4_Word_t sp; mutex_lock(&thrlock); li = list_find(thread_list, &tid, sizeof(L4_ThreadId_t)); if (!li) { mutex_unlock(&thrlock); return; } sp = STACK_BASE - (THREAD_TYPE(li->data)->index * STACK_SIZE); sp -= thread_prepare_stack(THREAD_TYPE(li->data)->space, sp, cmdline, npaths, paths, caps); /* send "start" message */ L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgAppendWord(&msg, ip); L4_MsgAppendWord(&msg, sp); L4_Set_Propagation(&msg.tag); L4_Set_VirtualSender(THREAD_TYPE(li->data)->space->pager); L4_MsgLoad(&msg); L4_Send(tid); mutex_unlock(&thrlock); }
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_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 send_startup_ipc (L4_ThreadId_t tid, L4_Word_t ip, L4_Word_t sp) { L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgAppendWord(&msg, ip); L4_MsgAppendWord(&msg, sp); L4_MsgLoad(&msg); L4_Send(tid); }
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); } } }
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); }
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."); } }
int __USER_TEXT L4_Map(L4_ThreadId_t where, memptr_t base, size_t size) { L4_Msg_t msg; L4_Word_t page[2] = { (base & 0xFFFFFFC0) | 0xA, size & 0xFFFFFFC0 }; L4_MsgPut(&msg, 0, 0, NULL, 2, page); L4_MsgLoad(&msg); L4_Send(where); return 0; }
static void __USER_TEXT start_thread(L4_ThreadId_t t, L4_Word_t ip, L4_Word_t sp, L4_Word_t stack_size) { L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgAppendWord(&msg, ip); L4_MsgAppendWord(&msg, sp); L4_MsgAppendWord(&msg, stack_size); L4_MsgAppendWord(&msg, 0); L4_MsgAppendWord(&msg, 0); L4_MsgLoad(&msg); L4_Send(t); }
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; }
__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()); } } }
void session_add_buffer(struct session *session, void *call_buf, void *return_buf) { assert(session->call_buf == NULL); assert(session->return_buf == NULL); session->call_buf = call_buf; session->return_buf = return_buf; /* Now tell the server about this development */ { /* * Zero timeout ping -- FIXME: This should be handled by idl upcall * code, but do this later */ struct pd *other = session->server->owner; L4_Msg_t msg; uintptr_t *size; uintptr_t *addr; /* Now notify client and server prot domains */ size = cb_alloc(other->cba, sizeof(uintptr_t)); if (size == NULL) { ERROR_PRINT("Couldn't do upcall"); return; } *size = 3 * sizeof(uintptr_t); addr = cb_alloc(other->cba, *size); addr[0] = 0x38; addr[1] = (uintptr_t)call_buf; addr[2] = (uintptr_t)return_buf; cb_sync_alloc(other->cba); L4_MsgClear(&msg); L4_MsgLoad(&msg); (void)L4_Reply(other->threads.first->data.id); } }
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); } } }
/* * Callback function to nfs_write to swapfile, Issues a read from swap if necessary * Replies to the thread if only swapout need to be done and no swapin */ void pager_write_callback(uintptr_t token, int status, fattr_t *attr) { struct page_token *token_val = (struct page_token *) token; int pageIndex = token_val -> pageIndex; int swapIndex = token_val -> swapIndex; if(status != 0) { //Something bad happened so we cannot overwrite the page content, lets delay for //next page fault page_table[pageIndex].error_in_transfer = 1; } //Increment the bytes transferred for each callback page_table[pageIndex].write_bytes_transferred += NFS_WRITE_SIZE; //If all callbacks have been received without an error we have a successful write if(page_table[pageIndex].write_bytes_transferred == PAGESIZE) { if(!page_table[pageIndex].error_in_transfer) { //Update the swap table swap_table[swapIndex].tid = token_val -> source_tid; swap_table[swapIndex].pageNo = token_val -> source_page; //Check if swapin needs to be done if(token_val -> send_reply) { L4_PhysDesc_t phys = L4_PhysDesc(new_low + pageIndex * PAGESIZE, L4_DefaultMemory); L4_Set_Rights(&(token_val -> destination_page),L4_Readable); //Map the page to the new tid L4_MapFpage(token_val -> destination_tid, token_val -> destination_page,phys); //Update page table page_table[pageIndex].tid = token_val -> destination_tid; page_table[pageIndex].pageNo = token_val -> destination_page; page_table[pageIndex].referenced = 1; page_table[pageIndex].dirty = 0; } else { //There is a read coming up readFromSwap(token_val -> swapIndexToBeReadIn,pageIndex,1,token_val -> destination_tid,token_val -> destination_page); } } else { // If there is an error in transfer, currently we have nothing to do //Since this write was invalidated we undo the change swap_file_size -= PAGESIZE; //Undo the swap that was allocated swap_table[swapIndex].next_free = head_free_swap; head_free_swap = swapIndex; } //If there was an error in transfer (we dont issue swapin even if needed) or //there was no swapin after swapoff we reply to faulting tid if(token_val -> send_reply || page_table[pageIndex].error_in_transfer) { //We clear the error in transfer value and being updated since the work is done page_table[pageIndex].being_updated = page_table[pageIndex].error_in_transfer = 0; //Now send the reply message //Update the process table size update_process_table_size(token_val -> source_tid,0); L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgLoad(&msg); L4_Reply(token_val ->destination_tid); } } //Free up the token free(token_val); }
/* * Callback function to nfs_read from swapfile * Always replies to the thread */ void pager_read_callback(uintptr_t token,int status, fattr_t *attr, int bytes_read,char *data) { struct page_token *token_val = (struct page_token *) token; int pagetableIndex = token_val -> pageIndex; int byte_index = token_val -> chunk_index; int swapIndex = token_val -> swapIndex; if(status != 0) { page_table[pagetableIndex].error_in_transfer = 1; } else { //Copy the data read to memory char *memstart = (char *) (new_low + pagetableIndex * PAGESIZE + byte_index*NFS_READ_SIZE); memcpy(memstart,data,NFS_READ_SIZE); } page_table[pagetableIndex].read_bytes_transferred += NFS_READ_SIZE; //Check if all the callbacks have been received if(page_table[pagetableIndex].read_bytes_transferred == PAGESIZE) { if(page_table[pagetableIndex].error_in_transfer == 1) { //The memory in pagetable is inconsistent so the best thing would be to mark the //page table entry as unreferenced and hopefully its evicted soon //If this occurs for a free frame its best to free the frame //This condition is not required we would always want to free the frame(think and remove) if(!token_val -> writeToSwapIssued) { frame_free(new_low + pagetableIndex * PAGESIZE); } //Unmap the page table page whose memory we corrupted L4_UnmapFpage(page_table[pagetableIndex].tid,page_table[pagetableIndex].pageNo); page_table[pagetableIndex].tid = L4_nilthread; page_table[pagetableIndex].referenced = 0; page_table[pagetableIndex].dirty = 0; } else { //Free up the swap entry from which we read in swap_table[swapIndex].tid = L4_nilthread; swap_table[swapIndex].next_free = head_free_swap; head_free_swap = swapIndex; //Update page table page_table[pagetableIndex].tid = token_val -> destination_tid; page_table[pagetableIndex].pageNo = token_val -> destination_page; page_table[pagetableIndex].referenced = 1; page_table[pagetableIndex].dirty = 0; //Unmap the page which was written out if(token_val -> writeToSwapIssued) { L4_UnmapFpage(token_val -> source_tid,token_val -> source_page); } L4_Set_Rights(&(token_val -> destination_page),L4_Readable); L4_PhysDesc_t phys = L4_PhysDesc(new_low + pagetableIndex * PAGESIZE, L4_DefaultMemory); L4_MapFpage(token_val -> destination_tid, token_val -> destination_page, phys); L4_CacheFlushAll(); //Everything went fine } L4_Msg_t msg; L4_MsgClear(&msg); L4_MsgLoad(&msg); L4_Reply(token_val -> destination_tid); //Update the process table size update_process_table_size(token_val -> destination_tid,1); page_table[pagetableIndex].being_updated = page_table[pagetableIndex].error_in_transfer = 0; } free(token_val); }
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; }