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

Last change on this file since 2984 was 2984, checked in by sandervl, 25 years ago

moved registry apis into kernel32 + cleanup

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