VirtualBox

source: vbox/trunk/src/VBox/VMM/IOMInternal.h@ 20961

Last change on this file since 20961 was 20722, checked in by vboxsync, 15 years ago

More IOM locking and checks.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 20.6 KB
Line 
1/* $Id: IOMInternal.h 20722 2009-06-19 12:34:21Z vboxsync $ */
2/** @file
3 * IOM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#ifndef ___IOMInternal_h
23#define ___IOMInternal_h
24
25#include <VBox/cdefs.h>
26#include <VBox/types.h>
27#include <VBox/iom.h>
28#include <VBox/stam.h>
29#include <VBox/pgm.h>
30#include <VBox/pdmcritsect.h>
31#include <VBox/param.h>
32#include <iprt/avl.h>
33
34
35
36/** @defgroup grp_iom_int Internals
37 * @ingroup grp_iom
38 * @internal
39 * @{
40 */
41
42/**
43 * MMIO range descriptor.
44 */
45typedef struct IOMMMIORANGE
46{
47 /** Avl node core with GCPhys as Key and GCPhys + cbSize - 1 as KeyLast. */
48 AVLROGCPHYSNODECORE Core;
49 /** Start physical address. */
50 RTGCPHYS GCPhys;
51 /** Size of the range. */
52 uint32_t cb;
53 uint32_t u32Alignment; /**< Alignment padding. */
54
55 /** Pointer to user argument - R3. */
56 RTR3PTR pvUserR3;
57 /** Pointer to device instance - R3. */
58 PPDMDEVINSR3 pDevInsR3;
59 /** Pointer to write callback function - R3. */
60 R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR3;
61 /** Pointer to read callback function - R3. */
62 R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR3;
63 /** Pointer to fill (memset) callback function - R3. */
64 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR3;
65
66 /** Pointer to user argument - R0. */
67 RTR0PTR pvUserR0;
68 /** Pointer to device instance - R0. */
69 PPDMDEVINSR0 pDevInsR0;
70 /** Pointer to write callback function - R0. */
71 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR0;
72 /** Pointer to read callback function - R0. */
73 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR0;
74 /** Pointer to fill (memset) callback function - R0. */
75 R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR0;
76
77 /** Pointer to user argument - RC. */
78 RTRCPTR pvUserRC;
79 /** Pointer to device instance - RC. */
80 PPDMDEVINSRC pDevInsRC;
81 /** Pointer to write callback function - RC. */
82 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackRC;
83 /** Pointer to read callback function - RC. */
84 RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackRC;
85 /** Pointer to fill (memset) callback function - RC. */
86 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackRC;
87 /** Alignment padding. */
88 RTRCPTR RCPtrAlignment;
89
90 /** Description / Name. For easing debugging. */
91 R3PTRTYPE(const char *) pszDesc;
92} IOMMMIORANGE;
93/** Pointer to a MMIO range descriptor, R3 version. */
94typedef struct IOMMMIORANGE *PIOMMMIORANGE;
95
96
97/**
98 * MMIO address statistics. (one address)
99 *
100 * This is a simple way of making on demand statistics, however it's a
101 * bit free with the hypervisor heap memory.
102 */
103typedef struct IOMMMIOSTATS
104{
105 /** Avl node core with the address as Key. */
106 AVLOGCPHYSNODECORE Core;
107
108 /** Number of reads to this address from R3. */
109 STAMCOUNTER ReadR3;
110 /** Profiling read handler overhead in R3. */
111 STAMPROFILEADV ProfReadR3;
112
113 /** Number of writes to this address from R3. */
114 STAMCOUNTER WriteR3;
115 /** Profiling write handler overhead in R3. */
116 STAMPROFILEADV ProfWriteR3;
117
118 /** Number of reads to this address from R0/RC. */
119 STAMCOUNTER ReadRZ;
120 /** Profiling read handler overhead in R0/RC. */
121 STAMPROFILEADV ProfReadRZ;
122 /** Number of reads to this address from R0/RC which was serviced in R3. */
123 STAMCOUNTER ReadRZToR3;
124
125 /** Number of writes to this address from R0/RC. */
126 STAMCOUNTER WriteRZ;
127 /** Profiling write handler overhead in R0/RC. */
128 STAMPROFILEADV ProfWriteRZ;
129 /** Number of writes to this address from R0/RC which was serviced in R3. */
130 STAMCOUNTER WriteRZToR3;
131} IOMMMIOSTATS;
132/** Pointer to I/O port statistics. */
133typedef IOMMMIOSTATS *PIOMMMIOSTATS;
134
135
136/**
137 * I/O port range descriptor, R3 version.
138 */
139typedef struct IOMIOPORTRANGER3
140{
141 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
142 AVLROIOPORTNODECORE Core;
143#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
144 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
145#endif
146 /** Start I/O port address. */
147 RTIOPORT Port;
148 /** Size of the range. */
149 uint16_t cPorts;
150 /** Pointer to user argument. */
151 RTR3PTR pvUser;
152 /** Pointer to the associated device instance. */
153 R3PTRTYPE(PPDMDEVINS) pDevIns;
154 /** Pointer to OUT callback function. */
155 R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
156 /** Pointer to IN callback function. */
157 R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
158 /** Pointer to string OUT callback function. */
159 R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
160 /** Pointer to string IN callback function. */
161 R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
162 /** Description / Name. For easing debugging. */
163 R3PTRTYPE(const char *) pszDesc;
164} IOMIOPORTRANGER3;
165/** Pointer to I/O port range descriptor, R3 version. */
166typedef IOMIOPORTRANGER3 *PIOMIOPORTRANGER3;
167
168/**
169 * I/O port range descriptor, R0 version.
170 */
171typedef struct IOMIOPORTRANGER0
172{
173 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
174 AVLROIOPORTNODECORE Core;
175#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
176 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
177#endif
178 /** Start I/O port address. */
179 RTIOPORT Port;
180 /** Size of the range. */
181 uint16_t cPorts;
182 /** Pointer to user argument. */
183 RTR0PTR pvUser;
184 /** Pointer to the associated device instance. */
185 R0PTRTYPE(PPDMDEVINS) pDevIns;
186 /** Pointer to OUT callback function. */
187 R0PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
188 /** Pointer to IN callback function. */
189 R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
190 /** Pointer to string OUT callback function. */
191 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
192 /** Pointer to string IN callback function. */
193 R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
194 /** Description / Name. For easing debugging. */
195 R3PTRTYPE(const char *) pszDesc;
196} IOMIOPORTRANGER0;
197/** Pointer to I/O port range descriptor, R0 version. */
198typedef IOMIOPORTRANGER0 *PIOMIOPORTRANGER0;
199
200/**
201 * I/O port range descriptor, RC version.
202 */
203typedef struct IOMIOPORTRANGERC
204{
205 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
206 AVLROIOPORTNODECORE Core;
207 /** Start I/O port address. */
208 RTIOPORT Port;
209 /** Size of the range. */
210 uint16_t cPorts;
211 /** Pointer to user argument. */
212 RTRCPTR pvUser;
213 /** Pointer to the associated device instance. */
214 RCPTRTYPE(PPDMDEVINS) pDevIns;
215 /** Pointer to OUT callback function. */
216 RCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
217 /** Pointer to IN callback function. */
218 RCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
219 /** Pointer to string OUT callback function. */
220 RCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
221 /** Pointer to string IN callback function. */
222 RCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
223#if HC_ARCH_BITS == 64
224 RTRCPTR RCPtrAlignment; /**< pszDesc is 8 byte aligned. */
225#endif
226 /** Description / Name. For easing debugging. */
227 R3PTRTYPE(const char *) pszDesc;
228} IOMIOPORTRANGERC;
229/** Pointer to I/O port range descriptor, RC version. */
230typedef IOMIOPORTRANGERC *PIOMIOPORTRANGERC;
231
232
233/**
234 * I/O port statistics. (one I/O port)
235 *
236 * This is a simple way of making on demand statistics, however it's a
237 * bit free with the hypervisor heap memory.
238 */
239typedef struct IOMIOPORTSTATS
240{
241 /** Avl node core with the port as Key. */
242 AVLOIOPORTNODECORE Core;
243#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
244 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
245#endif
246 /** Number of INs to this port from R3. */
247 STAMCOUNTER InR3;
248 /** Profiling IN handler overhead in R3. */
249 STAMPROFILEADV ProfInR3;
250 /** Number of OUTs to this port from R3. */
251 STAMCOUNTER OutR3;
252 /** Profiling OUT handler overhead in R3. */
253 STAMPROFILEADV ProfOutR3;
254
255 /** Number of INs to this port from R0/RC. */
256 STAMCOUNTER InRZ;
257 /** Profiling IN handler overhead in R0/RC. */
258 STAMPROFILEADV ProfInRZ;
259 /** Number of INs to this port from R0/RC which was serviced in R3. */
260 STAMCOUNTER InRZToR3;
261
262 /** Number of OUTs to this port from R0/RC. */
263 STAMCOUNTER OutRZ;
264 /** Profiling OUT handler overhead in R0/RC. */
265 STAMPROFILEADV ProfOutRZ;
266 /** Number of OUTs to this port from R0/RC which was serviced in R3. */
267 STAMCOUNTER OutRZToR3;
268} IOMIOPORTSTATS;
269/** Pointer to I/O port statistics. */
270typedef IOMIOPORTSTATS *PIOMIOPORTSTATS;
271
272
273/**
274 * The IOM trees.
275 * These are offset based the nodes and root must be in the same
276 * memory block in HC. The locations of IOM structure and the hypervisor heap
277 * are quite different in R3, R0 and RC.
278 */
279typedef struct IOMTREES
280{
281 /** Tree containing I/O port range descriptors registered for HC (IOMIOPORTRANGEHC). */
282 AVLROIOPORTTREE IOPortTreeR3;
283 /** Tree containing I/O port range descriptors registered for R0 (IOMIOPORTRANGER0). */
284 AVLROIOPORTTREE IOPortTreeR0;
285 /** Tree containing I/O port range descriptors registered for RC (IOMIOPORTRANGERC). */
286 AVLROIOPORTTREE IOPortTreeRC;
287
288 /** Tree containing the MMIO range descriptors (IOMMMIORANGE). */
289 AVLROGCPHYSTREE MMIOTree;
290
291 /** Tree containing I/O port statistics (IOMIOPORTSTATS). */
292 AVLOIOPORTTREE IOPortStatTree;
293 /** Tree containing MMIO statistics (IOMMMIOSTATS). */
294 AVLOGCPHYSTREE MMIOStatTree;
295} IOMTREES;
296/** Pointer to the IOM trees. */
297typedef IOMTREES *PIOMTREES;
298
299
300/**
301 * Converts an IOM pointer into a VM pointer.
302 * @returns Pointer to the VM structure the PGM is part of.
303 * @param pIOM Pointer to IOM instance data.
304 */
305#define IOM2VM(pIOM) ( (PVM)((char*)pIOM - pIOM->offVM) )
306
307/**
308 * IOM Data (part of VM)
309 */
310typedef struct IOM
311{
312 /** Offset to the VM structure. */
313 RTINT offVM;
314
315 /** Pointer to the trees - RC ptr. */
316 RCPTRTYPE(PIOMTREES) pTreesRC;
317 /** Pointer to the trees - R3 ptr. */
318 R3PTRTYPE(PIOMTREES) pTreesR3;
319 /** Pointer to the trees - R0 ptr. */
320 R0PTRTYPE(PIOMTREES) pTreesR0;
321
322 /** The ring-0 address of IOMMMIOHandler. */
323 R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnMMIOHandlerR0;
324 /** The RC address of IOMMMIOHandler. */
325 RCPTRTYPE(PFNPGMRCPHYSHANDLER) pfnMMIOHandlerRC;
326#if HC_ARCH_BITS == 64
327 RTRCPTR padding;
328#endif
329
330 /** Lock serializing EMT access to IOM. */
331 PDMCRITSECT EmtLock;
332
333 /** @name Caching of I/O Port and MMIO ranges and statistics.
334 * (Saves quite some time in rep outs/ins instruction emulation.)
335 * @{ */
336 R3PTRTYPE(PIOMIOPORTRANGER3) pRangeLastReadR3;
337 R3PTRTYPE(PIOMIOPORTRANGER3) pRangeLastWriteR3;
338 R3PTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR3;
339 R3PTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR3;
340 R3PTRTYPE(PIOMMMIORANGE) pMMIORangeLastR3;
341 R3PTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastR3;
342
343 R0PTRTYPE(PIOMIOPORTRANGER0) pRangeLastReadR0;
344 R0PTRTYPE(PIOMIOPORTRANGER0) pRangeLastWriteR0;
345 R0PTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR0;
346 R0PTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR0;
347 R0PTRTYPE(PIOMMMIORANGE) pMMIORangeLastR0;
348 R0PTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastR0;
349
350 RCPTRTYPE(PIOMIOPORTRANGERC) pRangeLastReadRC;
351 RCPTRTYPE(PIOMIOPORTRANGERC) pRangeLastWriteRC;
352 RCPTRTYPE(PIOMIOPORTSTATS) pStatsLastReadRC;
353 RCPTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteRC;
354 RCPTRTYPE(PIOMMMIORANGE) pMMIORangeLastRC;
355 RCPTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastRC;
356 /** @} */
357
358 /** @name I/O Port statistics.
359 * @{ */
360 STAMCOUNTER StatInstIn;
361 STAMCOUNTER StatInstOut;
362 STAMCOUNTER StatInstIns;
363 STAMCOUNTER StatInstOuts;
364 /** @} */
365
366 /** @name MMIO statistics.
367 * @{ */
368 STAMPROFILE StatRZMMIOHandler;
369 STAMCOUNTER StatRZMMIOFailures;
370
371 STAMPROFILE StatRZInstMov;
372 STAMPROFILE StatRZInstCmp;
373 STAMPROFILE StatRZInstAnd;
374 STAMPROFILE StatRZInstOr;
375 STAMPROFILE StatRZInstXor;
376 STAMPROFILE StatRZInstBt;
377 STAMPROFILE StatRZInstTest;
378 STAMPROFILE StatRZInstXchg;
379 STAMPROFILE StatRZInstStos;
380 STAMPROFILE StatRZInstLods;
381#ifdef IOM_WITH_MOVS_SUPPORT
382 STAMPROFILEADV StatRZInstMovs;
383 STAMPROFILE StatRZInstMovsToMMIO;
384 STAMPROFILE StatRZInstMovsFromMMIO;
385 STAMPROFILE StatRZInstMovsMMIO;
386#endif
387 STAMCOUNTER StatRZInstOther;
388
389 STAMCOUNTER StatRZMMIO1Byte;
390 STAMCOUNTER StatRZMMIO2Bytes;
391 STAMCOUNTER StatRZMMIO4Bytes;
392 STAMCOUNTER StatRZMMIO8Bytes;
393
394 STAMCOUNTER StatR3MMIOHandler;
395
396 RTUINT cMovsMaxBytes;
397 RTUINT cStosMaxBytes;
398 /** @} */
399} IOM;
400/** Pointer to IOM instance data. */
401typedef IOM *PIOM;
402
403
404/**
405 * IOM per virtual CPU instance data.
406 */
407typedef struct IOMCPU
408{
409 /** For saving stack space, the disassembler state is allocated here instead of
410 * on the stack.
411 * @note The DISCPUSTATE structure is not R3/R0/RZ clean! */
412 union
413 {
414 /** The disassembler scratch space. */
415 DISCPUSTATE DisState;
416 /** Padding. */
417 uint8_t abDisStatePadding[DISCPUSTATE_PADDING_SIZE];
418 };
419 uint8_t Dummy[16];
420} IOMCPU;
421/** Pointer to IOM per virtual CPU instance data. */
422typedef IOMCPU *PIOMCPU;
423
424
425RT_C_DECLS_BEGIN
426
427#ifdef IN_RING3
428PIOMIOPORTSTATS iomR3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc);
429PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc);
430#endif /* IN_RING3 */
431
432/**
433 * \#PF Handler callback for MMIO ranges.
434 *
435 * @returns VBox status code (appropriate for GC return).
436 *
437 * @param pVM VM Handle.
438 * @param uErrorCode CPU Error code.
439 * @param pRegFrame Trap register frame.
440 * @param pvFault The fault address (cr2).
441 * @param GCPhysFault The GC physical address corresponding to pvFault.
442 * @param pvUser Pointer to the MMIO range entry.
443 */
444VMMDECL(int) IOMMMIOHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
445
446#ifdef IN_RING3
447/**
448 * \#PF Handler callback for MMIO ranges.
449 *
450 * @returns VINF_SUCCESS if the handler have carried out the operation.
451 * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
452 * @param pVM VM Handle.
453 * @param GCPhys The physical address the guest is writing to.
454 * @param pvPhys The HC mapping of that address.
455 * @param pvBuf What the guest is reading/writing.
456 * @param cbBuf How much it's reading/writing.
457 * @param enmAccessType The access type.
458 * @param pvUser Pointer to the MMIO range entry.
459 */
460DECLCALLBACK(int) IOMR3MMIOHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
461#endif
462
463
464/**
465 * Gets the I/O port range for the specified I/O port in the current context.
466 *
467 * @returns Pointer to I/O port range.
468 * @returns NULL if no port registered.
469 *
470 * @param pIOM IOM instance data.
471 * @param Port Port to lookup.
472 */
473DECLINLINE(CTX_SUFF(PIOMIOPORTRANGE)) iomIOPortGetRange(PIOM pIOM, RTIOPORT Port)
474{
475#ifdef IN_RING3
476 if (PDMCritSectIsInitialized(&pIOM->EmtLock))
477#endif
478 Assert(IOMIsLockOwner(IOM2VM(pIOM)));
479 CTX_SUFF(PIOMIOPORTRANGE) pRange = (CTX_SUFF(PIOMIOPORTRANGE))RTAvlroIOPortRangeGet(&pIOM->CTX_SUFF(pTrees)->CTX_SUFF(IOPortTree), Port);
480 return pRange;
481}
482
483
484/**
485 * Gets the I/O port range for the specified I/O port in the HC.
486 *
487 * @returns Pointer to I/O port range.
488 * @returns NULL if no port registered.
489 *
490 * @param pIOM IOM instance data.
491 * @param Port Port to lookup.
492 */
493DECLINLINE(PIOMIOPORTRANGER3) iomIOPortGetRangeR3(PIOM pIOM, RTIOPORT Port)
494{
495#ifdef IN_RING3
496 if (PDMCritSectIsInitialized(&pIOM->EmtLock))
497#endif
498 Assert(IOMIsLockOwner(IOM2VM(pIOM)));
499 PIOMIOPORTRANGER3 pRange = (PIOMIOPORTRANGER3)RTAvlroIOPortRangeGet(&pIOM->CTX_SUFF(pTrees)->IOPortTreeR3, Port);
500 return pRange;
501}
502
503
504/**
505 * Gets the MMIO range for the specified physical address in the current context.
506 *
507 * @returns Pointer to MMIO range.
508 * @returns NULL if address not in a MMIO range.
509 *
510 * @param pIOM IOM instance data.
511 * @param GCPhys Physical address to lookup.
512 */
513DECLINLINE(PIOMMMIORANGE) iomMMIOGetRange(PIOM pIOM, RTGCPHYS GCPhys)
514{
515#ifdef IN_RING3
516 if (PDMCritSectIsInitialized(&pIOM->EmtLock))
517#endif
518 Assert(IOMIsLockOwner(IOM2VM(pIOM)));
519 PIOMMMIORANGE pRange = pIOM->CTX_SUFF(pMMIORangeLast);
520 if ( !pRange
521 || GCPhys - pRange->GCPhys >= pRange->cb)
522 pIOM->CTX_SUFF(pMMIORangeLast) = pRange = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pIOM->CTX_SUFF(pTrees)->MMIOTree, GCPhys);
523 return pRange;
524}
525
526#ifdef VBOX_STRICT
527/**
528 * Gets the MMIO range for the specified physical address in the current context.
529 *
530 * @returns Pointer to MMIO range.
531 * @returns NULL if address not in a MMIO range.
532 *
533 * @param pIOM IOM instance data.
534 * @param GCPhys Physical address to lookup.
535 */
536DECLINLINE(PIOMMMIORANGE) iomMMIOGetRangeUnsafe(PIOM pIOM, RTGCPHYS GCPhys)
537{
538 PIOMMMIORANGE pRange = pIOM->CTX_SUFF(pMMIORangeLast);
539 if ( !pRange
540 || GCPhys - pRange->GCPhys >= pRange->cb)
541 pIOM->CTX_SUFF(pMMIORangeLast) = pRange = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pIOM->CTX_SUFF(pTrees)->MMIOTree, GCPhys);
542 return pRange;
543}
544#endif
545
546
547#ifdef VBOX_WITH_STATISTICS
548/**
549 * Gets the MMIO statistics record.
550 *
551 * In ring-3 this will lazily create missing records, while in GC/R0 the caller has to
552 * return the appropriate status to defer the operation to ring-3.
553 *
554 * @returns Pointer to MMIO stats.
555 * @returns NULL if not found (R0/GC), or out of memory (R3).
556 *
557 * @param pIOM IOM instance data.
558 * @param GCPhys Physical address to lookup.
559 * @param pRange The MMIO range.
560 */
561DECLINLINE(PIOMMMIOSTATS) iomMMIOGetStats(PIOM pIOM, RTGCPHYS GCPhys, PIOMMMIORANGE pRange)
562{
563 Assert(IOMIsLockOwner(IOM2VM(pIOM)));
564 /* For large ranges, we'll put everything on the first byte. */
565 if (pRange->cb > PAGE_SIZE)
566 GCPhys = pRange->GCPhys;
567
568 PIOMMMIOSTATS pStats = pIOM->CTX_SUFF(pMMIOStatsLast);
569 if ( !pStats
570 || pStats->Core.Key != GCPhys)
571 {
572 pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pIOM->CTX_SUFF(pTrees)->MMIOStatTree, GCPhys);
573# ifdef IN_RING3
574 if (!pStats)
575 pStats = iomR3MMIOStatsCreate(IOM2VM(pIOM), GCPhys, pRange->pszDesc);
576# endif
577 }
578 return pStats;
579}
580#endif
581
582/* IOM locking helpers. */
583int iomLock(PVM pVM);
584int iomTryLock(PVM pVM);
585void iomUnlock(PVM pVM);
586
587/* Disassembly helpers used in IOMAll.cpp & IOMAllMMIO.cpp */
588bool iomGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint64_t *pu64Data, unsigned *pcbSize);
589bool iomSaveDataToReg(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint64_t u32Data);
590
591RT_C_DECLS_END
592
593
594#ifdef IN_RING3
595
596#endif
597
598/** @} */
599
600#endif /* ___IOMInternal_h */
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