Beispiel #1
0
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;
}
Beispiel #2
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();
}
Beispiel #4
0
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);
}
Beispiel #5
0
/**
 *
 * 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;
}
Beispiel #6
0
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) { }
}
Beispiel #7
0
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) ;
}
Beispiel #9
0
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;
    }
}
Beispiel #13
0
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);
    }
}
Beispiel #15
0
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) ;
}
Beispiel #16
0
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());
}
Beispiel #17
0
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);
}
Beispiel #18
0
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());
}
Beispiel #19
0
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);
}
Beispiel #20
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 #21
0
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;
}
Beispiel #23
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 */
}
Beispiel #24
0
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
}