VirtualBox

source: vbox/trunk/src/VBox/VMM/include/PDMInternal.h@ 93554

Last change on this file since 93554 was 93554, checked in by vboxsync, 3 years ago

VMM: Changed PAGE_SIZE -> GUEST_PAGE_SIZE / HOST_PAGE_SIZE, PAGE_SHIFT -> GUEST_PAGE_SHIFT / HOST_PAGE_SHIFT, and PAGE_OFFSET_MASK -> GUEST_PAGE_OFFSET_MASK / HOST_PAGE_OFFSET_MASK. Also removed most usage of ASMMemIsZeroPage and ASMMemZeroPage since the host and guest page size doesn't need to be the same any more. Some work left to do in the page pool code. bugref:9898

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 71.0 KB
Line 
1/* $Id: PDMInternal.h 93554 2022-02-02 22:57:02Z vboxsync $ */
2/** @file
3 * PDM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2022 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_PDMInternal_h
19#define VMM_INCLUDED_SRC_include_PDMInternal_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <VBox/types.h>
25#include <VBox/param.h>
26#include <VBox/vmm/cfgm.h>
27#include <VBox/vmm/stam.h>
28#include <VBox/vusb.h>
29#include <VBox/vmm/iom.h>
30#include <VBox/vmm/pdmasynccompletion.h>
31#ifdef VBOX_WITH_NETSHAPER
32# include <VBox/vmm/pdmnetshaper.h>
33#endif
34#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
35# include <VBox/vmm/pdmasynccompletion.h>
36#endif
37#include <VBox/vmm/pdmblkcache.h>
38#include <VBox/vmm/pdmcommon.h>
39#include <VBox/vmm/pdmtask.h>
40#include <VBox/sup.h>
41#include <VBox/msi.h>
42#include <iprt/assert.h>
43#include <iprt/critsect.h>
44#ifdef IN_RING3
45# include <iprt/thread.h>
46#endif
47
48RT_C_DECLS_BEGIN
49
50
51/** @defgroup grp_pdm_int Internal
52 * @ingroup grp_pdm
53 * @internal
54 * @{
55 */
56
57/** @def PDM_WITH_R3R0_CRIT_SECT
58 * Enables or disabled ring-3/ring-0 critical sections. */
59#if defined(DOXYGEN_RUNNING) || 1
60# define PDM_WITH_R3R0_CRIT_SECT
61#endif
62
63/** @def PDMCRITSECT_STRICT
64 * Enables/disables PDM critsect strictness like deadlock detection. */
65#if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(PDMCRITSECT_STRICT)) \
66 || defined(DOXYGEN_RUNNING)
67# define PDMCRITSECT_STRICT
68#endif
69
70/** @def PDMCRITSECT_STRICT
71 * Enables/disables PDM read/write critsect strictness like deadlock
72 * detection. */
73#if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(PDMCRITSECTRW_STRICT)) \
74 || defined(DOXYGEN_RUNNING)
75# define PDMCRITSECTRW_STRICT
76#endif
77
78/** The maximum device instance (total) size, ring-0/raw-mode capable devices. */
79#define PDM_MAX_DEVICE_INSTANCE_SIZE _4M
80/** The maximum device instance (total) size, ring-3 only devices. */
81#define PDM_MAX_DEVICE_INSTANCE_SIZE_R3 _8M
82/** The maximum size for the DBGF tracing tracking structure allocated for each device. */
83#define PDM_MAX_DEVICE_DBGF_TRACING_TRACK HOST_PAGE_SIZE
84
85
86
87/*******************************************************************************
88* Structures and Typedefs *
89*******************************************************************************/
90
91/** Pointer to a PDM Device. */
92typedef struct PDMDEV *PPDMDEV;
93/** Pointer to a pointer to a PDM Device. */
94typedef PPDMDEV *PPPDMDEV;
95
96/** Pointer to a PDM USB Device. */
97typedef struct PDMUSB *PPDMUSB;
98/** Pointer to a pointer to a PDM USB Device. */
99typedef PPDMUSB *PPPDMUSB;
100
101/** Pointer to a PDM Driver. */
102typedef struct PDMDRV *PPDMDRV;
103/** Pointer to a pointer to a PDM Driver. */
104typedef PPDMDRV *PPPDMDRV;
105
106/** Pointer to a PDM Logical Unit. */
107typedef struct PDMLUN *PPDMLUN;
108/** Pointer to a pointer to a PDM Logical Unit. */
109typedef PPDMLUN *PPPDMLUN;
110
111/** Pointer to a DMAC instance. */
112typedef struct PDMDMAC *PPDMDMAC;
113/** Pointer to a RTC instance. */
114typedef struct PDMRTC *PPDMRTC;
115
116/** Pointer to an USB HUB registration record. */
117typedef struct PDMUSBHUB *PPDMUSBHUB;
118
119/**
120 * Supported asynchronous completion endpoint classes.
121 */
122typedef enum PDMASYNCCOMPLETIONEPCLASSTYPE
123{
124 /** File class. */
125 PDMASYNCCOMPLETIONEPCLASSTYPE_FILE = 0,
126 /** Number of supported classes. */
127 PDMASYNCCOMPLETIONEPCLASSTYPE_MAX,
128 /** 32bit hack. */
129 PDMASYNCCOMPLETIONEPCLASSTYPE_32BIT_HACK = 0x7fffffff
130} PDMASYNCCOMPLETIONEPCLASSTYPE;
131
132
133/**
134 * MMIO/IO port registration tracking structure for DBGF tracing.
135 */
136typedef struct PDMDEVINSDBGFTRACK
137{
138 /** Flag whether this tracks a IO port or MMIO registration. */
139 bool fMmio;
140 /** Opaque user data passed during registration. */
141 void *pvUser;
142 /** Type dependent data. */
143 union
144 {
145 /** I/O port registration. */
146 struct
147 {
148 /** IOM I/O port handle. */
149 IOMIOPORTHANDLE hIoPorts;
150 /** Original OUT handler of the device. */
151 PFNIOMIOPORTNEWOUT pfnOut;
152 /** Original IN handler of the device. */
153 PFNIOMIOPORTNEWIN pfnIn;
154 /** Original string OUT handler of the device. */
155 PFNIOMIOPORTNEWOUTSTRING pfnOutStr;
156 /** Original string IN handler of the device. */
157 PFNIOMIOPORTNEWINSTRING pfnInStr;
158 } IoPort;
159 /** MMIO registration. */
160 struct
161 {
162 /** IOM MMIO region handle. */
163 IOMMMIOHANDLE hMmioRegion;
164 /** Original MMIO write handler of the device. */
165 PFNIOMMMIONEWWRITE pfnWrite;
166 /** Original MMIO read handler of the device. */
167 PFNIOMMMIONEWREAD pfnRead;
168 /** Original MMIO fill handler of the device. */
169 PFNIOMMMIONEWFILL pfnFill;
170 } Mmio;
171 } u;
172} PDMDEVINSDBGFTRACK;
173/** Pointer to a MMIO/IO port registration tracking structure. */
174typedef PDMDEVINSDBGFTRACK *PPDMDEVINSDBGFTRACK;
175/** Pointer to a const MMIO/IO port registration tracking structure. */
176typedef const PDMDEVINSDBGFTRACK *PCPDMDEVINSDBGFTRACK;
177
178
179/**
180 * Private device instance data, ring-3.
181 */
182typedef struct PDMDEVINSINTR3
183{
184 /** Pointer to the next instance.
185 * (Head is pointed to by PDM::pDevInstances.) */
186 R3PTRTYPE(PPDMDEVINS) pNextR3;
187 /** Pointer to the next per device instance.
188 * (Head is pointed to by PDMDEV::pInstances.) */
189 R3PTRTYPE(PPDMDEVINS) pPerDeviceNextR3;
190 /** Pointer to device structure. */
191 R3PTRTYPE(PPDMDEV) pDevR3;
192 /** Pointer to the list of logical units associated with the device. (FIFO) */
193 R3PTRTYPE(PPDMLUN) pLunsR3;
194 /** Pointer to the asynchronous notification callback set while in
195 * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */
196 R3PTRTYPE(PFNPDMDEVASYNCNOTIFY) pfnAsyncNotify;
197 /** Configuration handle to the instance node. */
198 R3PTRTYPE(PCFGMNODE) pCfgHandle;
199
200 /** R3 pointer to the VM this instance was created for. */
201 PVMR3 pVMR3;
202 /** DBGF trace event source handle if tracing is configured. */
203 DBGFTRACEREVTSRC hDbgfTraceEvtSrc;
204 /** Pointer to the base of the page containing the DBGF tracing tracking structures. */
205 PPDMDEVINSDBGFTRACK paDbgfTraceTrack;
206 /** Index of the next entry to use for tracking. */
207 uint32_t idxDbgfTraceTrackNext;
208 /** Maximum number of records fitting into the single page. */
209 uint32_t cDbgfTraceTrackMax;
210
211 /** Flags, see PDMDEVINSINT_FLAGS_XXX. */
212 uint32_t fIntFlags;
213 /** The last IRQ tag (for tracing it thru clearing). */
214 uint32_t uLastIrqTag;
215 /** The ring-0 device index (for making ring-0 calls). */
216 uint32_t idxR0Device;
217} PDMDEVINSINTR3;
218
219
220/**
221 * Private device instance data, ring-0.
222 */
223typedef struct PDMDEVINSINTR0
224{
225 /** Pointer to the VM this instance was created for. */
226 R0PTRTYPE(PGVM) pGVM;
227 /** Pointer to device structure. */
228 R0PTRTYPE(struct PDMDEVREGR0 const *) pRegR0;
229 /** The ring-0 module reference. */
230 RTR0PTR hMod;
231 /** Pointer to the ring-0 mapping of the ring-3 internal data (for uLastIrqTag). */
232 R0PTRTYPE(PDMDEVINSINTR3 *) pIntR3R0;
233 /** Pointer to the ring-0 mapping of the ring-3 instance (for idTracing). */
234 R0PTRTYPE(struct PDMDEVINSR3 *) pInsR3R0;
235 /** DBGF trace event source handle if tracing is configured. */
236 DBGFTRACEREVTSRC hDbgfTraceEvtSrc;
237 /** The device instance memory. */
238 RTR0MEMOBJ hMemObj;
239 /** The ring-3 mapping object. */
240 RTR0MEMOBJ hMapObj;
241 /** The page memory object for tracking MMIO and I/O port registrations when tracing is configured. */
242 RTR0MEMOBJ hDbgfTraceObj;
243 /** Pointer to the base of the page containing the DBGF tracing tracking structures. */
244 PPDMDEVINSDBGFTRACK paDbgfTraceTrack;
245 /** Index of the next entry to use for tracking. */
246 uint32_t idxDbgfTraceTrackNext;
247 /** Maximum number of records fitting into the single page. */
248 uint32_t cDbgfTraceTrackMax;
249 /** Index into PDMR0PERVM::apDevInstances. */
250 uint32_t idxR0Device;
251} PDMDEVINSINTR0;
252
253
254/**
255 * Private device instance data, raw-mode
256 */
257typedef struct PDMDEVINSINTRC
258{
259 /** Pointer to the VM this instance was created for. */
260 RGPTRTYPE(PVM) pVMRC;
261} PDMDEVINSINTRC;
262
263
264/**
265 * Private device instance data.
266 */
267typedef struct PDMDEVINSINT
268{
269 /** Pointer to the next instance (HC Ptr).
270 * (Head is pointed to by PDM::pDevInstances.) */
271 R3PTRTYPE(PPDMDEVINS) pNextR3;
272 /** Pointer to the next per device instance (HC Ptr).
273 * (Head is pointed to by PDMDEV::pInstances.) */
274 R3PTRTYPE(PPDMDEVINS) pPerDeviceNextR3;
275 /** Pointer to device structure - HC Ptr. */
276 R3PTRTYPE(PPDMDEV) pDevR3;
277 /** Pointer to the list of logical units associated with the device. (FIFO) */
278 R3PTRTYPE(PPDMLUN) pLunsR3;
279 /** Pointer to the asynchronous notification callback set while in
280 * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */
281 R3PTRTYPE(PFNPDMDEVASYNCNOTIFY) pfnAsyncNotify;
282 /** Configuration handle to the instance node. */
283 R3PTRTYPE(PCFGMNODE) pCfgHandle;
284
285 /** R3 pointer to the VM this instance was created for. */
286 PVMR3 pVMR3;
287
288 /** R0 pointer to the VM this instance was created for. */
289 R0PTRTYPE(PVMCC) pVMR0;
290
291 /** RC pointer to the VM this instance was created for. */
292 PVMRC pVMRC;
293
294 /** Flags, see PDMDEVINSINT_FLAGS_XXX. */
295 uint32_t fIntFlags;
296 /** The last IRQ tag (for tracing it thru clearing). */
297 uint32_t uLastIrqTag;
298} PDMDEVINSINT;
299
300/** @name PDMDEVINSINT::fIntFlags
301 * @{ */
302/** Used by pdmR3Load to mark device instances it found in the saved state. */
303#define PDMDEVINSINT_FLAGS_FOUND RT_BIT_32(0)
304/** Indicates that the device hasn't been powered on or resumed.
305 * This is used by PDMR3PowerOn, PDMR3Resume, PDMR3Suspend and PDMR3PowerOff
306 * to make sure each device gets exactly one notification for each of those
307 * events. PDMR3Resume and PDMR3PowerOn also makes use of it to bail out on
308 * a failure (already resumed/powered-on devices are suspended).
309 * PDMR3PowerOff resets this flag once before going through the devices to make sure
310 * every device gets the power off notification even if it was suspended before with
311 * PDMR3Suspend.
312 */
313#define PDMDEVINSINT_FLAGS_SUSPENDED RT_BIT_32(1)
314/** Indicates that the device has been reset already. Used by PDMR3Reset. */
315#define PDMDEVINSINT_FLAGS_RESET RT_BIT_32(2)
316#define PDMDEVINSINT_FLAGS_R0_ENABLED RT_BIT_32(3)
317#define PDMDEVINSINT_FLAGS_RC_ENABLED RT_BIT_32(4)
318/** Set if we've called the ring-0 constructor. */
319#define PDMDEVINSINT_FLAGS_R0_CONTRUCT RT_BIT_32(5)
320/** Set if using non-default critical section. */
321#define PDMDEVINSINT_FLAGS_CHANGED_CRITSECT RT_BIT_32(6)
322/** @} */
323
324
325/**
326 * Private USB device instance data.
327 */
328typedef struct PDMUSBINSINT
329{
330 /** The UUID of this instance. */
331 RTUUID Uuid;
332 /** Pointer to the next instance.
333 * (Head is pointed to by PDM::pUsbInstances.) */
334 R3PTRTYPE(PPDMUSBINS) pNext;
335 /** Pointer to the next per USB device instance.
336 * (Head is pointed to by PDMUSB::pInstances.) */
337 R3PTRTYPE(PPDMUSBINS) pPerDeviceNext;
338
339 /** Pointer to device structure. */
340 R3PTRTYPE(PPDMUSB) pUsbDev;
341
342 /** Pointer to the VM this instance was created for. */
343 PVMR3 pVM;
344 /** Pointer to the list of logical units associated with the device. (FIFO) */
345 R3PTRTYPE(PPDMLUN) pLuns;
346 /** The per instance device configuration. */
347 R3PTRTYPE(PCFGMNODE) pCfg;
348 /** Same as pCfg if the configuration should be deleted when detaching the device. */
349 R3PTRTYPE(PCFGMNODE) pCfgDelete;
350 /** The global device configuration. */
351 R3PTRTYPE(PCFGMNODE) pCfgGlobal;
352
353 /** Pointer to the USB hub this device is attached to.
354 * This is NULL if the device isn't connected to any HUB. */
355 R3PTRTYPE(PPDMUSBHUB) pHub;
356 /** The port number that we're connected to. */
357 uint32_t iPort;
358 /** Indicates that the USB device hasn't been powered on or resumed.
359 * See PDMDEVINSINT_FLAGS_SUSPENDED. */
360 bool fVMSuspended;
361 /** Indicates that the USB device has been reset. */
362 bool fVMReset;
363 /** Pointer to the asynchronous notification callback set while in
364 * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */
365 R3PTRTYPE(PFNPDMUSBASYNCNOTIFY) pfnAsyncNotify;
366} PDMUSBINSINT;
367
368
369/**
370 * Private driver instance data.
371 */
372typedef struct PDMDRVINSINT
373{
374 /** Pointer to the driver instance above.
375 * This is NULL for the topmost drive. */
376 R3PTRTYPE(PPDMDRVINS) pUp;
377 /** Pointer to the driver instance below.
378 * This is NULL for the bottommost driver. */
379 R3PTRTYPE(PPDMDRVINS) pDown;
380 /** Pointer to the logical unit this driver chained on. */
381 R3PTRTYPE(PPDMLUN) pLun;
382 /** Pointer to driver structure from which this was instantiated. */
383 R3PTRTYPE(PPDMDRV) pDrv;
384 /** Pointer to the VM this instance was created for, ring-3 context. */
385 PVMR3 pVMR3;
386 /** Pointer to the VM this instance was created for, ring-0 context. */
387 R0PTRTYPE(PVMCC) pVMR0;
388 /** Pointer to the VM this instance was created for, raw-mode context. */
389 PVMRC pVMRC;
390 /** Flag indicating that the driver is being detached and destroyed.
391 * (Helps detect potential recursive detaching.) */
392 bool fDetaching;
393 /** Indicates that the driver hasn't been powered on or resumed.
394 * See PDMDEVINSINT_FLAGS_SUSPENDED. */
395 bool fVMSuspended;
396 /** Indicates that the driver has been reset already. */
397 bool fVMReset;
398 /** Set if allocated on the hyper heap, false if on the ring-3 heap. */
399 bool fHyperHeap;
400 /** Pointer to the asynchronous notification callback set while in
401 * PDMUSBREG::pfnVMSuspend or PDMUSBREG::pfnVMPowerOff. */
402 R3PTRTYPE(PFNPDMDRVASYNCNOTIFY) pfnAsyncNotify;
403 /** Configuration handle to the instance node. */
404 R3PTRTYPE(PCFGMNODE) pCfgHandle;
405 /** Pointer to the ring-0 request handler function. */
406 PFNPDMDRVREQHANDLERR0 pfnReqHandlerR0;
407} PDMDRVINSINT;
408
409
410/**
411 * Private critical section data.
412 */
413typedef struct PDMCRITSECTINT
414{
415 /** The critical section core which is shared with IPRT.
416 * @note The semaphore is a SUPSEMEVENT. */
417 RTCRITSECT Core;
418 /** Pointer to the next critical section.
419 * This chain is used for device cleanup and the dbgf info item. */
420 R3PTRTYPE(struct PDMCRITSECTINT *) pNext;
421 /** Owner identifier.
422 * This is pDevIns if the owner is a device. Similarly for a driver or service.
423 * PDMR3CritSectInit() sets this to point to the critsect itself. */
424 RTR3PTR pvKey;
425 /** Set if this critical section is the automatically created default
426 * section of a device. */
427 bool fAutomaticDefaultCritsect;
428 /** Set if the critical section is used by a timer or similar.
429 * See PDMR3DevGetCritSect. */
430 bool fUsedByTimerOrSimilar;
431 /** Alignment padding. */
432 bool afPadding[2+4];
433 /** Support driver event semaphore that is scheduled to be signaled upon leaving
434 * the critical section. This is only for Ring-3 and Ring-0. */
435 SUPSEMEVENT volatile hEventToSignal;
436 /** The lock name. */
437 R3PTRTYPE(const char *) pszName;
438 /** The ring-3 pointer to this critical section, for leave queueing. */
439 R3PTRTYPE(PPDMCRITSECT) pSelfR3;
440 /** R0/RC lock contention. */
441 STAMCOUNTER StatContentionRZLock;
442 /** R0/RC lock contention: returning rcBusy or VERR_SEM_BUSY (try). */
443 STAMCOUNTER StatContentionRZLockBusy;
444 /** R0/RC lock contention: Profiling waiting time. */
445 STAMPROFILE StatContentionRZWait;
446 /** R0/RC unlock contention. */
447 STAMCOUNTER StatContentionRZUnlock;
448 /** R3 lock contention. */
449 STAMCOUNTER StatContentionR3;
450 /** R3 lock contention: Profiling waiting time. */
451 STAMPROFILE StatContentionR3Wait;
452 /** Profiling the time the section is locked. */
453 STAMPROFILEADV StatLocked;
454} PDMCRITSECTINT;
455AssertCompileMemberAlignment(PDMCRITSECTINT, StatContentionRZLock, 8);
456/** Pointer to private critical section data. */
457typedef PDMCRITSECTINT *PPDMCRITSECTINT;
458
459/** Special magic value set when we failed to abort entering in ring-0 due to a
460 * timeout, interruption or pending thread termination. */
461#define PDMCRITSECT_MAGIC_FAILED_ABORT UINT32_C(0x0bad0326)
462/** Special magic value set if we detected data/state corruption. */
463#define PDMCRITSECT_MAGIC_CORRUPTED UINT32_C(0x0bad2603)
464
465/** Indicates that the critical section is queued for unlock.
466 * PDMCritSectIsOwner and PDMCritSectIsOwned optimizations. */
467#define PDMCRITSECT_FLAGS_PENDING_UNLOCK RT_BIT_32(17)
468
469
470/**
471 * Private critical section data.
472 */
473typedef struct PDMCRITSECTRWINT
474{
475 /** The read/write critical section core which is shared with IPRT.
476 * @note The semaphores are SUPSEMEVENT and SUPSEMEVENTMULTI. */
477 RTCRITSECTRW Core;
478
479 /** Pointer to the next critical section.
480 * This chain is used for device cleanup and the dbgf info item. */
481 R3PTRTYPE(struct PDMCRITSECTRWINT *) pNext;
482 /** Self pointer. */
483 R3PTRTYPE(PPDMCRITSECTRW) pSelfR3;
484 /** Owner identifier.
485 * This is pDevIns if the owner is a device. Similarly for a driver or service.
486 * PDMR3CritSectRwInit() sets this to point to the critsect itself. */
487 RTR3PTR pvKey;
488 /** The lock name. */
489 R3PTRTYPE(const char *) pszName;
490
491 /** R0/RC write lock contention. */
492 STAMCOUNTER StatContentionRZEnterExcl;
493 /** R0/RC write unlock contention. */
494 STAMCOUNTER StatContentionRZLeaveExcl;
495 /** R0/RC read lock contention. */
496 STAMCOUNTER StatContentionRZEnterShared;
497 /** R0/RC read unlock contention. */
498 STAMCOUNTER StatContentionRZLeaveShared;
499 /** R0/RC writes. */
500 STAMCOUNTER StatRZEnterExcl;
501 /** R0/RC reads. */
502 STAMCOUNTER StatRZEnterShared;
503 /** R3 write lock contention. */
504 STAMCOUNTER StatContentionR3EnterExcl;
505 /** R3 write unlock contention. */
506 STAMCOUNTER StatContentionR3LeaveExcl;
507 /** R3 read lock contention. */
508 STAMCOUNTER StatContentionR3EnterShared;
509 /** R3 writes. */
510 STAMCOUNTER StatR3EnterExcl;
511 /** R3 reads. */
512 STAMCOUNTER StatR3EnterShared;
513 /** Profiling the time the section is write locked. */
514 STAMPROFILEADV StatWriteLocked;
515} PDMCRITSECTRWINT;
516AssertCompileMemberAlignment(PDMCRITSECTRWINT, StatContentionRZEnterExcl, 8);
517AssertCompileMemberAlignment(PDMCRITSECTRWINT, Core.u, 16);
518AssertCompileMemberAlignment(PDMCRITSECTRWINT, Core.u.s.u64State, 8);
519/** Pointer to private critical section data. */
520typedef PDMCRITSECTRWINT *PPDMCRITSECTRWINT;
521
522/** Special magic value we set the structure has become corrupted. */
523#define PDMCRITSECTRW_MAGIC_CORRUPT UINT32_C(0x0bad0620)
524
525
526/**
527 * The usual device/driver/internal/external stuff.
528 */
529typedef enum
530{
531 /** The usual invalid entry. */
532 PDMTHREADTYPE_INVALID = 0,
533 /** Device type. */
534 PDMTHREADTYPE_DEVICE,
535 /** USB Device type. */
536 PDMTHREADTYPE_USB,
537 /** Driver type. */
538 PDMTHREADTYPE_DRIVER,
539 /** Internal type. */
540 PDMTHREADTYPE_INTERNAL,
541 /** External type. */
542 PDMTHREADTYPE_EXTERNAL,
543 /** The usual 32-bit hack. */
544 PDMTHREADTYPE_32BIT_HACK = 0x7fffffff
545} PDMTHREADTYPE;
546
547
548/**
549 * The internal structure for the thread.
550 */
551typedef struct PDMTHREADINT
552{
553 /** The VM pointer. */
554 PVMR3 pVM;
555 /** The event semaphore the thread blocks on when not running. */
556 RTSEMEVENTMULTI BlockEvent;
557 /** The event semaphore the thread sleeps on while running. */
558 RTSEMEVENTMULTI SleepEvent;
559 /** Pointer to the next thread. */
560 R3PTRTYPE(struct PDMTHREAD *) pNext;
561 /** The thread type. */
562 PDMTHREADTYPE enmType;
563} PDMTHREADINT;
564
565
566
567/* Must be included after PDMDEVINSINT is defined. */
568#define PDMDEVINSINT_DECLARED
569#define PDMUSBINSINT_DECLARED
570#define PDMDRVINSINT_DECLARED
571#define PDMCRITSECTINT_DECLARED
572#define PDMCRITSECTRWINT_DECLARED
573#define PDMTHREADINT_DECLARED
574#ifdef ___VBox_pdm_h
575# error "Invalid header PDM order. Include PDMInternal.h before VBox/vmm/pdm.h!"
576#endif
577RT_C_DECLS_END
578#include <VBox/vmm/pdm.h>
579RT_C_DECLS_BEGIN
580
581/**
582 * PDM Logical Unit.
583 *
584 * This typically the representation of a physical port on a
585 * device, like for instance the PS/2 keyboard port on the
586 * keyboard controller device. The LUNs are chained on the
587 * device they belong to (PDMDEVINSINT::pLunsR3).
588 */
589typedef struct PDMLUN
590{
591 /** The LUN - The Logical Unit Number. */
592 RTUINT iLun;
593 /** Pointer to the next LUN. */
594 PPDMLUN pNext;
595 /** Pointer to the top driver in the driver chain. */
596 PPDMDRVINS pTop;
597 /** Pointer to the bottom driver in the driver chain. */
598 PPDMDRVINS pBottom;
599 /** Pointer to the device instance which the LUN belongs to.
600 * Either this is set or pUsbIns is set. Both is never set at the same time. */
601 PPDMDEVINS pDevIns;
602 /** Pointer to the USB device instance which the LUN belongs to. */
603 PPDMUSBINS pUsbIns;
604 /** Pointer to the device base interface. */
605 PPDMIBASE pBase;
606 /** Description of this LUN. */
607 const char *pszDesc;
608} PDMLUN;
609
610
611/**
612 * PDM Device, ring-3.
613 */
614typedef struct PDMDEV
615{
616 /** Pointer to the next device (R3 Ptr). */
617 R3PTRTYPE(PPDMDEV) pNext;
618 /** Device name length. (search optimization) */
619 uint32_t cchName;
620 /** Registration structure. */
621 R3PTRTYPE(const struct PDMDEVREGR3 *) pReg;
622 /** Number of instances. */
623 uint32_t cInstances;
624 /** Pointer to chain of instances (R3 Ptr). */
625 PPDMDEVINSR3 pInstances;
626 /** The search path for raw-mode context modules (';' as separator). */
627 char *pszRCSearchPath;
628 /** The search path for ring-0 context modules (';' as separator). */
629 char *pszR0SearchPath;
630} PDMDEV;
631
632
633#if 0
634/**
635 * PDM Device, ring-0.
636 */
637typedef struct PDMDEVR0
638{
639 /** Pointer to the next device. */
640 R0PTRTYPE(PPDMDEVR0) pNext;
641 /** Device name length. (search optimization) */
642 uint32_t cchName;
643 /** Registration structure. */
644 R3PTRTYPE(const struct PDMDEVREGR0 *) pReg;
645 /** Number of instances. */
646 uint32_t cInstances;
647 /** Pointer to chain of instances. */
648 PPDMDEVINSR0 pInstances;
649} PDMDEVR0;
650#endif
651
652
653/**
654 * PDM USB Device.
655 */
656typedef struct PDMUSB
657{
658 /** Pointer to the next device (R3 Ptr). */
659 R3PTRTYPE(PPDMUSB) pNext;
660 /** Device name length. (search optimization) */
661 RTUINT cchName;
662 /** Registration structure. */
663 R3PTRTYPE(const struct PDMUSBREG *) pReg;
664 /** Next instance number. */
665 uint32_t iNextInstance;
666 /** Pointer to chain of instances (R3 Ptr). */
667 R3PTRTYPE(PPDMUSBINS) pInstances;
668} PDMUSB;
669
670
671/**
672 * PDM Driver.
673 */
674typedef struct PDMDRV
675{
676 /** Pointer to the next device. */
677 PPDMDRV pNext;
678 /** Registration structure. */
679 const struct PDMDRVREG * pReg;
680 /** Current number of instances. */
681 uint32_t cInstances;
682 /** The next instance number. */
683 uint32_t iNextInstance;
684 /** The search path for raw-mode context modules (';' as separator). */
685 char *pszRCSearchPath;
686 /** The search path for ring-0 context modules (';' as separator). */
687 char *pszR0SearchPath;
688} PDMDRV;
689
690
691/**
692 * PDM IOMMU, shared ring-3.
693 */
694typedef struct PDMIOMMUR3
695{
696 /** IOMMU index. */
697 uint32_t idxIommu;
698 uint32_t uPadding0; /**< Alignment padding.*/
699
700 /** Pointer to the IOMMU device instance - R3. */
701 PPDMDEVINSR3 pDevInsR3;
702 /** @copydoc PDMIOMMUREGR3::pfnMemAccess */
703 DECLR3CALLBACKMEMBER(int, pfnMemAccess,(PPDMDEVINS pDevIns, uint16_t idDevice, uint64_t uIova, size_t cbIova,
704 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContig));
705 /** @copydoc PDMIOMMUREGR3::pfnMemBulkAccess */
706 DECLR3CALLBACKMEMBER(int, pfnMemBulkAccess,(PPDMDEVINS pDevIns, uint16_t idDevice, size_t cIovas, uint64_t const *pauIovas,
707 uint32_t fFlags, PRTGCPHYS paGCPhysSpa));
708 /** @copydoc PDMIOMMUREGR3::pfnMsiRemap */
709 DECLR3CALLBACKMEMBER(int, pfnMsiRemap,(PPDMDEVINS pDevIns, uint16_t idDevice, PCMSIMSG pMsiIn, PMSIMSG pMsiOut));
710} PDMIOMMUR3;
711/** Pointer to a PDM IOMMU instance. */
712typedef PDMIOMMUR3 *PPDMIOMMUR3;
713/** Pointer to a const PDM IOMMU instance. */
714typedef const PDMIOMMUR3 *PCPDMIOMMUR3;
715
716
717/**
718 * PDM IOMMU, ring-0.
719 */
720typedef struct PDMIOMMUR0
721{
722 /** IOMMU index. */
723 uint32_t idxIommu;
724 uint32_t uPadding0; /**< Alignment padding.*/
725
726 /** Pointer to IOMMU device instance. */
727 PPDMDEVINSR0 pDevInsR0;
728 /** @copydoc PDMIOMMUREGR3::pfnMemAccess */
729 DECLR0CALLBACKMEMBER(int, pfnMemAccess,(PPDMDEVINS pDevIns, uint16_t idDevice, uint64_t uIova, size_t cbIova,
730 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContig));
731 /** @copydoc PDMIOMMUREGR3::pfnMemBulkAccess */
732 DECLR0CALLBACKMEMBER(int, pfnMemBulkAccess,(PPDMDEVINS pDevIns, uint16_t idDevice, size_t cIovas, uint64_t const *pauIovas,
733 uint32_t fFlags, PRTGCPHYS paGCPhysSpa));
734 /** @copydoc PDMIOMMUREGR3::pfnMsiRemap */
735 DECLR0CALLBACKMEMBER(int, pfnMsiRemap,(PPDMDEVINS pDevIns, uint16_t idDevice, PCMSIMSG pMsiIn, PMSIMSG pMsiOut));
736} PDMIOMMUR0;
737/** Pointer to a ring-0 IOMMU data. */
738typedef PDMIOMMUR0 *PPDMIOMMUR0;
739/** Pointer to a const ring-0 IOMMU data. */
740typedef const PDMIOMMUR0 *PCPDMIOMMUR0;
741
742/** Pointer to a PDM IOMMU for the current context. */
743#ifdef IN_RING3
744typedef PPDMIOMMUR3 PPDMIOMMU;
745#else
746typedef PPDMIOMMUR0 PPDMIOMMU;
747#endif
748
749
750/**
751 * PDM registered PIC device.
752 */
753typedef struct PDMPIC
754{
755 /** Pointer to the PIC device instance - R3. */
756 PPDMDEVINSR3 pDevInsR3;
757 /** @copydoc PDMPICREG::pfnSetIrq */
758 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
759 /** @copydoc PDMPICREG::pfnGetInterrupt */
760 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
761
762 /** Pointer to the PIC device instance - R0. */
763 PPDMDEVINSR0 pDevInsR0;
764 /** @copydoc PDMPICREG::pfnSetIrq */
765 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
766 /** @copydoc PDMPICREG::pfnGetInterrupt */
767 DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
768
769 /** Pointer to the PIC device instance - RC. */
770 PPDMDEVINSRC pDevInsRC;
771 /** @copydoc PDMPICREG::pfnSetIrq */
772 DECLRCCALLBACKMEMBER(void, pfnSetIrqRC,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
773 /** @copydoc PDMPICREG::pfnGetInterrupt */
774 DECLRCCALLBACKMEMBER(int, pfnGetInterruptRC,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
775 /** Alignment padding. */
776 RTRCPTR RCPtrPadding;
777} PDMPIC;
778
779
780/**
781 * PDM registered APIC device.
782 */
783typedef struct PDMAPIC
784{
785 /** Pointer to the APIC device instance - R3 Ptr. */
786 PPDMDEVINSR3 pDevInsR3;
787 /** Pointer to the APIC device instance - R0 Ptr. */
788 PPDMDEVINSR0 pDevInsR0;
789 /** Pointer to the APIC device instance - RC Ptr. */
790 PPDMDEVINSRC pDevInsRC;
791 uint8_t Alignment[4];
792} PDMAPIC;
793
794
795/**
796 * PDM registered I/O APIC device.
797 */
798typedef struct PDMIOAPIC
799{
800 /** Pointer to the I/O APIC device instance - R3 Ptr. */
801 PPDMDEVINSR3 pDevInsR3;
802 /** @copydoc PDMIOAPICREG::pfnSetIrq */
803 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, int iIrq, int iLevel, uint32_t uTagSrc));
804 /** @copydoc PDMIOAPICREG::pfnSendMsi */
805 DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc));
806 /** @copydoc PDMIOAPICREG::pfnSetEoi */
807 DECLR3CALLBACKMEMBER(void, pfnSetEoiR3,(PPDMDEVINS pDevIns, uint8_t u8Vector));
808
809 /** Pointer to the I/O APIC device instance - R0. */
810 PPDMDEVINSR0 pDevInsR0;
811 /** @copydoc PDMIOAPICREG::pfnSetIrq */
812 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, int iIrq, int iLevel, uint32_t uTagSrc));
813 /** @copydoc PDMIOAPICREG::pfnSendMsi */
814 DECLR0CALLBACKMEMBER(void, pfnSendMsiR0,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc));
815 /** @copydoc PDMIOAPICREG::pfnSetEoi */
816 DECLR0CALLBACKMEMBER(void, pfnSetEoiR0,(PPDMDEVINS pDevIns, uint8_t u8Vector));
817
818 /** Pointer to the I/O APIC device instance - RC Ptr. */
819 PPDMDEVINSRC pDevInsRC;
820 /** @copydoc PDMIOAPICREG::pfnSetIrq */
821 DECLRCCALLBACKMEMBER(void, pfnSetIrqRC,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, int iIrq, int iLevel, uint32_t uTagSrc));
822 /** @copydoc PDMIOAPICREG::pfnSendMsi */
823 DECLRCCALLBACKMEMBER(void, pfnSendMsiRC,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc));
824 /** @copydoc PDMIOAPICREG::pfnSendMsi */
825 DECLRCCALLBACKMEMBER(void, pfnSetEoiRC,(PPDMDEVINS pDevIns, uint8_t u8Vector));
826} PDMIOAPIC;
827/** Pointer to a PDM IOAPIC instance. */
828typedef PDMIOAPIC *PPDMIOAPIC;
829/** Pointer to a const PDM IOAPIC instance. */
830typedef PDMIOAPIC const *PCPDMIOAPIC;
831
832/** Maximum number of PCI busses for a VM. */
833#define PDM_PCI_BUSSES_MAX 8
834/** Maximum number of IOMMUs (at most one per PCI bus). */
835#define PDM_IOMMUS_MAX PDM_PCI_BUSSES_MAX
836
837
838#ifdef IN_RING3
839/**
840 * PDM registered firmware device.
841 */
842typedef struct PDMFW
843{
844 /** Pointer to the firmware device instance. */
845 PPDMDEVINSR3 pDevIns;
846 /** Copy of the registration structure. */
847 PDMFWREG Reg;
848} PDMFW;
849/** Pointer to a firmware instance. */
850typedef PDMFW *PPDMFW;
851#endif
852
853
854/**
855 * PDM PCI bus instance.
856 */
857typedef struct PDMPCIBUS
858{
859 /** PCI bus number. */
860 uint32_t iBus;
861 uint32_t uPadding0; /**< Alignment padding.*/
862
863 /** Pointer to PCI bus device instance. */
864 PPDMDEVINSR3 pDevInsR3;
865 /** @copydoc PDMPCIBUSREGR3::pfnSetIrqR3 */
866 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
867
868 /** @copydoc PDMPCIBUSREGR3::pfnRegisterR3 */
869 DECLR3CALLBACKMEMBER(int, pfnRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
870 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName));
871 /** @copydoc PDMPCIBUSREGR3::pfnRegisterMsiR3 */
872 DECLR3CALLBACKMEMBER(int, pfnRegisterMsi,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg));
873 /** @copydoc PDMPCIBUSREGR3::pfnIORegionRegisterR3 */
874 DECLR3CALLBACKMEMBER(int, pfnIORegionRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
875 RTGCPHYS cbRegion, PCIADDRESSSPACE enmType, uint32_t fFlags,
876 uint64_t hHandle, PFNPCIIOREGIONMAP pfnCallback));
877 /** @copydoc PDMPCIBUSREGR3::pfnInterceptConfigAccesses */
878 DECLR3CALLBACKMEMBER(void, pfnInterceptConfigAccesses,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
879 PFNPCICONFIGREAD pfnRead, PFNPCICONFIGWRITE pfnWrite));
880 /** @copydoc PDMPCIBUSREGR3::pfnConfigWrite */
881 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnConfigWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
882 uint32_t uAddress, unsigned cb, uint32_t u32Value));
883 /** @copydoc PDMPCIBUSREGR3::pfnConfigRead */
884 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnConfigRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
885 uint32_t uAddress, unsigned cb, uint32_t *pu32Value));
886} PDMPCIBUS;
887/** Pointer to a PDM PCI Bus instance. */
888typedef PDMPCIBUS *PPDMPCIBUS;
889/** Pointer to a const PDM PCI Bus instance. */
890typedef const PDMPCIBUS *PCPDMPCIBUS;
891
892
893/**
894 * Ring-0 PDM PCI bus instance data.
895 */
896typedef struct PDMPCIBUSR0
897{
898 /** PCI bus number. */
899 uint32_t iBus;
900 uint32_t uPadding0; /**< Alignment padding.*/
901 /** Pointer to PCI bus device instance. */
902 PPDMDEVINSR0 pDevInsR0;
903 /** @copydoc PDMPCIBUSREGR0::pfnSetIrq */
904 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
905} PDMPCIBUSR0;
906/** Pointer to the ring-0 PCI bus data. */
907typedef PDMPCIBUSR0 *PPDMPCIBUSR0;
908/** Pointer to the const ring-0 PCI bus data. */
909typedef const PDMPCIBUSR0 *PCPDMPCIBUSR0;
910
911
912#ifdef IN_RING3
913/**
914 * PDM registered DMAC (DMA Controller) device.
915 */
916typedef struct PDMDMAC
917{
918 /** Pointer to the DMAC device instance. */
919 PPDMDEVINSR3 pDevIns;
920 /** Copy of the registration structure. */
921 PDMDMACREG Reg;
922} PDMDMAC;
923
924
925/**
926 * PDM registered RTC (Real Time Clock) device.
927 */
928typedef struct PDMRTC
929{
930 /** Pointer to the RTC device instance. */
931 PPDMDEVINSR3 pDevIns;
932 /** Copy of the registration structure. */
933 PDMRTCREG Reg;
934} PDMRTC;
935
936#endif /* IN_RING3 */
937
938/**
939 * Module type.
940 */
941typedef enum PDMMODTYPE
942{
943 /** Raw-mode (RC) context module. */
944 PDMMOD_TYPE_RC,
945 /** Ring-0 (host) context module. */
946 PDMMOD_TYPE_R0,
947 /** Ring-3 (host) context module. */
948 PDMMOD_TYPE_R3
949} PDMMODTYPE;
950
951
952/** The module name length including the terminator. */
953#define PDMMOD_NAME_LEN 32
954
955/**
956 * Loaded module instance.
957 */
958typedef struct PDMMOD
959{
960 /** Module name. This is used for referring to
961 * the module internally, sort of like a handle. */
962 char szName[PDMMOD_NAME_LEN];
963 /** Module type. */
964 PDMMODTYPE eType;
965 /** Loader module handle. Not used for R0 modules. */
966 RTLDRMOD hLdrMod;
967 /** Loaded address.
968 * This is the 'handle' for R0 modules. */
969 RTUINTPTR ImageBase;
970 /** Old loaded address.
971 * This is used during relocation of GC modules. Not used for R0 modules. */
972 RTUINTPTR OldImageBase;
973 /** Where the R3 HC bits are stored.
974 * This can be equal to ImageBase but doesn't have to. Not used for R0 modules. */
975 void *pvBits;
976
977 /** Pointer to next module. */
978 struct PDMMOD *pNext;
979 /** Module filename. */
980 char szFilename[1];
981} PDMMOD;
982/** Pointer to loaded module instance. */
983typedef PDMMOD *PPDMMOD;
984
985
986
987/** Extra space in the free array. */
988#define PDMQUEUE_FREE_SLACK 16
989
990/**
991 * Queue type.
992 */
993typedef enum PDMQUEUETYPE
994{
995 /** Device consumer. */
996 PDMQUEUETYPE_DEV = 1,
997 /** Driver consumer. */
998 PDMQUEUETYPE_DRV,
999 /** Internal consumer. */
1000 PDMQUEUETYPE_INTERNAL,
1001 /** External consumer. */
1002 PDMQUEUETYPE_EXTERNAL
1003} PDMQUEUETYPE;
1004
1005/** Pointer to a PDM Queue. */
1006typedef struct PDMQUEUE *PPDMQUEUE;
1007
1008/**
1009 * PDM Queue.
1010 */
1011typedef struct PDMQUEUE
1012{
1013 /** Pointer to the next queue in the list. */
1014 R3PTRTYPE(PPDMQUEUE) pNext;
1015 /** Type specific data. */
1016 union
1017 {
1018 /** PDMQUEUETYPE_DEV */
1019 struct
1020 {
1021 /** Pointer to consumer function. */
1022 R3PTRTYPE(PFNPDMQUEUEDEV) pfnCallback;
1023 /** Pointer to the device instance owning the queue. */
1024 R3PTRTYPE(PPDMDEVINS) pDevIns;
1025 } Dev;
1026 /** PDMQUEUETYPE_DRV */
1027 struct
1028 {
1029 /** Pointer to consumer function. */
1030 R3PTRTYPE(PFNPDMQUEUEDRV) pfnCallback;
1031 /** Pointer to the driver instance owning the queue. */
1032 R3PTRTYPE(PPDMDRVINS) pDrvIns;
1033 } Drv;
1034 /** PDMQUEUETYPE_INTERNAL */
1035 struct
1036 {
1037 /** Pointer to consumer function. */
1038 R3PTRTYPE(PFNPDMQUEUEINT) pfnCallback;
1039 } Int;
1040 /** PDMQUEUETYPE_EXTERNAL */
1041 struct
1042 {
1043 /** Pointer to consumer function. */
1044 R3PTRTYPE(PFNPDMQUEUEEXT) pfnCallback;
1045 /** Pointer to user argument. */
1046 R3PTRTYPE(void *) pvUser;
1047 } Ext;
1048 } u;
1049 /** Queue type. */
1050 PDMQUEUETYPE enmType;
1051 /** The interval between checking the queue for events.
1052 * The realtime timer below is used to do the waiting.
1053 * If 0, the queue will use the VM_FF_PDM_QUEUE forced action. */
1054 uint32_t cMilliesInterval;
1055 /** Interval timer. Only used if cMilliesInterval is non-zero. */
1056 TMTIMERHANDLE hTimer;
1057 /** Pointer to the VM - R3. */
1058 PVMR3 pVMR3;
1059 /** LIFO of pending items - R3. */
1060 R3PTRTYPE(PPDMQUEUEITEMCORE) volatile pPendingR3;
1061 /** Pointer to the VM - R0. */
1062 PVMR0 pVMR0;
1063 /** LIFO of pending items - R0. */
1064 R0PTRTYPE(PPDMQUEUEITEMCORE) volatile pPendingR0;
1065
1066 /** Item size (bytes). */
1067 uint32_t cbItem;
1068 /** Number of items in the queue. */
1069 uint32_t cItems;
1070 /** Index to the free head (where we insert). */
1071 uint32_t volatile iFreeHead;
1072 /** Index to the free tail (where we remove). */
1073 uint32_t volatile iFreeTail;
1074
1075 /** Unique queue name. */
1076 R3PTRTYPE(const char *) pszName;
1077#if HC_ARCH_BITS == 32
1078 RTR3PTR Alignment1;
1079#endif
1080 /** Stat: Times PDMQueueAlloc fails. */
1081 STAMCOUNTER StatAllocFailures;
1082 /** Stat: PDMQueueInsert calls. */
1083 STAMCOUNTER StatInsert;
1084 /** Stat: Queue flushes. */
1085 STAMCOUNTER StatFlush;
1086 /** Stat: Queue flushes with pending items left over. */
1087 STAMCOUNTER StatFlushLeftovers;
1088#ifdef VBOX_WITH_STATISTICS
1089 /** State: Profiling the flushing. */
1090 STAMPROFILE StatFlushPrf;
1091 /** State: Pending items. */
1092 uint32_t volatile cStatPending;
1093 uint32_t volatile cAlignment;
1094#endif
1095
1096 /** Array of pointers to free items. Variable size. */
1097 struct PDMQUEUEFREEITEM
1098 {
1099 /** Pointer to the free item - HC Ptr. */
1100 R3PTRTYPE(PPDMQUEUEITEMCORE) volatile pItemR3;
1101 /** Pointer to the free item - HC Ptr. */
1102 R0PTRTYPE(PPDMQUEUEITEMCORE) volatile pItemR0;
1103 } aFreeItems[1];
1104} PDMQUEUE;
1105
1106/** @name PDM::fQueueFlushing
1107 * @{ */
1108/** Used to make sure only one EMT will flush the queues.
1109 * Set when an EMT is flushing queues, clear otherwise. */
1110#define PDM_QUEUE_FLUSH_FLAG_ACTIVE_BIT 0
1111/** Indicating there are queues with items pending.
1112 * This is make sure we don't miss inserts happening during flushing. The FF
1113 * cannot be used for this since it has to be cleared immediately to prevent
1114 * other EMTs from spinning. */
1115#define PDM_QUEUE_FLUSH_FLAG_PENDING_BIT 1
1116/** @} */
1117
1118
1119/** @name PDM task structures.
1120 * @{ */
1121
1122/**
1123 * A asynchronous user mode task.
1124 */
1125typedef struct PDMTASK
1126{
1127 /** Task owner type. */
1128 PDMTASKTYPE volatile enmType;
1129 /** Queue flags. */
1130 uint32_t volatile fFlags;
1131 /** User argument for the callback. */
1132 R3PTRTYPE(void *) volatile pvUser;
1133 /** The callback (will be cast according to enmType before callout). */
1134 R3PTRTYPE(PFNRT) volatile pfnCallback;
1135 /** The owner identifier. */
1136 R3PTRTYPE(void *) volatile pvOwner;
1137 /** Task name. */
1138 R3PTRTYPE(const char *) pszName;
1139 /** Number of times already triggered when PDMTaskTrigger was called. */
1140 uint32_t volatile cAlreadyTrigged;
1141 /** Number of runs. */
1142 uint32_t cRuns;
1143} PDMTASK;
1144/** Pointer to a PDM task. */
1145typedef PDMTASK *PPDMTASK;
1146
1147/**
1148 * A task set.
1149 *
1150 * This is served by one task executor thread.
1151 */
1152typedef struct PDMTASKSET
1153{
1154 /** Magic value (PDMTASKSET_MAGIC). */
1155 uint32_t u32Magic;
1156 /** Set if this task set works for ring-0 and raw-mode. */
1157 bool fRZEnabled;
1158 /** Number of allocated taks. */
1159 uint8_t volatile cAllocated;
1160 /** Base handle value for this set. */
1161 uint16_t uHandleBase;
1162 /** The task executor thread. */
1163 R3PTRTYPE(RTTHREAD) hThread;
1164 /** Event semaphore for waking up the thread when fRZEnabled is set. */
1165 SUPSEMEVENT hEventR0;
1166 /** Event semaphore for waking up the thread when fRZEnabled is clear. */
1167 R3PTRTYPE(RTSEMEVENT) hEventR3;
1168 /** The VM pointer. */
1169 PVM pVM;
1170 /** Padding so fTriggered is in its own cacheline. */
1171 uint64_t au64Padding2[3];
1172
1173 /** Bitmask of triggered tasks. */
1174 uint64_t volatile fTriggered;
1175 /** Shutdown thread indicator. */
1176 bool volatile fShutdown;
1177 /** Padding. */
1178 bool volatile afPadding3[3];
1179 /** Task currently running, UINT32_MAX if idle. */
1180 uint32_t volatile idxRunning;
1181 /** Padding so fTriggered and fShutdown are in their own cacheline. */
1182 uint64_t volatile au64Padding3[6];
1183
1184 /** The individual tasks. (Unallocated tasks have NULL pvOwner.) */
1185 PDMTASK aTasks[64];
1186} PDMTASKSET;
1187AssertCompileMemberAlignment(PDMTASKSET, fTriggered, 64);
1188AssertCompileMemberAlignment(PDMTASKSET, aTasks, 64);
1189/** Magic value for PDMTASKSET::u32Magic. */
1190#define PDMTASKSET_MAGIC UINT32_C(0x19320314)
1191/** Pointer to a task set. */
1192typedef PDMTASKSET *PPDMTASKSET;
1193
1194/** @} */
1195
1196
1197/**
1198 * Queue device helper task operation.
1199 */
1200typedef enum PDMDEVHLPTASKOP
1201{
1202 /** The usual invalid 0 entry. */
1203 PDMDEVHLPTASKOP_INVALID = 0,
1204 /** IsaSetIrq, IoApicSetIrq */
1205 PDMDEVHLPTASKOP_ISA_SET_IRQ,
1206 /** PciSetIrq */
1207 PDMDEVHLPTASKOP_PCI_SET_IRQ,
1208 /** PciSetIrq */
1209 PDMDEVHLPTASKOP_IOAPIC_SET_IRQ,
1210 /** IoApicSendMsi */
1211 PDMDEVHLPTASKOP_IOAPIC_SEND_MSI,
1212 /** IoApicSettEoi */
1213 PDMDEVHLPTASKOP_IOAPIC_SET_EOI,
1214 /** The usual 32-bit hack. */
1215 PDMDEVHLPTASKOP_32BIT_HACK = 0x7fffffff
1216} PDMDEVHLPTASKOP;
1217
1218/**
1219 * Queued Device Helper Task.
1220 */
1221typedef struct PDMDEVHLPTASK
1222{
1223 /** The queue item core (don't touch). */
1224 PDMQUEUEITEMCORE Core;
1225 /** Pointer to the device instance (R3 Ptr). */
1226 PPDMDEVINSR3 pDevInsR3;
1227 /** This operation to perform. */
1228 PDMDEVHLPTASKOP enmOp;
1229#if HC_ARCH_BITS == 64
1230 uint32_t Alignment0;
1231#endif
1232 /** Parameters to the operation. */
1233 union PDMDEVHLPTASKPARAMS
1234 {
1235 /**
1236 * PDMDEVHLPTASKOP_ISA_SET_IRQ and PDMDEVHLPTASKOP_IOAPIC_SET_IRQ.
1237 */
1238 struct PDMDEVHLPTASKISASETIRQ
1239 {
1240 /** The bus:device:function of the device initiating the IRQ. Can be NIL_PCIBDF. */
1241 PCIBDF uBusDevFn;
1242 /** The IRQ */
1243 int iIrq;
1244 /** The new level. */
1245 int iLevel;
1246 /** The IRQ tag and source. */
1247 uint32_t uTagSrc;
1248 } IsaSetIrq, IoApicSetIrq;
1249
1250 /**
1251 * PDMDEVHLPTASKOP_PCI_SET_IRQ
1252 */
1253 struct PDMDEVHLPTASKPCISETIRQ
1254 {
1255 /** Pointer to the PCI device (R3 Ptr). */
1256 R3PTRTYPE(PPDMPCIDEV) pPciDevR3;
1257 /** The IRQ */
1258 int iIrq;
1259 /** The new level. */
1260 int iLevel;
1261 /** The IRQ tag and source. */
1262 uint32_t uTagSrc;
1263 } PciSetIrq;
1264
1265 /**
1266 * PDMDEVHLPTASKOP_IOAPIC_SEND_MSI
1267 */
1268 struct PDMDEVHLPTASKIOAPICSENDMSI
1269 {
1270 /** The bus:device:function of the device sending the MSI. */
1271 PCIBDF uBusDevFn;
1272 /** The MSI. */
1273 MSIMSG Msi;
1274 /** The IRQ tag and source. */
1275 uint32_t uTagSrc;
1276 } IoApicSendMsi;
1277
1278 /**
1279 * PDMDEVHLPTASKOP_IOAPIC_SET_EOI
1280 */
1281 struct PDMDEVHLPTASKIOAPICSETEOI
1282 {
1283 /** The vector corresponding to the EOI. */
1284 uint8_t uVector;
1285 } IoApicSetEoi;
1286
1287 /** Expanding the structure. */
1288 uint64_t au64[3];
1289 } u;
1290} PDMDEVHLPTASK;
1291/** Pointer to a queued Device Helper Task. */
1292typedef PDMDEVHLPTASK *PPDMDEVHLPTASK;
1293/** Pointer to a const queued Device Helper Task. */
1294typedef const PDMDEVHLPTASK *PCPDMDEVHLPTASK;
1295
1296
1297
1298/**
1299 * An USB hub registration record.
1300 */
1301typedef struct PDMUSBHUB
1302{
1303 /** The USB versions this hub support.
1304 * Note that 1.1 hubs can take on 2.0 devices. */
1305 uint32_t fVersions;
1306 /** The number of ports on the hub. */
1307 uint32_t cPorts;
1308 /** The number of available ports (0..cPorts). */
1309 uint32_t cAvailablePorts;
1310 /** The driver instance of the hub. */
1311 PPDMDRVINS pDrvIns;
1312 /** Copy of the to the registration structure. */
1313 PDMUSBHUBREG Reg;
1314
1315 /** Pointer to the next hub in the list. */
1316 struct PDMUSBHUB *pNext;
1317} PDMUSBHUB;
1318
1319/** Pointer to a const USB HUB registration record. */
1320typedef const PDMUSBHUB *PCPDMUSBHUB;
1321
1322/** Pointer to a PDM Async I/O template. */
1323typedef struct PDMASYNCCOMPLETIONTEMPLATE *PPDMASYNCCOMPLETIONTEMPLATE;
1324
1325/** Pointer to the main PDM Async completion endpoint class. */
1326typedef struct PDMASYNCCOMPLETIONEPCLASS *PPDMASYNCCOMPLETIONEPCLASS;
1327
1328/** Pointer to the global block cache structure. */
1329typedef struct PDMBLKCACHEGLOBAL *PPDMBLKCACHEGLOBAL;
1330
1331/**
1332 * PDM VMCPU Instance data.
1333 * Changes to this must checked against the padding of the pdm union in VMCPU!
1334 */
1335typedef struct PDMCPU
1336{
1337 /** The number of entries in the apQueuedCritSectsLeaves table that's currently
1338 * in use. */
1339 uint32_t cQueuedCritSectLeaves;
1340 uint32_t uPadding0; /**< Alignment padding.*/
1341 /** Critical sections queued in RC/R0 because of contention preventing leave to
1342 * complete. (R3 Ptrs)
1343 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */
1344 R3PTRTYPE(PPDMCRITSECT) apQueuedCritSectLeaves[8];
1345
1346 /** The number of entries in the apQueuedCritSectRwExclLeaves table that's
1347 * currently in use. */
1348 uint32_t cQueuedCritSectRwExclLeaves;
1349 uint32_t uPadding1; /**< Alignment padding.*/
1350 /** Read/write critical sections queued in RC/R0 because of contention
1351 * preventing exclusive leave to complete. (R3 Ptrs)
1352 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */
1353 R3PTRTYPE(PPDMCRITSECTRW) apQueuedCritSectRwExclLeaves[8];
1354
1355 /** The number of entries in the apQueuedCritSectsRwShrdLeaves table that's
1356 * currently in use. */
1357 uint32_t cQueuedCritSectRwShrdLeaves;
1358 uint32_t uPadding2; /**< Alignment padding.*/
1359 /** Read/write critical sections queued in RC/R0 because of contention
1360 * preventing shared leave to complete. (R3 Ptrs)
1361 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */
1362 R3PTRTYPE(PPDMCRITSECTRW) apQueuedCritSectRwShrdLeaves[8];
1363} PDMCPU;
1364
1365
1366/**
1367 * PDM VM Instance data.
1368 * Changes to this must checked against the padding of the cfgm union in VM!
1369 */
1370typedef struct PDM
1371{
1372 /** The PDM lock.
1373 * This is used to protect everything that deals with interrupts, i.e.
1374 * the PIC, APIC, IOAPIC and PCI devices plus some PDM functions. */
1375 PDMCRITSECT CritSect;
1376 /** The NOP critical section.
1377 * This is a dummy critical section that will not do any thread
1378 * serialization but instead let all threads enter immediately and
1379 * concurrently. */
1380 PDMCRITSECT NopCritSect;
1381
1382 /** The ring-0 capable task sets (max 128). */
1383 PDMTASKSET aTaskSets[2];
1384 /** Pointer to task sets (max 512). */
1385 R3PTRTYPE(PPDMTASKSET) apTaskSets[8];
1386
1387 /** PCI Buses. */
1388 PDMPCIBUS aPciBuses[PDM_PCI_BUSSES_MAX];
1389 /** IOMMU devices. */
1390 PDMIOMMUR3 aIommus[PDM_IOMMUS_MAX];
1391 /** The register PIC device. */
1392 PDMPIC Pic;
1393 /** The registered APIC device. */
1394 PDMAPIC Apic;
1395 /** The registered I/O APIC device. */
1396 PDMIOAPIC IoApic;
1397 /** The registered HPET device. */
1398 PPDMDEVINSR3 pHpet;
1399
1400 /** List of registered devices. (FIFO) */
1401 R3PTRTYPE(PPDMDEV) pDevs;
1402 /** List of devices instances. (FIFO) */
1403 R3PTRTYPE(PPDMDEVINS) pDevInstances;
1404 /** List of registered USB devices. (FIFO) */
1405 R3PTRTYPE(PPDMUSB) pUsbDevs;
1406 /** List of USB devices instances. (FIFO) */
1407 R3PTRTYPE(PPDMUSBINS) pUsbInstances;
1408 /** List of registered drivers. (FIFO) */
1409 R3PTRTYPE(PPDMDRV) pDrvs;
1410 /** The registered firmware device (can be NULL). */
1411 R3PTRTYPE(PPDMFW) pFirmware;
1412 /** The registered DMAC device. */
1413 R3PTRTYPE(PPDMDMAC) pDmac;
1414 /** The registered RTC device. */
1415 R3PTRTYPE(PPDMRTC) pRtc;
1416 /** The registered USB HUBs. (FIFO) */
1417 R3PTRTYPE(PPDMUSBHUB) pUsbHubs;
1418
1419 /** @name Queues
1420 * @{ */
1421 /** Queue in which devhlp tasks are queued for R3 execution - R3 Ptr. */
1422 R3PTRTYPE(PPDMQUEUE) pDevHlpQueueR3;
1423 /** Queue in which devhlp tasks are queued for R3 execution - R0 Ptr. */
1424 R0PTRTYPE(PPDMQUEUE) pDevHlpQueueR0;
1425 /** Pointer to the queue which should be manually flushed - R0 Ptr.
1426 * Only touched by EMT. */
1427 R0PTRTYPE(struct PDMQUEUE *) pQueueFlushR0;
1428 /** Bitmask controlling the queue flushing.
1429 * See PDM_QUEUE_FLUSH_FLAG_ACTIVE and PDM_QUEUE_FLUSH_FLAG_PENDING. */
1430 uint32_t volatile fQueueFlushing;
1431 /** @} */
1432
1433 /** The current IRQ tag (tracing purposes). */
1434 uint32_t volatile uIrqTag;
1435
1436 /** Pending reset flags (PDMVMRESET_F_XXX). */
1437 uint32_t volatile fResetFlags;
1438
1439 /** Set by pdmR3LoadExec for use in assertions. */
1440 bool fStateLoaded;
1441 /** Alignment padding. */
1442 bool afPadding[3];
1443
1444 /** The tracing ID of the next device instance.
1445 *
1446 * @remarks We keep the device tracing ID seperate from the rest as these are
1447 * then more likely to end up with the same ID from one run to
1448 * another, making analysis somewhat easier. Drivers and USB devices
1449 * are more volatile and can be changed at runtime, thus these are much
1450 * less likely to remain stable, so just heap them all together. */
1451 uint32_t idTracingDev;
1452 /** The tracing ID of the next driver instance, USB device instance or other
1453 * PDM entity requiring an ID. */
1454 uint32_t idTracingOther;
1455
1456 /** @name VMM device heap
1457 * @{ */
1458 /** The heap size. */
1459 uint32_t cbVMMDevHeap;
1460 /** Free space. */
1461 uint32_t cbVMMDevHeapLeft;
1462 /** Pointer to the heap base (MMIO2 ring-3 mapping). NULL if not registered. */
1463 RTR3PTR pvVMMDevHeap;
1464 /** Ring-3 mapping/unmapping notification callback for the user. */
1465 PFNPDMVMMDEVHEAPNOTIFY pfnVMMDevHeapNotify;
1466 /** The current mapping. NIL_RTGCPHYS if not mapped or registered. */
1467 RTGCPHYS GCPhysVMMDevHeap;
1468 /** @} */
1469
1470 /** Number of times a critical section leave request needed to be queued for ring-3 execution. */
1471 STAMCOUNTER StatQueuedCritSectLeaves;
1472 /** Number of times we've successfully aborted a wait in ring-0. */
1473 STAMCOUNTER StatAbortedCritSectEnters;
1474 /** Number of times we've got the critical section ownership while trying to
1475 * abort a wait due to VERR_INTERRUPTED. */
1476 STAMCOUNTER StatCritSectEntersWhileAborting;
1477 STAMCOUNTER StatCritSectVerrTimeout;
1478 STAMCOUNTER StatCritSectVerrInterrupted;
1479 STAMCOUNTER StatCritSectNonInterruptibleWaits;
1480
1481 STAMCOUNTER StatCritSectRwExclVerrTimeout;
1482 STAMCOUNTER StatCritSectRwExclVerrInterrupted;
1483 STAMCOUNTER StatCritSectRwExclNonInterruptibleWaits;
1484
1485 STAMCOUNTER StatCritSectRwEnterSharedWhileAborting;
1486 STAMCOUNTER StatCritSectRwSharedVerrTimeout;
1487 STAMCOUNTER StatCritSectRwSharedVerrInterrupted;
1488 STAMCOUNTER StatCritSectRwSharedNonInterruptibleWaits;
1489} PDM;
1490AssertCompileMemberAlignment(PDM, CritSect, 8);
1491AssertCompileMemberAlignment(PDM, aTaskSets, 64);
1492AssertCompileMemberAlignment(PDM, StatQueuedCritSectLeaves, 8);
1493AssertCompileMemberAlignment(PDM, GCPhysVMMDevHeap, sizeof(RTGCPHYS));
1494/** Pointer to PDM VM instance data. */
1495typedef PDM *PPDM;
1496
1497
1498/**
1499 * PDM data kept in the ring-0 GVM.
1500 */
1501typedef struct PDMR0PERVM
1502{
1503 /** PCI Buses, ring-0 data. */
1504 PDMPCIBUSR0 aPciBuses[PDM_PCI_BUSSES_MAX];
1505 /** IOMMUs, ring-0 data. */
1506 PDMIOMMUR0 aIommus[PDM_IOMMUS_MAX];
1507 /** Number of valid ring-0 device instances (apDevInstances). */
1508 uint32_t cDevInstances;
1509 uint32_t u32Padding;
1510 /** Pointer to ring-0 device instances. */
1511 R0PTRTYPE(struct PDMDEVINSR0 *) apDevInstances[190];
1512} PDMR0PERVM;
1513
1514
1515/**
1516 * PDM data kept in the UVM.
1517 */
1518typedef struct PDMUSERPERVM
1519{
1520 /** @todo move more stuff over here. */
1521
1522 /** Linked list of timer driven PDM queues.
1523 * Currently serialized by PDM::CritSect. */
1524 R3PTRTYPE(struct PDMQUEUE *) pQueuesTimer;
1525 /** Linked list of force action driven PDM queues.
1526 * Currently serialized by PDM::CritSect. */
1527 R3PTRTYPE(struct PDMQUEUE *) pQueuesForced;
1528
1529 /** Lock protecting the lists below it. */
1530 RTCRITSECT ListCritSect;
1531 /** Pointer to list of loaded modules. */
1532 PPDMMOD pModules;
1533 /** List of initialized critical sections. (LIFO) */
1534 R3PTRTYPE(PPDMCRITSECTINT) pCritSects;
1535 /** List of initialized read/write critical sections. (LIFO) */
1536 R3PTRTYPE(PPDMCRITSECTRWINT) pRwCritSects;
1537 /** Head of the PDM Thread list. (singly linked) */
1538 R3PTRTYPE(PPDMTHREAD) pThreads;
1539 /** Tail of the PDM Thread list. (singly linked) */
1540 R3PTRTYPE(PPDMTHREAD) pThreadsTail;
1541
1542 /** @name PDM Async Completion
1543 * @{ */
1544 /** Pointer to the array of supported endpoint classes. */
1545 PPDMASYNCCOMPLETIONEPCLASS apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_MAX];
1546 /** Head of the templates. Singly linked, protected by ListCritSect. */
1547 R3PTRTYPE(PPDMASYNCCOMPLETIONTEMPLATE) pAsyncCompletionTemplates;
1548 /** @} */
1549
1550 /** Global block cache data. */
1551 R3PTRTYPE(PPDMBLKCACHEGLOBAL) pBlkCacheGlobal;
1552#ifdef VBOX_WITH_NETSHAPER
1553 /** Pointer to network shaper instance. */
1554 R3PTRTYPE(PPDMNETSHAPER) pNetShaper;
1555#endif /* VBOX_WITH_NETSHAPER */
1556
1557} PDMUSERPERVM;
1558/** Pointer to the PDM data kept in the UVM. */
1559typedef PDMUSERPERVM *PPDMUSERPERVM;
1560
1561
1562
1563/*******************************************************************************
1564* Global Variables *
1565*******************************************************************************/
1566#ifdef IN_RING3
1567extern const PDMDRVHLPR3 g_pdmR3DrvHlp;
1568extern const PDMDEVHLPR3 g_pdmR3DevHlpTrusted;
1569# ifdef VBOX_WITH_DBGF_TRACING
1570extern const PDMDEVHLPR3 g_pdmR3DevHlpTracing;
1571# endif
1572extern const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted;
1573extern const PDMPICHLP g_pdmR3DevPicHlp;
1574extern const PDMIOAPICHLP g_pdmR3DevIoApicHlp;
1575extern const PDMFWHLPR3 g_pdmR3DevFirmwareHlp;
1576extern const PDMPCIHLPR3 g_pdmR3DevPciHlp;
1577extern const PDMIOMMUHLPR3 g_pdmR3DevIommuHlp;
1578extern const PDMDMACHLP g_pdmR3DevDmacHlp;
1579extern const PDMRTCHLP g_pdmR3DevRtcHlp;
1580extern const PDMHPETHLPR3 g_pdmR3DevHpetHlp;
1581extern const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp;
1582#endif
1583
1584
1585/*******************************************************************************
1586* Defined Constants And Macros *
1587*******************************************************************************/
1588/** @def PDMDEV_ASSERT_DEVINS
1589 * Asserts the validity of the device instance.
1590 */
1591#ifdef VBOX_STRICT
1592# define PDMDEV_ASSERT_DEVINS(pDevIns) \
1593 do { \
1594 AssertPtr(pDevIns); \
1595 Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \
1596 Assert(pDevIns->CTX_SUFF(pvInstanceDataFor) == (void *)&pDevIns->achInstanceData[0]); \
1597 } while (0)
1598#else
1599# define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0)
1600#endif
1601
1602/** @def PDMDRV_ASSERT_DRVINS
1603 * Asserts the validity of the driver instance.
1604 */
1605#ifdef VBOX_STRICT
1606# define PDMDRV_ASSERT_DRVINS(pDrvIns) \
1607 do { \
1608 AssertPtr(pDrvIns); \
1609 Assert(pDrvIns->u32Version == PDM_DRVINS_VERSION); \
1610 Assert(pDrvIns->CTX_SUFF(pvInstanceData) == (void *)&pDrvIns->achInstanceData[0]); \
1611 } while (0)
1612#else
1613# define PDMDRV_ASSERT_DRVINS(pDrvIns) do { } while (0)
1614#endif
1615
1616
1617/*******************************************************************************
1618* Internal Functions *
1619*******************************************************************************/
1620#ifdef IN_RING3
1621bool pdmR3IsValidName(const char *pszName);
1622
1623int pdmR3CritSectBothInitStatsAndInfo(PVM pVM);
1624int pdmR3CritSectBothDeleteDevice(PVM pVM, PPDMDEVINS pDevIns);
1625int pdmR3CritSectBothDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns);
1626int pdmR3CritSectInitDevice( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
1627 const char *pszNameFmt, va_list va);
1628int pdmR3CritSectInitDeviceAuto( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
1629 const char *pszNameFmt, ...);
1630int pdmR3CritSectInitDriver( PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
1631 const char *pszNameFmt, ...);
1632int pdmR3CritSectRwInitDevice( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
1633 const char *pszNameFmt, va_list va);
1634int pdmR3CritSectRwInitDeviceAuto( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
1635 const char *pszNameFmt, ...);
1636int pdmR3CritSectRwInitDriver( PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
1637 const char *pszNameFmt, ...);
1638
1639int pdmR3DevInit(PVM pVM);
1640int pdmR3DevInitComplete(PVM pVM);
1641PPDMDEV pdmR3DevLookup(PVM pVM, const char *pszName);
1642int pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);
1643DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem);
1644
1645int pdmR3UsbLoadModules(PVM pVM);
1646int pdmR3UsbInstantiateDevices(PVM pVM);
1647PPDMUSB pdmR3UsbLookup(PVM pVM, const char *pszName);
1648int pdmR3UsbRegisterHub(PVM pVM, PPDMDRVINS pDrvIns, uint32_t fVersions, uint32_t cPorts, PCPDMUSBHUBREG pUsbHubReg, PPCPDMUSBHUBHLP ppUsbHubHlp);
1649int pdmR3UsbVMInitComplete(PVM pVM);
1650
1651int pdmR3DrvInit(PVM pVM);
1652int pdmR3DrvInstantiate(PVM pVM, PCFGMNODE pNode, PPDMIBASE pBaseInterface, PPDMDRVINS pDrvAbove,
1653 PPDMLUN pLun, PPDMIBASE *ppBaseInterface);
1654int pdmR3DrvDetach(PPDMDRVINS pDrvIns, uint32_t fFlags);
1655void pdmR3DrvDestroyChain(PPDMDRVINS pDrvIns, uint32_t fFlags);
1656PPDMDRV pdmR3DrvLookup(PVM pVM, const char *pszName);
1657
1658int pdmR3LdrInitU(PUVM pUVM);
1659void pdmR3LdrTermU(PUVM pUVM, bool fFinal);
1660char *pdmR3FileR3(const char *pszFile, bool fShared);
1661int pdmR3LoadR3U(PUVM pUVM, const char *pszFilename, const char *pszName);
1662
1663int pdmR3TaskInit(PVM pVM);
1664void pdmR3TaskTerm(PVM pVM);
1665
1666int pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
1667 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1668int pdmR3ThreadCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
1669 PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1670int pdmR3ThreadCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
1671 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1672int pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
1673int pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
1674int pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
1675void pdmR3ThreadDestroyAll(PVM pVM);
1676int pdmR3ThreadResumeAll(PVM pVM);
1677int pdmR3ThreadSuspendAll(PVM pVM);
1678
1679#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
1680int pdmR3AsyncCompletionInit(PVM pVM);
1681int pdmR3AsyncCompletionTerm(PVM pVM);
1682void pdmR3AsyncCompletionResume(PVM pVM);
1683int pdmR3AsyncCompletionTemplateCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDEV pfnCompleted, const char *pszDesc);
1684int pdmR3AsyncCompletionTemplateCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
1685 PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc);
1686int pdmR3AsyncCompletionTemplateCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEUSB pfnCompleted, const char *pszDesc);
1687int pdmR3AsyncCompletionTemplateDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
1688int pdmR3AsyncCompletionTemplateDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
1689int pdmR3AsyncCompletionTemplateDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
1690#endif
1691
1692#ifdef VBOX_WITH_NETSHAPER
1693int pdmR3NetShaperInit(PVM pVM);
1694int pdmR3NetShaperTerm(PVM pVM);
1695#endif
1696
1697int pdmR3BlkCacheInit(PVM pVM);
1698void pdmR3BlkCacheTerm(PVM pVM);
1699int pdmR3BlkCacheResume(PVM pVM);
1700
1701#endif /* IN_RING3 */
1702
1703void pdmLock(PVMCC pVM);
1704int pdmLockEx(PVMCC pVM, int rcBusy);
1705void pdmUnlock(PVMCC pVM);
1706bool pdmLockIsOwner(PVMCC pVM);
1707
1708#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
1709bool pdmIommuIsPresent(PPDMDEVINS pDevIns);
1710int pdmIommuMsiRemap(PPDMDEVINS pDevIns, uint16_t idDevice, PCMSIMSG pMsiIn, PMSIMSG pMsiOut);
1711int pdmIommuMemAccessRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags);
1712int pdmIommuMemAccessWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags);
1713# ifdef IN_RING3
1714int pdmR3IommuMemAccessReadCCPtr(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock);
1715int pdmR3IommuMemAccessWriteCCPtr(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock);
1716int pdmR3IommuMemAccessBulkReadCCPtr(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t cPages, PCRTGCPHYS paGCPhysPages, uint32_t fFlags, const void **papvPages, PPGMPAGEMAPLOCK paLocks);
1717int pdmR3IommuMemAccessBulkWriteCCPtr(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t cPages, PCRTGCPHYS paGCPhysPages, uint32_t fFlags, void **papvPages, PPGMPAGEMAPLOCK paLocks);
1718# endif
1719#endif
1720
1721#if defined(IN_RING3) || defined(IN_RING0)
1722void pdmCritSectRwLeaveSharedQueued(PVMCC pVM, PPDMCRITSECTRW pThis);
1723void pdmCritSectRwLeaveExclQueued(PVMCC pVM, PPDMCRITSECTRW pThis);
1724#endif
1725
1726#ifdef IN_RING0
1727DECLHIDDEN(bool) pdmR0IsaSetIrq(PGVM pGVM, int iIrq, int iLevel, uint32_t uTagSrc);
1728#endif
1729
1730#ifdef VBOX_WITH_DBGF_TRACING
1731# ifdef IN_RING3
1732DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_IoPortCreateEx(PPDMDEVINS pDevIns, RTIOPORT cPorts, uint32_t fFlags, PPDMPCIDEV pPciDev,
1733 uint32_t iPciRegion, PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
1734 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, RTR3PTR pvUser,
1735 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts);
1736DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_IoPortMap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT Port);
1737DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_IoPortUnmap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts);
1738DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_MmioCreateEx(PPDMDEVINS pDevIns, RTGCPHYS cbRegion,
1739 uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
1740 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill,
1741 void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion);
1742DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_MmioMap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys);
1743DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_MmioUnmap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion);
1744DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags);
1745DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags);
1746DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_PCIPhysRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags);
1747DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_PCIPhysWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags);
1748DECL_HIDDEN_CALLBACK(void) pdmR3DevHlpTracing_PCISetIrq(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel);
1749DECL_HIDDEN_CALLBACK(void) pdmR3DevHlpTracing_PCISetIrqNoWait(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel);
1750DECL_HIDDEN_CALLBACK(void) pdmR3DevHlpTracing_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
1751DECL_HIDDEN_CALLBACK(void) pdmR3DevHlpTracing_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel);
1752# elif defined(IN_RING0)
1753DECL_HIDDEN_CALLBACK(int) pdmR0DevHlpTracing_IoPortSetUpContextEx(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
1754 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
1755 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr,
1756 void *pvUser);
1757DECL_HIDDEN_CALLBACK(int) pdmR0DevHlpTracing_MmioSetUpContextEx(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIONEWWRITE pfnWrite,
1758 PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill, void *pvUser);
1759DECL_HIDDEN_CALLBACK(int) pdmR0DevHlpTracing_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags);
1760DECL_HIDDEN_CALLBACK(int) pdmR0DevHlpTracing_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags);
1761DECL_HIDDEN_CALLBACK(int) pdmR0DevHlpTracing_PCIPhysRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags);
1762DECL_HIDDEN_CALLBACK(int) pdmR0DevHlpTracing_PCIPhysWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags);
1763DECL_HIDDEN_CALLBACK(void) pdmR0DevHlpTracing_PCISetIrq(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel);
1764DECL_HIDDEN_CALLBACK(void) pdmR0DevHlpTracing_PCISetIrqNoWait(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel);
1765DECL_HIDDEN_CALLBACK(void) pdmR0DevHlpTracing_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
1766DECL_HIDDEN_CALLBACK(void) pdmR0DevHlpTracing_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel);
1767# else
1768# error "Invalid environment selected"
1769# endif
1770#endif
1771
1772
1773/** @} */
1774
1775RT_C_DECLS_END
1776
1777#endif /* !VMM_INCLUDED_SRC_include_PDMInternal_h */
1778
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