improve page protection handling
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3050
This commit is contained in:
parent
28c34f2b04
commit
cb37216a20
7 changed files with 204 additions and 95 deletions
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: paging.h,v 1.28 2007-10-05 17:45:52 c2woody Exp $ */
|
||||
/* $Id: paging.h,v 1.29 2007-11-24 17:26:48 c2woody Exp $ */
|
||||
|
||||
#ifndef DOSBOX_PAGING_H
|
||||
#define DOSBOX_PAGING_H
|
||||
|
@ -88,6 +88,7 @@ void PAGING_InitTLB(void);
|
|||
void PAGING_ClearTLB(void);
|
||||
|
||||
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page);
|
||||
void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page);
|
||||
void PAGING_UnlinkPages(Bitu lin_page,Bitu pages);
|
||||
/* This maps the page directly, only use when paging is disabled */
|
||||
void PAGING_MapPage(Bitu lin_page,Bitu phys_page);
|
||||
|
@ -142,7 +143,8 @@ union X86PageEntry {
|
|||
typedef struct {
|
||||
HostPt read;
|
||||
HostPt write;
|
||||
PageHandler * handler;
|
||||
PageHandler * readhandler;
|
||||
PageHandler * writehandler;
|
||||
Bit32u phys_page;
|
||||
} tlb_entry;
|
||||
#endif
|
||||
|
@ -158,7 +160,8 @@ struct PagingBlock {
|
|||
struct {
|
||||
HostPt read[TLB_SIZE];
|
||||
HostPt write[TLB_SIZE];
|
||||
PageHandler * handler[TLB_SIZE];
|
||||
PageHandler * readhandler[TLB_SIZE];
|
||||
PageHandler * writehandler[TLB_SIZE];
|
||||
Bit32u phys_page[TLB_SIZE];
|
||||
} tlb;
|
||||
#else
|
||||
|
@ -199,8 +202,11 @@ INLINE HostPt get_tlb_read(PhysPt address) {
|
|||
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];
|
||||
INLINE PageHandler* get_tlb_readhandler(PhysPt address) {
|
||||
return paging.tlb.readhandler[address>>12];
|
||||
}
|
||||
INLINE PageHandler* get_tlb_writehandler(PhysPt address) {
|
||||
return paging.tlb.writehandler[address>>12];
|
||||
}
|
||||
|
||||
/* Use these helper functions to access linear addresses in readX/writeX functions */
|
||||
|
@ -233,8 +239,11 @@ INLINE HostPt get_tlb_read(PhysPt address) {
|
|||
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;
|
||||
INLINE PageHandler* get_tlb_readhandler(PhysPt address) {
|
||||
return get_tlb_entry(address)->readhandler;
|
||||
}
|
||||
INLINE PageHandler* get_tlb_writehandler(PhysPt address) {
|
||||
return get_tlb_entry(address)->writehandler;
|
||||
}
|
||||
|
||||
/* Use these helper functions to access linear addresses in readX/writeX functions */
|
||||
|
@ -254,14 +263,14 @@ INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
|
|||
INLINE Bit8u mem_readb_inline(PhysPt 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);
|
||||
else return (Bit8u)(get_tlb_readhandler(address))->readb(address);
|
||||
}
|
||||
|
||||
INLINE Bit16u mem_readw_inline(PhysPt address) {
|
||||
if ((address & 0xfff)<0xfff) {
|
||||
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 (Bit16u)(get_tlb_readhandler(address))->readw(address);
|
||||
} else return mem_unalignedreadw(address);
|
||||
}
|
||||
|
||||
|
@ -269,21 +278,21 @@ INLINE Bit32u mem_readd_inline(PhysPt address) {
|
|||
if ((address & 0xfff)<0xffd) {
|
||||
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 (get_tlb_readhandler(address))->readd(address);
|
||||
} else return mem_unalignedreadd(address);
|
||||
}
|
||||
|
||||
INLINE void mem_writeb_inline(PhysPt address,Bit8u 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);
|
||||
else (get_tlb_writehandler(address))->writeb(address,val);
|
||||
}
|
||||
|
||||
INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
|
||||
if ((address & 0xfff)<0xfff) {
|
||||
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 (get_tlb_writehandler(address))->writew(address,val);
|
||||
} else mem_unalignedwritew(address,val);
|
||||
}
|
||||
|
||||
|
@ -291,7 +300,7 @@ INLINE void mem_writed_inline(PhysPt address,Bit32u val) {
|
|||
if ((address & 0xfff)<0xffd) {
|
||||
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 (get_tlb_writehandler(address))->writed(address,val);
|
||||
} else mem_unalignedwrited(address,val);
|
||||
}
|
||||
|
||||
|
@ -301,7 +310,7 @@ INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) {
|
|||
if (tlb_addr) {
|
||||
*val=host_readb(tlb_addr+address);
|
||||
return false;
|
||||
} else return (get_tlb_handler(address))->readb_checked(address, val);
|
||||
} else return (get_tlb_readhandler(address))->readb_checked(address, val);
|
||||
}
|
||||
|
||||
INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) {
|
||||
|
@ -310,7 +319,7 @@ INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) {
|
|||
if (tlb_addr) {
|
||||
*val=host_readw(tlb_addr+address);
|
||||
return false;
|
||||
} else return (get_tlb_handler(address))->readw_checked(address, val);
|
||||
} else return (get_tlb_readhandler(address))->readw_checked(address, val);
|
||||
} else return mem_unalignedreadw_checked(address, val);
|
||||
}
|
||||
|
||||
|
@ -320,7 +329,7 @@ INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) {
|
|||
if (tlb_addr) {
|
||||
*val=host_readd(tlb_addr+address);
|
||||
return false;
|
||||
} else return (get_tlb_handler(address))->readd_checked(address, val);
|
||||
} else return (get_tlb_readhandler(address))->readd_checked(address, val);
|
||||
} else return mem_unalignedreadd_checked(address, val);
|
||||
}
|
||||
|
||||
|
@ -329,7 +338,7 @@ INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) {
|
|||
if (tlb_addr) {
|
||||
host_writeb(tlb_addr+address,val);
|
||||
return false;
|
||||
} else return (get_tlb_handler(address))->writeb_checked(address,val);
|
||||
} else return (get_tlb_writehandler(address))->writeb_checked(address,val);
|
||||
}
|
||||
|
||||
INLINE bool mem_writew_checked(PhysPt address,Bit16u val) {
|
||||
|
@ -338,7 +347,7 @@ INLINE bool mem_writew_checked(PhysPt address,Bit16u val) {
|
|||
if (tlb_addr) {
|
||||
host_writew(tlb_addr+address,val);
|
||||
return false;
|
||||
} else return (get_tlb_handler(address))->writew_checked(address,val);
|
||||
} else return (get_tlb_writehandler(address))->writew_checked(address,val);
|
||||
} else return mem_unalignedwritew_checked(address,val);
|
||||
}
|
||||
|
||||
|
@ -348,7 +357,7 @@ INLINE bool mem_writed_checked(PhysPt address,Bit32u val) {
|
|||
if (tlb_addr) {
|
||||
host_writed(tlb_addr+address,val);
|
||||
return false;
|
||||
} else return (get_tlb_handler(address))->writed_checked(address,val);
|
||||
} else return (get_tlb_writehandler(address))->writed_checked(address,val);
|
||||
} else return mem_unalignedwrited_checked(address,val);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* 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 $ */
|
||||
/* $Id: core_dyn_x86.cpp,v 1.34 2007-11-24 17:26:48 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
|
||||
|
@ -348,7 +348,7 @@ run_block:
|
|||
case BR_Link2:
|
||||
{
|
||||
Bitu temp_ip=SegPhys(cs)+reg_eip;
|
||||
CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_handler(temp_ip);
|
||||
CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_readhandler(temp_ip);
|
||||
if (temp_handler->flags & PFLAG_HASCODE) {
|
||||
block=temp_handler->FindCacheBlock(temp_ip & 4095);
|
||||
if (!block) goto restart_core;
|
||||
|
|
|
@ -54,7 +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;
|
||||
PageHandler * handler=get_tlb_handler(lin_addr);
|
||||
PageHandler * handler=get_tlb_readhandler(lin_addr);
|
||||
if (handler->flags & PFLAG_HASCODE) {
|
||||
cph=( CodePageHandler *)handler;
|
||||
return false;
|
||||
|
@ -462,7 +462,7 @@ static void dyn_read_intro(DynReg * addr,bool release_addr=true) {
|
|||
}
|
||||
|
||||
bool mem_readb_checked_dcx86(PhysPt address) {
|
||||
return get_tlb_handler(address)->readb_checked(address, (Bit8u*)(&core_dyn.readdata));
|
||||
return get_tlb_readhandler(address)->readb_checked(address, (Bit8u*)(&core_dyn.readdata));
|
||||
}
|
||||
|
||||
static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) {
|
||||
|
@ -548,7 +548,7 @@ bool mem_readd_checked_dcx86(PhysPt address) {
|
|||
core_dyn.readdata=host_readd(tlb_addr+address);
|
||||
return false;
|
||||
} else {
|
||||
return get_tlb_handler(address)->readd_checked(address, &core_dyn.readdata);
|
||||
return get_tlb_readhandler(address)->readd_checked(address, &core_dyn.readdata);
|
||||
}
|
||||
} else return mem_unalignedreadd_checked(address, &core_dyn.readdata);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* 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 $ */
|
||||
/* $Id: core_dynrec.cpp,v 1.9 2007-11-24 17:26:48 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
|
||||
|
@ -153,7 +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;
|
||||
CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_handler(temp_ip);
|
||||
CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_readhandler(temp_ip);
|
||||
if (temp_handler->flags & PFLAG_HASCODE) {
|
||||
// see if the target is an already translated block
|
||||
block=temp_handler->FindCacheBlock(temp_ip & 4095);
|
||||
|
|
|
@ -132,7 +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;
|
||||
|
||||
PageHandler * handler=get_tlb_handler(lin_addr);
|
||||
PageHandler * handler=get_tlb_readhandler(lin_addr);
|
||||
if (handler->flags & PFLAG_HASCODE) {
|
||||
// this is a codepage handler, and the one that we're looking for
|
||||
cph=(CodePageHandlerDynRec *)handler;
|
||||
|
@ -569,7 +569,7 @@ bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) {
|
|||
*((Bit8u*)(&core_dynrec.readdata))=host_readb(tlb_addr+address);
|
||||
return false;
|
||||
} else {
|
||||
return get_tlb_handler(address)->readb_checked(address, (Bit8u*)(&core_dynrec.readdata));
|
||||
return get_tlb_readhandler(address)->readb_checked(address, (Bit8u*)(&core_dynrec.readdata));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -579,7 +579,7 @@ bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) {
|
|||
if (tlb_addr) {
|
||||
host_writeb(tlb_addr+address,val);
|
||||
return false;
|
||||
} else return get_tlb_handler(address)->writeb_checked(address,val);
|
||||
} else return get_tlb_writehandler(address)->writeb_checked(address,val);
|
||||
}
|
||||
|
||||
bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) DRC_FC;
|
||||
|
@ -589,7 +589,7 @@ bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) {
|
|||
if (tlb_addr) {
|
||||
*((Bit16u*)(&core_dynrec.readdata))=host_readw(tlb_addr+address);
|
||||
return false;
|
||||
} else return get_tlb_handler(address)->readw_checked(address, (Bit16u*)(&core_dynrec.readdata));
|
||||
} else return get_tlb_readhandler(address)->readw_checked(address, (Bit16u*)(&core_dynrec.readdata));
|
||||
} else return mem_unalignedreadw_checked(address, ((Bit16u*)(&core_dynrec.readdata)));
|
||||
}
|
||||
|
||||
|
@ -600,7 +600,7 @@ bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) {
|
|||
if (tlb_addr) {
|
||||
*((Bit32u*)(&core_dynrec.readdata))=host_readd(tlb_addr+address);
|
||||
return false;
|
||||
} else return get_tlb_handler(address)->readd_checked(address, (Bit32u*)(&core_dynrec.readdata));
|
||||
} else return get_tlb_readhandler(address)->readd_checked(address, (Bit32u*)(&core_dynrec.readdata));
|
||||
} else return mem_unalignedreadd_checked(address, ((Bit32u*)(&core_dynrec.readdata)));
|
||||
}
|
||||
|
||||
|
@ -611,7 +611,7 @@ bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) {
|
|||
if (tlb_addr) {
|
||||
host_writew(tlb_addr+address,val);
|
||||
return false;
|
||||
} else return get_tlb_handler(address)->writew_checked(address,val);
|
||||
} else return get_tlb_writehandler(address)->writew_checked(address,val);
|
||||
} else return mem_unalignedwritew_checked(address,val);
|
||||
}
|
||||
|
||||
|
@ -622,7 +622,7 @@ bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) {
|
|||
if (tlb_addr) {
|
||||
host_writed(tlb_addr+address,val);
|
||||
return false;
|
||||
} else return get_tlb_handler(address)->writed_checked(address,val);
|
||||
} else return get_tlb_writehandler(address)->writed_checked(address,val);
|
||||
} else return mem_unalignedwrited_checked(address,val);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* 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 $ */
|
||||
/* $Id: paging.cpp,v 1.29 2007-11-24 17:26:48 c2woody Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
@ -132,7 +132,7 @@ Bitu DEBUG_EnableDebugger(void);
|
|||
|
||||
bool first=false;
|
||||
|
||||
void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,bool writefault,Bitu faultcode) {
|
||||
void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) {
|
||||
/* Save the state of the cpu cores */
|
||||
LazyFlags old_lflags;
|
||||
memcpy(&old_lflags,&lflags,sizeof(LazyFlags));
|
||||
|
@ -141,14 +141,14 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,bool writefault,Bitu faultc
|
|||
cpudecoder=&PageFaultCore;
|
||||
paging.cr2=lin_addr;
|
||||
PF_Entry * entry=&pf_queue.entries[pf_queue.used++];
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type [%x:%x] queue %d",lin_addr,writefault,faultcode,pf_queue.used);
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type [%x] queue %d",lin_addr,faultcode,pf_queue.used);
|
||||
// LOG_MSG("EAX:%04X ECX:%04X EDX:%04X EBX:%04X",reg_eax,reg_ecx,reg_edx,reg_ebx);
|
||||
// LOG_MSG("CS:%04X EIP:%08X SS:%04x SP:%08X",SegValue(cs),reg_eip,SegValue(ss),reg_esp);
|
||||
entry->cs=SegValue(cs);
|
||||
entry->eip=reg_eip;
|
||||
entry->page_addr=page_addr;
|
||||
//Caused by a write by default?
|
||||
CPU_Exception(14,(writefault?0x02:0x00) | faultcode);
|
||||
CPU_Exception(14,faultcode);
|
||||
#if C_DEBUG
|
||||
// DEBUG_EnableDebugger();
|
||||
#endif
|
||||
|
@ -176,54 +176,57 @@ public:
|
|||
return mem_readd(addr);
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
InitPage(addr,true);
|
||||
bool needs_reset=InitPage(addr,true);
|
||||
mem_writeb(addr,val);
|
||||
if (GCC_UNLIKELY(needs_reset)) PAGING_UnlinkPages(addr>>12,1);
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
InitPage(addr,true);
|
||||
bool needs_reset=InitPage(addr,true);
|
||||
mem_writew(addr,val);
|
||||
if (GCC_UNLIKELY(needs_reset)) PAGING_UnlinkPages(addr>>12,1);
|
||||
}
|
||||
void writed(PhysPt addr,Bitu val) {
|
||||
InitPage(addr,true);
|
||||
bool needs_reset=InitPage(addr,true);
|
||||
mem_writed(addr,val);
|
||||
if (GCC_UNLIKELY(needs_reset)) PAGING_UnlinkPages(addr>>12,1);
|
||||
}
|
||||
bool readb_checked(PhysPt addr, Bit8u * val) {
|
||||
if (InitPage(addr,false,true)) {
|
||||
if (InitPageCheckOnly(addr,false)) {
|
||||
*val=mem_readb(addr);
|
||||
return false;
|
||||
} else return true;
|
||||
}
|
||||
bool readw_checked(PhysPt addr, Bit16u * val) {
|
||||
if (InitPage(addr,false,true)){
|
||||
if (InitPageCheckOnly(addr,false)){
|
||||
*val=mem_readw(addr);
|
||||
return false;
|
||||
} else return true;
|
||||
}
|
||||
bool readd_checked(PhysPt addr, Bit32u * val) {
|
||||
if (InitPage(addr,false,true)) {
|
||||
if (InitPageCheckOnly(addr,false)) {
|
||||
*val=mem_readd(addr);
|
||||
return false;
|
||||
} else return true;
|
||||
}
|
||||
bool writeb_checked(PhysPt addr,Bitu val) {
|
||||
if (InitPage(addr,true,true)) {
|
||||
if (InitPageCheckOnly(addr,true)) {
|
||||
mem_writeb(addr,val);
|
||||
return false;
|
||||
} else return true;
|
||||
}
|
||||
bool writew_checked(PhysPt addr,Bitu val) {
|
||||
if (InitPage(addr,true,true)) {
|
||||
if (InitPageCheckOnly(addr,true)) {
|
||||
mem_writew(addr,val);
|
||||
return false;
|
||||
} else return true;
|
||||
}
|
||||
bool writed_checked(PhysPt addr,Bitu val) {
|
||||
if (InitPage(addr,true,true)) {
|
||||
if (InitPageCheckOnly(addr,true)) {
|
||||
mem_writed(addr,val);
|
||||
return false;
|
||||
} else return true;
|
||||
}
|
||||
bool InitPage(Bitu lin_addr,bool writing,bool check_only=false) {
|
||||
bool InitPage(Bitu lin_addr,bool writing) {
|
||||
Bitu lin_page=lin_addr >> 12;
|
||||
Bitu phys_page;
|
||||
if (paging.enabled) {
|
||||
|
@ -233,64 +236,109 @@ public:
|
|||
X86PageEntry table;
|
||||
table.load=phys_readd(table_addr);
|
||||
if (!table.block.p) {
|
||||
if (check_only) {
|
||||
paging.cr2=lin_addr;
|
||||
cpu.exception.which=14;
|
||||
cpu.exception.error=writing?0x02:0x00;
|
||||
return false;
|
||||
}
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("NP Table");
|
||||
PAGING_PageFault(lin_addr,table_addr,false,writing?0x02:0x00);
|
||||
PAGING_PageFault(lin_addr,table_addr,(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04));
|
||||
table.load=phys_readd(table_addr);
|
||||
if (!table.block.p)
|
||||
E_Exit("Pagefault didn't correct table");
|
||||
}
|
||||
if (!table.block.a) {
|
||||
table.block.a=1; //Set access
|
||||
phys_writed(table_addr,table.load);
|
||||
}
|
||||
X86PageEntry entry;
|
||||
Bitu entry_addr=(table.block.base<<12)+t_index*4;
|
||||
entry.load=phys_readd(entry_addr);
|
||||
if (!entry.block.p) {
|
||||
if (check_only) {
|
||||
paging.cr2=lin_addr;
|
||||
cpu.exception.which=14;
|
||||
cpu.exception.error=writing?0x02:0x00;
|
||||
return false;
|
||||
}
|
||||
// LOG(LOG_PAGING,LOG_NORMAL)("NP Page");
|
||||
PAGING_PageFault(lin_addr,entry_addr,false,writing?0x02:0x00);
|
||||
PAGING_PageFault(lin_addr,entry_addr,(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04));
|
||||
entry.load=phys_readd(entry_addr);
|
||||
if (!entry.block.p)
|
||||
E_Exit("Pagefault didn't correct page");
|
||||
}
|
||||
if (cpu.cpl==3) {
|
||||
// if (((entry.block.us==0) || (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) {
|
||||
if (((entry.block.us==0) && (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) {
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
|
||||
if (check_only) {
|
||||
paging.cr2=lin_addr;
|
||||
cpu.exception.which=14;
|
||||
cpu.exception.error=0x05 | (writing?0x02:0x00);
|
||||
return false;
|
||||
}
|
||||
PAGING_PageFault(lin_addr,entry_addr,writing,0x05 | (writing?0x02:0x00));
|
||||
}
|
||||
|
||||
// 0: no action
|
||||
// 1: can (but currently does not) fail a privilege check
|
||||
// 2: fails a privilege check
|
||||
Bitu priv_check=0;
|
||||
// if ((entry.block.us==0) || (table.block.us==0)) {
|
||||
if ((entry.block.us==0) && (table.block.us==0)) {
|
||||
if (cpu.cpl==3) priv_check=2;
|
||||
else priv_check=1;
|
||||
}
|
||||
if ((entry.block.wr==0) || (table.block.wr==0)) {
|
||||
priv_check=1;
|
||||
if (writing && (cpu.cpl==3)) priv_check=2;
|
||||
}
|
||||
if (priv_check==2) {
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
|
||||
PAGING_PageFault(lin_addr,entry_addr,0x05 | (writing?0x02:0x00));
|
||||
}
|
||||
|
||||
if (!table.block.a) {
|
||||
table.block.a=1; //Set access
|
||||
phys_writed(table_addr,table.load);
|
||||
}
|
||||
if (check_only) return true;
|
||||
if ((!entry.block.a) || (!entry.block.d)) {
|
||||
entry.block.a=1; //Set access
|
||||
entry.block.d=1; //Set dirty
|
||||
entry.block.a=1; //Set access
|
||||
if (writing) entry.block.d=1; //Set dirty
|
||||
phys_writed(entry_addr,entry.load);
|
||||
}
|
||||
phys_page=entry.block.base;
|
||||
if (priv_check==0) PAGING_LinkPage(lin_page,phys_page);
|
||||
else {
|
||||
if (writing) {
|
||||
PAGING_LinkPage(lin_page,phys_page);
|
||||
return true;
|
||||
} else {
|
||||
PAGING_LinkPage_ReadOnly(lin_page,phys_page);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (lin_page<LINK_START) phys_page=paging.firstmb[lin_page];
|
||||
else phys_page=lin_page;
|
||||
PAGING_LinkPage(lin_page,phys_page);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool InitPageCheckOnly(Bitu lin_addr,bool writing) {
|
||||
Bitu lin_page=lin_addr >> 12;
|
||||
if (paging.enabled) {
|
||||
Bitu d_index=lin_page >> 10;
|
||||
Bitu t_index=lin_page & 0x3ff;
|
||||
Bitu table_addr=(paging.base.page<<12)+d_index*4;
|
||||
X86PageEntry table;
|
||||
table.load=phys_readd(table_addr);
|
||||
if (!table.block.p) {
|
||||
paging.cr2=lin_addr;
|
||||
cpu.exception.which=14;
|
||||
cpu.exception.error=(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04);
|
||||
return false;
|
||||
}
|
||||
X86PageEntry entry;
|
||||
Bitu entry_addr=(table.block.base<<12)+t_index*4;
|
||||
entry.load=phys_readd(entry_addr);
|
||||
if (!entry.block.p) {
|
||||
paging.cr2=lin_addr;
|
||||
cpu.exception.which=14;
|
||||
cpu.exception.error=(writing?0x02:0x00) | ((cpu.cpl==0)?0x00:0x04);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cpu.cpl!=3) return true;
|
||||
|
||||
// if (((entry.block.us==0) || (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) {
|
||||
if (((entry.block.us==0) && (table.block.us==0)) || (((entry.block.wr==0) || (table.block.wr==0)) && writing)) {
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
|
||||
paging.cr2=lin_addr;
|
||||
cpu.exception.which=14;
|
||||
cpu.exception.error=0x05 | (writing?0x02:0x00);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
Bitu phys_page;
|
||||
if (lin_page<LINK_START) phys_page=paging.firstmb[lin_page];
|
||||
else phys_page=lin_page;
|
||||
PAGING_LinkPage(lin_page,phys_page);
|
||||
return true;
|
||||
}
|
||||
PAGING_LinkPage(lin_page,phys_page);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -324,7 +372,8 @@ void PAGING_InitTLB(void) {
|
|||
for (Bitu i=0;i<TLB_SIZE;i++) {
|
||||
paging.tlb.read[i]=0;
|
||||
paging.tlb.write[i]=0;
|
||||
paging.tlb.handler[i]=&init_page_handler;
|
||||
paging.tlb.readhandler[i]=&init_page_handler;
|
||||
paging.tlb.writehandler[i]=&init_page_handler;
|
||||
}
|
||||
paging.links.used=0;
|
||||
}
|
||||
|
@ -335,7 +384,8 @@ void PAGING_ClearTLB(void) {
|
|||
Bitu page=*entries++;
|
||||
paging.tlb.read[page]=0;
|
||||
paging.tlb.write[page]=0;
|
||||
paging.tlb.handler[page]=&init_page_handler;
|
||||
paging.tlb.readhandler[page]=&init_page_handler;
|
||||
paging.tlb.writehandler[page]=&init_page_handler;
|
||||
}
|
||||
paging.links.used=0;
|
||||
}
|
||||
|
@ -344,7 +394,9 @@ void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) {
|
|||
for (;pages>0;pages--) {
|
||||
paging.tlb.read[lin_page]=0;
|
||||
paging.tlb.write[lin_page]=0;
|
||||
paging.tlb.handler[lin_page]=&init_page_handler;
|
||||
paging.tlb.readhandler[lin_page]=&init_page_handler;
|
||||
paging.tlb.writehandler[lin_page]=&init_page_handler;
|
||||
lin_page++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,7 +405,8 @@ void PAGING_MapPage(Bitu lin_page,Bitu phys_page) {
|
|||
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.tlb.readhandler[lin_page]=&init_page_handler;
|
||||
paging.tlb.writehandler[lin_page]=&init_page_handler;
|
||||
} else {
|
||||
PAGING_LinkPage(lin_page,phys_page);
|
||||
}
|
||||
|
@ -377,7 +430,28 @@ void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
|
|||
else paging.tlb.write[lin_page]=0;
|
||||
|
||||
paging.links.entries[paging.links.used++]=lin_page;
|
||||
paging.tlb.handler[lin_page]=handler;
|
||||
paging.tlb.readhandler[lin_page]=handler;
|
||||
paging.tlb.writehandler[lin_page]=handler;
|
||||
}
|
||||
|
||||
void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page) {
|
||||
PageHandler * handler=MEM_GetPageHandler(phys_page);
|
||||
Bitu lin_base=lin_page << 12;
|
||||
if (lin_page>=TLB_SIZE || phys_page>=TLB_SIZE)
|
||||
E_Exit("Illegal page");
|
||||
|
||||
if (paging.links.used>=PAGING_LINKS) {
|
||||
LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache");
|
||||
PAGING_ClearTLB();
|
||||
}
|
||||
|
||||
paging.tlb.phys_page[lin_page]=phys_page;
|
||||
if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=handler->GetHostReadPt(phys_page)-lin_base;
|
||||
else paging.tlb.read[lin_page]=0;
|
||||
paging.tlb.write[lin_page]=0;
|
||||
|
||||
paging.links.entries[paging.links.used++]=lin_page;
|
||||
paging.tlb.readhandler[lin_page]=handler;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -386,7 +460,8 @@ 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;
|
||||
bank[i].readhandler=&init_page_handler;
|
||||
bank[i].writehandler=&init_page_handler;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,7 +483,8 @@ void PAGING_ClearTLB(void) {
|
|||
tlb_entry *entry = get_tlb_entry(page<<12);
|
||||
entry->read=0;
|
||||
entry->write=0;
|
||||
entry->handler=&init_page_handler;
|
||||
entry->readhandler=&init_page_handler;
|
||||
entry->writehandler=&init_page_handler;
|
||||
}
|
||||
paging.links.used=0;
|
||||
}
|
||||
|
@ -418,7 +494,8 @@ void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) {
|
|||
for (;pages>0;pages--) {
|
||||
entry->read=0;
|
||||
entry->write=0;
|
||||
entry->handler=&init_page_handler;
|
||||
entry->readhandler=&init_page_handler;
|
||||
entry->writehandler=&init_page_handler;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -427,7 +504,8 @@ void PAGING_MapPage(Bitu lin_page,Bitu phys_page) {
|
|||
paging.firstmb[lin_page]=phys_page;
|
||||
paging.tlbh[lin_page].read=0;
|
||||
paging.tlbh[lin_page].write=0;
|
||||
paging.tlbh[lin_page].handler=&init_page_handler;
|
||||
paging.tlbh[lin_page].readhandler=&init_page_handler;
|
||||
paging.tlbh[lin_page].writehandler=&init_page_handler;
|
||||
} else {
|
||||
PAGING_LinkPage(lin_page,phys_page);
|
||||
}
|
||||
|
@ -452,7 +530,29 @@ void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
|
|||
else entry->write=0;
|
||||
|
||||
paging.links.entries[paging.links.used++]=lin_page;
|
||||
entry->handler=handler;
|
||||
entry->readhandler=handler;
|
||||
entry->writehandler=handler;
|
||||
}
|
||||
|
||||
void PAGING_LinkPage_ReadOnly(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;
|
||||
entry->write=0;
|
||||
|
||||
paging.links.entries[paging.links.used++]=lin_page;
|
||||
entry->readhandler=handler;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: debug.cpp,v 1.89 2007-10-05 17:45:53 c2woody Exp $ */
|
||||
/* $Id: debug.cpp,v 1.90 2007-11-24 17:26:48 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 (!(get_tlb_handler(address)->flags & PFLAG_INIT)) {
|
||||
if (!(get_tlb_readhandler(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 (!(get_tlb_handler(address)->flags & PFLAG_INIT)) {
|
||||
if (!(get_tlb_readhandler(address)->flags & PFLAG_INIT)) {
|
||||
static char outmask[] = "%s:[%04X]=%02X";
|
||||
|
||||
if (cpu.pmode) outmask[6] = '8';
|
||||
|
|
Loading…
Add table
Reference in a new issue