OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [src/] [platform/] [beagle/] [perfmon.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * Platform specific perfmon initialization
3
 *
4
 * Copyright (C) 2010 B Labs Ltd.
5
 *
6
 * Author: Bahadir Balban
7
 */
8
#include INC_PLAT(timer.h)
9
#include <l4/lib/printk.h>
10
#include INC_PLAT(offsets.h)
11
#include INC_SUBARCH(perfmon.h)
12
#include INC_SUBARCH(mmu_ops.h)
13
#include INC_GLUE(memlayout.h)
14
/*
15
 * Current findings by these tests:
16
 *
17
 * Cpu cycle count and timer ticks are consistently showing 400Mhz
18
 * with a reference timer tick of 1Mhz. So cycle counts are fixed
19
 * with regard to the timer.
20
 *
21
 * Instruction execute count on the busy_loop however, is varying
22
 * between x1, x2 combinations when compared to timer and cycle
23
 * count values. This is happening by trivial changes in code such
24
 * as adding a function call. (Other variables are ruled out, e.g.
25
 * no concurrent memory accesses, caches are off)
26
 *
27
 * There may be two causes to this:
28
 * - Due to missing dmb/dsb/isb instructions.
29
 * - Due to BTC (busy_loop has one branch) which may describe
30
 * the doubling in IPC, since out of the 2 instructions in the
31
 * busy loop one is a branch.
32
 *
33
 * Disabling the BTC increased cycle counts per instruction
34
 * significantly, advising us not to expect any accuracy in counting
35
 * instructions in cycles. Hence instruction-based tests are
36
 * commented out. It is wise to only rely upon timer and cycle counts.
37
 */
38
void platform_test_tick_cycles()
39
{
40
        /* Initialize the timer */
41
        const unsigned int load_value = 0xffffffff - 100000;
42
        int mhz_top, mhz_bot, temp;
43
        unsigned long timer_base = PLATFORM_TIMER1_VBASE;
44
        int cyccnt;
45
 
46
        /* Make sure timer is disabled */
47
        timer_stop(timer_base);
48
 
49
        /* One shot, 32 bits, no irqs */
50
        timer_init_oneshot(timer_base);
51
 
52
        /* Load the timer with ticks value */
53
        timer_load(timer_base, load_value);
54
 
55
        /* Start the timer */
56
        timer_start(timer_base);
57
 
58
        /* Start counter */
59
        perfmon_reset_start_cyccnt();
60
 
61
        /* Wait until 0 */
62
        while (timer_read(timer_base) != 0)
63
                ;
64
 
65
        cyccnt = perfmon_read_cyccnt();
66
 
67
        /* Fixed-point accuracy on bottom digit */
68
        temp = cyccnt * 64 * 10 * 13 / 100000;
69
        mhz_top = temp / 10;
70
        mhz_bot = temp - mhz_top * 10;
71
 
72
        printk("Perfmon: 0x%x cycle count \n", cyccnt);
73
        printk("%s: %d.%d MHz CPU speed measured by timer REFCLK at 13MHz\n",
74
               __KERNELNAME__, mhz_top, mhz_bot);
75
}
76
 
77
void platform_test_cpucycles(void)
78
{
79
        /*
80
         * Variable results:
81
         *
82
         * platform_test_loop_cycles();
83
         * platform_test_loop_ticks();
84
         */
85
 
86
        /* Fixed result */
87
        platform_test_tick_cycles();
88
}
89
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.