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

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

GetSystemInfo supports SMP machines now

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