VirtualBox

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

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

DevPci*,PDM: Doxygen fixes. bugrefx:9218

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 54.5 KB
Line 
1/* $Id: PDMInternal.h 80962 2019-09-23 23:04:49Z vboxsync $ */
2/** @file
3 * PDM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef VMM_INCLUDED_SRC_include_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/pdmasynccompletion.h>
30#ifdef VBOX_WITH_NETSHAPER
31# include <VBox/vmm/pdmnetshaper.h>
32#endif
33#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
34# include <VBox/vmm/pdmasynccompletion.h>
35#endif
36#include <VBox/vmm/pdmblkcache.h>
37#include <VBox/vmm/pdmcommon.h>
38#include <VBox/sup.h>
39#include <iprt/assert.h>
40#include <iprt/critsect.h>
41#ifdef IN_RING3
42# include <iprt/thread.h>
43#endif
44
45RT_C_DECLS_BEGIN
46
47
48/** @defgroup grp_pdm_int Internal
49 * @ingroup grp_pdm
50 * @internal
51 * @{
52 */
53
54/** @def PDM_WITH_R3R0_CRIT_SECT
55 * Enables or disabled ring-3/ring-0 critical sections. */
56#if defined(DOXYGEN_RUNNING) || 1
57# define PDM_WITH_R3R0_CRIT_SECT
58#endif
59
60/** @def PDMCRITSECT_STRICT
61 * Enables/disables PDM critsect strictness like deadlock detection. */
62#if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(PDMCRITSECT_STRICT)) \
63 || defined(DOXYGEN_RUNNING)
64# define PDMCRITSECT_STRICT
65#endif
66
67/** @def PDMCRITSECT_STRICT
68 * Enables/disables PDM read/write critsect strictness like deadlock
69 * detection. */
70#if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(PDMCRITSECTRW_STRICT)) \
71 || defined(DOXYGEN_RUNNING)
72# define PDMCRITSECTRW_STRICT
73#endif
74
75
76/*******************************************************************************
77* Structures and Typedefs *
78*******************************************************************************/
79
80/** Pointer to a PDM Device. */
81typedef struct PDMDEV *PPDMDEV;
82/** Pointer to a pointer to a PDM Device. */
83typedef PPDMDEV *PPPDMDEV;
84
85/** Pointer to a PDM USB Device. */
86typedef struct PDMUSB *PPDMUSB;
87/** Pointer to a pointer to a PDM USB Device. */
88typedef PPDMUSB *PPPDMUSB;
89
90/** Pointer to a PDM Driver. */
91typedef struct PDMDRV *PPDMDRV;
92/** Pointer to a pointer to a PDM Driver. */
93typedef PPDMDRV *PPPDMDRV;
94
95/** Pointer to a PDM Logical Unit. */
96typedef struct PDMLUN *PPDMLUN;
97/** Pointer to a pointer to a PDM Logical Unit. */
98typedef PPDMLUN *PPPDMLUN;
99
100/** Pointer to a PDM PCI Bus instance. */
101typedef struct PDMPCIBUS *PPDMPCIBUS;
102/** Pointer to a DMAC instance. */
103typedef struct PDMDMAC *PPDMDMAC;
104/** Pointer to a RTC instance. */
105typedef struct PDMRTC *PPDMRTC;
106
107/** Pointer to an USB HUB registration record. */
108typedef struct PDMUSBHUB *PPDMUSBHUB;
109
110/**
111 * Supported asynchronous completion endpoint classes.
112 */
113typedef enum PDMASYNCCOMPLETIONEPCLASSTYPE
114{
115 /** File class. */
116 PDMASYNCCOMPLETIONEPCLASSTYPE_FILE = 0,
117 /** Number of supported classes. */
118 PDMASYNCCOMPLETIONEPCLASSTYPE_MAX,
119 /** 32bit hack. */
120 PDMASYNCCOMPLETIONEPCLASSTYPE_32BIT_HACK = 0x7fffffff
121} PDMASYNCCOMPLETIONEPCLASSTYPE;
122
123/**
124 * Private device instance data, ring-3.
125 */
126typedef struct PDMDEVINSINTR3
127{
128 /** Pointer to the next instance.
129 * (Head is pointed to by PDM::pDevInstances.) */
130 R3PTRTYPE(PPDMDEVINS) pNextR3;
131 /** Pointer to the next per device instance.
132 * (Head is pointed to by PDMDEV::pInstances.) */
133 R3PTRTYPE(PPDMDEVINS) pPerDeviceNextR3;
134 /** Pointer to device structure. */
135 R3PTRTYPE(PPDMDEV) pDevR3;
136 /** Pointer to the list of logical units associated with the device. (FIFO) */
137 R3PTRTYPE(PPDMLUN) pLunsR3;
138 /** Pointer to the asynchronous notification callback set while in
139 * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */
140 R3PTRTYPE(PFNPDMDEVASYNCNOTIFY) pfnAsyncNotify;
141 /** Configuration handle to the instance node. */
142 R3PTRTYPE(PCFGMNODE) pCfgHandle;
143
144 /** R3 pointer to the VM this instance was created for. */
145 PVMR3 pVMR3;
146 /** Associated PCI device list head (first is default). */
147 R3PTRTYPE(PPDMPCIDEV) pHeadPciDevR3;
148
149 /** Flags, see PDMDEVINSINT_FLAGS_XXX. */
150 uint32_t fIntFlags;
151 /** The last IRQ tag (for tracing it thru clearing). */
152 uint32_t uLastIrqTag;
153 /** The ring-0 device index (for making ring-0 calls). */
154 uint32_t idxR0Device;
155} PDMDEVINSINTR3;
156
157
158/**
159 * Private device instance data, ring-0.
160 */
161typedef struct PDMDEVINSINTR0
162{
163 /** Pointer to the VM this instance was created for. */
164 R0PTRTYPE(PGVM) pGVM;
165 /** Associated PCI device list head (first is default). */
166 R0PTRTYPE(PPDMPCIDEV) pHeadPciDevR0;
167 /** Pointer to device structure. */
168 R0PTRTYPE(struct PDMDEVREGR0 const *) pRegR0;
169 /** The ring-0 module reference. */
170 RTR0PTR hMod;
171 /** Pointer to the ring-0 mapping of the ring-3 internal data (for uLastIrqTag). */
172 R0PTRTYPE(PDMDEVINSINTR3 *) pIntR3R0;
173 /** Pointer to the ring-0 mapping of the ring-3 instance (for idTracing). */
174 R0PTRTYPE(struct PDMDEVINSR3 *) pInsR3R0;
175 /** The device instance memory. */
176 RTR0MEMOBJ hMemObj;
177 /** The ring-3 mapping object. */
178 RTR0MEMOBJ hMapObj;
179 /** Index into PDMR0PERVM::apDevInstances. */
180 uint32_t idxR0Device;
181} PDMDEVINSINTR0;
182
183
184/**
185 * Private device instance data, raw-mode
186 */
187typedef struct PDMDEVINSINTRC
188{
189 /** Pointer to the VM this instance was created for. */
190 RGPTRTYPE(PVM) pVMRC;
191} PDMDEVINSINTRC;
192
193
194/**
195 * Private device instance data.
196 */
197typedef struct PDMDEVINSINT
198{
199 /** Pointer to the next instance (HC Ptr).
200 * (Head is pointed to by PDM::pDevInstances.) */
201 R3PTRTYPE(PPDMDEVINS) pNextR3;
202 /** Pointer to the next per device instance (HC Ptr).
203 * (Head is pointed to by PDMDEV::pInstances.) */
204 R3PTRTYPE(PPDMDEVINS) pPerDeviceNextR3;
205 /** Pointer to device structure - HC Ptr. */
206 R3PTRTYPE(PPDMDEV) pDevR3;
207 /** Pointer to the list of logical units associated with the device. (FIFO) */
208 R3PTRTYPE(PPDMLUN) pLunsR3;
209 /** Pointer to the asynchronous notification callback set while in
210 * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */
211 R3PTRTYPE(PFNPDMDEVASYNCNOTIFY) pfnAsyncNotify;
212 /** Configuration handle to the instance node. */
213 R3PTRTYPE(PCFGMNODE) pCfgHandle;
214
215 /** R3 pointer to the VM this instance was created for. */
216 PVMR3 pVMR3;
217 /** Associated PCI device list head (first is default). (R3 ptr) */
218 R3PTRTYPE(PPDMPCIDEV) pHeadPciDevR3;
219
220 /** R0 pointer to the VM this instance was created for. */
221 R0PTRTYPE(PVMCC) pVMR0;
222 /** Associated PCI device list head (first is default). (R0 ptr) */
223 R0PTRTYPE(PPDMPCIDEV) pHeadPciDevR0;
224
225 /** RC pointer to the VM this instance was created for. */
226 PVMRC pVMRC;
227 /** Associated PCI device list head (first is default). (RC ptr) */
228 RCPTRTYPE(PPDMPCIDEV) pHeadPciDevRC;
229
230 /** Flags, see PDMDEVINSINT_FLAGS_XXX. */
231 uint32_t fIntFlags;
232 /** The last IRQ tag (for tracing it thru clearing). */
233 uint32_t uLastIrqTag;
234} PDMDEVINSINT;
235
236/** @name PDMDEVINSINT::fIntFlags
237 * @{ */
238/** Used by pdmR3Load to mark device instances it found in the saved state. */
239#define PDMDEVINSINT_FLAGS_FOUND RT_BIT_32(0)
240/** Indicates that the device hasn't been powered on or resumed.
241 * This is used by PDMR3PowerOn, PDMR3Resume, PDMR3Suspend and PDMR3PowerOff
242 * to make sure each device gets exactly one notification for each of those
243 * events. PDMR3Resume and PDMR3PowerOn also makes use of it to bail out on
244 * a failure (already resumed/powered-on devices are suspended).
245 * PDMR3PowerOff resets this flag once before going through the devices to make sure
246 * every device gets the power off notification even if it was suspended before with
247 * PDMR3Suspend.
248 */
249#define PDMDEVINSINT_FLAGS_SUSPENDED RT_BIT_32(1)
250/** Indicates that the device has been reset already. Used by PDMR3Reset. */
251#define PDMDEVINSINT_FLAGS_RESET RT_BIT_32(2)
252#define PDMDEVINSINT_FLAGS_R0_ENABLED RT_BIT_32(3)
253#define PDMDEVINSINT_FLAGS_RC_ENABLED RT_BIT_32(4)
254/** Set if we've called the ring-0 constructor. */
255#define PDMDEVINSINT_FLAGS_R0_CONTRUCT RT_BIT_32(5)
256/** Set if using non-default critical section. */
257#define PDMDEVINSINT_FLAGS_CHANGED_CRITSECT RT_BIT_32(6)
258/** @} */
259
260
261/**
262 * Private USB device instance data.
263 */
264typedef struct PDMUSBINSINT
265{
266 /** The UUID of this instance. */
267 RTUUID Uuid;
268 /** Pointer to the next instance.
269 * (Head is pointed to by PDM::pUsbInstances.) */
270 R3PTRTYPE(PPDMUSBINS) pNext;
271 /** Pointer to the next per USB device instance.
272 * (Head is pointed to by PDMUSB::pInstances.) */
273 R3PTRTYPE(PPDMUSBINS) pPerDeviceNext;
274
275 /** Pointer to device structure. */
276 R3PTRTYPE(PPDMUSB) pUsbDev;
277
278 /** Pointer to the VM this instance was created for. */
279 PVMR3 pVM;
280 /** Pointer to the list of logical units associated with the device. (FIFO) */
281 R3PTRTYPE(PPDMLUN) pLuns;
282 /** The per instance device configuration. */
283 R3PTRTYPE(PCFGMNODE) pCfg;
284 /** Same as pCfg if the configuration should be deleted when detaching the device. */
285 R3PTRTYPE(PCFGMNODE) pCfgDelete;
286 /** The global device configuration. */
287 R3PTRTYPE(PCFGMNODE) pCfgGlobal;
288
289 /** Pointer to the USB hub this device is attached to.
290 * This is NULL if the device isn't connected to any HUB. */
291 R3PTRTYPE(PPDMUSBHUB) pHub;
292 /** The port number that we're connected to. */
293 uint32_t iPort;
294 /** Indicates that the USB device hasn't been powered on or resumed.
295 * See PDMDEVINSINT_FLAGS_SUSPENDED. */
296 bool fVMSuspended;
297 /** Indicates that the USB device has been reset. */
298 bool fVMReset;
299 /** Pointer to the asynchronous notification callback set while in
300 * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */
301 R3PTRTYPE(PFNPDMUSBASYNCNOTIFY) pfnAsyncNotify;
302} PDMUSBINSINT;
303
304
305/**
306 * Private driver instance data.
307 */
308typedef struct PDMDRVINSINT
309{
310 /** Pointer to the driver instance above.
311 * This is NULL for the topmost drive. */
312 R3PTRTYPE(PPDMDRVINS) pUp;
313 /** Pointer to the driver instance below.
314 * This is NULL for the bottommost driver. */
315 R3PTRTYPE(PPDMDRVINS) pDown;
316 /** Pointer to the logical unit this driver chained on. */
317 R3PTRTYPE(PPDMLUN) pLun;
318 /** Pointer to driver structure from which this was instantiated. */
319 R3PTRTYPE(PPDMDRV) pDrv;
320 /** Pointer to the VM this instance was created for, ring-3 context. */
321 PVMR3 pVMR3;
322 /** Pointer to the VM this instance was created for, ring-0 context. */
323 R0PTRTYPE(PVMCC) pVMR0;
324 /** Pointer to the VM this instance was created for, raw-mode context. */
325 PVMRC pVMRC;
326 /** Flag indicating that the driver is being detached and destroyed.
327 * (Helps detect potential recursive detaching.) */
328 bool fDetaching;
329 /** Indicates that the driver hasn't been powered on or resumed.
330 * See PDMDEVINSINT_FLAGS_SUSPENDED. */
331 bool fVMSuspended;
332 /** Indicates that the driver has been reset already. */
333 bool fVMReset;
334 /** Set if allocated on the hyper heap, false if on the ring-3 heap. */
335 bool fHyperHeap;
336 /** Pointer to the asynchronous notification callback set while in
337 * PDMUSBREG::pfnVMSuspend or PDMUSBREG::pfnVMPowerOff. */
338 R3PTRTYPE(PFNPDMDRVASYNCNOTIFY) pfnAsyncNotify;
339 /** Configuration handle to the instance node. */
340 R3PTRTYPE(PCFGMNODE) pCfgHandle;
341 /** Pointer to the ring-0 request handler function. */
342 PFNPDMDRVREQHANDLERR0 pfnReqHandlerR0;
343} PDMDRVINSINT;
344
345
346/**
347 * Private critical section data.
348 */
349typedef struct PDMCRITSECTINT
350{
351 /** The critical section core which is shared with IPRT.
352 * @note The semaphore is a SUPSEMEVENT. */
353 RTCRITSECT Core;
354 /** Pointer to the next critical section.
355 * This chain is used for relocating pVMRC and device cleanup. */
356 R3PTRTYPE(struct PDMCRITSECTINT *) pNext;
357 /** Owner identifier.
358 * This is pDevIns if the owner is a device. Similarly for a driver or service.
359 * PDMR3CritSectInit() sets this to point to the critsect itself. */
360 RTR3PTR pvKey;
361 /** Pointer to the VM - R3Ptr. */
362 PVMR3 pVMR3;
363 /** Pointer to the VM - R0Ptr. */
364 R0PTRTYPE(PVMCC) pVMR0;
365 /** Pointer to the VM - GCPtr. */
366 PVMRC pVMRC;
367 /** Set if this critical section is the automatically created default
368 * section of a device. */
369 bool fAutomaticDefaultCritsect;
370 /** Set if the critical section is used by a timer or similar.
371 * See PDMR3DevGetCritSect. */
372 bool fUsedByTimerOrSimilar;
373 /** Alignment padding. */
374 bool afPadding[2];
375 /** Support driver event semaphore that is scheduled to be signaled upon leaving
376 * the critical section. This is only for Ring-3 and Ring-0. */
377 SUPSEMEVENT hEventToSignal;
378 /** The lock name. */
379 R3PTRTYPE(const char *) pszName;
380 /** R0/RC lock contention. */
381 STAMCOUNTER StatContentionRZLock;
382 /** R0/RC unlock contention. */
383 STAMCOUNTER StatContentionRZUnlock;
384 /** R3 lock contention. */
385 STAMCOUNTER StatContentionR3;
386 /** Profiling the time the section is locked. */
387 STAMPROFILEADV StatLocked;
388} PDMCRITSECTINT;
389AssertCompileMemberAlignment(PDMCRITSECTINT, StatContentionRZLock, 8);
390/** Pointer to private critical section data. */
391typedef PDMCRITSECTINT *PPDMCRITSECTINT;
392
393/** Indicates that the critical section is queued for unlock.
394 * PDMCritSectIsOwner and PDMCritSectIsOwned optimizations. */
395#define PDMCRITSECT_FLAGS_PENDING_UNLOCK RT_BIT_32(17)
396
397
398/**
399 * Private critical section data.
400 */
401typedef struct PDMCRITSECTRWINT
402{
403 /** The read/write critical section core which is shared with IPRT.
404 * @note The semaphores are SUPSEMEVENT and SUPSEMEVENTMULTI. */
405 RTCRITSECTRW Core;
406
407 /** Pointer to the next critical section.
408 * This chain is used for relocating pVMRC and device cleanup. */
409 R3PTRTYPE(struct PDMCRITSECTRWINT *) pNext;
410 /** Owner identifier.
411 * This is pDevIns if the owner is a device. Similarly for a driver or service.
412 * PDMR3CritSectInit() sets this to point to the critsect itself. */
413 RTR3PTR pvKey;
414 /** Pointer to the VM - R3Ptr. */
415 PVMR3 pVMR3;
416 /** Pointer to the VM - R0Ptr. */
417 R0PTRTYPE(PVMCC) pVMR0;
418 /** Pointer to the VM - GCPtr. */
419 PVMRC pVMRC;
420#if HC_ARCH_BITS == 64
421 /** Alignment padding. */
422 RTRCPTR RCPtrPadding;
423#endif
424 /** The lock name. */
425 R3PTRTYPE(const char *) pszName;
426 /** R0/RC write lock contention. */
427 STAMCOUNTER StatContentionRZEnterExcl;
428 /** R0/RC write unlock contention. */
429 STAMCOUNTER StatContentionRZLeaveExcl;
430 /** R0/RC read lock contention. */
431 STAMCOUNTER StatContentionRZEnterShared;
432 /** R0/RC read unlock contention. */
433 STAMCOUNTER StatContentionRZLeaveShared;
434 /** R0/RC writes. */
435 STAMCOUNTER StatRZEnterExcl;
436 /** R0/RC reads. */
437 STAMCOUNTER StatRZEnterShared;
438 /** R3 write lock contention. */
439 STAMCOUNTER StatContentionR3EnterExcl;
440 /** R3 read lock contention. */
441 STAMCOUNTER StatContentionR3EnterShared;
442 /** R3 writes. */
443 STAMCOUNTER StatR3EnterExcl;
444 /** R3 reads. */
445 STAMCOUNTER StatR3EnterShared;
446 /** Profiling the time the section is write locked. */
447 STAMPROFILEADV StatWriteLocked;
448} PDMCRITSECTRWINT;
449AssertCompileMemberAlignment(PDMCRITSECTRWINT, StatContentionRZEnterExcl, 8);
450AssertCompileMemberAlignment(PDMCRITSECTRWINT, Core.u64State, 8);
451/** Pointer to private critical section data. */
452typedef PDMCRITSECTRWINT *PPDMCRITSECTRWINT;
453
454
455
456/**
457 * The usual device/driver/internal/external stuff.
458 */
459typedef enum
460{
461 /** The usual invalid entry. */
462 PDMTHREADTYPE_INVALID = 0,
463 /** Device type. */
464 PDMTHREADTYPE_DEVICE,
465 /** USB Device type. */
466 PDMTHREADTYPE_USB,
467 /** Driver type. */
468 PDMTHREADTYPE_DRIVER,
469 /** Internal type. */
470 PDMTHREADTYPE_INTERNAL,
471 /** External type. */
472 PDMTHREADTYPE_EXTERNAL,
473 /** The usual 32-bit hack. */
474 PDMTHREADTYPE_32BIT_HACK = 0x7fffffff
475} PDMTHREADTYPE;
476
477
478/**
479 * The internal structure for the thread.
480 */
481typedef struct PDMTHREADINT
482{
483 /** The VM pointer. */
484 PVMR3 pVM;
485 /** The event semaphore the thread blocks on when not running. */
486 RTSEMEVENTMULTI BlockEvent;
487 /** The event semaphore the thread sleeps on while running. */
488 RTSEMEVENTMULTI SleepEvent;
489 /** Pointer to the next thread. */
490 R3PTRTYPE(struct PDMTHREAD *) pNext;
491 /** The thread type. */
492 PDMTHREADTYPE enmType;
493} PDMTHREADINT;
494
495
496
497/* Must be included after PDMDEVINSINT is defined. */
498#define PDMDEVINSINT_DECLARED
499#define PDMUSBINSINT_DECLARED
500#define PDMDRVINSINT_DECLARED
501#define PDMCRITSECTINT_DECLARED
502#define PDMCRITSECTRWINT_DECLARED
503#define PDMTHREADINT_DECLARED
504#ifdef ___VBox_pdm_h
505# error "Invalid header PDM order. Include PDMInternal.h before VBox/vmm/pdm.h!"
506#endif
507RT_C_DECLS_END
508#include <VBox/vmm/pdm.h>
509RT_C_DECLS_BEGIN
510
511/**
512 * PDM Logical Unit.
513 *
514 * This typically the representation of a physical port on a
515 * device, like for instance the PS/2 keyboard port on the
516 * keyboard controller device. The LUNs are chained on the
517 * device they belong to (PDMDEVINSINT::pLunsR3).
518 */
519typedef struct PDMLUN
520{
521 /** The LUN - The Logical Unit Number. */
522 RTUINT iLun;
523 /** Pointer to the next LUN. */
524 PPDMLUN pNext;
525 /** Pointer to the top driver in the driver chain. */
526 PPDMDRVINS pTop;
527 /** Pointer to the bottom driver in the driver chain. */
528 PPDMDRVINS pBottom;
529 /** Pointer to the device instance which the LUN belongs to.
530 * Either this is set or pUsbIns is set. Both is never set at the same time. */
531 PPDMDEVINS pDevIns;
532 /** Pointer to the USB device instance which the LUN belongs to. */
533 PPDMUSBINS pUsbIns;
534 /** Pointer to the device base interface. */
535 PPDMIBASE pBase;
536 /** Description of this LUN. */
537 const char *pszDesc;
538} PDMLUN;
539
540
541/**
542 * PDM Device, ring-3.
543 */
544typedef struct PDMDEV
545{
546 /** Pointer to the next device (R3 Ptr). */
547 R3PTRTYPE(PPDMDEV) pNext;
548 /** Device name length. (search optimization) */
549 uint32_t cchName;
550 /** Registration structure. */
551 R3PTRTYPE(const struct PDMDEVREGR3 *) pReg;
552 /** Number of instances. */
553 uint32_t cInstances;
554 /** Pointer to chain of instances (R3 Ptr). */
555 PPDMDEVINSR3 pInstances;
556 /** The search path for raw-mode context modules (';' as separator). */
557 char *pszRCSearchPath;
558 /** The search path for ring-0 context modules (';' as separator). */
559 char *pszR0SearchPath;
560} PDMDEV;
561
562
563#if 0
564/**
565 * PDM Device, ring-0.
566 */
567typedef struct PDMDEVR0
568{
569 /** Pointer to the next device. */
570 R0PTRTYPE(PPDMDEVR0) pNext;
571 /** Device name length. (search optimization) */
572 uint32_t cchName;
573 /** Registration structure. */
574 R3PTRTYPE(const struct PDMDEVREGR0 *) pReg;
575 /** Number of instances. */
576 uint32_t cInstances;
577 /** Pointer to chain of instances. */
578 PPDMDEVINSR0 pInstances;
579} PDMDEVR0;
580#endif
581
582
583/**
584 * PDM USB Device.
585 */
586typedef struct PDMUSB
587{
588 /** Pointer to the next device (R3 Ptr). */
589 R3PTRTYPE(PPDMUSB) pNext;
590 /** Device name length. (search optimization) */
591 RTUINT cchName;
592 /** Registration structure. */
593 R3PTRTYPE(const struct PDMUSBREG *) pReg;
594 /** Next instance number. */
595 uint32_t iNextInstance;
596 /** Pointer to chain of instances (R3 Ptr). */
597 R3PTRTYPE(PPDMUSBINS) pInstances;
598} PDMUSB;
599
600
601/**
602 * PDM Driver.
603 */
604typedef struct PDMDRV
605{
606 /** Pointer to the next device. */
607 PPDMDRV pNext;
608 /** Registration structure. */
609 const struct PDMDRVREG * pReg;
610 /** Current number of instances. */
611 uint32_t cInstances;
612 /** The next instance number. */
613 uint32_t iNextInstance;
614 /** The search path for raw-mode context modules (';' as separator). */
615 char *pszRCSearchPath;
616 /** The search path for ring-0 context modules (';' as separator). */
617 char *pszR0SearchPath;
618} PDMDRV;
619
620
621/**
622 * PDM registered PIC device.
623 */
624typedef struct PDMPIC
625{
626 /** Pointer to the PIC device instance - R3. */
627 PPDMDEVINSR3 pDevInsR3;
628 /** @copydoc PDMPICREG::pfnSetIrqR3 */
629 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
630 /** @copydoc PDMPICREG::pfnGetInterruptR3 */
631 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
632
633 /** Pointer to the PIC device instance - R0. */
634 PPDMDEVINSR0 pDevInsR0;
635 /** @copydoc PDMPICREG::pfnSetIrqR3 */
636 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
637 /** @copydoc PDMPICREG::pfnGetInterruptR3 */
638 DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
639
640 /** Pointer to the PIC device instance - RC. */
641 PPDMDEVINSRC pDevInsRC;
642 /** @copydoc PDMPICREG::pfnSetIrqR3 */
643 DECLRCCALLBACKMEMBER(void, pfnSetIrqRC,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
644 /** @copydoc PDMPICREG::pfnGetInterruptR3 */
645 DECLRCCALLBACKMEMBER(int, pfnGetInterruptRC,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
646 /** Alignment padding. */
647 RTRCPTR RCPtrPadding;
648} PDMPIC;
649
650
651/**
652 * PDM registered APIC device.
653 */
654typedef struct PDMAPIC
655{
656 /** Pointer to the APIC device instance - R3 Ptr. */
657 PPDMDEVINSR3 pDevInsR3;
658 /** Pointer to the APIC device instance - R0 Ptr. */
659 PPDMDEVINSR0 pDevInsR0;
660 /** Pointer to the APIC device instance - RC Ptr. */
661 PPDMDEVINSRC pDevInsRC;
662 uint8_t Alignment[4];
663} PDMAPIC;
664
665
666/**
667 * PDM registered I/O APIC device.
668 */
669typedef struct PDMIOAPIC
670{
671 /** Pointer to the APIC device instance - R3 Ptr. */
672 PPDMDEVINSR3 pDevInsR3;
673 /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
674 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
675 /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
676 DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc));
677 /** @copydoc PDMIOAPICREG::pfnSetEoiR3 */
678 DECLR3CALLBACKMEMBER(int, pfnSetEoiR3,(PPDMDEVINS pDevIns, uint8_t u8Vector));
679
680 /** Pointer to the PIC device instance - R0. */
681 PPDMDEVINSR0 pDevInsR0;
682 /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
683 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
684 /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
685 DECLR0CALLBACKMEMBER(void, pfnSendMsiR0,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc));
686 /** @copydoc PDMIOAPICREG::pfnSetEoiR3 */
687 DECLR0CALLBACKMEMBER(int, pfnSetEoiR0,(PPDMDEVINS pDevIns, uint8_t u8Vector));
688
689 /** Pointer to the APIC device instance - RC Ptr. */
690 PPDMDEVINSRC pDevInsRC;
691 /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
692 DECLRCCALLBACKMEMBER(void, pfnSetIrqRC,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
693 /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
694 DECLRCCALLBACKMEMBER(void, pfnSendMsiRC,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc));
695 /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
696 DECLRCCALLBACKMEMBER(int, pfnSetEoiRC,(PPDMDEVINS pDevIns, uint8_t u8Vector));
697} PDMIOAPIC;
698
699/** Maximum number of PCI busses for a VM. */
700#define PDM_PCI_BUSSES_MAX 8
701
702
703#ifdef IN_RING3
704/**
705 * PDM registered firmware device.
706 */
707typedef struct PDMFW
708{
709 /** Pointer to the firmware device instance. */
710 PPDMDEVINSR3 pDevIns;
711 /** Copy of the registration structure. */
712 PDMFWREG Reg;
713} PDMFW;
714/** Pointer to a firmware instance. */
715typedef PDMFW *PPDMFW;
716#endif
717
718
719/**
720 * PDM PCI bus instance.
721 */
722typedef struct PDMPCIBUS
723{
724 /** PCI bus number. */
725 uint32_t iBus;
726 uint32_t uPadding0; /**< Alignment padding.*/
727
728 /** Pointer to PCI bus device instance. */
729 PPDMDEVINSR3 pDevInsR3;
730 /** @copydoc PDMPCIBUSREGR3::pfnSetIrqR3 */
731 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
732
733 /** @copydoc PDMPCIBUSREGR3::pfnRegisterR3 */
734 DECLR3CALLBACKMEMBER(int, pfnRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
735 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName));
736 /** @copydoc PDMPCIBUSREGR3::pfnRegisterMsiR3 */
737 DECLR3CALLBACKMEMBER(int, pfnRegisterMsi,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg));
738 /** @copydoc PDMPCIBUSREGR3::pfnIORegionRegisterR3 */
739 DECLR3CALLBACKMEMBER(int, pfnIORegionRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iRegion, RTGCPHYS cbRegion,
740 PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
741 /** @copydoc PDMPCIBUSREGR3::pfnInterceptConfigAccesses */
742 DECLR3CALLBACKMEMBER(void, pfnInterceptConfigAccesses,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
743 PFNPCICONFIGREAD pfnRead, PFNPCICONFIGWRITE pfnWrite));
744 /** @copydoc PDMPCIBUSREGR3::pfnConfigWrite */
745 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnConfigWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
746 uint32_t uAddress, unsigned cb, uint32_t u32Value));
747 /** @copydoc PDMPCIBUSREGR3::pfnConfigRead */
748 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnConfigRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
749 uint32_t uAddress, unsigned cb, uint32_t *pu32Value));
750} PDMPCIBUS;
751
752
753/**
754 * Ring-0 PDM PCI bus instance data.
755 */
756typedef struct PDMPCIBUSR0
757{
758 /** PCI bus number. */
759 uint32_t iBus;
760 uint32_t uPadding0; /**< Alignment padding.*/
761 /** Pointer to PCI bus device instance. */
762 PPDMDEVINSR0 pDevInsR0;
763 /** @copydoc PDMPCIBUSREGR0::pfnSetIrq */
764 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
765} PDMPCIBUSR0;
766/** Pointer to the ring-0 PCI bus data. */
767typedef PDMPCIBUSR0 *PPDMPCIBUSR0;
768
769#ifdef IN_RING3
770/**
771 * PDM registered DMAC (DMA Controller) device.
772 */
773typedef struct PDMDMAC
774{
775 /** Pointer to the DMAC device instance. */
776 PPDMDEVINSR3 pDevIns;
777 /** Copy of the registration structure. */
778 PDMDMACREG Reg;
779} PDMDMAC;
780
781
782/**
783 * PDM registered RTC (Real Time Clock) device.
784 */
785typedef struct PDMRTC
786{
787 /** Pointer to the RTC device instance. */
788 PPDMDEVINSR3 pDevIns;
789 /** Copy of the registration structure. */
790 PDMRTCREG Reg;
791} PDMRTC;
792
793#endif /* IN_RING3 */
794
795/**
796 * Module type.
797 */
798typedef enum PDMMODTYPE
799{
800 /** Raw-mode (RC) context module. */
801 PDMMOD_TYPE_RC,
802 /** Ring-0 (host) context module. */
803 PDMMOD_TYPE_R0,
804 /** Ring-3 (host) context module. */
805 PDMMOD_TYPE_R3
806} PDMMODTYPE;
807
808
809/** The module name length including the terminator. */
810#define PDMMOD_NAME_LEN 32
811
812/**
813 * Loaded module instance.
814 */
815typedef struct PDMMOD
816{
817 /** Module name. This is used for referring to
818 * the module internally, sort of like a handle. */
819 char szName[PDMMOD_NAME_LEN];
820 /** Module type. */
821 PDMMODTYPE eType;
822 /** Loader module handle. Not used for R0 modules. */
823 RTLDRMOD hLdrMod;
824 /** Loaded address.
825 * This is the 'handle' for R0 modules. */
826 RTUINTPTR ImageBase;
827 /** Old loaded address.
828 * This is used during relocation of GC modules. Not used for R0 modules. */
829 RTUINTPTR OldImageBase;
830 /** Where the R3 HC bits are stored.
831 * This can be equal to ImageBase but doesn't have to. Not used for R0 modules. */
832 void *pvBits;
833
834 /** Pointer to next module. */
835 struct PDMMOD *pNext;
836 /** Module filename. */
837 char szFilename[1];
838} PDMMOD;
839/** Pointer to loaded module instance. */
840typedef PDMMOD *PPDMMOD;
841
842
843
844/** Extra space in the free array. */
845#define PDMQUEUE_FREE_SLACK 16
846
847/**
848 * Queue type.
849 */
850typedef enum PDMQUEUETYPE
851{
852 /** Device consumer. */
853 PDMQUEUETYPE_DEV = 1,
854 /** Driver consumer. */
855 PDMQUEUETYPE_DRV,
856 /** Internal consumer. */
857 PDMQUEUETYPE_INTERNAL,
858 /** External consumer. */
859 PDMQUEUETYPE_EXTERNAL
860} PDMQUEUETYPE;
861
862/** Pointer to a PDM Queue. */
863typedef struct PDMQUEUE *PPDMQUEUE;
864
865/**
866 * PDM Queue.
867 */
868typedef struct PDMQUEUE
869{
870 /** Pointer to the next queue in the list. */
871 R3PTRTYPE(PPDMQUEUE) pNext;
872 /** Type specific data. */
873 union
874 {
875 /** PDMQUEUETYPE_DEV */
876 struct
877 {
878 /** Pointer to consumer function. */
879 R3PTRTYPE(PFNPDMQUEUEDEV) pfnCallback;
880 /** Pointer to the device instance owning the queue. */
881 R3PTRTYPE(PPDMDEVINS) pDevIns;
882 } Dev;
883 /** PDMQUEUETYPE_DRV */
884 struct
885 {
886 /** Pointer to consumer function. */
887 R3PTRTYPE(PFNPDMQUEUEDRV) pfnCallback;
888 /** Pointer to the driver instance owning the queue. */
889 R3PTRTYPE(PPDMDRVINS) pDrvIns;
890 } Drv;
891 /** PDMQUEUETYPE_INTERNAL */
892 struct
893 {
894 /** Pointer to consumer function. */
895 R3PTRTYPE(PFNPDMQUEUEINT) pfnCallback;
896 } Int;
897 /** PDMQUEUETYPE_EXTERNAL */
898 struct
899 {
900 /** Pointer to consumer function. */
901 R3PTRTYPE(PFNPDMQUEUEEXT) pfnCallback;
902 /** Pointer to user argument. */
903 R3PTRTYPE(void *) pvUser;
904 } Ext;
905 } u;
906 /** Queue type. */
907 PDMQUEUETYPE enmType;
908 /** The interval between checking the queue for events.
909 * The realtime timer below is used to do the waiting.
910 * If 0, the queue will use the VM_FF_PDM_QUEUE forced action. */
911 uint32_t cMilliesInterval;
912 /** Interval timer. Only used if cMilliesInterval is non-zero. */
913 PTMTIMERR3 pTimer;
914 /** Pointer to the VM - R3. */
915 PVMR3 pVMR3;
916 /** LIFO of pending items - R3. */
917 R3PTRTYPE(PPDMQUEUEITEMCORE) volatile pPendingR3;
918 /** Pointer to the VM - R0. */
919 PVMR0 pVMR0;
920 /** LIFO of pending items - R0. */
921 R0PTRTYPE(PPDMQUEUEITEMCORE) volatile pPendingR0;
922 /** Pointer to the GC VM and indicator for GC enabled queue.
923 * If this is NULL, the queue cannot be used in GC.
924 */
925 PVMRC pVMRC;
926 /** LIFO of pending items - GC. */
927 RCPTRTYPE(PPDMQUEUEITEMCORE) volatile pPendingRC;
928
929 /** Item size (bytes). */
930 uint32_t cbItem;
931 /** Number of items in the queue. */
932 uint32_t cItems;
933 /** Index to the free head (where we insert). */
934 uint32_t volatile iFreeHead;
935 /** Index to the free tail (where we remove). */
936 uint32_t volatile iFreeTail;
937
938 /** Unique queue name. */
939 R3PTRTYPE(const char *) pszName;
940#if HC_ARCH_BITS == 32
941 RTR3PTR Alignment1;
942#endif
943 /** Stat: Times PDMQueueAlloc fails. */
944 STAMCOUNTER StatAllocFailures;
945 /** Stat: PDMQueueInsert calls. */
946 STAMCOUNTER StatInsert;
947 /** Stat: Queue flushes. */
948 STAMCOUNTER StatFlush;
949 /** Stat: Queue flushes with pending items left over. */
950 STAMCOUNTER StatFlushLeftovers;
951#ifdef VBOX_WITH_STATISTICS
952 /** State: Profiling the flushing. */
953 STAMPROFILE StatFlushPrf;
954 /** State: Pending items. */
955 uint32_t volatile cStatPending;
956 uint32_t volatile cAlignment;
957#endif
958
959 /** Array of pointers to free items. Variable size. */
960 struct PDMQUEUEFREEITEM
961 {
962 /** Pointer to the free item - HC Ptr. */
963 R3PTRTYPE(PPDMQUEUEITEMCORE) volatile pItemR3;
964 /** Pointer to the free item - HC Ptr. */
965 R0PTRTYPE(PPDMQUEUEITEMCORE) volatile pItemR0;
966 /** Pointer to the free item - GC Ptr. */
967 RCPTRTYPE(PPDMQUEUEITEMCORE) volatile pItemRC;
968#if HC_ARCH_BITS == 64
969 RTRCPTR Alignment0;
970#endif
971 } aFreeItems[1];
972} PDMQUEUE;
973
974/** @name PDM::fQueueFlushing
975 * @{ */
976/** Used to make sure only one EMT will flush the queues.
977 * Set when an EMT is flushing queues, clear otherwise. */
978#define PDM_QUEUE_FLUSH_FLAG_ACTIVE_BIT 0
979/** Indicating there are queues with items pending.
980 * This is make sure we don't miss inserts happening during flushing. The FF
981 * cannot be used for this since it has to be cleared immediately to prevent
982 * other EMTs from spinning. */
983#define PDM_QUEUE_FLUSH_FLAG_PENDING_BIT 1
984/** @} */
985
986
987/**
988 * Queue device helper task operation.
989 */
990typedef enum PDMDEVHLPTASKOP
991{
992 /** The usual invalid 0 entry. */
993 PDMDEVHLPTASKOP_INVALID = 0,
994 /** ISASetIrq */
995 PDMDEVHLPTASKOP_ISA_SET_IRQ,
996 /** PCISetIrq */
997 PDMDEVHLPTASKOP_PCI_SET_IRQ,
998 /** PCISetIrq */
999 PDMDEVHLPTASKOP_IOAPIC_SET_IRQ,
1000 /** The usual 32-bit hack. */
1001 PDMDEVHLPTASKOP_32BIT_HACK = 0x7fffffff
1002} PDMDEVHLPTASKOP;
1003
1004/**
1005 * Queued Device Helper Task.
1006 */
1007typedef struct PDMDEVHLPTASK
1008{
1009 /** The queue item core (don't touch). */
1010 PDMQUEUEITEMCORE Core;
1011 /** Pointer to the device instance (R3 Ptr). */
1012 PPDMDEVINSR3 pDevInsR3;
1013 /** This operation to perform. */
1014 PDMDEVHLPTASKOP enmOp;
1015#if HC_ARCH_BITS == 64
1016 uint32_t Alignment0;
1017#endif
1018 /** Parameters to the operation. */
1019 union PDMDEVHLPTASKPARAMS
1020 {
1021 /**
1022 * PDMDEVHLPTASKOP_ISA_SET_IRQ and PDMDEVHLPTASKOP_IOAPIC_SET_IRQ.
1023 */
1024 struct PDMDEVHLPTASKISASETIRQ
1025 {
1026 /** The IRQ */
1027 int iIrq;
1028 /** The new level. */
1029 int iLevel;
1030 /** The IRQ tag and source. */
1031 uint32_t uTagSrc;
1032 } IsaSetIRQ, IoApicSetIRQ;
1033
1034 /**
1035 * PDMDEVHLPTASKOP_PCI_SET_IRQ
1036 */
1037 struct PDMDEVHLPTASKPCISETIRQ
1038 {
1039 /** Pointer to the PCI device (R3 Ptr). */
1040 R3PTRTYPE(PPDMPCIDEV) pPciDevR3;
1041 /** The IRQ */
1042 int iIrq;
1043 /** The new level. */
1044 int iLevel;
1045 /** The IRQ tag and source. */
1046 uint32_t uTagSrc;
1047 } PciSetIRQ;
1048
1049 /** Expanding the structure. */
1050 uint64_t au64[3];
1051 } u;
1052} PDMDEVHLPTASK;
1053/** Pointer to a queued Device Helper Task. */
1054typedef PDMDEVHLPTASK *PPDMDEVHLPTASK;
1055/** Pointer to a const queued Device Helper Task. */
1056typedef const PDMDEVHLPTASK *PCPDMDEVHLPTASK;
1057
1058
1059
1060/**
1061 * An USB hub registration record.
1062 */
1063typedef struct PDMUSBHUB
1064{
1065 /** The USB versions this hub support.
1066 * Note that 1.1 hubs can take on 2.0 devices. */
1067 uint32_t fVersions;
1068 /** The number of ports on the hub. */
1069 uint32_t cPorts;
1070 /** The number of available ports (0..cPorts). */
1071 uint32_t cAvailablePorts;
1072 /** The driver instance of the hub. */
1073 PPDMDRVINS pDrvIns;
1074 /** Copy of the to the registration structure. */
1075 PDMUSBHUBREG Reg;
1076
1077 /** Pointer to the next hub in the list. */
1078 struct PDMUSBHUB *pNext;
1079} PDMUSBHUB;
1080
1081/** Pointer to a const USB HUB registration record. */
1082typedef const PDMUSBHUB *PCPDMUSBHUB;
1083
1084/** Pointer to a PDM Async I/O template. */
1085typedef struct PDMASYNCCOMPLETIONTEMPLATE *PPDMASYNCCOMPLETIONTEMPLATE;
1086
1087/** Pointer to the main PDM Async completion endpoint class. */
1088typedef struct PDMASYNCCOMPLETIONEPCLASS *PPDMASYNCCOMPLETIONEPCLASS;
1089
1090/** Pointer to the global block cache structure. */
1091typedef struct PDMBLKCACHEGLOBAL *PPDMBLKCACHEGLOBAL;
1092
1093/**
1094 * PDM VMCPU Instance data.
1095 * Changes to this must checked against the padding of the pdm union in VMCPU!
1096 */
1097typedef struct PDMCPU
1098{
1099 /** The number of entries in the apQueuedCritSectsLeaves table that's currently
1100 * in use. */
1101 uint32_t cQueuedCritSectLeaves;
1102 uint32_t uPadding0; /**< Alignment padding.*/
1103 /** Critical sections queued in RC/R0 because of contention preventing leave to
1104 * complete. (R3 Ptrs)
1105 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */
1106 R3PTRTYPE(PPDMCRITSECT) apQueuedCritSectLeaves[8];
1107
1108 /** The number of entries in the apQueuedCritSectRwExclLeaves table that's
1109 * currently in use. */
1110 uint32_t cQueuedCritSectRwExclLeaves;
1111 uint32_t uPadding1; /**< Alignment padding.*/
1112 /** Read/write critical sections queued in RC/R0 because of contention
1113 * preventing exclusive leave to complete. (R3 Ptrs)
1114 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */
1115 R3PTRTYPE(PPDMCRITSECTRW) apQueuedCritSectRwExclLeaves[8];
1116
1117 /** The number of entries in the apQueuedCritSectsRwShrdLeaves table that's
1118 * currently in use. */
1119 uint32_t cQueuedCritSectRwShrdLeaves;
1120 uint32_t uPadding2; /**< Alignment padding.*/
1121 /** Read/write critical sections queued in RC/R0 because of contention
1122 * preventing shared leave to complete. (R3 Ptrs)
1123 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */
1124 R3PTRTYPE(PPDMCRITSECTRW) apQueuedCritSectRwShrdLeaves[8];
1125} PDMCPU;
1126
1127
1128/**
1129 * PDM VM Instance data.
1130 * Changes to this must checked against the padding of the cfgm union in VM!
1131 */
1132typedef struct PDM
1133{
1134 /** The PDM lock.
1135 * This is used to protect everything that deals with interrupts, i.e.
1136 * the PIC, APIC, IOAPIC and PCI devices plus some PDM functions. */
1137 PDMCRITSECT CritSect;
1138 /** The NOP critical section.
1139 * This is a dummy critical section that will not do any thread
1140 * serialization but instead let all threads enter immediately and
1141 * concurrently. */
1142 PDMCRITSECT NopCritSect;
1143
1144 /** List of registered devices. (FIFO) */
1145 R3PTRTYPE(PPDMDEV) pDevs;
1146 /** List of devices instances. (FIFO) */
1147 R3PTRTYPE(PPDMDEVINS) pDevInstances;
1148 /** List of registered USB devices. (FIFO) */
1149 R3PTRTYPE(PPDMUSB) pUsbDevs;
1150 /** List of USB devices instances. (FIFO) */
1151 R3PTRTYPE(PPDMUSBINS) pUsbInstances;
1152 /** List of registered drivers. (FIFO) */
1153 R3PTRTYPE(PPDMDRV) pDrvs;
1154 /** The registered firmware device (can be NULL). */
1155 R3PTRTYPE(PPDMFW) pFirmware;
1156 /** PCI Buses. */
1157 PDMPCIBUS aPciBuses[PDM_PCI_BUSSES_MAX];
1158 /** The register PIC device. */
1159 PDMPIC Pic;
1160 /** The registered APIC device. */
1161 PDMAPIC Apic;
1162 /** The registered I/O APIC device. */
1163 PDMIOAPIC IoApic;
1164 /** The registered DMAC device. */
1165 R3PTRTYPE(PPDMDMAC) pDmac;
1166 /** The registered RTC device. */
1167 R3PTRTYPE(PPDMRTC) pRtc;
1168 /** The registered USB HUBs. (FIFO) */
1169 R3PTRTYPE(PPDMUSBHUB) pUsbHubs;
1170
1171 /** Queue in which devhlp tasks are queued for R3 execution - R3 Ptr. */
1172 R3PTRTYPE(PPDMQUEUE) pDevHlpQueueR3;
1173 /** Queue in which devhlp tasks are queued for R3 execution - R0 Ptr. */
1174 R0PTRTYPE(PPDMQUEUE) pDevHlpQueueR0;
1175 /** Queue in which devhlp tasks are queued for R3 execution - RC Ptr. */
1176 RCPTRTYPE(PPDMQUEUE) pDevHlpQueueRC;
1177 /** Pointer to the queue which should be manually flushed - RC Ptr.
1178 * Only touched by EMT. */
1179 RCPTRTYPE(struct PDMQUEUE *) pQueueFlushRC;
1180 /** Pointer to the queue which should be manually flushed - R0 Ptr.
1181 * Only touched by EMT. */
1182 R0PTRTYPE(struct PDMQUEUE *) pQueueFlushR0;
1183 /** Bitmask controlling the queue flushing.
1184 * See PDM_QUEUE_FLUSH_FLAG_ACTIVE and PDM_QUEUE_FLUSH_FLAG_PENDING. */
1185 uint32_t volatile fQueueFlushing;
1186
1187 /** The current IRQ tag (tracing purposes). */
1188 uint32_t volatile uIrqTag;
1189
1190 /** Pending reset flags (PDMVMRESET_F_XXX). */
1191 uint32_t volatile fResetFlags;
1192
1193 /** Set by pdmR3LoadExec for use in assertions. */
1194 bool fStateLoaded;
1195 /** Alignment padding. */
1196 bool afPadding[3];
1197
1198 /** The tracing ID of the next device instance.
1199 *
1200 * @remarks We keep the device tracing ID seperate from the rest as these are
1201 * then more likely to end up with the same ID from one run to
1202 * another, making analysis somewhat easier. Drivers and USB devices
1203 * are more volatile and can be changed at runtime, thus these are much
1204 * less likely to remain stable, so just heap them all together. */
1205 uint32_t idTracingDev;
1206 /** The tracing ID of the next driver instance, USB device instance or other
1207 * PDM entity requiring an ID. */
1208 uint32_t idTracingOther;
1209
1210 /** @name VMM device heap
1211 * @{ */
1212 /** The heap size. */
1213 uint32_t cbVMMDevHeap;
1214 /** Free space. */
1215 uint32_t cbVMMDevHeapLeft;
1216 /** Pointer to the heap base (MMIO2 ring-3 mapping). NULL if not registered. */
1217 RTR3PTR pvVMMDevHeap;
1218 /** Ring-3 mapping/unmapping notification callback for the user. */
1219 PFNPDMVMMDEVHEAPNOTIFY pfnVMMDevHeapNotify;
1220 /** The current mapping. NIL_RTGCPHYS if not mapped or registered. */
1221 RTGCPHYS GCPhysVMMDevHeap;
1222 /** @} */
1223
1224 /** Number of times a critical section leave request needed to be queued for ring-3 execution. */
1225 STAMCOUNTER StatQueuedCritSectLeaves;
1226} PDM;
1227AssertCompileMemberAlignment(PDM, GCPhysVMMDevHeap, sizeof(RTGCPHYS));
1228AssertCompileMemberAlignment(PDM, CritSect, 8);
1229AssertCompileMemberAlignment(PDM, StatQueuedCritSectLeaves, 8);
1230/** Pointer to PDM VM instance data. */
1231typedef PDM *PPDM;
1232
1233
1234/**
1235 * PDM data kept in the ring-0 GVM.
1236 */
1237typedef struct PDMR0PERVM
1238{
1239 /** PCI Buses, ring-0 data. */
1240 PDMPCIBUSR0 aPciBuses[PDM_PCI_BUSSES_MAX];
1241 /** Number of valid ring-0 device instances (apDevInstances). */
1242 uint32_t cDevInstances;
1243 uint32_t u32Padding;
1244 /** Pointer to ring-0 device instances. */
1245 R0PTRTYPE(struct PDMDEVINSR0 *) apDevInstances[190];
1246} PDMR0PERVM;
1247
1248
1249/**
1250 * PDM data kept in the UVM.
1251 */
1252typedef struct PDMUSERPERVM
1253{
1254 /** @todo move more stuff over here. */
1255
1256 /** Linked list of timer driven PDM queues.
1257 * Currently serialized by PDM::CritSect. */
1258 R3PTRTYPE(struct PDMQUEUE *) pQueuesTimer;
1259 /** Linked list of force action driven PDM queues.
1260 * Currently serialized by PDM::CritSect. */
1261 R3PTRTYPE(struct PDMQUEUE *) pQueuesForced;
1262
1263 /** Lock protecting the lists below it. */
1264 RTCRITSECT ListCritSect;
1265 /** Pointer to list of loaded modules. */
1266 PPDMMOD pModules;
1267 /** List of initialized critical sections. (LIFO) */
1268 R3PTRTYPE(PPDMCRITSECTINT) pCritSects;
1269 /** List of initialized read/write critical sections. (LIFO) */
1270 R3PTRTYPE(PPDMCRITSECTRWINT) pRwCritSects;
1271 /** Head of the PDM Thread list. (singly linked) */
1272 R3PTRTYPE(PPDMTHREAD) pThreads;
1273 /** Tail of the PDM Thread list. (singly linked) */
1274 R3PTRTYPE(PPDMTHREAD) pThreadsTail;
1275
1276 /** @name PDM Async Completion
1277 * @{ */
1278 /** Pointer to the array of supported endpoint classes. */
1279 PPDMASYNCCOMPLETIONEPCLASS apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_MAX];
1280 /** Head of the templates. Singly linked, protected by ListCritSect. */
1281 R3PTRTYPE(PPDMASYNCCOMPLETIONTEMPLATE) pAsyncCompletionTemplates;
1282 /** @} */
1283
1284 /** Global block cache data. */
1285 R3PTRTYPE(PPDMBLKCACHEGLOBAL) pBlkCacheGlobal;
1286#ifdef VBOX_WITH_NETSHAPER
1287 /** Pointer to network shaper instance. */
1288 R3PTRTYPE(PPDMNETSHAPER) pNetShaper;
1289#endif /* VBOX_WITH_NETSHAPER */
1290
1291} PDMUSERPERVM;
1292/** Pointer to the PDM data kept in the UVM. */
1293typedef PDMUSERPERVM *PPDMUSERPERVM;
1294
1295
1296
1297/*******************************************************************************
1298* Global Variables *
1299*******************************************************************************/
1300#ifdef IN_RING3
1301extern const PDMDRVHLPR3 g_pdmR3DrvHlp;
1302extern const PDMDEVHLPR3 g_pdmR3DevHlpTrusted;
1303extern const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted;
1304extern const PDMPICHLPR3 g_pdmR3DevPicHlp;
1305extern const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp;
1306extern const PDMFWHLPR3 g_pdmR3DevFirmwareHlp;
1307extern const PDMPCIHLPR3 g_pdmR3DevPciHlp;
1308extern const PDMDMACHLP g_pdmR3DevDmacHlp;
1309extern const PDMRTCHLP g_pdmR3DevRtcHlp;
1310extern const PDMHPETHLPR3 g_pdmR3DevHpetHlp;
1311extern const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp;
1312#endif
1313
1314
1315/*******************************************************************************
1316* Defined Constants And Macros *
1317*******************************************************************************/
1318/** @def PDMDEV_ASSERT_DEVINS
1319 * Asserts the validity of the device instance.
1320 */
1321#ifdef VBOX_STRICT
1322# define PDMDEV_ASSERT_DEVINS(pDevIns) \
1323 do { \
1324 AssertPtr(pDevIns); \
1325 Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \
1326 Assert(pDevIns->CTX_SUFF(pvInstanceDataFor) == (void *)&pDevIns->achInstanceData[0]); \
1327 } while (0)
1328#else
1329# define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0)
1330#endif
1331
1332/** @def PDMDRV_ASSERT_DRVINS
1333 * Asserts the validity of the driver instance.
1334 */
1335#ifdef VBOX_STRICT
1336# define PDMDRV_ASSERT_DRVINS(pDrvIns) \
1337 do { \
1338 AssertPtr(pDrvIns); \
1339 Assert(pDrvIns->u32Version == PDM_DRVINS_VERSION); \
1340 Assert(pDrvIns->CTX_SUFF(pvInstanceData) == (void *)&pDrvIns->achInstanceData[0]); \
1341 } while (0)
1342#else
1343# define PDMDRV_ASSERT_DRVINS(pDrvIns) do { } while (0)
1344#endif
1345
1346
1347/*******************************************************************************
1348* Internal Functions *
1349*******************************************************************************/
1350#ifdef IN_RING3
1351bool pdmR3IsValidName(const char *pszName);
1352
1353int pdmR3CritSectBothInitStats(PVM pVM);
1354void pdmR3CritSectBothRelocate(PVM pVM);
1355int pdmR3CritSectBothDeleteDevice(PVM pVM, PPDMDEVINS pDevIns);
1356int pdmR3CritSectBothDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns);
1357int pdmR3CritSectInitDevice( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
1358 const char *pszNameFmt, va_list va);
1359int pdmR3CritSectInitDeviceAuto( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
1360 const char *pszNameFmt, ...);
1361int pdmR3CritSectInitDriver( PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
1362 const char *pszNameFmt, ...);
1363int pdmR3CritSectRwInitDevice( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
1364 const char *pszNameFmt, va_list va);
1365int pdmR3CritSectRwInitDeviceAuto( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
1366 const char *pszNameFmt, ...);
1367int pdmR3CritSectRwInitDriver( PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
1368 const char *pszNameFmt, ...);
1369
1370int pdmR3DevInit(PVM pVM);
1371int pdmR3DevInitComplete(PVM pVM);
1372PPDMDEV pdmR3DevLookup(PVM pVM, const char *pszName);
1373int pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);
1374DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem);
1375
1376int pdmR3UsbLoadModules(PVM pVM);
1377int pdmR3UsbInstantiateDevices(PVM pVM);
1378PPDMUSB pdmR3UsbLookup(PVM pVM, const char *pszName);
1379int pdmR3UsbRegisterHub(PVM pVM, PPDMDRVINS pDrvIns, uint32_t fVersions, uint32_t cPorts, PCPDMUSBHUBREG pUsbHubReg, PPCPDMUSBHUBHLP ppUsbHubHlp);
1380int pdmR3UsbVMInitComplete(PVM pVM);
1381
1382int pdmR3DrvInit(PVM pVM);
1383int pdmR3DrvInstantiate(PVM pVM, PCFGMNODE pNode, PPDMIBASE pBaseInterface, PPDMDRVINS pDrvAbove,
1384 PPDMLUN pLun, PPDMIBASE *ppBaseInterface);
1385int pdmR3DrvDetach(PPDMDRVINS pDrvIns, uint32_t fFlags);
1386void pdmR3DrvDestroyChain(PPDMDRVINS pDrvIns, uint32_t fFlags);
1387PPDMDRV pdmR3DrvLookup(PVM pVM, const char *pszName);
1388
1389int pdmR3LdrInitU(PUVM pUVM);
1390void pdmR3LdrTermU(PUVM pUVM);
1391char *pdmR3FileR3(const char *pszFile, bool fShared);
1392int pdmR3LoadR3U(PUVM pUVM, const char *pszFilename, const char *pszName);
1393
1394void pdmR3QueueRelocate(PVM pVM, RTGCINTPTR offDelta);
1395
1396int pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
1397 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1398int pdmR3ThreadCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
1399 PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1400int pdmR3ThreadCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
1401 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1402int pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
1403int pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
1404int pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
1405void pdmR3ThreadDestroyAll(PVM pVM);
1406int pdmR3ThreadResumeAll(PVM pVM);
1407int pdmR3ThreadSuspendAll(PVM pVM);
1408
1409#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
1410int pdmR3AsyncCompletionInit(PVM pVM);
1411int pdmR3AsyncCompletionTerm(PVM pVM);
1412void pdmR3AsyncCompletionResume(PVM pVM);
1413int pdmR3AsyncCompletionTemplateCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDEV pfnCompleted, const char *pszDesc);
1414int pdmR3AsyncCompletionTemplateCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
1415 PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc);
1416int pdmR3AsyncCompletionTemplateCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEUSB pfnCompleted, const char *pszDesc);
1417int pdmR3AsyncCompletionTemplateDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
1418int pdmR3AsyncCompletionTemplateDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
1419int pdmR3AsyncCompletionTemplateDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
1420#endif
1421
1422#ifdef VBOX_WITH_NETSHAPER
1423int pdmR3NetShaperInit(PVM pVM);
1424int pdmR3NetShaperTerm(PVM pVM);
1425#endif
1426
1427int pdmR3BlkCacheInit(PVM pVM);
1428void pdmR3BlkCacheTerm(PVM pVM);
1429int pdmR3BlkCacheResume(PVM pVM);
1430
1431#endif /* IN_RING3 */
1432
1433void pdmLock(PVMCC pVM);
1434int pdmLockEx(PVMCC pVM, int rc);
1435void pdmUnlock(PVMCC pVM);
1436
1437#if defined(IN_RING3) || defined(IN_RING0)
1438void pdmCritSectRwLeaveSharedQueued(PPDMCRITSECTRW pThis);
1439void pdmCritSectRwLeaveExclQueued(PPDMCRITSECTRW pThis);
1440#endif
1441
1442/** @} */
1443
1444RT_C_DECLS_END
1445
1446#endif /* !VMM_INCLUDED_SRC_include_PDMInternal_h */
1447
Note: See TracBrowser for help on using the repository browser.

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