Optimize TLB flush methods
This commit is contained in:
parent
870925d575
commit
dcb82ec4bf
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.507 2008-08-12 05:03:51 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.508 2008-08-13 21:51:53 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -2994,7 +2994,12 @@ public: // for now...
|
||||
return translate_linear(laddr, curr_pl, rw, DATA_ACCESS);
|
||||
}
|
||||
|
||||
BX_SMF void TLB_flush(bx_bool invalidateGlobal);
|
||||
#if BX_SUPPORT_GLOBAL_PAGES
|
||||
BX_SMF void TLB_flushNonGlobal(void);
|
||||
#else
|
||||
#define TLB_flushNonGlobal() TLB_flush()
|
||||
#endif
|
||||
BX_SMF void TLB_flush(void);
|
||||
BX_SMF void TLB_invlpg(bx_address laddr);
|
||||
BX_SMF void TLB_init(void);
|
||||
BX_SMF void set_INTR(bx_bool value);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: exception.cc,v 1.119 2008-07-26 14:19:06 sshwarts Exp $
|
||||
// $Id: exception.cc,v 1.120 2008-08-13 21:51:54 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -254,7 +254,7 @@ void BX_CPU_C::long_mode_int(Bit8u vector, bx_bool is_INT, bx_bool is_error_code
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value);
|
||||
write_new_stack_qword_64(RSP - 16, cs_descriptor.dpl, old_RSP);
|
||||
write_new_stack_qword_64(RSP - 24, cs_descriptor.dpl, read_eflags());
|
||||
write_new_stack_qword_64(RSP - 32, cs_descriptor.dpl,
|
||||
write_new_stack_qword_64(RSP - 32, cs_descriptor.dpl,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value);
|
||||
write_new_stack_qword_64(RSP - 40, cs_descriptor.dpl, RIP);
|
||||
RSP -= 40;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: init.cc,v 1.176 2008-08-13 20:54:03 sshwarts Exp $
|
||||
// $Id: init.cc,v 1.177 2008-08-13 21:51:54 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -649,7 +649,7 @@ void BX_CPU_C::after_restore_state(void)
|
||||
|
||||
SetCR0(cr0.val32);
|
||||
SetCR3(cr3);
|
||||
TLB_flush(1);
|
||||
TLB_flush();
|
||||
assert_checks();
|
||||
invalidate_prefetch_q();
|
||||
debug(RIP);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: paging.cc,v 1.150 2008-08-10 20:32:00 sshwarts Exp $
|
||||
// $Id: paging.cc,v 1.151 2008-08-13 21:51:54 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -401,7 +401,7 @@ BX_CPU_C::pagingCR0Changed(Bit32u oldCR0, Bit32u newCR0)
|
||||
// Additionally, the TLB strategy is based on the current value of
|
||||
// WP, so if that changes we must also flush the TLB.
|
||||
if ((oldCR0 & 0x80010001) != (newCR0 & 0x80010001))
|
||||
TLB_flush(1); // 1 = Flush Global entries also.
|
||||
TLB_flush(); // Flush Global entries also.
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
@ -409,7 +409,7 @@ BX_CPU_C::pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4)
|
||||
{
|
||||
// Modification of PGE,PAE,PSE flushes TLB cache according to docs.
|
||||
if ((oldCR4 & 0x000000b0) != (newCR4 & 0x000000b0))
|
||||
TLB_flush(1); // 1 = Flush Global entries also.
|
||||
TLB_flush(); // Flush Global entries also.
|
||||
|
||||
#if BX_SUPPORT_PAE
|
||||
if ((oldCR4 & 0x00000020) != (newCR4 & 0x00000020)) {
|
||||
@ -425,7 +425,7 @@ BX_CPU_C::pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4)
|
||||
BX_CPU_C::SetCR3(bx_address val)
|
||||
{
|
||||
// flush TLB even if value does not change
|
||||
TLB_flush(0); // 0 = Don't flush Global entries.
|
||||
TLB_flushNonGlobal(); // Don't flush Global entries.
|
||||
|
||||
#if BX_SUPPORT_PAE
|
||||
if (BX_CPU_THIS_PTR cr4.get_PAE() && !long_mode()) {
|
||||
@ -456,9 +456,6 @@ void BX_CPU_C::TLB_init(void)
|
||||
{
|
||||
unsigned n, wp, us_combined, rw_combined, us_current, rw_current;
|
||||
|
||||
for (n=0; n<BX_TLB_SIZE; n++)
|
||||
BX_CPU_THIS_PTR TLB.entry[n].lpf = BX_INVALID_TLB_ENTRY;
|
||||
|
||||
//
|
||||
// Setup privilege check matrix.
|
||||
//
|
||||
@ -490,27 +487,18 @@ void BX_CPU_C::TLB_init(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TLB_flush();
|
||||
}
|
||||
|
||||
void BX_CPU_C::TLB_flush(bx_bool invalidateGlobal)
|
||||
void BX_CPU_C::TLB_flush(void)
|
||||
{
|
||||
#if InstrumentTLB
|
||||
if (invalidateGlobal)
|
||||
InstrTLB_Increment(tlbGlobalFlushes);
|
||||
else
|
||||
InstrTLB_Increment(tlbNonGlobalFlushes);
|
||||
InstrTLB_Increment(tlbGlobalFlushes);
|
||||
#endif
|
||||
|
||||
for (unsigned n=0; n<BX_TLB_SIZE; n++) {
|
||||
// To be conscious of the native cache line usage, only
|
||||
// write to (invalidate) entries which need it.
|
||||
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[n];
|
||||
if (tlbEntry->lpf != BX_INVALID_TLB_ENTRY) {
|
||||
#if BX_SUPPORT_GLOBAL_PAGES
|
||||
if (invalidateGlobal || !(tlbEntry->accessBits & TLB_GlobalPage))
|
||||
#endif
|
||||
tlbEntry->lpf = BX_INVALID_TLB_ENTRY;
|
||||
}
|
||||
BX_CPU_THIS_PTR TLB.entry[n].lpf = BX_INVALID_TLB_ENTRY;
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_PAE
|
||||
@ -524,13 +512,41 @@ void BX_CPU_C::TLB_flush(bx_bool invalidateGlobal)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_GLOBAL_PAGES
|
||||
|
||||
void BX_CPU_C::TLB_flushNonGlobal(void)
|
||||
{
|
||||
#if InstrumentTLB
|
||||
InstrTLB_Increment(tlbNonGlobalFlushes);
|
||||
#endif
|
||||
|
||||
for (unsigned n=0; n<BX_TLB_SIZE; n++) {
|
||||
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[n];
|
||||
if (!(tlbEntry->accessBits & TLB_GlobalPage))
|
||||
tlbEntry->lpf = BX_INVALID_TLB_ENTRY;
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_PAE
|
||||
BX_CPU_THIS_PTR PDPE_CACHE.valid = 0;
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_MONITOR_MWAIT
|
||||
// invalidating of the TLB might change translation for monitored page
|
||||
// and cause subsequent MWAIT instruction to wait forever
|
||||
BX_CPU_THIS_PTR monitor.reset_monitor();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::TLB_invlpg(bx_address laddr)
|
||||
{
|
||||
BX_DEBUG(("TLB_invlpg(0x"FMT_ADDRX"): invalidate TLB entry", laddr));
|
||||
|
||||
unsigned TLB_index = BX_TLB_INDEX_OF(laddr, 0);
|
||||
bx_address lpf = LPFOf(laddr);
|
||||
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[TLB_index];
|
||||
if (tlbEntry->lpf == LPFOf(laddr)) {
|
||||
if (tlbEntry->lpf == lpf) {
|
||||
tlbEntry->lpf = BX_INVALID_TLB_ENTRY;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.252 2008-08-09 19:18:09 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.253 2008-08-13 21:51:54 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1772,7 +1772,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::WRMSR(bxInstruction_c *i)
|
||||
#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
|
||||
TLB_flush(); // don't care about performance of apic relocation
|
||||
}
|
||||
else {
|
||||
BX_INFO(("WRMSR: MSR_APICBASE APIC global enable bit cleared !"));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: smm.cc,v 1.42 2008-08-03 19:53:09 sshwarts Exp $
|
||||
// $Id: smm.cc,v 1.43 2008-08-13 21:51:54 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2006 Stanislav Shwartsman
|
||||
@ -135,7 +135,7 @@ void BX_CPU_C::enter_system_management_mode(void)
|
||||
BX_CPU_THIS_PTR cr0.set_PG(0); // paging disabled (bit 31)
|
||||
|
||||
// paging mode was changed - flush TLB
|
||||
TLB_flush(1); // 1 = Flush Global entries also
|
||||
TLB_flush(); // Flush Global entries also
|
||||
|
||||
#if BX_CPU_LEVEL >= 4
|
||||
BX_CPU_THIS_PTR cr4.setRegister(0);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: pc_system.cc,v 1.71 2008-05-10 20:39:53 sshwarts Exp $
|
||||
// $Id: pc_system.cc,v 1.72 2008-08-13 21:51:53 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -183,7 +183,7 @@ bx_bool bx_pc_system_c::get_enable_a20(void)
|
||||
void bx_pc_system_c::MemoryMappingChanged(void)
|
||||
{
|
||||
for (unsigned i=0; i<BX_SMP_PROCESSORS; i++)
|
||||
BX_CPU(i)->TLB_flush(1);
|
||||
BX_CPU(i)->TLB_flush();
|
||||
}
|
||||
|
||||
void bx_pc_system_c::invlpg(bx_address addr)
|
||||
|
Loading…
Reference in New Issue
Block a user