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:
parent
7aef2d5892
commit
08f958f458
@ -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
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user