diff options
author | jkoshy <jkoshy@FreeBSD.org> | 2007-12-07 08:20:17 +0000 |
---|---|---|
committer | jkoshy <jkoshy@FreeBSD.org> | 2007-12-07 08:20:17 +0000 |
commit | 72c27d71d82569aec187c30f6ff208631abc02f4 (patch) | |
tree | fa5327bc9f466a5a1b4e68e43a72d22b1b35f5e5 /sys/dev/hwpmc/hwpmc_amd.c | |
parent | 12b5f9c8c99a01b1d40e88aaa1a58ce757e68d5e (diff) | |
download | FreeBSD-src-72c27d71d82569aec187c30f6ff208631abc02f4.zip FreeBSD-src-72c27d71d82569aec187c30f6ff208631abc02f4.tar.gz |
Kernel and hwpmc(4) support for callchain capture.
Sponsored by: FreeBSD Foundation and Google Inc.
Diffstat (limited to 'sys/dev/hwpmc/hwpmc_amd.c')
-rw-r--r-- | sys/dev/hwpmc/hwpmc_amd.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c index b7cdee8..3576234 100644 --- a/sys/dev/hwpmc/hwpmc_amd.c +++ b/sys/dev/hwpmc/hwpmc_amd.c @@ -1,7 +1,11 @@ /*- - * Copyright (c) 2003-2005 Joseph Koshy + * Copyright (c) 2003-2007 Joseph Koshy + * Copyright (c) 2007 The FreeBSD Foundation * All rights reserved. * + * Portions of this software were developed by A. Joseph Koshy under + * sponsorship from the FreeBSD Foundation and Google, Inc. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -38,9 +42,9 @@ __FBSDID("$FreeBSD$"); #include <sys/smp.h> #include <sys/systm.h> +#include <machine/cpu.h> #include <machine/cpufunc.h> #include <machine/md_var.h> -#include <machine/pmc_mdep.h> #include <machine/specialreg.h> #ifdef DEBUG @@ -667,7 +671,7 @@ amd_stop_pmc(int cpu, int ri) */ static int -amd_intr(int cpu, uintptr_t eip, int usermode) +amd_intr(int cpu, struct trapframe *tf) { int i, error, retval, ri; uint32_t config, evsel, perfctr; @@ -679,8 +683,8 @@ amd_intr(int cpu, uintptr_t eip, int usermode) KASSERT(cpu >= 0 && cpu < mp_ncpus, ("[amd,%d] out of range CPU %d", __LINE__, cpu)); - PMCDBG(MDP,INT,1, "cpu=%d eip=%p um=%d", cpu, (void *) eip, - usermode); + PMCDBG(MDP,INT,1, "cpu=%d tf=0x%p um=%d", cpu, (void *) tf, + TRAPF_USERMODE(tf)); retval = 0; @@ -696,8 +700,8 @@ amd_intr(int cpu, uintptr_t eip, int usermode) * * If multiple PMCs interrupt at the same time, the AMD64 * processor appears to deliver as many NMIs as there are - * outstanding PMC interrupts. Thus we need to only process - * one interrupt at a time. + * outstanding PMC interrupts. So we process only one NMI + * interrupt at a time. */ for (i = 0; retval == 0 && i < AMD_NPMCS-1; i++) { @@ -717,9 +721,9 @@ amd_intr(int cpu, uintptr_t eip, int usermode) continue; } - retval = 1; /* found an interrupting PMC */ + retval = 1; /* Found an interrupting PMC. */ - /* stop the PMC, reload count */ + /* Stop the PMC, reload count. */ evsel = AMD_PMC_EVSEL_0 + i; perfctr = AMD_PMC_PERFCTR_0 + i; v = pm->pm_sc.pm_reloadcount; @@ -733,8 +737,8 @@ amd_intr(int cpu, uintptr_t eip, int usermode) wrmsr(evsel, config & ~AMD_PMC_ENABLE); wrmsr(perfctr, AMD_RELOAD_COUNT_TO_PERFCTR_VALUE(v)); - /* restart the counter if there was no error during logging */ - error = pmc_process_interrupt(cpu, pm, eip, usermode); + /* Restart the counter if logging succeeded. */ + error = pmc_process_interrupt(cpu, pm, tf, TRAPF_USERMODE(tf)); if (error == 0) wrmsr(evsel, config | AMD_PMC_ENABLE); } @@ -742,7 +746,7 @@ amd_intr(int cpu, uintptr_t eip, int usermode) atomic_add_int(retval ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); - return retval; + return (retval); } /* |