2 Copyright © 2000, The AROS Development Team. All rights reserved.
5 Desc: Probe installed AMD CPUs and display relevant information
9 /* BIG TO DO - SEPERATE THE INDIVIDUAL PROCESSOR FAMILY "PROBES" INTO RUNTIME SHARED LIBS OR SIMILAR */
11 /****************************************************************************************************
14 i386 compatable families...
15 AMD 486/5x86/K5/K6/K6-II/K6-III/Athlon/Duron/Opteron/Athlon64
17 *****************************************************************************************************/
21 /********************************************
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 /********************************************
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",
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",
63 "22 : AMD MMX Instruction Extensions",
64 "MMX : MMX instructions",
65 "FXSR : FXSAVE/FXRSTOR",
71 "30 : 3DNow! Instruction Extensions",
72 "31 : 3DNow instructions",
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
)
114 //if (CPUi386->x86_capability & X86_FEATURE_TSC)
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 */
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
;
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 );
162 /********************************************/
164 void i386_AMD_K6_Parse_MSR ( int family
, int model
, int stepping
)
166 unsigned long msrvala
=0,msrvalb
=0;
168 printf("\t\t\t\t31 23 15 7 \n");
169 i386_Parse_MSR( MSR_K6_WHCR
, 32 );
171 if ( ( model
< 8 ) || ( ( model
==8 ) && ( stepping
<8 ) ) ) /* Original K6 or K6-2 (old core). */
173 i386_rdmsr( MSR_K6_WHCR
, msrvala
, msrvalb
)
174 if ( ( ( msrvalb
<< 32 ) | msrvala
) == 1 )
176 printf ("Write allocate enable limit: %dMbytes\n", (int) ( ( ( ( msrvalb
<< 32 ) | msrvala
) & 0x7e ) >>1 ) * 4 );
177 printf ("Write allocate 15-16M bytes: %s\n", ( ( msrvalb
<< 32 ) | msrvala
) & 1 ? "enabled" : "disabled" );
179 else printf ("Couldn't read WHCR register.\n");
183 if ( ( model
> 8 ) || ( ( model
== 8 ) && ( stepping
>= 8 ) ) ) /* K6-2 core (Stepping 8-F), K6-III or later. */
185 i386_rdmsr( MSR_K6_WHCR
, msrvala
, msrvalb
);
186 if ( ( ( msrvalb
<< 32 ) | msrvala
) == 1)
188 if (!( ( ( msrvalb
<< 32 ) | msrvala
) & ( 0x3ff << 22 ) ) ) printf (" Write allocate disabled\n");
191 printf (" Write allocate enable limit: %dMbytes\n", (int) ( ( ( ( msrvalb
<< 32 ) | msrvala
) >> 22) & 0x3ff ) * 4 );
192 printf (" Write allocate 15-16M bytes: %s\n", ( ( msrvalb
<< 32 ) | msrvala
) & (1<<16) ? "enabled" : "disabled" );
195 else printf (" Couldn't read WHCR register.\n");
199 if ( ( family
== 5 ) && ( model
>= 8 ) ) /* Dump EWBE register on K6-2 & K6-3 */
201 i386_rdmsr( MSR_K6_EFER
, msrvala
, msrvalb
);
202 if ( ( ( msrvalb
<< 32 ) | msrvala
) == 1 )
204 if ( ( ( msrvalb
<< 32 ) | msrvala
) & ( 1 << 0 ) ) printf ("System call extension present.\n");
205 if ( ( ( msrvalb
<< 32 ) | msrvala
) & ( 1 << 1 ) ) printf ("Data prefetch enabled.\n");
206 else printf (" Data prefetch disabled.\n");
208 printf (" EWBE mode: ");
209 switch ( ( ( ( msrvalb
<< 32 ) | msrvala
) & ( 1 << 2 | 1 << 3 | 1 << 4 ) ) >> 2 )
211 case 0: printf (" strong ordering (slowest performance)\n");
213 case 1: printf (" speculative disable (close to best performance)\n");
215 case 2: printf (" invalid\n");
217 case 3: printf (" global disable (best performance)\n");
221 else printf (" Couldn't read EFER register.\n");
227 /********************************************/
230 /********************************************/
232 void parse_i386_AMD ( int maxi
, struct i386_compat_intern
* CPUi386
)
234 struct CPU_INTERN_DATA
*global
;
235 ULONG speed
, maxei
,unused
,connection
;
236 char *BUFF_STR
, *AMD_CPU_NAME
, *AMD_CPU_IDENTITY
, *AMD_CPU_FEATURES
, *AMD_CPU_CACHE
, *AMD_CPU_ADDR
;
237 int AMD_CPU_NAME_cnt
, AMD_CPU_IDENTITY_cnt
, AMD_CPU_FEATURES_cnt
, AMD_CPU_CACHE_cnt
, AMD_CPU_ADDR_cnt
;
238 int stepping
,model
,reserved
;
241 if ( ( global
= AllocMem( sizeof( struct CPU_INTERN_DATA
), MEMF_PUBLIC
|MEMF_CLEAR
) ) )
243 AMD_CPU_NAME
= global
->CPU_NAME
;
244 AMD_CPU_IDENTITY
= global
->CPU_IDENTITY
;
245 AMD_CPU_FEATURES
= global
->CPU_FEATURES
;
246 AMD_CPU_CACHE
= global
->CPU_CACHE
;
247 AMD_CPU_ADDR
= global
->CPU_ADDR
;
248 BUFF_STR
= global
->CPU_BUFF
;
250 AMD_CPU_NAME_cnt
= AMD_CPU_IDENTITY_cnt
= AMD_CPU_FEATURES_cnt
= AMD_CPU_CACHE_cnt
= AMD_CPU_ADDR_cnt
= 0;
252 AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, " AMD-specific functions\n");
254 if ( maxi
>= 1 ) /* Do standard stuff */
256 unsigned long eax
,ebx
,edx
,unused
,extended_family
;
258 i386_cpuid( 1, eax
, ebx
, unused
, edx
);
260 stepping
= eax
& 0xf;
261 model
= ( eax
>> 4 ) & 0xf;
262 family
= ( eax
>> 8 ) & 0xf;
263 reserved
= eax
>> 12;
267 extended_family
= (eax
>> 20) & 0xff;
268 sprintf( BUFF_STR
," Extended family %d",extended_family
);
269 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, BUFF_STR
);
271 switch ( extended_family
)
274 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "AMD K8" );
280 sprintf( BUFF_STR
," Version %08lx:\n",eax
);
281 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, BUFF_STR
);
282 sprintf( BUFF_STR
," Family: %d Model: %d [",family
,model
);
283 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, BUFF_STR
);
287 connection
= CONN_SOCKET_3
;
291 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "486DX2" );
294 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "486DX2-WB" );
297 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "486DX4");
300 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "486DX4-WB");
303 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Elan SC400");
306 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "5x86");
309 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "5x86-WB");
314 connection
= CONN_SOCKET_7
;
318 connection
= CONN_SOCKET_5_7
;
319 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "SSA5 (PR75/90/100)");
322 connection
= CONN_SOCKET_5_7
;
323 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "5k86 (PR120/133)");
326 connection
= CONN_SOCKET_5_7
;
327 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "5k86 (PR166)");
330 connection
= CONN_SOCKET_5_7
;
331 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "5k86 (PR200)");
334 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6 Model 6 (0.30 µm)");
337 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6 Model 7 (0.25 µm)");
340 connection
= CONN_SUPER_SOCKET_7
;
341 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6-2");
344 connection
= CONN_SUPER_SOCKET_7
;
345 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6-III");
348 connection
= CONN_SUPER_SOCKET_7
;
349 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6-2+ (0.18 µm)");
352 connection
= CONN_SUPER_SOCKET_7
;
353 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6-2+ or K6-III+ (0.18 µm)");
356 sprintf( BUFF_STR
,"K5/K6 model %d",model
);
357 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, BUFF_STR
);
362 connection
= CONN_SOCKET_A
;
363 if ( ( model
> 4) && ( i386_AMD_isMobile( maxi
) == TRUE
) ) AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Mobile ");
367 connection
= CONN_SLOT_A
;
368 switch ( CPUi386
->x86
)
371 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [C1] (0.25 µm)");
374 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [C2] (0.25 µm)");
379 connection
= CONN_SLOT_A
;
380 switch ( CPUi386
->x86
)
383 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A1] (0.18 µm)");
386 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A2] (0.18 µm)");
391 switch ( CPUi386
->x86
)
394 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Duron Model [A0] (0.18 µm)(SF Core)");
397 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Duron Model [A2] (0.18 µm)(SF Core)");
402 switch ( CPUi386
->x86
)
405 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A1] (0.18 µm) (TB Core)");
408 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A2] (0.18 µm) (TB Core)");
411 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A4-A8] (0.18 µm) (TB Core)");
414 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A9] (0.18 µm) (TB Core)");
419 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon MP/Mobile Athlon Model 6 (0.18 µm) (PM Core)");
422 switch ( CPUi386
->x86
)
425 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Duron Model [A0] (MG Core)");
428 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Duron Model [A1] (MG Core)");
433 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model 8 (TH/AP Core)");
436 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model 10 (BT Core)");
439 sprintf( BUFF_STR
,"Duron/Athlon model %d",model
);
440 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, BUFF_STR
);
448 connection
= CONN_SOCKET_754
;
449 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon 64 (0.13 µm)");
452 connection
= CONN_SOCKET_754
;
453 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon 64 FX or Opteron (0.13 µm)");
456 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Unknown 64bit Model!");
462 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Unknown Model!");
466 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "]\n");
470 sprintf( BUFF_STR
," Standard feature flags [%08lx]:\n",edx
);
471 AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, BUFF_STR
);
474 if(family
== 5 && model
== 0)
476 if(i
== 9) AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, " Global Paging Extensions\n");
477 else if(i
== 13) AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, "13 - reserved\n");
479 else if(edx
& (1<<i
))
481 sprintf( BUFF_STR
," %s\n",AMD_feature_flags
[i
]);
482 AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, BUFF_STR
);
486 AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, "\n");
490 i386_cpuid( 0x80000000, maxei
, unused
, unused
, unused
); /* Check for presence of extended info */
492 if ( maxei
== 0 ) return;
494 int stepping
,model
,generation
,reserved
;
496 if ( maxei
>= 0x80000001 )
498 unsigned long eax
,ebx
,ecx
,edx
;
501 i386_cpuid(0x80000001,eax
,ebx
,ecx
,edx
);
502 stepping
= eax
& 0xf;
503 model
= (eax
>> 4) & 0xf;
504 generation
= (eax
>> 8) & 0xf;
505 reserved
= eax
>> 12;
507 sprintf( BUFF_STR
," Generation: %d Model: %d\n\n",generation
,model
);
508 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, BUFF_STR
);
509 sprintf( BUFF_STR
," Extended feature flags [%08lx]:\n",edx
);
510 AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, BUFF_STR
);
513 if(family
== 5 && model
== 0 && i
== 9) AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, " Global Paging Extensions\n");
514 else if(edx
& (1<<i
))
516 sprintf( BUFF_STR
," %s\n",AMD_feature_flags
[i
]);
517 AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, BUFF_STR
);
522 AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, "\n");
523 if ( maxei
>= 0x80000002 ) /* Processor identification string */
526 AMD_CPU_NAME_cnt
= AddBufferLine( AMD_CPU_NAME_cnt
, AMD_CPU_NAME
, " Processor name string: ");
527 for(j
=0x80000002;j
<=0x80000004;j
++)
529 unsigned long eax
,ebx
,ecx
,edx
;
531 i386_cpuid(j
,eax
,ebx
,ecx
,edx
);
532 AMD_CPU_NAME_cnt
= i386_sprintregs(AMD_CPU_NAME_cnt
, AMD_CPU_NAME
, eax
,ebx
,ecx
,edx
);
534 AMD_CPU_NAME_cnt
= AddBufferLine( AMD_CPU_NAME_cnt
, AMD_CPU_NAME
, "\n");
537 if ( maxei
>= 0x80000005 ) /* TLB and cache info */
540 unsigned long eax
,ebx
,ecx
,edx
;
542 i386_cpuid(0x80000005,eax
,ebx
,ecx
,edx
);
543 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, " L1 Cache Information:\n");
547 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, " 2/4-MB Pages:\n");
548 sprintf( BUFF_STR
," Data TLB: associativity %ld-way #entries %ld\n", (eax
>> 24) & 0xff,(eax
>> 16) & 0xff);
549 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
550 sprintf( BUFF_STR
," Instruction TLB: associativity %ld-way #entries %ld\n", (eax
>> 8) & 0xff,eax
& 0xff);
551 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
554 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, " 4-KB Pages:\n");
555 sprintf( BUFF_STR
," Data TLB: associativity %ld-way #entries %ld\n", (ebx
>> 24) & 0xff,(ebx
>> 16) & 0xff);
556 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
557 sprintf( BUFF_STR
," Instruction TLB: associativity %ld-way #entries %ld\n", (ebx
>> 8) & 0xff,ebx
& 0xff);
558 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
560 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, " L1 Data cache:\n");
561 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);
562 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
564 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, " L1 Instruction cache:\n");
565 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);
566 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
569 if ( maxei
>= 0x80000006 ) /* check K6-III (and later?) on-chip L2 cache size */
571 unsigned long eax
,ebx
,ecx
,unused
;
574 i386_cpuid(0x80000006,eax
,ebx
,ecx
,unused
);
575 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, " L2 Cache Information:\n");
579 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, " 2/4-MB Pages:\n");
580 assoc
= (eax
>> 24) & 0xff;
582 if(assoc
== 6) assoc
= 8;
584 sprintf( BUFF_STR
," Data TLB: associativity %s #entries %ld\n", Assoc
[(eax
>> 24) & 0xf],(eax
>> 16) & 0xff);
585 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
586 assoc
= (eax
>> 16) & 0xff;
587 sprintf( BUFF_STR
," Instruction TLB: associativity %s #entries %ld\n", Assoc
[(eax
>> 8) & 0xf],eax
& 0xff);
588 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
590 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, " 4-KB Pages:\n");
591 sprintf( BUFF_STR
," Data TLB: associativity %s #entries %ld\n", Assoc
[(ebx
>> 24) & 0xf],(ebx
>> 16) & 0xff);
592 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
593 sprintf( BUFF_STR
," Instruction TLB: associativity %s #entries %ld\n", Assoc
[(ebx
>> 8) & 0xf],ebx
& 0xff);
594 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
596 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);
597 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, BUFF_STR
);
599 AMD_CPU_CACHE_cnt
= AddBufferLine( AMD_CPU_CACHE_cnt
, AMD_CPU_CACHE
, "\n");
602 if ( maxei
>= 0x80000007 ) /* Check power management feature flags */
604 unsigned long unused
,edx
;
606 AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, " Advanced Power Management (PowerNOW!) Feature Flags\n");
608 i386_cpuid(0x80000007,unused
,unused
,unused
,edx
);
609 if(edx
& 1) AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, " Temperature Sensing Diode\n");
610 if(edx
& 2) AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, " Supports Frequency ID control\n");
611 if(edx
& 4) AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, " Supports Voltage ID control\n");
612 if(edx
& 8) AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, " Supports Thermal Trip\n");
613 if(edx
& 16) AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, " Supports Thermal Monitoring\n");
614 if(edx
& 31) AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, " Supports Software Thermal Control\n");
615 AMD_CPU_FEATURES_cnt
= AddBufferLine( AMD_CPU_FEATURES_cnt
, AMD_CPU_FEATURES
, "\n");
618 if ( maxei
>= 0x80000008 ) /* Check phys address & linear address size */
620 unsigned long unused
,eax
;
622 i386_cpuid(0x80000008,eax
,unused
,unused
,unused
);
623 sprintf( BUFF_STR
," Maximum LINEAR address: %ld; Maximum PHYSICAL address %ld\n\n", (eax
>>8) & 0xff,eax
&0xff);
624 AMD_CPU_ADDR_cnt
= AddBufferLine( AMD_CPU_ADDR_cnt
, AMD_CPU_ADDR
, BUFF_STR
);
627 /** DUMP ALL THE INFORMATION WE HAVE GATHERED **/
629 if ( AMD_CPU_NAME_cnt
> 0 ) printf( AMD_CPU_NAME
); /* CPUs Retail Name */
631 speed
= i386_approx_mhz();
633 i386_poll_AMD32_FSB( speed
, CPUi386
); /* Calculate FSB .. */
636 if ( AMD_CPU_IDENTITY_cnt
> 0 ) printf( AMD_CPU_IDENTITY
); /* CPUs Internal Name */
637 if ( AMD_CPU_FEATURES_cnt
> 0 ) printf( AMD_CPU_FEATURES
); /* CPUs Feature Set */
638 if ( AMD_CPU_ADDR_cnt
> 0 ) printf( AMD_CPU_ADDR
); /* CPUs Address Range */
639 if ( AMD_CPU_CACHE_cnt
> 0 ) printf( AMD_CPU_CACHE
); /* CPUs Cache Details */
641 /*if ( family == 5 ) i386_AMD_K6_Parse_MSR( family, model, stepping );
642 if ( family == 6 ) i386_AMD_Athlon_Parse_MSR(); */
646 printf( "ERROR: Couldn't allocate memory to parse CPU information .." );
649 FreeMem(global
,sizeof(struct CPU_INTERN_DATA
));