diff --git a/bochs/cpu/cpu.cc b/bochs/cpu/cpu.cc index 7fb4f6be1..9badc2741 100644 --- a/bochs/cpu/cpu.cc +++ b/bochs/cpu/cpu.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.cc,v 1.76 2003-03-17 00:40:57 cbothamy Exp $ +// $Id: cpu.cc,v 1.77 2003-05-10 22:25:43 kevinlawton Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -193,18 +193,16 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count) #if BX_SupportICache unsigned iCacheHash; - Bit32u pAddr, pageWriteStamp, fetchModeMask; + Bit32u pAddr, pageWriteStamp; pAddr = BX_CPU_THIS_PTR pAddrA20Page + eipBiased; iCacheHash = BX_CPU_THIS_PTR iCache.hash( pAddr ); i = & BX_CPU_THIS_PTR iCache.entry[iCacheHash].i; pageWriteStamp = BX_CPU_THIS_PTR iCache.pageWriteStampTable[pAddr>>12]; - fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask; if ( (BX_CPU_THIS_PTR iCache.entry[iCacheHash].pAddr == pAddr) && - (BX_CPU_THIS_PTR iCache.entry[iCacheHash].writeStamp == pageWriteStamp) && - ((pageWriteStamp & fetchModeMask) == fetchModeMask) ) { + (BX_CPU_THIS_PTR iCache.entry[iCacheHash].writeStamp == pageWriteStamp) ) { // iCache hit. Instruction is already decoded and stored in // the instruction cache. @@ -228,6 +226,7 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count) // case we always have an iCache miss. :^) bx_address remainingInPage; unsigned maxFetch; + Bit32u fetchModeMask; remainingInPage = (BX_CPU_THIS_PTR eipPageWindowSize - eipBiased); maxFetch = 15; @@ -243,6 +242,7 @@ BX_CPU_C::cpu_loop(Bit32s max_instr_count) // willing to dump all iCache entries which can hash to this page. // Therefore, in either case, we can keep the counter as-is and // replace the fetch mode bits. + fetchModeMask = BX_CPU_THIS_PTR iCache.fetchModeMask; pageWriteStamp &= 0x1fffffff; // Clear out old fetch mode bits. pageWriteStamp |= fetchModeMask; // Add in new ones. BX_CPU_THIS_PTR iCache.pageWriteStampTable[pAddr>>12] = pageWriteStamp; @@ -776,6 +776,21 @@ BX_CPU_C::prefetch(void) pAddr)); } } + + Bit32u pageWriteStamp; + Bit32u fetchModeMask; + Bit32u phyPageIndex; + + phyPageIndex = pAddr >> 12; + pageWriteStamp = BX_CPU_THIS_PTR iCache.pageWriteStampTable[phyPageIndex]; + fetchModeMask = BX_CPU_THIS_PTR iCache.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. + BX_CPU_THIS_PTR iCache.pageWriteStampTable[phyPageIndex] = pageWriteStamp; + } } @@ -842,33 +857,6 @@ BX_CPU_THIS_PTR eipPageWindowSize = 0; // Fixme } -#if 0 -// Now a no-op. - - // If control has transfered locally, it is possible the prefetch Q is - // still valid. This would happen for repeat instructions, and small - // branches. - void -BX_CPU_C::revalidate_prefetch_q(void) -{ -#ifdef __GNUC__ -#warning "::revalidate_prefetch_q() is ifdef'd out." -#endif - bx_address eipBiased; - - eipBiased = RIP + BX_CPU_THIS_PTR eipPageBias; - if ( eipBiased < BX_CPU_THIS_PTR eipPageWindowSize ) { - // Good, EIP still within prefetch window. - } - else { - // EIP has branched outside the prefetch window. Mark the - // prefetch info as invalid, and requiring update. - BX_CPU_THIS_PTR eipPageWindowSize = 0; - } -} -#endif - - #if BX_EXTERNAL_DEBUGGER void diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index ba5fbb174..cd6c40edf 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.h,v 1.137 2003-04-22 20:21:31 sshwarts Exp $ +// $Id: cpu.h,v 1.138 2003-05-10 22:25:48 kevinlawton Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -990,6 +990,7 @@ typedef void (BX_CPU_C::*BxExecutePtr_tR)(bxInstruction_c *) BX_CPP_AttrRegparmN #define ICacheWriteStampInvalid 0x1fffffff #define ICacheWriteStampMax 0x1fffffff // Decrements from here. #define ICacheWriteStampMask 0x1fffffff +#define ICacheFetchModeMask (~ICacheWriteStampMask) class bxICacheEntry_c { public: diff --git a/bochs/cpu/ctrl_xfer16.cc b/bochs/cpu/ctrl_xfer16.cc index 37b4474d2..e37d12222 100644 --- a/bochs/cpu/ctrl_xfer16.cc +++ b/bochs/cpu/ctrl_xfer16.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer16.cc,v 1.19 2003-02-13 15:03:59 sshwarts Exp $ +// $Id: ctrl_xfer16.cc,v 1.20 2003-05-10 22:25:51 kevinlawton Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -40,7 +40,7 @@ BailBigRSP("RETnear16_Iw"); Bit16u imm16; Bit16u return_IP; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_ret; @@ -70,7 +70,7 @@ BX_CPU_C::RETnear16(bxInstruction_c *i) BailBigRSP("RETnear16"); Bit16u return_IP; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_ret; @@ -164,7 +164,7 @@ BX_CPU_C::CALL_Aw(bxInstruction_c *i) BailBigRSP("CALL_Aw"); Bit32u new_EIP; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_call; @@ -226,7 +226,7 @@ BX_CPU_C::CALL_Ew(bxInstruction_c *i) BailBigRSP("CALL_Ew"); Bit16u op1_16; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_call; @@ -298,7 +298,7 @@ BX_CPU_C::JMP_Jw(bxInstruction_c *i) BailBigRSP("JMP_Jw"); Bit32u new_EIP; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); new_EIP = EIP + (Bit32s) i->Id(); new_EIP &= 0x0000ffff; @@ -438,7 +438,7 @@ BailBigRSP("JMP_Ew"); Bit32u new_EIP; Bit16u op1_16; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); if (i->modC0()) { op1_16 = BX_READ_16BIT_REG(i->rm()); diff --git a/bochs/cpu/ctrl_xfer32.cc b/bochs/cpu/ctrl_xfer32.cc index 9e31cd326..5aeee8705 100644 --- a/bochs/cpu/ctrl_xfer32.cc +++ b/bochs/cpu/ctrl_xfer32.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer32.cc,v 1.25 2003-02-13 15:03:59 sshwarts Exp $ +// $Id: ctrl_xfer32.cc,v 1.26 2003-05-10 22:25:52 kevinlawton Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -43,7 +43,7 @@ BailBigRSP("RETnear32_Iw"); Bit32u temp_ESP; Bit32u return_EIP; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_ret; @@ -102,7 +102,7 @@ BailBigRSP("RETnear32"); Bit32u temp_ESP; Bit32u return_EIP; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_ret; @@ -218,7 +218,7 @@ BailBigRSP("CALL_Ad"); Bit32u new_EIP; Bit32s disp32; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_call; @@ -279,7 +279,7 @@ BailBigRSP("CALL_Ed"); Bit32u temp_ESP; Bit32u op1_32; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_call; @@ -356,7 +356,7 @@ BX_CPU_C::JMP_Jd(bxInstruction_c *i) BailBigRSP("JMP_Jd"); Bit32u new_EIP; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); new_EIP = EIP + (Bit32s) i->Id(); @@ -527,7 +527,7 @@ BailBigRSP("JMP_Ed"); Bit32u new_EIP; Bit32u op1_32; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); /* op1_32 is a register or memory reference */ if (i->modC0()) { diff --git a/bochs/cpu/ctrl_xfer64.cc b/bochs/cpu/ctrl_xfer64.cc index 0cee881d7..78ab8c4f9 100644 --- a/bochs/cpu/ctrl_xfer64.cc +++ b/bochs/cpu/ctrl_xfer64.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: ctrl_xfer64.cc,v 1.21 2003-03-13 00:43:00 ptrumpet Exp $ +// $Id: ctrl_xfer64.cc,v 1.22 2003-05-10 22:25:54 kevinlawton Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -43,7 +43,7 @@ BX_CPU_C::RETnear64_Iw(bxInstruction_c *i) Bit64u temp_RSP; Bit64u return_RIP; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_ret; @@ -79,7 +79,7 @@ BX_CPU_C::RETnear64(bxInstruction_c *i) Bit64u temp_RSP; Bit64u return_RIP; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_ret; @@ -171,7 +171,7 @@ BX_CPU_C::CALL_Aq(bxInstruction_c *i) Bit64u new_RIP; Bit32s disp32; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_call; @@ -223,7 +223,7 @@ BX_CPU_C::CALL_Eq(bxInstruction_c *i) Bit64u temp_RSP; Bit64u op1_64; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); #if BX_DEBUGGER BX_CPU_THIS_PTR show_flag |= Flag_call; @@ -285,7 +285,7 @@ done: void BX_CPU_C::JMP_Jq(bxInstruction_c *i) { - invalidate_prefetch_q(); + //invalidate_prefetch_q(); RIP += (Bit32s) i->Id(); if (i->os32L()==0) @@ -379,7 +379,7 @@ BX_CPU_C::JMP_Eq(bxInstruction_c *i) { Bit64u op1_64; - invalidate_prefetch_q(); + //invalidate_prefetch_q(); if (i->modC0()) { op1_64 = BX_READ_64BIT_REG(i->rm()); diff --git a/bochs/cpu/proc_ctrl.cc b/bochs/cpu/proc_ctrl.cc index 14060f5c9..78821fd65 100644 --- a/bochs/cpu/proc_ctrl.cc +++ b/bochs/cpu/proc_ctrl.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: proc_ctrl.cc,v 1.69 2003-05-02 12:22:48 vruppert Exp $ +// $Id: proc_ctrl.cc,v 1.70 2003-05-10 22:25:55 kevinlawton Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -1986,7 +1986,7 @@ BX_CPU_C::SYSENTER (bxInstruction_c *i) return; } - invalidate_prefetch_q (); + invalidate_prefetch_q(); BX_CPU_THIS_PTR set_VM(0); // do this just like the book says to do BX_CPU_THIS_PTR set_IF(0); @@ -2051,7 +2051,7 @@ BX_CPU_C::SYSEXIT (bxInstruction_c *i) return; } - invalidate_prefetch_q (); + invalidate_prefetch_q(); BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value = (BX_CPU_THIS_PTR sysenter_cs_msr + 16) | 3; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.index = (BX_CPU_THIS_PTR sysenter_cs_msr + 16) >> 3; diff --git a/bochs/cpu/segment_ctrl_pro.cc b/bochs/cpu/segment_ctrl_pro.cc index b5dbde915..93fe1758d 100644 --- a/bochs/cpu/segment_ctrl_pro.cc +++ b/bochs/cpu/segment_ctrl_pro.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: segment_ctrl_pro.cc,v 1.24 2003-03-02 23:59:09 cbothamy Exp $ +// $Id: segment_ctrl_pro.cc,v 1.25 2003-05-10 22:25:55 kevinlawton Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -55,6 +55,7 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value) BX_CPU_THIS_PTR iCache.fetchModeMask = BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS); #endif + invalidate_prefetch_q(); } else seg->cache.u.segment.executable = 0; /* data segment */ @@ -337,6 +338,7 @@ BX_CPU_C::load_seg_reg(bx_segment_reg_t *seg, Bit16u new_value) BX_CPU_THIS_PTR iCache.fetchModeMask = BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS); #endif + invalidate_prefetch_q(); } else { /* SS, DS, ES, FS, GS */ seg->selector.value = new_value; @@ -557,6 +559,8 @@ BX_CPU_C::load_cs(bx_selector_t *selector, bx_descriptor_t *descriptor, BX_CPU_THIS_PTR iCache.fetchModeMask = BX_CPU_THIS_PTR iCache.createFetchModeMask(BX_CPU_THIS); #endif + // Loading CS will invalidate the EIP fetch window. + invalidate_prefetch_q(); } void BX_CPP_AttrRegparmN(3)