Separate pageWriteStamp from ICACHE. The pageWriteStamp has totally independant structure and could be used in future with icache structure. Also it could be significantly speeded up using BX_SMF analog constructions.

This commit is contained in:
Stanislav Shwartsman 2005-04-10 19:42:48 +00:00
parent a61f035998
commit 1755589376
11 changed files with 107 additions and 79 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: access.cc,v 1.55 2005-03-30 19:55:47 sshwarts Exp $
// $Id: access.cc,v 1.56 2005-04-10 19:42:46 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -305,7 +305,7 @@ accessOK:
if (hostPageAddr) {
*hostAddr = *data;
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.decWriteStamp(tlbEntry->ppf);
pageWriteStampTable.decWriteStamp(tlbEntry->ppf);
#endif
return;
}
@ -356,7 +356,7 @@ accessOK:
if (hostPageAddr) {
WriteHostWordToLittleEndian(hostAddr, *data);
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.decWriteStamp(tlbEntry->ppf);
pageWriteStampTable.decWriteStamp(tlbEntry->ppf);
#endif
return;
}
@ -408,7 +408,7 @@ accessOK:
if (hostPageAddr) {
WriteHostDWordToLittleEndian(hostAddr, *data);
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.decWriteStamp(tlbEntry->ppf);
pageWriteStampTable.decWriteStamp(tlbEntry->ppf);
#endif
return;
}
@ -460,7 +460,7 @@ accessOK:
if (hostPageAddr) {
WriteHostQWordToLittleEndian(hostAddr, *data);
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.decWriteStamp(tlbEntry->ppf);
pageWriteStampTable.decWriteStamp(tlbEntry->ppf);
#endif
return;
}
@ -700,7 +700,7 @@ accessOK:
*data = *hostAddr;
BX_CPU_THIS_PTR address_xlation.pages = (bx_ptr_equiv_t) hostAddr;
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.decWriteStamp(tlbEntry->ppf);
pageWriteStampTable.decWriteStamp(tlbEntry->ppf);
#endif
return;
}
@ -754,7 +754,7 @@ accessOK:
ReadHostWordFromLittleEndian(hostAddr, *data);
BX_CPU_THIS_PTR address_xlation.pages = (bx_ptr_equiv_t) hostAddr;
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.decWriteStamp(tlbEntry->ppf);
pageWriteStampTable.decWriteStamp(tlbEntry->ppf);
#endif
return;
}
@ -807,7 +807,7 @@ accessOK:
ReadHostDWordFromLittleEndian(hostAddr, *data);
BX_CPU_THIS_PTR address_xlation.pages = (bx_ptr_equiv_t) hostAddr;
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.decWriteStamp(tlbEntry->ppf);
pageWriteStampTable.decWriteStamp(tlbEntry->ppf);
#endif
return;
}
@ -860,7 +860,7 @@ accessOK:
ReadHostQWordFromLittleEndian(hostAddr, *data);
BX_CPU_THIS_PTR address_xlation.pages = (bx_ptr_equiv_t) hostAddr;
#if BX_SUPPORT_ICACHE
BX_CPU_THIS_PTR iCache.decWriteStamp(tlbEntry->ppf);
pageWriteStampTable.decWriteStamp(tlbEntry->ppf);
#endif
return;
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: apic.cc,v 1.46 2005-04-02 18:49:42 sshwarts Exp $
// $Id: apic.cc,v 1.47 2005-04-10 19:42:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
#define NEED_CPU_REG_SHORTCUTS 1
@ -485,10 +485,6 @@ void bx_local_apic_c::write (Bit32u addr, Bit32u *data, unsigned len)
int dest_mode = (icr_low >> 11) & 1;
int delivery_mode = (icr_low >> 8) & 7;
int vector = (icr_low & 0xff);
#if BX_CPU_LEVEL >= 6 && BX_SUPPORT_SSE >= 2
trig_mode = 0; // these flags have no meaning for P4 processor
level = 1;
#endif
// deliver will call get_delivery_bitmask to decide who to send to.
// This local_apic class redefines get_delivery_bitmask to
// implement the destination shorthand field, which doesn't exist

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: apic.h,v 1.14 2005-03-19 20:44:00 sshwarts Exp $
// $Id: apic.h,v 1.15 2005-04-10 19:42:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -38,7 +38,7 @@ typedef enum {
#define APIC_BASE_ADDR 0xfee00000 // default APIC address
// todo: Pentium APIC_VERSION_ID (Pentium has 3 LVT entries)
#if BX_CPU_LEVEL >= 6 && BX_SUPPORT_SSE >= 2
#if BX_CPU_LEVEL == 6 && BX_SUPPORT_SSE >= 2
# define APIC_VERSION_ID 0x00050014 // P4 has 6 LVT entries
#else
# define APIC_VERSION_ID 0x00040010 // P6 has 4 LVT entries

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.cc,v 1.102 2005-03-19 18:43:00 sshwarts Exp $
// $Id: cpu.cc,v 1.103 2005-04-10 19:42:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -67,6 +67,18 @@ BOCHSAPI BX_MEM_C *bx_mem_array[BX_ADDRESS_SPACES];
#if BX_SUPPORT_ICACHE
bxPageWriteStampTable pageWriteStampTable;
void invalidateIcacheEntries(Bit32u a20Addr)
{
#if BX_SMP_PROCESSORS == 1
BX_CPU(0)->iCache.invalidatePage(a20Addr);
#else
for (unsigned i=0; i<BX_SMP_PROCESSORS; i++)
BX_CPU(i)->iCache.invalidatePage(a20Addr);
#endif
}
#define InstrumentICACHE 0
#if InstrumentICACHE
@ -215,7 +227,7 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count)
bxICacheEntry_c *cache_entry = &(BX_CPU_THIS_PTR iCache.entry[iCacheHash]);
i = &(cache_entry->i);
Bit32u pageWriteStamp = BX_CPU_THIS_PTR iCache.getPageWriteStamp(pAddr);
Bit32u pageWriteStamp = pageWriteStampTable.getPageWriteStamp(pAddr);
#if BX_SUPPORT_ICACHE
InstrICache_Increment(iCacheLookups);
@ -278,7 +290,7 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count)
Bit32u fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
pageWriteStamp &= ICacheWriteStampMask; // Clear out old fetch mode bits.
pageWriteStamp |= fetchModeMask; // Add in new ones.
BX_CPU_THIS_PTR iCache.setPageWriteStamp(pAddr, pageWriteStamp);
pageWriteStampTable.setPageWriteStamp(pAddr, pageWriteStamp);
cache_entry->pAddr = pAddr;
cache_entry->writeStamp = pageWriteStamp;
#endif
@ -775,7 +787,7 @@ void BX_CPU_C::prefetch(void)
}
#if BX_SUPPORT_ICACHE
Bit32u pageWriteStamp = BX_CPU_THIS_PTR iCache.getPageWriteStamp(pAddr);
Bit32u pageWriteStamp = pageWriteStampTable.getPageWriteStamp(pAddr);
Bit32u fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask;
if ((pageWriteStamp & ICacheFetchModeMask) != fetchModeMask)
{
@ -783,7 +795,7 @@ void BX_CPU_C::prefetch(void)
// physical page.
pageWriteStamp &= ICacheWriteStampMask; // Clear out old fetch mode bits.
pageWriteStamp |= fetchModeMask; // Add in new ones.
BX_CPU_THIS_PTR iCache.setPageWriteStamp(pAddr, pageWriteStamp);
pageWriteStampTable.setPageWriteStamp(pAddr, pageWriteStamp);
}
#endif
}

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: cpu.h,v 1.213 2005-03-30 22:30:37 sshwarts Exp $
// $Id: cpu.h,v 1.214 2005-04-10 19:42:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -343,7 +343,7 @@
#if BX_SUPPORT_APIC
#define BX_CPU_INTR (BX_CPU_THIS_PTR INTR || BX_CPU_THIS_PTR local_apic.INTR)
#else
#define BX_CPU_INTR BX_CPU_THIS_PTR INTR
#define BX_CPU_INTR (BX_CPU_THIS_PTR INTR)
#endif
class BX_CPU_C;

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: icache.h,v 1.5 2005-03-19 20:44:00 sshwarts Exp $
// $Id: icache.h,v 1.6 2005-04-10 19:42:47 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -26,7 +26,7 @@
#ifndef BX_ICACHE_H
# define BX_ICACHE_H 1
#define BX_ICACHE_H
#define BxICacheEntries (32 * 1024) // Must be a power of 2.
@ -37,6 +37,7 @@
#define ICacheWriteStampMax 0x1fffffff // Decrements from here.
#define ICacheWriteStampMask 0x1fffffff
#define ICacheFetchModeMask (~ICacheWriteStampMask)
#define iCachePageDataMask 0x20000000
class bxICacheEntry_c {
public:
@ -47,50 +48,67 @@ class bxICacheEntry_c {
bxInstruction_c i; // The instruction decode information.
};
class BOCHSAPI bxICache_c
{
// A table (dynamically allocated) to store write-stamp
// generation IDs. 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; // Allocated later.
class BOCHSAPI bxICache_c {
public:
bxICacheEntry_c entry[BxICacheEntries];
Bit32u fetchModeMask;
Bit32u memSizeInBytes;
public:
bxICache_c()
{
// Initially clear the iCache;
memset(this, 0, sizeof(*this));
pageWriteStampTable = NULL;
memSizeInBytes = 0;
for (unsigned i=0; i<BxICacheEntries; i++) {
entry[i].writeStamp = ICacheWriteStampInvalid;
}
}
BX_CPP_INLINE void alloc(Bit32u memSize)
{
memSizeInBytes = memSize;
pageWriteStampTable =
(Bit32u*) malloc(sizeof(Bit32u) * (memSizeInBytes>>12));
for (unsigned i=0; i<(memSizeInBytes>>12); i++) {
pageWriteStampTable[i] = ICacheWriteStampInvalid;
}
fetchModeMask = 0; // CS is 16-bit, Long Mode disabled, Data page
}
BX_CPP_INLINE void decWriteStamp(Bit32u a20Addr);
BX_CPP_INLINE unsigned hash(Bit32u pAddr) const
{
// A pretty dumb hash function for now.
return pAddr & (BxICacheEntries-1);
}
BX_CPP_INLINE void invalidatePage(Bit32u a20Addr);
};
BX_CPP_INLINE void bxICache_c::invalidatePage(Bit32u a20Addr)
{
// Take the hash of the 0th page offset.
unsigned iCacheHash = hash(a20Addr & 0xfffff000);
for (unsigned o=0; o<4096; o++) {
entry[iCacheHash].writeStamp = ICacheWriteStampInvalid;
iCacheHash = (iCacheHash + 1) % BxICacheEntries;
}
}
extern void invalidateIcacheEntries(Bit32u a20AddrPage);
class bxPageWriteStampTable {
// A table (dynamically allocated) to store write-stamp generation IDs.
// 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;
public:
bxPageWriteStampTable(): pageWriteStampTable(NULL), memSizeInBytes(0) {}
bxPageWriteStampTable(Bit32u memSize) { alloc(memSize); }
~bxPageWriteStampTable() { delete [] pageWriteStampTable; }
BX_CPP_INLINE void alloc(Bit32u memSize)
{
memSizeInBytes = memSize;
pageWriteStampTable = new Bit32u [memSizeInBytes>>12];
for (Bit32u i=0; i<(memSizeInBytes>>12); i++) {
pageWriteStampTable[i] = ICacheWriteStampInvalid;
}
}
BX_CPP_INLINE Bit32u getPageWriteStamp(Bit32u pAddr) const
{
if (pAddr < memSizeInBytes)
@ -104,15 +122,18 @@ public:
if (pAddr < memSizeInBytes)
pageWriteStampTable[pAddr>>12] = pageWriteStamp;
}
BX_CPP_INLINE void decWriteStamp(Bit32u a20Addr);
};
BX_CPP_INLINE void bxICache_c::decWriteStamp(Bit32u a20Addr)
BX_CPP_INLINE void bxPageWriteStampTable::decWriteStamp(Bit32u a20Addr)
{
// Increment page write stamp, so iCache entries with older stamps
// are effectively invalidated.
Bit32u pageIndex = a20Addr >> 12;
Bit32u writeStamp = pageWriteStampTable[pageIndex];
if (writeStamp & 0x20000000)
if (writeStamp & iCachePageDataMask)
{
// Page possibly contains iCache code.
if (writeStamp & ICacheWriteStampMask) {
@ -120,21 +141,18 @@ BX_CPP_INLINE void bxICache_c::decWriteStamp(Bit32u a20Addr)
pageWriteStampTable[pageIndex]--;
}
else {
// Long case: there is no more room to decrement. We have dump
// Long case: there is no more room to decrement. We have to dump
// all iCache entries which can possibly hash to this page since
// we don't keep track of individual entries.
invalidateIcacheEntries(a20Addr);
// Take the hash of the 0th page offset.
unsigned iCacheHash = hash(a20Addr & 0xfffff000);
for (unsigned o=0; o<4096; o++) {
entry[iCacheHash].writeStamp = ICacheWriteStampInvalid;
iCacheHash = (iCacheHash + 1) % BxICacheEntries;
}
// Reset write stamp to highest value to begin the decrementing process
// again.
// Reset write stamp to highest value to begin the decrementing
// process again.
pageWriteStampTable[pageIndex] = ICacheWriteStampInvalid;
}
}
}
extern bxPageWriteStampTable pageWriteStampTable;
#endif

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: init.cc,v 1.69 2005-03-22 18:19:54 kevinlawton Exp $
// $Id: init.cc,v 1.70 2005-04-10 19:42:48 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -160,7 +160,7 @@ cpu_param_handler (bx_param_c *param, int set, Bit64s val)
void BX_CPU_C::init(BX_MEM_C *addrspace)
{
BX_DEBUG(( "Init $Id: init.cc,v 1.69 2005-03-22 18:19:54 kevinlawton Exp $"));
BX_DEBUG(( "Init $Id: init.cc,v 1.70 2005-04-10 19:42:48 sshwarts Exp $"));
// BX_CPU_C constructor
BX_CPU_THIS_PTR set_INTR (0);
#if BX_SUPPORT_APIC
@ -416,10 +416,6 @@ void BX_CPU_C::init(BX_MEM_C *addrspace)
bx_param_num_c::set_default_format (oldfmt);
}
#endif
#if BX_SUPPORT_ICACHE
iCache.alloc(mem->len);
#endif
}
BX_CPU_C::~BX_CPU_C(void)

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: ioapic.cc,v 1.15 2005-03-19 18:43:00 sshwarts Exp $
// $Id: ioapic.cc,v 1.16 2005-04-10 19:42:48 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
#include <stdio.h>
@ -138,11 +138,10 @@ void bx_ioapic_c::raise_irq (unsigned vector, unsigned from)
{
BX_DEBUG(("IOAPIC: received vector %d", vector));
if ((vector >= 0) && (vector <= BX_APIC_LAST_VECTOR)) {
if (vector == 0) vector = 2;
Bit32u bit = 1<<vector;
if ((irr & bit) == 0) {
irr |= bit;
service_ioapic ();
}
irr |= bit;
service_ioapic ();
} else {
BX_PANIC(("IOAPIC: vector %d out of range", vector));
}
@ -164,6 +163,7 @@ void bx_ioapic_c::service_ioapic ()
entry->parse_value();
if (!entry->masked) {
// clear irr bit and deliver
BX_INFO (("dest=%02x, masked=%d, trig_mode=%d, remote_irr=%d, polarity=%d, delivery_status=%d, dest_mode=%d, delivery_mode=%d, vector=%02x", entry->dest, entry->masked, entry->trig_mode, entry->remote_irr, entry->polarity, entry->delivery_status, entry->dest_mode, entry->delivery_mode, entry->vector));
bx_bool done = deliver (entry->dest, entry->dest_mode, entry->delivery_mode, entry->vector, entry->polarity, entry->trig_mode);
if (done) {
irr &= ~(1<<bit);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: main.cc,v 1.286 2005-03-16 16:36:31 vruppert Exp $
// $Id: main.cc,v 1.287 2005-04-10 19:42:46 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -848,8 +848,14 @@ bx_init_hardware()
BX_ERROR(("No romimage to load. Is your bochsrc file loaded/valid ?"));
}
Bit32u memSize = bx_options.memory.Osize->get ()*1024*1024;
#if BX_SUPPORT_ICACHE
pageWriteStampTable.alloc(memSize);
#endif`
#if BX_SMP_PROCESSORS==1
BX_MEM(0)->init_memory(bx_options.memory.Osize->get () * 1024*1024);
BX_MEM(0)->init_memory(memSize);
// First load the BIOS and VGABIOS
BX_MEM(0)->load_ROM(bx_options.rom.Opath->getptr (), bx_options.rom.Oaddress->get (), 0);
@ -876,7 +882,7 @@ bx_init_hardware()
#else
// SMP initialization
bx_mem_array[0] = new BX_MEM_C ();
bx_mem_array[0]->init_memory(bx_options.memory.Osize->get () * 1024*1024);
bx_mem_array[0]->init_memory(memSize);
// First load the BIOS and VGABIOS
bx_mem_array[0]->load_ROM(bx_options.rom.Opath->getptr (), bx_options.rom.Oaddress->get (), 0);

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: memory.cc,v 1.39 2005-01-15 13:10:15 sshwarts Exp $
// $Id: memory.cc,v 1.40 2005-04-10 19:42:48 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -67,7 +67,7 @@ BX_MEM_C::writePhysicalPage(BX_CPU_C *cpu, Bit32u addr, unsigned len, void *data
#if BX_SUPPORT_ICACHE
if (a20addr < BX_MEM_THIS len)
cpu->iCache.decWriteStamp(a20addr);
pageWriteStampTable.decWriteStamp(a20addr);
#endif
#if BX_SUPPORT_APIC

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: misc_mem.cc,v 1.58 2005-01-29 23:29:08 vruppert Exp $
// $Id: misc_mem.cc,v 1.59 2005-04-10 19:42:48 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -95,7 +95,7 @@ void BX_MEM_C::init_memory(int memsize)
{
int idx;
BX_DEBUG(("Init $Id: misc_mem.cc,v 1.58 2005-01-29 23:29:08 vruppert Exp $"));
BX_DEBUG(("Init $Id: misc_mem.cc,v 1.59 2005-04-10 19:42:48 sshwarts Exp $"));
// you can pass 0 if memory has been allocated already through
// the constructor, or the desired size of memory if it hasn't
// BX_INFO(("%.2fMB", (float)(BX_MEM_THIS megabytes) ));
@ -470,7 +470,7 @@ BX_MEM_C::getHostMemAddr(BX_CPU_C *cpu, Bit32u a20Addr, unsigned op)
}
#if BX_SUPPORT_ICACHE
cpu->iCache.decWriteStamp(a20Addr);
pageWriteStampTable.decWriteStamp(a20Addr);
#endif
return(retAddr);