diff --git a/include/paging.h b/include/paging.h index 29afcce8..8a95c040 100644 --- a/include/paging.h +++ b/include/paging.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: paging.h,v 1.27 2007-09-30 14:10:04 c2woody Exp $ */ +/* $Id: paging.h,v 1.28 2007-10-05 17:45:52 c2woody Exp $ */ #ifndef DOSBOX_PAGING_H #define DOSBOX_PAGING_H @@ -28,11 +28,23 @@ #include "mem.h" #endif +// disable this to reduce the size of the TLB +// NOTE: does not work with the dynamic core (dynrec is fine) +#define USE_FULL_TLB + class PageDirectory; #define MEM_PAGE_SIZE (4096) #define XMS_START (0x110) + +#if defined(USE_FULL_TLB) #define TLB_SIZE (1024*1024) +#else +#define TLB_SIZE 65536 // This must a power of 2 and greater then LINK_START +#define BANK_SHIFT 28 +#define BANK_MASK 0xffff // always the same as TLB_SIZE-1? +#define TLB_BANKS ((1024*1024/TLB_SIZE)-1) +#endif #define PFLAG_READABLE 0x1 #define PFLAG_WRITEABLE 0x2 @@ -126,6 +138,15 @@ union X86PageEntry { X86_PageEntryBlock block; }; +#if !defined(USE_FULL_TLB) +typedef struct { + HostPt read; + HostPt write; + PageHandler * handler; + Bit32u phys_page; +} tlb_entry; +#endif + struct PagingBlock { Bitu cr3; Bitu cr2; @@ -133,12 +154,17 @@ struct PagingBlock { Bitu page; PhysPt addr; } base; +#if defined(USE_FULL_TLB) struct { HostPt read[TLB_SIZE]; HostPt write[TLB_SIZE]; PageHandler * handler[TLB_SIZE]; Bit32u phys_page[TLB_SIZE]; } tlb; +#else + tlb_entry tlbh[TLB_SIZE]; + tlb_entry *tlbh_banks[TLB_BANKS]; +#endif struct { Bitu used; Bit32u entries[PAGING_LINKS]; @@ -153,15 +179,6 @@ extern PagingBlock paging; PageHandler * MEM_GetPageHandler(Bitu phys_page); -/* Use this helper function to access linear addresses in readX/writeX functions */ -INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { - return (paging.tlb.phys_page[linePage>>12]<<12); -} - -INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { - return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff); -} - /* Unaligned address handlers */ Bit16u mem_unalignedreadw(PhysPt address); @@ -174,111 +191,164 @@ bool mem_unalignedreadd_checked(PhysPt address,Bit32u * val); bool mem_unalignedwritew_checked(PhysPt address,Bit16u val); bool mem_unalignedwrited_checked(PhysPt address,Bit32u val); +#if defined(USE_FULL_TLB) + +INLINE HostPt get_tlb_read(PhysPt address) { + return paging.tlb.read[address>>12]; +} +INLINE HostPt get_tlb_write(PhysPt address) { + return paging.tlb.write[address>>12]; +} +INLINE PageHandler* get_tlb_handler(PhysPt address) { + return paging.tlb.handler[address>>12]; +} + +/* Use these helper functions to access linear addresses in readX/writeX functions */ +INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { + return (paging.tlb.phys_page[linePage>>12]<<12); +} + +INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { + return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff); +} + +#else + +void PAGING_InitTLBBank(tlb_entry **bank); + +INLINE tlb_entry *get_tlb_entry(PhysPt address) { + Bitu index=(address>>12); + if (TLB_BANKS && (index > TLB_SIZE)) { + Bitu bank=(address>>BANK_SHIFT) - 1; + if (!paging.tlbh_banks[bank]) + PAGING_InitTLBBank(&paging.tlbh_banks[bank]); + return &paging.tlbh_banks[bank][index & BANK_MASK]; + } + return &paging.tlbh[index]; +} + +INLINE HostPt get_tlb_read(PhysPt address) { + return get_tlb_entry(address)->read; +} +INLINE HostPt get_tlb_write(PhysPt address) { + return get_tlb_entry(address)->write; +} +INLINE PageHandler* get_tlb_handler(PhysPt address) { + return get_tlb_entry(address)->handler; +} + +/* Use these helper functions to access linear addresses in readX/writeX functions */ +INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) { + tlb_entry *entry = get_tlb_entry(linePage); + return (entry->phys_page<<12); +} + +INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) { + tlb_entry *entry = get_tlb_entry(linAddr); + return (entry->phys_page<<12)|(linAddr&0xfff); +} +#endif + /* Special inlined memory reading/writing */ INLINE Bit8u mem_readb_inline(PhysPt address) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) return host_readb(paging.tlb.read[index]+address); - else return (Bit8u)paging.tlb.handler[index]->readb(address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) return host_readb(tlb_addr+address); + else return (Bit8u)(get_tlb_handler(address))->readb(address); } INLINE Bit16u mem_readw_inline(PhysPt address) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - - if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); - else return (Bit16u) paging.tlb.handler[index]->readw(address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) return host_readw(tlb_addr+address); + else return (Bit16u)(get_tlb_handler(address))->readw(address); } else return mem_unalignedreadw(address); } INLINE Bit32u mem_readd_inline(PhysPt address) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - - if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address); - else return paging.tlb.handler[index]->readd(address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) return host_readd(tlb_addr+address); + else return (get_tlb_handler(address))->readd(address); } else return mem_unalignedreadd(address); } INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { - Bitu index=(address>>12); - - if (paging.tlb.write[index]) host_writeb(paging.tlb.write[index]+address,val); - else paging.tlb.handler[index]->writeb(address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) host_writeb(tlb_addr+address,val); + else (get_tlb_handler(address))->writeb(address,val); } INLINE void mem_writew_inline(PhysPt address,Bit16u val) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - - if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val); - else paging.tlb.handler[index]->writew(address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) host_writew(tlb_addr+address,val); + else (get_tlb_handler(address))->writew(address,val); } else mem_unalignedwritew(address,val); } INLINE void mem_writed_inline(PhysPt address,Bit32u val) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - - if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val); - else paging.tlb.handler[index]->writed(address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) host_writed(tlb_addr+address,val); + else (get_tlb_handler(address))->writed(address,val); } else mem_unalignedwrited(address,val); } INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *val=host_readb(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *val=host_readb(tlb_addr+address); return false; - } else return paging.tlb.handler[index]->readb_checked(address, val); + } else return (get_tlb_handler(address))->readb_checked(address, val); } INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *val=host_readw(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *val=host_readw(tlb_addr+address); return false; - } else return paging.tlb.handler[index]->readw_checked(address, val); + } else return (get_tlb_handler(address))->readw_checked(address, val); } else return mem_unalignedreadw_checked(address, val); } INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *val=host_readd(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *val=host_readd(tlb_addr+address); return false; - } else return paging.tlb.handler[index]->readd_checked(address, val); + } else return (get_tlb_handler(address))->readd_checked(address, val); } else return mem_unalignedreadd_checked(address, val); } INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writeb(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writeb(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writeb_checked(address,val); + } else return (get_tlb_handler(address))->writeb_checked(address,val); } INLINE bool mem_writew_checked(PhysPt address,Bit16u val) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writew(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writew(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writew_checked(address,val); + } else return (get_tlb_handler(address))->writew_checked(address,val); } else return mem_unalignedwritew_checked(address,val); } INLINE bool mem_writed_checked(PhysPt address,Bit32u val) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writed(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writed(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writed_checked(address,val); + } else return (get_tlb_handler(address))->writed_checked(address,val); } else return mem_unalignedwrited_checked(address,val); } diff --git a/src/cpu/core_dyn_x86.cpp b/src/cpu/core_dyn_x86.cpp index 8e78b8ad..a1799557 100644 --- a/src/cpu/core_dyn_x86.cpp +++ b/src/cpu/core_dyn_x86.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: core_dyn_x86.cpp,v 1.33 2007-10-05 17:45:52 c2woody Exp $ */ + #include "dosbox.h" #if (C_DYNAMIC_X86) @@ -346,8 +348,7 @@ run_block: case BR_Link2: { Bitu temp_ip=SegPhys(cs)+reg_eip; - Bitu temp_page=temp_ip >> 12; - CodePageHandler * temp_handler=(CodePageHandler *)paging.tlb.handler[temp_page]; + CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_handler(temp_ip); if (temp_handler->flags & PFLAG_HASCODE) { block=temp_handler->FindCacheBlock(temp_ip & 4095); if (!block) goto restart_core; diff --git a/src/cpu/core_dyn_x86/cache.h b/src/cpu/core_dyn_x86/cache.h index 968f26c6..a3c43ba9 100644 --- a/src/cpu/core_dyn_x86/cache.h +++ b/src/cpu/core_dyn_x86/cache.h @@ -69,7 +69,7 @@ public: Bits index=1+(end>>DYN_HASH_SHIFT); bool is_current_block=false; Bit32u ip_point=SegPhys(cs)+reg_eip; - ip_point=((paging.tlb.phys_page[ip_point>>12]-phys_page)<<12)+(ip_point&0xfff); + ip_point=(PAGING_GetPhysicalPage(ip_point)-(phys_page<<12))+(ip_point&0xfff); while (index>=0) { Bitu map=0; for (Bitu count=start;count<=end;count++) map+=write_map[count]; diff --git a/src/cpu/core_dyn_x86/decoder.h b/src/cpu/core_dyn_x86/decoder.h index 6122415c..4270a024 100644 --- a/src/cpu/core_dyn_x86/decoder.h +++ b/src/cpu/core_dyn_x86/decoder.h @@ -54,8 +54,7 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { Bit8u rdval; //Ensure page contains memory: if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; - Bitu lin_page=lin_addr >> 12; - PageHandler * handler=paging.tlb.handler[lin_page]; + PageHandler * handler=get_tlb_handler(lin_addr); if (handler->flags & PFLAG_HASCODE) { cph=( CodePageHandler *)handler; return false; @@ -64,6 +63,7 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { LOG_MSG("DYNX86:Can't run code in this page"); cph=0; return false; } + Bitu lin_page=lin_addr >> 12; Bitu phys_page=lin_page; if (!PAGING_MakePhysPage(phys_page)) { LOG_MSG("DYNX86:Can't find physpage"); @@ -176,9 +176,9 @@ static INLINE void decode_increase_wmapmask(Bitu size) { static bool decode_fetchb_imm(Bitu & val) { if (decode.page.index<4096) { - Bitu index=(decode.code>>12); - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + HostPt tlb_addr=get_tlb_read(decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(1); decode.code++; decode.page.index++; @@ -190,9 +190,9 @@ static bool decode_fetchb_imm(Bitu & val) { } static bool decode_fetchw_imm(Bitu & val) { if (decode.page.index<4095) { - Bitu index=(decode.code>>12); - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + HostPt tlb_addr=get_tlb_read(decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(2); decode.code+=2; decode.page.index+=2; @@ -204,9 +204,9 @@ static bool decode_fetchw_imm(Bitu & val) { } static bool decode_fetchd_imm(Bitu & val) { if (decode.page.index<4093) { - Bitu index=(decode.code>>12); - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + HostPt tlb_addr=get_tlb_read(decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(4); decode.code+=4; decode.page.index+=4; @@ -462,7 +462,7 @@ static void dyn_read_intro(DynReg * addr,bool release_addr=true) { } bool mem_readb_checked_dcx86(PhysPt address) { - return paging.tlb.handler[address>>12]->readb_checked(address, (Bit8u*)(&core_dyn.readdata)); + return get_tlb_handler(address)->readb_checked(address, (Bit8u*)(&core_dyn.readdata)); } static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { @@ -543,12 +543,12 @@ static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { bool mem_readd_checked_dcx86(PhysPt address) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - core_dyn.readdata=host_readd(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + core_dyn.readdata=host_readd(tlb_addr+address); return false; } else { - return paging.tlb.handler[index]->readd_checked(address, &core_dyn.readdata); + return get_tlb_handler(address)->readd_checked(address, &core_dyn.readdata); } } else return mem_unalignedreadd_checked(address, &core_dyn.readdata); } diff --git a/src/cpu/core_dynrec.cpp b/src/cpu/core_dynrec.cpp index 7e6944f1..e39bb8c8 100644 --- a/src/cpu/core_dynrec.cpp +++ b/src/cpu/core_dynrec.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: core_dynrec.cpp,v 1.8 2007-10-05 17:45:52 c2woody Exp $ */ + #include "dosbox.h" #if (C_DYNREC) @@ -151,8 +153,7 @@ CacheBlockDynRec * LinkBlocks(BlockReturn ret) { CacheBlockDynRec * block=NULL; // the last instruction was a control flow modifying instruction Bitu temp_ip=SegPhys(cs)+reg_eip; - Bitu temp_page=temp_ip >> 12; - CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)paging.tlb.handler[temp_page]; + CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_handler(temp_ip); if (temp_handler->flags & PFLAG_HASCODE) { // see if the target is an already translated block block=temp_handler->FindCacheBlock(temp_ip & 4095); diff --git a/src/cpu/core_dynrec/cache.h b/src/cpu/core_dynrec/cache.h index 52baff65..78d671c5 100644 --- a/src/cpu/core_dynrec/cache.h +++ b/src/cpu/core_dynrec/cache.h @@ -117,7 +117,7 @@ public: bool is_current_block=false; // if the current block is modified, it has to be exited as soon as possible Bit32u ip_point=SegPhys(cs)+reg_eip; - ip_point=((paging.tlb.phys_page[ip_point>>12]-phys_page)<<12)+(ip_point&0xfff); + ip_point=(PAGING_GetPhysicalPage(ip_point)-(phys_page<<12))+(ip_point&0xfff); while (index>=0) { Bitu map=0; // see if there is still some code in the range diff --git a/src/cpu/core_dynrec/decoder_basic.h b/src/cpu/core_dynrec/decoder_basic.h index 3e684cd1..2fb7845d 100644 --- a/src/cpu/core_dynrec/decoder_basic.h +++ b/src/cpu/core_dynrec/decoder_basic.h @@ -132,9 +132,7 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { //Ensure page contains memory: if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true; - Bitu lin_page=lin_addr >> 12; - - PageHandler * handler=paging.tlb.handler[lin_page]; + PageHandler * handler=get_tlb_handler(lin_addr); if (handler->flags & PFLAG_HASCODE) { // this is a codepage handler, and the one that we're looking for cph=(CodePageHandlerDynRec *)handler; @@ -145,6 +143,7 @@ static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { cph=0; return false; } + Bitu lin_page=lin_addr>>12; Bitu phys_page=lin_page; // find the physical page that the linear page is mapped to if (!PAGING_MakePhysPage(phys_page)) { @@ -280,10 +279,10 @@ static bool decode_fetchb_imm(Bitu & val) { if (GCC_UNLIKELY(decode.page.index>=4096)) { decode_advancepage(); } - Bitu index=(decode.code>>12); + HostPt tlb_addr=get_tlb_read(decode.code); // see if position is directly accessible - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(1); decode.code++; decode.page.index++; @@ -298,10 +297,10 @@ static bool decode_fetchb_imm(Bitu & val) { // otherwise val contains the current value read from the position static bool decode_fetchw_imm(Bitu & val) { if (decode.page.index<4095) { - Bitu index=(decode.code>>12); + HostPt tlb_addr=get_tlb_read(decode.code); // see if position is directly accessible - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(2); decode.code+=2; decode.page.index+=2; @@ -317,10 +316,10 @@ static bool decode_fetchw_imm(Bitu & val) { // otherwise val contains the current value read from the position static bool decode_fetchd_imm(Bitu & val) { if (decode.page.index<4093) { - Bitu index=(decode.code>>12); + HostPt tlb_addr=get_tlb_read(decode.code); // see if position is directly accessible - if (paging.tlb.read[index]) { - val=(Bitu)(paging.tlb.read[index]+decode.code); + if (tlb_addr) { + val=(Bitu)(tlb_addr+decode.code); decode_increase_wmapmask(4); decode.code+=4; decode.page.index+=4; @@ -565,65 +564,65 @@ static void dyn_check_exception(HostReg reg) { bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *((Bit8u*)(&core_dynrec.readdata))=host_readb(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *((Bit8u*)(&core_dynrec.readdata))=host_readb(tlb_addr+address); return false; } else { - return paging.tlb.handler[index]->readb_checked(address, (Bit8u*)(&core_dynrec.readdata)); + return get_tlb_handler(address)->readb_checked(address, (Bit8u*)(&core_dynrec.readdata)); } } bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) DRC_FC; bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writeb(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writeb(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writeb_checked(address,val); + } else return get_tlb_handler(address)->writeb_checked(address,val); } bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *((Bit16u*)(&core_dynrec.readdata))=host_readw(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *((Bit16u*)(&core_dynrec.readdata))=host_readw(tlb_addr+address); return false; - } else return paging.tlb.handler[index]->readw_checked(address, (Bit16u*)(&core_dynrec.readdata)); + } else return get_tlb_handler(address)->readw_checked(address, (Bit16u*)(&core_dynrec.readdata)); } else return mem_unalignedreadw_checked(address, ((Bit16u*)(&core_dynrec.readdata))); } bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - if (paging.tlb.read[index]) { - *((Bit32u*)(&core_dynrec.readdata))=host_readd(paging.tlb.read[index]+address); + HostPt tlb_addr=get_tlb_read(address); + if (tlb_addr) { + *((Bit32u*)(&core_dynrec.readdata))=host_readd(tlb_addr+address); return false; - } else return paging.tlb.handler[index]->readd_checked(address, (Bit32u*)(&core_dynrec.readdata)); + } else return get_tlb_handler(address)->readd_checked(address, (Bit32u*)(&core_dynrec.readdata)); } else return mem_unalignedreadd_checked(address, ((Bit32u*)(&core_dynrec.readdata))); } bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) DRC_FC; bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) { if ((address & 0xfff)<0xfff) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writew(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writew(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writew_checked(address,val); + } else return get_tlb_handler(address)->writew_checked(address,val); } else return mem_unalignedwritew_checked(address,val); } bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) DRC_FC; bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) { if ((address & 0xfff)<0xffd) { - Bitu index=(address>>12); - if (paging.tlb.write[index]) { - host_writed(paging.tlb.write[index]+address,val); + HostPt tlb_addr=get_tlb_write(address); + if (tlb_addr) { + host_writed(tlb_addr+address,val); return false; - } else return paging.tlb.handler[index]->writed_checked(address,val); + } else return get_tlb_handler(address)->writed_checked(address,val); } else return mem_unalignedwrited_checked(address,val); } diff --git a/src/cpu/paging.cpp b/src/cpu/paging.cpp index 15f01659..7e960e52 100644 --- a/src/cpu/paging.cpp +++ b/src/cpu/paging.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: paging.cpp,v 1.28 2007-10-05 17:45:52 c2woody Exp $ */ + #include #include #include @@ -317,6 +319,7 @@ Bitu PAGING_GetDirBase(void) { return paging.cr3; } +#if defined(USE_FULL_TLB) void PAGING_InitTLB(void) { for (Bitu i=0;i0;paging.links.used--) { + Bitu page=*entries++; + tlb_entry *entry = get_tlb_entry(page<<12); + entry->read=0; + entry->write=0; + entry->handler=&init_page_handler; + } + paging.links.used=0; +} + +void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) { + tlb_entry *entry = get_tlb_entry(lin_page<<12); + for (;pages>0;pages--) { + entry->read=0; + entry->write=0; + entry->handler=&init_page_handler; + } +} + void PAGING_MapPage(Bitu lin_page,Bitu phys_page) { if (lin_page=(TLB_SIZE*(TLB_BANKS+1)) || phys_page>=(TLB_SIZE*(TLB_BANKS+1))) + E_Exit("Illegal page"); + + if (paging.links.used>=PAGING_LINKS) { + LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache"); + PAGING_ClearTLB(); + } + + tlb_entry *entry = get_tlb_entry(lin_base); + entry->phys_page=phys_page; + if (handler->flags & PFLAG_READABLE) entry->read=handler->GetHostReadPt(phys_page)-lin_base; + else entry->read=0; + if (handler->flags & PFLAG_WRITEABLE) entry->write=handler->GetHostWritePt(phys_page)-lin_base; + else entry->write=0; + + paging.links.entries[paging.links.used++]=lin_page; + entry->handler=handler; +} + +#endif + + void PAGING_SetDirBase(Bitu cr3) { paging.cr3=cr3; @@ -392,10 +473,8 @@ void PAGING_Enable(bool enabled) { /* If paging is disable we work from a default paging table */ if (paging.enabled==enabled) return; paging.enabled=enabled; - if (!enabled) { -// LOG(LOG_PAGING,LOG_NORMAL)("Disabled"); - } else { - if (cpudecoder==CPU_Core_Simple_Run) { + if (enabled) { + if (GCC_UNLIKELY(cpudecoder==CPU_Core_Simple_Run)) { // LOG_MSG("CPU core simple won't run this game,switching to normal"); cpudecoder=CPU_Core_Normal_Run; CPU_CycleLeft+=CPU_Cycles; diff --git a/src/debug/debug.cpp b/src/debug/debug.cpp index 4bfec5db..7e0ec1b5 100644 --- a/src/debug/debug.cpp +++ b/src/debug/debug.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: debug.cpp,v 1.88 2007-06-12 20:22:07 c2woody Exp $ */ +/* $Id: debug.cpp,v 1.89 2007-10-05 17:45:53 c2woody Exp $ */ #include "dosbox.h" #if C_DEBUG @@ -674,7 +674,7 @@ static void DrawData(void) { else mvwprintw (dbg.win_data,1+y,0,"%04X:%08X ",dataSeg,add); for (int x=0; x<16; x++) { address = GetAddress(dataSeg,add); - if (!(paging.tlb.handler[address >> 12]->flags & PFLAG_INIT)) { + if (!(get_tlb_handler(address)->flags & PFLAG_INIT)) { ch = mem_readb(address); } else ch = 0; mvwprintw (dbg.win_data,1+y,14+3*x,"%02X",ch); @@ -1344,7 +1344,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) pos++; }; Bit32u address = GetAddress(seg,adr); - if (!(paging.tlb.handler[address >> 12]->flags & PFLAG_INIT)) { + if (!(get_tlb_handler(address)->flags & PFLAG_INIT)) { static char outmask[] = "%s:[%04X]=%02X"; if (cpu.pmode) outmask[6] = '8';