1
0
Fork 0

Changes for new paging/memory functions

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1353
This commit is contained in:
Sjoerd van der Berg 2003-10-22 14:25:52 +00:00
parent a2948b3d58
commit f634f27924
2 changed files with 71 additions and 128 deletions

View file

@ -26,7 +26,7 @@ typedef Bit32u PhysPt;
typedef Bit8u * HostPt;
typedef Bit32u RealPt;
typedef Bits MemHandle;
typedef Bit32s MemHandle;
#define MEM_PAGESIZE 4096
@ -43,12 +43,9 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence);
PhysPt MEM_AllocatePage(void);
void MEM_ReleasePages(MemHandle handle);
bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence);
void MEM_MapPagesHandle(Bitu lin_page,MemHandle mem,Bitu mem_page,Bitu pages);
void MEM_MapPagesDirect(Bitu lin_page,Bitu phys_page,Bitu pages);
void MEM_UnmapPages(Bitu phys_page,Bitu pages);
MemHandle MEM_NextHandle(MemHandle handle);
MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where);
/*
The folowing six functions are used everywhere in the end so these should be changed for
@ -57,23 +54,23 @@ MemHandle MEM_NextHandle(MemHandle handle);
#ifdef WORDS_BIGENDIAN
INLINE Bit8u readb(HostPt off) {
INLINE Bit8u host_readb(HostPt off) {
return off[0];
};
INLINE Bit16u readw(HostPt off) {
INLINE Bit16u host_readw(HostPt off) {
return off[0] | (off[1] << 8);
};
INLINE Bit32u readd(HostPt off) {
INLINE Bit32u host_readd(HostPt off) {
return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24);
};
INLINE void writeb(HostPt off,Bit8u val) {
INLINE void host_writeb(HostPt off,Bit8u val) {
off[0]=val;
};
INLINE void writew(HostPt off,Bit16u val) {
INLINE void host_writew(HostPt off,Bit16u val) {
off[0]=(Bit8u)(val);
off[1]=(Bit8u)(val >> 8);
};
INLINE void writed(HostPt off,Bit32u val) {
INLINE void host_writed(HostPt off,Bit32u val) {
off[0]=(Bit8u)(val);
off[1]=(Bit8u)(val >> 8);
off[2]=(Bit8u)(val >> 16);
@ -86,22 +83,22 @@ INLINE void writed(HostPt off,Bit32u val) {
#else
INLINE Bit8u readb(HostPt off) {
INLINE Bit8u host_readb(HostPt off) {
return *(Bit8u *)off;
};
INLINE Bit16u readw(HostPt off) {
INLINE Bit16u host_readw(HostPt off) {
return *(Bit16u *)off;
};
INLINE Bit32u readd(HostPt off) {
INLINE Bit32u host_readd(HostPt off) {
return *(Bit32u *)off;
};
INLINE void writeb(HostPt off,Bit8u val) {
INLINE void host_writeb(HostPt off,Bit8u val) {
*(Bit8u *)(off)=val;
};
INLINE void writew(HostPt off,Bit16u val) {
INLINE void host_writew(HostPt off,Bit16u val) {
*(Bit16u *)(off)=val;
};
INLINE void writed(HostPt off,Bit32u val) {
INLINE void host_writed(HostPt off,Bit32u val) {
*(Bit32u *)(off)=val;
};

View file

@ -22,49 +22,52 @@
#include "mem.h"
class PageDirectory;
struct PageEntry;
struct PageLink;
#define MEM_PAGE_SIZE (4096)
#define XMS_START (0x110)
#define TLB_SIZE (1024*1024)
enum EntryTypes { //The type of memory contained in this link
ENTRY_VGA,
ENTRY_CHANGES,
ENTRY_INIT,
ENTRY_NA,
ENTRY_ROM,
ENTRY_LFB,
ENTRY_RAM,
ENTRY_ALLOC,
};
#define PFLAG_READABLE 0x1
#define PFLAG_WRITEABLE 0x2
#define PFLAG_HASROM 0x4
#define PFLAG_HASCODE 0x8 //Page contains dynamic code
#define PFLAG_NOCODE 0x10 //No dynamic code can be generated here
#define PFLAG_ILLEGAL 0x20 //No dynamic code can be generated here
enum VGA_RANGES {
VGA_RANGE_A000,
VGA_RANGE_B000,
VGA_RANGE_B800,
};
#define LINK_START ((1024+64)/4) //Start right after the HMA
class PageChange {
class PageHandler {
public:
virtual void Changed(PageLink * link,Bitu start,Bitu end)=0;
virtual Bitu readb(PhysPt addr);
virtual Bitu readw(PhysPt addr);
virtual Bitu readd(PhysPt addr);
virtual void writeb(PhysPt addr,Bitu val);
virtual void writew(PhysPt addr,Bitu val);
virtual void writed(PhysPt addr,Bitu val);
virtual void AddPageLink(Bitu lin_page, Bitu phys_page)=0;
virtual HostPt GetHostPt(Bitu phys_page);
Bitu flags;
};
/* Some other functions */
void PAGING_Enable(bool enabled);
bool PAGING_Enabled(void);
void MEM_CheckLinks(PageEntry * theentry);
PageDirectory * MEM_DefaultDirectory(void);
Bitu PAGING_GetDirBase(void);
void PAGING_SetDirBase(Bitu cr3);
void PAGING_InitTLB(void);
void PAGING_ClearTLB(void);
void PAGING_ClearTLBEntries(Bitu pages,Bit32u * entries);
PageLink * MEM_LinkPage(Bitu phys_page,PhysPt lin_base);
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page);
/* This maps the page directly, only use when paging is disabled */
void PAGING_MapPage(Bitu lin_page,Bitu phys_page);
void MEM_UnlinkPage(PageLink * link);
void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt);
void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler);
void MEM_UnlinkPages(void);
#pragma pack(1)
typedef struct {
@ -87,57 +90,18 @@ union X86PageEntry {
X86_PageEntryBlock block;
};
struct PageLink {
HostPt read;
HostPt write;
PageChange * change;
PhysPt lin_base;
PageEntry * entry;
union {
PageDirectory * dir;
Bitu table;
} data;
PageLink * next;
};
struct PageEntry {
PageLink * links;
EntryTypes type;
union {
HostPt mem;
PhysPt vga_base;
PageDirectory * dir;
} data;
MemHandle next_handle;
};
class PageDirectory {
public:
PageDirectory();
~PageDirectory();
void ClearDirectory(void);
void SetBase(PhysPt page);
void LinkPage(Bitu lin_page,Bitu phys_page);
bool InitPage(Bitu lin_address);
bool InitPageLinear(Bitu lin_address);
void InvalidateTable(Bitu table);
void InvalidateLink(Bitu table,Bitu index);
PageDirectory * next;
PageLink *links[1024*1024];
PageLink *tables[1024];
PageLink *link_dir; //Handler for main directory table
PageEntry entry_init; //Handler for pages that need init
PageLink link_init; //Handler for pages that need init
Bit32u base_page; //Base got from CR3
PageChange * table_change;
PageChange * dir_change;
};
struct PagingBlock {
PageDirectory * cache;
PageDirectory * dir;
PageLink * free_link;
Bitu cr3;
struct {
Bitu page;
PhysPt addr;
} base;
struct {
HostPt read[TLB_SIZE];
HostPt write[TLB_SIZE];
PageHandler * handler[TLB_SIZE];
Bit32u phys_page[TLB_SIZE];
} tlb;
bool enabled;
};
@ -145,24 +109,7 @@ extern PagingBlock paging;
/* Some support functions */
static INLINE PageLink * GetPageLink(PhysPt address) {
Bitu index=(address>>12);
return paging.dir->links[index];
}
void PAGING_AddFreePageLink(PageLink * link);
PageLink * PAGING_GetFreePageLink(void);
void MEM_SetupVGA(VGA_RANGES range,HostPt base);
/* Page Handler functions */
Bit8u ENTRY_readb(PageEntry * pentry,PhysPt address);
Bit16u ENTRY_readw(PageEntry * pentry,PhysPt address);
Bit32u ENTRY_readd(PageEntry * pentry,PhysPt address);
void ENTRY_writeb(PageEntry * pentry,PhysPt address,Bit8u val);
void ENTRY_writew(PageEntry * pentry,PhysPt address,Bit16u val);
void ENTRY_writed(PageEntry * pentry,PhysPt address,Bit32u val);
PageHandler * MEM_GetPageHandler(Bitu phys_page);
/* Unaligned address handlers */
Bit16u mem_unalignedreadw(PhysPt address);
@ -173,52 +120,51 @@ void mem_unalignedwrited(PhysPt address,Bit32u val);
/* Special inlined memory reading/writing */
INLINE Bit8u mem_readb_inline(PhysPt address) {
PageLink * plink=GetPageLink(address);
if (plink->read) return readb(plink->read+address);
else return ENTRY_readb(plink->entry,address);
Bitu index=(address>>12);
if (paging.tlb.read[index]) return host_readb(paging.tlb.read[index]+address);
else return paging.tlb.handler[index]->readb(address);
}
INLINE Bit16u mem_readw_inline(PhysPt address) {
if (address & 1) return mem_unalignedreadw(address);
PageLink * plink=GetPageLink(address);
if (plink->read) return readw(plink->read+address);
else return ENTRY_readw(plink->entry,address);
Bitu index=(address>>12);
if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address);
else return paging.tlb.handler[index]->readw(address);
}
INLINE Bit32u mem_readd_inline(PhysPt address) {
if (address & 3) return mem_unalignedreadd(address);
PageLink * plink=GetPageLink(address);
if (plink->read) return readd(plink->read+address);
else return ENTRY_readd(plink->entry,address);
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);
}
INLINE void mem_writeb_inline(PhysPt address,Bit8u val) {
PageLink * plink=GetPageLink(address);
Bitu index=(address>>12);
if (plink->write) writeb(plink->write+address,val);
else ENTRY_writeb(plink->entry,address,val);
if (paging.tlb.write[index]) host_writeb(paging.tlb.write[index]+address,val);
else return paging.tlb.handler[index]->writeb(address,val);
}
INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
if (address & 1) {mem_unalignedwritew(address,val);return;}
PageLink * plink=GetPageLink(address);
Bitu index=(address>>12);
if (plink->write) writew(plink->write+address,val);
else ENTRY_writew(plink->entry,address,val);
if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val);
else return paging.tlb.handler[index]->writew(address,val);
}
INLINE void mem_writed_inline(PhysPt address,Bit32u val) {
if (address & 3) {mem_unalignedwrited(address,val);return;}
PageLink * plink=GetPageLink(address);
Bitu index=(address>>12);
if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val);
else return paging.tlb.handler[index]->writed(address,val);
if (plink->write) writed(plink->write+address,val);
else ENTRY_writed(plink->entry,address,val);
}
#endif