VirtualBox

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

Last change on this file since 37466 was 37466, checked in by vboxsync, 14 years ago

VMM,Devices: Automatically use a per-device lock instead of the giant IOM lock. With exception of the PIC, APIC, IOAPIC and PCI buses which are all using the PDM crit sect, there should be no calls between devices. So, this change should be relatively safe.

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