VirtualBox

source: vbox/trunk/include/VBox/pgm.h@ 15382

Last change on this file since 15382 was 15344, checked in by vboxsync, 16 years ago

#3202: Optimizations of the dynamic page mapping code (ring-0). Do lots of the stuff inline, using the set as a 2st level cache and not releasing it for each inner VT-x iteration.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 29.2 KB
Line 
1/** @file
2 * PGM - Page Monitor / Monitor.
3 */
4
5/*
6 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 *
25 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26 * Clara, CA 95054 USA or visit http://www.sun.com if you need
27 * additional information or have any questions.
28 */
29
30#ifndef ___VBox_pgm_h
31#define ___VBox_pgm_h
32
33#include <VBox/cdefs.h>
34#include <VBox/types.h>
35#include <VBox/sup.h>
36#include <VBox/vmapi.h>
37#include <VBox/x86.h>
38#include <VBox/hwacc_vmx.h>
39#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE)
40# include <iprt/err.h>
41# include <VBox/param.h>
42#endif
43
44__BEGIN_DECLS
45
46/** @defgroup grp_pgm The Page Monitor / Manager API
47 * @{
48 */
49
50/** Chunk size for dynamically allocated physical memory. */
51#define PGM_DYNAMIC_CHUNK_SIZE (1*1024*1024)
52/** Shift GC physical address by 20 bits to get the offset into the pvHCChunkHC array. */
53#define PGM_DYNAMIC_CHUNK_SHIFT 20
54/** Dynamic chunk offset mask. */
55#define PGM_DYNAMIC_CHUNK_OFFSET_MASK 0xfffff
56/** Dynamic chunk base mask. */
57#define PGM_DYNAMIC_CHUNK_BASE_MASK (~(RTGCPHYS)PGM_DYNAMIC_CHUNK_OFFSET_MASK)
58
59
60/**
61 * FNPGMRELOCATE callback mode.
62 */
63typedef enum PGMRELOCATECALL
64{
65 /** The callback is for checking if the suggested address is suitable. */
66 PGMRELOCATECALL_SUGGEST = 1,
67 /** The callback is for executing the relocation. */
68 PGMRELOCATECALL_RELOCATE
69} PGMRELOCATECALL;
70
71
72/**
73 * Callback function which will be called when PGM is trying to find
74 * a new location for the mapping.
75 *
76 * The callback is called in two modes, 1) the check mode and 2) the relocate mode.
77 * In 1) the callback should say if it objects to a suggested new location. If it
78 * accepts the new location, it is called again for doing it's relocation.
79 *
80 *
81 * @returns true if the location is ok.
82 * @returns false if another location should be found.
83 * @param GCPtrOld The old virtual address.
84 * @param GCPtrNew The new virtual address.
85 * @param enmMode Used to indicate the callback mode.
86 * @param pvUser User argument.
87 * @remark The return value is no a failure indicator, it's an acceptance
88 * indicator. Relocation can not fail!
89 */
90typedef DECLCALLBACK(bool) FNPGMRELOCATE(PVM pVM, RTGCPTR GCPtrOld, RTGCPTR GCPtrNew, PGMRELOCATECALL enmMode, void *pvUser);
91/** Pointer to a relocation callback function. */
92typedef FNPGMRELOCATE *PFNPGMRELOCATE;
93
94
95/**
96 * Physical page access handler type.
97 */
98typedef enum PGMPHYSHANDLERTYPE
99{
100 /** MMIO range. Pages are not present, all access is done in interpreter or recompiler. */
101 PGMPHYSHANDLERTYPE_MMIO = 1,
102 /** Handler all write access to a physical page range. */
103 PGMPHYSHANDLERTYPE_PHYSICAL_WRITE,
104 /** Handler all access to a physical page range. */
105 PGMPHYSHANDLERTYPE_PHYSICAL_ALL
106
107} PGMPHYSHANDLERTYPE;
108
109/**
110 * \#PF Handler callback for physical access handler ranges in RC.
111 *
112 * @returns VBox status code (appropriate for RC return).
113 * @param pVM VM Handle.
114 * @param uErrorCode CPU Error code.
115 * @param pRegFrame Trap register frame.
116 * NULL on DMA and other non CPU access.
117 * @param pvFault The fault address (cr2).
118 * @param GCPhysFault The GC physical address corresponding to pvFault.
119 * @param pvUser User argument.
120 */
121typedef DECLCALLBACK(int) FNPGMRCPHYSHANDLER(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
122/** Pointer to PGM access callback. */
123typedef FNPGMRCPHYSHANDLER *PFNPGMRCPHYSHANDLER;
124
125/**
126 * \#PF Handler callback for physical access handler ranges in R0.
127 *
128 * @returns VBox status code (appropriate for R0 return).
129 * @param pVM VM Handle.
130 * @param uErrorCode CPU Error code.
131 * @param pRegFrame Trap register frame.
132 * NULL on DMA and other non CPU access.
133 * @param pvFault The fault address (cr2).
134 * @param GCPhysFault The GC physical address corresponding to pvFault.
135 * @param pvUser User argument.
136 */
137typedef DECLCALLBACK(int) FNPGMR0PHYSHANDLER(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
138/** Pointer to PGM access callback. */
139typedef FNPGMR0PHYSHANDLER *PFNPGMR0PHYSHANDLER;
140
141/**
142 * Guest Access type
143 */
144typedef enum PGMACCESSTYPE
145{
146 /** Read access. */
147 PGMACCESSTYPE_READ = 1,
148 /** Write access. */
149 PGMACCESSTYPE_WRITE
150} PGMACCESSTYPE;
151
152/**
153 * \#PF Handler callback for physical access handler ranges (MMIO among others) in HC.
154 *
155 * The handler can not raise any faults, it's mainly for monitoring write access
156 * to certain pages.
157 *
158 * @returns VINF_SUCCESS if the handler have carried out the operation.
159 * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
160 * @param pVM VM Handle.
161 * @param GCPhys The physical address the guest is writing to.
162 * @param pvPhys The HC mapping of that address.
163 * @param pvBuf What the guest is reading/writing.
164 * @param cbBuf How much it's reading/writing.
165 * @param enmAccessType The access type.
166 * @param pvUser User argument.
167 */
168typedef DECLCALLBACK(int) FNPGMR3PHYSHANDLER(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
169/** Pointer to PGM access callback. */
170typedef FNPGMR3PHYSHANDLER *PFNPGMR3PHYSHANDLER;
171
172
173/**
174 * Virtual access handler type.
175 */
176typedef enum PGMVIRTHANDLERTYPE
177{
178 /** Write access handled. */
179 PGMVIRTHANDLERTYPE_WRITE = 1,
180 /** All access handled. */
181 PGMVIRTHANDLERTYPE_ALL,
182 /** Hypervisor write access handled.
183 * This is used to catch the guest trying to write to LDT, TSS and any other
184 * system structure which the brain dead intel guys let unprivilegde code find. */
185 PGMVIRTHANDLERTYPE_HYPERVISOR
186} PGMVIRTHANDLERTYPE;
187
188/**
189 * \#PF Handler callback for virtual access handler ranges, RC.
190 *
191 * Important to realize that a physical page in a range can have aliases, and
192 * for ALL and WRITE handlers these will also trigger.
193 *
194 * @returns VBox status code (appropriate for GC return).
195 * @param pVM VM Handle.
196 * @param uErrorCode CPU Error code.
197 * @param pRegFrame Trap register frame.
198 * @param pvFault The fault address (cr2).
199 * @param pvRange The base address of the handled virtual range.
200 * @param offRange The offset of the access into this range.
201 * (If it's a EIP range this's the EIP, if not it's pvFault.)
202 */
203typedef DECLCALLBACK(int) FNPGMRCVIRTHANDLER(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
204/** Pointer to PGM access callback. */
205typedef FNPGMRCVIRTHANDLER *PFNPGMRCVIRTHANDLER;
206
207/**
208 * \#PF Handler callback for virtual access handler ranges, R3.
209 *
210 * Important to realize that a physical page in a range can have aliases, and
211 * for ALL and WRITE handlers these will also trigger.
212 *
213 * @returns VINF_SUCCESS if the handler have carried out the operation.
214 * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
215 * @param pVM VM Handle.
216 * @param GCPtr The virtual address the guest is writing to. (not correct if it's an alias!)
217 * @param pvPtr The HC mapping of that address.
218 * @param pvBuf What the guest is reading/writing.
219 * @param cbBuf How much it's reading/writing.
220 * @param enmAccessType The access type.
221 * @param pvUser User argument.
222 */
223typedef DECLCALLBACK(int) FNPGMR3VIRTHANDLER(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
224/** Pointer to PGM access callback. */
225typedef FNPGMR3VIRTHANDLER *PFNPGMR3VIRTHANDLER;
226
227
228/**
229 * \#PF Handler callback for invalidation of virtual access handler ranges.
230 *
231 * @param pVM VM Handle.
232 * @param GCPtr The virtual address the guest has changed.
233 */
234typedef DECLCALLBACK(int) FNPGMR3VIRTINVALIDATE(PVM pVM, RTGCPTR GCPtr);
235/** Pointer to PGM invalidation callback. */
236typedef FNPGMR3VIRTINVALIDATE *PFNPGMR3VIRTINVALIDATE;
237
238/**
239 * Paging mode.
240 */
241typedef enum PGMMODE
242{
243 /** The usual invalid value. */
244 PGMMODE_INVALID = 0,
245 /** Real mode. */
246 PGMMODE_REAL,
247 /** Protected mode, no paging. */
248 PGMMODE_PROTECTED,
249 /** 32-bit paging. */
250 PGMMODE_32_BIT,
251 /** PAE paging. */
252 PGMMODE_PAE,
253 /** PAE paging with NX enabled. */
254 PGMMODE_PAE_NX,
255 /** 64-bit AMD paging (long mode). */
256 PGMMODE_AMD64,
257 /** 64-bit AMD paging (long mode) with NX enabled. */
258 PGMMODE_AMD64_NX,
259 /** Nested paging mode (shadow only; guest physical to host physical). */
260 PGMMODE_NESTED,
261 /** Extended paging (Intel) mode. */
262 PGMMODE_EPT,
263 /** The max number of modes */
264 PGMMODE_MAX,
265 /** 32bit hackishness. */
266 PGMMODE_32BIT_HACK = 0x7fffffff
267} PGMMODE;
268
269/** Macro for checking if the guest is using paging.
270 * @param uType PGMMODE_*
271 * @remark ASSUMES certain order of the PGMMODE_* values.
272 */
273#define PGMMODE_WITH_PAGING(enmMode) ((enmMode) >= PGMMODE_32_BIT)
274
275/**
276 * The current ROM page protection.
277 */
278typedef enum PGMROMPROT
279{
280 /** The customary invalid value. */
281 PGMROMPROT_INVALID = 0,
282 /** Read from the virgin ROM page, ignore writes.
283 * Map the virgin page, use write access handler to ignore writes. */
284 PGMROMPROT_READ_ROM_WRITE_IGNORE,
285 /** Read from the virgin ROM page, write to the shadow RAM.
286 * Map the virgin page, use write access handler change the RAM. */
287 PGMROMPROT_READ_ROM_WRITE_RAM,
288 /** Read from the shadow ROM page, ignore writes.
289 * Map the shadow page read-only, use write access handler to ignore writes. */
290 PGMROMPROT_READ_RAM_WRITE_IGNORE,
291 /** Read from the shadow ROM page, ignore writes.
292 * Map the shadow page read-write, disabled write access handler. */
293 PGMROMPROT_READ_RAM_WRITE_RAM,
294 /** The end of valid values. */
295 PGMROMPROT_END,
296 /** The usual 32-bit type size hack. */
297 PGMROMPROT_32BIT_HACK = 0x7fffffff
298} PGMROMPROT;
299
300/**
301 * Is the ROM mapped (true) or is the shadow RAM mapped (false).
302 *
303 * @returns boolean.
304 * @param enmProt The PGMROMPROT value, must be valid.
305 */
306#define PGMROMPROT_IS_ROM(enmProt) \
307 ( (enmProt) == PGMROMPROT_READ_ROM_WRITE_IGNORE \
308 || (enmProt) == PGMROMPROT_READ_ROM_WRITE_RAM )
309
310
311VMMDECL(RTHCPHYS) PGMGetHyperCR3(PVM pVM);
312VMMDECL(RTHCPHYS) PGMGetNestedCR3(PVM pVM, PGMMODE enmShadowMode);
313VMMDECL(RTHCPHYS) PGMGetEPTCR3(PVM pVM);
314VMMDECL(RTHCPHYS) PGMGetHyper32BitCR3(PVM pVM);
315VMMDECL(RTHCPHYS) PGMGetHyperPaeCR3(PVM pVM);
316VMMDECL(RTHCPHYS) PGMGetHyperAmd64CR3(PVM pVM);
317VMMDECL(RTHCPHYS) PGMGetInterHCCR3(PVM pVM);
318VMMDECL(RTHCPHYS) PGMGetInterRCCR3(PVM pVM);
319VMMDECL(RTHCPHYS) PGMGetInter32BitCR3(PVM pVM);
320VMMDECL(RTHCPHYS) PGMGetInterPaeCR3(PVM pVM);
321VMMDECL(RTHCPHYS) PGMGetInterAmd64CR3(PVM pVM);
322VMMDECL(int) PGMTrap0eHandler(PVM pVM, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault);
323VMMDECL(int) PGMPrefetchPage(PVM pVM, RTGCPTR GCPtrPage);
324VMMDECL(int) PGMVerifyAccess(PVM pVM, RTGCPTR Addr, uint32_t cbSize, uint32_t fAccess);
325VMMDECL(int) PGMIsValidAccess(PVM pVM, RTGCPTR Addr, uint32_t cbSize, uint32_t fAccess);
326VMMDECL(int) PGMInterpretInstruction(PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault);
327VMMDECL(int) PGMMap(PVM pVM, RTGCPTR GCPtr, RTHCPHYS HCPhys, uint32_t cbPages, unsigned fFlags);
328VMMDECL(int) PGMMapSetPage(PVM pVM, RTGCPTR GCPtr, uint64_t cb, uint64_t fFlags);
329VMMDECL(int) PGMMapModifyPage(PVM pVM, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
330VMMDECL(int) PGMShwGetPage(PVM pVM, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys);
331VMMDECL(int) PGMShwSetPage(PVM pVM, RTGCPTR GCPtr, size_t cb, uint64_t fFlags);
332VMMDECL(int) PGMShwModifyPage(PVM pVM, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
333VMMDECL(int) PGMGstGetPage(PVM pVM, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys);
334VMMDECL(bool) PGMGstIsPagePresent(PVM pVM, RTGCPTR GCPtr);
335VMMDECL(int) PGMGstSetPage(PVM pVM, RTGCPTR GCPtr, size_t cb, uint64_t fFlags);
336VMMDECL(int) PGMGstModifyPage(PVM pVM, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
337VMMDECL(X86PDPE) PGMGstGetPaePDPtr(PVM pVM, unsigned iPdPt);
338
339VMMDECL(int) PGMInvalidatePage(PVM pVM, RTGCPTR GCPtrPage);
340VMMDECL(int) PGMFlushTLB(PVM pVM, uint64_t cr3, bool fGlobal);
341VMMDECL(int) PGMSyncCR3(PVM pVM, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal);
342VMMDECL(int) PGMUpdateCR3(PVM pVM, uint64_t cr3);
343VMMDECL(int) PGMChangeMode(PVM pVM, uint64_t cr0, uint64_t cr4, uint64_t efer);
344VMMDECL(PGMMODE) PGMGetGuestMode(PVM pVM);
345VMMDECL(PGMMODE) PGMGetShadowMode(PVM pVM);
346VMMDECL(PGMMODE) PGMGetHostMode(PVM pVM);
347VMMDECL(const char *) PGMGetModeName(PGMMODE enmMode);
348VMMDECL(int) PGMHandlerPhysicalRegisterEx(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
349 R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3, RTR3PTR pvUserR3,
350 R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0, RTR0PTR pvUserR0,
351 RCPTRTYPE(PFNPGMRCPHYSHANDLER) pfnHandlerRC, RTRCPTR pvUserRC,
352 R3PTRTYPE(const char *) pszDesc);
353VMMDECL(int) PGMHandlerPhysicalModify(PVM pVM, RTGCPHYS GCPhysCurrent, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast);
354VMMDECL(int) PGMHandlerPhysicalDeregister(PVM pVM, RTGCPHYS GCPhys);
355VMMDECL(int) PGMHandlerPhysicalChangeCallbacks(PVM pVM, RTGCPHYS GCPhys,
356 R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3, RTR3PTR pvUserR3,
357 R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0, RTR0PTR pvUserR0,
358 RCPTRTYPE(PFNPGMRCPHYSHANDLER) pfnHandlerRC, RTRCPTR pvUserRC,
359 R3PTRTYPE(const char *) pszDesc);
360VMMDECL(int) PGMHandlerPhysicalSplit(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysSplit);
361VMMDECL(int) PGMHandlerPhysicalJoin(PVM pVM, RTGCPHYS GCPhys1, RTGCPHYS GCPhys2);
362VMMDECL(int) PGMHandlerPhysicalPageTempOff(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage);
363VMMDECL(int) PGMHandlerPhysicalPageAlias(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage, RTGCPHYS GCPhysPageRemap);
364VMMDECL(int) PGMHandlerPhysicalReset(PVM pVM, RTGCPHYS GCPhys);
365VMMDECL(int) PGMHandlerPhysicalPageReset(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage);
366VMMDECL(bool) PGMHandlerPhysicalIsRegistered(PVM pVM, RTGCPHYS GCPhys);
367VMMDECL(bool) PGMHandlerVirtualIsRegistered(PVM pVM, RTGCPTR GCPtr);
368VMMDECL(bool) PGMPhysIsA20Enabled(PVM pVM);
369VMMDECL(bool) PGMPhysIsGCPhysValid(PVM pVM, RTGCPHYS GCPhys);
370VMMDECL(bool) PGMPhysIsGCPhysNormal(PVM pVM, RTGCPHYS GCPhys);
371VMMDECL(int) PGMPhysGCPhys2HCPhys(PVM pVM, RTGCPHYS GCPhys, PRTHCPHYS pHCPhys);
372VMMDECL(int) PGMPhysGCPtr2GCPhys(PVM pVM, RTGCPTR GCPtr, PRTGCPHYS pGCPhys);
373VMMDECL(int) PGMPhysGCPtr2HCPhys(PVM pVM, RTGCPTR GCPtr, PRTHCPHYS pHCPhys);
374VMMDECL(void) PGMPhysInvalidatePageGCMapTLB(PVM pVM);
375VMMDECL(void) PGMPhysInvalidatePageR0MapTLB(PVM pVM);
376VMMDECL(void) PGMPhysInvalidatePageR3MapTLB(PVM pVM);
377
378/**
379 * Page mapping lock.
380 *
381 * @remarks This doesn't work in structures shared between
382 * ring-3, ring-0 and/or GC.
383 */
384typedef struct PGMPAGEMAPLOCK
385{
386 /** @todo see PGMPhysIsPageMappingLockValid for possibly incorrect assumptions */
387#ifdef IN_RC
388 /** Just a dummy for the time being. */
389 uint32_t u32Dummy;
390#else
391 /** Pointer to the PGMPAGE. */
392 void *pvPage;
393 /** Pointer to the PGMCHUNKR3MAP. */
394 void *pvMap;
395#endif
396} PGMPAGEMAPLOCK;
397/** Pointer to a page mapping lock. */
398typedef PGMPAGEMAPLOCK *PPGMPAGEMAPLOCK;
399
400VMMDECL(int) PGMPhysGCPhys2CCPtr(PVM pVM, RTGCPHYS GCPhys, void **ppv, PPGMPAGEMAPLOCK pLock);
401VMMDECL(int) PGMPhysGCPhys2CCPtrReadOnly(PVM pVM, RTGCPHYS GCPhys, void const **ppv, PPGMPAGEMAPLOCK pLock);
402VMMDECL(int) PGMPhysGCPtr2CCPtr(PVM pVM, RTGCPTR GCPtr, void **ppv, PPGMPAGEMAPLOCK pLock);
403VMMDECL(int) PGMPhysGCPtr2CCPtrReadOnly(PVM pVM, RTGCPTR GCPtr, void const **ppv, PPGMPAGEMAPLOCK pLock);
404VMMDECL(void) PGMPhysReleasePageMappingLock(PVM pVM, PPGMPAGEMAPLOCK pLock);
405
406/**
407 * Checks if the lock structure is valid
408 *
409 * @param pVM The VM handle.
410 * @param pLock The lock structure initialized by the mapping function.
411 */
412DECLINLINE(bool) PGMPhysIsPageMappingLockValid(PVM pVM, PPGMPAGEMAPLOCK pLock)
413{
414 /** @todo -> complete/change this */
415#ifdef IN_RC
416 return !!(pLock->u32Dummy);
417#else
418 return !!(pLock->pvPage);
419#endif
420}
421
422VMMDECL(int) PGMPhysGCPhys2R3Ptr(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange, PRTR3PTR pR3Ptr);
423VMMDECL(RTR3PTR) PGMPhysGCPhys2R3PtrAssert(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange);
424VMMDECL(int) PGMPhysGCPtr2R3Ptr(PVM pVM, RTGCPTR GCPtr, PRTR3PTR pR3Ptr);
425VMMDECL(int) PGMPhysGCPtr2R3PtrByGstCR3(PVM pVM, RTGCPTR GCPtr, uint64_t cr3, unsigned fFlags, PRTR3PTR pR3Ptr);
426VMMDECL(void) PGMPhysRead(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
427VMMDECL(void) PGMPhysWrite(PVM pVM, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
428#ifndef IN_RC /* Only ring 0 & 3. */
429VMMDECL(int) PGMPhysSimpleReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb);
430VMMDECL(int) PGMPhysSimpleWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb);
431VMMDECL(int) PGMPhysSimpleReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
432VMMDECL(int) PGMPhysSimpleWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb);
433VMMDECL(int) PGMPhysReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
434VMMDECL(int) PGMPhysWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb);
435VMMDECL(int) PGMPhysSimpleDirtyWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb);
436#endif /* !IN_RC */
437VMMDECL(int) PGMPhysInterpretedRead(PVM pVM, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
438#ifdef VBOX_STRICT
439VMMDECL(unsigned) PGMAssertHandlerAndFlagsInSync(PVM pVM);
440VMMDECL(unsigned) PGMAssertNoMappingConflicts(PVM pVM);
441VMMDECL(unsigned) PGMAssertCR3(PVM pVM, uint64_t cr3, uint64_t cr4);
442#endif /* VBOX_STRICT */
443
444#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE)
445VMMDECL(int) PGMDynMapGCPage(PVM pVM, RTGCPHYS GCPhys, void **ppv);
446VMMDECL(int) PGMDynMapGCPageOff(PVM pVM, RTGCPHYS GCPhys, void **ppv);
447VMMDECL(int) PGMDynMapHCPage(PVM pVM, RTHCPHYS HCPhys, void **ppv);
448VMMDECL(void) PGMDynMapStartAutoSet(PVMCPU pVCpu);
449VMMDECL(void) PGMDynMapReleaseAutoSet(PVMCPU pVCpu);
450VMMDECL(void) PGMDynMapFlushAutoSet(PVMCPU pVCpu);
451VMMDECL(void) PGMDynMapMigrateAutoSet(PVMCPU pVCpu);
452
453/**
454 * Temporarily maps one host page specified by HC physical address, returning
455 * pointer within the page.
456 *
457 * Be WARNED that the dynamic page mapping area is small, 8 pages, thus the space is
458 * reused after 8 mappings (or perhaps a few more if you score with the cache).
459 *
460 * @returns VBox status.
461 * @param pVM VM handle.
462 * @param HCPhys HC Physical address of the page.
463 * @param ppv Where to store the address corresponding to HCPhys.
464 */
465DECLINLINE(int) PGMDynMapHCPageOff(PVM pVM, RTHCPHYS HCPhys, void **ppv)
466{
467 int rc = PGMDynMapHCPage(pVM, HCPhys & ~(RTHCPHYS)PAGE_OFFSET_MASK, ppv);
468 if (RT_SUCCESS(rc))
469 *ppv = (void *)((uintptr_t)*ppv | (HCPhys & PAGE_OFFSET_MASK));
470 return rc;
471}
472#endif
473
474
475#ifdef IN_RC
476/** @defgroup grp_pgm_gc The PGM Guest Context API
477 * @ingroup grp_pgm
478 * @{
479 */
480/** @} */
481#endif /* IN_RC */
482
483
484#ifdef IN_RING0
485/** @defgroup grp_pgm_r0 The PGM Host Context Ring-0 API
486 * @ingroup grp_pgm
487 * @{
488 */
489VMMR0DECL(int) PGMR0PhysAllocateHandyPages(PVM pVM);
490VMMR0DECL(int) PGMR0Trap0eHandlerNestedPaging(PVM pVM, PGMMODE enmShwPagingMode, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPHYS pvFault);
491# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
492VMMR0DECL(int) PGMR0DynMapInit(void);
493VMMR0DECL(void) PGMR0DynMapTerm(void);
494VMMR0DECL(int) PGMR0DynMapInitVM(PVM pVM);
495VMMR0DECL(void) PGMR0DynMapTermVM(PVM pVM);
496VMMR0DECL(int) PGMR0DynMapAssertIntegrity(void);
497# endif
498/** @} */
499#endif /* IN_RING0 */
500
501
502
503#ifdef IN_RING3
504/** @defgroup grp_pgm_r3 The PGM Host Context Ring-3 API
505 * @ingroup grp_pgm
506 * @{
507 */
508VMMR3DECL(int) PGMR3Init(PVM pVM);
509VMMR3DECL(int) PGMR3InitCPU(PVM pVM);
510VMMR3DECL(int) PGMR3InitDynMap(PVM pVM);
511VMMR3DECL(int) PGMR3InitFinalize(PVM pVM);
512VMMR3DECL(void) PGMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
513VMMR3DECL(void) PGMR3Reset(PVM pVM);
514VMMR3DECL(int) PGMR3Term(PVM pVM);
515VMMR3DECL(int) PGMR3TermCPU(PVM pVM);
516VMMR3DECL(int) PGMR3LockCall(PVM pVM);
517VMMR3DECL(int) PGMR3ChangeShwPDMappings(PVM pVM, bool fEnable);
518VMMR3DECL(int) PGMR3ChangeMode(PVM pVM, PGMMODE enmGuestMode);
519
520#ifndef VBOX_WITH_NEW_PHYS_CODE
521VMMR3DECL(int) PGM3PhysGrowRange(PVM pVM, PCRTGCPHYS GCPhys);
522#endif /* !VBOX_WITH_NEW_PHYS_CODE */
523VMMR3DECL(int) PGMR3PhysRegisterRam(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, const char *pszDesc);
524VMMR3DECL(int) PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
525 R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3, RTR3PTR pvUserR3,
526 R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0, RTR0PTR pvUserR0,
527 RCPTRTYPE(PFNPGMRCPHYSHANDLER) pfnHandlerRC, RTRCPTR pvUserRC,
528 R3PTRTYPE(const char *) pszDesc);
529VMMR3DECL(int) PGMR3PhysMMIODeregister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb);
530VMMR3DECL(int) PGMR3PhysMMIO2Register(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);
531VMMR3DECL(int) PGMR3PhysMMIO2Deregister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion);
532VMMR3DECL(int) PGMR3PhysMMIO2Map(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);
533VMMR3DECL(int) PGMR3PhysMMIO2Unmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);
534VMMR3DECL(bool) PGMR3PhysMMIO2IsBase(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys);
535VMMR3DECL(int) PGMR3PhysMMIO2GetHCPhys(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, PRTHCPHYS pHCPhys);
536VMMR3DECL(int) PGMR3PhysMMIO2MapKernel(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTR0PTR pR0Ptr);
537
538/** @group PGMR3PhysRegisterRom flags.
539 * @{ */
540/** Inidicates that ROM shadowing should be enabled. */
541#define PGMPHYS_ROM_FLAG_SHADOWED RT_BIT_32(0)
542/** Indicates that what pvBinary points to won't go away
543 * and can be used for strictness checks. */
544#define PGMPHYS_ROM_FLAG_PERMANENT_BINARY RT_BIT_32(1)
545/** @} */
546
547VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb,
548 const void *pvBinary, uint32_t fFlags, const char *pszDesc);
549VMMR3DECL(int) PGMR3PhysRomProtect(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, PGMROMPROT enmProt);
550VMMR3DECL(int) PGMR3PhysRegister(PVM pVM, void *pvRam, RTGCPHYS GCPhys, size_t cb, unsigned fFlags, const SUPPAGE *paPages, const char *pszDesc);
551#ifndef VBOX_WITH_NEW_PHYS_CODE
552VMMR3DECL(int) PGMR3PhysRegisterChunk(PVM pVM, void *pvRam, RTGCPHYS GCPhys, size_t cb, unsigned fFlags, const SUPPAGE *paPages, const char *pszDesc);
553#endif /* !VBOX_WITH_NEW_PHYS_CODE */
554VMMR3DECL(int) PGMR3PhysSetFlags(PVM pVM, RTGCPHYS GCPhys, size_t cb, unsigned fFlags, unsigned fMask);
555VMMDECL(void) PGMR3PhysSetA20(PVM pVM, bool fEnable);
556VMMR3DECL(int) PGMR3MapPT(PVM pVM, RTGCPTR GCPtr, uint32_t cb, PFNPGMRELOCATE pfnRelocate, void *pvUser, const char *pszDesc);
557VMMR3DECL(int) PGMR3UnmapPT(PVM pVM, RTGCPTR GCPtr);
558VMMR3DECL(int) PGMR3MappingsSize(PVM pVM, uint32_t *pcb);
559VMMR3DECL(int) PGMR3MappingsFix(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb);
560VMMR3DECL(int) PGMR3MappingsUnfix(PVM pVM);
561VMMR3DECL(int) PGMR3MapIntermediate(PVM pVM, RTUINTPTR Addr, RTHCPHYS HCPhys, unsigned cbPages);
562VMMR3DECL(bool) PGMR3MapHasConflicts(PVM pVM, uint64_t cr3, bool fRawR0);
563VMMR3DECL(int) PGMR3MapRead(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
564VMMR3DECL(int) PGMR3MapActivate(PVM pVM);
565VMMR3DECL(int) PGMR3MapDeactivate(PVM pVM);
566
567VMMR3DECL(int) PGMR3HandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
568 PFNPGMR3PHYSHANDLER pfnHandlerR3, void *pvUserR3,
569 const char *pszModR0, const char *pszHandlerR0, RTR0PTR pvUserR0,
570 const char *pszModRC, const char *pszHandlerRC, RTRCPTR pvUserRC, const char *pszDesc);
571VMMDECL(int) PGMR3HandlerVirtualRegisterEx(PVM pVM, PGMVIRTHANDLERTYPE enmType, RTGCPTR GCPtr, RTGCPTR GCPtrLast,
572 R3PTRTYPE(PFNPGMR3VIRTINVALIDATE) pfnInvalidateR3,
573 R3PTRTYPE(PFNPGMR3VIRTHANDLER) pfnHandlerR3,
574 RCPTRTYPE(PFNPGMRCVIRTHANDLER) pfnHandlerRC,
575 R3PTRTYPE(const char *) pszDesc);
576VMMR3DECL(int) PGMR3HandlerVirtualRegister(PVM pVM, PGMVIRTHANDLERTYPE enmType, RTGCPTR GCPtr, RTGCPTR GCPtrLast,
577 PFNPGMR3VIRTINVALIDATE pfnInvalidateR3,
578 PFNPGMR3VIRTHANDLER pfnHandlerR3,
579 const char *pszHandlerRC, const char *pszModRC, const char *pszDesc);
580VMMDECL(int) PGMHandlerVirtualChangeInvalidateCallback(PVM pVM, RTGCPTR GCPtr, R3PTRTYPE(PFNPGMR3VIRTINVALIDATE) pfnInvalidateR3);
581VMMDECL(int) PGMHandlerVirtualDeregister(PVM pVM, RTGCPTR GCPtr);
582VMMR3DECL(int) PGMR3PoolGrow(PVM pVM);
583#ifdef ___VBox_dbgf_h /** @todo fix this! */
584VMMR3DECL(int) PGMR3DumpHierarchyHC(PVM pVM, uint64_t cr3, uint64_t cr4, bool fLongMode, unsigned cMaxDepth, PCDBGFINFOHLP pHlp);
585#endif
586VMMR3DECL(int) PGMR3DumpHierarchyGC(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCPHYS PhysSearch);
587
588VMMR3DECL(int) PGMR3PhysTlbGCPhys2Ptr(PVM pVM, RTGCPHYS GCPhys, bool fWritable, void **pvPtr);
589VMMR3DECL(uint8_t) PGMR3PhysReadU8(PVM pVM, RTGCPHYS GCPhys);
590VMMR3DECL(uint16_t) PGMR3PhysReadU16(PVM pVM, RTGCPHYS GCPhys);
591VMMR3DECL(uint32_t) PGMR3PhysReadU32(PVM pVM, RTGCPHYS GCPhys);
592VMMR3DECL(uint64_t) PGMR3PhysReadU64(PVM pVM, RTGCPHYS GCPhys);
593VMMR3DECL(void) PGMR3PhysWriteU8(PVM pVM, RTGCPHYS GCPhys, uint8_t Value);
594VMMR3DECL(void) PGMR3PhysWriteU16(PVM pVM, RTGCPHYS GCPhys, uint16_t Value);
595VMMR3DECL(void) PGMR3PhysWriteU32(PVM pVM, RTGCPHYS GCPhys, uint32_t Value);
596VMMR3DECL(void) PGMR3PhysWriteU64(PVM pVM, RTGCPHYS GCPhys, uint64_t Value);
597VMMR3DECL(int) PGMR3PhysChunkMap(PVM pVM, uint32_t idChunk);
598VMMR3DECL(void) PGMR3PhysChunkInvalidateTLB(PVM pVM);
599VMMR3DECL(int) PGMR3PhysAllocateHandyPages(PVM pVM);
600
601VMMR3DECL(int) PGMR3CheckIntegrity(PVM pVM);
602
603VMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PVM pVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys);
604VMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PVM pVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys);
605VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys);
606VMMR3DECL(int) PGMR3DbgReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb, uint32_t fFlags, size_t *pcbRead);
607VMMR3DECL(int) PGMR3DbgWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten);
608VMMR3DECL(int) PGMR3DbgReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, uint32_t fFlags, size_t *pcbRead);
609VMMR3DECL(int) PGMR3DbgWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten);
610VMMR3DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit);
611VMMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, RTGCPTR GCPtr, RTGCPTR cbRange, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit);
612/** @} */
613#endif /* IN_RING3 */
614
615__END_DECLS
616
617/** @} */
618#endif
619
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette