static int sync_ldt(struct task_struct *tsk, u32 entry_1, u32 entry_2, int index) { struct task_struct *p; struct mm_struct *mm; L4_Word_t dummy; p = tsk; mm = tsk->mm; do { L4_LoadMR(0, index); L4_LoadMR(1, entry_1); L4_LoadMR(2, entry_2); if (0 == L4_ExchangeRegisters( task_thread_info(p)->user_tid, L4_ExReg_Tls, 0, 0, 0, 0, L4_nilthread, &dummy, &dummy, &dummy, &dummy, &dummy)) { printk("OKLinux: ldtctrl() failed. errcode 0x%lx\n", L4_ErrorCode()); return -EINVAL; } } while ((p = next_thread(p)) != tsk); return 0; }
/* Flush a range of memory from the kernel's virtual address space */ void flush_tlb_kernel_range(unsigned long start, unsigned long end) { #if 0 unsigned long base, count; L4_Fpage_t fpage; count = 0; base = start & PAGE_MASK; while (1) { fpage = L4_FpageLog2(base, PAGE_SHIFT); L4_Set_Rights(&fpage, L4_FullyAccessible); /* To unmap */ L4_LoadMR(count++, fpage.raw); if (count == __L4_NUM_MRS) { L4_Unmap(count-1); count = 0; } base += PAGE_SIZE; if (base >= end) { if (count) L4_Unmap(count-1); return; } } #endif }
END_TEST /* \begin{test}{SIGRAPH0401} \TestDescription{Schedule inheritance graph: mutex release test} \TestImplementationProcess{ Thread 3 (main thread) releases mutex1, effective priority of main thread should be 7. } \TestPassStatus{pass} \TestImplementationStatus{Implemented} \TestRegressionStatus{In regression test suite} \end{test} */ START_TEST(SIGRAPH0401) { L4_MsgTag_t tag; setup_graph(); L4_Receive(main_thread); tag = L4_Make_MsgTag(0x3, 0); L4_Set_MsgTag(tag); L4_Send(main_thread); L4_Receive(main_thread); L4_LoadMR(0, 0); L4_Send(main_thread); measure_effective_prio(7); delete_all(); }
static void ipc_irq_teardown(struct new_bench_test *test, int args[]) { int r = 0; L4_Word_t control; //L4_DeassociateInterrupt(thread_tid); control = 0 | (1 << 6) | (31<<27); L4_LoadMR(0, interrupt); r = L4_InterruptControl(handler_tid, control); if (r == 0) { printf("Cannot unregister interrupt\n"); } #if SPINNER /* Delete spinner */ r = L4_ThreadControl (spinner_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert (r == 1); #endif /* Delete handler thread */ r = L4_ThreadControl (handler_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert (r == 1); /* Delete pager */ r = L4_ThreadControl (pager_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert (r == 1); }
/** * * DESCRIPTION: This function causes the next available thread in the pend queue * to be unblocked. If no thread is pending on this semaphore, the * semaphore becomes 'full'. */ PUBLIC IX_STATUS ixOsalSemaphorePost(IxOsalSemaphore *sid) { VALID_HANDLE(sid); struct semaphore *sem = *sid; L4_ThreadId_t tid = { 0 }; /*Get the lock, up the value, take the head, and get out*/ ixOsalFastMutexLock(&sem->fInterlockP); if (sem->fQueue) { assert((int) sem->fCount < 0); // Hand the count over to the next thread struct tid_list *head = sem->fQueue; tid = head->fTid; sem->fQueue = head->fNext; // Drop the node, it will be freed later } sem->fCount++; ixOsalFastMutexUnlock(&sem->fInterlockP); // Ping the waiting thread if any if (tid.raw) { L4_LoadMR(0, 0); // Empty message L4_Send_Nonblocking(tid); } return IX_SUCCESS; }
static void waiting_notify_thread(void *arg) { L4_Word_t notifybits; L4_MsgTag_t tag; L4_Word_t mask; tag = L4_Receive(main_tid); notifybits = L4_Label(tag); L4_Set_NotifyMask(notifybits); L4_Accept(L4_NotifyMsgAcceptor); L4_LoadMR(0, 0); L4_Send(main_tid); tag = L4_WaitNotify(&mask); if (L4_IpcFailed(tag)) { FAILED(); return; } L4_Set_Label(&tag, notifybits); L4_Set_MsgTag(tag); L4_Call(main_tid); while (1) { } }
static void ipc_test_fault(struct bench_test *test, int args[]) { /* Send empty message to notify pager to startup both threads */ L4_LoadMR (0, 0); L4_Send (pager_tid); L4_Receive (pager_tid); }
static void other_sending_thread(void) { L4_LoadMR(0, 0); L4_Send(prio5_thread); L4_WaitForever(); while(1) ; }
static void ipc_irq_test(struct new_bench_test *test, int args[], volatile uint64_t *count) { results = count; /* Send empty message to notify pager to startup test thread */ L4_LoadMR (0, 0); L4_Send (handler_tid); L4_Receive (handler_tid); }
/* * The lowest priority thread acquires a mutex at initialisation time, releases * it the next it is run in scenario 1. It increments a counter on success. * It sends IPC to medium thread in scenario 2. It increments a counter on success. */ void mixed_pi_low(int argc, char **argv) { L4_ThreadId_t tid; L4_MsgTag_t tag; int counter = 10000; while (!libs_ready) ; while (L4_IsNilThread(medium3_prio_thread)) ; tid = medium3_prio_thread; //printf("Low thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { // Initalisation if (scenario1) { //printf("Low thread %lx/%lx acquires mutex for resource\n", me, pi_main.raw); okl4_libmutex_count_lock(resource_mutex); cnt_l++; } //printf("(Initialisation) Low thread %lx/%lx blocks sending to Medium thread\n", me, pi_main.raw); L4_LoadMR(0, 0); L4_Send(tid); //printf("(Initialisation) Low thread %lx/%lx sent to Medium thread\n", me, pi_main.raw); L4_Yield(); /*** Start test ***/ while (stop_spinning) ; wait_a_bit(counter); if (!flag1 && (counter < LIMIT)) { counter *= 2; } if (scenario1) { okl4_libmutex_count_unlock(resource_mutex); } else if (scenario2) { cnt_l++; //printf("Low thread %lx/%lx blocks sending to Medium thread\n", me, pi_main.raw); L4_LoadMR(0, 0); tag = L4_Send(medium2_prio_thread); if (L4_IpcFailed(tag)) cnt_l--; } L4_Yield(); tid = medium2_prio_thread; } }
/* * The highest priority thread blocks sending to medium thread in the * first scenario. It increments a counter on success. * It tries to acquire a mutex in the second scenario. It increments a counter on success. */ void mixed_pi_high(int argc, char **argv) { L4_MsgTag_t tag; while (!libs_ready) ; L4_Receive(pi_main); //printf("High thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { while (stop_spinning) ; if (scenario1) { L4_LoadMR(0, 0); tag = L4_Send(medium2_prio_thread); if (L4_IpcSucceeded(tag)) cnt_h++; } else if (scenario2) { //printf("High thread %lx/%lx acquiring mutex for resource, current holder: 0x%lx\n", me, pi_main.raw, resource_mutex->holder); okl4_libmutex_count_lock(resource_mutex); //printf("High thread %lx/%lx acquired mutex for resource\n", me, pi_main.raw); cnt_h++; } // If intermediate threads have run, then increment respective counter. if (flag1) cnt_i1++; if (flag3) cnt_i2++; if (scenario2) okl4_libmutex_count_unlock(resource_mutex); // Tell main thread iteration is done. L4_LoadMR(0, 0); L4_Call(pi_main); // Re-initialise. if (flag1) { L4_Receive_Nonblocking(medium1_prio_thread); flag1 = 0; } if (flag3) { L4_Receive_Nonblocking(medium3_prio_thread); flag3 = 0; } } }
/* * The medium thread tries to acquire a mutex, releases it once acquired and then * receives from highest priority thread in scenario 1. It increments 2 counters * on success, one for each operation. * It acquires a mutex at initialisation time and waits for any thread before * releasing the mutex in scenario 2. It increments 2 counters on success, * one for each operation. */ void mixed_pi_medium(int argc, char **argv) { L4_ThreadId_t any_thread, tid; L4_MsgTag_t tag; int counter = 10000; while (!libs_ready) ; while (L4_IsNilThread(medium1_prio_thread)) ; tid = medium1_prio_thread; //printf("Middle thread %lx/%lx starts PI test\n", me, pi_main.raw); while (1) { // Initialisation if (scenario2) { //printf("Middle thread %lx/%lx acquires mutex for resource\n", me, pi_main.raw); okl4_libmutex_count_lock(resource_mutex); cnt_m1++; } //printf("(Initialisation) Medium thread %lx/%lx blocks open receiving\n", me, pi_main.raw); L4_Wait(&any_thread); //printf("(Initialisation) Medium thread %lx/%lx received from 0x%lx\n", me, pi_main.raw, any_thread.raw); L4_LoadMR(0, 0); L4_Send(tid); L4_Yield(); /*** Start test ***/ while (stop_spinning) ; wait_a_bit(counter); if (scenario1) { okl4_libmutex_count_lock(resource_mutex); cnt_m1++; wait_a_bit(counter); } else if (scenario2) { //printf("Middle thread %lx/%lx blocks open receiving\n", me, pi_main.raw); tag = L4_Wait(&any_thread); if (L4_IpcSucceeded(tag) && (any_thread.raw == low_prio_thread.raw)) cnt_m2++; wait_a_bit(counter); } okl4_libmutex_count_unlock(resource_mutex); if (!flag1 && (counter < LIMIT)) { counter *= 2; } if (scenario1) { cnt_m2++; tag = L4_Receive(high_prio_thread); if (L4_IpcFailed(tag)) cnt_m2--; } L4_Yield(); tid = pi_main; } }
static void run_copying_thread(L4_Word_t direction, int small_remote_buffer, int unmapped) { L4_MsgTag_t tag; memset(copying_thread_buffer, COPYING_THREAD_PATTERN, sizeof(copying_thread_buffer)); tag = L4_Niltag; L4_Set_MemoryCopy(&tag); L4_LoadMR(0, tag.raw); if (unmapped) { L4_LoadMR(1, (word_t)unmapped_address); } else { L4_LoadMR(1, (word_t)copying_thread_buffer); } if (small_remote_buffer) { L4_LoadMR(2, SMALL_BUFFER_SIZE); } else { L4_LoadMR(2, sizeof(copying_thread_buffer)); } L4_LoadMR(3, direction); tag = L4_Call(test_tid); assert(L4_IpcSucceeded(tag)); }
/* * Intermediate thread 1 has priority in between highest and medium thread. * Intermediate thread 2 has priority in between medium and lowest thread. * They set their flag each time they run during the PI test. */ void mixed_pi_intermediate(int argc, char **argv) { int num = 0; L4_ThreadId_t any_thread; L4_MsgTag_t tag = L4_Niltag; while (!libs_ready) ; if (argc) { num = atoi(argv[0]); } else { printf("(%s Intermediate Thread) Error: Argument(s) missing!\n", test_name); L4_Set_Label(&tag, 0xdead); L4_Set_MsgTag(tag); L4_Call(pi_main); } // Initialisation if (num == 1) { L4_Wait(&any_thread); L4_LoadMR(0, 0); L4_Send(pi_main); } else if (num == 2) { L4_Wait(&any_thread); while (L4_IsNilThread(medium2_prio_thread)) ; L4_LoadMR(0, 0); L4_Send(medium2_prio_thread); } L4_Yield(); // Thread is now ready to set the flag the next time it is run. while(1) { if (num == 1) { flag1 = 1; } else if (num == 2) { flag3 = 1; } L4_LoadMR(0, 0); L4_Send(high_prio_thread); } }
static void sending_thread(void) { L4_Word_t result; L4_MsgTag_t tag; if (L4_UserDefinedHandle()) { result = L4_Lock(mutex2); fail_unless(result == 1, "L4_Lock() failed"); } L4_LoadMR(0, 0); L4_Send(main_thread); tag = L4_Receive(setup_thread); if (L4_Label(tag) == 0x3) { L4_Unlock(mutex2); L4_LoadMR(0, 0); L4_Send(main_thread); } L4_WaitForever(); while(1) ; }
static void synch_pong (void *arg) { L4_ThreadId_t caller; L4_MsgTag_t tag; VERBOSE_HIGH("Pong running\n"); while(pingpong_cleanup == 0) { tag = L4_Wait(&caller); pingpong_counter++; L4_LoadMR (0, 0); L4_Send(caller); } L4_Call(L4_Myself()); }
static void setup_extended_graph(void) { setup_graph(); prio8_thread = createThread(other_sending_thread); L4_KDB_SetThreadName(prio8_thread, "prio8_thread"); L4_Set_Priority(prio8_thread, 201); L4_Set_Priority(prio8_thread, 8); prio6bis_thread = createThread(other_sending_thread); L4_KDB_SetThreadName(prio6bis_thread, "prio6bis_thread"); L4_Set_Priority(prio6bis_thread, 201); L4_Set_Priority(prio6bis_thread, 6); L4_Receive(main_thread); L4_LoadMR(0, 0); L4_Send(main_thread); }
static void synch_ping (void *arg) { L4_ThreadId_t partner; L4_MsgTag_t tag; VERBOSE_HIGH("Ping running\n"); /* XXX partner always thread 0 (created before us) */ partner = get_thread_id(0); while(pingpong_cleanup == 0) { L4_LoadMR (0, 0); L4_Send(partner); tag = L4_Wait(&partner); } L4_Call(L4_Myself()); }
static void setup_graph(void) { main_thread = createThread(runnable_main_thread); L4_KDB_SetThreadName(main_thread, "main_thread"); L4_Set_Priority(main_thread, 3); L4_Receive(main_thread); prio6_thread = createThread(sending_thread); L4_KDB_SetThreadName(prio6_thread, "prio6_thread"); L4_Set_UserDefinedHandleOf(prio6_thread, 0); L4_Set_Priority(prio6_thread, 201); L4_Set_Priority(prio6_thread, 6); prio1_thread = createThread(sending_thread); L4_KDB_SetThreadName(prio1_thread, "prio1_thread"); L4_Set_UserDefinedHandleOf(prio1_thread, 1); L4_Set_Priority(prio1_thread, 201); L4_Set_Priority(prio1_thread, 1); prio2_thread = createThread(locking_m1_thread); L4_KDB_SetThreadName(prio2_thread, "prio2_thread"); L4_Set_Priority(prio2_thread, 201); L4_Set_Priority(prio2_thread, 2); prio5_thread = createThread(locking_m1_thread); L4_KDB_SetThreadName(prio5_thread, "prio5_thread"); L4_Set_Priority(prio5_thread, 201); L4_Set_Priority(prio5_thread, 5); prio4_thread = createThread(locking_m2_thread); L4_KDB_SetThreadName(prio4_thread, "prio4_thread"); L4_Set_Priority(prio4_thread, 201); L4_Set_Priority(prio4_thread, 4); prio7_thread = createThread(locking_m2_thread); L4_KDB_SetThreadName(prio7_thread, "prio7_thread"); L4_Set_Priority(prio7_thread, 201); L4_Set_Priority(prio7_thread, 7); L4_LoadMR(0, 0); L4_Send(main_thread); measure_thread = createThread(measure_effective_prio_thread); L4_KDB_SetThreadName(measure_thread, "measure_thread"); L4_Set_Priority(measure_thread, 9); }
/* 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) {
int okl4_irqset_register(okl4_irqset_t *set, okl4_irqset_register_attr_t *attr) { okl4_word_t success; /* Ensure we have enough room in our struct. */ if (set->num_interrupts == set->max_interrupts) { return OKL4_ALLOC_EXHAUSTED; } /* Register the interrupt. */ L4_LoadMR(0, attr->irq); success = L4_RegisterInterrupt(set->owner->cap, set->notify_bits, 0, 0); if (!success) { /* Either the interrupt is already registered, or does not exist. The * kernel does not give us enough information to distinguish. */ return OKL4_INVALID_ARGUMENT; } /* Save the interrupt. */ set->irqs[set->num_interrupts++] = attr->irq; return OKL4_OK; }
int main(int argc, char **argv) { struct okl4_libmutex rm; L4_ThreadId_t tid; int i, max_iteration, eg_num, server_on; L4_Word_t me; L4_MsgTag_t tag = L4_Niltag; /*** Initialisation ***/ pi_main = thread_l4tid(env_thread(iguana_getenv("MAIN"))); me = pi_main.raw; eg_num = max_iteration = server_on = 0; if (argc == 3) { eg_num = atoi(argv[0]); max_iteration = atoi(argv[1]); server_on = atoi(argv[2]); } else { printf("(%s 0x%lx) Error: Argument(s) missing!\n", test_name, me); return 1; } resource_mutex = &rm; okl4_libmutex_init(resource_mutex); high_prio_thread = medium1_prio_thread = medium2_prio_thread = medium3_prio_thread = low_prio_thread = L4_nilthread; high_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_HIGH"))); medium3_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_INTERMEDIATE_2"))); medium2_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_MEDIUM"))); medium1_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_INTERMEDIATE_1"))); low_prio_thread = thread_l4tid(env_thread(iguana_getenv("MIXED_PI_LOW"))); // Tell other threads that it is safe to use libraries libs_ready = 1; if (!server_on) printf("Start %s test #%d(0x%lx)\n", test_name, eg_num, me); /*** Start test ***/ scenario1 = 1; for (i = 0; i < 2 * max_iteration; i++) { // Wait for threads to be ready tag = L4_Wait(&tid); // If one thread had a problem while initialisation, then stop the test and notify // server that the test is dead. if (L4_Label(tag) == 0xdead) { rtos_init(); test_died(test_name, eg_num); rtos_cleanup(); return 1; } // Tell high prio thread to start the next iteration. L4_LoadMR(0, 0); tag = L4_Send(high_prio_thread); stop_spinning = 0; // Wait for the iteration to finish. L4_Receive(high_prio_thread); stop_spinning = 1; // If end of iterations for scenario1, then report results to RTOS server if server is on. if (i == (max_iteration - 1)) { if (server_on) { rtos_init(); mixed_priority_inversion_results(eg_num, 1, max_iteration, cnt_h, cnt_m1, cnt_m2, cnt_l, cnt_i1, cnt_i2); } else print_metrics(max_iteration); // Start scenario2 cnt_h = cnt_m1 = cnt_m2 = cnt_l = cnt_i1 = cnt_i2 = 0; scenario1 = 0; scenario2 = 1; } } /*** Test finished ***/ thread_delete(medium1_prio_thread); thread_delete(medium3_prio_thread); thread_delete(high_prio_thread); thread_delete(medium2_prio_thread); thread_delete(low_prio_thread); /* Clean up allocated mutexes. */ okl4_libmutex_free(resource_mutex); // If RTOS server is on, report results to it. if (server_on) { mixed_priority_inversion_results(eg_num, 2, max_iteration, cnt_h, cnt_m1, cnt_m2, cnt_l, cnt_i1, cnt_i2); rtos_cleanup(); } else { print_metrics(max_iteration); printf("%s test #%d(0x%lx) finished\n", test_name, eg_num, me); } return 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 */ }
static void ipc_irq_setup(struct new_bench_test *test, int args[]) { int r; L4_Word_t utcb; L4_Word_t utcb_size; // L4_Word_t dummy; num_iterations = args[0]; handler_space = L4_nilspace; /* We need a maximum of two threads per task */ utcb_size = L4_GetUtcbSize(); #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb =(L4_Word_t)L4_GetUtcbBase() + utcb_size; #endif /* Create pager */ master_tid = KBENCH_SERVER; pager_tid.raw = KBENCH_SERVER.raw + 1; handler_tid.raw = KBENCH_SERVER.raw + 2; interrupt = PMU_IRQ; #if SPINNER spinner_tid = L4_GlobalId (L4_ThreadNo (master_tid) + 3, 2); #endif r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, master_tid, 0, (void*)utcb); if (r == 0 && (L4_ErrorCode() == 2)) { r = L4_ThreadControl (pager_tid, L4_nilspace, L4_nilthread, L4_nilthread, L4_nilthread, 0, (void *) 0); assert(r == 1); r = L4_ThreadControl (pager_tid, KBENCH_SPACE, master_tid, master_tid, master_tid, 0, (void*)utcb); assert(r == 1); } L4_KDB_SetThreadName(pager_tid, "pager"); //L4_Schedule(pager_tid, -1, -1, 1, -1, -1, 0, &dummy, &dummy); L4_Set_Priority(pager_tid, 254); L4_Start_SpIp (pager_tid, (L4_Word_t) pager_stack + sizeof(pager_stack) - 32, START_ADDR (pager)); L4_Receive(pager_tid); #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb += utcb_size; #endif r = L4_ThreadControl(handler_tid, KBENCH_SPACE, master_tid, pager_tid, pager_tid, 0, (void *) utcb); assert(r == 1); L4_KDB_SetThreadName(handler_tid, "handler"); L4_Set_Priority(handler_tid, 100); // Startup notification, start handler thread //printf("register irq %ld, to %lx\n", interrupt, handler_tid.raw); L4_Word_t control = 0 | (0 << 6) | (31<<27); L4_LoadMR(0, interrupt); r = L4_InterruptControl(handler_tid, control); if (r == 0) { printf("Cannot register interrupt %lu\n", interrupt); } L4_Start_SpIp (handler_tid, (L4_Word_t) handler_stack + sizeof(handler_stack) - 32, START_ADDR(handler)); L4_Receive(handler_tid); #if SPINNER //Create spinner thread #ifdef NO_UTCB_RELOCATE utcb = ~0UL; #else utcb += utcb_size; #endif r = L4_ThreadControl (spinner_tid, KBENCH_SPACE, master_tid, pager_tid, pager_tid, 0, (void*) utcb); if (r == 0) printf("create spinner failed %ld\n", L4_ErrorCode()); assert(r == 1); L4_KDB_SetThreadName(spinner_tid, "spinner"); //L4_Schedule(spinner_tid, -1, -1, 1, -1, -1, 0, &dummy, &dummy); //Set priority to the lowest. L4_Set_Priority(spinner_tid, 1); L4_Start_SpIp (spinner_tid, (L4_Word_t) spinner_stack + sizeof(spinner_stack) - 32, START_ADDR (spinner)); #endif }