Example #1
0
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);
}
Example #2
0
/**
 * 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;
}
Example #3
0
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);
}
Example #4
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[], _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;
}
Example #5
0
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);
    }


}
Example #6
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;

  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;
}