int main(void) { l4re_env_t *env = l4re_env(); // get environment l4_msg_regs_t *mr = l4_utcb_mr(); // get msg regs char *str = "Hello, world!\n"; const int str_length = 15; mr->mr[0] = L4_VCON_WRITE_OP; mr->mr[1] = str_length; memcpy(&mr->mr[2], str, str_length); l4_msgtag_t tag, ret; tag = l4_msgtag(L4_PROTO_LOG, // long label (protocol) 6, // unsigned words 0, // unsigned items 0); // unsigned flags ret = l4_ipc_send(env->log, // l4_cap_idx_t dest l4_utcb(), // l4_utcb_t *utcb tag, // l4_msgtag_t tag L4_IPC_SEND_TIMEOUT_0); // l4_timeout_t timeout if (l4_msgtag_has_error(ret)) fprintf(stderr, "Error in message tag.\n"); }
/** * Map RAM. * * \param pager pager implementing Sigma0 protocol * \return #0 on success * -#L4SIGMA0_NOTALIGNED phys, virt, or size not aligned * -#L4SIGMA0_IPCERROR IPC error * -#L4SIGMA0_NOFPAGE no fpage received */ L4_CV int l4sigma0_map_mem(l4_cap_idx_t pager, l4_addr_t phys, l4_addr_t virt, l4_addr_t size) { l4_addr_t d = L4_SUPERPAGESIZE; unsigned l = L4_LOG2_SUPERPAGESIZE; l4_msgtag_t tag; int error; l4_utcb_t *utcb = l4_utcb(); if ((phys & (d-1)) || (size & (d-1)) || (virt & (d-1))) { l = L4_LOG2_PAGESIZE; d = L4_PAGESIZE; } if ((phys & (d-1)) || (size & (d-1)) || (virt & (d-1))) return -L4SIGMA0_NOTALIGNED; for (; size>0; phys+=d, size-=d, virt+=d) { do { l4_msg_regs_t *m = l4_utcb_mr_u(utcb); l4_buf_regs_t *b = l4_utcb_br_u(utcb); tag = l4_msgtag(L4_PROTO_SIGMA0, 2, 0, 0); m->mr[0] = SIGMA0_REQ_FPAGE_RAM; m->mr[1] = l4_fpage(phys, l, L4_FPAGE_RWX).raw; b->bdr = 0; b->br[0] = L4_ITEM_MAP; b->br[1] = l4_fpage(virt, l, L4_FPAGE_RWX).raw; tag = l4_ipc_call(pager, utcb, tag, L4_IPC_NEVER); if (l4_msgtag_has_error(tag)) error = l4_utcb_tcr_u(utcb)->error; else error = 0; } while (error == L4_IPC_SECANCELED || error == L4_IPC_SEABORTED); if (error) return -L4SIGMA0_IPCERROR; if (l4_msgtag_items(tag) < 1) return -L4SIGMA0_NOFPAGE; } return 0; }
int main(void) { l4_msgtag_t tag; #ifdef MEASURE l4_cpu_time_t s, e; #endif l4_utcb_t *u = l4_utcb(); l4_exc_regs_t exc; l4_umword_t mr0, mr1; printf("Alien feature testing\n"); l4_debugger_set_object_name(l4re_env()->main_thread, "alientest"); /* Start alien thread */ if (l4_is_invalid_cap(alien = l4re_util_cap_alloc())) return 1; l4_touch_rw(alien_thread_stack, sizeof(alien_thread_stack)); tag = l4_factory_create_thread(l4re_env()->factory, alien); if (l4_error(tag)) return 1; l4_debugger_set_object_name(alien, "alienth"); l4_thread_control_start(); l4_thread_control_pager(l4re_env()->main_thread); l4_thread_control_exc_handler(l4re_env()->main_thread); l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb, L4RE_THIS_TASK_CAP); l4_thread_control_alien(1); tag = l4_thread_control_commit(alien); if (l4_error(tag)) return 2; tag = l4_thread_ex_regs(alien, (l4_umword_t)alien_thread, (l4_umword_t)alien_thread_stack + sizeof(alien_thread_stack), 0); if (l4_error(tag)) return 3; l4_sched_param_t sp = l4_sched_param(1, 0); tag = l4_scheduler_run_thread(l4re_env()->scheduler, alien, &sp); if (l4_error(tag)) return 4; #ifdef MEASURE l4_calibrate_tsc(l4re_kip()); #endif /* Pager/Exception loop */ if (l4_msgtag_has_error(tag = l4_ipc_receive(alien, u, L4_IPC_NEVER))) { printf("l4_ipc_receive failed"); return 1; } memcpy(&exc, l4_utcb_exc(), sizeof(exc)); mr0 = l4_utcb_mr()->mr[0]; mr1 = l4_utcb_mr()->mr[1]; for (;;) { #ifdef MEASURE s = l4_rdtsc(); #endif if (l4_msgtag_is_exception(tag)) { #ifndef MEASURE printf("PC=%08lx SP=%08lx Err=%08lx Trap=%lx, %s syscall, SC-Nr: %lx\n", l4_utcb_exc_pc(&exc), exc.sp, exc.err, exc.trapno, (exc.err & 4) ? " after" : "before", exc.err >> 3); #endif tag = l4_msgtag((exc.err & 4) ? 0 : L4_PROTO_ALLOW_SYSCALL, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0); } else printf("Umm, non-handled request (like PF): %lx %lx\n", mr0, mr1); memcpy(l4_utcb_exc(), &exc, sizeof(exc)); /* Reply and wait */ if (l4_msgtag_has_error(tag = l4_ipc_call(alien, u, tag, L4_IPC_NEVER))) { printf("l4_ipc_call failed\n"); return 1; } memcpy(&exc, l4_utcb_exc(), sizeof(exc)); mr0 = l4_utcb_mr()->mr[0]; mr1 = l4_utcb_mr()->mr[1]; #ifdef MEASURE e = l4_rdtsc(); printf("time %lld\n", l4_tsc_to_ns(e - s)); #endif }
/* Our main function */ int main(void) { /* Get a capability slot for our new thread. */ l4_cap_idx_t t1 = l4re_util_cap_alloc(); l4_utcb_t *u = l4_utcb(); l4_exc_regs_t *e = l4_utcb_exc_u(u); l4_msgtag_t tag; int err; extern char _start[], _end[], _etext[]; if (l4_is_invalid_cap(t1)) return 1; /* Prevent pagefaults of our new thread because we do not want to * implement a pager as well. */ l4_touch_ro(_start, _end - _start + 1); l4_touch_rw(_etext, _end - _etext); /* Create the thread using our default factory */ tag = l4_factory_create_thread(l4re_env()->factory, t1); if (l4_msgtag_has_error(tag)) return 1; /* Setup the thread by setting the pager and task. */ l4_thread_control_start(); l4_thread_control_pager(l4re_env()->main_thread); l4_thread_control_exc_handler(l4re_env()->main_thread); l4_thread_control_bind((l4_utcb_t *)l4re_env()->first_free_utcb, L4RE_THIS_TASK_CAP); tag = l4_thread_control_commit(t1); if (l4_msgtag_has_error(tag)) return 2; /* Start the thread by finally setting instruction and stack pointer */ tag = l4_thread_ex_regs(t1, (l4_umword_t)thread, (l4_umword_t)thread_stack + sizeof(thread_stack), L4_THREAD_EX_REGS_TRIGGER_EXCEPTION); if (l4_msgtag_has_error(tag)) return 3; /* Receive initial exception from just started thread */ tag = l4_ipc_receive(t1, u, L4_IPC_NEVER); if ((err = l4_ipc_error(tag, u))) { printf("Umm, ipc error: %x\n", err); return 1; } /* We expect an exception IPC */ if (!l4_msgtag_is_exception(tag)) { printf("PF?: %lx %lx (not prepared to handle this) %ld\n", l4_utcb_mr_u(u)->mr[0], l4_utcb_mr_u(u)->mr[1], l4_msgtag_label(tag)); return 1; } /* Fill out the complete register set of the new thread */ e->ip = (l4_umword_t)thread; e->sp = (l4_umword_t)(thread_stack + sizeof(thread_stack)); e->eax = 1; e->ebx = 4; e->ecx = 2; e->edx = 3; e->esi = 6; e->edi = 7; e->ebp = 5; /* Send a complete exception */ tag = l4_msgtag(0, L4_UTCB_EXCEPTION_REGS_SIZE, 0, 0); /* Send reply and start the thread with the defined CPU register set */ tag = l4_ipc_send(t1, u, tag, L4_IPC_NEVER); if ((err = l4_ipc_error(tag, u))) printf("Error sending IPC: %x\n", err); /* Idle around */ while (1) l4_sleep(10000); return 0; }