1 #include "pmu.h" 2 3 struct pmu_caps pmu; 4 5 void pmu_init(void) 6 { 7 pmu.is_intel = is_intel(); 8 9 if (pmu.is_intel) { 10 struct cpuid cpuid_10 = cpuid(10); 11 12 pmu.version = cpuid_10.a & 0xff; 13 14 if (pmu.version > 1) { 15 pmu.nr_fixed_counters = cpuid_10.d & 0x1f; 16 pmu.fixed_counter_width = (cpuid_10.d >> 5) & 0xff; 17 } 18 19 if (pmu.version > 1) { 20 pmu.nr_fixed_counters = cpuid_10.d & 0x1f; 21 pmu.fixed_counter_width = (cpuid_10.d >> 5) & 0xff; 22 } 23 24 pmu.nr_gp_counters = (cpuid_10.a >> 8) & 0xff; 25 pmu.gp_counter_width = (cpuid_10.a >> 16) & 0xff; 26 pmu.gp_counter_mask_length = (cpuid_10.a >> 24) & 0xff; 27 28 /* CPUID.0xA.EBX bit is '1' if a counter is NOT available. */ 29 pmu.gp_counter_available = ~cpuid_10.b; 30 31 if (this_cpu_has(X86_FEATURE_PDCM)) 32 pmu.perf_cap = rdmsr(MSR_IA32_PERF_CAPABILITIES); 33 pmu.msr_gp_counter_base = MSR_IA32_PERFCTR0; 34 pmu.msr_gp_event_select_base = MSR_P6_EVNTSEL0; 35 36 if (this_cpu_has_perf_global_status()) { 37 pmu.msr_global_status = MSR_CORE_PERF_GLOBAL_STATUS; 38 pmu.msr_global_ctl = MSR_CORE_PERF_GLOBAL_CTRL; 39 pmu.msr_global_status_clr = MSR_CORE_PERF_GLOBAL_OVF_CTRL; 40 } 41 } else { 42 if (this_cpu_has(X86_FEATURE_PERFCTR_CORE)) { 43 /* Performance Monitoring Version 2 Supported */ 44 if (this_cpu_has(X86_FEATURE_AMD_PMU_V2)) { 45 pmu.version = 2; 46 pmu.nr_gp_counters = cpuid(0x80000022).b & 0xf; 47 } else { 48 pmu.nr_gp_counters = AMD64_NUM_COUNTERS_CORE; 49 } 50 pmu.msr_gp_counter_base = MSR_F15H_PERF_CTR0; 51 pmu.msr_gp_event_select_base = MSR_F15H_PERF_CTL0; 52 } else { 53 pmu.nr_gp_counters = AMD64_NUM_COUNTERS; 54 pmu.msr_gp_counter_base = MSR_K7_PERFCTR0; 55 pmu.msr_gp_event_select_base = MSR_K7_EVNTSEL0; 56 } 57 pmu.gp_counter_width = PMC_DEFAULT_WIDTH; 58 pmu.gp_counter_mask_length = pmu.nr_gp_counters; 59 pmu.gp_counter_available = (1u << pmu.nr_gp_counters) - 1; 60 61 if (this_cpu_has_perf_global_status()) { 62 pmu.msr_global_status = MSR_AMD64_PERF_CNTR_GLOBAL_STATUS; 63 pmu.msr_global_ctl = MSR_AMD64_PERF_CNTR_GLOBAL_CTL; 64 pmu.msr_global_status_clr = MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR; 65 } 66 } 67 68 pmu_reset_all_counters(); 69 } 70