Small optimization in icache page-write-stamp
This commit is contained in:
parent
fbd61d0a00
commit
55ceecf79b
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.cc,v 1.132 2006-02-23 18:23:31 sshwarts Exp $
|
||||
// $Id: cpu.cc,v 1.133 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -226,7 +226,7 @@ void BX_CPU_C::cpu_loop(Bit32s max_instr_count)
|
||||
#if BX_DEBUGGER
|
||||
if (BX_CPU_THIS_PTR trace) {
|
||||
// print the instruction that is about to be executed.
|
||||
bx_dbg_disassemble_current (BX_CPU_ID, 1); // only one cpu, print time stamp
|
||||
bx_dbg_disassemble_current(BX_CPU_ID, 1); // only one cpu, print time stamp
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -486,9 +486,8 @@ bxInstruction_c* BX_CPU_C::fetchInstruction(bxInstruction_c *iStorage, bx_addres
|
||||
// willing to dump all iCache entries which can hash to this page.
|
||||
// Therefore, in either case, we can keep the counter as-is and
|
||||
// replace the fetch mode bits.
|
||||
Bit32u fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
|
||||
pageWriteStamp &= ICacheWriteStampMask; // Clear out old fetch mode bits.
|
||||
pageWriteStamp |= fetchModeMask; // Add in new ones.
|
||||
pageWriteStamp |= BX_CPU_THIS_PTR fetchModeMask; // Add in new ones.
|
||||
pageWriteStampTable.setPageWriteStamp(pAddr, pageWriteStamp);
|
||||
cache_entry->pAddr = pAddr;
|
||||
cache_entry->writeStamp = pageWriteStamp;
|
||||
@ -790,7 +789,7 @@ void BX_CPU_C::prefetch(void)
|
||||
#if BX_SUPPORT_ICACHE
|
||||
BX_CPU_THIS_PTR currPageWriteStampPtr = pageWriteStampTable.getPageWriteStampPtr(pAddr);
|
||||
Bit32u pageWriteStamp = *(BX_CPU_THIS_PTR currPageWriteStampPtr);
|
||||
Bit32u fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
|
||||
Bit32u fetchModeMask = BX_CPU_THIS_PTR fetchModeMask;
|
||||
if ((pageWriteStamp & ICacheFetchModeMask) != fetchModeMask)
|
||||
{
|
||||
// The current CPU mode does not match iCache entries for this
|
||||
@ -853,11 +852,11 @@ void BX_CPU_C::boundaryFetch(Bit8u *fetchPtr, unsigned remainingInPage, bxInstru
|
||||
// Restore EIP since we fudged it to start at the 2nd page boundary.
|
||||
RIP = BX_CPU_THIS_PTR prev_eip;
|
||||
|
||||
// Since we cross an instruction boundary, note that we need a prefetch()
|
||||
// again on the next instruction. Perhaps we can optimize this to
|
||||
// eliminate the extra prefetch() since we do it above, but have to
|
||||
// think about repeated instructions, etc.
|
||||
BX_CPU_THIS_PTR eipPageWindowSize = 0; // Fixme
|
||||
// Since we cross an instruction boundary, note that we need a prefetch()
|
||||
// again on the next instruction. Perhaps we can optimize this to
|
||||
// eliminate the extra prefetch() since we do it above, but have to
|
||||
// think about repeated instructions, etc.
|
||||
invalidate_prefetch_q();
|
||||
|
||||
BX_INSTR_OPCODE(BX_CPU_ID, fetchBuffer, i->ilen(),
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode());
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.262 2006-02-23 18:23:31 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.263 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -647,7 +647,7 @@ public:
|
||||
// 4...4 os32
|
||||
// 3...3 (unused)
|
||||
// 2...0 seg
|
||||
unsigned metaInfo;
|
||||
Bit32u metaInfo;
|
||||
|
||||
union {
|
||||
// Form (longest case): [opcode+modrm+sib/displacement32/immediate32]
|
||||
@ -1219,7 +1219,8 @@ public: // for now...
|
||||
// this structure should be aligned on a 32-byte boundary to be friendly
|
||||
// with the host cache lines.
|
||||
#if BX_SUPPORT_ICACHE
|
||||
bxICache_c iCache BX_CPP_AlignN(32);
|
||||
bxICache_c iCache BX_CPP_AlignN(32);
|
||||
Bit32u fetchModeMask;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// $Id: ctrl_xfer_pro.cc,v 1.50 2005-08-02 18:44:16 sshwarts Exp $
|
||||
// $Id: ctrl_xfer_pro.cc,v 1.51 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -118,7 +118,7 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, Bit8u cp
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_ICACHE
|
||||
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
|
||||
// Loading CS will invalidate the EIP fetch window.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: debugstuff.cc,v 1.58 2006-02-14 20:14:18 sshwarts Exp $
|
||||
// $Id: debugstuff.cc,v 1.59 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -717,7 +717,7 @@ bx_bool BX_CPU_C::dbg_set_cpu(bx_dbg_cpu_t *cpu)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit;
|
||||
|
||||
#if BX_SUPPORT_ICACHE
|
||||
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
|
||||
// SS:
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: icache.h,v 1.11 2006-01-16 19:22:28 sshwarts Exp $
|
||||
// $Id: icache.h,v 1.12 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -28,6 +28,8 @@
|
||||
#ifndef BX_ICACHE_H
|
||||
#define BX_ICACHE_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// bit31: 1=CS is 32/64-bit, 0=CS is 16-bit.
|
||||
// bit30: 1=Long Mode, 0=not Long Mode.
|
||||
// bit29: 1=iCache page, 0=Data.
|
||||
@ -35,7 +37,6 @@ const Bit32u ICacheWriteStampInvalid = 0x1fffffff;
|
||||
const Bit32u ICacheWriteStampMax = 0x1fffffff;
|
||||
const Bit32u ICacheWriteStampMask = 0x1fffffff;
|
||||
const Bit32u ICacheFetchModeMask = ~ICacheWriteStampMask;
|
||||
const Bit32u iCachePageDataMask = 0x20000000;
|
||||
|
||||
class bxPageWriteStampTable
|
||||
{
|
||||
@ -77,21 +78,16 @@ public:
|
||||
|
||||
BX_CPP_INLINE void setPageWriteStamp(Bit32u pAddr, Bit32u pageWriteStamp)
|
||||
{
|
||||
if (pAddr < memSizeInBytes)
|
||||
if (pAddr < memSizeInBytes)
|
||||
pageWriteStampTable[pAddr>>12] = pageWriteStamp;
|
||||
}
|
||||
|
||||
BX_CPP_INLINE void decWriteStamp(Bit32u a20Addr)
|
||||
BX_CPP_INLINE void decWriteStamp(Bit32u pAddr)
|
||||
{
|
||||
// Increment page write stamp, so iCache entries with older stamps
|
||||
assert(pAddr < memSizeInBytes);
|
||||
// Decrement page write stamp, so iCache entries with older stamps
|
||||
// are effectively invalidated.
|
||||
Bit32u pageIndex = a20Addr >> 12;
|
||||
Bit32u writeStamp = pageWriteStampTable[pageIndex];
|
||||
|
||||
if (writeStamp & iCachePageDataMask)
|
||||
{
|
||||
pageWriteStampTable[pageIndex]--;
|
||||
}
|
||||
pageWriteStampTable[pAddr >> 12]--;
|
||||
}
|
||||
|
||||
BX_CPP_INLINE void resetWriteStamps(void);
|
||||
@ -108,29 +104,20 @@ extern bxPageWriteStampTable pageWriteStampTable;
|
||||
|
||||
#define BxICacheEntries (32 * 1024) // Must be a power of 2.
|
||||
|
||||
class bxICacheEntry_c {
|
||||
public:
|
||||
|
||||
Bit32u pAddr; // Physical address of the instruction.
|
||||
Bit32u writeStamp; // Generation ID. Each write to a physical page
|
||||
// decrements this value.
|
||||
bxInstruction_c i; // The instruction decode information.
|
||||
struct bxICacheEntry_c
|
||||
{
|
||||
Bit32u pAddr; // Physical address of the instruction
|
||||
Bit32u writeStamp; // Generation ID. Each write to a physical page
|
||||
// decrements this value
|
||||
bxInstruction_c i; // The instruction decode information
|
||||
};
|
||||
|
||||
class BOCHSAPI bxICache_c {
|
||||
public:
|
||||
bxICacheEntry_c entry[BxICacheEntries];
|
||||
Bit32u fetchModeMask;
|
||||
|
||||
public:
|
||||
bxICache_c()
|
||||
{
|
||||
// Initially clear the iCache;
|
||||
for (unsigned i=0; i<BxICacheEntries; i++) {
|
||||
entry[i].writeStamp = ICacheWriteStampInvalid;
|
||||
}
|
||||
fetchModeMask = iCachePageDataMask; // CS is 16-bit, Long Mode disabled
|
||||
}
|
||||
bxICache_c() { flushICacheEntries(); }
|
||||
|
||||
BX_CPP_INLINE unsigned hash(Bit32u pAddr) const
|
||||
{
|
||||
@ -143,19 +130,21 @@ public:
|
||||
};
|
||||
|
||||
BX_CPP_INLINE void bxICache_c::flushICacheEntries(void)
|
||||
{ bxICacheEntry_c* e = entry;
|
||||
{
|
||||
bxICacheEntry_c* e = entry;
|
||||
for (unsigned i=0; i<BxICacheEntries; i++, e++) {
|
||||
e->writeStamp = ICacheWriteStampInvalid;
|
||||
}
|
||||
}
|
||||
|
||||
BX_CPP_INLINE void bxICache_c::purgeICacheEntries(void)
|
||||
{ bxICacheEntry_c* e = entry;
|
||||
{
|
||||
bxICacheEntry_c* e = entry;
|
||||
|
||||
// Since the write stamps may overflow if we always simply decrese them,
|
||||
// this function has to be called often enough that we can reset them
|
||||
// (without invalidating the cache).
|
||||
for (unsigned i=0;i<BxICacheEntries;i++, e++)
|
||||
for (unsigned i=0;i<BxICacheEntries;i++,e++)
|
||||
{
|
||||
Bit32u pageWriteStamp = pageWriteStampTable.getPageWriteStamp(e->pAddr);
|
||||
if (e->writeStamp != pageWriteStamp)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: init.cc,v 1.84 2006-02-14 20:03:14 sshwarts Exp $
|
||||
// $Id: init.cc,v 1.85 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -526,7 +526,7 @@ void BX_CPU_C::reset(unsigned source)
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_ICACHE
|
||||
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
|
||||
/* SS (Stack Segment) and descriptor cache */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: paging.cc,v 1.63 2005-11-26 21:36:51 sshwarts Exp $
|
||||
// $Id: paging.cc,v 1.64 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -432,7 +432,7 @@ BX_CPU_C::pagingCR0Changed(Bit32u oldCR0, Bit32u newCR0)
|
||||
TLB_flush(1); // 1 = Flush Global entries also.
|
||||
|
||||
if (bx_dbg.paging)
|
||||
BX_INFO(("pagingCR0Changed(0x%x -> 0x%x):", oldCR0, newCR0));
|
||||
BX_INFO(("pagingCR0Changed: (0x%x -> 0x%x)", oldCR0, newCR0));
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(2)
|
||||
@ -443,7 +443,7 @@ BX_CPU_C::pagingCR4Changed(Bit32u oldCR4, Bit32u newCR4)
|
||||
TLB_flush(1); // 1 = Flush Global entries also.
|
||||
|
||||
if (bx_dbg.paging)
|
||||
BX_INFO(("pagingCR4Changed(0x%x -> 0x%x):", oldCR4, newCR4));
|
||||
BX_INFO(("pagingCR4Changed: (0x%x -> 0x%x)", oldCR4, newCR4));
|
||||
|
||||
#if BX_SUPPORT_PAE
|
||||
if ( (oldCR4 & 0x00000020) != (newCR4 & 0x00000020) ) {
|
||||
@ -550,7 +550,7 @@ BX_CPU_C::TLB_flush(bx_bool invalidateGlobal)
|
||||
bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[i];
|
||||
if (tlbEntry->lpf != BX_INVALID_TLB_ENTRY) {
|
||||
#if BX_SUPPORT_GLOBAL_PAGES
|
||||
if ( invalidateGlobal || !(tlbEntry->accessBits & TLB_GlobalPage) )
|
||||
if (invalidateGlobal || !(tlbEntry->accessBits & TLB_GlobalPage))
|
||||
#endif
|
||||
{
|
||||
tlbEntry->lpf = BX_INVALID_TLB_ENTRY;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.134 2006-02-14 19:00:08 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.135 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1160,7 +1160,7 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_ICACHE
|
||||
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
|
||||
/* ES */
|
||||
@ -1869,7 +1869,7 @@ void BX_CPU_C::SYSENTER (bxInstruction_c *i)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; // available for use by system
|
||||
|
||||
#if BX_SUPPORT_ICACHE
|
||||
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 8) & BX_SELECTOR_RPL_MASK;
|
||||
@ -1929,7 +1929,7 @@ void BX_CPU_C::SYSEXIT (bxInstruction_c *i)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; // available for use by system
|
||||
|
||||
#if BX_SUPPORT_ICACHE
|
||||
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 24) | 3;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: segment_ctrl_pro.cc,v 1.52 2006-02-22 20:58:16 sshwarts Exp $
|
||||
// $Id: segment_ctrl_pro.cc,v 1.53 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -222,7 +222,7 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value)
|
||||
if (seg == &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]) {
|
||||
seg->cache.u.segment.executable = 1; /* code segment */
|
||||
#if BX_SUPPORT_ICACHE
|
||||
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
invalidate_prefetch_q();
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: tasking.cc,v 1.29 2006-01-16 19:22:28 sshwarts Exp $
|
||||
// $Id: tasking.cc,v 1.30 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -608,7 +608,7 @@ void BX_CPU_C::task_switch(bx_selector_t *tss_selector,
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_ICACHE // update instruction cache
|
||||
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
|
||||
// SS
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: vm8086.cc,v 1.23 2006-01-16 19:22:28 sshwarts Exp $
|
||||
// $Id: vm8086.cc,v 1.24 2006-02-28 17:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -254,7 +254,7 @@ void BX_CPU_C::init_v8086_mode(void)
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 3;
|
||||
|
||||
#if BX_SUPPORT_ICACHE // update instruction cache
|
||||
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
|
||||
#endif
|
||||
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user