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
This commit is contained in:
parent
81f6a283e2
commit
78327d3e5e
@ -89,7 +89,7 @@ OBJS = \
|
||||
data_xfer16.o \
|
||||
data_xfer32.o \
|
||||
exception.o \
|
||||
cpuid.o \
|
||||
generic_cpuid.o \
|
||||
proc_ctrl.o \
|
||||
crregs.o \
|
||||
msr.o \
|
||||
@ -284,7 +284,7 @@ cpu.o: cpu.@CPP_SUFFIX@ ../bochs.h ../config.h ../osdep.h ../bx_debug/debug.h \
|
||||
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 \
|
||||
|
@ -814,9 +814,9 @@ public: // for now...
|
||||
|
||||
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,27 +3449,13 @@ public: // for now...
|
||||
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);
|
||||
#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);
|
||||
|
||||
#if BX_SUPPORT_APIC
|
||||
BX_SMF BX_CPP_INLINE Bit8u get_apic_id(void) { return BX_CPU_THIS_PTR bx_cpuid; }
|
||||
#endif
|
||||
|
||||
BX_SMF BX_CPP_INLINE int bx_cpuid_support_debug_extensions(void);
|
||||
@ -3916,18 +3902,18 @@ BX_CPP_INLINE bx_bool BX_CPU_C::alignment_check(void)
|
||||
|
||||
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_pcid(void)
|
||||
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_fsgsbase(void)
|
||||
|
||||
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
|
||||
|
@ -31,6 +31,25 @@ struct cpuid_function_t {
|
||||
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 */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 @@ BX_CPU_C::BX_CPU_C(unsigned id): bx_cpuid(id)
|
||||
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,13 +145,17 @@ static Bit64s cpu_param_handler(bx_param_c *param, int set, Bit64s val)
|
||||
|
||||
#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()
|
||||
|
||||
@ -698,6 +705,10 @@ void BX_CPU_C::after_restore_state(void)
|
||||
|
||||
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 @@ void BX_CPU_C::reset(unsigned source)
|
||||
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 @@ void BX_CPU_C::reset(unsigned source)
|
||||
}
|
||||
#endif
|
||||
|
||||
// initialize CPUID values - make sure apicbase already initialized
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
set_cpuid_defaults();
|
||||
#endif
|
||||
|
||||
updateFetchModeMask();
|
||||
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
BX_CPU_THIS_PTR cpuid->dump_cpuid();
|
||||
#endif
|
||||
|
||||
BX_INSTR_RESET(BX_CPU_ID, source);
|
||||
}
|
||||
|
||||
|
@ -703,12 +703,6 @@ bx_bool BX_CPU_C::relocate_apic(Bit64u val_64)
|
||||
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 !"));
|
||||
|
@ -60,6 +60,29 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PREFETCH(bxInstruction_c *i)
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user