VirtualBox

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

Last change on this file since 105853 was 104840, checked in by vboxsync, 6 months ago

VMM/PGM: Refactored RAM ranges, MMIO2 ranges and ROM ranges and added MMIO ranges (to PGM) so we can safely access RAM ranges at runtime w/o fear of them ever being freed up. It is now only possible to create these during VM creation and loading, and they will live till VM destruction (except for MMIO2 which could be destroyed during loading (PCNet fun)). The lookup handling is by table instead of pointer tree. No more ring-0 pointers in shared data. bugref:10687 bugref:10093

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 25.7 KB
Line 
1/* $Id: IOMInternal.h 104840 2024-06-05 00:59:51Z vboxsync $ */
2/** @file
3 * IOM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef VMM_INCLUDED_SRC_include_IOMInternal_h
29#define VMM_INCLUDED_SRC_include_IOMInternal_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#define IOM_WITH_CRIT_SECT_RW
35
36#include <VBox/cdefs.h>
37#include <VBox/types.h>
38#include <VBox/vmm/iom.h>
39#include <VBox/vmm/stam.h>
40#include <VBox/vmm/pgm.h>
41#include <VBox/vmm/pdmcritsect.h>
42#ifdef IOM_WITH_CRIT_SECT_RW
43# include <VBox/vmm/pdmcritsectrw.h>
44#endif
45#include <VBox/param.h>
46#include <iprt/assert.h>
47#include <iprt/avl.h>
48
49
50
51/** @defgroup grp_iom_int Internals
52 * @ingroup grp_iom
53 * @internal
54 * @{
55 */
56
57/**
58 * I/O port lookup table entry.
59 */
60typedef struct IOMIOPORTLOOKUPENTRY
61{
62 /** The first port in the range. */
63 RTIOPORT uFirstPort;
64 /** The last port in the range (inclusive). */
65 RTIOPORT uLastPort;
66 /** The registration handle/index. */
67 uint16_t idx;
68} IOMIOPORTLOOKUPENTRY;
69/** Pointer to an I/O port lookup table entry. */
70typedef IOMIOPORTLOOKUPENTRY *PIOMIOPORTLOOKUPENTRY;
71/** Pointer to a const I/O port lookup table entry. */
72typedef IOMIOPORTLOOKUPENTRY const *PCIOMIOPORTLOOKUPENTRY;
73
74/**
75 * Ring-0 I/O port handle table entry.
76 */
77typedef struct IOMIOPORTENTRYR0
78{
79 /** Pointer to user argument. */
80 RTR0PTR pvUser;
81 /** Pointer to the associated device instance, NULL if entry not used. */
82 R0PTRTYPE(PPDMDEVINS) pDevIns;
83 /** Pointer to OUT callback function. */
84 R0PTRTYPE(PFNIOMIOPORTNEWOUT) pfnOutCallback;
85 /** Pointer to IN callback function. */
86 R0PTRTYPE(PFNIOMIOPORTNEWIN) pfnInCallback;
87 /** Pointer to string OUT callback function. */
88 R0PTRTYPE(PFNIOMIOPORTNEWOUTSTRING) pfnOutStrCallback;
89 /** Pointer to string IN callback function. */
90 R0PTRTYPE(PFNIOMIOPORTNEWINSTRING) pfnInStrCallback;
91 /** The entry of the first statistics entry, UINT16_MAX if no stats. */
92 uint16_t idxStats;
93 /** The number of ports covered by this entry, 0 if entry not used. */
94 RTIOPORT cPorts;
95 /** Same as the handle index. */
96 uint16_t idxSelf;
97 /** IOM_IOPORT_F_XXX (copied from ring-3). */
98 uint16_t fFlags;
99} IOMIOPORTENTRYR0;
100/** Pointer to a ring-0 I/O port handle table entry. */
101typedef IOMIOPORTENTRYR0 *PIOMIOPORTENTRYR0;
102/** Pointer to a const ring-0 I/O port handle table entry. */
103typedef IOMIOPORTENTRYR0 const *PCIOMIOPORTENTRYR0;
104
105/**
106 * Ring-3 I/O port handle table entry.
107 */
108typedef struct IOMIOPORTENTRYR3
109{
110 /** Pointer to user argument. */
111 RTR3PTR pvUser;
112 /** Pointer to the associated device instance. */
113 R3PTRTYPE(PPDMDEVINS) pDevIns;
114 /** Pointer to OUT callback function. */
115 R3PTRTYPE(PFNIOMIOPORTNEWOUT) pfnOutCallback;
116 /** Pointer to IN callback function. */
117 R3PTRTYPE(PFNIOMIOPORTNEWIN) pfnInCallback;
118 /** Pointer to string OUT callback function. */
119 R3PTRTYPE(PFNIOMIOPORTNEWOUTSTRING) pfnOutStrCallback;
120 /** Pointer to string IN callback function. */
121 R3PTRTYPE(PFNIOMIOPORTNEWINSTRING) pfnInStrCallback;
122 /** Description / Name. For easing debugging. */
123 R3PTRTYPE(const char *) pszDesc;
124 /** Extended port description table, optional. */
125 R3PTRTYPE(PCIOMIOPORTDESC) paExtDescs;
126 /** PCI device the registration is associated with. */
127 R3PTRTYPE(PPDMPCIDEV) pPciDev;
128 /** The PCI device region (high 16-bit word) and subregion (low word),
129 * UINT32_MAX if not applicable. */
130 uint32_t iPciRegion;
131 /** The number of ports covered by this entry. */
132 RTIOPORT cPorts;
133 /** The current port mapping (duplicates lookup table). */
134 RTIOPORT uPort;
135 /** The entry of the first statistics entry, UINT16_MAX if no stats. */
136 uint16_t idxStats;
137 /** Set if mapped, clear if not.
138 * Only updated when critsect is held exclusively. */
139 bool fMapped;
140 /** Set if there is an ring-0 entry too. */
141 bool fRing0;
142 /** Set if there is an raw-mode entry too. */
143 bool fRawMode;
144 /** IOM_IOPORT_F_XXX */
145 uint8_t fFlags;
146 /** Same as the handle index. */
147 uint16_t idxSelf;
148} IOMIOPORTENTRYR3;
149AssertCompileSize(IOMIOPORTENTRYR3, 9 * sizeof(RTR3PTR) + 16);
150/** Pointer to a ring-3 I/O port handle table entry. */
151typedef IOMIOPORTENTRYR3 *PIOMIOPORTENTRYR3;
152/** Pointer to a const ring-3 I/O port handle table entry. */
153typedef IOMIOPORTENTRYR3 const *PCIOMIOPORTENTRYR3;
154
155/**
156 * I/O port statistics entry (one I/O port).
157 */
158typedef struct IOMIOPORTSTATSENTRY
159{
160 /** All accesses (only updated for the first port in a range). */
161 STAMCOUNTER Total;
162
163 /** Number of INs to this port from R3. */
164 STAMCOUNTER InR3;
165 /** Profiling IN handler overhead in R3. */
166 STAMPROFILE ProfInR3;
167 /** Number of OUTs to this port from R3. */
168 STAMCOUNTER OutR3;
169 /** Profiling OUT handler overhead in R3. */
170 STAMPROFILE ProfOutR3;
171
172 /** Number of INs to this port from R0/RC. */
173 STAMCOUNTER InRZ;
174 /** Profiling IN handler overhead in R0/RC. */
175 STAMPROFILE ProfInRZ;
176 /** Number of INs to this port from R0/RC which was serviced in R3. */
177 STAMCOUNTER InRZToR3;
178
179 /** Number of OUTs to this port from R0/RC. */
180 STAMCOUNTER OutRZ;
181 /** Profiling OUT handler overhead in R0/RC. */
182 STAMPROFILE ProfOutRZ;
183 /** Number of OUTs to this port from R0/RC which was serviced in R3. */
184 STAMCOUNTER OutRZToR3;
185} IOMIOPORTSTATSENTRY;
186/** Pointer to I/O port statistics entry. */
187typedef IOMIOPORTSTATSENTRY *PIOMIOPORTSTATSENTRY;
188
189
190
191/**
192 * MMIO lookup table entry.
193 */
194typedef struct IOMMMIOLOOKUPENTRY
195{
196 /** The first port in the range. */
197 RTGCPHYS GCPhysFirst;
198 /** The last port in the range (inclusive). */
199 RTGCPHYS GCPhysLast;
200 /** The registration handle/index.
201 * @todo bake this into the lower/upper bits of GCPhysFirst & GCPhysLast. */
202 uint16_t idx;
203 uint16_t abPadding[3];
204} IOMMMIOLOOKUPENTRY;
205/** Pointer to an MMIO lookup table entry. */
206typedef IOMMMIOLOOKUPENTRY *PIOMMMIOLOOKUPENTRY;
207/** Pointer to a const MMIO lookup table entry. */
208typedef IOMMMIOLOOKUPENTRY const *PCIOMMMIOLOOKUPENTRY;
209
210/**
211 * Ring-0 MMIO handle table entry.
212 */
213typedef struct IOMMMIOENTRYR0
214{
215 /** The number of bytes covered by this entry, 0 if entry not used. */
216 RTGCPHYS cbRegion;
217 /** Pointer to user argument. */
218 RTR0PTR pvUser;
219 /** Pointer to the associated device instance, NULL if entry not used. */
220 R0PTRTYPE(PPDMDEVINS) pDevIns;
221 /** Pointer to the write callback function. */
222 R0PTRTYPE(PFNIOMMMIONEWWRITE) pfnWriteCallback;
223 /** Pointer to the read callback function. */
224 R0PTRTYPE(PFNIOMMMIONEWREAD) pfnReadCallback;
225 /** Pointer to the fill callback function. */
226 R0PTRTYPE(PFNIOMMMIONEWFILL) pfnFillCallback;
227 /** The entry of the first statistics entry, UINT16_MAX if no stats.
228 * @note For simplicity, this is always copied from ring-3 for all entries at
229 * the end of VM creation. */
230 uint16_t idxStats;
231 /** Same as the handle index. */
232 uint16_t idxSelf;
233 /** IOM_MMIO_F_XXX (copied from ring-3). */
234 uint32_t fFlags;
235} IOMMMIOENTRYR0;
236/** Pointer to a ring-0 MMIO handle table entry. */
237typedef IOMMMIOENTRYR0 *PIOMMMIOENTRYR0;
238/** Pointer to a const ring-0 MMIO handle table entry. */
239typedef IOMMMIOENTRYR0 const *PCIOMMMIOENTRYR0;
240
241/**
242 * Ring-3 MMIO handle table entry.
243 */
244typedef struct IOMMMIOENTRYR3
245{
246 /** The number of bytes covered by this entry. */
247 RTGCPHYS cbRegion;
248 /** The current mapping address (duplicates lookup table).
249 * This is set to NIL_RTGCPHYS if not mapped (exclusive lock + atomic). */
250 RTGCPHYS volatile GCPhysMapping;
251 /** Pointer to user argument. */
252 RTR3PTR pvUser;
253 /** Pointer to the associated device instance. */
254 R3PTRTYPE(PPDMDEVINS) pDevIns;
255 /** Pointer to the write callback function. */
256 R3PTRTYPE(PFNIOMMMIONEWWRITE) pfnWriteCallback;
257 /** Pointer to the read callback function. */
258 R3PTRTYPE(PFNIOMMMIONEWREAD) pfnReadCallback;
259 /** Pointer to the fill callback function. */
260 R3PTRTYPE(PFNIOMMMIONEWFILL) pfnFillCallback;
261 /** Description / Name. For easing debugging. */
262 R3PTRTYPE(const char *) pszDesc;
263 /** PCI device the registration is associated with. */
264 R3PTRTYPE(PPDMPCIDEV) pPciDev;
265 /** The PCI device region (high 16-bit word) and subregion (low word),
266 * UINT32_MAX if not applicable. */
267 uint32_t iPciRegion;
268 /** IOM_MMIO_F_XXX */
269 uint32_t fFlags;
270 /** The entry of the first statistics entry, UINT16_MAX if no stats. */
271 uint16_t idxStats;
272 /** Set if mapped, clear if not.
273 * Only updated when critsect is held exclusively.
274 * @todo remove as GCPhysMapping != NIL_RTGCPHYS serves the same purpose. */
275 bool volatile fMapped;
276 /** Set if there is an ring-0 entry too. */
277 bool fRing0 : 1;
278 /** Set if there is an raw-mode entry too. */
279 bool fRawMode : 1;
280 bool fPadding : 6;
281 /** Pre-registered ad-hoc RAM range ID. */
282 uint16_t idRamRange;
283 /** Same as the handle index. */
284 uint16_t idxSelf;
285} IOMMMIOENTRYR3;
286AssertCompileSize(IOMMMIOENTRYR3, sizeof(RTGCPHYS) * 2 + 7 * sizeof(RTR3PTR) + 16);
287/** Pointer to a ring-3 MMIO handle table entry. */
288typedef IOMMMIOENTRYR3 *PIOMMMIOENTRYR3;
289/** Pointer to a const ring-3 MMIO handle table entry. */
290typedef IOMMMIOENTRYR3 const *PCIOMMMIOENTRYR3;
291
292/**
293 * MMIO statistics entry (one MMIO).
294 */
295typedef struct IOMMMIOSTATSENTRY
296{
297 /** Counting and profiling reads in R0/RC. */
298 STAMPROFILE ProfReadRZ;
299 /** Number of successful read accesses. */
300 STAMCOUNTER Reads;
301 /** Number of reads to this address from R0/RC which was serviced in R3. */
302 STAMCOUNTER ReadRZToR3;
303 /** Number of complicated reads. */
304 STAMCOUNTER ComplicatedReads;
305 /** Number of reads of 0xff or 0x00. */
306 STAMCOUNTER FFor00Reads;
307 /** Profiling read handler overhead in R3. */
308 STAMPROFILE ProfReadR3;
309
310 /** Counting and profiling writes in R0/RC. */
311 STAMPROFILE ProfWriteRZ;
312 /** Number of successful read accesses. */
313 STAMCOUNTER Writes;
314 /** Number of writes to this address from R0/RC which was serviced in R3. */
315 STAMCOUNTER WriteRZToR3;
316 /** Number of writes to this address from R0/RC which was committed in R3. */
317 STAMCOUNTER CommitRZToR3;
318 /** Number of complicated writes. */
319 STAMCOUNTER ComplicatedWrites;
320 /** Profiling write handler overhead in R3. */
321 STAMPROFILE ProfWriteR3;
322} IOMMMIOSTATSENTRY;
323/** Pointer to MMIO statistics entry. */
324typedef IOMMMIOSTATSENTRY *PIOMMMIOSTATSENTRY;
325
326
327/**
328 * IOM per virtual CPU instance data.
329 */
330typedef struct IOMCPU
331{
332 /**
333 * Pending I/O port write commit (VINF_IOM_R3_IOPORT_COMMIT_WRITE).
334 *
335 * This is a converted VINF_IOM_R3_IOPORT_WRITE handler return that lets the
336 * execution engine commit the instruction and then return to ring-3 to complete
337 * the I/O port write there. This avoids having to decode the instruction again
338 * in ring-3.
339 */
340 struct
341 {
342 /** The value size (0 if not pending). */
343 uint16_t cbValue;
344 /** The I/O port. */
345 RTIOPORT IOPort;
346 /** The value. */
347 uint32_t u32Value;
348 } PendingIOPortWrite;
349
350 /**
351 * Pending MMIO write commit (VINF_IOM_R3_MMIO_COMMIT_WRITE).
352 *
353 * This is a converted VINF_IOM_R3_MMIO_WRITE handler return that lets the
354 * execution engine commit the instruction, stop any more REPs, and return to
355 * ring-3 to complete the MMIO write there. The avoid the tedious decoding of
356 * the instruction again once we're in ring-3, more importantly it allows us to
357 * correctly deal with read-modify-write instructions like XCHG, OR, and XOR.
358 */
359 struct
360 {
361 /** Guest physical MMIO address. */
362 RTGCPHYS GCPhys;
363 /** The number of bytes to write (0 if nothing pending). */
364 uint32_t cbValue;
365 /** Hint. */
366 uint32_t idxMmioRegionHint;
367 /** The value to write. */
368 uint8_t abValue[128];
369 } PendingMmioWrite;
370
371 /** @name Caching of I/O Port and MMIO ranges and statistics.
372 * (Saves quite some time in rep outs/ins instruction emulation.)
373 * @{ */
374 /** I/O port registration index for the last read operation. */
375 uint16_t idxIoPortLastRead;
376 /** I/O port registration index for the last write operation. */
377 uint16_t idxIoPortLastWrite;
378 /** I/O port registration index for the last read string operation. */
379 uint16_t idxIoPortLastReadStr;
380 /** I/O port registration index for the last write string operation. */
381 uint16_t idxIoPortLastWriteStr;
382
383 /** MMIO port registration index for the last IOMR3MmioPhysHandler call.
384 * @note pretty static as only used by APIC on AMD-V. */
385 uint16_t idxMmioLastPhysHandler;
386 uint16_t au16Padding[2];
387 /** @} */
388
389 /** MMIO recursion guard (see @bugref{10315}). */
390 uint8_t cMmioRecursionDepth;
391 uint8_t bPadding;
392 /** The MMIO recursion stack (ring-3 version). */
393 PPDMDEVINSR3 apMmioRecursionStack[2];
394} IOMCPU;
395/** Pointer to IOM per virtual CPU instance data. */
396typedef IOMCPU *PIOMCPU;
397
398
399/**
400 * IOM Data (part of VM)
401 */
402typedef struct IOM
403{
404 /** Lock serializing EMT access to IOM. */
405#ifdef IOM_WITH_CRIT_SECT_RW
406 PDMCRITSECTRW CritSect;
407#else
408 PDMCRITSECT CritSect;
409#endif
410
411 /** @name I/O ports
412 * @note The updating of these variables is done exclusively from EMT(0).
413 * @{ */
414 /** Number of I/O port registrations. */
415 uint32_t cIoPortRegs;
416 /** The size of the paIoPortRegs allocation (in entries). */
417 uint32_t cIoPortAlloc;
418 /** I/O port registration table for ring-3.
419 * There is a parallel table in ring-0, IOMR0PERVM::paIoPortRegs. */
420 R3PTRTYPE(PIOMIOPORTENTRYR3) paIoPortRegs;
421 /** I/O port lookup table. */
422 R3PTRTYPE(PIOMIOPORTLOOKUPENTRY) paIoPortLookup;
423 /** Number of entries in the lookup table. */
424 uint32_t cIoPortLookupEntries;
425 /** Set if I/O port registrations are frozen. */
426 bool fIoPortsFrozen;
427 bool afPadding1[3];
428
429 /** The number of valid entries in paioPortStats. */
430 uint32_t cIoPortStats;
431 /** The size of the paIoPortStats allocation (in entries). */
432 uint32_t cIoPortStatsAllocation;
433 /** I/O port lookup table. */
434 R3PTRTYPE(PIOMIOPORTSTATSENTRY) paIoPortStats;
435 /** Dummy stats entry so we don't need to check for NULL pointers so much. */
436 IOMIOPORTSTATSENTRY IoPortDummyStats;
437 /** @} */
438
439 /** @name MMIO ports
440 * @note The updating of these variables is done exclusively from EMT(0).
441 * @{ */
442 /** MMIO physical access handler type, new style. */
443 PGMPHYSHANDLERTYPE hNewMmioHandlerType;
444 /** Number of MMIO registrations. */
445 uint32_t cMmioRegs;
446 /** The size of the paMmioRegs allocation (in entries). */
447 uint32_t cMmioAlloc;
448 /** MMIO registration table for ring-3.
449 * There is a parallel table in ring-0, IOMR0PERVM::paMmioRegs. */
450 R3PTRTYPE(PIOMMMIOENTRYR3) paMmioRegs;
451 /** MMIO lookup table. */
452 R3PTRTYPE(PIOMMMIOLOOKUPENTRY) paMmioLookup;
453 /** Number of entries in the lookup table. */
454 uint32_t cMmioLookupEntries;
455 /** Set if MMIO registrations are frozen. */
456 bool fMmioFrozen;
457 bool afPadding2[3];
458
459 /** The number of valid entries in paioPortStats. */
460 uint32_t cMmioStats;
461 /** The size of the paMmioStats allocation (in entries). */
462 uint32_t cMmioStatsAllocation;
463 /** MMIO lookup table. */
464 R3PTRTYPE(PIOMMMIOSTATSENTRY) paMmioStats;
465 /** Dummy stats entry so we don't need to check for NULL pointers so much. */
466 IOMMMIOSTATSENTRY MmioDummyStats;
467 /** @} */
468
469 /** @name I/O Port statistics.
470 * @{ */
471 STAMCOUNTER StatIoPortIn;
472 STAMCOUNTER StatIoPortOut;
473 STAMCOUNTER StatIoPortInS;
474 STAMCOUNTER StatIoPortOutS;
475 STAMCOUNTER StatIoPortCommits;
476 /** @} */
477
478 /** @name MMIO statistics.
479 * @{ */
480 STAMPROFILE StatMmioPfHandler;
481 STAMPROFILE StatMmioPhysHandler;
482 STAMCOUNTER StatMmioHandlerR3;
483 STAMCOUNTER StatMmioHandlerR0;
484 STAMCOUNTER StatMmioReadsR0ToR3;
485 STAMCOUNTER StatMmioWritesR0ToR3;
486 STAMCOUNTER StatMmioCommitsR0ToR3;
487 STAMCOUNTER StatMmioCommitsDirect;
488 STAMCOUNTER StatMmioCommitsPgm;
489 STAMCOUNTER StatMmioStaleMappings;
490 STAMCOUNTER StatMmioDevLockContentionR0;
491 STAMCOUNTER StatMmioTooDeepRecursion;
492 /** @} */
493} IOM;
494#ifdef IOM_WITH_CRIT_SECT_RW
495AssertCompileMemberAlignment(IOM, CritSect, 64);
496#endif
497/** Pointer to IOM instance data. */
498typedef IOM *PIOM;
499
500
501/**
502 * IOM data kept in the ring-0 GVM.
503 */
504typedef struct IOMR0PERVM
505{
506 /** @name I/O ports
507 * @{ */
508 /** The higest ring-0 I/O port registration plus one. */
509 uint32_t cIoPortMax;
510 /** The size of the paIoPortRegs allocation (in entries). */
511 uint32_t cIoPortAlloc;
512 /** I/O port registration table for ring-0.
513 * There is a parallel table for ring-3, paIoPortRing3Regs. */
514 R0PTRTYPE(PIOMIOPORTENTRYR0) paIoPortRegs;
515 /** I/O port lookup table. */
516 R0PTRTYPE(PIOMIOPORTLOOKUPENTRY) paIoPortLookup;
517 /** I/O port registration table for ring-3.
518 * Also mapped to ring-3 as IOM::paIoPortRegs. */
519 R0PTRTYPE(PIOMIOPORTENTRYR3) paIoPortRing3Regs;
520 /** Handle to the allocation backing both the ring-0 and ring-3 registration
521 * tables as well as the lookup table. */
522 RTR0MEMOBJ hIoPortMemObj;
523 /** Handle to the ring-3 mapping of the lookup and ring-3 registration table. */
524 RTR0MEMOBJ hIoPortMapObj;
525#ifdef VBOX_WITH_STATISTICS
526 /** The size of the paIoPortStats allocation (in entries). */
527 uint32_t cIoPortStatsAllocation;
528 /** Prevents paIoPortStats from growing, set by IOMR0IoPortSyncStatisticsIndices(). */
529 bool fIoPortStatsFrozen;
530 /** I/O port lookup table. */
531 R0PTRTYPE(PIOMIOPORTSTATSENTRY) paIoPortStats;
532 /** Handle to the allocation backing the I/O port statistics. */
533 RTR0MEMOBJ hIoPortStatsMemObj;
534 /** Handle to the ring-3 mapping of the I/O port statistics. */
535 RTR0MEMOBJ hIoPortStatsMapObj;
536#endif
537 /** @} */
538
539 /** @name MMIO
540 * @{ */
541 /** The higest ring-0 MMIO registration plus one. */
542 uint32_t cMmioMax;
543 /** The size of the paMmioRegs allocation (in entries). */
544 uint32_t cMmioAlloc;
545 /** MMIO registration table for ring-0.
546 * There is a parallel table for ring-3, paMmioRing3Regs. */
547 R0PTRTYPE(PIOMMMIOENTRYR0) paMmioRegs;
548 /** MMIO lookup table. */
549 R0PTRTYPE(PIOMMMIOLOOKUPENTRY) paMmioLookup;
550 /** MMIO registration table for ring-3.
551 * Also mapped to ring-3 as IOM::paMmioRegs. */
552 R0PTRTYPE(PIOMMMIOENTRYR3) paMmioRing3Regs;
553 /** Handle to the allocation backing both the ring-0 and ring-3 registration
554 * tables as well as the lookup table. */
555 RTR0MEMOBJ hMmioMemObj;
556 /** Handle to the ring-3 mapping of the lookup and ring-3 registration table. */
557 RTR0MEMOBJ hMmioMapObj;
558#ifdef VBOX_WITH_STATISTICS
559 /** The size of the paMmioStats allocation (in entries). */
560 uint32_t cMmioStatsAllocation;
561 /* Prevents paMmioStats from growing, set by IOMR0MmioSyncStatisticsIndices(). */
562 bool fMmioStatsFrozen;
563 /** MMIO lookup table. */
564 R0PTRTYPE(PIOMMMIOSTATSENTRY) paMmioStats;
565 /** Handle to the allocation backing the MMIO statistics. */
566 RTR0MEMOBJ hMmioStatsMemObj;
567 /** Handle to the ring-3 mapping of the MMIO statistics. */
568 RTR0MEMOBJ hMmioStatsMapObj;
569#endif
570 /** @} */
571
572} IOMR0PERVM;
573
574
575RT_C_DECLS_BEGIN
576
577#ifdef IN_RING3
578DECLCALLBACK(void) iomR3IoPortInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
579void iomR3IoPortRegStats(PVM pVM, PIOMIOPORTENTRYR3 pRegEntry);
580DECLCALLBACK(void) iomR3MmioInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
581void iomR3MmioRegStats(PVM pVM, PIOMMMIOENTRYR3 pRegEntry);
582VBOXSTRICTRC iomR3MmioCommitWorker(PVM pVM, PVMCPU pVCpu, PIOMMMIOENTRYR3 pRegEntry, RTGCPHYS offRegion); /* IOMAllMmioNew.cpp */
583#endif /* IN_RING3 */
584#ifdef IN_RING0
585void iomR0IoPortCleanupVM(PGVM pGVM);
586void iomR0IoPortInitPerVMData(PGVM pGVM);
587void iomR0MmioCleanupVM(PGVM pGVM);
588void iomR0MmioInitPerVMData(PGVM pGVM);
589#endif
590
591#ifndef IN_RING3
592DECLCALLBACK(FNPGMRZPHYSPFHANDLER) iomMmioPfHandlerNew;
593#endif
594DECLCALLBACK(FNPGMPHYSHANDLER) iomMmioHandlerNew;
595
596/* IOM locking helpers. */
597#ifdef IOM_WITH_CRIT_SECT_RW
598# define IOM_LOCK_EXCL(a_pVM) PDMCritSectRwEnterExcl((a_pVM), &(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
599# define IOM_UNLOCK_EXCL(a_pVM) do { PDMCritSectRwLeaveExcl((a_pVM), &(a_pVM)->iom.s.CritSect); } while (0)
600# if 0 /* (in case needed for debugging) */
601# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, (a_rcBusy))
602# define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0)
603# define IOM_IS_SHARED_LOCK_OWNER(a_pVM) PDMCritSectRwIsWriteOwner(&(a_pVM)->iom.s.CritSect)
604# else
605# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectRwEnterShared((a_pVM), &(a_pVM)->iom.s.CritSect, (a_rcBusy))
606# define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectRwLeaveShared((a_pVM), &(a_pVM)->iom.s.CritSect); } while (0)
607# define IOM_IS_SHARED_LOCK_OWNER(a_pVM) PDMCritSectRwIsReadOwner((a_pVM), &(a_pVM)->iom.s.CritSect, true)
608# endif
609# define IOM_IS_EXCL_LOCK_OWNER(a_pVM) PDMCritSectRwIsWriteOwner((a_pVM), &(a_pVM)->iom.s.CritSect)
610#else
611# define IOM_LOCK_EXCL(a_pVM) PDMCritSectEnter((a_pVM), &(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
612# define IOM_UNLOCK_EXCL(a_pVM) do { PDMCritSectLeave((a_pVM), &(a_pVM)->iom.s.CritSect); } while (0)
613# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectEnter((a_pVM), &(a_pVM)->iom.s.CritSect, (a_rcBusy))
614# define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectLeave((a_pVM), &(a_pVM)->iom.s.CritSect); } while (0)
615# define IOM_IS_SHARED_LOCK_OWNER(a_pVM) PDMCritSectIsOwner((a_pVM), &(a_pVM)->iom.s.CritSect)
616# define IOM_IS_EXCL_LOCK_OWNER(a_pVM) PDMCritSectIsOwner((a_pVM), &(a_pVM)->iom.s.CritSect)
617#endif
618#define IOM_LOCK_SHARED(a_pVM) IOM_LOCK_SHARED_EX(a_pVM, VERR_SEM_BUSY)
619
620
621RT_C_DECLS_END
622
623
624#ifdef IN_RING3
625
626#endif
627
628/** @} */
629
630#endif /* !VMM_INCLUDED_SRC_include_IOMInternal_h */
631
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