VirtualBox

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

Last change on this file since 81136 was 81136, checked in by vboxsync, 5 years ago

IOM,RTC,PCI: Make the port parameter in the I/O port callbacks relative to the start of the mapping rather than absolute. For absolute port numbers, use the IOM_IOPORT_F_ABS flag. bugref:9218

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 26.5 KB
Line 
1/* $Id: IOMInternal.h 81136 2019-10-08 08:26:49Z vboxsync $ */
2/** @file
3 * IOM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2019 Oracle Corporation
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
18#ifndef VMM_INCLUDED_SRC_include_IOMInternal_h
19#define VMM_INCLUDED_SRC_include_IOMInternal_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#define IOM_WITH_CRIT_SECT_RW
25
26#include <VBox/cdefs.h>
27#include <VBox/types.h>
28#include <VBox/vmm/iom.h>
29#include <VBox/vmm/stam.h>
30#include <VBox/vmm/pgm.h>
31#include <VBox/vmm/pdmcritsect.h>
32#ifdef IOM_WITH_CRIT_SECT_RW
33# include <VBox/vmm/pdmcritsectrw.h>
34#endif
35#include <VBox/param.h>
36#include <iprt/assert.h>
37#include <iprt/avl.h>
38
39
40
41/** @defgroup grp_iom_int Internals
42 * @ingroup grp_iom
43 * @internal
44 * @{
45 */
46
47/**
48 * MMIO range descriptor.
49 */
50typedef struct IOMMMIORANGE
51{
52 /** Avl node core with GCPhys as Key and GCPhys + cbSize - 1 as KeyLast. */
53 AVLROGCPHYSNODECORE Core;
54 /** Start physical address. */
55 RTGCPHYS GCPhys;
56 /** Size of the range. */
57 RTGCPHYS cb;
58 /** The reference counter. */
59 uint32_t volatile cRefs;
60 /** Flags, see IOMMMIO_FLAGS_XXX. */
61 uint32_t fFlags;
62
63 /** Pointer to user argument - R0. */
64 RTR0PTR pvUserR0;
65 /** Pointer to device instance - R0. */
66 PPDMDEVINSR0 pDevInsR0;
67 /** Pointer to write callback function - R0. */
68 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR0;
69 /** Pointer to read callback function - R0. */
70 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR0;
71 /** Pointer to fill (memset) callback function - R0. */
72 R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR0;
73
74 /** Pointer to user argument - R3. */
75 RTR3PTR pvUserR3;
76 /** Pointer to device instance - R3. */
77 PPDMDEVINSR3 pDevInsR3;
78 /** Pointer to write callback function - R3. */
79 R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR3;
80 /** Pointer to read callback function - R3. */
81 R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR3;
82 /** Pointer to fill (memset) callback function - R3. */
83 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR3;
84
85 /** Description / Name. For easing debugging. */
86 R3PTRTYPE(const char *) pszDesc;
87
88#if 0
89 /** Pointer to user argument - RC. */
90 RTRCPTR pvUserRC;
91 /** Pointer to device instance - RC. */
92 PPDMDEVINSRC pDevInsRC;
93 /** Pointer to write callback function - RC. */
94 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackRC;
95 /** Pointer to read callback function - RC. */
96 RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackRC;
97 /** Pointer to fill (memset) callback function - RC. */
98 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackRC;
99#if HC_ARCH_BITS == 64
100 /** Padding structure length to multiple of 8 bytes. */
101 RTRCPTR RCPtrPadding;
102#endif
103#endif
104} IOMMMIORANGE;
105/** Pointer to a MMIO range descriptor, R3 version. */
106typedef struct IOMMMIORANGE *PIOMMMIORANGE;
107
108
109/**
110 * MMIO address statistics. (one address)
111 *
112 * This is a simple way of making on demand statistics, however it's a
113 * bit free with the hypervisor heap memory.
114 */
115typedef struct IOMMMIOSTATS
116{
117 /** Avl node core with the address as Key. */
118 AVLOGCPHYSNODECORE Core;
119
120 /** Number of accesses (subtract ReadRZToR3 and WriteRZToR3 to get the right
121 * number). */
122 STAMCOUNTER Accesses;
123
124 /** Profiling read handler overhead in R3. */
125 STAMPROFILE ProfReadR3;
126 /** Profiling write handler overhead in R3. */
127 STAMPROFILE ProfWriteR3;
128 /** Counting and profiling reads in R0/RC. */
129 STAMPROFILE ProfReadRZ;
130 /** Counting and profiling writes in R0/RC. */
131 STAMPROFILE ProfWriteRZ;
132
133 /** Number of reads to this address from R0/RC which was serviced in R3. */
134 STAMCOUNTER ReadRZToR3;
135 /** Number of writes to this address from R0/RC which was serviced in R3. */
136 STAMCOUNTER WriteRZToR3;
137} IOMMMIOSTATS;
138AssertCompileMemberAlignment(IOMMMIOSTATS, Accesses, 8);
139/** Pointer to I/O port statistics. */
140typedef IOMMMIOSTATS *PIOMMMIOSTATS;
141
142/**
143 * I/O port lookup table entry.
144 */
145typedef struct IOMIOPORTLOOKUPENTRY
146{
147 /** The first port in the range. */
148 RTIOPORT uFirstPort;
149 /** The last port in the range (inclusive). */
150 RTIOPORT uLastPort;
151 /** The registration handle/index. */
152 uint16_t idx;
153} IOMIOPORTLOOKUPENTRY;
154/** Pointer to an I/O port lookup table entry. */
155typedef IOMIOPORTLOOKUPENTRY *PIOMIOPORTLOOKUPENTRY;
156/** Pointer to a const I/O port lookup table entry. */
157typedef IOMIOPORTLOOKUPENTRY const *PCIOMIOPORTLOOKUPENTRY;
158
159/**
160 * Ring-0 I/O port handle table entry.
161 */
162typedef struct IOMIOPORTENTRYR0
163{
164 /** Pointer to user argument. */
165 RTR0PTR pvUser;
166 /** Pointer to the associated device instance, NULL if entry not used. */
167 R0PTRTYPE(PPDMDEVINS) pDevIns;
168 /** Pointer to OUT callback function. */
169 R0PTRTYPE(PFNIOMIOPORTNEWOUT) pfnOutCallback;
170 /** Pointer to IN callback function. */
171 R0PTRTYPE(PFNIOMIOPORTNEWIN) pfnInCallback;
172 /** Pointer to string OUT callback function. */
173 R0PTRTYPE(PFNIOMIOPORTNEWOUTSTRING) pfnOutStrCallback;
174 /** Pointer to string IN callback function. */
175 R0PTRTYPE(PFNIOMIOPORTNEWINSTRING) pfnInStrCallback;
176 /** The entry of the first statistics entry, UINT16_MAX if no stats. */
177 uint16_t idxStats;
178 /** The number of ports covered by this entry, 0 if entry not used. */
179 RTIOPORT cPorts;
180 /** Same as the handle index. */
181 uint16_t idxSelf;
182 /** IOM_IOPORT_F_XXX (copied from ring-3). */
183 uint16_t fFlags;
184} IOMIOPORTENTRYR0;
185/** Pointer to a ring-0 I/O port handle table entry. */
186typedef IOMIOPORTENTRYR0 *PIOMIOPORTENTRYR0;
187/** Pointer to a const ring-0 I/O port handle table entry. */
188typedef IOMIOPORTENTRYR0 const *PCIOMIOPORTENTRYR0;
189
190/**
191 * Ring-3 I/O port handle table entry.
192 */
193typedef struct IOMIOPORTENTRYR3
194{
195 /** Pointer to user argument. */
196 RTR3PTR pvUser;
197 /** Pointer to the associated device instance. */
198 R3PTRTYPE(PPDMDEVINS) pDevIns;
199 /** Pointer to OUT callback function. */
200 R3PTRTYPE(PFNIOMIOPORTNEWOUT) pfnOutCallback;
201 /** Pointer to IN callback function. */
202 R3PTRTYPE(PFNIOMIOPORTNEWIN) pfnInCallback;
203 /** Pointer to string OUT callback function. */
204 R3PTRTYPE(PFNIOMIOPORTNEWOUTSTRING) pfnOutStrCallback;
205 /** Pointer to string IN callback function. */
206 R3PTRTYPE(PFNIOMIOPORTNEWINSTRING) pfnInStrCallback;
207 /** Description / Name. For easing debugging. */
208 R3PTRTYPE(const char *) pszDesc;
209 /** Extended port description table, optional. */
210 R3PTRTYPE(PCIOMIOPORTDESC) paExtDescs;
211 /** PCI device the registration is associated with. */
212 R3PTRTYPE(PPDMPCIDEV) pPciDev;
213 /** The PCI device region (high 16-bit word) and subregion (low word),
214 * UINT32_MAX if not applicable. */
215 uint32_t iPciRegion;
216 /** The number of ports covered by this entry. */
217 RTIOPORT cPorts;
218 /** The current port mapping (duplicates lookup table). */
219 RTIOPORT uPort;
220 /** The entry of the first statistics entry, UINT16_MAX if no stats. */
221 uint16_t idxStats;
222 /** Set if mapped, clear if not.
223 * Only updated when critsect is held exclusively. */
224 bool fMapped;
225 /** Set if there is an ring-0 entry too. */
226 bool fRing0;
227 /** Set if there is an raw-mode entry too. */
228 bool fRawMode;
229 /** IOM_IOPORT_F_XXX */
230 uint8_t fFlags;
231 /** Same as the handle index. */
232 uint16_t idxSelf;
233} IOMIOPORTENTRYR3;
234AssertCompileSize(IOMIOPORTENTRYR3, 9 * sizeof(RTR3PTR) + 16);
235/** Pointer to a ring-3 I/O port handle table entry. */
236typedef IOMIOPORTENTRYR3 *PIOMIOPORTENTRYR3;
237/** Pointer to a const ring-3 I/O port handle table entry. */
238typedef IOMIOPORTENTRYR3 const *PCIOMIOPORTENTRYR3;
239
240/**
241 * I/O port statistics entry (one I/O port).
242 */
243typedef struct IOMIOPORTSTATSENTRY
244{
245 /** Number of INs to this port from R3. */
246 STAMCOUNTER InR3;
247 /** Profiling IN handler overhead in R3. */
248 STAMPROFILE ProfInR3;
249 /** Number of OUTs to this port from R3. */
250 STAMCOUNTER OutR3;
251 /** Profiling OUT handler overhead in R3. */
252 STAMPROFILE ProfOutR3;
253
254 /** Number of INs to this port from R0/RC. */
255 STAMCOUNTER InRZ;
256 /** Profiling IN handler overhead in R0/RC. */
257 STAMPROFILE ProfInRZ;
258 /** Number of INs to this port from R0/RC which was serviced in R3. */
259 STAMCOUNTER InRZToR3;
260
261 /** Number of OUTs to this port from R0/RC. */
262 STAMCOUNTER OutRZ;
263 /** Profiling OUT handler overhead in R0/RC. */
264 STAMPROFILE ProfOutRZ;
265 /** Number of OUTs to this port from R0/RC which was serviced in R3. */
266 STAMCOUNTER OutRZToR3;
267} IOMIOPORTSTATSENTRY;
268/** Pointer to I/O port statistics entry. */
269typedef IOMIOPORTSTATSENTRY *PIOMIOPORTSTATSENTRY;
270
271
272/**
273 * I/O port range descriptor, R3 version.
274 */
275typedef struct IOMIOPORTRANGER3
276{
277 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
278 AVLROIOPORTNODECORE Core;
279#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
280 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
281#endif
282 /** Start I/O port address. */
283 RTIOPORT Port;
284 /** Size of the range. */
285 uint16_t cPorts;
286 /** Pointer to user argument. */
287 RTR3PTR pvUser;
288 /** Pointer to the associated device instance. */
289 R3PTRTYPE(PPDMDEVINS) pDevIns;
290 /** Pointer to OUT callback function. */
291 R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
292 /** Pointer to IN callback function. */
293 R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
294 /** Pointer to string OUT callback function. */
295 R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
296 /** Pointer to string IN callback function. */
297 R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
298 /** Description / Name. For easing debugging. */
299 R3PTRTYPE(const char *) pszDesc;
300} IOMIOPORTRANGER3;
301/** Pointer to I/O port range descriptor, R3 version. */
302typedef IOMIOPORTRANGER3 *PIOMIOPORTRANGER3;
303
304/**
305 * I/O port range descriptor, R0 version.
306 */
307typedef struct IOMIOPORTRANGER0
308{
309 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
310 AVLROIOPORTNODECORE Core;
311#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
312 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
313#endif
314 /** Start I/O port address. */
315 RTIOPORT Port;
316 /** Size of the range. */
317 uint16_t cPorts;
318 /** Pointer to user argument. */
319 RTR0PTR pvUser;
320 /** Pointer to the associated device instance. */
321 R0PTRTYPE(PPDMDEVINS) pDevIns;
322 /** Pointer to OUT callback function. */
323 R0PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
324 /** Pointer to IN callback function. */
325 R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
326 /** Pointer to string OUT callback function. */
327 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
328 /** Pointer to string IN callback function. */
329 R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
330 /** Description / Name. For easing debugging. */
331 R3PTRTYPE(const char *) pszDesc;
332} IOMIOPORTRANGER0;
333/** Pointer to I/O port range descriptor, R0 version. */
334typedef IOMIOPORTRANGER0 *PIOMIOPORTRANGER0;
335
336/**
337 * I/O port range descriptor, RC version.
338 */
339typedef struct IOMIOPORTRANGERC
340{
341 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
342 AVLROIOPORTNODECORE Core;
343 /** Start I/O port address. */
344 RTIOPORT Port;
345 /** Size of the range. */
346 uint16_t cPorts;
347 /** Pointer to user argument. */
348 RTRCPTR pvUser;
349 /** Pointer to the associated device instance. */
350 RCPTRTYPE(PPDMDEVINS) pDevIns;
351 /** Pointer to OUT callback function. */
352 RCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
353 /** Pointer to IN callback function. */
354 RCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
355 /** Pointer to string OUT callback function. */
356 RCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
357 /** Pointer to string IN callback function. */
358 RCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
359#if HC_ARCH_BITS == 64
360 RTRCPTR RCPtrAlignment; /**< pszDesc is 8 byte aligned. */
361#endif
362 /** Description / Name. For easing debugging. */
363 R3PTRTYPE(const char *) pszDesc;
364} IOMIOPORTRANGERC;
365/** Pointer to I/O port range descriptor, RC version. */
366typedef IOMIOPORTRANGERC *PIOMIOPORTRANGERC;
367
368
369/**
370 * I/O port statistics. (one I/O port)
371 *
372 * This is a simple way of making on demand statistics, however it's a
373 * bit free with the hypervisor heap memory.
374 */
375typedef struct IOMIOPORTSTATS
376{
377 /** Avl node core with the port as Key. */
378 AVLOIOPORTNODECORE Core;
379#if HC_ARCH_BITS != 64 || !defined(RT_OS_WINDOWS)
380 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
381#endif
382 /** Number of INs to this port from R3. */
383 STAMCOUNTER InR3;
384 /** Profiling IN handler overhead in R3. */
385 STAMPROFILE ProfInR3;
386 /** Number of OUTs to this port from R3. */
387 STAMCOUNTER OutR3;
388 /** Profiling OUT handler overhead in R3. */
389 STAMPROFILE ProfOutR3;
390
391 /** Number of INs to this port from R0/RC. */
392 STAMCOUNTER InRZ;
393 /** Profiling IN handler overhead in R0/RC. */
394 STAMPROFILE ProfInRZ;
395 /** Number of INs to this port from R0/RC which was serviced in R3. */
396 STAMCOUNTER InRZToR3;
397
398 /** Number of OUTs to this port from R0/RC. */
399 STAMCOUNTER OutRZ;
400 /** Profiling OUT handler overhead in R0/RC. */
401 STAMPROFILE ProfOutRZ;
402 /** Number of OUTs to this port from R0/RC which was serviced in R3. */
403 STAMCOUNTER OutRZToR3;
404} IOMIOPORTSTATS;
405AssertCompileMemberAlignment(IOMIOPORTSTATS, InR3, 8);
406/** Pointer to I/O port statistics. */
407typedef IOMIOPORTSTATS *PIOMIOPORTSTATS;
408
409
410/**
411 * The IOM trees.
412 *
413 * These are offset based the nodes and root must be in the same
414 * memory block in HC. The locations of IOM structure and the hypervisor heap
415 * are quite different in R3, R0 and RC.
416 */
417typedef struct IOMTREES
418{
419 /** Tree containing I/O port range descriptors registered for HC (IOMIOPORTRANGEHC). */
420 AVLROIOPORTTREE IOPortTreeR3;
421 /** Tree containing I/O port range descriptors registered for R0 (IOMIOPORTRANGER0). */
422 AVLROIOPORTTREE IOPortTreeR0;
423#if 0
424 /** Tree containing I/O port range descriptors registered for RC (IOMIOPORTRANGERC). */
425 AVLROIOPORTTREE IOPortTreeRC;
426#endif
427
428 /** Tree containing the MMIO range descriptors (IOMMMIORANGE). */
429 AVLROGCPHYSTREE MMIOTree;
430
431 /** Tree containing I/O port statistics (IOMIOPORTSTATS). */
432 AVLOIOPORTTREE IOPortStatTree;
433 /** Tree containing MMIO statistics (IOMMMIOSTATS). */
434 AVLOGCPHYSTREE MmioStatTree;
435} IOMTREES;
436/** Pointer to the IOM trees. */
437typedef IOMTREES *PIOMTREES;
438
439
440/**
441 * IOM per virtual CPU instance data.
442 */
443typedef struct IOMCPU
444{
445 /** For saving stack space, the disassembler state is allocated here instead of
446 * on the stack. */
447 DISCPUSTATE DisState;
448
449 /**
450 * Pending I/O port write commit (VINF_IOM_R3_IOPORT_COMMIT_WRITE).
451 *
452 * This is a converted VINF_IOM_R3_IOPORT_WRITE handler return that lets the
453 * execution engine commit the instruction and then return to ring-3 to complete
454 * the I/O port write there. This avoids having to decode the instruction again
455 * in ring-3.
456 */
457 struct
458 {
459 /** The value size (0 if not pending). */
460 uint16_t cbValue;
461 /** The I/O port. */
462 RTIOPORT IOPort;
463 /** The value. */
464 uint32_t u32Value;
465 } PendingIOPortWrite;
466
467 /**
468 * Pending MMIO write commit (VINF_IOM_R3_MMIO_COMMIT_WRITE).
469 *
470 * This is a converted VINF_IOM_R3_MMIO_WRITE handler return that lets the
471 * execution engine commit the instruction, stop any more REPs, and return to
472 * ring-3 to complete the MMIO write there. The avoid the tedious decoding of
473 * the instruction again once we're in ring-3, more importantly it allows us to
474 * correctly deal with read-modify-write instructions like XCHG, OR, and XOR.
475 */
476 struct
477 {
478 /** Guest physical MMIO address. */
479 RTGCPHYS GCPhys;
480 /** The value to write. */
481 uint8_t abValue[128];
482 /** The number of bytes to write (0 if nothing pending). */
483 uint32_t cbValue;
484 /** Alignment padding. */
485 uint32_t uAlignmentPadding;
486 } PendingMmioWrite;
487
488 /** @name Caching of I/O Port and MMIO ranges and statistics.
489 * (Saves quite some time in rep outs/ins instruction emulation.)
490 * @{ */
491 /** I/O port registration index for the last read operation. */
492 uint16_t idxIoPortLastRead;
493 /** I/O port registration index for the last write operation. */
494 uint16_t idxIoPortLastWrite;
495 /** I/O port registration index for the last read string operation. */
496 uint16_t idxIoPortLastReadStr;
497 /** I/O port registration index for the last write string operation. */
498 uint16_t idxIoPortLastWriteStr;
499 uint32_t u32Padding;
500
501 R3PTRTYPE(PIOMIOPORTRANGER3) pRangeLastReadR3;
502 R3PTRTYPE(PIOMIOPORTRANGER3) pRangeLastWriteR3;
503 R3PTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR3;
504 R3PTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR3;
505 R3PTRTYPE(PIOMMMIORANGE) pMMIORangeLastR3;
506 R3PTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastR3;
507
508 R0PTRTYPE(PIOMIOPORTRANGER0) pRangeLastReadR0;
509 R0PTRTYPE(PIOMIOPORTRANGER0) pRangeLastWriteR0;
510 R0PTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR0;
511 R0PTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR0;
512 R0PTRTYPE(PIOMMMIORANGE) pMMIORangeLastR0;
513 R0PTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastR0;
514 /** @} */
515} IOMCPU;
516/** Pointer to IOM per virtual CPU instance data. */
517typedef IOMCPU *PIOMCPU;
518
519
520/**
521 * IOM Data (part of VM)
522 */
523typedef struct IOM
524{
525 /** Pointer to the trees - R3 ptr. */
526 R3PTRTYPE(PIOMTREES) pTreesR3;
527 /** Pointer to the trees - R0 ptr. */
528 R0PTRTYPE(PIOMTREES) pTreesR0;
529
530 /** MMIO physical access handler type. */
531 PGMPHYSHANDLERTYPE hMmioHandlerType;
532 uint32_t u32Padding;
533
534 /** @name I/O ports
535 * @note The updating of these variables is done exclusively from EMT(0).
536 * @{ */
537 /** Number of I/O port registrations. */
538 uint32_t cIoPortRegs;
539 /** The size of the paIoPortsRegs allocation (in entries). */
540 uint32_t cIoPortAlloc;
541 /** I/O port registration table for ring-3.
542 * There is a parallel table in ring-0, IOMR0PERVM::paIoPortRegs. */
543 R3PTRTYPE(PIOMIOPORTENTRYR3) paIoPortRegs;
544 /** Number of entries in the lookup table. */
545 uint32_t cIoPortLookupEntries;
546 uint32_t u32Padding1;
547 /** I/O port lookup table. */
548 R3PTRTYPE(PIOMIOPORTLOOKUPENTRY) paIoPortLookup;
549
550 /** The number of valid entries in paioPortStats. */
551 uint32_t cIoPortStats;
552 /** The size of the paIoPortStats allocation (in entries). */
553 uint32_t cIoPortStatsAllocation;
554 /** I/O port lookup table. */
555 R3PTRTYPE(PIOMIOPORTSTATSENTRY) paIoPortStats;
556 /** Dummy stats entry so we don't need to check for NULL pointers so much. */
557 IOMIOPORTSTATSENTRY IoPortDummyStats;
558 /** @} */
559
560
561 /** Lock serializing EMT access to IOM. */
562#ifdef IOM_WITH_CRIT_SECT_RW
563 PDMCRITSECTRW CritSect;
564#else
565 PDMCRITSECT CritSect;
566#endif
567
568#if 0 /* unused */
569 /** @name I/O Port statistics.
570 * @{ */
571 STAMCOUNTER StatInstIn;
572 STAMCOUNTER StatInstOut;
573 STAMCOUNTER StatInstIns;
574 STAMCOUNTER StatInstOuts;
575 /** @} */
576#endif
577
578 /** @name MMIO statistics.
579 * @{ */
580 STAMPROFILE StatRZMMIOHandler;
581 STAMCOUNTER StatRZMMIOFailures;
582
583 STAMPROFILE StatRZInstMov;
584 STAMPROFILE StatRZInstCmp;
585 STAMPROFILE StatRZInstAnd;
586 STAMPROFILE StatRZInstOr;
587 STAMPROFILE StatRZInstXor;
588 STAMPROFILE StatRZInstBt;
589 STAMPROFILE StatRZInstTest;
590 STAMPROFILE StatRZInstXchg;
591 STAMPROFILE StatRZInstStos;
592 STAMPROFILE StatRZInstLods;
593#ifdef IOM_WITH_MOVS_SUPPORT
594 STAMPROFILEADV StatRZInstMovs;
595 STAMPROFILE StatRZInstMovsToMMIO;
596 STAMPROFILE StatRZInstMovsFromMMIO;
597 STAMPROFILE StatRZInstMovsMMIO;
598#endif
599 STAMCOUNTER StatRZInstOther;
600
601 STAMCOUNTER StatRZMMIO1Byte;
602 STAMCOUNTER StatRZMMIO2Bytes;
603 STAMCOUNTER StatRZMMIO4Bytes;
604 STAMCOUNTER StatRZMMIO8Bytes;
605
606 STAMCOUNTER StatR3MMIOHandler;
607
608 RTUINT cMovsMaxBytes;
609 RTUINT cStosMaxBytes;
610 /** @} */
611} IOM;
612/** Pointer to IOM instance data. */
613typedef IOM *PIOM;
614
615
616/**
617 * IOM data kept in the ring-0 GVM.
618 */
619typedef struct IOMR0PERVM
620{
621 /** @name I/O ports
622 * @{ */
623 /** The higest ring-0 I/O port registration plus one. */
624 uint32_t cIoPortMax;
625 /** The size of the paIoPortsRegs allocation (in entries). */
626 uint32_t cIoPortAlloc;
627 /** I/O port registration table for ring-0.
628 * There is a parallel table for ring-3, paIoPortRing3Regs. */
629 R0PTRTYPE(PIOMIOPORTENTRYR0) paIoPortRegs;
630 /** I/O port lookup table. */
631 R0PTRTYPE(PIOMIOPORTLOOKUPENTRY) paIoPortLookup;
632 /** I/O port registration table for ring-3.
633 * Also mapped to ring-3 as IOM::paIoPortRegs. */
634 R0PTRTYPE(PIOMIOPORTENTRYR3) paIoPortRing3Regs;
635 /** Handle to the allocation backing both the ring-0 and ring-3 registration
636 * tables as well as the lookup table. */
637 RTR0MEMOBJ hIoPortMemObj;
638 /** Handle to the ring-3 mapping of the lookup and ring-3 registration table. */
639 RTR0MEMOBJ hIoPortMapObj;
640#ifdef VBOX_WITH_STATISTICS
641 /** The size of the paIoPortStats allocation (in entries). */
642 uint32_t cIoPortStatsAllocation;
643 /** I/O port lookup table. */
644 R0PTRTYPE(PIOMIOPORTSTATSENTRY) paIoPortStats;
645 /** Handle to the allocation backing the I/O port statistics. */
646 RTR0MEMOBJ hIoPortStatsMemObj;
647 /** Handle to the ring-3 mapping of the I/O port statistics. */
648 RTR0MEMOBJ hIoPortStatsMapObj;
649#endif
650 /** @} */
651} IOMR0PERVM;
652
653
654RT_C_DECLS_BEGIN
655
656void iomMmioFreeRange(PVMCC pVM, PIOMMMIORANGE pRange);
657#ifdef IN_RING3
658PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc);
659#endif /* IN_RING3 */
660
661#ifndef IN_RING3
662DECLEXPORT(FNPGMRZPHYSPFHANDLER) iomMmioPfHandler;
663#endif
664PGM_ALL_CB2_PROTO(FNPGMPHYSHANDLER) iomMmioHandler;
665
666/* IOM locking helpers. */
667#ifdef IOM_WITH_CRIT_SECT_RW
668# define IOM_LOCK_EXCL(a_pVM) PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
669# define IOM_UNLOCK_EXCL(a_pVM) do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0)
670# if 0 /* (in case needed for debugging) */
671# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, (a_rcBusy))
672# define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0)
673# define IOM_IS_SHARED_LOCK_OWNER(a_pVM) PDMCritSectRwIsWriteOwner(&(a_pVM)->iom.s.CritSect)
674# else
675# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectRwEnterShared(&(a_pVM)->iom.s.CritSect, (a_rcBusy))
676# define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectRwLeaveShared(&(a_pVM)->iom.s.CritSect); } while (0)
677# define IOM_IS_SHARED_LOCK_OWNER(a_pVM) PDMCritSectRwIsReadOwner(&(a_pVM)->iom.s.CritSect, true)
678# endif
679# define IOM_IS_EXCL_LOCK_OWNER(a_pVM) PDMCritSectRwIsWriteOwner(&(a_pVM)->iom.s.CritSect)
680#else
681# define IOM_LOCK_EXCL(a_pVM) PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
682# define IOM_UNLOCK_EXCL(a_pVM) do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)
683# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, (a_rcBusy))
684# define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)
685# define IOM_IS_SHARED_LOCK_OWNER(a_pVM) PDMCritSectIsOwner(&(a_pVM)->iom.s.CritSect)
686# define IOM_IS_EXCL_LOCK_OWNER(a_pVM) PDMCritSectIsOwner(&(a_pVM)->iom.s.CritSect)
687#endif
688#define IOM_LOCK_SHARED(a_pVM) IOM_LOCK_SHARED_EX(a_pVM, VERR_SEM_BUSY)
689
690
691RT_C_DECLS_END
692
693
694#ifdef IN_RING3
695
696#endif
697
698/** @} */
699
700#endif /* !VMM_INCLUDED_SRC_include_IOMInternal_h */
701
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