Rework SMM mess
This commit is contained in:
parent
cd367becd7
commit
a396c8a1ce
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.553 2009-01-17 18:56:25 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.554 2009-01-17 22:35:44 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -3084,6 +3084,7 @@ public: // for now...
|
||||
#endif
|
||||
BX_SMF void exception(unsigned vector, Bit16u error_code, bx_bool trap)
|
||||
BX_CPP_AttrNoReturn();
|
||||
BX_SMF void init_SMRAM(void);
|
||||
BX_SMF void smram_save_state(Bit32u *smm_saved_state);
|
||||
BX_SMF bx_bool smram_restore_state(const Bit32u *smm_saved_state);
|
||||
BX_SMF int int_number(unsigned s);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: init.cc,v 1.190 2009-01-10 11:30:20 vruppert Exp $
|
||||
// $Id: init.cc,v 1.191 2009-01-17 22:35:45 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -171,6 +171,8 @@ void BX_CPU_C::initialize(void)
|
||||
load_MSRs(msrs_filename);
|
||||
#endif
|
||||
|
||||
init_SMRAM();
|
||||
|
||||
#if BX_WITH_WX
|
||||
register_wx_state();
|
||||
#endif
|
||||
|
751
bochs/cpu/smm.cc
751
bochs/cpu/smm.cc
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: smm.cc,v 1.52 2009-01-17 18:56:25 sshwarts Exp $
|
||||
// $Id: smm.cc,v 1.53 2009-01-17 22:35:45 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2006 Stanislav Shwartsman
|
||||
@ -199,7 +199,191 @@ void BX_CPU_C::enter_system_management_mode(void)
|
||||
}
|
||||
|
||||
#define SMRAM_TRANSLATE(addr) (((0x8000 - (addr)) >> 2) - 1)
|
||||
#define SMRAM_FIELD(state, addr) (state[SMRAM_TRANSLATE(addr)])
|
||||
|
||||
// SMRAM SMM_SAVE_STATE_MAP_SIZE is 128 elements, find the element for each field
|
||||
static unsigned smram_map[SMRAM_FIELD_LAST];
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
|
||||
void BX_CPU_C::init_SMRAM(void)
|
||||
{
|
||||
static bx_bool smram_map_ready = 0;
|
||||
|
||||
if (smram_map_ready) return;
|
||||
smram_map_ready = 1;
|
||||
|
||||
smram_map[SMRAM_FIELD_SMBASE_OFFSET] = SMRAM_TRANSLATE(0x7f00);
|
||||
smram_map[SMRAM_FIELD_SMM_REVISION_ID] = SMRAM_TRANSLATE(0x7efc);
|
||||
smram_map[SMRAM_FIELD_RAX_HI32] = SMRAM_TRANSLATE(0x7ffc);
|
||||
smram_map[SMRAM_FIELD_EAX] = SMRAM_TRANSLATE(0x7ff8);
|
||||
smram_map[SMRAM_FIELD_RCX_HI32] = SMRAM_TRANSLATE(0x7ff4);
|
||||
smram_map[SMRAM_FIELD_ECX] = SMRAM_TRANSLATE(0x7ff0);
|
||||
smram_map[SMRAM_FIELD_RDX_HI32] = SMRAM_TRANSLATE(0x7fec);
|
||||
smram_map[SMRAM_FIELD_EDX] = SMRAM_TRANSLATE(0x7fe8);
|
||||
smram_map[SMRAM_FIELD_RBX_HI32] = SMRAM_TRANSLATE(0x7fe4);
|
||||
smram_map[SMRAM_FIELD_EBX] = SMRAM_TRANSLATE(0x7fe0);
|
||||
smram_map[SMRAM_FIELD_RSP_HI32] = SMRAM_TRANSLATE(0x7fdc);
|
||||
smram_map[SMRAM_FIELD_ESP] = SMRAM_TRANSLATE(0x7fd8);
|
||||
smram_map[SMRAM_FIELD_RBP_HI32] = SMRAM_TRANSLATE(0x7fd4);
|
||||
smram_map[SMRAM_FIELD_EBP] = SMRAM_TRANSLATE(0x7fd0);
|
||||
smram_map[SMRAM_FIELD_RSI_HI32] = SMRAM_TRANSLATE(0x7fcc);
|
||||
smram_map[SMRAM_FIELD_ESI] = SMRAM_TRANSLATE(0x7fc8);
|
||||
smram_map[SMRAM_FIELD_RDI_HI32] = SMRAM_TRANSLATE(0x7fc4);
|
||||
smram_map[SMRAM_FIELD_EDI] = SMRAM_TRANSLATE(0x7fc0);
|
||||
smram_map[SMRAM_FIELD_R8_HI32] = SMRAM_TRANSLATE(0x7fbc);
|
||||
smram_map[SMRAM_FIELD_R8] = SMRAM_TRANSLATE(0x7fb8);
|
||||
smram_map[SMRAM_FIELD_R9_HI32] = SMRAM_TRANSLATE(0x7fb4);
|
||||
smram_map[SMRAM_FIELD_R9] = SMRAM_TRANSLATE(0x7fb0);
|
||||
smram_map[SMRAM_FIELD_R10_HI32] = SMRAM_TRANSLATE(0x7fac);
|
||||
smram_map[SMRAM_FIELD_R10] = SMRAM_TRANSLATE(0x7fa8);
|
||||
smram_map[SMRAM_FIELD_R11_HI32] = SMRAM_TRANSLATE(0x7fa4);
|
||||
smram_map[SMRAM_FIELD_R11] = SMRAM_TRANSLATE(0x7fa0);
|
||||
smram_map[SMRAM_FIELD_R12_HI32] = SMRAM_TRANSLATE(0x7f9c);
|
||||
smram_map[SMRAM_FIELD_R12] = SMRAM_TRANSLATE(0x7f98);
|
||||
smram_map[SMRAM_FIELD_R13_HI32] = SMRAM_TRANSLATE(0x7f94);
|
||||
smram_map[SMRAM_FIELD_R13] = SMRAM_TRANSLATE(0x7f90);
|
||||
smram_map[SMRAM_FIELD_R14_HI32] = SMRAM_TRANSLATE(0x7f8c);
|
||||
smram_map[SMRAM_FIELD_R14] = SMRAM_TRANSLATE(0x7f88);
|
||||
smram_map[SMRAM_FIELD_R15_HI32] = SMRAM_TRANSLATE(0x7f84);
|
||||
smram_map[SMRAM_FIELD_R15] = SMRAM_TRANSLATE(0x7f80);
|
||||
smram_map[SMRAM_FIELD_RIP_HI32] = SMRAM_TRANSLATE(0x7f7c);
|
||||
smram_map[SMRAM_FIELD_EIP] = SMRAM_TRANSLATE(0x7f78);
|
||||
smram_map[SMRAM_FIELD_RFLAGS_HI32] = SMRAM_TRANSLATE(0x7f74); // always zero
|
||||
smram_map[SMRAM_FIELD_EFLAGS] = SMRAM_TRANSLATE(0x7f70);
|
||||
smram_map[SMRAM_FIELD_DR6_HI32] = SMRAM_TRANSLATE(0x7f6c); // always zero
|
||||
smram_map[SMRAM_FIELD_DR6] = SMRAM_TRANSLATE(0x7f68);
|
||||
smram_map[SMRAM_FIELD_DR7_HI32] = SMRAM_TRANSLATE(0x7f64); // always zero
|
||||
smram_map[SMRAM_FIELD_DR7] = SMRAM_TRANSLATE(0x7f60);
|
||||
smram_map[SMRAM_FIELD_CR0_HI32] = SMRAM_TRANSLATE(0x7f5c); // always zero
|
||||
smram_map[SMRAM_FIELD_CR0] = SMRAM_TRANSLATE(0x7f58);
|
||||
smram_map[SMRAM_FIELD_CR3_HI32] = SMRAM_TRANSLATE(0x7f54); // zero when physical address size 32-bit
|
||||
smram_map[SMRAM_FIELD_CR3] = SMRAM_TRANSLATE(0x7f50);
|
||||
smram_map[SMRAM_FIELD_CR4_HI32] = SMRAM_TRANSLATE(0x7f4c); // always zero
|
||||
smram_map[SMRAM_FIELD_CR4] = SMRAM_TRANSLATE(0x7f48);
|
||||
smram_map[SMRAM_FIELD_EFER_HI32] = SMRAM_TRANSLATE(0x7ed4); // always zero
|
||||
smram_map[SMRAM_FIELD_EFER] = SMRAM_TRANSLATE(0x7ed0);
|
||||
smram_map[SMRAM_FIELD_IO_INSTRUCTION_RESTART] = SMRAM_TRANSLATE(0x7ec8);
|
||||
smram_map[SMRAM_FIELD_AUTOHALT_RESTART] = SMRAM_TRANSLATE(0x7ec8);
|
||||
smram_map[SMRAM_FIELD_NMI_MASK] = SMRAM_TRANSLATE(0x7ec8);
|
||||
smram_map[SMRAM_FIELD_TR_BASE_HI32] = SMRAM_TRANSLATE(0x7e9c);
|
||||
smram_map[SMRAM_FIELD_TR_BASE] = SMRAM_TRANSLATE(0x7e98);
|
||||
smram_map[SMRAM_FIELD_TR_LIMIT] = SMRAM_TRANSLATE(0x7e94);
|
||||
smram_map[SMRAM_FIELD_TR_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e90);
|
||||
smram_map[SMRAM_FIELD_IDTR_BASE_HI32] = SMRAM_TRANSLATE(0x7e8c);
|
||||
smram_map[SMRAM_FIELD_IDTR_BASE] = SMRAM_TRANSLATE(0x7e88);
|
||||
smram_map[SMRAM_FIELD_IDTR_LIMIT] = SMRAM_TRANSLATE(0x7e84);
|
||||
smram_map[SMRAM_FIELD_LDTR_BASE_HI32] = SMRAM_TRANSLATE(0x7e7c);
|
||||
smram_map[SMRAM_FIELD_LDTR_BASE] = SMRAM_TRANSLATE(0x7e78);
|
||||
smram_map[SMRAM_FIELD_LDTR_LIMIT] = SMRAM_TRANSLATE(0x7e74);
|
||||
smram_map[SMRAM_FIELD_LDTR_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e70);
|
||||
smram_map[SMRAM_FIELD_GDTR_BASE_HI32] = SMRAM_TRANSLATE(0x7e6c);
|
||||
smram_map[SMRAM_FIELD_GDTR_BASE] = SMRAM_TRANSLATE(0x7e68);
|
||||
smram_map[SMRAM_FIELD_GDTR_LIMIT] = SMRAM_TRANSLATE(0x7e64);
|
||||
smram_map[SMRAM_FIELD_ES_BASE_HI32] = SMRAM_TRANSLATE(0x7e0c);
|
||||
smram_map[SMRAM_FIELD_ES_BASE] = SMRAM_TRANSLATE(0x7e08);
|
||||
smram_map[SMRAM_FIELD_ES_LIMIT] = SMRAM_TRANSLATE(0x7e04);
|
||||
smram_map[SMRAM_FIELD_ES_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e00);
|
||||
smram_map[SMRAM_FIELD_CS_BASE_HI32] = SMRAM_TRANSLATE(0x7e1c);
|
||||
smram_map[SMRAM_FIELD_CS_BASE] = SMRAM_TRANSLATE(0x7e18);
|
||||
smram_map[SMRAM_FIELD_CS_LIMIT] = SMRAM_TRANSLATE(0x7e14);
|
||||
smram_map[SMRAM_FIELD_CS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e10);
|
||||
smram_map[SMRAM_FIELD_SS_BASE_HI32] = SMRAM_TRANSLATE(0x7e2c);
|
||||
smram_map[SMRAM_FIELD_SS_BASE] = SMRAM_TRANSLATE(0x7e28);
|
||||
smram_map[SMRAM_FIELD_SS_LIMIT] = SMRAM_TRANSLATE(0x7e24);
|
||||
smram_map[SMRAM_FIELD_SS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e20);
|
||||
smram_map[SMRAM_FIELD_DS_BASE_HI32] = SMRAM_TRANSLATE(0x7e3c);
|
||||
smram_map[SMRAM_FIELD_DS_BASE] = SMRAM_TRANSLATE(0x7e38);
|
||||
smram_map[SMRAM_FIELD_DS_LIMIT] = SMRAM_TRANSLATE(0x7e34);
|
||||
smram_map[SMRAM_FIELD_DS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e30);
|
||||
smram_map[SMRAM_FIELD_FS_BASE_HI32] = SMRAM_TRANSLATE(0x7e4c);
|
||||
smram_map[SMRAM_FIELD_FS_BASE] = SMRAM_TRANSLATE(0x7e48);
|
||||
smram_map[SMRAM_FIELD_FS_LIMIT] = SMRAM_TRANSLATE(0x7e44);
|
||||
smram_map[SMRAM_FIELD_FS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e40);
|
||||
smram_map[SMRAM_FIELD_GS_BASE_HI32] = SMRAM_TRANSLATE(0x7e5c);
|
||||
smram_map[SMRAM_FIELD_GS_BASE] = SMRAM_TRANSLATE(0x7e58);
|
||||
smram_map[SMRAM_FIELD_GS_LIMIT] = SMRAM_TRANSLATE(0x7e54);
|
||||
smram_map[SMRAM_FIELD_GS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7e50);
|
||||
|
||||
for (unsigned n=0; n<SMRAM_FIELD_LAST;n++) {
|
||||
if (smram_map[n] >= SMM_SAVE_STATE_MAP_SIZE) {
|
||||
BX_PANIC(("smram map[%d] = %d", n, smram_map[n]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// source for Intel P6 SMM save state map used: www.sandpile.org
|
||||
|
||||
void BX_CPU_C::init_SMRAM(void)
|
||||
{
|
||||
smram_map[SMRAM_FIELD_SMBASE_OFFSET] = SMRAM_TRANSLATE(0x7ef8);
|
||||
smram_map[SMRAM_FIELD_SMM_REVISION_ID] = SMRAM_TRANSLATE(0x7efc);
|
||||
smram_map[SMRAM_FIELD_EAX] = SMRAM_TRANSLATE(0x7fd0);
|
||||
smram_map[SMRAM_FIELD_ECX] = SMRAM_TRANSLATE(0x7fd4);
|
||||
smram_map[SMRAM_FIELD_EDX] = SMRAM_TRANSLATE(0x7fd8);
|
||||
smram_map[SMRAM_FIELD_EBX] = SMRAM_TRANSLATE(0x7fdc);
|
||||
smram_map[SMRAM_FIELD_ESP] = SMRAM_TRANSLATE(0x7fe0);
|
||||
smram_map[SMRAM_FIELD_EBP] = SMRAM_TRANSLATE(0x7fe4);
|
||||
smram_map[SMRAM_FIELD_ESI] = SMRAM_TRANSLATE(0x7fe8);
|
||||
smram_map[SMRAM_FIELD_EDI] = SMRAM_TRANSLATE(0x7fec);
|
||||
smram_map[SMRAM_FIELD_EIP] = SMRAM_TRANSLATE(0x7ff0);
|
||||
smram_map[SMRAM_FIELD_EFLAGS] = SMRAM_TRANSLATE(0x7ff4);
|
||||
smram_map[SMRAM_FIELD_DR6] = SMRAM_TRANSLATE(0x7fcc);
|
||||
smram_map[SMRAM_FIELD_DR7] = SMRAM_TRANSLATE(0x7fc8);
|
||||
smram_map[SMRAM_FIELD_CR0] = SMRAM_TRANSLATE(0x7ffc);
|
||||
smram_map[SMRAM_FIELD_CR3] = SMRAM_TRANSLATE(0x7ff8);
|
||||
smram_map[SMRAM_FIELD_CR4] = SMRAM_TRANSLATE(0x7f14);
|
||||
smram_map[SMRAM_FIELD_IO_INSTRUCTION_RESTART] = SMRAM_TRANSLATE(0x7f00);
|
||||
smram_map[SMRAM_FIELD_AUTOHALT_RESTART] = SMRAM_TRANSLATE(0x7f00);
|
||||
smram_map[SMRAM_FIELD_NMI_MASK] = SMRAM_TRANSLATE(0x7f00);
|
||||
smram_map[SMRAM_FIELD_TR_SELECTOR] = SMRAM_TRANSLATE(0x7fc4);
|
||||
smram_map[SMRAM_FIELD_TR_BASE] = SMRAM_TRANSLATE(0x7f64);
|
||||
smram_map[SMRAM_FIELD_TR_LIMIT] = SMRAM_TRANSLATE(0x7f60);
|
||||
smram_map[SMRAM_FIELD_TR_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f5c);
|
||||
smram_map[SMRAM_FIELD_LDTR_SELECTOR] = SMRAM_TRANSLATE(0x7fc0);
|
||||
smram_map[SMRAM_FIELD_LDTR_BASE] = SMRAM_TRANSLATE(0x7f80);
|
||||
smram_map[SMRAM_FIELD_LDTR_LIMIT] = SMRAM_TRANSLATE(0x7f7c);
|
||||
smram_map[SMRAM_FIELD_LDTR_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f78);
|
||||
smram_map[SMRAM_FIELD_IDTR_BASE] = SMRAM_TRANSLATE(0x7f58);
|
||||
smram_map[SMRAM_FIELD_IDTR_LIMIT] = SMRAM_TRANSLATE(0x7f54);
|
||||
smram_map[SMRAM_FIELD_GDTR_BASE] = SMRAM_TRANSLATE(0x7f74);
|
||||
smram_map[SMRAM_FIELD_GDTR_LIMIT] = SMRAM_TRANSLATE(0x7f70);
|
||||
smram_map[SMRAM_FIELD_ES_SELECTOR] = SMRAM_TRANSLATE(0x7fa8);
|
||||
smram_map[SMRAM_FIELD_ES_BASE] = SMRAM_TRANSLATE(0x7f8c);
|
||||
smram_map[SMRAM_FIELD_ES_LIMIT] = SMRAM_TRANSLATE(0x7f88);
|
||||
smram_map[SMRAM_FIELD_ES_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f84);
|
||||
smram_map[SMRAM_FIELD_CS_SELECTOR] = SMRAM_TRANSLATE(0x7fac);
|
||||
smram_map[SMRAM_FIELD_CS_BASE] = SMRAM_TRANSLATE(0x7f98);
|
||||
smram_map[SMRAM_FIELD_CS_LIMIT] = SMRAM_TRANSLATE(0x7f94);
|
||||
smram_map[SMRAM_FIELD_CS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f90);
|
||||
smram_map[SMRAM_FIELD_SS_SELECTOR] = SMRAM_TRANSLATE(0x7fb0);
|
||||
smram_map[SMRAM_FIELD_SS_BASE] = SMRAM_TRANSLATE(0x7fa4);
|
||||
smram_map[SMRAM_FIELD_SS_LIMIT] = SMRAM_TRANSLATE(0x7fa0);
|
||||
smram_map[SMRAM_FIELD_SS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f9c);
|
||||
smram_map[SMRAM_FIELD_DS_SELECTOR] = SMRAM_TRANSLATE(0x7fb4);
|
||||
smram_map[SMRAM_FIELD_DS_BASE] = SMRAM_TRANSLATE(0x7f34);
|
||||
smram_map[SMRAM_FIELD_DS_LIMIT] = SMRAM_TRANSLATE(0x7f30);
|
||||
smram_map[SMRAM_FIELD_DS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f2c);
|
||||
smram_map[SMRAM_FIELD_FS_SELECTOR] = SMRAM_TRANSLATE(0x7fb8);
|
||||
smram_map[SMRAM_FIELD_FS_BASE] = SMRAM_TRANSLATE(0x7f40);
|
||||
smram_map[SMRAM_FIELD_FS_LIMIT] = SMRAM_TRANSLATE(0x7f3c);
|
||||
smram_map[SMRAM_FIELD_FS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f38);
|
||||
smram_map[SMRAM_FIELD_GS_SELECTOR] = SMRAM_TRANSLATE(0x7fbc);
|
||||
smram_map[SMRAM_FIELD_GS_BASE] = SMRAM_TRANSLATE(0x7f4c);
|
||||
smram_map[SMRAM_FIELD_GS_LIMIT] = SMRAM_TRANSLATE(0x7f48);
|
||||
smram_map[SMRAM_FIELD_GS_SELECTOR_AR] = SMRAM_TRANSLATE(0x7f44);
|
||||
|
||||
for (unsigned n=0; n<SMRAM_FIELD_LAST;n++) {
|
||||
if (smram_map[n] >= SMM_SAVE_STATE_MAP_SIZE) {
|
||||
BX_PANIC(("smram map[%d] = %d", n, smram_map[n]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define SMRAM_FIELD(state, field) (state[smram_map[field]])
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
|
||||
@ -213,129 +397,68 @@ BX_CPP_INLINE Bit64u SMRAM_FIELD64(const Bit32u *saved_state, unsigned hi, unsig
|
||||
void BX_CPU_C::smram_save_state(Bit32u *saved_state)
|
||||
{
|
||||
// --- General Purpose Registers --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RAX_HI32) = (Bit32u)(RAX >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RAX_LO32) = EAX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RCX_HI32) = (Bit32u)(RCX >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RCX_LO32) = ECX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDX_HI32) = (Bit32u)(RDX >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDX_LO32) = EDX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBX_HI32) = (Bit32u)(RBX >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBX_LO32) = EBX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSP_HI32) = (Bit32u)(RSP >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSP_LO32) = ESP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBP_HI32) = (Bit32u)(RBP >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RBP_LO32) = EBP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSI_HI32) = (Bit32u)(RSI >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RSI_LO32) = ESI;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDI_HI32) = (Bit32u)(RDI >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RDI_LO32) = EDI;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R8_HI32) = (Bit32u)(R8 >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R8_LO32) = (Bit32u)(R8 & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R9_HI32) = (Bit32u)(R9 >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R9_LO32) = (Bit32u)(R9 & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R10_HI32) = (Bit32u)(R10 >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R10_LO32) = (Bit32u)(R10 & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R11_HI32) = (Bit32u)(R11 >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R11_LO32) = (Bit32u)(R11 & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R12_HI32) = (Bit32u)(R12 >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R12_LO32) = (Bit32u)(R12 & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R13_HI32) = (Bit32u)(R13 >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R13_LO32) = (Bit32u)(R13 & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R14_HI32) = (Bit32u)(R14 >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R14_LO32) = (Bit32u)(R14 & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R15_HI32) = (Bit32u)(R15 >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_R15_LO32) = (Bit32u)(R15 & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RIP_HI32) = (Bit32u)(RIP >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RIP_LO32) = EIP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_RFLAGS32) = read_eflags();
|
||||
for (int n=0; n<BX_GENERAL_REGISTERS; n++) {
|
||||
Bit64u val_64 = BX_READ_64BIT_REG(n);
|
||||
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_RAX_HI32 + 2*n) = GET32H(val_64);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_EAX + 2*n) = GET32L(val_64);
|
||||
}
|
||||
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_RIP_HI32) = GET32H(RIP);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_EIP) = EIP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_EFLAGS) = read_eflags();
|
||||
|
||||
// --- Debug and Control Registers --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6) = BX_CPU_THIS_PTR dr6;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7) = BX_CPU_THIS_PTR dr7;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0) = BX_CPU_THIS_PTR cr0.get32();
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3) = BX_CPU_THIS_PTR cr3;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4) = BX_CPU_THIS_PTR cr4.get32();
|
||||
/* base+0x7f44 to base+0x7f04 is reserved */
|
||||
SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET) = BX_CPU_THIS_PTR smbase;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SMM_REVISION_ID) = SMM_REVISION_ID;
|
||||
/* base+0x7ef8 to base+0x7ed8 is reserved */
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFER) = BX_CPU_THIS_PTR efer.get32();
|
||||
/* base+0x7ecc is reserved */
|
||||
/* base+0x7ec8 is I/O Instruction Restart, Auto-Halt Restart and NMI Mask */
|
||||
/* base+0x7ec4 is reserved */
|
||||
/* base+0x7ec0 is SMM I/O Trap */
|
||||
/* base+0x7ebc to base+0x7ea0 is reserved */
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6) = BX_CPU_THIS_PTR dr6;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7) = BX_CPU_THIS_PTR dr7;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR0) = BX_CPU_THIS_PTR cr0.get32();
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR3_HI32) = GET32H(BX_CPU_THIS_PTR cr3);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR3) = GET32L(BX_CPU_THIS_PTR cr3);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR4) = BX_CPU_THIS_PTR cr4.get32();
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_EFER) = BX_CPU_THIS_PTR efer.get32();
|
||||
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_SMBASE_OFFSET) = BX_CPU_THIS_PTR smbase;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_SMM_REVISION_ID) = SMM_REVISION_ID;
|
||||
|
||||
// --- Task Register --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_BASE_HI32) = (Bit32u)(BX_CPU_THIS_PTR tr.cache.u.system.base >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_BASE_LO32) = (Bit32u)(BX_CPU_THIS_PTR tr.cache.u.system.base & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_BASE_HI32) = GET32H(BX_CPU_THIS_PTR tr.cache.u.system.base);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_BASE) = GET32L(BX_CPU_THIS_PTR tr.cache.u.system.base);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled;
|
||||
Bit32u tr_ar = ((get_descriptor_h(&BX_CPU_THIS_PTR tr.cache) >> 8) & 0xffff) | (BX_CPU_THIS_PTR tr.cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) = BX_CPU_THIS_PTR tr.selector.value | (tr_ar << 16);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) = BX_CPU_THIS_PTR tr.selector.value | (tr_ar << 16);
|
||||
|
||||
// --- LDTR --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_BASE_HI32) = GET32H(BX_CPU_THIS_PTR ldtr.cache.u.system.base);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_BASE) = GET32L(BX_CPU_THIS_PTR ldtr.cache.u.system.base);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_LIMIT) = BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled;
|
||||
Bit32u ldtr_ar = ((get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache) >> 8) & 0xffff) | (BX_CPU_THIS_PTR ldtr.cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) = BX_CPU_THIS_PTR ldtr.selector.value | (ldtr_ar << 16);
|
||||
|
||||
// --- IDTR --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE_HI32) = (Bit32u)(BX_CPU_THIS_PTR idtr.base >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE_LO32) = (Bit32u)(BX_CPU_THIS_PTR idtr.base & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT) = BX_CPU_THIS_PTR idtr.limit;
|
||||
// --- LDTR --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE_HI32) = (Bit32u)(BX_CPU_THIS_PTR ldtr.cache.u.system.base >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE_LO32) = (Bit32u)(BX_CPU_THIS_PTR ldtr.cache.u.system.base & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT) = BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled;
|
||||
Bit32u ldtr_ar = ((get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache) >> 8) & 0xffff) | (BX_CPU_THIS_PTR ldtr.cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) = BX_CPU_THIS_PTR ldtr.selector.value | (ldtr_ar << 16);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_BASE_HI32) = GET32H(BX_CPU_THIS_PTR idtr.base);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_BASE) = GET32L(BX_CPU_THIS_PTR idtr.base);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_LIMIT) = BX_CPU_THIS_PTR idtr.limit;
|
||||
|
||||
// --- GDTR --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE_HI32) = (Bit32u)(BX_CPU_THIS_PTR gdtr.base >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE_LO32) = (Bit32u)(BX_CPU_THIS_PTR gdtr.base & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT) = BX_CPU_THIS_PTR gdtr.limit;
|
||||
// --- GS selector --- //
|
||||
bx_segment_reg_t *seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_BASE_HI32) = GET32H(BX_CPU_THIS_PTR gdtr.base);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_BASE) = GET32L(BX_CPU_THIS_PTR gdtr.base);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_LIMIT) = BX_CPU_THIS_PTR gdtr.limit;
|
||||
|
||||
for (int segreg = 0; segreg < 6; segreg++) {
|
||||
bx_segment_reg_t *seg = &(BX_CPU_THIS_PTR sregs[segreg]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_BASE_HI32 + 4*segreg) = GET32H(seg->cache.u.segment.base);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_BASE + 4*segreg) = GET32L(seg->cache.u.segment.base);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_LIMIT + 4*segreg) = seg->cache.u.segment.limit_scaled;
|
||||
Bit32u seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
// --- FS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
// --- DS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
// --- SS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
// --- CS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
// --- ES selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_BASE_HI32) = (Bit32u)(seg->cache.u.segment.base >> 32);
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_BASE_LO32) = (Bit32u)(seg->cache.u.segment.base & 0xffffffff);
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) = seg->selector.value | (seg_ar << 16);
|
||||
}
|
||||
}
|
||||
|
||||
bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
{
|
||||
Bit32u temp_cr0 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0);
|
||||
Bit32u temp_eflags = SMRAM_FIELD(saved_state, SMRAM_OFFSET_RFLAGS32);
|
||||
Bit32u temp_efer = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFER);
|
||||
Bit32u temp_cr0 = SMRAM_FIELD(saved_state, SMRAM_FIELD_CR0);
|
||||
Bit32u temp_eflags = SMRAM_FIELD(saved_state, SMRAM_FIELD_EFLAGS);
|
||||
Bit32u temp_efer = SMRAM_FIELD(saved_state, SMRAM_FIELD_EFER);
|
||||
|
||||
bx_bool pe = (temp_cr0 & 0x1);
|
||||
bx_bool nw = (temp_cr0 >> 29) & 0x1;
|
||||
@ -354,7 +477,7 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
}
|
||||
|
||||
// shutdown if write to reserved CR4 bits
|
||||
if (! SetCR4(SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4))) {
|
||||
if (! SetCR4(SMRAM_FIELD(saved_state, SMRAM_FIELD_CR4))) {
|
||||
BX_PANIC(("SMM restore: incorrect CR4 state !"));
|
||||
return 0;
|
||||
}
|
||||
@ -394,121 +517,49 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
}
|
||||
setEFlags(temp_eflags);
|
||||
|
||||
bx_phy_address temp_cr3 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3);
|
||||
bx_phy_address temp_cr3 = SMRAM_FIELD64(saved_state, SMRAM_FIELD_CR3_HI32, SMRAM_FIELD_CR3);
|
||||
SetCR3(temp_cr3);
|
||||
|
||||
RAX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RAX_HI32, SMRAM_OFFSET_RAX_LO32);
|
||||
RBX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RBX_HI32, SMRAM_OFFSET_RBX_LO32);
|
||||
RCX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RCX_HI32, SMRAM_OFFSET_RCX_LO32);
|
||||
RDX = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RDX_HI32, SMRAM_OFFSET_RDX_LO32);
|
||||
RSP = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RSP_HI32, SMRAM_OFFSET_RSP_LO32);
|
||||
RBP = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RBP_HI32, SMRAM_OFFSET_RBP_LO32);
|
||||
RSI = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RSI_HI32, SMRAM_OFFSET_RSI_LO32);
|
||||
RDI = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RDI_HI32, SMRAM_OFFSET_RDI_LO32);
|
||||
R8 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R8_HI32, SMRAM_OFFSET_R8_LO32);
|
||||
R9 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R9_HI32, SMRAM_OFFSET_R9_LO32);
|
||||
R10 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R10_HI32, SMRAM_OFFSET_R10_LO32);
|
||||
R11 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R11_HI32, SMRAM_OFFSET_R11_LO32);
|
||||
R12 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R12_HI32, SMRAM_OFFSET_R12_LO32);
|
||||
R13 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R13_HI32, SMRAM_OFFSET_R13_LO32);
|
||||
R14 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R14_HI32, SMRAM_OFFSET_R14_LO32);
|
||||
R15 = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_R15_HI32, SMRAM_OFFSET_R15_LO32);
|
||||
RIP = SMRAM_FIELD64(saved_state, SMRAM_OFFSET_RIP_HI32, SMRAM_OFFSET_RIP_LO32);
|
||||
for (int n=0; n<BX_GENERAL_REGISTERS; n++) {
|
||||
Bit64u val_64 = SMRAM_FIELD64(saved_state,
|
||||
SMRAM_FIELD_RAX_HI32 + 2*n, SMRAM_FIELD_EAX + 2*n);
|
||||
|
||||
BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6);
|
||||
BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7);
|
||||
BX_WRITE_64BIT_REG(n, val_64);
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR gdtr.base = SMRAM_FIELD64(saved_state, SMRAM_GDTR_BASE_HI32, SMRAM_GDTR_BASE_LO32);
|
||||
BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT);
|
||||
BX_CPU_THIS_PTR idtr.base = SMRAM_FIELD64(saved_state, SMRAM_IDTR_BASE_HI32, SMRAM_IDTR_BASE_LO32);
|
||||
BX_CPU_THIS_PTR idtr.limit = SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT);
|
||||
RIP = SMRAM_FIELD64(saved_state, SMRAM_FIELD_RIP_HI32, SMRAM_FIELD_EIP);
|
||||
|
||||
Bit16u ar_data = SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS],
|
||||
BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6);
|
||||
BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7);
|
||||
|
||||
BX_CPU_THIS_PTR gdtr.base = SMRAM_FIELD64(saved_state, SMRAM_FIELD_GDTR_BASE_HI32, SMRAM_FIELD_GDTR_BASE);
|
||||
BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_LIMIT);
|
||||
BX_CPU_THIS_PTR idtr.base = SMRAM_FIELD64(saved_state, SMRAM_FIELD_IDTR_BASE_HI32, SMRAM_FIELD_IDTR_BASE);
|
||||
BX_CPU_THIS_PTR idtr.limit = SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_LIMIT);
|
||||
|
||||
for (int segreg = 0; segreg < 6; segreg++) {
|
||||
Bit16u ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[segreg],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_CS_BASE_HI32, SMRAM_CS_BASE_LO32),
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT), ar_data))
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_FIELD_ES_BASE_HI32 + 4*segreg, SMRAM_FIELD_ES_BASE + 4*segreg),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_LIMIT + 4*segreg), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment CS !"));
|
||||
if (! BX_CPU_THIS_PTR sregs[segreg].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment %d !", segreg));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleCpuModeChange();
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_DS_BASE_HI32, SMRAM_DS_BASE_LO32),
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment DS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_SS_BASE_HI32, SMRAM_SS_BASE_LO32),
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment SS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_ES_BASE_HI32, SMRAM_ES_BASE_LO32),
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment ES !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_FS_BASE_HI32, SMRAM_FS_BASE_LO32),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment FS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_GS_BASE_HI32, SMRAM_GS_BASE_LO32),
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment GS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) >> 16;
|
||||
Bit16u ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR ldtr,
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_LDTR_BASE_HI32, SMRAM_LDTR_BASE_LO32),
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT), ar_data))
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_FIELD_LDTR_BASE_HI32, SMRAM_FIELD_LDTR_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_LIMIT), ar_data))
|
||||
{
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.type != BX_SYS_SEGMENT_LDT) {
|
||||
BX_PANIC(("SMM restore: LDTR is not LDT descriptor type !"));
|
||||
@ -516,12 +567,12 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) >> 16;
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR tr,
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_TR_BASE_HI32, SMRAM_TR_BASE_LO32),
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT), ar_data))
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD64(saved_state, SMRAM_FIELD_TR_BASE_HI32, SMRAM_FIELD_TR_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_LIMIT), ar_data))
|
||||
{
|
||||
if (BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_286_TSS &&
|
||||
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_286_TSS &&
|
||||
@ -534,7 +585,7 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
}
|
||||
|
||||
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION)
|
||||
BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET);
|
||||
BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_FIELD_SMBASE_OFFSET);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -543,111 +594,62 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
|
||||
void BX_CPU_C::smram_save_state(Bit32u *saved_state)
|
||||
{
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0) = BX_CPU_THIS_PTR cr0.get32();
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3) = BX_CPU_THIS_PTR cr3;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFLAGS) = read_eflags();
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EIP) = EIP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDI) = EDI;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESI) = ESI;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBP) = EBP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESP) = ESP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBX) = EBX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDX) = EDX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_ECX) = ECX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_EAX) = EAX;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6) = BX_CPU_THIS_PTR dr6;
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7) = BX_CPU_THIS_PTR dr7;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR) = BX_CPU_THIS_PTR tr.selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR) = BX_CPU_THIS_PTR ldtr.selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_SMM_REVISION_ID) = SMM_REVISION_ID;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_SMBASE_OFFSET) = BX_CPU_THIS_PTR smbase;
|
||||
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR) =
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].selector.value;
|
||||
for (int n=0; n<BX_GENERAL_REGISTERS; n++) {
|
||||
Bit32u val_32 = BX_READ_32BIT_REG(n);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_EAX + n) = val_32;
|
||||
}
|
||||
|
||||
// --- SS selector --- //
|
||||
bx_segment_reg_t *seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
Bit32u seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
// --- CS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
// --- ES selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
// --- LDTR --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE) = BX_CPU_THIS_PTR ldtr.cache.u.system.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT) = BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled;
|
||||
Bit32u ldtr_ar = ((get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache) >> 8) & 0xffff) | (BX_CPU_THIS_PTR ldtr.cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) = BX_CPU_THIS_PTR ldtr.selector.value | (ldtr_ar << 16);
|
||||
// --- GDTR --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE) = BX_CPU_THIS_PTR gdtr.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT) = BX_CPU_THIS_PTR gdtr.limit;
|
||||
/* base+0x7f6c is reserved */
|
||||
/* base+0x7f68 is reserved */
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_EIP) = EIP;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_EFLAGS) = read_eflags();
|
||||
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR0) = BX_CPU_THIS_PTR cr0.get32();
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR3) = BX_CPU_THIS_PTR cr3;
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_CR4) = BX_CPU_THIS_PTR cr4.get32();
|
||||
#endif
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6) = BX_CPU_THIS_PTR dr6;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7) = BX_CPU_THIS_PTR dr7;
|
||||
|
||||
// --- Task Register --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_BASE) = BX_CPU_THIS_PTR tr.cache.u.system.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR) = BX_CPU_THIS_PTR tr.selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_BASE) = BX_CPU_THIS_PTR tr.cache.u.system.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_LIMIT) = BX_CPU_THIS_PTR tr.cache.u.system.limit_scaled;
|
||||
Bit32u tr_ar = ((get_descriptor_h(&BX_CPU_THIS_PTR tr.cache) >> 8) & 0xffff) | (BX_CPU_THIS_PTR tr.cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) = BX_CPU_THIS_PTR tr.selector.value | (tr_ar << 16);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) = BX_CPU_THIS_PTR tr.selector.value | (tr_ar << 16);
|
||||
|
||||
// --- LDTR --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR) = BX_CPU_THIS_PTR ldtr.selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_BASE) = BX_CPU_THIS_PTR ldtr.cache.u.system.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_LIMIT) = BX_CPU_THIS_PTR ldtr.cache.u.system.limit_scaled;
|
||||
Bit32u ldtr_ar = ((get_descriptor_h(&BX_CPU_THIS_PTR ldtr.cache) >> 8) & 0xffff) | (BX_CPU_THIS_PTR ldtr.cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) = BX_CPU_THIS_PTR ldtr.selector.value | (ldtr_ar << 16);
|
||||
|
||||
// --- IDTR --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE) = BX_CPU_THIS_PTR idtr.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT) = BX_CPU_THIS_PTR idtr.limit;
|
||||
/* base+0x7f50 is reserved */
|
||||
// --- GS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
// --- FS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
// --- DS selector --- //
|
||||
seg = &(BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_BASE) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT) = seg->cache.u.segment.limit_scaled;
|
||||
seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) = seg->selector.value | (seg_ar << 16);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_BASE) = BX_CPU_THIS_PTR idtr.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_LIMIT) = BX_CPU_THIS_PTR idtr.limit;
|
||||
|
||||
/* base+0x7f28 to base+7f18 is reserved */
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4) = BX_CPU_THIS_PTR cr4.get32();
|
||||
#endif
|
||||
// --- GDTR --- //
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_BASE) = BX_CPU_THIS_PTR gdtr.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_LIMIT) = BX_CPU_THIS_PTR gdtr.limit;
|
||||
|
||||
/* base+0x7f02 is Auto HALT restart field (2 byte) */
|
||||
/* base+0x7f00 is I/O restart field (2 byte) */
|
||||
SMRAM_FIELD(saved_state, SMRAM_SMM_REVISION_ID) = SMM_REVISION_ID;
|
||||
SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET) = BX_CPU_THIS_PTR smbase;
|
||||
/* base+0x7ef4 to base+0x7e00 is reserved */
|
||||
for (int segreg = 0; segreg < 6; segreg++) {
|
||||
bx_segment_reg_t *seg = &(BX_CPU_THIS_PTR sregs[segreg]);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR + 4*segreg) = seg->selector.value;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_BASE + 4*segreg) = seg->cache.u.segment.base;
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_LIMIT + 4*segreg) = seg->cache.u.segment.limit_scaled;
|
||||
Bit32u seg_ar = ((get_descriptor_h(&seg->cache) >> 8) & 0xffff) | (seg->cache.valid << 8);
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) = seg->selector.value | (seg_ar << 16);
|
||||
}
|
||||
}
|
||||
|
||||
bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
{
|
||||
Bit32u temp_cr0 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR0);
|
||||
Bit32u temp_eflags = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EFLAGS);
|
||||
Bit32u temp_cr3 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR3);
|
||||
Bit32u temp_cr0 = SMRAM_FIELD(saved_state, SMRAM_FIELD_CR0);
|
||||
Bit32u temp_eflags = SMRAM_FIELD(saved_state, SMRAM_FIELD_EFLAGS);
|
||||
Bit32u temp_cr3 = SMRAM_FIELD(saved_state, SMRAM_FIELD_CR3);
|
||||
|
||||
bx_bool pe = (temp_cr0 & 0x01);
|
||||
bx_bool nw = (temp_cr0 >> 29) & 0x01;
|
||||
@ -673,116 +675,49 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
setEFlags(temp_eflags);
|
||||
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
if (! SetCR4(SMRAM_FIELD(saved_state, SMRAM_OFFSET_CR4))) {
|
||||
if (! SetCR4(SMRAM_FIELD(saved_state, SMRAM_FIELD_CR4))) {
|
||||
BX_PANIC(("SMM restore: incorrect CR4 state !"));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
EIP = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EIP);
|
||||
EDI = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDI);
|
||||
ESI = SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESI);
|
||||
EBP = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBP);
|
||||
ESP = SMRAM_FIELD(saved_state, SMRAM_OFFSET_ESP);
|
||||
EBX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EBX);
|
||||
EDX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EDX);
|
||||
ECX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_ECX);
|
||||
EAX = SMRAM_FIELD(saved_state, SMRAM_OFFSET_EAX);
|
||||
for (int n=0; n<BX_GENERAL_REGISTERS; n++) {
|
||||
Bit32u val_32 = SMRAM_FIELD(saved_state, SMRAM_FIELD_EAX + n);
|
||||
BX_WRITE_32BIT_REGZ(n, val_32);
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR6);
|
||||
BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_OFFSET_DR7);
|
||||
EIP = SMRAM_FIELD(saved_state, SMRAM_FIELD_EIP);
|
||||
|
||||
BX_CPU_THIS_PTR gdtr.base = SMRAM_FIELD(saved_state, SMRAM_GDTR_BASE);
|
||||
BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_GDTR_LIMIT);
|
||||
BX_CPU_THIS_PTR idtr.base = SMRAM_FIELD(saved_state, SMRAM_IDTR_BASE);
|
||||
BX_CPU_THIS_PTR idtr.limit = SMRAM_FIELD(saved_state, SMRAM_IDTR_LIMIT);
|
||||
BX_CPU_THIS_PTR dr6 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR6);
|
||||
BX_CPU_THIS_PTR dr7 = SMRAM_FIELD(saved_state, SMRAM_FIELD_DR7);
|
||||
|
||||
Bit16u ar_data = SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS],
|
||||
BX_CPU_THIS_PTR gdtr.base = SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_BASE);
|
||||
BX_CPU_THIS_PTR gdtr.limit = SMRAM_FIELD(saved_state, SMRAM_FIELD_GDTR_LIMIT);
|
||||
|
||||
BX_CPU_THIS_PTR idtr.base = SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_BASE);
|
||||
BX_CPU_THIS_PTR idtr.limit = SMRAM_FIELD(saved_state, SMRAM_FIELD_IDTR_LIMIT);
|
||||
|
||||
for (int segreg = 0; segreg < 6; segreg++) {
|
||||
Bit32u ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[segreg],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_CS_LIMIT), ar_data))
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_SELECTOR_AR + 4*segreg) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_BASE + 4*segreg),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_ES_LIMIT + 4*segreg), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment CS !"));
|
||||
if (! BX_CPU_THIS_PTR sregs[segreg].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment %d !", segreg));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
handleCpuModeChange();
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_DS_LIMIT), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment DS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_SS_LIMIT), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment SS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_ES_LIMIT), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment ES !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FS_LIMIT), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment FS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS],
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_GS_LIMIT), ar_data))
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS].cache.segment) {
|
||||
BX_PANIC(("SMM restore: restored valid non segment GS !"));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) >> 16;
|
||||
Bit32u ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR ldtr,
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_LDTR_LIMIT), ar_data))
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_LDTR_LIMIT), ar_data))
|
||||
{
|
||||
if (BX_CPU_THIS_PTR ldtr.cache.type != BX_SYS_SEGMENT_LDT) {
|
||||
BX_PANIC(("SMM restore: LDTR is not LDT descriptor type !"));
|
||||
@ -790,12 +725,12 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
}
|
||||
}
|
||||
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) >> 16;
|
||||
ar_data = SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) >> 16;
|
||||
if (set_segment_ar_data(&BX_CPU_THIS_PTR tr,
|
||||
(ar_data >> 8) & 1,
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_TR_LIMIT), ar_data))
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_SELECTOR_AR) & 0xffff,
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_BASE),
|
||||
SMRAM_FIELD(saved_state, SMRAM_FIELD_TR_LIMIT), ar_data))
|
||||
{
|
||||
if (BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_AVAIL_286_TSS &&
|
||||
BX_CPU_THIS_PTR tr.cache.type != BX_SYS_SEGMENT_BUSY_286_TSS &&
|
||||
@ -808,7 +743,7 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
}
|
||||
|
||||
if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) {
|
||||
BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_SMBASE_OFFSET);
|
||||
BX_CPU_THIS_PTR smbase = SMRAM_FIELD(saved_state, SMRAM_FIELD_SMBASE_OFFSET);
|
||||
#if BX_CPU_LEVEL < 6
|
||||
if (BX_CPU_THIS_PTR smbase & 0x7fff) {
|
||||
BX_PANIC(("SMM restore: SMBASE must be aligned to 32K !"));
|
||||
|
437
bochs/cpu/smm.h
437
bochs/cpu/smm.h
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: smm.h,v 1.6 2009-01-16 18:18:58 sshwarts Exp $
|
||||
// $Id: smm.h,v 1.7 2009-01-17 22:35:45 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2006 Stanislav Shwartsman
|
||||
@ -29,280 +29,175 @@
|
||||
|
||||
#define SMM_SAVE_STATE_MAP_SIZE 128
|
||||
|
||||
//
|
||||
// - For x86-64 configuration using AMD Athlon 64 512-byte SMM save state map
|
||||
// revision ID according to QEMU/Bochs BIOS
|
||||
//
|
||||
// - For x86-32 configuration using Intel P6 512-byte SMM save state map
|
||||
//
|
||||
|
||||
#define SMM_REVISION_ID \
|
||||
((BX_SUPPORT_X86_64 ? 0x00000064 : 0) | SMM_SMBASE_RELOCATION)
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
|
||||
// for x86-64 configuration using AMD Athlon 64 512-byte SMM save state map
|
||||
// revision ID according to QEMU/Bochs BIOS
|
||||
#define SMM_REVISION_ID (0x00000064 | SMM_SMBASE_RELOCATION)
|
||||
enum SMMRAM_Fields {
|
||||
SMRAM_FIELD_SMBASE_OFFSET = 0,
|
||||
SMRAM_FIELD_SMM_REVISION_ID,
|
||||
SMRAM_FIELD_RAX_HI32,
|
||||
SMRAM_FIELD_EAX,
|
||||
SMRAM_FIELD_RCX_HI32,
|
||||
SMRAM_FIELD_ECX,
|
||||
SMRAM_FIELD_RDX_HI32,
|
||||
SMRAM_FIELD_EDX,
|
||||
SMRAM_FIELD_RBX_HI32,
|
||||
SMRAM_FIELD_EBX,
|
||||
SMRAM_FIELD_RSP_HI32,
|
||||
SMRAM_FIELD_ESP,
|
||||
SMRAM_FIELD_RBP_HI32,
|
||||
SMRAM_FIELD_EBP,
|
||||
SMRAM_FIELD_RSI_HI32,
|
||||
SMRAM_FIELD_ESI,
|
||||
SMRAM_FIELD_RDI_HI32,
|
||||
SMRAM_FIELD_EDI,
|
||||
SMRAM_FIELD_R8_HI32,
|
||||
SMRAM_FIELD_R8,
|
||||
SMRAM_FIELD_R9_HI32,
|
||||
SMRAM_FIELD_R9,
|
||||
SMRAM_FIELD_R10_HI32,
|
||||
SMRAM_FIELD_R10,
|
||||
SMRAM_FIELD_R11_HI32,
|
||||
SMRAM_FIELD_R11,
|
||||
SMRAM_FIELD_R12_HI32,
|
||||
SMRAM_FIELD_R12,
|
||||
SMRAM_FIELD_R13_HI32,
|
||||
SMRAM_FIELD_R13,
|
||||
SMRAM_FIELD_R14_HI32,
|
||||
SMRAM_FIELD_R14,
|
||||
SMRAM_FIELD_R15_HI32,
|
||||
SMRAM_FIELD_R15,
|
||||
SMRAM_FIELD_RIP_HI32,
|
||||
SMRAM_FIELD_EIP,
|
||||
SMRAM_FIELD_RFLAGS_HI32, // always zero
|
||||
SMRAM_FIELD_EFLAGS,
|
||||
SMRAM_FIELD_DR6_HI32, // always zero
|
||||
SMRAM_FIELD_DR6,
|
||||
SMRAM_FIELD_DR7_HI32, // always zero
|
||||
SMRAM_FIELD_DR7,
|
||||
SMRAM_FIELD_CR0_HI32, // always zero
|
||||
SMRAM_FIELD_CR0,
|
||||
SMRAM_FIELD_CR3_HI32, // zero when physical address size 32-bit
|
||||
SMRAM_FIELD_CR3,
|
||||
SMRAM_FIELD_CR4_HI32, // always zero
|
||||
SMRAM_FIELD_CR4,
|
||||
SMRAM_FIELD_EFER_HI32, // always zero
|
||||
SMRAM_FIELD_EFER,
|
||||
SMRAM_FIELD_IO_INSTRUCTION_RESTART,
|
||||
SMRAM_FIELD_AUTOHALT_RESTART,
|
||||
SMRAM_FIELD_NMI_MASK,
|
||||
SMRAM_FIELD_TR_BASE_HI32,
|
||||
SMRAM_FIELD_TR_BASE,
|
||||
SMRAM_FIELD_TR_LIMIT,
|
||||
SMRAM_FIELD_TR_SELECTOR_AR,
|
||||
SMRAM_FIELD_LDTR_BASE_HI32,
|
||||
SMRAM_FIELD_LDTR_BASE,
|
||||
SMRAM_FIELD_LDTR_LIMIT,
|
||||
SMRAM_FIELD_LDTR_SELECTOR_AR,
|
||||
SMRAM_FIELD_IDTR_BASE_HI32,
|
||||
SMRAM_FIELD_IDTR_BASE,
|
||||
SMRAM_FIELD_IDTR_LIMIT,
|
||||
SMRAM_FIELD_GDTR_BASE_HI32,
|
||||
SMRAM_FIELD_GDTR_BASE,
|
||||
SMRAM_FIELD_GDTR_LIMIT,
|
||||
SMRAM_FIELD_ES_BASE_HI32,
|
||||
SMRAM_FIELD_ES_BASE,
|
||||
SMRAM_FIELD_ES_LIMIT,
|
||||
SMRAM_FIELD_ES_SELECTOR_AR,
|
||||
SMRAM_FIELD_CS_BASE_HI32,
|
||||
SMRAM_FIELD_CS_BASE,
|
||||
SMRAM_FIELD_CS_LIMIT,
|
||||
SMRAM_FIELD_CS_SELECTOR_AR,
|
||||
SMRAM_FIELD_SS_BASE_HI32,
|
||||
SMRAM_FIELD_SS_BASE,
|
||||
SMRAM_FIELD_SS_LIMIT,
|
||||
SMRAM_FIELD_SS_SELECTOR_AR,
|
||||
SMRAM_FIELD_DS_BASE_HI32,
|
||||
SMRAM_FIELD_DS_BASE,
|
||||
SMRAM_FIELD_DS_LIMIT,
|
||||
SMRAM_FIELD_DS_SELECTOR_AR,
|
||||
SMRAM_FIELD_FS_BASE_HI32,
|
||||
SMRAM_FIELD_FS_BASE,
|
||||
SMRAM_FIELD_FS_LIMIT,
|
||||
SMRAM_FIELD_FS_SELECTOR_AR,
|
||||
SMRAM_FIELD_GS_BASE_HI32,
|
||||
SMRAM_FIELD_GS_BASE,
|
||||
SMRAM_FIELD_GS_LIMIT,
|
||||
SMRAM_FIELD_GS_SELECTOR_AR,
|
||||
SMRAM_FIELD_LAST
|
||||
};
|
||||
|
||||
#define SMRAM_OFFSET_RAX_HI32 0x7ffc
|
||||
#define SMRAM_OFFSET_RAX_LO32 0x7ff8
|
||||
#define SMRAM_OFFSET_RCX_HI32 0x7ff4
|
||||
#define SMRAM_OFFSET_RCX_LO32 0x7ff0
|
||||
#define SMRAM_OFFSET_RDX_HI32 0x7fec
|
||||
#define SMRAM_OFFSET_RDX_LO32 0x7fe8
|
||||
#define SMRAM_OFFSET_RBX_HI32 0x7fe4
|
||||
#define SMRAM_OFFSET_RBX_LO32 0x7fe0
|
||||
#define SMRAM_OFFSET_RSP_HI32 0x7fdc
|
||||
#define SMRAM_OFFSET_RSP_LO32 0x7fd8
|
||||
#define SMRAM_OFFSET_RBP_HI32 0x7fd4
|
||||
#define SMRAM_OFFSET_RBP_LO32 0x7fd0
|
||||
#define SMRAM_OFFSET_RSI_HI32 0x7fcc
|
||||
#define SMRAM_OFFSET_RSI_LO32 0x7fc8
|
||||
#define SMRAM_OFFSET_RDI_HI32 0x7fc4
|
||||
#define SMRAM_OFFSET_RDI_LO32 0x7fc0
|
||||
#define SMRAM_OFFSET_R8_HI32 0x7fbc
|
||||
#define SMRAM_OFFSET_R8_LO32 0x7fb8
|
||||
#define SMRAM_OFFSET_R9_HI32 0x7fb4
|
||||
#define SMRAM_OFFSET_R9_LO32 0x7fb0
|
||||
#define SMRAM_OFFSET_R10_HI32 0x7fac
|
||||
#define SMRAM_OFFSET_R10_LO32 0x7fa8
|
||||
#define SMRAM_OFFSET_R11_HI32 0x7fa4
|
||||
#define SMRAM_OFFSET_R11_LO32 0x7fa0
|
||||
#define SMRAM_OFFSET_R12_HI32 0x7f9c
|
||||
#define SMRAM_OFFSET_R12_LO32 0x7f98
|
||||
#define SMRAM_OFFSET_R13_HI32 0x7f94
|
||||
#define SMRAM_OFFSET_R13_LO32 0x7f90
|
||||
#define SMRAM_OFFSET_R14_HI32 0x7f8c
|
||||
#define SMRAM_OFFSET_R14_LO32 0x7f88
|
||||
#define SMRAM_OFFSET_R15_HI32 0x7f84
|
||||
#define SMRAM_OFFSET_R15_LO32 0x7f80
|
||||
#define SMRAM_OFFSET_RIP_HI32 0x7f7c
|
||||
#define SMRAM_OFFSET_RIP_LO32 0x7f78
|
||||
// Hi32 part of RFLAGS64 0x7f74 (always zero)
|
||||
#define SMRAM_OFFSET_RFLAGS32 0x7f70
|
||||
// Hi32 part of 64-bit DR6 0x7f6c (always zero)
|
||||
#define SMRAM_OFFSET_DR6 0x7f68
|
||||
// Hi32 part of 64-bit DR7 0x7f64 (always zero)
|
||||
#define SMRAM_OFFSET_DR7 0x7f60
|
||||
// Hi32 part of 64-bit CR0 0x7f5c (always zero)
|
||||
#define SMRAM_OFFSET_CR0 0x7f58
|
||||
// Hi32 part of 64-bit CR3 0x7f54 (always zero, 32-bit physical address)
|
||||
#define SMRAM_OFFSET_CR3 0x7f50
|
||||
// Hi32 part of 64-bit CR4 0x7f4c (always zero)
|
||||
#define SMRAM_OFFSET_CR4 0x7f48
|
||||
// reserved 0x7f44
|
||||
// reserved 0x7f40
|
||||
// reserved 0x7f3c
|
||||
// reserved 0x7f38
|
||||
// reserved 0x7f34
|
||||
// reserved 0x7f30
|
||||
// reserved 0x7f2c
|
||||
// reserved 0x7f28
|
||||
// reserved 0x7f24
|
||||
// reserved 0x7f20
|
||||
// reserved 0x7f1c
|
||||
// reserved 0x7f18
|
||||
// reserved 0x7f14
|
||||
// reserved 0x7f10
|
||||
// reserved 0x7f0c
|
||||
// reserved 0x7f08
|
||||
// reserved 0x7f04
|
||||
#define SMRAM_SMBASE_OFFSET 0x7f00
|
||||
#define SMRAM_SMM_REVISION_ID 0x7efc
|
||||
// reserved 0x7ef8
|
||||
// reserved 0x7ef4
|
||||
// reserved 0x7ef0
|
||||
// reserved 0x7eec
|
||||
// reserved 0x7ee8
|
||||
// reserved 0x7ee4
|
||||
// reserved 0x7ee0
|
||||
// reserved 0x7edc
|
||||
// reserved 0x7ed8
|
||||
// High part of 64-bit EFER 0x7ed4 (always zero)
|
||||
#define SMRAM_OFFSET_EFER 0x7ed0
|
||||
// reserved 0x7ecc
|
||||
#define SMRAM_IO_INSTRUCTION_RESTART 0x7ec8
|
||||
#define SMRAM_AUTOHALT_RESTART 0x7ec8
|
||||
#define SMRAM_NMI_MASK 0x7ec8
|
||||
// reserved 0x7ec4
|
||||
#define SMRAM_SMM_IO_TRAP 0x7ec0
|
||||
// reserved 0x7ebc
|
||||
// reserved 0x7eb8
|
||||
// reserved 0x7eb4
|
||||
// reserved 0x7eb0
|
||||
// reserved 0x7eac
|
||||
// reserved 0x7ea8
|
||||
// reserved 0x7ea4
|
||||
// reserved 0x7ea0
|
||||
#define SMRAM_TR_BASE_HI32 0x7e9c
|
||||
#define SMRAM_TR_BASE_LO32 0x7e98
|
||||
#define SMRAM_TR_LIMIT 0x7e94
|
||||
#define SMRAM_TR_SELECTOR_AR 0x7e90
|
||||
#define SMRAM_IDTR_BASE_HI32 0x7e8c
|
||||
#define SMRAM_IDTR_BASE_LO32 0x7e88
|
||||
#define SMRAM_IDTR_LIMIT 0x7e84
|
||||
// reserved 0x7e80
|
||||
#define SMRAM_LDTR_BASE_HI32 0x7e7c
|
||||
#define SMRAM_LDTR_BASE_LO32 0x7e78
|
||||
#define SMRAM_LDTR_LIMIT 0x7e74
|
||||
#define SMRAM_LDTR_SELECTOR_AR 0x7e70
|
||||
#define SMRAM_GDTR_BASE_HI32 0x7e6c
|
||||
#define SMRAM_GDTR_BASE_LO32 0x7e68
|
||||
#define SMRAM_GDTR_LIMIT 0x7e64
|
||||
// reserved 0x7e60
|
||||
#define SMRAM_GS_BASE_HI32 0x7e5c
|
||||
#define SMRAM_GS_BASE_LO32 0x7e58
|
||||
#define SMRAM_GS_LIMIT 0x7e54
|
||||
#define SMRAM_GS_SELECTOR_AR 0x7e50
|
||||
#define SMRAM_FS_BASE_HI32 0x7e4c
|
||||
#define SMRAM_FS_BASE_LO32 0x7e48
|
||||
#define SMRAM_FS_LIMIT 0x7e44
|
||||
#define SMRAM_FS_SELECTOR_AR 0x7e40
|
||||
#define SMRAM_DS_BASE_HI32 0x7e3c
|
||||
#define SMRAM_DS_BASE_LO32 0x7e38
|
||||
#define SMRAM_DS_LIMIT 0x7e34
|
||||
#define SMRAM_DS_SELECTOR_AR 0x7e30
|
||||
#define SMRAM_SS_BASE_HI32 0x7e2c
|
||||
#define SMRAM_SS_BASE_LO32 0x7e28
|
||||
#define SMRAM_SS_LIMIT 0x7e24
|
||||
#define SMRAM_SS_SELECTOR_AR 0x7e20
|
||||
#define SMRAM_CS_BASE_HI32 0x7e1c
|
||||
#define SMRAM_CS_BASE_LO32 0x7e18
|
||||
#define SMRAM_CS_LIMIT 0x7e14
|
||||
#define SMRAM_CS_SELECTOR_AR 0x7e10
|
||||
#define SMRAM_ES_BASE_HI32 0x7e0c
|
||||
#define SMRAM_ES_BASE_LO32 0x7e08
|
||||
#define SMRAM_ES_LIMIT 0x7e04
|
||||
#define SMRAM_ES_SELECTOR_AR 0x7e00
|
||||
#else
|
||||
|
||||
#else /* BX_SUPPORT_X86_64 == 0 */
|
||||
enum SMMRAM_Fields {
|
||||
SMRAM_FIELD_SMBASE_OFFSET = 0,
|
||||
SMRAM_FIELD_SMM_REVISION_ID,
|
||||
SMRAM_FIELD_EAX,
|
||||
SMRAM_FIELD_ECX,
|
||||
SMRAM_FIELD_EDX,
|
||||
SMRAM_FIELD_EBX,
|
||||
SMRAM_FIELD_ESP,
|
||||
SMRAM_FIELD_EBP,
|
||||
SMRAM_FIELD_ESI,
|
||||
SMRAM_FIELD_EDI,
|
||||
SMRAM_FIELD_EIP,
|
||||
SMRAM_FIELD_EFLAGS,
|
||||
SMRAM_FIELD_DR6,
|
||||
SMRAM_FIELD_DR7,
|
||||
SMRAM_FIELD_CR0,
|
||||
SMRAM_FIELD_CR3,
|
||||
SMRAM_FIELD_CR4,
|
||||
SMRAM_FIELD_IO_INSTRUCTION_RESTART,
|
||||
SMRAM_FIELD_AUTOHALT_RESTART,
|
||||
SMRAM_FIELD_NMI_MASK,
|
||||
SMRAM_FIELD_TR_SELECTOR,
|
||||
SMRAM_FIELD_TR_BASE,
|
||||
SMRAM_FIELD_TR_LIMIT,
|
||||
SMRAM_FIELD_TR_SELECTOR_AR,
|
||||
SMRAM_FIELD_LDTR_SELECTOR,
|
||||
SMRAM_FIELD_LDTR_BASE,
|
||||
SMRAM_FIELD_LDTR_LIMIT,
|
||||
SMRAM_FIELD_LDTR_SELECTOR_AR,
|
||||
SMRAM_FIELD_IDTR_BASE,
|
||||
SMRAM_FIELD_IDTR_LIMIT,
|
||||
SMRAM_FIELD_GDTR_BASE,
|
||||
SMRAM_FIELD_GDTR_LIMIT,
|
||||
SMRAM_FIELD_ES_SELECTOR,
|
||||
SMRAM_FIELD_ES_BASE,
|
||||
SMRAM_FIELD_ES_LIMIT,
|
||||
SMRAM_FIELD_ES_SELECTOR_AR,
|
||||
SMRAM_FIELD_CS_SELECTOR,
|
||||
SMRAM_FIELD_CS_BASE,
|
||||
SMRAM_FIELD_CS_LIMIT,
|
||||
SMRAM_FIELD_CS_SELECTOR_AR,
|
||||
SMRAM_FIELD_SS_SELECTOR,
|
||||
SMRAM_FIELD_SS_BASE,
|
||||
SMRAM_FIELD_SS_LIMIT,
|
||||
SMRAM_FIELD_SS_SELECTOR_AR,
|
||||
SMRAM_FIELD_DS_SELECTOR,
|
||||
SMRAM_FIELD_DS_BASE,
|
||||
SMRAM_FIELD_DS_LIMIT,
|
||||
SMRAM_FIELD_DS_SELECTOR_AR,
|
||||
SMRAM_FIELD_FS_SELECTOR,
|
||||
SMRAM_FIELD_FS_BASE,
|
||||
SMRAM_FIELD_FS_LIMIT,
|
||||
SMRAM_FIELD_FS_SELECTOR_AR,
|
||||
SMRAM_FIELD_GS_SELECTOR,
|
||||
SMRAM_FIELD_GS_BASE,
|
||||
SMRAM_FIELD_GS_LIMIT,
|
||||
SMRAM_FIELD_GS_SELECTOR_AR,
|
||||
SMRAM_FIELD_LAST
|
||||
};
|
||||
|
||||
// for x86-32 configuration using Intel P6 512-byte SMM save state map
|
||||
#define SMM_REVISION_ID (0x00000000 | SMM_SMBASE_RELOCATION)
|
||||
|
||||
// source for Intel P6 SMM save state map used: www.sandpile.org
|
||||
|
||||
#define SMRAM_OFFSET_CR0 0x7ffc
|
||||
#define SMRAM_OFFSET_CR3 0x7ff8
|
||||
#define SMRAM_OFFSET_EFLAGS 0x7ff4
|
||||
#define SMRAM_OFFSET_EIP 0x7ff0
|
||||
#define SMRAM_OFFSET_EDI 0x7fec
|
||||
#define SMRAM_OFFSET_ESI 0x7fe8
|
||||
#define SMRAM_OFFSET_EBP 0x7fe4
|
||||
#define SMRAM_OFFSET_ESP 0x7fe0
|
||||
#define SMRAM_OFFSET_EBX 0x7fdc
|
||||
#define SMRAM_OFFSET_EDX 0x7fd8
|
||||
#define SMRAM_OFFSET_ECX 0x7fd4
|
||||
#define SMRAM_OFFSET_EAX 0x7fd0
|
||||
#define SMRAM_OFFSET_DR6 0x7fcc
|
||||
#define SMRAM_OFFSET_DR7 0x7fc8
|
||||
#define SMRAM_TR_SELECTOR 0x7fc4
|
||||
#define SMRAM_LDTR_SELECTOR 0x7fc0
|
||||
#define SMRAM_GS_SELECTOR 0x7fbc
|
||||
#define SMRAM_FS_SELECTOR 0x7fb8
|
||||
#define SMRAM_DS_SELECTOR 0x7fb4
|
||||
#define SMRAM_SS_SELECTOR 0x7fb0
|
||||
#define SMRAM_CS_SELECTOR 0x7fac
|
||||
#define SMRAM_ES_SELECTOR 0x7fa8
|
||||
#define SMRAM_SS_BASE 0x7fa4
|
||||
#define SMRAM_SS_LIMIT 0x7fa0
|
||||
#define SMRAM_SS_SELECTOR_AR 0x7f9c
|
||||
#define SMRAM_CS_BASE 0x7f98
|
||||
#define SMRAM_CS_LIMIT 0x7f94
|
||||
#define SMRAM_CS_SELECTOR_AR 0x7f90
|
||||
#define SMRAM_ES_BASE 0x7f8c
|
||||
#define SMRAM_ES_LIMIT 0x7f88
|
||||
#define SMRAM_ES_SELECTOR_AR 0x7f84
|
||||
#define SMRAM_LDTR_BASE 0x7f80
|
||||
#define SMRAM_LDTR_LIMIT 0x7f7c
|
||||
#define SMRAM_LDTR_SELECTOR_AR 0x7f78
|
||||
#define SMRAM_GDTR_BASE 0x7f74
|
||||
#define SMRAM_GDTR_LIMIT 0x7f70
|
||||
// reserved 0x7f6c
|
||||
// reserved 0x7f68
|
||||
#define SMRAM_TR_BASE 0x7f64
|
||||
#define SMRAM_TR_LIMIT 0x7f60
|
||||
#define SMRAM_TR_SELECTOR_AR 0x7f5c
|
||||
#define SMRAM_IDTR_BASE 0x7f58
|
||||
#define SMRAM_IDTR_LIMIT 0x7f54
|
||||
// reserved 0x7f50
|
||||
#define SMRAM_GS_BASE 0x7f4c
|
||||
#define SMRAM_GS_LIMIT 0x7f48
|
||||
#define SMRAM_GS_SELECTOR_AR 0x7f44
|
||||
#define SMRAM_FS_BASE 0x7f40
|
||||
#define SMRAM_FS_LIMIT 0x7f3c
|
||||
#define SMRAM_FS_SELECTOR_AR 0x7f38
|
||||
#define SMRAM_DS_BASE 0x7f34
|
||||
#define SMRAM_DS_LIMIT 0x7f30
|
||||
#define SMRAM_DS_SELECTOR_AR 0x7f2c
|
||||
// reserved 0x7f28
|
||||
// reserved 0x7f24
|
||||
// reserved 0x7f20
|
||||
// reserved 0x7f1c
|
||||
// reserved 0x7f18
|
||||
#define SMRAM_OFFSET_CR4 0x7f14
|
||||
// reserved 0x7f10 (used for I/O restart)
|
||||
// reserved 0x7f0c (used for I/O restart)
|
||||
// reserved 0x7f08 (used for I/O restart)
|
||||
// reserved 0x7f04 (used for I/O restart)
|
||||
#define SMRAM_IO_INSTRUCTION_RESTART 0x7f00
|
||||
#define SMRAM_AUTOHALT_RESTART 0x7f00
|
||||
#define SMRAM_SMM_REVISION_ID 0x7efc
|
||||
#define SMRAM_SMBASE_OFFSET 0x7ef8
|
||||
// reserved 0x7ef4
|
||||
// reserved 0x7ef0
|
||||
// reserved 0x7eec
|
||||
// reserved 0x7ee8
|
||||
// reserved 0x7ee4
|
||||
// reserved 0x7ee0
|
||||
// reserved 0x7edc
|
||||
// reserved 0x7ed8
|
||||
// reserved 0x7ed4
|
||||
// reserved 0x7ed0
|
||||
// reserved 0x7ecc
|
||||
// reserved 0x7ec8
|
||||
// reserved 0x7ec4
|
||||
// reserved 0x7ec0
|
||||
// reserved 0x7ebc
|
||||
// reserved 0x7eb8
|
||||
// reserved 0x7eb4
|
||||
// reserved 0x7eb0
|
||||
// reserved 0x7eac
|
||||
// reserved 0x7ea8
|
||||
// reserved 0x7ea4
|
||||
// reserved 0x7ea0
|
||||
// reserved 0x7e9c
|
||||
// reserved 0x7e98
|
||||
// reserved 0x7e94
|
||||
// reserved 0x7e90
|
||||
// reserved 0x7e8c
|
||||
// reserved 0x7e88
|
||||
// reserved 0x7e84
|
||||
// reserved 0x7e80
|
||||
// reserved 0x7e7c
|
||||
// reserved 0x7e78
|
||||
// reserved 0x7e74
|
||||
// reserved 0x7e70
|
||||
// reserved 0x7e6c
|
||||
// reserved 0x7e68
|
||||
// reserved 0x7e64
|
||||
// reserved 0x7e60
|
||||
// reserved 0x7e5c
|
||||
// reserved 0x7e58
|
||||
// reserved 0x7e54
|
||||
// reserved 0x7e50
|
||||
// reserved 0x7e4c
|
||||
// reserved 0x7e48
|
||||
// reserved 0x7e44
|
||||
// reserved 0x7e40
|
||||
// reserved 0x7e3c
|
||||
// reserved 0x7e38
|
||||
// reserved 0x7e34
|
||||
// reserved 0x7e30
|
||||
// reserved 0x7e2c
|
||||
// reserved 0x7e28
|
||||
// reserved 0x7e24
|
||||
// reserved 0x7e20
|
||||
// reserved 0x7e1c
|
||||
// reserved 0x7e18
|
||||
// reserved 0x7e14
|
||||
// reserved 0x7e10
|
||||
// reserved 0x7e0c
|
||||
// reserved 0x7e08
|
||||
// reserved 0x7e04
|
||||
// reserved 0x7e00
|
||||
|
||||
#endif /* BX_SUPPORT_X86_64 */
|
||||
#endif // BX_SUPPORT_X86_64
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user