00001
00053 #include "x86.h"
00054 #include "memory.h"
00055
00056
00057 #if 1!=DKUTIL_CSTD_MSVC_IASM
00058
00059 #else
00060
00061 BOOL WINAPI dkcstd_getX86CPUInfo(DKCSTD_CPU_INFO *dest,int CPUClockCalcTime)
00062 {
00063
00064 char CPUName[256] = "";
00065 char CPUType[128] = "";
00066 long bFPU = FALSE;
00067 long bTSC = FALSE;
00068 long bCMOV = FALSE;
00069 long bFCMOV = FALSE;
00070 long bCPUID = FALSE;
00071 long bMMX = FALSE;
00072 long bMMX2 = FALSE;
00073 long bSSE = FALSE;
00074 long bSSE2 = FALSE;
00075 long b3DNOW = FALSE;
00076 long bE3DNOW = FALSE;
00077 long TypeID = 0;
00078 long FamilyID = 0;
00079 long ModelID = 0;
00080 long SteppingID = 0;
00081 long CPUClock = 0;
00082
00083 __asm
00084 {
00085
00086
00087
00088 PUSHFD
00089 POP EAX
00090 MOV EBX, EAX
00091 XOR EAX, 1<<21
00092 PUSH EAX
00093 POPFD
00094 PUSHFD
00095 POP EAX
00096 CMP EAX, EBX
00097 JE EXIT
00098 MOV bCPUID, 1
00099
00100
00101
00102
00103 MOV EAX, 0
00104 CPUID
00105
00106 CMP EAX, 0
00107 JE EXIT
00108
00109 MOV DWORD PTR [CPUType+0], EBX
00110 MOV DWORD PTR [CPUType+8], ECX
00111 MOV DWORD PTR [CPUType+4], EDX
00112
00113
00114
00115
00116 MOV EAX, 1
00117 CPUID
00118
00119
00120
00121
00122
00123 MOV ESI, EAX
00124 AND ESI, 0x0F;
00125 MOV [SteppingID],ESI
00126
00127
00128 SHR EAX, 4
00129 MOV ESI, EAX
00130 AND ESI, 0x0F
00131 MOV [ModelID], ESI
00132
00133
00134 SHR EAX, 4
00135 MOV ESI, EAX
00136 AND ESI, 0x0F
00137 MOV [FamilyID], ESI
00138
00139
00140 SHR EAX, 4
00141 MOV ESI, EAX
00142 AND ESI, 0x03
00143 MOV [TypeID], ESI
00144
00145
00146
00147
00148
00149 XOR EAX, EAX
00150 TEST EDX, 1<<0
00151 SETNZ AL
00152 MOV [bFPU], EAX
00153
00154
00155 TEST EDX, 1<<4
00156 SETNZ AL
00157 MOV [bTSC], EAX
00158
00159
00160 XOR EAX, EAX
00161 TEST EDX, 1<<15
00162 SETNZ AL
00163 MOV [bCMOV], EAX
00164
00165
00166 XOR EAX, EAX
00167 TEST EDX, 1<<23
00168 SETNZ AL
00169 MOV [bMMX], EAX
00170
00171
00172 XOR EAX, EAX
00173 TEST EDX, 1<<25
00174 SETNZ AL
00175 MOV [bMMX2], EAX
00176 MOV [bSSE], EAX
00177
00179
00181
00182
00183
00184
00185 MOV EAX, 0x80000000
00186 CPUID
00187
00188 CMP EAX, 0x80000001
00189 JB EXIT
00190
00191
00192
00193
00194 MOV EAX, 0x80000001
00195 CPUID
00196
00197
00198 XOR EAX, EAX
00199 TEST EDX, 1<<22
00200 SETNZ AL
00201 MOV [bMMX2], EAX
00202
00203
00204 XOR EAX, EAX
00205 TEST EDX, 1<<30
00206 SETNZ AL
00207 MOV [bE3DNOW], EAX
00208
00209
00210 XOR EAX, EAX
00211 TEST EDX, 1<<31
00212 SETNZ AL
00213 MOV [b3DNOW], EAX
00214
00215
00216
00217
00218
00219 MOV EAX, 0x80000000
00220 CPUID
00221 CMP EAX, 0x80000004
00222 JB EXIT
00223
00224
00225 MOV EAX, 0x80000002
00226 CPUID
00227
00228 MOV DWORD PTR [CPUName+ 0], EAX
00229 MOV DWORD PTR [CPUName+ 4], EBX
00230 MOV DWORD PTR [CPUName+ 8], ECX
00231 MOV DWORD PTR [CPUName+12], EDX
00232
00233
00234 MOV EAX, 0x80000003
00235 CPUID
00236
00237 MOV DWORD PTR [CPUName+16], EAX
00238 MOV DWORD PTR [CPUName+20], EBX
00239 MOV DWORD PTR [CPUName+24], ECX
00240 MOV DWORD PTR [CPUName+28], EDX
00241
00242
00243 MOV EAX, 0x80000004
00244 CPUID
00245
00246 MOV DWORD PTR [CPUName+32], EAX
00247 MOV DWORD PTR [CPUName+36], EBX
00248 MOV DWORD PTR [CPUName+40], ECX
00249 MOV DWORD PTR [CPUName+44], EDX
00250
00251
00252 EXIT:
00253 }
00254
00255
00256
00257
00258
00259
00260 if ( bTSC && 0 != CPUClockCalcTime)
00261 {
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 __asm
00282 {
00283 RDTSC
00284 MOV [CPUClock], EAX
00285 }
00286
00287 Sleep( CPUClockCalcTime );
00288
00289 __asm
00290 {
00291 RDTSC
00292 SUB EAX, [CPUClock]
00293 MOV [CPUClock], EAX
00294 }
00295
00296 CPUClock /= (CPUClockCalcTime * 1000);
00297 }
00298
00299
00300
00301
00302
00303
00304 {
00305 size_t cns = sizeof(dest->CPUName);
00306 size_t cts = sizeof(dest->CPUType);
00307
00308 dkcstd_memcpy(dest->CPUName,CPUName,cns);
00309 dest->CPUName[cns - 1] = '\0';
00310
00311 dkcstd_memcpy(dest->CPUType,CPUType,cts);
00312 dest->CPUType[cts - 1] = '\0';
00313
00314 dest->bFPU = (unsigned char)bFPU;
00315 dest->bTSC = (unsigned char)bTSC;
00316 dest->bCMOV = (unsigned char)bCMOV;
00317 dest->bCPUID = (unsigned char)bCPUID;
00318 dest->bMMX = (unsigned char)bMMX;
00319 dest->bMMX2 = (unsigned char)bMMX2;
00320 dest->bSSE = (unsigned char)bSSE;
00321 dest->bSSE2 = (unsigned char)bSSE2;
00322 dest->b3DNOW = (unsigned char)b3DNOW;
00323 dest->bE3DNOW = (unsigned char)bE3DNOW;
00324 dest->TypeID = TypeID;
00325 dest->FamilyID= FamilyID;
00326 dest->ModelID = ModelID;
00327 dest->SteppingID = SteppingID;
00328 dest->CPUClock = CPUClock;
00329 }
00330 return TRUE;
00331 }
00332
00333 int WINAPI dkcstd_IsCPUID(){
00334 int flag = 0;
00335
00336 __asm{
00337 pushfd
00338 pop eax
00339 mov ebx,eax
00340 xor eax,00200000h
00341 push eax
00342 popfd
00343 pushfd
00344 pop eax
00345 cmp eax,ebx
00346 je end
00347 mov flag,1
00348 end:
00349 }
00350 return flag;
00351 }
00352
00353 int WINAPI dkcstd_getCPUID(){
00354 int flags=0;
00355 __asm {
00356 xor eax,eax;
00357 cpuid;
00358 or eax,eax;
00359 jz quit;
00360 mov eax,1;
00361 cpuid;
00362 mov flags,edx;
00363 quit:
00364 }
00365 return flags;
00366 }
00367
00368 uint32 WINAPI dkcstd_getX86CPUType() {
00369 int flags;
00370 uint32 type;
00371
00372 if(FALSE==dkcstd_IsCPUID()){
00373 return 0;
00374 }
00375 flags=dkcstd_getCPUID();
00376
00377
00378
00379 if (flags&(1<<31))
00380 {
00381 type|=edkcCPU_3DNOW;
00382 if (flags&(1<<30))
00383 {
00384 type|=edkcCPU_E3DNOW;
00385 }
00386 }
00387
00388 if (flags&(1<<23))
00389 {
00390 type|=edkcCPU_MMX;
00391 if (flags&(1<<25))
00392 {
00393 type|=edkcCPU_SSE;
00394
00395 type|=edkcCPU_MMX2;
00396 if (flags&(1<<26))
00397 {
00398 type|=edkcCPU_SSE2;
00399 }
00400 }
00401 }
00402 return type;
00403 }
00404
00405 uint16 WINAPI dkcstd_getFPUMode(){
00406 uint16 wSave;
00407 __asm fstcw wSave
00408
00409 return wSave;
00410 }
00411
00412 int WINAPI dkcstd_setFPUMode(uint16 data){
00413 if(data > 0x300){
00414 return edk_FAILED;
00415 }
00416 __asm fldcw data
00417 return edk_SUCCEEDED;
00418 }
00419
00420
00421 void WINAPI dkcstd_getRDTSC(DKC_UINT64_STRUCT *p)
00422 {
00423 *p = dkcstd_getRDTSC_Fast();
00424 }
00425 #endif