VirtualBox

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

Last change on this file since 43667 was 43657, checked in by vboxsync, 12 years ago

VMM: APIC refactor. Moved APIC base MSR to the VCPU (where it belongs) for lockless accesses.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use