This patch fixes the processor name string for Rev F. CPUs.
It moves the complete naming functionality to src/cpu/amd/model_fxx/processor_name.c. The current code sets the processor name string twice for Rev. F CPUs. In src/cpu/amd/model_fxx/model_fxx_init.c the function amd_set_name_string_f is called first. Several lines later init_processor_name is called which doesn't recognize newer CPUs and actually programs incorrect values, thus overwriting the previously set CPU name. For example, this resulted in identifying an Opteron 2218 as a Turion processor. This patch removes the amd_set_name_string_f function from src/cpu/amd/model_fxx/model_fxx_init.c and adds support for Rev. F CPUs to src/cpu/amd/model_fxx/processor_name.c as described in the Revision Guide for AMD NPT Family 0Fh Processors, AMD Document ID 33610 Rev 3.00, October 2006. Signed-off-by: Sven Kapferer <skapfere@rumms.uni-mannheim.de> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@2699 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
cd3afc0524
commit
4834a4f206
|
@ -462,87 +462,6 @@ static inline void k8_errata(void)
|
|||
|
||||
}
|
||||
|
||||
#if K8_REV_F_SUPPORT == 1
|
||||
static void amd_set_name_string_f(device_t dev)
|
||||
{
|
||||
unsigned socket;
|
||||
unsigned cmpCap;
|
||||
unsigned pwrLmt;
|
||||
unsigned brandId;
|
||||
unsigned brandTableIndex;
|
||||
unsigned nN;
|
||||
unsigned unknown = 1;
|
||||
|
||||
uint8_t str[48];
|
||||
uint32_t *p;
|
||||
|
||||
msr_t msr;
|
||||
unsigned i;
|
||||
|
||||
brandId = cpuid_ebx(0x80000001) & 0xffff;
|
||||
|
||||
printk_debug("brandId=%04x\n", brandId);
|
||||
pwrLmt = ((brandId>>14) & 1) | ((brandId>>5) & 0x0e);
|
||||
brandTableIndex = (brandId>>9) & 0x1f;
|
||||
nN = (brandId & 0x3f) | ((brandId>>(15-6)) &(1<<6));
|
||||
|
||||
socket = (dev->device >> 4) & 0x3;
|
||||
|
||||
cmpCap = cpuid_ecx(0x80000008) & 0xff;
|
||||
|
||||
|
||||
if((brandTableIndex == 0) && (pwrLmt == 0)) {
|
||||
memset(str, 0, 48);
|
||||
sprintf(str, "AMD Engineering Sample");
|
||||
unknown = 0;
|
||||
} else {
|
||||
|
||||
memset(str, 0, 48);
|
||||
sprintf(str, "AMD Processor model unknown");
|
||||
|
||||
#if CPU_SOCKET_TYPE == 0x10
|
||||
if(socket == 0x01) { // socket F
|
||||
if ((cmpCap == 1) && ((brandTableIndex==0) ||(brandTableIndex ==1) ||(brandTableIndex == 4)) ) {
|
||||
uint8_t pc[2];
|
||||
unknown = 0;
|
||||
switch (pwrLmt) {
|
||||
case 2: pc[0]= 'E'; pc[1] = 'E'; break;
|
||||
case 6: pc[0]= 'H'; pc[1] = 'E'; break;
|
||||
case 0xa: pc[0]= ' '; pc[1] = ' '; break;
|
||||
case 0xc: pc[0]= 'S'; pc[1] = 'E'; break;
|
||||
default: unknown = 1;
|
||||
|
||||
}
|
||||
if(!unknown) {
|
||||
memset(str, 0, 48);
|
||||
sprintf(str, "Dual-Core AMD Opteron(tm) Processor %1d2%2d %c%c", brandTableIndex<<1, (nN-1)&0x3f, pc[0], pc[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#if CPU_SOCKET_TYPE == 0x11
|
||||
if(socket == 0x00) { // socket AM2
|
||||
if(cmpCap == 0) {
|
||||
sprintf(str, "Athlon 64");
|
||||
} else {
|
||||
sprintf(str, "Athlon 64 Dual Core");
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
p = str;
|
||||
for(i=0;i<6;i++) {
|
||||
msr.lo = *p; p++; msr.hi = *p; p++;
|
||||
wrmsr(0xc0010030+i, msr);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void model_fxx_update_microcode(unsigned cpu_deviceid);
|
||||
int init_processor_name(void);
|
||||
|
||||
|
@ -561,10 +480,6 @@ void model_fxx_init(device_t dev)
|
|||
struct cpuinfo_x86 c;
|
||||
|
||||
get_fms(&c, dev->device);
|
||||
|
||||
if((c.x86_model & 0xf0) == 0x40) {
|
||||
amd_set_name_string_f(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_USBDEBUG_DIRECT
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
*
|
||||
* (C) 2006 by coresystems GmbH <info@coresystems.de>
|
||||
*
|
||||
* Updated by Sven Kapferer <skapfere@rumms.uni-mannheim.de> using
|
||||
* the Revision Guide for AMD NPT Family 0Fh Processors
|
||||
* Document ID 33610 Rev 3.00, October 2006 (Public Version)
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General
|
||||
* Public License. See the file COPYING in the main directory of this
|
||||
* archive for more details.
|
||||
|
@ -25,6 +29,7 @@
|
|||
* your mainboard will not be posted on the AMD Recommended Motherboard Website
|
||||
*/
|
||||
|
||||
#if K8_REV_F_SUPPORT == 0
|
||||
static char *processor_names[]={
|
||||
/* 0x00 */ "AMD Engineering Sample",
|
||||
/* 0x01-0x03 */ NULL, NULL, NULL,
|
||||
|
@ -80,6 +85,7 @@ static char *processor_names[]={
|
|||
/* 0x3A */ "Dual Core AMD Opteron(tm) Processor 8RR"
|
||||
#define MAX_CPU_NUMBER 0x3A
|
||||
};
|
||||
#endif
|
||||
|
||||
/* wrmsr_amd() is from yhlu's changes to model_fxx_init.c */
|
||||
|
||||
|
@ -92,6 +98,17 @@ static inline void wrmsr_amd(unsigned index, msr_t msr)
|
|||
);
|
||||
}
|
||||
|
||||
static inline unsigned int cpuid_eax(unsigned int op)
|
||||
{
|
||||
unsigned int eax;
|
||||
|
||||
__asm__("cpuid"
|
||||
: "=a" (eax)
|
||||
: "0" (op)
|
||||
: "ebx", "ecx", "edx");
|
||||
return eax;
|
||||
}
|
||||
|
||||
static inline unsigned int cpuid_ebx(unsigned int op)
|
||||
{
|
||||
unsigned int eax, ebx;
|
||||
|
@ -103,6 +120,17 @@ static inline unsigned int cpuid_ebx(unsigned int op)
|
|||
return ebx;
|
||||
}
|
||||
|
||||
static inline unsigned int cpuid_ecx(unsigned int op)
|
||||
{
|
||||
unsigned int eax, ecx;
|
||||
|
||||
__asm__("cpuid"
|
||||
: "=a" (eax), "=c" (ecx)
|
||||
: "0" (op)
|
||||
: "ebx", "edx" );
|
||||
return ecx;
|
||||
}
|
||||
|
||||
static inline void strcpy(char *dst, char *src)
|
||||
{
|
||||
while (*src) *dst++ = *src++;
|
||||
|
@ -123,6 +151,7 @@ int init_processor_name(void)
|
|||
char program_string[48];
|
||||
unsigned int *program_values = (unsigned int *)program_string;
|
||||
|
||||
#if K8_REV_F_SUPPORT == 0
|
||||
/* Find out which CPU brand it is */
|
||||
EightBitBrandId = cpuid_ebx(0x00000001) & 0xff;
|
||||
BrandId = cpuid_ebx(0x80000001) & 0xffff;
|
||||
|
@ -144,6 +173,103 @@ int init_processor_name(void)
|
|||
|
||||
if (!processor_name_string)
|
||||
processor_name_string = "AMD Processor model unknown";
|
||||
#endif
|
||||
|
||||
#if K8_REV_F_SUPPORT == 1
|
||||
u32 Socket;
|
||||
u32 CmpCap;
|
||||
u32 PwrLmt;
|
||||
|
||||
BrandId = cpuid_ebx(0x80000001) & 0xffff;
|
||||
Socket = (cpuid_eax(0x80000001) & 0x00000030) >> 4; // 00b = S1g1, 01b = F (1207), 11b = AM2
|
||||
CmpCap = cpuid_ecx(0x80000008) & 0x03; // Number of CPU cores
|
||||
|
||||
PwrLmt = ((BrandId >> 14) & 0x01) | ((BrandId >> 5) & 0x0e); // BrandId[8:6,14]
|
||||
BrandTableIndex = (BrandId >> 9) & 0x1f; // BrandId[13:9]
|
||||
NN = ((BrandId >> 15) & 0x01) | (BrandId & 0x3f); // BrandId[15,5:0]
|
||||
|
||||
if (((BrandTableIndex == 0) && (PwrLmt == 0)) || (NN == 0)) {
|
||||
processor_name_string = "AMD Engineering Sample";
|
||||
} else {
|
||||
/* Use all fields to identify CPU */
|
||||
switch ((Socket << 16) | (CmpCap << 12) | (BrandTableIndex << 4)
|
||||
| PwrLmt) {
|
||||
/* Socket F */
|
||||
case 0x11016:
|
||||
processor_name_string =
|
||||
"Dual-Core AMD Opteron(tm) Processor 22RR HE";
|
||||
break;
|
||||
case 0x1101a:
|
||||
processor_name_string =
|
||||
"Dual-Core AMD Opteron(tm) Processor 22RR";
|
||||
break;
|
||||
case 0x1101c:
|
||||
processor_name_string =
|
||||
"Dual-Core AMD Opteron(tm) Processor 22RR SE";
|
||||
break;
|
||||
case 0x11046:
|
||||
processor_name_string =
|
||||
"Dual-Core AMD Opteron(tm) Processor 82RR HE";
|
||||
break;
|
||||
case 0x1104a:
|
||||
processor_name_string =
|
||||
"Dual-Core AMD Opteron(tm) Processor 82RR";
|
||||
break;
|
||||
case 0x1104c:
|
||||
processor_name_string =
|
||||
"Dual-Core AMD Opteron(tm) Processor 82RR SE";
|
||||
break;
|
||||
/* Socket AM2 */
|
||||
case 0x30044:
|
||||
processor_name_string =
|
||||
"AMD Athlon(tm) 64 Processor TT00+";
|
||||
break;
|
||||
case 0x30048:
|
||||
processor_name_string =
|
||||
"AMD Athlon(tm) 64 Processor TT00+";
|
||||
break;
|
||||
case 0x30064:
|
||||
processor_name_string =
|
||||
"AMD Sempron(tm) Processor TT00+";
|
||||
break;
|
||||
case 0x30068:
|
||||
processor_name_string =
|
||||
"AMD Sempron(tm) Processor TT00+";
|
||||
break;
|
||||
case 0x3101a:
|
||||
processor_name_string =
|
||||
"Dual-Core AMD Opteron(tm) Processor 12RR";
|
||||
break;
|
||||
case 0x3101c:
|
||||
processor_name_string =
|
||||
"Dual-Core AMD Opteron(tm) Processor 12RR SE";
|
||||
break;
|
||||
case 0x31042:
|
||||
processor_name_string =
|
||||
"AMD Athlon(tm) 64 X2 Dual Core Processor TT00+";
|
||||
break;
|
||||
case 0x31046:
|
||||
processor_name_string =
|
||||
"AMD Athlon(tm) 64 X2 Dual Core Processor TT00+";
|
||||
break;
|
||||
case 0x31048:
|
||||
processor_name_string =
|
||||
"AMD Athlon(tm) 64 X2 Dual Core Processor TT00+";
|
||||
break;
|
||||
case 0x3105c:
|
||||
processor_name_string =
|
||||
"AMD Athlon(tm) 64 FX-ZZ Dual Core Processor";
|
||||
break;
|
||||
/* Socket S1g1 */
|
||||
case 0x0102c:
|
||||
processor_name_string =
|
||||
"AMD Turion(tm) 64 X2 Mobile Technology TL-YY";
|
||||
break;
|
||||
default:
|
||||
processor_name_string = "AMD Processor model unknown";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(program_string, 0, 48);
|
||||
strcpy(program_string, processor_name_string);
|
||||
|
@ -156,12 +282,22 @@ int init_processor_name(void)
|
|||
for (i=0; i<47; i++) { // 48 -1
|
||||
if(program_string[i] == program_string[i+1]) {
|
||||
switch (program_string[i]) {
|
||||
#if K8_REV_F_SUPPORT == 0
|
||||
case 'X': ModelNumber = 22+ NN; break;
|
||||
case 'Y': ModelNumber = 38 + (2*NN); break;
|
||||
case 'Z':
|
||||
case 'T': ModelNumber = 24 + NN; break;
|
||||
case 'R': ModelNumber = 45 + (5*NN); break;
|
||||
case 'V': ModelNumber = 9 + NN; break;
|
||||
#endif
|
||||
|
||||
#if K8_REV_F_SUPPORT == 1
|
||||
case 'R': ModelNumber = NN - 1; break;
|
||||
case 'P': ModelNumber = 26 + NN; break;
|
||||
case 'T': ModelNumber = 15 + (CmpCap * 10) + NN; break;
|
||||
case 'Z': ModelNumber = 57 + NN; break;
|
||||
case 'Y': ModelNumber = 29 + NN; break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(ModelNumber && ModelNumber < 100) {
|
||||
|
|
Loading…
Reference in New Issue