VirtualBox

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

Last change on this file since 40901 was 40652, checked in by vboxsync, 13 years ago

NetShaper,E1000: Basic framework and partial implementation for network shaper

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 46.6 KB
Line 
1/* $Id: PDMInternal.h 40652 2012-03-26 16:36:16Z vboxsync $ */
2/** @file
3 * PDM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2011 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 ___PDMInternal_h
19#define ___PDMInternal_h
20
21#include <VBox/types.h>
22#include <VBox/param.h>
23#include <VBox/vmm/cfgm.h>
24#include <VBox/vmm/stam.h>
25#include <VBox/vusb.h>
26#include <VBox/vmm/pdmasynccompletion.h>
27#ifdef VBOX_WITH_NETSHAPER
28#include <VBox/vmm/pdmnetshaper.h>
29#endif /* VBOX_WITH_NETSHAPER */
30#include <VBox/vmm/pdmblkcache.h>
31#include <VBox/vmm/pdmcommon.h>
32#include <iprt/assert.h>
33#include <iprt/critsect.h>
34#ifdef IN_RING3
35# include <iprt/thread.h>
36#endif
37
38RT_C_DECLS_BEGIN
39
40
41/** @defgroup grp_pdm_int Internal
42 * @ingroup grp_pdm
43 * @internal
44 * @{
45 */
46
47/** @def PDM_WITH_R3R0_CRIT_SECT
48 * Enables or disabled ring-3/ring-0 critical sections. */
49#if defined(DOXYGEN_RUNNING) || 1
50# define PDM_WITH_R3R0_CRIT_SECT
51#endif
52
53/** @def PDMCRITSECT_STRICT
54 * Enables/disables PDM critsect strictness like deadlock detection. */
55#if (defined(RT_LOCK_STRICT) && defined(IN_RING3) && !defined(IEM_VERIFICATION_MODE)) || defined(DOXYGEN_RUNNING)
56# define PDMCRITSECT_STRICT
57#endif
58
59
60/*******************************************************************************
61* Structures and Typedefs *
62*******************************************************************************/
63
64/** Pointer to a PDM Device. */
65typedef struct PDMDEV *PPDMDEV;
66/** Pointer to a pointer to a PDM Device. */
67typedef PPDMDEV *PPPDMDEV;
68
69/** Pointer to a PDM USB Device. */
70typedef struct PDMUSB *PPDMUSB;
71/** Pointer to a pointer to a PDM USB Device. */
72typedef PPDMUSB *PPPDMUSB;
73
74/** Pointer to a PDM Driver. */
75typedef struct PDMDRV *PPDMDRV;
76/** Pointer to a pointer to a PDM Driver. */
77typedef PPDMDRV *PPPDMDRV;
78
79/** Pointer to a PDM Logical Unit. */
80typedef struct PDMLUN *PPDMLUN;
81/** Pointer to a pointer to a PDM Logical Unit. */
82typedef PPDMLUN *PPPDMLUN;
83
84/** Pointer to a PDM PCI Bus instance. */
85typedef struct PDMPCIBUS *PPDMPCIBUS;
86/** Pointer to a DMAC instance. */
87typedef struct PDMDMAC *PPDMDMAC;
88/** Pointer to a RTC instance. */
89typedef struct PDMRTC *PPDMRTC;
90
91/** Pointer to an USB HUB registration record. */
92typedef struct PDMUSBHUB *PPDMUSBHUB;
93
94/**
95 * Supported asynchronous completion endpoint classes.
96 */
97typedef enum PDMASYNCCOMPLETIONEPCLASSTYPE
98{
99 /** File class. */
100 PDMASYNCCOMPLETIONEPCLASSTYPE_FILE = 0,
101 /** Number of supported classes. */
102 PDMASYNCCOMPLETIONEPCLASSTYPE_MAX,
103 /** 32bit hack. */
104 PDMASYNCCOMPLETIONEPCLASSTYPE_32BIT_HACK = 0x7fffffff
105} PDMASYNCCOMPLETIONEPCLASSTYPE;
106
107/**
108 * Private device instance data.
109 */
110typedef struct PDMDEVINSINT
111{
112 /** Pointer to the next instance (HC Ptr).
113 * (Head is pointed to by PDM::pDevInstances.) */
114 R3PTRTYPE(PPDMDEVINS) pNextR3;
115 /** Pointer to the next per device instance (HC Ptr).
116 * (Head is pointed to by PDMDEV::pInstances.) */
117 R3PTRTYPE(PPDMDEVINS) pPerDeviceNextR3;
118 /** Pointer to device structure - HC Ptr. */
119 R3PTRTYPE(PPDMDEV) pDevR3;
120 /** Pointer to the list of logical units associated with the device. (FIFO) */
121 R3PTRTYPE(PPDMLUN) pLunsR3;
122 /** Pointer to the asynchronous notification callback set while in
123 * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */
124 R3PTRTYPE(PFNPDMDEVASYNCNOTIFY) pfnAsyncNotify;
125 /** Configuration handle to the instance node. */
126 R3PTRTYPE(PCFGMNODE) pCfgHandle;
127
128 /** R3 pointer to the VM this instance was created for. */
129 PVMR3 pVMR3;
130 /** R3 pointer to associated PCI device structure. */
131 R3PTRTYPE(struct PCIDevice *) pPciDeviceR3;
132 /** R3 pointer to associated PCI bus structure. */
133 R3PTRTYPE(PPDMPCIBUS) pPciBusR3;
134
135 /** R0 pointer to the VM this instance was created for. */
136 PVMR0 pVMR0;
137 /** R0 pointer to associated PCI device structure. */
138 R0PTRTYPE(struct PCIDevice *) pPciDeviceR0;
139 /** R0 pointer to associated PCI bus structure. */
140 R0PTRTYPE(PPDMPCIBUS) pPciBusR0;
141
142 /** RC pointer to the VM this instance was created for. */
143 PVMRC pVMRC;
144 /** RC pointer to associated PCI device structure. */
145 RCPTRTYPE(struct PCIDevice *) pPciDeviceRC;
146 /** RC pointer to associated PCI bus structure. */
147 RCPTRTYPE(PPDMPCIBUS) pPciBusRC;
148
149 /** Flags, see PDMDEVINSINT_FLAGS_XXX. */
150 uint32_t fIntFlags;
151} PDMDEVINSINT;
152
153/** @name PDMDEVINSINT::fIntFlags
154 * @{ */
155/** Used by pdmR3Load to mark device instances it found in the saved state. */
156#define PDMDEVINSINT_FLAGS_FOUND RT_BIT_32(0)
157/** Indicates that the device hasn't been powered on or resumed.
158 * This is used by PDMR3PowerOn, PDMR3Resume, PDMR3Suspend and PDMR3PowerOff
159 * to make sure each device gets exactly one notification for each of those
160 * events. PDMR3Resume and PDMR3PowerOn also makes use of it to bail out on
161 * a failure (already resumed/powered-on devices are suspended). */
162#define PDMDEVINSINT_FLAGS_SUSPENDED RT_BIT_32(1)
163/** Indicates that the device has been reset already. Used by PDMR3Reset. */
164#define PDMDEVINSINT_FLAGS_RESET RT_BIT_32(2)
165/** @} */
166
167
168/**
169 * Private USB device instance data.
170 */
171typedef struct PDMUSBINSINT
172{
173 /** The UUID of this instance. */
174 RTUUID Uuid;
175 /** Pointer to the next instance.
176 * (Head is pointed to by PDM::pUsbInstances.) */
177 R3PTRTYPE(PPDMUSBINS) pNext;
178 /** Pointer to the next per USB device instance.
179 * (Head is pointed to by PDMUSB::pInstances.) */
180 R3PTRTYPE(PPDMUSBINS) pPerDeviceNext;
181
182 /** Pointer to device structure. */
183 R3PTRTYPE(PPDMUSB) pUsbDev;
184
185 /** Pointer to the VM this instance was created for. */
186 PVMR3 pVM;
187 /** Pointer to the list of logical units associated with the device. (FIFO) */
188 R3PTRTYPE(PPDMLUN) pLuns;
189 /** The per instance device configuration. */
190 R3PTRTYPE(PCFGMNODE) pCfg;
191 /** Same as pCfg if the configuration should be deleted when detaching the device. */
192 R3PTRTYPE(PCFGMNODE) pCfgDelete;
193 /** The global device configuration. */
194 R3PTRTYPE(PCFGMNODE) pCfgGlobal;
195
196 /** Pointer to the USB hub this device is attached to.
197 * This is NULL if the device isn't connected to any HUB. */
198 R3PTRTYPE(PPDMUSBHUB) pHub;
199 /** The port number that we're connected to. */
200 uint32_t iPort;
201 /** Indicates that the USB device hasn't been powered on or resumed.
202 * See PDMDEVINSINT_FLAGS_SUSPENDED. */
203 bool fVMSuspended;
204 /** Indicates that the USB device has been reset. */
205 bool fVMReset;
206 /** Pointer to the asynchronous notification callback set while in
207 * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */
208 R3PTRTYPE(PFNPDMUSBASYNCNOTIFY) pfnAsyncNotify;
209} PDMUSBINSINT;
210
211
212/**
213 * Private driver instance data.
214 */
215typedef struct PDMDRVINSINT
216{
217 /** Pointer to the driver instance above.
218 * This is NULL for the topmost drive. */
219 R3PTRTYPE(PPDMDRVINS) pUp;
220 /** Pointer to the driver instance below.
221 * This is NULL for the bottommost driver. */
222 R3PTRTYPE(PPDMDRVINS) pDown;
223 /** Pointer to the logical unit this driver chained on. */
224 R3PTRTYPE(PPDMLUN) pLun;
225 /** Pointer to driver structure from which this was instantiated. */
226 R3PTRTYPE(PPDMDRV) pDrv;
227 /** Pointer to the VM this instance was created for, ring-3 context. */
228 PVMR3 pVMR3;
229 /** Pointer to the VM this instance was created for, ring-0 context. */
230 PVMR0 pVMR0;
231 /** Pointer to the VM this instance was created for, raw-mode context. */
232 PVMRC pVMRC;
233 /** Flag indicating that the driver is being detached and destroyed.
234 * (Helps detect potential recursive detaching.) */
235 bool fDetaching;
236 /** Indicates that the driver hasn't been powered on or resumed.
237 * See PDMDEVINSINT_FLAGS_SUSPENDED. */
238 bool fVMSuspended;
239 /** Indicates that the driver has been reset already. */
240 bool fVMReset;
241 /** Set if allocated on the hyper heap, false if on the ring-3 heap. */
242 bool fHyperHeap;
243 /** Pointer to the asynchronous notification callback set while in
244 * PDMUSBREG::pfnVMSuspend or PDMUSBREG::pfnVMPowerOff. */
245 R3PTRTYPE(PFNPDMDRVASYNCNOTIFY) pfnAsyncNotify;
246 /** Configuration handle to the instance node. */
247 R3PTRTYPE(PCFGMNODE) pCfgHandle;
248 /** Pointer to the ring-0 request handler function. */
249 PFNPDMDRVREQHANDLERR0 pfnReqHandlerR0;
250} PDMDRVINSINT;
251
252
253/**
254 * Private critical section data.
255 */
256typedef struct PDMCRITSECTINT
257{
258 /** The critical section core which is shared with IPRT. */
259 RTCRITSECT Core;
260 /** Pointer to the next critical section.
261 * This chain is used for relocating pVMRC and device cleanup. */
262 R3PTRTYPE(struct PDMCRITSECTINT *) pNext;
263 /** Owner identifier.
264 * This is pDevIns if the owner is a device. Similarly for a driver or service.
265 * PDMR3CritSectInit() sets this to point to the critsect itself. */
266 RTR3PTR pvKey;
267 /** Pointer to the VM - R3Ptr. */
268 PVMR3 pVMR3;
269 /** Pointer to the VM - R0Ptr. */
270 PVMR0 pVMR0;
271 /** Pointer to the VM - GCPtr. */
272 PVMRC pVMRC;
273 /** Set if this critical section is the automatically created default
274 * section of a device.. */
275 bool fAutomaticDefaultCritsect;
276 /** Set if the critical section is used by a timer or similar.
277 * See PDMR3DevGetCritSect. */
278 bool fUsedByTimerOrSimilar;
279 /** Alignment padding. */
280 bool afPadding[2];
281 /** Event semaphore that is scheduled to be signaled upon leaving the
282 * critical section. This is Ring-3 only of course. */
283 RTSEMEVENT EventToSignal;
284 /** The lock name. */
285 R3PTRTYPE(const char *) pszName;
286 /** R0/RC lock contention. */
287 STAMCOUNTER StatContentionRZLock;
288 /** R0/RC unlock contention. */
289 STAMCOUNTER StatContentionRZUnlock;
290 /** R3 lock contention. */
291 STAMCOUNTER StatContentionR3;
292 /** Profiling the time the section is locked. */
293 STAMPROFILEADV StatLocked;
294} PDMCRITSECTINT;
295AssertCompileMemberAlignment(PDMCRITSECTINT, StatContentionRZLock, 8);
296/** Pointer to private critical section data. */
297typedef PDMCRITSECTINT *PPDMCRITSECTINT;
298
299/** Indicates that the critical section is queued for unlock.
300 * PDMCritSectIsOwner and PDMCritSectIsOwned optimizations. */
301#define PDMCRITSECT_FLAGS_PENDING_UNLOCK RT_BIT_32(17)
302
303
304/**
305 * The usual device/driver/internal/external stuff.
306 */
307typedef enum
308{
309 /** The usual invalid entry. */
310 PDMTHREADTYPE_INVALID = 0,
311 /** Device type. */
312 PDMTHREADTYPE_DEVICE,
313 /** USB Device type. */
314 PDMTHREADTYPE_USB,
315 /** Driver type. */
316 PDMTHREADTYPE_DRIVER,
317 /** Internal type. */
318 PDMTHREADTYPE_INTERNAL,
319 /** External type. */
320 PDMTHREADTYPE_EXTERNAL,
321 /** The usual 32-bit hack. */
322 PDMTHREADTYPE_32BIT_HACK = 0x7fffffff
323} PDMTHREADTYPE;
324
325
326/**
327 * The internal structure for the thread.
328 */
329typedef struct PDMTHREADINT
330{
331 /** The VM pointer. */
332 PVMR3 pVM;
333 /** The event semaphore the thread blocks on when not running. */
334 RTSEMEVENTMULTI BlockEvent;
335 /** The event semaphore the thread sleeps on while running. */
336 RTSEMEVENTMULTI SleepEvent;
337 /** Pointer to the next thread. */
338 R3PTRTYPE(struct PDMTHREAD *) pNext;
339 /** The thread type. */
340 PDMTHREADTYPE enmType;
341} PDMTHREADINT;
342
343
344
345/* Must be included after PDMDEVINSINT is defined. */
346#define PDMDEVINSINT_DECLARED
347#define PDMUSBINSINT_DECLARED
348#define PDMDRVINSINT_DECLARED
349#define PDMCRITSECTINT_DECLARED
350#define PDMTHREADINT_DECLARED
351#ifdef ___VBox_pdm_h
352# error "Invalid header PDM order. Include PDMInternal.h before VBox/vmm/pdm.h!"
353#endif
354RT_C_DECLS_END
355#include <VBox/vmm/pdm.h>
356RT_C_DECLS_BEGIN
357
358/**
359 * PDM Logical Unit.
360 *
361 * This typically the representation of a physical port on a
362 * device, like for instance the PS/2 keyboard port on the
363 * keyboard controller device. The LUNs are chained on the
364 * device the belong to (PDMDEVINSINT::pLunsR3).
365 */
366typedef struct PDMLUN
367{
368 /** The LUN - The Logical Unit Number. */
369 RTUINT iLun;
370 /** Pointer to the next LUN. */
371 PPDMLUN pNext;
372 /** Pointer to the top driver in the driver chain. */
373 PPDMDRVINS pTop;
374 /** Pointer to the bottom driver in the driver chain. */
375 PPDMDRVINS pBottom;
376 /** Pointer to the device instance which the LUN belongs to.
377 * Either this is set or pUsbIns is set. Both is never set at the same time. */
378 PPDMDEVINS pDevIns;
379 /** Pointer to the USB device instance which the LUN belongs to. */
380 PPDMUSBINS pUsbIns;
381 /** Pointer to the device base interface. */
382 PPDMIBASE pBase;
383 /** Description of this LUN. */
384 const char *pszDesc;
385} PDMLUN;
386
387
388/**
389 * PDM Device.
390 */
391typedef struct PDMDEV
392{
393 /** Pointer to the next device (R3 Ptr). */
394 R3PTRTYPE(PPDMDEV) pNext;
395 /** Device name length. (search optimization) */
396 RTUINT cchName;
397 /** Registration structure. */
398 R3PTRTYPE(const struct PDMDEVREG *) pReg;
399 /** Number of instances. */
400 uint32_t cInstances;
401 /** Pointer to chain of instances (R3 Ptr). */
402 PPDMDEVINSR3 pInstances;
403 /** The search path for raw-mode context modules (';' as separator). */
404 char *pszRCSearchPath;
405 /** The search path for ring-0 context modules (';' as separator). */
406 char *pszR0SearchPath;
407} PDMDEV;
408
409
410/**
411 * PDM USB Device.
412 */
413typedef struct PDMUSB
414{
415 /** Pointer to the next device (R3 Ptr). */
416 R3PTRTYPE(PPDMUSB) pNext;
417 /** Device name length. (search optimization) */
418 RTUINT cchName;
419 /** Registration structure. */
420 R3PTRTYPE(const struct PDMUSBREG *) pReg;
421 /** Next instance number. */
422 uint32_t iNextInstance;
423 /** Pointer to chain of instances (R3 Ptr). */
424 R3PTRTYPE(PPDMUSBINS) pInstances;
425} PDMUSB;
426
427
428/**
429 * PDM Driver.
430 */
431typedef struct PDMDRV
432{
433 /** Pointer to the next device. */
434 PPDMDRV pNext;
435 /** Registration structure. */
436 const struct PDMDRVREG * pReg;
437 /** Current number of instances. */
438 uint32_t cInstances;
439 /** The next instance number. */
440 uint32_t iNextInstance;
441 /** The search path for raw-mode context modules (';' as separator). */
442 char *pszRCSearchPath;
443 /** The search path for ring-0 context modules (';' as separator). */
444 char *pszR0SearchPath;
445} PDMDRV;
446
447
448/**
449 * PDM registered PIC device.
450 */
451typedef struct PDMPIC
452{
453 /** Pointer to the PIC device instance - R3. */
454 PPDMDEVINSR3 pDevInsR3;
455 /** @copydoc PDMPICREG::pfnSetIrqR3 */
456 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
457 /** @copydoc PDMPICREG::pfnGetInterruptR3 */
458 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns));
459
460 /** Pointer to the PIC device instance - R0. */
461 PPDMDEVINSR0 pDevInsR0;
462 /** @copydoc PDMPICREG::pfnSetIrqR3 */
463 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
464 /** @copydoc PDMPICREG::pfnGetInterruptR3 */
465 DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns));
466
467 /** Pointer to the PIC device instance - RC. */
468 PPDMDEVINSRC pDevInsRC;
469 /** @copydoc PDMPICREG::pfnSetIrqR3 */
470 DECLRCCALLBACKMEMBER(void, pfnSetIrqRC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
471 /** @copydoc PDMPICREG::pfnGetInterruptR3 */
472 DECLRCCALLBACKMEMBER(int, pfnGetInterruptRC,(PPDMDEVINS pDevIns));
473 /** Alignment padding. */
474 RTRCPTR RCPtrPadding;
475} PDMPIC;
476
477
478/**
479 * PDM registered APIC device.
480 */
481typedef struct PDMAPIC
482{
483 /** Pointer to the APIC device instance - R3 Ptr. */
484 PPDMDEVINSR3 pDevInsR3;
485 /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
486 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns));
487 /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */
488 DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns));
489 /** @copydoc PDMAPICREG::pfnSetBaseR3 */
490 DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, uint64_t u64Base));
491 /** @copydoc PDMAPICREG::pfnGetBaseR3 */
492 DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns));
493 /** @copydoc PDMAPICREG::pfnSetTPRR3 */
494 DECLR3CALLBACKMEMBER(void, pfnSetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR));
495 /** @copydoc PDMAPICREG::pfnGetTPRR3 */
496 DECLR3CALLBACKMEMBER(uint8_t, pfnGetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu));
497 /** @copydoc PDMAPICREG::pfnWriteMSRR3 */
498 DECLR3CALLBACKMEMBER(int, pfnWriteMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value));
499 /** @copydoc PDMAPICREG::pfnReadMSRR3 */
500 DECLR3CALLBACKMEMBER(int, pfnReadMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value));
501 /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
502 DECLR3CALLBACKMEMBER(int, pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
503 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
504 /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
505 DECLR3CALLBACKMEMBER(int, pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
506
507 /** Pointer to the APIC device instance - R0 Ptr. */
508 PPDMDEVINSR0 pDevInsR0;
509 /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
510 DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns));
511 /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */
512 DECLR0CALLBACKMEMBER(bool, pfnHasPendingIrqR0,(PPDMDEVINS pDevIns));
513 /** @copydoc PDMAPICREG::pfnSetBaseR3 */
514 DECLR0CALLBACKMEMBER(void, pfnSetBaseR0,(PPDMDEVINS pDevIns, uint64_t u64Base));
515 /** @copydoc PDMAPICREG::pfnGetBaseR3 */
516 DECLR0CALLBACKMEMBER(uint64_t, pfnGetBaseR0,(PPDMDEVINS pDevIns));
517 /** @copydoc PDMAPICREG::pfnSetTPRR3 */
518 DECLR0CALLBACKMEMBER(void, pfnSetTPRR0,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR));
519 /** @copydoc PDMAPICREG::pfnGetTPRR3 */
520 DECLR0CALLBACKMEMBER(uint8_t, pfnGetTPRR0,(PPDMDEVINS pDevIns, VMCPUID idCpu));
521 /** @copydoc PDMAPICREG::pfnWriteMSRR3 */
522 DECLR0CALLBACKMEMBER(uint32_t, pfnWriteMSRR0, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value));
523 /** @copydoc PDMAPICREG::pfnReadMSRR3 */
524 DECLR0CALLBACKMEMBER(uint32_t, pfnReadMSRR0, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value));
525 /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
526 DECLR0CALLBACKMEMBER(int, pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
527 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
528 /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
529 DECLR0CALLBACKMEMBER(int, pfnLocalInterruptR0,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
530
531 /** Pointer to the APIC device instance - RC Ptr. */
532 PPDMDEVINSRC pDevInsRC;
533 /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
534 DECLRCCALLBACKMEMBER(int, pfnGetInterruptRC,(PPDMDEVINS pDevIns));
535 /** @copydoc PDMAPICREG::pfnHasPendingIrqR3 */
536 DECLRCCALLBACKMEMBER(bool, pfnHasPendingIrqRC,(PPDMDEVINS pDevIns));
537 /** @copydoc PDMAPICREG::pfnSetBaseR3 */
538 DECLRCCALLBACKMEMBER(void, pfnSetBaseRC,(PPDMDEVINS pDevIns, uint64_t u64Base));
539 /** @copydoc PDMAPICREG::pfnGetBaseR3 */
540 DECLRCCALLBACKMEMBER(uint64_t, pfnGetBaseRC,(PPDMDEVINS pDevIns));
541 /** @copydoc PDMAPICREG::pfnSetTPRR3 */
542 DECLRCCALLBACKMEMBER(void, pfnSetTPRRC,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR));
543 /** @copydoc PDMAPICREG::pfnGetTPRR3 */
544 DECLRCCALLBACKMEMBER(uint8_t, pfnGetTPRRC,(PPDMDEVINS pDevIns, VMCPUID idCpu));
545 /** @copydoc PDMAPICREG::pfnWriteMSRR3 */
546 DECLRCCALLBACKMEMBER(uint32_t, pfnWriteMSRRC, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value));
547 /** @copydoc PDMAPICREG::pfnReadMSRR3 */
548 DECLRCCALLBACKMEMBER(uint32_t, pfnReadMSRRC, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value));
549 /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
550 DECLRCCALLBACKMEMBER(int, pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
551 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
552 /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
553 DECLRCCALLBACKMEMBER(int, pfnLocalInterruptRC,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
554 RTRCPTR RCPtrAlignment;
555
556} PDMAPIC;
557
558
559/**
560 * PDM registered I/O APIC device.
561 */
562typedef struct PDMIOAPIC
563{
564 /** Pointer to the APIC device instance - R3 Ptr. */
565 PPDMDEVINSR3 pDevInsR3;
566 /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
567 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
568 /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
569 DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
570
571 /** Pointer to the PIC device instance - R0. */
572 PPDMDEVINSR0 pDevInsR0;
573 /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
574 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
575 /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
576 DECLR0CALLBACKMEMBER(void, pfnSendMsiR0,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
577
578 /** Pointer to the APIC device instance - RC Ptr. */
579 PPDMDEVINSRC pDevInsRC;
580 /** @copydoc PDMIOAPICREG::pfnSetIrqR3 */
581 DECLRCCALLBACKMEMBER(void, pfnSetIrqRC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
582 /** @copydoc PDMIOAPICREG::pfnSendMsiR3 */
583 DECLRCCALLBACKMEMBER(void, pfnSendMsiRC,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
584
585 uint8_t Alignment[4];
586} PDMIOAPIC;
587
588/** Maximum number of PCI busses for a VM. */
589#define PDM_PCI_BUSSES_MAX 8
590
591/**
592 * PDM PCI Bus instance.
593 */
594typedef struct PDMPCIBUS
595{
596 /** PCI bus number. */
597 RTUINT iBus;
598 RTUINT uPadding0; /**< Alignment padding.*/
599
600 /** Pointer to PCI Bus device instance. */
601 PPDMDEVINSR3 pDevInsR3;
602 /** @copydoc PDMPCIBUSREG::pfnSetIrqR3 */
603 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
604 /** @copydoc PDMPCIBUSREG::pfnRegisterR3 */
605 DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev));
606 /** @copydoc PDMPCIBUSREG::pfnPCIRegisterMsiR3 */
607 DECLR3CALLBACKMEMBER(int, pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg));
608 /** @copydoc PDMPCIBUSREG::pfnIORegionRegisterR3 */
609 DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, uint32_t cbRegion,
610 PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
611 /** @copydoc PDMPCIBUSREG::pfnSetConfigCallbacksR3 */
612 DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead,
613 PPFNPCICONFIGREAD ppfnReadOld, PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
614 /** @copydoc PDMPCIBUSREG::pfnSaveExecR3 */
615 DECLR3CALLBACKMEMBER(int, pfnSaveExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
616 /** @copydoc PDMPCIBUSREG::pfnLoadExecR3 */
617 DECLR3CALLBACKMEMBER(int, pfnLoadExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
618 /** @copydoc PDMPCIBUSREG::pfnFakePCIBIOSR3 */
619 DECLR3CALLBACKMEMBER(int, pfnFakePCIBIOSR3,(PPDMDEVINS pDevIns));
620
621 /** Pointer to the PIC device instance - R0. */
622 R0PTRTYPE(PPDMDEVINS) pDevInsR0;
623 /** @copydoc PDMPCIBUSREG::pfnSetIrqR3 */
624 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
625
626 /** Pointer to PCI Bus device instance. */
627 PPDMDEVINSRC pDevInsRC;
628 /** @copydoc PDMPCIBUSREG::pfnSetIrqR3 */
629 DECLRCCALLBACKMEMBER(void, pfnSetIrqRC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
630} PDMPCIBUS;
631
632
633#ifdef IN_RING3
634/**
635 * PDM registered DMAC (DMA Controller) device.
636 */
637typedef struct PDMDMAC
638{
639 /** Pointer to the DMAC device instance. */
640 PPDMDEVINSR3 pDevIns;
641 /** Copy of the registration structure. */
642 PDMDMACREG Reg;
643} PDMDMAC;
644
645
646/**
647 * PDM registered RTC (Real Time Clock) device.
648 */
649typedef struct PDMRTC
650{
651 /** Pointer to the RTC device instance. */
652 PPDMDEVINSR3 pDevIns;
653 /** Copy of the registration structure. */
654 PDMRTCREG Reg;
655} PDMRTC;
656
657#endif /* IN_RING3 */
658
659/**
660 * Module type.
661 */
662typedef enum PDMMODTYPE
663{
664 /** Raw-mode (RC) context module. */
665 PDMMOD_TYPE_RC,
666 /** Ring-0 (host) context module. */
667 PDMMOD_TYPE_R0,
668 /** Ring-3 (host) context module. */
669 PDMMOD_TYPE_R3
670} PDMMODTYPE;
671
672
673/** The module name length including the terminator. */
674#define PDMMOD_NAME_LEN 32
675
676/**
677 * Loaded module instance.
678 */
679typedef struct PDMMOD
680{
681 /** Module name. This is used for referring to
682 * the module internally, sort of like a handle. */
683 char szName[PDMMOD_NAME_LEN];
684 /** Module type. */
685 PDMMODTYPE eType;
686 /** Loader module handle. Not used for R0 modules. */
687 RTLDRMOD hLdrMod;
688 /** Loaded address.
689 * This is the 'handle' for R0 modules. */
690 RTUINTPTR ImageBase;
691 /** Old loaded address.
692 * This is used during relocation of GC modules. Not used for R0 modules. */
693 RTUINTPTR OldImageBase;
694 /** Where the R3 HC bits are stored.
695 * This can be equal to ImageBase but doesn't have to. Not used for R0 modules. */
696 void *pvBits;
697
698 /** Pointer to next module. */
699 struct PDMMOD *pNext;
700 /** Module filename. */
701 char szFilename[1];
702} PDMMOD;
703/** Pointer to loaded module instance. */
704typedef PDMMOD *PPDMMOD;
705
706
707
708/** Extra space in the free array. */
709#define PDMQUEUE_FREE_SLACK 16
710
711/**
712 * Queue type.
713 */
714typedef enum PDMQUEUETYPE
715{
716 /** Device consumer. */
717 PDMQUEUETYPE_DEV = 1,
718 /** Driver consumer. */
719 PDMQUEUETYPE_DRV,
720 /** Internal consumer. */
721 PDMQUEUETYPE_INTERNAL,
722 /** External consumer. */
723 PDMQUEUETYPE_EXTERNAL
724} PDMQUEUETYPE;
725
726/** Pointer to a PDM Queue. */
727typedef struct PDMQUEUE *PPDMQUEUE;
728
729/**
730 * PDM Queue.
731 */
732typedef struct PDMQUEUE
733{
734 /** Pointer to the next queue in the list. */
735 R3PTRTYPE(PPDMQUEUE) pNext;
736 /** Type specific data. */
737 union
738 {
739 /** PDMQUEUETYPE_DEV */
740 struct
741 {
742 /** Pointer to consumer function. */
743 R3PTRTYPE(PFNPDMQUEUEDEV) pfnCallback;
744 /** Pointer to the device instance owning the queue. */
745 R3PTRTYPE(PPDMDEVINS) pDevIns;
746 } Dev;
747 /** PDMQUEUETYPE_DRV */
748 struct
749 {
750 /** Pointer to consumer function. */
751 R3PTRTYPE(PFNPDMQUEUEDRV) pfnCallback;
752 /** Pointer to the driver instance owning the queue. */
753 R3PTRTYPE(PPDMDRVINS) pDrvIns;
754 } Drv;
755 /** PDMQUEUETYPE_INTERNAL */
756 struct
757 {
758 /** Pointer to consumer function. */
759 R3PTRTYPE(PFNPDMQUEUEINT) pfnCallback;
760 } Int;
761 /** PDMQUEUETYPE_EXTERNAL */
762 struct
763 {
764 /** Pointer to consumer function. */
765 R3PTRTYPE(PFNPDMQUEUEEXT) pfnCallback;
766 /** Pointer to user argument. */
767 R3PTRTYPE(void *) pvUser;
768 } Ext;
769 } u;
770 /** Queue type. */
771 PDMQUEUETYPE enmType;
772 /** The interval between checking the queue for events.
773 * The realtime timer below is used to do the waiting.
774 * If 0, the queue will use the VM_FF_PDM_QUEUE forced action. */
775 uint32_t cMilliesInterval;
776 /** Interval timer. Only used if cMilliesInterval is non-zero. */
777 PTMTIMERR3 pTimer;
778 /** Pointer to the VM - R3. */
779 PVMR3 pVMR3;
780 /** LIFO of pending items - R3. */
781 R3PTRTYPE(PPDMQUEUEITEMCORE) volatile pPendingR3;
782 /** Pointer to the VM - R0. */
783 PVMR0 pVMR0;
784 /** LIFO of pending items - R0. */
785 R0PTRTYPE(PPDMQUEUEITEMCORE) volatile pPendingR0;
786 /** Pointer to the GC VM and indicator for GC enabled queue.
787 * If this is NULL, the queue cannot be used in GC.
788 */
789 PVMRC pVMRC;
790 /** LIFO of pending items - GC. */
791 RCPTRTYPE(PPDMQUEUEITEMCORE) volatile pPendingRC;
792
793 /** Item size (bytes). */
794 uint32_t cbItem;
795 /** Number of items in the queue. */
796 uint32_t cItems;
797 /** Index to the free head (where we insert). */
798 uint32_t volatile iFreeHead;
799 /** Index to the free tail (where we remove). */
800 uint32_t volatile iFreeTail;
801
802 /** Unique queue name. */
803 R3PTRTYPE(const char *) pszName;
804#if HC_ARCH_BITS == 32
805 RTR3PTR Alignment1;
806#endif
807 /** Stat: Times PDMQueueAlloc fails. */
808 STAMCOUNTER StatAllocFailures;
809 /** Stat: PDMQueueInsert calls. */
810 STAMCOUNTER StatInsert;
811 /** Stat: Queue flushes. */
812 STAMCOUNTER StatFlush;
813 /** Stat: Queue flushes with pending items left over. */
814 STAMCOUNTER StatFlushLeftovers;
815#ifdef VBOX_WITH_STATISTICS
816 /** State: Profiling the flushing. */
817 STAMPROFILE StatFlushPrf;
818 /** State: Pending items. */
819 uint32_t volatile cStatPending;
820 uint32_t volatile cAlignment;
821#endif
822
823 /** Array of pointers to free items. Variable size. */
824 struct PDMQUEUEFREEITEM
825 {
826 /** Pointer to the free item - HC Ptr. */
827 R3PTRTYPE(PPDMQUEUEITEMCORE) volatile pItemR3;
828 /** Pointer to the free item - HC Ptr. */
829 R0PTRTYPE(PPDMQUEUEITEMCORE) volatile pItemR0;
830 /** Pointer to the free item - GC Ptr. */
831 RCPTRTYPE(PPDMQUEUEITEMCORE) volatile pItemRC;
832#if HC_ARCH_BITS == 64
833 RTRCPTR Alignment0;
834#endif
835 } aFreeItems[1];
836} PDMQUEUE;
837
838/** @name PDM::fQueueFlushing
839 * @{ */
840/** Used to make sure only one EMT will flush the queues.
841 * Set when an EMT is flushing queues, clear otherwise. */
842#define PDM_QUEUE_FLUSH_FLAG_ACTIVE_BIT 0
843/** Indicating there are queues with items pending.
844 * This is make sure we don't miss inserts happening during flushing. The FF
845 * cannot be used for this since it has to be cleared immediately to prevent
846 * other EMTs from spinning. */
847#define PDM_QUEUE_FLUSH_FLAG_PENDING_BIT 1
848/** }@ */
849
850
851/**
852 * Queue device helper task operation.
853 */
854typedef enum PDMDEVHLPTASKOP
855{
856 /** The usual invalid 0 entry. */
857 PDMDEVHLPTASKOP_INVALID = 0,
858 /** ISASetIrq */
859 PDMDEVHLPTASKOP_ISA_SET_IRQ,
860 /** PCISetIrq */
861 PDMDEVHLPTASKOP_PCI_SET_IRQ,
862 /** PCISetIrq */
863 PDMDEVHLPTASKOP_IOAPIC_SET_IRQ,
864 /** The usual 32-bit hack. */
865 PDMDEVHLPTASKOP_32BIT_HACK = 0x7fffffff
866} PDMDEVHLPTASKOP;
867
868/**
869 * Queued Device Helper Task.
870 */
871typedef struct PDMDEVHLPTASK
872{
873 /** The queue item core (don't touch). */
874 PDMQUEUEITEMCORE Core;
875 /** Pointer to the device instance (R3 Ptr). */
876 PPDMDEVINSR3 pDevInsR3;
877 /** This operation to perform. */
878 PDMDEVHLPTASKOP enmOp;
879#if HC_ARCH_BITS == 64
880 uint32_t Alignment0;
881#endif
882 /** Parameters to the operation. */
883 union PDMDEVHLPTASKPARAMS
884 {
885 /**
886 * PDMDEVHLPTASKOP_ISA_SET_IRQ and PDMDEVHLPTASKOP_PCI_SET_IRQ.
887 */
888 struct PDMDEVHLPTASKSETIRQ
889 {
890 /** The IRQ */
891 int iIrq;
892 /** The new level. */
893 int iLevel;
894 } SetIRQ;
895 } u;
896} PDMDEVHLPTASK;
897/** Pointer to a queued Device Helper Task. */
898typedef PDMDEVHLPTASK *PPDMDEVHLPTASK;
899/** Pointer to a const queued Device Helper Task. */
900typedef const PDMDEVHLPTASK *PCPDMDEVHLPTASK;
901
902
903
904/**
905 * An USB hub registration record.
906 */
907typedef struct PDMUSBHUB
908{
909 /** The USB versions this hub support.
910 * Note that 1.1 hubs can take on 2.0 devices. */
911 uint32_t fVersions;
912 /** The number of ports on the hub. */
913 uint32_t cPorts;
914 /** The number of available ports (0..cPorts). */
915 uint32_t cAvailablePorts;
916 /** The driver instance of the hub. */
917 PPDMDRVINS pDrvIns;
918 /** Copy of the to the registration structure. */
919 PDMUSBHUBREG Reg;
920
921 /** Pointer to the next hub in the list. */
922 struct PDMUSBHUB *pNext;
923} PDMUSBHUB;
924
925/** Pointer to a const USB HUB registration record. */
926typedef const PDMUSBHUB *PCPDMUSBHUB;
927
928/** Pointer to a PDM Async I/O template. */
929typedef struct PDMASYNCCOMPLETIONTEMPLATE *PPDMASYNCCOMPLETIONTEMPLATE;
930
931/** Pointer to the main PDM Async completion endpoint class. */
932typedef struct PDMASYNCCOMPLETIONEPCLASS *PPDMASYNCCOMPLETIONEPCLASS;
933
934/** Pointer to the global block cache structure. */
935typedef struct PDMBLKCACHEGLOBAL *PPDMBLKCACHEGLOBAL;
936
937/**
938 * PDM VMCPU Instance data.
939 * Changes to this must checked against the padding of the cfgm union in VMCPU!
940 */
941typedef struct PDMCPU
942{
943 /** The number of entries in the apQueuedCritSectsLeaves table that's currently in use. */
944 uint32_t cQueuedCritSectLeaves;
945 uint32_t uPadding0; /**< Alignment padding.*/
946 /** Critical sections queued in RC/R0 because of contention preventing leave to complete. (R3 Ptrs)
947 * We will return to Ring-3 ASAP, so this queue doesn't have to be very long. */
948 R3PTRTYPE(PPDMCRITSECT) apQueuedCritSectsLeaves[8];
949} PDMCPU;
950
951
952/**
953 * PDM VM Instance data.
954 * Changes to this must checked against the padding of the cfgm union in VM!
955 */
956typedef struct PDM
957{
958 /** The PDM lock.
959 * This is used to protect everything that deals with interrupts, i.e.
960 * the PIC, APIC, IOAPIC and PCI devices plus some PDM functions. */
961 PDMCRITSECT CritSect;
962 /** The NOP critical section.
963 * This is a dummy critical section that will not do any thread
964 * serialization but instead let all threads enter immediately and
965 * concurrently. */
966 PDMCRITSECT NopCritSect;
967
968 /** List of registered devices. (FIFO) */
969 R3PTRTYPE(PPDMDEV) pDevs;
970 /** List of devices instances. (FIFO) */
971 R3PTRTYPE(PPDMDEVINS) pDevInstances;
972 /** List of registered USB devices. (FIFO) */
973 R3PTRTYPE(PPDMUSB) pUsbDevs;
974 /** List of USB devices instances. (FIFO) */
975 R3PTRTYPE(PPDMUSBINS) pUsbInstances;
976 /** List of registered drivers. (FIFO) */
977 R3PTRTYPE(PPDMDRV) pDrvs;
978 /** PCI Buses. */
979 PDMPCIBUS aPciBuses[PDM_PCI_BUSSES_MAX];
980 /** The register PIC device. */
981 PDMPIC Pic;
982 /** The registered APIC device. */
983 PDMAPIC Apic;
984 /** The registered I/O APIC device. */
985 PDMIOAPIC IoApic;
986 /** The registered DMAC device. */
987 R3PTRTYPE(PPDMDMAC) pDmac;
988 /** The registered RTC device. */
989 R3PTRTYPE(PPDMRTC) pRtc;
990 /** The registered USB HUBs. (FIFO) */
991 R3PTRTYPE(PPDMUSBHUB) pUsbHubs;
992
993 /** Queue in which devhlp tasks are queued for R3 execution - R3 Ptr. */
994 R3PTRTYPE(PPDMQUEUE) pDevHlpQueueR3;
995 /** Queue in which devhlp tasks are queued for R3 execution - R0 Ptr. */
996 R0PTRTYPE(PPDMQUEUE) pDevHlpQueueR0;
997 /** Queue in which devhlp tasks are queued for R3 execution - RC Ptr. */
998 RCPTRTYPE(PPDMQUEUE) pDevHlpQueueRC;
999 /** Pointer to the queue which should be manually flushed - RC Ptr.
1000 * Only touched by EMT. */
1001 RCPTRTYPE(struct PDMQUEUE *) pQueueFlushRC;
1002 /** Pointer to the queue which should be manually flushed - R0 Ptr.
1003 * Only touched by EMT. */
1004 R0PTRTYPE(struct PDMQUEUE *) pQueueFlushR0;
1005 /** Bitmask controlling the queue flushing.
1006 * See PDM_QUEUE_FLUSH_FLAG_ACTIVE and PDM_QUEUE_FLUSH_FLAG_PENDING. */
1007 uint32_t volatile fQueueFlushing;
1008 /** Alignment padding. */
1009 uint32_t u32Padding2;
1010
1011 /** @name VMM device heap
1012 * @{ */
1013 /** Pointer to the heap base (MMIO2 ring-3 mapping). NULL if not registered. */
1014 RTR3PTR pvVMMDevHeap;
1015 /** The heap size. */
1016 uint32_t cbVMMDevHeap;
1017 /** Free space. */
1018 uint32_t cbVMMDevHeapLeft;
1019 /** The current mapping. NIL_RTGCPHYS if not mapped or registered. */
1020 RTGCPHYS GCPhysVMMDevHeap;
1021 /** @} */
1022
1023 /** Number of times a critical section leave request needed to be queued for ring-3 execution. */
1024 STAMCOUNTER StatQueuedCritSectLeaves;
1025} PDM;
1026AssertCompileMemberAlignment(PDM, GCPhysVMMDevHeap, sizeof(RTGCPHYS));
1027AssertCompileMemberAlignment(PDM, CritSect, 8);
1028AssertCompileMemberAlignment(PDM, StatQueuedCritSectLeaves, 8);
1029/** Pointer to PDM VM instance data. */
1030typedef PDM *PPDM;
1031
1032
1033
1034/**
1035 * PDM data kept in the UVM.
1036 */
1037typedef struct PDMUSERPERVM
1038{
1039 /** @todo move more stuff over here. */
1040
1041 /** Linked list of timer driven PDM queues.
1042 * Currently serialized by PDM::CritSect. */
1043 R3PTRTYPE(struct PDMQUEUE *) pQueuesTimer;
1044 /** Linked list of force action driven PDM queues.
1045 * Currently serialized by PDM::CritSect. */
1046 R3PTRTYPE(struct PDMQUEUE *) pQueuesForced;
1047
1048 /** Lock protecting the lists below it. */
1049 RTCRITSECT ListCritSect;
1050 /** Pointer to list of loaded modules. */
1051 PPDMMOD pModules;
1052 /** List of initialized critical sections. (LIFO) */
1053 R3PTRTYPE(PPDMCRITSECTINT) pCritSects;
1054 /** Head of the PDM Thread list. (singly linked) */
1055 R3PTRTYPE(PPDMTHREAD) pThreads;
1056 /** Tail of the PDM Thread list. (singly linked) */
1057 R3PTRTYPE(PPDMTHREAD) pThreadsTail;
1058
1059 /** @name PDM Async Completion
1060 * @{ */
1061 /** Pointer to the array of supported endpoint classes. */
1062 PPDMASYNCCOMPLETIONEPCLASS apAsyncCompletionEndpointClass[PDMASYNCCOMPLETIONEPCLASSTYPE_MAX];
1063 /** Head of the templates. Singly linked, protected by ListCritSect. */
1064 R3PTRTYPE(PPDMASYNCCOMPLETIONTEMPLATE) pAsyncCompletionTemplates;
1065 /** @} */
1066#ifdef VBOX_WITH_NETSHAPER
1067 /** Pointer to network shaper instance. */
1068 R3PTRTYPE(PPDMNETSHAPER) pNetShaper;
1069#endif /* VBOX_WITH_NETSHAPER */
1070
1071 R3PTRTYPE(PPDMBLKCACHEGLOBAL) pBlkCacheGlobal;
1072
1073} PDMUSERPERVM;
1074/** Pointer to the PDM data kept in the UVM. */
1075typedef PDMUSERPERVM *PPDMUSERPERVM;
1076
1077
1078
1079/*******************************************************************************
1080* Global Variables *
1081*******************************************************************************/
1082#ifdef IN_RING3
1083extern const PDMDRVHLPR3 g_pdmR3DrvHlp;
1084extern const PDMDEVHLPR3 g_pdmR3DevHlpTrusted;
1085extern const PDMDEVHLPR3 g_pdmR3DevHlpUnTrusted;
1086extern const PDMPICHLPR3 g_pdmR3DevPicHlp;
1087extern const PDMAPICHLPR3 g_pdmR3DevApicHlp;
1088extern const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp;
1089extern const PDMPCIHLPR3 g_pdmR3DevPciHlp;
1090extern const PDMDMACHLP g_pdmR3DevDmacHlp;
1091extern const PDMRTCHLP g_pdmR3DevRtcHlp;
1092extern const PDMHPETHLPR3 g_pdmR3DevHpetHlp;
1093extern const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp;
1094#endif
1095
1096
1097/*******************************************************************************
1098* Defined Constants And Macros *
1099*******************************************************************************/
1100/** @def PDMDEV_ASSERT_DEVINS
1101 * Asserts the validity of the device instance.
1102 */
1103#ifdef VBOX_STRICT
1104# define PDMDEV_ASSERT_DEVINS(pDevIns) \
1105 do { \
1106 AssertPtr(pDevIns); \
1107 Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \
1108 Assert(pDevIns->CTX_SUFF(pvInstanceData) == (void *)&pDevIns->achInstanceData[0]); \
1109 } while (0)
1110#else
1111# define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0)
1112#endif
1113
1114/** @def PDMDRV_ASSERT_DRVINS
1115 * Asserts the validity of the driver instance.
1116 */
1117#ifdef VBOX_STRICT
1118# define PDMDRV_ASSERT_DRVINS(pDrvIns) \
1119 do { \
1120 AssertPtr(pDrvIns); \
1121 Assert(pDrvIns->u32Version == PDM_DRVINS_VERSION); \
1122 Assert(pDrvIns->CTX_SUFF(pvInstanceData) == (void *)&pDrvIns->achInstanceData[0]); \
1123 } while (0)
1124#else
1125# define PDMDRV_ASSERT_DRVINS(pDrvIns) do { } while (0)
1126#endif
1127
1128
1129/*******************************************************************************
1130* Internal Functions *
1131*******************************************************************************/
1132#ifdef IN_RING3
1133bool pdmR3IsValidName(const char *pszName);
1134
1135int pdmR3CritSectInitStats(PVM pVM);
1136void pdmR3CritSectRelocate(PVM pVM);
1137int pdmR3CritSectInitDevice(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, va_list va);
1138int pdmR3CritSectInitDeviceAuto(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
1139 const char *pszNameFmt, ...);
1140int pdmR3CritSectDeleteDevice(PVM pVM, PPDMDEVINS pDevIns);
1141int pdmR3CritSectInitDriver(PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...);
1142int pdmR3CritSectDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns);
1143
1144int pdmR3DevInit(PVM pVM);
1145PPDMDEV pdmR3DevLookup(PVM pVM, const char *pszName);
1146int pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);
1147DECLCALLBACK(bool) pdmR3DevHlpQueueConsumer(PVM pVM, PPDMQUEUEITEMCORE pItem);
1148
1149int pdmR3UsbLoadModules(PVM pVM);
1150int pdmR3UsbInstantiateDevices(PVM pVM);
1151PPDMUSB pdmR3UsbLookup(PVM pVM, const char *pszName);
1152int pdmR3UsbFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);
1153int pdmR3UsbRegisterHub(PVM pVM, PPDMDRVINS pDrvIns, uint32_t fVersions, uint32_t cPorts, PCPDMUSBHUBREG pUsbHubReg, PPCPDMUSBHUBHLP ppUsbHubHlp);
1154int pdmR3UsbVMInitComplete(PVM pVM);
1155
1156int pdmR3DrvInit(PVM pVM);
1157int pdmR3DrvInstantiate(PVM pVM, PCFGMNODE pNode, PPDMIBASE pBaseInterface, PPDMDRVINS pDrvAbove,
1158 PPDMLUN pLun, PPDMIBASE *ppBaseInterface);
1159int pdmR3DrvDetach(PPDMDRVINS pDrvIns, uint32_t fFlags);
1160void pdmR3DrvDestroyChain(PPDMDRVINS pDrvIns, uint32_t fFlags);
1161PPDMDRV pdmR3DrvLookup(PVM pVM, const char *pszName);
1162
1163int pdmR3LdrInitU(PUVM pUVM);
1164void pdmR3LdrTermU(PUVM pUVM);
1165char *pdmR3FileR3(const char *pszFile, bool fShared);
1166int pdmR3LoadR3U(PUVM pUVM, const char *pszFilename, const char *pszName);
1167
1168void pdmR3QueueRelocate(PVM pVM, RTGCINTPTR offDelta);
1169
1170int pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
1171 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1172int pdmR3ThreadCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
1173 PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1174int pdmR3ThreadCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
1175 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
1176int pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
1177int pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
1178int pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
1179void pdmR3ThreadDestroyAll(PVM pVM);
1180int pdmR3ThreadResumeAll(PVM pVM);
1181int pdmR3ThreadSuspendAll(PVM pVM);
1182
1183#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
1184int pdmR3AsyncCompletionInit(PVM pVM);
1185int pdmR3AsyncCompletionTerm(PVM pVM);
1186void pdmR3AsyncCompletionResume(PVM pVM);
1187#endif
1188
1189#ifdef VBOX_WITH_NETSHAPER
1190int pdmR3NetShaperInit(PVM pVM);
1191int pdmR3NetShaperTerm(PVM pVM);
1192#endif
1193
1194int pdmR3BlkCacheInit(PVM pVM);
1195void pdmR3BlkCacheTerm(PVM pVM);
1196int pdmR3BlkCacheResume(PVM pVM);
1197
1198#endif /* IN_RING3 */
1199
1200void pdmLock(PVM pVM);
1201int pdmLockEx(PVM pVM, int rc);
1202void pdmUnlock(PVM pVM);
1203
1204/** @} */
1205
1206RT_C_DECLS_END
1207
1208#endif
1209
Note: See TracBrowser for help on using the repository browser.

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