summaryrefslogtreecommitdiff
path: root/src/cpu/amd
diff options
context:
space:
mode:
authorSven Kapferer <skapfere@rumms.uni-mannheim.de>2007-05-26 13:56:34 +0000
committerUwe Hermann <uwe@hermann-uwe.de>2007-05-26 13:56:34 +0000
commit4834a4f2063509cbdb2ab20114f18664d5e9caf2 (patch)
treea78788a0e9b8aacd31005a3c3f3f4dc19b8ce994 /src/cpu/amd
parentcd3afc052492e577774b1978f47f2ed28cea7d01 (diff)
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
Diffstat (limited to 'src/cpu/amd')
-rw-r--r--src/cpu/amd/model_fxx/model_fxx_init.c85
-rw-r--r--src/cpu/amd/model_fxx/processor_name.c136
2 files changed, 136 insertions, 85 deletions
diff --git a/src/cpu/amd/model_fxx/model_fxx_init.c b/src/cpu/amd/model_fxx/model_fxx_init.c
index 4087ad6e11..685b9e1804 100644
--- a/src/cpu/amd/model_fxx/model_fxx_init.c
+++ b/src/cpu/amd/model_fxx/model_fxx_init.c
@@ -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
diff --git a/src/cpu/amd/model_fxx/processor_name.c b/src/cpu/amd/model_fxx/processor_name.c
index 6bbc353b8c..5e5e2589d9 100644
--- a/src/cpu/amd/model_fxx/processor_name.c
+++ b/src/cpu/amd/model_fxx/processor_name.c
@@ -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) {