summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2016-02-12 07:27:24 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2016-02-12 07:27:24 +0000
commit411c83ccd691eec84686df54c5cc7ee3cdbeb265 (patch)
tree03b7658a0a050f361c040e69c7caca92eb3b1e78
parent70c1d5a32a1aac6fc6541fc4097cdc69b4dc4fc1 (diff)
Notes
-rw-r--r--sys/dev/hwpmc/hwpmc_core.c36
-rw-r--r--sys/dev/hwpmc/hwpmc_core.h9
2 files changed, 34 insertions, 11 deletions
diff --git a/sys/dev/hwpmc/hwpmc_core.c b/sys/dev/hwpmc/hwpmc_core.c
index d26c9655a78c8..f092a21d374c0 100644
--- a/sys/dev/hwpmc/hwpmc_core.c
+++ b/sys/dev/hwpmc/hwpmc_core.c
@@ -103,6 +103,7 @@ static int core_iaf_npmc;
static int core_iap_width;
static int core_iap_npmc;
+static int core_iap_wroffset;
static int
core_pcpu_noop(struct pmc_mdep *md, int cpu)
@@ -2473,7 +2474,7 @@ iap_read_pmc(int cpu, int ri, pmc_value_t *v)
*v = tmp & ((1ULL << core_iap_width) - 1);
PMCDBG4(MDP,REA,1, "iap-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri,
- ri, *v);
+ IAP_PMC0 + ri, *v);
return (0);
}
@@ -2605,19 +2606,20 @@ iap_write_pmc(int cpu, int ri, pmc_value_t v)
("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__,
cpu, ri));
- PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
- IAP_PMC0 + ri, v);
-
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
v = iap_reload_count_to_perfctr_value(v);
- /*
- * Write the new value to the counter. The counter will be in
- * a stopped state when the pcd_write() entry point is called.
- */
+ v &= (1ULL << core_iap_width) - 1;
- wrmsr(IAP_PMC0 + ri, v & ((1ULL << core_iap_width) - 1));
+ PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri,
+ IAP_PMC0 + ri, v);
+ /*
+ * Write the new value to the counter (or it's alias). The
+ * counter will be in a stopped state when the pcd_write()
+ * entry point is called.
+ */
+ wrmsr(core_iap_wroffset + IAP_PMC0 + ri, v);
return (0);
}
@@ -2700,7 +2702,7 @@ core_intr(int cpu, struct trapframe *tf)
*/
msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK;
wrmsr(IAP_EVSEL0 + ri, msr);
- wrmsr(IAP_PMC0 + ri, v);
+ wrmsr(core_iap_wroffset + IAP_PMC0 + ri, v);
if (error)
continue;
@@ -2814,7 +2816,7 @@ core2_intr(int cpu, struct trapframe *tf)
(uintmax_t) v);
/* Reload sampling count. */
- wrmsr(IAP_PMC0 + n, v);
+ wrmsr(core_iap_wroffset + IAP_PMC0 + n, v);
}
/*
@@ -2865,6 +2867,18 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu, int version_override)
return (EPROGMISMATCH);
}
+ core_iap_wroffset = 0;
+ if (cpu_feature2 & CPUID2_PDCM) {
+ if (rdmsr(IA32_PERF_CAPABILITIES) & PERFCAP_FW_WRITE) {
+ PMCDBG0(MDP, INI, 1,
+ "core-init full-width write supported");
+ core_iap_wroffset = IAP_A_PMC0 - IAP_PMC0;
+ } else
+ PMCDBG0(MDP, INI, 1,
+ "core-init full-width write NOT supported");
+ } else
+ PMCDBG0(MDP, INI, 1, "core-init pdcm not supported");
+
core_pmcmask = 0;
/*
diff --git a/sys/dev/hwpmc/hwpmc_core.h b/sys/dev/hwpmc/hwpmc_core.h
index 63b6d02d32ede..7196d9dfb1fa9 100644
--- a/sys/dev/hwpmc/hwpmc_core.h
+++ b/sys/dev/hwpmc/hwpmc_core.h
@@ -29,6 +29,14 @@
#ifndef _DEV_HWPMC_CORE_H_
#define _DEV_HWPMC_CORE_H_ 1
+#define IA32_PERF_CAPABILITIES 0x345
+#define PERFCAP_LBR_FORMAT 0x003f
+#define PERFCAP_PEBS_TRAP 0x0040
+#define PERFCAP_PEBS_SAVEARCH 0x0080
+#define PERFCAP_PEBS_RECFORMAT 0x0f00
+#define PERFCAP_SMM_FREEZE 0x1000
+#define PERFCAP_FW_WRITE 0x2000 /* full width write aliases */
+
/*
* Fixed-function PMCs.
*/
@@ -101,6 +109,7 @@ struct pmc_md_iap_op_pmcallocate {
*/
#define IAP_PMC0 0x0C1
+#define IAP_A_PMC0 0x4C1
/*
* IAP_EVSEL(n) is laid out in the following way.