diff options
author | fabient <fabient@FreeBSD.org> | 2012-05-23 13:23:40 +0000 |
---|---|---|
committer | fabient <fabient@FreeBSD.org> | 2012-05-23 13:23:40 +0000 |
commit | be5bfc030892300b830d9ec66dedf914f18f7c56 (patch) | |
tree | 2a58b21b51fcdbd56f399d0d54582aff8004ba40 | |
parent | ea96526248e89c13c464597f4973614e622c1e5c (diff) | |
download | FreeBSD-src-be5bfc030892300b830d9ec66dedf914f18f7c56.zip FreeBSD-src-be5bfc030892300b830d9ec66dedf914f18f7c56.tar.gz |
Soft PMC support for ARM.
Callgraph is not captured, only current location.
Sample system wide profiling: "pmcstat -Sclock.hard -T"
-rw-r--r-- | sys/arm/arm/machdep.c | 6 | ||||
-rw-r--r-- | sys/arm/include/pmc_mdep.h | 6 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_arm.c | 25 |
3 files changed, 26 insertions, 11 deletions
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index abd04a7..1ec4bc4 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -674,9 +674,9 @@ fake_preload_metadata(void) static uint32_t fake_preload[35]; fake_preload[i++] = MODINFO_NAME; - fake_preload[i++] = strlen("elf kernel") + 1; - strcpy((char*)&fake_preload[i++], "elf kernel"); - i += 2; + fake_preload[i++] = strlen("kernel") + 1; + strcpy((char*)&fake_preload[i++], "kernel"); + i += 1; fake_preload[i++] = MODINFO_TYPE; fake_preload[i++] = strlen("elf kernel") + 1; strcpy((char*)&fake_preload[i++], "elf kernel"); diff --git a/sys/arm/include/pmc_mdep.h b/sys/arm/include/pmc_mdep.h index 185fbd1..ab08d36 100644 --- a/sys/arm/include/pmc_mdep.h +++ b/sys/arm/include/pmc_mdep.h @@ -54,6 +54,12 @@ union pmc_md_pmc { #define PMC_TRAPFRAME_TO_FP(TF) ((TF)->tf_usr_lr) #define PMC_TRAPFRAME_TO_SP(TF) ((TF)->tf_usr_sp) +/* Build a fake kernel trapframe from current instruction pointer. */ +#define PMC_FAKE_TRAPFRAME(TF) \ + do { \ + __asm __volatile("mov %0, pc" : "=r" ((TF)->tf_pc)); \ + } while (0) + /* * Prototypes */ diff --git a/sys/dev/hwpmc/hwpmc_arm.c b/sys/dev/hwpmc/hwpmc_arm.c index 86cfaf3..fc76165 100644 --- a/sys/dev/hwpmc/hwpmc_arm.c +++ b/sys/dev/hwpmc/hwpmc_arm.c @@ -38,38 +38,47 @@ __FBSDID("$FreeBSD$"); struct pmc_mdep * pmc_md_initialize() { +#ifdef CPU_XSCALE_IXP425 if (cpu_class == CPU_CLASS_XSCALE) return pmc_xscale_initialize(); else +#endif return NULL; } void pmc_md_finalize(struct pmc_mdep *md) { +#ifdef CPU_XSCALE_IXP425 if (cpu_class == CPU_CLASS_XSCALE) pmc_xscale_finalize(md); else KASSERT(0, ("[arm,%d] Unknown CPU Class 0x%x", __LINE__, cpu_class)); +#endif +} + +static int +pmc_save_callchain(uintptr_t *cc, int maxsamples, + struct trapframe *tf) +{ + + *cc = PMC_TRAPFRAME_TO_PC(tf); + return (1); } int pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples, struct trapframe *tf) { - (void) cc; - (void) maxsamples; - (void) tf; - return (0); + + return pmc_save_callchain(cc, maxsamples, tf); } int pmc_save_user_callchain(uintptr_t *cc, int maxsamples, struct trapframe *tf) { - (void) cc; - (void) maxsamples; - (void) tf; - return (0); + + return pmc_save_callchain(cc, maxsamples, tf); } |