grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / c / CPUInfo / x86_AMD.c
blob42772af7b3bddc3970bb63b716bff19015a8952d
1 /*
2 Copyright © 2000, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Probe installed AMD CPUs and display relevant information
6 Lang: english
7 */
9 /* BIG TO DO - SEPERATE THE INDIVIDUAL PROCESSOR FAMILY "PROBES" INTO RUNTIME SHARED LIBS OR SIMILAR */
11 /****************************************************************************************************
12 Currently Supports:
14 i386 compatable families...
15 AMD 486/5x86/K5/K6/K6-II/K6-III/Athlon/Duron/Opteron/Athlon64
17 *****************************************************************************************************/
19 #include "x86.h"
21 /********************************************
22 Structures
23 ********************************************/
25 #define i386_amd_MAXBRANDS 7
26 char *i386_amd_Brands[i386_amd_MAXBRANDS] = {
27 "engineering sample NN (NN=xxxxxb)",
28 "AMD Athlon 64 XX00+ (XX=22+xxxxxb)",
29 "AMD Athlon 64 XX00+ (XX=22+xxxxxb) mobile",
30 "AMD Opteron UP 1YY (YY=38+2*xxxxxb)",
31 "AMD Opteron DP 2YY (YY=38+2*xxxxxb)",
32 "AMD Opteron MP 8YY (YY=38+2*xxxxxb)",
33 "AMD Athlon 64 FX-ZZ (ZZ=24+xxxxxb)",
36 /********************************************
37 AMD CPU Features
38 ********************************************/
40 char *AMD_feature_flags[] = {
41 "FPU : Floating Point Unit",
42 "VME : Virtual Mode Extensions",
43 "DE : Debugging Extensions",
44 "PSE : Page Size Extensions",
45 "TSC : Time Stamp Counter (with RDTSC and CR4 disable bit)",
46 "MSR : Model Specific Registers with i386_rdmsr & WRMSR",
47 "PAE : Page Address Extensions",
48 "MCE : Machine Check Exception",
49 "CX8 : COMPXCHG8B Instruction",
50 "APIC : On-chip Advanced Programmable Interrupt Controller present and enabled",
51 "10 : Reserved",
52 "SEP : SYSCALL/SYSRET or SYSENTER/SYSEXIT instructions",
53 "MTRR : Memory Type Range Registers",
54 "PGE : Global paging extension",
55 "MCA : Machine Check Architecture",
56 "CMOV : Conditional Move Instruction",
57 "PAT : Page Attribute Table",
58 "PSE-36 : Page Size Extensions",
59 "18 : Reserved",
60 "19 : Reserved",
61 "20 : Reserved",
62 "21 : Reserved",
63 "22 : AMD MMX Instruction Extensions",
64 "MMX : MMX instructions",
65 "FXSR : FXSAVE/FXRSTOR",
66 "25 : Reserved",
67 "26 : Reserved",
68 "27 : Reserved",
69 "28 : Reserved",
70 "29 : Reserved",
71 "30 : 3DNow! Instruction Extensions",
72 "31 : 3DNow instructions",
75 char *Assoc[] = {
76 "L2 off",
77 "Direct mapped",
78 "2-way",
79 "Reserved",
80 "4-way",
81 "Reserved",
82 "8-way",
83 "Reserved",
84 "16-way",
85 "Reserved",
86 "Reserved",
87 "Reserved",
88 "Reserved",
89 "Reserved",
90 "Reserved",
91 "FULL",
94 /********************************************
95 Data for FSB detection
96 ********************************************/
98 int amd64cm[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x4, 0x6, 0xB, 0xA, 0xC, 0xE, 0x10, 0x12, 0x14};
99 float athloncoef[] = {11, 11.5, 12.0, 12.5, 5.0, 5.5, 6.0, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 10.5};
100 float athloncoef2[] = {12, 19.0, 12, 20.0, 13.0, 13.5, 14.0, 21.0, 15, 22, 16, 16.5, 17, 18.0, 23, 24};
102 /********************************************
103 AMD-specific information
104 ********************************************/
106 void i386_poll_AMD32_FSB ( ULONG extclock, struct i386_compat_intern * CPUi386 )
108 //unsigned int mcgsrl;
109 //unsigned int mcgsth;
110 //unsigned long temp;
111 //double dramclock;
112 //float coef;
114 //if (CPUi386->x86_capability & X86_FEATURE_TSC)
116 // coef = 10;
118 // i386_rdmsr(MSR_K7_HWCR, mcgsrl, mcgsth); /* First, got the FID */
119 // temp = (mcgsrl >> 24)&0x0F;
121 // if ((mcgsrl >> 19)&1) { coef = athloncoef2[temp]; }
122 // else { coef = athloncoef[temp]; }
124 // if (coef == 0) { coef = 1; };
126 // dramclock = (extclock /1000) / coef; /* Compute the final FSB Clock */
128 /* ...and print */
129 // printf(" Settings: FSB : %d Mhz (DDR) %d ", dramclock, (dramclock*2));
131 //else printf("\n WARNING! CPU doesnt support RDMSR - could not obtain FSB speed.\n");
134 /********************************************/
136 BOOL i386_AMD_isMobile ( int maxi )
138 unsigned long eax, ebx, ecx, edx;
140 if ( maxi >= 0x80000007 )
142 i386_cpuid( 0x80000007, eax, ebx, ecx, edx );
143 if ((edx & (1<<1|1<<2)) == 0) return FALSE;
144 else return TRUE;
146 else return FALSE;
149 /********************************************/
151 void i386_AMD_Athlon_Parse_MSR ( void )
153 printf("\t\t\t\t31 23 15 7 \n");
154 i386_Parse_MSR( 0x2A, 32 );
155 i386_Parse_MSR( MSR_K6_EFER, 32 );
156 i386_Parse_MSR( 0xC0010010, 32 );
157 i386_Parse_MSR( MSR_K7_HWCR, 32 );
158 i386_Parse_MSR( 0xC001001B, 32 );
159 printf ("\n");
162 /********************************************/
164 void i386_AMD_K6_Parse_MSR ( int family, int model, int stepping )
166 unsigned long msrvala=0,msrvalb=0;
167 unsigned long long msrval;
169 printf("\t\t\t\t31 23 15 7 \n");
170 i386_Parse_MSR( MSR_K6_WHCR, 32 );
172 if ( ( model < 8 ) || ( ( model==8 ) && ( stepping <8 ) ) ) /* Original K6 or K6-2 (old core). */
174 i386_rdmsr( MSR_K6_WHCR, msrvala, msrvalb )
175 msrval = ( (unsigned long long)msrvalb << 32 ) | msrvala;
176 if ( msrval == 1 )
178 printf ("Write allocate enable limit: %dMbytes\n", (int) ( ( msrval & 0x7e ) >>1 ) * 4 );
179 printf ("Write allocate 15-16M bytes: %s\n", msrval & 1 ? "enabled" : "disabled" );
181 else printf ("Couldn't read WHCR register.\n");
185 if ( ( model > 8 ) || ( ( model == 8 ) && ( stepping >= 8 ) ) ) /* K6-2 core (Stepping 8-F), K6-III or later. */
187 i386_rdmsr( MSR_K6_WHCR, msrvala, msrvalb );
188 if ( msrval == 1)
190 if (!( msrval & ( 0x3ff << 22 ) ) ) printf (" Write allocate disabled\n");
191 else
193 printf (" Write allocate enable limit: %dMbytes\n", (int) ( ( msrval >> 22) & 0x3ff ) * 4 );
194 printf (" Write allocate 15-16M bytes: %s\n", msrval & (1<<16) ? "enabled" : "disabled" );
197 else printf (" Couldn't read WHCR register.\n");
201 if ( ( family == 5 ) && ( model >= 8 ) ) /* Dump EWBE register on K6-2 & K6-3 */
203 i386_rdmsr( MSR_K6_EFER, msrvala, msrvalb );
204 if ( msrval == 1 )
206 if ( msrval & ( 1 << 0 ) ) printf ("System call extension present.\n");
207 if ( msrval & ( 1 << 1 ) ) printf ("Data prefetch enabled.\n");
208 else printf (" Data prefetch disabled.\n");
210 printf (" EWBE mode: ");
211 switch ( ( msrval & ( 1 << 2 | 1 << 3 | 1 << 4 ) ) >> 2 )
213 case 0: printf (" strong ordering (slowest performance)\n");
214 break;
215 case 1: printf (" speculative disable (close to best performance)\n");
216 break;
217 case 2: printf (" invalid\n");
218 break;
219 case 3: printf (" global disable (best performance)\n");
220 break;
223 else printf (" Couldn't read EFER register.\n");
226 printf ("\n");
229 /********************************************
232 ********************************************/
234 void parse_i386_AMD ( int maxi, struct i386_compat_intern * CPUi386 )
236 struct CPU_INTERN_DATA *global;
237 ULONG __unused__ speed, maxei,unused,connection;
238 char *BUFF_STR, *AMD_CPU_NAME, *AMD_CPU_IDENTITY, *AMD_CPU_FEATURES, *AMD_CPU_CACHE, *AMD_CPU_ADDR;
239 int AMD_CPU_NAME_cnt, AMD_CPU_IDENTITY_cnt, AMD_CPU_FEATURES_cnt, AMD_CPU_CACHE_cnt, AMD_CPU_ADDR_cnt;
240 int __unused__ stepping,model,reserved;
241 int family = 0;
243 if ( ( global = AllocMem( sizeof( struct CPU_INTERN_DATA ), MEMF_PUBLIC|MEMF_CLEAR ) ) )
245 AMD_CPU_NAME = global->CPU_NAME;
246 AMD_CPU_IDENTITY = global->CPU_IDENTITY;
247 AMD_CPU_FEATURES = global->CPU_FEATURES;
248 AMD_CPU_CACHE = global->CPU_CACHE;
249 AMD_CPU_ADDR = global->CPU_ADDR;
250 BUFF_STR = global->CPU_BUFF;
252 AMD_CPU_NAME_cnt = AMD_CPU_IDENTITY_cnt = AMD_CPU_FEATURES_cnt = AMD_CPU_CACHE_cnt = AMD_CPU_ADDR_cnt = 0;
254 AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, " AMD-specific functions\n");
256 if ( maxi >= 1 ) /* Do standard stuff */
258 unsigned long eax,ebx,edx,unused,extended_family;
260 i386_cpuid( 1, eax, ebx, unused, edx);
262 stepping = eax & 0xf;
263 model = ( eax >> 4 ) & 0xf;
264 family = ( eax >> 8 ) & 0xf;
265 reserved = eax >> 12;
267 if ( family == 15 )
269 extended_family = (eax >> 20) & 0xff;
270 sprintf( BUFF_STR," Extended family %lu",extended_family);
271 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, BUFF_STR);
273 switch ( extended_family )
275 case 0:
276 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "AMD K8" );
277 break;
282 sprintf( BUFF_STR," Version %08lx:\n",eax);
283 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, BUFF_STR );
284 sprintf( BUFF_STR," Family: %d Model: %d [",family,model);
285 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, BUFF_STR );
286 switch(family)
288 case 4:
289 connection = CONN_SOCKET_3;
290 switch ( model )
292 case 3:
293 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "486DX2" );
294 break;
295 case 7:
296 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "486DX2-WB" );
297 break;
298 case 8:
299 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "486DX4");
300 break;
301 case 9:
302 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "486DX4-WB");
303 break;
304 case 10:
305 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Elan SC400");
306 break;
307 case 14:
308 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "5x86");
309 break;
310 case 15:
311 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "5x86-WB");
312 break;
314 break;
315 case 5:
316 connection = CONN_SOCKET_7;
317 switch ( model )
319 case 0:
320 connection = CONN_SOCKET_5_7;
321 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "SSA5 (PR75/90/100)");
322 break;
323 case 1:
324 connection = CONN_SOCKET_5_7;
325 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "5k86 (PR120/133)");
326 break;
327 case 2:
328 connection = CONN_SOCKET_5_7;
329 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "5k86 (PR166)");
330 break;
331 case 3:
332 connection = CONN_SOCKET_5_7;
333 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "5k86 (PR200)");
334 break;
335 case 6:
336 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "K6 Model 6 (0.30 µm)");
337 break;
338 case 7:
339 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "K6 Model 7 (0.25 µm)");
340 break;
341 case 8:
342 connection = CONN_SUPER_SOCKET_7;
343 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "K6-2");
344 break;
345 case 9:
346 connection = CONN_SUPER_SOCKET_7;
347 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "K6-III");
348 break;
349 case 11:
350 connection = CONN_SUPER_SOCKET_7;
351 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "K6-2+ (0.18 µm)");
352 break;
353 case 13:
354 connection = CONN_SUPER_SOCKET_7;
355 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "K6-2+ or K6-III+ (0.18 µm)");
356 break;
357 default:
358 sprintf( BUFF_STR,"K5/K6 model %d",model);
359 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, BUFF_STR);
360 break;
362 break;
363 case 6:
364 connection = CONN_SOCKET_A;
365 if ( ( model > 4) && ( i386_AMD_isMobile( maxi ) == TRUE ) ) AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Mobile ");
366 switch ( model )
368 case 1:
369 connection = CONN_SLOT_A;
370 switch ( CPUi386->x86 )
372 case 1:
373 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon Model [C1] (0.25 µm)");
374 break;
375 case 2:
376 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon Model [C2] (0.25 µm)");
377 break;
379 break;
380 case 2:
381 connection = CONN_SLOT_A;
382 switch ( CPUi386->x86 )
384 case 1:
385 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon Model [A1] (0.18 µm)");
386 break;
387 case 2:
388 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon Model [A2] (0.18 µm)");
389 break;
391 break;
392 case 3:
393 switch ( CPUi386->x86 )
395 case 0:
396 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Duron Model [A0] (0.18 µm)(SF Core)");
397 break;
398 case 1:
399 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Duron Model [A2] (0.18 µm)(SF Core)");
400 break;
402 break;
403 case 4:
404 switch ( CPUi386->x86 )
406 case 0:
407 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon Model [A1] (0.18 µm) (TB Core)");
408 break;
409 case 1:
410 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon Model [A2] (0.18 µm) (TB Core)");
411 break;
412 case 2:
413 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon Model [A4-A8] (0.18 µm) (TB Core)");
414 break;
415 case 3:
416 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon Model [A9] (0.18 µm) (TB Core)");
417 break;
419 break;
420 case 6:
421 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon MP/Mobile Athlon Model 6 (0.18 µm) (PM Core)");
422 break;
423 case 7:
424 switch ( CPUi386->x86 )
426 case 0:
427 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Duron Model [A0] (MG Core)");
428 break;
429 case 1:
430 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Duron Model [A1] (MG Core)");
431 break;
433 break;
434 case 8:
435 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon Model 8 (TH/AP Core)");
436 break;
437 case 10:
438 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon Model 10 (BT Core)");
439 break;
440 default:
441 sprintf( BUFF_STR,"Duron/Athlon model %d",model);
442 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, BUFF_STR);
443 break;
445 break;
446 case 15:
447 switch ( model )
449 case 4:
450 connection = CONN_SOCKET_754;
451 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon 64 (0.13 µm)");
452 break;
453 case 5:
454 connection = CONN_SOCKET_754;
455 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Athlon 64 FX or Opteron (0.13 µm)");
456 break;
457 default:
458 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Unknown 64bit Model!");
459 break;
461 break;
463 default:
464 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "Unknown Model!");
465 break;
468 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, "]\n");
470 int i;
472 sprintf( BUFF_STR," Standard feature flags [%08lx]:\n",edx);
473 AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, BUFF_STR);
474 for(i=0;i<32;i++)
476 if(family == 5 && model == 0)
478 if(i == 9) AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, " Global Paging Extensions\n");
479 else if(i == 13) AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, "13 - reserved\n");
481 else if(edx & (1<<i))
483 sprintf( BUFF_STR," %s\n",AMD_feature_flags[i]);
484 AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, BUFF_STR);
488 AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, "\n");
492 i386_cpuid( 0x80000000, maxei, unused, unused, unused ); /* Check for presence of extended info */
494 if ( maxei == 0 ) return;
496 int __unused__ stepping,model,generation,reserved;
498 if ( maxei >= 0x80000001 )
500 unsigned long eax,ebx,ecx,edx;
501 int i;
503 i386_cpuid(0x80000001,eax,ebx,ecx,edx);
504 stepping = eax & 0xf;
505 model = (eax >> 4) & 0xf;
506 generation = (eax >> 8) & 0xf;
507 reserved = eax >> 12;
509 sprintf( BUFF_STR," Generation: %d Model: %d\n\n",generation,model);
510 AMD_CPU_IDENTITY_cnt = AddBufferLine( AMD_CPU_IDENTITY_cnt, AMD_CPU_IDENTITY, BUFF_STR);
511 sprintf( BUFF_STR," Extended feature flags [%08lx]:\n",edx);
512 AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, BUFF_STR);
513 for(i=0;i<32;i++)
515 if(family == 5 && model == 0 && i == 9) AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, " Global Paging Extensions\n");
516 else if(edx & (1<<i))
518 sprintf( BUFF_STR," %s\n",AMD_feature_flags[i]);
519 AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, BUFF_STR);
524 AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, "\n");
525 if ( maxei >= 0x80000002 ) /* Processor identification string */
527 int j;
528 AMD_CPU_NAME_cnt = AddBufferLine( AMD_CPU_NAME_cnt, AMD_CPU_NAME, " Processor name string: ");
529 for(j=0x80000002;j<=0x80000004;j++)
531 unsigned long eax,ebx,ecx,edx;
533 i386_cpuid(j,eax,ebx,ecx,edx);
534 AMD_CPU_NAME_cnt = i386_sprintregs(AMD_CPU_NAME_cnt, AMD_CPU_NAME, eax,ebx,ecx,edx);
536 AMD_CPU_NAME_cnt = AddBufferLine( AMD_CPU_NAME_cnt, AMD_CPU_NAME, "\n");
539 if ( maxei >= 0x80000005 ) /* TLB and cache info */
542 unsigned long eax,ebx,ecx,edx;
544 i386_cpuid(0x80000005,eax,ebx,ecx,edx);
545 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, " L1 Cache Information:\n");
547 if(family >= 6)
549 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, " 2/4-MB Pages:\n");
550 sprintf( BUFF_STR," Data TLB: associativity %ld-way #entries %ld\n", (eax >> 24) & 0xff,(eax >> 16) & 0xff);
551 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
552 sprintf( BUFF_STR," Instruction TLB: associativity %ld-way #entries %ld\n", (eax >> 8) & 0xff,eax & 0xff);
553 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
556 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, " 4-KB Pages:\n");
557 sprintf( BUFF_STR," Data TLB: associativity %ld-way #entries %ld\n", (ebx >> 24) & 0xff,(ebx >> 16) & 0xff);
558 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
559 sprintf( BUFF_STR," Instruction TLB: associativity %ld-way #entries %ld\n", (ebx >> 8) & 0xff,ebx & 0xff);
560 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
562 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, " L1 Data cache:\n");
563 sprintf( BUFF_STR," size %ld KB associativity %lx-way lines per tag %ld line size %ld\n", ecx >> 24,(ecx>>16) & 0xff,(ecx >> 8)&0xff,ecx&0xff);
564 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
566 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, " L1 Instruction cache:\n");
567 sprintf( BUFF_STR," size %ld KB associativity %lx-way lines per tag %ld line size %ld\n\n", edx >> 24,(edx>>16) & 0xff,(edx >> 8)&0xff,edx&0xff);
568 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
571 if ( maxei >= 0x80000006 ) /* check K6-III (and later?) on-chip L2 cache size */
573 unsigned long eax,ebx,ecx,unused;
574 int assoc;
576 i386_cpuid(0x80000006,eax,ebx,ecx,unused);
577 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, " L2 Cache Information:\n");
579 if(family >= 6)
581 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, " 2/4-MB Pages:\n");
582 assoc = (eax >> 24) & 0xff;
584 if(assoc == 6) assoc = 8;
586 sprintf( BUFF_STR," Data TLB: associativity %s #entries %ld\n", Assoc[(eax >> 24) & 0xf],(eax >> 16) & 0xff);
587 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
588 assoc = (eax >> 16) & 0xff;
589 sprintf( BUFF_STR," Instruction TLB: associativity %s #entries %ld\n", Assoc[(eax >> 8) & 0xf],eax & 0xff);
590 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
592 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, " 4-KB Pages:\n");
593 sprintf( BUFF_STR," Data TLB: associativity %s #entries %ld\n", Assoc[(ebx >> 24) & 0xf],(ebx >> 16) & 0xff);
594 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
595 sprintf( BUFF_STR," Instruction TLB: associativity %s #entries %ld\n", Assoc[(ebx >> 8) & 0xf],ebx & 0xff);
596 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
598 sprintf( BUFF_STR," size %ld KB associativity %s lines per tag %ld line size %ld\n", ecx >> 24,Assoc[(ecx>>16) & 0xf],(ecx >> 8)&0xff,ecx&0xff);
599 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, BUFF_STR);
601 AMD_CPU_CACHE_cnt = AddBufferLine( AMD_CPU_CACHE_cnt, AMD_CPU_CACHE, "\n");
604 if ( maxei >= 0x80000007 ) /* Check power management feature flags */
606 unsigned long unused,edx;
608 AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, " Advanced Power Management (PowerNOW!) Feature Flags\n");
610 i386_cpuid(0x80000007,unused,unused,unused,edx);
611 if(edx & 1) AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, " Temperature Sensing Diode\n");
612 if(edx & 2) AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, " Supports Frequency ID control\n");
613 if(edx & 4) AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, " Supports Voltage ID control\n");
614 if(edx & 8) AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, " Supports Thermal Trip\n");
615 if(edx & 16) AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, " Supports Thermal Monitoring\n");
616 if(edx & 31) AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, " Supports Software Thermal Control\n");
617 AMD_CPU_FEATURES_cnt = AddBufferLine( AMD_CPU_FEATURES_cnt, AMD_CPU_FEATURES, "\n");
620 if ( maxei >= 0x80000008 ) /* Check phys address & linear address size */
622 unsigned long unused,eax;
624 i386_cpuid(0x80000008,eax,unused,unused,unused);
625 sprintf( BUFF_STR," Maximum LINEAR address: %ld; Maximum PHYSICAL address %ld\n\n", (eax>>8) & 0xff,eax&0xff);
626 AMD_CPU_ADDR_cnt = AddBufferLine( AMD_CPU_ADDR_cnt, AMD_CPU_ADDR, BUFF_STR);
629 /** DUMP ALL THE INFORMATION WE HAVE GATHERED **/
631 if ( AMD_CPU_NAME_cnt > 0 ) printf( AMD_CPU_NAME ); /* CPUs Retail Name */
633 speed = i386_approx_mhz();
635 i386_poll_AMD32_FSB( speed, CPUi386 ); /* Calculate FSB .. */
638 if ( AMD_CPU_IDENTITY_cnt > 0 ) printf( AMD_CPU_IDENTITY ); /* CPUs Internal Name */
639 if ( AMD_CPU_FEATURES_cnt > 0 ) printf( AMD_CPU_FEATURES ); /* CPUs Feature Set */
640 if ( AMD_CPU_ADDR_cnt > 0 ) printf( AMD_CPU_ADDR ); /* CPUs Address Range */
641 if ( AMD_CPU_CACHE_cnt > 0 ) printf( AMD_CPU_CACHE ); /* CPUs Cache Details */
643 /*if ( family == 5 ) i386_AMD_K6_Parse_MSR( family, model, stepping );
644 if ( family == 6 ) i386_AMD_Athlon_Parse_MSR(); */
646 else
648 printf( "ERROR: Couldn't allocate memory to parse CPU information .." );
649 return;
651 FreeMem(global,sizeof(struct CPU_INTERN_DATA));