static void timer_set_mode(enum clock_event_mode mode, struct clock_event_device *clk) { const l4timer_time_t increment = 1000000 / HZ; int r; switch (mode) { case CLOCK_EVT_MODE_SHUTDOWN: case CLOCK_EVT_MODE_ONESHOT: r = L4XV_FN_i(l4_error(l4timer_stop(timer_srv))); if (r) printk(KERN_WARNING "l4timer: stop failed (%d)\n", r); while (L4XV_FN_i(l4_ipc_error(l4_irq_receive(timer_irq_cap, L4_IPC_BOTH_TIMEOUT_0), l4_utcb())) != L4_IPC_RETIMEOUT) ; break; case CLOCK_EVT_MODE_PERIODIC: case CLOCK_EVT_MODE_RESUME: r = L4XV_FN_i(l4_error(l4timer_start(timer_srv, 0, l4lx_kinfo->clock, increment))); if (r) printk(KERN_WARNING "l4timer: start failed (%d)\n", r); break; case CLOCK_EVT_MODE_UNUSED: break; default: printk("l4timer_set_mode: Unknown mode %d\n", mode); break; } }
static void L4_CV timer_thread(void *data) { l4_timeout_t to; l4_utcb_t *u = l4_utcb(); l4_cap_idx_t irq_cap = *(l4_cap_idx_t *)data; l4_msgtag_t t; l4_umword_t l; l4_msg_regs_t *v = l4_utcb_mr_u(u); l4timer_time_t increment = 0; l4_cpu_time_t next_to = 0; enum { idx_at = 2, idx_increment = idx_at + sizeof(l4timer_time_t) / sizeof(v->mr[0]), }; to = L4_IPC_NEVER; t = l4_ipc_wait(u, &l, to); while (1) { int reply = 1; int r = 0; if (l4_ipc_error(t, u) == L4_IPC_RETIMEOUT) { if (l4_error(l4_irq_trigger_u(irq_cap, u)) != -1) LOG_printf("IRQ timer trigger failed\n"); if (increment) { next_to += increment; to = l4_timeout(L4_IPC_TIMEOUT_0, l4_timeout_abs_u(next_to, 1, u)); } else to = L4_IPC_NEVER; reply = 0; } else if (l4_error(t) == L4_PROTO_TIMER) { switch (v->mr[0]) { case L4_TIMER_OP_START: next_to = *(l4timer_time_t *)&v->mr[idx_at]; to = l4_timeout(L4_IPC_TIMEOUT_0, l4_timeout_abs_u(next_to, 1, u)); increment = *(l4timer_time_t *)&v->mr[idx_increment]; r = 0; break; case L4_TIMER_OP_STOP: to = L4_IPC_NEVER; increment = 0; r = 0; break; default: LOG_printf("l4timer: invalid opcode\n"); r = -ENOSYS; break; }; } else LOG_printf("l4timer: msg r=%ld\n", l4_error(t)); t = l4_msgtag(r, 0, 0, 0); if (reply) t = l4_ipc_reply_and_wait(u, t, &l, to); else t = l4_ipc_wait(u, &l, to); } }
static l4_msgtag_t l4timer_start(l4_cap_idx_t timer, unsigned flags, l4timer_time_t at, l4timer_time_t increment) { return l4timer_start_u(timer, flags, at, increment, l4_utcb()); }
static l4_msgtag_t l4timer_stop(l4_cap_idx_t timer) { return l4timer_stop_u(timer, l4_utcb()); }
int copy_thread(unsigned long clone_flags, unsigned long sp, unsigned long stack_size___used_for_inkernel_process_flag, struct task_struct *p, struct pt_regs *regs) { struct pt_regs *childregs; struct task_struct *tsk = current; int err; #ifdef CONFIG_L4_VCPU asmlinkage void ret_from_fork(void); p->thread.regsp = task_pt_regs_v(p); #endif childregs = task_pt_regs(p); *childregs = *regs; childregs->ax = 0; childregs->sp = sp; childregs->flags |= 0x200; /* sanity: set EI flag */ childregs->flags &= 0x1ffff; #ifdef CONFIG_L4_VCPU p->thread.sp = (unsigned long) childregs; p->thread.sp0 = (unsigned long) (childregs+0); p->thread.sp -= sizeof(long); *(unsigned long *)p->thread.sp = 0; p->thread.sp -= sizeof(long); *(unsigned long *)p->thread.sp = (unsigned long)&ret_from_fork; #endif //p->thread.ip = (unsigned long) ret_from_fork; //task_user_gs(p) = get_user_gs(regs); p->fpu_counter = 0; p->thread.io_bitmap_ptr = NULL; tsk = current; err = -ENOMEM; /* Copy segment registers */ p->thread.gs = tsk->thread.gs; memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps)); if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) { p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr, IO_BITMAP_BYTES, GFP_KERNEL); if (!p->thread.io_bitmap_ptr) { p->thread.io_bitmap_max = 0; return -ENOMEM; } set_tsk_thread_flag(p, TIF_IO_BITMAP); } err = 0; /* * Set a new TLS for the child thread? */ if (clone_flags & CLONE_SETTLS) err = do_set_thread_area(p, -1, (struct user_desc __user *)childregs->si, 0); if (err && p->thread.io_bitmap_ptr) { kfree(p->thread.io_bitmap_ptr); p->thread.io_bitmap_max = 0; } #ifndef CONFIG_L4_VCPU /* create the user task */ if (!err) { l4x_stack_set(p->stack, l4_utcb()); err = l4x_thread_create(p, clone_flags, stack_size___used_for_inkernel_process_flag == COPY_THREAD_STACK_SIZE___FLAG_INKERNEL); } #endif return err; }
void leaveMeasurement() const{ l4_utcb_t * utcb = l4_utcb(); _lock.enter(); if(--_measuring[utcb] == 0) _measuring.erase(utcb); _lock.leave(); }
void leaveExclusive() const{ l4_utcb_t * utcb = l4_utcb(); _lock.enter(); if(--_locked[utcb] == 0) _locked.erase(utcb); _lock.leave(); }
/* 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; printf("Example showing how to start a thread with an exception.\n"); /* We do not want to implement a pager here, take the shortcut. */ printf("Make sure to start this program with ldr-flags=eager_map\n"); if (l4_is_invalid_cap(t1)) return 1; /* Create the thread using our default factory */ tag = l4_factory_create_thread(l4re_env()->factory, t1); if (l4_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_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_error(tag)) return 3; l4_sched_param_t sp = l4_sched_param(1, 0); tag = l4_scheduler_run_thread(l4re_env()->scheduler, t1, &sp); if (l4_error(tag)) return 4; /* 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->sp = (l4_umword_t)(thread_stack + sizeof(thread_stack)); #ifdef ARCH_x86 e->ip = (l4_umword_t)thread; e->eax = 1; e->ebx = 4; e->ecx = 2; e->edx = 3; e->esi = 6; e->edi = 7; e->ebp = 5; #endif #ifdef ARCH_arm e->pc = (l4_umword_t)thread; e->r[0] = 0; e->r[1] = 1; e->r[2] = 2; e->r[3] = 3; e->r[4] = 4; e->r[5] = 5; e->r[6] = 6; e->r[7] = 7; #endif /* 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; }
/* 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[], _sdata[]; 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, _sdata - _start + 1); l4_touch_rw(_sdata, _end - _sdata); /* Create the thread using our default factory */ tag = l4_factory_create_thread(l4re_env()->factory, t1); if (l4_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_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_error(tag)) return 3; l4_sched_param_t sp = l4_sched_param(1, 0); tag = l4_scheduler_run_thread(l4re_env()->scheduler, t1, &sp); if (l4_error(tag)) return 4; /* 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; }