source: trunk/src/kernel32/cpu.cpp@ 2007

Last change on this file since 2007 was 1838, checked in by sandervl, 26 years ago

EB's unicode changes + removal of advapi32 dependency

File size: 6.3 KB
Line 
1/* $Id: cpu.cpp,v 1.3 1999-11-25 19:19:57 sandervl Exp $ */
2/*
3 * Odin win32 CPU apis
4 *
5 * Copyright 1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 *
7 * Based on Wine Code (991031: misc\cpu.c)
8 *
9 * Copyright 1995,1997 Morten Welinder
10 * Copyright 1997-1998 Marcus Meissner
11 */
12
13#include <os2win.h>
14#include <ctype.h>
15#include <string.h>
16#include "winreg.h"
17#include "global.h"
18#include "winnt.h"
19#include "winerror.h"
20#include "winreg.h"
21#include "debugtools.h"
22#include "cpuhlp.h"
23
24DEFAULT_DEBUG_CHANNEL(CPU)
25
26static BYTE PF[64] = {0,};
27static nrCPUs = 1;
28static HINSTANCE hInstance = 0;
29
30LONG (WINAPI *ADVAPI32_RegCloseKey)(HKEY) = 0;
31LONG (WINAPI *ADVAPI32_RegCreateKeyA)(HKEY,LPCSTR,LPHKEY) = 0;
32LONG (WINAPI *ADVAPI32_RegSetValueExA)(HKEY,LPSTR,DWORD,DWORD,LPBYTE,DWORD) = 0;
33
34//******************************************************************************
35//******************************************************************************
36void InitSystemInfo(int nrcpus)
37{
38 SYSTEM_INFO si;
39
40 hInstance = LoadLibraryA("ADVAPI32.DLL");
41 if(hInstance) {
42 *(VOID **)&ADVAPI32_RegCloseKey=(void*)GetProcAddress(hInstance, (LPCSTR)"RegCloseKey");
43 *(VOID **)&ADVAPI32_RegCreateKeyA=(void*)GetProcAddress(hInstance, (LPCSTR)"RegCreateKeyA");
44 *(VOID **)&ADVAPI32_RegSetValueExA=(void*)GetProcAddress(hInstance, (LPCSTR)"RegSetValueExA");
45 }
46
47 nrCPUs = nrcpus;
48 GetSystemInfo(&si);
49}
50/***********************************************************************
51 * GetSystemInfo [KERNELL32.404]
52 *
53 * Gets the current system information.
54 *
55 * On the first call it reads cached values, so it doesn't have to determine
56 * them repeatedly. On Linux, the /proc/cpuinfo special file is used.
57 *
58 * It creates a registry subhierarchy, looking like:
59 * \HARDWARE\DESCRIPTION\System\CentralProcessor\<processornumber>\
60 * Identifier (CPU x86)
61 * Note that there is a hierarchy for every processor installed, so this
62 * supports multiprocessor systems. This is done like Win95 does it, I think.
63 *
64 * It also creates a cached flag array for IsProcessorFeaturePresent().
65 *
66 * RETURNS
67 * nothing, really
68 */
69VOID WINAPI GetSystemInfo(LPSYSTEM_INFO si) /* [out] system information */
70{
71 static int cache = 0;
72 static SYSTEM_INFO cachedsi;
73 HKEY xhkey=0,hkey;
74 HKEY fpukey=0, xhfpukey;
75 char buf[20];
76 DWORD features, signature;
77
78 if(!si) {
79 dprintf(("GetSystemInfo -> si == NULL!!"));
80 SetLastError(ERROR_INVALID_PARAMETER);
81 return;
82 }
83 dprintf(("GetSystemInfo"));
84 if (cache) {
85 memcpy(si,&cachedsi,sizeof(*si));
86 return;
87 }
88 memset(PF,0,sizeof(PF));
89
90 /* choose sensible defaults ...
91 * FIXME: perhaps overrideable with precompiler flags?
92 */
93 cachedsi.u.x.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
94 cachedsi.dwPageSize = 4096;
95
96 /* FIXME: better values for the two entries below... */
97 cachedsi.lpMinimumApplicationAddress = (void *)0x40000000;
98 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
99 cachedsi.dwActiveProcessorMask = 1;
100 cachedsi.dwNumberOfProcessors = nrCPUs;
101 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
102 cachedsi.dwAllocationGranularity = 0x10000;
103 cachedsi.wProcessorLevel = 3; /* 386 */
104 cachedsi.wProcessorRevision = 0;
105
106 cache = 1; /* even if there is no more info, we now have a cacheentry */
107 memcpy(si,&cachedsi,sizeof(*si));
108
109 /* Hmm, reasonable processor feature defaults? */
110
111 /* Create this registry key for all systems */
112 if (ADVAPI32_RegCreateKeyA(HKEY_LOCAL_MACHINE,"HARDWARE\\DESCRIPTION\\System\\CentralProcessor",&hkey)!=ERROR_SUCCESS) {
113 dprintf(("Unable to register CPU information\n"));
114 }
115
116 if(SupportsCPUID())
117 {
118 for(int i=0;i<cachedsi.dwNumberOfProcessors;i++)
119 {
120 // Create a new processor subkey
121 sprintf(buf,"%d",i);
122 if (xhkey)
123 ADVAPI32_RegCloseKey(xhkey);
124 ADVAPI32_RegCreateKeyA(hkey,buf,&xhkey);
125
126 signature = GetCPUSignature();
127
128 switch ((signature >> 8)&0xf) {
129 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
130 cachedsi.wProcessorLevel= 3;
131 break;
132 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
133 cachedsi.wProcessorLevel= 4;
134 break;
135 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
136 cachedsi.wProcessorLevel= 5;
137 break;
138 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
139 cachedsi.wProcessorLevel= 5;
140 break;
141 default:
142 break;
143 }
144 /* set the CPU type of the current processor */
145 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
146 if (xhkey) {
147 ADVAPI32_RegSetValueExA(xhkey,"Identifier",0,REG_SZ,(LPBYTE)buf,strlen(buf));
148 memset(buf, 0, sizeof(buf));
149 GetCPUVendorString(buf);
150 ADVAPI32_RegSetValueExA(xhkey,"VendorIdentifier",0,REG_SZ,(LPBYTE)buf,strlen(buf));
151 }
152 cachedsi.wProcessorRevision = signature & 0xf;
153
154//TODO: FPU fdiv bug
155#if 0
156 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
157 if (!lstrncmpiA(value,"yes",3))
158 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
159
160 continue;
161 }
162#endif
163 features = GetCPUFeatures();
164 if (features & CPUID_CMPXCHG8B_INSTRUCTION)
165 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
166 if (features & CPUID_MMX)
167 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
168
169 //Create FPU key if one is present
170 if (features & CPUID_FPU_PRESENT) {
171 if (i == 0) {
172 if(ADVAPI32_RegCreateKeyA(HKEY_LOCAL_MACHINE,"HARDWARE\\DESCRIPTION\\System\\FloatingPointProcessor",&fpukey)!=ERROR_SUCCESS)
173 dprintf(("Unable to register FPU information\n"));
174 }
175 // Create a new processor subkey
176 if(fpukey) {
177 sprintf(buf,"%d",i);
178 ADVAPI32_RegCreateKeyA(fpukey,buf,&xhfpukey);
179 }
180 }
181
182 } //for each cpu
183 }
184 memcpy(si,&cachedsi,sizeof(*si));
185
186 if (xhkey)
187 ADVAPI32_RegCloseKey(xhkey);
188 if (hkey)
189 ADVAPI32_RegCloseKey(hkey);
190 if (xhfpukey)
191 ADVAPI32_RegCloseKey(xhfpukey);
192 if (fpukey)
193 ADVAPI32_RegCloseKey(fpukey);
194
195}
196
197
198/***********************************************************************
199 * IsProcessorFeaturePresent [KERNELL32.880]
200 * RETURNS:
201 * TRUE if processorfeature present
202 * FALSE otherwise
203 */
204BOOL WINAPI IsProcessorFeaturePresent (DWORD feature) /* [in] feature number, see PF_ defines */
205{
206 SYSTEM_INFO si;
207 GetSystemInfo (&si); /* To ensure the information is loaded and cached */
208
209 if (feature < 64)
210 return PF[feature];
211 else
212 return FALSE;
213}
214//******************************************************************************
215//******************************************************************************
Note: See TracBrowser for help on using the repository browser.