diff --git a/bochs/build/win32/vs2013ex-plugins-workspace.zip b/bochs/build/win32/vs2013ex-plugins-workspace.zip index b1814ac5f..b74e5f863 100644 Binary files a/bochs/build/win32/vs2013ex-plugins-workspace.zip and b/bochs/build/win32/vs2013ex-plugins-workspace.zip differ diff --git a/bochs/build/win32/vs2013ex-workspace.zip b/bochs/build/win32/vs2013ex-workspace.zip index 414ecc917..321c34a1f 100644 Binary files a/bochs/build/win32/vs2013ex-workspace.zip and b/bochs/build/win32/vs2013ex-workspace.zip differ diff --git a/bochs/config.h.in b/bochs/config.h.in index 279d6102f..8e0726b66 100644 --- a/bochs/config.h.in +++ b/bochs/config.h.in @@ -664,6 +664,7 @@ typedef #define BX_SUPPORT_FPU 0 #define BX_SUPPORT_3DNOW 0 #define BX_SUPPORT_MONITOR_MWAIT 0 +#define BX_SUPPORT_PERFMON 0 #define BX_SUPPORT_SVM 0 #define BX_SUPPORT_VMX 0 #define BX_SUPPORT_AVX 0 diff --git a/bochs/configure b/bochs/configure index d82ac9b77..25e615ef3 100755 --- a/bochs/configure +++ b/bochs/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Id: configure.in 12475 2014-08-31 17:08:58Z vruppert . +# From configure.in Id: configure.in 12501 2014-10-14 15:59:10Z sshwarts . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69. # @@ -1026,6 +1026,7 @@ enable_svm enable_3dnow enable_alignment_check enable_monitor_mwait +enable_perfmon enable_avx enable_evex enable_x86_debugger @@ -1751,6 +1752,8 @@ Optional Features: 3) --enable-monitor-mwait support for MONITOR/MWAIT instructions (yes, if cpu level > 5 - experimental) + --enable-perfmon support for limiteed hardware performance monitoring + emulation (yes, if cpu level > 5 - experimental) --enable-avx support for AVX instructions (no) --enable-evex support for EVEX prefix and AVX-512 extensions (no) --enable-x86-debugger x86 debugger support (no) @@ -5171,7 +5174,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5174 "configure"' > conftest.$ac_ext + echo '#line 5177 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6859,11 +6862,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6862: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6865: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6866: \$? = $ac_status" >&5 + echo "$as_me:6869: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -7092,11 +7095,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7095: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7098: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7099: \$? = $ac_status" >&5 + echo "$as_me:7102: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -7159,11 +7162,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7162: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7165: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7166: \$? = $ac_status" >&5 + echo "$as_me:7169: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -8949,7 +8952,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:11168: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:11169: \$? = $ac_status" >&5 + echo "$as_me:11172: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -11229,11 +11232,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:11232: $lt_compile\"" >&5) + (eval echo "\"\$as_me:11235: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:11236: \$? = $ac_status" >&5 + echo "$as_me:11239: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -12254,7 +12257,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:13181: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:13182: \$? = $ac_status" >&5 + echo "$as_me:13185: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -13242,11 +13245,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:13245: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13248: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:13249: \$? = $ac_status" >&5 + echo "$as_me:13252: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -15207,11 +15210,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15210: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15213: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:15214: \$? = $ac_status" >&5 + echo "$as_me:15217: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -15440,11 +15443,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15443: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15446: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:15447: \$? = $ac_status" >&5 + echo "$as_me:15450: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -15507,11 +15510,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:15510: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15513: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:15514: \$? = $ac_status" >&5 + echo "$as_me:15517: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -17297,7 +17300,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <&6; } fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for limited hardware performance monitoring emulation support (experimental)" >&5 +$as_echo_n "checking for limited hardware performance monitoring emulation support (experimental)... " >&6; } +# Check whether --enable-perfmon was given. +if test "${enable_perfmon+set}" = set; then : + enableval=$enable_perfmon; if test "$enableval" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + $as_echo "#define BX_SUPPORT_PERFMON 1" >>confdefs.h + + elif test "$enableval" = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + $as_echo "#define BX_SUPPORT_PERFMON 0" >>confdefs.h + + fi + +else + + if test "$bx_cpu_level" -gt 5; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + $as_echo "#define BX_SUPPORT_PERFMON 1" >>confdefs.h + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + $as_echo "#define BX_SUPPORT_PERFMON 0" >>confdefs.h + + fi + + +fi + + support_avx=0 AVX_LIB_VAR='' { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AVX instructions support" >&5 diff --git a/bochs/configure.in b/bochs/configure.in index 5bbba3892..1b09af933 100644 --- a/bochs/configure.in +++ b/bochs/configure.in @@ -1296,6 +1296,28 @@ AC_ARG_ENABLE(monitor_mwait, ] ) +AC_MSG_CHECKING(for limited hardware performance monitoring emulation support (experimental)) +AC_ARG_ENABLE(perfmon, + AS_HELP_STRING([--enable-perfmon], [support for limiteed hardware performance monitoring emulation (yes, if cpu level > 5 - experimental)]), + [if test "$enableval" = yes; then + AC_MSG_RESULT(yes) + AC_DEFINE(BX_SUPPORT_PERFMON, 1) + elif test "$enableval" = no; then + AC_MSG_RESULT(no) + AC_DEFINE(BX_SUPPORT_PERFMON, 0) + fi + ], + [ + if test "$bx_cpu_level" -gt 5; then + AC_MSG_RESULT(yes) + AC_DEFINE(BX_SUPPORT_PERFMON, 1) + else + AC_MSG_RESULT(no) + AC_DEFINE(BX_SUPPORT_PERFMON, 0) + fi + ] + ) + support_avx=0 AVX_LIB_VAR='' AC_MSG_CHECKING(for AVX instructions support) diff --git a/bochs/cpu/Makefile.in b/bochs/cpu/Makefile.in index 3c3ab33b2..adfba014f 100644 --- a/bochs/cpu/Makefile.in +++ b/bochs/cpu/Makefile.in @@ -90,6 +90,7 @@ OBJS = \ data_xfer16.o \ data_xfer32.o \ exception.o \ + cpuid.o \ generic_cpuid.o \ proc_ctrl.o \ crregs.o \ @@ -423,13 +424,19 @@ fpu_emu.o: fpu_emu.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \ descriptor.h instr.h ia_opcodes.h lazy_flags.h icache.h apic.h i387.h \ fpu/softfloat.h fpu/tag_w.h fpu/status_w.h fpu/control_w.h xmm.h vmx.h \ svm.h stack.h +cpuid.o: cpuid.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \ + ../config.h ../osdep.h ../gui/siminterface.h ../cpudb.h \ + ../gui/paramtree.h ../memory/memory.h ../pc_system.h ../gui/gui.h \ + ../instrument/stubs/instrument.h cpu.h cpuid.h crregs.h descriptor.h \ + instr.h ia_opcodes.h lazy_flags.h icache.h apic.h i387.h fpu/softfloat.h \ + fpu/tag_w.h fpu/status_w.h fpu/control_w.h xmm.h vmx.h svm.h ../param_names.h generic_cpuid.o: generic_cpuid.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \ ../bx_debug/debug.h ../config.h ../osdep.h ../gui/siminterface.h \ ../cpudb.h ../gui/paramtree.h ../memory/memory.h ../pc_system.h \ ../gui/gui.h ../instrument/stubs/instrument.h cpu.h cpuid.h crregs.h \ descriptor.h instr.h ia_opcodes.h lazy_flags.h icache.h apic.h i387.h \ fpu/softfloat.h fpu/tag_w.h fpu/status_w.h fpu/control_w.h xmm.h vmx.h \ - svm.h ../param_names.h generic_cpuid.h ../cpu/cpuid.h + svm.h ../param_names.h generic_cpuid.h icache.o: icache.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \ ../config.h ../osdep.h ../gui/siminterface.h ../cpudb.h \ ../gui/paramtree.h ../memory/memory.h ../pc_system.h ../gui/gui.h \ diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 4eaa02db9..362e89cca 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -433,6 +433,18 @@ struct BxExceptionInfo { #define BX_MSR_MTRR_DEFTYPE 0x2ff #endif +#if BX_SUPPORT_PERFMON + #define BX_MSR_PMC0 0x0c1 /* PERFCTR0 */ + #define BX_MSR_PMC1 0x0c2 /* PERFCTR1 */ + #define BX_MSR_PERFEVTSEL0 0x186 + #define BX_MSR_PERFEVTSEL1 0x187 + #define BX_MSR_PERF_FIXED_CTR0 0x309 /* Fixed Performance Counter 0 (R/W): Counts Instr_Retired.Any */ + #define BX_MSR_PERF_FIXED_CTR1 0x30a /* Fixed Performance Counter 1 (R/W): Counts CPU_CLK_Unhalted.Core */ + #define BX_MSR_PERF_FIXED_CTR2 0x30b /* Fixed Performance Counter 2 (R/W): Counts CPU_CLK_Unhalted.Ref */ + #define BX_MSR_FIXED_CTR_CTRL 0x38d /* Fixed Performance Counter Control (R/W) */ + #define BX_MSR_PERF_GLOBAL_CTRL 0x38f /* Global Performance Counter Control */ +#endif + #define BX_MSR_TSC_DEADLINE 0x6E0 /* Intel MPX supervisor bound configuration register */ diff --git a/bochs/cpu/cpudb/amd_k6_2_chomper.cc b/bochs/cpu/cpudb/amd_k6_2_chomper.cc index 3e294b5b2..c9ca3b5a2 100644 --- a/bochs/cpu/cpudb/amd_k6_2_chomper.cc +++ b/bochs/cpu/cpudb/amd_k6_2_chomper.cc @@ -289,19 +289,9 @@ void amd_k6_2_chomper_t::get_cpuid_hidden_level(cpuid_function_t *leaf) const void amd_k6_2_chomper_t::dump_cpuid(void) const { + bx_cpuid_t::dump_cpuid(0x1, 0x5); + struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=1; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000005; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - get_cpuid_leaf(0x8fffffff, 0x00000000, &leaf); BX_INFO(("CPUID[0x8fffffff]: %08x %08x %08x %08x", leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); } diff --git a/bochs/cpu/cpudb/athlon64_clawhammer.cc b/bochs/cpu/cpudb/athlon64_clawhammer.cc index dcfb3b3b1..42302dae6 100644 --- a/bochs/cpu/cpudb/athlon64_clawhammer.cc +++ b/bochs/cpu/cpudb/athlon64_clawhammer.cc @@ -386,19 +386,9 @@ void athlon64_clawhammer_t::get_cpuid_hidden_level(cpuid_function_t *leaf) const void athlon64_clawhammer_t::dump_cpuid(void) const { + bx_cpuid_t::dump_cpuid(0x1, 0x18); + struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=1; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000018; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - get_cpuid_leaf(0x8fffffff, 0x00000000, &leaf); BX_INFO(("CPUID[0x8fffffff]: %08x %08x %08x %08x", leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); } diff --git a/bochs/cpu/cpudb/athlon64_venice.cc b/bochs/cpu/cpudb/athlon64_venice.cc index a41e9d523..2a5dd8a04 100644 --- a/bochs/cpu/cpudb/athlon64_venice.cc +++ b/bochs/cpu/cpudb/athlon64_venice.cc @@ -437,19 +437,9 @@ void athlon64_venice_t::get_cpuid_hidden_level(cpuid_function_t *leaf) const void athlon64_venice_t::dump_cpuid(void) const { + bx_cpuid_t::dump_cpuid(0x1, 0x18); + struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=1; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000018; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - get_cpuid_leaf(0x8fffffff, 0x00000000, &leaf); BX_INFO(("CPUID[0x8fffffff]: %08x %08x %08x %08x", leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); } diff --git a/bochs/cpu/cpudb/atom_n270.cc b/bochs/cpu/cpudb/atom_n270.cc index cddfcca7b..16bf59247 100644 --- a/bochs/cpu/cpudb/atom_n270.cc +++ b/bochs/cpu/cpudb/atom_n270.cc @@ -417,17 +417,41 @@ void atom_n270_t::get_std_cpuid_leaf_6(cpuid_function_t *leaf) const void atom_n270_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf) const { // CPUID function 0x0000000A - Architectural Performance Monitoring Leaf -/* + + // EAX: + // [7:0] Version ID of architectural performance monitoring + // [15:8] Number of general-purpose performance monitoring counters per logical processor + // [23:16] Bit width of general-purpose, performance monitoring counter + // [31:24] Length of EBX bit vector to enumerate architectural performance + // monitoring events. + + // EBX: + // [0] Core cycle event not available if 1 + // [1] Instruction retired event not available if 1 + // [2] Reference cycles event not available if 1 + // [3] Last-level cache reference event not available if 1 + // [4] Last-level cache misses event not available if 1 + // [5] Branch instruction retired event not available if 1 + // [6] Branch mispredict retired event not available if 1 + // [31:7] reserved + + // ECX: reserved + + // EDX: + // [4:0] Number of fixed performance counters (if Version ID > 1) + // [12:5] Bit width of fixed-function performance counters (if Version ID > 1) + // [31:13] reserved + leaf->eax = 0x07280203; leaf->ebx = 0x00000000; leaf->ecx = 0x00000000; leaf->edx = 0x00002501; -*/ - leaf->eax = 0; // reporting true capabilities breaks Win7 x64 installation +/* + leaf->eax = 0; // reporting true capabilities without supporting it breaks Win7 x64 installation leaf->ebx = 0; leaf->ecx = 0; leaf->edx = 0; - +*/ BX_INFO(("WARNING: Architectural Performance Monitoring is not implemented")); } @@ -526,18 +550,7 @@ void atom_n270_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) const void atom_n270_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=0xA; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000008; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0xA, 0x8); } bx_cpuid_t *create_atom_n270_cpuid(BX_CPU_C *cpu) { return new atom_n270_t(cpu); } diff --git a/bochs/cpu/cpudb/core2_penryn_t9600.cc b/bochs/cpu/cpudb/core2_penryn_t9600.cc index 20f56c576..30c104dcf 100644 --- a/bochs/cpu/cpudb/core2_penryn_t9600.cc +++ b/bochs/cpu/cpudb/core2_penryn_t9600.cc @@ -470,16 +470,41 @@ void core2_penryn_t9600_t::get_std_cpuid_leaf_6(cpuid_function_t *leaf) const void core2_penryn_t9600_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf) const { // CPUID function 0x0000000A - Architectural Performance Monitoring Leaf -/* + + // EAX: + // [7:0] Version ID of architectural performance monitoring + // [15:8] Number of general-purpose performance monitoring counters per logical processor + // [23:16] Bit width of general-purpose, performance monitoring counter + // [31:24] Length of EBX bit vector to enumerate architectural performance + // monitoring events. + + // EBX: + // [0] Core cycle event not available if 1 + // [1] Instruction retired event not available if 1 + // [2] Reference cycles event not available if 1 + // [3] Last-level cache reference event not available if 1 + // [4] Last-level cache misses event not available if 1 + // [5] Branch instruction retired event not available if 1 + // [6] Branch mispredict retired event not available if 1 + // [31:7] reserved + + // ECX: reserved + + // EDX: + // [4:0] Number of fixed performance counters (if Version ID > 1) + // [12:5] Bit width of fixed-function performance counters (if Version ID > 1) + // [31:13] reserved + leaf->eax = 0x07280202; leaf->ebx = 0x00000000; leaf->ecx = 0x00000000; leaf->edx = 0x00000503; -*/ - leaf->eax = 0; // reporting true capabilities breaks Win7 x64 installation +/* + leaf->eax = 0; // reporting true capabilities without supporting it breaks Win7 x64 installation leaf->ebx = 0; leaf->ecx = 0; leaf->edx = 0; +*/ BX_INFO(("WARNING: Architectural Performance Monitoring is not implemented")); } @@ -610,18 +635,7 @@ void core2_penryn_t9600_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) const void core2_penryn_t9600_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=0xd; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000008; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0xD, 0x8); } bx_cpuid_t *create_core2_penryn_t9600_cpuid(BX_CPU_C *cpu) { return new core2_penryn_t9600_t(cpu); } diff --git a/bochs/cpu/cpudb/core_duo_t2400_yonah.cc b/bochs/cpu/cpudb/core_duo_t2400_yonah.cc index 2f3092126..1d1438fb9 100644 --- a/bochs/cpu/cpudb/core_duo_t2400_yonah.cc +++ b/bochs/cpu/cpudb/core_duo_t2400_yonah.cc @@ -417,16 +417,41 @@ void core_duo_t2400_yonah_t::get_std_cpuid_leaf_6(cpuid_function_t *leaf) const void core_duo_t2400_yonah_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf) const { // CPUID function 0x0000000A - Architectural Performance Monitoring Leaf -/* + + // EAX: + // [7:0] Version ID of architectural performance monitoring + // [15:8] Number of general-purpose performance monitoring counters per logical processor + // [23:16] Bit width of general-purpose, performance monitoring counter + // [31:24] Length of EBX bit vector to enumerate architectural performance + // monitoring events. + + // EBX: + // [0] Core cycle event not available if 1 + // [1] Instruction retired event not available if 1 + // [2] Reference cycles event not available if 1 + // [3] Last-level cache reference event not available if 1 + // [4] Last-level cache misses event not available if 1 + // [5] Branch instruction retired event not available if 1 + // [6] Branch mispredict retired event not available if 1 + // [31:7] reserved + + // ECX: reserved + + // EDX: + // [4:0] Number of fixed performance counters (if Version ID > 1) + // [12:5] Bit width of fixed-function performance counters (if Version ID > 1) + // [31:13] reserved + leaf->eax = 0x07280201; leaf->ebx = 0x00000000; leaf->ecx = 0x00000000; leaf->edx = 0x00000000; -*/ - leaf->eax = 0; // reporting true capabilities breaks Win7 x64 installation +/* + leaf->eax = 0; // reporting true capabilities without supporting it breaks Win7 x64 installation leaf->ebx = 0; leaf->ecx = 0; leaf->edx = 0; +*/ BX_INFO(("WARNING: Architectural Performance Monitoring is not implemented")); } @@ -524,18 +549,7 @@ void core_duo_t2400_yonah_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) const void core_duo_t2400_yonah_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=0xA; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000008; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0xA, 0x8); } bx_cpuid_t *create_core_duo_t2400_yonah_cpuid(BX_CPU_C *cpu) { return new core_duo_t2400_yonah_t(cpu); } diff --git a/bochs/cpu/cpudb/corei5_arrandale_m520.cc b/bochs/cpu/cpudb/corei5_arrandale_m520.cc index e0929b3f6..e9bb85958 100644 --- a/bochs/cpu/cpudb/corei5_arrandale_m520.cc +++ b/bochs/cpu/cpudb/corei5_arrandale_m520.cc @@ -494,16 +494,41 @@ void corei5_arrandale_m520_t::get_std_cpuid_leaf_6(cpuid_function_t *leaf) const void corei5_arrandale_m520_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf) const { // CPUID function 0x0000000A - Architectural Performance Monitoring Leaf -/* + + // EAX: + // [7:0] Version ID of architectural performance monitoring + // [15:8] Number of general-purpose performance monitoring counters per logical processor + // [23:16] Bit width of general-purpose, performance monitoring counter + // [31:24] Length of EBX bit vector to enumerate architectural performance + // monitoring events. + + // EBX: + // [0] Core cycle event not available if 1 + // [1] Instruction retired event not available if 1 + // [2] Reference cycles event not available if 1 + // [3] Last-level cache reference event not available if 1 + // [4] Last-level cache misses event not available if 1 + // [5] Branch instruction retired event not available if 1 + // [6] Branch mispredict retired event not available if 1 + // [31:7] reserved + + // ECX: reserved + + // EDX: + // [4:0] Number of fixed performance counters (if Version ID > 1) + // [12:5] Bit width of fixed-function performance counters (if Version ID > 1) + // [31:13] reserved + leaf->eax = 0x07300403; leaf->ebx = 0x00000004; leaf->ecx = 0x00000000; leaf->edx = 0x00000603; -*/ - leaf->eax = 0; // reporting true capabilities breaks Win7 x64 installation +/* + leaf->eax = 0; // reporting true capabilities without supporting it breaks Win7 x64 installation leaf->ebx = 0; leaf->ecx = 0; leaf->edx = 0; +*/ BX_INFO(("WARNING: Architectural Performance Monitoring is not implemented")); } @@ -681,18 +706,7 @@ void corei5_arrandale_m520_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) const void corei5_arrandale_m520_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=0xb; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000008; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0xB, 0x8); } bx_cpuid_t *create_corei5_arrandale_m520_cpuid(BX_CPU_C *cpu) { return new corei5_arrandale_m520_t(cpu); } diff --git a/bochs/cpu/cpudb/corei5_lynnfield_750.cc b/bochs/cpu/cpudb/corei5_lynnfield_750.cc index 59634f060..83534ed0b 100644 --- a/bochs/cpu/cpudb/corei5_lynnfield_750.cc +++ b/bochs/cpu/cpudb/corei5_lynnfield_750.cc @@ -470,17 +470,41 @@ void corei5_lynnfield_750_t::get_std_cpuid_leaf_6(cpuid_function_t *leaf) const void corei5_lynnfield_750_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf) const { // CPUID function 0x0000000A - Architectural Performance Monitoring Leaf -/* + + // EAX: + // [7:0] Version ID of architectural performance monitoring + // [15:8] Number of general-purpose performance monitoring counters per logical processor + // [23:16] Bit width of general-purpose, performance monitoring counter + // [31:24] Length of EBX bit vector to enumerate architectural performance + // monitoring events. + + // EBX: + // [0] Core cycle event not available if 1 + // [1] Instruction retired event not available if 1 + // [2] Reference cycles event not available if 1 + // [3] Last-level cache reference event not available if 1 + // [4] Last-level cache misses event not available if 1 + // [5] Branch instruction retired event not available if 1 + // [6] Branch mispredict retired event not available if 1 + // [31:7] reserved + + // ECX: reserved + + // EDX: + // [4:0] Number of fixed performance counters (if Version ID > 1) + // [12:5] Bit width of fixed-function performance counters (if Version ID > 1) + // [31:13] reserved + leaf->eax = 0x07300403; leaf->ebx = 0x00000044; leaf->ecx = 0x00000000; leaf->edx = 0x00000603; -*/ - leaf->eax = 0; // reporting true capabilities breaks Win7 x64 installation +/* + leaf->eax = 0; // reporting true capabilities without supporting it breaks Win7 x64 installation leaf->ebx = 0; leaf->ecx = 0; leaf->edx = 0; - +*/ BX_INFO(("WARNING: Architectural Performance Monitoring is not implemented")); } @@ -657,18 +681,7 @@ void corei5_lynnfield_750_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) const void corei5_lynnfield_750_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=0xb; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000008; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0xB, 0x8); } bx_cpuid_t *create_corei5_lynnfield_750_cpuid(BX_CPU_C *cpu) { return new corei5_lynnfield_750_t(cpu); } diff --git a/bochs/cpu/cpudb/corei7_haswell_4770.cc b/bochs/cpu/cpudb/corei7_haswell_4770.cc index 1cd2b1837..e803129fc 100644 --- a/bochs/cpu/cpudb/corei7_haswell_4770.cc +++ b/bochs/cpu/cpudb/corei7_haswell_4770.cc @@ -568,16 +568,41 @@ void corei7_haswell_4770_t::get_std_cpuid_leaf_7(Bit32u subfunction, cpuid_funct void corei7_haswell_4770_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf) const { // CPUID function 0x0000000A - Architectural Performance Monitoring Leaf -/* + + // EAX: + // [7:0] Version ID of architectural performance monitoring + // [15:8] Number of general-purpose performance monitoring counters per logical processor + // [23:16] Bit width of general-purpose, performance monitoring counter + // [31:24] Length of EBX bit vector to enumerate architectural performance + // monitoring events. + + // EBX: + // [0] Core cycle event not available if 1 + // [1] Instruction retired event not available if 1 + // [2] Reference cycles event not available if 1 + // [3] Last-level cache reference event not available if 1 + // [4] Last-level cache misses event not available if 1 + // [5] Branch instruction retired event not available if 1 + // [6] Branch mispredict retired event not available if 1 + // [31:7] reserved + + // ECX: reserved + + // EDX: + // [4:0] Number of fixed performance counters (if Version ID > 1) + // [12:5] Bit width of fixed-function performance counters (if Version ID > 1) + // [31:13] reserved + leaf->eax = 0x07300403; leaf->ebx = 0x00000000; leaf->ecx = 0x00000000; leaf->edx = 0x00000603; -*/ - leaf->eax = 0; // reporting true capabilities breaks Win7 x64 installation +/* + leaf->eax = 0; // reporting true capabilities without supporting it breaks Win7 x64 installation leaf->ebx = 0; leaf->ecx = 0; leaf->edx = 0; +*/ BX_INFO(("WARNING: Architectural Performance Monitoring is not implemented")); } @@ -812,18 +837,7 @@ void corei7_haswell_4770_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) const void corei7_haswell_4770_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=0xd; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000008; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0xD, 0x8); } bx_cpuid_t *create_corei7_haswell_4770_cpuid(BX_CPU_C *cpu) { return new corei7_haswell_4770_t(cpu); } diff --git a/bochs/cpu/cpudb/corei7_ivy_bridge_3770K.cc b/bochs/cpu/cpudb/corei7_ivy_bridge_3770K.cc index ce398f2fd..5e35bb548 100644 --- a/bochs/cpu/cpudb/corei7_ivy_bridge_3770K.cc +++ b/bochs/cpu/cpudb/corei7_ivy_bridge_3770K.cc @@ -562,16 +562,41 @@ void corei7_ivy_bridge_3770k_t::get_std_cpuid_leaf_7(Bit32u subfunction, cpuid_f void corei7_ivy_bridge_3770k_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf) const { // CPUID function 0x0000000A - Architectural Performance Monitoring Leaf -/* + + // EAX: + // [7:0] Version ID of architectural performance monitoring + // [15:8] Number of general-purpose performance monitoring counters per logical processor + // [23:16] Bit width of general-purpose, performance monitoring counter + // [31:24] Length of EBX bit vector to enumerate architectural performance + // monitoring events. + + // EBX: + // [0] Core cycle event not available if 1 + // [1] Instruction retired event not available if 1 + // [2] Reference cycles event not available if 1 + // [3] Last-level cache reference event not available if 1 + // [4] Last-level cache misses event not available if 1 + // [5] Branch instruction retired event not available if 1 + // [6] Branch mispredict retired event not available if 1 + // [31:7] reserved + + // ECX: reserved + + // EDX: + // [4:0] Number of fixed performance counters (if Version ID > 1) + // [12:5] Bit width of fixed-function performance counters (if Version ID > 1) + // [31:13] reserved + leaf->eax = 0x07300403; leaf->ebx = 0x00000000; leaf->ecx = 0x00000000; leaf->edx = 0x00000603; -*/ - leaf->eax = 0; // reporting true capabilities breaks Win7 x64 installation +/* + leaf->eax = 0; // reporting true capabilities without supporting it breaks Win7 x64 installation leaf->ebx = 0; leaf->ecx = 0; leaf->edx = 0; +*/ BX_INFO(("WARNING: Architectural Performance Monitoring is not implemented")); } @@ -804,18 +829,7 @@ void corei7_ivy_bridge_3770k_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) con void corei7_ivy_bridge_3770k_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=0xd; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000008; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0xD, 0x8); } bx_cpuid_t *create_corei7_ivy_bridge_3770k_cpuid(BX_CPU_C *cpu) { return new corei7_ivy_bridge_3770k_t(cpu); } diff --git a/bochs/cpu/cpudb/corei7_sandy_bridge_2600K.cc b/bochs/cpu/cpudb/corei7_sandy_bridge_2600K.cc index 49eefba67..73d29384a 100644 --- a/bochs/cpu/cpudb/corei7_sandy_bridge_2600K.cc +++ b/bochs/cpu/cpudb/corei7_sandy_bridge_2600K.cc @@ -517,16 +517,41 @@ void corei7_sandy_bridge_2600k_t::get_std_cpuid_leaf_6(cpuid_function_t *leaf) c void corei7_sandy_bridge_2600k_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf) const { // CPUID function 0x0000000A - Architectural Performance Monitoring Leaf -/* + + // EAX: + // [7:0] Version ID of architectural performance monitoring + // [15:8] Number of general-purpose performance monitoring counters per logical processor + // [23:16] Bit width of general-purpose, performance monitoring counter + // [31:24] Length of EBX bit vector to enumerate architectural performance + // monitoring events. + + // EBX: + // [0] Core cycle event not available if 1 + // [1] Instruction retired event not available if 1 + // [2] Reference cycles event not available if 1 + // [3] Last-level cache reference event not available if 1 + // [4] Last-level cache misses event not available if 1 + // [5] Branch instruction retired event not available if 1 + // [6] Branch mispredict retired event not available if 1 + // [31:7] reserved + + // ECX: reserved + + // EDX: + // [4:0] Number of fixed performance counters (if Version ID > 1) + // [12:5] Bit width of fixed-function performance counters (if Version ID > 1) + // [31:13] reserved + leaf->eax = 0x07300803; leaf->ebx = 0x00000000; leaf->ecx = 0x00000000; leaf->edx = 0x00000603; -*/ - leaf->eax = 0; // reporting true capabilities breaks Win7 x64 installation +/* + leaf->eax = 0; // reporting true capabilities without supporting it breaks Win7 x64 installation leaf->ebx = 0; leaf->ecx = 0; leaf->edx = 0; +*/ BX_INFO(("WARNING: Architectural Performance Monitoring is not implemented")); } @@ -757,18 +782,7 @@ void corei7_sandy_bridge_2600k_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) c void corei7_sandy_bridge_2600k_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=0xd; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000008; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0xD, 0x8); } bx_cpuid_t *create_corei7_sandy_bridge_2600k_cpuid(BX_CPU_C *cpu) { return new corei7_sandy_bridge_2600k_t(cpu); } diff --git a/bochs/cpu/cpudb/p2_klamath.cc b/bochs/cpu/cpudb/p2_klamath.cc index b63b6d8ae..975cd9a49 100644 --- a/bochs/cpu/cpudb/p2_klamath.cc +++ b/bochs/cpu/cpudb/p2_klamath.cc @@ -177,12 +177,7 @@ void p2_klamath_t::get_std_cpuid_leaf_2(cpuid_function_t *leaf) const void p2_klamath_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - - for (unsigned n=0; n<=0x2; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0x2, 0); } bx_cpuid_t *create_p2_klamath_cpuid(BX_CPU_C *cpu) { return new p2_klamath_t(cpu); } diff --git a/bochs/cpu/cpudb/p3_katmai.cc b/bochs/cpu/cpudb/p3_katmai.cc index 4ea74f9ed..9ce24b074 100644 --- a/bochs/cpu/cpudb/p3_katmai.cc +++ b/bochs/cpu/cpudb/p3_katmai.cc @@ -195,12 +195,7 @@ void p3_katmai_t::get_std_cpuid_leaf_3(cpuid_function_t *leaf) const void p3_katmai_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - - for (unsigned n=0; n<=0x3; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0x3, 0); } bx_cpuid_t *create_p3_katmai_cpuid(BX_CPU_C *cpu) { return new p3_katmai_t(cpu); } diff --git a/bochs/cpu/cpudb/p4_prescott_celeron_336.cc b/bochs/cpu/cpudb/p4_prescott_celeron_336.cc index 624d72752..9eb3df39d 100644 --- a/bochs/cpu/cpudb/p4_prescott_celeron_336.cc +++ b/bochs/cpu/cpudb/p4_prescott_celeron_336.cc @@ -393,18 +393,7 @@ void p4_prescott_celeron_336_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf) con void p4_prescott_celeron_336_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=0x3; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000008; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0x3, 0x8); } bx_cpuid_t *create_p4_prescott_celeron_336_cpuid(BX_CPU_C *cpu) { return new p4_prescott_celeron_336_t(cpu); } diff --git a/bochs/cpu/cpudb/p4_willamette.cc b/bochs/cpu/cpudb/p4_willamette.cc index 6bd7cd8af..fc3a6cdaa 100644 --- a/bochs/cpu/cpudb/p4_willamette.cc +++ b/bochs/cpu/cpudb/p4_willamette.cc @@ -277,18 +277,7 @@ void p4_willamette_t::get_ext_cpuid_leaf_1(cpuid_function_t *leaf) const void p4_willamette_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=0x2; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000004; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0x2, 0x4); } bx_cpuid_t *create_p4_willamette_cpuid(BX_CPU_C *cpu) { return new p4_willamette_t(cpu); } diff --git a/bochs/cpu/cpudb/pentium_mmx.cc b/bochs/cpu/cpudb/pentium_mmx.cc index d03d8547e..1e7f28d83 100644 --- a/bochs/cpu/cpudb/pentium_mmx.cc +++ b/bochs/cpu/cpudb/pentium_mmx.cc @@ -157,12 +157,7 @@ void pentium_mmx_t::get_std_cpuid_leaf_1(cpuid_function_t *leaf) const void pentium_mmx_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - - for (unsigned n=0; n<=0x1; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0x1, 0); } bx_cpuid_t *create_pentium_mmx_cpuid(BX_CPU_C *cpu) { return new pentium_mmx_t(cpu); } diff --git a/bochs/cpu/cpudb/phenomx3_8650_toliman.cc b/bochs/cpu/cpudb/phenomx3_8650_toliman.cc index b0a5a4640..75a9bb256 100644 --- a/bochs/cpu/cpudb/phenomx3_8650_toliman.cc +++ b/bochs/cpu/cpudb/phenomx3_8650_toliman.cc @@ -583,18 +583,7 @@ void phenom_8650_toliman_t::get_ext_cpuid_leaf_1A(cpuid_function_t *leaf) const void phenom_8650_toliman_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n <= (BX_SUPPORT_MONITOR_MWAIT ? 0x5 : 0x1); n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x8000001A; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(BX_SUPPORT_MONITOR_MWAIT ? 0x5 : 0x1, 0x1A); } bx_cpuid_t *create_phenom_8650_toliman_cpuid(BX_CPU_C *cpu) { return new phenom_8650_toliman_t(cpu); } diff --git a/bochs/cpu/cpudb/trinity_apu.cc b/bochs/cpu/cpudb/trinity_apu.cc index 81acddb95..d9f23fe17 100644 --- a/bochs/cpu/cpudb/trinity_apu.cc +++ b/bochs/cpu/cpudb/trinity_apu.cc @@ -795,18 +795,7 @@ void trinity_apu_t::get_ext_cpuid_leaf_1E(cpuid_function_t *leaf) const void trinity_apu_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n <= 0xd; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x8000001E; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0xD, 0x1E); } bx_cpuid_t *create_trinity_apu_cpuid(BX_CPU_C *cpu) { return new trinity_apu_t(cpu); } diff --git a/bochs/cpu/cpudb/turion64_tyler.cc b/bochs/cpu/cpudb/turion64_tyler.cc index 3b025b4b4..e6c04448f 100644 --- a/bochs/cpu/cpudb/turion64_tyler.cc +++ b/bochs/cpu/cpudb/turion64_tyler.cc @@ -481,18 +481,7 @@ void turion64_tyler_t::get_ext_cpuid_leaf_A(cpuid_function_t *leaf) const void turion64_tyler_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n<=1; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x80000018; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0x1, 0x18); } bx_cpuid_t *create_turion64_tyler_cpuid(BX_CPU_C *cpu) { return new turion64_tyler_t(cpu); } diff --git a/bochs/cpu/cpudb/zambezi.cc b/bochs/cpu/cpudb/zambezi.cc index f55c3ffd4..891b85f2a 100644 --- a/bochs/cpu/cpudb/zambezi.cc +++ b/bochs/cpu/cpudb/zambezi.cc @@ -745,18 +745,7 @@ void zambezi_t::get_ext_cpuid_leaf_1E(cpuid_function_t *leaf) const void zambezi_t::dump_cpuid(void) const { - struct cpuid_function_t leaf; - unsigned n; - - for (n=0; n <= 0xd; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } - - for (n=0x80000000; n<=0x8000001E; n++) { - get_cpuid_leaf(n, 0x00000000, &leaf); - BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); - } + bx_cpuid_t::dump_cpuid(0xD, 0x1E); } bx_cpuid_t *create_zambezi_cpuid(BX_CPU_C *cpu) { return new zambezi_t(cpu); } diff --git a/bochs/cpu/cpuid.cc b/bochs/cpu/cpuid.cc new file mode 100644 index 000000000..c7ef49ae6 --- /dev/null +++ b/bochs/cpu/cpuid.cc @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////// +// $Id$ +///////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2014 Stanislav Shwartsman +// Written by Stanislav Shwartsman [sshwarts at sourceforge net] +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA +// +///////////////////////////////////////////////////////////////////////// + +#include "bochs.h" +#include "cpu.h" +#include "param_names.h" +#include "cpuid.h" + +#define LOG_THIS cpu-> + +bx_cpuid_t::bx_cpuid_t(BX_CPU_C *_cpu): cpu(_cpu) +{ +#if BX_SUPPORT_SMP + nthreads = SIM->get_param_num(BXPN_CPU_NTHREADS)->get(); + ncores = SIM->get_param_num(BXPN_CPU_NCORES)->get(); + nprocessors = SIM->get_param_num(BXPN_CPU_NPROCESSORS)->get(); +#else + nthreads = 1; + ncores = 1; + nprocessors = 1; +#endif + + for (unsigned n=0; n < BX_ISA_EXTENSIONS_ARRAY_SIZE; n++) + ia_extensions_bitmask[n] = 0; +} + +void bx_cpuid_t::dump_cpuid(unsigned max_std_leaf, unsigned max_ext_leaf) const +{ + struct cpuid_function_t leaf; + unsigned n; + + for (n=0; n<=max_std_leaf; n++) { + get_cpuid_leaf(n, 0x00000000, &leaf); + BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); + } + + if (max_ext_leaf == 0) return; + + for (n=0x80000000; n<=(0x8000000 + max_ext_leaf); n++) { + get_cpuid_leaf(n, 0x00000000, &leaf); + BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx)); + } +} diff --git a/bochs/cpu/cpuid.h b/bochs/cpu/cpuid.h index 19e64ef92..b56eeea1f 100644 --- a/bochs/cpu/cpuid.h +++ b/bochs/cpu/cpuid.h @@ -228,6 +228,8 @@ protected: #endif } + void dump_cpuid(unsigned max_std_leaf, unsigned max_ext_leaf) const; + }; typedef bx_cpuid_t* (*bx_create_cpuid_method)(BX_CPU_C *cpu); diff --git a/bochs/cpu/generic_cpuid.cc b/bochs/cpu/generic_cpuid.cc index 02081ce86..d1e05c650 100644 --- a/bochs/cpu/generic_cpuid.cc +++ b/bochs/cpu/generic_cpuid.cc @@ -33,22 +33,6 @@ #define BX_CPUID_SUPPORT_ISA_EXTENSION(feature) \ (this->is_cpu_extension_supported(feature)) -bx_cpuid_t::bx_cpuid_t(BX_CPU_C *_cpu): cpu(_cpu) -{ -#if BX_SUPPORT_SMP - nthreads = SIM->get_param_num(BXPN_CPU_NTHREADS)->get(); - ncores = SIM->get_param_num(BXPN_CPU_NCORES)->get(); - nprocessors = SIM->get_param_num(BXPN_CPU_NPROCESSORS)->get(); -#else - nthreads = 1; - ncores = 1; - nprocessors = 1; -#endif - - for (unsigned n=0; n < BX_ISA_EXTENSIONS_ARRAY_SIZE; n++) - ia_extensions_bitmask[n] = 0; -} - #if BX_CPU_LEVEL >= 4 bx_generic_cpuid_t::bx_generic_cpuid_t(BX_CPU_C *cpu): bx_cpuid_t(cpu) @@ -336,6 +320,31 @@ void bx_generic_cpuid_t::get_std_cpuid_leaf_7(Bit32u subfunction, cpuid_function void bx_generic_cpuid_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf) const { // CPUID function 0x0000000A - Architectural Performance Monitoring Leaf + + // EAX: + // [7:0] Version ID of architectural performance monitoring + // [15:8] Number of general-purpose performance monitoring counters per logical processor + // [23:16] Bit width of general-purpose, performance monitoring counter + // [31:24] Length of EBX bit vector to enumerate architectural performance + // monitoring events. + + // EBX: + // [0] Core cycle event not available if 1 + // [1] Instruction retired event not available if 1 + // [2] Reference cycles event not available if 1 + // [3] Last-level cache reference event not available if 1 + // [4] Last-level cache misses event not available if 1 + // [5] Branch instruction retired event not available if 1 + // [6] Branch mispredict retired event not available if 1 + // [31:7] reserved + + // ECX: reserved + + // EDX: + // [4:0] Number of fixed performance counters (if Version ID > 1) + // [12:5] Bit width of fixed-function performance counters (if Version ID > 1) + // [31:13] reserved + leaf->eax = 0; leaf->ebx = 0; leaf->ecx = 0; diff --git a/bochs/cpu/generic_cpuid.h b/bochs/cpu/generic_cpuid.h index f201cd96c..12779ca0d 100644 --- a/bochs/cpu/generic_cpuid.h +++ b/bochs/cpu/generic_cpuid.h @@ -26,7 +26,7 @@ #if BX_CPU_LEVEL >= 4 -#include "cpu/cpuid.h" +#include "cpuid.h" class bx_generic_cpuid_t : public bx_cpuid_t { public: