Small optimization in icache page-write-stamp

This commit is contained in:
Stanislav Shwartsman 2006-02-28 17:47:33 +00:00
parent fbd61d0a00
commit 55ceecf79b
11 changed files with 53 additions and 64 deletions

View File

@ -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. // Copyright (C) 2001 MandrakeSoft S.A.
@ -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. // willing to dump all iCache entries which can hash to this page.
// Therefore, in either case, we can keep the counter as-is and // Therefore, in either case, we can keep the counter as-is and
// replace the fetch mode bits. // replace the fetch mode bits.
Bit32u fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
pageWriteStamp &= ICacheWriteStampMask; // Clear out old fetch mode bits. 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); pageWriteStampTable.setPageWriteStamp(pAddr, pageWriteStamp);
cache_entry->pAddr = pAddr; cache_entry->pAddr = pAddr;
cache_entry->writeStamp = pageWriteStamp; cache_entry->writeStamp = pageWriteStamp;
@ -790,7 +789,7 @@ void BX_CPU_C::prefetch(void)
#if BX_SUPPORT_ICACHE #if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR currPageWriteStampPtr = pageWriteStampTable.getPageWriteStampPtr(pAddr); BX_CPU_THIS_PTR currPageWriteStampPtr = pageWriteStampTable.getPageWriteStampPtr(pAddr);
Bit32u pageWriteStamp = *(BX_CPU_THIS_PTR currPageWriteStampPtr); 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) if ((pageWriteStamp & ICacheFetchModeMask) != fetchModeMask)
{ {
// The current CPU mode does not match iCache entries for this // The current CPU mode does not match iCache entries for this
@ -857,7 +856,7 @@ void BX_CPU_C::boundaryFetch(Bit8u *fetchPtr, unsigned remainingInPage, bxInstru
// again on the next instruction. Perhaps we can optimize this to // again on the next instruction. Perhaps we can optimize this to
// eliminate the extra prefetch() since we do it above, but have to // eliminate the extra prefetch() since we do it above, but have to
// think about repeated instructions, etc. // think about repeated instructions, etc.
BX_CPU_THIS_PTR eipPageWindowSize = 0; // Fixme invalidate_prefetch_q();
BX_INSTR_OPCODE(BX_CPU_ID, fetchBuffer, i->ilen(), BX_INSTR_OPCODE(BX_CPU_ID, fetchBuffer, i->ilen(),
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode()); BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b, Is64BitMode());

View File

@ -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. // Copyright (C) 2001 MandrakeSoft S.A.
@ -647,7 +647,7 @@ public:
// 4...4 os32 // 4...4 os32
// 3...3 (unused) // 3...3 (unused)
// 2...0 seg // 2...0 seg
unsigned metaInfo; Bit32u metaInfo;
union { union {
// Form (longest case): [opcode+modrm+sib/displacement32/immediate32] // Form (longest case): [opcode+modrm+sib/displacement32/immediate32]
@ -1220,6 +1220,7 @@ public: // for now...
// with the host cache lines. // with the host cache lines.
#if BX_SUPPORT_ICACHE #if BX_SUPPORT_ICACHE
bxICache_c iCache BX_CPP_AlignN(32); bxICache_c iCache BX_CPP_AlignN(32);
Bit32u fetchModeMask;
#endif #endif

View File

@ -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. // 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 #endif
#if BX_SUPPORT_ICACHE #if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS); BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif #endif
// Loading CS will invalidate the EIP fetch window. // Loading CS will invalidate the EIP fetch window.

View File

@ -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. // 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; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit;
#if BX_SUPPORT_ICACHE #if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS); BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif #endif
// SS: // SS:

View File

@ -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. // Copyright (C) 2001 MandrakeSoft S.A.
@ -28,6 +28,8 @@
#ifndef BX_ICACHE_H #ifndef BX_ICACHE_H
#define BX_ICACHE_H #define BX_ICACHE_H
#include <assert.h>
// bit31: 1=CS is 32/64-bit, 0=CS is 16-bit. // bit31: 1=CS is 32/64-bit, 0=CS is 16-bit.
// bit30: 1=Long Mode, 0=not Long Mode. // bit30: 1=Long Mode, 0=not Long Mode.
// bit29: 1=iCache page, 0=Data. // bit29: 1=iCache page, 0=Data.
@ -35,7 +37,6 @@ const Bit32u ICacheWriteStampInvalid = 0x1fffffff;
const Bit32u ICacheWriteStampMax = 0x1fffffff; const Bit32u ICacheWriteStampMax = 0x1fffffff;
const Bit32u ICacheWriteStampMask = 0x1fffffff; const Bit32u ICacheWriteStampMask = 0x1fffffff;
const Bit32u ICacheFetchModeMask = ~ICacheWriteStampMask; const Bit32u ICacheFetchModeMask = ~ICacheWriteStampMask;
const Bit32u iCachePageDataMask = 0x20000000;
class bxPageWriteStampTable class bxPageWriteStampTable
{ {
@ -81,17 +82,12 @@ public:
pageWriteStampTable[pAddr>>12] = pageWriteStamp; 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. // are effectively invalidated.
Bit32u pageIndex = a20Addr >> 12; pageWriteStampTable[pAddr >> 12]--;
Bit32u writeStamp = pageWriteStampTable[pageIndex];
if (writeStamp & iCachePageDataMask)
{
pageWriteStampTable[pageIndex]--;
}
} }
BX_CPP_INLINE void resetWriteStamps(void); BX_CPP_INLINE void resetWriteStamps(void);
@ -108,29 +104,20 @@ extern bxPageWriteStampTable pageWriteStampTable;
#define BxICacheEntries (32 * 1024) // Must be a power of 2. #define BxICacheEntries (32 * 1024) // Must be a power of 2.
class bxICacheEntry_c { struct bxICacheEntry_c
public: {
Bit32u pAddr; // Physical address of the instruction
Bit32u pAddr; // Physical address of the instruction.
Bit32u writeStamp; // Generation ID. Each write to a physical page Bit32u writeStamp; // Generation ID. Each write to a physical page
// decrements this value. // decrements this value
bxInstruction_c i; // The instruction decode information. bxInstruction_c i; // The instruction decode information
}; };
class BOCHSAPI bxICache_c { class BOCHSAPI bxICache_c {
public: public:
bxICacheEntry_c entry[BxICacheEntries]; bxICacheEntry_c entry[BxICacheEntries];
Bit32u fetchModeMask;
public: public:
bxICache_c() bxICache_c() { flushICacheEntries(); }
{
// Initially clear the iCache;
for (unsigned i=0; i<BxICacheEntries; i++) {
entry[i].writeStamp = ICacheWriteStampInvalid;
}
fetchModeMask = iCachePageDataMask; // CS is 16-bit, Long Mode disabled
}
BX_CPP_INLINE unsigned hash(Bit32u pAddr) const BX_CPP_INLINE unsigned hash(Bit32u pAddr) const
{ {
@ -143,14 +130,16 @@ public:
}; };
BX_CPP_INLINE void bxICache_c::flushICacheEntries(void) BX_CPP_INLINE void bxICache_c::flushICacheEntries(void)
{ bxICacheEntry_c* e = entry; {
bxICacheEntry_c* e = entry;
for (unsigned i=0; i<BxICacheEntries; i++, e++) { for (unsigned i=0; i<BxICacheEntries; i++, e++) {
e->writeStamp = ICacheWriteStampInvalid; e->writeStamp = ICacheWriteStampInvalid;
} }
} }
BX_CPP_INLINE void bxICache_c::purgeICacheEntries(void) 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, // 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 // this function has to be called often enough that we can reset them

View File

@ -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. // Copyright (C) 2001 MandrakeSoft S.A.
@ -526,7 +526,7 @@ void BX_CPU_C::reset(unsigned source)
#endif #endif
#if BX_SUPPORT_ICACHE #if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS); BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif #endif
/* SS (Stack Segment) and descriptor cache */ /* SS (Stack Segment) and descriptor cache */

View File

@ -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. // 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. TLB_flush(1); // 1 = Flush Global entries also.
if (bx_dbg.paging) 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) 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. TLB_flush(1); // 1 = Flush Global entries also.
if (bx_dbg.paging) 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 BX_SUPPORT_PAE
if ( (oldCR4 & 0x00000020) != (newCR4 & 0x00000020) ) { if ( (oldCR4 & 0x00000020) != (newCR4 & 0x00000020) ) {

View File

@ -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. // Copyright (C) 2001 MandrakeSoft S.A.
@ -1160,7 +1160,7 @@ void BX_CPU_C::LOADALL(bxInstruction_c *i)
} }
#if BX_SUPPORT_ICACHE #if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS); BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif #endif
/* ES */ /* 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 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; // available for use by system
#if BX_SUPPORT_ICACHE #if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS); BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif #endif
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 8) & BX_SELECTOR_RPL_MASK; 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 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; // available for use by system
#if BX_SUPPORT_ICACHE #if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS); BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif #endif
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 24) | 3; BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 24) | 3;

View File

@ -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. // 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]) { if (seg == &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS]) {
seg->cache.u.segment.executable = 1; /* code segment */ seg->cache.u.segment.executable = 1; /* code segment */
#if BX_SUPPORT_ICACHE #if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.fetchModeMask = createFetchModeMask(BX_CPU_THIS); BX_CPU_THIS_PTR fetchModeMask = createFetchModeMask(BX_CPU_THIS);
#endif #endif
invalidate_prefetch_q(); invalidate_prefetch_q();
} }

View File

@ -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. // 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 #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 #endif
// SS // SS

View File

@ -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. // 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; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.rpl = 3;
#if BX_SUPPORT_ICACHE // update instruction cache #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 #endif
BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS].cache.valid = 1;