File: paging.h

package info (click to toggle)
dosbox 0.63-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 3,488 kB
  • ctags: 8,517
  • sloc: cpp: 50,650; ansic: 5,113; sh: 3,338; makefile: 161
file content (185 lines) | stat: -rw-r--r-- 5,043 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/*
 *  Copyright (C) 2002-2004  The DOSBox Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

/* $Id: paging.h,v 1.12 2004/10/12 10:45:10 harekiet Exp $ */

#ifndef _PAGING_H_
#define _PAGING_H_

#include "dosbox.h"
#include "mem.h"

class PageDirectory;

#define MEM_PAGE_SIZE	(4096)
#define XMS_START		(0x110)
#define TLB_SIZE		(1024*1024)

#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_INIT			0x20			//No dynamic code can be generated here

#define LINK_START	((1024+64)/4)			//Start right after the HMA

//Allow 128 mb of memory to be linked
#define PAGING_LINKS (128*1024/4)

class PageHandler {
public:
	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 HostPt GetHostPt(Bitu phys_page);
	Bitu flags;
};

/* Some other functions */
void PAGING_Enable(bool enabled);
bool PAGING_Enabled(void);

Bitu PAGING_GetDirBase(void);
void PAGING_SetDirBase(Bitu cr3);
void PAGING_InitTLB(void);
void PAGING_ClearTLB(void);

void PAGING_LinkPage(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);
bool PAGING_MakePhysPage(Bitu & page);

void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt);
void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler);
void MEM_ResetPageHandler(Bitu phys_page, Bitu pages);


#ifdef _MSC_VER
#pragma pack (1)
#endif
struct X86_PageEntryBlock{
	Bit32u		p:1;
	Bit32u		wr:1;
	Bit32u		us:1;
	Bit32u		pwt:1;
	Bit32u		pcd:1;
	Bit32u		a:1;
	Bit32u		d:1;
	Bit32u		pat:1;
	Bit32u		g:1;
	Bit32u		avl:3;
	Bit32u		base:20;
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack ()
#endif


union X86PageEntry {
	Bit32u load;
	X86_PageEntryBlock block;
};

struct PagingBlock {
	Bitu			cr3;
	Bitu			cr2;
	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;
	struct {
		Bitu used;
		Bit32u entries[PAGING_LINKS];
	} links;
	bool			enabled;
};

extern PagingBlock paging; 

/* Some support functions */

PageHandler * MEM_GetPageHandler(Bitu phys_page);

/* Unaligned address handlers */
Bit16u mem_unalignedreadw(PhysPt address);
Bit32u mem_unalignedreadd(PhysPt address);
void mem_unalignedwritew(PhysPt address,Bit16u val);
void mem_unalignedwrited(PhysPt address,Bit32u val);

/* 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 paging.tlb.handler[index]->readb(address);
}

INLINE Bit16u mem_readw_inline(PhysPt address) {
	if (address & 1) return mem_unalignedreadw(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);

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

INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
	if (address & 1) {mem_unalignedwritew(address,val);return;}

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

INLINE void mem_writed_inline(PhysPt address,Bit32u val) {
	if (address & 3) {mem_unalignedwrited(address,val);return;}

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

}

#endif