int /*? me.interface.name ?*/__run(void) { seL4_Word fault_type; seL4_Word length; seL4_MessageInfo_t info; seL4_Word args[4]; seL4_Word reply_cap = /*? reply_cap_slot ?*/; while (1) { /* Wait for fault */ info = seL4_Recv(/*? ep ?*/, &gdb_state.current_thread_tcb); /* Get the relevant registers */ fault_type = seL4_MessageInfo_get_label(info); length = seL4_MessageInfo_get_length(info); for (int i = 0; i < length; i++) { args[i] = seL4_GetMR(i); } gdb_state.current_pc = args[0]; ZF_LOGD("------------------------------"); ZF_LOGD("Received fault for tcb %zu", gdb_state.current_thread_tcb); ZF_LOGD("Stopped at %zx", gdb_state.current_pc); ZF_LOGD("Length: %zu", length); // Save the reply cap seL4_CNode_SaveCaller(/*? cnode ?*/, reply_cap, 32); gdb_state.stop_reason = find_stop_reason(fault_type, args); gdb_state.current_thread_step_mode = false; /* Send fault message to gdb client */ gdb_handle_fault(&gdb_state); /* Wait for gdb client to deal with fault */ int UNUSED error = b_wait(); /* Reply to the fault ep to restart the thread. We look inside the gdb_state struct to interpret how to restart the thread. */ if (gdb_state.stop_reason == stop_step && gdb_state.current_thread_step_mode==false) { /* If this was a Debug Exception, then we respond with a bp_num and the number of instruction to step Since we're going to continue, we set MR0 to 0 */ info = seL4_MessageInfo_new(0, 0, 0, 1); seL4_SetMR(0, 0); seL4_Send(reply_cap, info); } else if (gdb_state.stop_reason == stop_none) { /* If this was a fault, set the instruction pointer to what we expect it to be */ info = seL4_MessageInfo_new(0, 0, 0, 1); seL4_SetMR(0, gdb_state.current_pc); seL4_Send(reply_cap, info); } else { ZF_LOGD("Responding to some other debug exception %d", gdb_state.stop_reason); seL4_Signal(reply_cap); } } UNREACHABLE(); }
pid_t my_id(void) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 1); seL4_SetMR (0, SYSCALL_PROCESS_GETPID); seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
int /*? me.interface.name ?*/__run(void) { // Make connection to gdb seL4_Word delegate_tcb; seL4_UserContext regs; while (1) { seL4_Recv(/*? mem_ep ?*/, &delegate_tcb); seL4_TCB_ReadRegisters(delegate_tcb, false, 0, sizeof(seL4_UserContext) / sizeof(seL4_Word), ®s); // Check eax is 0 so that we know they were checking memory // TODO Add a check on pc to see if they were in the mem check function if (regs.eax == 0) { // Signal to the delegate the memory is invalid regs.eax = 1; // Increment past the faulting instruction regs.eip += 2; // Write registers back seL4_TCB_WriteRegisters(delegate_tcb, false, 0, sizeof(seL4_UserContext) / sizeof(seL4_Word), ®s); // Resume the caller seL4_MessageInfo_t info = seL4_MessageInfo_new(0, 0, 0, 1); seL4_SetMR(0, regs.eip); seL4_Reply(info); } } }
/* IRQ handler thread. Wait on a notification object for IRQs. When one arrives, send a * synchronous message to the registered endpoint. If no synchronous endpoint was * registered, call the appropriate handler function directly (must be thread safe) */ static void _irq_thread_entry(struct irq_server_thread* st) { seL4_CPtr sep; seL4_CPtr notification; uintptr_t node_ptr; seL4_Word label; sep = st->delivery_sep; notification = st->node->notification; node_ptr = (uintptr_t)st->node; label = st->label; DIRQSERVER("thread started. Waiting on endpoint %d\n", notification); while (1) { seL4_Word badge; seL4_Wait(notification, &badge); assert(badge != 0); if (sep != seL4_CapNull) { /* Synchronous endpoint registered. Send IPC */ seL4_MessageInfo_t info = seL4_MessageInfo_new(label, 0, 0, 2); seL4_SetMR(0, badge); seL4_SetMR(1, node_ptr); seL4_Send(sep, info); } else { /* No synchronous endpoint. Call the handler directly */ irq_server_node_handle_irq(st->node, badge); } } }
int read (fildes_t file, char *buf, size_t nbyte) { if (nbyte >= (1 << 12)) { return -1; /* FIXME: crappy limitation */ } struct sos_fhandle* fh = sos_lookup_fhandle (file); if (!fh) { return -1; } seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, pawpaw_share_attach (fh->share), 3); //seL4_SetCap (0, fh->share->cap); seL4_SetMR (0, VFS_READ); seL4_SetMR (1, fh->share->id); seL4_SetMR (2, nbyte); seL4_Call (fh->cap, msg); int read = seL4_GetMR (0); if (read > 0) { memcpy (buf, fh->share->buf, read); } return read; }
int call_func_ta(int ta_num,int func_id,int simp_arg,void *data,size_t size,seL4_Word *res){ int length = size/(double)sizeof(seL4_Word); if((length+5) > seL4_MsgMaxLength){ printf("Params too large. operation failed\n"); return -1; }else{ seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 5+length); seL4_SetTag(tag); seL4_SetMR(0, CALL_FUNC_CMD); seL4_SetMR(1, ta_num); seL4_SetMR(2,func_id); seL4_SetMR(3,simp_arg); seL4_SetMR(4,length); seL4_Word* blockptr = (seL4_Word*)data; for(int i =0; i < length;++i){ seL4_SetMR(i+5,*blockptr); blockptr++; } seL4_Call(TEE_EP_CPTR,tag); int res_val = seL4_GetMR(0); if(res != NULL){ int len = seL4_GetMR(1); for(int i =0; i < len;++i){ res[i] = seL4_GetMR(i+2); } } return res_val; } }
static int ipc_caller(seL4_Word ep0, seL4_Word ep1, seL4_Word word_bits, seL4_Word arg4) { /* Let our parent know we are ready. */ seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 1); seL4_SetMR(0, READY_MAGIC); seL4_Send(ep0, tag); /* * The parent has changed our cspace on us. Check that it makes sense. * * Basically the entire cspace should be empty except for the cap at ep0. * We should still test that various points in the cspace resolve correctly. */ /* Check that none of the typical endpoints are valid. */ for (unsigned long i = 0; i < word_bits; i++) { seL4_MessageInfo_ptr_new(&tag, 0, 0, 0, 0); tag = seL4_Call(i, tag); test_assert(seL4_MessageInfo_get_label(tag) == seL4_InvalidCapability); } /* Check that changing one bit still gives an invalid cap. */ for (unsigned long i = 0; i < word_bits; i++) { seL4_MessageInfo_ptr_new(&tag, 0, 0, 0, 0); tag = seL4_Call(ep1 ^ BIT(i), tag); test_assert(seL4_MessageInfo_get_label(tag) == seL4_InvalidCapability); } /* And we're done. This should be a valid cap and get us out of here! */ seL4_MessageInfo_ptr_new(&tag, 0, 0, 0, 1); seL4_SetMR(0, SUCCESS_MAGIC); seL4_Send(ep1, tag); return sel4test_get_result(); }
// Block a thread forever // we do this by making an unimplemented system call. static void thread_block(void){ seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 1); seL4_SetTag(tag); seL4_SetMR(0, 100); seL4_Call(SYSCALL_ENDPOINT_SLOT, tag); }
void replyFromKernel_success_empty(tcb_t *thread) { setRegister(thread, badgeRegister, 0); setRegister(thread, msgInfoRegister, wordFromMessageInfo( seL4_MessageInfo_new(0, 0, 0, 0))); }
int process_delete(pid_t pid) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 2); seL4_SetMR (0, SYSCALL_PROCESS_DESTROY); seL4_SetMR (1, pid); seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
/** * Signal that a thrd has finished */ static void signal_thrd_finished(seL4_CPtr local_endpoint, int val) { seL4_MessageInfo_t info = seL4_MessageInfo_new(0, 0, 0, 1); seL4_SetMR(0, val); seL4_Call(local_endpoint, info); assert(0); while (1); }
pid_t process_wait(pid_t pid) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 2); seL4_SetMR (0, SYSCALL_PROCESS_WAIT); seL4_SetMR (1, pid); seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
/* sends: * vaddr in process address space of processes buffer (should do map-in-out) * maximum number to place in buffer */ int process_status(process_t *processes, unsigned max) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 3); seL4_SetMR (0, SYSCALL_PROCESS_SEND_STATUS); seL4_SetMR (1, (seL4_Word)processes); seL4_SetMR (2, max); seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
int rpc_call_server() { seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, _rpc_cp, _rpc_mr); int ept = rpc_get_endpoint(_rpc_label); _rpc_minfo = seL4_Call(ept, tag); rpc_reset_contents(NULL); return 0; }
int syscall_alloc_cnodes (struct pawpaw_event* evt) { evt->reply = seL4_MessageInfo_new (0, 0, 0, 2); seL4_CPtr root_cptr = 0; seL4_SetMR (1, thread_cspace_new_cnodes (current_thread, evt->args[0], &root_cptr)); seL4_SetMR (0, root_cptr); /* root_cptr depends on above; don't reorder */ return PAWPAW_EVENT_NEEDS_REPLY; }
pid_t process_create_args_env (const char* path, const char* argv[], const int argc, const char* envv[], const int envc) { seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 3); seL4_SetMR (0, SYSCALL_PROCESS_CREATE); seL4_SetMR (1, (seL4_Word)path); seL4_SetMR (2, (seL4_Word)argv); char* seL4_SetMR (3, argc + envc) seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
static int bouncer_func(seL4_CPtr ep, seL4_Word arg1, seL4_Word arg2, seL4_Word arg3) { seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 0); seL4_Word sender_badge; seL4_Recv(ep, &sender_badge); while (1) { seL4_ReplyRecv(ep, tag, &sender_badge); } return 0; }
void replyFromKernel_error(tcb_t *thread) { word_t len; word_t *ipcBuffer; ipcBuffer = lookupIPCBuffer(true, thread); setRegister(thread, badgeRegister, 0); len = setMRs_syscall_error(thread, ipcBuffer); setRegister(thread, msgInfoRegister, wordFromMessageInfo( seL4_MessageInfo_new(current_syscall_error.type, 0, 0, len))); }
/* override abort, called by exit (and assert fail) */ void abort(void) { /* send back a failure */ seL4_MessageInfo_t info = seL4_MessageInfo_new(seL4_NoFault, 0, 0, 1); seL4_SetMR(0, -1); seL4_Send(endpoint, info); /* we should not get here */ assert(0); while (1); }
void rpc_sv_reply(void* cl) { if (rpc_sv_skip_reply(cl)) return; seL4_CPtr reply_endpoint = rpc_sv_get_reply_endpoint(cl); seL4_MessageInfo_t reply = seL4_MessageInfo_new(0, 0, _rpc_cp, _rpc_mr); if (reply_endpoint) { seL4_Send(reply_endpoint, reply); } else { seL4_Reply(reply); } }
pid_t process_create_args (const char* path, const char* argv[]) { #endif seL4_MessageInfo_t msg = seL4_MessageInfo_new (0, 0, 0, 3); seL4_SetMR (0, SYSCALL_PROCESS_CREATE); seL4_SetMR (1, (seL4_Word)path); seL4_SetMR (2, strlen (path)); //seL4_SetMR (2, (seL4_Word)argv); //seL4_SetMR (3, ) seL4_Call (PAPAYA_SYSCALL_SLOT, msg); return seL4_GetMR (0); }
void doFaultTransfer(word_t badge, tcb_t *sender, tcb_t *receiver, word_t *receiverIPCBuffer) { word_t sent; seL4_MessageInfo_t msgInfo; sent = setMRs_fault(sender, receiver, receiverIPCBuffer); msgInfo = seL4_MessageInfo_new( fault_get_faultType(sender->tcbFault), 0, 0, sent); setRegister(receiver, msgInfoRegister, wordFromMessageInfo(msgInfo)); setRegister(receiver, badgeRegister, badge); }
int syscall_bind_async_tcb (struct pawpaw_event* evt) { evt->reply = seL4_MessageInfo_new (0, 0, 0, 1); seL4_CPtr our_cap = cspace_copy_cap (cur_cspace, current_thread->croot, evt->args[0], seL4_AllRights); if (!our_cap) { seL4_SetMR (0, 0); } else { seL4_SetMR (0, seL4_TCB_BindAEP (current_thread->tcb_cap, our_cap)); } return PAWPAW_EVENT_NEEDS_REPLY; }
/* * Test threads at all possible priorities, and that they get scheduled in the * correct order. */ static int prio_test_func(seL4_Word my_prio, seL4_Word* last_prio, seL4_CPtr ep) { test_check(*last_prio - 1 == my_prio); *last_prio = my_prio; /* Unsuspend the top thread if we are the last one. */ if (my_prio == MIN_PRIO) { seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 0); seL4_Send(ep, tag); } return 0; }
void ffiseL4_Send(unsigned char *c, long clen, unsigned char *a, long alen) { seL4_CPtr ep; int offset = 1; memcpy(&ep, a + offset, sizeof(ep)); offset += sizeof(ep); seL4_Word len; memcpy(&len, a + offset, sizeof(len)); offset += sizeof(len); memcpy(&seL4_GetIPCBuffer()->msg[0], a + offset, len); seL4_Send( ep, seL4_MessageInfo_new(0, 0, 0, ROUND_UP_UNSAFE(len, sizeof(seL4_Word)) / sizeof(seL4_Word))); a[0] = FFI_SUCCESS; }
/* map the init data into the process, and send the address via ipc */ static void * send_init_data(env_t env, seL4_CPtr endpoint, sel4utils_process_t *process) { /* map the cap into remote vspace */ void *remote_vaddr = vspace_map_pages(&process->vspace, &env->init_frame_cap_copy, NULL, seL4_AllRights, 1, PAGE_BITS_4K, 1); assert(remote_vaddr != 0); /* now send a message telling the process what address the data is at */ seL4_MessageInfo_t info = seL4_MessageInfo_new(seL4_NoFault, 0, 0, 1); seL4_SetMR(0, (seL4_Word) remote_vaddr); seL4_Send(endpoint, info); return remote_vaddr; }
static exception_t performPageGetAddress(void *vbase_ptr) { paddr_t capFBasePtr; /* Get the physical address of this frame. */ capFBasePtr = pptr_to_paddr(vbase_ptr); /* return it in the first message register */ setRegister(ksCurThread, msgRegisters[0], capFBasePtr); setRegister(ksCurThread, msgInfoRegister, wordFromMessageInfo(seL4_MessageInfo_new(0, 0, 0, 1))); return EXCEPTION_NONE; }
static inline seL4_Word fault_handler_start(seL4_CPtr ep, seL4_CPtr done_ep, seL4_CPtr reply) { seL4_Word ip; /* signal driver to convert us to passive and block */ if (config_set(CONFIG_KERNEL_RT)) { api_nbsend_recv(done_ep, seL4_MessageInfo_new(0, 0, 0, 0), ep, NULL, reply); ip = seL4_GetMR(0); } else { /* wait for first fault */ seL4_RecvWith1MR(ep, &ip, reply); } return ip; }
static int ep_test_func(seL4_CPtr sync_ep, seL4_CPtr test_ep, volatile seL4_Word *status, seL4_Word arg4) { seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 0); seL4_Word sender_badge; while (1) { seL4_Recv(sync_ep, &sender_badge); /* Hit up the test end point */ seL4_MessageInfo_t reply = seL4_Call(test_ep, tag); /* See what the status was */ *status = !!(seL4_MessageInfo_get_label(reply) != seL4_InvalidCapability); /* Reply */ seL4_Reply(tag); } return sel4test_get_result(); }
int stat (const char *path, stat_t *buf) { seL4_MessageInfo_t msg; if (!vfs_ep) { vfs_ep = pawpaw_service_lookup ("svc_vfs"); } struct pawpaw_share* share = pawpaw_share_new (); if (!share) { return -1; } memset (share->buf, 0, PAPAYA_IPC_PAGE_SIZE); if (path && path[0] != '/') { strcpy (share->buf, cwd); int cwdlen = strlen (cwd); if (cwdlen > 0 && cwd[cwdlen - 1] != '/') { strcat (share->buf, "/"); } strcat (share->buf, path); /* XXX: check if buffer overflows */ } else { strcpy (share->buf, path); } msg = seL4_MessageInfo_new (0, 0, 1, 2); seL4_CPtr recv_cap = pawpaw_cspace_alloc_slot (); if (!recv_cap) { pawpaw_share_unmount (share); return -1; } seL4_SetCapReceivePath (PAPAYA_ROOT_CNODE_SLOT, recv_cap, PAPAYA_CSPACE_DEPTH); seL4_SetCap (0, share->cap); seL4_SetMR (0, VFS_STAT); seL4_SetMR (1, share->id); seL4_Call (vfs_ep, msg); int status = seL4_GetMR (0); if (status == 0) { memcpy (buf, share->buf, sizeof (stat_t)); } pawpaw_share_unmount (share); return status; }