メインページ | アルファベット順一覧 | データ構造 | ファイル一覧 | データフィールド | グローバル | 関連ページ

x86.c

説明を見る。
00001 
00053 #include "x86.h"
00054 #include "memory.h"
00055 
00056 
00057 #if 1!=DKUTIL_CSTD_MSVC_IASM
00058 //# error "unsupport msvc inline assembler"
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         // CPUID命令の存在チェック
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         // CPUID 0
00102         //-----------------------------------------------------------
00103         MOV     EAX,        0
00104         CPUID
00105 
00106         CMP     EAX,        0
00107         JE      EXIT                // 0では話にならん
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         // CPUID 1
00115         //-----------------------------------------------------------
00116         MOV     EAX,        1
00117         CPUID
00118 
00119         //----------------------------------------------
00120         // EAXレジスタの中身検証
00121         //----------------------------------------------
00122         // ステッピングID
00123         MOV     ESI,        EAX
00124         AND     ESI,        0x0F;       // 下位4バイトにステッピングID
00125         MOV     [SteppingID],ESI
00126 
00127         // モデルID
00128         SHR     EAX,        4           // 右ステッピングID分に詰めて・・・
00129         MOV     ESI,        EAX
00130         AND     ESI,        0x0F        // さらに4バイトに
00131         MOV     [ModelID],  ESI
00132 
00133         // ファミリーID
00134         SHR     EAX,        4           // また詰めて・・・
00135         MOV     ESI,        EAX
00136         AND     ESI,        0x0F        // おなじみ4バイト
00137         MOV     [FamilyID], ESI
00138 
00139         // タイプID
00140         SHR     EAX,        4           // もうええがな
00141         MOV     ESI,        EAX
00142         AND     ESI,        0x03        // 今度は2バイト
00143         MOV     [TypeID],   ESI
00144 
00145         //----------------------------------------------
00146         // EDXレジスタの中身検証
00147         //----------------------------------------------
00148         // FPU(なかったらヤバイと思うけどね^^;
00149         XOR     EAX,        EAX         // ゼロクリア
00150         TEST    EDX,        1<<0        // 1バイト目チェック
00151         SETNZ   AL                      // 0でないならALレジスタへ転送
00152         MOV     [bFPU],     EAX         // 結果やいかに
00153 
00154         // TSC
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         // MMX命令
00166         XOR     EAX,        EAX
00167         TEST    EDX,        1<<23
00168         SETNZ   AL
00169         MOV     [bMMX],     EAX
00170 
00171         // MMX2 & SSE 命令
00172         XOR     EAX,        EAX
00173         TEST    EDX,        1<<25
00174         SETNZ   AL
00175         MOV     [bMMX2],    EAX
00176         MOV     [bSSE],     EAX
00177 
00179 //      以下はAMDのCPU情報      //
00181 
00182         //-----------------------------------------------------------
00183         // CPUID 0x80000000
00184         //-----------------------------------------------------------
00185         MOV     EAX,        0x80000000
00186         CPUID
00187 
00188         CMP     EAX,        0x80000001  // 次のCPUID命令のサポートチェック
00189         JB      EXIT
00190 
00191         //-----------------------------------------------------------
00192         // CPUID 0x80000001
00193         //-----------------------------------------------------------
00194         MOV     EAX,        0x80000001
00195         CPUID
00196 
00197         // MMX2
00198         XOR     EAX,        EAX
00199         TEST    EDX,        1<<22
00200         SETNZ   AL
00201         MOV     [bMMX2],    EAX
00202 
00203         // Enhansed 3DNow!
00204         XOR     EAX,        EAX
00205         TEST    EDX,        1<<30
00206         SETNZ   AL
00207         MOV     [bE3DNOW],  EAX
00208 
00209         // Enhansed 3DNow!
00210         XOR     EAX,        EAX
00211         TEST    EDX,        1<<31
00212         SETNZ   AL
00213         MOV     [b3DNOW],   EAX
00214 
00215         //-----------------------------------------------------------
00216         // CPUID 0x80000002 - 0x80000004
00217         //-----------------------------------------------------------
00218         // サポートしてるか?
00219         MOV     EAX,        0x80000000
00220         CPUID
00221         CMP     EAX,        0x80000004
00222         JB      EXIT
00223 
00224         // 0x80000002
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         // 0x80000003
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         // 0x80000004
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     // CPUクロック取得
00259     //------------------------------------------------------------------------
00260     if ( bTSC && 0 != CPUClockCalcTime)
00261     {
00262 
00263         /*__asm
00264         {
00265             RDTSC
00266             MOV     [CPUClock],     EAX
00267         }
00268 
00269         Sleep( 1000 );
00270 
00271         __asm
00272         {
00273             RDTSC
00274             SUB     EAX,            [CPUClock]
00275             MOV     [CPUClock],     EAX
00276         }
00277 
00278         CPUClock /= 1000000;
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 //CPUIDの有無を比較
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     //AMD系
00379     if (flags&(1<<31))
00380     {
00381         type|=edkcCPU_3DNOW;
00382         if (flags&(1<<30))
00383         {
00384             type|=edkcCPU_E3DNOW;
00385         }
00386     }
00387     //Intel系
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

dkutil_cstdに対してSat Sep 10 09:19:18 2005に生成されました。  doxygen 1.4.4