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(); }
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; }
/* 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); } } }
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); }
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); }
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(); }
/* 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 /*? me.interface.name ?*/_send(void *p, unsigned int len, ip_addr_t addr) { seL4_SetMR(0, len); seL4_SetMR(1, addr.addr); if (len > 4096) { len = 4096; } memcpy(/*? me.interface.name?*/_buf, p, len); seL4_Call(/*? ep ?*/, seL4_MessageInfo_new(0, 0, 0, 2)); return len; }
int /*? me.interface.name ?*/_send(void *p, unsigned int len, uint32_t addr) { seL4_SetMR(0, len); seL4_SetMR(1, addr); if (len > MAX_UDP_PACKET) { len = MAX_UDP_PACKET; } memcpy(/*? me.interface.name?*/_buf, p, len); seL4_Call(/*? ep ?*/, seL4_MessageInfo_new(0, 0, 0, 2)); return len; }
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); }
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 (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); }
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; }
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; }
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); } } }
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); }
// 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); }
long sys_brk(va_list ap) { //printf("sysbrk\n"); uintptr_t newbrk = va_arg(ap, uintptr_t); //printf("newbrk before = %d\n",newbrk); seL4_MessageInfo_t tag = seL4_MessageInfo_new(seL4_NoFault, 0, 0, 2); seL4_SetTag(tag); seL4_SetMR(0, SOS_SYSCALL_SYSBRK); seL4_SetMR(1, newbrk); seL4_MessageInfo_t message = seL4_Call(SYSCALL_ENDPOINT_SLOT, tag); newbrk = seL4_MessageInfo_get_label(message); //printf("newbrk result = %d\n",newbrk); return newbrk; }
/** * 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); }
int start_ta(char *ta_name){ seL4_Word msg; int arg_len = strlen(ta_name); seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 2+arg_len); seL4_SetTag(tag); seL4_SetMR(0, START_TA_CMD); printf("client-os: Calling TEE-CONTAINER to start TA \n"); seL4_Word *ptr = (seL4_Word*)ta_name; for(int i=0;i < arg_len;++i){ seL4_SetMR(i+2,*ptr); ptr++; } ptr = ta_name; seL4_SetMR(1,arg_len); seL4_Call(TEE_EP_CPTR,tag); msg = seL4_GetMR(0); return msg; }
int getdirent (int pos, char *path, size_t nbyte) { 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; } msg = seL4_MessageInfo_new (0, 0, 1, 4); 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); memset (share->buf, 0, PAPAYA_IPC_PAGE_SIZE); strcpy (share->buf, cwd); seL4_SetMR (0, VFS_LISTDIR); seL4_SetMR (1, share->id); seL4_SetMR (2, pos); seL4_SetMR (3, nbyte); seL4_Call (vfs_ep, msg); int read = seL4_GetMR (0); if (read >= 0) { memcpy (path, share->buf, nbyte); pawpaw_share_unmount (share); return read; } else { pawpaw_share_unmount (share); return -1; } }
uint32_t rpc_marshall(uint32_t cur_mr, const char *str, uint32_t slen) { assert(str); if (slen == 0) { return cur_mr; } int i; for (i = 0; i < ROUND_DOWN(slen, 4); i+=4, str+=4) { seL4_SetMR(cur_mr++, *(seL4_Word*) str); } if (i != slen) { seL4_Word w = 0; memcpy(&w, str, slen - i); seL4_SetMR(cur_mr++, w); } return cur_mr; }
/* 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); }
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; } }
/** Performs the IPC register setup for a write() call to the server. * * The Server's ABI for the write() request has changed a little: the server * now returns the number of bytes it wrote out to the serial in a msg-reg, * aside from also returning an error code in the "label" of the header. * * @param conn Initialized connection token returned by * serial_server_client_connect(). * @param len length of the data in the buffer. * @param server_nbytes_written The value the server reports that it actually * wrote to the serial device. * @return 0 on success, or integer error value on error. */ static ssize_t serial_server_write_ipc_invoke(serial_client_context_t *conn, ssize_t len) { seL4_MessageInfo_t tag; seL4_SetMR(SSMSGREG_FUNC, FUNC_WRITE_REQ); seL4_SetMR(SSMSGREG_WRITE_REQ_BUFF_LEN, len); tag = seL4_MessageInfo_new(0, 0, 0, SSMSGREG_WRITE_REQ_END); tag = seL4_Call(conn->badged_server_ep_cspath.capPtr, tag); if (seL4_GetMR(SSMSGREG_FUNC) != FUNC_WRITE_ACK) { ZF_LOGE(SERSERVC"printf: Reply message was not a WRITE_ACK as " "expected."); return - seL4_IllegalOperation; } if (seL4_MessageInfo_get_label(tag) != 0) { return - seL4_MessageInfo_get_label(tag); } return seL4_GetMR(SSMSGREG_WRITE_ACK_N_BYTES_WRITTEN); }
void init(){ printf("client-os: client os has started\n"); seL4_Word sender_badge; seL4_MessageInfo_t tag; seL4_Word msg,func_id; printf("client-os:receiver...........\n"); tag = seL4_Recv(TEE_EP_CPTR,&sender_badge); msg = seL4_GetMR(0); printf("client-os: msg = %d \n",msg ); seL4_SetMR(0,3221); seL4_ReplyRecv(TEE_EP_CPTR,tag,&sender_badge); }
/* 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 int call_func(seL4_CPtr ep, seL4_Word msg, volatile seL4_Word *done, seL4_Word arg3) { seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 1); /* Send the given message once. */ seL4_SetMR(0, msg); tag = seL4_Call(ep, tag); test_check(seL4_MessageInfo_get_length(tag) == 1); test_check(seL4_GetMR(0) == ~msg); *done = 0; /* Send the given message again - should (eventually) fault this time. */ seL4_SetMR(0, msg); tag = seL4_Call(ep, tag); /* The call should fail. */ test_check(seL4_MessageInfo_get_label(tag) == seL4_InvalidCapability); *done = 1; return sel4test_get_result(); }
int write(fildes_t file, const 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; } memcpy (fh->share->buf, buf, nbyte); 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_WRITE); seL4_SetMR (1, fh->share->id); seL4_SetMR (2, nbyte); seL4_Call (fh->cap, msg); int wrote = seL4_GetMR (0); return wrote; }
void rpc_init(const char* name_str, int32_t label) { _rpc_label = label; _rpc_name = name_str; rpc_reset_contents(NULL); if (!_rpc_recv_cslot) { rpc_setup_recv(REFOS_THREAD_CAP_RECV); } else if (seL4_MessageInfo_get_extraCaps(_rpc_minfo) > 0) { // Flush recieving path of previous recieved caps. seL4_CNode_Delete(REFOS_CSPACE, _rpc_recv_cslot, REFOS_CDEPTH); } seL4_SetMR(0, label); }