gcc8 update. (NicJA)
[AROS.git] / workbench / c / CPUInfo / x86_Cyrix.c
blob1a1497d313921f6dc498c77e5eb194ec42daff47
1 /*
2 Copyright © 2000, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Probe installed Cyrix 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 Cyrix 5x86/M1/MediaGX/M2
17 *****************************************************************************************************/
19 #include "x86.h"
21 /********************************************
22 Cyrix CPU Features
23 ********************************************/
25 char *Cyrix_standard_feature_flags_5[] = {
26 "FPU : Floating Point Unit",
27 "V86 : Virtual Mode Extensions",
28 " : Debug Extension",
29 " : 4MB Page Size",
30 " : Time Stamp Counter",
31 " : i386_rdmsr/WRMSR (Model Specific Registers)",
32 "PAE : ",
33 " : Machine Check Exception",
34 " : COMPXCHG8B Instruction",
35 "APIC : APIC - On-chip Advanced Programmable Interrupt Controller present and enabled",
36 "10 : Reserved",
37 "11 : Reserved",
38 "MTRR : Memory Type Range Registers",
39 "13 : Reserved",
40 " : RMachine Check",
41 "CMOV : Conditional Move Instruction",
42 "16 : Reserved",
43 "17 : Reserved",
44 "18 : Reserved",
45 "19 : Reserved",
46 "20 : Reserved",
47 "21 : Reserved",
48 "22 : Reserved",
49 " : MMX instructions",
50 "24 : Reserved",
51 "25 : Reserved",
52 "26 : Reserved",
53 "27 : Reserved",
54 "28 : Reserved",
55 "29 : Reserved",
56 "30 : Reserved",
59 char *Cyrix_standard_feature_flags_not5[] = {
60 "FPU : Floating Point Unit",
61 "V86 : Virtual Mode Extensions",
62 " : Debug Extension",
63 " : 4MB Page Size",
64 " : Time Stamp Counter",
65 " : i386_rdmsr/WRMSR (Model Specific Registers)",
66 "PAE : ",
67 " : Machine Check Exception",
68 " : COMPXCHG8B Instruction",
69 " : APIC - On-chip Advanced Programmable Interrupt Controller present and enabled",
70 "10 : Reserved",
71 "11 : Reserved",
72 "MTRR : Memory Type Range Registers",
73 " : Global Paging Extension",
74 " : Machine Check",
75 "CMOV : Conditional Move Instruction",
76 "16 : Reserved",
77 "17 : Reserved",
78 "18 : Reserved",
79 "19 : Reserved",
80 "20 : Reserved",
81 "21 : Reserved",
82 "22 : Reserved",
83 " : MMX instructions",
84 "24 : Reserved",
85 "25 : Reserved",
86 "26 : Reserved",
87 "27 : Reserved",
88 "28 : Reserved",
89 "29 : Reserved",
90 "30 : Reserved",
93 char *Cyrix_extended_feature_flags[] = {
94 "FPU : Floating Point Unit",
95 "V86 : Virtual Mode Extensions",
96 " : Debug Extension",
97 " : Page Size Extensions",
98 " : Time Stamp Counter",
99 " : Cyrix MSR",
100 "PAE : ",
101 " : MC Exception",
102 " : COMPXCHG8B",
103 " : APIC on chip",
104 " : SYSCALL/SYSRET",
105 "11 : Reserved",
106 "MTRR : ",
107 " : Global bit",
108 " : Machine Check",
109 "CMOV : ",
110 " : FPU CMOV",
111 "17 : Reserved",
112 "18 : Reserved",
113 "19 : Reserved",
114 "20 : Reserved",
115 "21 : Reserved",
116 "22 : Reserved",
117 " : MMX",
118 " : Extended MMX",
119 "25 : Reserved",
120 "26 : Reserved",
121 "27 : Reserved",
122 "28 : Reserved",
123 "29 : Reserved",
124 "30 : Reserved",
125 " : 3DNow instructions",
128 /********************************************
129 Cyrix specific information
130 ********************************************/
132 char *i386_cyrix_TLB_decode ( int tlb, char *BUFF_STR )
134 switch(tlb & 0xff)
136 case 0:
137 break;
138 case 0x70:
139 sprintf( BUFF_STR, " TLB: 32 entries 4-way associative 4KB pages\n" );
140 break;
141 case 0x80:
142 sprintf( BUFF_STR, " L1 Cache: 16KB 4-way associative 16 bytes/line\n" );
143 break;
146 return BUFF_STR;
149 /********************************************/
151 void parse_i386_Cyrix ( int maxi, struct i386_compat_intern * CPUi386 )
153 struct CPU_INTERN_DATA *global;
154 ULONG __unused__ speed, maxei,unused;
155 int __unused__ family = 0;
156 char *BUFF_STR, *Cyrix_CPU_NAME, *Cyrix_CPU_IDENTITY, *Cyrix_CPU_FEATURES, *Cyrix_CPU_CACHE, *Cyrix_CPU_ADDR;
157 int Cyrix_CPU_NAME_cnt, Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_FEATURES_cnt, Cyrix_CPU_CACHE_cnt, Cyrix_CPU_ADDR_cnt;
159 if ((global = AllocMem(sizeof(struct CPU_INTERN_DATA),MEMF_PUBLIC|MEMF_CLEAR)))
161 Cyrix_CPU_NAME = global->CPU_NAME;
162 Cyrix_CPU_IDENTITY = global->CPU_IDENTITY;
163 Cyrix_CPU_FEATURES = global->CPU_FEATURES;
164 Cyrix_CPU_CACHE = global->CPU_CACHE;
165 Cyrix_CPU_ADDR = global->CPU_ADDR;
166 BUFF_STR = global->CPU_BUFF;
168 Cyrix_CPU_NAME_cnt = Cyrix_CPU_IDENTITY_cnt = Cyrix_CPU_FEATURES_cnt = Cyrix_CPU_CACHE_cnt = Cyrix_CPU_ADDR_cnt = 0;
170 Cyrix_CPU_FEATURES_cnt = AddBufferLine( Cyrix_CPU_FEATURES_cnt, Cyrix_CPU_FEATURES, " Cyrix-specific functions\n" );
172 i386_cpuid(0x80000000,maxei,unused,unused,unused);
174 /* Do standard stuff */
175 if(maxi >= 1)
177 unsigned long eax,unused,edx;
178 int __unused__ stepping,model,family,reserved;
180 i386_cpuid(1,eax,unused,unused,edx);
182 stepping = eax & 0xf;
183 model = (eax >> 4) & 0xf;
184 family = (eax >> 8) & 0xf;
185 reserved = eax >> 12;
187 sprintf( BUFF_STR," Family: %d Model: %d [",family,model);
188 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, BUFF_STR);
189 switch ( family )
191 case 4:
192 switch ( model )
194 case 9:
195 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, "5x86");
196 break;
198 break;
199 case 5:
200 switch ( model )
202 case 2:
203 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, "6x86");
204 break;
205 case 4:
206 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, "GX, GXm");
207 break;
209 break;
210 case 6:
211 switch ( model )
213 case 0:
214 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, "6x86MX");
215 break;
217 break;
219 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, "]\n\n");
221 if ( family == 5 && model == 0 )
223 int i;
225 for ( i=0 ; i<32 ; i++ )
227 if ( edx & (1<<i) )
229 sprintf( BUFF_STR," %s\n",Cyrix_standard_feature_flags_5[i]);
230 Cyrix_CPU_FEATURES_cnt = AddBufferLine(Cyrix_CPU_FEATURES_cnt, Cyrix_CPU_FEATURES, BUFF_STR);
234 else
236 int i;
238 for ( i=0 ; i<32 ; i++ )
240 if ( edx & (1<<i) )
242 sprintf( BUFF_STR," %s\n",Cyrix_standard_feature_flags_not5[i]);
243 Cyrix_CPU_FEATURES_cnt = AddBufferLine(Cyrix_CPU_FEATURES_cnt, Cyrix_CPU_FEATURES, BUFF_STR);
249 if ( maxi >= 2 ) /* TLB and L1 Cache info */
251 int ntlb = 255;
252 int i;
254 for( i=0 ; i<ntlb ; i++ )
256 unsigned long eax,edx,unused;
258 i386_cpuid( 2, eax, unused, unused, edx);
259 ntlb = eax & 0xff;
261 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( eax >> 8, BUFF_STR ));
262 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( eax >> 16, BUFF_STR ));
263 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( eax >> 24, BUFF_STR ));
265 /* ebx and ecx are reserved */
267 if (( edx & 0x80000000 ) == 0 )
269 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( edx, BUFF_STR ));
270 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( edx >> 8, BUFF_STR ));
271 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( edx >> 16, BUFF_STR ));
272 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( edx >> 24, BUFF_STR ));
278 if ( maxei < 0x80000000 ) return; /* Check for presence of extended info */
281 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, "\n Extended info:\n");
283 if ( maxei >= 0x80000001 )
285 unsigned long eax, ebx, ecx, edx;
286 int __unused__ stepping, model, family, reserved, i;
288 i386_cpuid( 0x80000001, eax, ebx, ecx, edx );
290 stepping = eax & 0xf;
291 model = (eax >> 4) & 0xf;
292 family = (eax >> 8) & 0xf;
293 reserved = eax >> 12;
295 sprintf( BUFF_STR," Family: %d Model: %d [",family,model);
296 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, BUFF_STR);
297 switch ( family )
299 case 4:
300 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, "MediaGX");
301 break;
302 case 5:
303 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, "6x86/GXm");
304 break;
305 case 6:
306 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, "6x86/MX");
308 Cyrix_CPU_IDENTITY_cnt = AddBufferLine(Cyrix_CPU_IDENTITY_cnt, Cyrix_CPU_IDENTITY, "]\n\n");
310 Cyrix_CPU_FEATURES_cnt = AddBufferLine(Cyrix_CPU_FEATURES_cnt, Cyrix_CPU_FEATURES, "Extended feature flags:\n");
311 for( i=0 ; i<32 ; i++ )
313 if ( edx & (1<<i) )
315 sprintf( BUFF_STR," %s\n",Cyrix_extended_feature_flags[i]);
316 Cyrix_CPU_FEATURES_cnt = AddBufferLine(Cyrix_CPU_FEATURES_cnt, Cyrix_CPU_FEATURES, BUFF_STR);
320 Cyrix_CPU_FEATURES_cnt = AddBufferLine(Cyrix_CPU_FEATURES_cnt, Cyrix_CPU_FEATURES, "\n");
322 if ( maxei >= 0x80000002 ) /* Processor identification string */
324 char __unused__ namestring[49],*cp;
325 int j;
326 cp = namestring;
328 Cyrix_CPU_NAME_cnt = AddBufferLine(Cyrix_CPU_NAME_cnt, Cyrix_CPU_NAME, " Processor name string: ");
329 for ( j=0x80000002 ; j<=0x80000004 ; j++ )
331 unsigned long eax, ebx, ecx, edx;
333 i386_cpuid( j, eax, ebx, ecx, edx );
334 Cyrix_CPU_NAME_cnt = i386_sprintregs(Cyrix_CPU_NAME_cnt, Cyrix_CPU_NAME, eax,ebx,ecx,edx);
338 if ( maxei >= 0x80000005 ) /* TLB and L1 Cache info */
340 int ntlb = 255;
341 int i;
343 for ( i=0 ; i<ntlb ; i++ )
345 unsigned long eax, ebx, ecx, unused;
347 i386_cpuid( 0x80000005, eax, ebx, ecx, unused);
348 ntlb = eax & 0xff;
350 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( ebx >> 8, BUFF_STR ));
351 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( ebx >> 16, BUFF_STR ));
352 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( ebx >> 24, BUFF_STR ));
354 /* eax and edx are reserved */
356 if (( ecx & 0x80000000 ) == 0 )
358 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( ecx, BUFF_STR ));
359 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( ecx >> 8, BUFF_STR ));
360 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( ecx >> 16, BUFF_STR ));
361 Cyrix_CPU_CACHE_cnt = AddBufferLine(Cyrix_CPU_CACHE_cnt, Cyrix_CPU_CACHE, i386_cyrix_TLB_decode( ecx >> 24, BUFF_STR ));
367 //for(i=0x80000000;i<=maxei;i++) /* Dump extended info, if any, in raw hex */
369 // unsigned long eax,ebx,ecx,edx;
371 // i386_cpuid(i,eax,ebx,ecx,edx);
372 // printf("eax in: 0x%x, eax = %08lx ebx = %08lx ecx = %08lx edx = %08lx\n",i,eax,ebx,ecx,edx);
375 if ( Cyrix_CPU_NAME_cnt > 0 ) printf( Cyrix_CPU_NAME ); /* CPUs Retail Name */
377 speed = i386_approx_mhz();
379 /* TODO : Calculate FSB .. */
381 if ( Cyrix_CPU_IDENTITY_cnt > 0 ) printf( Cyrix_CPU_IDENTITY ); /* CPUs Internal Name */
382 if ( Cyrix_CPU_FEATURES_cnt > 0 ) printf( Cyrix_CPU_FEATURES ); /* CPUs Feature Set */
383 if ( Cyrix_CPU_ADDR_cnt > 0 ) printf( Cyrix_CPU_ADDR ); /* CPUs Address Range */
384 if ( Cyrix_CPU_CACHE_cnt > 0 ) printf( Cyrix_CPU_CACHE ); /* CPUs Cache Details */
387 else
389 printf( "ERROR: Couldn't allocate memory to parse CPU information .." );
390 return;
392 FreeMem(global,sizeof(struct CPU_INTERN_DATA));