]> git.ipfire.org Git - people/ms/u-boot.git/blame - board/MAI/bios_emulator/scitech/src/pm/cpuinfo.c
* Code cleanup:
[people/ms/u-boot.git] / board / MAI / bios_emulator / scitech / src / pm / cpuinfo.c
CommitLineData
c7de829c
WD
1/****************************************************************************
2*
3* SciTech OS Portability Manager Library
4*
5* ========================================================================
6*
7* The contents of this file are subject to the SciTech MGL Public
8* License Version 1.0 (the "License"); you may not use this file
9* except in compliance with the License. You may obtain a copy of
10* the License at http://www.scitechsoft.com/mgl-license.txt
11*
12* Software distributed under the License is distributed on an
13* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14* implied. See the License for the specific language governing
15* rights and limitations under the License.
16*
17* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
18*
19* The Initial Developer of the Original Code is SciTech Software, Inc.
20* All Rights Reserved.
21*
22* ========================================================================
23*
24* Language: ANSI C
25* Environment: Any
26*
27* Description: Main module to implement the Zen Timer support functions.
28*
29****************************************************************************/
30
31#include "ztimer.h"
32#include "pmapi.h"
33#include "oshdr.h"
34#if !defined(__WIN32_VXD__) && !defined(__OS2_VDD__) && !defined(__NT_DRIVER__)
35#include <stdio.h>
36#include <string.h>
37#endif
38
39/*----------------------------- Implementation ----------------------------*/
40
41/* External Intel assembler functions */
42#ifdef __INTEL__
43/* {secret} */
44ibool _ASMAPI _CPU_haveCPUID(void);
45/* {secret} */
46ibool _ASMAPI _CPU_check80386(void);
47/* {secret} */
48ibool _ASMAPI _CPU_check80486(void);
49/* {secret} */
50uint _ASMAPI _CPU_checkCPUID(void);
51/* {secret} */
52uint _ASMAPI _CPU_getCPUIDModel(void);
53/* {secret} */
54uint _ASMAPI _CPU_getCPUIDStepping(void);
55/* {secret} */
56uint _ASMAPI _CPU_getCPUIDFeatures(void);
57/* {secret} */
58uint _ASMAPI _CPU_getCacheSize(void);
59/* {secret} */
60uint _ASMAPI _CPU_have3DNow(void);
61/* {secret} */
62ibool _ASMAPI _CPU_checkClone(void);
63/* {secret} */
64void _ASMAPI _CPU_readTimeStamp(CPU_largeInteger *time);
65/* {secret} */
66void _ASMAPI _CPU_runBSFLoop(ulong iterations);
67/* {secret} */
68ulong _ASMAPI _CPU_mulDiv(ulong a,ulong b,ulong c);
69/* {secret} */
70void ZTimerQuickInit(void);
71#define CPU_HaveMMX 0x00800000
72#define CPU_HaveRDTSC 0x00000010
73#define CPU_HaveSSE 0x02000000
74#endif
75
76#if defined(__SMX32__)
77#include "smx/cpuinfo.c"
78#elif defined(__RTTARGET__)
79#include "rttarget/cpuinfo.c"
80#elif defined(__REALDOS__)
81#include "dos/cpuinfo.c"
82#elif defined(__NT_DRIVER__)
83#include "ntdrv/cpuinfo.c"
84#elif defined(__WIN32_VXD__)
85#include "vxd/cpuinfo.c"
86#elif defined(__WINDOWS32__)
87#include "win32/cpuinfo.c"
88#elif defined(__OS2_VDD__)
89#include "vdd/cpuinfo.c"
90#elif defined(__OS2__)
91#include "os2/cpuinfo.c"
92#elif defined(__LINUX__)
93#include "linux/cpuinfo.c"
94#elif defined(__QNX__)
95#include "qnx/cpuinfo.c"
96#elif defined(__BEOS__)
97#include "beos/cpuinfo.c"
98#else
99#error CPU library not ported to this platform yet!
100#endif
101
102/*------------------------ Public interface routines ----------------------*/
103
104/****************************************************************************
105REMARKS:
106Read an I/O port location.
107****************************************************************************/
108static uchar rdinx(
109 int port,
110 int index)
111{
112 PM_outpb(port,(uchar)index);
113 return PM_inpb(port+1);
114}
115
116/****************************************************************************
117REMARKS:
118Write an I/O port location.
119****************************************************************************/
120static void wrinx(
121 ushort port,
122 ushort index,
123 ushort value)
124{
125 PM_outpb(port,(uchar)index);
126 PM_outpb(port+1,(uchar)value);
127}
128
129/****************************************************************************
130REMARKS:
131Enables the Cyrix CPUID instruction to properly detect MediaGX and 6x86
132processors.
133****************************************************************************/
134static void _CPU_enableCyrixCPUID(void)
135{
136 uchar ccr3;
137
138 PM_init();
139 ccr3 = rdinx(0x22,0xC3);
140 wrinx(0x22,0xC3,(uchar)(ccr3 | 0x10));
141 wrinx(0x22,0xE8,(uchar)(rdinx(0x22,0xE8) | 0x80));
142 wrinx(0x22,0xC3,ccr3);
143}
144
145/****************************************************************************
146DESCRIPTION:
147Returns the type of processor in the system.
148
149HEADER:
150ztimer.h
151
152RETURNS:
153Numerical identifier for the installed processor
154
155REMARKS:
156Returns the type of processor in the system. Note that if the CPU is an
157unknown Pentium family processor that we don't have an enumeration for,
158the return value will be greater than or equal to the value of CPU_UnkPentium
159(depending on the value returned by the CPUID instruction).
160
161SEE ALSO:
162CPU_getProcessorSpeed, CPU_haveMMX, CPU_getProcessorName
163****************************************************************************/
164uint ZAPI CPU_getProcessorType(void)
165{
166#if defined(__INTEL__)
167 uint cpu,vendor,model,cacheSize;
168 static ibool firstTime = true;
169
170 if (_CPU_haveCPUID()) {
8bde7f77
WD
171 cpu = _CPU_checkCPUID();
172 vendor = cpu & ~CPU_mask;
173 if (vendor == CPU_Intel) {
174 /* Check for Intel processors */
175 switch (cpu & CPU_mask) {
176 case 4: cpu = CPU_i486; break;
177 case 5: cpu = CPU_Pentium; break;
178 case 6:
179 if ((model = _CPU_getCPUIDModel()) == 1)
180 cpu = CPU_PentiumPro;
181 else if (model <= 6) {
182 cacheSize = _CPU_getCacheSize();
183 if ((model == 5 && cacheSize == 0) ||
184 (model == 5 && cacheSize == 256) ||
185 (model == 6 && cacheSize == 128))
186 cpu = CPU_Celeron;
187 else
188 cpu = CPU_PentiumII;
189 }
190 else if (model >= 7) {
191 /* Model 7 == Pentium III */
192 /* Model 8 == Celeron/Pentium III Coppermine */
193 cacheSize = _CPU_getCacheSize();
194 if ((model == 8 && cacheSize == 128))
195 cpu = CPU_Celeron;
196 else
197 cpu = CPU_PentiumIII;
198 }
199 break;
200 default:
201 cpu = CPU_UnkIntel;
202 }
203 }
204 else if (vendor == CPU_Cyrix) {
205 /* Check for Cyrix processors */
206 switch (cpu & CPU_mask) {
207 case 4:
208 if ((model = _CPU_getCPUIDModel()) == 4)
209 cpu = CPU_CyrixMediaGX;
210 else
211 cpu = CPU_UnkCyrix;
212 break;
213 case 5:
214 if ((model = _CPU_getCPUIDModel()) == 2)
215 cpu = CPU_Cyrix6x86;
216 else if (model == 4)
217 cpu = CPU_CyrixMediaGXm;
218 else
219 cpu = CPU_UnkCyrix;
220 break;
221 case 6:
222 if ((model = _CPU_getCPUIDModel()) <= 1)
223 cpu = CPU_Cyrix6x86MX;
224 else
225 cpu = CPU_UnkCyrix;
226 break;
227 default:
228 cpu = CPU_UnkCyrix;
229 }
230 }
231 else if (vendor == CPU_AMD) {
232 /* Check for AMD processors */
233 switch (cpu & CPU_mask) {
234 case 4:
235 if ((model = _CPU_getCPUIDModel()) == 0)
236 cpu = CPU_AMDAm5x86;
237 else
238 cpu = CPU_AMDAm486;
239 break;
240 case 5:
241 if ((model = _CPU_getCPUIDModel()) <= 3)
242 cpu = CPU_AMDK5;
243 else if (model <= 7)
244 cpu = CPU_AMDK6;
245 else if (model == 8)
246 cpu = CPU_AMDK6_2;
247 else if (model == 9)
248 cpu = CPU_AMDK6_III;
249 else if (model == 13) {
250 if (_CPU_getCPUIDStepping() <= 3)
251 cpu = CPU_AMDK6_IIIplus;
252 else
253 cpu = CPU_AMDK6_2plus;
254 }
255 else
256 cpu = CPU_UnkAMD;
257 break;
258 case 6:
259 if ((model = _CPU_getCPUIDModel()) == 3)
260 cpu = CPU_AMDDuron;
261 else
262 cpu = CPU_AMDAthlon;
263 break;
264 default:
265 cpu = CPU_UnkAMD;
266 }
267 }
268 else if (vendor == CPU_IDT) {
269 /* Check for IDT WinChip processors */
270 switch (cpu & CPU_mask) {
271 case 5:
272 if ((model = _CPU_getCPUIDModel()) <= 4)
273 cpu = CPU_WinChipC6;
274 else if (model == 8)
275 cpu = CPU_WinChip2;
276 else
277 cpu = CPU_UnkIDT;
278 break;
279 default:
280 cpu = CPU_UnkIDT;
281 }
282 }
283 else {
284 /* Assume a Pentium compatible Intel clone */
285 cpu = CPU_Pentium;
286 }
287 return cpu | vendor | (_CPU_getCPUIDStepping() << CPU_steppingShift);
288 }
c7de829c 289 else {
8bde7f77
WD
290 if (_CPU_check80386())
291 cpu = CPU_i386;
292 else if (_CPU_check80486()) {
293 /* If we get here we may have a Cyrix processor so we can try
294 * enabling the CPUID instruction and trying again.
295 */
296 if (firstTime) {
297 firstTime = false;
298 _CPU_enableCyrixCPUID();
299 return CPU_getProcessorType();
300 }
301 cpu = CPU_i486;
302 }
303 else
304 cpu = CPU_Pentium;
305 if (!_CPU_checkClone())
306 return cpu | CPU_Intel;
307 return cpu;
308 }
c7de829c
WD
309#elif defined(__ALPHA__)
310 return CPU_Alpha;
311#elif defined(__MIPS__)
312 return CPU_Mips;
313#elif defined(__PPC__)
314 return CPU_PowerPC;
315#endif
316}
317
318/****************************************************************************
319DESCRIPTION:
320Returns true if the processor supports Intel MMX extensions.
321
322HEADER:
323ztimer.h
324
325RETURNS:
326True if MMX is available, false if not.
327
328REMARKS:
329This function determines if the processor supports the Intel MMX extended
330instruction set.
331
332SEE ALSO:
333CPU_getProcessorType, CPU_getProcessorSpeed, CPU_have3DNow, CPU_haveSSE,
334CPU_getProcessorName
335****************************************************************************/
336ibool ZAPI CPU_haveMMX(void)
337{
338#ifdef __INTEL__
339 if (_CPU_haveCPUID())
8bde7f77 340 return (_CPU_getCPUIDFeatures() & CPU_HaveMMX) != 0;
c7de829c
WD
341 return false;
342#else
343 return false;
344#endif
345}
346
347/****************************************************************************
348DESCRIPTION:
349Returns true if the processor supports AMD 3DNow! extensions.
350
351HEADER:
352ztimer.h
353
354RETURNS:
355True if 3DNow! is available, false if not.
356
357REMARKS:
358This function determines if the processor supports the AMD 3DNow! extended
359instruction set.
360
361SEE ALSO:
362CPU_getProcessorType, CPU_getProcessorSpeed, CPU_haveMMX, CPU_haveSSE,
363CPU_getProcessorName
364****************************************************************************/
365ibool ZAPI CPU_have3DNow(void)
366{
367#ifdef __INTEL__
368 if (_CPU_haveCPUID())
8bde7f77 369 return _CPU_have3DNow();
c7de829c
WD
370 return false;
371#else
372 return false;
373#endif
374}
375
376/****************************************************************************
377DESCRIPTION:
378Returns true if the processor supports Intel KNI extensions.
379
380HEADER:
381ztimer.h
382
383RETURNS:
384True if Intel KNI is available, false if not.
385
386REMARKS:
387This function determines if the processor supports the Intel KNI extended
388instruction set.
389
390SEE ALSO:
391CPU_getProcessorType, CPU_getProcessorSpeed, CPU_haveMMX, CPU_have3DNow,
392CPU_getProcessorName
393****************************************************************************/
394ibool ZAPI CPU_haveSSE(void)
395{
396#ifdef __INTEL__
397 if (_CPU_haveCPUID())
8bde7f77 398 return (_CPU_getCPUIDFeatures() & CPU_HaveSSE) != 0;
c7de829c
WD
399 return false;
400#else
401 return false;
402#endif
403}
404
405/****************************************************************************
406RETURNS:
407True if the RTSC instruction is available, false if not.
408
409REMARKS:
410This function determines if the processor supports the Intel RDTSC
411instruction, for high precision timing. If the processor is not an Intel or
412Intel clone CPU, this function will always return false.
413
414DESCRIPTION:
415Returns true if the processor supports RDTSC extensions.
416
417HEADER:
418ztimer.h
419
420RETURNS:
421True if RTSC is available, false if not.
422
423REMARKS:
424This function determines if the processor supports the RDTSC instruction
425for reading the processor time stamp counter.
426
427SEE ALSO:
428CPU_getProcessorType, CPU_getProcessorSpeed, CPU_haveMMX, CPU_have3DNow,
429CPU_getProcessorName
430****************************************************************************/
431ibool ZAPI CPU_haveRDTSC(void)
432{
433#ifdef __INTEL__
434 if (_CPU_haveCPUID())
8bde7f77 435 return (_CPU_getCPUIDFeatures() & CPU_HaveRDTSC) != 0;
c7de829c
WD
436 return false;
437#else
438 return false;
439#endif
440}
441
442#ifdef __INTEL__
443
444#define ITERATIONS 16000
445#define SAMPLINGS 2
446#define INNER_LOOPS 400
447
448/****************************************************************************
449REMARKS:
450If processor does not support time stamp reading, but is at least a 386 or
451above, utilize method of timing a loop of BSF instructions which take a
452known number of cycles to run on i386(tm), i486(tm), and Pentium(R)
453processors.
454****************************************************************************/
455static ulong GetBSFCpuSpeed(
456 ulong cycles)
457{
458 CPU_largeInteger t0,t1,count_freq;
459 ulong ticks; /* Microseconds elapsed during test */
460 ulong current; /* Variable to store time elapsed */
461 int i,j,iPriority;
462 ulong lowest = (ulong)-1;
463
464 iPriority = SetMaxThreadPriority();
465 GetCounterFrequency(&count_freq);
466 for (i = 0; i < SAMPLINGS; i++) {
8bde7f77
WD
467 GetCounter(&t0);
468 for (j = 0; j < INNER_LOOPS; j++)
469 _CPU_runBSFLoop(ITERATIONS);
470 GetCounter(&t1);
471 current = t1.low - t0.low;
472 if (current < lowest)
473 lowest = current;
474 }
c7de829c
WD
475 RestoreThreadPriority(iPriority);
476
477 /* Compute frequency */
478 ticks = _CPU_mulDiv(lowest,1000000,count_freq.low);
479 if ((ticks % count_freq.low) > (count_freq.low/2))
8bde7f77 480 ticks++; /* Round up if necessary */
c7de829c 481 if (ticks == 0)
8bde7f77 482 return 0;
c7de829c
WD
483 return ((cycles*INNER_LOOPS)/ticks);
484}
485
486#define TOLERANCE 1
487
488/****************************************************************************
489REMARKS:
490On processors supporting the Read Time Stamp opcode, compare elapsed
491time on the High-Resolution Counter with elapsed cycles on the Time
492Stamp Register.
493
494The inner loop runs up to 20 times oruntil the average of the previous
495three calculated frequencies is within 1 MHz of each of the individual
496calculated frequencies. This resampling increases the accuracy of the
497results since outside factors could affect this calculation.
498****************************************************************************/
499static ulong GetRDTSCCpuSpeed(
500 ibool accurate)
501{
502 CPU_largeInteger t0,t1,s0,s1,count_freq;
503 u64 stamp0, stamp1, ticks0, ticks1;
504 u64 total_cycles, cycles, hz, freq;
505 u64 total_ticks, ticks;
506 int tries,iPriority;
507 ulong maxCount;
508
509 PM_set64_32(total_cycles,0);
510 PM_set64_32(total_ticks,0);
511 maxCount = accurate ? 600000 : 30000;
512 iPriority = SetMaxThreadPriority();
513 GetCounterFrequency(&count_freq);
514 PM_set64(freq,count_freq.high,count_freq.low);
515 for (tries = 0; tries < 3; tries++) {
8bde7f77
WD
516 /* Loop until 100 ticks have passed since last read of hi-res
517 * counter. This accounts for overhead later.
518 */
519 GetCounter(&t0);
520 t1.low = t0.low;
521 t1.high = t0.high;
522 while ((t1.low - t0.low) < 100) {
523 GetCounter(&t1);
524 _CPU_readTimeStamp(&s0);
525 }
526
527 /* Loop until 30000 ticks have passed since last read of hi-res counter.
528 * This allows for elapsed time for sampling. For a hi-res frequency
529 * of 1MHz, this is about 0.03 of a second. The frequency reported
530 * by the OS dependent code should be tuned to provide a good
531 * sample period depending on the accuracy of the OS timers (ie:
532 * if the accuracy is lower, lower the frequency to spend more time
533 * in the inner loop to get better accuracy).
534 */
535 t0.low = t1.low;
536 t0.high = t1.high;
537 while ((t1.low - t0.low) < maxCount) {
538 GetCounter(&t1);
539 _CPU_readTimeStamp(&s1);
540 }
541
542 /* Find the difference during the timing loop */
543 PM_set64(stamp0,s0.high,s0.low);
544 PM_set64(stamp1,s1.high,s1.low);
545 PM_set64(ticks0,t0.high,t0.low);
546 PM_set64(ticks1,t1.high,t1.low);
547 PM_sub64(cycles,stamp1,stamp0);
548 PM_sub64(ticks,ticks1,ticks0);
549
550 /* Sum up the results */
551 PM_add64(total_ticks,total_ticks,ticks);
552 PM_add64(total_cycles,total_cycles,cycles);
553 }
c7de829c
WD
554 RestoreThreadPriority(iPriority);
555
556 /* Compute frequency in Hz */
557 PM_mul64(hz,total_cycles,freq);
558 PM_div64(hz,hz,total_ticks);
559 return PM_64to32(hz);
560}
561
562#endif /* __INTEL__ */
563
564/****************************************************************************
565DESCRIPTION:
566Returns the speed of the processor in MHz.
567
568HEADER:
569ztimer.h
570
571PARAMETERS:
572accurate - True of the speed should be measured accurately
573
574RETURNS:
575Processor speed in MHz.
576
577REMARKS:
578This function returns the speed of the CPU in MHz. Note that if the speed
579cannot be determined, this function will return 0.
580
581If the accurate parameter is set to true, this function will spend longer
582profiling the speed of the CPU, and will not round the CPU speed that is
583reported. This is important for highly accurate timing using the Pentium
584RDTSC instruction, but it does take a lot longer for the profiling to
585produce accurate results.
586
587SEE ALSO:
588CPU_getProcessorSpeedInHz, CPU_getProcessorType, CPU_haveMMX,
589CPU_getProcessorName
590****************************************************************************/
591ulong ZAPI CPU_getProcessorSpeed(
592 ibool accurate)
593{
594#if defined(__INTEL__)
595 /* Number of cycles needed to execute a single BSF instruction on i386+
596 * processors.
597 */
598 ulong cpuSpeed;
599 uint i;
600 static ulong intel_cycles[] = {
8bde7f77
WD
601 115,47,43,
602 };
c7de829c 603 static ulong cyrix_cycles[] = {
8bde7f77
WD
604 38,38,52,52,
605 };
c7de829c 606 static ulong amd_cycles[] = {
8bde7f77
WD
607 49,
608 };
c7de829c 609 static ulong known_speeds[] = {
8bde7f77
WD
610 1000,950,900,850,800,750,700,650,600,550,500,450,433,400,350,
611 333,300,266,233,200,166,150,133,120,100,90,75,66,60,50,33,20,0,
612 };
c7de829c
WD
613
614 if (CPU_haveRDTSC()) {
8bde7f77
WD
615 cpuSpeed = (GetRDTSCCpuSpeed(accurate) + 500000) / 1000000;
616 }
c7de829c 617 else {
8bde7f77
WD
618 int type = CPU_getProcessorType();
619 int processor = type & CPU_mask;
620 int vendor = type & CPU_familyMask;
621 if (vendor == CPU_Intel)
622 cpuSpeed = GetBSFCpuSpeed(ITERATIONS * intel_cycles[processor - CPU_i386]);
623 else if (vendor == CPU_Cyrix)
624 cpuSpeed = GetBSFCpuSpeed(ITERATIONS * cyrix_cycles[processor - CPU_Cyrix6x86]);
625 else if (vendor == CPU_AMD)
626 cpuSpeed = GetBSFCpuSpeed(ITERATIONS * amd_cycles[0]);
627 else
628 return 0;
629 }
c7de829c
WD
630
631 /* Now normalise the results given known processors speeds, if the
632 * speed we measure is within 2MHz of the expected values
633 */
634 if (!accurate) {
8bde7f77
WD
635 for (i = 0; known_speeds[i] != 0; i++) {
636 if (cpuSpeed >= (known_speeds[i]-3) && cpuSpeed <= (known_speeds[i]+3)) {
637 return known_speeds[i];
638 }
639 }
640 }
c7de829c
WD
641 return cpuSpeed;
642#else
643 return 0;
644#endif
645}
646
647/****************************************************************************
648DESCRIPTION:
649Returns the speed of the processor in Hz.
650
651HEADER:
652ztimer.h
653
654RETURNS:
655Accurate processor speed in Hz.
656
657REMARKS:
658This function returns the accurate speed of the CPU in Hz. Note that if the
659speed cannot be determined, this function will return 0.
660
661This function is similar to the CPU_getProcessorSpeed function, except that
662it attempts to accurately measure the CPU speed in Hz. This is used
663internally in the Zen Timer libraries to provide accurate real world timing
664information. This is important for highly accurate timing using the Pentium
665RDTSC instruction, but it does take a lot longer for the profiling to
666produce accurate results.
667
668SEE ALSO:
669CPU_getProcessorSpeed, CPU_getProcessorType, CPU_haveMMX,
670CPU_getProcessorName
671****************************************************************************/
672ulong ZAPI CPU_getProcessorSpeedInHZ(
673 ibool accurate)
674{
675#if defined(__INTEL__)
676 if (CPU_haveRDTSC()) {
8bde7f77
WD
677 return GetRDTSCCpuSpeed(accurate);
678 }
c7de829c
WD
679 return CPU_getProcessorSpeed(false) * 1000000;
680#else
681 return 0;
682#endif
683}
684
685/****************************************************************************
686DESCRIPTION:
687Returns a string defining the speed and name of the processor.
688
689HEADER:
690ztimer.h
691
692RETURNS:
693Processor name string.
694
695REMARKS:
696This function returns an English string describing the speed and name of the
697CPU.
698
699SEE ALSO:
700CPU_getProcessorType, CPU_haveMMX, CPU_getProcessorName
701****************************************************************************/
702char * ZAPI CPU_getProcessorName(void)
703{
704#if defined(__INTEL__)
705 static int cpu,speed = -1;
706 static char name[80];
707
708 if (speed == -1) {
8bde7f77
WD
709 cpu = CPU_getProcessorType();
710 speed = CPU_getProcessorSpeed(false);
711 }
c7de829c
WD
712 sprintf(name,"%d MHz ", speed);
713 switch (cpu & CPU_mask) {
8bde7f77
WD
714 case CPU_i386:
715 strcat(name,"Intel i386 processor");
716 break;
717 case CPU_i486:
718 strcat(name,"Intel i486 processor");
719 break;
720 case CPU_Pentium:
721 strcat(name,"Intel Pentium processor");
722 break;
723 case CPU_PentiumPro:
724 strcat(name,"Intel Pentium Pro processor");
725 break;
726 case CPU_PentiumII:
727 strcat(name,"Intel Pentium II processor");
728 break;
729 case CPU_Celeron:
730 strcat(name,"Intel Celeron processor");
731 break;
732 case CPU_PentiumIII:
733 strcat(name,"Intel Pentium III processor");
734 break;
735 case CPU_UnkIntel:
736 strcat(name,"Unknown Intel processor");
737 break;
738 case CPU_Cyrix6x86:
739 strcat(name,"Cyrix 6x86 processor");
740 break;
741 case CPU_Cyrix6x86MX:
742 strcat(name,"Cyrix 6x86MX processor");
743 break;
744 case CPU_CyrixMediaGX:
745 strcat(name,"Cyrix MediaGX processor");
746 break;
747 case CPU_CyrixMediaGXm:
748 strcat(name,"Cyrix MediaGXm processor");
749 break;
750 case CPU_UnkCyrix:
751 strcat(name,"Unknown Cyrix processor");
752 break;
753 case CPU_AMDAm486:
754 strcat(name,"AMD Am486 processor");
755 break;
756 case CPU_AMDAm5x86:
757 strcat(name,"AMD Am5x86 processor");
758 break;
759 case CPU_AMDK5:
760 strcat(name,"AMD K5 processor");
761 break;
762 case CPU_AMDK6:
763 strcat(name,"AMD K6 processor");
764 break;
765 case CPU_AMDK6_2:
766 strcat(name,"AMD K6-2 processor");
767 break;
768 case CPU_AMDK6_III:
769 strcat(name,"AMD K6-III processor");
770 break;
771 case CPU_AMDK6_2plus:
772 strcat(name,"AMD K6-2+ processor");
773 break;
774 case CPU_AMDK6_IIIplus:
775 strcat(name,"AMD K6-III+ processor");
776 break;
777 case CPU_UnkAMD:
778 strcat(name,"Unknown AMD processor");
779 break;
780 case CPU_AMDAthlon:
781 strcat(name,"AMD Athlon processor");
782 break;
783 case CPU_AMDDuron:
784 strcat(name,"AMD Duron processor");
785 break;
786 case CPU_WinChipC6:
787 strcat(name,"IDT WinChip C6 processor");
788 break;
789 case CPU_WinChip2:
790 strcat(name,"IDT WinChip 2 processor");
791 break;
792 case CPU_UnkIDT:
793 strcat(name,"Unknown IDT processor");
794 break;
795 default:
796 strcat(name,"Unknown processor");
797 }
c7de829c 798 if (CPU_haveMMX())
8bde7f77 799 strcat(name," with MMX(R)");
c7de829c 800 if (CPU_have3DNow())
8bde7f77 801 strcat(name,", 3DNow!(R)");
c7de829c 802 if (CPU_haveSSE())
8bde7f77 803 strcat(name,", SSE(R)");
c7de829c
WD
804 return name;
805#else
806 return "Unknown";
807#endif
808}