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

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

Added GetSystemInfo + IsProcessorFeaturePresent

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