summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhibbits <jhibbits@FreeBSD.org>2014-01-15 04:44:52 +0000
committerjhibbits <jhibbits@FreeBSD.org>2014-01-15 04:44:52 +0000
commit44cab258a2754ab2d2c9af0fabd9cd6bda591fb9 (patch)
tree048cb1fc6ec8e56ad4e20840906010e1603ef4d9
parent541949d319d897c3c628f5879ce9628087d2b581 (diff)
downloadFreeBSD-src-44cab258a2754ab2d2c9af0fabd9cd6bda591fb9.zip
FreeBSD-src-44cab258a2754ab2d2c9af0fabd9cd6bda591fb9.tar.gz
MFC r259394,r259395,r259699
r259394: Rebase the PMC indices at 1, since PMC_SOFT is at 0. r259395,r259699: Add userland PMC backtracing, and use the PMC trapframe macros for kernel backtraces.
-rw-r--r--sys/dev/hwpmc/hwpmc_powerpc.c25
-rw-r--r--sys/powerpc/include/pmc_mdep.h8
2 files changed, 22 insertions, 11 deletions
diff --git a/sys/dev/hwpmc/hwpmc_powerpc.c b/sys/dev/hwpmc/hwpmc_powerpc.c
index 25a32fa..ed1f023 100644
--- a/sys/dev/hwpmc/hwpmc_powerpc.c
+++ b/sys/dev/hwpmc/hwpmc_powerpc.c
@@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$");
#define INKERNEL(x) (((vm_offset_t)(x)) <= VM_MAX_KERNEL_ADDRESS && \
((vm_offset_t)(x)) >= VM_MIN_KERNEL_ADDRESS)
+#define INUSER(x) (((vm_offset_t)(x)) <= VM_MAXUSER_ADDRESS && \
+ ((vm_offset_t)(x)) >= VM_MIN_ADDRESS)
struct powerpc_cpu **powerpc_pcpu;
@@ -55,13 +57,13 @@ pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples,
int frames = 0;
uintptr_t *sp;
- cc[frames++] = tf->srr0;
- sp = (uintptr_t *)tf->fixreg[1];
+ cc[frames++] = PMC_TRAPFRAME_TO_PC(tf);
+ sp = (uintptr_t *)PMC_TRAPFRAME_TO_FP(tf);
for (frames = 1; frames < maxsamples; frames++) {
if (!INKERNEL(sp))
break;
- cc[frames++] = *(sp + 1);
+ cc[frames++] = sp[1];
sp = (uintptr_t *)*sp;
}
return (frames);
@@ -172,8 +174,17 @@ int
pmc_save_user_callchain(uintptr_t *cc, int maxsamples,
struct trapframe *tf)
{
- (void) cc;
- (void) maxsamples;
- (void) tf;
- return (0);
+ uintptr_t *sp;
+ int frames = 0;
+
+ cc[frames++] = PMC_TRAPFRAME_TO_PC(tf);
+ sp = (uintptr_t *)PMC_TRAPFRAME_TO_FP(tf);
+
+ for (frames = 1; frames < maxsamples; frames++) {
+ if (!INUSER(sp))
+ break;
+ cc[frames++] = fuword(sp + 1);
+ sp = (uintptr_t *)fuword(sp);
+ }
+ return (frames);
}
diff --git a/sys/powerpc/include/pmc_mdep.h b/sys/powerpc/include/pmc_mdep.h
index 678852b..a0f2062 100644
--- a/sys/powerpc/include/pmc_mdep.h
+++ b/sys/powerpc/include/pmc_mdep.h
@@ -7,8 +7,8 @@
#ifndef _MACHINE_PMC_MDEP_H_
#define _MACHINE_PMC_MDEP_H_
-#define PMC_MDEP_CLASS_INDEX_PPC7450 0
-#define PMC_MDEP_CLASS_INDEX_PPC970 0
+#define PMC_MDEP_CLASS_INDEX_PPC7450 1
+#define PMC_MDEP_CLASS_INDEX_PPC970 1
union pmc_md_op_pmcallocate {
uint64_t __pad[4];
@@ -28,8 +28,8 @@ union pmc_md_pmc {
struct pmc_md_powerpc_pmc pm_powerpc;
};
-#define PMC_TRAPFRAME_TO_PC(TF) (0) /* Stubs */
-#define PMC_TRAPFRAME_TO_FP(TF) (0)
+#define PMC_TRAPFRAME_TO_PC(TF) ((TF)->srr0)
+#define PMC_TRAPFRAME_TO_FP(TF) ((TF)->fixreg[1])
#define PMC_TRAPFRAME_TO_SP(TF) (0)
#endif
OpenPOWER on IntegriCloud