VirtualBox

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

最後變更 在這個檔案從81153是 81031,由 vboxsync 提交於 5 年 前

PDM,Devices: Moving the PDMPCIDEV structures into the PDMDEVINS allocation. Preps for extending the config space to 4KB. bugref:9218

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

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