Finalize XSAVE/XRSTOR instructions

This commit is contained in:
Stanislav Shwartsman 2008-02-13 22:25:24 +00:00
parent 03363f167c
commit ae86ad28a0
4 changed files with 39 additions and 16 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.424 2008-02-13 16:45:20 sshwarts Exp $
// $Id: cpu.h,v 1.425 2008-02-13 22:25:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -552,7 +552,7 @@ typedef struct
} bx_regs_msr_t;
#endif
#define MAX_STD_CPUID_FUNCTION 8
#define MAX_STD_CPUID_FUNCTION 15
#define MAX_EXT_CPUID_FUNCTION 8
struct cpuid_function_t {

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpuid.cc,v 1.62 2008-02-13 16:45:20 sshwarts Exp $
// $Id: cpuid.cc,v 1.63 2008-02-13 22:25:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007 Stanislav Shwartsman
@ -255,7 +255,7 @@ Bit32u BX_CPU_C::get_std_cpuid_features()
void BX_CPU_C::CPUID(bxInstruction_c *i)
{
Bit32u function = EAX;
Bit32u function = EAX, subfunction = ECX;
#if BX_CPU_LEVEL >= 4
if(function < 0x80000000) {
@ -271,6 +271,14 @@ void BX_CPU_C::CPUID(bxInstruction_c *i)
if ((BX_CPU_THIS_PTR msr.apicbase & 0x800) == 0)
RDX &= ~(1<<9); // APIC on chip
}
#endif
#if BX_SUPPORT_XSAVE
if (function == 0xD && subfunction > 0) {
RAX = 0;
RBX = 0;
RCX = 0;
RDX = 0;
}
#endif
return;
}
@ -338,7 +346,11 @@ void BX_CPU_C::set_cpuid_defaults(void)
cpuid->eax = 1;
#else
// for Pentium Pro, Pentium II, Pentium 4 processors
cpuid->eax = BX_SUPPORT_MONITOR_MWAIT ? 5 : 2;
cpuid->eax = 2;
if (BX_SUPPORT_MONITOR_MWAIT)
cpuid->eax = 0x5;
if (BX_SUPPORT_XSAVE)
cpuid->eax = 0xD;
#endif
#if BX_CPU_VENDOR_INTEL
@ -491,6 +503,21 @@ void BX_CPU_C::set_cpuid_defaults(void)
cpuid->edx = 0;
#endif
#if BX_SUPPORT_XSAVE
// ------------------------------------------------------
// CPUID function 0x0000000D
cpuid = &(BX_CPU_THIS_PTR cpuid_std_function[0xD]);
// EAX - XCR0 lower 32 bits
// EBX - Maximum size (in bytes) required by enabled features
// ECX - Maximum size (in bytes) required by CPU supported features
// EDX - XCR0 upper 32 bits
cpuid->eax = BX_CPU_THIS_PTR xcr0.getRegister();
cpuid->ebx = 512+64;
cpuid->ecx = 512+64;
cpuid->edx = 0;
#endif
#if BX_SUPPORT_SSE >= 2 // report Pentium 4 extended functions
// ------------------------------------------------------

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: sse_move.cc,v 1.79 2008-02-13 17:06:44 sshwarts Exp $
// $Id: sse_move.cc,v 1.80 2008-02-13 22:25:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003 Stanislav Shwartsman
@ -243,7 +243,7 @@ void BX_CPU_C::FXSAVE(bxInstruction_c *i)
xmm.xmm32u(3) = 0;
#endif
write_virtual_dqword_aligned(i->seg(), RMAddr(i) + 16, (Bit8u *) &xmm);
write_virtual_dqword(i->seg(), RMAddr(i) + 16, (Bit8u *) &xmm);
/* store i387 register file */
for(index=0; index < 8; index++)
@ -254,7 +254,7 @@ void BX_CPU_C::FXSAVE(bxInstruction_c *i)
xmm.xmm64u(1) = 0;
xmm.xmm16u(4) = fp.exp;
write_virtual_dqword_aligned(i->seg(), RMAddr(i)+index*16+32, (Bit8u *) &xmm);
write_virtual_dqword(i->seg(), RMAddr(i)+index*16+32, (Bit8u *) &xmm);
}
#if BX_SUPPORT_X86_64
@ -268,7 +268,7 @@ void BX_CPU_C::FXSAVE(bxInstruction_c *i)
{
// save XMM8-XMM15 only in 64-bit mode
if (index < 8 || Is64BitMode()) {
write_virtual_dqword_aligned(i->seg(),
write_virtual_dqword(i->seg(),
RMAddr(i)+index*16+160, (Bit8u *) &(BX_CPU_THIS_PTR xmm[index]));
}
}
@ -326,7 +326,7 @@ void BX_CPU_C::FXRSTOR(bxInstruction_c *i)
Bit32u tag_byte = xmm.xmmubyte(4);
/* Restore x87 FPU DP */
read_virtual_dqword_aligned(i->seg(), RMAddr(i) + 16, (Bit8u *) &xmm);
read_virtual_dqword(i->seg(), RMAddr(i) + 16, (Bit8u *) &xmm);
#if BX_SUPPORT_X86_64
if (i->os64L()) {
@ -376,7 +376,7 @@ void BX_CPU_C::FXRSTOR(bxInstruction_c *i)
{
// restore XMM8-XMM15 only in 64-bit mode
if (index < 8 || Is64BitMode()) {
read_virtual_dqword_aligned(i->seg(),
read_virtual_dqword(i->seg(),
RMAddr(i)+index*16+160, (Bit8u *) &(BX_CPU_THIS_PTR xmm[index]));
}
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: xsave.cc,v 1.3 2008-02-13 17:06:44 sshwarts Exp $
// $Id: xsave.cc,v 1.4 2008-02-13 22:25:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008 Stanislav Shwartsman
@ -32,10 +32,6 @@
#define RDX EDX
#endif
// TODO:
// 1. CPUID leaf, CPU function ECX[26], ECX[27]
// 2. SSE #UD generation new way
#if BX_SUPPORT_XSAVE
void BX_CPU_C::prepareXSAVE(void)
{