Difference between revisions of "ARM Cycle Counter"

From Tuxamito
Jump to: navigation, search
(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);