add banked tlb (crazyc)
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3007
This commit is contained in:
parent
733a0244db
commit
72199985fa
9 changed files with 275 additions and 125 deletions
184
include/paging.h
184
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
|
|
Loading…
Add table
Reference in a new issue