5555#define MSR_PWR_UNIT 0xC0010299
5656#define MSR_PKG_ENERGY_STAT 0xC001029B
5757
58+ static inline int
59+ read_amd_msr (struct msr_info_t * info , uint32_t msr_index , uint8_t highbit , uint8_t lowbit , uint64_t * result )
60+ {
61+ if (info -> handle -> driver_type != WR0_DRIVER_PAWNIO )
62+ return cpu_rdmsr_range (info -> handle , msr_index , highbit , lowbit , result );
63+
64+ int err ;
65+ const uint8_t bits = highbit - lowbit + 1 ;
66+ ULONG64 in = msr_index ;
67+ ULONG64 out = 0 ;
68+ struct pio_mod_t * pio = NULL ;
69+
70+ if (highbit > 63 || lowbit > highbit )
71+ return cpuid_set_error (ERR_INVRANGE );
72+
73+ if (info -> id -> x86 .ext_family == 0x0f )
74+ pio = & info -> handle -> pio_amd0f ;
75+ else if (info -> id -> x86 .ext_family >= 0x10 && info -> id -> x86 .ext_family <= 0x16 )
76+ pio = & info -> handle -> pio_amd10 ;
77+ else if (info -> id -> x86 .ext_family >= 0x17 && info -> id -> x86 .ext_family <= 0x1A )
78+ pio = & info -> handle -> pio_amd17 ;
79+ else
80+ return cpuid_set_error (ERR_CPU_UNKN );
81+
82+ err = WR0_ExecPawn (info -> handle , pio , "ioctl_read_msr" , & in , 1 , & out , 1 , NULL );
83+
84+ if (!err && bits < 64 )
85+ {
86+ /* Show only part of register */
87+ out >>= lowbit ;
88+ out &= (1ULL << bits ) - 1 ;
89+ * result = out ;
90+ }
91+
92+ return err ;
93+ }
94+
5895static int get_amd_multipliers (struct msr_info_t * info , uint32_t pstate , double * multiplier )
5996{
6097 int i , err ;
@@ -97,8 +134,8 @@ static int get_amd_multipliers(struct msr_info_t* info, uint32_t pstate, double*
97134 MSRC001_00[6B:64][3:0] is cpu_did
98135 CPU COF is (100MHz * (cpu_fid + 10h) / (divisor specified by cpu_did))
99136 Note: This family contains only APUs */
100- err = cpu_rdmsr_range (info -> handle , pstate , 8 , 4 , & cpu_fid );
101- err += cpu_rdmsr_range (info -> handle , pstate , 3 , 0 , & cpu_did );
137+ err = read_amd_msr (info , pstate , 8 , 4 , & cpu_fid );
138+ err += read_amd_msr (info , pstate , 3 , 0 , & cpu_did );
102139 i = 0 ;
103140 while (i < num_dids && divisor_t [i ].did != cpu_did )
104141 i ++ ;
@@ -115,8 +152,8 @@ static int get_amd_multipliers(struct msr_info_t* info, uint32_t pstate, double*
115152 Divisor is (CpuDidMSD + (cpu_did_lsd * 0.25) + 1)
116153 CPU COF is (main PLL frequency specified by D18F3xD4[MainPllOpFreqId]) / (core clock divisor specified by CpuDidMSD and cpu_did_lsd)
117154 Note: This family contains only APUs */
118- err = cpu_rdmsr_range (info -> handle , pstate , 8 , 4 , & cpu_did );
119- err += cpu_rdmsr_range (info -> handle , pstate , 3 , 0 , & cpu_did_lsd );
155+ err = read_amd_msr (info , pstate , 8 , 4 , & cpu_did );
156+ err += read_amd_msr (info , pstate , 3 , 0 , & cpu_did_lsd );
120157 * multiplier = (double )(((info -> cpu_clock + 5LL ) / 100 + magic_constant ) / (cpu_did + cpu_did_lsd * 0.25 + 1 ));
121158 break ;
122159 case 0x10 : /* K10 */
@@ -146,8 +183,8 @@ static int get_amd_multipliers(struct msr_info_t* info, uint32_t pstate, double*
146183 MSRC001_00[6B:64][5:0] is cpu_fid
147184 CoreCOF is (100 * (MSRC001_00[6B:64][cpu_fid] + 10h) / (2^MSRC001_00[6B:64][cpu_did]))
148185 Note: This family contains only APUs */
149- err = cpu_rdmsr_range (info -> handle , pstate , 8 , 6 , & cpu_did );
150- err += cpu_rdmsr_range (info -> handle , pstate , 5 , 0 , & cpu_fid );
186+ err = read_amd_msr (info , pstate , 8 , 6 , & cpu_did );
187+ err += read_amd_msr (info , pstate , 5 , 0 , & cpu_fid );
151188 * multiplier = ((double )(cpu_fid + magic_constant ) / (1ull << cpu_did )) / divisor ;
152189 break ;
153190 case 0x17 : /* Zen / Zen+ / Zen 2 */
@@ -165,15 +202,15 @@ static int get_amd_multipliers(struct msr_info_t* info, uint32_t pstate, double*
165202 MSRC001_006[4...B][13:8] is CpuDfsId
166203 MSRC001_006[4...B][7:0] is cpu_fid
167204 CoreCOF is (Core::X86::Msr::PStateDef[cpu_fid[7:0]]/Core::X86::Msr::PStateDef[CpuDfsId]) *200 */
168- err = cpu_rdmsr_range (info -> handle , pstate , 13 , 8 , & cpu_did );
169- err += cpu_rdmsr_range (info -> handle , pstate , 7 , 0 , & cpu_fid );
205+ err = read_amd_msr (info , pstate , 13 , 8 , & cpu_did );
206+ err += read_amd_msr (info , pstate , 7 , 0 , & cpu_fid );
170207 * multiplier = ((double )cpu_fid / cpu_did ) * 2 ;
171208 break ;
172209 case 0x1A : /* Zen 5 */
173210 /* PPR for AMD Family 1Ah Model 02h C1, pages 235
174211 MSRC001_006[4...B][11:0] is cpu_fid
175212 CoreCOF is Core::X86::Msr::PStateDef[CpuFid[11:0]] *5 */
176- err = cpu_rdmsr_range (info -> handle , pstate , 11 , 0 , & cpu_fid );
213+ err = read_amd_msr (info , pstate , 11 , 0 , & cpu_fid );
177214 * multiplier = ((double )cpu_fid ) * 0.05 ;
178215 break ;
179216 default :
@@ -196,7 +233,7 @@ static uint32_t get_amd_last_pstate_addr(struct msr_info_t* info)
196233 while ((reg == 0x0 ) && (last_addr > MSR_PSTATE_0 ))
197234 {
198235 last_addr -- ;
199- cpu_rdmsr_range (info -> handle , last_addr , 63 , 63 , & reg );
236+ read_amd_msr (info , last_addr , 63 , 63 , & reg );
200237 }
201238 return last_addr ;
202239}
@@ -223,7 +260,7 @@ static double get_cur_multiplier(struct msr_info_t* info)
223260 /* Refer links above
224261 MSRC001_0063[2:0] is CurPstate
225262 */
226- if (cpu_rdmsr_range (info -> handle , MSR_PSTATE_S , 2 , 0 , & reg ))
263+ if (read_amd_msr (info , MSR_PSTATE_S , 2 , 0 , & reg ))
227264 goto fail ;
228265 if (get_amd_multipliers (info , MSR_PSTATE_0 + (uint32_t )reg , & mult ))
229266 goto fail ;
@@ -396,8 +433,18 @@ static float amd_17h_temperature(struct msr_info_t* info)
396433 uint32_t temperature ;
397434 float offset = 0.0f ;
398435
399- WR0_WrPciConf32 (info -> handle , 0 , FAMILY_17H_PCI_CONTROL_REGISTER , F17H_M01H_THM_TCON_CUR_TMP );
400- temperature = WR0_RdPciConf32 (info -> handle , 0 , FAMILY_17H_PCI_CONTROL_REGISTER + 4 );
436+ if (info -> handle -> driver_type != WR0_DRIVER_PAWNIO )
437+ {
438+ WR0_WrPciConf32 (info -> handle , 0 , FAMILY_17H_PCI_CONTROL_REGISTER , F17H_M01H_THM_TCON_CUR_TMP );
439+ temperature = WR0_RdPciConf32 (info -> handle , 0 , FAMILY_17H_PCI_CONTROL_REGISTER + 4 );
440+ }
441+ else
442+ {
443+ ULONG64 in = F17H_M01H_THM_TCON_CUR_TMP ;
444+ ULONG64 out = 0 ;
445+ WR0_ExecPawn (info -> handle , & info -> handle -> pio_amd17 , "ioctl_read_smn" , & in , 1 , & out , 1 , NULL );
446+ temperature = (uint32_t )out ;
447+ }
401448
402449 if (strstr (info -> id -> brand_str , "1600X" ) ||
403450 strstr (info -> id -> brand_str , "1700X" ) ||
@@ -417,13 +464,16 @@ static float amd_17h_temperature(struct msr_info_t* info)
417464
418465static int get_pkg_temperature (struct msr_info_t * info )
419466{
467+ int ret = CPU_INVALID_VALUE ;
468+ WR0_WaitPciBus (10 );
420469 if (info -> id -> x86 .ext_family >= 0x17 )
421- return (int )amd_17h_temperature (info );
470+ ret = (int )amd_17h_temperature (info );
422471 else if (info -> id -> x86 .ext_family > 0x0F )
423- return amd_k10_temperature (info );
472+ ret = amd_k10_temperature (info );
424473 else if (info -> id -> x86 .ext_family == 0x0F )
425- return amd_k8_temperature (info );
426- return CPU_INVALID_VALUE ;
474+ ret = amd_k8_temperature (info );
475+ WR0_ReleasePciBus ();
476+ return ret ;
427477}
428478
429479static double get_pkg_energy (struct msr_info_t * info )
@@ -434,9 +484,9 @@ static double get_pkg_energy(struct msr_info_t* info)
434484 // 19h: Zen 3 / Zen 3+ / Zen 4
435485 if (info -> id -> x86 .ext_family < 0x17 )
436486 goto fail ;
437- if (cpu_rdmsr_range (info -> handle , MSR_PKG_ENERGY_STAT , 31 , 0 , & total_energy ))
487+ if (read_amd_msr (info , MSR_PKG_ENERGY_STAT , 31 , 0 , & total_energy ))
438488 goto fail ;
439- if (cpu_rdmsr_range (info -> handle , MSR_PWR_UNIT , 12 , 8 , & energy_units ))
489+ if (read_amd_msr (info , MSR_PWR_UNIT , 12 , 8 , & energy_units ))
440490 goto fail ;
441491 return (double )total_energy / (1ULL << energy_units );
442492fail :
@@ -497,7 +547,7 @@ static double get_voltage(struct msr_info_t* info)
497547 uint64_t reg , vid ;
498548 uint8_t range_h , range_l ;
499549
500- if (cpu_rdmsr_range (info -> handle , MSR_PSTATE_S , 2 , 0 , & reg ))
550+ if (read_amd_msr (info , MSR_PSTATE_S , 2 , 0 , & reg ))
501551 goto fail ;
502552 if (info -> id -> x86 .ext_family < 0x15
503553 || ((info -> id -> x86 .ext_family == 0x15 ) && (info -> id -> x86 .ext_model < 0x10 )))
@@ -515,7 +565,7 @@ static double get_voltage(struct msr_info_t* info)
515565 range_h = 21 ;
516566 range_l = 14 ;
517567 }
518- if (cpu_rdmsr_range (info -> handle , MSR_PSTATE_0 + (uint32_t )reg , range_h , range_l , & vid ))
568+ if (read_amd_msr (info , MSR_PSTATE_0 + (uint32_t )reg , range_h , range_l , & vid ))
519569 goto fail ;
520570 if (MSR_PSTATE_0 + (uint32_t )reg <= MSR_PSTATE_7 )
521571 return 1.550 - vid_step * vid ;
@@ -532,7 +582,7 @@ static double get_bus_clock(struct msr_info_t* info)
532582 double mult ;
533583 uint64_t reg ;
534584 uint32_t addr = get_amd_last_pstate_addr (info );
535- if (cpu_rdmsr_range (info -> handle , MSR_PSTATE_L , 6 , 4 , & reg ))
585+ if (read_amd_msr (info , MSR_PSTATE_L , 6 , 4 , & reg ))
536586 goto fail ;
537587 if (get_amd_multipliers (info , addr - (uint32_t )reg , & mult ))
538588 goto fail ;
0 commit comments