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; }
/* 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) {
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"); } }
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 */ }