On Sun, Dec 27, 2020 at 07:48:58PM +0000, James Cook wrote:
> > from your earlier bsd.mp dmesg:
> > 
> > cpu0: Enhanced SpeedStep 16268 MHz: speeds: 1601, 1600, 1500, 1400, 1300, 
> > 1200, 1100, 1000, 900, 800, 700, 600, 500, 400 MHz
> > 
> > 1601 is variable/turbo speed the others are fixed.  When running in
> > turbo mode getting the current frequency involves msrs which
> > hw.cpuspeed doesn't do. The initial 'x MHz:' is from cpuspeed not from
> > the acpi table.
> > 
> > On modern machines these values are from acpicpu(4)/acpi _PSS.
> > 
> > Can you show the output of running with the following diff to dump the
> > performance counter control values?
> > 
> > MSR_PERF_FIXED_CTR_CTRL 0x38d 
> > MSR_PERF_GLOBAL_CTRL 0x38f
> > 
> > on a broadwell laptop this shows
> > 
> > cpu0 cpu_freq_ctr cpuid 0x0a eax 0x7300403 ebx 0x0 ecx 0x0 edx 0x603
> > cpu0 cpu_freq_ctr perf ver 3 gp ctrs 4 fixed 3
> > cpu0 cpu_freq_ctr MSR_PERF_FIXED_CTR_CTRL 0x0
> > cpu0 cpu_freq_ctr MSR_PERF_GLOBAL_CTRL 0xf
> > cpu1 cpu_freq_ctr cpuid 0x0a eax 0x7300403 ebx 0x0 ecx 0x0 edx 0x603
> > cpu1 cpu_freq_ctr perf ver 3 gp ctrs 4 fixed 3
> > cpu1 cpu_freq_ctr MSR_PERF_FIXED_CTR_CTRL 0x0
> > cpu1 cpu_freq_ctr MSR_PERF_GLOBAL_CTRL 0xf
> > cpu2 cpu_freq_ctr cpuid 0x0a eax 0x7300403 ebx 0x0 ecx 0x0 edx 0x603
> > cpu2 cpu_freq_ctr perf ver 3 gp ctrs 4 fixed 3
> > cpu2 cpu_freq_ctr MSR_PERF_FIXED_CTR_CTRL 0x0
> > cpu2 cpu_freq_ctr MSR_PERF_GLOBAL_CTRL 0xf
> > cpu3 cpu_freq_ctr cpuid 0x0a eax 0x7300403 ebx 0x0 ecx 0x0 edx 0x603
> > cpu3 cpu_freq_ctr perf ver 3 gp ctrs 4 fixed 3
> > cpu3 cpu_freq_ctr MSR_PERF_FIXED_CTR_CTRL 0x0
> > cpu3 cpu_freq_ctr MSR_PERF_GLOBAL_CTRL 0xf
> 
> Here's dmesg with that patch.

Thanks, here is another diff to try.  It sets the bit to be enabled
not just for ring 0, fixes clearing a value and shows the values
read out of the counter.

Index: sys/arch/amd64/amd64/identcpu.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/identcpu.c,v
retrieving revision 1.117
diff -u -p -r1.117 identcpu.c
--- sys/arch/amd64/amd64/identcpu.c     13 Sep 2020 05:57:28 -0000      1.117
+++ sys/arch/amd64/amd64/identcpu.c     28 Dec 2020 02:03:27 -0000
@@ -411,6 +411,9 @@ via_update_sensor(void *args)
 }
 #endif
 
+#define MSR_PERF_GLOBAL_STATUS 0x38e
+#define MSR_PERF_GLOBAL_INUSE 0x392
+
 uint64_t
 cpu_freq_ctr(struct cpu_info *ci)
 {
@@ -421,13 +424,22 @@ cpu_freq_ctr(struct cpu_info *ci)
            CPUIDEDX_NUM_FC(cpu_perf_edx) <= 1)
                return (0);
 
+       if ((cpu_perf_eax & CPUIDEAX_VERID) > 3) {
+               msr = rdmsr(MSR_PERF_GLOBAL_INUSE);
+               printf("%s %s MSR_PERF_GLOBAL_INUSE 0x%llx\n", 
ci->ci_dev->dv_xname,
+                   __func__, msr);
+       }
+       msr = rdmsr(MSR_PERF_GLOBAL_STATUS);
+       printf("%s %s MSR_PERF_GLOBAL_STATUS before 0x%llx\n", 
ci->ci_dev->dv_xname,
+           __func__, msr);
+
        msr = rdmsr(MSR_PERF_FIXED_CTR_CTRL);
        if (msr & MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_MASK)) {
                /* some hypervisor is dicking us around */
                return (0);
        }
 
-       msr |= MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_1);
+       msr |= MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_ANY);
        wrmsr(MSR_PERF_FIXED_CTR_CTRL, msr);
 
        msr = rdmsr(MSR_PERF_GLOBAL_CTRL) | MSR_PERF_GLOBAL_CTR1_EN;
@@ -437,13 +449,20 @@ cpu_freq_ctr(struct cpu_info *ci)
        delay(100000);
        count = rdmsr(MSR_PERF_FIXED_CTR1);
 
+       msr = rdmsr(MSR_PERF_GLOBAL_STATUS);
+       printf("%s %s MSR_PERF_GLOBAL_STATUS after 0x%llx\n", 
ci->ci_dev->dv_xname,
+           __func__, msr);
+
        msr = rdmsr(MSR_PERF_FIXED_CTR_CTRL);
-       msr &= MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_MASK);
+       msr &= ~MSR_PERF_FIXED_CTR_FC(1, MSR_PERF_FIXED_CTR_FC_MASK);
        wrmsr(MSR_PERF_FIXED_CTR_CTRL, msr);
 
        msr = rdmsr(MSR_PERF_GLOBAL_CTRL);
        msr &= ~MSR_PERF_GLOBAL_CTR1_EN;
        wrmsr(MSR_PERF_GLOBAL_CTRL, msr);
+
+       printf("%s %s count %lld last_count %lld freq %lld\n", 
ci->ci_dev->dv_xname,
+           __func__, count, last_count, ((count - last_count) * 10));
 
        return ((count - last_count) * 10);
 }

Reply via email to