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

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

Added new logging feature

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