1
0
Fork 0

add banked tlb (crazyc)

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3007
This commit is contained in:
Sebastian Strohhäcker 2007-10-05 17:45:53 +00:00
parent 733a0244db
commit 72199985fa
9 changed files with 275 additions and 125 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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];

View file

@ -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);
}

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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 <stdlib.h>
#include <assert.h>
#include <string.h>
@ -317,6 +319,7 @@ Bitu PAGING_GetDirBase(void) {
return paging.cr3;
}
#if defined(USE_FULL_TLB)
void PAGING_InitTLB(void) {
for (Bitu i=0;i<TLB_SIZE;i++) {
paging.tlb.read[i]=0;
@ -345,6 +348,17 @@ void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) {
}
}
void PAGING_MapPage(Bitu lin_page,Bitu phys_page) {
if (lin_page<LINK_START) {
paging.firstmb[lin_page]=phys_page;
paging.tlb.read[lin_page]=0;
paging.tlb.write[lin_page]=0;
paging.tlb.handler[lin_page]=&init_page_handler;
} else {
PAGING_LinkPage(lin_page,phys_page);
}
}
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
PageHandler * handler=MEM_GetPageHandler(phys_page);
Bitu lin_base=lin_page << 12;
@ -366,17 +380,84 @@ void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
paging.tlb.handler[lin_page]=handler;
}
#else
static INLINE void InitTLBInt(tlb_entry *bank) {
for (Bitu i=0;i<TLB_SIZE;i++) {
bank[i].read=0;
bank[i].write=0;
bank[i].handler=&init_page_handler;
}
}
void PAGING_InitTLBBank(tlb_entry **bank) {
*bank = (tlb_entry *)malloc(sizeof(tlb_entry)*TLB_SIZE);
if(!*bank) E_Exit("Out of Memory");
InitTLBInt(*bank);
}
void PAGING_InitTLB(void) {
InitTLBInt(paging.tlbh);
paging.links.used=0;
}
void PAGING_ClearTLB(void) {
Bit32u * entries=&paging.links.entries[0];
for (;paging.links.used>0;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<LINK_START) {
paging.firstmb[lin_page]=phys_page;
paging.tlb.read[lin_page]=0;
paging.tlb.write[lin_page]=0;
paging.tlb.handler[lin_page]=&init_page_handler;
paging.tlbh[lin_page].read=0;
paging.tlbh[lin_page].write=0;
paging.tlbh[lin_page].handler=&init_page_handler;
} else {
PAGING_LinkPage(lin_page,phys_page);
}
}
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
PageHandler * handler=MEM_GetPageHandler(phys_page);
Bitu lin_base=lin_page << 12;
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;

View file

@ -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';