@@ -690,4 +690,58 @@ static inline bool cpuid_osxsave(void)
return cpuid(1).c & (1 << (X86_FEATURE_OSXSAVE % 32));
}
+static inline u8 pmu_version(void)
+{
+ return cpuid(10).a & 0xff;
+}
+
+static inline u32 pmu_arch_info(void)
+{
+ return cpuid(10).a;
+}
+
+static inline u32 pmu_gp_events(void)
+{
+ return cpuid(10).b;
+}
+
+static inline u32 pmu_fixed_counters(void)
+{
+ return cpuid(10).d;
+}
+
+static inline u8 pmu_gp_counter_number(void)
+{
+ return (cpuid(10).a >> 8) & 0xff;
+}
+
+static inline u8 pmu_gp_counter_width(void)
+{
+ return (cpuid(10).a >> 16) & 0xff;
+}
+
+static inline u8 pmu_gp_counter_mask_length(void)
+{
+ return (cpuid(10).a >> 24) & 0xff;
+}
+
+static inline u8 pmu_fixed_counter_number(void)
+{
+ struct cpuid id = cpuid(10);
+
+ if ((id.a & 0xff) > 1)
+ return id.d & 0x1f;
+ else
+ return 0;
+}
+
+static inline u8 pmu_fixed_counter_width(void)
+{
+ struct cpuid id = cpuid(10);
+
+ if ((id.a & 0xff) > 1)
+ return (id.d >> 5) & 0xff;
+ else
+ return 0;
+}
#endif
@@ -655,34 +655,32 @@ static void set_ref_cycle_expectations(void)
int main(int ac, char **av)
{
- struct cpuid id = cpuid(10);
-
setup_vm();
handle_irq(PC_VECTOR, cnt_overflow);
buf = malloc(N*64);
- eax.full = id.a;
- ebx.full = id.b;
- edx.full = id.d;
+ eax.full = pmu_arch_info();
+ ebx.full = pmu_gp_events();
+ edx.full = pmu_fixed_counters();
- if (!eax.split.version_id) {
- printf("No pmu is detected!\n");
+ if (!pmu_version()) {
+ report_skip("No pmu is detected!");
return report_summary();
}
- if (eax.split.version_id == 1) {
- printf("PMU version 1 is not supported\n");
+ if (pmu_version() == 1) {
+ report_skip("PMU version 1 is not supported.");
return report_summary();
}
set_ref_cycle_expectations();
- printf("PMU version: %d\n", eax.split.version_id);
- printf("GP counters: %d\n", eax.split.num_counters);
- printf("GP counter width: %d\n", eax.split.bit_width);
- printf("Mask length: %d\n", eax.split.mask_length);
- printf("Fixed counters: %d\n", edx.split.num_counters_fixed);
- printf("Fixed counter width: %d\n", edx.split.bit_width_fixed);
+ printf("PMU version: %d\n", pmu_version());
+ printf("GP counters: %d\n", pmu_gp_counter_number());
+ printf("GP counter width: %d\n", pmu_gp_counter_width());
+ printf("Mask length: %d\n", pmu_gp_counter_mask_length());
+ printf("Fixed counters: %d\n", pmu_fixed_counter_number());
+ printf("Fixed counter width: %d\n", pmu_fixed_counter_width());
num_counters = eax.split.num_counters;
Platform pmu fixed counter and GP events info is enumerated in CPUID(0xA). Add helpers to fetch the data, other apps can also rely them to check underneath pmu capabilities. No functional change intended. Signed-off-by: Yang Weijiang <weijiang.yang@intel.com> --- lib/x86/processor.h | 54 +++++++++++++++++++++++++++++++++++++++++++++ x86/pmu.c | 28 +++++++++++------------ 2 files changed, 67 insertions(+), 15 deletions(-)