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
)
108 //unsigned int mcgsrl;
109 //unsigned int mcgsth;
110 //unsigned long temp;
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;
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
;
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
);
190 if (!( msrval
& ( 0x3ff << 22 ) ) ) printf (" Write allocate disabled\n");
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
);
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");
215 case 1: printf (" speculative disable (close to best performance)\n");
217 case 2: printf (" invalid\n");
219 case 3: printf (" global disable (best performance)\n");
223 else printf (" Couldn't read EFER register.\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
;
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;
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
)
276 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "AMD K8" );
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
);
289 connection
= CONN_SOCKET_3
;
293 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "486DX2" );
296 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "486DX2-WB" );
299 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "486DX4");
302 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "486DX4-WB");
305 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Elan SC400");
308 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "5x86");
311 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "5x86-WB");
316 connection
= CONN_SOCKET_7
;
320 connection
= CONN_SOCKET_5_7
;
321 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "SSA5 (PR75/90/100)");
324 connection
= CONN_SOCKET_5_7
;
325 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "5k86 (PR120/133)");
328 connection
= CONN_SOCKET_5_7
;
329 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "5k86 (PR166)");
332 connection
= CONN_SOCKET_5_7
;
333 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "5k86 (PR200)");
336 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6 Model 6 (0.30 µm)");
339 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6 Model 7 (0.25 µm)");
342 connection
= CONN_SUPER_SOCKET_7
;
343 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6-2");
346 connection
= CONN_SUPER_SOCKET_7
;
347 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6-III");
350 connection
= CONN_SUPER_SOCKET_7
;
351 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "K6-2+ (0.18 µm)");
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)");
358 sprintf( BUFF_STR
,"K5/K6 model %d",model
);
359 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, BUFF_STR
);
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 ");
369 connection
= CONN_SLOT_A
;
370 switch ( CPUi386
->x86
)
373 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [C1] (0.25 µm)");
376 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [C2] (0.25 µm)");
381 connection
= CONN_SLOT_A
;
382 switch ( CPUi386
->x86
)
385 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A1] (0.18 µm)");
388 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A2] (0.18 µm)");
393 switch ( CPUi386
->x86
)
396 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Duron Model [A0] (0.18 µm)(SF Core)");
399 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Duron Model [A2] (0.18 µm)(SF Core)");
404 switch ( CPUi386
->x86
)
407 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A1] (0.18 µm) (TB Core)");
410 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A2] (0.18 µm) (TB Core)");
413 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A4-A8] (0.18 µm) (TB Core)");
416 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model [A9] (0.18 µm) (TB Core)");
421 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon MP/Mobile Athlon Model 6 (0.18 µm) (PM Core)");
424 switch ( CPUi386
->x86
)
427 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Duron Model [A0] (MG Core)");
430 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Duron Model [A1] (MG Core)");
435 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model 8 (TH/AP Core)");
438 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon Model 10 (BT Core)");
441 sprintf( BUFF_STR
,"Duron/Athlon model %d",model
);
442 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, BUFF_STR
);
450 connection
= CONN_SOCKET_754
;
451 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Athlon 64 (0.13 µm)");
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)");
458 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Unknown 64bit Model!");
464 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "Unknown Model!");
468 AMD_CPU_IDENTITY_cnt
= AddBufferLine( AMD_CPU_IDENTITY_cnt
, AMD_CPU_IDENTITY
, "]\n");
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
);
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
;
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
);
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 */
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");
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
;
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");
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(); */
648 printf( "ERROR: Couldn't allocate memory to parse CPU information .." );
651 FreeMem(global
,sizeof(struct CPU_INTERN_DATA
));