diff --git a/dev/hwpmc/hwpmc_core.c b/dev/hwpmc/hwpmc_core.c index 2956e14..0aaecee 100644 --- a/dev/hwpmc/hwpmc_core.c +++ b/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) @@ -2353,7 +2354,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); } @@ -2485,19 +2486,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); } @@ -2580,7 +2582,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; @@ -2694,7 +2696,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); } /* @@ -2742,6 +2744,16 @@ pmc_core_initialize(struct pmc_mdep *md, int maxcpu) 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_cputype = md->pmd_cputype; core_pmcmask = 0; diff --git a/dev/hwpmc/hwpmc_core.h b/dev/hwpmc/hwpmc_core.h index 45f75cf..b0e34a5 100644 --- a/dev/hwpmc/hwpmc_core.h +++ b/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. diff --git a/dev/hwpmc/hwpmc_mod.c b/dev/hwpmc/hwpmc_mod.c index dd9b070..705e4ed 100644 --- a/dev/hwpmc/hwpmc_mod.c +++ b/dev/hwpmc/hwpmc_mod.c @@ -1453,7 +1453,7 @@ pmc_process_csw_out(struct thread *td) * increasing monotonically, modulo a 64 * bit wraparound. */ - KASSERT((int64_t) tmp >= 0, + KASSERT(tmp >= 0, ("[pmc,%d] negative increment cpu=%d " "ri=%d newvalue=%jx saved=%jx " "incr=%jx", __LINE__, cpu, ri, diff --git a/sys/pmc.h b/sys/pmc.h index 2c6517a..cd380d7 100644 --- a/sys/pmc.h +++ b/sys/pmc.h @@ -1011,7 +1011,7 @@ extern struct pmc_debugflags pmc_debugflags; #define KTR_PMC KTR_SUBSYS #define PMC_DEBUG_STRSIZE 128 -#define PMC_DEBUG_DEFAULT_FLAGS { 0, 0, 0, 0, 0, 0, 0, 0 } +#define PMC_DEBUG_DEFAULT_FLAGS { 0, 0, 0, 0, 0, 0, 0, 0, 0 } #define PMCDBG0(M, N, L, F) do { \ if (pmc_debugflags.pdb_ ## M & (1 << PMC_DEBUG_MIN_ ## N)) \