@@ -114,6 +114,10 @@ static unsigned char COFVID_MAX_VID = 1;
114114static unsigned char COFVID_MIN_VID = 128 ;
115115static signed short MAIN_PLL_COFF = -1 ;
116116
117+ static char * CPU_NBPST_BITS = NULL ;
118+ static char * CPBC_NUM_BOOST_STATES_BITS = NULL ;
119+ static signed char nbPst = -1 , maxNbPst = -1 ;
120+
117121static uint64_t buffer ;
118122static unsigned char currentOnly = 0 , debug = 0 , DIDS = 5 , quiet = 0 , PSTATES = 8 , pvi = 0 , testMode = 0 ;
119123static signed char cpuDid = -1 , togglePs = -1 ;
@@ -259,6 +263,28 @@ void checkFamily() {
259263 fprintf (stderr , "Your CPU is not supported by amdctl (Family %xh ; Model %xh).\n" , cpuFamily , cpuModel );
260264 exit (EXIT_FAILURE );
261265 }
266+ switch (cpuFamily ) {
267+ case AMD10H :
268+ CPBC_NUM_BOOST_STATES_BITS = "2:2" ;
269+ break ;
270+ case AMD12H :
271+ case AMD14H :
272+ case AMD15H :
273+ case AMD16H :
274+ CPBC_NUM_BOOST_STATES_BITS = "4:2" ;
275+ break ;
276+ default :
277+ break ;
278+ }
279+ switch (cpuFamily ) {
280+ case AMD15H :
281+ case AMD16H :
282+ CPU_NBPST_BITS = "22:22" ;
283+ maxNbPst = 1 ;
284+ break ;
285+ default :
286+ break ;
287+ }
262288}
263289
264290/**
@@ -315,7 +341,15 @@ void parseOpts(const int argc, char **argv) {
315341 case 'm' : // Kernel >= 5.9, check / set /sys/module/msr/parameters/allow_writes to on.
316342 allowWrites = 1 ;
317343 break ;
318- case 'n' : // Northbridge vid to set.
344+ case 'n' : // Northbridge vid/pstate to set.
345+ if (CPU_NBPST_BITS ) {
346+ nbPst = atoi (optarg );
347+ if (nbPst < 0 || nbPst > maxNbPst ) {
348+ fprintf (stderr , "ERROR: Option -n must be between 0 and %d.\n" , maxNbPst );
349+ exit (EXIT_FAILURE );
350+ }
351+ break ;
352+ }
319353 if (cpuFamily > AMD11H ) {
320354 error ("Currently amdctl can only change the NB vid on 10h and 11h CPU's." );
321355 }
@@ -414,6 +448,8 @@ void usage() {
414448 printf (" -v Set CPU voltage id (vid).\n" );
415449 if (cpuFamily == AMD10H || cpuFamily == AMD11H ) {
416450 printf (" -n Set north bridge voltage id (vid).\n" );
451+ } else if (CPU_NBPST_BITS ) {
452+ printf (" -n Set north bridge P-State.\n" );
417453 }
418454 if (cpuFamily == AMD14H ) {
419455 printf (" -d Set the CPU divisor ID most significant digit (CpuDidMSD).\n" );
@@ -460,6 +496,7 @@ void fieldDescriptions() {
460496 printf ("CpuVolt: Core voltage, in millivolts.\n" );
461497 printf ("NbVid: North bridge voltage ID.\n" );
462498 printf ("NbVolt: North bridge voltage, in millivolts.\n" );
499+ printf ("NbPst: North bridge P-State. (lower numbers mean higher performance).\n" );
463500 printf ("IddVal: Core current (intensity) ID. Used to calculate cpu current draw and power draw.\n" );
464501 printf ("IddDiv Core current (intensity) dividor.\n" );
465502 printf ("CpuCurr: The cpu current draw, in amps.\n" );
@@ -522,8 +559,7 @@ void uwmsrCheck(const unsigned char allowWrites) {
522559 */
523560void wrCpuStates () {
524561 uint32_t tmp_pstates [PSTATES ];
525- unsigned char pstates_count = 0 ;
526- unsigned char extra = 1 ;
562+ unsigned char pstates_count = 0 , bstates = 0 ;
527563 if (pstate == -1 ) {
528564 for (; pstates_count < PSTATES ; pstates_count ++ ) {
529565 tmp_pstates [pstates_count ] = (MSR_PSTATE_BASE + pstates_count );
@@ -532,49 +568,28 @@ void wrCpuStates() {
532568 tmp_pstates [0 ] = MSR_PSTATE_BASE + pstate ;
533569 pstates_count = 1 ;
534570 }
571+ if (CPBC_NUM_BOOST_STATES_BITS ) {
572+ rwPciReg ("18.4" , 0x15c , 1 );
573+ bstates = getDec (CPBC_NUM_BOOST_STATES_BITS );
574+ }
535575
536576 for (; core < cores ; core ++ ) {
537577 rwMsrReg (MSR_PSTATE_CURRENT_LIMIT , 1 );
538- int i , curPstate = getDec (CUR_PSTATE_BITS ), minPstate = getDec (PSTATE_MAX_VAL_BITS ), maxPstate = getDec (CUR_PSTATE_LIMIT_BITS );
539- switch (cpuFamily ) {
540- case AMD10H :
541- if (cpuModel == 0x05 ) {
542- extra = 0 ;
543- }
544- break ;
545- case AMD14H :
546- if (cpuModel == 0x02 ) {
547- extra = 0 ;
548- }
549- break ;
550- case AMD16H :
551- if (cpuModel == 0x30 ) {
552- extra = 2 ;
553- }
554- break ;
555- case AMD17H :
556- case AMD19H :
557- extra = 0 ;
558- break ;
559- default :
560- break ;
561- }
562- curPstate += extra ;
563- minPstate += extra ;
564- maxPstate += extra ;
578+ int i , curPstate , minPstate = bstates + getDec (PSTATE_MAX_VAL_BITS ), maxPstate = bstates + getDec (CUR_PSTATE_LIMIT_BITS );
565579 rwMsrReg (MSR_PSTATE_STATUS , 1 );
580+ curPstate = bstates + getDec (CUR_PSTATE_BITS );
566581 if (!quiet ) {
567582 printf ("\nCore %d | P-State Limits (non-turbo): Highest: %d ; Lowest %d | Current P-State: %d\n" , core , maxPstate , minPstate , curPstate );
568583 printf (" Pstate Status CpuFid CpuDid CpuVid CpuMult CpuFreq CpuVolt IddVal IddDiv CpuCurr CpuPower" );
569- printf ("%s\n" , (cpuFamily == AMD10H || cpuFamily == AMD11H ) ? " NbVid NbVolt" : "" );
584+ printf ("%s\n" , (cpuFamily == AMD10H || cpuFamily == AMD11H ) ? " NbVid NbVolt" : ( CPU_NBPST_BITS ? " NbPst" : "" ) );
570585 }
571586 if (!currentOnly ) {
572587 for (i = 0 ; i < pstates_count ; i ++ ) {
573588 if (!quiet ) {
574589 printf ("%7d" , (pstate >= 0 ? pstate : i ));
575590 }
576591 rwMsrReg (tmp_pstates [i ], 1 );
577- if (nbVid > -1 || cpuVid > -1 || cpuFid > -1 || cpuDid > -1 || togglePs > -1 ) {
592+ if (nbVid > -1 || cpuVid > -1 || cpuFid > -1 || cpuDid > -1 || togglePs > -1 || nbPst > -1 ) {
578593 if (togglePs > -1 ) {
579594 updateBuffer (PSTATE_EN_BITS , togglePs );
580595 }
@@ -590,6 +605,9 @@ void wrCpuStates() {
590605 if (cpuDid > -1 ) {
591606 updateBuffer (CPU_DID_BITS , cpuDid );
592607 }
608+ if (nbPst > -1 ) {
609+ updateBuffer (CPU_NBPST_BITS , nbPst );
610+ }
593611 rwMsrReg (tmp_pstates [i ], 0 );
594612 }
595613 printCpuPstate (1 );
@@ -662,6 +680,13 @@ void printCpuPstate(const unsigned char idd) {
662680 printf ("%7s%7s%8s%9s" , "" , "" , "" , "" );
663681 }
664682 printf ("%6d%5dmV" , NbVid , vidTomV (NbVid ));
683+ } else if (CPU_NBPST_BITS ) {
684+ if (!idd ) {
685+ printf ("%7s%7s%8s%9s%6s" , "" , "" , "" , "" , "" );
686+ } else {
687+ const int NbPst = getDec (CPU_NBPST_BITS );
688+ printf ("%6d" , NbPst );
689+ }
665690 }
666691 printf ("\n" );
667692 }
@@ -891,7 +916,7 @@ unsigned short vidTomV(const unsigned short vid) {
891916
892917 // https://github.com/mpollice/AmdMsrTweaker/blob/master/Info.cpp#L47
893918 if ((cpuFamily == AMD15H && ((cpuModel > 0x0f && cpuModel < 0x20 ) || (cpuModel > 0x2f && cpuModel < 0x40 ))) ||
894- ( cpuFamily == AMD16H && cpuModel == 0x30 ) ||
919+ cpuFamily == AMD16H ||
895920 cpuFamily == AMD17H ||
896921 cpuFamily == AMD19H ) {
897922 return (MAX_VOLTAGE - (vid * VID_DIVIDOR3 ));
0 commit comments