Release 980517
[wine/multimedia.git] / misc / cpu.c
blob390c4773f56f177ec432816e3f2c25405aca08c2
1 /*
2 * What processor?
4 * Copyright 1995,1997 Morten Welinder
5 * Copyright 1997 Marcus Meissner
6 */
8 #include <stdio.h>
9 #include <ctype.h>
10 #include <string.h>
11 #include "global.h"
12 #include "windows.h"
13 #include "winnt.h"
14 #include "winerror.h"
15 #include "winreg.h"
16 #include "debug.h"
18 /* Should this write to the registry? */
19 #define DO_REG FALSE
21 static BYTE PF[64] = {0,};
23 /***********************************************************************
24 * GetSystemInfo [KERNELL32.404]
26 VOID WINAPI GetSystemInfo(LPSYSTEM_INFO si)
28 static int cache = 0;
29 static SYSTEM_INFO cachedsi;
30 HKEY hkey;
31 char buf[20];
33 if (cache) {
34 memcpy(si,&cachedsi,sizeof(*si));
35 return;
37 memset(PF,0,sizeof(PF));
39 /* choose sensible defaults ...
40 * FIXME: perhaps overrideable with precompiler flags?
42 cachedsi.u.x.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
43 cachedsi.dwPageSize = VIRTUAL_GetPageSize();
45 /* FIXME: better values for the two entries below... */
46 cachedsi.lpMinimumApplicationAddress = (void *)0x40000000;
47 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
48 cachedsi.dwActiveProcessorMask = 1;
49 cachedsi.dwNumberOfProcessors = 1;
50 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
51 cachedsi.dwAllocationGranularity = 0x10000;
52 cachedsi.wProcessorLevel = 3; /* 386 */
53 cachedsi.wProcessorRevision = 0;
55 cache = 1; /* even if there is no more info, we now have a cacheentry */
56 memcpy(si,&cachedsi,sizeof(*si));
58 /* hmm, reasonable processor feature defaults? */
60 /* The registry calls were removed because they were being called
61 before the registries were loaded, and they were giving errors */
62 /* Create this registry key for all systems */
64 #if DO_REG
65 if (RegCreateKey16(HKEY_LOCAL_MACHINE,"HARDWARE\\DESCRIPTION\\System\\CentralProcessor",&hkey)!=ERROR_SUCCESS) {
66 WARN(reg,"Unable to register CPU information\n");
68 #endif
70 #ifdef linux
72 char line[200];
73 FILE *f = fopen ("/proc/cpuinfo", "r");
75 if (!f)
76 return;
77 /*xhkey = 0;*/
78 while (fgets(line,200,f)!=NULL) {
79 char *s,*value;
81 /* NOTE: the ':' is the only character we can rely on */
82 if (!(value = strchr(line,':')))
83 continue;
84 /* terminate the valuename */
85 *value++ = '\0';
86 /* skip any leading spaces */
87 while (*value==' ') value++;
88 if ((s=strchr(value,'\n')))
89 *s='\0';
91 /* 2.1 method */
92 if (!lstrncmpi32A(line, "cpu family",strlen("cpu family"))) {
93 if (isdigit (value[0])) {
94 switch (value[0] - '0') {
95 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
96 cachedsi.wProcessorLevel= 3;
97 break;
98 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
99 cachedsi.wProcessorLevel= 4;
100 break;
101 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
102 cachedsi.wProcessorLevel= 5;
103 break;
104 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
105 cachedsi.wProcessorLevel= 5;
106 break;
107 default:
108 break;
111 #if DO_REG
112 /* set the CPU type of the current processor */
113 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
114 if (hkey)
115 RegSetValueEx32A(hkey,"Identifier",0,REG_SZ,buf,strlen(buf));
116 #endif
117 continue;
119 /* old 2.0 method */
120 if (!lstrncmpi32A(line, "cpu",strlen("cpu"))) {
121 if ( isdigit (value[0]) && value[1] == '8' &&
122 value[2] == '6' && value[3] == 0
124 switch (value[0] - '0') {
125 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
126 cachedsi.wProcessorLevel= 3;
127 break;
128 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
129 cachedsi.wProcessorLevel= 4;
130 break;
131 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
132 cachedsi.wProcessorLevel= 5;
133 break;
134 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
135 cachedsi.wProcessorLevel= 5;
136 break;
137 default:
138 break;
141 #if DO_REG
142 /* set the CPU type of the current processor */
143 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
144 if (hkey)
145 RegSetValueEx32A(hkey,"Identifier",0,REG_SZ,buf,strlen(buf));
146 #endif
147 continue;
149 if (!lstrncmpi32A(line,"fdiv_bug",strlen("fdiv_bug"))) {
150 if (!lstrncmpi32A(value,"yes",3))
151 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
153 continue;
155 if (!lstrncmpi32A(line,"fpu",strlen("fpu"))) {
156 if (!lstrncmpi32A(value,"no",2))
157 PF[PF_FLOATING_POINT_EMULATED] = TRUE;
159 continue;
161 if (!lstrncmpi32A(line,"processor",strlen("processor"))) {
162 /* processor number counts up...*/
163 int x;
165 if (sscanf(value,"%d",&x))
166 if (x+1>cachedsi.dwNumberOfProcessors)
167 cachedsi.dwNumberOfProcessors=x+1;
169 #if 0
170 /* create a new processor subkey */
171 /* What exactly is trying to be done here? */
172 sprintf(buf,"%d",x);
173 if (xhkey)
174 RegCloseKey(xhkey);
175 RegCreateKey16(hkey,buf,&xhkey);
176 #endif
178 if (!lstrncmpi32A(line,"stepping",strlen("stepping"))) {
179 int x;
181 if (sscanf(value,"%d",&x))
182 cachedsi.wProcessorRevision = x;
184 if (!lstrncmpi32A(line,"flags",strlen("flags"))) {
185 if (strstr(value,"cx8"))
186 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
187 if (strstr(value,"mmx"))
188 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
192 fclose (f);
194 memcpy(si,&cachedsi,sizeof(*si));
195 #else /* linux */
196 /* FIXME: how do we do this on other systems? */
198 #if 0
199 RegSetValueEx32A(xhkey,"Identifier",0,REG_SZ,"CPU 386",strlen("CPU 386"));
200 #endif
202 #endif /* !linux */
204 #if 0
205 (xhkey)
206 RegCloseKey(xhkey);
207 #endif
208 #if DO_REG
209 if (hkey)
210 RegCloseKey(hkey);
211 #endif
216 /***********************************************************************
217 * IsProcessorFeaturePresent [KERNELL32.880]
219 BOOL32 WINAPI IsProcessorFeaturePresent (DWORD feature)
221 SYSTEM_INFO si;
222 GetSystemInfo (&si); /* to ensure the information is loaded and cached */
224 if (feature < 64)
225 return PF[feature];
226 else
227 return FALSE;