[coreboot] Patch set updated for coreboot: 00bff57 Fixes several issues with amd k8 SSDT P-state generation

Oskar Enoksson (enok@lysator.liu.se) gerrit at coreboot.org
Fri Oct 7 21:28:44 CEST 2011


Oskar Enoksson (enok at lysator.liu.se) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/239

-gerrit

commit 00bff5758e8104153ff9668fe739026ab977ab9a
Author: Oskar Enoksson <enok at lysator.liu.se>
Date:   Thu Oct 6 18:43:43 2011 +0200

    Fixes several issues with amd k8 SSDT P-state generation
    
    For multi-socket CPU the current implementation emitted
    Processor objects for cores in the first CPU only. This
    commit fixes the bug. One caveat though: the unlikely case
    of mixed CPU models is still not handled correctly.
    
    Second issue fixed:
    One loop was wrong in case a processor in the table declares
    no P-states at all. The rewritten loop is safe. Some possibly
    dangerous array lengths were also fixed.
    
    Third issue: on MP-boards the recommended ramp-voltage (RVO) is 0mV
    according to the BKDG. The current implementation always set it
    to 25mV. This commit selects 0 or 25mV depending on CONFIG_MAX_PHYSICAL_CPUS.
    
    Signed-off-by: Oskar Enoksson <enok at lysator.liu.se>
    Change-Id: I61f6e2210b84ccba33a36c5efc866447b7134417
---
 src/cpu/amd/model_fxx/powernow_acpi.c |   81 +++++++++++++++++++++++++--------
 1 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/src/cpu/amd/model_fxx/powernow_acpi.c b/src/cpu/amd/model_fxx/powernow_acpi.c
index bbcf013..c49322f 100644
--- a/src/cpu/amd/model_fxx/powernow_acpi.c
+++ b/src/cpu/amd/model_fxx/powernow_acpi.c
@@ -586,15 +586,17 @@ static int pstates_algorithm(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
 	u8 cmp_cap;
 	struct cpuentry *data = NULL;
 	uint32_t control;
-	int i = 0, index, len = 0, Pstate_num = 0;
+	int i = 0, index = 0, len = 0, Pstate_num = 0, dev = 0;
 	msr_t msr;
-	u8 Pstate_fid[10];
-	u16 Pstate_feq[10];
-	u8 Pstate_vid[10];
-	u32 Pstate_power[10];
+	u8 Pstate_fid[MAXP+1];
+	u16 Pstate_feq[MAXP+1];
+	u8 Pstate_vid[MAXP+1];
+	u32 Pstate_power[MAXP+1];
 	u8 Max_fid, Start_fid, Start_vid, Max_vid;
 	struct cpuid_result cpuid1 = cpuid(0x80000001);
 
+	// Because I don't know how to read msr registers from
+	// other CPU's I assume they all have the same SYSCONF values
 	msr = rdmsr(0xc0010042);
 	Max_fid = (msr.lo & 0x3F0000) >> 16;
 	Max_vid = (msr.hi & 0x3F0000) >> 16;
@@ -619,25 +621,57 @@ static int pstates_algorithm(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
 		printk(BIOS_WARNING, "Unknown CPU, please update the powernow_acpi.c\n");
 		return 0;
 	}
+	/* See if the CPUID(0x80000007) returned EDX[2:1]==11b */
+	cpuid1 = cpuid(0x80000007);
+	if((cpuid1.edx & 0x6)!=0x6) {
+		printk(BIOS_INFO, "Processor not capable of performing P-state transitions\n");
+		return 0;
+	}
+
+#if CONFIG_MAX_PHYSICAL_CPUS==1
+	// IRT 80us RVO = 50mV PLL_LOCK_TIME 2us, MVS 25mv, VST 100us
+	control = (3 << 30) | (2 << 28) | (2 << 20) | (0 << 18) | (5 << 11);
+#else
+	// MP-systems should default to RVO=0mV (no ramp voltage)
+	// IRT 80us RVO = 0mV PLL_LOCK_TIME 2us, MVS 25mv, VST 100us
+	control = (3 << 30) | (0 << 28) | (2 << 20) | (0 << 18) | (5 << 11);
+#endif
+	// RVO (Ramp Voltage Offset)
+	//   00   0mV (default for MP-systems)
+	//   01  25mV
+	//   10  50mV (default)
+	//   11  75mV
+	// IRT (Isochronous Release Time)
+	//   00  10uS
+	//   01  20uS
+	//   10  40uS
+	//   11  80uS (default)
+	// MVS (Maximum Voltage Step)
+	//   00  25mV (default)
+	//   01  50mV (reserved)
+	//   10 100mV (reserved)
+	//   11 200mV (reserved)
+	// VST (Voltage Stabilization Time)
+	//   time = value*20uS  (default value: 5 => 100uS)
+	// PLL_LOCK_TIME
+	//   time is value*1uS (often seen value: 2uS)
+	//
 
-	/* IRT 80us, PLL_LOCK_TIME 2us, MVS 25mv, VST 100us */
-	control = (3 << 30) | (2 << 20) | (0 << 18) | (5 << 11) | (1 << 29);
 	len = 0;
-	Pstate_num = 0;
 
-	Pstate_fid[Pstate_num] = Max_fid;
-	Pstate_feq[Pstate_num] = fid_to_freq(Max_fid);
-	Pstate_vid[Pstate_num] = Max_vid;
-	Pstate_power[Pstate_num] = data->pwr * 100;
-	Pstate_num++;
+	Pstate_fid[0] = Max_fid;
+	Pstate_feq[0] = fid_to_freq(Max_fid);
+	Pstate_vid[0] = Max_vid;
+	Pstate_power[0] = data->pwr * 100;
 
-	do {
+	for(Pstate_num = 1;
+	    (Pstate_num <= MAXP) && (data->pstates[Pstate_num - 1].freqMhz != 0);
+	    Pstate_num++) {
 		Pstate_fid[Pstate_num] = freq_to_fid(data->pstates[Pstate_num - 1].freqMhz) & 0x3f;
 		Pstate_feq[Pstate_num] = data->pstates[Pstate_num - 1].freqMhz;
 		Pstate_vid[Pstate_num] = vid_to_reg(data->pstates[Pstate_num - 1].voltage);
 		Pstate_power[Pstate_num] = data->pstates[Pstate_num - 1].tdp * 100;
-		Pstate_num++;
-	} while ((Pstate_num < MAXP) && (data->pstates[Pstate_num - 1].freqMhz != 0));
+	}
 
 	for (i=0;i<Pstate_num;i++)
 		printk(BIOS_DEBUG, "P#%d freq %d [MHz] voltage %d [mV] TDP %d [mW]\n", i,
@@ -645,11 +679,18 @@ static int pstates_algorithm(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
 		       vid_from_reg(Pstate_vid[i]),
 		       Pstate_power[i]);
 
-	for (index = 0; index < (cmp_cap + 1); index++) {
-		len += write_pstates_for_core(Pstate_num, Pstate_feq, Pstate_vid,
-				Pstate_fid, Pstate_power, index,
-				pcontrol_blk, plen, onlyBSP, control);
+	for (dev = 0x18; dev < 0x1c; dev++) {
+		if(dev_find_slot(0, PCI_DEVFN(dev, 0))==NULL)
+			continue;
+
+		for (i = 0; i < (cmp_cap + 1); i++) {
+			len += write_pstates_for_core(Pstate_num, Pstate_feq, Pstate_vid,
+					Pstate_fid, Pstate_power, index+i,
+					pcontrol_blk, plen, onlyBSP, control);
+		}
+		index += i;
 	}
+	printk(BIOS_DEBUG,"%d Processor objects emitted to SSDT\n",index);
 
 	return len;
 }




More information about the coreboot mailing list