VirtualBox

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

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

PDM: Introducing a asynchronous ring-3 task concept to alliviate the places where we use single item PDM queues to trigger ring-3 work from ring-0 (and formerly raw-mode). Untested code, not enabled yet. bugref:9218

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 56.7 KB
Line 
1/* $Id: PDMInternal.h 81390 2019-10-20 23:50:44Z 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} PDMTASK;
1000/** Pointer to a PDM task. */
1001typedef PDMTASK *PPDMTASK;
1002
1003/**
1004 * A task set.
1005 *
1006 * This is served by one task executor thread.
1007 */
1008typedef struct PDMTASKSET
1009{
1010 /** Magic value (PDMTASKSET_MAGIC). */
1011 uint32_t u32Magic;
1012 /** Set if this task set works for ring-0 and raw-mode. */
1013 bool fRZEnabled;
1014 /** Number of allocated taks. */
1015 uint8_t volatile cAllocated;
1016 /** Base handle value for this set. */
1017 uint16_t uHandleBase;
1018 /** The task executor thread. */
1019 R3PTRTYPE(RTTHREAD) hThread;
1020 /** Event semaphore for waking up the thread when fRZEnabled is set. */
1021 SUPSEMEVENT hEventR0;
1022 /** Event semaphore for waking up the thread when fRZEnabled is clear. */
1023 R3PTRTYPE(RTSEMEVENT) hEventR3;
1024 /** Padding so fTriggered is in its own cacheline. */
1025 uint64_t au64Padding2[4];
1026
1027 /** Bitmask of triggered tasks. */
1028 uint64_t volatile fTriggered;
1029 /** Shutdown thread indicator. */
1030 bool volatile fShutdown;
1031 /** Padding. */
1032 bool volatile afPadding3[3];
1033 /** Task currently running, UINT32_MAX if idle. */
1034 uint32_t volatile idxRunning;
1035 /** Padding so fTriggered and fShutdown are in their own cacheline. */
1036 uint64_t volatile au64Padding3[6];
1037
1038 /** The individual tasks. (Unallocated tasks have NULL pvOwner.) */
1039 PDMTASK aTasks[64];
1040} PDMTASKSET;
1041AssertCompileMemberAlignment(PDMTASKSET, fTriggered, 64);
1042AssertCompileMemberAlignment(PDMTASKSET, aTasks, 64);
1043/** Magic value for PDMTASKSET::u32Magic. */
1044#define PDMTASKSET_MAGIC UINT32_C(0x19320314)
1045/** Pointer to a task set. */
1046typedef PDMTASKSET *PPDMTASKSET;
1047
1048/** @} */
1049
1050
1051/**
1052 * Queue device helper task operation.
1053 */
1054typedef enum PDMDEVHLPTASKOP
1055{
1056 /** The usual invalid 0 entry. */
1057 PDMDEVHLPTASKOP_INVALID = 0,
1058 /** ISASetIrq */
1059 PDMDEVHLPTASKOP_ISA_SET_IRQ,
1060 /** PCISetIrq */
1061 PDMDEVHLPTASKOP_PCI_SET_IRQ,
1062 /** PCISetIrq */
1063 PDMDEVHLPTASKOP_IOAPIC_SET_IRQ,
1064 /** The usual 32-bit hack. */
1065 PDMDEVHLPTASKOP_32BIT_HACK = 0x7fffffff
1066} PDMDEVHLPTASKOP;
1067
1068/**
1069 * Queued Device Helper Task.
1070 */
1071typedef struct PDMDEVHLPTASK
1072{
1073 /** The queue item core (don't touch). */
1074 PDMQUEUEITEMCORE Core;
1075 /** Pointer to the device instance (R3 Ptr). */
1076 PPDMDEVINSR3 pDevInsR3;
1077 /** This operation to perform. */
1078 PDMDEVHLPTASKOP enmOp;
1079#if HC_ARCH_BITS == 64
1080 uint32_t Alignment0;
1081#endif
1082 /** Parameters to the operation. */
1083 union PDMDEVHLPTASKPARAMS
1084 {
1085 /**
1086 * PDMDEVHLPTASKOP_ISA_SET_IRQ and PDMDEVHLPTASKOP_IOAPIC_SET_IRQ.
1087 */
1088 struct PDMDEVHLPTASKISASETIRQ
1089 {
1090 /** The IRQ */
1091 int iIrq;
1092 /** The new level. */
1093 int iLevel;
1094 /** The IRQ tag and source. */
1095 uint32_t uTagSrc;
1096 } IsaSetIRQ, IoApicSetIRQ;
1097
1098 /**
1099 * PDMDEVHLPTASKOP_PCI_SET_IRQ
1100 */
1101 struct PDMDEVHLPTASKPCISETIRQ
1102 {
1103 /** Pointer to the PCI device (R3 Ptr). */
1104 R3PTRTYPE(PPDMPCIDEV) pPciDevR3;
1105 /** The IRQ */
1106 int iIrq;
1107 /** The new level. */
1108 int iLevel;
1109 /** The IRQ tag and source. */
1110 uint32_t uTagSrc;
1111 } PciSetIRQ;
1112
1113 /** Expanding the structure. */
1114 uint64_t au64[3];
1115 } u;
1116} PDMDEVHLPTASK;
1117/** Pointer to a queued Device Helper Task. */
1118typedef PDMDEVHLPTASK *PPDMDEVHLPTASK;
1119/** Pointer to a const queued Device Helper Task. */
1120typedef const PDMDEVHLPTASK *PCPDMDEVHLPTASK;
1121
1122
1123
1124/**
1125 * An USB hub registration record.
1126 */
1127typedef struct PDMUSBHUB
1128{
1129 /** The USB versions this hub support.
1130 * Note that 1.1 hubs can take on 2.0 devices. */
1131 uint32_t fVersions;
1132 /** The number of ports on the hub. */
1133 uint32_t cPorts;
1134 /** The number of available ports (0..cPorts). */
1135 uint32_t cAvailablePorts;
1136 /** The driver instance of the hub. */
1137 PPDMDRVINS pDrvIns;
1138 /** Copy of the to the registration structure. */
1139 PDMUSBHUBREG Reg;
1140
1141 /** Pointer to the next hub in the list. */
1142 struct PDMUSBHUB *pNext;
1143} PDMUSBHUB;
1144
1145/** Pointer to a const USB HUB registration record. */
1146typedef const PDMUSBHUB *PCPDMUSBHUB;
1147
1148/** Pointer to a PDM Async I/O template. */
1149typedef struct PDMASYNCCOMPLETIONTEMPLATE *PPDMASYNCCOMPLETIONTEMPLATE;
1150
1151/** Pointer to the main PDM Async completion endpoint class. */
1152typedef struct PDMASYNCCOMPLETIONEPCLASS *PPDMASYNCCOMPLETIONEPCLASS;
1153
1154/** Pointer to the global block cache structure. */
1155typedef struct PDMBLKCACHEGLOBAL *PPDMBLKCACHEGLOBAL;
1156
1157/**
1158 * PDM VMCPU Instance data.
1159 * Changes to this must checked against the padding of the pdm union in VMCPU!
1160 */
1161typedef struct PDMCPU
1162{
1163 /** The number of entries in the apQueuedCritSectsLeaves table that's currently
1164 * in use. */
1165 uint32_t cQueuedCritSectLeaves;
1166 uint32_t uPadding0; /**< Alignment padding.*/
1167 /** Critical sections queued in RC/R0 because of contention preventing leave to
1168 * complete. (R3 Ptrs)
1169 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */
1170 R3PTRTYPE(PPDMCRITSECT) apQueuedCritSectLeaves[8];
1171
1172 /** The number of entries in the apQueuedCritSectRwExclLeaves table that's
1173 * currently in use. */
1174 uint32_t cQueuedCritSectRwExclLeaves;
1175 uint32_t uPadding1; /**< Alignment padding.*/
1176 /** Read/write critical sections queued in RC/R0 because of contention
1177 * preventing exclusive leave to complete. (R3 Ptrs)
1178 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */
1179 R3PTRTYPE(PPDMCRITSECTRW) apQueuedCritSectRwExclLeaves[8];
1180
1181 /** The number of entries in the apQueuedCritSectsRwShrdLeaves table that's
1182 * currently in use. */
1183 uint32_t cQueuedCritSectRwShrdLeaves;
1184 uint32_t uPadding2; /**< Alignment padding.*/
1185 /** Read/write critical sections queued in RC/R0 because of contention
1186 * preventing shared leave to complete. (R3 Ptrs)
1187 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */
1188 R3PTRTYPE(PPDMCRITSECTRW) apQueuedCritSectRwShrdLeaves[8];
1189} PDMCPU;
1190
1191
1192/**
1193 * PDM VM Instance data.
1194 * Changes to this must checked against the padding of the cfgm union in VM!
1195 */
1196typedef struct PDM
1197{
1198 /** The PDM lock.
1199 * This is used to protect everything that deals with interrupts, i.e.
1200 * the PIC, APIC, IOAPIC and PCI devices plus some PDM functions. */
1201 PDMCRITSECT CritSect;
1202 /** The NOP critical section.
1203 * This is a dummy critical section that will not do any thread
1204 * serialization but instead let all threads enter immediately and
1205 * concurrently. */
1206 PDMCRITSECT NopCritSect;
1207
1208 /** The ring-0 capable task sets (max 128). */
1209 PDMTASKSET aTaskSets[2];
1210 /** Pointer to task sets (max 512). */
1211 R3PTRTYPE(PPDMTASKSET) apTaskSets[8];
1212
1213 /** PCI Buses. */
1214 PDMPCIBUS aPciBuses[PDM_PCI_BUSSES_MAX];
1215 /** The register PIC device. */
1216 PDMPIC Pic;
1217 /** The registered APIC device. */
1218 PDMAPIC Apic;
1219 /** The registered I/O APIC device. */
1220 PDMIOAPIC IoApic;
1221
1222 /** List of registered devices. (FIFO) */
1223 R3PTRTYPE(PPDMDEV) pDevs;
1224 /** List of devices instances. (FIFO) */
1225 R3PTRTYPE(PPDMDEVINS) pDevInstances;
1226 /** List of registered USB devices. (FIFO) */
1227 R3PTRTYPE(PPDMUSB) pUsbDevs;
1228 /** List of USB devices instances. (FIFO) */
1229 R3PTRTYPE(PPDMUSBINS) pUsbInstances;
1230 /** List of registered drivers. (FIFO) */
1231 R3PTRTYPE(PPDMDRV) pDrvs;
1232 /** The registered firmware device (can be NULL). */
1233 R3PTRTYPE(PPDMFW) pFirmware;
1234 /** The registered DMAC device. */
1235 R3PTRTYPE(PPDMDMAC) pDmac;
1236 /** The registered RTC device. */
1237 R3PTRTYPE(PPDMRTC) pRtc;
1238 /** The registered USB HUBs. (FIFO) */
1239 R3PTRTYPE(PPDMUSBHUB) pUsbHubs;
1240
1241 /** @name Queues
1242 * @{ */
1243 /** Queue in which devhlp tasks are queued for R3 execution - R3 Ptr. */
1244 R3PTRTYPE(PPDMQUEUE) pDevHlpQueueR3;
1245 /** Queue in which devhlp tasks are queued for R3 execution - R0 Ptr. */
1246 R0PTRTYPE(PPDMQUEUE) pDevHlpQueueR0;
1247 /** Queue in which devhlp tasks are queued for R3 execution - RC Ptr. */
1248 RCPTRTYPE(PPDMQUEUE) pDevHlpQueueRC;
1249 /** Pointer to the queue which should be manually flushed - RC Ptr.
1250 * Only touched by EMT. */
1251 RCPTRTYPE(struct PDMQUEUE *) pQueueFlushRC;
1252 /** Pointer to the queue which should be manually flushed - R0 Ptr.
1253 * Only touched by EMT. */
1254 R0PTRTYPE(struct PDMQUEUE *) pQueueFlushR0;
1255 /** Bitmask controlling the queue flushing.
1256 * See PDM_QUEUE_FLUSH_FLAG_ACTIVE and PDM_QUEUE_FLUSH_FLAG_PENDING. */
1257 uint32_t volatile fQueueFlushing;
1258 /** @} */
1259
1260 /** The current IRQ tag (tracing purposes). */
1261 uint32_t volatile uIrqTag;
1262
1263 /** Pending reset flags (PDMVMRESET_F_XXX). */
1264 uint32_t volatile fResetFlags;
1265
1266 /** Set by pdmR3LoadExec for use in assertions. */
1267 bool fStateLoaded;
1268 /** Alignment padding. */
1269 bool afPadding[3];
1270
1271 /** The tracing ID of the next device instance.
1272 *
1273 * @remarks We keep the device tracing ID seperate from the rest as these are
1274 * then more likely to end up with the same ID from one run to
1275 * another, making analysis somewhat easier. Drivers and USB devices
1276 * are more volatile and can be changed at runtime, thus these are much
1277 * less likely to remain stable, so just heap them all together. */
1278 uint32_t idTracingDev;
1279 /** The tracing ID of the next driver instance, USB device instance or other
1280 * PDM entity requiring an ID. */
1281 uint32_t idTracingOther;
1282
1283 /** @name VMM device heap
1284 * @{ */
1285 /** The heap size. */
1286 uint32_t cbVMMDevHeap;
1287 /** Free space. */
1288 uint32_t cbVMMDevHeapLeft;
1289 /** Pointer to the heap base (MMIO2 ring-3 mapping). NULL if not registered. */
1290 RTR3PTR pvVMMDevHeap;
1291 /** Ring-3 mapping/unmapping notification callback for the user. */
1292 PFNPDMVMMDEVHEAPNOTIFY pfnVMMDevHeapNotify;
1293 /** The current mapping. NIL_RTGCPHYS if not mapped or registered. */
1294 RTGCPHYS GCPhysVMMDevHeap;
1295 /** @} */
1296
1297 /** Number of times a critical section leave request needed to be queued for ring-3 execution. */
1298 STAMCOUNTER StatQueuedCritSectLeaves;
1299} PDM;
1300AssertCompileMemberAlignment(PDM, CritSect, 8);
1301AssertCompileMemberAlignment(PDM, aTaskSets, 64);
1302AssertCompileMemberAlignment(PDM, StatQueuedCritSectLeaves, 8);
1303AssertCompileMemberAlignment(PDM, GCPhysVMMDevHeap, sizeof(RTGCPHYS));
1304/** Pointer to PDM VM instance data. */
1305typedef PDM *PPDM;
1306
1307
1308/**
1309 * PDM data kept in the ring-0 GVM.
1310 */
1311typedef struct PDMR0PERVM
1312{
1313 /** PCI Buses, ring-0 data. */
1314 PDMPCIBUSR0 aPciBuses[PDM_PCI_BUSSES_MAX];
1315 /** Number of valid ring-0 device instances (apDevInstances). */
1316 uint32_t cDevInstances;
1317 uint32_t u32Padding;
1318 /** Pointer to ring-0 device instances. */
1319 R0PTRTYPE(struct PDMDEVINSR0 *) apDevInstances[190];
1320} PDMR0PERVM;
1321
1322
1323/**
1324 * PDM data kept in the UVM.
1325 */
1326typedef struct PDMUSERPERVM
1327{
1328 /** @todo move more stuff over here. */
1329
1330 /** Linked list of timer driven PDM queues.
1331 * Currently serialized by PDM::CritSect. */
1332 R3PTRTYPE(struct PDMQUEUE *) pQueuesTimer;
1333 /** Linked list of force action driven PDM queues.
1334 * Currently serialized by PDM::CritSect. */
1335 R3PTRTYPE(struct PDMQUEUE *) pQueuesForced;
1336
1337 /** Lock protecting the lists below it. */
1338 RTCRITSECT ListCritSect;
1339 /** Pointer to list of loaded modules. */
1340 PPDMMOD pModules;
1341 /** List of initialized critical sections. (LIFO) */
1342 R3PTRTYPE(PPDMCRITSECTINT) pCritSects;
1343 /** List of initialized read/write critical sections. (LIFO) */
1344 R3PTRTYPE(PPDMCRITSECTRWINT) pRwCritSects;
1345 /** Head of the PDM Thread list. (singly linked) */
1346 R3PTRTYPE(PPDMTHREAD) pThreads;
1347 /** Tail of the PDM Thread list. (singly linked) */
1348 R3PTRTYPE(PPDMTHREAD) pThreadsTail;
1349
1350 /** @name PDM Async Completion
1351 * @{ */
1352 /** Pointer to the array of supported endpoint classes. */
1353 PPDMASYNCCOMPLETIONEPCLASS apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_MAX];
1354 /** Head of the templates. Singly linked, protected by ListCritSect. */
1355 R3PTRTYPE(PPDMASYNCCOMPLETIONTEMPLATE) pAsyncCompletionTemplates;
1356 /** @} */
1357
1358 /** Global block cache data. */
1359 R3PTRTYPE(PPDMBLKCACHEGLOBAL) pBlkCacheGlobal;
1360#ifdef VBOX_WITH_NETSHAPER
1361 /** Pointer to network shaper instance. */
1362 R3PTRTYPE(PPDMNETSHAPER) pNetShaper;
1363#endif /* VBOX_WITH_NETSHAPER */
1364
1365} PDMUSERPERVM;
1366/** Pointer to the PDM data kept in the UVM. */
1367typedef PDMUSERPERVM *PPDMUSERPERVM;
1368
1369
1370
1371/*******************************************************************************
1372* Global Variables *
1373*******************************************************************************/
1374#ifdef IN_RING3
1375extern const PDMDRVHLPR3 g_pdmR3DrvHlp;
1376extern const PDMDEVHLPR3 g_pdmR3DevHlpTrusted;
1377extern const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted;
1378extern const PDMPICHLPR3 g_pdmR3DevPicHlp;
1379extern const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp;
1380extern const PDMFWHLPR3 g_pdmR3DevFirmwareHlp;
1381extern const PDMPCIHLPR3 g_pdmR3DevPciHlp;
1382extern const PDMDMACHLP g_pdmR3DevDmacHlp;
1383extern const PDMRTCHLP g_pdmR3DevRtcHlp;
1384extern const PDMHPETHLPR3 g_pdmR3DevHpetHlp;
1385extern const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp;
1386#endif
1387
1388
1389/*******************************************************************************
1390* Defined Constants And Macros *
1391*******************************************************************************/
1392/** @def PDMDEV_ASSERT_DEVINS
1393 * Asserts the validity of the device instance.
1394 */
1395#ifdef VBOX_STRICT
1396# define PDMDEV_ASSERT_DEVINS(pDevIns) \
1397 do { \
1398 AssertPtr(pDevIns); \
1399 Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \
1400 Assert(pDevIns->CTX_SUFF(pvInstanceDataFor) == (void *)&pDevIns->achInstanceData[0]); \
1401 } while (0)
1402#else
1403# define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0)
1404#endif
1405
1406/** @def PDMDRV_ASSERT_DRVINS
1407 * Asserts the validity of the driver instance.
1408 */
1409#ifdef VBOX_STRICT
1410# define PDMDRV_ASSERT_DRVINS(pDrvIns) \
1411 do { \
1412 AssertPtr(pDrvIns); \
1413 Assert(pDrvIns->u32Version == PDM_DRVINS_VERSION); \
1414 Assert(pDrvIns->CTX_SUFF(pvInstanceData) == (void *)&pDrvIns->achInstanceData[0]); \
1415 } while (0)
1416#else
1417# define PDMDRV_ASSERT_DRVINS(pDrvIns) do { } while (0)
1418#endif
1419
1420
1421/*******************************************************************************
1422* Internal Functions *
1423*******************************************************************************/
1424#ifdef IN_RING3
1425bool pdmR3IsValidName(const char *pszName);
1426
1427int pdmR3CritSectBothInitStats(PVM pVM);
1428void pdmR3CritSectBothRelocate(PVM pVM);
1429int pdmR3CritSectBothDeleteDevice(PVM pVM, PPDMDEVINS pDevIns);
1430int pdmR3CritSectBothDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns);
1431int pdmR3CritSectInitDevice( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
1432 const char *pszNameFmt, va_list va);
1433int pdmR3CritSectInitDeviceAuto( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
1434 const char *pszNameFmt, ...);
1435int pdmR3CritSectInitDriver( PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
1436 const char *pszNameFmt, ...);
1437int pdmR3CritSectRwInitDevice( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
1438 const char *pszNameFmt, va_list va);
1439int pdmR3CritSectRwInitDeviceAuto( PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
1440 const char *pszNameFmt, ...);
1441int pdmR3CritSectRwInitDriver( PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
1442 const char *pszNameFmt, ...);
1443
1444int pdmR3DevInit(PVM pVM);
1445int pdmR3DevInitComplete(PVM pVM);
1446PPDMDEV pdmR3DevLookup(PVM pVM, const char *pszName);
1447int pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);
1448DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem);
1449
1450int pdmR3UsbLoadModules(PVM pVM);
1451int pdmR3UsbInstantiateDevices(PVM pVM);
1452PPDMUSB pdmR3UsbLookup(PVM pVM, const char *pszName);
1453int pdmR3UsbRegisterHub(PVM pVM, PPDMDRVINS pDrvIns, uint32_t fVersions, uint32_t cPorts, PCPDMUSBHUBREG pUsbHubReg, PPCPDMUSBHUBHLP ppUsbHubHlp);
1454int pdmR3UsbVMInitComplete(PVM pVM);
1455
1456int pdmR3DrvInit(PVM pVM);
1457int pdmR3DrvInstantiate(PVM pVM, PCFGMNODE pNode, PPDMIBASE pBaseInterface, PPDMDRVINS pDrvAbove,
1458 PPDMLUN pLun, PPDMIBASE *ppBaseInterface);
1459int pdmR3DrvDetach(PPDMDRVINS pDrvIns, uint32_t fFlags);
1460void pdmR3DrvDestroyChain(PPDMDRVINS pDrvIns, uint32_t fFlags);
1461PPDMDRV pdmR3DrvLookup(PVM pVM, const char *pszName);
1462
1463int pdmR3LdrInitU(PUVM pUVM);
1464void pdmR3LdrTermU(PUVM pUVM);
1465char *pdmR3FileR3(const char *pszFile, bool fShared);
1466int pdmR3LoadR3U(PUVM pUVM, const char *pszFilename, const char *pszName);
1467
1468void pdmR3QueueRelocate(PVM pVM, RTGCINTPTR offDelta);
1469
1470int pdmR3TaskInit(PVM pVM);
1471void pdmR3TaskTerm(PVM pVM);
1472
1473int pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
1474 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1475int pdmR3ThreadCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
1476 PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1477int pdmR3ThreadCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
1478 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1479int pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
1480int pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
1481int pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
1482void pdmR3ThreadDestroyAll(PVM pVM);
1483int pdmR3ThreadResumeAll(PVM pVM);
1484int pdmR3ThreadSuspendAll(PVM pVM);
1485
1486#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
1487int pdmR3AsyncCompletionInit(PVM pVM);
1488int pdmR3AsyncCompletionTerm(PVM pVM);
1489void pdmR3AsyncCompletionResume(PVM pVM);
1490int pdmR3AsyncCompletionTemplateCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDEV pfnCompleted, const char *pszDesc);
1491int pdmR3AsyncCompletionTemplateCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
1492 PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc);
1493int pdmR3AsyncCompletionTemplateCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEUSB pfnCompleted, const char *pszDesc);
1494int pdmR3AsyncCompletionTemplateDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
1495int pdmR3AsyncCompletionTemplateDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
1496int pdmR3AsyncCompletionTemplateDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
1497#endif
1498
1499#ifdef VBOX_WITH_NETSHAPER
1500int pdmR3NetShaperInit(PVM pVM);
1501int pdmR3NetShaperTerm(PVM pVM);
1502#endif
1503
1504int pdmR3BlkCacheInit(PVM pVM);
1505void pdmR3BlkCacheTerm(PVM pVM);
1506int pdmR3BlkCacheResume(PVM pVM);
1507
1508#endif /* IN_RING3 */
1509
1510void pdmLock(PVMCC pVM);
1511int pdmLockEx(PVMCC pVM, int rc);
1512void pdmUnlock(PVMCC pVM);
1513
1514#if defined(IN_RING3) || defined(IN_RING0)
1515void pdmCritSectRwLeaveSharedQueued(PPDMCRITSECTRW pThis);
1516void pdmCritSectRwLeaveExclQueued(PPDMCRITSECTRW pThis);
1517#endif
1518
1519/** @} */
1520
1521RT_C_DECLS_END
1522
1523#endif /* !VMM_INCLUDED_SRC_include_PDMInternal_h */
1524
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