@@ -24,29 +24,72 @@ const (
2424 CPUID_PROCESSOR_FREQUENCY = 0x16
2525)
2626
27+ type CpuExtendedFamily uint16
28+
29+ const (
30+ // AMD
31+ CPU_FAMILY_AMD_11H CpuExtendedFamily = 0x11
32+ // Intel
33+ CPU_FAMILY_INTEL_CORE CpuExtendedFamily = 6
34+ CPU_MODEL_NEHALEM CpuExtendedFamily = 0x1e
35+ CPU_MODEL_NEHALEM_EP CpuExtendedFamily = 0x1a
36+ CPU_MODEL_NEHALEM_EX CpuExtendedFamily = 0x2e
37+ CPU_MODEL_WESTMERE CpuExtendedFamily = 0x25
38+ CPU_MODEL_WESTMERE_EP CpuExtendedFamily = 0x2c
39+ CPU_MODEL_WESTMERE_EX CpuExtendedFamily = 0x2f
40+ CPU_MODEL_SANDYBRIDGE CpuExtendedFamily = 0x2a
41+ CPU_MODEL_SANDYBRIDGE_EP CpuExtendedFamily = 0x2d
42+ CPU_MODEL_IVYBRIDGE_EP CpuExtendedFamily = 0x3a
43+ CPU_MODEL_HASWELL_E3 CpuExtendedFamily = 0x3c
44+ CPU_MODEL_HASWELL_E7 CpuExtendedFamily = 0x3f
45+ CPU_MODEL_BROADWELL CpuExtendedFamily = 0x3d
46+ )
47+
48+ func GetExtendedCpuFamily () CpuExtendedFamily {
49+ var family CpuExtendedFamily
50+ family = CpuExtendedFamily ((stdCpuid1Eax >> 8 ) & 0x0f )
51+ family += CpuExtendedFamily ((stdCpuid1Eax >> 20 ) & 0xff )
52+ return family
53+ }
54+
2755//export asmPause
2856func AsmPause ()
2957
3058//export asmReadRdtsc
3159func AsmReadRdtsc () uint64
3260
3361//export asmCpuid
34- func AsmCpuid (index uint32 , registerEax * uint32 , registerRbx * uint32 , registerEcx * uint32 , registerEdx * uint32 ) int
62+ func AsmCpuid (index uint32 , registerEax * uint32 , registerEbx * uint32 , registerEcx * uint32 , registerEdx * uint32 ) int
3563
3664var maxCpuidIndex uint32
65+ var stdVendorName0 uint32
66+ var stdCpuid1Eax uint32
67+ var stdCpuid1Ebx uint32
68+ var stdCpuid1Ecx uint32
69+ var stdCpuid1Edx uint32
3770
3871func init () {
39- AsmCpuid (0 , & maxCpuidIndex , nil , nil , nil )
72+ AsmCpuid (0 , & maxCpuidIndex , & stdVendorName0 , nil , nil )
73+ AsmCpuid (1 , & stdCpuid1Eax , & stdCpuid1Ebx , & stdCpuid1Ecx , & stdCpuid1Edx )
4074}
4175
4276func GetMaxCpuidIndex () uint32 {
4377 return maxCpuidIndex
4478}
4579
46- func InternalGetPerformanceCounterFrequency () uint64 {
47- //FIXME: how to find it?
48- //See https://github.com/torvalds/linux/blob/master/arch/x86/kernel/tsc.c
80+ func IsIntel () bool {
81+ return stdVendorName0 == 0x756e6547
82+ }
83+
84+ func IsIntelFamilyCore () bool {
85+ return IsIntel () && GetExtendedCpuFamily () == CPU_FAMILY_INTEL_CORE
86+ }
4987
88+ func IsAmd () bool {
89+ return stdVendorName0 == 0x68747541
90+ }
91+
92+ func InternalGetPerformanceCounterFrequency () uint64 {
5093 if maxCpuidIndex >= CPUID_TIME_STAMP_COUNTER {
5194 return CpuidCoreClockCalculateTscFrequency ()
5295 }
@@ -73,9 +116,21 @@ func CpuidCoreClockCalculateTscFrequency() uint64 {
73116 //
74117 if RegEcx == 0 {
75118 // Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Frequency.
76- // Intel Xeon Processor Scalable Family with CPUID signature 06_55H = 25000000 (25MHz)
77- // 6th and 7th generation Intel Core processors and Intel Xeon W Processor Family = 24000000 (24MHz)
78- // Intel Atom processors based on Goldmont Microarchitecture with CPUID signature 06_5CH = 19200000 (19.2MHz)
119+ // https://github.com/torvalds/linux/blob/master/tools/power/x86/turbostat/turbostat.c
120+ if IsIntelFamilyCore () {
121+ switch GetExtendedCpuFamily () {
122+ case 0x5F : // INTEL_FAM6_ATOM_GOLDMONT_D
123+ CoreXtalFrequency = 25000000
124+ case 0x5C : // INTEL_FAM6_ATOM_GOLDMONT
125+ CoreXtalFrequency = 19200000
126+ case 0x7A : // INTEL_FAM6_ATOM_GOLDMONT_PLUS
127+ CoreXtalFrequency = 19200000
128+ default :
129+ return 0
130+ }
131+ } else {
132+ return 0
133+ }
79134 CoreXtalFrequency = 24000000
80135 } else {
81136 CoreXtalFrequency = uint64 (RegEcx )
0 commit comments