1 #include "pmu.h" 2 3 struct pmu_caps pmu; 4 5 void pmu_init(void) 6 { 7 struct cpuid cpuid_10 = cpuid(10); 8 9 pmu.is_intel = is_intel(); 10 11 if (!pmu.is_intel) 12 return; 13 14 pmu.version = cpuid_10.a & 0xff; 15 16 if (pmu.version > 1) { 17 pmu.nr_fixed_counters = cpuid_10.d & 0x1f; 18 pmu.fixed_counter_width = (cpuid_10.d >> 5) & 0xff; 19 } 20 21 pmu.nr_gp_counters = (cpuid_10.a >> 8) & 0xff; 22 pmu.gp_counter_width = (cpuid_10.a >> 16) & 0xff; 23 pmu.gp_counter_mask_length = (cpuid_10.a >> 24) & 0xff; 24 25 /* CPUID.0xA.EBX bit is '1' if a counter is NOT available. */ 26 pmu.gp_counter_available = ~cpuid_10.b; 27 28 if (this_cpu_has(X86_FEATURE_PDCM)) 29 pmu.perf_cap = rdmsr(MSR_IA32_PERF_CAPABILITIES); 30 pmu.msr_gp_counter_base = MSR_IA32_PERFCTR0; 31 pmu.msr_gp_event_select_base = MSR_P6_EVNTSEL0; 32 33 if (this_cpu_has_perf_global_status()) { 34 pmu.msr_global_status = MSR_CORE_PERF_GLOBAL_STATUS; 35 pmu.msr_global_ctl = MSR_CORE_PERF_GLOBAL_CTRL; 36 pmu.msr_global_status_clr = MSR_CORE_PERF_GLOBAL_OVF_CTRL; 37 } 38 39 pmu_reset_all_counters(); 40 } 41