diff --git a/bochs/config.h.in b/bochs/config.h.in index 3213a8e06..cea6343c6 100644 --- a/bochs/config.h.in +++ b/bochs/config.h.in @@ -108,31 +108,6 @@ #define SIGALRM 14 #endif -// Paging Options: -// --------------- -// Support Paging mechanism. -// 0 = don't support paging at all (DOS & Minix don't require it) -// 1 = support paging. (Most other OS's require paging) -// Use Translation Lookaside Buffer (TLB) for caching -// paging translations. This will make paging mode -// more efficient. If you're OS doesn't use paging, -// then you won't need either. -// 1 = Use a TLB for effiency -// 0 = don't use a TLB, walk the page tables for every access -// BX_TLB_SIZE: Number of entries in TLB -// BX_TLB_INDEX_OF(lpf): This macro is passed the linear page frame -// (top 20 bits of the linear address. It must map these bits to -// one of the TLB cache slots, given the size of BX_TLB_SIZE. -// There will be a many-to-one mapping to each TLB cache slot. -// When there are collisions, the old entry is overwritten with -// one for the newest access. - -#define BX_USE_TLB 1 - -#define BX_TLB_SIZE 1024 -#define BX_TLB_MASK ((BX_TLB_SIZE-1) << 12) -#define BX_TLB_INDEX_OF(lpf, len) ((((unsigned)(lpf) + (len)) & BX_TLB_MASK) >> 12) - // Compile in support for DMA & FLOPPY IO. You'll need this // if you plan to use the floppy drive emulation. But if // you're environment doesn't require it, you can change diff --git a/bochs/cpu/cpu.cc b/bochs/cpu/cpu.cc index 096d1d913..f404e601b 100644 --- a/bochs/cpu/cpu.cc +++ b/bochs/cpu/cpu.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.cc,v 1.215 2008-03-31 18:53:08 sshwarts Exp $ +// $Id: cpu.cc,v 1.216 2008-04-05 20:41:00 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -635,20 +635,36 @@ void BX_CPU_C::prefetch(void) } } - if (BX_CPU_THIS_PTR cr0.get_PG()) { - // aligned block guaranteed to be all in one page, same A20 address - pAddr = itranslate_linear(laddr, CPL); - pAddr = A20ADDR(pAddr); - } - else - { - pAddr = A20ADDR(laddr); + bx_address lpf = LPFOf(laddr); + unsigned TLB_index = BX_TLB_INDEX_OF(lpf, 0); + bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[TLB_index]; + Bit8u *fetchPtr = 0; + + if (tlbEntry->lpf == lpf) { // always have permissions for CODE access + pAddr = A20ADDR(tlbEntry->ppf | PAGE_OFFSET(laddr)); +#if BX_SupportGuest2HostTLB + fetchPtr = (Bit8u*) (tlbEntry->hostPageAddr); +#endif + } + else { + if (BX_CPU_THIS_PTR cr0.get_PG()) { + pAddr = translate_linear(laddr, CPL, BX_READ, CODE_ACCESS); + pAddr = A20ADDR(pAddr); + } + else { + pAddr = A20ADDR(laddr); + } } BX_CPU_THIS_PTR pAddrA20Page = pAddr & 0xfffff000; - BX_CPU_THIS_PTR eipFetchPtr = - BX_CPU_THIS_PTR mem->getHostMemAddr(BX_CPU_THIS, - BX_CPU_THIS_PTR pAddrA20Page, BX_READ, CODE_ACCESS); + + if (fetchPtr) { + BX_CPU_THIS_PTR eipFetchPtr = fetchPtr; + } + else { + BX_CPU_THIS_PTR eipFetchPtr = BX_CPU_THIS_PTR mem->getHostMemAddr(BX_CPU_THIS, + BX_CPU_THIS_PTR pAddrA20Page, BX_READ, CODE_ACCESS); + } // Sanity checks if (! BX_CPU_THIS_PTR eipFetchPtr) { diff --git a/bochs/cpu/cpu.h b/bochs/cpu/cpu.h index 58516a57d..9f8d52c13 100644 --- a/bochs/cpu/cpu.h +++ b/bochs/cpu/cpu.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: cpu.h,v 1.447 2008-04-05 19:08:01 sshwarts Exp $ +// $Id: cpu.h,v 1.448 2008-04-05 20:41:00 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -588,7 +588,18 @@ struct cpuid_function_t { #include "icache.h" #endif -#if BX_USE_TLB +// BX_TLB_SIZE: Number of entries in TLB +// BX_TLB_INDEX_OF(lpf): This macro is passed the linear page frame +// (top 20 bits of the linear address. It must map these bits to +// one of the TLB cache slots, given the size of BX_TLB_SIZE. +// There will be a many-to-one mapping to each TLB cache slot. +// When there are collisions, the old entry is overwritten with +// one for the newest access. + +#define BX_TLB_SIZE 1024 +#define BX_TLB_MASK ((BX_TLB_SIZE-1) << 12) +#define BX_TLB_INDEX_OF(lpf, len) ((((unsigned)(lpf) + (len)) & BX_TLB_MASK) >> 12) + typedef bx_ptr_equiv_t bx_hostpageaddr_t; typedef struct { @@ -597,7 +608,6 @@ typedef struct { Bit32u accessBits; // Page Table Address for updating A & D bits bx_hostpageaddr_t hostPageAddr; } bx_TLB_entry; -#endif // general purpose register #if BX_SUPPORT_X86_64 @@ -899,8 +909,6 @@ public: // for now... Bit8u trace; // for paging -#if BX_USE_TLB - struct { bx_TLB_entry entry[BX_TLB_SIZE] BX_CPP_AlignN(16); } TLB; @@ -912,10 +920,7 @@ public: // for now... #define LPF_MASK 0xfffff000 #endif -#define LPFOf(laddr) ((laddr) & LPF_MASK) - -#endif // #if BX_USE_TLB - +#define LPFOf(laddr) ((laddr) & LPF_MASK) #define PAGE_OFFSET(laddr) ((Bit32u)(laddr) & 0xfff) // An instruction cache. Each entry should be exactly 32 bytes, and @@ -2899,10 +2904,7 @@ public: // for now... // linear address for translate_linear expected to be canonical ! BX_SMF bx_phy_address translate_linear(bx_address laddr, unsigned curr_pl, unsigned rw, unsigned access_type); - BX_SMF BX_CPP_INLINE bx_phy_address itranslate_linear(bx_address laddr, unsigned curr_pl) - { - return translate_linear(laddr, curr_pl, BX_READ, CODE_ACCESS); - } + BX_SMF BX_CPP_INLINE bx_phy_address dtranslate_linear(bx_address laddr, unsigned curr_pl, unsigned rw) { return translate_linear(laddr, curr_pl, rw, DATA_ACCESS); diff --git a/bochs/cpu/init.cc b/bochs/cpu/init.cc index 5e4468e66..0a32e3a3a 100644 --- a/bochs/cpu/init.cc +++ b/bochs/cpu/init.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: init.cc,v 1.161 2008-04-03 17:56:59 sshwarts Exp $ +// $Id: init.cc,v 1.162 2008-04-05 20:41:00 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -937,9 +937,7 @@ void BX_CPU_C::reset(unsigned source) BX_CPU_THIS_PTR EXT = 0; -#if BX_USE_TLB TLB_init(); -#endif // invalidate the prefetch queue BX_CPU_THIS_PTR eipPageBias = 0; diff --git a/bochs/cpu/paging.cc b/bochs/cpu/paging.cc index d168fa35b..7b6652340 100644 --- a/bochs/cpu/paging.cc +++ b/bochs/cpu/paging.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: paging.cc,v 1.115 2008-03-31 20:56:27 sshwarts Exp $ +// $Id: paging.cc,v 1.116 2008-04-05 20:41:00 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2001 MandrakeSoft S.A. @@ -472,10 +472,8 @@ void BX_CPU_C::TLB_init(void) { unsigned i, wp, us_combined, rw_combined, us_current, rw_current; -#if BX_USE_TLB for (i=0; iResolveModrm, (i)); bx_address laddr = BX_CPU_THIS_PTR get_segment_base(i->seg()) + RMAddr(i); BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_INVLPG, laddr); TLB_invlpg(laddr); InstrTLB_Increment(tlbEntryInvlpg); -#endif - #else // not supported on < 486 BX_INFO(("INVLPG: required i486, use --enable-cpu=4 option")); @@ -617,7 +608,6 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un bx_bool isWrite = (rw >= BX_WRITE); // write or r-m-w unsigned pl = (curr_pl == 3); -#if BX_USE_TLB InstrTLB_Increment(tlbLookups); InstrTLB_Stats(); @@ -625,7 +615,8 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un unsigned TLB_index = BX_TLB_INDEX_OF(lpf, 0); bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[TLB_index]; - if (tlbEntry->lpf == lpf) + // already looked up TLB for code access + if (access_type != CODE_ACCESS && tlbEntry->lpf == lpf) { paddress = tlbEntry->ppf | poffset; accessBits = tlbEntry->accessBits; @@ -640,7 +631,6 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un } InstrTLB_Increment(tlbMisses); -#endif #if BX_SUPPORT_PAE if (BX_CPU_THIS_PTR cr4.get_PAE()) @@ -968,10 +958,8 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un // Calculate physical memory address and fill in TLB cache entry paddress = ppf | poffset; -#if BX_USE_TLB BX_CPU_THIS_PTR TLB.entry[TLB_index].lpf = lpf; BX_CPU_THIS_PTR TLB.entry[TLB_index].ppf = ppf; -#endif // b3: Write User OK // b2: Write Sys OK @@ -1001,7 +989,6 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un accessBits |= combined_access & TLB_GlobalPage; // Global bit #endif -#if BX_USE_TLB #if BX_SupportGuest2HostTLB // Attempt to get a host pointer to this physical page. Put that // pointer in the TLB cache. Note if the request is vetoed, NULL @@ -1016,7 +1003,6 @@ bx_phy_address BX_CPU_C::translate_linear(bx_address laddr, unsigned curr_pl, un } #endif BX_CPU_THIS_PTR TLB.entry[TLB_index].accessBits = accessBits; -#endif return paddress; } @@ -1033,7 +1019,6 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy) bx_phy_address paddress; // see if page is in the TLB first -#if BX_USE_TLB bx_address lpf = LPFOf(laddr); unsigned TLB_index = BX_TLB_INDEX_OF(lpf, 0); bx_TLB_entry *tlbEntry = &BX_CPU_THIS_PTR TLB.entry[TLB_index]; @@ -1043,7 +1028,6 @@ bx_bool BX_CPU_C::dbg_xlate_linear2phy(bx_address laddr, bx_phy_address *phy) *phy = paddress; return 1; } -#endif bx_phy_address pt_address = BX_CPU_THIS_PTR cr3_masked; bx_address offset_mask = 0xfff; diff --git a/bochs/main.cc b/bochs/main.cc index f992ba61f..b847fccf0 100644 --- a/bochs/main.cc +++ b/bochs/main.cc @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// $Id: main.cc,v 1.376 2008-03-29 21:01:23 sshwarts Exp $ +// $Id: main.cc,v 1.377 2008-04-05 20:41:00 sshwarts Exp $ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2002 MandrakeSoft S.A. @@ -977,7 +977,6 @@ void bx_init_hardware() BX_INFO((" APIC support: %s",BX_SUPPORT_APIC?"yes":"no")); BX_INFO(("CPU configuration")); BX_INFO((" level: %d",BX_CPU_LEVEL)); - BX_INFO((" TLB enabled: %s",BX_USE_TLB?"yes":"no")); #if BX_SUPPORT_SMP BX_INFO((" SMP support: yes, quantum=%d", SIM->get_param_num(BXPN_SMP_QUANTUM)->get())); #else