Fixed setting of reserved bits in CR3 register
This commit is contained in:
parent
8a94fc2315
commit
4a76bd2169
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.475 2008-05-10 20:35:03 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.476 2008-05-11 19:36:06 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -805,7 +805,7 @@ public: // for now...
|
||||
bx_cr0_t cr0;
|
||||
Bit32u cr1;
|
||||
bx_address cr2;
|
||||
bx_phy_address cr3, cr3_masked;
|
||||
bx_address cr3, cr3_masked;
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
bx_cr4_t cr4;
|
||||
#endif
|
||||
@ -2952,7 +2952,7 @@ public: // for now...
|
||||
BX_SMF int int_number(bx_segment_reg_t *seg);
|
||||
BX_SMF int int_number(unsigned s);
|
||||
BX_SMF void SetCR0(Bit32u val_32) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void CR3_change(bx_phy_address value) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void SetCR3(bx_address value) BX_CPP_AttrRegparmN(1);
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
BX_SMF bx_bool SetCR4(bx_address val) BX_CPP_AttrRegparmN(1);
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: init.cc,v 1.169 2008-04-27 19:48:58 sshwarts Exp $
|
||||
// $Id: init.cc,v 1.170 2008-05-11 19:36:06 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -646,7 +646,7 @@ Bit64s BX_CPU_C::param_restore(bx_param_c *param, Bit64s val)
|
||||
void BX_CPU_C::after_restore_state(void)
|
||||
{
|
||||
SetCR0(cr0.val32);
|
||||
CR3_change(cr3);
|
||||
SetCR3(cr3);
|
||||
TLB_flush(1);
|
||||
assert_checks();
|
||||
invalidate_prefetch_q();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: paging.cc,v 1.128 2008-05-10 22:11:48 sshwarts Exp $
|
||||
// $Id: paging.cc,v 1.129 2008-05-11 19:36:06 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -409,8 +409,12 @@ static unsigned tlbNonGlobalFlushes=0;
|
||||
#define InstrTLB_Increment(v)
|
||||
#endif
|
||||
|
||||
// ==============================================================
|
||||
#define BX_PHY_ADDRESS_MASK ((((Bit64u)(1)) << BX_PHY_ADDRESS_WIDTH) - 1)
|
||||
|
||||
#define BX_PHY_ADDRESS_RESERVED_BITS \
|
||||
(~BX_PHY_ADDRESS_MASK & BX_CONST64(0xfffffffffffff))
|
||||
|
||||
// ==============================================================
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
BX_CPU_C::pagingCR0Changed(Bit32u oldCR0, Bit32u newCR0)
|
||||
@ -446,22 +450,36 @@ BX_CPU_C::pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4)
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(1)
|
||||
BX_CPU_C::CR3_change(bx_phy_address value)
|
||||
BX_CPU_C::SetCR3(bx_address val)
|
||||
{
|
||||
if (bx_dbg.paging) {
|
||||
BX_DEBUG(("CR3_change(): flush TLB cache"));
|
||||
BX_DEBUG(("Page Directory Base: 0x" FMT_PHY_ADDRX, value));
|
||||
BX_DEBUG(("SetCR3(): flush TLB cache"));
|
||||
BX_DEBUG(("Page Directory Base: 0x" FMT_PHY_ADDRX, val));
|
||||
}
|
||||
|
||||
// flush TLB even if value does not change
|
||||
TLB_flush(0); // 0 = Don't flush Global entries.
|
||||
BX_CPU_THIS_PTR cr3 = value;
|
||||
|
||||
#if BX_SUPPORT_PAE
|
||||
if (BX_CPU_THIS_PTR cr4.get_PAE() && !long_mode())
|
||||
BX_CPU_THIS_PTR cr3_masked = value & 0xffffffe0;
|
||||
if (BX_CPU_THIS_PTR cr4.get_PAE() && !long_mode()) {
|
||||
BX_CPU_THIS_PTR cr3_masked = val & 0xffffffe0;
|
||||
BX_CPU_THIS_PTR cr3 = val & 0xffffffff;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
BX_CPU_THIS_PTR cr3_masked = value & BX_CONST64(0x000ffffffffff000);
|
||||
{
|
||||
#if BX_PHY_ADDRESS_WIDTH == 32
|
||||
if (val & BX_CONST64(0x000fffff00000000)) {
|
||||
BX_PANIC(("SetCR3() 0x%08x%08x: Only 32 bit physical address space is emulated !", GET32H(val), GET32L(val)));
|
||||
}
|
||||
#endif
|
||||
if (val & BX_PHY_ADDRESS_RESERVED_BITS) {
|
||||
BX_ERROR(("SetCR3(): Attempt to write to reserved bits of CR3"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
BX_CPU_THIS_PTR cr3_masked = val & BX_CONST64(0x000ffffffffff000);
|
||||
BX_CPU_THIS_PTR cr3 = val;
|
||||
}
|
||||
}
|
||||
|
||||
// Called to initialize the TLB upon startup.
|
||||
@ -598,27 +616,23 @@ void BX_CPU_C::page_fault(unsigned fault, bx_address laddr, unsigned user, unsig
|
||||
exception(BX_PF_EXCEPTION, error_code, 0);
|
||||
}
|
||||
|
||||
#define BX_PHY_ADDRESS_MASK ~((((Bit64u)(1)) << BX_PHY_ADDRESS_WIDTH) - 1)
|
||||
|
||||
/* PAE PML4: bits [51 .. physical address width], [7] */
|
||||
#define PAGING_PAE_PML4_RESERVED_BITS \
|
||||
(BX_PHY_ADDRESS_MASK & BX_CONST64(0x000FFFFFFFFFFFFF) | BX_CONST64(0x00000080))
|
||||
(BX_PHY_ADDRESS_RESERVED_BITS | BX_CONST64(0x00000080))
|
||||
|
||||
/* PAE PDPE: bits [51 .. physical address width], [7] - not support 1G paging */
|
||||
#define PAGING_PAE_PDPE_RESERVED_BITS \
|
||||
(BX_PHY_ADDRESS_MASK & BX_CONST64(0x000FFFFFFFFFFFFF) | BX_CONST64(0x00000080))
|
||||
(BX_PHY_ADDRESS_RESERVED_BITS | BX_CONST64(0x00000080))
|
||||
|
||||
/* PAE PDE: bits [51 .. physical address width] */
|
||||
#define PAGING_PAE_PDE_RESERVED_BITS \
|
||||
(BX_PHY_ADDRESS_MASK & BX_CONST64(0x000FFFFFFFFFFFFF))
|
||||
#define PAGING_PAE_PDE_RESERVED_BITS (BX_PHY_ADDRESS_RESERVED_BITS)
|
||||
|
||||
/* PAE PDE4M: bits [51 .. physical address width], [20:13] */
|
||||
#define PAGING_PAE_PDE4M_RESERVED_BITS \
|
||||
(PAGING_PAE_PDE_RESERVED_BITS | BX_CONST64(0x001FE000))
|
||||
|
||||
/* PAE PTE: bits [51 .. physical address width] */
|
||||
#define PAGING_PAE_PTE_RESERVED_BITS \
|
||||
(BX_PHY_ADDRESS_MASK & BX_CONST64(0x000FFFFFFFFFFFFF))
|
||||
#define PAGING_PAE_PTE_RESERVED_BITS (BX_PHY_ADDRESS_RESERVED_BITS)
|
||||
|
||||
|
||||
#define PAGE_DIRECTORY_NX_BIT (BX_CONST64(0x8000000000000000))
|
||||
@ -683,9 +697,11 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un
|
||||
BX_DEBUG(("PML4: entry not present"));
|
||||
page_fault(ERROR_NOT_PRESENT, laddr, pl, isWrite, access_type);
|
||||
}
|
||||
#if BX_PHY_ADDRESS_WIDTH == 32
|
||||
if (pml4 & BX_CONST64(0x000fffff00000000)) {
|
||||
BX_PANIC(("PML4 0x%08x%08x: Only 32 bit physical address space is emulated !", GET32H(pml4), GET32L(pml4)));
|
||||
}
|
||||
#endif
|
||||
if (pml4 & PAGING_PAE_PML4_RESERVED_BITS) {
|
||||
BX_DEBUG(("PML4: reserved bit is set PML4=%08x:%08x", GET32H(pml4), GET32L(pml4)));
|
||||
page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type);
|
||||
@ -723,9 +739,11 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un
|
||||
BX_DEBUG(("PAE PDPE: entry not present"));
|
||||
page_fault(ERROR_NOT_PRESENT, laddr, pl, isWrite, access_type);
|
||||
}
|
||||
#if BX_PHY_ADDRESS_WIDTH == 32
|
||||
if (pdpe & BX_CONST64(0x000fffff00000000)) {
|
||||
BX_PANIC(("PAE PDPE 0x%08x%08x: Only 32 bit physical address space is emulated !", GET32H(pdpe), GET32L(pdpe)));
|
||||
}
|
||||
#endif
|
||||
if (pdpe & PAGING_PAE_PDPE_RESERVED_BITS) {
|
||||
BX_DEBUG(("PAE PDPE: reserved bit is set: PDPE=%08x:%08x", GET32H(pdpe), GET32L(pdpe)));
|
||||
page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type);
|
||||
@ -752,9 +770,11 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un
|
||||
BX_DEBUG(("PAE PDE: entry not present"));
|
||||
page_fault(ERROR_NOT_PRESENT, laddr, pl, isWrite, access_type);
|
||||
}
|
||||
#if BX_PHY_ADDRESS_WIDTH == 32
|
||||
if (pde & BX_CONST64(0x000fffff00000000)) {
|
||||
BX_PANIC(("PAE PDE 0x%08x%08x: Only 32 bit physical address space is emulated !", GET32H(pde), GET32L(pde)));
|
||||
}
|
||||
#endif
|
||||
if (pde & PAGING_PAE_PDE_RESERVED_BITS) {
|
||||
BX_DEBUG(("PAE PDE: reserved bit is set PDE=%08x:%08x", GET32H(pde), GET32L(pde)));
|
||||
page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type);
|
||||
@ -833,9 +853,11 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un
|
||||
BX_DEBUG(("PAE PTE: entry not present"));
|
||||
page_fault(ERROR_NOT_PRESENT, laddr, pl, isWrite, access_type);
|
||||
}
|
||||
#if BX_PHY_ADDRESS_WIDTH == 32
|
||||
if (pte & BX_CONST64(0x000fffff00000000)) {
|
||||
BX_PANIC(("PAE PTE 0x%08x%08x: Only 32 bit physical address space is emulated !", GET32H(pte), GET32L(pte)));
|
||||
}
|
||||
#endif
|
||||
if (pte & PAGING_PAE_PTE_RESERVED_BITS) {
|
||||
BX_DEBUG(("PAE PTE: reserved bit is set PTE=%08x:%08x", GET32H(pte), GET32L(pte)));
|
||||
page_fault(ERROR_RESERVED | ERROR_PROTECTION, laddr, pl, isWrite, access_type);
|
||||
@ -923,11 +945,11 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un
|
||||
{
|
||||
// Note: when the PSE and PAE flags in CR4 are set, the
|
||||
// processor generates a PF if the reserved bits are not zero.
|
||||
|
||||
#if BX_PHY_ADDRESS_WIDTH == 32
|
||||
if (pde & 0x0001e000) {
|
||||
BX_PANIC(("PSE PDE 0x%08x: Only 32 bit physical address space is emulated !", pde));
|
||||
}
|
||||
|
||||
#endif
|
||||
// Combined access is just access from the pde (no pte involved).
|
||||
combined_access = pde & 0x06; // U/S and R/W
|
||||
|
||||
@ -1103,7 +1125,7 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy)
|
||||
BX_MEM(0)->readPhysicalPage(BX_CPU_THIS, pt_address, 8, &pte);
|
||||
if(!(pte & 1))
|
||||
goto page_fault;
|
||||
if ((pte & BX_PHY_ADDRESS_MASK & BX_CONST64(0x000fffffffffffff)))
|
||||
if (pte & BX_PHY_ADDRESS_RESERVED_BITS)
|
||||
goto page_fault;
|
||||
pt_address = bx_phy_address(pte & BX_CONST64(0x000ffffffffff000));
|
||||
if (level == 1 && (pte & 0x80)) { // PSE page
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.229 2008-05-10 18:10:53 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.230 2008-05-11 19:36:06 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -624,7 +624,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_CdRd(bxInstruction_c *i)
|
||||
case 3: // CR3
|
||||
BX_DEBUG(("MOV_CdRd:CR3 = %08x", val_32));
|
||||
// Reserved bits take on value of MOV instruction
|
||||
CR3_change(val_32);
|
||||
SetCR3(val_32);
|
||||
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_MOV_CR3, val_32);
|
||||
break;
|
||||
case 4: // CR4
|
||||
@ -676,7 +676,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_RdCd(bxInstruction_c *i)
|
||||
break;
|
||||
case 3: // CR3
|
||||
BX_DEBUG(("MOV_RdCd: reading CR3"));
|
||||
val_32 = BX_CPU_THIS_PTR cr3;
|
||||
val_32 = (Bit32u) BX_CPU_THIS_PTR cr3;
|
||||
break;
|
||||
case 4: // CR4
|
||||
#if BX_CPU_LEVEL < 4
|
||||
@ -733,16 +733,13 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::MOV_CqRq(bxInstruction_c *i)
|
||||
break;
|
||||
case 3: // CR3
|
||||
BX_DEBUG(("MOV_CqRq: write to CR3 of %08x:%08x", GET32H(val_64), GET32L(val_64)));
|
||||
if (val_64 & BX_CONST64(0xffffffff00000000)) {
|
||||
BX_PANIC(("CR3 write: Only 32 bit physical address space is emulated !"));
|
||||
}
|
||||
// Reserved bits take on value of MOV instruction
|
||||
CR3_change((bx_phy_address) val_64);
|
||||
SetCR3(val_64);
|
||||
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_MOV_CR3, val_64);
|
||||
break;
|
||||
case 4: // CR4
|
||||
// Protected mode: #GP(0) if attempt to write a 1 to
|
||||
// any reserved bit of CR4
|
||||
// Protected mode: #GP(0) if attempt to write a 1 to
|
||||
// any reserved bit of CR4
|
||||
BX_DEBUG(("MOV_CqRq: write to CR4 of %08x:%08x", GET32H(val_64), GET32L(val_64)));
|
||||
if (! SetCR4(val_64))
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
@ -1817,9 +1814,11 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::WRMSR(bxInstruction_c *i)
|
||||
if (BX_CPU_THIS_PTR msr.apicbase & 0x800) {
|
||||
BX_INFO(("WRMSR: wrote %08x:%08x to MSR_APICBASE", EDX, EAX));
|
||||
BX_CPU_THIS_PTR msr.apicbase = EAX; /* ignore the high 32bits */
|
||||
#if BX_PHY_ADDRESS_WIDTH == 32
|
||||
if (EDX != 0) {
|
||||
BX_PANIC(("MSR_APICBASE: Only 32 bit physical address space is emulated !"));
|
||||
}
|
||||
#endif
|
||||
BX_CPU_THIS_PTR local_apic.set_base(BX_CPU_THIS_PTR msr.apicbase);
|
||||
// TLB flush is required for emulation correctness
|
||||
TLB_flush(1); // don't care about performance of apic relocation
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: smm.cc,v 1.38 2008-04-27 19:49:02 sshwarts Exp $
|
||||
// $Id: smm.cc,v 1.39 2008-05-11 19:36:06 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2006 Stanislav Shwartsman
|
||||
@ -395,7 +395,7 @@ 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);
|
||||
CR3_change(temp_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);
|
||||
@ -658,7 +658,7 @@ bx_bool BX_CPU_C::smram_restore_state(const Bit32u *saved_state)
|
||||
}
|
||||
|
||||
SetCR0(temp_cr0);
|
||||
CR3_change(temp_cr3);
|
||||
SetCR3(temp_cr3);
|
||||
setEFlags(temp_eflags);
|
||||
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: tasking.cc,v 1.58 2008-05-09 22:33:36 sshwarts Exp $
|
||||
// $Id: tasking.cc,v 1.59 2008-05-11 19:36:06 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -420,7 +420,7 @@ void BX_CPU_C::task_switch(bx_selector_t *tss_selector,
|
||||
if ((tss_descriptor->type >= 9) && BX_CPU_THIS_PTR cr0.get_PG()) {
|
||||
// change CR3 only if it actually modified
|
||||
if (newCR3 != BX_CPU_THIS_PTR cr3) {
|
||||
CR3_change(newCR3); // Tell paging unit about new cr3 value
|
||||
SetCR3(newCR3); // Tell paging unit about new cr3 value
|
||||
BX_DEBUG (("task_switch changing CR3 to 0x" FMT_PHY_ADDRX, newCR3));
|
||||
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_TASKSWITCH, newCR3);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user