VirtualBox

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

Last change on this file since 6862 was 6796, checked in by vboxsync, 17 years ago

Fixed init problems wrt. VM ownership by implementing the UVM structure (U = user mode) and moving problematic ring-3 stuff over there (emt+reqs, r3heap, stam, loader[VMMR0.r0]). Big change, but it works fine here... :-)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 33.4 KB
Line 
1/* $Id: PDMInternal.h 6796 2008-02-04 18:19:58Z vboxsync $ */
2/** @file
3 * PDM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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/cdefs.h>
22#include <VBox/types.h>
23#include <VBox/param.h>
24#include <VBox/cfgm.h>
25#include <VBox/stam.h>
26#include <VBox/vusb.h>
27#include <VBox/pdmasynccompletion.h>
28#include <iprt/critsect.h>
29#ifdef IN_RING3
30# include <iprt/thread.h>
31#endif
32
33__BEGIN_DECLS
34
35
36/** @defgroup grp_pdm_int Internal
37 * @ingroup grp_pdm
38 * @internal
39 * @{
40 */
41
42/*******************************************************************************
43* Structures and Typedefs *
44*******************************************************************************/
45
46/** Pointer to a PDM Device. */
47typedef struct PDMDEV *PPDMDEV;
48/** Pointer to a pointer to a PDM Device. */
49typedef PPDMDEV *PPPDMDEV;
50
51/** Pointer to a PDM USB Device. */
52typedef struct PDMUSB *PPDMUSB;
53/** Pointer to a pointer to a PDM USB Device. */
54typedef PPDMUSB *PPPDMUSB;
55
56/** Pointer to a PDM Driver. */
57typedef struct PDMDRV *PPDMDRV;
58/** Pointer to a pointer to a PDM Driver. */
59typedef PPDMDRV *PPPDMDRV;
60
61/** Pointer to a PDM Logical Unit. */
62typedef struct PDMLUN *PPDMLUN;
63/** Pointer to a pointer to a PDM Logical Unit. */
64typedef PPDMLUN *PPPDMLUN;
65
66/** Pointer to a PDM PCI Bus instance. */
67typedef struct PDMPCIBUS *PPDMPCIBUS;
68/** Pointer to a DMAC instance. */
69typedef struct PDMDMAC *PPDMDMAC;
70/** Pointer to a RTC instance. */
71typedef struct PDMRTC *PPDMRTC;
72
73/** Pointer to an USB HUB registration record. */
74typedef struct PDMUSBHUB *PPDMUSBHUB;
75
76/**
77 * Private device instance data.
78 */
79typedef struct PDMDEVINSINT
80{
81 /** Pointer to the next instance (HC Ptr).
82 * (Head is pointed to by PDM::pDevInstances.) */
83 R3PTRTYPE(PPDMDEVINS) pNextHC;
84 /** Pointer to the next per device instance (HC Ptr).
85 * (Head is pointed to by PDMDEV::pInstances.) */
86 R3PTRTYPE(PPDMDEVINS) pPerDeviceNextHC;
87
88 /** Pointer to device structure - HC Ptr. */
89 R3PTRTYPE(PPDMDEV) pDevHC;
90
91 /** Pointer to the VM this instance was created for - HC Ptr. */
92 R3R0PTRTYPE(PVM) pVMHC;
93 /** Pointer to the list of logical units associated with the device. (FIFO) */
94 R3PTRTYPE(PPDMLUN) pLunsHC;
95 /** Configuration handle to the instance node. */
96 R3PTRTYPE(PCFGMNODE) pCfgHandle;
97 /** HC pointer to associated PCI device structure. */
98 R3R0PTRTYPE(struct PCIDevice *) pPciDeviceHC;
99 /** HC pointer to associated PCI bus structure. */
100 R3R0PTRTYPE(PPDMPCIBUS) pPciBusHC;
101
102 /** GC pointer to associated PCI device structure. */
103 GCPTRTYPE(struct PCIDevice *) pPciDeviceGC;
104 /** Pointer to the VM this instance was created for - GC Ptr. */
105 GCPTRTYPE(PVM) pVMGC;
106 /** GC pointer to associated PCI bus structure. */
107 GCPTRTYPE(PPDMPCIBUS) pPciBusGC;
108#if GC_ARCH_BITS == 32
109 uint32_t Alignment0;
110#endif
111} PDMDEVINSINT;
112
113
114/**
115 * Private USB device instance data.
116 */
117typedef struct PDMUSBINSINT
118{
119 /** The UUID of this instance. */
120 RTUUID Uuid;
121 /** Pointer to the next instance.
122 * (Head is pointed to by PDM::pUsbInstances.) */
123 R3PTRTYPE(PPDMUSBINS) pNext;
124 /** Pointer to the next per USB device instance.
125 * (Head is pointed to by PDMUSB::pInstances.) */
126 R3PTRTYPE(PPDMUSBINS) pPerDeviceNext;
127
128 /** Pointer to device structure. */
129 R3PTRTYPE(PPDMUSB) pUsbDev;
130
131 /** Pointer to the VM this instance was created for. */
132 PVMR3 pVM;
133 /** Pointer to the list of logical units associated with the device. (FIFO) */
134 R3PTRTYPE(PPDMLUN) pLuns;
135 /** The per instance device configuration. */
136 R3PTRTYPE(PCFGMNODE) pCfg;
137 /** Same as pCfg if the configuration should be deleted when detaching the device. */
138 R3PTRTYPE(PCFGMNODE) pCfgDelete;
139 /** The global device configuration. */
140 R3PTRTYPE(PCFGMNODE) pCfgGlobal;
141
142 /** Pointer to the USB hub this device is attached to.
143 * This is NULL if the device isn't connected to any HUB. */
144 R3PTRTYPE(PPDMUSBHUB) pHub;
145 /** The port number that we're connected to. */
146 uint32_t iPort;
147#if HC_ARCH_BITS == 64
148 uint32_t Alignment0;
149#endif
150} PDMUSBINSINT;
151
152
153/**
154 * Private driver instance data.
155 */
156typedef struct PDMDRVINSINT
157{
158 /** Pointer to the driver instance above.
159 * This is NULL for the topmost drive. */
160 PPDMDRVINS pUp;
161 /** Pointer to the driver instance below.
162 * This is NULL for the bottommost driver. */
163 PPDMDRVINS pDown;
164 /** Pointer to the logical unit this driver chained on. */
165 PPDMLUN pLun;
166 /** Pointer to driver structure from which this was instantiated. */
167 PPDMDRV pDrv;
168 /** Pointer to the VM this instance was created for. */
169 PVM pVM;
170 /** Flag indicating that the driver is being detached and destroyed.
171 * (Helps detect potential recursive detaching.) */
172 bool fDetaching;
173 /** Configuration handle to the instance node. */
174 PCFGMNODE pCfgHandle;
175
176} PDMDRVINSINT;
177
178
179/**
180 * Private critical section data.
181 */
182typedef struct PDMCRITSECTINT
183{
184 /** The critical section core which is shared with IPRT. */
185 RTCRITSECT Core;
186 /** Pointer to the next critical section.
187 * This chain is used for relocating pVMGC and device cleanup. */
188 R3PTRTYPE(struct PDMCRITSECTINT *) pNext;
189 /** Owner identifier.
190 * This is pDevIns if the owner is a device. Similarily for a driver or service.
191 * PDMR3CritSectInit() sets this to point to the critsect itself. */
192 RTR3PTR pvKey;
193 /** Pointer to the VM - R3Ptr. */
194 R3PTRTYPE(PVM) pVMR3;
195 /** Pointer to the VM - R0Ptr. */
196 R0PTRTYPE(PVM) pVMR0;
197 /** Pointer to the VM - GCPtr. */
198 GCPTRTYPE(PVM) pVMGC;
199#if HC_ARCH_BITS == 64 && GC_ARCH_BITS == 32
200 uint32_t padding;
201#endif
202 /** Event semaphore that is scheduled to be signaled upon leaving the
203 * critical section. This is Ring-3 only of course. */
204 RTSEMEVENT EventToSignal;
205 /** R0/GC lock contention. */
206 STAMCOUNTER StatContentionR0GCLock;
207 /** R0/GC unlock contention. */
208 STAMCOUNTER StatContentionR0GCUnlock;
209 /** R3 lock contention. */
210 STAMCOUNTER StatContentionR3;
211 /** Profiling the time the section is locked. */
212 STAMPROFILEADV StatLocked;
213} PDMCRITSECTINT, *PPDMCRITSECTINT;
214
215
216/**
217 * The usual device/driver/internal/external stuff.
218 */
219typedef enum
220{
221 /** The usual invalid entry. */
222 PDMTHREADTYPE_INVALID = 0,
223 /** Device type. */
224 PDMTHREADTYPE_DEVICE,
225 /** USB Device type. */
226 PDMTHREADTYPE_USB,
227 /** Driver type. */
228 PDMTHREADTYPE_DRIVER,
229 /** Internal type. */
230 PDMTHREADTYPE_INTERNAL,
231 /** External type. */
232 PDMTHREADTYPE_EXTERNAL,
233 /** The usual 32-bit hack. */
234 PDMTHREADTYPE_32BIT_HACK = 0x7fffffff
235} PDMTHREADTYPE;
236
237
238/**
239 * The internal structure for the thread.
240 */
241typedef struct PDMTHREADINT
242{
243 /** The VM pointer. */
244 PVMR3 pVM;
245 /** The event semaphore the thread blocks on. */
246 RTSEMEVENTMULTI BlockEvent;
247 /** Pointer to the next thread. */
248 R3PTRTYPE(struct PDMTHREAD *) pNext;
249 /** The thread type. */
250 PDMTHREADTYPE enmType;
251} PDMTHREADINT;
252
253
254
255/* Must be included after PDMDEVINSINT is defined. */
256#define PDMDEVINSINT_DECLARED
257#define PDMUSBINSINT_DECLARED
258#define PDMDRVINSINT_DECLARED
259#define PDMCRITSECTINT_DECLARED
260#define PDMTHREADINT_DECLARED
261#ifdef ___VBox_pdm_h
262# error "Invalid header PDM order. Include PDMInternal.h before VBox/pdm.h!"
263#endif
264__END_DECLS
265#include <VBox/pdm.h>
266__BEGIN_DECLS
267
268/**
269 * PDM Logical Unit.
270 *
271 * This typically the representation of a physical port on a
272 * device, like for instance the PS/2 keyboard port on the
273 * keyboard controller device. The LUNs are chained on the
274 * device the belong to (PDMDEVINSINT::pLunsHC).
275 */
276typedef struct PDMLUN
277{
278 /** The LUN - The Logical Unit Number. */
279 RTUINT iLun;
280 /** Pointer to the next LUN. */
281 PPDMLUN pNext;
282 /** Pointer to the top driver in the driver chain. */
283 PPDMDRVINS pTop;
284 /** Pointer to the bottom driver in the driver chain. */
285 PPDMDRVINS pBottom;
286 /** Pointer to the device instance which the LUN belongs to.
287 * Either this is set or pUsbIns is set. Both is never set at the same time. */
288 PPDMDEVINS pDevIns;
289 /** Pointer to the USB device instance which the LUN belongs to. */
290 PPDMUSBINS pUsbIns;
291 /** Pointer to the device base interface. */
292 PPDMIBASE pBase;
293 /** Description of this LUN. */
294 const char *pszDesc;
295} PDMLUN;
296
297
298/**
299 * PDM Device.
300 */
301typedef struct PDMDEV
302{
303 /** Pointer to the next device (HC Ptr). */
304 R3PTRTYPE(PPDMDEV) pNext;
305 /** Device name length. (search optimization) */
306 RTUINT cchName;
307 /** Registration structure. */
308 R3PTRTYPE(const struct PDMDEVREG *) pDevReg;
309 /** Number of instances. */
310 RTUINT cInstances;
311 /** Pointer to chain of instances (HC Ptr). */
312 R3PTRTYPE(PPDMDEVINS) pInstances;
313} PDMDEV;
314
315
316/**
317 * PDM USB Device.
318 */
319typedef struct PDMUSB
320{
321 /** Pointer to the next device (R3 Ptr). */
322 R3PTRTYPE(PPDMUSB) pNext;
323 /** Device name length. (search optimization) */
324 RTUINT cchName;
325 /** Registration structure. */
326 R3PTRTYPE(const struct PDMUSBREG *) pUsbReg;
327 /** Next instance number. */
328 RTUINT iNextInstance;
329 /** Pointer to chain of instances (R3 Ptr). */
330 R3PTRTYPE(PPDMUSBINS) pInstances;
331} PDMUSB;
332
333
334/**
335 * PDM Driver.
336 */
337typedef struct PDMDRV
338{
339 /** Pointer to the next device. */
340 PPDMDRV pNext;
341 /** Registration structure. */
342 const struct PDMDRVREG * pDrvReg;
343 /** Number of instances. */
344 RTUINT cInstances;
345} PDMDRV;
346
347
348/**
349 * PDM registered PIC device.
350 */
351typedef struct PDMPIC
352{
353 /** Pointer to the PIC device instance - HC. */
354 R3PTRTYPE(PPDMDEVINS) pDevInsR3;
355 /** @copydoc PDMPICREG::pfnSetIrqHC */
356 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
357 /** @copydoc PDMPICREG::pfnGetInterruptHC */
358 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns));
359
360 /** Pointer to the PIC device instance - R0. */
361 R0PTRTYPE(PPDMDEVINS) pDevInsR0;
362 /** @copydoc PDMPICREG::pfnSetIrqHC */
363 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
364 /** @copydoc PDMPICREG::pfnGetInterruptHC */
365 DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns));
366
367 /** Pointer to the PIC device instance - GC. */
368 GCPTRTYPE(PPDMDEVINS) pDevInsGC;
369 /** @copydoc PDMPICREG::pfnSetIrqHC */
370 DECLGCCALLBACKMEMBER(void, pfnSetIrqGC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
371 /** @copydoc PDMPICREG::pfnGetInterruptHC */
372 DECLGCCALLBACKMEMBER(int, pfnGetInterruptGC,(PPDMDEVINS pDevIns));
373#if GC_ARCH_BITS == 32
374 RTGCPTR GCPtrPadding; /**< Alignment padding. */
375#endif
376} PDMPIC;
377
378
379/**
380 * PDM registered APIC device.
381 */
382typedef struct PDMAPIC
383{
384 /** Pointer to the APIC device instance - HC Ptr. */
385 PPDMDEVINSR3 pDevInsR3;
386 /** @copydoc PDMAPICREG::pfnGetInterruptHC */
387 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns));
388 /** @copydoc PDMAPICREG::pfnSetBaseHC */
389 DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, uint64_t u64Base));
390 /** @copydoc PDMAPICREG::pfnGetBaseHC */
391 DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns));
392 /** @copydoc PDMAPICREG::pfnSetTPRHC */
393 DECLR3CALLBACKMEMBER(void, pfnSetTPRR3,(PPDMDEVINS pDevIns, uint8_t u8TPR));
394 /** @copydoc PDMAPICREG::pfnGetTPRHC */
395 DECLR3CALLBACKMEMBER(uint8_t, pfnGetTPRR3,(PPDMDEVINS pDevIns));
396 /** @copydoc PDMAPICREG::pfnBusDeliverHC */
397 DECLR3CALLBACKMEMBER(void, pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
398 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
399
400 /** Pointer to the PIC device instance - R0. */
401 R0PTRTYPE(PPDMDEVINS) pDevInsR0;
402 /** @copydoc PDMAPICREG::pfnGetInterruptHC */
403 DECLR0CALLBACKMEMBER(int, pfnGetInterruptR0,(PPDMDEVINS pDevIns));
404 /** @copydoc PDMAPICREG::pfnSetBaseHC */
405 DECLR0CALLBACKMEMBER(void, pfnSetBaseR0,(PPDMDEVINS pDevIns, uint64_t u64Base));
406 /** @copydoc PDMAPICREG::pfnGetBaseHC */
407 DECLR0CALLBACKMEMBER(uint64_t, pfnGetBaseR0,(PPDMDEVINS pDevIns));
408 /** @copydoc PDMAPICREG::pfnSetTPRHC */
409 DECLR0CALLBACKMEMBER(void, pfnSetTPRR0,(PPDMDEVINS pDevIns, uint8_t u8TPR));
410 /** @copydoc PDMAPICREG::pfnGetTPRHC */
411 DECLR0CALLBACKMEMBER(uint8_t, pfnGetTPRR0,(PPDMDEVINS pDevIns));
412 /** @copydoc PDMAPICREG::pfnBusDeliverHC */
413 DECLR0CALLBACKMEMBER(void, pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
414 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
415
416 /** Pointer to the APIC device instance - GC Ptr. */
417 PPDMDEVINSGC pDevInsGC;
418 /** @copydoc PDMAPICREG::pfnGetInterruptHC */
419 DECLGCCALLBACKMEMBER(int, pfnGetInterruptGC,(PPDMDEVINS pDevIns));
420 /** @copydoc PDMAPICREG::pfnSetBaseHC */
421 DECLGCCALLBACKMEMBER(void, pfnSetBaseGC,(PPDMDEVINS pDevIns, uint64_t u64Base));
422 /** @copydoc PDMAPICREG::pfnGetBaseHC */
423 DECLGCCALLBACKMEMBER(uint64_t, pfnGetBaseGC,(PPDMDEVINS pDevIns));
424 /** @copydoc PDMAPICREG::pfnSetTPRHC */
425 DECLGCCALLBACKMEMBER(void, pfnSetTPRGC,(PPDMDEVINS pDevIns, uint8_t u8TPR));
426 /** @copydoc PDMAPICREG::pfnGetTPRHC */
427 DECLGCCALLBACKMEMBER(uint8_t, pfnGetTPRGC,(PPDMDEVINS pDevIns));
428 /** @copydoc PDMAPICREG::pfnBusDeliverHC */
429 DECLGCCALLBACKMEMBER(void, pfnBusDeliverGC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
430 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
431#if GC_ARCH_BITS == 32
432 RTGCPTR GCPtrPadding; /**< Alignment padding. */
433#endif
434} PDMAPIC;
435
436
437/**
438 * PDM registered I/O APIC device.
439 */
440typedef struct PDMIOAPIC
441{
442 /** Pointer to the APIC device instance - HC Ptr. */
443 PPDMDEVINSR3 pDevInsR3;
444 /** @copydoc PDMIOAPICREG::pfnSetIrqHC */
445 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
446
447 /** Pointer to the PIC device instance - R0. */
448 R0PTRTYPE(PPDMDEVINS) pDevInsR0;
449 /** @copydoc PDMIOAPICREG::pfnSetIrqHC */
450 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
451
452 /** Pointer to the APIC device instance - GC Ptr. */
453 PPDMDEVINSGC pDevInsGC;
454 /** @copydoc PDMIOAPICREG::pfnSetIrqHC */
455 DECLGCCALLBACKMEMBER(void, pfnSetIrqGC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
456} PDMIOAPIC;
457
458
459/**
460 * PDM PCI Bus instance.
461 */
462typedef struct PDMPCIBUS
463{
464 /** PCI bus number. */
465 RTUINT iBus;
466 RTUINT uPadding0; /**< Alignment padding.*/
467
468 /** Pointer to PCI Bus device instance. */
469 PPDMDEVINSR3 pDevInsR3;
470 /** @copydoc PDMPCIBUSREG::pfnSetIrqHC */
471 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
472 /** @copydoc PDMPCIBUSREG::pfnRegisterHC */
473 DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev));
474 /** @copydoc PDMPCIBUSREG::pfnIORegionRegisterHC */
475 DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, uint32_t cbRegion,
476 PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
477 /** @copydoc PDMPCIBUSREG::pfnSetConfigCallbacksHC */
478 DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead,
479 PPFNPCICONFIGREAD ppfnReadOld, PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
480 /** @copydoc PDMPCIBUSREG::pfnSaveExecHC */
481 DECLR3CALLBACKMEMBER(int, pfnSaveExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
482 /** @copydoc PDMPCIBUSREG::pfnLoadExecHC */
483 DECLR3CALLBACKMEMBER(int, pfnLoadExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
484 /** @copydoc PDMPCIBUSREG::pfnFakePCIBIOSHC */
485 DECLR3CALLBACKMEMBER(int, pfnFakePCIBIOSR3,(PPDMDEVINS pDevIns));
486
487 /** Pointer to the PIC device instance - R0. */
488 R0PTRTYPE(PPDMDEVINS) pDevInsR0;
489 /** @copydoc PDMPCIBUSREG::pfnSetIrqHC */
490 DECLR0CALLBACKMEMBER(void, pfnSetIrqR0,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
491
492 /** Pointer to PCI Bus device instance. */
493 PPDMDEVINSGC pDevInsGC;
494 /** @copydoc PDMPCIBUSREG::pfnSetIrqHC */
495 DECLGCCALLBACKMEMBER(void, pfnSetIrqGC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
496} PDMPCIBUS;
497
498
499#ifdef IN_RING3
500/**
501 * PDM registered DMAC (DMA Controller) device.
502 */
503typedef struct PDMDMAC
504{
505 /** Pointer to the DMAC device instance. */
506 PPDMDEVINS pDevIns;
507 /** Copy of the registration structure. */
508 PDMDMACREG Reg;
509} PDMDMAC;
510
511
512/**
513 * PDM registered RTC (Real Time Clock) device.
514 */
515typedef struct PDMRTC
516{
517 /** Pointer to the RTC device instance. */
518 PPDMDEVINS pDevIns;
519 /** Copy of the registration structure. */
520 PDMRTCREG Reg;
521} PDMRTC;
522
523#endif /* IN_RING3 */
524
525/**
526 * Module type.
527 */
528typedef enum PDMMODTYPE
529{
530 /** Guest context module. */
531 PDMMOD_TYPE_GC,
532 /** Ring-0 (host) context module. */
533 PDMMOD_TYPE_R0,
534 /** Ring-3 (host) context module. */
535 PDMMOD_TYPE_R3
536} PDMMODTYPE, *PPDMMODTYPE;
537
538
539/** The module name length including the terminator. */
540#define PDMMOD_NAME_LEN 32
541
542/**
543 * Loaded module instance.
544 */
545typedef struct PDMMOD
546{
547 /** Module name. This is used for refering to
548 * the module internally, sort of like a handle. */
549 char szName[PDMMOD_NAME_LEN];
550 /** Module type. */
551 PDMMODTYPE eType;
552 /** Loader module handle. Not used for R0 modules. */
553 RTLDRMOD hLdrMod;
554 /** Loaded address.
555 * This is the 'handle' for R0 modules. */
556 RTUINTPTR ImageBase;
557 /** Old loaded address.
558 * This is used during relocation of GC modules. Not used for R0 modules. */
559 RTUINTPTR OldImageBase;
560 /** Where the R3 HC bits are stored.
561 * This can be equal to ImageBase but doesn't have to. Not used for R0 modules. */
562 void *pvBits;
563
564 /** Pointer to next module. */
565 struct PDMMOD *pNext;
566 /** Module filename. */
567 char szFilename[1];
568} PDMMOD;
569/** Pointer to loaded module instance. */
570typedef PDMMOD *PPDMMOD;
571
572
573
574/** Extra space in the free array. */
575#define PDMQUEUE_FREE_SLACK 16
576
577/**
578 * Queue type.
579 */
580typedef enum PDMQUEUETYPE
581{
582 /** Device consumer. */
583 PDMQUEUETYPE_DEV = 1,
584 /** Driver consumer. */
585 PDMQUEUETYPE_DRV,
586 /** Internal consumer. */
587 PDMQUEUETYPE_INTERNAL,
588 /** External consumer. */
589 PDMQUEUETYPE_EXTERNAL
590} PDMQUEUETYPE;
591
592/** Pointer to a PDM Queue. */
593typedef struct PDMQUEUE *PPDMQUEUE;
594
595/**
596 * PDM Queue.
597 */
598typedef struct PDMQUEUE
599{
600 /** Pointer to the next queue in the list. */
601 R3PTRTYPE(PPDMQUEUE) pNext;
602 /** Type specific data. */
603 union
604 {
605 /** PDMQUEUETYPE_DEV */
606 struct
607 {
608 /** Pointer to consumer function. */
609 R3PTRTYPE(PFNPDMQUEUEDEV) pfnCallback;
610 /** Pointer to the device instance owning the queue. */
611 R3PTRTYPE(PPDMDEVINS) pDevIns;
612 } Dev;
613 /** PDMQUEUETYPE_DRV */
614 struct
615 {
616 /** Pointer to consumer function. */
617 R3PTRTYPE(PFNPDMQUEUEDRV) pfnCallback;
618 /** Pointer to the driver instance owning the queue. */
619 R3PTRTYPE(PPDMDRVINS) pDrvIns;
620 } Drv;
621 /** PDMQUEUETYPE_INTERNAL */
622 struct
623 {
624 /** Pointer to consumer function. */
625 R3PTRTYPE(PFNPDMQUEUEINT) pfnCallback;
626 } Int;
627 /** PDMQUEUETYPE_EXTERNAL */
628 struct
629 {
630 /** Pointer to consumer function. */
631 R3PTRTYPE(PFNPDMQUEUEEXT) pfnCallback;
632 /** Pointer to user argument. */
633 R3PTRTYPE(void *) pvUser;
634 } Ext;
635 } u;
636 /** Queue type. */
637 PDMQUEUETYPE enmType;
638 /** The interval between checking the queue for events.
639 * The realtime timer below is used to do the waiting.
640 * If 0, the queue will use the VM_FF_PDM_QUEUE forced action. */
641 uint32_t cMilliesInterval;
642 /** Interval timer. Only used if cMilliesInterval is non-zero. */
643 PTMTIMERR3 pTimer;
644 /** Pointer to the VM. */
645 R3R0PTRTYPE(PVM) pVMHC;
646 /** LIFO of pending items - HC. */
647 R3R0PTRTYPE(PPDMQUEUEITEMCORE) volatile pPendingHC;
648 /** Pointer to the GC VM and indicator for GC enabled queue.
649 * If this is NULL, the queue cannot be used in GC.
650 */
651 GCPTRTYPE(PVM) pVMGC;
652 /** LIFO of pending items - GC. */
653 GCPTRTYPE(PPDMQUEUEITEMCORE) pPendingGC;
654 /** Item size (bytes). */
655 RTUINT cbItem;
656 /** Number of items in the queue. */
657 RTUINT cItems;
658 /** Index to the free head (where we insert). */
659 uint32_t volatile iFreeHead;
660 /** Index to the free tail (where we remove). */
661 uint32_t volatile iFreeTail;
662 /** Array of pointers to free items. Variable size. */
663 struct PDMQUEUEFREEITEM
664 {
665 /** Pointer to the free item - HC Ptr. */
666 R3R0PTRTYPE(PPDMQUEUEITEMCORE) volatile pItemHC;
667 /** Pointer to the free item - GC Ptr. */
668 GCPTRTYPE(PPDMQUEUEITEMCORE) volatile pItemGC;
669#if HC_ARCH_BITS == 64 && GC_ARCH_BITS == 32
670 uint32_t Alignment0;
671#endif
672 } aFreeItems[1];
673} PDMQUEUE;
674
675
676/**
677 * Queue device helper task operation.
678 */
679typedef enum PDMDEVHLPTASKOP
680{
681 /** The usual invalid 0 entry. */
682 PDMDEVHLPTASKOP_INVALID = 0,
683 /** ISASetIrq */
684 PDMDEVHLPTASKOP_ISA_SET_IRQ,
685 /** PCISetIrq */
686 PDMDEVHLPTASKOP_PCI_SET_IRQ,
687 /** PCISetIrq */
688 PDMDEVHLPTASKOP_IOAPIC_SET_IRQ,
689 /** The usual 32-bit hack. */
690 PDMDEVHLPTASKOP_32BIT_HACK = 0x7fffffff
691} PDMDEVHLPTASKOP;
692
693/**
694 * Queued Device Helper Task.
695 */
696typedef struct PDMDEVHLPTASK
697{
698 /** The queue item core (don't touch). */
699 PDMQUEUEITEMCORE Core;
700 /** Pointer to the device instance (HC Ptr). */
701 R3R0PTRTYPE(PPDMDEVINS) pDevInsHC;
702 /** This operation to perform. */
703 PDMDEVHLPTASKOP enmOp;
704#if HC_ARCH_BITS == 64
705 uint32_t Alignment0;
706#endif
707 /** Parameters to the operation. */
708 union PDMDEVHLPTASKPARAMS
709 {
710 /**
711 * PDMDEVHLPTASKOP_ISA_SET_IRQ and PDMDEVHLPTASKOP_PCI_SET_IRQ.
712 */
713 struct PDMDEVHLPTASKSETIRQ
714 {
715 /** The IRQ */
716 int iIrq;
717 /** The new level. */
718 int iLevel;
719 } SetIRQ;
720 } u;
721} PDMDEVHLPTASK;
722/** Pointer to a queued Device Helper Task. */
723typedef PDMDEVHLPTASK *PPDMDEVHLPTASK;
724/** Pointer to a const queued Device Helper Task. */
725typedef const PDMDEVHLPTASK *PCPDMDEVHLPTASK;
726
727
728
729/**
730 * An USB hub registration record.
731 */
732typedef struct PDMUSBHUB
733{
734 /** The USB versions this hub support.
735 * Note that 1.1 hubs can take on 2.0 devices. */
736 uint32_t fVersions;
737 /** The number of ports on the hub. */
738 uint32_t cPorts;
739 /** The number of available ports (0..cPorts). */
740 uint32_t cAvailablePorts;
741 /** The driver instance of the hub. */
742 PPDMDRVINS pDrvIns;
743 /** Copy of the to the registration structure. */
744 PDMUSBHUBREG Reg;
745
746 /** Pointer to the next hub in the list. */
747 struct PDMUSBHUB *pNext;
748} PDMUSBHUB;
749
750/** Pointer to a const USB HUB registration record. */
751typedef const PDMUSBHUB *PCPDMUSBHUB;
752
753/** Pointer to a PDM Async I/O template. */
754typedef struct PDMASYNCCOMPLETIONTEMPLATE *PPDMASYNCCOMPLETIONTEMPLATE;
755
756/** Pointer to the main PDM Async completion structure. */
757typedef struct PDMASYNCCOMPLETIONMANAGER *PPDMASYNCCOMPLETIONMANAGER;
758
759/**
760 * Converts a PDM pointer into a VM pointer.
761 * @returns Pointer to the VM structure the PDM is part of.
762 * @param pPDM Pointer to PDM instance data.
763 */
764#define PDM2VM(pPDM) ( (PVM)((char*)pPDM - pPDM->offVM) )
765
766
767/**
768 * PDM VM Instance data.
769 * Changes to this must checked against the padding of the cfgm union in VM!
770 */
771typedef struct PDM
772{
773 /** Offset to the VM structure.
774 * See PDM2VM(). */
775 RTUINT offVM;
776 RTUINT uPadding0; /**< Alignment padding.*/
777
778 /** List of registered devices. (FIFO) */
779 R3PTRTYPE(PPDMDEV) pDevs;
780 /** List of devices instances. (FIFO) */
781 R3PTRTYPE(PPDMDEVINS) pDevInstances;
782 /** List of registered USB devices. (FIFO) */
783 R3PTRTYPE(PPDMUSB) pUsbDevs;
784 /** List of USB devices instances. (FIFO) */
785 R3PTRTYPE(PPDMUSBINS) pUsbInstances;
786 /** List of registered drivers. (FIFO) */
787 R3PTRTYPE(PPDMDRV) pDrvs;
788 /** List of initialized critical sections. (LIFO) */
789 R3PTRTYPE(PPDMCRITSECTINT) pCritSects;
790 /** PCI Buses. */
791 PDMPCIBUS aPciBuses[1];
792 /** The register PIC device. */
793 PDMPIC Pic;
794 /** The registerd APIC device. */
795 PDMAPIC Apic;
796 /** The registerd I/O APIC device. */
797 PDMIOAPIC IoApic;
798 /** The registered DMAC device. */
799 R3PTRTYPE(PPDMDMAC) pDmac;
800 /** The registered RTC device. */
801 R3PTRTYPE(PPDMRTC) pRtc;
802 /** The registered USB HUBs. (FIFO) */
803 R3PTRTYPE(PPDMUSBHUB) pUsbHubs;
804
805 /** Queue in which devhlp tasks are queued for R3 execution - HC Ptr. */
806 R3R0PTRTYPE(PPDMQUEUE) pDevHlpQueueHC;
807 /** Queue in which devhlp tasks are queued for R3 execution - GC Ptr. */
808 GCPTRTYPE(PPDMQUEUE) pDevHlpQueueGC;
809
810 /** The number of entries in the apQueuedCritSectsLeaves table that's currnetly in use. */
811 RTUINT cQueuedCritSectLeaves;
812 /** Critical sections queued in GC/R0 because of contention preventing leave to complete. (R3 Ptrs)
813 * We will return to Ring-3 ASAP, so this queue doesn't has to be very long. */
814 R3PTRTYPE(PPDMCRITSECT) apQueuedCritSectsLeaves[8];
815
816 /** Linked list of timer driven PDM queues. */
817 R3PTRTYPE(struct PDMQUEUE *) pQueuesTimer;
818 /** Linked list of force action driven PDM queues. */
819 R3PTRTYPE(struct PDMQUEUE *) pQueuesForced;
820 /** Pointer to the queue which should be manually flushed - HCPtr.
821 * Only touched by EMT. */
822 R3R0PTRTYPE(struct PDMQUEUE *) pQueueFlushHC;
823 /** Pointer to the queue which should be manually flushed - GCPtr. */
824 GCPTRTYPE(struct PDMQUEUE *) pQueueFlushGC;
825#if HC_ARCH_BITS == 64
826 uint32_t padding0;
827#endif
828
829 /** Head of the PDM Thread list. (singly linked) */
830 R3PTRTYPE(PPDMTHREAD) pThreads;
831 /** Tail of the PDM Thread list. (singly linked) */
832 R3PTRTYPE(PPDMTHREAD) pThreadsTail;
833
834 /** Head of the asychronous tasks managers. (singly linked) */
835 R3PTRTYPE(PPDMASYNCCOMPLETIONMANAGER) pAsyncCompletionManagerHead;
836 /** Head of the templates. (singly linked) */
837 R3PTRTYPE(PPDMASYNCCOMPLETIONTEMPLATE) pAsyncCompletionTemplates;
838
839 /** TEMPORARY HACKS FOR NETWORK POLLING.
840 * @todo fix NAT and kill this!
841 * @{ */
842 RTUINT cPollers;
843#if HC_ARCH_BITS == 64
844 RTUINT padding1;
845#endif
846 R3PTRTYPE(PFNPDMDRVPOLLER) apfnPollers[16];
847 R3PTRTYPE(PPDMDRVINS) aDrvInsPollers[16];
848 PTMTIMERR3 pTimerPollers;
849 /** @} */
850
851#ifdef VBOX_WITH_PDM_LOCK
852 /** The PDM lock.
853 * This is used to protect everything that deals with interrupts, i.e.
854 * the PIC, APIC, IOAPIC and PCI devices pluss some PDM functions. */
855 PDMCRITSECT CritSect;
856#endif
857
858
859 /** Number of times a critical section leave requesed needed to be queued for ring-3 execution. */
860 STAMCOUNTER StatQueuedCritSectLeaves;
861} PDM;
862/** Pointer to PDM VM instance data. */
863typedef PDM *PPDM;
864
865
866/**
867 * PDM data kept in the UVM.
868 */
869typedef struct PDMUSERPERVM
870{
871 /** Pointer to list of loaded modules. */
872 PPDMMOD pModules;
873 /** @todo move more stuff over here. */
874} PDMUSERPERVM;
875/** Pointer to the PDM data kept in the UVM. */
876typedef PDMUSERPERVM *PPDMUSERPERVM;
877
878
879
880/*******************************************************************************
881* Global Variables *
882*******************************************************************************/
883#ifdef IN_RING3
884extern const PDMDRVHLP g_pdmR3DrvHlp;
885#endif
886
887
888/*******************************************************************************
889* Internal Functions *
890*******************************************************************************/
891#ifdef IN_RING3
892int pdmR3CritSectInit(PVM pVM);
893int pdmR3CritSectTerm(PVM pVM);
894void pdmR3CritSectRelocate(PVM pVM);
895int pdmR3CritSectInitDevice(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName);
896int pdmR3CritSectDeleteDevice(PVM pVM, PPDMDEVINS pDevIns);
897
898int pdmR3DevInit(PVM pVM);
899PPDMDEV pdmR3DevLookup(PVM pVM, const char *pszName);
900int pdmR3DevFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);
901
902int pdmR3UsbLoadModules(PVM pVM);
903int pdmR3UsbInstantiateDevices(PVM pVM);
904PPDMUSB pdmR3UsbLookup(PVM pVM, const char *pszName);
905int pdmR3UsbFindLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMLUN *ppLun);
906int pdmR3UsbRegisterHub(PVM pVM, PPDMDRVINS pDrvIns, uint32_t fVersions, uint32_t cPorts, PCPDMUSBHUBREG pUsbHubReg, PPCPDMUSBHUBHLP ppUsbHubHlp);
907int pdmR3UsbVMInitComplete(PVM pVM);
908
909int pdmR3DrvInit(PVM pVM);
910int pdmR3DrvDetach(PPDMDRVINS pDrvIns);
911void pdmR3DrvDestroyChain(PPDMDRVINS pDrvIns);
912PPDMDRV pdmR3DrvLookup(PVM pVM, const char *pszName);
913
914int pdmR3LdrInitU(PUVM pUVM);
915void pdmR3LdrTermU(PUVM pUVM);
916char * pdmR3FileR3(const char *pszFile, bool fShared = false);
917int pdmR3LoadR3U(PUVM pUVM, const char *pszFilename, const char *pszName);
918
919void pdmR3QueueRelocate(PVM pVM, RTGCINTPTR offDelta);
920
921int pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
922 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
923int pdmR3ThreadCreateUsb(PVM pVM, PPDMDRVINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
924 PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
925int pdmR3ThreadCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
926 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
927int pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
928int pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
929int pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
930void pdmR3ThreadDestroyAll(PVM pVM);
931int pdmR3ThreadResumeAll(PVM pVM);
932int pdmR3ThreadSuspendAll(PVM pVM);
933
934#ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
935int pdmR3AsyncCompletionInit(PVM pVM);
936int pdmR3AsyncCompletionTerm(PVM pVM);
937#endif
938
939#endif /* IN_RING3 */
940
941#ifdef VBOX_WITH_PDM_LOCK
942void pdmLock(PVM pVM);
943int pdmLockEx(PVM pVM, int rc);
944void pdmUnlock(PVM pVM);
945#else
946# define pdmLock(pVM) do {} while (0)
947# define pdmLockEx(pVM, rc) (VINF_SUCCESS)
948# define pdmUnlock(pVM) do {} while (0)
949#endif
950
951/** @} */
952
953__END_DECLS
954
955#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