/****************************************************************************** TrickLibrary extra ia32info ia32info ソースファイル Coded by Wraith in Jan 3, 2004. ******************************************************************************/ // Tab幅を4文字に設定して表示させてください。 /////////////////////////////////////////////////////////////////////////////// // // ■ ia32info.cpp // http://tricklib.com/cxx/ex/ia32info/ia32info.cpp // // □ リファレンス・サポートページ // http://tricklib.com/cxx/ex/ia32info/ // // □ ライセンス情報 // http://tricklib.com/license.htm // #if defined(__BORLANDC__) // for cpuid. #pragma option -5 #endif // 以下は http://tricklib.com/cxx/ex/dwarf/dwarf.h よりハンドインクルード #ifndef __DWARF_H__ #define __DWARF_H__ #if defined(__GNUC__) # define ASM_HEX(X) "$0x" #X #elif defined(__BORLANDC__) # pragma inline # define ASM_HEX(X) 0##X##h # define ASM_MEMBER(X) .X #elif defined(__INTEL_COMPILER) # define ASM_HEX(X) 0##X##h # define ASM_MEMBER(X) this.X //# define ASM_MEMBER(X) .X // こっちでもOK。 #elif defined(_MSC_VER) # define ASM_HEX(X) 0##X##h # define ASM_MEMBER(X) this.X #elif defined(__MWERKS__) # define ASM_HEX(X) 0x##X # define ASM_MEMBER(X) X #elif defined(__DMC__) # define ASM_HEX(X) 0##X##h # define ASM_MEMBER(X) X //# define ASM_MEMBER(X) .X // こっちでもOK。 #else # define ASM_HEX(X) 0##X##h #endif #if defined(ASM_MEMBER) # define ASM_MEMBER_EX(X, num) ASM_MEMBER(X) #else # define ASM_MEMBER_EX(X, num) [num] #endif #endif // __DWARF_H__ // 以上は http://tricklib.com/cxx/ex/dwarf/dwarf.h よりハンドインクルード #include "ia32info.h" #include // for // extern "C" int sprintf(char *, const char *...); // extern "C" int printf(const char *...); // このソースを単体でテストしたい時は下のコメントを外して __TEST_IA32INFO__ // を有効にした上でコンパイルすれば、コンソールアプリとして実行できます。 // //#define __TEST_IA32INFO__ namespace ia32info { bool enabled_cpuid() { unsigned int pre_EFlags; unsigned int new_EFlags; # ifdef __GNUC__ asm ( // EFlags の値の取得 "pushfl;\n" "popl %%eax;\n" "movl %%eax, %0;\n" // CPUID 命令の存在のチェック (ID フラグのチェック) "xorl " ASM_HEX(00200000) ", %%eax;\n" "pushl %%eax;\n" "popfl;\n" // EFlags の値の取得 "pushfl;\n" "popl %%eax;\n" "movl %%eax, %1;\n" :"=g"(pre_EFlags), "=g"(new_EFlags) : :"%eax"); # else __asm { // EFlags の値の取得 pushfd; pop eax; mov pre_EFlags, eax; // CPUID 命令の存在のチェック (ID フラグのチェック) xor eax, ASM_HEX(00200000); push eax; popfd; // EFlags の値の取得 pushfd; pop eax; mov new_EFlags, eax; } # endif return pre_EFlags != new_EFlags; } cpuid_info::cpuid_info(unsigned int option) { # if defined(__GNUC__) asm("cpuid": "=a"(reg_eax), "=b"(reg_ebx), "=c"(reg_ecx), "=d"(reg_edx): "a"(option)); # else __asm { pushad; mov eax, option; cpuid; mov esi, this; mov [esi]ASM_MEMBER(reg_eax), eax; mov [esi]ASM_MEMBER(reg_ebx), ebx; mov [esi]ASM_MEMBER(reg_ecx), ecx; mov [esi]ASM_MEMBER(reg_edx), edx; popad } # endif } const char * cpuid_signature::brand_name() const { // processor|Processor は元にしたインテルの資料(AP-485)に忠実にしたがった // 結果で、typo じゃないです。 switch(brand_id()) { case 0x01: return "Intel(R) Celeron(R) processor"; case 0x02: return "Intel(R) Pentium(R) III processor"; case 0x03: if (0x000006B1 != processor_signature()) { return "Intel(R) Pentium(R) III Xeon(TM) processor"; } else { return "Intel(R) Celeron(R) processor"; } case 0x04: return "Intel(R) Pentium(R) III processor"; case 0x06: return "Mobile Intel(R) Pentium(R) III Processor-M"; case 0x07: return "Mobile Intel(R) Celeron(R) processor"; case 0x08: if (0x00000F13 <= processor_signature()) { return "Intel(R) Genuine processor"; } else { return "Intel(R) Pentium(R) 4 processor"; } case 0x09: return "Intel(R) Pentium(R) 4 processor"; case 0x0A: return "Intel(R) Celeron(R) Processor"; case 0x0B: if (0x00000F13 <= processor_signature()) { return "Intel(R) Xeon(TM) processor"; } else { return "Intel(R) Xeon(TM) processor MP"; } case 0x0C: return "Intel(R) Xeon(TM) processor MP"; case 0x0E: if (0x00000F13 <= processor_signature()) { return "Mobile Intel(R) Pentium(R) 4 processor-M"; } else { return "Intel(R) Xeon(TM) processor"; } case 0x0F: return "Mobile Intel(R) Celeron(R) Processor"; case 0x00: default: return "unknown"; } } cpuid_serial_number_string::cpuid_serial_number_string(const cpuid_serial_number &X) { sprintf(value, "%04.4X-%04.4X-%04.4X-%04.4X-%04.4X-%04.4X", X[0] >> 16, X[0] & 0xFFFF, X[1] >> 16, X[1] & 0xFFFF, X[2] >> 16, X[2] & 0xFFFF); } } // using namespace ia32info #ifdef __TEST_IA32INFO__ int main() { using namespace ia32info; const char *bool_value_name[] = { "false", "true" }; const bool X_enabled_cpuid = enabled_cpuid(); printf("cpuid命令の実装: %s\n", bool_value_name[X_enabled_cpuid]); if (X_enabled_cpuid) { const unsigned int max_index = cpuid_baseinfo_maxindex(); printf("cpuid - 基本情報最大インデックス: 0x%X\n", max_index); printf("CPU のベンダID: %s\n", cpuid_venderid().get_string()); if (1 <= max_index) { const cpuid_signature signature; printf("ステッピングID: 0x%X\n", signature.stepping_id()); printf("モデル番号: 0x%X\n", signature.model_number()); printf("ファミリーコード: 0x%X\n", signature.family_code()); printf("プロセッサタイプ: 0x%X\n", signature.processor_type()); printf("拡張モデル: 0x%X\n", signature.ex_model()); printf("拡張ファミリ: 0x%X\n", signature.ex_family()); printf("ブランドID: 0x%X\n", signature.brand_id()); printf("ブランド名: %s\n", signature.brand_name()); printf("チャンク: 0x%X\n", signature.chunk()); printf("APIC ID: 0x%X\n", signature.apic_id()); printf("オンチップの浮動小数点演算ユニット: %s\n", bool_value_name[signature.fpu()]); printf("仮想モード拡張: %s\n", bool_value_name[signature.vme()]); printf("デバッグ機能拡張: %s\n", bool_value_name[signature.de()]); printf("ページサイズ拡張: %s\n", bool_value_name[signature.pse()]); printf("タイムスタンプカウンタ: %s\n", bool_value_name[signature.tsc()]); printf("モデル固有レジスタ: %s\n", bool_value_name[signature.msr()]); printf("物理アドレス拡張: %s\n", bool_value_name[signature.pae()]); printf("マシンチェック例外: %s\n", bool_value_name[signature.mce()]); printf("CMPXCHG8命令のサポート: %s\n", bool_value_name[signature.cx8()]); printf("オンチップAPICハードウェアのサポート: %s\n", bool_value_name[signature.apic()]); printf("高速システムコール: %s\n", bool_value_name[signature.sep()]); printf("メモリタイプレンジレジスタ: %s\n", bool_value_name[signature.mtrr()]); printf("ページグローバルイネーブル: %s\n", bool_value_name[signature.pge()]); printf("マシンチェックアーキテクチャ: %s\n", bool_value_name[signature.mca()]); printf("条件付移動命令のサポート: %s\n", bool_value_name[signature.cmov()]); printf("ページ属性テーブル: %s\n", bool_value_name[signature.pat()]); printf("36ビットページサイズ拡張: %s\n", bool_value_name[signature.pse_36()]); printf("プロセッサシリアルナンバーのサポートとイネーブル: %s\n", bool_value_name[signature.psn()]); printf("CLFLUSH命令のサポート: %s\n", bool_value_name[signature.clfsh()]); printf("デバッグストア: %s\n", bool_value_name[signature.ds()]); printf("温度モニタおよびソフトウェア制御されるクロック機能のサポート: %s\n", bool_value_name[signature.acpi()]); printf("インテルアーキテクチャMMXテクノロジのサポート: %s\n", bool_value_name[signature.mmx()]); printf("浮動小数点コンテキストの高速セーブ/リストア: %s\n", bool_value_name[signature.fxsr()]); printf("ストリーミングSIMD拡張命令のサポート: %s\n", bool_value_name[signature.sse()]); printf("ストリーミングSIMD拡張命令2のサポート: %s\n", bool_value_name[signature.sse2()]); printf("セルフスヌープ: %s\n", bool_value_name[signature.ss()]); printf("温度モニタのサポート: %s\n", bool_value_name[signature.tm()]); if (3 <= max_index && signature.psn()) { printf("プロセッサシリアルナンバー: %s\n", (const char *)cpuid_serial_number_string(signature)); } } const cpuid_extra_maxindex extra_maxindex; const bool X_enabled_extra = extra_maxindex.enabled_extra(); printf("cpuid - 拡張機能のサポート: %s\n", bool_value_name[X_enabled_extra]); if (X_enabled_extra) { const unsigned int max_ex_index = extra_maxindex; printf("cpuid - 拡張機能最大インデックス: 0x%X\n", max_ex_index); const bool X_enabled_brand_string = extra_maxindex.enabled_brand_string(); printf("プロセッサブランドストリング機能のサポート: %s\n", bool_value_name[X_enabled_brand_string]); if (X_enabled_brand_string) { printf("プロセッサブランドストリング: %s\n", cpuid_processor_brand_string().get_string()); } } } return 0; } #endif /****************************************************************************** □■□■ Wraith the Trickster □■□■ ■□■□ 〜I'll go with heaven's advantage and fool's wisdom.〜 ■□■□ ******************************************************************************/