VirtualBox

source: vbox/trunk/include/VBox/pdmdrv.h@ 27933

Last change on this file since 27933 was 27933, checked in by vboxsync, 15 years ago

DrvNamedPipe.cpp: Don't assume we'll get a PowerOff call. Always wait for the thread as we created it with RTTHREADFLAGS_WAITABLE. Use volatile on fShutdown. Must shutdown the server socket or accept() might not abort.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 56.6 KB
Line 
1/** @file
2 * PDM - Pluggable Device Manager, Drivers. (VMM)
3 */
4
5/*
6 * Copyright (C) 2006-2010 Sun Microsystems, Inc.
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.215389.xyz. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 *
25 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26 * Clara, CA 95054 USA or visit http://www.sun.com if you need
27 * additional information or have any questions.
28 */
29
30#ifndef ___VBox_pdmdrv_h
31#define ___VBox_pdmdrv_h
32
33#include <VBox/pdmqueue.h>
34#include <VBox/pdmcritsect.h>
35#include <VBox/pdmthread.h>
36#include <VBox/pdmifs.h>
37#include <VBox/pdmins.h>
38#include <VBox/pdmcommon.h>
39#include <VBox/pdmasynccompletion.h>
40#include <VBox/tm.h>
41#include <VBox/ssm.h>
42#include <VBox/cfgm.h>
43#include <VBox/dbgf.h>
44#include <VBox/mm.h>
45#include <VBox/err.h>
46#include <iprt/stdarg.h>
47
48RT_C_DECLS_BEGIN
49
50/** @defgroup grp_pdm_driver The PDM Drivers API
51 * @ingroup grp_pdm
52 * @{
53 */
54
55/** Pointer const PDM Driver API, ring-3. */
56typedef R3PTRTYPE(struct PDMDRVHLPR3 const *) PCPDMDRVHLPR3;
57/** Pointer const PDM Driver API, ring-0. */
58typedef R0PTRTYPE(struct PDMDRVHLPR0 const *) PCPDMDRVHLPR0;
59/** Pointer const PDM Driver API, raw-mode context. */
60typedef RCPTRTYPE(struct PDMDRVHLPRC const *) PCPDMDRVHLPRC;
61
62
63/**
64 * Construct a driver instance for a VM.
65 *
66 * @returns VBox status.
67 * @param pDrvIns The driver instance data. If the registration structure
68 * is needed, it can be accessed thru pDrvIns->pReg.
69 * @param pCfg Configuration node handle for the driver. This is
70 * expected to be in high demand in the constructor and is
71 * therefore passed as an argument. When using it at other
72 * times, it can be accessed via pDrvIns->pCfg.
73 * @param fFlags Flags, combination of the PDM_TACH_FLAGS_* \#defines.
74 */
75typedef DECLCALLBACK(int) FNPDMDRVCONSTRUCT(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
76/** Pointer to a FNPDMDRVCONSTRUCT() function. */
77typedef FNPDMDRVCONSTRUCT *PFNPDMDRVCONSTRUCT;
78
79/**
80 * Destruct a driver instance.
81 *
82 * Most VM resources are freed by the VM. This callback is provided so that
83 * any non-VM resources can be freed correctly.
84 *
85 * @param pDrvIns The driver instance data.
86 */
87typedef DECLCALLBACK(void) FNPDMDRVDESTRUCT(PPDMDRVINS pDrvIns);
88/** Pointer to a FNPDMDRVDESTRUCT() function. */
89typedef FNPDMDRVDESTRUCT *PFNPDMDRVDESTRUCT;
90
91/**
92 * Driver relocation callback.
93 *
94 * This is called when the instance data has been relocated in raw-mode context
95 * (RC). It is also called when the RC hypervisor selects changes. The driver
96 * must fixup all necessary pointers and re-query all interfaces to other RC
97 * devices and drivers.
98 *
99 * Before the RC code is executed the first time, this function will be called
100 * with a 0 delta so RC pointer calculations can be one in one place.
101 *
102 * @param pDrvIns Pointer to the driver instance.
103 * @param offDelta The relocation delta relative to the old location.
104 *
105 * @remark A relocation CANNOT fail.
106 */
107typedef DECLCALLBACK(void) FNPDMDRVRELOCATE(PPDMDRVINS pDrvIns, RTGCINTPTR offDelta);
108/** Pointer to a FNPDMDRVRELOCATE() function. */
109typedef FNPDMDRVRELOCATE *PFNPDMDRVRELOCATE;
110
111/**
112 * Driver I/O Control interface.
113 *
114 * This is used by external components, such as the COM interface, to
115 * communicate with a driver using a driver specific interface. Generally,
116 * the driver interfaces are used for this task.
117 *
118 * @returns VBox status code.
119 * @param pDrvIns Pointer to the driver instance.
120 * @param uFunction Function to perform.
121 * @param pvIn Pointer to input data.
122 * @param cbIn Size of input data.
123 * @param pvOut Pointer to output data.
124 * @param cbOut Size of output data.
125 * @param pcbOut Where to store the actual size of the output data.
126 */
127typedef DECLCALLBACK(int) FNPDMDRVIOCTL(PPDMDRVINS pDrvIns, uint32_t uFunction,
128 void *pvIn, uint32_t cbIn,
129 void *pvOut, uint32_t cbOut, uint32_t *pcbOut);
130/** Pointer to a FNPDMDRVIOCTL() function. */
131typedef FNPDMDRVIOCTL *PFNPDMDRVIOCTL;
132
133/**
134 * Power On notification.
135 *
136 * @param pDrvIns The driver instance data.
137 */
138typedef DECLCALLBACK(void) FNPDMDRVPOWERON(PPDMDRVINS pDrvIns);
139/** Pointer to a FNPDMDRVPOWERON() function. */
140typedef FNPDMDRVPOWERON *PFNPDMDRVPOWERON;
141
142/**
143 * Reset notification.
144 *
145 * @returns VBox status.
146 * @param pDrvIns The driver instance data.
147 */
148typedef DECLCALLBACK(void) FNPDMDRVRESET(PPDMDRVINS pDrvIns);
149/** Pointer to a FNPDMDRVRESET() function. */
150typedef FNPDMDRVRESET *PFNPDMDRVRESET;
151
152/**
153 * Suspend notification.
154 *
155 * @returns VBox status.
156 * @param pDrvIns The driver instance data.
157 */
158typedef DECLCALLBACK(void) FNPDMDRVSUSPEND(PPDMDRVINS pDrvIns);
159/** Pointer to a FNPDMDRVSUSPEND() function. */
160typedef FNPDMDRVSUSPEND *PFNPDMDRVSUSPEND;
161
162/**
163 * Resume notification.
164 *
165 * @returns VBox status.
166 * @param pDrvIns The driver instance data.
167 */
168typedef DECLCALLBACK(void) FNPDMDRVRESUME(PPDMDRVINS pDrvIns);
169/** Pointer to a FNPDMDRVRESUME() function. */
170typedef FNPDMDRVRESUME *PFNPDMDRVRESUME;
171
172/**
173 * Power Off notification.
174 *
175 * @param pDrvIns The driver instance data.
176 */
177typedef DECLCALLBACK(void) FNPDMDRVPOWEROFF(PPDMDRVINS pDrvIns);
178/** Pointer to a FNPDMDRVPOWEROFF() function. */
179typedef FNPDMDRVPOWEROFF *PFNPDMDRVPOWEROFF;
180
181/**
182 * Attach command.
183 *
184 * This is called to let the drive attach to a driver at runtime. This is not
185 * called during VM construction, the driver constructor have to do this by
186 * calling PDMDrvHlpAttach.
187 *
188 * This is like plugging in the keyboard or mouse after turning on the PC.
189 *
190 * @returns VBox status code.
191 * @param pDrvIns The driver instance.
192 * @param fFlags Flags, combination of the PDM_TACH_FLAGS_* \#defines.
193 */
194typedef DECLCALLBACK(int) FNPDMDRVATTACH(PPDMDRVINS pDrvIns, uint32_t fFlags);
195/** Pointer to a FNPDMDRVATTACH() function. */
196typedef FNPDMDRVATTACH *PFNPDMDRVATTACH;
197
198/**
199 * Detach notification.
200 *
201 * This is called when a driver below it in the chain is detaching itself
202 * from it. The driver should adjust it's state to reflect this.
203 *
204 * This is like ejecting a cdrom or floppy.
205 *
206 * @param pDrvIns The driver instance.
207 * @param fFlags PDM_TACH_FLAGS_NOT_HOT_PLUG or 0.
208 */
209typedef DECLCALLBACK(void) FNPDMDRVDETACH(PPDMDRVINS pDrvIns, uint32_t fFlags);
210/** Pointer to a FNPDMDRVDETACH() function. */
211typedef FNPDMDRVDETACH *PFNPDMDRVDETACH;
212
213
214
215/**
216 * PDM Driver Registration Structure.
217 *
218 * This structure is used when registering a driver from VBoxInitDrivers() (in
219 * host ring-3 context). PDM will continue use till the VM is terminated.
220 */
221typedef struct PDMDRVREG
222{
223 /** Structure version. PDM_DRVREG_VERSION defines the current version. */
224 uint32_t u32Version;
225 /** Driver name. */
226 char szName[32];
227 /** Name of the raw-mode context module (no path).
228 * Only evalutated if PDM_DRVREG_FLAGS_RC is set. */
229 char szRCMod[32];
230 /** Name of the ring-0 module (no path).
231 * Only evalutated if PDM_DRVREG_FLAGS_R0 is set. */
232 char szR0Mod[32];
233 /** The description of the driver. The UTF-8 string pointed to shall, like this structure,
234 * remain unchanged from registration till VM destruction. */
235 const char *pszDescription;
236
237 /** Flags, combination of the PDM_DRVREG_FLAGS_* \#defines. */
238 uint32_t fFlags;
239 /** Driver class(es), combination of the PDM_DRVREG_CLASS_* \#defines. */
240 uint32_t fClass;
241 /** Maximum number of instances (per VM). */
242 uint32_t cMaxInstances;
243 /** Size of the instance data. */
244 uint32_t cbInstance;
245
246 /** Construct instance - required. */
247 PFNPDMDRVCONSTRUCT pfnConstruct;
248 /** Destruct instance - optional. */
249 PFNPDMDRVDESTRUCT pfnDestruct;
250 /** Relocation command - optional. */
251 PFNPDMDRVRELOCATE pfnRelocate;
252 /** I/O control - optional. */
253 PFNPDMDRVIOCTL pfnIOCtl;
254 /** Power on notification - optional. */
255 PFNPDMDRVPOWERON pfnPowerOn;
256 /** Reset notification - optional. */
257 PFNPDMDRVRESET pfnReset;
258 /** Suspend notification - optional. */
259 PFNPDMDRVSUSPEND pfnSuspend;
260 /** Resume notification - optional. */
261 PFNPDMDRVRESUME pfnResume;
262 /** Attach command - optional. */
263 PFNPDMDRVATTACH pfnAttach;
264 /** Detach notification - optional. */
265 PFNPDMDRVDETACH pfnDetach;
266 /** Power off notification - optional. */
267 PFNPDMDRVPOWEROFF pfnPowerOff;
268 /** @todo */
269 PFNRT pfnSoftReset;
270 /** Initialization safty marker. */
271 uint32_t u32VersionEnd;
272} PDMDRVREG;
273/** Pointer to a PDM Driver Structure. */
274typedef PDMDRVREG *PPDMDRVREG;
275/** Const pointer to a PDM Driver Structure. */
276typedef PDMDRVREG const *PCPDMDRVREG;
277
278/** Current DRVREG version number. */
279#define PDM_DRVREG_VERSION PDM_VERSION_MAKE(0xf0ff, 1, 0)
280
281/** PDM Driver Flags.
282 * @{ */
283/** @def PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT
284 * The bit count for the current host. */
285#if HC_ARCH_BITS == 32
286# define PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT UINT32_C(0x00000001)
287#elif HC_ARCH_BITS == 64
288# define PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT UINT32_C(0x00000002)
289#else
290# error Unsupported HC_ARCH_BITS value.
291#endif
292/** The host bit count mask. */
293#define PDM_DRVREG_FLAGS_HOST_BITS_MASK UINT32_C(0x00000003)
294/** This flag is used to indicate that the driver has a RC component. */
295#define PDM_DRVREG_FLAGS_RC UINT32_C(0x00000010)
296/** This flag is used to indicate that the driver has a R0 component. */
297#define PDM_DRVREG_FLAGS_R0 UINT32_C(0x00000020)
298
299/** @} */
300
301
302/** PDM Driver Classes.
303 * @{ */
304/** Mouse input driver. */
305#define PDM_DRVREG_CLASS_MOUSE RT_BIT(0)
306/** Keyboard input driver. */
307#define PDM_DRVREG_CLASS_KEYBOARD RT_BIT(1)
308/** Display driver. */
309#define PDM_DRVREG_CLASS_DISPLAY RT_BIT(2)
310/** Network transport driver. */
311#define PDM_DRVREG_CLASS_NETWORK RT_BIT(3)
312/** Block driver. */
313#define PDM_DRVREG_CLASS_BLOCK RT_BIT(4)
314/** Media driver. */
315#define PDM_DRVREG_CLASS_MEDIA RT_BIT(5)
316/** Mountable driver. */
317#define PDM_DRVREG_CLASS_MOUNTABLE RT_BIT(6)
318/** Audio driver. */
319#define PDM_DRVREG_CLASS_AUDIO RT_BIT(7)
320/** VMMDev driver. */
321#define PDM_DRVREG_CLASS_VMMDEV RT_BIT(8)
322/** Status driver. */
323#define PDM_DRVREG_CLASS_STATUS RT_BIT(9)
324/** ACPI driver. */
325#define PDM_DRVREG_CLASS_ACPI RT_BIT(10)
326/** USB related driver. */
327#define PDM_DRVREG_CLASS_USB RT_BIT(11)
328/** ISCSI Transport related driver. */
329#define PDM_DRVREG_CLASS_ISCSITRANSPORT RT_BIT(12)
330/** Char driver. */
331#define PDM_DRVREG_CLASS_CHAR RT_BIT(13)
332/** Stream driver. */
333#define PDM_DRVREG_CLASS_STREAM RT_BIT(14)
334/** SCSI driver. */
335#define PDM_DRVREG_CLASS_SCSI RT_BIT(15)
336/** @} */
337
338
339/**
340 * PDM Driver Instance.
341 *
342 * @implements PDMIBASE
343 */
344typedef struct PDMDRVINS
345{
346 /** Structure version. PDM_DRVINS_VERSION defines the current version. */
347 uint32_t u32Version;
348 /** Driver instance number. */
349 uint32_t iInstance;
350
351 /** Pointer the PDM Driver API. */
352 RCPTRTYPE(PCPDMDRVHLPRC) pHlpRC;
353 /** Pointer to driver instance data. */
354 RCPTRTYPE(void *) pvInstanceDataRC;
355
356 /** Pointer the PDM Driver API. */
357 R0PTRTYPE(PCPDMDRVHLPR0) pHlpR0;
358 /** Pointer to driver instance data. */
359 R0PTRTYPE(void *) pvInstanceDataR0;
360
361 /** Pointer the PDM Driver API. */
362 R3PTRTYPE(PCPDMDRVHLPR3) pHlpR3;
363 /** Pointer to driver instance data. */
364 R3PTRTYPE(void *) pvInstanceDataR3;
365
366 /** Pointer to driver registration structure. */
367 R3PTRTYPE(PCPDMDRVREG) pReg;
368 /** Configuration handle. */
369 R3PTRTYPE(PCFGMNODE) pCfg;
370
371 /** Pointer to the base interface of the device/driver instance above. */
372 R3PTRTYPE(PPDMIBASE) pUpBase;
373 /** Pointer to the base interface of the driver instance below. */
374 R3PTRTYPE(PPDMIBASE) pDownBase;
375
376 /** The base interface of the driver.
377 * The driver constructor initializes this. */
378 PDMIBASE IBase;
379 /** Align the internal data more naturally. */
380 RTR3PTR R3PtrPadding;
381
382 /** Internal data. */
383 union
384 {
385#ifdef PDMDRVINSINT_DECLARED
386 PDMDRVINSINT s;
387#endif
388 uint8_t padding[HC_ARCH_BITS == 32 ? 40 + 32 : 72 + 24];
389 } Internal;
390
391 /** Driver instance data. The size of this area is defined
392 * in the PDMDRVREG::cbInstanceData field. */
393 char achInstanceData[4];
394} PDMDRVINS;
395
396/** Current DRVREG version number. */
397#define PDM_DRVINS_VERSION PDM_VERSION_MAKE(0xf0fe, 1, 0)
398
399/** Converts a pointer to the PDMDRVINS::IBase to a pointer to PDMDRVINS. */
400#define PDMIBASE_2_PDMDRV(pInterface) ( (PPDMDRVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDRVINS, IBase)) )
401
402/**
403 * Checks the structure versions of the drive instance and driver helpers,
404 * returning if they are incompatible.
405 *
406 * Intended for the constructor.
407 *
408 * @param pDrvIns Pointer to the PDM driver instance.
409 */
410#define PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns) \
411 do \
412 { \
413 PPDMDRVINS pDrvInsTypeCheck = (pDrvIns); NOREF(pDrvInsTypeCheck); \
414 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->u32Version, PDM_DRVINS_VERSION), \
415 ("DrvIns=%#x mine=%#x\n", (pDrvIns)->u32Version, PDM_DRVINS_VERSION), \
416 VERR_VERSION_MISMATCH); \
417 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->pHlpR3->u32Version, PDM_DRVHLPR3_VERSION), \
418 ("DrvHlp=%#x mine=%#x\n", (pDrvIns)->pHlpR3->u32Version, PDM_DRVHLPR3_VERSION), \
419 VERR_VERSION_MISMATCH); \
420 } while (0)
421
422/**
423 * Quietly checks the structure versions of the drive instance and driver
424 * helpers, returning if they are incompatible.
425 *
426 * Intended for the destructor.
427 *
428 * @param pDrvIns Pointer to the PDM driver instance.
429 */
430#define PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns) \
431 do \
432 { \
433 PPDMDRVINS pDrvInsTypeCheck = (pDrvIns); NOREF(pDrvInsTypeCheck); \
434 if (RT_UNLIKELY( !PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->u32Version, PDM_DRVINS_VERSION) \
435 || !PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->pHlpR3->u32Version, PDM_DRVHLPR3_VERSION)) ) \
436 return; \
437 } while (0)
438
439/**
440 * Wrapper around CFGMR3ValidateConfig for the root config for use in the
441 * constructor - returns on failure.
442 *
443 * This should be invoked after having initialized the instance data
444 * sufficiently for the correct operation of the destructor. The destructor is
445 * always called!
446 *
447 * @param pDrvIns Pointer to the PDM driver instance.
448 * @param pszValidValues Patterns describing the valid value names. See
449 * RTStrSimplePatternMultiMatch for details on the
450 * pattern syntax.
451 * @param pszValidNodes Patterns describing the valid node (key) names.
452 * Pass empty string if no valid nodess.
453 */
454#define PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, pszValidValues, pszValidNodes) \
455 do \
456 { \
457 int rcValCfg = CFGMR3ValidateConfig((pDrvIns)->pCfg, "/", pszValidValues, pszValidNodes, \
458 (pDrvIns)->pReg->szName, (pDrvIns)->iInstance); \
459 if (RT_FAILURE(rcValCfg)) \
460 return rcValCfg; \
461 } while (0)
462
463
464
465/**
466 * USB hub registration structure.
467 */
468typedef struct PDMUSBHUBREG
469{
470 /** Structure version number. PDM_USBHUBREG_VERSION defines the current version. */
471 uint32_t u32Version;
472
473 /**
474 * Request the hub to attach of the specified device.
475 *
476 * @returns VBox status code.
477 * @param pDrvIns The hub instance.
478 * @param pUsbIns The device to attach.
479 * @param piPort Where to store the port number the device was attached to.
480 * @thread EMT.
481 */
482 DECLR3CALLBACKMEMBER(int, pfnAttachDevice,(PPDMDRVINS pDrvIns, PPDMUSBINS pUsbIns, uint32_t *piPort));
483
484 /**
485 * Request the hub to detach of the specified device.
486 *
487 * The device has previously been attached to the hub with the
488 * pfnAttachDevice call. This call is not currently expected to
489 * fail.
490 *
491 * @returns VBox status code.
492 * @param pDrvIns The hub instance.
493 * @param pUsbIns The device to detach.
494 * @param iPort The port number returned by the attach call.
495 * @thread EMT.
496 */
497 DECLR3CALLBACKMEMBER(int, pfnDetachDevice,(PPDMDRVINS pDrvIns, PPDMUSBINS pUsbIns, uint32_t iPort));
498
499 /** Counterpart to u32Version, same value. */
500 uint32_t u32TheEnd;
501} PDMUSBHUBREG;
502/** Pointer to a const USB hub registration structure. */
503typedef const PDMUSBHUBREG *PCPDMUSBHUBREG;
504
505/** Current PDMUSBHUBREG version number. */
506#define PDM_USBHUBREG_VERSION PDM_VERSION_MAKE(0xf0fd, 1, 0)
507
508
509/**
510 * USB hub helpers.
511 * This is currently just a place holder.
512 */
513typedef struct PDMUSBHUBHLP
514{
515 /** Structure version. PDM_USBHUBHLP_VERSION defines the current version. */
516 uint32_t u32Version;
517
518 /** Just a safety precaution. */
519 uint32_t u32TheEnd;
520} PDMUSBHUBHLP;
521/** Pointer to PCI helpers. */
522typedef PDMUSBHUBHLP *PPDMUSBHUBHLP;
523/** Pointer to const PCI helpers. */
524typedef const PDMUSBHUBHLP *PCPDMUSBHUBHLP;
525/** Pointer to const PCI helpers pointer. */
526typedef PCPDMUSBHUBHLP *PPCPDMUSBHUBHLP;
527
528/** Current PDMUSBHUBHLP version number. */
529#define PDM_USBHUBHLP_VERSION PDM_VERSION_MAKE(0xf0fc, 1, 0)
530
531
532/**
533 * PDM Driver API - raw-mode context variant.
534 */
535typedef struct PDMDRVHLPRC
536{
537 /** Structure version. PDM_DRVHLPRC_VERSION defines the current version. */
538 uint32_t u32Version;
539
540 /**
541 * Set the VM error message
542 *
543 * @returns rc.
544 * @param pDrvIns Driver instance.
545 * @param rc VBox status code.
546 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
547 * @param pszFormat Error message format string.
548 * @param ... Error message arguments.
549 */
550 DECLRCCALLBACKMEMBER(int, pfnVMSetError,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
551
552 /**
553 * Set the VM error message
554 *
555 * @returns rc.
556 * @param pDrvIns Driver instance.
557 * @param rc VBox status code.
558 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
559 * @param pszFormat Error message format string.
560 * @param va Error message arguments.
561 */
562 DECLRCCALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
563
564 /**
565 * Set the VM runtime error message
566 *
567 * @returns VBox status code.
568 * @param pDrvIns Driver instance.
569 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
570 * @param pszErrorId Error ID string.
571 * @param pszFormat Error message format string.
572 * @param ... Error message arguments.
573 */
574 DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
575
576 /**
577 * Set the VM runtime error message
578 *
579 * @returns VBox status code.
580 * @param pDrvIns Driver instance.
581 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
582 * @param pszErrorId Error ID string.
583 * @param pszFormat Error message format string.
584 * @param va Error message arguments.
585 */
586 DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
587
588 /**
589 * Assert that the current thread is the emulation thread.
590 *
591 * @returns True if correct.
592 * @returns False if wrong.
593 * @param pDrvIns Driver instance.
594 * @param pszFile Filename of the assertion location.
595 * @param iLine Linenumber of the assertion location.
596 * @param pszFunction Function of the assertion location.
597 */
598 DECLRCCALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
599
600 /**
601 * Assert that the current thread is NOT the emulation thread.
602 *
603 * @returns True if correct.
604 * @returns False if wrong.
605 * @param pDrvIns Driver instance.
606 * @param pszFile Filename of the assertion location.
607 * @param iLine Linenumber of the assertion location.
608 * @param pszFunction Function of the assertion location.
609 */
610 DECLRCCALLBACKMEMBER(bool, pfnAssertOther,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
611
612 /** Just a safety precaution. */
613 uint32_t u32TheEnd;
614} PDMDRVHLPRC;
615/** Current PDMDRVHLPRC version number. */
616#define PDM_DRVHLPRC_VERSION PDM_VERSION_MAKE(0xf0f9, 1, 0)
617
618
619/**
620 * PDM Driver API, ring-0 context.
621 */
622typedef struct PDMDRVHLPR0
623{
624 /** Structure version. PDM_DRVHLPR0_VERSION defines the current version. */
625 uint32_t u32Version;
626
627 /**
628 * Set the VM error message
629 *
630 * @returns rc.
631 * @param pDrvIns Driver instance.
632 * @param rc VBox status code.
633 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
634 * @param pszFormat Error message format string.
635 * @param ... Error message arguments.
636 */
637 DECLR0CALLBACKMEMBER(int, pfnVMSetError,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
638
639 /**
640 * Set the VM error message
641 *
642 * @returns rc.
643 * @param pDrvIns Driver instance.
644 * @param rc VBox status code.
645 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
646 * @param pszFormat Error message format string.
647 * @param va Error message arguments.
648 */
649 DECLR0CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
650
651 /**
652 * Set the VM runtime error message
653 *
654 * @returns VBox status code.
655 * @param pDrvIns Driver instance.
656 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
657 * @param pszErrorId Error ID string.
658 * @param pszFormat Error message format string.
659 * @param ... Error message arguments.
660 */
661 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
662
663 /**
664 * Set the VM runtime error message
665 *
666 * @returns VBox status code.
667 * @param pDrvIns Driver instance.
668 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
669 * @param pszErrorId Error ID string.
670 * @param pszFormat Error message format string.
671 * @param va Error message arguments.
672 */
673 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
674
675 /**
676 * Assert that the current thread is the emulation thread.
677 *
678 * @returns True if correct.
679 * @returns False if wrong.
680 * @param pDrvIns Driver instance.
681 * @param pszFile Filename of the assertion location.
682 * @param iLine Linenumber of the assertion location.
683 * @param pszFunction Function of the assertion location.
684 */
685 DECLR0CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
686
687 /**
688 * Assert that the current thread is NOT the emulation thread.
689 *
690 * @returns True if correct.
691 * @returns False if wrong.
692 * @param pDrvIns Driver instance.
693 * @param pszFile Filename of the assertion location.
694 * @param iLine Linenumber of the assertion location.
695 * @param pszFunction Function of the assertion location.
696 */
697 DECLR0CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
698
699 /** Just a safety precaution. */
700 uint32_t u32TheEnd;
701} PDMDRVHLPR0;
702/** Current DRVHLP version number. */
703#define PDM_DRVHLPR0_VERSION PDM_VERSION_MAKE(0xf0f8, 1, 0)
704
705
706#ifdef IN_RING3
707
708/**
709 * PDM Driver API.
710 */
711typedef struct PDMDRVHLPR3
712{
713 /** Structure version. PDM_DRVHLPR3_VERSION defines the current version. */
714 uint32_t u32Version;
715
716 /**
717 * Attaches a driver (chain) to the driver.
718 *
719 * @returns VBox status code.
720 * @param pDrvIns Driver instance.
721 * @param fFlags PDM_TACH_FLAGS_NOT_HOT_PLUG or 0.
722 * @param ppBaseInterface Where to store the pointer to the base interface.
723 */
724 DECLR3CALLBACKMEMBER(int, pfnAttach,(PPDMDRVINS pDrvIns, uint32_t fFlags, PPDMIBASE *ppBaseInterface));
725
726 /**
727 * Detach the driver the drivers below us.
728 *
729 * @returns VBox status code.
730 * @param pDrvIns Driver instance.
731 * @param fFlags PDM_TACH_FLAGS_NOT_HOT_PLUG or 0.
732 */
733 DECLR3CALLBACKMEMBER(int, pfnDetach,(PPDMDRVINS pDrvIns, uint32_t fFlags));
734
735 /**
736 * Detach the driver from the driver above it and destroy this
737 * driver and all drivers below it.
738 *
739 * @returns VBox status code.
740 * @param pDrvIns Driver instance.
741 * @param fFlags PDM_TACH_FLAGS_NOT_HOT_PLUG or 0.
742 */
743 DECLR3CALLBACKMEMBER(int, pfnDetachSelf,(PPDMDRVINS pDrvIns, uint32_t fFlags));
744
745 /**
746 * Prepare a media mount.
747 *
748 * The driver must not have anything attached to itself
749 * when calling this function as the purpose is to set up the configuration
750 * of an future attachment.
751 *
752 * @returns VBox status code
753 * @param pDrvIns Driver instance.
754 * @param pszFilename Pointer to filename. If this is NULL it assumed that the caller have
755 * constructed a configuration which can be attached to the bottom driver.
756 * @param pszCoreDriver Core driver name. NULL will cause autodetection. Ignored if pszFilanem is NULL.
757 */
758 DECLR3CALLBACKMEMBER(int, pfnMountPrepare,(PPDMDRVINS pDrvIns, const char *pszFilename, const char *pszCoreDriver));
759
760 /**
761 * Assert that the current thread is the emulation thread.
762 *
763 * @returns True if correct.
764 * @returns False if wrong.
765 * @param pDrvIns Driver instance.
766 * @param pszFile Filename of the assertion location.
767 * @param iLine Linenumber of the assertion location.
768 * @param pszFunction Function of the assertion location.
769 */
770 DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
771
772 /**
773 * Assert that the current thread is NOT the emulation thread.
774 *
775 * @returns True if correct.
776 * @returns False if wrong.
777 * @param pDrvIns Driver instance.
778 * @param pszFile Filename of the assertion location.
779 * @param iLine Linenumber of the assertion location.
780 * @param pszFunction Function of the assertion location.
781 */
782 DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
783
784 /**
785 * Set the VM error message
786 *
787 * @returns rc.
788 * @param pDrvIns Driver instance.
789 * @param rc VBox status code.
790 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
791 * @param pszFormat Error message format string.
792 * @param ... Error message arguments.
793 */
794 DECLR3CALLBACKMEMBER(int, pfnVMSetError,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
795
796 /**
797 * Set the VM error message
798 *
799 * @returns rc.
800 * @param pDrvIns Driver instance.
801 * @param rc VBox status code.
802 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
803 * @param pszFormat Error message format string.
804 * @param va Error message arguments.
805 */
806 DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
807
808 /**
809 * Set the VM runtime error message
810 *
811 * @returns VBox status code.
812 * @param pDrvIns Driver instance.
813 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
814 * @param pszErrorId Error ID string.
815 * @param pszFormat Error message format string.
816 * @param ... Error message arguments.
817 */
818 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
819
820 /**
821 * Set the VM runtime error message
822 *
823 * @returns VBox status code.
824 * @param pDrvIns Driver instance.
825 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
826 * @param pszErrorId Error ID string.
827 * @param pszFormat Error message format string.
828 * @param va Error message arguments.
829 */
830 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
831
832 /**
833 * Gets the VM state.
834 *
835 * @returns VM state.
836 * @param pDrvIns The driver instance.
837 * @thread Any thread (just keep in mind that it's volatile info).
838 */
839 DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDRVINS pDrvIns));
840
841 /**
842 * Checks if the VM was teleported and hasn't been fully resumed yet.
843 *
844 * @returns true / false.
845 * @param pDrvIns The driver instance.
846 * @thread Any thread.
847 */
848 DECLR3CALLBACKMEMBER(bool, pfnVMTeleportedAndNotFullyResumedYet,(PPDMDRVINS pDrvIns));
849
850 /**
851 * Create a queue.
852 *
853 * @returns VBox status code.
854 * @param pDrvIns Driver instance.
855 * @param cbItem Size a queue item.
856 * @param cItems Number of items in the queue.
857 * @param cMilliesInterval Number of milliseconds between polling the queue.
858 * If 0 then the emulation thread will be notified whenever an item arrives.
859 * @param pfnCallback The consumer function.
860 * @param pszName The queue base name. The instance number will be
861 * appended automatically.
862 * @param ppQueue Where to store the queue handle on success.
863 * @thread The emulation thread.
864 */
865 DECLR3CALLBACKMEMBER(int, pfnPDMQueueCreate,(PPDMDRVINS pDrvIns, uint32_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
866 PFNPDMQUEUEDRV pfnCallback, const char *pszName, PPDMQUEUE *ppQueue));
867
868 /**
869 * Query the virtual timer frequency.
870 *
871 * @returns Frequency in Hz.
872 * @param pDrvIns Driver instance.
873 * @thread Any thread.
874 */
875 DECLR3CALLBACKMEMBER(uint64_t, pfnTMGetVirtualFreq,(PPDMDRVINS pDrvIns));
876
877 /**
878 * Query the virtual time.
879 *
880 * @returns The current virtual time.
881 * @param pDrvIns Driver instance.
882 * @thread Any thread.
883 */
884 DECLR3CALLBACKMEMBER(uint64_t, pfnTMGetVirtualTime,(PPDMDRVINS pDrvIns));
885
886 /**
887 * Creates a timer.
888 *
889 * @returns VBox status.
890 * @param pDrvIns Driver instance.
891 * @param enmClock The clock to use on this timer.
892 * @param pfnCallback Callback function.
893 * @param pvUser The user argument to the callback.
894 * @param fFlags Timer creation flags, see grp_tm_timer_flags.
895 * @param pszDesc Pointer to description string which must stay around
896 * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
897 * @param ppTimer Where to store the timer on success.
898 * @thread EMT
899 */
900 DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
901
902 /**
903 * Register a save state data unit.
904 *
905 * @returns VBox status.
906 * @param pDrvIns Driver instance.
907 * @param uVersion Data layout version number.
908 * @param cbGuess The approximate amount of data in the unit.
909 * Only for progress indicators.
910 *
911 * @param pfnLivePrep Prepare live save callback, optional.
912 * @param pfnLiveExec Execute live save callback, optional.
913 * @param pfnLiveVote Vote live save callback, optional.
914 *
915 * @param pfnSavePrep Prepare save callback, optional.
916 * @param pfnSaveExec Execute save callback, optional.
917 * @param pfnSaveDone Done save callback, optional.
918 *
919 * @param pfnLoadPrep Prepare load callback, optional.
920 * @param pfnLoadExec Execute load callback, optional.
921 * @param pfnLoadDone Done load callback, optional.
922 */
923 DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDRVINS pDrvIns, uint32_t uVersion, size_t cbGuess,
924 PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote,
925 PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone,
926 PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone));
927
928 /**
929 * Deregister a save state data unit.
930 *
931 * @returns VBox status.
932 * @param pDrvIns Driver instance.
933 * @param pszName Data unit name.
934 * @param uInstance The instance identifier of the data unit.
935 * This must together with the name be unique.
936 */
937 DECLR3CALLBACKMEMBER(int, pfnSSMDeregister,(PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance));
938
939 /**
940 * Registers a statistics sample if statistics are enabled.
941 *
942 * @param pDrvIns Driver instance.
943 * @param pvSample Pointer to the sample.
944 * @param enmType Sample type. This indicates what pvSample is pointing at.
945 * @param pszName Sample name. The name is on this form "/<component>/<sample>".
946 * Further nesting is possible.
947 * @param enmUnit Sample unit.
948 * @param pszDesc Sample description.
949 */
950 DECLR3CALLBACKMEMBER(void, pfnSTAMRegister,(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, const char *pszName,
951 STAMUNIT enmUnit, const char *pszDesc));
952
953 /**
954 * Same as pfnSTAMRegister except that the name is specified in a
955 * RTStrPrintf like fashion.
956 *
957 * @param pDrvIns Driver instance.
958 * @param pvSample Pointer to the sample.
959 * @param enmType Sample type. This indicates what pvSample is pointing at.
960 * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
961 * @param enmUnit Sample unit.
962 * @param pszDesc Sample description.
963 * @param pszName The sample name format string.
964 * @param ... Arguments to the format string.
965 */
966 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterF,(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
967 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...));
968
969 /**
970 * Same as pfnSTAMRegister except that the name is specified in a
971 * RTStrPrintfV like fashion.
972 *
973 * @param pDrvIns Driver instance.
974 * @param pvSample Pointer to the sample.
975 * @param enmType Sample type. This indicates what pvSample is pointing at.
976 * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
977 * @param enmUnit Sample unit.
978 * @param pszDesc Sample description.
979 * @param pszName The sample name format string.
980 * @param args Arguments to the format string.
981 */
982 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
983 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args));
984
985 /**
986 * Deregister a statistic item previously registered with pfnSTAMRegister,
987 * pfnSTAMRegisterF or pfnSTAMRegisterV
988 *
989 * @returns VBox status.
990 * @param pDrvIns Driver instance.
991 * @param pvSample Pointer to the sample.
992 */
993 DECLR3CALLBACKMEMBER(int, pfnSTAMDeregister,(PPDMDRVINS pDrvIns, void *pvSample));
994
995 /**
996 * Calls the HC R0 VMM entry point, in a safer but slower manner than
997 * SUPR3CallVMMR0.
998 *
999 * When entering using this call the R0 components can call into the host kernel
1000 * (i.e. use the SUPR0 and RT APIs).
1001 *
1002 * See VMMR0Entry() for more details.
1003 *
1004 * @returns error code specific to uFunction.
1005 * @param pDrvIns The driver instance.
1006 * @param uOperation Operation to execute.
1007 * This is limited to services.
1008 * @param pvArg Pointer to argument structure or if cbArg is 0 just an value.
1009 * @param cbArg The size of the argument. This is used to copy whatever the argument
1010 * points at into a kernel buffer to avoid problems like the user page
1011 * being invalidated while we're executing the call.
1012 */
1013 DECLR3CALLBACKMEMBER(int, pfnSUPCallVMMR0Ex,(PPDMDRVINS pDrvIns, unsigned uOperation, void *pvArg, unsigned cbArg));
1014
1015 /**
1016 * Registers a USB HUB.
1017 *
1018 * @returns VBox status code.
1019 * @param pDrvIns The driver instance.
1020 * @param fVersions Indicates the kinds of USB devices that can be attached to this HUB.
1021 * @param cPorts The number of ports.
1022 * @param pUsbHubReg The hub callback structure that PDMUsb uses to interact with it.
1023 * @param ppUsbHubHlp The helper callback structure that the hub uses to talk to PDMUsb.
1024 *
1025 * @thread EMT.
1026 */
1027 DECLR3CALLBACKMEMBER(int, pfnUSBRegisterHub,(PPDMDRVINS pDrvIns, uint32_t fVersions, uint32_t cPorts, PCPDMUSBHUBREG pUsbHubReg, PPCPDMUSBHUBHLP ppUsbHubHlp));
1028
1029 /**
1030 * Set up asynchronous handling of a suspend, reset or power off notification.
1031 *
1032 * This shall only be called when getting the notification. It must be called
1033 * for each one.
1034 *
1035 * @returns VBox status code.
1036 * @param pDrvIns The driver instance.
1037 * @param pfnAsyncNotify The callback.
1038 * @thread EMT(0)
1039 */
1040 DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDRVINS pDrvIns, PFNPDMDRVASYNCNOTIFY pfnAsyncNotify));
1041
1042 /**
1043 * Notify EMT(0) that the driver has completed the asynchronous notification
1044 * handling.
1045 *
1046 * This can be called at any time, spurious calls will simply be ignored.
1047 *
1048 * @param pDrvIns The driver instance.
1049 * @thread Any
1050 */
1051 DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMDRVINS pDrvIns));
1052
1053 /**
1054 * Creates a PDM thread.
1055 *
1056 * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
1057 * resuming, and destroying the thread as the VM state changes.
1058 *
1059 * @returns VBox status code.
1060 * @param pDrvIns The driver instance.
1061 * @param ppThread Where to store the thread 'handle'.
1062 * @param pvUser The user argument to the thread function.
1063 * @param pfnThread The thread function.
1064 * @param pfnWakeup The wakup callback. This is called on the EMT thread when
1065 * a state change is pending.
1066 * @param cbStack See RTThreadCreate.
1067 * @param enmType See RTThreadCreate.
1068 * @param pszName See RTThreadCreate.
1069 */
1070 DECLR3CALLBACKMEMBER(int, pfnPDMThreadCreate,(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
1071 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
1072
1073 /**
1074 * Creates a async completion template for a driver instance.
1075 *
1076 * The template is used when creating new completion tasks.
1077 *
1078 * @returns VBox status code.
1079 * @param pDrvIns The driver instance.
1080 * @param ppTemplate Where to store the template pointer on success.
1081 * @param pfnCompleted The completion callback routine.
1082 * @param pvTemplateUser Template user argument.
1083 * @param pszDesc Description.
1084 */
1085 DECLR3CALLBACKMEMBER(int, pfnPDMAsyncCompletionTemplateCreate,(PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
1086 PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser,
1087 const char *pszDesc));
1088
1089
1090 /**
1091 * Resolves the symbol for a raw-mode context interface.
1092 *
1093 * @returns VBox status code.
1094 * @param pDrvIns The driver instance.
1095 * @param pvInterface The interface structure.
1096 * @param cbInterface The size of the interface structure.
1097 * @param pszSymPrefix What to prefix the symbols in the list with before
1098 * resolving them. This must start with 'drv' and
1099 * contain the driver name.
1100 * @param pszSymList List of symbols corresponding to the interface.
1101 * There is generally a there is generally a define
1102 * holding this list associated with the interface
1103 * definition (INTERFACE_SYM_LIST). For more details
1104 * see PDMR3LdrGetInterfaceSymbols.
1105 * @thread EMT
1106 */
1107 DECLR3CALLBACKMEMBER(int, pfnPDMLdrGetRCInterfaceSymbols,(PPDMDRVINS pDrvIns, void *pvInterface, size_t cbInterface,
1108 const char *pszSymPrefix, const char *pszSymList));
1109
1110 /**
1111 * Resolves the symbol for a ring-0 context interface.
1112 *
1113 * @returns VBox status code.
1114 * @param pDrvIns The driver instance.
1115 * @param pvInterface The interface structure.
1116 * @param cbInterface The size of the interface structure.
1117 * @param pszSymPrefix What to prefix the symbols in the list with before
1118 * resolving them. This must start with 'drv' and
1119 * contain the driver name.
1120 * @param pszSymList List of symbols corresponding to the interface.
1121 * There is generally a there is generally a define
1122 * holding this list associated with the interface
1123 * definition (INTERFACE_SYM_LIST). For more details
1124 * see PDMR3LdrGetInterfaceSymbols.
1125 * @thread EMT
1126 */
1127 DECLR3CALLBACKMEMBER(int, pfnPDMLdrGetR0InterfaceSymbols,(PPDMDRVINS pDrvIns, void *pvInterface, size_t cbInterface,
1128 const char *pszSymPrefix, const char *pszSymList));
1129 /** Just a safety precaution. */
1130 uint32_t u32TheEnd;
1131} PDMDRVHLPR3;
1132/** Current DRVHLP version number. */
1133#define PDM_DRVHLPR3_VERSION PDM_VERSION_MAKE(0xf0fb, 1, 0)
1134
1135#endif /* IN_RING3 */
1136
1137
1138/**
1139 * @copydoc PDMDRVHLP::pfnVMSetError
1140 */
1141DECLINLINE(int) PDMDrvHlpVMSetError(PPDMDRVINS pDrvIns, const int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
1142{
1143 va_list va;
1144 va_start(va, pszFormat);
1145 pDrvIns->CTX_SUFF(pHlp)->pfnVMSetErrorV(pDrvIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
1146 va_end(va);
1147 return rc;
1148}
1149
1150/** @def PDMDRV_SET_ERROR
1151 * Set the VM error. See PDMDrvHlpVMSetError() for printf like message formatting.
1152 */
1153#define PDMDRV_SET_ERROR(pDrvIns, rc, pszError) \
1154 PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, "%s", pszError)
1155
1156/**
1157 * @copydoc PDMDRVHLP::pfnVMSetErrorV
1158 */
1159DECLINLINE(int) PDMDrvHlpVMSetErrorV(PPDMDRVINS pDrvIns, const int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
1160{
1161 return pDrvIns->CTX_SUFF(pHlp)->pfnVMSetErrorV(pDrvIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
1162}
1163
1164
1165/**
1166 * @copydoc PDMDRVHLP::pfnVMSetRuntimeError
1167 */
1168DECLINLINE(int) PDMDrvHlpVMSetRuntimeError(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
1169{
1170 va_list va;
1171 int rc;
1172 va_start(va, pszFormat);
1173 rc = pDrvIns->CTX_SUFF(pHlp)->pfnVMSetRuntimeErrorV(pDrvIns, fFlags, pszErrorId, pszFormat, va);
1174 va_end(va);
1175 return rc;
1176}
1177
1178/** @def PDMDRV_SET_RUNTIME_ERROR
1179 * Set the VM runtime error. See PDMDrvHlpVMSetRuntimeError() for printf like message formatting.
1180 */
1181#define PDMDRV_SET_RUNTIME_ERROR(pDrvIns, fFlags, pszErrorId, pszError) \
1182 PDMDrvHlpVMSetRuntimeError(pDrvIns, fFlags, pszErrorId, "%s", pszError)
1183
1184/**
1185 * @copydoc PDMDRVHLP::pfnVMSetRuntimeErrorV
1186 */
1187DECLINLINE(int) PDMDrvHlpVMSetRuntimeErrorV(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
1188{
1189 return pDrvIns->CTX_SUFF(pHlp)->pfnVMSetRuntimeErrorV(pDrvIns, fFlags, pszErrorId, pszFormat, va);
1190}
1191
1192
1193
1194/** @def PDMDRV_ASSERT_EMT
1195 * Assert that the current thread is the emulation thread.
1196 */
1197#ifdef VBOX_STRICT
1198# define PDMDRV_ASSERT_EMT(pDrvIns) pDrvIns->CTX_SUFF(pHlp)->pfnAssertEMT(pDrvIns, __FILE__, __LINE__, __FUNCTION__)
1199#else
1200# define PDMDRV_ASSERT_EMT(pDrvIns) do { } while (0)
1201#endif
1202
1203/** @def PDMDRV_ASSERT_OTHER
1204 * Assert that the current thread is NOT the emulation thread.
1205 */
1206#ifdef VBOX_STRICT
1207# define PDMDRV_ASSERT_OTHER(pDrvIns) pDrvIns->CTX_SUFF(pHlp)->pfnAssertOther(pDrvIns, __FILE__, __LINE__, __FUNCTION__)
1208#else
1209# define PDMDRV_ASSERT_OTHER(pDrvIns) do { } while (0)
1210#endif
1211
1212
1213#ifdef IN_RING3
1214
1215/**
1216 * @copydoc PDMDRVHLP::pfnAttach
1217 */
1218DECLINLINE(int) PDMDrvHlpAttach(PPDMDRVINS pDrvIns, uint32_t fFlags, PPDMIBASE *ppBaseInterface)
1219{
1220 return pDrvIns->pHlpR3->pfnAttach(pDrvIns, fFlags, ppBaseInterface);
1221}
1222
1223/**
1224 * Check that there is no driver below the us that we should attach to.
1225 *
1226 * @returns VERR_PDM_NO_ATTACHED_DRIVER if there is no driver.
1227 * @param pDrvIns The driver instance.
1228 */
1229DECLINLINE(int) PDMDrvHlpNoAttach(PPDMDRVINS pDrvIns)
1230{
1231 return pDrvIns->pHlpR3->pfnAttach(pDrvIns, 0, NULL);
1232}
1233
1234/**
1235 * @copydoc PDMDRVHLP::pfnDetach
1236 */
1237DECLINLINE(int) PDMDrvHlpDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
1238{
1239 return pDrvIns->pHlpR3->pfnDetach(pDrvIns, fFlags);
1240}
1241
1242/**
1243 * @copydoc PDMDRVHLP::pfnDetachSelf
1244 */
1245DECLINLINE(int) PDMDrvHlpDetachSelf(PPDMDRVINS pDrvIns, uint32_t fFlags)
1246{
1247 return pDrvIns->pHlpR3->pfnDetachSelf(pDrvIns, fFlags);
1248}
1249
1250/**
1251 * @copydoc PDMDRVHLP::pfnMountPrepare
1252 */
1253DECLINLINE(int) PDMDrvHlpMountPrepare(PPDMDRVINS pDrvIns, const char *pszFilename, const char *pszCoreDriver)
1254{
1255 return pDrvIns->pHlpR3->pfnMountPrepare(pDrvIns, pszFilename, pszCoreDriver);
1256}
1257
1258/**
1259 * @copydoc PDMDRVHLP::pfnVMState
1260 */
1261DECLINLINE(VMSTATE) PDMDrvHlpVMState(PPDMDRVINS pDrvIns)
1262{
1263 return pDrvIns->CTX_SUFF(pHlp)->pfnVMState(pDrvIns);
1264}
1265
1266/**
1267 * @copydoc PDMDRVHLP::pfnVMTeleportedAndNotFullyResumedYet
1268 */
1269DECLINLINE(bool) PDMDrvHlpVMTeleportedAndNotFullyResumedYet(PPDMDRVINS pDrvIns)
1270{
1271 return pDrvIns->pHlpR3->pfnVMTeleportedAndNotFullyResumedYet(pDrvIns);
1272}
1273
1274/**
1275 * @copydoc PDMDRVHLP::pfnPDMQueueCreate
1276 */
1277DECLINLINE(int) PDMDrvHlpPDMQueueCreate(PPDMDRVINS pDrvIns, uint32_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
1278 PFNPDMQUEUEDRV pfnCallback, const char *pszName, PPDMQUEUE *ppQueue)
1279{
1280 return pDrvIns->pHlpR3->pfnPDMQueueCreate(pDrvIns, cbItem, cItems, cMilliesInterval, pfnCallback, pszName, ppQueue);
1281}
1282
1283/**
1284 * @copydoc PDMDRVHLP::pfnTMGetVirtualFreq
1285 */
1286DECLINLINE(uint64_t) PDMDrvHlpTMGetVirtualFreq(PPDMDRVINS pDrvIns)
1287{
1288 return pDrvIns->pHlpR3->pfnTMGetVirtualFreq(pDrvIns);
1289}
1290
1291/**
1292 * @copydoc PDMDRVHLP::pfnTMGetVirtualTime
1293 */
1294DECLINLINE(uint64_t) PDMDrvHlpTMGetVirtualTime(PPDMDRVINS pDrvIns)
1295{
1296 return pDrvIns->pHlpR3->pfnTMGetVirtualTime(pDrvIns);
1297}
1298
1299/**
1300 * @copydoc PDMDRVHLP::pfnTMTimerCreate
1301 */
1302DECLINLINE(int) PDMDrvHlpTMTimerCreate(PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
1303{
1304 return pDrvIns->pHlpR3->pfnTMTimerCreate(pDrvIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
1305}
1306
1307/**
1308 * Register a save state data unit.
1309 *
1310 * @returns VBox status.
1311 * @param pDrvIns Driver instance.
1312 * @param uVersion Data layout version number.
1313 * @param cbGuess The approximate amount of data in the unit.
1314 * Only for progress indicators.
1315 * @param pfnSaveExec Execute save callback, optional.
1316 * @param pfnLoadExec Execute load callback, optional.
1317 */
1318DECLINLINE(int) PDMDrvHlpSSMRegister(PPDMDRVINS pDrvIns, uint32_t uVersion, size_t cbGuess,
1319 PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVLOADEXEC pfnLoadExec)
1320{
1321 return pDrvIns->pHlpR3->pfnSSMRegister(pDrvIns, uVersion, cbGuess,
1322 NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveVote*/,
1323 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
1324 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
1325}
1326
1327/**
1328 * @copydoc PDMDRVHLP::pfnSSMRegister
1329 */
1330DECLINLINE(int) PDMDrvHlpSSMRegisterEx(PPDMDRVINS pDrvIns, uint32_t uVersion, size_t cbGuess,
1331 PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote,
1332 PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone,
1333 PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone)
1334{
1335 return pDrvIns->pHlpR3->pfnSSMRegister(pDrvIns, uVersion, cbGuess,
1336 pfnLivePrep, pfnLiveExec, pfnLiveVote,
1337 pfnSavePrep, pfnSaveExec, pfnSaveDone,
1338 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
1339}
1340
1341/**
1342 * Register a load done callback.
1343 *
1344 * @returns VBox status.
1345 * @param pDrvIns Driver instance.
1346 * @param pfnLoadDone Done load callback, optional.
1347 */
1348DECLINLINE(int) PDMDrvHlpSSMRegisterLoadDone(PPDMDRVINS pDrvIns, PFNSSMDRVLOADDONE pfnLoadDone)
1349{
1350 return pDrvIns->pHlpR3->pfnSSMRegister(pDrvIns, 0 /*uVersion*/, 0 /*cbGuess*/,
1351 NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveVote*/,
1352 NULL /*pfnSavePrep*/, NULL /*pfnSaveExec*/, NULL /*pfnSaveDone*/,
1353 NULL /*pfnLoadPrep*/, NULL /*pfnLoadExec*/, pfnLoadDone);
1354}
1355
1356/**
1357 * @copydoc PDMDRVHLP::pfnSTAMRegister
1358 */
1359DECLINLINE(void) PDMDrvHlpSTAMRegister(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
1360{
1361 pDrvIns->pHlpR3->pfnSTAMRegister(pDrvIns, pvSample, enmType, pszName, enmUnit, pszDesc);
1362}
1363
1364/**
1365 * @copydoc PDMDRVHLP::pfnSTAMRegisterF
1366 */
1367DECLINLINE(void) PDMDrvHlpSTAMRegisterF(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
1368 const char *pszDesc, const char *pszName, ...)
1369{
1370 va_list va;
1371 va_start(va, pszName);
1372 pDrvIns->pHlpR3->pfnSTAMRegisterV(pDrvIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, va);
1373 va_end(va);
1374}
1375
1376/**
1377 * @copydoc PDMDRVHLP::pfnSTAMDeregister
1378 */
1379DECLINLINE(int) PDMDrvHlpSTAMDeregister(PPDMDRVINS pDrvIns, void *pvSample)
1380{
1381 return pDrvIns->pHlpR3->pfnSTAMDeregister(pDrvIns, pvSample);
1382}
1383
1384/**
1385 * @copydoc PDMDRVHLP::pfnSUPCallVMMR0Ex
1386 */
1387DECLINLINE(int) PDMDrvHlpSUPCallVMMR0Ex(PPDMDRVINS pDrvIns, unsigned uOperation, void *pvArg, unsigned cbArg)
1388{
1389 return pDrvIns->pHlpR3->pfnSUPCallVMMR0Ex(pDrvIns, uOperation, pvArg, cbArg);
1390}
1391
1392/**
1393 * @copydoc PDMDRVHLP::pfnUSBRegisterHub
1394 */
1395DECLINLINE(int) PDMDrvHlpUSBRegisterHub(PPDMDRVINS pDrvIns, uint32_t fVersions, uint32_t cPorts, PCPDMUSBHUBREG pUsbHubReg, PPCPDMUSBHUBHLP ppUsbHubHlp)
1396{
1397 return pDrvIns->pHlpR3->pfnUSBRegisterHub(pDrvIns, fVersions, cPorts, pUsbHubReg, ppUsbHubHlp);
1398}
1399
1400/**
1401 * @copydoc PDMDRVHLP::pfnSetAsyncNotification
1402 */
1403DECLINLINE(int) PDMDrvHlpSetAsyncNotification(PPDMDRVINS pDrvIns, PFNPDMDRVASYNCNOTIFY pfnAsyncNotify)
1404{
1405 return pDrvIns->pHlpR3->pfnSetAsyncNotification(pDrvIns, pfnAsyncNotify);
1406}
1407
1408/**
1409 * @copydoc PDMDRVHLP::pfnAsyncNotificationCompleted
1410 */
1411DECLINLINE(void) PDMDrvHlpAsyncNotificationCompleted(PPDMDRVINS pDrvIns)
1412{
1413 pDrvIns->pHlpR3->pfnAsyncNotificationCompleted(pDrvIns);
1414}
1415
1416/**
1417 * @copydoc PDMDRVHLP::pfnPDMThreadCreate
1418 */
1419DECLINLINE(int) PDMDrvHlpPDMThreadCreate(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
1420 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
1421{
1422 return pDrvIns->pHlpR3->pfnPDMThreadCreate(pDrvIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
1423}
1424
1425# ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
1426/**
1427 * @copydoc PDMDRVHLP::pfnPDMAsyncCompletionTemplateCreate
1428 */
1429DECLINLINE(int) PDMDrvHlpPDMAsyncCompletionTemplateCreate(PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
1430 PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc)
1431{
1432 return pDrvIns->pHlpR3->pfnPDMAsyncCompletionTemplateCreate(pDrvIns, ppTemplate, pfnCompleted, pvTemplateUser, pszDesc);
1433}
1434# endif
1435
1436
1437/** Pointer to callbacks provided to the VBoxDriverRegister() call. */
1438typedef struct PDMDRVREGCB *PPDMDRVREGCB;
1439/** Pointer to const callbacks provided to the VBoxDriverRegister() call. */
1440typedef const struct PDMDRVREGCB *PCPDMDRVREGCB;
1441
1442/**
1443 * Callbacks for VBoxDriverRegister().
1444 */
1445typedef struct PDMDRVREGCB
1446{
1447 /** Interface version.
1448 * This is set to PDM_DRVREG_CB_VERSION. */
1449 uint32_t u32Version;
1450
1451 /**
1452 * Registers a driver with the current VM instance.
1453 *
1454 * @returns VBox status code.
1455 * @param pCallbacks Pointer to the callback table.
1456 * @param pReg Pointer to the driver registration record.
1457 * This data must be permanent and readonly.
1458 */
1459 DECLR3CALLBACKMEMBER(int, pfnRegister,(PCPDMDRVREGCB pCallbacks, PCPDMDRVREG pReg));
1460} PDMDRVREGCB;
1461
1462/** Current version of the PDMDRVREGCB structure. */
1463#define PDM_DRVREG_CB_VERSION PDM_VERSION_MAKE(0xf0fa, 1, 0)
1464
1465
1466/**
1467 * The VBoxDriverRegister callback function.
1468 *
1469 * PDM will invoke this function after loading a driver module and letting
1470 * the module decide which drivers to register and how to handle conflicts.
1471 *
1472 * @returns VBox status code.
1473 * @param pCallbacks Pointer to the callback table.
1474 * @param u32Version VBox version number.
1475 */
1476typedef DECLCALLBACK(int) FNPDMVBOXDRIVERSREGISTER(PCPDMDRVREGCB pCallbacks, uint32_t u32Version);
1477
1478VMMR3DECL(int) PDMR3RegisterDrivers(PVM pVM, FNPDMVBOXDRIVERSREGISTER pfnCallback);
1479
1480#endif /* IN_RING3 */
1481
1482/** @} */
1483
1484RT_C_DECLS_END
1485
1486#endif
Note: See TracBrowser for help on using the repository browser.

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