/* * Function ide_write (drive, sec, buf, length) * * Invokes an IPC to the IDE driver. The buffer is mapped read- * only to the driver, and the driver unmaps the buffer prior to * sending the reply IPC. * */ int ide_write(dword_t drive, dword_t sec, void *buf, dword_t length) { l4_msgdope_t result; dword_t dw0, dw1, dw2; l4_fpage_t fp; l4_idearg_t arg; int r; length = (length + L4_IDE_SECTOR_SIZE-1) & ~(L4_IDE_SECTOR_SIZE-1); arg.args.pos = sec; arg.args.length = length / L4_IDE_SECTOR_SIZE; arg.args.drive = drive; arg.args.write = 1; /* Create fpage that contains the buffer. */ dw0 = (dword_t) buf & PAGE_MASK; dw1 = ((dword_t) buf + length + PAGE_SIZE-1) & PAGE_MASK; for ( r = PAGE_BITS-1, dw2 = (dw1-dw0) >> PAGE_BITS; dw2 > 0; dw2 >>= 1, r++ ) {} fp = l4_fpage(dw0, r, 0, 0); r = l4_ipc_call(idedrv_id, (void *) 2, /* Map fpage */ (dword_t) buf, (dword_t) fp.fpage, (dword_t) arg.raw, (void *) 0, &dw0, &dw1, &dw2, L4_IPC_NEVER, &result); return r; }
static ssize_t onda_pwm_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { ssize_t status; l4_msgtag_t tag; l4_umword_t label; l4_cap_idx_t comm_cap; int value = 0; int ipc_error; mutex_lock(&sysfs_lock); comm_cap = l4re_get_env_cap("comm"); /* Get a free capability slot for the comm capability */ if (l4_is_invalid_cap(comm_cap)) { printk("Did not find an comm\n"); mutex_unlock(&sysfs_lock); return 0; } /* To an L4 IPC call, i.e. send a message to thread2 and wait for a * reply from thread2. The '1' in the msgtag denotes that we want to * transfer one word of our message registers (i.e. MR0). No timeout. */ if (sscanf(buf,"%d\n", &value) > 0) { l4_utcb_mr()->mr[0] = 0x67; l4_utcb_mr()->mr[1] = value; tag = l4_ipc_call(comm_cap, l4_utcb(), l4_msgtag(0x67, 2, 0, 0), L4_IPC_NEVER); } mutex_unlock(&sysfs_lock); return size; }
static l4_msgtag_t l4timer_stop_u(l4_cap_idx_t timer, l4_utcb_t *utcb) { l4_msg_regs_t *v = l4_utcb_mr_u(utcb); v->mr[0] = L4_TIMER_OP_STOP; return l4_ipc_call(timer, utcb, l4_msgtag(L4_PROTO_TIMER, 1, 0, 0), L4_IPC_NEVER); }
L4_CV void l4sigma0_debug_dump(l4_cap_idx_t pager) { l4_msgtag_t tag = l4_msgtag(L4_PROTO_SIGMA0, 1, 0, 0); l4_utcb_mr()->mr[0] = SIGMA0_REQ_DEBUG_DUMP; l4_ipc_call(pager, l4_utcb(), tag, L4_IPC_NEVER); }
/** * 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; }
static void alien_thread(void) { volatile l4_msgtag_t x; while (1) { x = l4_ipc_call(0x1234 << L4_CAP_SHIFT, l4_utcb(), l4_msgtag(0, 0, 0, 0), L4_IPC_NEVER); #ifdef MEASURE l4_sleep(0); #else l4_sleep(1000); outstring("An int3 -- you should see this\n"); outnstring("345", 3); #endif } }
static l4_msgtag_t l4timer_start_u(l4_cap_idx_t timer, unsigned flags, l4timer_time_t at, l4timer_time_t increment, l4_utcb_t *utcb) { int idx = 2; l4_msg_regs_t *v = l4_utcb_mr_u(utcb); v->mr[0] = L4_TIMER_OP_START; v->mr[1] = flags; *(l4timer_time_t *)(&v->mr[idx]) = at; idx += sizeof(l4timer_time_t) / sizeof(v->mr[0]); *(l4timer_time_t *)(&v->mr[idx]) = increment; idx += sizeof(l4timer_time_t) / sizeof(v->mr[0]); return l4_ipc_call(timer, utcb, l4_msgtag(L4_PROTO_TIMER, idx, 0, 0), L4_IPC_NEVER); }
static ssize_t onda_interval_show(struct device *dev, struct device_attribute *attr, char *buf) { ssize_t status; l4_msgtag_t tag; l4_umword_t label; l4_cap_idx_t comm_cap; int value = 0; int ipc_error; mutex_lock(&sysfs_lock); comm_cap = l4re_get_env_cap("comm"); /* Get a free capability slot for the comm capability */ if (l4_is_invalid_cap(comm_cap)) { printk("Did not find an comm\n"); mutex_unlock(&sysfs_lock); return 0; } /* To an L4 IPC call, i.e. send a message to thread2 and wait for a * reply from thread2. The '1' in the msgtag denotes that we want to * transfer one word of our message registers (i.e. MR0). No timeout. */ l4_utcb_mr()->mr[0] = 0x56; tag = l4_ipc_call(comm_cap, l4_utcb(), l4_msgtag(0x56, 1, 0, 0), L4_IPC_NEVER); /* Check for IPC error, if yes, print out the IPC error code, if not, * print the received result. */ ipc_error = l4_ipc_error(tag, l4_utcb()); if (ipc_error) { printk("IPC error: %x\n", ipc_error); return 0; buf[0] = '\n'; buf[1] = '\0'; status = 1; } else { value = (int)(l4_utcb_mr()->mr[0]); status = sprintf(buf, "%d\n", value); } mutex_unlock(&sysfs_lock); return status; }
static void touch_repeat(unsigned code, unsigned repeat) { l4_msgdope_t result; l4_umword_t dummy; int error; error = l4_ipc_call(btn_l4id, L4_IPC_SHORT_MSG, code, repeat, L4_IPC_SHORT_MSG, &dummy, &dummy, L4_IPC_SEND_TIMEOUT_0, &result); if (error) { key_pending = 1; key_code = code; key_repeat = repeat; } }
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 }