VirtualBox

source: vbox/trunk/include/VBox/mm.h@ 8006

Last change on this file since 8006 was 7635, checked in by vboxsync, 16 years ago

The new MMIO2 code.
WARNING! This changes the pci mapping protocol for MMIO2 so it's working the same way as I/O ports and normal MMIO memory. External users of the interface will have to update their mapping routines.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.0 KB
Line 
1/** @file
2 * MM - The Memory Manager.
3 */
4
5/*
6 * Copyright (C) 2006-2007 innotek GmbH
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
26#ifndef ___VBox_mm_h
27#define ___VBox_mm_h
28
29#include <VBox/cdefs.h>
30#include <VBox/types.h>
31#include <VBox/x86.h>
32#include <VBox/sup.h>
33
34
35__BEGIN_DECLS
36
37/** @defgroup grp_mm The Memory Manager API
38 * @{
39 */
40
41/** @name RAM Page Flags
42 * Since internal ranges have a byte granularity it's possible for a
43 * page be flagged for several uses. The access virtualization in PGM
44 * will choose the most restricted one and use EM to emulate access to
45 * the less restricted areas of the page.
46 *
47 * Bits 0-11 only since they are fitted into the offset part of a physical memory address.
48 * @{
49 */
50#if 1
51/** Reserved - Not RAM, ROM nor MMIO2.
52 * If this bit is cleared the memory is assumed to be some kind of RAM.
53 * Normal MMIO may set it but that depends on whether the RAM range was
54 * created specially for the MMIO or not.
55 *
56 * @remarks The current implementation will always reserve backing
57 * memory for reserved ranges to simplify things.
58 */
59#define MM_RAM_FLAGS_RESERVED RT_BIT(0)
60/** ROM - Read Only Memory.
61 * The page have a HC physical address which contains the BIOS code. All write
62 * access is trapped and ignored.
63 *
64 * HACK: Writable shadow ROM is indicated by both ROM and MMIO2 being
65 * set. (We're out of bits.)
66 */
67#define MM_RAM_FLAGS_ROM RT_BIT(1)
68/** MMIO - Memory Mapped I/O.
69 * All access is trapped and emulated. No physical backing is required, but
70 * might for various reasons be present.
71 */
72#define MM_RAM_FLAGS_MMIO RT_BIT(2)
73/** MMIO2 - Memory Mapped I/O, variation 2.
74 * The virtualization is performed using real memory and only catching
75 * a few accesses for like keeping track for dirty pages.
76 * @remark Involved in the shadow ROM hack.
77 */
78#define MM_RAM_FLAGS_MMIO2 RT_BIT(3)
79#endif
80
81#ifndef VBOX_WITH_NEW_PHYS_CODE
82/** Physical backing memory is allocated dynamically. Not set implies a one time static allocation. */
83#define MM_RAM_FLAGS_DYNAMIC_ALLOC RT_BIT(11)
84#endif /* !VBOX_WITH_NEW_PHYS_CODE */
85
86/** The shift used to get the reference count. */
87#define MM_RAM_FLAGS_CREFS_SHIFT 62
88/** The mask applied to the the page pool idx after using MM_RAM_FLAGS_CREFS_SHIFT to shift it down. */
89#define MM_RAM_FLAGS_CREFS_MASK 0x3
90/** The (shifted) cRef value used to indiciate that the idx is the head of a
91 * physical cross reference extent list. */
92#define MM_RAM_FLAGS_CREFS_PHYSEXT MM_RAM_FLAGS_CREFS_MASK
93/** The shift used to get the page pool idx. (Apply MM_RAM_FLAGS_IDX_MASK to the result when shifting down). */
94#define MM_RAM_FLAGS_IDX_SHIFT 48
95/** The mask applied to the the page pool idx after using MM_RAM_FLAGS_IDX_SHIFT to shift it down. */
96#define MM_RAM_FLAGS_IDX_MASK 0x3fff
97/** The idx value when we're out of of extents or there are simply too many mappings of this page. */
98#define MM_RAM_FLAGS_IDX_OVERFLOWED MM_RAM_FLAGS_IDX_MASK
99
100/** Mask for masking off any references to the page. */
101#define MM_RAM_FLAGS_NO_REFS_MASK UINT64_C(0x0000ffffffffffff)
102/** @} */
103
104#ifndef VBOX_WITH_NEW_PHYS_CODE
105/** @name MMR3PhysRegisterEx registration type
106 * @{
107 */
108typedef enum
109{
110 /** Normal physical region (flags specify exact page type) */
111 MM_PHYS_TYPE_NORMAL = 0,
112 /** Allocate part of a dynamically allocated physical region */
113 MM_PHYS_TYPE_DYNALLOC_CHUNK,
114
115 MM_PHYS_TYPE_32BIT_HACK = 0x7fffffff
116} MMPHYSREG;
117/** @} */
118#endif
119
120/**
121 * Memory Allocation Tags.
122 * For use with MMHyperAlloc(), MMR3HeapAlloc(), MMR3HeapAllocEx(),
123 * MMR3HeapAllocZ() and MMR3HeapAllocZEx().
124 *
125 * @remark Don't forget to update the dump command in MMHeap.cpp!
126 */
127typedef enum MMTAG
128{
129 MM_TAG_INVALID = 0,
130
131 MM_TAG_CFGM,
132 MM_TAG_CFGM_BYTES,
133 MM_TAG_CFGM_STRING,
134 MM_TAG_CFGM_USER,
135
136 MM_TAG_CSAM,
137 MM_TAG_CSAM_PATCH,
138
139 MM_TAG_DBGF,
140 MM_TAG_DBGF_INFO,
141 MM_TAG_DBGF_LINE,
142 MM_TAG_DBGF_LINE_DUP,
143 MM_TAG_DBGF_STACK,
144 MM_TAG_DBGF_SYMBOL,
145 MM_TAG_DBGF_SYMBOL_DUP,
146 MM_TAG_DBGF_MODULE,
147
148 MM_TAG_EM,
149
150 MM_TAG_IOM,
151 MM_TAG_IOM_STATS,
152
153 MM_TAG_MM,
154 MM_TAG_MM_LOOKUP_GUEST,
155 MM_TAG_MM_LOOKUP_PHYS,
156 MM_TAG_MM_LOOKUP_VIRT,
157 MM_TAG_MM_PAGE,
158
159 MM_TAG_PATM,
160 MM_TAG_PATM_PATCH,
161
162 MM_TAG_PDM,
163 MM_TAG_PDM_ASYNC_COMPLETION,
164 MM_TAG_PDM_DEVICE,
165 MM_TAG_PDM_DEVICE_USER,
166 MM_TAG_PDM_DRIVER,
167 MM_TAG_PDM_DRIVER_USER,
168 MM_TAG_PDM_USB,
169 MM_TAG_PDM_USB_USER,
170 MM_TAG_PDM_LUN,
171 MM_TAG_PDM_QUEUE,
172 MM_TAG_PDM_THREAD,
173
174 MM_TAG_PGM,
175 MM_TAG_PGM_CHUNK_MAPPING,
176 MM_TAG_PGM_HANDLERS,
177 MM_TAG_PGM_PHYS,
178 MM_TAG_PGM_POOL,
179
180 MM_TAG_REM,
181
182 MM_TAG_SELM,
183
184 MM_TAG_SSM,
185
186 MM_TAG_STAM,
187
188 MM_TAG_TM,
189
190 MM_TAG_TRPM,
191
192 MM_TAG_VM,
193 MM_TAG_VM_REQ,
194
195 MM_TAG_VMM,
196
197 MM_TAG_HWACCM,
198
199 MM_TAG_32BIT_HACK = 0x7fffffff
200} MMTAG;
201
202
203
204
205/** @defgroup grp_mm_hyper Hypervisor Memory Management
206 * @ingroup grp_mm
207 * @{ */
208
209MMDECL(RTR3PTR) MMHyperR0ToR3(PVM pVM, RTR0PTR R0Ptr);
210MMDECL(RTGCPTR) MMHyperR0ToGC(PVM pVM, RTR0PTR R0Ptr);
211#ifndef IN_RING0
212MMDECL(void *) MMHyperR0ToCC(PVM pVM, RTR0PTR R0Ptr);
213#endif
214MMDECL(RTR0PTR) MMHyperR3ToR0(PVM pVM, RTR3PTR R3Ptr);
215MMDECL(RTGCPTR) MMHyperR3ToGC(PVM pVM, RTR3PTR R3Ptr);
216MMDECL(RTR3PTR) MMHyperGCToR3(PVM pVM, RTGCPTR GCPtr);
217MMDECL(RTR0PTR) MMHyperGCToR0(PVM pVM, RTGCPTR GCPtr);
218
219#ifndef IN_RING3
220MMDECL(void *) MMHyperR3ToCC(PVM pVM, RTR3PTR R3Ptr);
221#else
222DECLINLINE(void *) MMHyperR3ToCC(PVM pVM, RTR3PTR R3Ptr)
223{
224 NOREF(pVM);
225 return R3Ptr;
226}
227#endif
228
229
230#ifndef IN_GC
231MMDECL(void *) MMHyperGCToCC(PVM pVM, RTGCPTR GCPtr);
232#else
233DECLINLINE(void *) MMHyperGCToCC(PVM pVM, RTGCPTR GCPtr)
234{
235 NOREF(pVM);
236 return GCPtr;
237}
238#endif
239
240#ifndef IN_RING3
241MMDECL(RTR3PTR) MMHyperCCToR3(PVM pVM, void *pv);
242#else
243DECLINLINE(RTR3PTR) MMHyperCCToR3(PVM pVM, void *pv)
244{
245 NOREF(pVM);
246 return pv;
247}
248#endif
249
250#ifndef IN_RING0
251MMDECL(RTR0PTR) MMHyperCCToR0(PVM pVM, void *pv);
252#else
253DECLINLINE(RTR0PTR) MMHyperCCToR0(PVM pVM, void *pv)
254{
255 NOREF(pVM);
256 return pv;
257}
258#endif
259
260#ifndef IN_GC
261MMDECL(RTGCPTR) MMHyperCCToGC(PVM pVM, void *pv);
262#else
263DECLINLINE(RTGCPTR) MMHyperCCToGC(PVM pVM, void *pv)
264{
265 NOREF(pVM);
266 return pv;
267}
268#endif
269
270
271#ifdef IN_GC
272MMDECL(RTHCPTR) MMHyper2HC(PVM pVM, uintptr_t Ptr);
273#else
274DECLINLINE(RTHCPTR) MMHyper2HC(PVM pVM, uintptr_t Ptr)
275{
276 NOREF(pVM);
277 return (RTHCPTR)Ptr;
278}
279#endif
280
281#ifndef IN_GC
282MMDECL(RTGCPTR) MMHyper2GC(PVM pVM, uintptr_t Ptr);
283#else
284DECLINLINE(RTGCPTR) MMHyper2GC(PVM pVM, uintptr_t Ptr)
285{
286 NOREF(pVM);
287 return (RTGCPTR)Ptr;
288}
289#endif
290
291MMDECL(RTGCPTR) MMHyperHC2GC(PVM pVM, RTHCPTR HCPtr);
292MMDECL(RTHCPTR) MMHyperGC2HC(PVM pVM, RTGCPTR GCPtr);
293MMDECL(int) MMHyperAlloc(PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, void **ppv);
294MMDECL(int) MMHyperFree(PVM pVM, void *pv);
295MMDECL(void) MMHyperHeapCheck(PVM pVM);
296#ifdef DEBUG
297MMDECL(void) MMHyperHeapDump(PVM pVM);
298#endif
299MMDECL(size_t) MMHyperHeapGetFreeSize(PVM pVM);
300MMDECL(size_t) MMHyperHeapGetSize(PVM pVM);
301MMDECL(RTGCPTR) MMHyperGetArea(PVM pVM, size_t *pcb);
302MMDECL(bool) MMHyperIsInsideArea(PVM pVM, RTGCPTR GCPtr);
303
304
305MMDECL(RTHCPHYS) MMPage2Phys(PVM pVM, void *pvPage);
306MMDECL(void *) MMPagePhys2Page(PVM pVM, RTHCPHYS HCPhysPage);
307MMDECL(int) MMPagePhys2PageEx(PVM pVM, RTHCPHYS HCPhysPage, void **ppvPage);
308MMDECL(int) MMPagePhys2PageTry(PVM pVM, RTHCPHYS HCPhysPage, void **ppvPage);
309MMDECL(void *) MMPhysGCPhys2HCVirt(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange);
310
311
312/** @def MMHYPER_GC_ASSERT_GCPTR
313 * Asserts that an address is either NULL or inside the hypervisor memory area.
314 * This assertion only works while IN_GC, it's a NOP everywhere else.
315 * @thread The Emulation Thread.
316 */
317#ifdef IN_GC
318# define MMHYPER_GC_ASSERT_GCPTR(pVM, GCPtr) Assert(MMHyperIsInsideArea((pVM), (GCPtr)) || !(GCPtr))
319#else
320# define MMHYPER_GC_ASSERT_GCPTR(pVM, GCPtr) do { } while (0)
321#endif
322
323/** @} */
324
325
326#ifdef IN_RING3
327/** @defgroup grp_mm_r3 The MM Host Context Ring-3 API
328 * @ingroup grp_mm
329 * @{
330 */
331
332MMR3DECL(int) MMR3InitUVM(PUVM pUVM);
333MMR3DECL(int) MMR3Init(PVM pVM);
334MMR3DECL(int) MMR3InitPaging(PVM pVM);
335MMR3DECL(int) MMR3HyperInitFinalize(PVM pVM);
336MMR3DECL(int) MMR3Term(PVM pVM);
337MMR3DECL(void) MMR3TermUVM(PUVM pUVM);
338MMR3DECL(void) MMR3Reset(PVM pVM);
339MMR3DECL(int) MMR3IncreaseBaseReservation(PVM pVM, uint64_t cAddBasePages);
340MMR3DECL(int) MMR3AdjustFixedReservation(PVM pVM, int32_t cDeltaFixedPages, const char *pszDesc);
341MMR3DECL(int) MMR3UpdateShadowReservation(PVM pVM, uint32_t cShadowPages);
342
343MMR3DECL(int) MMR3HCPhys2HCVirt(PVM pVM, RTHCPHYS HCPhys, void **ppv);
344MMR3DECL(int) MMR3ReadGCVirt(PVM pVM, void *pvDst, RTGCPTR GCPtr, size_t cb);
345MMR3DECL(int) MMR3WriteGCVirt(PVM pVM, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb);
346
347
348/** @defgroup grp_mm_r3_hyper Hypervisor Memory Manager (HC R3 Portion)
349 * @ingroup grp_mm_r3
350 * @{ */
351MMDECL(int) MMR3HyperAllocOnceNoRel(PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, void **ppv);
352MMR3DECL(int) MMR3HyperMapHCPhys(PVM pVM, void *pvHC, RTHCPHYS HCPhys, size_t cb, const char *pszDesc, PRTGCPTR pGCPtr);
353MMR3DECL(int) MMR3HyperMapGCPhys(PVM pVM, RTGCPHYS GCPhys, size_t cb, const char *pszDesc, PRTGCPTR pGCPtr);
354MMR3DECL(int) MMR3HyperMapMMIO2(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTGCPTR pGCPtr);
355MMR3DECL(int) MMR3HyperMapHCRam(PVM pVM, void *pvHC, size_t cb, bool fFree, const char *pszDesc, PRTGCPTR pGCPtr);
356MMR3DECL(int) MMR3HyperMapPages(PVM pVM, void *pvR3, RTR0PTR pvR0, size_t cPages, PCSUPPAGE paPages, const char *pszDesc, PRTGCPTR pGCPtr);
357MMR3DECL(int) MMR3HyperReserve(PVM pVM, unsigned cb, const char *pszDesc, PRTGCPTR pGCPtr);
358MMR3DECL(RTHCPHYS) MMR3HyperHCVirt2HCPhys(PVM pVM, void *pvHC);
359MMR3DECL(int) MMR3HyperHCVirt2HCPhysEx(PVM pVM, void *pvHC, PRTHCPHYS pHCPhys);
360MMR3DECL(void *) MMR3HyperHCPhys2HCVirt(PVM pVM, RTHCPHYS HCPhys);
361MMR3DECL(int) MMR3HyperHCPhys2HCVirtEx(PVM pVM, RTHCPHYS HCPhys, void **ppv);
362MMR3DECL(int) MMR3HyperReadGCVirt(PVM pVM, void *pvDst, RTGCPTR GCPtr, size_t cb);
363/** @} */
364
365
366/** @defgroup grp_mm_phys Guest Physical Memory Manager
367 * @ingroup grp_mm_r3
368 * @{ */
369MMR3DECL(int) MMR3PhysRegister(PVM pVM, void *pvRam, RTGCPHYS GCPhys, unsigned cb, unsigned fFlags, const char *pszDesc);
370#ifndef VBOX_WITH_NEW_PHYS_CODE
371MMR3DECL(int) MMR3PhysRegisterEx(PVM pVM, void *pvRam, RTGCPHYS GCPhys, unsigned cb, unsigned fFlags, MMPHYSREG enmType, const char *pszDesc);
372#endif
373MMR3DECL(int) MMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc);
374MMR3DECL(int) MMR3PhysRomProtect(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange);
375MMR3DECL(int) MMR3PhysReserve(PVM pVM, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc);
376MMR3DECL(uint64_t) MMR3PhysGetRamSize(PVM pVM);
377/** @} */
378
379
380/** @defgroup grp_mm_page Physical Page Pool
381 * @ingroup grp_mm_r3
382 * @{ */
383MMR3DECL(void *) MMR3PageAlloc(PVM pVM);
384MMR3DECL(RTHCPHYS) MMR3PageAllocPhys(PVM pVM);
385MMR3DECL(void) MMR3PageFree(PVM pVM, void *pvPage);
386MMR3DECL(void *) MMR3PageAllocLow(PVM pVM);
387MMR3DECL(void) MMR3PageFreeLow(PVM pVM, void *pvPage);
388MMR3DECL(void) MMR3PageFreeByPhys(PVM pVM, RTHCPHYS HCPhysPage);
389MMR3DECL(void *) MMR3PageDummyHCPtr(PVM pVM);
390MMR3DECL(RTHCPHYS) MMR3PageDummyHCPhys(PVM pVM);
391/** @} */
392
393
394/** @defgroup grp_mm_heap Heap Manager
395 * @ingroup grp_mm_r3
396 * @{ */
397MMR3DECL(void *) MMR3HeapAlloc(PVM pVM, MMTAG enmTag, size_t cbSize);
398MMR3DECL(void *) MMR3HeapAllocU(PUVM pUVM, MMTAG enmTag, size_t cbSize);
399MMR3DECL(int) MMR3HeapAllocEx(PVM pVM, MMTAG enmTag, size_t cbSize, void **ppv);
400MMR3DECL(int) MMR3HeapAllocExU(PUVM pUVM, MMTAG enmTag, size_t cbSize, void **ppv);
401MMR3DECL(void *) MMR3HeapAllocZ(PVM pVM, MMTAG enmTag, size_t cbSize);
402MMR3DECL(void *) MMR3HeapAllocZU(PUVM pUVM, MMTAG enmTag, size_t cbSize);
403MMR3DECL(int) MMR3HeapAllocZEx(PVM pVM, MMTAG enmTag, size_t cbSize, void **ppv);
404MMR3DECL(int) MMR3HeapAllocZExU(PUVM pUVM, MMTAG enmTag, size_t cbSize, void **ppv);
405MMR3DECL(void *) MMR3HeapRealloc(void *pv, size_t cbNewSize);
406MMR3DECL(char *) MMR3HeapStrDup(PVM pVM, MMTAG enmTag, const char *psz);
407MMR3DECL(char *) MMR3HeapStrDupU(PUVM pUVM, MMTAG enmTag, const char *psz);
408MMR3DECL(void) MMR3HeapFree(void *pv);
409/** @} */
410
411/** @} */
412#endif /* IN_RING3 */
413
414
415
416#ifdef IN_GC
417/** @defgroup grp_mm_gc The MM Guest Context API
418 * @ingroup grp_mm
419 * @{
420 */
421
422MMGCDECL(void) MMGCRamRegisterTrapHandler(PVM pVM);
423MMGCDECL(void) MMGCRamDeregisterTrapHandler(PVM pVM);
424MMGCDECL(int) MMGCRamReadNoTrapHandler(void *pDst, void *pSrc, size_t cb);
425MMGCDECL(int) MMGCRamWriteNoTrapHandler(void *pDst, void *pSrc, size_t cb);
426MMGCDECL(int) MMGCRamRead(PVM pVM, void *pDst, void *pSrc, size_t cb);
427MMGCDECL(int) MMGCRamWrite(PVM pVM, void *pDst, void *pSrc, size_t cb);
428
429/** @} */
430#endif /* IN_GC */
431
432/** @} */
433__END_DECLS
434
435
436#endif
437
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use