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

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

create reg keys for CSD version

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