Fixed pageWriteStampTable to handle BIOS code as well - increased the table to all 4G instead of allocated memory size

Avoid checking of pageWriteStamp in the heart of cpu loop with trace cache - now decWriteStamp will post stopTraceExecution event if it hits code page
This commit is contained in:
Stanislav Shwartsman 2008-03-29 21:01:25 +00:00
parent 7aef2d5892
commit 08f958f458
6 changed files with 51 additions and 57 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.212 2008-03-22 21:29:39 sshwarts Exp $
// $Id: cpu.cc,v 1.213 2008-03-29 21:01:23 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -224,9 +224,7 @@ no_async_event:
break;
}
// check for end of the trace and self modifying code
if ((--length == 0) || currPageWriteStamp != *(BX_CPU_THIS_PTR currPageWriteStampPtr))
goto no_async_event;
if (--length == 0) goto no_async_event;
}
#endif
} // while (1)
@ -656,15 +654,9 @@ 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 fetchModeMask;
if ((pageWriteStamp & ICacheFetchModeMask) != fetchModeMask)
{
// The current CPU mode does not match iCache entries for this
// physical page.
pageWriteStamp &= ICacheWriteStampMask; // Clear out old fetch mode bits.
pageWriteStamp |= fetchModeMask; // Add in new ones.
pageWriteStampTable.setPageWriteStamp(pAddr, pageWriteStamp);
}
pageWriteStamp &= ~ICacheWriteStampFetchModeMask; // Clear out old fetch mode bits
pageWriteStamp |= BX_CPU_THIS_PTR fetchModeMask; // And add new ones
pageWriteStampTable.setPageWriteStamp(pAddr, pageWriteStamp);
#endif
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.440 2008-03-29 18:44:13 sshwarts Exp $
// $Id: cpu.h,v 1.441 2008-03-29 21:01:24 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -854,7 +854,9 @@ public: // for now...
Bit32u debug_trap; // holds DR6 value (16bit) to be set as well
volatile Bit32u async_event;
#define BX_ASYNC_EVENT_STOP_TRACE (0x80000000)
#if BX_SUPPORT_TRACE_CACHE
#define BX_ASYNC_EVENT_STOP_TRACE (0x80000000)
#endif
volatile bx_bool INTR;
volatile bx_bool smi_pending;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: icache.cc,v 1.10 2008-03-06 20:22:24 sshwarts Exp $
// $Id: icache.cc,v 1.11 2008-03-29 21:01:25 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007 Stanislav Shwartsman
@ -73,6 +73,12 @@ void flushICaches(void)
#if BX_SUPPORT_TRACE_CACHE
void stopTraceExecution(void)
{
for (unsigned i=0; i<BX_SMP_PROCESSORS; i++)
BX_CPU(i)->async_event |= BX_ASYNC_EVENT_STOP_TRACE;
}
void BX_CPU_C::serveICacheMiss(bxICacheEntry_c *cache_entry, Bit32u eipBiased, bx_phy_address pAddr)
{
// Cache miss. We weren't so lucky, but let's be optimistic - try to build

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: icache.h,v 1.29 2008-03-21 20:02:48 sshwarts Exp $
// $Id: icache.h,v 1.30 2008-03-29 21:01:25 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -29,15 +29,20 @@
#ifndef BX_ICACHE_H
#define BX_ICACHE_H
#if BX_SUPPORT_ICACHE
#include <assert.h>
// bit31: 1=CS is 32/64-bit, 0=CS is 16-bit.
// bit30: 1=Long Mode, 0=not Long Mode.
// Combination bit31=1 & bit30=1 is invalid.
const Bit32u ICacheWriteStampInvalid = 0xffffffff;
const Bit32u ICacheWriteStampStart = 0x3fffffff;
const Bit32u ICacheWriteStampMask = 0x3fffffff;
const Bit32u ICacheFetchModeMask = ~ICacheWriteStampMask;
// Combination bit31=1 & bit30=1 is invalid (data page)
const Bit32u ICacheWriteStampInvalid = 0xffffffff;
const Bit32u ICacheWriteStampStart = 0x3fffffff;
const Bit32u ICacheWriteStampFetchModeMask = ~ICacheWriteStampStart;
#if BX_SUPPORT_TRACE_CACHE
extern void stopTraceExecution(void);
#endif
class bxPageWriteStampTable
{
@ -45,53 +50,43 @@ class bxPageWriteStampTable
// Each time a write occurs to a physical page, a generation ID is
// decremented. Only iCache entries which have write stamps matching
// the physical page write stamp are valid.
Bit32u *pageWriteStampTable;
Bit32u memSizeInBytes;
#define PHY_MEM_SIZE_IN_MB (1024*1024)
public:
bxPageWriteStampTable(): pageWriteStampTable(NULL), memSizeInBytes(0) {}
bxPageWriteStampTable(Bit32u memSize) { alloc(memSize); }
~bxPageWriteStampTable() { delete [] pageWriteStampTable; }
BX_CPP_INLINE void alloc(Bit32u memSize)
{
if (memSizeInBytes > 0) {
delete [] pageWriteStampTable;
}
memSizeInBytes = memSize;
pageWriteStampTable = new Bit32u [memSizeInBytes>>12];
bxPageWriteStampTable() {
pageWriteStampTable = new Bit32u[PHY_MEM_SIZE_IN_MB];
resetWriteStamps();
}
~bxPageWriteStampTable() { delete [] pageWriteStampTable; }
BX_CPP_INLINE Bit32u getPageWriteStamp(bx_phy_address pAddr) const
{
if (pAddr < memSizeInBytes)
return pageWriteStampTable[pAddr>>12];
else
return ICacheWriteStampInvalid;
return pageWriteStampTable[pAddr>>12];
}
BX_CPP_INLINE const Bit32u *getPageWriteStampPtr(bx_phy_address pAddr) const
{
if (pAddr < memSizeInBytes)
return &pageWriteStampTable[pAddr>>12];
else
return &ICacheWriteStampInvalid;
return &pageWriteStampTable[pAddr>>12];
}
BX_CPP_INLINE void setPageWriteStamp(bx_phy_address pAddr, Bit32u pageWriteStamp)
{
if (pAddr < memSizeInBytes)
pageWriteStampTable[pAddr>>12] = pageWriteStamp;
pageWriteStampTable[pAddr>>12] = pageWriteStamp;
}
BX_CPP_INLINE void decWriteStamp(bx_phy_address pAddr)
{
assert(pAddr < memSizeInBytes);
pAddr >>= 12;
#if BX_SUPPORT_TRACE_CACHE
if ((pageWriteStampTable[pAddr] & ICacheWriteStampFetchModeMask) != ICacheWriteStampFetchModeMask) {
stopTraceExecution(); // one of the CPUs running trace from this page
}
#endif
// Decrement page write stamp, so iCache entries with older stamps
// are effectively invalidated.
pageWriteStampTable[pAddr >> 12]--;
pageWriteStampTable[pAddr]--;
}
BX_CPP_INLINE void resetWriteStamps(void);
@ -100,15 +95,15 @@ public:
BX_CPP_INLINE void bxPageWriteStampTable::resetWriteStamps(void)
{
for (Bit32u i=0; i<(memSizeInBytes>>12); i++) {
for (Bit32u i=0; i<PHY_MEM_SIZE_IN_MB; i++) {
pageWriteStampTable[i] = ICacheWriteStampInvalid;
}
}
BX_CPP_INLINE void bxPageWriteStampTable::purgeWriteStamps(void)
{
for (Bit32u i=0; i<(memSizeInBytes>>12); i++) {
pageWriteStampTable[i] |= ICacheWriteStampMask;
for (Bit32u i=0; i<PHY_MEM_SIZE_IN_MB; i++) {
pageWriteStampTable[i] |= ICacheWriteStampStart;
}
}
@ -177,11 +172,13 @@ BX_CPP_INLINE void bxICache_c::purgeICacheEntries(void)
if (e->writeStamp != pageWriteStamp)
e->writeStamp = ICacheWriteStampInvalid; // invalidate entry
else
e->writeStamp |= ICacheWriteStampMask;
e->writeStamp |= ICacheWriteStampStart;
}
}
extern void purgeICaches(void);
extern void flushICaches(void);
#endif // BX_SUPPORT_ICACHE
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: init.cc,v 1.157 2008-03-29 09:34:35 sshwarts Exp $
// $Id: init.cc,v 1.158 2008-03-29 21:01:25 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -765,6 +765,7 @@ void BX_CPU_C::reset(unsigned source)
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR updateFetchModeMask();
flushICaches();
BX_CPU_THIS_PTR currPageWriteStampPtr = pageWriteStampTable.getPageWriteStampPtr(0xFFFFFFF0);
#endif
/* DS (Data Segment) and descriptor cache */

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: main.cc,v 1.375 2008-03-26 22:39:38 sshwarts Exp $
// $Id: main.cc,v 1.376 2008-03-29 21:01:23 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -1032,10 +1032,6 @@ void bx_init_hardware()
bx_param_num_c *bxp_memsize = SIM->get_param_num(BXPN_MEM_SIZE);
Bit32u memSize = bxp_memsize->get() * 1024*1024;
#if BX_SUPPORT_ICACHE
pageWriteStampTable.alloc(memSize);
#endif
BX_MEM(0)->init_memory(memSize);
// First load the BIOS and VGABIOS