VirtualBox

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

最後變更 在這個檔案從80641是 80641,由 vboxsync 提交於 6 年 前

IOM: New I/O port registration code. bugref:9218

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id Revision
檔案大小: 26.0 KB
 
1/* $Id: IOMInternal.h 80641 2019-09-06 20:09:16Z 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.alldomusa.eu.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(PFNIOMIOPORTOUT) pfnOutCallback;
170 /** Pointer to IN callback function. */
171 R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
172 /** Pointer to string OUT callback function. */
173 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
174 /** Pointer to string IN callback function. */
175 R0PTRTYPE(PFNIOMIOPORTINSTRING) 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} IOMIOPORTENTRYR0;
183/** Pointer to a ring-0 I/O port handle table entry. */
184typedef IOMIOPORTENTRYR0 *PIOMIOPORTENTRYR0;
185/** Pointer to a const ring-0 I/O port handle table entry. */
186typedef IOMIOPORTENTRYR0 const *PCIOMIOPORTENTRYR0;
187
188/**
189 * Ring-3 I/O port handle table entry.
190 */
191typedef struct IOMIOPORTENTRYR3
192{
193 /** Pointer to user argument. */
194 RTR3PTR pvUser;
195 /** Pointer to the associated device instance. */
196 R3PTRTYPE(PPDMDEVINS) pDevIns;
197 /** Pointer to OUT callback function. */
198 R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
199 /** Pointer to IN callback function. */
200 R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
201 /** Pointer to string OUT callback function. */
202 R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
203 /** Pointer to string IN callback function. */
204 R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
205 /** Description / Name. For easing debugging. */
206 R3PTRTYPE(const char *) pszDesc;
207 /** PCI device the registration is associated with. */
208 R3PTRTYPE(PPDMPCIDEV) pPciDev;
209 /** The PCI device region (high 16-bit word) and subregion (low word),
210 * UINT32_MAX if not applicable. */
211 uint32_t iPciRegion;
212 /** The number of ports covered by this entry. */
213 RTIOPORT cPorts;
214 /** The current port mapping (duplicates lookup table). */
215 RTIOPORT uPort;
216 /** The entry of the first statistics entry, UINT16_MAX if no stats. */
217 uint16_t idxStats;
218 /** Set if mapped, clear if not.
219 * Only updated when critsect is held exclusively. */
220 bool fMapped;
221 /** Same as the handle index. */
222 uint16_t idxSelf;
223} IOMIOPORTENTRYR3;
224/** Pointer to a ring-3 I/O port handle table entry. */
225typedef IOMIOPORTENTRYR3 *PIOMIOPORTENTRYR3;
226/** Pointer to a const ring-3 I/O port handle table entry. */
227typedef IOMIOPORTENTRYR3 const *PCIOMIOPORTENTRYR3;
228
229/**
230 * I/O port statistics entry (one I/O port).
231 */
232typedef struct IOMIOPORTSTATSENTRY
233{
234 /** Number of INs to this port from R3. */
235 STAMCOUNTER InR3;
236 /** Profiling IN handler overhead in R3. */
237 STAMPROFILE ProfInR3;
238 /** Number of OUTs to this port from R3. */
239 STAMCOUNTER OutR3;
240 /** Profiling OUT handler overhead in R3. */
241 STAMPROFILE ProfOutR3;
242
243 /** Number of INs to this port from R0/RC. */
244 STAMCOUNTER InRZ;
245 /** Profiling IN handler overhead in R0/RC. */
246 STAMPROFILE ProfInRZ;
247 /** Number of INs to this port from R0/RC which was serviced in R3. */
248 STAMCOUNTER InRZToR3;
249
250 /** Number of OUTs to this port from R0/RC. */
251 STAMCOUNTER OutRZ;
252 /** Profiling OUT handler overhead in R0/RC. */
253 STAMPROFILE ProfOutRZ;
254 /** Number of OUTs to this port from R0/RC which was serviced in R3. */
255 STAMCOUNTER OutRZToR3;
256} IOMIOPORTSTATSENTRY;
257/** Pointer to I/O port statistics entry. */
258typedef IOMIOPORTSTATSENTRY *PIOMIOPORTSTATSENTRY;
259
260
261/**
262 * I/O port range descriptor, R3 version.
263 */
264typedef struct IOMIOPORTRANGER3
265{
266 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
267 AVLROIOPORTNODECORE Core;
268#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
269 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
270#endif
271 /** Start I/O port address. */
272 RTIOPORT Port;
273 /** Size of the range. */
274 uint16_t cPorts;
275 /** Pointer to user argument. */
276 RTR3PTR pvUser;
277 /** Pointer to the associated device instance. */
278 R3PTRTYPE(PPDMDEVINS) pDevIns;
279 /** Pointer to OUT callback function. */
280 R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
281 /** Pointer to IN callback function. */
282 R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
283 /** Pointer to string OUT callback function. */
284 R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
285 /** Pointer to string IN callback function. */
286 R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
287 /** Description / Name. For easing debugging. */
288 R3PTRTYPE(const char *) pszDesc;
289} IOMIOPORTRANGER3;
290/** Pointer to I/O port range descriptor, R3 version. */
291typedef IOMIOPORTRANGER3 *PIOMIOPORTRANGER3;
292
293/**
294 * I/O port range descriptor, R0 version.
295 */
296typedef struct IOMIOPORTRANGER0
297{
298 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
299 AVLROIOPORTNODECORE Core;
300#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
301 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
302#endif
303 /** Start I/O port address. */
304 RTIOPORT Port;
305 /** Size of the range. */
306 uint16_t cPorts;
307 /** Pointer to user argument. */
308 RTR0PTR pvUser;
309 /** Pointer to the associated device instance. */
310 R0PTRTYPE(PPDMDEVINS) pDevIns;
311 /** Pointer to OUT callback function. */
312 R0PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
313 /** Pointer to IN callback function. */
314 R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
315 /** Pointer to string OUT callback function. */
316 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
317 /** Pointer to string IN callback function. */
318 R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
319 /** Description / Name. For easing debugging. */
320 R3PTRTYPE(const char *) pszDesc;
321} IOMIOPORTRANGER0;
322/** Pointer to I/O port range descriptor, R0 version. */
323typedef IOMIOPORTRANGER0 *PIOMIOPORTRANGER0;
324
325/**
326 * I/O port range descriptor, RC version.
327 */
328typedef struct IOMIOPORTRANGERC
329{
330 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
331 AVLROIOPORTNODECORE Core;
332 /** Start I/O port address. */
333 RTIOPORT Port;
334 /** Size of the range. */
335 uint16_t cPorts;
336 /** Pointer to user argument. */
337 RTRCPTR pvUser;
338 /** Pointer to the associated device instance. */
339 RCPTRTYPE(PPDMDEVINS) pDevIns;
340 /** Pointer to OUT callback function. */
341 RCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
342 /** Pointer to IN callback function. */
343 RCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
344 /** Pointer to string OUT callback function. */
345 RCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
346 /** Pointer to string IN callback function. */
347 RCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
348#if HC_ARCH_BITS == 64
349 RTRCPTR RCPtrAlignment; /**< pszDesc is 8 byte aligned. */
350#endif
351 /** Description / Name. For easing debugging. */
352 R3PTRTYPE(const char *) pszDesc;
353} IOMIOPORTRANGERC;
354/** Pointer to I/O port range descriptor, RC version. */
355typedef IOMIOPORTRANGERC *PIOMIOPORTRANGERC;
356
357
358/**
359 * I/O port statistics. (one I/O port)
360 *
361 * This is a simple way of making on demand statistics, however it's a
362 * bit free with the hypervisor heap memory.
363 */
364typedef struct IOMIOPORTSTATS
365{
366 /** Avl node core with the port as Key. */
367 AVLOIOPORTNODECORE Core;
368#if HC_ARCH_BITS != 64 || !defined(RT_OS_WINDOWS)
369 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
370#endif
371 /** Number of INs to this port from R3. */
372 STAMCOUNTER InR3;
373 /** Profiling IN handler overhead in R3. */
374 STAMPROFILE ProfInR3;
375 /** Number of OUTs to this port from R3. */
376 STAMCOUNTER OutR3;
377 /** Profiling OUT handler overhead in R3. */
378 STAMPROFILE ProfOutR3;
379
380 /** Number of INs to this port from R0/RC. */
381 STAMCOUNTER InRZ;
382 /** Profiling IN handler overhead in R0/RC. */
383 STAMPROFILE ProfInRZ;
384 /** Number of INs to this port from R0/RC which was serviced in R3. */
385 STAMCOUNTER InRZToR3;
386
387 /** Number of OUTs to this port from R0/RC. */
388 STAMCOUNTER OutRZ;
389 /** Profiling OUT handler overhead in R0/RC. */
390 STAMPROFILE ProfOutRZ;
391 /** Number of OUTs to this port from R0/RC which was serviced in R3. */
392 STAMCOUNTER OutRZToR3;
393} IOMIOPORTSTATS;
394AssertCompileMemberAlignment(IOMIOPORTSTATS, InR3, 8);
395/** Pointer to I/O port statistics. */
396typedef IOMIOPORTSTATS *PIOMIOPORTSTATS;
397
398
399/**
400 * The IOM trees.
401 *
402 * These are offset based the nodes and root must be in the same
403 * memory block in HC. The locations of IOM structure and the hypervisor heap
404 * are quite different in R3, R0 and RC.
405 */
406typedef struct IOMTREES
407{
408 /** Tree containing I/O port range descriptors registered for HC (IOMIOPORTRANGEHC). */
409 AVLROIOPORTTREE IOPortTreeR3;
410 /** Tree containing I/O port range descriptors registered for R0 (IOMIOPORTRANGER0). */
411 AVLROIOPORTTREE IOPortTreeR0;
412#if 0
413 /** Tree containing I/O port range descriptors registered for RC (IOMIOPORTRANGERC). */
414 AVLROIOPORTTREE IOPortTreeRC;
415#endif
416
417 /** Tree containing the MMIO range descriptors (IOMMMIORANGE). */
418 AVLROGCPHYSTREE MMIOTree;
419
420 /** Tree containing I/O port statistics (IOMIOPORTSTATS). */
421 AVLOIOPORTTREE IOPortStatTree;
422 /** Tree containing MMIO statistics (IOMMMIOSTATS). */
423 AVLOGCPHYSTREE MmioStatTree;
424} IOMTREES;
425/** Pointer to the IOM trees. */
426typedef IOMTREES *PIOMTREES;
427
428
429/**
430 * IOM per virtual CPU instance data.
431 */
432typedef struct IOMCPU
433{
434 /** For saving stack space, the disassembler state is allocated here instead of
435 * on the stack. */
436 DISCPUSTATE DisState;
437
438 /**
439 * Pending I/O port write commit (VINF_IOM_R3_IOPORT_COMMIT_WRITE).
440 *
441 * This is a converted VINF_IOM_R3_IOPORT_WRITE handler return that lets the
442 * execution engine commit the instruction and then return to ring-3 to complete
443 * the I/O port write there. This avoids having to decode the instruction again
444 * in ring-3.
445 */
446 struct
447 {
448 /** The value size (0 if not pending). */
449 uint16_t cbValue;
450 /** The I/O port. */
451 RTIOPORT IOPort;
452 /** The value. */
453 uint32_t u32Value;
454 } PendingIOPortWrite;
455
456 /**
457 * Pending MMIO write commit (VINF_IOM_R3_MMIO_COMMIT_WRITE).
458 *
459 * This is a converted VINF_IOM_R3_MMIO_WRITE handler return that lets the
460 * execution engine commit the instruction, stop any more REPs, and return to
461 * ring-3 to complete the MMIO write there. The avoid the tedious decoding of
462 * the instruction again once we're in ring-3, more importantly it allows us to
463 * correctly deal with read-modify-write instructions like XCHG, OR, and XOR.
464 */
465 struct
466 {
467 /** Guest physical MMIO address. */
468 RTGCPHYS GCPhys;
469 /** The value to write. */
470 uint8_t abValue[128];
471 /** The number of bytes to write (0 if nothing pending). */
472 uint32_t cbValue;
473 /** Alignment padding. */
474 uint32_t uAlignmentPadding;
475 } PendingMmioWrite;
476
477 /** @name Caching of I/O Port and MMIO ranges and statistics.
478 * (Saves quite some time in rep outs/ins instruction emulation.)
479 * @{ */
480 /** I/O port registration index for the last read operation. */
481 uint16_t idxIoPortLastRead;
482 /** I/O port registration index for the last write operation. */
483 uint16_t idxIoPortLastWrite;
484 /** I/O port registration index for the last read string operation. */
485 uint16_t idxIoPortLastReadStr;
486 /** I/O port registration index for the last write string operation. */
487 uint16_t idxIoPortLastWriteStr;
488 uint32_t u32Padding;
489
490 R3PTRTYPE(PIOMIOPORTRANGER3) pRangeLastReadR3;
491 R3PTRTYPE(PIOMIOPORTRANGER3) pRangeLastWriteR3;
492 R3PTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR3;
493 R3PTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR3;
494 R3PTRTYPE(PIOMMMIORANGE) pMMIORangeLastR3;
495 R3PTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastR3;
496
497 R0PTRTYPE(PIOMIOPORTRANGER0) pRangeLastReadR0;
498 R0PTRTYPE(PIOMIOPORTRANGER0) pRangeLastWriteR0;
499 R0PTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR0;
500 R0PTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR0;
501 R0PTRTYPE(PIOMMMIORANGE) pMMIORangeLastR0;
502 R0PTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastR0;
503 /** @} */
504} IOMCPU;
505/** Pointer to IOM per virtual CPU instance data. */
506typedef IOMCPU *PIOMCPU;
507
508
509/**
510 * IOM Data (part of VM)
511 */
512typedef struct IOM
513{
514 /** Pointer to the trees - R3 ptr. */
515 R3PTRTYPE(PIOMTREES) pTreesR3;
516 /** Pointer to the trees - R0 ptr. */
517 R0PTRTYPE(PIOMTREES) pTreesR0;
518
519 /** MMIO physical access handler type. */
520 PGMPHYSHANDLERTYPE hMmioHandlerType;
521 uint32_t u32Padding;
522
523 /** @name I/O ports
524 * @note The updating of these variables is done exclusively from EMT(0).
525 * @{ */
526 /** Number of I/O port registrations. */
527 uint32_t cIoPortRegs;
528 /** The size of the paIoPortsRegs allocation (in entries). */
529 uint32_t cIoPortAlloc;
530 /** I/O port registration table for ring-3.
531 * There is a parallel table in ring-0, IOMR0PERVM::paIoPortRegs. */
532 R3PTRTYPE(PIOMIOPORTENTRYR3) paIoPortRegs;
533 /** Number of entries in the lookup table. */
534 uint32_t cIoPortLookupEntries;
535 uint32_t u32Padding1;
536 /** I/O port lookup table. */
537 R3PTRTYPE(PIOMIOPORTLOOKUPENTRY) paIoPortLookup;
538
539 /** The number of valid entries in paioPortStats. */
540 uint32_t cIoPortStats;
541 /** The size of the paIoPortStats allocation (in entries). */
542 uint32_t cIoPortStatsAllocation;
543 /** I/O port lookup table. */
544 R3PTRTYPE(PIOMIOPORTSTATSENTRY) paIoPortStats;
545 /** Dummy stats entry so we don't need to check for NULL pointers so much. */
546 IOMIOPORTSTATSENTRY IoPortDummyStats;
547 /** @} */
548
549
550 /** Lock serializing EMT access to IOM. */
551#ifdef IOM_WITH_CRIT_SECT_RW
552 PDMCRITSECTRW CritSect;
553#else
554 PDMCRITSECT CritSect;
555#endif
556
557#if 0 /* unused */
558 /** @name I/O Port statistics.
559 * @{ */
560 STAMCOUNTER StatInstIn;
561 STAMCOUNTER StatInstOut;
562 STAMCOUNTER StatInstIns;
563 STAMCOUNTER StatInstOuts;
564 /** @} */
565#endif
566
567 /** @name MMIO statistics.
568 * @{ */
569 STAMPROFILE StatRZMMIOHandler;
570 STAMCOUNTER StatRZMMIOFailures;
571
572 STAMPROFILE StatRZInstMov;
573 STAMPROFILE StatRZInstCmp;
574 STAMPROFILE StatRZInstAnd;
575 STAMPROFILE StatRZInstOr;
576 STAMPROFILE StatRZInstXor;
577 STAMPROFILE StatRZInstBt;
578 STAMPROFILE StatRZInstTest;
579 STAMPROFILE StatRZInstXchg;
580 STAMPROFILE StatRZInstStos;
581 STAMPROFILE StatRZInstLods;
582#ifdef IOM_WITH_MOVS_SUPPORT
583 STAMPROFILEADV StatRZInstMovs;
584 STAMPROFILE StatRZInstMovsToMMIO;
585 STAMPROFILE StatRZInstMovsFromMMIO;
586 STAMPROFILE StatRZInstMovsMMIO;
587#endif
588 STAMCOUNTER StatRZInstOther;
589
590 STAMCOUNTER StatRZMMIO1Byte;
591 STAMCOUNTER StatRZMMIO2Bytes;
592 STAMCOUNTER StatRZMMIO4Bytes;
593 STAMCOUNTER StatRZMMIO8Bytes;
594
595 STAMCOUNTER StatR3MMIOHandler;
596
597 RTUINT cMovsMaxBytes;
598 RTUINT cStosMaxBytes;
599 /** @} */
600} IOM;
601/** Pointer to IOM instance data. */
602typedef IOM *PIOM;
603
604
605/**
606 * IOM data kept in the ring-0 GVM.
607 */
608typedef struct IOMR0PERVM
609{
610 /** @name I/O ports
611 * @{ */
612 /** The higest ring-0 I/O port registration plus one. */
613 uint32_t cIoPortMax;
614 /** The size of the paIoPortsRegs allocation (in entries). */
615 uint32_t cIoPortAlloc;
616 /** I/O port registration table for ring-0.
617 * There is a parallel table for ring-3, paIoPortRing3Regs. */
618 R0PTRTYPE(PIOMIOPORTENTRYR0) paIoPortRegs;
619 /** I/O port lookup table. */
620 R0PTRTYPE(PIOMIOPORTLOOKUPENTRY) paIoPortLookup;
621 /** I/O port registration table for ring-3.
622 * Also mapped to ring-3 as IOM::paIoPortRegs. */
623 R0PTRTYPE(PIOMIOPORTENTRYR3) paIoPortRing3Regs;
624 /** Handle to the allocation backing both the ring-0 and ring-3 registration
625 * tables as well as the lookup table. */
626 RTR0MEMOBJ hIoPortMemObj;
627 /** Handle to the ring-3 mapping of the lookup and ring-3 registration table. */
628 RTR0MEMOBJ hIoPortMapObj;
629#ifdef VBOX_WITH_STATISTICS
630 /** The size of the paIoPortStats allocation (in entries). */
631 uint32_t cIoPortStatsAllocation;
632 /** I/O port lookup table. */
633 R0PTRTYPE(PIOMIOPORTSTATSENTRY) paIoPortStats;
634 /** Handle to the allocation backing the I/O port statistics. */
635 RTR0MEMOBJ hIoPortStatsMemObj;
636 /** Handle to the ring-3 mapping of the I/O port statistics. */
637 RTR0MEMOBJ hIoPortStatsMapObj;
638#endif
639 /** @} */
640} IOMR0PERVM;
641
642
643RT_C_DECLS_BEGIN
644
645void iomMmioFreeRange(PVMCC pVM, PIOMMMIORANGE pRange);
646#ifdef IN_RING3
647PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc);
648#endif /* IN_RING3 */
649
650#ifndef IN_RING3
651DECLEXPORT(FNPGMRZPHYSPFHANDLER) iomMmioPfHandler;
652#endif
653PGM_ALL_CB2_PROTO(FNPGMPHYSHANDLER) iomMmioHandler;
654
655/* IOM locking helpers. */
656#ifdef IOM_WITH_CRIT_SECT_RW
657# define IOM_LOCK_EXCL(a_pVM) PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
658# define IOM_UNLOCK_EXCL(a_pVM) do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0)
659# if 0 /* (in case needed for debugging) */
660# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, (a_rcBusy))
661# define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0)
662# define IOM_IS_SHARED_LOCK_OWNER(a_pVM) PDMCritSectRwIsWriteOwner(&(a_pVM)->iom.s.CritSect)
663# else
664# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectRwEnterShared(&(a_pVM)->iom.s.CritSect, (a_rcBusy))
665# define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectRwLeaveShared(&(a_pVM)->iom.s.CritSect); } while (0)
666# define IOM_IS_SHARED_LOCK_OWNER(a_pVM) PDMCritSectRwIsReadOwner(&(a_pVM)->iom.s.CritSect, true)
667# endif
668# define IOM_IS_EXCL_LOCK_OWNER(a_pVM) PDMCritSectRwIsWriteOwner(&(a_pVM)->iom.s.CritSect)
669#else
670# define IOM_LOCK_EXCL(a_pVM) PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
671# define IOM_UNLOCK_EXCL(a_pVM) do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)
672# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy) PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, (a_rcBusy))
673# define IOM_UNLOCK_SHARED(a_pVM) do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)
674# define IOM_IS_SHARED_LOCK_OWNER(a_pVM) PDMCritSectIsOwner(&(a_pVM)->iom.s.CritSect)
675# define IOM_IS_EXCL_LOCK_OWNER(a_pVM) PDMCritSectIsOwner(&(a_pVM)->iom.s.CritSect)
676#endif
677#define IOM_LOCK_SHARED(a_pVM) IOM_LOCK_SHARED_EX(a_pVM, VERR_SEM_BUSY)
678
679
680RT_C_DECLS_END
681
682
683#ifdef IN_RING3
684
685#endif
686
687/** @} */
688
689#endif /* !VMM_INCLUDED_SRC_include_IOMInternal_h */
690
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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