amd/amdfam10: Fix incorrect core count identification

The core count identification code in the PowerNow! _PSS
ACPI object generation code was incorrectly copied from the
model_fxx code.  This code has been rewritten to properly
return the number of cores installed in the system.

Change-Id: I19567486f2de9dc2c43970addf4d91fa3d233a99
Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com>
Reviewed-on: http://review.coreboot.org/8421
Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Tested-by: build bot (Jenkins)
This commit is contained in:
Timothy Pearson 2015-02-10 21:15:39 -06:00 committed by Alexandru Gagniuc
parent 2f5bb6548d
commit 6fdb4d5d3c
1 changed files with 29 additions and 7 deletions

View File

@ -69,6 +69,13 @@ static void write_pstates_for_core(u8 pstate_num, u16 *pstate_feq, u32 *pstate_p
/* /*
* For details of this algorithm, please refer to the BDKG 3.62 page 69 * For details of this algorithm, please refer to the BDKG 3.62 page 69
*
* WARNING: The core count algorithm below assumes that all processors
* are identical, with the same number of active cores. While the BKDG
* states the BIOS must enforce this coreboot does not currently do so.
* As a result it is possible that this code may break if an illegal
* processor combination is installed. If it does break please fix the
* code in the proper locations!
*/ */
static void pstates_algorithm(u32 pcontrol_blk, u8 plen, u8 onlyBSP) static void pstates_algorithm(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
{ {
@ -106,15 +113,31 @@ static void pstates_algorithm(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
processor_brand[48] = 0; processor_brand[48] = 0;
printk(BIOS_INFO, "processor_brand=%s\n", processor_brand); printk(BIOS_INFO, "processor_brand=%s\n", processor_brand);
uint32_t dtemp;
uint32_t cpuid_fms;
uint8_t model;
uint8_t node_count;
/* /*
* Based on the CPU socket type,cmp_cap and pwr_lmt , get the power limit. * Based on the CPU socket type,cmp_cap and pwr_lmt , get the power limit.
* socket_type : 0x10 SocketF; 0x11 AM2/ASB1 ; 0x12 S1G1 * socket_type : 0x10 SocketF; 0x11 AM2/ASB1 ; 0x12 S1G1
* cmp_cap : 0x0 SingleCore ; 0x1 DualCore ; 0x2 TripleCore ; 0x3 QuadCore ; 0x5 QuintupleCore ; 0x6 HexCore * cmp_cap : 0x0 SingleCore ; 0x1 DualCore ; 0x2 TripleCore ; 0x3 QuadCore ; 0x4 QuintupleCore ; 0x5 HexCore
*/ */
printk(BIOS_INFO, "Pstates Algorithm ...\n"); printk(BIOS_INFO, "Pstates algorithm ...\n");
cmp_cap = /* Get CPU model */
(pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xE8) & cpuid_fms = cpuid_eax(0x80000001);
0x7000) >> 12; model = ((cpuid_fms & 0xf0000) >> 16) | ((cpuid_fms & 0xf0) >> 4);
/* Get number of cores */
dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xE8);
cmp_cap = (dtemp & 0x3000) >> 12;
if ((model == 0x8) || (model == 0x9)) /* revision D */
cmp_cap |= (dtemp & 0x8000) >> 13;
/* Get number of nodes */
dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 0)), 0x60);
node_count = ((dtemp & 0x70) >> 4) + 1;
/* Compute total number of cores installed in system */
cmp_cap++;
cmp_cap *= node_count;
Pstate_num = 0; Pstate_num = 0;
@ -125,7 +148,6 @@ static void pstates_algorithm(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
goto write_pstates; goto write_pstates;
} }
uint32_t dtemp;
uint8_t pviModeFlag; uint8_t pviModeFlag;
uint8_t Pstate_max; uint8_t Pstate_max;
uint8_t cpufid; uint8_t cpufid;
@ -237,7 +259,7 @@ static void pstates_algorithm(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
} }
write_pstates: write_pstates:
for (index = 0; index < (cmp_cap + 1); index++) for (index = 0; index < cmp_cap; index++)
write_pstates_for_core(Pstate_num, Pstate_feq, Pstate_power, write_pstates_for_core(Pstate_num, Pstate_feq, Pstate_power,
Pstate_latency, Pstate_control, Pstate_status, Pstate_latency, Pstate_control, Pstate_status,
index, pcontrol_blk, plen, onlyBSP); index, pcontrol_blk, plen, onlyBSP);