diff --git a/bochs/cpu/access.cc b/bochs/cpu/access.cc index 45dd3eee8..2bd54a249 100644 --- a/bochs/cpu/access.cc +++ b/bochs/cpu/access.cc @@ -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; } diff --git a/bochs/cpu/apic.cc b/bochs/cpu/apic.cc index a69625170..3ec0e9e89 100644 --- a/bochs/cpu/apic.cc +++ b/bochs/cpu/apic.cc @@ -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 diff --git a/bochs/cpu/apic.h b/bochs/cpu/apic.h index 62df6df02..2778935c7 100644 --- a/bochs/cpu/apic.h +++ b/bochs/cpu/apic.h @@ -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 diff --git a/bochs/cpu/cpu.cc b/bochs/cpu/cpu.cc index b9768bbfc..a18f6b01e 100644 --- a/bochs/cpu/cpu.cc +++ b/bochs/cpu/cpu.cc @@ -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; iiCache.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 } diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index fabfcbf33..70b08c167 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -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; diff --git a/bochs/cpu/icache.h b/bochs/cpu/icache.h index c7309ecd7..20127a85a 100755 --- a/bochs/cpu/icache.h +++ b/bochs/cpu/icache.h @@ -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>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 diff --git a/bochs/cpu/init.cc b/bochs/cpu/init.cc index bd1846d2b..ccd32a8c2 100644 --- a/bochs/cpu/init.cc +++ b/bochs/cpu/init.cc @@ -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) diff --git a/bochs/iodev/ioapic.cc b/bochs/iodev/ioapic.cc index 947f81094..bb9092ec0 100644 --- a/bochs/iodev/ioapic.cc +++ b/bochs/iodev/ioapic.cc @@ -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 @@ -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<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<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); diff --git a/bochs/memory/memory.cc b/bochs/memory/memory.cc index 3289c3d4a..8eea9ca4b 100644 --- a/bochs/memory/memory.cc +++ b/bochs/memory/memory.cc @@ -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 diff --git a/bochs/memory/misc_mem.cc b/bochs/memory/misc_mem.cc index d2cd7e2f8..01ec6a975 100644 --- a/bochs/memory/misc_mem.cc +++ b/bochs/memory/misc_mem.cc @@ -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);