VirtualBox

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

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

PDMR3Task: execution thread fix. bugref:9218

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