Difference between revisions of "ARM Cycle Counter"
(Created page with "<syntaxhighlight lang="c"> asm ("MCR p15, 0, %0, C9, C14, 0\n\t" :: "r"(1)); asm ("MCR p15, 0, %0, C9, C14, 2\n\t" :: "r"(0x8000000f)); </syntaxhighlight> <syntaxhighlight la...") |
|||
Line 39: | Line 39: | ||
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
+ | <pre> | ||
+ | taskset -c 0 insmod eacc.ko | ||
+ | </pre> | ||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> |
Revision as of 10:58, 31 May 2015
asm ("MCR p15, 0, %0, C9, C14, 0\n\t" :: "r"(1));
asm ("MCR p15, 0, %0, C9, C14, 2\n\t" :: "r"(0x8000000f));
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Daniel Rubio Bonilla");
MODULE_DESCRIPTION("Enable ARM Cycle Counter");
static int __init eacc_init(void) {
asm ("MCR p15, 0, %0, C9, C14, 0\n\t" :: "r"(1));
asm ("MCR p15, 0, %0, C9, C14, 2\n\t" :: "r"(0x8000000f));
printk(KERN_INFO "EACC loaded\n");
return 0;
}
static void __exit eacc_exit(void) {
printk(KERN_INFO "EACC unloaded\n");
}
module_init(eacc_init);
module_exit(eacc_exit);
obj-m += eacc.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
taskset -c 0 insmod eacc.ko
static inline unsigned int get_cyclecount (void) {
unsigned int value;
// Read CCNT Register
asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(value));
return value;
}
static inline void init_perfcounters (int32_t do_reset, int32_t enable_divider) {
// in general enable all counters (including cycle counter)
int32_t value = 1;
// peform reset:
if (do_reset) {
value |= 2; // reset all counters to zero.
value |= 4; // reset cycle counter to zero.
}
if (enable_divider)
value |= 8; // enable "by 64" divider for CCNT.
value |= 16;
// program the performance-counter control-register:
asm volatile ("MCR p15, 0, %0, c9, c12, 0\t\n" :: "r"(value));
// enable all counters:
asm volatile ("MCR p15, 0, %0, c9, c12, 1\t\n" :: "r"(0x8000000f));
// clear overflows:
asm volatile ("MCR p15, 0, %0, c9, c12, 3\t\n" :: "r"(0x8000000f));
}
init_perfcounters (1, 0);
// measure the counting overhead:
unsigned int overhead = get_cyclecount();
overhead = get_cyclecount() - overhead;
unsigned int t = get_cyclecount();
// do some stuff
printf("Hello World!!\n");
t = get_cyclecount() - t;
printf ("function took exactly %d cycles (including function call)\n", t - overhead);