Beispiel #1
0
int
thread_new
(
    struct thread   * thread,
    L4_SpaceId_t    space,
    L4_ThreadId_t   scheduler,
    L4_ThreadId_t   pager,
    L4_ThreadId_t   exception
)
{
    int     rv;
    int fpu = 0;

#if defined(ARCH_IA32)
    /* Always allocate FPU resources to every thread iguana creates on IA32
     * (bug 2836)
     */
    fpu = 0x80000001;
#endif

    rv =
        L4_ThreadControl
        (
            thread->id, space, scheduler, pager, exception, fpu, (void *)thread->utcb
        );

    if (rv == 1)
    {
        L4_Word_t handle;
        L4_StoreMR(0, &handle);

        thread->handle.raw = handle;

        assert(hash_lookup(l4tid_to_thread, handle) == NULL);

        /* Guaranteed to work because hash_lookup was just performed */
        hash_insert(l4tid_to_thread, handle, thread);

        L4_Set_Priority(thread->id, 100);
    } else {
        /* Initialise the handle to an invalid valid. */
        thread->handle = L4_nilthread;
    }
    
    return rv;
}
Beispiel #2
0
/* poke/peek thread. obeys POKE, PEEK, and QUIT. */
static void poke_peek_fn(void *param_ptr)
{
#if 0
	diag("%s: started as %lu:%lu. pager is %#lx", __func__,
		L4_ThreadNo(L4_MyGlobalId()), L4_Version(L4_MyGlobalId()),
		L4_Pager());
#endif
	for(;;) {
		L4_ThreadId_t from;
		L4_MsgTag_t tag = L4_Wait(&from);

		for(;;) {
			if(L4_IpcFailed(tag)) break;

			if(tag.X.label == QUIT_LABEL) {
				// diag("%s: quitting", __func__);
				return;
			} else if(tag.X.label == PEEK_LABEL) {
				L4_Word_t addr;
				L4_StoreMR(1, &addr);
				L4_LoadMR(0, (L4_MsgTag_t){ .X.u = 1 }.raw);
				L4_LoadMR(1, *(uint8_t *)addr);
			} else if(tag.X.label == POKE_LABEL) {
Beispiel #3
0
static void
ipc_setup(struct bench_test *test, int args[])
{
    static bool setup = false;
    int r;
    L4_Word_t utcb;
    fass = (test == &bench_ipc_fass);
    pagertimer = (test == &bench_ipc_pagemap);
    pagertimer_simulated = (test == &bench_ipc_pagemap_simulated);
    inter = (test == &bench_ipc_inter);
    fass_buffer = ((test == &bench_ipc_fass_buffer) || (test == &bench_ipc_fass_buffer_vspace));
    fault_test = (test == &bench_ipc_page_faults);
    intra_open = (test == &bench_ipc_intra_open);
    intra_close = (test == &bench_ipc_intra_close);
    intra_rpc = (test == &bench_ipc_intra_rpc);
    intra_ovh = (test == &bench_ipc_intra_ovh);
    intra_async = (test == &bench_ipc_intra_async);
    intra_async_ovh = (test == &bench_ipc_intra_async_ovh);

    num_iterations = args[0];
    num_mrs = args[1];

    ping_space = pong_space = L4_nilspace;

    if (! setup) {
        /* Find smallest supported page size. There's better at least one
         * bit set. */

        /* Size for one UTCB */
        utcb_size = L4_GetUtcbSize();

        /* We need a maximum of two threads per task */
#ifdef NO_UTCB_RELOCATE
        no_utcb_alloc = 1;
        utcb_area = L4_Nilpage;
        if (fass) {
            pong_utcb_area = L4_Nilpage;
        }
#else
        no_utcb_alloc = 0;
        utcb_area = L4_Fpage((L4_Word_t) UTCB_ADDRESS,
                             L4_GetUtcbAreaSize() + 1);
        if (fass) {
            pong_utcb_area = L4_Fpage ((L4_Word_t) UTCB_ADDRESS,
                                       L4_GetUtcbAreaSize() + 1);
        }
#endif

        /* Create pager */
        master_tid.raw = KBENCH_SERVER.raw;
        pager_tid.raw = KBENCH_SERVER.raw + 1;
        ping_tid.raw  = KBENCH_SERVER.raw + 2;
        pong_tid.raw  = KBENCH_SERVER.raw + 3;

        /* VU: calculate UTCB address -- this has to be revised */
        /** @todo FIXME: Should put into arch subdir - changhua. */
#if defined(ARCH_ARM)
        L4_Word_t pager_utcb = (L4_Word_t) __L4_ARM_Utcb();
#elif defined(ARCH_IA32)
        L4_Word_t pager_utcb = (L4_Word_t) __L4_X86_Utcb();
#elif defined(ARCH_SH)
        L4_Word_t pager_utcb = (L4_Word_t) L4_GetUtcbBase();
#else
        #error "Please define arch get_Utcb()"
#endif
        pager_utcb = no_utcb_alloc ? ~0UL : (pager_utcb & ~(utcb_size - 1)) + utcb_size;
        r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, 
                      master_tid, 0, (void*)pager_utcb);
        if (r == 0) printf("Thread create Error: %lx\n", L4_ErrorCode());
        assert(r == 1);
        L4_KDB_SetThreadName(pager_tid, "pager");
        L4_Start_SpIp (pager_tid, (L4_Word_t) pager_stack + sizeof(pager_stack) - 32, START_ADDR (pager));
        /* Find some area of memory to page to */
        setup = true;
    }

    if (pagertimer) {
        /* Only create ping space and ping thread. */
        r = okl4_kspaceid_allocany(spaceid_pool, &ping_space);
        assert(r == OKL4_OK);
        r = L4_SpaceControl(ping_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, 0, NULL);
        assert(r == 1);

        utcb = no_utcb_alloc ? ~0UL : UTCB(0);

        r = L4_ThreadControl(ping_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb);
        L4_StoreMR(0, &ping_th.raw);
        assert(r == 1);
    } else if (fault_test) {
        /* Only create pong space and pong thread. */
        r = okl4_kspaceid_allocany(spaceid_pool, &pong_space);
        assert(r == OKL4_OK);
        r = L4_SpaceControl(pong_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, 0, NULL);
        assert(r == 1);

        utcb = no_utcb_alloc ? ~0UL : UTCB(0);

        r = L4_ThreadControl(pong_tid, pong_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb);
        L4_StoreMR(0, &pong_th.raw);
        assert(r == 1);
    } else if (pagertimer_simulated || inter || fass || fass_buffer) {
        /* Create both ping, pong space, and create ping, pong thread in their own space */
        L4_Word_t ctrl = 0;
        if (test == &bench_ipc_fass_buffer_vspace) {
            ctrl = (1 << 16);
        }
        r = okl4_kspaceid_allocany(spaceid_pool, &ping_space);
        assert(r == OKL4_OK);

        r = L4_SpaceControl(ping_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, ctrl, NULL);
        if (r == 0) printf("Space control Error: 0x%lx\n", L4_ErrorCode());
        assert( r == 1 );
        r = okl4_kspaceid_allocany(spaceid_pool, &pong_space);
        assert(r == OKL4_OK);
        r = L4_SpaceControl(pong_space, L4_SpaceCtrl_new, KBENCH_CLIST, (fass ? pong_utcb_area : utcb_area), ctrl, NULL);
        assert( r == 1);

        utcb = no_utcb_alloc ? ~0UL : UTCB(0);

        r = L4_ThreadControl(ping_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb);
        L4_StoreMR(0, &ping_th.raw);
        assert( r == 1);

        utcb = no_utcb_alloc ? ~0UL : fass ? PONGUTCB(1) : UTCB(1);

        r = L4_ThreadControl(pong_tid, pong_space, master_tid, pager_tid, pager_tid, 0, (void *)utcb);
        L4_StoreMR(0, &pong_th.raw);
    } else {
        /* Only Create ping space, but create both ping, pong thread in that space. */
        r = okl4_kspaceid_allocany(spaceid_pool, &ping_space);
        assert(r == OKL4_OK);
        r = L4_SpaceControl(ping_space, L4_SpaceCtrl_new, KBENCH_CLIST, utcb_area, 0, NULL);
        assert( r == 1 );

        utcb = no_utcb_alloc ? ~0UL : UTCB(0);

        r = L4_ThreadControl(ping_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb);
        L4_StoreMR(0, &ping_th.raw);
        assert( r == 1);

        utcb = no_utcb_alloc ? ~0UL : UTCB(1);

        r = L4_ThreadControl(pong_tid, ping_space, master_tid, pager_tid, pager_tid, 0, (void *) utcb);
        L4_StoreMR(0, &pong_th.raw);
        assert( r == 1);
    }

    L4_KDB_SetThreadName(ping_tid, "ping");
    if (test != &bench_ipc_pagemap) {
        L4_KDB_SetThreadName(pong_tid, "pong");
    }
}
Beispiel #4
0
static void
handler(void)
{
    int i;
    L4_Word_t irq, control;
    irq = interrupt;

    //L4_MsgTag_t tag;
    L4_Call(master_tid);

    /* Accept interrupts */
    L4_Accept(L4_NotifyMsgAcceptor);
    L4_Set_NotifyMask(~0UL);

    /* Handle interrupts */
    for (i=0; i < num_iterations + 2; i++)
    {
        int k,j;
        struct counter **count;
        uint64_t cnt = 0;

        L4_Word_t mask;
#if defined(CONFIG_CPU_ARM_XSCALE) || defined(CONFIG_CPU_ARM_ARM1136JS) || defined(CONFIG_CPU_ARM_ARM1176JZS)
        //Setup pmu irq
        L4_KDB_PMN_Write(REG_CCNT, 0xFF800000); //At least leave 0x100000 cycles
        L4_Word_t PMNC = L4_KDB_PMN_Read(REG_PMNC) & ~PMNC_CCNT_64DIV;
        L4_KDB_PMN_Write(REG_PMNC, (PMNC | PMNC_CCNT_OFL | PMNC_CCNT_ENABLE) & ~PMNC_CCNT_RESET);
        L4_KDB_PMN_Ofl_Write(REG_CCNT, ~0UL);
#endif
        // ack/wait IRQ
        control = 0 | (3 << 6);
        L4_LoadMR(0, irq);
        (void)L4_InterruptControl(L4_nilthread, control);
        L4_StoreMR(1, &mask);

        irq = __L4_TCR_PlatformReserved(0);

        //tag.raw = 0x0000C000;
        //tag = L4_Ipc(from, thread_tid, tag, &from);
        //if (getTagE(tag))
        //    printf("ipc error %lx\n", L4_ErrorCode());
        //printf("Receive irq ipc from %lx\n", from.raw);
#if defined(CONFIG_CPU_ARM_XSCALE) || defined(CONFIG_CPU_ARM_ARM1136JS) || defined(CONFIG_CPU_ARM_ARM1176JZS)
        //Get CCNT count
        cnt = L4_KDB_PMN_Read(REG_CCNT);
        PMNC = L4_KDB_PMN_Read(REG_PMNC);
        assert(PMNC & ~PMNC_CCNT_OFL);
        //Since on ARM11, PMNC IRQ can only be deasserted when PMU is enabled,
        //need to clear overflow flag and disable IRQ before disable PMU.
        L4_KDB_PMN_Write(REG_PMNC, (PMNC | PMNC_CCNT_OFL) & ~PMNC_CCNT_ENIRQ);
        //Stop CCNT.
        L4_KDB_PMN_Write(REG_PMNC, PMNC & ~PMNC_CCNT_ENABLE);
        //printf("CNT is %016lld\n", cnt);
#endif

        //Write result back.
        for (k = 0, count = irq_ipc_counters; *count != NULL; count++, k++)
        {
            for (j = 0; j < (*count)->get_num_counters(*count); j++)
            {
                results[k] += cnt;
                if ( i == 0 || i == 1) //we don't count the first 2 run, since they contain page fault and cache miss latency.
                    results[k] -= cnt;
            }
        }
    }

    /* Tell master that we're finished */
    L4_Set_MsgTag (L4_Niltag);
    L4_Send (master_tid);

    for (;;)
        L4_WaitForever();

    /* NOTREACHED */
}