[prev in list] [next in list] [prev in thread] [next in thread] 

List:       bochs-cvs
Subject:    [Bochs-cvs] SF.net SVN: bochs:[10498] trunk/bochs/cpu
From:       sshwarts () users ! sourceforge ! net
Date:       2011-07-28 16:17:42
Message-ID: E1QmTHK-0000z3-IG () sfp-svn-5 ! v30 ! ch3 ! sourceforge ! com
[Download RAW message or body]

Revision: 10498
          http://bochs.svn.sourceforge.net/bochs/?rev=10498&view=rev
Author:   sshwarts
Date:     2011-07-28 16:17:42 +0000 (Thu, 28 Jul 2011)

Log Message:
-----------
First step toward completely configurable CPU.
Change CPUID to generic interface which could be chosen from .bochsrc.
Bochs CPU emulation will enable/disable features (like instruction sets) according to \
                CPUID that is selected.
TODO: Add database of CPUID from real hardware CPUs

Modified Paths:
--------------
    trunk/bochs/cpu/Makefile.in
    trunk/bochs/cpu/cpu.h
    trunk/bochs/cpu/cpuid.h
    trunk/bochs/cpu/init.cc
    trunk/bochs/cpu/msr.cc
    trunk/bochs/cpu/proc_ctrl.cc

Added Paths:
-----------
    trunk/bochs/cpu/generic_cpuid.cc

Removed Paths:
-------------
    trunk/bochs/cpu/cpuid.cc

Modified: trunk/bochs/cpu/Makefile.in
===================================================================
--- trunk/bochs/cpu/Makefile.in	2011-07-27 14:16:51 UTC (rev 10497)
+++ trunk/bochs/cpu/Makefile.in	2011-07-28 16:17:42 UTC (rev 10498)
@@ -89,7 +89,7 @@
 	data_xfer16.o \
 	data_xfer32.o \
 	exception.o \
-	cpuid.o \
+	generic_cpuid.o \
 	proc_ctrl.o \
 	crregs.o \
 	msr.o \
@@ -284,7 +284,7 @@
  icache.h apic.h ../cpu/i387.h ../fpu/softfloat.h ../fpu/tag_w.h \
  ../fpu/status_w.h ../fpu/control_w.h ../cpu/xmm.h vmx.h stack.h \
  ../iodev/iodev.h ../param_names.h
-cpuid.o: cpuid.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
+generic_cpuid.o: generic_cpuid.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h \
                ../bx_debug/debug.h \
  ../config.h ../osdep.h ../bxversion.h ../gui/siminterface.h \
  ../gui/paramtree.h ../memory/memory.h ../pc_system.h ../plugin.h \
  ../extplugin.h ../gui/gui.h ../instrument/stubs/instrument.h cpu.h \

Modified: trunk/bochs/cpu/cpu.h
===================================================================
--- trunk/bochs/cpu/cpu.h	2011-07-27 14:16:51 UTC (rev 10497)
+++ trunk/bochs/cpu/cpu.h	2011-07-28 16:17:42 UTC (rev 10498)
@@ -814,9 +814,9 @@
 
   unsigned bx_cpuid;
 
-  // cpuid
-  cpuid_function_t cpuid_std_function[MAX_STD_CPUID_FUNCTION];
-  cpuid_function_t cpuid_ext_function[MAX_EXT_CPUID_FUNCTION];
+#if BX_CPU_LEVEL >= 4
+  bx_cpuid_t *cpuid;
+#endif
 
   Bit32u isa_extensions_bitmask;
   Bit32u cpu_extensions_bitmask;
@@ -3449,28 +3449,14 @@
   BX_SMF void    iobreakpoint_match(unsigned port, unsigned len);
   BX_SMF Bit32u  code_breakpoint_match(bx_address laddr);
   BX_SMF void    hwbreakpoint_match(bx_address laddr, unsigned len, unsigned rw);
-  BX_SMF Bit32u  hwdebug_compare(bx_address laddr, unsigned len,
-                                 unsigned opa, unsigned opb);
+  BX_SMF Bit32u  hwdebug_compare(bx_address laddr, unsigned len, unsigned opa, \
unsigned opb);  #endif
 
-  BX_SMF Bit32u get_cpu_version_information(void);
-  BX_SMF Bit32u get_extended_cpuid_features(void);
-  BX_SMF Bit32u get_std_cpuid_features(void);
-  BX_SMF Bit32u get_std2_cpuid_features(void);
-  BX_SMF Bit32u get_ext2_cpuid_features(void);
-
-  BX_SMF void init_isa_features_bitmask(void);
-  BX_SMF void init_cpu_features_bitmask(void);
   BX_SMF void init_FetchDecodeTables(void);
-#if BX_CPU_LEVEL >= 4
-  BX_SMF void set_cpuid_defaults(void);
+
+#if BX_SUPPORT_APIC
+  BX_SMF BX_CPP_INLINE Bit8u get_apic_id(void) { return BX_CPU_THIS_PTR bx_cpuid; }
 #endif
-#if BX_CPU_LEVEL >= 6
-  BX_SMF void bx_cpuid_extended_topology_leaf(Bit32u subfunction);
-  BX_SMF void bx_cpuid_xsave_leaf(Bit32u subfunction);
-  BX_SMF void bx_cpuid_extended_cpuid_leaf(Bit32u subfunction);
-  BX_SMF Bit32u get_ext3_cpuid_features(void);
-#endif
 
   BX_SMF BX_CPP_INLINE int bx_cpuid_support_debug_extensions(void);
   BX_SMF BX_CPP_INLINE int bx_cpuid_support_1g_paging(void);
@@ -3916,18 +3902,18 @@
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_xsave(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].ecx & BX_CPUID_EXT_XSAVE);
+  return (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_XSAVE);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_x2apic(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].ecx & BX_CPUID_EXT_X2APIC);
+  return (BX_CPU_THIS_PTR cpu_extensions_bitmask & BX_CPU_X2APIC);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_pcid(void)
 {
 #if BX_SUPPORT_X86_64
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].ecx & BX_CPUID_EXT_PCID);
+  return (BX_CPU_THIS_PTR cpu_extensions_bitmask & BX_CPU_PCID);
 #else
   return 0;
 #endif
@@ -3936,7 +3922,7 @@
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_fsgsbase(void)
 {
 #if BX_SUPPORT_X86_64
-  return BX_CPU_THIS_PTR cpuid_std_function[7].ebx & BX_CPUID_EXT3_FSGSBASE;
+  return (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_FSGSBASE);
 #else
   return 0;
 #endif
@@ -3944,63 +3930,63 @@
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_smep(void)
 {
-  return BX_CPU_THIS_PTR cpuid_std_function[7].ebx & BX_CPUID_EXT3_SMEP;
+  return (BX_CPU_THIS_PTR cpu_extensions_bitmask & BX_CPU_SMEP);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_vme(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].edx & BX_CPUID_STD_VME);
+  return (BX_CPU_THIS_PTR cpu_extensions_bitmask & BX_CPU_VME);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_debug_extensions(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].edx & \
BX_CPUID_STD_DEBUG_EXTENSIONS); +  return (BX_CPU_THIS_PTR cpu_extensions_bitmask & \
BX_CPU_DEBUG_EXTENSIONS);  }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_pse(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].edx & BX_CPUID_STD_PSE);
+  return (BX_CPU_THIS_PTR cpu_extensions_bitmask & BX_CPU_PSE);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_pae(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].edx & BX_CPUID_STD_PAE);
+  return (BX_CPU_THIS_PTR cpu_extensions_bitmask & BX_CPU_PAE);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_pge(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].edx & BX_CPUID_STD_GLOBAL_PAGES);
+  return (BX_CPU_THIS_PTR cpu_extensions_bitmask & BX_CPU_PGE);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_pse36(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].edx & BX_CPUID_STD_PSE36);
+  return (BX_CPU_THIS_PTR cpu_extensions_bitmask & BX_CPU_PSE36);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_mmx(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].edx & BX_CPUID_STD_MMX);
+  return (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_MMX);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_sse(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].edx & BX_CPUID_STD_SSE);
+  return (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_SSE);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_sep(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].edx & \
BX_CPUID_STD_SYSENTER_SYSEXIT); +  return (BX_CPU_THIS_PTR isa_extensions_bitmask & \
BX_CPU_SYSENTER_SYSEXIT);  }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_fxsave_fxrstor(void)
 {
-  return (BX_CPU_THIS_PTR cpuid_std_function[1].edx & BX_CPUID_STD_FXSAVE_FXRSTOR);
+  return (BX_CPU_THIS_PTR isa_extensions_bitmask & BX_CPU_FXSAVE_FXRSTOR);
 }
 
 BX_CPP_INLINE int BX_CPU_C::bx_cpuid_support_1g_paging(void)
 {
 #if BX_SUPPORT_X86_64
-  return (BX_CPU_THIS_PTR cpuid_ext_function[1].edx & BX_CPUID_STD2_1G_PAGES);
+  return (BX_CPU_THIS_PTR cpu_extensions_bitmask & BX_CPU_1G_PAGES);
 #else
   return 0;
 #endif

Deleted: trunk/bochs/cpu/cpuid.cc
===================================================================
--- trunk/bochs/cpu/cpuid.cc	2011-07-27 14:16:51 UTC (rev 10497)
+++ trunk/bochs/cpu/cpuid.cc	2011-07-28 16:17:42 UTC (rev 10498)
@@ -1,1244 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// $Id$
-/////////////////////////////////////////////////////////////////////////
-//
-//   Copyright (c) 2007-2011 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
-//
-/////////////////////////////////////////////////////////////////////////
-
-#define NEED_CPU_REG_SHORTCUTS 1
-#include "bochs.h"
-#include "cpu.h"
-#define LOG_THIS BX_CPU_THIS_PTR
-
-#include "param_names.h"
-
-/*
- * Get CPU version information:
- *
- * [3:0]   Stepping ID
- * [7:4]   Model: starts at 1
- * [11:8]  Family: 4=486, 5=Pentium, 6=PPro, ...
- * [13:12] Type: 0=OEM, 1=overdrive, 2=dual cpu, 3=reserved
- * [19:16] Extended Model
- * [27:29] Extended Family
- */
-
-Bit32u BX_CPU_C::get_cpu_version_information(void)
-{
-#if BX_CPU_LEVEL >= 4
-  Bit32u stepping = SIM->get_param_num(BXPN_CPUID_STEPPING)->get();
-  Bit32u model = SIM->get_param_num(BXPN_CPUID_MODEL)->get();
-  Bit32u family = SIM->get_param_num(BXPN_CPUID_FAMILY)->get();
-
-  if (family < 6 && family != BX_CPU_LEVEL)
-    BX_PANIC(("PANIC: CPUID family %x not matching configured cpu level %d", family, \
                BX_CPU_LEVEL));
-
-  return ((family & 0xfff0) << 16) |
-         ((model & 0xf0) << 12) |
-         ((family & 0x0f) << 8) |
-         ((model & 0x0f) << 4) | stepping;
-#else
-  return 0; /* CPUID not supported */
-#endif
-}
-
-/* Get CPU extended feature flags. */
-Bit32u BX_CPU_C::get_extended_cpuid_features(void)
-{
-  // [0:0]   SSE3: SSE3 Instructions
-  // [1:1]   PCLMULQDQ Instruction support
-  // [2:2]   DTES64: 64-bit DS area
-  // [3:3]   MONITOR/MWAIT support
-  // [4:4]   DS-CPL: CPL qualified debug store
-  // [5:5]   VMX: Virtual Machine Technology
-  // [6:6]   SMX: Secure Virtual Machine Technology
-  // [7:7]   EST: Enhanced Intel SpeedStep Technology
-  // [8:8]   TM2: Thermal Monitor 2
-  // [9:9]   SSSE3: SSSE3 Instructions
-  // [10:10] CNXT-ID: L1 context ID
-  // [11:11] reserved
-  // [12:12] FMA Instructions support
-  // [13:13] CMPXCHG16B: CMPXCHG16B instruction support
-  // [14:14] xTPR update control
-  // [15:15] PDCM - Perfon and Debug Capability MSR
-  // [16:16] reserved
-  // [17:17] PCID: Process Context Identifiers
-  // [18:18] DCA - Direct Cache Access
-  // [19:19] SSE4.1 Instructions
-  // [20:20] SSE4.2 Instructions
-  // [21:21] X2APIC
-  // [22:22] MOVBE instruction
-  // [23:23] POPCNT instruction
-  // [24:24] TSC Deadline
-  // [25:25] AES Instructions
-  // [26:26] XSAVE extensions support
-  // [27:27] OSXSAVE support
-  // [28:28] AVX extensions support
-  // [29:29] AVX F16C - Float16 conversion support
-  // [30:30] RDRAND instruction
-  // [31:31] reserved
-
-  Bit32u features = 0;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE3))
-    features |= BX_CPUID_EXT_SSE3;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_AES_PCLMULQDQ))
-    features |= BX_CPUID_EXT_PCLMULQDQ;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_MONITOR_MWAIT))
-    features |= BX_CPUID_EXT_MONITOR_MWAIT;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_VMX))
-    features |= BX_CPUID_EXT_VMX;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSSE3))
-    features |= BX_CPUID_EXT_SSSE3;
-
-#if BX_SUPPORT_X86_64
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_X86_64))
-    features |= BX_CPUID_EXT_CMPXCHG16B;
-
-  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PCID))
-    features |= BX_CPUID_EXT_PCID;
-#endif
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE4_1))
-    features |= BX_CPUID_EXT_SSE4_1;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE4_2))
-    features |= BX_CPUID_EXT_SSE4_2;
-
-  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_X2APIC))
-    features |= BX_CPUID_EXT_X2APIC;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_MOVBE))
-    features |= BX_CPUID_EXT_MOVBE;
-
-  // enable POPCNT if SSE4_2 is enabled
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE4_2))
-    features |= BX_CPUID_EXT_POPCNT;
-
-  // support for AES
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_AES_PCLMULQDQ))
-    features |= BX_CPUID_EXT_AES;
-
-  // support XSAVE extensions
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE))
-    features |= BX_CPUID_EXT_XSAVE | BX_CPUID_EXT_OSXSAVE;
-
-#if BX_SUPPORT_AVX
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_AVX))
-    features |= BX_CPUID_EXT_AVX;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_AVX_F16C))
-    features |= BX_CPUID_EXT_AVX_F16C;
-#endif
-
-  return features;
-}
-
-#if BX_CPU_LEVEL >= 6
-Bit32u BX_CPU_C::get_ext3_cpuid_features(void)
-{
-  Bit32u features = 0;
-
-  //   [0:0]    FS/GS BASE access instructions
-  //   [2:1]    reserved
-  //   [3:3]    BMI1: Advanced Bit Manipulation Extensions
-  //   [4:4]    reserved
-  //   [5:5]    AVX2
-  //   [6:6]    reserved
-  //   [7:7]    SMEP: Supervisor Mode Execution Protection
-  //   [8:8]    BMI2: Advanced Bit Manipulation Extensions
-  //   [9:9]    Support for Enhanced REP MOVSB/STOSB
-  //   [10:10]  Support for INVPCID instruction
-  //   [31:10]  reserved
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_FSGSBASE))
-    features |= BX_CPUID_EXT3_FSGSBASE;
-
-  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_SMEP))
-    features |= BX_CPUID_EXT3_SMEP;
-
-  return features;
-}
-#endif
-
-/* Get CPU feature flags. Returned by CPUID functions 1 and 80000001.  */
-Bit32u BX_CPU_C::get_std_cpuid_features(void)
-{
-  //   [0:0]   FPU on chip
-  //   [1:1]   VME: Virtual-8086 Mode enhancements
-  //   [2:2]   DE: Debug Extensions (I/O breakpoints)
-  //   [3:3]   PSE: Page Size Extensions
-  //   [4:4]   TSC: Time Stamp Counter
-  //   [5:5]   MSR: RDMSR and WRMSR support
-  //   [6:6]   PAE: Physical Address Extensions
-  //   [7:7]   MCE: Machine Check Exception
-  //   [8:8]   CXS: CMPXCHG8B instruction
-  //   [9:9]   APIC: APIC on Chip
-  //   [10:10] Reserved
-  //   [11:11] SYSENTER/SYSEXIT support
-  //   [12:12] MTRR: Memory Type Range Reg
-  //   [13:13] PGE/PTE Global Bit
-  //   [14:14] MCA: Machine Check Architecture
-  //   [15:15] CMOV: Cond Mov/Cmp Instructions
-  //   [16:16] PAT: Page Attribute Table
-  //   [17:17] PSE-36: Physical Address Extensions
-  //   [18:18] PSN: Processor Serial Number
-  //   [19:19] CLFLUSH: CLFLUSH Instruction support
-  //   [20:20] Reserved
-  //   [21:21] DS: Debug Store
-  //   [22:22] ACPI: Thermal Monitor and Software Controlled Clock Facilities
-  //   [23:23] MMX Technology
-  //   [24:24] FXSR: FXSAVE/FXRSTOR (also indicates CR4.OSFXSR is available)
-  //   [25:25] SSE: SSE Extensions
-  //   [26:26] SSE2: SSE2 Extensions
-  //   [27:27] Self Snoop
-  //   [28:28] Hyper Threading Technology
-  //   [29:29] TM: Thermal Monitor
-  //   [30:30] Reserved
-  //   [31:31] PBE: Pending Break Enable
-
-  Bit32u features = 0;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_X87))
-    features |= BX_CPUID_STD_X87;
-
-#if BX_CPU_LEVEL >= 5
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_PENTIUM)) {
-    // Pentium only features
-    features |= BX_CPUID_STD_TSC;
-    features |= BX_CPUID_STD_MSR;
-    // support Machine Check
-    features |= BX_CPUID_STD_MCE | BX_CPUID_STD_MCA;
-    features |= BX_CPUID_STD_CMPXCHG8B;
-  }
-
-  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_VME))
-    features |= BX_CPUID_STD_VME;
-
-  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_DEBUG_EXTENSIONS))
-    features |= BX_CPUID_STD_DEBUG_EXTENSIONS;
-
-  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PSE))
-    features |= BX_CPUID_STD_PSE;
-#endif
-
-#if BX_SUPPORT_APIC
-  // if MSR_APICBASE APIC Global Enable bit has been cleared,
-  // the CPUID feature flag for the APIC is set to 0.
-  if (BX_CPU_THIS_PTR msr.apicbase & 0x800)
-    features |= BX_CPUID_STD_APIC; // APIC on chip
-#endif
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SYSENTER_SYSEXIT))
-    features |= BX_CPUID_STD_SYSENTER_SYSEXIT;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_CLFLUSH))
-    features |= BX_CPUID_STD_CLFLUSH;
-
-#if BX_CPU_LEVEL >= 5
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_MMX))
-    features |= BX_CPUID_STD_MMX;
-#endif
-
-#if BX_CPU_LEVEL >= 6
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_P6)) {
-    features |= BX_CPUID_STD_CMOV;
-    features |= BX_CPUID_STD_ACPI;
-  }
-
-  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PAT_MTRR))
-    features |= BX_CPUID_STD_PAT | BX_CPUID_STD_MTRR;
-
-  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PAE))
-    features |= BX_CPUID_STD_PAE;
-
-  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PGE))
-    features |= BX_CPUID_STD_GLOBAL_PAGES;
-
-  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PSE36))
-    features |= BX_CPUID_STD_PSE36;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_FXSAVE_FXRSTOR))
-    features |= BX_CPUID_STD_FXSAVE_FXRSTOR;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE))
-    features |= BX_CPUID_STD_SSE;
-
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE2))
-    features |= BX_CPUID_STD_SSE2;
-
-  if (BX_CPU_VENDOR_INTEL)
-    features |= BX_CPUID_STD_SELF_SNOOP;
-#endif
-
-#if BX_SUPPORT_SMP
-  // Intel(R) HyperThreading Technology
-  if (SIM->get_param_num(BXPN_CPU_NTHREADS)->get() > 1)
-    features |= BX_CPUID_STD_HT;
-#endif
-
-  return features;
-}
-
-/* Get CPU feature flags. Returned by CPUID function 80000001 in EDX register */
-Bit32u BX_CPU_C::get_std2_cpuid_features(void)
-{
-  // Many of the bits in EDX are the same as EAX [*] for AMD
-  // [*] [0:0]   FPU on chip
-  // [*] [1:1]   VME: Virtual-8086 Mode enhancements
-  // [*] [2:2]   DE: Debug Extensions (I/O breakpoints)
-  // [*] [3:3]   PSE: Page Size Extensions
-  // [*] [4:4]   TSC: Time Stamp Counter
-  // [*] [5:5]   MSR: RDMSR and WRMSR support
-  // [*] [6:6]   PAE: Physical Address Extensions
-  // [*] [7:7]   MCE: Machine Check Exception
-  // [*] [8:8]   CXS: CMPXCHG8B instruction
-  // [*] [9:9]   APIC: APIC on Chip
-  //     [10:10] Reserved
-  //     [11:11] SYSCALL/SYSRET support
-  // [*] [12:12] MTRR: Memory Type Range Reg
-  // [*] [13:13] PGE/PTE Global Bit
-  // [*] [14:14] MCA: Machine Check Architecture
-  // [*] [15:15] CMOV: Cond Mov/Cmp Instructions
-  // [*] [16:16] PAT: Page Attribute Table
-  // [*] [17:17] PSE-36: Physical Address Extensions
-  //     [18:19] Reserved
-  //     [20:20] No-Execute page protection
-  //     [21:21] Reserved
-  //     [22:22] AMD MMX Extensions
-  // [*] [23:23] MMX Technology
-  // [*] [24:24] FXSR: FXSAVE/FXRSTOR (also indicates CR4.OSFXSR is available)
-  //     [25:25] Fast FXSAVE/FXRSTOR mode support
-  //     [26:26] 1G paging support
-  //     [27:27] Support RDTSCP Instruction
-  //     [28:28] Reserved
-  //     [29:29] Long Mode
-  //     [30:30] AMD 3DNow! Extensions
-  //     [31:31] AMD 3DNow! Instructions
-  Bit32u features = BX_CPU_VENDOR_INTEL ? 0 : get_std_cpuid_features();
-  features &= 0x0183F3FF;
-#if BX_SUPPORT_3DNOW
-  // only AMD is interesting in AMD MMX extensions
-  features |= BX_CPUID_STD2_AMD_MMX_EXT | BX_CPUID_STD2_3DNOW_EXT | \
                BX_CPUID_STD2_3DNOW;
-#endif
-#if BX_SUPPORT_X86_64
-  features |= BX_CPUID_STD2_SYSCALL_SYSRET |
-              BX_CPUID_STD2_NX |
-              BX_CPUID_STD2_FFXSR |
-              BX_CPUID_STD2_RDTSCP | BX_CPUID_STD2_LONG_MODE;
-  static bx_bool xlarge_pages = SIM->get_param_bool(BXPN_CPUID_1G_PAGES)->get();
-  if (xlarge_pages)
-    features |= BX_CPUID_STD2_1G_PAGES;
-#endif
-
-  return features;
-}
-
-/* Get CPU feature flags. Returned by CPUID function 80000001 in ECX register */
-Bit32u BX_CPU_C::get_ext2_cpuid_features(void)
-{
-  // ECX:
-  //     [0:0]   LAHF/SAHF instructions support in 64-bit mode
-  //     [1:1]   CMP_Legacy: Core multi-processing legacy mode (AMD)
-  //     [2:2]   SVM: Secure Virtual Machine (AMD)
-  //     [3:3]   Extended APIC Space
-  //     [4:4]   AltMovCR8: LOCK MOV CR0 means MOV CR8
-  //     [5:5]   LZCNT: LZCNT instruction support
-  //     [6:6]   SSE4A: SSE4A Instructions support (deprecated?)
-  //     [7:7]   Misaligned SSE support
-  //     [8:8]   PREFETCHW: PREFETCHW instruction support
-  //     [9:9]   OSVW: OS visible workarounds (AMD)
-  //     [11:10] reserved
-  //     [12:12] SKINIT support
-  //     [13:13] WDT: Watchdog timer support
-  //     [31:14] reserved
-  Bit32u features = 0;
-
-#if BX_SUPPORT_X86_64
-  features |= BX_CPUID_EXT2_LAHF_SAHF;
-#endif
-#if BX_SUPPORT_MISALIGNED_SSE
-  features |= BX_CPUID_EXT2_MISALIGNED_SSE;
-#endif
-
-  return features;
-}
-
-BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CPUID(bxInstruction_c *i)
-{
-#if BX_CPU_LEVEL >= 4
-  Bit32u function = EAX;
-
-#if BX_SUPPORT_VMX
-  if (BX_CPU_THIS_PTR in_vmx_guest) {
-    BX_ERROR(("VMEXIT: CPUID in VMX non-root operation"));
-    VMexit(i, VMX_VMEXIT_CPUID, 0);
-  }
-#endif
-
-  unsigned max_std_function = BX_CPU_THIS_PTR cpuid_std_function[0].eax;
-  unsigned max_ext_function = BX_CPU_THIS_PTR cpuid_ext_function[0].eax;
-
-  if(function < 0x80000000) {
-    if(function <= max_std_function) {
-#if BX_CPU_LEVEL >= 6
-      Bit32u subfunction = ECX;
-
-      if (function == 0xb) {
-        bx_cpuid_extended_topology_leaf(subfunction);
-      }
-      else if (function == 0x7) {
-        bx_cpuid_extended_cpuid_leaf(subfunction);
-      }
-      else if (function == 0xd) {
-        bx_cpuid_xsave_leaf(subfunction);
-      }
-      else
-#endif
-      {
-        RAX = BX_CPU_THIS_PTR cpuid_std_function[function].eax;
-        RBX = BX_CPU_THIS_PTR cpuid_std_function[function].ebx;
-        RCX = BX_CPU_THIS_PTR cpuid_std_function[function].ecx;
-        RDX = BX_CPU_THIS_PTR cpuid_std_function[function].edx;
-      }
-
-      BX_NEXT_INSTR(i);
-    }
-  }
-  else {
-    if(function <= max_ext_function) {
-      function -= 0x80000000;
-      RAX = BX_CPU_THIS_PTR cpuid_ext_function[function].eax;
-      RBX = BX_CPU_THIS_PTR cpuid_ext_function[function].ebx;
-      RCX = BX_CPU_THIS_PTR cpuid_ext_function[function].ecx;
-      RDX = BX_CPU_THIS_PTR cpuid_ext_function[function].edx;
-
-      BX_NEXT_INSTR(i);
-    }
-  }
-
-  // unknown CPUID function - return maximum standard leaf
-  RAX = BX_CPU_THIS_PTR cpuid_std_function[max_std_function].eax;
-  RBX = BX_CPU_THIS_PTR cpuid_std_function[max_std_function].ebx;
-  RCX = BX_CPU_THIS_PTR cpuid_std_function[max_std_function].ecx;
-  RDX = BX_CPU_THIS_PTR cpuid_std_function[max_std_function].edx;
-#endif
-
-  BX_NEXT_INSTR(i);
-}
-
-#if BX_CPU_LEVEL >= 4
-void BX_CPU_C::set_cpuid_defaults(void)
-{
-  Bit8u *vendor_string = (Bit8u \
                *)SIM->get_param_string(BXPN_VENDOR_STRING)->getptr();
-  Bit8u *brand_string = (Bit8u *)SIM->get_param_string(BXPN_BRAND_STRING)->getptr();
-  bx_bool cpuid_limit_winnt = SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->get();
-
-  cpuid_function_t *cpuid;
-  int i;
-
-  for (i=0;i<MAX_STD_CPUID_FUNCTION;i++) {
-    BX_CPU_THIS_PTR cpuid_std_function[i].eax = 0;
-    BX_CPU_THIS_PTR cpuid_std_function[i].ebx = 0;
-    BX_CPU_THIS_PTR cpuid_std_function[i].ecx = 0;
-    BX_CPU_THIS_PTR cpuid_std_function[i].edx = 0;
-  }
-
-  for (i=0;i<MAX_EXT_CPUID_FUNCTION;i++) {
-    BX_CPU_THIS_PTR cpuid_ext_function[i].eax = 0;
-    BX_CPU_THIS_PTR cpuid_ext_function[i].ebx = 0;
-    BX_CPU_THIS_PTR cpuid_ext_function[i].ecx = 0;
-    BX_CPU_THIS_PTR cpuid_ext_function[i].edx = 0;
-  }
-
-  // ------------------------------------------------------
-  // CPUID function 0x00000000
-  cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[0]);
-
-  // EAX: highest input value understood by CPUID
-  // EBX: vendor ID string
-  // EDX: vendor ID string
-  // ECX: vendor ID string
-
-#if BX_CPU_LEVEL <= 5
-  // 486 and Pentium processors
-  cpuid->eax = 1;
-#else
-  // for Pentium Pro, Pentium II, Pentium 4 processors
-  cpuid->eax = 3;
-
-  // do not report CPUID functions above 0x3 if cpuid_limit_winnt is set
-  // to workaround WinNT issue.
-  if (! cpuid_limit_winnt) {
-    if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_MONITOR_MWAIT))
-      cpuid->eax = 0x5;
-    if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_X2APIC))
-      cpuid->eax = 0xb;
-    if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE))
-      cpuid->eax = 0xd;
-  }
-#endif
-
-  // CPUID vendor string (e.g. GenuineIntel, AuthenticAMD, CentaurHauls, ...)
-  memcpy(&(cpuid->ebx), vendor_string,     4);
-  memcpy(&(cpuid->edx), vendor_string + 4, 4);
-  memcpy(&(cpuid->ecx), vendor_string + 8, 4);
-#ifdef BX_BIG_ENDIAN
-  cpuid->ebx = bx_bswap32(cpuid->ebx);
-  cpuid->ecx = bx_bswap32(cpuid->ecx);
-  cpuid->edx = bx_bswap32(cpuid->edx);
-#endif
-
-  BX_INFO(("CPUID[0x00000000]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-  // ------------------------------------------------------
-  // CPUID function 0x00000001
-  cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[1]);
-
-  // EAX:       CPU Version Information
-  //   [3:0]   Stepping ID
-  //   [7:4]   Model: starts at 1
-  //   [11:8]  Family: 4=486, 5=Pentium, 6=PPro, ...
-  //   [13:12] Type: 0=OEM, 1=overdrive, 2=dual cpu, 3=reserved
-  //   [19:16] Extended Model
-  //   [27:20] Extended Family
-  cpuid->eax = get_cpu_version_information();
-
-  // EBX:
-  //   [7:0]   Brand ID
-  //   [15:8]  CLFLUSH cache line size (value*8 = cache line size in bytes)
-  //   [23:16] Number of logical processors in one physical processor
-  //   [31:24] Local Apic ID
-
-  cpuid->ebx = 0;
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_CLFLUSH)) {
-    cpuid->ebx |= (CACHE_LINE_SIZE / 8) << 8;
-  }
-  unsigned n_logical_processors = \
SIM->get_param_num(BXPN_CPU_NCORES)->get()*SIM->get_param_num(BXPN_CPU_NTHREADS)->get();
                
-  if (n_logical_processors > 1)
-    cpuid->ebx |= (n_logical_processors << 16);
-#if BX_SUPPORT_APIC
-  cpuid->ebx |= ((BX_CPU_THIS_PTR lapic.get_id() & 0xff) << 24);
-#endif
-
-  // ECX: Extended Feature Flags
-  cpuid->ecx = get_extended_cpuid_features();
-
-  // EDX: Standard Feature Flags
-  cpuid->edx = get_std_cpuid_features();
-
-  BX_INFO(("CPUID[0x00000001]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-#if BX_CPU_LEVEL >= 6
-  // ------------------------------------------------------
-  // CPUID function 0x00000002 - Cache and TLB Descriptors
-  cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[2]);
-
-#if BX_CPU_VENDOR_INTEL
-  cpuid->eax = 0x00410601;  // for Pentium Pro compatibility
-  cpuid->ebx = 0;
-  cpuid->ecx = 0;
-  cpuid->edx = 0;
-#else
-  cpuid->eax = 0;           // ignore for AMD
-  cpuid->ebx = 0;
-  cpuid->ecx = 0;
-  cpuid->edx = 0;
-#endif
-
-  BX_INFO(("CPUID[0x00000002]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-  // ------------------------------------------------------
-  // CPUID function 0x00000003 - Processor Serial Number
-  cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[3]);
-
-  cpuid->eax = 0;
-  cpuid->ebx = 0;
-  cpuid->ecx = 0;
-  cpuid->edx = 0;
-
-  BX_INFO(("CPUID[0x00000003]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-  // do not report CPUID functions above 0x3 if cpuid_limit_winnt is set
-  // to workaround WinNT issue.
-  if (cpuid_limit_winnt) return;
-
-  // ------------------------------------------------------
-  // CPUID function 0x00000004 - Deterministic Cache Parameters
-  cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[4]);
-
-  cpuid->eax = 0;
-  cpuid->ebx = 0;
-  cpuid->ecx = 0;
-  cpuid->edx = 0;
-
-  BX_INFO(("CPUID[0x00000004]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-#if BX_SUPPORT_MONITOR_MWAIT
-  // ------------------------------------------------------
-  // CPUID function 0x00000005
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_MONITOR_MWAIT))
-  {
-    cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[5]);
-
-    // EAX - Smallest monitor-line size in bytes
-    // EBX - Largest  monitor-line size in bytes
-    // ECX -
-    //   [31:2] - reserved
-    //    [1:1] - exit MWAIT even with EFLAGS.IF = 0
-    //    [0:0] - MONITOR/MWAIT extensions are supported
-    // EDX - Reserved
-    cpuid->eax = CACHE_LINE_SIZE;
-    cpuid->ebx = CACHE_LINE_SIZE;
-    cpuid->ecx = 3;
-    cpuid->edx = 0;
-
-    BX_INFO(("CPUID[0x00000005]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-  }
-#endif
-
-  // ------------------------------------------------------
-  // CPUID function 0x00000007
-  cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[7]);
-
-  cpuid->ebx = get_ext3_cpuid_features();
-  cpuid->ecx = 0;
-  cpuid->edx = 0;
-  if (cpuid->ebx)
-    cpuid->eax = 1; /* report max sub-leaves that are supported in leaf 7 */
-  else
-    cpuid->eax = 0; /* leaf 7 not supported */
-  
-  BX_INFO(("CPUID[0x00000007]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-  // ------------------------------------------------------
-  // CPUID function 0x0000000d
-  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE))
-  {
-    cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[0xd]);
-
-    // EAX - valid bits of XCR0 (lower part)
-    // EBX - Maximum size (in bytes) required by enabled features
-    // ECX - Maximum size (in bytes) required by CPU supported features
-    // EDX - valid bits of XCR0 (upper part)
-    cpuid->eax = BX_CPU_THIS_PTR xcr0_suppmask;
-    cpuid->ebx = 512+64;
-#if BX_SUPPORT_AVX
-    if (BX_CPU_THIS_PTR xcr0_suppmask & BX_XCR0_AVX_MASK)
-      cpuid->ebx += 256;
-#endif
-    cpuid->ecx = 512+64;
-#if BX_SUPPORT_AVX
-    if (BX_CPU_THIS_PTR xcr0_suppmask & BX_XCR0_AVX_MASK)
-      cpuid->ecx += 256;
-#endif
-    cpuid->edx = 0;
-
-    BX_INFO(("CPUID[0x0000000d]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-  }
-
-  // do not report Pentium 4 extended functions if not needed
-  if (! BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE2))
-    return;
-
-  // ------------------------------------------------------
-  // CPUID function 0x80000000
-  cpuid = &(BX_CPU_THIS_PTR cpuid_ext_function[0]);
-
-  // EAX: highest input value understood by CPUID
-  // EBX: vendor ID string
-  // EDX: vendor ID string
-  // ECX: vendor ID string
-  cpuid->eax = BX_SUPPORT_X86_64 ? 0x80000008 : 0x80000004;
-#if BX_CPU_VENDOR_INTEL
-  cpuid->ebx = 0;
-  cpuid->edx = 0;          // Reserved for Intel
-  cpuid->ecx = 0;
-#else
-  memcpy(&(cpuid->ebx), vendor_string,     4);
-  memcpy(&(cpuid->edx), vendor_string + 4, 4);
-  memcpy(&(cpuid->ecx), vendor_string + 8, 4);
-#endif
-
-#ifdef BX_BIG_ENDIAN
-  cpuid->ebx = bx_bswap32(cpuid->ebx);
-  cpuid->ecx = bx_bswap32(cpuid->ecx);
-  cpuid->edx = bx_bswap32(cpuid->edx);
-#endif
-
-  BX_INFO(("CPUID[0x80000000]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-  // ------------------------------------------------------
-  // CPUID function 0x80000001
-  cpuid = &(BX_CPU_THIS_PTR cpuid_ext_function[1]);
-
-  // EAX:       CPU Version Information
-  cpuid->eax = BX_CPU_VENDOR_INTEL ? 0 : get_cpu_version_information();
-
-  // EBX:       Brand ID
-  cpuid->ebx = 0;
-
-  // ECX:
-  cpuid->ecx = get_ext2_cpuid_features();
-
-  // EDX:
-  // Many of the bits in EDX are the same as EAX [*] for AMD
-  // [*] [0:0]   FPU on chip
-  // [*] [1:1]   VME: Virtual-8086 Mode enhancements
-  // [*] [2:2]   DE: Debug Extensions (I/O breakpoints)
-  // [*] [3:3]   PSE: Page Size Extensions
-  // [*] [4:4]   TSC: Time Stamp Counter
-  // [*] [5:5]   MSR: RDMSR and WRMSR support
-  // [*] [6:6]   PAE: Physical Address Extensions
-  // [*] [7:7]   MCE: Machine Check Exception
-  // [*] [8:8]   CXS: CMPXCHG8B instruction
-  // [*] [9:9]   APIC: APIC on Chip
-  //     [10:10] Reserved
-  //     [11:11] SYSCALL/SYSRET support
-  // [*] [12:12] MTRR: Memory Type Range Reg
-  // [*] [13:13] PGE/PTE Global Bit
-  // [*] [14:14] MCA: Machine Check Architecture
-  // [*] [15:15] CMOV: Cond Mov/Cmp Instructions
-  // [*] [16:16] PAT: Page Attribute Table
-  // [*] [17:17] PSE-36: Physical Address Extensions
-  //     [18:19] Reserved
-  //     [20:20] No-Execute page protection
-  //     [21:21] Reserved
-  //     [22:22] AMD MMX Extensions
-  // [*] [23:23] MMX Technology
-  // [*] [24:24] FXSR: FXSAVE/FXRSTOR (also indicates CR4.OSFXSR is available)
-  //     [25:25] Fast FXSAVE/FXRSTOR mode support
-  //     [26:26] 1G paging support
-  //     [27:27] Support RDTSCP Instruction
-  //     [28:28] Reserved
-  //     [29:29] Long Mode
-  //     [30:30] AMD 3DNow! Extensions
-  //     [31:31] AMD 3DNow! Instructions
-  cpuid->edx = get_std2_cpuid_features();
-
-  BX_INFO(("CPUID[0x80000001]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-  // Processor Brand String, use the value that is returned
-  // by the first processor in the Pentium 4 family
-  // (according to Intel manual or the AMD manual)
-
-  // ------------------------------------------------------
-  // CPUID function 0x80000002
-
-  cpuid = &(BX_CPU_THIS_PTR cpuid_ext_function[2]);
-  memcpy(&(cpuid->eax), brand_string     , 4);
-  memcpy(&(cpuid->ebx), brand_string +  4, 4);
-  memcpy(&(cpuid->ecx), brand_string +  8, 4);
-  memcpy(&(cpuid->edx), brand_string + 12, 4);
-#ifdef BX_BIG_ENDIAN
-  cpuid->eax = bx_bswap32(cpuid->eax);
-  cpuid->ebx = bx_bswap32(cpuid->ebx);
-  cpuid->ecx = bx_bswap32(cpuid->ecx);
-  cpuid->edx = bx_bswap32(cpuid->edx);
-#endif
-
-  BX_INFO(("CPUID[0x80000002]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-  // ------------------------------------------------------
-  // CPUID function 0x80000003
-
-  cpuid = &(BX_CPU_THIS_PTR cpuid_ext_function[3]);
-  memcpy(&(cpuid->eax), brand_string + 16, 4);
-  memcpy(&(cpuid->ebx), brand_string + 20, 4);
-  memcpy(&(cpuid->ecx), brand_string + 24, 4);
-  memcpy(&(cpuid->edx), brand_string + 28, 4);
-#ifdef BX_BIG_ENDIAN
-  cpuid->eax = bx_bswap32(cpuid->eax);
-  cpuid->ebx = bx_bswap32(cpuid->ebx);
-  cpuid->ecx = bx_bswap32(cpuid->ecx);
-  cpuid->edx = bx_bswap32(cpuid->edx);
-#endif
-
-  BX_INFO(("CPUID[0x80000003]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-  // ------------------------------------------------------
-  // CPUID function 0x80000004
-
-  cpuid = &(BX_CPU_THIS_PTR cpuid_ext_function[4]);
-  memcpy(&(cpuid->eax), brand_string + 32, 4);
-  memcpy(&(cpuid->ebx), brand_string + 36, 4);
-  memcpy(&(cpuid->ecx), brand_string + 40, 4);
-  memcpy(&(cpuid->edx), brand_string + 44, 4);
-#ifdef BX_BIG_ENDIAN
-  cpuid->eax = bx_bswap32(cpuid->eax);
-  cpuid->ebx = bx_bswap32(cpuid->ebx);
-  cpuid->ecx = bx_bswap32(cpuid->ecx);
-  cpuid->edx = bx_bswap32(cpuid->edx);
-#endif
-
-  BX_INFO(("CPUID[0x80000004]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-#if BX_SUPPORT_X86_64
-  // ------------------------------------------------------
-  // CPUID function 0x80000005
-
-#if BX_CPU_VENDOR_INTEL == 0
-  cpuid = &(BX_CPU_THIS_PTR cpuid_ext_function[5]);
-
-  /* cache info (L1 cache) */
-  cpuid->eax = 0x01ff01ff;
-  cpuid->ebx = 0x01ff01ff;
-  cpuid->ecx = 0x40020140;
-  cpuid->edx = 0x40020140;
-
-  BX_INFO(("CPUID[0x80000005]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-#endif
-
-  // ------------------------------------------------------
-  // CPUID function 0x80000006
-  cpuid = &(BX_CPU_THIS_PTR cpuid_ext_function[6]);
-
-  /* cache info (L2 cache) */
-  cpuid->eax = 0;
-  cpuid->ebx = 0x42004200;
-  cpuid->ecx = 0x02008140;
-  cpuid->edx = 0;
-
-  BX_INFO(("CPUID[0x80000006]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-  // ------------------------------------------------------
-  // CPUID function 0x80000007
-  cpuid = &(BX_CPU_THIS_PTR cpuid_ext_function[7]);
-
-  cpuid->eax = 0;
-  cpuid->ebx = 0;
-  cpuid->ecx = 0;
-  cpuid->edx = 0;
-
-  BX_INFO(("CPUID[0x80000007]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-  // ------------------------------------------------------
-  // CPUID function 0x80000008
-  cpuid = &(BX_CPU_THIS_PTR cpuid_ext_function[8]);
-
-  // virtual & phys address size in low 2 bytes.
-  cpuid->eax = BX_PHY_ADDRESS_WIDTH | (BX_LIN_ADDRESS_WIDTH << 8);
-  cpuid->ebx = 0;
-  cpuid->ecx = 0; // Reserved, undefined
-  cpuid->edx = 0;
-
-  BX_INFO(("CPUID[0x80000008]: %08x %08x %08x %08x", cpuid->eax, cpuid->ebx, \
                cpuid->ecx, cpuid->edx));
-
-#endif // BX_SUPPORT_X86_64
-
-#endif // BX_CPU_LEVEL >= 6
-}
-
-#if BX_CPU_LEVEL >= 6
-
-BX_CPP_INLINE static Bit32u ilog2(Bit32u x)
-{
-  Bit32u count = 0;
-  while(x>>=1) count++;
-  return count;
-}
-
-void BX_CPU_C::bx_cpuid_extended_topology_leaf(Bit32u subfunction)
-{
-  if (! bx_cpuid_support_x2apic()) {
-    RAX = 0;
-    RBX = 0;
-    RCX = 0;
-    RDX = 0;
-    return;
-  }
-
-  static int nthreads = SIM->get_param_num(BXPN_CPU_NTHREADS)->get();
-  static int ncores = SIM->get_param_num(BXPN_CPU_NCORES)->get();
-  static int nprocessors = SIM->get_param_num(BXPN_CPU_NPROCESSORS)->get();
-
-  RCX = subfunction;
-  RDX = BX_CPU_THIS_PTR lapic.get_id(); // x2apic ID
-
-  switch(subfunction) {
-  case 0:
-     if (nthreads > 1) {
-        RAX = ilog2(nthreads-1)+1;
-        RBX = nthreads;
-        RCX |= (1<<8);
-     }
-     else if (ncores > 1) {
-        RAX = ilog2(ncores-1)+1;
-        RBX = ncores;
-        RCX |= (2<<8);
-     }
-     else if (nprocessors > 1) {
-        RAX = ilog2(nprocessors-1)+1;
-        RBX = nprocessors;
-     }
-     else {
-        RAX = 0;
-        RBX = 0;
-     }
-     break;
-
-  case 1:
-     if (nthreads > 1) {
-        if (ncores > 1) {
-           RAX = ilog2(ncores-1)+1;
-           RBX = ncores;
-           RCX |= (2<<8);
-        }
-        else if (nprocessors > 1) {
-           RAX = ilog2(nprocessors-1)+1;
-           RBX = nprocessors;
-        }
-        else {
-           RAX = 0;
-           RBX = 0;
-        }
-     }
-     else if (ncores > 1) {
-        if (nprocessors > 1) {
-           RAX = ilog2(nprocessors-1)+1;
-           RBX = nprocessors;
-        }
-        else {
-           RAX = 0;
-           RBX = 0;
-        }
-     } else {
-        RAX = 0;
-        RBX = 0;
-     }
-     break;
-
-  case 2:
-     if (nthreads > 1) {
-        if (nprocessors > 1) {
-           RAX = ilog2(nprocessors-1)+1;
-           RBX = nprocessors;
-        }
-        else {
-           RAX = 0;
-           RBX = 0;
-        }
-     }
-     else {
-        RAX = 0;
-        RBX = 0;
-     }
-     break;
-
-   default:
-     RAX = 0;
-     RBX = 0;
-     break;
-   }
-}
-
-void BX_CPU_C::bx_cpuid_extended_cpuid_leaf(Bit32u subfunction)
-{
-  if (subfunction == 0) {
-    RAX = BX_CPU_THIS_PTR cpuid_std_function[0x7].eax;
-    RBX = BX_CPU_THIS_PTR cpuid_std_function[0x7].ebx;
-    RCX = BX_CPU_THIS_PTR cpuid_std_function[0x7].ecx;
-    RDX = BX_CPU_THIS_PTR cpuid_std_function[0x7].edx;
-  }
-  else {
-    RAX = 0; // reserved
-    RBX = 0; // reserved
-    RCX = 0; // reserved
-    RDX = 0; // reserved
-  }
-}
-
-void BX_CPU_C::bx_cpuid_xsave_leaf(Bit32u subfunction)
-{
-  BX_ASSERT(BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE));
-
-  switch(subfunction) {
-  case 0:
-    RAX = BX_CPU_THIS_PTR cpuid_std_function[0xd].eax;
-    RBX = BX_CPU_THIS_PTR cpuid_std_function[0xd].ebx;
-    RCX = BX_CPU_THIS_PTR cpuid_std_function[0xd].ecx;
-    RDX = BX_CPU_THIS_PTR cpuid_std_function[0xd].edx;
-    break;
-
-  case 1:
-    RAX = BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVEOPT);
-    RBX = 0;
-    RCX = 0;
-    RDX = 0;
-    break;
-
-#if BX_SUPPORT_AVX
-  case 2: // AVX leaf
-    if (BX_CPU_THIS_PTR xcr0_suppmask & BX_XCR0_AVX_MASK) {
-      RAX = 256;
-      RBX = 576;
-      RCX = 0;
-      RDX = 0;
-      break;
-    }
-    // else fall through
-#endif
-
-  default:
-    RAX = 0; // reserved
-    RBX = 0; // reserved
-    RCX = 0; // reserved
-    RDX = 0; // reserved
-    break;
-  }
-}
-#endif
-
-#endif
-
-void BX_CPU_C::init_isa_features_bitmask(void)
-{
-  Bit32u features_bitmask = 0;
-
-#if BX_SUPPORT_FPU
-  features_bitmask |= BX_CPU_X87;
-#endif
-
-#if BX_CPU_LEVEL >= 4
-  features_bitmask |= BX_CPU_486;
-
-#if BX_CPU_LEVEL >= 5
-  features_bitmask |= BX_CPU_PENTIUM;
-
-  static bx_bool mmx_enabled = SIM->get_param_bool(BXPN_CPUID_MMX)->get();
-  if (mmx_enabled)
-    features_bitmask |= BX_CPU_MMX;
-
-#if BX_SUPPORT_3DNOW
-  features_bitmask |= BX_CPU_3DNOW;
-
-  if (! mmx_enabled) {
-    BX_PANIC(("PANIC: 3DNOW emulation requires MMX support !"));
-    return;
-  }
-#endif
-
-#if BX_CPU_LEVEL >= 6
-  features_bitmask |= BX_CPU_P6;
-
-#if BX_SUPPORT_MONITOR_MWAIT
-  static bx_bool mwait_enabled = SIM->get_param_bool(BXPN_CPUID_MWAIT)->get();
-  if (mwait_enabled)
-    features_bitmask |= BX_CPU_MONITOR_MWAIT;
-#endif
-
-  // FXSAVE/FXRSTOR support come with Pentium II
-  if (mmx_enabled)
-    features_bitmask |= BX_CPU_FXSAVE_FXRSTOR;
-
-  static unsigned sse_enabled = SIM->get_param_enum(BXPN_CPUID_SSE)->get();
-  // determine SSE in runtime
-  switch (sse_enabled) {
-    case BX_CPUID_SUPPORT_SSE4_2:
-      features_bitmask |= BX_CPU_SSE4_2;
-    case BX_CPUID_SUPPORT_SSE4_1:
-      features_bitmask |= BX_CPU_SSE4_1;
-    case BX_CPUID_SUPPORT_SSSE3:
-      features_bitmask |= BX_CPU_SSSE3;
-    case BX_CPUID_SUPPORT_SSE3:
-      features_bitmask |= BX_CPU_SSE3;
-    case BX_CPUID_SUPPORT_SSE2:
-      features_bitmask |= BX_CPU_SSE2;
-    case BX_CPUID_SUPPORT_SSE:
-      features_bitmask |= BX_CPU_SSE;
-    case BX_CPUID_SUPPORT_NOSSE:
-    default:
-      break;
-  };
-
-  if (sse_enabled) {
-     if (mmx_enabled == 0 || BX_CPU_LEVEL < 6) {
-       BX_PANIC(("PANIC: SSE support requires P6 emulation with MMX enabled !"));
-       return;
-     }
-  }
-
-  // enabled CLFLUSH only when SSE2 or higher is enabled
-  if (sse_enabled >= BX_CPUID_SUPPORT_SSE2)
-    features_bitmask |= BX_CPU_CLFLUSH;
-
-  static bx_bool sep_enabled = SIM->get_param_bool(BXPN_CPUID_SEP)->get();
-  if (sep_enabled)
-    features_bitmask |= BX_CPU_SYSENTER_SYSEXIT;
-
-  static bx_bool xsave_enabled = SIM->get_param_bool(BXPN_CPUID_XSAVE)->get();
-  if (xsave_enabled) {
-    features_bitmask |= BX_CPU_XSAVE;
-
-    if (! sse_enabled) {
-       BX_PANIC(("PANIC: XSAVE emulation requires SSE support !"));
-       return;
-    }
-  }
-
-  static bx_bool xsaveopt_enabled = SIM->get_param_bool(BXPN_CPUID_XSAVEOPT)->get();
-  if (xsaveopt_enabled) {
-    features_bitmask |= BX_CPU_XSAVEOPT;
-
-    if (! xsave_enabled) {
-      BX_PANIC(("PANIC: XSAVEOPT emulation requires XSAVE !"));
-      return;
-    }
-  }
-
-  static bx_bool aes_enabled = SIM->get_param_bool(BXPN_CPUID_AES)->get();
-  if (aes_enabled) {
-    features_bitmask |= BX_CPU_AES_PCLMULQDQ;
-
-     // AES required 3-byte opcode (SSS3E support or more)
-     if (sse_enabled < BX_CPUID_SUPPORT_SSSE3) {
-       BX_PANIC(("PANIC: AES support requires SSSE3 or higher !"));
-       return;
-     }
-  }
-
-  static bx_bool movbe_enabled = SIM->get_param_bool(BXPN_CPUID_MOVBE)->get();
-  if (movbe_enabled) {
-    features_bitmask |= BX_CPU_MOVBE;
-
-    // MOVBE required 3-byte opcode (SSS3E support or more)
-    if (sse_enabled < BX_CPUID_SUPPORT_SSSE3) {
-      BX_PANIC(("PANIC: MOVBE support requires SSSE3 or higher !"));
-      return;
-    }
-  }
-
-#if BX_SUPPORT_AVX
-  static bx_bool avx_enabled = SIM->get_param_bool(BXPN_CPUID_AVX)->get();
-  if (avx_enabled) {
-    features_bitmask |= BX_CPU_AVX;
-
-    if (! xsave_enabled) {
-      BX_PANIC(("PANIC: AVX emulation requires XSAVE support !"));
-      return;
-    }
-  }
-
-  static bx_bool avx_f16c_enabled = \
                SIM->get_param_bool(BXPN_CPUID_AVX_F16CVT)->get();
-  if (avx_f16c_enabled) {
-    if (! avx_enabled) {
-      BX_PANIC(("PANIC: Float16 convert emulation requires AVX support !"));
-      return;
-    }
-
-    features_bitmask |= BX_CPU_AVX_F16C;
-  }
-#endif
-
-#if BX_SUPPORT_VMX
-  features_bitmask |= BX_CPU_VMX;
-
-  if (! sep_enabled) {
-    BX_PANIC(("PANIC: VMX emulation requires SYSENTER/SYSEXIT support !"));
-    return;
-  }
-#endif
-
-#if BX_SUPPORT_X86_64
-  features_bitmask |= BX_CPU_X86_64;
-
-  if (sse_enabled < BX_CPUID_SUPPORT_SSE2) {
-    BX_PANIC(("PANIC: x86-64 emulation requires SSE2 support !"));
-    return;
-  }
-
-  if (! sep_enabled) {
-    BX_PANIC(("PANIC: x86-64 emulation requires SYSENTER/SYSEXIT support !"));
-    return;
-  }
-
-  static bx_bool fsgsbase_enabled = SIM->get_param_bool(BXPN_CPUID_FSGSBASE)->get();
-  if (fsgsbase_enabled)
-    features_bitmask |= BX_CPU_FSGSBASE;
-
-  static unsigned apic_enabled = SIM->get_param_enum(BXPN_CPUID_APIC)->get();
-  if (apic_enabled < BX_CPUID_SUPPORT_XAPIC) {
-    BX_PANIC(("PANIC: x86-64 emulation requires XAPIC support !"));
-    return;
-  }
-#endif
-
-#endif // CPU_LEVEL >= 6
-
-#endif // CPU_LEVEL >= 5
-
-#endif // CPU_LEVEL >= 4
-
-  BX_CPU_THIS_PTR isa_extensions_bitmask = features_bitmask;
-}
-
-void BX_CPU_C::init_cpu_features_bitmask(void)
-{
-  Bit32u features_bitmask = 0;
-
-#if BX_SUPPORT_APIC
-  static unsigned apic_enabled = SIM->get_param_enum(BXPN_CPUID_APIC)->get();
-  // determine SSE in runtime
-  switch (apic_enabled) {
-    case BX_CPUID_SUPPORT_X2APIC:
-      features_bitmask |= BX_CPU_X2APIC;
-    case BX_CPUID_SUPPORT_XAPIC:
-      features_bitmask |= BX_CPU_XAPIC;
-    case BX_CPUID_SUPPORT_LEGACY_APIC:
-    default:
-      break;
-  };
-
-  // I would like to allow XAPIC configuration with i586 together
-  if (apic_enabled >= BX_CPUID_SUPPORT_X2APIC && BX_CPU_LEVEL < 6) {
-    BX_PANIC(("PANIC: X2APIC require CPU_LEVEL >= 6 !"));
-    return;
-  }
-#endif
-
-#if BX_CPU_LEVEL >= 5
-  features_bitmask |= BX_CPU_VME;
-  features_bitmask |= BX_CPU_DEBUG_EXTENSIONS;
-  features_bitmask |= BX_CPU_PSE;
-
-#if BX_CPU_LEVEL >= 6
-  features_bitmask |= BX_CPU_PAE;
-  features_bitmask |= BX_CPU_PGE;
-  features_bitmask |= BX_CPU_PSE36;
-  features_bitmask |= BX_CPU_PAT_MTRR;
-
-  static bx_bool smep_enabled = SIM->get_param_bool(BXPN_CPUID_SMEP)->get();
-  if (smep_enabled)
-    features_bitmask |= BX_CPU_SMEP;
-
-#if BX_SUPPORT_X86_64
-  static bx_bool pcid_enabled = SIM->get_param_bool(BXPN_CPUID_PCID)->get();
-  if (pcid_enabled)
-    features_bitmask |= BX_CPU_PCID;
-#endif
-
-#endif // CPU_LEVEL >= 6
-
-#endif // CPU_LEVEL >= 5
-
-  BX_CPU_THIS_PTR cpu_extensions_bitmask = features_bitmask;
-}

Modified: trunk/bochs/cpu/cpuid.h
===================================================================
--- trunk/bochs/cpu/cpuid.h	2011-07-27 14:16:51 UTC (rev 10497)
+++ trunk/bochs/cpu/cpuid.h	2011-07-28 16:17:42 UTC (rev 10498)
@@ -31,6 +31,25 @@
   Bit32u edx;
 };
 
+class bx_cpuid_t {
+public:
+  bx_cpuid_t(BX_CPU_C *_cpu): cpu(_cpu) {}
+  virtual ~bx_cpuid_t() {}
+
+  // return CPU name
+  virtual const char *get_name(void) const { return NULL; }
+
+  virtual Bit32u get_isa_extensions_bitmask(void) const = 0;
+  virtual Bit32u get_cpu_extensions_bitmask(void) const = 0;
+
+  virtual void get_cpuid_leaf(Bit32u function, Bit32u subfunction, cpuid_function_t \
*leaf) {} +
+  virtual void dump_cpuid(void) = 0;
+
+protected:
+  BX_CPU_C *cpu;
+};
+
 // cpuid ISA (duplicated in disasm.h)
 #define BX_CPU_X87              (1 << 0)        /* FPU (X87) instruction */
 #define BX_CPU_486              (1 << 1)        /* 486 new instruction */

Copied: trunk/bochs/cpu/generic_cpuid.cc (from rev 10497, trunk/bochs/cpu/cpuid.cc)
===================================================================
--- trunk/bochs/cpu/generic_cpuid.cc	                        (rev 0)
+++ trunk/bochs/cpu/generic_cpuid.cc	2011-07-28 16:17:42 UTC (rev 10498)
@@ -0,0 +1,1224 @@
+/////////////////////////////////////////////////////////////////////////
+// $Id$
+/////////////////////////////////////////////////////////////////////////
+//
+//   Copyright (c) 2011 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 "generic_cpuid.h"
+
+#define LOG_THIS cpu->
+
+bx_generic_cpuid_t::bx_generic_cpuid_t(BX_CPU_C *cpu): bx_cpuid_t(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();
+#endif
+
+  init_isa_extensions_bitmask();
+  init_cpu_extensions_bitmask();
+}
+
+void bx_generic_cpuid_t::get_cpuid_leaf(Bit32u function, Bit32u subfunction, \
cpuid_function_t *leaf) +{
+  static bx_bool cpuid_limit_winnt = \
SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->get(); +  if (function > 3 && \
cpuid_limit_winnt) +    function = 3;
+
+  switch(function) {
+#if BX_CPU_LEVEL >= 6
+  case 0x80000000:
+    get_ext_cpuid_leaf_0(leaf);
+    return;
+  case 0x80000001:
+    get_ext_cpuid_leaf_1(leaf);
+    return;
+  case 0x80000002:
+  case 0x80000003:
+  case 0x80000004:
+    get_ext_cpuid_brand_string_leaf(function, leaf);
+    return;
+#if BX_SUPPORT_X86_64
+  case 0x80000005:
+    get_ext_cpuid_leaf_5(leaf);
+    return;
+  case 0x80000006:
+    get_ext_cpuid_leaf_6(leaf);
+    return;
+  case 0x80000007:
+    get_ext_cpuid_leaf_7(leaf);
+    return;
+  case 0x80000008:
+    get_ext_cpuid_leaf_8(leaf);
+    return;
+#endif
+#endif
+  case 0x00000000:
+    get_std_cpuid_leaf_0(leaf);
+    return;
+  case 0x00000001:
+    get_std_cpuid_leaf_1(leaf);
+    return;
+#if BX_CPU_LEVEL >= 6
+  case 0x00000002:
+    get_std_cpuid_leaf_2(leaf);
+    return;
+  case 0x00000003:
+    get_std_cpuid_leaf_3(leaf);
+    return;
+  case 0x00000004:
+    get_std_cpuid_leaf_4(subfunction, leaf);
+    return;
+  case 0x00000005:
+    get_std_cpuid_leaf_5(leaf);
+    return;
+  case 0x00000006:
+    get_std_cpuid_leaf_6(leaf);
+    return;
+  case 0x00000007:
+    get_std_cpuid_leaf_7(subfunction, leaf);
+    return;
+  case 0x00000008:
+    get_std_cpuid_leaf_8(leaf);
+    return;
+  case 0x00000009:
+    get_std_cpuid_leaf_9(leaf);
+    return;
+  case 0x0000000A:
+    get_std_cpuid_leaf_A(leaf);
+    return;
+  case 0x0000000B:
+    get_std_cpuid_extended_topology_leaf(subfunction, leaf);
+    return;
+  case 0x0000000C:
+    get_std_cpuid_leaf_C(leaf);
+    return;
+  case 0x0000000D:
+  default:
+    get_std_cpuid_xsave_leaf(subfunction, leaf);
+    return;
+#endif
+  }
+}
+
+// leaf 0x00000000 //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_0(cpuid_function_t *leaf)
+{
+  static Bit8u *vendor_string = (Bit8u \
*)SIM->get_param_string(BXPN_VENDOR_STRING)->getptr(); +
+  // EAX: highest input value understood by CPUID
+  // EBX: vendor ID string
+  // EDX: vendor ID string
+  // ECX: vendor ID string
+
+#if BX_CPU_LEVEL <= 5
+  // 486 and Pentium processors
+  leaf->eax = 1;
+#else
+  // for Pentium Pro, Pentium II, Pentium 4 processors
+  leaf->eax = 3;
+
+  // do not report CPUID functions above 0x3 if cpuid_limit_winnt is set
+  // to workaround WinNT issue.
+  static bx_bool cpuid_limit_winnt = \
SIM->get_param_bool(BXPN_CPUID_LIMIT_WINNT)->get(); +  if (! cpuid_limit_winnt) {
+    if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_MONITOR_MWAIT))
+      leaf->eax = 0x5;
+    if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_X2APIC))
+      leaf->eax = 0xb;
+    if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE))
+      leaf->eax = 0xd;
+  }
+#endif
+
+  // CPUID vendor string (e.g. GenuineIntel, AuthenticAMD, CentaurHauls, ...)
+  memcpy(&(leaf->ebx), vendor_string,     4);
+  memcpy(&(leaf->edx), vendor_string + 4, 4);
+  memcpy(&(leaf->ecx), vendor_string + 8, 4);
+#ifdef BX_BIG_ENDIAN
+  leaf->ebx = bx_bswap32(leaf->ebx);
+  leaf->ecx = bx_bswap32(leaf->ecx);
+  leaf->edx = bx_bswap32(leaf->edx);
+#endif
+}
+
+// leaf 0x00000001 //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_1(cpuid_function_t *leaf)
+{
+  // EAX:       CPU Version Information
+  //   [3:0]   Stepping ID
+  //   [7:4]   Model: starts at 1
+  //   [11:8]  Family: 4=486, 5=Pentium, 6=PPro, ...
+  //   [13:12] Type: 0=OEM, 1=overdrive, 2=dual cpu, 3=reserved
+  //   [19:16] Extended Model
+  //   [27:20] Extended Family
+  leaf->eax = get_cpu_version_information();
+
+  // EBX:
+  //   [7:0]   Brand ID
+  //   [15:8]  CLFLUSH cache line size (value*8 = cache line size in bytes)
+  //   [23:16] Number of logical processors in one physical processor
+  //   [31:24] Local Apic ID
+  leaf->ebx = 0;
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_CLFLUSH)) {
+    leaf->ebx |= (CACHE_LINE_SIZE / 8) << 8;
+  }
+#if BX_SUPPORT_SMP
+  unsigned n_logical_processors = ncores*nthreads;
+  if (n_logical_processors > 1)
+    leaf->ebx |= (n_logical_processors << 16);
+#endif
+#if BX_SUPPORT_APIC
+  leaf->ebx |= ((cpu->get_apic_id() & 0xff) << 24);
+#endif
+
+  // ECX: Extended Feature Flags
+  leaf->ecx = get_extended_cpuid_features();
+
+  // EDX: Standard Feature Flags
+  leaf->edx = get_std_cpuid_features();
+}
+
+// leaf 0x00000002 //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_2(cpuid_function_t *leaf)
+{
+  // CPUID function 0x00000002 - Cache and TLB Descriptors
+#if BX_CPU_VENDOR_INTEL
+  leaf->eax = 0x00410601;  // for Pentium Pro compatibility
+  leaf->ebx = 0;
+  leaf->ecx = 0;
+  leaf->edx = 0;
+#else
+  leaf->eax = 0;           // ignore for AMD
+  leaf->ebx = 0;
+  leaf->ecx = 0;
+  leaf->edx = 0;
+#endif
+}
+
+// leaf 0x00000003 //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_3(cpuid_function_t *leaf)
+{
+  // CPUID function 0x00000003 - Processor Serial Number
+  leaf->eax = 0;
+  leaf->ebx = 0;
+  leaf->ecx = 0;
+  leaf->edx = 0;
+}
+
+// leaf 0x00000004 //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_4(Bit32u subfunction, cpuid_function_t \
*leaf) +{
+  // CPUID function 0x00000004 - Deterministic Cache Parameters
+  leaf->eax = 0;
+  leaf->ebx = 0;
+  leaf->ecx = 0;
+  leaf->edx = 0;
+}
+
+// leaf 0x00000005 //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_5(cpuid_function_t *leaf)
+{
+  // CPUID function 0x00000005 - MONITOR/MWAIT Leaf
+#if BX_SUPPORT_MONITOR_MWAIT
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_MONITOR_MWAIT))
+  {
+    // EAX - Smallest monitor-line size in bytes
+    // EBX - Largest  monitor-line size in bytes
+    // ECX -
+    //   [31:2] - reserved
+    //    [1:1] - exit MWAIT even with EFLAGS.IF = 0
+    //    [0:0] - MONITOR/MWAIT extensions are supported
+    // EDX - Reserved
+    leaf->eax = CACHE_LINE_SIZE;
+    leaf->ebx = CACHE_LINE_SIZE;
+    leaf->ecx = 3;
+    leaf->edx = 0;
+  }
+  else
+#endif
+  {
+    leaf->eax = 0;
+    leaf->ebx = 0;
+    leaf->ecx = 0;
+    leaf->edx = 0;
+  }
+}
+
+// leaf 0x00000006 //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_6(cpuid_function_t *leaf)
+{
+  // CPUID function 0x00000006 - Thermal and Power Management Leaf
+  leaf->eax = 0;
+  leaf->ebx = 0;
+  leaf->ecx = 0;
+  leaf->edx = 0;
+}
+
+// leaf 0x00000007 //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_7(Bit32u subfunction, cpuid_function_t \
*leaf) +{
+  leaf->ebx = get_ext3_cpuid_features();
+  leaf->ecx = 0;
+  leaf->edx = 0;
+  if (leaf->ebx)
+    leaf->eax = 1; /* report max sub-leaves that are supported in leaf 7 */
+  else
+    leaf->eax = 0; /* leaf 7 not supported */
+}
+
+// leaf 0x00000008 //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_8(cpuid_function_t *leaf)
+{
+  // CPUID function 0x00000008 - reserved
+  leaf->eax = 0;
+  leaf->ebx = 0;
+  leaf->ecx = 0;
+  leaf->edx = 0;
+}
+
+// leaf 0x00000009 //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_9(cpuid_function_t *leaf)
+{
+  // CPUID function 0x00000009 - Direct Cache Access Information Leaf
+  leaf->eax = 0;
+  leaf->ebx = 0;
+  leaf->ecx = 0;
+  leaf->edx = 0;
+}
+
+// leaf 0x0000000A //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_A(cpuid_function_t *leaf)
+{
+  // CPUID function 0x0000000A - Architectural Performance Monitoring Leaf
+  leaf->eax = 0;
+  leaf->ebx = 0;
+  leaf->ecx = 0;
+  leaf->edx = 0;
+}
+
+BX_CPP_INLINE static Bit32u ilog2(Bit32u x)
+{
+  Bit32u count = 0;
+  while(x>>=1) count++;
+  return count;
+}
+
+// leaf 0x0000000B //
+void bx_generic_cpuid_t::get_std_cpuid_extended_topology_leaf(Bit32u subfunction, \
cpuid_function_t *leaf) +{
+  // CPUID function 0x0000000B - Extended Topology Leaf
+  leaf->eax = 0;
+  leaf->ebx = 0;
+  leaf->ecx = subfunction;
+  leaf->edx = cpu->get_apic_id();
+
+#if BX_SUPPORT_SMP
+  switch(subfunction) {
+  case 0:
+     if (nthreads > 1) {
+        leaf->eax = ilog2(nthreads-1)+1;
+        leaf->ebx = nthreads;
+        leaf->ecx |= (1<<8);
+     }
+     else if (ncores > 1) {
+        leaf->eax = ilog2(ncores-1)+1;
+        leaf->ebx = ncores;
+        leaf->ecx |= (2<<8);
+     }
+     else if (nprocessors > 1) {
+        leaf->eax = ilog2(nprocessors-1)+1;
+        leaf->ebx = nprocessors;
+     }
+     else {
+        leaf->eax = 1;
+        leaf->ebx = 1; // number of logical CPUs at this level
+     }
+     break;
+
+  case 1:
+     if (nthreads > 1) {
+        if (ncores > 1) {
+           leaf->eax = ilog2(ncores-1)+1;
+           leaf->ebx = ncores;
+           leaf->ecx |= (2<<8);
+        }
+        else if (nprocessors > 1) {
+           leaf->eax = ilog2(nprocessors-1)+1;
+           leaf->ebx = nprocessors;
+        }
+     }
+     else if (ncores > 1) {
+        if (nprocessors > 1) {
+           leaf->eax = ilog2(nprocessors-1)+1;
+           leaf->ebx = nprocessors;
+        }
+     }
+     break;
+
+  case 2:
+     if (nthreads > 1) {
+        if (nprocessors > 1) {
+           leaf->eax = ilog2(nprocessors-1)+1;
+           leaf->ebx = nprocessors;
+        }
+     }
+     break;
+
+  default:
+     break;
+  }
+#endif
+}
+
+// leaf 0x0000000C //
+void bx_generic_cpuid_t::get_std_cpuid_leaf_C(cpuid_function_t *leaf)
+{
+  // CPUID function 0x0000000C - reserved
+  leaf->eax = 0;
+  leaf->ebx = 0;
+  leaf->ecx = 0;
+  leaf->edx = 0;
+}
+
+// leaf 0x0000000D //
+void bx_generic_cpuid_t::get_std_cpuid_xsave_leaf(Bit32u subfunction, \
cpuid_function_t *leaf) +{
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE))
+  {
+    switch(subfunction) {
+    case 0:
+      // EAX - valid bits of XCR0 (lower part)
+      // EBX - Maximum size (in bytes) required by enabled features
+      // ECX - Maximum size (in bytes) required by CPU supported features
+      // EDX - valid bits of XCR0 (upper part)
+      leaf->eax = cpu->xcr0_suppmask;
+      leaf->ebx = 512+64;
+#if BX_SUPPORT_AVX
+      if (cpu->xcr0_suppmask & BX_XCR0_AVX_MASK)
+        leaf->ebx += 256;
+#endif
+      leaf->ecx = 512+64;
+#if BX_SUPPORT_AVX
+      if (cpu->xcr0_suppmask & BX_XCR0_AVX_MASK)
+        leaf->ecx += 256;
+#endif
+      leaf->edx = 0;
+      return;
+
+    case 1:
+      leaf->eax = BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVEOPT);
+      leaf->ebx = 0;
+      leaf->ecx = 0;
+      leaf->edx = 0;
+      return;
+
+#if BX_SUPPORT_AVX
+    case 2: // AVX leaf
+      if (cpu->xcr0_suppmask & BX_XCR0_AVX_MASK) {
+        leaf->eax = 256;
+        leaf->ebx = 576;
+        leaf->ecx = 0;
+        leaf->edx = 0;
+        break;
+      }
+      // else fall through
+#endif
+
+    default:
+      leaf->eax = 0; // reserved
+      leaf->ebx = 0; // reserved
+      leaf->ecx = 0; // reserved
+      leaf->edx = 0; // reserved
+      break;
+    }
+  }
+}
+
+// leaf 0x80000000 //
+void bx_generic_cpuid_t::get_ext_cpuid_leaf_0(cpuid_function_t *leaf)
+{
+  // EAX: highest extended function understood by CPUID
+  // EBX: vendor ID string
+  // EDX: vendor ID string
+  // ECX: vendor ID string
+  leaf->eax = BX_SUPPORT_X86_64 ? 0x80000008 : 0x80000004;
+#if BX_CPU_VENDOR_INTEL
+  leaf->ebx = 0;
+  leaf->edx = 0;          // Reserved for Intel
+  leaf->ecx = 0;
+#else
+  static Bit8u *vendor_string = (Bit8u \
*)SIM->get_param_string(BXPN_VENDOR_STRING)->getptr(); +
+  memcpy(&(leaf->ebx), vendor_string,     4);
+  memcpy(&(leaf->edx), vendor_string + 4, 4);
+  memcpy(&(leaf->ecx), vendor_string + 8, 4);
+#endif
+
+#ifdef BX_BIG_ENDIAN
+  leaf->ebx = bx_bswap32(leaf->ebx);
+  leaf->ecx = bx_bswap32(leaf->ecx);
+  leaf->edx = bx_bswap32(leaf->edx);
+#endif
+}
+
+// leaf 0x80000001 //
+void bx_generic_cpuid_t::get_ext_cpuid_leaf_1(cpuid_function_t *leaf)
+{
+  // EAX:       CPU Version Information
+  leaf->eax = BX_CPU_VENDOR_INTEL ? 0 : get_cpu_version_information();
+
+  // EBX:       Brand ID
+  leaf->ebx = 0;
+
+  // ECX:
+  leaf->ecx = get_ext2_cpuid_features();
+
+  // EDX:
+  // Many of the bits in EDX are the same as EAX [*] for AMD
+  // [*] [0:0]   FPU on chip
+  // [*] [1:1]   VME: Virtual-8086 Mode enhancements
+  // [*] [2:2]   DE: Debug Extensions (I/O breakpoints)
+  // [*] [3:3]   PSE: Page Size Extensions
+  // [*] [4:4]   TSC: Time Stamp Counter
+  // [*] [5:5]   MSR: RDMSR and WRMSR support
+  // [*] [6:6]   PAE: Physical Address Extensions
+  // [*] [7:7]   MCE: Machine Check Exception
+  // [*] [8:8]   CXS: CMPXCHG8B instruction
+  // [*] [9:9]   APIC: APIC on Chip
+  //     [10:10] Reserved
+  //     [11:11] SYSCALL/SYSRET support
+  // [*] [12:12] MTRR: Memory Type Range Reg
+  // [*] [13:13] PGE/PTE Global Bit
+  // [*] [14:14] MCA: Machine Check Architecture
+  // [*] [15:15] CMOV: Cond Mov/Cmp Instructions
+  // [*] [16:16] PAT: Page Attribute Table
+  // [*] [17:17] PSE-36: Physical Address Extensions
+  //     [18:19] Reserved
+  //     [20:20] No-Execute page protection
+  //     [21:21] Reserved
+  //     [22:22] AMD MMX Extensions
+  // [*] [23:23] MMX Technology
+  // [*] [24:24] FXSR: FXSAVE/FXRSTOR (also indicates CR4.OSFXSR is available)
+  //     [25:25] Fast FXSAVE/FXRSTOR mode support
+  //     [26:26] 1G paging support
+  //     [27:27] Support RDTSCP Instruction
+  //     [28:28] Reserved
+  //     [29:29] Long Mode
+  //     [30:30] AMD 3DNow! Extensions
+  //     [31:31] AMD 3DNow! Instructions
+  leaf->edx = get_std2_cpuid_features();
+}
+
+// leaf 0x80000002 //
+// leaf 0x80000003 //
+// leaf 0x80000004 //
+void bx_generic_cpuid_t::get_ext_cpuid_brand_string_leaf(Bit32u function, \
cpuid_function_t *leaf) +{
+  static Bit8u *brand_string = (Bit8u \
*)SIM->get_param_string(BXPN_BRAND_STRING)->getptr(); +
+  switch(function) {
+  case 0x80000002:
+    memcpy(&(leaf->eax), brand_string     , 4);
+    memcpy(&(leaf->ebx), brand_string +  4, 4);
+    memcpy(&(leaf->ecx), brand_string +  8, 4);
+    memcpy(&(leaf->edx), brand_string + 12, 4);
+    break;
+  case 0x80000003:
+    memcpy(&(leaf->eax), brand_string + 16, 4);
+    memcpy(&(leaf->ebx), brand_string + 20, 4);
+    memcpy(&(leaf->ecx), brand_string + 24, 4);
+    memcpy(&(leaf->edx), brand_string + 28, 4);
+    break;
+  case 0x80000004:
+    memcpy(&(leaf->eax), brand_string + 32, 4);
+    memcpy(&(leaf->ebx), brand_string + 36, 4);
+    memcpy(&(leaf->ecx), brand_string + 40, 4);
+    memcpy(&(leaf->edx), brand_string + 44, 4);
+    break;
+  default:
+    break;
+  }
+
+#ifdef BX_BIG_ENDIAN
+  leaf->eax = bx_bswap32(leaf->eax);
+  leaf->ebx = bx_bswap32(leaf->ebx);
+  leaf->ecx = bx_bswap32(leaf->ecx);
+  leaf->edx = bx_bswap32(leaf->edx);
+#endif
+}
+
+// leaf 0x80000005 //
+void bx_generic_cpuid_t::get_ext_cpuid_leaf_5(cpuid_function_t *leaf)
+{
+  /* cache info (L1 cache) */
+  leaf->eax = 0x01ff01ff;
+  leaf->ebx = 0x01ff01ff;
+  leaf->ecx = 0x40020140;
+  leaf->edx = 0x40020140;
+}
+
+// leaf 0x80000006 //
+void bx_generic_cpuid_t::get_ext_cpuid_leaf_6(cpuid_function_t *leaf)
+{
+  /* cache info (L2 cache) */
+  leaf->eax = 0;
+  leaf->ebx = 0x42004200;
+  leaf->ecx = 0x02008140;
+  leaf->edx = 0;
+}
+
+// leaf 0x80000007 //
+void bx_generic_cpuid_t::get_ext_cpuid_leaf_7(cpuid_function_t *leaf)
+{
+  leaf->eax = 0;
+  leaf->ebx = 0;
+  leaf->ecx = 0;
+  leaf->edx = 0;
+}
+
+// leaf 0x80000008 //
+void bx_generic_cpuid_t::get_ext_cpuid_leaf_8(cpuid_function_t *leaf)
+{
+  // virtual & phys address size in low 2 bytes.
+  leaf->eax = BX_PHY_ADDRESS_WIDTH | (BX_LIN_ADDRESS_WIDTH << 8);
+  leaf->ebx = 0;
+  leaf->ecx = 0; // Reserved, undefined
+  leaf->edx = 0;
+}
+
+void bx_generic_cpuid_t::init_isa_extensions_bitmask(void)
+{
+  Bit32u features_bitmask = 0;
+
+#if BX_SUPPORT_FPU
+  features_bitmask |= BX_CPU_X87;
+#endif
+
+#if BX_CPU_LEVEL >= 4
+  features_bitmask |= BX_CPU_486;
+
+#if BX_CPU_LEVEL >= 5
+  features_bitmask |= BX_CPU_PENTIUM;
+
+  static bx_bool mmx_enabled = SIM->get_param_bool(BXPN_CPUID_MMX)->get();
+  if (mmx_enabled)
+    features_bitmask |= BX_CPU_MMX;
+
+#if BX_SUPPORT_3DNOW
+  features_bitmask |= BX_CPU_3DNOW;
+
+  if (! mmx_enabled) {
+    BX_PANIC(("PANIC: 3DNOW emulation requires MMX support !"));
+    return;
+  }
+#endif
+
+#if BX_CPU_LEVEL >= 6
+  features_bitmask |= BX_CPU_P6;
+
+#if BX_SUPPORT_MONITOR_MWAIT
+  static bx_bool mwait_enabled = SIM->get_param_bool(BXPN_CPUID_MWAIT)->get();
+  if (mwait_enabled)
+    features_bitmask |= BX_CPU_MONITOR_MWAIT;
+#endif
+
+  // FXSAVE/FXRSTOR support come with Pentium II
+  if (mmx_enabled)
+    features_bitmask |= BX_CPU_FXSAVE_FXRSTOR;
+
+  static unsigned sse_enabled = SIM->get_param_enum(BXPN_CPUID_SSE)->get();
+  // determine SSE in runtime
+  switch (sse_enabled) {
+    case BX_CPUID_SUPPORT_SSE4_2:
+      features_bitmask |= BX_CPU_SSE4_2;
+    case BX_CPUID_SUPPORT_SSE4_1:
+      features_bitmask |= BX_CPU_SSE4_1;
+    case BX_CPUID_SUPPORT_SSSE3:
+      features_bitmask |= BX_CPU_SSSE3;
+    case BX_CPUID_SUPPORT_SSE3:
+      features_bitmask |= BX_CPU_SSE3;
+    case BX_CPUID_SUPPORT_SSE2:
+      features_bitmask |= BX_CPU_SSE2;
+    case BX_CPUID_SUPPORT_SSE:
+      features_bitmask |= BX_CPU_SSE;
+    case BX_CPUID_SUPPORT_NOSSE:
+    default:
+      break;
+  };
+
+  if (sse_enabled) {
+     if (mmx_enabled == 0 || BX_CPU_LEVEL < 6) {
+       BX_PANIC(("PANIC: SSE support requires P6 emulation with MMX enabled !"));
+       return;
+     }
+  }
+
+  // enabled CLFLUSH only when SSE2 or higher is enabled
+  if (sse_enabled >= BX_CPUID_SUPPORT_SSE2)
+    features_bitmask |= BX_CPU_CLFLUSH;
+
+  static bx_bool sep_enabled = SIM->get_param_bool(BXPN_CPUID_SEP)->get();
+  if (sep_enabled)
+    features_bitmask |= BX_CPU_SYSENTER_SYSEXIT;
+
+  static bx_bool xsave_enabled = SIM->get_param_bool(BXPN_CPUID_XSAVE)->get();
+  if (xsave_enabled) {
+    features_bitmask |= BX_CPU_XSAVE;
+
+    if (! sse_enabled) {
+       BX_PANIC(("PANIC: XSAVE emulation requires SSE support !"));
+       return;
+    }
+  }
+
+  static bx_bool xsaveopt_enabled = SIM->get_param_bool(BXPN_CPUID_XSAVEOPT)->get();
+  if (xsaveopt_enabled) {
+    features_bitmask |= BX_CPU_XSAVEOPT;
+
+    if (! xsave_enabled) {
+      BX_PANIC(("PANIC: XSAVEOPT emulation requires XSAVE !"));
+      return;
+    }
+  }
+
+  static bx_bool aes_enabled = SIM->get_param_bool(BXPN_CPUID_AES)->get();
+  if (aes_enabled) {
+    features_bitmask |= BX_CPU_AES_PCLMULQDQ;
+
+     // AES required 3-byte opcode (SSS3E support or more)
+     if (sse_enabled < BX_CPUID_SUPPORT_SSSE3) {
+       BX_PANIC(("PANIC: AES support requires SSSE3 or higher !"));
+       return;
+     }
+  }
+
+  static bx_bool movbe_enabled = SIM->get_param_bool(BXPN_CPUID_MOVBE)->get();
+  if (movbe_enabled) {
+    features_bitmask |= BX_CPU_MOVBE;
+
+    // MOVBE required 3-byte opcode (SSS3E support or more)
+    if (sse_enabled < BX_CPUID_SUPPORT_SSSE3) {
+      BX_PANIC(("PANIC: MOVBE support requires SSSE3 or higher !"));
+      return;
+    }
+  }
+
+#if BX_SUPPORT_AVX
+  static bx_bool avx_enabled = SIM->get_param_bool(BXPN_CPUID_AVX)->get();
+  if (avx_enabled) {
+    features_bitmask |= BX_CPU_AVX;
+
+    if (! xsave_enabled) {
+      BX_PANIC(("PANIC: AVX emulation requires XSAVE support !"));
+      return;
+    }
+  }
+
+  static bx_bool avx_f16c_enabled = \
SIM->get_param_bool(BXPN_CPUID_AVX_F16CVT)->get(); +  if (avx_f16c_enabled) {
+    if (! avx_enabled) {
+      BX_PANIC(("PANIC: Float16 convert emulation requires AVX support !"));
+      return;
+    }
+
+    features_bitmask |= BX_CPU_AVX_F16C;
+  }
+#endif
+
+#if BX_SUPPORT_VMX
+  features_bitmask |= BX_CPU_VMX;
+
+  if (! sep_enabled) {
+    BX_PANIC(("PANIC: VMX emulation requires SYSENTER/SYSEXIT support !"));
+    return;
+  }
+#endif
+
+#if BX_SUPPORT_X86_64
+  features_bitmask |= BX_CPU_X86_64;
+
+  if (sse_enabled < BX_CPUID_SUPPORT_SSE2) {
+    BX_PANIC(("PANIC: x86-64 emulation requires SSE2 support !"));
+    return;
+  }
+
+  if (! sep_enabled) {
+    BX_PANIC(("PANIC: x86-64 emulation requires SYSENTER/SYSEXIT support !"));
+    return;
+  }
+
+  static bx_bool fsgsbase_enabled = SIM->get_param_bool(BXPN_CPUID_FSGSBASE)->get();
+  if (fsgsbase_enabled)
+    features_bitmask |= BX_CPU_FSGSBASE;
+
+  static unsigned apic_enabled = SIM->get_param_enum(BXPN_CPUID_APIC)->get();
+  if (apic_enabled < BX_CPUID_SUPPORT_XAPIC) {
+    BX_PANIC(("PANIC: x86-64 emulation requires XAPIC support !"));
+    return;
+  }
+#endif
+
+#endif // CPU_LEVEL >= 6
+
+#endif // CPU_LEVEL >= 5
+
+#endif // CPU_LEVEL >= 4
+
+  this->isa_extensions_bitmask = features_bitmask;
+}
+
+void bx_generic_cpuid_t::init_cpu_extensions_bitmask(void)
+{
+  Bit32u features_bitmask = 0;
+
+#if BX_SUPPORT_APIC
+  static unsigned apic_enabled = SIM->get_param_enum(BXPN_CPUID_APIC)->get();
+  // determine SSE in runtime
+  switch (apic_enabled) {
+    case BX_CPUID_SUPPORT_X2APIC:
+      features_bitmask |= BX_CPU_X2APIC;
+    case BX_CPUID_SUPPORT_XAPIC:
+      features_bitmask |= BX_CPU_XAPIC;
+    case BX_CPUID_SUPPORT_LEGACY_APIC:
+    default:
+      break;
+  };
+
+  // I would like to allow XAPIC configuration with i586 together
+  if (apic_enabled >= BX_CPUID_SUPPORT_X2APIC && BX_CPU_LEVEL < 6) {
+    BX_PANIC(("PANIC: X2APIC require CPU_LEVEL >= 6 !"));
+    return;
+  }
+#endif
+
+#if BX_CPU_LEVEL >= 5
+  features_bitmask |= BX_CPU_VME;
+  features_bitmask |= BX_CPU_DEBUG_EXTENSIONS;
+  features_bitmask |= BX_CPU_PSE;
+
+#if BX_CPU_LEVEL >= 6
+  features_bitmask |= BX_CPU_PAE;
+  features_bitmask |= BX_CPU_PGE;
+  features_bitmask |= BX_CPU_PSE36;
+  features_bitmask |= BX_CPU_PAT_MTRR;
+
+  static bx_bool smep_enabled = SIM->get_param_bool(BXPN_CPUID_SMEP)->get();
+  if (smep_enabled)
+    features_bitmask |= BX_CPU_SMEP;
+
+#if BX_SUPPORT_X86_64
+  static bx_bool pcid_enabled = SIM->get_param_bool(BXPN_CPUID_PCID)->get();
+  if (pcid_enabled)
+    features_bitmask |= BX_CPU_PCID;
+#endif
+
+#endif // CPU_LEVEL >= 6
+
+#endif // CPU_LEVEL >= 5
+
+  this->cpu_extensions_bitmask = features_bitmask;
+}
+
+/*
+ * Get CPU version information:
+ *
+ * [3:0]   Stepping ID
+ * [7:4]   Model: starts at 1
+ * [11:8]  Family: 4=486, 5=Pentium, 6=PPro, ...
+ * [13:12] Type: 0=OEM, 1=overdrive, 2=dual cpu, 3=reserved
+ * [19:16] Extended Model
+ * [27:29] Extended Family
+ */
+
+Bit32u bx_generic_cpuid_t::get_cpu_version_information(void)
+{
+  static Bit32u stepping = SIM->get_param_num(BXPN_CPUID_STEPPING)->get();
+  static Bit32u model = SIM->get_param_num(BXPN_CPUID_MODEL)->get();
+  static Bit32u family = SIM->get_param_num(BXPN_CPUID_FAMILY)->get();
+
+  if (family < 6 && family != BX_CPU_LEVEL)
+    BX_PANIC(("PANIC: CPUID family %x not matching configured cpu level %d", family, \
BX_CPU_LEVEL)); +
+  return ((family & 0xfff0) << 16) |
+         ((model & 0xf0) << 12) |
+         ((family & 0x0f) << 8) |
+         ((model & 0x0f) << 4) | stepping;
+}
+
+/* Get CPU extended feature flags. */
+Bit32u bx_generic_cpuid_t::get_extended_cpuid_features(void)
+{
+  // [0:0]   SSE3: SSE3 Instructions
+  // [1:1]   PCLMULQDQ Instruction support
+  // [2:2]   DTES64: 64-bit DS area
+  // [3:3]   MONITOR/MWAIT support
+  // [4:4]   DS-CPL: CPL qualified debug store
+  // [5:5]   VMX: Virtual Machine Technology
+  // [6:6]   SMX: Secure Virtual Machine Technology
+  // [7:7]   EST: Enhanced Intel SpeedStep Technology
+  // [8:8]   TM2: Thermal Monitor 2
+  // [9:9]   SSSE3: SSSE3 Instructions
+  // [10:10] CNXT-ID: L1 context ID
+  // [11:11] reserved
+  // [12:12] FMA Instructions support
+  // [13:13] CMPXCHG16B: CMPXCHG16B instruction support
+  // [14:14] xTPR update control
+  // [15:15] PDCM - Perfon and Debug Capability MSR
+  // [16:16] reserved
+  // [17:17] PCID: Process Context Identifiers
+  // [18:18] DCA - Direct Cache Access
+  // [19:19] SSE4.1 Instructions
+  // [20:20] SSE4.2 Instructions
+  // [21:21] X2APIC
+  // [22:22] MOVBE instruction
+  // [23:23] POPCNT instruction
+  // [24:24] TSC Deadline
+  // [25:25] AES Instructions
+  // [26:26] XSAVE extensions support
+  // [27:27] OSXSAVE support
+  // [28:28] AVX extensions support
+  // [29:29] AVX F16C - Float16 conversion support
+  // [30:30] RDRAND instruction
+  // [31:31] reserved
+
+  Bit32u features = 0;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE3))
+    features |= BX_CPUID_EXT_SSE3;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_AES_PCLMULQDQ))
+    features |= BX_CPUID_EXT_PCLMULQDQ;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_MONITOR_MWAIT))
+    features |= BX_CPUID_EXT_MONITOR_MWAIT;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_VMX))
+    features |= BX_CPUID_EXT_VMX;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSSE3))
+    features |= BX_CPUID_EXT_SSSE3;
+
+#if BX_SUPPORT_X86_64
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_X86_64))
+    features |= BX_CPUID_EXT_CMPXCHG16B;
+
+  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PCID))
+    features |= BX_CPUID_EXT_PCID;
+#endif
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE4_1))
+    features |= BX_CPUID_EXT_SSE4_1;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE4_2))
+    features |= BX_CPUID_EXT_SSE4_2;
+
+  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_X2APIC))
+    features |= BX_CPUID_EXT_X2APIC;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_MOVBE))
+    features |= BX_CPUID_EXT_MOVBE;
+
+  // enable POPCNT if SSE4_2 is enabled
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE4_2))
+    features |= BX_CPUID_EXT_POPCNT;
+
+  // support for AES
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_AES_PCLMULQDQ))
+    features |= BX_CPUID_EXT_AES;
+
+  // support XSAVE extensions
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_XSAVE))
+    features |= BX_CPUID_EXT_XSAVE | BX_CPUID_EXT_OSXSAVE;
+
+#if BX_SUPPORT_AVX
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_AVX))
+    features |= BX_CPUID_EXT_AVX;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_AVX_F16C))
+    features |= BX_CPUID_EXT_AVX_F16C;
+#endif
+
+  return features;
+}
+
+#if BX_CPU_LEVEL >= 6
+Bit32u bx_generic_cpuid_t::get_ext3_cpuid_features(void)
+{
+  Bit32u features = 0;
+
+  //   [0:0]    FS/GS BASE access instructions
+  //   [2:1]    reserved
+  //   [3:3]    BMI1: Advanced Bit Manipulation Extensions
+  //   [4:4]    reserved
+  //   [5:5]    AVX2
+  //   [6:6]    reserved
+  //   [7:7]    SMEP: Supervisor Mode Execution Protection
+  //   [8:8]    BMI2: Advanced Bit Manipulation Extensions
+  //   [9:9]    Support for Enhanced REP MOVSB/STOSB
+  //   [10:10]  Support for INVPCID instruction
+  //   [31:10]  reserved
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_FSGSBASE))
+    features |= BX_CPUID_EXT3_FSGSBASE;
+
+  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_SMEP))
+    features |= BX_CPUID_EXT3_SMEP;
+
+  return features;
+}
+#endif
+
+/* Get CPU feature flags. Returned by CPUID functions 1 and 80000001.  */
+Bit32u bx_generic_cpuid_t::get_std_cpuid_features(void)
+{
+  //   [0:0]   FPU on chip
+  //   [1:1]   VME: Virtual-8086 Mode enhancements
+  //   [2:2]   DE: Debug Extensions (I/O breakpoints)
+  //   [3:3]   PSE: Page Size Extensions
+  //   [4:4]   TSC: Time Stamp Counter
+  //   [5:5]   MSR: RDMSR and WRMSR support
+  //   [6:6]   PAE: Physical Address Extensions
+  //   [7:7]   MCE: Machine Check Exception
+  //   [8:8]   CXS: CMPXCHG8B instruction
+  //   [9:9]   APIC: APIC on Chip
+  //   [10:10] Reserved
+  //   [11:11] SYSENTER/SYSEXIT support
+  //   [12:12] MTRR: Memory Type Range Reg
+  //   [13:13] PGE/PTE Global Bit
+  //   [14:14] MCA: Machine Check Architecture
+  //   [15:15] CMOV: Cond Mov/Cmp Instructions
+  //   [16:16] PAT: Page Attribute Table
+  //   [17:17] PSE-36: Physical Address Extensions
+  //   [18:18] PSN: Processor Serial Number
+  //   [19:19] CLFLUSH: CLFLUSH Instruction support
+  //   [20:20] Reserved
+  //   [21:21] DS: Debug Store
+  //   [22:22] ACPI: Thermal Monitor and Software Controlled Clock Facilities
+  //   [23:23] MMX Technology
+  //   [24:24] FXSR: FXSAVE/FXRSTOR (also indicates CR4.OSFXSR is available)
+  //   [25:25] SSE: SSE Extensions
+  //   [26:26] SSE2: SSE2 Extensions
+  //   [27:27] Self Snoop
+  //   [28:28] Hyper Threading Technology
+  //   [29:29] TM: Thermal Monitor
+  //   [30:30] Reserved
+  //   [31:31] PBE: Pending Break Enable
+
+  Bit32u features = 0;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_X87))
+    features |= BX_CPUID_STD_X87;
+
+#if BX_CPU_LEVEL >= 5
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_PENTIUM)) {
+    // Pentium only features
+    features |= BX_CPUID_STD_TSC;
+    features |= BX_CPUID_STD_MSR;
+    // support Machine Check
+    features |= BX_CPUID_STD_MCE | BX_CPUID_STD_MCA;
+    features |= BX_CPUID_STD_CMPXCHG8B;
+  }
+
+  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_VME))
+    features |= BX_CPUID_STD_VME;
+
+  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_DEBUG_EXTENSIONS))
+    features |= BX_CPUID_STD_DEBUG_EXTENSIONS;
+
+  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PSE))
+    features |= BX_CPUID_STD_PSE;
+#endif
+
+#if BX_SUPPORT_APIC
+  // if MSR_APICBASE APIC Global Enable bit has been cleared,
+  // the CPUID feature flag for the APIC is set to 0.
+  if (cpu->msr.apicbase & 0x800)
+    features |= BX_CPUID_STD_APIC; // APIC on chip
+#endif
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SYSENTER_SYSEXIT))
+    features |= BX_CPUID_STD_SYSENTER_SYSEXIT;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_CLFLUSH))
+    features |= BX_CPUID_STD_CLFLUSH;
+
+#if BX_CPU_LEVEL >= 5
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_MMX))
+    features |= BX_CPUID_STD_MMX;
+#endif
+
+#if BX_CPU_LEVEL >= 6
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_P6)) {
+    features |= BX_CPUID_STD_CMOV;
+    features |= BX_CPUID_STD_ACPI;
+  }
+
+  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PAT_MTRR))
+    features |= BX_CPUID_STD_PAT | BX_CPUID_STD_MTRR;
+
+  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PAE))
+    features |= BX_CPUID_STD_PAE;
+
+  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PGE))
+    features |= BX_CPUID_STD_GLOBAL_PAGES;
+
+  if (BX_CPUID_SUPPORT_CPU_EXTENSION(BX_CPU_PSE36))
+    features |= BX_CPUID_STD_PSE36;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_FXSAVE_FXRSTOR))
+    features |= BX_CPUID_STD_FXSAVE_FXRSTOR;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE))
+    features |= BX_CPUID_STD_SSE;
+
+  if (BX_CPUID_SUPPORT_ISA_EXTENSION(BX_CPU_SSE2))
+    features |= BX_CPUID_STD_SSE2;
+
+  if (BX_CPU_VENDOR_INTEL)
+    features |= BX_CPUID_STD_SELF_SNOOP;
+#endif
+
+#if BX_SUPPORT_SMP
+  // Intel(R) HyperThreading Technology
+  if (SIM->get_param_num(BXPN_CPU_NTHREADS)->get() > 1)
+    features |= BX_CPUID_STD_HT;
+#endif
+
+  return features;
+}
+
+/* Get CPU feature flags. Returned by CPUID function 80000001 in EDX register */
+Bit32u bx_generic_cpuid_t::get_std2_cpuid_features(void)
+{
+  // Many of the bits in EDX are the same as EAX [*] for AMD
+  // [*] [0:0]   FPU on chip
+  // [*] [1:1]   VME: Virtual-8086 Mode enhancements
+  // [*] [2:2]   DE: Debug Extensions (I/O breakpoints)
+  // [*] [3:3]   PSE: Page Size Extensions
+  // [*] [4:4]   TSC: Time Stamp Counter
+  // [*] [5:5]   MSR: RDMSR and WRMSR support
+  // [*] [6:6]   PAE: Physical Address Extensions
+  // [*] [7:7]   MCE: Machine Check Exception
+  // [*] [8:8]   CXS: CMPXCHG8B instruction
+  // [*] [9:9]   APIC: APIC on Chip
+  //     [10:10] Reserved
+  //     [11:11] SYSCALL/SYSRET support
+  // [*] [12:12] MTRR: Memory Type Range Reg
+  // [*] [13:13] PGE/PTE Global Bit
+  // [*] [14:14] MCA: Machine Check Architecture
+  // [*] [15:15] CMOV: Cond Mov/Cmp Instructions
+  // [*] [16:16] PAT: Page Attribute Table
+  // [*] [17:17] PSE-36: Physical Address Extensions
+  //     [18:19] Reserved
+  //     [20:20] No-Execute page protection
+  //     [21:21] Reserved
+  //     [22:22] AMD MMX Extensions
+  // [*] [23:23] MMX Technology
+  // [*] [24:24] FXSR: FXSAVE/FXRSTOR (also indicates CR4.OSFXSR is available)
+  //     [25:25] Fast FXSAVE/FXRSTOR mode support
+  //     [26:26] 1G paging support
+  //     [27:27] Support RDTSCP Instruction
+  //     [28:28] Reserved
+  //     [29:29] Long Mode
+  //     [30:30] AMD 3DNow! Extensions
+  //     [31:31] AMD 3DNow! Instructions
+  Bit32u features = BX_CPU_VENDOR_INTEL ? 0 : get_std_cpuid_features();
+  features &= 0x0183F3FF;
+#if BX_SUPPORT_3DNOW
+  // only AMD is interesting in AMD MMX extensions
+  features |= BX_CPUID_STD2_AMD_MMX_EXT | BX_CPUID_STD2_3DNOW_EXT | \
BX_CPUID_STD2_3DNOW; +#endif
+#if BX_SUPPORT_X86_64
+  features |= BX_CPUID_STD2_SYSCALL_SYSRET |
+              BX_CPUID_STD2_NX |
+              BX_CPUID_STD2_FFXSR |
+              BX_CPUID_STD2_RDTSCP | BX_CPUID_STD2_LONG_MODE;
+  static bx_bool xlarge_pages = SIM->get_param_bool(BXPN_CPUID_1G_PAGES)->get();
+  if (xlarge_pages)
+    features |= BX_CPUID_STD2_1G_PAGES;
+#endif
+
+  return features;
+}
+
+/* Get CPU feature flags. Returned by CPUID function 80000001 in ECX register */
+Bit32u bx_generic_cpuid_t::get_ext2_cpuid_features(void)
+{
+  // ECX:
+  //     [0:0]   LAHF/SAHF instructions support in 64-bit mode
+  //     [1:1]   CMP_Legacy: Core multi-processing legacy mode (AMD)
+  //     [2:2]   SVM: Secure Virtual Machine (AMD)
+  //     [3:3]   Extended APIC Space
+  //     [4:4]   AltMovCR8: LOCK MOV CR0 means MOV CR8
+  //     [5:5]   LZCNT: LZCNT instruction support
+  //     [6:6]   SSE4A: SSE4A Instructions support (deprecated?)
+  //     [7:7]   Misaligned SSE support
+  //     [8:8]   PREFETCHW: PREFETCHW instruction support
+  //     [9:9]   OSVW: OS visible workarounds (AMD)
+  //     [11:10] reserved
+  //     [12:12] SKINIT support
+  //     [13:13] WDT: Watchdog timer support
+  //     [31:14] reserved
+  Bit32u features = 0;
+
+#if BX_SUPPORT_X86_64
+  features |= BX_CPUID_EXT2_LAHF_SAHF;
+#endif
+#if BX_SUPPORT_MISALIGNED_SSE
+  features |= BX_CPUID_EXT2_MISALIGNED_SSE;
+#endif
+
+  return features;
+}
+
+void bx_generic_cpuid_t::dump_cpuid(void)
+{
+  struct cpuid_function_t leaf;
+
+  BX_CPU_THIS_PTR cpuid->get_cpuid_leaf(0x00000000, 0x00000000, &leaf);
+  BX_INFO(("CPUID[0x00000000]: %08x %08x %08x %08x", leaf.eax, leaf.ebx, leaf.ecx, \
leaf.edx)); +  Bit32u max_std_function = leaf.eax, n;
+
+  if (max_std_function > 0) {
+    for (n=1; n<=max_std_function;n++) {
+      BX_CPU_THIS_PTR cpuid->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 BX_CPU_LEVEL >= 6
+  BX_CPU_THIS_PTR cpuid->get_cpuid_leaf(0x80000000, 0x00000000, &leaf);
+  BX_INFO(("CPUID[0x80000000]: %08x %08x %08x %08x", leaf.eax, leaf.ebx, leaf.ecx, \
leaf.edx)); +  Bit32u max_ext_function = leaf.eax;
+
+  if (max_ext_function > 0) {
+    for (n=0x80000001; n<=max_ext_function;n++) {
+      BX_CPU_THIS_PTR cpuid->get_cpuid_leaf(n, 0x00000000, &leaf);
+      BX_INFO(("CPUID[0x%08x]: %08x %08x %08x %08x", n, leaf.eax, leaf.ebx, \
leaf.ecx, leaf.edx)); +    }
+  }
+#endif
+}
+
+bx_cpuid_t *create_bx_generic_cpuid(BX_CPU_C *cpu) { return new \
bx_generic_cpuid_t(cpu); }

Modified: trunk/bochs/cpu/init.cc
===================================================================
--- trunk/bochs/cpu/init.cc	2011-07-27 14:16:51 UTC (rev 10497)
+++ trunk/bochs/cpu/init.cc	2011-07-28 16:17:42 UTC (rev 10498)
@@ -27,7 +27,7 @@
 
 #include "param_names.h"
 
-BX_CPU_C::BX_CPU_C(unsigned id): bx_cpuid(id)
+BX_CPU_C::BX_CPU_C(unsigned id): bx_cpuid(id), cpuid(NULL)
 #if BX_SUPPORT_APIC
    ,lapic (this, id)
 #endif
@@ -38,6 +38,9 @@
   char buffer[16];
   sprintf(buffer, "CPU%x", bx_cpuid);
   put(buffer);
+
+  isa_extensions_bitmask = BX_SUPPORT_FPU ? BX_CPU_X87 : 0;
+  cpu_extensions_bitmask = 0;
 }
 
 #if BX_WITH_WX
@@ -142,14 +145,18 @@
 
 #endif
 
+#include "generic_cpuid.h"
+
 // BX_CPU_C constructor
 void BX_CPU_C::initialize(void)
 {
   BX_CPU_THIS_PTR set_INTR(0);
 
-  init_cpu_features_bitmask();
-  init_isa_features_bitmask();
+  BX_CPU_THIS_PTR cpuid = create_bx_generic_cpuid(this);
 
+  BX_CPU_THIS_PTR isa_extensions_bitmask = cpuid->get_isa_extensions_bitmask();
+  BX_CPU_THIS_PTR cpu_extensions_bitmask = cpuid->get_cpu_extensions_bitmask();
+
   init_FetchDecodeTables(); // must be called after init_isa_features_bitmask()
 
 #if BX_CONFIGURE_MSRS
@@ -698,6 +705,10 @@
 
 BX_CPU_C::~BX_CPU_C()
 {
+#if BX_CPU_LEVEL >= 4
+  delete cpuid;
+#endif
+
   BX_INSTR_EXIT(BX_CPU_ID);
   BX_DEBUG(("Exit."));
 }
@@ -716,7 +727,7 @@
   for (n=0;n<BX_GENERAL_REGISTERS;n++)
     BX_WRITE_32BIT_REGZ(n, 0);
 
-  BX_WRITE_32BIT_REGZ(BX_32BIT_REG_EDX, get_cpu_version_information());
+//BX_WRITE_32BIT_REGZ(BX_32BIT_REG_EDX, get_cpu_version_information());
 
   // initialize NIL register
   BX_WRITE_32BIT_REGZ(BX_NIL_REGISTER, 0);
@@ -1037,13 +1048,12 @@
   }
 #endif
 
-  // initialize CPUID values - make sure apicbase already initialized
+  updateFetchModeMask();
+
 #if BX_CPU_LEVEL >= 4
-  set_cpuid_defaults();
+  BX_CPU_THIS_PTR cpuid->dump_cpuid();
 #endif
 
-  updateFetchModeMask();
-
   BX_INSTR_RESET(BX_CPU_ID, source);
 }
 

Modified: trunk/bochs/cpu/msr.cc
===================================================================
--- trunk/bochs/cpu/msr.cc	2011-07-27 14:16:51 UTC (rev 10497)
+++ trunk/bochs/cpu/msr.cc	2011-07-28 16:17:42 UTC (rev 10498)
@@ -703,12 +703,6 @@
     BX_CPU_THIS_PTR lapic.set_base(BX_CPU_THIS_PTR msr.apicbase);
     // TLB flush is required for emulation correctness
     TLB_flush();  // don't care about performance of apic relocation
-
-    if ((val32_lo & 0x800) == 0) {
-      // APIC global enable bit cleared, clear APIC on chip CPUID feature flag
-      BX_CPU_THIS_PTR cpuid_std_function[0x1].edx &= ~BX_CPUID_STD_APIC;
-      BX_CPU_THIS_PTR cpuid_ext_function[0x1].edx &= ~BX_CPUID_STD_APIC;
-    }
   }
   else {
     BX_INFO(("WRMSR: MSR_APICBASE APIC global enable bit cleared !"));

Modified: trunk/bochs/cpu/proc_ctrl.cc
===================================================================
--- trunk/bochs/cpu/proc_ctrl.cc	2011-07-27 14:16:51 UTC (rev 10497)
+++ trunk/bochs/cpu/proc_ctrl.cc	2011-07-28 16:17:42 UTC (rev 10498)
@@ -60,6 +60,29 @@
   BX_NEXT_INSTR(i);
 }
 
+BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CPUID(bxInstruction_c *i)
+{
+#if BX_CPU_LEVEL >= 4
+
+#if BX_SUPPORT_VMX
+  if (BX_CPU_THIS_PTR in_vmx_guest) {
+    BX_ERROR(("VMEXIT: CPUID in VMX non-root operation"));
+    VMexit(i, VMX_VMEXIT_CPUID, 0);
+  }
+#endif
+
+  struct cpuid_function_t leaf;
+  BX_CPU_THIS_PTR cpuid->get_cpuid_leaf(EAX, ECX, &leaf);
+
+  RAX = leaf.eax;
+  RBX = leaf.ebx;
+  RCX = leaf.ecx;
+  RDX = leaf.edx;
+#endif
+
+  BX_NEXT_INSTR(i);
+}
+
 //
 // The shutdown state is very similar to the state following the exection
 // if HLT instruction. In this mode the processor stops executing


This was sent by the SourceForge.net collaborative development platform, the world's \
largest Open Source development site.

------------------------------------------------------------------------------
Got Input?   Slashdot Needs You.
Take our quick survey online.  Come on, we don't ask for help often.
Plus, you'll get a chance to win $100 to spend on ThinkGeek.
http://p.sf.net/sfu/slashdot-survey
_______________________________________________
Bochs-cvs mailing list
Bochs-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bochs-cvs


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic