Skip to content

Instantly share code, notes, and snippets.

@teqdruid
Created August 7, 2012 20:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teqdruid/3289014 to your computer and use it in GitHub Desktop.
Save teqdruid/3289014 to your computer and use it in GitHub Desktop.
An attempt at making an ARMv7 kernel module for performance counting
# depmod -a; modprobe pmu_sync_sample ; sleep 0; modprobe -r pmu_sync_sample
dmesg output
[91376.479217] Found 6 counters
[91376.479339] Hello, ARM from core 0
[91376.479492] PMNC registers dump:
[91376.479583] PMNC =0x41093001
[91376.479736] CNTENS=0x8000003f
[91376.479827] INTENS=0x00000000
[91376.479919] FLAGS =0x00000000
[91376.480010] SELECT=0x00000005
[91376.480163] CCNT =0x0007107b
[91376.480255] USREN =0x00000000
[91376.480346] CNT[0] count =0x00000000
[91376.480438] CNT[0] evtsel=0x00000010
[91376.480590] CNT[1] count =0x00000000
[91376.480682] CNT[1] evtsel=0x00000011
[91376.480773] CNT[2] count =0x00000000
[91376.480926] CNT[2] evtsel=0x00000012
[91376.481018] CNT[3] count =0x00000000
[91376.481079] CNT[3] evtsel=0x00000013
[91376.481262] CNT[4] count =0x00000000
[91376.481323] CNT[4] evtsel=0x00000014
[91376.481414] CNT[5] count =0x00000000
[91376.481567] CNT[5] evtsel=0x00000015
[91376.481658] Hello, ARM from core 1
[91376.481750] PMNC registers dump:
[91376.481903] PMNC =0x41093001
[91376.481994] CNTENS=0x8000003f
[91376.482086] INTENS=0x00000000
[91376.482177] FLAGS =0x00000000
[91376.482330] SELECT=0x00000005
[91376.482421] CCNT =0x0007033d
[91376.482482] USREN =0x00000000
[91376.482574] CNT[0] count =0x00000000
[91376.482727] CNT[0] evtsel=0x00000010
[91376.482818] CNT[1] count =0x00000000
[91376.482910] CNT[1] evtsel=0x00000011
[91376.483062] CNT[2] count =0x00000000
[91376.483154] CNT[2] evtsel=0x00000012
[91376.483245] CNT[3] count =0x00000000
[91376.483337] CNT[3] evtsel=0x00000013
[91376.483398] CNT[4] count =0x00000000
[91376.483489] CNT[4] evtsel=0x00000014
[91376.483581] CNT[5] count =0x00000000
[91376.483734] CNT[5] evtsel=0x00000015
[91376.495574] Goodbye, ARM
[91376.495666] PMNC registers dump:
[91376.495819] PMNC =0x41093001
[91376.495910] CNTENS=0x0000003f
[91376.496002] INTENS=0x00000000
[91376.496093] FLAGS =0x00000000
[91376.496246] SELECT=0x00000005
[91376.496337] CCNT =0x004991e4
[91376.496429] USREN =0x00000000
[91376.496490] CNT[0] count =0x00000000
[91376.496673] CNT[0] evtsel=0x00000010
[91376.496734] CNT[1] count =0x00000000
[91376.496826] CNT[1] evtsel=0x00000011
[91376.496978] CNT[2] count =0x00000000
[91376.497070] CNT[2] evtsel=0x00000012
[91376.497161] CNT[3] count =0x00000000
[91376.497314] CNT[3] evtsel=0x00000013
[91376.497406] CNT[4] count =0x00000000
[91376.497497] CNT[4] evtsel=0x00000014
[91376.497558] CNT[5] count =0x00000000
[91376.497741] CNT[5] evtsel=0x00000015
[91376.497802] Goodbye, ARM
[91376.497924] PMNC registers dump:
[91376.498077] PMNC =0x41093001
[91376.498168] CNTENS=0x0000003f
[91376.498229] INTENS=0x00000000
[91376.498321] FLAGS =0x00000000
[91376.498474] SELECT=0x00000005
[91376.498565] CCNT =0x00a65b6c
[91376.498657] USREN =0x00000000
[91376.498748] CNT[0] count =0x00000000
[91376.498901] CNT[0] evtsel=0x00000010
[91376.498992] CNT[1] count =0x00000000
[91376.499084] CNT[1] evtsel=0x00000011
[91376.499237] CNT[2] count =0x00000000
[91376.499328] CNT[2] evtsel=0x00000012
[91376.499420] CNT[3] count =0x00000000
[91376.499572] CNT[3] evtsel=0x00000013
[91376.499664] CNT[4] count =0x00000000
[91376.499725] CNT[4] evtsel=0x00000014
[91376.499877] CNT[5] count =0x00000000
[91376.499969] CNT[5] evtsel=0x00000015
# depmod -a; modprobe pmu_sync_sample ; sleep 1; modprobe -r pmu_sync_sample
dmesg:
[91516.869689] Found 6 counters
[91516.869781] Hello, ARM from core 0
[91516.870025] PMNC registers dump:
[91516.870117] PMNC =0x41093001
[91516.870208] CNTENS=0x8000003f
[91516.870300] INTENS=0x00000000
[91516.870452] FLAGS =0x00000000
[91516.870544] SELECT=0x00000005
[91516.870605] CCNT =0x0006532c
[91516.870697] USREN =0x00000000
[91516.870849] CNT[0] count =0x00000000
[91516.870941] CNT[0] evtsel=0x00000010
[91516.871032] CNT[1] count =0x00000000
[91516.871185] CNT[1] evtsel=0x00000011
[91516.871276] CNT[2] count =0x00000000
[91516.871368] CNT[2] evtsel=0x00000012
[91516.871520] CNT[3] count =0x00000000
[91516.871612] CNT[3] evtsel=0x00000013
[91516.871704] CNT[4] count =0x00000000
[91516.871795] CNT[4] evtsel=0x00000014
[91516.871948] CNT[5] count =0x00000000
[91516.872039] CNT[5] evtsel=0x00000015
[91516.872131] Hello, ARM from core 1
[91516.872283] PMNC registers dump:
[91516.872375] PMNC =0x41093001
[91516.872467] CNTENS=0x8000003f
[91516.872528] INTENS=0x00000000
[91516.872680] FLAGS =0x00000000
[91516.872772] SELECT=0x00000005
[91516.872863] CCNT =0x000638eb
[91516.873016] USREN =0x00000000
[91516.873107] CNT[0] count =0x00000000
[91516.873199] CNT[0] evtsel=0x00000010
[91516.873291] CNT[1] count =0x00000000
[91516.873443] CNT[1] evtsel=0x00000011
[91516.873535] CNT[2] count =0x00000000
[91516.873626] CNT[2] evtsel=0x00000012
[91516.873779] CNT[3] count =0x00000000
[91516.873840] CNT[3] evtsel=0x00000013
[91516.873931] CNT[4] count =0x00000000
[91516.874084] CNT[4] evtsel=0x00000014
[91516.874176] CNT[5] count =0x00000000
[91516.874267] CNT[5] evtsel=0x00000015
[91517.892883] Goodbye, ARM
[91517.893066] PMNC registers dump:
[91517.893218] PMNC =0x41093000
[91517.893402] CNTENS=0x0000003f
[91517.893707] INTENS=0x00000000
[91517.893890] FLAGS =0x00000000
[91517.894042] SELECT=0x00000000
[91517.894226] CCNT =0xe5f47fdb
[91517.894531] USREN =0x00000000
[91517.894683] CNT[0] count =0xb7fffbff
[91517.894866] CNT[0] evtsel=0x000000de
[91517.895019] CNT[1] count =0xdbf7fbf7
[91517.895355] CNT[1] evtsel=0x00000031
[91517.895507] CNT[2] count =0xbfcdeddf
[91517.895690] CNT[2] evtsel=0x000000f3
[91517.895996] CNT[3] count =0x57cce2f8
[91517.896179] CNT[3] evtsel=0x000000ef
[91517.896331] CNT[4] count =0xf4a5b6ef
[91517.896636] CNT[4] evtsel=0x000000f6
[91517.896820] CNT[5] count =0x2efbf77f
[91517.897003] CNT[5] evtsel=0x000000ff
[91517.897308] Goodbye, ARM
[91517.897491] PMNC registers dump:
[91517.897644] PMNC =0x41093000
[91517.897827] CNTENS=0x0000003f
[91517.898132] INTENS=0x00000000
[91517.898315] FLAGS =0x00000000
[91517.898468] SELECT=0x00000000
[91517.898651] CCNT =0xfdbd42dd
[91517.898956] USREN =0x00000000
[91517.899139] CNT[0] count =0xbea77fcf
[91517.899291] CNT[0] evtsel=0x000000ed
[91517.899597] CNT[1] count =0xff7bfcef
[91517.899780] CNT[1] evtsel=0x0000003a
[91517.899963] CNT[2] count =0xb731ef6e
[91517.900146] CNT[2] evtsel=0x000000d2
[91517.900451] CNT[3] count =0xe5fecdff
[91517.900634] CNT[3] evtsel=0x0000007f
[91517.900787] CNT[4] count =0x7ffaf4d6
[91517.901092] CNT[4] evtsel=0x0000007a
[91517.901275] CNT[5] count =0xbefa96fb
[91517.901458] CNT[5] evtsel=0x00000033
export ARCH=arm
export SUBARCH=arm
export CROSS_COMPILE=arm-eabi-
export PATH:=$(PWD)/../android_kernel/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$(PATH)
obj-m += pmu_sync_sample.o
pmu_sync_sample-objs := pmu_sync_sample_main.o v7_pmu.o
all:
make -C ../android_kernel/omap M=$(PWD) modules
clean:
make -C ../android_kernel/omap M=$(PWD) clean
/*
* Kernel module to use ARMv7 counters
*/
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include "v7_pmu.h"
static unsigned int num_counters = 0;
static void dump_regs(void)
{
u32 val;
unsigned int cnt;
printk(KERN_INFO "PMNC registers dump:\n");
asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
printk(KERN_INFO "PMNC =0x%08x\n", val);
asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
printk(KERN_INFO "CNTENS=0x%08x\n", val);
asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
printk(KERN_INFO "INTENS=0x%08x\n", val);
asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
printk(KERN_INFO "FLAGS =0x%08x\n", val);
asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
printk(KERN_INFO "SELECT=0x%08x\n", val);
asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
printk(KERN_INFO "CCNT =0x%08x\n", val);
asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r" (val));
printk(KERN_INFO "USREN =0x%08x\n", val);
for (cnt = 0; cnt < num_counters; cnt++) {
printk(KERN_INFO "CNT[%d] count =0x%08x\n",
cnt, read_pmn(cnt));
asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
cnt, val);
}
}
static void startCtrs(void* d) {
unsigned int i;
enable_pmu();
reset_ccnt();
reset_pmn();
printk(KERN_INFO "Hello, ARM from core %u\n", smp_processor_id());
for (i = 0; i < num_counters; i++) {
pmn_config(i, 0x10 + i);
}
enable_ccnt();
for (i = 0; i < num_counters; i++) {
enable_pmn(i);
}
dump_regs();
}
static void stopCtrs(void* d) {
unsigned int i;
printk(KERN_INFO "Goodbye, ARM\n");
disable_ccnt();
for (i = 0; i < num_counters; i++) {
disable_pmn(i);
}
dump_regs();
}
int init_module(void)
{
num_counters = getPMN();
printk(KERN_INFO "Found %u counters", num_counters);
if (num_counters > 16)
num_counters = 0;
on_each_cpu(startCtrs, NULL, 1);
return 0;
}
void cleanup_module(void)
{
// De-configure the counter
on_each_cpu(stopCtrs, NULL, 1);
}
MODULE_LICENSE("GPL");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment