From be5bfc030892300b830d9ec66dedf914f18f7c56 Mon Sep 17 00:00:00 2001 From: fabient Date: Wed, 23 May 2012 13:23:40 +0000 Subject: [PATCH] Soft PMC support for ARM. Callgraph is not captured, only current location. Sample system wide profiling: "pmcstat -Sclock.hard -T" --- sys/arm/arm/machdep.c | 6 +++--- sys/arm/include/pmc_mdep.h | 6 ++++++ 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 abd04a7f6574..1ec4bc41bedf 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 185fbd1744c0..ab08d3664486 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 86cfaf3cd93a..fc7616542185 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); }