VirtualBox

source: vbox/trunk/include/VBox/pdmdev.h@ 33799

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

PDM: Added DevHelps to query virtual time without requiring a timer.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 175.2 KB
Line 
1/** @file
2 * PDM - Pluggable Device Manager, Devices. (VMM)
3 */
4
5/*
6 * Copyright (C) 2006-2010 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. 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
26#ifndef ___VBox_pdmdev_h
27#define ___VBox_pdmdev_h
28
29#include <VBox/pdmqueue.h>
30#include <VBox/pdmcritsect.h>
31#include <VBox/pdmthread.h>
32#include <VBox/pdmifs.h>
33#include <VBox/pdmins.h>
34#include <VBox/pdmcommon.h>
35#include <VBox/iom.h>
36#include <VBox/tm.h>
37#include <VBox/ssm.h>
38#include <VBox/cfgm.h>
39#include <VBox/dbgf.h>
40#include <VBox/err.h>
41#include <VBox/pci.h>
42#include <iprt/stdarg.h>
43
44RT_C_DECLS_BEGIN
45
46/** @defgroup grp_pdm_device The PDM Devices API
47 * @ingroup grp_pdm
48 * @{
49 */
50
51/**
52 * Construct a device instance for a VM.
53 *
54 * @returns VBox status.
55 * @param pDevIns The device instance data. If the registration structure
56 * is needed, it can be accessed thru pDevIns->pReg.
57 * @param iInstance Instance number. Use this to figure out which registers
58 * and such to use. The instance number is also found in
59 * pDevIns->iInstance, but since it's likely to be
60 * frequently used PDM passes it as parameter.
61 * @param pCfg Configuration node handle for the driver. This is
62 * expected to be in high demand in the constructor and is
63 * therefore passed as an argument. When using it at other
64 * times, it can be found in pDrvIns->pCfg.
65 */
66typedef DECLCALLBACK(int) FNPDMDEVCONSTRUCT(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg);
67/** Pointer to a FNPDMDEVCONSTRUCT() function. */
68typedef FNPDMDEVCONSTRUCT *PFNPDMDEVCONSTRUCT;
69
70/**
71 * Destruct a device instance.
72 *
73 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
74 * resources can be freed correctly.
75 *
76 * @returns VBox status.
77 * @param pDevIns The device instance data.
78 */
79typedef DECLCALLBACK(int) FNPDMDEVDESTRUCT(PPDMDEVINS pDevIns);
80/** Pointer to a FNPDMDEVDESTRUCT() function. */
81typedef FNPDMDEVDESTRUCT *PFNPDMDEVDESTRUCT;
82
83/**
84 * Device relocation callback.
85 *
86 * This is called when the instance data has been relocated in raw-mode context
87 * (RC). It is also called when the RC hypervisor selects changes. The device
88 * must fixup all necessary pointers and re-query all interfaces to other RC
89 * devices and drivers.
90 *
91 * Before the RC code is executed the first time, this function will be called
92 * with a 0 delta so RC pointer calculations can be one in one place.
93 *
94 * @param pDevIns Pointer to the device instance.
95 * @param offDelta The relocation delta relative to the old location.
96 *
97 * @remark A relocation CANNOT fail.
98 */
99typedef DECLCALLBACK(void) FNPDMDEVRELOCATE(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
100/** Pointer to a FNPDMDEVRELOCATE() function. */
101typedef FNPDMDEVRELOCATE *PFNPDMDEVRELOCATE;
102
103/**
104 * Device I/O Control interface.
105 *
106 * This is used by external components, such as the COM interface, to
107 * communicate with devices using a class wide interface or a device
108 * specific interface.
109 *
110 * @returns VBox status code.
111 * @param pDevIns Pointer to the device instance.
112 * @param uFunction Function to perform.
113 * @param pvIn Pointer to input data.
114 * @param cbIn Size of input data.
115 * @param pvOut Pointer to output data.
116 * @param cbOut Size of output data.
117 * @param pcbOut Where to store the actual size of the output data.
118 */
119typedef DECLCALLBACK(int) FNPDMDEVIOCTL(PPDMDEVINS pDevIns, RTUINT uFunction,
120 void *pvIn, RTUINT cbIn,
121 void *pvOut, RTUINT cbOut, PRTUINT pcbOut);
122/** Pointer to a FNPDMDEVIOCTL() function. */
123typedef FNPDMDEVIOCTL *PFNPDMDEVIOCTL;
124
125/**
126 * Power On notification.
127 *
128 * @returns VBox status.
129 * @param pDevIns The device instance data.
130 */
131typedef DECLCALLBACK(void) FNPDMDEVPOWERON(PPDMDEVINS pDevIns);
132/** Pointer to a FNPDMDEVPOWERON() function. */
133typedef FNPDMDEVPOWERON *PFNPDMDEVPOWERON;
134
135/**
136 * Reset notification.
137 *
138 * @returns VBox status.
139 * @param pDevIns The device instance data.
140 */
141typedef DECLCALLBACK(void) FNPDMDEVRESET(PPDMDEVINS pDevIns);
142/** Pointer to a FNPDMDEVRESET() function. */
143typedef FNPDMDEVRESET *PFNPDMDEVRESET;
144
145/**
146 * Suspend notification.
147 *
148 * @returns VBox status.
149 * @param pDevIns The device instance data.
150 * @thread EMT(0)
151 */
152typedef DECLCALLBACK(void) FNPDMDEVSUSPEND(PPDMDEVINS pDevIns);
153/** Pointer to a FNPDMDEVSUSPEND() function. */
154typedef FNPDMDEVSUSPEND *PFNPDMDEVSUSPEND;
155
156/**
157 * Resume notification.
158 *
159 * @returns VBox status.
160 * @param pDevIns The device instance data.
161 */
162typedef DECLCALLBACK(void) FNPDMDEVRESUME(PPDMDEVINS pDevIns);
163/** Pointer to a FNPDMDEVRESUME() function. */
164typedef FNPDMDEVRESUME *PFNPDMDEVRESUME;
165
166/**
167 * Power Off notification.
168 *
169 * This is only called when the VMR3PowerOff call is made on a running VM. This
170 * means that there is no notification if the VM was suspended before being
171 * powered of. There will also be no callback when hot plugging devices.
172 *
173 * @param pDevIns The device instance data.
174 * @thread EMT(0)
175 */
176typedef DECLCALLBACK(void) FNPDMDEVPOWEROFF(PPDMDEVINS pDevIns);
177/** Pointer to a FNPDMDEVPOWEROFF() function. */
178typedef FNPDMDEVPOWEROFF *PFNPDMDEVPOWEROFF;
179
180/**
181 * Attach command.
182 *
183 * This is called to let the device attach to a driver for a specified LUN
184 * at runtime. This is not called during VM construction, the device
185 * constructor have to attach to all the available drivers.
186 *
187 * This is like plugging in the keyboard or mouse after turning on the PC.
188 *
189 * @returns VBox status code.
190 * @param pDevIns The device instance.
191 * @param iLUN The logical unit which is being detached.
192 * @param fFlags Flags, combination of the PDM_TACH_FLAGS_* \#defines.
193 */
194typedef DECLCALLBACK(int) FNPDMDEVATTACH(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags);
195/** Pointer to a FNPDMDEVATTACH() function. */
196typedef FNPDMDEVATTACH *PFNPDMDEVATTACH;
197
198/**
199 * Detach notification.
200 *
201 * This is called when a driver is detaching itself from a LUN of the device.
202 * The device should adjust it's state to reflect this.
203 *
204 * This is like unplugging the network cable to use it for the laptop or
205 * something while the PC is still running.
206 *
207 * @param pDevIns The device instance.
208 * @param iLUN The logical unit which is being detached.
209 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
210 */
211typedef DECLCALLBACK(void) FNPDMDEVDETACH(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags);
212/** Pointer to a FNPDMDEVDETACH() function. */
213typedef FNPDMDEVDETACH *PFNPDMDEVDETACH;
214
215/**
216 * Query the base interface of a logical unit.
217 *
218 * @returns VBOX status code.
219 * @param pDevIns The device instance.
220 * @param iLUN The logicial unit to query.
221 * @param ppBase Where to store the pointer to the base interface of the LUN.
222 */
223typedef DECLCALLBACK(int) FNPDMDEVQUERYINTERFACE(PPDMDEVINS pDevIns, unsigned iLUN, PPDMIBASE *ppBase);
224/** Pointer to a FNPDMDEVQUERYINTERFACE() function. */
225typedef FNPDMDEVQUERYINTERFACE *PFNPDMDEVQUERYINTERFACE;
226
227/**
228 * Init complete notification.
229 * This can be done to do communication with other devices and other
230 * initialization which requires everything to be in place.
231 *
232 * @returns VBOX status code.
233 * @param pDevIns The device instance.
234 */
235typedef DECLCALLBACK(int) FNPDMDEVINITCOMPLETE(PPDMDEVINS pDevIns);
236/** Pointer to a FNPDMDEVINITCOMPLETE() function. */
237typedef FNPDMDEVINITCOMPLETE *PFNPDMDEVINITCOMPLETE;
238
239
240
241/**
242 * PDM Device Registration Structure.
243 *
244 * This structure is used when registering a device from VBoxInitDevices() in HC
245 * Ring-3. PDM will continue use till the VM is terminated.
246 */
247typedef struct PDMDEVREG
248{
249 /** Structure version. PDM_DEVREG_VERSION defines the current version. */
250 uint32_t u32Version;
251 /** Device name. */
252 char szName[32];
253 /** Name of the raw-mode context module (no path).
254 * Only evalutated if PDM_DEVREG_FLAGS_RC is set. */
255 char szRCMod[32];
256 /** Name of the ring-0 module (no path).
257 * Only evalutated if PDM_DEVREG_FLAGS_R0 is set. */
258 char szR0Mod[32];
259 /** The description of the device. The UTF-8 string pointed to shall, like this structure,
260 * remain unchanged from registration till VM destruction. */
261 const char *pszDescription;
262
263 /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
264 uint32_t fFlags;
265 /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
266 uint32_t fClass;
267 /** Maximum number of instances (per VM). */
268 uint32_t cMaxInstances;
269 /** Size of the instance data. */
270 uint32_t cbInstance;
271
272 /** Construct instance - required. */
273 PFNPDMDEVCONSTRUCT pfnConstruct;
274 /** Destruct instance - optional. */
275 PFNPDMDEVDESTRUCT pfnDestruct;
276 /** Relocation command - optional. */
277 PFNPDMDEVRELOCATE pfnRelocate;
278 /** I/O Control interface - optional. */
279 PFNPDMDEVIOCTL pfnIOCtl;
280 /** Power on notification - optional. */
281 PFNPDMDEVPOWERON pfnPowerOn;
282 /** Reset notification - optional. */
283 PFNPDMDEVRESET pfnReset;
284 /** Suspend notification - optional. */
285 PFNPDMDEVSUSPEND pfnSuspend;
286 /** Resume notification - optional. */
287 PFNPDMDEVRESUME pfnResume;
288 /** Attach command - optional. */
289 PFNPDMDEVATTACH pfnAttach;
290 /** Detach notification - optional. */
291 PFNPDMDEVDETACH pfnDetach;
292 /** Query a LUN base interface - optional. */
293 PFNPDMDEVQUERYINTERFACE pfnQueryInterface;
294 /** Init complete notification - optional. */
295 PFNPDMDEVINITCOMPLETE pfnInitComplete;
296 /** Power off notification - optional. */
297 PFNPDMDEVPOWEROFF pfnPowerOff;
298 /** @todo */
299 PFNRT pfnSoftReset;
300 /** Initialization safty marker. */
301 uint32_t u32VersionEnd;
302} PDMDEVREG;
303/** Pointer to a PDM Device Structure. */
304typedef PDMDEVREG *PPDMDEVREG;
305/** Const pointer to a PDM Device Structure. */
306typedef PDMDEVREG const *PCPDMDEVREG;
307
308/** Current DEVREG version number. */
309#define PDM_DEVREG_VERSION PDM_VERSION_MAKE(0xffff, 1, 0)
310
311/** PDM Device Flags.
312 * @{ */
313/** This flag is used to indicate that the device has a RC component. */
314#define PDM_DEVREG_FLAGS_RC 0x00000001
315/** This flag is used to indicate that the device has a R0 component. */
316#define PDM_DEVREG_FLAGS_R0 0x00000002
317
318/** @def PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT
319 * The bit count for the current host. */
320#if HC_ARCH_BITS == 32
321# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT 0x00000010
322#elif HC_ARCH_BITS == 64
323# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT 0x00000020
324#else
325# error Unsupported HC_ARCH_BITS value.
326#endif
327/** The host bit count mask. */
328#define PDM_DEVREG_FLAGS_HOST_BITS_MASK 0x00000030
329
330/** The device support only 32-bit guests. */
331#define PDM_DEVREG_FLAGS_GUEST_BITS_32 0x00000100
332/** The device support only 64-bit guests. */
333#define PDM_DEVREG_FLAGS_GUEST_BITS_64 0x00000200
334/** The device support both 32-bit & 64-bit guests. */
335#define PDM_DEVREG_FLAGS_GUEST_BITS_32_64 0x00000300
336/** @def PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT
337 * The guest bit count for the current compilation. */
338#if GC_ARCH_BITS == 32
339# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT PDM_DEVREG_FLAGS_GUEST_BITS_32
340#elif GC_ARCH_BITS == 64
341# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT PDM_DEVREG_FLAGS_GUEST_BITS_32_64
342#else
343# error Unsupported GC_ARCH_BITS value.
344#endif
345/** The guest bit count mask. */
346#define PDM_DEVREG_FLAGS_GUEST_BITS_MASK 0x00000300
347
348/** A convenience. */
349#define PDM_DEVREG_FLAGS_DEFAULT_BITS (PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT)
350
351/** Indicates that the devices support PAE36 on a 32-bit guest. */
352#define PDM_DEVREG_FLAGS_PAE36 0x00001000
353
354/** Indicates that the device needs to be notified before the drivers when suspending. */
355#define PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION 0x00002000
356
357/** Indicates that the device needs to be notified before the drivers when powering off. */
358#define PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION 0x00004000
359/** @} */
360
361
362/** PDM Device Classes.
363 * The order is important, lower bit earlier instantiation.
364 * @{ */
365/** Architecture device. */
366#define PDM_DEVREG_CLASS_ARCH RT_BIT(0)
367/** Architecture BIOS device. */
368#define PDM_DEVREG_CLASS_ARCH_BIOS RT_BIT(1)
369/** PCI bus brigde. */
370#define PDM_DEVREG_CLASS_BUS_PCI RT_BIT(2)
371/** ISA bus brigde. */
372#define PDM_DEVREG_CLASS_BUS_ISA RT_BIT(3)
373/** Input device (mouse, keyboard, joystick, HID, ...). */
374#define PDM_DEVREG_CLASS_INPUT RT_BIT(4)
375/** Interrupt controller (PIC). */
376#define PDM_DEVREG_CLASS_PIC RT_BIT(5)
377/** Interval controoler (PIT). */
378#define PDM_DEVREG_CLASS_PIT RT_BIT(6)
379/** RTC/CMOS. */
380#define PDM_DEVREG_CLASS_RTC RT_BIT(7)
381/** DMA controller. */
382#define PDM_DEVREG_CLASS_DMA RT_BIT(8)
383/** VMM Device. */
384#define PDM_DEVREG_CLASS_VMM_DEV RT_BIT(9)
385/** Graphics device, like VGA. */
386#define PDM_DEVREG_CLASS_GRAPHICS RT_BIT(10)
387/** Storage controller device. */
388#define PDM_DEVREG_CLASS_STORAGE RT_BIT(11)
389/** Network interface controller. */
390#define PDM_DEVREG_CLASS_NETWORK RT_BIT(12)
391/** Audio. */
392#define PDM_DEVREG_CLASS_AUDIO RT_BIT(13)
393/** USB HIC. */
394#define PDM_DEVREG_CLASS_BUS_USB RT_BIT(14)
395/** ACPI. */
396#define PDM_DEVREG_CLASS_ACPI RT_BIT(15)
397/** Serial controller device. */
398#define PDM_DEVREG_CLASS_SERIAL RT_BIT(16)
399/** Parallel controller device */
400#define PDM_DEVREG_CLASS_PARALLEL RT_BIT(17)
401/** Host PCI pass-through device */
402#define PDM_DEVREG_CLASS_HOST_DEV RT_BIT(18)
403/** Misc devices (always last). */
404#define PDM_DEVREG_CLASS_MISC RT_BIT(31)
405/** @} */
406
407
408/** @name IRQ Level for use with the *SetIrq APIs.
409 * @{
410 */
411/** Assert the IRQ (can assume value 1). */
412#define PDM_IRQ_LEVEL_HIGH RT_BIT(0)
413/** Deassert the IRQ (can assume value 0). */
414#define PDM_IRQ_LEVEL_LOW 0
415/** flip-flop - assert and then deassert it again immediately. */
416#define PDM_IRQ_LEVEL_FLIP_FLOP (RT_BIT(1) | PDM_IRQ_LEVEL_HIGH)
417/** @} */
418
419/**
420 * Registration record for MSI.
421 */
422typedef struct PDMMSIREG
423{
424 /** Number of MSI interrupt vectors, 0 if MSI not supported */
425 uint16_t cMsiVectors;
426 /** Offset of MSI capability */
427 uint8_t iMsiCapOffset;
428 /** Offset of next capability to MSI */
429 uint8_t iMsiNextOffset;
430 /** If we support 64-bit MSI addressing */
431 bool fMsi64bit;
432
433 /** Number of MSI-X interrupt vectors, 0 if MSI-X not supported */
434 uint16_t cMsixVectors;
435 /** Offset of MSI-X capability */
436 uint8_t iMsixCapOffset;
437 /** Offset of next capability to MSI-X */
438 uint8_t iMsixNextOffset;
439 /** Value of PCI BAR (base addresss register) assigned by device for MSI-X page access */
440 uint8_t iMsixBar;
441} PDMMSIREG;
442typedef PDMMSIREG *PPDMMSIREG;
443
444/**
445 * PCI Bus registration structure.
446 * All the callbacks, except the PCIBIOS hack, are working on PCI devices.
447 */
448typedef struct PDMPCIBUSREG
449{
450 /** Structure version number. PDM_PCIBUSREG_VERSION defines the current version. */
451 uint32_t u32Version;
452
453 /**
454 * Registers the device with the default PCI bus.
455 *
456 * @returns VBox status code.
457 * @param pDevIns Device instance of the PCI Bus.
458 * @param pPciDev The PCI device structure.
459 * Any PCI enabled device must keep this in it's instance data!
460 * Fill in the PCI data config before registration, please.
461 * @param pszName Pointer to device name (permanent, readonly). For debugging, not unique.
462 * @param iDev The device number ((dev << 3) | function) the device should have on the bus.
463 * If negative, the pci bus device will assign one.
464 */
465 DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev));
466
467 /**
468 * Initialize MSI support in a PCI device.
469 *
470 * @returns VBox status code.
471 * @param pDevIns Device instance of the PCI Bus.
472 * @param pPciDev The PCI device structure.
473 * @param pMsiReg MSI registration structure
474 */
475 DECLR3CALLBACKMEMBER(int, pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg));
476
477 /**
478 * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
479 *
480 * @returns VBox status code.
481 * @param pDevIns Device instance of the PCI Bus.
482 * @param pPciDev The PCI device structure.
483 * @param iRegion The region number.
484 * @param cbRegion Size of the region.
485 * @param iType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
486 * @param pfnCallback Callback for doing the mapping.
487 */
488 DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
489
490 /**
491 * Register PCI configuration space read/write callbacks.
492 *
493 * @param pDevIns Device instance of the PCI Bus.
494 * @param pPciDev The PCI device structure.
495 * @param pfnRead Pointer to the user defined PCI config read function.
496 * @param ppfnReadOld Pointer to function pointer which will receive the old (default)
497 * PCI config read function. This way, user can decide when (and if)
498 * to call default PCI config read function. Can be NULL.
499 * @param pfnWrite Pointer to the user defined PCI config write function.
500 * @param pfnWriteOld Pointer to function pointer which will receive the old (default)
501 * PCI config write function. This way, user can decide when (and if)
502 * to call default PCI config write function. Can be NULL.
503 * @thread EMT
504 */
505 DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
506 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
507
508 /**
509 * Set the IRQ for a PCI device.
510 *
511 * @param pDevIns Device instance of the PCI Bus.
512 * @param pPciDev The PCI device structure.
513 * @param iIrq IRQ number to set.
514 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
515 */
516 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
517
518 /**
519 * Saves a state of the PCI device.
520 *
521 * @returns VBox status code.
522 * @param pDevIns Device instance of the PCI Bus.
523 * @param pPciDev Pointer to PCI device.
524 * @param pSSMHandle The handle to save the state to.
525 */
526 DECLR3CALLBACKMEMBER(int, pfnSaveExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
527
528 /**
529 * Loads a saved PCI device state.
530 *
531 * @returns VBox status code.
532 * @param pDevIns Device instance of the PCI Bus.
533 * @param pPciDev Pointer to PCI device.
534 * @param pSSMHandle The handle to the saved state.
535 */
536 DECLR3CALLBACKMEMBER(int, pfnLoadExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
537
538 /**
539 * Called to perform the job of the bios.
540 * This is only called for the first PCI Bus - it is expected to
541 * service all the PCI buses.
542 *
543 * @returns VBox status.
544 * @param pDevIns Device instance of the first bus.
545 */
546 DECLR3CALLBACKMEMBER(int, pfnFakePCIBIOSR3,(PPDMDEVINS pDevIns));
547
548 /** The name of the SetIrq RC entry point. */
549 const char *pszSetIrqRC;
550
551 /** The name of the SetIrq R0 entry point. */
552 const char *pszSetIrqR0;
553
554} PDMPCIBUSREG;
555/** Pointer to a PCI bus registration structure. */
556typedef PDMPCIBUSREG *PPDMPCIBUSREG;
557
558/** Current PDMPCIBUSREG version number. */
559#define PDM_PCIBUSREG_VERSION PDM_VERSION_MAKE(0xfffe, 2, 0)
560
561/**
562 * PCI Bus RC helpers.
563 */
564typedef struct PDMPCIHLPRC
565{
566 /** Structure version. PDM_PCIHLPRC_VERSION defines the current version. */
567 uint32_t u32Version;
568
569 /**
570 * Set an ISA IRQ.
571 *
572 * @param pDevIns PCI device instance.
573 * @param iIrq IRQ number to set.
574 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
575 * @thread EMT only.
576 */
577 DECLRCCALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
578
579 /**
580 * Set an I/O-APIC IRQ.
581 *
582 * @param pDevIns PCI device instance.
583 * @param iIrq IRQ number to set.
584 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
585 * @thread EMT only.
586 */
587 DECLRCCALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
588
589 /**
590 * Send an MSI.
591 *
592 * @param pDevIns PCI device instance.
593 * @param GCAddr Physical address MSI request was written.
594 * @param uValue Value written.
595 * @thread EMT only.
596 */
597 DECLRCCALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
598
599
600 /**
601 * Acquires the PDM lock.
602 *
603 * @returns VINF_SUCCESS on success.
604 * @returns rc if we failed to acquire the lock.
605 * @param pDevIns The PCI device instance.
606 * @param rc What to return if we fail to acquire the lock.
607 */
608 DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
609
610 /**
611 * Releases the PDM lock.
612 *
613 * @param pDevIns The PCI device instance.
614 */
615 DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
616
617 /** Just a safety precaution. */
618 uint32_t u32TheEnd;
619} PDMPCIHLPRC;
620/** Pointer to PCI helpers. */
621typedef RCPTRTYPE(PDMPCIHLPRC *) PPDMPCIHLPRC;
622/** Pointer to const PCI helpers. */
623typedef RCPTRTYPE(const PDMPCIHLPRC *) PCPDMPCIHLPRC;
624
625/** Current PDMPCIHLPRC version number. */
626#define PDM_PCIHLPRC_VERSION PDM_VERSION_MAKE(0xfffd, 2, 0)
627
628
629/**
630 * PCI Bus R0 helpers.
631 */
632typedef struct PDMPCIHLPR0
633{
634 /** Structure version. PDM_PCIHLPR0_VERSION defines the current version. */
635 uint32_t u32Version;
636
637 /**
638 * Set an ISA IRQ.
639 *
640 * @param pDevIns PCI device instance.
641 * @param iIrq IRQ number to set.
642 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
643 * @thread EMT only.
644 */
645 DECLR0CALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
646
647 /**
648 * Set an I/O-APIC IRQ.
649 *
650 * @param pDevIns PCI device instance.
651 * @param iIrq IRQ number to set.
652 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
653 * @thread EMT only.
654 */
655 DECLR0CALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
656
657 /**
658 * Send an MSI.
659 *
660 * @param pDevIns PCI device instance.
661 * @param GCAddr Physical address MSI request was written.
662 * @param uValue Value written.
663 * @thread EMT only.
664 */
665 DECLR0CALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
666
667
668 /**
669 * Acquires the PDM lock.
670 *
671 * @returns VINF_SUCCESS on success.
672 * @returns rc if we failed to acquire the lock.
673 * @param pDevIns The PCI device instance.
674 * @param rc What to return if we fail to acquire the lock.
675 */
676 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
677
678 /**
679 * Releases the PDM lock.
680 *
681 * @param pDevIns The PCI device instance.
682 */
683 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
684
685 /** Just a safety precaution. */
686 uint32_t u32TheEnd;
687} PDMPCIHLPR0;
688/** Pointer to PCI helpers. */
689typedef R0PTRTYPE(PDMPCIHLPR0 *) PPDMPCIHLPR0;
690/** Pointer to const PCI helpers. */
691typedef R0PTRTYPE(const PDMPCIHLPR0 *) PCPDMPCIHLPR0;
692
693/** Current PDMPCIHLPR0 version number. */
694#define PDM_PCIHLPR0_VERSION PDM_VERSION_MAKE(0xfffc, 2, 0)
695
696/**
697 * PCI device helpers.
698 */
699typedef struct PDMPCIHLPR3
700{
701 /** Structure version. PDM_PCIHLPR3_VERSION defines the current version. */
702 uint32_t u32Version;
703
704 /**
705 * Set an ISA IRQ.
706 *
707 * @param pDevIns The PCI device instance.
708 * @param iIrq IRQ number to set.
709 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
710 * @thread EMT only.
711 */
712 DECLR3CALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
713
714 /**
715 * Set an I/O-APIC IRQ.
716 *
717 * @param pDevIns The PCI device instance.
718 * @param iIrq IRQ number to set.
719 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
720 * @thread EMT only.
721 */
722 DECLR3CALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
723
724 /**
725 * Send an MSI.
726 *
727 * @param pDevIns PCI device instance.
728 * @param GCAddr Physical address MSI request was written.
729 * @param uValue Value written.
730 * @thread EMT only.
731 */
732 DECLR3CALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
733
734 /**
735 * Checks if the given address is an MMIO2 base address or not.
736 *
737 * @returns true/false accordingly.
738 * @param pDevIns The PCI device instance.
739 * @param pOwner The owner of the memory, optional.
740 * @param GCPhys The address to check.
741 */
742 DECLR3CALLBACKMEMBER(bool, pfnIsMMIO2Base,(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys));
743
744 /**
745 * Gets the address of the RC PCI Bus helpers.
746 *
747 * This should be called at both construction and relocation time
748 * to obtain the correct address of the RC helpers.
749 *
750 * @returns RC pointer to the PCI Bus helpers.
751 * @param pDevIns Device instance of the PCI Bus.
752 * @thread EMT only.
753 */
754 DECLR3CALLBACKMEMBER(PCPDMPCIHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
755
756 /**
757 * Gets the address of the R0 PCI Bus helpers.
758 *
759 * This should be called at both construction and relocation time
760 * to obtain the correct address of the R0 helpers.
761 *
762 * @returns R0 pointer to the PCI Bus helpers.
763 * @param pDevIns Device instance of the PCI Bus.
764 * @thread EMT only.
765 */
766 DECLR3CALLBACKMEMBER(PCPDMPCIHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
767
768 /**
769 * Acquires the PDM lock.
770 *
771 * @returns VINF_SUCCESS on success.
772 * @returns Fatal error on failure.
773 * @param pDevIns The PCI device instance.
774 * @param rc Dummy for making the interface identical to the RC and R0 versions.
775 */
776 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
777
778 /**
779 * Releases the PDM lock.
780 *
781 * @param pDevIns The PCI device instance.
782 */
783 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
784
785 /** Just a safety precaution. */
786 uint32_t u32TheEnd;
787} PDMPCIHLPR3;
788/** Pointer to PCI helpers. */
789typedef R3PTRTYPE(PDMPCIHLPR3 *) PPDMPCIHLPR3;
790/** Pointer to const PCI helpers. */
791typedef R3PTRTYPE(const PDMPCIHLPR3 *) PCPDMPCIHLPR3;
792
793/** Current PDMPCIHLPR3 version number. */
794#define PDM_PCIHLPR3_VERSION PDM_VERSION_MAKE(0xfffb, 2, 0)
795
796
797/**
798 * Programmable Interrupt Controller registration structure.
799 */
800typedef struct PDMPICREG
801{
802 /** Structure version number. PDM_PICREG_VERSION defines the current version. */
803 uint32_t u32Version;
804
805 /**
806 * Set the an IRQ.
807 *
808 * @param pDevIns Device instance of the PIC.
809 * @param iIrq IRQ number to set.
810 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
811 */
812 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
813
814 /**
815 * Get a pending interrupt.
816 *
817 * @returns Pending interrupt number.
818 * @param pDevIns Device instance of the PIC.
819 */
820 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns));
821
822 /** The name of the RC SetIrq entry point. */
823 const char *pszSetIrqRC;
824 /** The name of the RC GetInterrupt entry point. */
825 const char *pszGetInterruptRC;
826
827 /** The name of the R0 SetIrq entry point. */
828 const char *pszSetIrqR0;
829 /** The name of the R0 GetInterrupt entry point. */
830 const char *pszGetInterruptR0;
831} PDMPICREG;
832/** Pointer to a PIC registration structure. */
833typedef PDMPICREG *PPDMPICREG;
834
835/** Current PDMPICREG version number. */
836#define PDM_PICREG_VERSION PDM_VERSION_MAKE(0xfffa, 1, 0)
837
838/**
839 * PIC RC helpers.
840 */
841typedef struct PDMPICHLPRC
842{
843 /** Structure version. PDM_PICHLPRC_VERSION defines the current version. */
844 uint32_t u32Version;
845
846 /**
847 * Set the interrupt force action flag.
848 *
849 * @param pDevIns Device instance of the PIC.
850 */
851 DECLRCCALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
852
853 /**
854 * Clear the interrupt force action flag.
855 *
856 * @param pDevIns Device instance of the PIC.
857 */
858 DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
859
860 /**
861 * Acquires the PDM lock.
862 *
863 * @returns VINF_SUCCESS on success.
864 * @returns rc if we failed to acquire the lock.
865 * @param pDevIns The PIC device instance.
866 * @param rc What to return if we fail to acquire the lock.
867 */
868 DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
869
870 /**
871 * Releases the PDM lock.
872 *
873 * @param pDevIns The PIC device instance.
874 */
875 DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
876
877 /** Just a safety precaution. */
878 uint32_t u32TheEnd;
879} PDMPICHLPRC;
880
881/** Pointer to PIC RC helpers. */
882typedef RCPTRTYPE(PDMPICHLPRC *) PPDMPICHLPRC;
883/** Pointer to const PIC RC helpers. */
884typedef RCPTRTYPE(const PDMPICHLPRC *) PCPDMPICHLPRC;
885
886/** Current PDMPICHLPRC version number. */
887#define PDM_PICHLPRC_VERSION PDM_VERSION_MAKE(0xfff9, 1, 0)
888
889
890/**
891 * PIC R0 helpers.
892 */
893typedef struct PDMPICHLPR0
894{
895 /** Structure version. PDM_PICHLPR0_VERSION defines the current version. */
896 uint32_t u32Version;
897
898 /**
899 * Set the interrupt force action flag.
900 *
901 * @param pDevIns Device instance of the PIC.
902 */
903 DECLR0CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
904
905 /**
906 * Clear the interrupt force action flag.
907 *
908 * @param pDevIns Device instance of the PIC.
909 */
910 DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
911
912 /**
913 * Acquires the PDM lock.
914 *
915 * @returns VINF_SUCCESS on success.
916 * @returns rc if we failed to acquire the lock.
917 * @param pDevIns The PIC device instance.
918 * @param rc What to return if we fail to acquire the lock.
919 */
920 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
921
922 /**
923 * Releases the PDM lock.
924 *
925 * @param pDevIns The PCI device instance.
926 */
927 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
928
929 /** Just a safety precaution. */
930 uint32_t u32TheEnd;
931} PDMPICHLPR0;
932
933/** Pointer to PIC R0 helpers. */
934typedef R0PTRTYPE(PDMPICHLPR0 *) PPDMPICHLPR0;
935/** Pointer to const PIC R0 helpers. */
936typedef R0PTRTYPE(const PDMPICHLPR0 *) PCPDMPICHLPR0;
937
938/** Current PDMPICHLPR0 version number. */
939#define PDM_PICHLPR0_VERSION PDM_VERSION_MAKE(0xfff8, 1, 0)
940
941/**
942 * PIC R3 helpers.
943 */
944typedef struct PDMPICHLPR3
945{
946 /** Structure version. PDM_PICHLP_VERSION defines the current version. */
947 uint32_t u32Version;
948
949 /**
950 * Set the interrupt force action flag.
951 *
952 * @param pDevIns Device instance of the PIC.
953 */
954 DECLR3CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
955
956 /**
957 * Clear the interrupt force action flag.
958 *
959 * @param pDevIns Device instance of the PIC.
960 */
961 DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
962
963 /**
964 * Acquires the PDM lock.
965 *
966 * @returns VINF_SUCCESS on success.
967 * @returns Fatal error on failure.
968 * @param pDevIns The PIC device instance.
969 * @param rc Dummy for making the interface identical to the RC and R0 versions.
970 */
971 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
972
973 /**
974 * Releases the PDM lock.
975 *
976 * @param pDevIns The PIC device instance.
977 */
978 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
979
980 /**
981 * Gets the address of the RC PIC helpers.
982 *
983 * This should be called at both construction and relocation time
984 * to obtain the correct address of the RC helpers.
985 *
986 * @returns RC pointer to the PIC helpers.
987 * @param pDevIns Device instance of the PIC.
988 */
989 DECLR3CALLBACKMEMBER(PCPDMPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
990
991 /**
992 * Gets the address of the R0 PIC helpers.
993 *
994 * This should be called at both construction and relocation time
995 * to obtain the correct address of the R0 helpers.
996 *
997 * @returns R0 pointer to the PIC helpers.
998 * @param pDevIns Device instance of the PIC.
999 */
1000 DECLR3CALLBACKMEMBER(PCPDMPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
1001
1002 /** Just a safety precaution. */
1003 uint32_t u32TheEnd;
1004} PDMPICHLPR3;
1005
1006/** Pointer to PIC R3 helpers. */
1007typedef R3PTRTYPE(PDMPICHLPR3 *) PPDMPICHLPR3;
1008/** Pointer to const PIC R3 helpers. */
1009typedef R3PTRTYPE(const PDMPICHLPR3 *) PCPDMPICHLPR3;
1010
1011/** Current PDMPICHLPR3 version number. */
1012#define PDM_PICHLPR3_VERSION PDM_VERSION_MAKE(0xfff7, 1, 0)
1013
1014
1015
1016/**
1017 * Advanced Programmable Interrupt Controller registration structure.
1018 */
1019typedef struct PDMAPICREG
1020{
1021 /** Structure version number. PDM_APICREG_VERSION defines the current version. */
1022 uint32_t u32Version;
1023
1024 /**
1025 * Get a pending interrupt.
1026 *
1027 * @returns Pending interrupt number.
1028 * @param pDevIns Device instance of the APIC.
1029 */
1030 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns));
1031
1032 /**
1033 * Check if the APIC has a pending interrupt/if a TPR change would active one
1034 *
1035 * @returns Pending interrupt yes/no
1036 * @param pDevIns Device instance of the APIC.
1037 */
1038 DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns));
1039
1040 /**
1041 * Set the APIC base.
1042 *
1043 * @param pDevIns Device instance of the APIC.
1044 * @param u64Base The new base.
1045 */
1046 DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, uint64_t u64Base));
1047
1048 /**
1049 * Get the APIC base.
1050 *
1051 * @returns Current base.
1052 * @param pDevIns Device instance of the APIC.
1053 */
1054 DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns));
1055
1056 /**
1057 * Set the TPR (task priority register).
1058 *
1059 * @param pDevIns Device instance of the APIC.
1060 * @param idCpu VCPU id
1061 * @param u8TPR The new TPR.
1062 */
1063 DECLR3CALLBACKMEMBER(void, pfnSetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR));
1064
1065 /**
1066 * Get the TPR (task priority register).
1067 *
1068 * @returns The current TPR.
1069 * @param pDevIns Device instance of the APIC.
1070 * @param idCpu VCPU id
1071 */
1072 DECLR3CALLBACKMEMBER(uint8_t, pfnGetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu));
1073
1074 /**
1075 * Write MSR in APIC range.
1076 *
1077 * @returns VBox status code.
1078 * @param pDevIns Device instance of the APIC.
1079 * @param idCpu Target CPU.
1080 * @param u32Reg MSR to write.
1081 * @param u64Value Value to write.
1082 */
1083 DECLR3CALLBACKMEMBER(int, pfnWriteMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value));
1084
1085 /**
1086 * Read MSR in APIC range.
1087 *
1088 * @returns VBox status code.
1089 * @param pDevIns Device instance of the APIC.
1090 * @param idCpu Target CPU.
1091 * @param u32Reg MSR to read.
1092 * @param pu64Value Value read.
1093 */
1094 DECLR3CALLBACKMEMBER(int, pfnReadMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value));
1095
1096 /**
1097 * Private interface between the IOAPIC and APIC.
1098 *
1099 * This is a low-level, APIC/IOAPIC implementation specific interface
1100 * which is registered with PDM only because it makes life so much
1101 * simpler right now (GC bits). This is a bad bad hack! The correct
1102 * way of doing this would involve some way of querying GC interfaces
1103 * and relocating them. Perhaps doing some kind of device init in GC...
1104 *
1105 * @returns status code.
1106 * @param pDevIns Device instance of the APIC.
1107 * @param u8Dest See APIC implementation.
1108 * @param u8DestMode See APIC implementation.
1109 * @param u8DeliveryMode See APIC implementation.
1110 * @param iVector See APIC implementation.
1111 * @param u8Polarity See APIC implementation.
1112 * @param u8TriggerMode See APIC implementation.
1113 */
1114 DECLR3CALLBACKMEMBER(int, pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1115 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
1116
1117 /**
1118 * Deliver a signal to CPU's local interrupt pins (LINT0/LINT1). Used for
1119 * virtual wire mode when interrupts from the PIC are passed through LAPIC.
1120 *
1121 * @returns status code.
1122 * @param pDevIns Device instance of the APIC.
1123 * @param u8Pin Local pin number (0 or 1 for current CPUs).
1124 */
1125 DECLR3CALLBACKMEMBER(int, pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
1126
1127 /** The name of the RC GetInterrupt entry point. */
1128 const char *pszGetInterruptRC;
1129 /** The name of the RC HasPendingIrq entry point. */
1130 const char *pszHasPendingIrqRC;
1131 /** The name of the RC SetBase entry point. */
1132 const char *pszSetBaseRC;
1133 /** The name of the RC GetBase entry point. */
1134 const char *pszGetBaseRC;
1135 /** The name of the RC SetTPR entry point. */
1136 const char *pszSetTPRRC;
1137 /** The name of the RC GetTPR entry point. */
1138 const char *pszGetTPRRC;
1139 /** The name of the RC WriteMSR entry point. */
1140 const char *pszWriteMSRRC;
1141 /** The name of the RC ReadMSR entry point. */
1142 const char *pszReadMSRRC;
1143 /** The name of the RC BusDeliver entry point. */
1144 const char *pszBusDeliverRC;
1145 /** The name of the RC LocalInterrupt entry point. */
1146 const char *pszLocalInterruptRC;
1147
1148 /** The name of the R0 GetInterrupt entry point. */
1149 const char *pszGetInterruptR0;
1150 /** The name of the R0 HasPendingIrq entry point. */
1151 const char *pszHasPendingIrqR0;
1152 /** The name of the R0 SetBase entry point. */
1153 const char *pszSetBaseR0;
1154 /** The name of the R0 GetBase entry point. */
1155 const char *pszGetBaseR0;
1156 /** The name of the R0 SetTPR entry point. */
1157 const char *pszSetTPRR0;
1158 /** The name of the R0 GetTPR entry point. */
1159 const char *pszGetTPRR0;
1160 /** The name of the R0 WriteMSR entry point. */
1161 const char *pszWriteMSRR0;
1162 /** The name of the R0 ReadMSR entry point. */
1163 const char *pszReadMSRR0;
1164 /** The name of the R0 BusDeliver entry point. */
1165 const char *pszBusDeliverR0;
1166 /** The name of the R0 LocalInterrupt entry point. */
1167 const char *pszLocalInterruptR0;
1168
1169} PDMAPICREG;
1170/** Pointer to an APIC registration structure. */
1171typedef PDMAPICREG *PPDMAPICREG;
1172
1173/** Current PDMAPICREG version number. */
1174#define PDM_APICREG_VERSION PDM_VERSION_MAKE(0xfff6, 1, 0)
1175
1176
1177/**
1178 * APIC version argument for pfnChangeFeature.
1179 */
1180typedef enum PDMAPICVERSION
1181{
1182 /** Invalid 0 entry. */
1183 PDMAPICVERSION_INVALID = 0,
1184 /** No APIC. */
1185 PDMAPICVERSION_NONE,
1186 /** Standard APIC (X86_CPUID_FEATURE_EDX_APIC). */
1187 PDMAPICVERSION_APIC,
1188 /** Intel X2APIC (X86_CPUID_FEATURE_ECX_X2APIC). */
1189 PDMAPICVERSION_X2APIC,
1190 /** The usual 32-bit paranoia. */
1191 PDMAPICVERSION_32BIT_HACK = 0x7fffffff
1192} PDMAPICVERSION;
1193
1194/**
1195 * APIC irq argument for SetInterruptFF.
1196 */
1197typedef enum PDMAPICIRQ
1198{
1199 /** Invalid 0 entry. */
1200 PDMAPICIRQ_INVALID = 0,
1201 /** Normal hardware interrupt. */
1202 PDMAPICIRQ_HARDWARE,
1203 /** NMI. */
1204 PDMAPICIRQ_NMI,
1205 /** SMI. */
1206 PDMAPICIRQ_SMI,
1207 /** ExtINT (HW interrupt via PIC). */
1208 PDMAPICIRQ_EXTINT,
1209 /** The usual 32-bit paranoia. */
1210 PDMAPICIRQ_32BIT_HACK = 0x7fffffff
1211} PDMAPICIRQ;
1212
1213
1214/**
1215 * APIC RC helpers.
1216 */
1217typedef struct PDMAPICHLPRC
1218{
1219 /** Structure version. PDM_APICHLPRC_VERSION defines the current version. */
1220 uint32_t u32Version;
1221
1222 /**
1223 * Set the interrupt force action flag.
1224 *
1225 * @param pDevIns Device instance of the APIC.
1226 * @param enmType IRQ type.
1227 * @param idCpu Virtual CPU to set flag upon.
1228 */
1229 DECLRCCALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
1230
1231 /**
1232 * Clear the interrupt force action flag.
1233 *
1234 * @param pDevIns Device instance of the APIC.
1235 * @param enmType IRQ type.
1236 * @param idCpu Virtual CPU to clear flag upon.
1237 */
1238 DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
1239
1240 /**
1241 * Modifies APIC-related bits in the CPUID feature mask.
1242 *
1243 * @param pDevIns Device instance of the APIC.
1244 * @param enmVersion Supported APIC version.
1245 */
1246 DECLRCCALLBACKMEMBER(void, pfnChangeFeature,(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion));
1247
1248 /**
1249 * Acquires the PDM lock.
1250 *
1251 * @returns VINF_SUCCESS on success.
1252 * @returns rc if we failed to acquire the lock.
1253 * @param pDevIns The APIC device instance.
1254 * @param rc What to return if we fail to acquire the lock.
1255 */
1256 DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1257
1258 /**
1259 * Releases the PDM lock.
1260 *
1261 * @param pDevIns The APIC device instance.
1262 */
1263 DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1264
1265 /**
1266 * Get the virtual CPU id corresponding to the current EMT.
1267 *
1268 * @param pDevIns The APIC device instance.
1269 */
1270 DECLRCCALLBACKMEMBER(VMCPUID, pfnGetCpuId,(PPDMDEVINS pDevIns));
1271
1272 /** Just a safety precaution. */
1273 uint32_t u32TheEnd;
1274} PDMAPICHLPRC;
1275/** Pointer to APIC GC helpers. */
1276typedef RCPTRTYPE(PDMAPICHLPRC *) PPDMAPICHLPRC;
1277/** Pointer to const APIC helpers. */
1278typedef RCPTRTYPE(const PDMAPICHLPRC *) PCPDMAPICHLPRC;
1279
1280/** Current PDMAPICHLPRC version number. */
1281#define PDM_APICHLPRC_VERSION PDM_VERSION_MAKE(0xfff5, 1, 0)
1282
1283
1284/**
1285 * APIC R0 helpers.
1286 */
1287typedef struct PDMAPICHLPR0
1288{
1289 /** Structure version. PDM_APICHLPR0_VERSION defines the current version. */
1290 uint32_t u32Version;
1291
1292 /**
1293 * Set the interrupt force action flag.
1294 *
1295 * @param pDevIns Device instance of the APIC.
1296 * @param enmType IRQ type.
1297 * @param idCpu Virtual CPU to set flag upon.
1298 */
1299 DECLR0CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
1300
1301 /**
1302 * Clear the interrupt force action flag.
1303 *
1304 * @param pDevIns Device instance of the APIC.
1305 * @param enmType IRQ type.
1306 * @param idCpu Virtual CPU to clear flag upon.
1307 */
1308 DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
1309
1310 /**
1311 * Modifies APIC-related bits in the CPUID feature mask.
1312 *
1313 * @param pDevIns Device instance of the APIC.
1314 * @param enmVersion Supported APIC version.
1315 */
1316 DECLR0CALLBACKMEMBER(void, pfnChangeFeature,(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion));
1317
1318 /**
1319 * Acquires the PDM lock.
1320 *
1321 * @returns VINF_SUCCESS on success.
1322 * @returns rc if we failed to acquire the lock.
1323 * @param pDevIns The APIC device instance.
1324 * @param rc What to return if we fail to acquire the lock.
1325 */
1326 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1327
1328 /**
1329 * Releases the PDM lock.
1330 *
1331 * @param pDevIns The APIC device instance.
1332 */
1333 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1334
1335 /**
1336 * Get the virtual CPU id corresponding to the current EMT.
1337 *
1338 * @param pDevIns The APIC device instance.
1339 */
1340 DECLR0CALLBACKMEMBER(VMCPUID, pfnGetCpuId,(PPDMDEVINS pDevIns));
1341
1342 /** Just a safety precaution. */
1343 uint32_t u32TheEnd;
1344} PDMAPICHLPR0;
1345/** Pointer to APIC GC helpers. */
1346typedef RCPTRTYPE(PDMAPICHLPR0 *) PPDMAPICHLPR0;
1347/** Pointer to const APIC helpers. */
1348typedef R0PTRTYPE(const PDMAPICHLPR0 *) PCPDMAPICHLPR0;
1349
1350/** Current PDMAPICHLPR0 version number. */
1351#define PDM_APICHLPR0_VERSION PDM_VERSION_MAKE(0xfff4, 1, 0)
1352
1353/**
1354 * APIC R3 helpers.
1355 */
1356typedef struct PDMAPICHLPR3
1357{
1358 /** Structure version. PDM_APICHLPR3_VERSION defines the current version. */
1359 uint32_t u32Version;
1360
1361 /**
1362 * Set the interrupt force action flag.
1363 *
1364 * @param pDevIns Device instance of the APIC.
1365 * @param enmType IRQ type.
1366 * @param idCpu Virtual CPU to set flag upon.
1367 */
1368 DECLR3CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
1369
1370 /**
1371 * Clear the interrupt force action flag.
1372 *
1373 * @param pDevIns Device instance of the APIC.
1374 * @param enmType IRQ type.
1375 * @param idCpu Virtual CPU to clear flag upon.
1376 */
1377 DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
1378
1379 /**
1380 * Modifies APIC-related bits in the CPUID feature mask.
1381 *
1382 * @param pDevIns Device instance of the APIC.
1383 * @param enmVersion Supported APIC version.
1384 */
1385 DECLR3CALLBACKMEMBER(void, pfnChangeFeature,(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion));
1386
1387 /**
1388 * Get the virtual CPU id corresponding to the current EMT.
1389 *
1390 * @param pDevIns The APIC device instance.
1391 */
1392 DECLR3CALLBACKMEMBER(VMCPUID, pfnGetCpuId,(PPDMDEVINS pDevIns));
1393
1394 /**
1395 * Sends SIPI to given virtual CPU.
1396 *
1397 * @param pDevIns The APIC device instance.
1398 * @param idCpu Virtual CPU to perform SIPI on
1399 * @param iVector SIPI vector
1400 */
1401 DECLR3CALLBACKMEMBER(void, pfnSendSipi,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t uVector));
1402
1403 /**
1404 * Sends init IPI to given virtual CPU, should result in reset and
1405 * halting till SIPI.
1406 *
1407 * @param pDevIns The APIC device instance.
1408 * @param idCpu Virtual CPU to perform SIPI on
1409 */
1410 DECLR3CALLBACKMEMBER(void, pfnSendInitIpi,(PPDMDEVINS pDevIns, VMCPUID idCpu));
1411
1412 /**
1413 * Gets the address of the RC APIC helpers.
1414 *
1415 * This should be called at both construction and relocation time
1416 * to obtain the correct address of the RC helpers.
1417 *
1418 * @returns GC pointer to the APIC helpers.
1419 * @param pDevIns Device instance of the APIC.
1420 */
1421 DECLR3CALLBACKMEMBER(PCPDMAPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
1422
1423 /**
1424 * Gets the address of the R0 APIC helpers.
1425 *
1426 * This should be called at both construction and relocation time
1427 * to obtain the correct address of the R0 helpers.
1428 *
1429 * @returns R0 pointer to the APIC helpers.
1430 * @param pDevIns Device instance of the APIC.
1431 */
1432 DECLR3CALLBACKMEMBER(PCPDMAPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
1433
1434 /**
1435 * Get the critical section used to synchronize the PICs, PCI and stuff.
1436 *
1437 * @returns Ring-3 pointer to the critical section.
1438 * @param pDevIns The APIC device instance.
1439 */
1440 DECLR3CALLBACKMEMBER(R3PTRTYPE(PPDMCRITSECT), pfnGetR3CritSect,(PPDMDEVINS pDevIns));
1441
1442 /**
1443 * Get the critical section used to synchronize the PICs, PCI and stuff.
1444 *
1445 * @returns Raw-mode context pointer to the critical section.
1446 * @param pDevIns The APIC device instance.
1447 */
1448 DECLR3CALLBACKMEMBER(RCPTRTYPE(PPDMCRITSECT), pfnGetRCCritSect,(PPDMDEVINS pDevIns));
1449
1450 /**
1451 * Get the critical section used to synchronize the PICs, PCI and stuff.
1452 *
1453 * @returns Ring-0 pointer to the critical section.
1454 * @param pDevIns The APIC device instance.
1455 */
1456 DECLR3CALLBACKMEMBER(R0PTRTYPE(PPDMCRITSECT), pfnGetR0CritSect,(PPDMDEVINS pDevIns));
1457
1458 /** Just a safety precaution. */
1459 uint32_t u32TheEnd;
1460} PDMAPICHLPR3;
1461/** Pointer to APIC helpers. */
1462typedef R3PTRTYPE(PDMAPICHLPR3 *) PPDMAPICHLPR3;
1463/** Pointer to const APIC helpers. */
1464typedef R3PTRTYPE(const PDMAPICHLPR3 *) PCPDMAPICHLPR3;
1465
1466/** Current PDMAPICHLP version number. */
1467#define PDM_APICHLPR3_VERSION PDM_VERSION_MAKE(0xfff3, 1, 0)
1468
1469
1470/**
1471 * I/O APIC registration structure.
1472 */
1473typedef struct PDMIOAPICREG
1474{
1475 /** Struct version+magic number (PDM_IOAPICREG_VERSION). */
1476 uint32_t u32Version;
1477
1478 /**
1479 * Set the an IRQ.
1480 *
1481 * @param pDevIns Device instance of the I/O APIC.
1482 * @param iIrq IRQ number to set.
1483 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1484 */
1485 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
1486
1487 /** The name of the GC SetIrq entry point. */
1488 const char *pszSetIrqRC;
1489
1490 /** The name of the R0 SetIrq entry point. */
1491 const char *pszSetIrqR0;
1492
1493 /**
1494 * Send a MSI.
1495 *
1496 * @param pDevIns Device instance of the I/O APIC.
1497 * @param GCPhys Request address.
1498 * @param uValue Request value.
1499 */
1500 DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue));
1501
1502 /** The name of the GC SendMsi entry point. */
1503 const char *pszSendMsiRC;
1504
1505 /** The name of the R0 SendMsi entry point. */
1506 const char *pszSendMsiR0;
1507} PDMIOAPICREG;
1508/** Pointer to an APIC registration structure. */
1509typedef PDMIOAPICREG *PPDMIOAPICREG;
1510
1511/** Current PDMAPICREG version number. */
1512#define PDM_IOAPICREG_VERSION PDM_VERSION_MAKE(0xfff2, 2, 0)
1513
1514
1515/**
1516 * IOAPIC RC helpers.
1517 */
1518typedef struct PDMIOAPICHLPRC
1519{
1520 /** Structure version. PDM_IOAPICHLPRC_VERSION defines the current version. */
1521 uint32_t u32Version;
1522
1523 /**
1524 * Private interface between the IOAPIC and APIC.
1525 *
1526 * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
1527 *
1528 * @returns status code.
1529 * @param pDevIns Device instance of the IOAPIC.
1530 * @param u8Dest See APIC implementation.
1531 * @param u8DestMode See APIC implementation.
1532 * @param u8DeliveryMode See APIC implementation.
1533 * @param iVector See APIC implementation.
1534 * @param u8Polarity See APIC implementation.
1535 * @param u8TriggerMode See APIC implementation.
1536 */
1537 DECLRCCALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1538 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
1539
1540 /**
1541 * Acquires the PDM lock.
1542 *
1543 * @returns VINF_SUCCESS on success.
1544 * @returns rc if we failed to acquire the lock.
1545 * @param pDevIns The IOAPIC device instance.
1546 * @param rc What to return if we fail to acquire the lock.
1547 */
1548 DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1549
1550 /**
1551 * Releases the PDM lock.
1552 *
1553 * @param pDevIns The IOAPIC device instance.
1554 */
1555 DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1556
1557 /** Just a safety precaution. */
1558 uint32_t u32TheEnd;
1559} PDMIOAPICHLPRC;
1560/** Pointer to IOAPIC RC helpers. */
1561typedef RCPTRTYPE(PDMIOAPICHLPRC *) PPDMIOAPICHLPRC;
1562/** Pointer to const IOAPIC helpers. */
1563typedef RCPTRTYPE(const PDMIOAPICHLPRC *) PCPDMIOAPICHLPRC;
1564
1565/** Current PDMIOAPICHLPRC version number. */
1566#define PDM_IOAPICHLPRC_VERSION PDM_VERSION_MAKE(0xfff1, 1, 0)
1567
1568
1569/**
1570 * IOAPIC R0 helpers.
1571 */
1572typedef struct PDMIOAPICHLPR0
1573{
1574 /** Structure version. PDM_IOAPICHLPR0_VERSION defines the current version. */
1575 uint32_t u32Version;
1576
1577 /**
1578 * Private interface between the IOAPIC and APIC.
1579 *
1580 * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
1581 *
1582 * @returns status code.
1583 * @param pDevIns Device instance of the IOAPIC.
1584 * @param u8Dest See APIC implementation.
1585 * @param u8DestMode See APIC implementation.
1586 * @param u8DeliveryMode See APIC implementation.
1587 * @param iVector See APIC implementation.
1588 * @param u8Polarity See APIC implementation.
1589 * @param u8TriggerMode See APIC implementation.
1590 */
1591 DECLR0CALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1592 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
1593
1594 /**
1595 * Acquires the PDM lock.
1596 *
1597 * @returns VINF_SUCCESS on success.
1598 * @returns rc if we failed to acquire the lock.
1599 * @param pDevIns The IOAPIC device instance.
1600 * @param rc What to return if we fail to acquire the lock.
1601 */
1602 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1603
1604 /**
1605 * Releases the PDM lock.
1606 *
1607 * @param pDevIns The IOAPIC device instance.
1608 */
1609 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1610
1611 /** Just a safety precaution. */
1612 uint32_t u32TheEnd;
1613} PDMIOAPICHLPR0;
1614/** Pointer to IOAPIC R0 helpers. */
1615typedef R0PTRTYPE(PDMIOAPICHLPR0 *) PPDMIOAPICHLPR0;
1616/** Pointer to const IOAPIC helpers. */
1617typedef R0PTRTYPE(const PDMIOAPICHLPR0 *) PCPDMIOAPICHLPR0;
1618
1619/** Current PDMIOAPICHLPR0 version number. */
1620#define PDM_IOAPICHLPR0_VERSION PDM_VERSION_MAKE(0xfff0, 1, 0)
1621
1622/**
1623 * IOAPIC R3 helpers.
1624 */
1625typedef struct PDMIOAPICHLPR3
1626{
1627 /** Structure version. PDM_IOAPICHLPR3_VERSION defines the current version. */
1628 uint32_t u32Version;
1629
1630 /**
1631 * Private interface between the IOAPIC and APIC.
1632 *
1633 * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
1634 *
1635 * @returns status code
1636 * @param pDevIns Device instance of the IOAPIC.
1637 * @param u8Dest See APIC implementation.
1638 * @param u8DestMode See APIC implementation.
1639 * @param u8DeliveryMode See APIC implementation.
1640 * @param iVector See APIC implementation.
1641 * @param u8Polarity See APIC implementation.
1642 * @param u8TriggerMode See APIC implementation.
1643 */
1644 DECLR3CALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1645 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
1646
1647 /**
1648 * Acquires the PDM lock.
1649 *
1650 * @returns VINF_SUCCESS on success.
1651 * @returns Fatal error on failure.
1652 * @param pDevIns The IOAPIC device instance.
1653 * @param rc Dummy for making the interface identical to the GC and R0 versions.
1654 */
1655 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1656
1657 /**
1658 * Releases the PDM lock.
1659 *
1660 * @param pDevIns The IOAPIC device instance.
1661 */
1662 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1663
1664 /**
1665 * Gets the address of the RC IOAPIC helpers.
1666 *
1667 * This should be called at both construction and relocation time
1668 * to obtain the correct address of the RC helpers.
1669 *
1670 * @returns RC pointer to the IOAPIC helpers.
1671 * @param pDevIns Device instance of the IOAPIC.
1672 */
1673 DECLR3CALLBACKMEMBER(PCPDMIOAPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
1674
1675 /**
1676 * Gets the address of the R0 IOAPIC helpers.
1677 *
1678 * This should be called at both construction and relocation time
1679 * to obtain the correct address of the R0 helpers.
1680 *
1681 * @returns R0 pointer to the IOAPIC helpers.
1682 * @param pDevIns Device instance of the IOAPIC.
1683 */
1684 DECLR3CALLBACKMEMBER(PCPDMIOAPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
1685
1686 /** Just a safety precaution. */
1687 uint32_t u32TheEnd;
1688} PDMIOAPICHLPR3;
1689/** Pointer to IOAPIC R3 helpers. */
1690typedef R3PTRTYPE(PDMIOAPICHLPR3 *) PPDMIOAPICHLPR3;
1691/** Pointer to const IOAPIC helpers. */
1692typedef R3PTRTYPE(const PDMIOAPICHLPR3 *) PCPDMIOAPICHLPR3;
1693
1694/** Current PDMIOAPICHLPR3 version number. */
1695#define PDM_IOAPICHLPR3_VERSION PDM_VERSION_MAKE(0xffef, 1, 0)
1696
1697
1698/**
1699 * HPET registration structure.
1700 */
1701typedef struct PDMHPETREG
1702{
1703 /** Struct version+magic number (PDM_HPETREG_VERSION). */
1704 uint32_t u32Version;
1705
1706} PDMHPETREG;
1707/** Pointer to an HPET registration structure. */
1708typedef PDMHPETREG *PPDMHPETREG;
1709
1710/** Current PDMHPETREG version number. */
1711#define PDM_HPETREG_VERSION PDM_VERSION_MAKE(0xffe2, 1, 0)
1712
1713/**
1714 * HPET RC helpers.
1715 *
1716 * @remarks Keep this around in case HPET will need PDM interaction in again RC
1717 * at some later point.
1718 */
1719typedef struct PDMHPETHLPRC
1720{
1721 /** Structure version. PDM_HPETHLPRC_VERSION defines the current version. */
1722 uint32_t u32Version;
1723
1724 /** Just a safety precaution. */
1725 uint32_t u32TheEnd;
1726} PDMHPETHLPRC;
1727
1728/** Pointer to HPET RC helpers. */
1729typedef RCPTRTYPE(PDMHPETHLPRC *) PPDMHPETHLPRC;
1730/** Pointer to const HPET RC helpers. */
1731typedef RCPTRTYPE(const PDMHPETHLPRC *) PCPDMHPETHLPRC;
1732
1733/** Current PDMHPETHLPRC version number. */
1734#define PDM_HPETHLPRC_VERSION PDM_VERSION_MAKE(0xffee, 2, 0)
1735
1736
1737/**
1738 * HPET R0 helpers.
1739 *
1740 * @remarks Keep this around in case HPET will need PDM interaction in again R0
1741 * at some later point.
1742 */
1743typedef struct PDMHPETHLPR0
1744{
1745 /** Structure version. PDM_HPETHLPR0_VERSION defines the current version. */
1746 uint32_t u32Version;
1747
1748 /** Just a safety precaution. */
1749 uint32_t u32TheEnd;
1750} PDMHPETHLPR0;
1751
1752/** Pointer to HPET R0 helpers. */
1753typedef R0PTRTYPE(PDMHPETHLPR0 *) PPDMHPETHLPR0;
1754/** Pointer to const HPET R0 helpers. */
1755typedef R0PTRTYPE(const PDMHPETHLPR0 *) PCPDMHPETHLPR0;
1756
1757/** Current PDMHPETHLPR0 version number. */
1758#define PDM_HPETHLPR0_VERSION PDM_VERSION_MAKE(0xffed, 2, 0)
1759
1760/**
1761 * HPET R3 helpers.
1762 */
1763typedef struct PDMHPETHLPR3
1764{
1765 /** Structure version. PDM_HPETHLP_VERSION defines the current version. */
1766 uint32_t u32Version;
1767
1768 /**
1769 * Gets the address of the RC HPET helpers.
1770 *
1771 * This should be called at both construction and relocation time
1772 * to obtain the correct address of the RC helpers.
1773 *
1774 * @returns RC pointer to the HPET helpers.
1775 * @param pDevIns Device instance of the HPET.
1776 */
1777 DECLR3CALLBACKMEMBER(PCPDMHPETHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
1778
1779 /**
1780 * Gets the address of the R0 HPET helpers.
1781 *
1782 * This should be called at both construction and relocation time
1783 * to obtain the correct address of the R0 helpers.
1784 *
1785 * @returns R0 pointer to the HPET helpers.
1786 * @param pDevIns Device instance of the HPET.
1787 */
1788 DECLR3CALLBACKMEMBER(PCPDMHPETHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
1789
1790 /**
1791 * Set legacy mode on PIT and RTC.
1792 *
1793 * @returns VINF_SUCCESS on success.
1794 * @returns rc if we failed to set legacy mode.
1795 * @param pDevIns Device instance of the HPET.
1796 * @param fActivated Whether legacy mode is activated or deactivated.
1797 */
1798 DECLR3CALLBACKMEMBER(int, pfnSetLegacyMode,(PPDMDEVINS pDevIns, bool fActivated));
1799
1800
1801 /**
1802 * Set IRQ, bypassing ISA bus override rules.
1803 *
1804 * @returns VINF_SUCCESS on success.
1805 * @returns rc if we failed to set legacy mode.
1806 * @param pDevIns Device instance of the HPET.
1807 * @param fActivate Activate or deactivate legacy mode.
1808 */
1809 DECLR3CALLBACKMEMBER(int, pfnSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
1810
1811 /** Just a safety precaution. */
1812 uint32_t u32TheEnd;
1813} PDMHPETHLPR3;
1814
1815/** Pointer to HPET R3 helpers. */
1816typedef R3PTRTYPE(PDMHPETHLPR3 *) PPDMHPETHLPR3;
1817/** Pointer to const HPET R3 helpers. */
1818typedef R3PTRTYPE(const PDMHPETHLPR3 *) PCPDMHPETHLPR3;
1819
1820/** Current PDMHPETHLPR3 version number. */
1821#define PDM_HPETHLPR3_VERSION PDM_VERSION_MAKE(0xffec, 2, 0)
1822
1823
1824
1825#ifdef IN_RING3
1826
1827/**
1828 * DMA Transfer Handler.
1829 *
1830 * @returns Number of bytes transferred.
1831 * @param pDevIns Device instance of the DMA.
1832 * @param pvUser User pointer.
1833 * @param uChannel Channel number.
1834 * @param off DMA position.
1835 * @param cb Block size.
1836 */
1837typedef DECLCALLBACK(uint32_t) FNDMATRANSFERHANDLER(PPDMDEVINS pDevIns, void *pvUser, unsigned uChannel, uint32_t off, uint32_t cb);
1838/** Pointer to a FNDMATRANSFERHANDLER(). */
1839typedef FNDMATRANSFERHANDLER *PFNDMATRANSFERHANDLER;
1840
1841/**
1842 * DMA Controller registration structure.
1843 */
1844typedef struct PDMDMAREG
1845{
1846 /** Structure version number. PDM_DMACREG_VERSION defines the current version. */
1847 uint32_t u32Version;
1848
1849 /**
1850 * Execute pending transfers.
1851 *
1852 * @returns A more work indiciator. I.e. 'true' if there is more to be done, and 'false' if all is done.
1853 * @param pDevIns Device instance of the DMAC.
1854 */
1855 DECLR3CALLBACKMEMBER(bool, pfnRun,(PPDMDEVINS pDevIns));
1856
1857 /**
1858 * Register transfer function for DMA channel.
1859 *
1860 * @param pDevIns Device instance of the DMAC.
1861 * @param uChannel Channel number.
1862 * @param pfnTransferHandler Device specific transfer function.
1863 * @param pvUSer User pointer to be passed to the callback.
1864 */
1865 DECLR3CALLBACKMEMBER(void, pfnRegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
1866
1867 /**
1868 * Read memory
1869 *
1870 * @returns Number of bytes read.
1871 * @param pDevIns Device instance of the DMAC.
1872 * @param pvBuffer Pointer to target buffer.
1873 * @param off DMA position.
1874 * @param cbBlock Block size.
1875 */
1876 DECLR3CALLBACKMEMBER(uint32_t, pfnReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock));
1877
1878 /**
1879 * Write memory
1880 *
1881 * @returns Number of bytes written.
1882 * @param pDevIns Device instance of the DMAC.
1883 * @param pvBuffer Memory to write.
1884 * @param off DMA position.
1885 * @param cbBlock Block size.
1886 */
1887 DECLR3CALLBACKMEMBER(uint32_t, pfnWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock));
1888
1889 /**
1890 * Set the DREQ line.
1891 *
1892 * @param pDevIns Device instance of the DMAC.
1893 * @param uChannel Channel number.
1894 * @param uLevel Level of the line.
1895 */
1896 DECLR3CALLBACKMEMBER(void, pfnSetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
1897
1898 /**
1899 * Get channel mode
1900 *
1901 * @returns Channel mode.
1902 * @param pDevIns Device instance of the DMAC.
1903 * @param uChannel Channel number.
1904 */
1905 DECLR3CALLBACKMEMBER(uint8_t, pfnGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
1906
1907} PDMDMACREG;
1908/** Pointer to a DMAC registration structure. */
1909typedef PDMDMACREG *PPDMDMACREG;
1910
1911/** Current PDMDMACREG version number. */
1912#define PDM_DMACREG_VERSION PDM_VERSION_MAKE(0xffeb, 1, 0)
1913
1914
1915/**
1916 * DMA Controller device helpers.
1917 */
1918typedef struct PDMDMACHLP
1919{
1920 /** Structure version. PDM_DMACHLP_VERSION defines the current version. */
1921 uint32_t u32Version;
1922
1923 /* to-be-defined */
1924
1925} PDMDMACHLP;
1926/** Pointer to DMAC helpers. */
1927typedef PDMDMACHLP *PPDMDMACHLP;
1928/** Pointer to const DMAC helpers. */
1929typedef const PDMDMACHLP *PCPDMDMACHLP;
1930
1931/** Current PDMDMACHLP version number. */
1932#define PDM_DMACHLP_VERSION PDM_VERSION_MAKE(0xffea, 1, 0)
1933
1934#endif /* IN_RING3 */
1935
1936
1937
1938/**
1939 * RTC registration structure.
1940 */
1941typedef struct PDMRTCREG
1942{
1943 /** Structure version number. PDM_RTCREG_VERSION defines the current version. */
1944 uint32_t u32Version;
1945 uint32_t u32Alignment; /**< structure size alignment. */
1946
1947 /**
1948 * Write to a CMOS register and update the checksum if necessary.
1949 *
1950 * @returns VBox status code.
1951 * @param pDevIns Device instance of the RTC.
1952 * @param iReg The CMOS register index.
1953 * @param u8Value The CMOS register value.
1954 */
1955 DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
1956
1957 /**
1958 * Read a CMOS register.
1959 *
1960 * @returns VBox status code.
1961 * @param pDevIns Device instance of the RTC.
1962 * @param iReg The CMOS register index.
1963 * @param pu8Value Where to store the CMOS register value.
1964 */
1965 DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
1966
1967} PDMRTCREG;
1968/** Pointer to a RTC registration structure. */
1969typedef PDMRTCREG *PPDMRTCREG;
1970/** Pointer to a const RTC registration structure. */
1971typedef const PDMRTCREG *PCPDMRTCREG;
1972
1973/** Current PDMRTCREG version number. */
1974#define PDM_RTCREG_VERSION PDM_VERSION_MAKE(0xffe9, 1, 0)
1975
1976
1977/**
1978 * RTC device helpers.
1979 */
1980typedef struct PDMRTCHLP
1981{
1982 /** Structure version. PDM_RTCHLP_VERSION defines the current version. */
1983 uint32_t u32Version;
1984
1985 /* to-be-defined */
1986
1987} PDMRTCHLP;
1988/** Pointer to RTC helpers. */
1989typedef PDMRTCHLP *PPDMRTCHLP;
1990/** Pointer to const RTC helpers. */
1991typedef const PDMRTCHLP *PCPDMRTCHLP;
1992
1993/** Current PDMRTCHLP version number. */
1994#define PDM_RTCHLP_VERSION PDM_VERSION_MAKE(0xffe8, 1, 0)
1995
1996
1997
1998#ifdef IN_RING3
1999
2000/**
2001 * PDM Device API.
2002 */
2003typedef struct PDMDEVHLPR3
2004{
2005 /** Structure version. PDM_DEVHLP_VERSION defines the current version. */
2006 uint32_t u32Version;
2007
2008 /**
2009 * Register a number of I/O ports with a device.
2010 *
2011 * These callbacks are of course for the host context (HC).
2012 * Register HC handlers before guest context (GC) handlers! There must be a
2013 * HC handler for every GC handler!
2014 *
2015 * @returns VBox status.
2016 * @param pDevIns The device instance to register the ports with.
2017 * @param Port First port number in the range.
2018 * @param cPorts Number of ports to register.
2019 * @param pvUser User argument.
2020 * @param pfnOut Pointer to function which is gonna handle OUT operations.
2021 * @param pfnIn Pointer to function which is gonna handle IN operations.
2022 * @param pfnOutStr Pointer to function which is gonna handle string OUT operations.
2023 * @param pfnInStr Pointer to function which is gonna handle string IN operations.
2024 * @param pszDesc Pointer to description string. This must not be freed.
2025 */
2026 DECLR3CALLBACKMEMBER(int, pfnIOPortRegister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser,
2027 PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
2028 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc));
2029
2030 /**
2031 * Register a number of I/O ports with a device for RC.
2032 *
2033 * These callbacks are for the raw-mode context (RC). Register ring-3 context
2034 * (R3) handlers before raw-mode context handlers! There must be a R3 handler
2035 * for every RC handler!
2036 *
2037 * @returns VBox status.
2038 * @param pDevIns The device instance to register the ports with
2039 * and which RC module to resolve the names
2040 * against.
2041 * @param Port First port number in the range.
2042 * @param cPorts Number of ports to register.
2043 * @param pvUser User argument.
2044 * @param pszOut Name of the RC function which is gonna handle OUT operations.
2045 * @param pszIn Name of the RC function which is gonna handle IN operations.
2046 * @param pszOutStr Name of the RC function which is gonna handle string OUT operations.
2047 * @param pszInStr Name of the RC function which is gonna handle string IN operations.
2048 * @param pszDesc Pointer to description string. This must not be freed.
2049 */
2050 DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterRC,(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser,
2051 const char *pszOut, const char *pszIn,
2052 const char *pszOutStr, const char *pszInStr, const char *pszDesc));
2053
2054 /**
2055 * Register a number of I/O ports with a device.
2056 *
2057 * These callbacks are of course for the ring-0 host context (R0).
2058 * Register R3 (HC) handlers before R0 (R0) handlers! There must be a R3 (HC) handler for every R0 handler!
2059 *
2060 * @returns VBox status.
2061 * @param pDevIns The device instance to register the ports with.
2062 * @param Port First port number in the range.
2063 * @param cPorts Number of ports to register.
2064 * @param pvUser User argument. (if pointer, then it must be in locked memory!)
2065 * @param pszOut Name of the R0 function which is gonna handle OUT operations.
2066 * @param pszIn Name of the R0 function which is gonna handle IN operations.
2067 * @param pszOutStr Name of the R0 function which is gonna handle string OUT operations.
2068 * @param pszInStr Name of the R0 function which is gonna handle string IN operations.
2069 * @param pszDesc Pointer to description string. This must not be freed.
2070 */
2071 DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterR0,(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser,
2072 const char *pszOut, const char *pszIn,
2073 const char *pszOutStr, const char *pszInStr, const char *pszDesc));
2074
2075 /**
2076 * Deregister I/O ports.
2077 *
2078 * This naturally affects both guest context (GC), ring-0 (R0) and ring-3 (R3/HC) handlers.
2079 *
2080 * @returns VBox status.
2081 * @param pDevIns The device instance owning the ports.
2082 * @param Port First port number in the range.
2083 * @param cPorts Number of ports to deregister.
2084 */
2085 DECLR3CALLBACKMEMBER(int, pfnIOPortDeregister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts));
2086
2087 /**
2088 * Register a Memory Mapped I/O (MMIO) region.
2089 *
2090 * These callbacks are of course for the ring-3 context (R3). Register HC
2091 * handlers before raw-mode context (RC) and ring-0 context (R0) handlers! There
2092 * must be a R3 handler for every RC and R0 handler!
2093 *
2094 * @returns VBox status.
2095 * @param pDevIns The device instance to register the MMIO with.
2096 * @param GCPhysStart First physical address in the range.
2097 * @param cbRange The size of the range (in bytes).
2098 * @param pvUser User argument.
2099 * @param pfnWrite Pointer to function which is gonna handle Write operations.
2100 * @param pfnRead Pointer to function which is gonna handle Read operations.
2101 * @param pfnFill Pointer to function which is gonna handle Fill/memset operations. (optional)
2102 * @param pszDesc Pointer to description string. This must not be freed.
2103 */
2104 DECLR3CALLBACKMEMBER(int, pfnMMIORegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,
2105 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
2106 const char *pszDesc));
2107
2108 /**
2109 * Register a Memory Mapped I/O (MMIO) region for GC.
2110 *
2111 * These callbacks are for the raw-mode context (RC). Register ring-3 context
2112 * (R3) handlers before guest context handlers! There must be a R3 handler for
2113 * every RC handler!
2114 *
2115 * @returns VBox status.
2116 * @param pDevIns The device instance to register the MMIO with.
2117 * @param GCPhysStart First physical address in the range.
2118 * @param cbRange The size of the range (in bytes).
2119 * @param pvUser User argument.
2120 * @param pszWrite Name of the RC function which is gonna handle Write operations.
2121 * @param pszRead Name of the RC function which is gonna handle Read operations.
2122 * @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional)
2123 * @param pszDesc Obsolete. NULL is fine.
2124 * @todo Remove pszDesc in the next major revision of PDMDEVHLPR3.
2125 */
2126 DECLR3CALLBACKMEMBER(int, pfnMMIORegisterRC,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,
2127 const char *pszWrite, const char *pszRead, const char *pszFill,
2128 const char *pszDesc));
2129
2130 /**
2131 * Register a Memory Mapped I/O (MMIO) region for R0.
2132 *
2133 * These callbacks are for the ring-0 host context (R0). Register ring-3
2134 * constext (R3) handlers before R0 handlers! There must be a R3 handler for
2135 * every R0 handler!
2136 *
2137 * @returns VBox status.
2138 * @param pDevIns The device instance to register the MMIO with.
2139 * @param GCPhysStart First physical address in the range.
2140 * @param cbRange The size of the range (in bytes).
2141 * @param pvUser User argument. (if pointer, then it must be in locked memory!)
2142 * @param pszWrite Name of the RC function which is gonna handle Write operations.
2143 * @param pszRead Name of the RC function which is gonna handle Read operations.
2144 * @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional)
2145 * @param pszDesc Obsolete. NULL is fine.
2146 * @todo Remove pszDesc in the next major revision of PDMDEVHLPR3.
2147 */
2148 DECLR3CALLBACKMEMBER(int, pfnMMIORegisterR0,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,
2149 const char *pszWrite, const char *pszRead, const char *pszFill,
2150 const char *pszDesc));
2151
2152 /**
2153 * Deregister a Memory Mapped I/O (MMIO) region.
2154 *
2155 * This naturally affects both guest context (GC), ring-0 (R0) and ring-3 (R3/HC) handlers.
2156 *
2157 * @returns VBox status.
2158 * @param pDevIns The device instance owning the MMIO region(s).
2159 * @param GCPhysStart First physical address in the range.
2160 * @param cbRange The size of the range (in bytes).
2161 */
2162 DECLR3CALLBACKMEMBER(int, pfnMMIODeregister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange));
2163
2164 /**
2165 * Allocate and register a MMIO2 region.
2166 *
2167 * As mentioned elsewhere, MMIO2 is just RAM spelled differently. It's
2168 * RAM associated with a device. It is also non-shared memory with a
2169 * permanent ring-3 mapping and page backing (presently).
2170 *
2171 * @returns VBox status.
2172 * @param pDevIns The device instance.
2173 * @param iRegion The region number. Use the PCI region number as
2174 * this must be known to the PCI bus device too. If
2175 * it's not associated with the PCI device, then
2176 * any number up to UINT8_MAX is fine.
2177 * @param cb The size (in bytes) of the region.
2178 * @param fFlags Reserved for future use, must be zero.
2179 * @param ppv Where to store the address of the ring-3 mapping
2180 * of the memory.
2181 * @param pszDesc Pointer to description string. This must not be
2182 * freed.
2183 * @thread EMT.
2184 */
2185 DECLR3CALLBACKMEMBER(int, pfnMMIO2Register,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc));
2186
2187 /**
2188 * Deregisters and frees a MMIO2 region.
2189 *
2190 * Any physical (and virtual) access handlers registered for the region must
2191 * be deregistered before calling this function.
2192 *
2193 * @returns VBox status code.
2194 * @param pDevIns The device instance.
2195 * @param iRegion The region number used during registration.
2196 * @thread EMT.
2197 */
2198 DECLR3CALLBACKMEMBER(int, pfnMMIO2Deregister,(PPDMDEVINS pDevIns, uint32_t iRegion));
2199
2200 /**
2201 * Maps a MMIO2 region into the physical memory space.
2202 *
2203 * A MMIO2 range may overlap with base memory if a lot of RAM
2204 * is configured for the VM, in which case we'll drop the base
2205 * memory pages. Presently we will make no attempt to preserve
2206 * anything that happens to be present in the base memory that
2207 * is replaced, this is of course incorrectly but it's too much
2208 * effort.
2209 *
2210 * @returns VBox status code.
2211 * @param pDevIns The device instance.
2212 * @param iRegion The region number used during registration.
2213 * @param GCPhys The physical address to map it at.
2214 * @thread EMT.
2215 */
2216 DECLR3CALLBACKMEMBER(int, pfnMMIO2Map,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys));
2217
2218 /**
2219 * Unmaps a MMIO2 region previously mapped using pfnMMIO2Map.
2220 *
2221 * @returns VBox status code.
2222 * @param pDevIns The device instance.
2223 * @param iRegion The region number used during registration.
2224 * @param GCPhys The physical address it's currently mapped at.
2225 * @thread EMT.
2226 */
2227 DECLR3CALLBACKMEMBER(int, pfnMMIO2Unmap,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys));
2228
2229 /**
2230 * Maps a portion of an MMIO2 region into the hypervisor region.
2231 *
2232 * Callers of this API must never deregister the MMIO2 region before the
2233 * VM is powered off.
2234 *
2235 * @return VBox status code.
2236 * @param pDevIns The device owning the MMIO2 memory.
2237 * @param iRegion The region.
2238 * @param off The offset into the region. Will be rounded down
2239 * to closest page boundary.
2240 * @param cb The number of bytes to map. Will be rounded up
2241 * to the closest page boundary.
2242 * @param pszDesc Mapping description.
2243 * @param pRCPtr Where to store the RC address.
2244 */
2245 DECLR3CALLBACKMEMBER(int, pfnMMHyperMapMMIO2,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
2246 const char *pszDesc, PRTRCPTR pRCPtr));
2247
2248 /**
2249 * Maps a portion of an MMIO2 region into kernel space (host).
2250 *
2251 * The kernel mapping will become invalid when the MMIO2 memory is deregistered
2252 * or the VM is terminated.
2253 *
2254 * @return VBox status code.
2255 * @param pDevIns The device owning the MMIO2 memory.
2256 * @param iRegion The region.
2257 * @param off The offset into the region. Must be page
2258 * aligned.
2259 * @param cb The number of bytes to map. Must be page
2260 * aligned.
2261 * @param pszDesc Mapping description.
2262 * @param pR0Ptr Where to store the R0 address.
2263 */
2264 DECLR3CALLBACKMEMBER(int, pfnMMIO2MapKernel,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
2265 const char *pszDesc, PRTR0PTR pR0Ptr));
2266
2267 /**
2268 * Register a ROM (BIOS) region.
2269 *
2270 * It goes without saying that this is read-only memory. The memory region must be
2271 * in unassigned memory. I.e. from the top of the address space or on the PC in
2272 * the 0xa0000-0xfffff range.
2273 *
2274 * @returns VBox status.
2275 * @param pDevIns The device instance owning the ROM region.
2276 * @param GCPhysStart First physical address in the range.
2277 * Must be page aligned!
2278 * @param cbRange The size of the range (in bytes).
2279 * Must be page aligned!
2280 * @param pvBinary Pointer to the binary data backing the ROM image.
2281 * This must be cbRange bytes big.
2282 * It will be copied and doesn't have to stick around if fShadow is clear.
2283 * @param fFlags Shadow ROM flags, PGMPHYS_ROM_FLAGS_* in pgm.h.
2284 * @param pszDesc Pointer to description string. This must not be freed.
2285 *
2286 * @remark There is no way to remove the rom, automatically on device cleanup or
2287 * manually from the device yet. At present I doubt we need such features...
2288 */
2289 DECLR3CALLBACKMEMBER(int, pfnROMRegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, uint32_t fFlags, const char *pszDesc));
2290
2291 /**
2292 * Changes the protection of shadowed ROM mapping.
2293 *
2294 * This is intented for use by the system BIOS, chipset or device in question to
2295 * change the protection of shadowed ROM code after init and on reset.
2296 *
2297 * @param pDevIns The device instance.
2298 * @param GCPhysStart Where the mapping starts.
2299 * @param cbRange The size of the mapping.
2300 * @param enmProt The new protection type.
2301 */
2302 DECLR3CALLBACKMEMBER(int, pfnROMProtectShadow,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, PGMROMPROT enmProt));
2303
2304 /**
2305 * Register a save state data unit.
2306 *
2307 * @returns VBox status.
2308 * @param pDevIns The device instance.
2309 * @param pszName Data unit name.
2310 * @param uInstance The instance identifier of the data unit.
2311 * This must together with the name be unique.
2312 * @param uVersion Data layout version number.
2313 * @param cbGuess The approximate amount of data in the unit.
2314 * Only for progress indicators.
2315 * @param pszBefore Name of data unit which we should be put in
2316 * front of. Optional (NULL).
2317 *
2318 * @param pfnLivePrep Prepare live save callback, optional.
2319 * @param pfnLiveExec Execute live save callback, optional.
2320 * @param pfnLiveVote Vote live save callback, optional.
2321 *
2322 * @param pfnSavePrep Prepare save callback, optional.
2323 * @param pfnSaveExec Execute save callback, optional.
2324 * @param pfnSaveDone Done save callback, optional.
2325 *
2326 * @param pfnLoadPrep Prepare load callback, optional.
2327 * @param pfnLoadExec Execute load callback, optional.
2328 * @param pfnLoadDone Done load callback, optional.
2329 */
2330 DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
2331 PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
2332 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
2333 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone));
2334
2335 /**
2336 * Creates a timer.
2337 *
2338 * @returns VBox status.
2339 * @param pDevIns The device instance.
2340 * @param enmClock The clock to use on this timer.
2341 * @param pfnCallback Callback function.
2342 * @param pvUser User argument for the callback.
2343 * @param fFlags Flags, see TMTIMER_FLAGS_*.
2344 * @param pszDesc Pointer to description string which must stay around
2345 * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
2346 * @param ppTimer Where to store the timer on success.
2347 */
2348 DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
2349
2350 /**
2351 * Get the real world UTC time adjusted for VM lag, user offset and warpdrive.
2352 *
2353 * @returns pTime.
2354 * @param pDevIns The device instance.
2355 * @param pTime Where to store the time.
2356 */
2357 DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnTMUtcNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime));
2358
2359 /**
2360 * Read physical memory.
2361 *
2362 * @returns VINF_SUCCESS (for now).
2363 * @param pDevIns The device instance.
2364 * @param GCPhys Physical address start reading from.
2365 * @param pvBuf Where to put the read bits.
2366 * @param cbRead How many bytes to read.
2367 * @thread Any thread, but the call may involve the emulation thread.
2368 */
2369 DECLR3CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
2370
2371 /**
2372 * Write to physical memory.
2373 *
2374 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
2375 * @param pDevIns The device instance.
2376 * @param GCPhys Physical address to write to.
2377 * @param pvBuf What to write.
2378 * @param cbWrite How many bytes to write.
2379 * @thread Any thread, but the call may involve the emulation thread.
2380 */
2381 DECLR3CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
2382
2383 /**
2384 * Requests the mapping of a guest page into ring-3.
2385 *
2386 * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
2387 * release it.
2388 *
2389 * This API will assume your intention is to write to the page, and will
2390 * therefore replace shared and zero pages. If you do not intend to modify the
2391 * page, use the pfnPhysGCPhys2CCPtrReadOnly() API.
2392 *
2393 * @returns VBox status code.
2394 * @retval VINF_SUCCESS on success.
2395 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
2396 * backing or if the page has any active access handlers. The caller
2397 * must fall back on using PGMR3PhysWriteExternal.
2398 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
2399 *
2400 * @param pVM The VM handle.
2401 * @param GCPhys The guest physical address of the page that
2402 * should be mapped.
2403 * @param fFlags Flags reserved for future use, MBZ.
2404 * @param ppv Where to store the address corresponding to
2405 * GCPhys.
2406 * @param pLock Where to store the lock information that
2407 * pfnPhysReleasePageMappingLock needs.
2408 *
2409 * @remark Avoid calling this API from within critical sections (other than the
2410 * PGM one) because of the deadlock risk when we have to delegating the
2411 * task to an EMT.
2412 * @thread Any.
2413 */
2414 DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtr,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock));
2415
2416 /**
2417 * Requests the mapping of a guest page into ring-3, external threads.
2418 *
2419 * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
2420 * release it.
2421 *
2422 * @returns VBox status code.
2423 * @retval VINF_SUCCESS on success.
2424 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
2425 * backing or if the page as an active ALL access handler. The caller
2426 * must fall back on using PGMPhysRead.
2427 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
2428 *
2429 * @param pDevIns The device instance.
2430 * @param GCPhys The guest physical address of the page that
2431 * should be mapped.
2432 * @param fFlags Flags reserved for future use, MBZ.
2433 * @param ppv Where to store the address corresponding to
2434 * GCPhys.
2435 * @param pLock Where to store the lock information that
2436 * pfnPhysReleasePageMappingLock needs.
2437 *
2438 * @remark Avoid calling this API from within critical sections.
2439 * @thread Any.
2440 */
2441 DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock));
2442
2443 /**
2444 * Release the mapping of a guest page.
2445 *
2446 * This is the counter part of pfnPhysGCPhys2CCPtr and
2447 * pfnPhysGCPhys2CCPtrReadOnly.
2448 *
2449 * @param pDevIns The device instance.
2450 * @param pLock The lock structure initialized by the mapping
2451 * function.
2452 */
2453 DECLR3CALLBACKMEMBER(void, pfnPhysReleasePageMappingLock,(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock));
2454
2455 /**
2456 * Read guest physical memory by virtual address.
2457 *
2458 * @param pDevIns The device instance.
2459 * @param pvDst Where to put the read bits.
2460 * @param GCVirtSrc Guest virtual address to start reading from.
2461 * @param cb How many bytes to read.
2462 * @thread The emulation thread.
2463 */
2464 DECLR3CALLBACKMEMBER(int, pfnPhysReadGCVirt,(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb));
2465
2466 /**
2467 * Write to guest physical memory by virtual address.
2468 *
2469 * @param pDevIns The device instance.
2470 * @param GCVirtDst Guest virtual address to write to.
2471 * @param pvSrc What to write.
2472 * @param cb How many bytes to write.
2473 * @thread The emulation thread.
2474 */
2475 DECLR3CALLBACKMEMBER(int, pfnPhysWriteGCVirt,(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb));
2476
2477 /**
2478 * Convert a guest virtual address to a guest physical address.
2479 *
2480 * @returns VBox status code.
2481 * @param pDevIns The device instance.
2482 * @param GCPtr Guest virtual address.
2483 * @param pGCPhys Where to store the GC physical address
2484 * corresponding to GCPtr.
2485 * @thread The emulation thread.
2486 * @remark Careful with page boundaries.
2487 */
2488 DECLR3CALLBACKMEMBER(int, pfnPhysGCPtr2GCPhys, (PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys));
2489
2490 /**
2491 * Allocate memory which is associated with current VM instance
2492 * and automatically freed on it's destruction.
2493 *
2494 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
2495 * @param pDevIns The device instance.
2496 * @param cb Number of bytes to allocate.
2497 */
2498 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAlloc,(PPDMDEVINS pDevIns, size_t cb));
2499
2500 /**
2501 * Allocate memory which is associated with current VM instance
2502 * and automatically freed on it's destruction. The memory is ZEROed.
2503 *
2504 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
2505 * @param pDevIns The device instance.
2506 * @param cb Number of bytes to allocate.
2507 */
2508 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAllocZ,(PPDMDEVINS pDevIns, size_t cb));
2509
2510 /**
2511 * Free memory allocated with pfnMMHeapAlloc() and pfnMMHeapAllocZ().
2512 *
2513 * @param pDevIns The device instance.
2514 * @param pv Pointer to the memory to free.
2515 */
2516 DECLR3CALLBACKMEMBER(void, pfnMMHeapFree,(PPDMDEVINS pDevIns, void *pv));
2517
2518 /**
2519 * Gets the VM state.
2520 *
2521 * @returns VM state.
2522 * @param pDevIns The device instance.
2523 * @thread Any thread (just keep in mind that it's volatile info).
2524 */
2525 DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
2526
2527 /**
2528 * Checks if the VM was teleported and hasn't been fully resumed yet.
2529 *
2530 * @returns true / false.
2531 * @param pDevIns The device instance.
2532 * @thread Any thread.
2533 */
2534 DECLR3CALLBACKMEMBER(bool, pfnVMTeleportedAndNotFullyResumedYet,(PPDMDEVINS pDevIns));
2535
2536 /**
2537 * Set the VM error message
2538 *
2539 * @returns rc.
2540 * @param pDevIns The device instance.
2541 * @param rc VBox status code.
2542 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2543 * @param pszFormat Error message format string.
2544 * @param ... Error message arguments.
2545 */
2546 DECLR3CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
2547
2548 /**
2549 * Set the VM error message
2550 *
2551 * @returns rc.
2552 * @param pDevIns The device instance.
2553 * @param rc VBox status code.
2554 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2555 * @param pszFormat Error message format string.
2556 * @param va Error message arguments.
2557 */
2558 DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
2559
2560 /**
2561 * Set the VM runtime error message
2562 *
2563 * @returns VBox status code.
2564 * @param pDevIns The device instance.
2565 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
2566 * @param pszErrorId Error ID string.
2567 * @param pszFormat Error message format string.
2568 * @param ... Error message arguments.
2569 */
2570 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
2571
2572 /**
2573 * Set the VM runtime error message
2574 *
2575 * @returns VBox status code.
2576 * @param pDevIns The device instance.
2577 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
2578 * @param pszErrorId Error ID string.
2579 * @param pszFormat Error message format string.
2580 * @param va Error message arguments.
2581 */
2582 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
2583
2584 /**
2585 * Stops the VM and enters the debugger to look at the guest state.
2586 *
2587 * Use the PDMDeviceDBGFStop() inline function with the RT_SRC_POS macro instead of
2588 * invoking this function directly.
2589 *
2590 * @returns VBox status code which must be passed up to the VMM.
2591 * @param pDevIns The device instance.
2592 * @param pszFile Filename of the assertion location.
2593 * @param iLine The linenumber of the assertion location.
2594 * @param pszFunction Function of the assertion location.
2595 * @param pszFormat Message. (optional)
2596 * @param args Message parameters.
2597 */
2598 DECLR3CALLBACKMEMBER(int, pfnDBGFStopV,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args));
2599
2600 /**
2601 * Register a info handler with DBGF,
2602 *
2603 * @returns VBox status code.
2604 * @param pDevIns The device instance.
2605 * @param pszName The identifier of the info.
2606 * @param pszDesc The description of the info and any arguments
2607 * the handler may take.
2608 * @param pfnHandler The handler function to be called to display the
2609 * info.
2610 */
2611 DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler));
2612
2613 /**
2614 * Registers a statistics sample if statistics are enabled.
2615 *
2616 * @param pDevIns Device instance of the DMA.
2617 * @param pvSample Pointer to the sample.
2618 * @param enmType Sample type. This indicates what pvSample is
2619 * pointing at.
2620 * @param pszName Sample name. The name is on this form
2621 * "/<component>/<sample>". Further nesting is
2622 * possible.
2623 * @param enmUnit Sample unit.
2624 * @param pszDesc Sample description.
2625 */
2626 DECLR3CALLBACKMEMBER(void, pfnSTAMRegister,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc));
2627
2628 /**
2629 * Same as pfnSTAMRegister except that the name is specified in a
2630 * RTStrPrintf like fashion.
2631 *
2632 * @returns VBox status.
2633 * @param pDevIns Device instance of the DMA.
2634 * @param pvSample Pointer to the sample.
2635 * @param enmType Sample type. This indicates what pvSample is
2636 * pointing at.
2637 * @param enmVisibility Visibility type specifying whether unused
2638 * statistics should be visible or not.
2639 * @param enmUnit Sample unit.
2640 * @param pszDesc Sample description.
2641 * @param pszName The sample name format string.
2642 * @param ... Arguments to the format string.
2643 */
2644 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterF,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
2645 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...));
2646
2647 /**
2648 * Same as pfnSTAMRegister except that the name is specified in a
2649 * RTStrPrintfV like fashion.
2650 *
2651 * @returns VBox status.
2652 * @param pDevIns Device instance of the DMA.
2653 * @param pvSample Pointer to the sample.
2654 * @param enmType Sample type. This indicates what pvSample is
2655 * pointing at.
2656 * @param enmVisibility Visibility type specifying whether unused
2657 * statistics should be visible or not.
2658 * @param enmUnit Sample unit.
2659 * @param pszDesc Sample description.
2660 * @param pszName The sample name format string.
2661 * @param args Arguments to the format string.
2662 */
2663 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
2664 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args));
2665
2666 /**
2667 * Registers the device with the default PCI bus.
2668 *
2669 * @returns VBox status code.
2670 * @param pDevIns The device instance.
2671 * @param pPciDev The PCI device structure.
2672 * Any PCI enabled device must keep this in it's instance data!
2673 * Fill in the PCI data config before registration, please.
2674 * @remark This is the simple interface, a Ex interface will be created if
2675 * more features are needed later.
2676 */
2677 DECLR3CALLBACKMEMBER(int, pfnPCIRegister,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev));
2678
2679 /**
2680 * Initialize MSI support in a PCI device.
2681 *
2682 * @returns VBox status code.
2683 * @param pDevIns The device instance.
2684 * @param pMsiReg MSI registartion structure.
2685 */
2686 DECLR3CALLBACKMEMBER(int, pfnPCIRegisterMsi,(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg));
2687
2688 /**
2689 * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
2690 *
2691 * @returns VBox status code.
2692 * @param pDevIns The device instance.
2693 * @param iRegion The region number.
2694 * @param cbRegion Size of the region.
2695 * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
2696 * @param pfnCallback Callback for doing the mapping.
2697 */
2698 DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
2699
2700 /**
2701 * Register PCI configuration space read/write callbacks.
2702 *
2703 * @param pDevIns The device instance.
2704 * @param pPciDev The PCI device structure.
2705 * If NULL the default PCI device for this device instance is used.
2706 * @param pfnRead Pointer to the user defined PCI config read function.
2707 * @param ppfnReadOld Pointer to function pointer which will receive the old (default)
2708 * PCI config read function. This way, user can decide when (and if)
2709 * to call default PCI config read function. Can be NULL.
2710 * @param pfnWrite Pointer to the user defined PCI config write function.
2711 * @param pfnWriteOld Pointer to function pointer which will receive the old (default)
2712 * PCI config write function. This way, user can decide when (and if)
2713 * to call default PCI config write function. Can be NULL.
2714 * @thread EMT
2715 */
2716 DECLR3CALLBACKMEMBER(void, pfnPCISetConfigCallbacks,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
2717 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
2718
2719 /**
2720 * Set the IRQ for a PCI device.
2721 *
2722 * @param pDevIns The device instance.
2723 * @param iIrq IRQ number to set.
2724 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2725 * @thread Any thread, but will involve the emulation thread.
2726 */
2727 DECLR3CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2728
2729 /**
2730 * Set the IRQ for a PCI device, but don't wait for EMT to process
2731 * the request when not called from EMT.
2732 *
2733 * @param pDevIns The device instance.
2734 * @param iIrq IRQ number to set.
2735 * @param iLevel IRQ level.
2736 * @thread Any thread, but will involve the emulation thread.
2737 */
2738 DECLR3CALLBACKMEMBER(void, pfnPCISetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2739
2740 /**
2741 * Set ISA IRQ for a device.
2742 *
2743 * @param pDevIns The device instance.
2744 * @param iIrq IRQ number to set.
2745 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2746 * @thread Any thread, but will involve the emulation thread.
2747 */
2748 DECLR3CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2749
2750 /**
2751 * Set the ISA IRQ for a device, but don't wait for EMT to process
2752 * the request when not called from EMT.
2753 *
2754 * @param pDevIns The device instance.
2755 * @param iIrq IRQ number to set.
2756 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2757 * @thread Any thread, but will involve the emulation thread.
2758 */
2759 DECLR3CALLBACKMEMBER(void, pfnISASetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2760
2761 /**
2762 * Attaches a driver (chain) to the device.
2763 *
2764 * The first call for a LUN this will serve as a registartion of the LUN. The pBaseInterface and
2765 * the pszDesc string will be registered with that LUN and kept around for PDMR3QueryDeviceLun().
2766 *
2767 * @returns VBox status code.
2768 * @param pDevIns The device instance.
2769 * @param iLun The logical unit to attach.
2770 * @param pBaseInterface Pointer to the base interface for that LUN. (device side / down)
2771 * @param ppBaseInterface Where to store the pointer to the base interface. (driver side / up)
2772 * @param pszDesc Pointer to a string describing the LUN. This string must remain valid
2773 * for the live of the device instance.
2774 */
2775 DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc));
2776
2777 /**
2778 * Create a queue.
2779 *
2780 * @returns VBox status code.
2781 * @param pDevIns The device instance.
2782 * @param cbItem The size of a queue item.
2783 * @param cItems The number of items in the queue.
2784 * @param cMilliesInterval The number of milliseconds between polling the queue.
2785 * If 0 then the emulation thread will be notified whenever an item arrives.
2786 * @param pfnCallback The consumer function.
2787 * @param fRZEnabled Set if the queue should work in RC and R0.
2788 * @param pszName The queue base name. The instance number will be
2789 * appended automatically.
2790 * @param ppQueue Where to store the queue handle on success.
2791 * @thread The emulation thread.
2792 */
2793 DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
2794 PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue));
2795
2796 /**
2797 * Initializes a PDM critical section.
2798 *
2799 * The PDM critical sections are derived from the IPRT critical sections, but
2800 * works in RC and R0 as well.
2801 *
2802 * @returns VBox status code.
2803 * @param pDevIns The device instance.
2804 * @param pCritSect Pointer to the critical section.
2805 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2806 * @param pszNameFmt Format string for naming the critical section.
2807 * For statistics and lock validation.
2808 * @param va Arguments for the format string.
2809 */
2810 DECLR3CALLBACKMEMBER(int, pfnCritSectInit,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
2811 const char *pszNameFmt, va_list va));
2812
2813 /**
2814 * Creates a PDM thread.
2815 *
2816 * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
2817 * resuming, and destroying the thread as the VM state changes.
2818 *
2819 * @returns VBox status code.
2820 * @param pDevIns The device instance.
2821 * @param ppThread Where to store the thread 'handle'.
2822 * @param pvUser The user argument to the thread function.
2823 * @param pfnThread The thread function.
2824 * @param pfnWakeup The wakup callback. This is called on the EMT
2825 * thread when a state change is pending.
2826 * @param cbStack See RTThreadCreate.
2827 * @param enmType See RTThreadCreate.
2828 * @param pszName See RTThreadCreate.
2829 */
2830 DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
2831 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
2832
2833 /**
2834 * Set up asynchronous handling of a suspend, reset or power off notification.
2835 *
2836 * This shall only be called when getting the notification. It must be called
2837 * for each one.
2838 *
2839 * @returns VBox status code.
2840 * @param pDevIns The device instance.
2841 * @param pfnAsyncNotify The callback.
2842 * @thread EMT(0)
2843 */
2844 DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify));
2845
2846 /**
2847 * Notify EMT(0) that the device has completed the asynchronous notification
2848 * handling.
2849 *
2850 * This can be called at any time, spurious calls will simply be ignored.
2851 *
2852 * @param pDevIns The device instance.
2853 * @thread Any
2854 */
2855 DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMDEVINS pDevIns));
2856
2857 /**
2858 * Register the RTC device.
2859 *
2860 * @returns VBox status code.
2861 * @param pDevIns The device instance.
2862 * @param pRtcReg Pointer to a RTC registration structure.
2863 * @param ppRtcHlp Where to store the pointer to the helper
2864 * functions.
2865 */
2866 DECLR3CALLBACKMEMBER(int, pfnRTCRegister,(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp));
2867
2868 /**
2869 * Register the PCI Bus.
2870 *
2871 * @returns VBox status code.
2872 * @param pDevIns The device instance.
2873 * @param pPciBusReg Pointer to PCI bus registration structure.
2874 * @param ppPciHlpR3 Where to store the pointer to the PCI Bus
2875 * helpers.
2876 */
2877 DECLR3CALLBACKMEMBER(int, pfnPCIBusRegister,(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3));
2878
2879 /**
2880 * Register the PIC device.
2881 *
2882 * @returns VBox status code.
2883 * @param pDevIns The device instance.
2884 * @param pPicReg Pointer to a PIC registration structure.
2885 * @param ppPicHlpR3 Where to store the pointer to the PIC HC
2886 * helpers.
2887 */
2888 DECLR3CALLBACKMEMBER(int, pfnPICRegister,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3));
2889
2890 /**
2891 * Register the APIC device.
2892 *
2893 * @returns VBox status code.
2894 * @param pDevIns The device instance.
2895 * @param pApicReg Pointer to a APIC registration structure.
2896 * @param ppApicHlpR3 Where to store the pointer to the APIC helpers.
2897 */
2898 DECLR3CALLBACKMEMBER(int, pfnAPICRegister,(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3));
2899
2900 /**
2901 * Register the I/O APIC device.
2902 *
2903 * @returns VBox status code.
2904 * @param pDevIns The device instance.
2905 * @param pIoApicReg Pointer to a I/O APIC registration structure.
2906 * @param ppIoApicHlpR3 Where to store the pointer to the IOAPIC
2907 * helpers.
2908 */
2909 DECLR3CALLBACKMEMBER(int, pfnIOAPICRegister,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3));
2910
2911 /**
2912 * Register the HPET device.
2913 *
2914 * @returns VBox status code.
2915 * @param pDevIns The device instance.
2916 * @param pHpetReg Pointer to a HPET registration structure.
2917 * @param ppHpetHlpR3 Where to store the pointer to the HPET
2918 * helpers.
2919 */
2920 DECLR3CALLBACKMEMBER(int, pfnHPETRegister,(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3));
2921
2922 /**
2923 * Register the DMA device.
2924 *
2925 * @returns VBox status code.
2926 * @param pDevIns The device instance.
2927 * @param pDmacReg Pointer to a DMAC registration structure.
2928 * @param ppDmacHlp Where to store the pointer to the DMA helpers.
2929 */
2930 DECLR3CALLBACKMEMBER(int, pfnDMACRegister,(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp));
2931
2932 /**
2933 * Register transfer function for DMA channel.
2934 *
2935 * @returns VBox status code.
2936 * @param pDevIns The device instance.
2937 * @param uChannel Channel number.
2938 * @param pfnTransferHandler Device specific transfer callback function.
2939 * @param pvUser User pointer to pass to the callback.
2940 * @thread EMT
2941 */
2942 DECLR3CALLBACKMEMBER(int, pfnDMARegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
2943
2944 /**
2945 * Read memory.
2946 *
2947 * @returns VBox status code.
2948 * @param pDevIns The device instance.
2949 * @param uChannel Channel number.
2950 * @param pvBuffer Pointer to target buffer.
2951 * @param off DMA position.
2952 * @param cbBlock Block size.
2953 * @param pcbRead Where to store the number of bytes which was
2954 * read. optional.
2955 * @thread EMT
2956 */
2957 DECLR3CALLBACKMEMBER(int, pfnDMAReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead));
2958
2959 /**
2960 * Write memory.
2961 *
2962 * @returns VBox status code.
2963 * @param pDevIns The device instance.
2964 * @param uChannel Channel number.
2965 * @param pvBuffer Memory to write.
2966 * @param off DMA position.
2967 * @param cbBlock Block size.
2968 * @param pcbWritten Where to store the number of bytes which was
2969 * written. optional.
2970 * @thread EMT
2971 */
2972 DECLR3CALLBACKMEMBER(int, pfnDMAWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten));
2973
2974 /**
2975 * Set the DREQ line.
2976 *
2977 * @returns VBox status code.
2978 * @param pDevIns Device instance.
2979 * @param uChannel Channel number.
2980 * @param uLevel Level of the line.
2981 * @thread EMT
2982 */
2983 DECLR3CALLBACKMEMBER(int, pfnDMASetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
2984
2985 /**
2986 * Get channel mode.
2987 *
2988 * @returns Channel mode. See specs.
2989 * @param pDevIns The device instance.
2990 * @param uChannel Channel number.
2991 * @thread EMT
2992 */
2993 DECLR3CALLBACKMEMBER(uint8_t, pfnDMAGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
2994
2995 /**
2996 * Schedule DMA execution.
2997 *
2998 * @param pDevIns The device instance.
2999 * @thread Any thread.
3000 */
3001 DECLR3CALLBACKMEMBER(void, pfnDMASchedule,(PPDMDEVINS pDevIns));
3002
3003 /**
3004 * Write CMOS value and update the checksum(s).
3005 *
3006 * @returns VBox status code.
3007 * @param pDevIns The device instance.
3008 * @param iReg The CMOS register index.
3009 * @param u8Value The CMOS register value.
3010 * @thread EMT
3011 */
3012 DECLR3CALLBACKMEMBER(int, pfnCMOSWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
3013
3014 /**
3015 * Read CMOS value.
3016 *
3017 * @returns VBox status code.
3018 * @param pDevIns The device instance.
3019 * @param iReg The CMOS register index.
3020 * @param pu8Value Where to store the CMOS register value.
3021 * @thread EMT
3022 */
3023 DECLR3CALLBACKMEMBER(int, pfnCMOSRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
3024
3025 /**
3026 * Assert that the current thread is the emulation thread.
3027 *
3028 * @returns True if correct.
3029 * @returns False if wrong.
3030 * @param pDevIns The device instance.
3031 * @param pszFile Filename of the assertion location.
3032 * @param iLine The linenumber of the assertion location.
3033 * @param pszFunction Function of the assertion location.
3034 */
3035 DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
3036
3037 /**
3038 * Assert that the current thread is NOT the emulation thread.
3039 *
3040 * @returns True if correct.
3041 * @returns False if wrong.
3042 * @param pDevIns The device instance.
3043 * @param pszFile Filename of the assertion location.
3044 * @param iLine The linenumber of the assertion location.
3045 * @param pszFunction Function of the assertion location.
3046 */
3047 DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
3048
3049 /**
3050 * Resolves the symbol for a raw-mode context interface.
3051 *
3052 * @returns VBox status code.
3053 * @param pDevIns The device instance.
3054 * @param pvInterface The interface structure.
3055 * @param cbInterface The size of the interface structure.
3056 * @param pszSymPrefix What to prefix the symbols in the list with
3057 * before resolving them. This must start with
3058 * 'dev' and contain the driver name.
3059 * @param pszSymList List of symbols corresponding to the interface.
3060 * There is generally a there is generally a define
3061 * holding this list associated with the interface
3062 * definition (INTERFACE_SYM_LIST). For more
3063 * details see PDMR3LdrGetInterfaceSymbols.
3064 * @thread EMT
3065 */
3066 DECLR3CALLBACKMEMBER(int, pfnLdrGetRCInterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
3067 const char *pszSymPrefix, const char *pszSymList));
3068
3069 /**
3070 * Resolves the symbol for a ring-0 context interface.
3071 *
3072 * @returns VBox status code.
3073 * @param pDevIns The device instance.
3074 * @param pvInterface The interface structure.
3075 * @param cbInterface The size of the interface structure.
3076 * @param pszSymPrefix What to prefix the symbols in the list with
3077 * before resolving them. This must start with
3078 * 'dev' and contain the driver name.
3079 * @param pszSymList List of symbols corresponding to the interface.
3080 * There is generally a there is generally a define
3081 * holding this list associated with the interface
3082 * definition (INTERFACE_SYM_LIST). For more
3083 * details see PDMR3LdrGetInterfaceSymbols.
3084 * @thread EMT
3085 */
3086 DECLR3CALLBACKMEMBER(int, pfnLdrGetR0InterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
3087 const char *pszSymPrefix, const char *pszSymList));
3088
3089 /**
3090 * Call the ring-0 request handler routine of the device.
3091 *
3092 * For this to work, the device must be ring-0 enabled and export a request
3093 * handler function. The name of the function must be the device name in
3094 * the PDMDRVREG struct prefixed with 'drvR0' and suffixed with
3095 * 'ReqHandler'. The device name will be captialized. It shall take the
3096 * exact same arguments as this function and be declared using
3097 * PDMBOTHCBDECL. See FNPDMDEVREQHANDLERR0.
3098 *
3099 * Unlike PDMDrvHlpCallR0, this is current unsuitable for more than a call
3100 * or two as the handler address will be resolved on each invocation. This
3101 * is the reason for the EMT only restriction as well.
3102 *
3103 * @returns VBox status code.
3104 * @retval VERR_SYMBOL_NOT_FOUND if the device doesn't export the required
3105 * handler function.
3106 * @retval VERR_ACCESS_DENIED if the device isn't ring-0 capable.
3107 *
3108 * @param pDevIns The device instance.
3109 * @param uOperation The operation to perform.
3110 * @param u64Arg 64-bit integer argument.
3111 * @thread EMT
3112 */
3113 DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg));
3114
3115 /** Space reserved for future members.
3116 * @{ */
3117 DECLR3CALLBACKMEMBER(void, pfnReserved1,(void));
3118 DECLR3CALLBACKMEMBER(void, pfnReserved2,(void));
3119 DECLR3CALLBACKMEMBER(void, pfnReserved3,(void));
3120 DECLR3CALLBACKMEMBER(void, pfnReserved4,(void));
3121 DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
3122 DECLR3CALLBACKMEMBER(void, pfnReserved6,(void));
3123 DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
3124 DECLR3CALLBACKMEMBER(void, pfnReserved8,(void));
3125 DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));
3126 DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));
3127 /** @} */
3128
3129
3130 /** API available to trusted devices only.
3131 *
3132 * These APIs are providing unrestricted access to the guest and the VM,
3133 * or they are interacting intimately with PDM.
3134 *
3135 * @{
3136 */
3137 /**
3138 * Gets the VM handle. Restricted API.
3139 *
3140 * @returns VM Handle.
3141 * @param pDevIns The device instance.
3142 */
3143 DECLR3CALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
3144
3145 /**
3146 * Gets the VMCPU handle. Restricted API.
3147 *
3148 * @returns VMCPU Handle.
3149 * @param pDevIns The device instance.
3150 */
3151 DECLR3CALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
3152
3153 /**
3154 * Registers the VMM device heap
3155 *
3156 * @returns VBox status code.
3157 * @param pDevIns The device instance.
3158 * @param GCPhys The physical address.
3159 * @param pvHeap Ring 3 heap pointer.
3160 * @param cbSize Size of the heap.
3161 * @thread EMT.
3162 */
3163 DECLR3CALLBACKMEMBER(int, pfnRegisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize));
3164
3165 /**
3166 * Unregisters the VMM device heap
3167 *
3168 * @returns VBox status code.
3169 * @param pDevIns The device instance.
3170 * @param GCPhys The physical address.
3171 * @thread EMT.
3172 */
3173 DECLR3CALLBACKMEMBER(int, pfnUnregisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys));
3174
3175 /**
3176 * Resets the VM.
3177 *
3178 * @returns The appropriate VBox status code to pass around on reset.
3179 * @param pDevIns The device instance.
3180 * @thread The emulation thread.
3181 */
3182 DECLR3CALLBACKMEMBER(int, pfnVMReset,(PPDMDEVINS pDevIns));
3183
3184 /**
3185 * Suspends the VM.
3186 *
3187 * @returns The appropriate VBox status code to pass around on suspend.
3188 * @param pDevIns The device instance.
3189 * @thread The emulation thread.
3190 */
3191 DECLR3CALLBACKMEMBER(int, pfnVMSuspend,(PPDMDEVINS pDevIns));
3192
3193 /**
3194 * Suspends, saves and powers off the VM.
3195 *
3196 * @returns The appropriate VBox status code to pass around.
3197 * @param pDevIns The device instance.
3198 * @thread An emulation thread.
3199 */
3200 DECLR3CALLBACKMEMBER(int, pfnVMSuspendSaveAndPowerOff,(PPDMDEVINS pDevIns));
3201
3202 /**
3203 * Power off the VM.
3204 *
3205 * @returns The appropriate VBox status code to pass around on power off.
3206 * @param pDevIns The device instance.
3207 * @thread The emulation thread.
3208 */
3209 DECLR3CALLBACKMEMBER(int, pfnVMPowerOff,(PPDMDEVINS pDevIns));
3210
3211 /**
3212 * Checks if the Gate A20 is enabled or not.
3213 *
3214 * @returns true if A20 is enabled.
3215 * @returns false if A20 is disabled.
3216 * @param pDevIns The device instance.
3217 * @thread The emulation thread.
3218 */
3219 DECLR3CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
3220
3221 /**
3222 * Enables or disables the Gate A20.
3223 *
3224 * @param pDevIns The device instance.
3225 * @param fEnable Set this flag to enable the Gate A20; clear it
3226 * to disable.
3227 * @thread The emulation thread.
3228 */
3229 DECLR3CALLBACKMEMBER(void, pfnA20Set,(PPDMDEVINS pDevIns, bool fEnable));
3230
3231 /**
3232 * Get the specified CPUID leaf for the virtual CPU associated with the calling
3233 * thread.
3234 *
3235 * @param pDevIns The device instance.
3236 * @param iLeaf The CPUID leaf to get.
3237 * @param pEax Where to store the EAX value.
3238 * @param pEbx Where to store the EBX value.
3239 * @param pEcx Where to store the ECX value.
3240 * @param pEdx Where to store the EDX value.
3241 * @thread EMT.
3242 */
3243 DECLR3CALLBACKMEMBER(void, pfnGetCpuId,(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx));
3244
3245 /**
3246 * Get the current virtual clock time in a VM. The clock frequency must be
3247 * queried separately.
3248 *
3249 * @returns Current clock time.
3250 * @param pDevIns The device instance.
3251 */
3252 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
3253
3254 /**
3255 * Get the frequency of the virtual clock.
3256 *
3257 * @returns The clock frequency (not variable at run-time).
3258 * @param pDevIns The device instance.
3259 */
3260 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
3261
3262 /**
3263 * Get the current virtual clock time in a VM, in nanoseconds.
3264 *
3265 * @returns Current clock time (in ns).
3266 * @param pDevIns The device instance.
3267 */
3268 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
3269
3270 /** @} */
3271
3272 /** Just a safety precaution. (PDM_DEVHLP_VERSION) */
3273 uint32_t u32TheEnd;
3274} PDMDEVHLPR3;
3275#endif /* !IN_RING3 */
3276/** Pointer to the R3 PDM Device API. */
3277typedef R3PTRTYPE(struct PDMDEVHLPR3 *) PPDMDEVHLPR3;
3278/** Pointer to the R3 PDM Device API, const variant. */
3279typedef R3PTRTYPE(const struct PDMDEVHLPR3 *) PCPDMDEVHLPR3;
3280
3281/** Current PDMDEVHLPR3 version number. */
3282#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE(0xffe7, 3, 0)
3283
3284
3285/**
3286 * PDM Device API - RC Variant.
3287 */
3288typedef struct PDMDEVHLPRC
3289{
3290 /** Structure version. PDM_DEVHLPRC_VERSION defines the current version. */
3291 uint32_t u32Version;
3292
3293 /**
3294 * Set the IRQ for a PCI device.
3295 *
3296 * @param pDevIns Device instance.
3297 * @param iIrq IRQ number to set.
3298 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3299 * @thread Any thread, but will involve the emulation thread.
3300 */
3301 DECLRCCALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3302
3303 /**
3304 * Set ISA IRQ for a device.
3305 *
3306 * @param pDevIns Device instance.
3307 * @param iIrq IRQ number to set.
3308 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3309 * @thread Any thread, but will involve the emulation thread.
3310 */
3311 DECLRCCALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3312
3313 /**
3314 * Read physical memory.
3315 *
3316 * @returns VINF_SUCCESS (for now).
3317 * @param pDevIns Device instance.
3318 * @param GCPhys Physical address start reading from.
3319 * @param pvBuf Where to put the read bits.
3320 * @param cbRead How many bytes to read.
3321 */
3322 DECLRCCALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
3323
3324 /**
3325 * Write to physical memory.
3326 *
3327 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
3328 * @param pDevIns Device instance.
3329 * @param GCPhys Physical address to write to.
3330 * @param pvBuf What to write.
3331 * @param cbWrite How many bytes to write.
3332 */
3333 DECLRCCALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
3334
3335 /**
3336 * Checks if the Gate A20 is enabled or not.
3337 *
3338 * @returns true if A20 is enabled.
3339 * @returns false if A20 is disabled.
3340 * @param pDevIns Device instance.
3341 * @thread The emulation thread.
3342 */
3343 DECLRCCALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
3344
3345 /**
3346 * Gets the VM state.
3347 *
3348 * @returns VM state.
3349 * @param pDevIns The device instance.
3350 * @thread Any thread (just keep in mind that it's volatile info).
3351 */
3352 DECLRCCALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
3353
3354 /**
3355 * Set the VM error message
3356 *
3357 * @returns rc.
3358 * @param pDrvIns Driver instance.
3359 * @param rc VBox status code.
3360 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3361 * @param pszFormat Error message format string.
3362 * @param ... Error message arguments.
3363 */
3364 DECLRCCALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
3365
3366 /**
3367 * Set the VM error message
3368 *
3369 * @returns rc.
3370 * @param pDrvIns Driver instance.
3371 * @param rc VBox status code.
3372 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3373 * @param pszFormat Error message format string.
3374 * @param va Error message arguments.
3375 */
3376 DECLRCCALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
3377
3378 /**
3379 * Set the VM runtime error message
3380 *
3381 * @returns VBox status code.
3382 * @param pDevIns Device instance.
3383 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3384 * @param pszErrorId Error ID string.
3385 * @param pszFormat Error message format string.
3386 * @param ... Error message arguments.
3387 */
3388 DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
3389
3390 /**
3391 * Set the VM runtime error message
3392 *
3393 * @returns VBox status code.
3394 * @param pDevIns Device instance.
3395 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3396 * @param pszErrorId Error ID string.
3397 * @param pszFormat Error message format string.
3398 * @param va Error message arguments.
3399 */
3400 DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
3401
3402 /**
3403 * Set parameters for pending MMIO patch operation
3404 *
3405 * @returns VBox status code.
3406 * @param pDevIns Device instance.
3407 * @param GCPhys MMIO physical address
3408 * @param pCachedData GC pointer to cached data
3409 */
3410 DECLRCCALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
3411
3412 /**
3413 * Gets the VM handle. Restricted API.
3414 *
3415 * @returns VM Handle.
3416 * @param pDevIns Device instance.
3417 */
3418 DECLRCCALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
3419
3420 /**
3421 * Gets the VMCPU handle. Restricted API.
3422 *
3423 * @returns VMCPU Handle.
3424 * @param pDevIns The device instance.
3425 */
3426 DECLRCCALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
3427
3428 /**
3429 * Get the current virtual clock time in a VM. The clock frequency must be
3430 * queried separately.
3431 *
3432 * @returns Current clock time.
3433 * @param pDevIns The device instance.
3434 */
3435 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
3436
3437 /**
3438 * Get the frequency of the virtual clock.
3439 *
3440 * @returns The clock frequency (not variable at run-time).
3441 * @param pDevIns The device instance.
3442 */
3443 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
3444
3445 /**
3446 * Get the current virtual clock time in a VM, in nanoseconds.
3447 *
3448 * @returns Current clock time (in ns).
3449 * @param pDevIns The device instance.
3450 */
3451 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
3452
3453 /** Just a safety precaution. */
3454 uint32_t u32TheEnd;
3455} PDMDEVHLPRC;
3456/** Pointer PDM Device RC API. */
3457typedef RCPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC;
3458/** Pointer PDM Device RC API. */
3459typedef RCPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC;
3460
3461/** Current PDMDEVHLP version number. */
3462#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 1, 0)
3463
3464
3465/**
3466 * PDM Device API - R0 Variant.
3467 */
3468typedef struct PDMDEVHLPR0
3469{
3470 /** Structure version. PDM_DEVHLPR0_VERSION defines the current version. */
3471 uint32_t u32Version;
3472
3473 /**
3474 * Set the IRQ for a PCI device.
3475 *
3476 * @param pDevIns Device instance.
3477 * @param iIrq IRQ number to set.
3478 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3479 * @thread Any thread, but will involve the emulation thread.
3480 */
3481 DECLR0CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3482
3483 /**
3484 * Set ISA IRQ for a device.
3485 *
3486 * @param pDevIns Device instance.
3487 * @param iIrq IRQ number to set.
3488 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3489 * @thread Any thread, but will involve the emulation thread.
3490 */
3491 DECLR0CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3492
3493 /**
3494 * Read physical memory.
3495 *
3496 * @returns VINF_SUCCESS (for now).
3497 * @param pDevIns Device instance.
3498 * @param GCPhys Physical address start reading from.
3499 * @param pvBuf Where to put the read bits.
3500 * @param cbRead How many bytes to read.
3501 */
3502 DECLR0CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
3503
3504 /**
3505 * Write to physical memory.
3506 *
3507 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
3508 * @param pDevIns Device instance.
3509 * @param GCPhys Physical address to write to.
3510 * @param pvBuf What to write.
3511 * @param cbWrite How many bytes to write.
3512 */
3513 DECLR0CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
3514
3515 /**
3516 * Checks if the Gate A20 is enabled or not.
3517 *
3518 * @returns true if A20 is enabled.
3519 * @returns false if A20 is disabled.
3520 * @param pDevIns Device instance.
3521 * @thread The emulation thread.
3522 */
3523 DECLR0CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
3524
3525 /**
3526 * Gets the VM state.
3527 *
3528 * @returns VM state.
3529 * @param pDevIns The device instance.
3530 * @thread Any thread (just keep in mind that it's volatile info).
3531 */
3532 DECLR0CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
3533
3534 /**
3535 * Set the VM error message
3536 *
3537 * @returns rc.
3538 * @param pDrvIns Driver instance.
3539 * @param rc VBox status code.
3540 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3541 * @param pszFormat Error message format string.
3542 * @param ... Error message arguments.
3543 */
3544 DECLR0CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
3545
3546 /**
3547 * Set the VM error message
3548 *
3549 * @returns rc.
3550 * @param pDrvIns Driver instance.
3551 * @param rc VBox status code.
3552 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3553 * @param pszFormat Error message format string.
3554 * @param va Error message arguments.
3555 */
3556 DECLR0CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
3557
3558 /**
3559 * Set the VM runtime error message
3560 *
3561 * @returns VBox status code.
3562 * @param pDevIns Device instance.
3563 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3564 * @param pszErrorId Error ID string.
3565 * @param pszFormat Error message format string.
3566 * @param ... Error message arguments.
3567 */
3568 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
3569
3570 /**
3571 * Set the VM runtime error message
3572 *
3573 * @returns VBox status code.
3574 * @param pDevIns Device instance.
3575 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3576 * @param pszErrorId Error ID string.
3577 * @param pszFormat Error message format string.
3578 * @param va Error message arguments.
3579 */
3580 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
3581
3582 /**
3583 * Set parameters for pending MMIO patch operation
3584 *
3585 * @returns rc.
3586 * @param pDevIns Device instance.
3587 * @param GCPhys MMIO physical address
3588 * @param pCachedData GC pointer to cached data
3589 */
3590 DECLR0CALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
3591
3592 /**
3593 * Gets the VM handle. Restricted API.
3594 *
3595 * @returns VM Handle.
3596 * @param pDevIns Device instance.
3597 */
3598 DECLR0CALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
3599
3600 /**
3601 * Checks if our current CPU state allows for IO block emulation fallback to the recompiler
3602 *
3603 * @returns true = yes, false = no
3604 * @param pDevIns Device instance.
3605 */
3606 DECLR0CALLBACKMEMBER(bool, pfnCanEmulateIoBlock,(PPDMDEVINS pDevIns));
3607
3608 /**
3609 * Gets the VMCPU handle. Restricted API.
3610 *
3611 * @returns VMCPU Handle.
3612 * @param pDevIns The device instance.
3613 */
3614 DECLR0CALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
3615
3616 /**
3617 * Get the current virtual clock time in a VM. The clock frequency must be
3618 * queried separately.
3619 *
3620 * @returns Current clock time.
3621 * @param pDevIns The device instance.
3622 */
3623 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
3624
3625 /**
3626 * Get the frequency of the virtual clock.
3627 *
3628 * @returns The clock frequency (not variable at run-time).
3629 * @param pDevIns The device instance.
3630 */
3631 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
3632
3633 /**
3634 * Get the current virtual clock time in a VM, in nanoseconds.
3635 *
3636 * @returns Current clock time (in ns).
3637 * @param pDevIns The device instance.
3638 */
3639 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
3640
3641 /** Just a safety precaution. */
3642 uint32_t u32TheEnd;
3643} PDMDEVHLPR0;
3644/** Pointer PDM Device R0 API. */
3645typedef R0PTRTYPE(struct PDMDEVHLPR0 *) PPDMDEVHLPR0;
3646/** Pointer PDM Device GC API. */
3647typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0;
3648
3649/** Current PDMDEVHLP version number. */
3650#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 1, 0)
3651
3652
3653
3654/**
3655 * PDM Device Instance.
3656 */
3657typedef struct PDMDEVINS
3658{
3659 /** Structure version. PDM_DEVINS_VERSION defines the current version. */
3660 uint32_t u32Version;
3661 /** Device instance number. */
3662 uint32_t iInstance;
3663
3664 /** Pointer the GC PDM Device API. */
3665 PCPDMDEVHLPRC pHlpRC;
3666 /** Pointer to device instance data. */
3667 RTRCPTR pvInstanceDataRC;
3668 /** The critical section for the device, see pCritSectR3.
3669 * This is automatically resolved by PDM when pCritSectR3 is set by the
3670 * constructor. */
3671 RCPTRTYPE(PPDMCRITSECT) pCritSectRC;
3672 /** Alignment padding. */
3673 RTRCPTR pAlignmentRC;
3674
3675 /** Pointer the R0 PDM Device API. */
3676 PCPDMDEVHLPR0 pHlpR0;
3677 /** Pointer to device instance data (R0). */
3678 RTR0PTR pvInstanceDataR0;
3679 /** The critical section for the device, see pCritSectR3.
3680 * This is automatically resolved by PDM when pCritSectR3 is set by the
3681 * constructor. */
3682 R0PTRTYPE(PPDMCRITSECT) pCritSectR0;
3683
3684 /** Pointer the HC PDM Device API. */
3685 PCPDMDEVHLPR3 pHlpR3;
3686 /** Pointer to device instance data. */
3687 RTR3PTR pvInstanceDataR3;
3688 /** The critical section for the device. (Optional)
3689 *
3690 * The device constructor initializes this if it has a critical section for
3691 * the device and desires it to be taken automatically by MMIO, I/O port
3692 * and timer callbacks to the device. The advantages using this locking
3693 * approach is both less code and avoiding the global IOM lock.
3694 *
3695 * @remarks Will not yet be taken by SSM.
3696 */
3697 R3PTRTYPE(PPDMCRITSECT) pCritSectR3;
3698
3699 /** Pointer to device registration structure. */
3700 R3PTRTYPE(PCPDMDEVREG) pReg;
3701 /** Configuration handle. */
3702 R3PTRTYPE(PCFGMNODE) pCfg;
3703
3704 /** The base interface of the device.
3705 *
3706 * The device constructor initializes this if it has any
3707 * device level interfaces to export. To obtain this interface
3708 * call PDMR3QueryDevice(). */
3709 PDMIBASE IBase;
3710 /** Align the internal data more naturally. */
3711 RTR3PTR R3PtrPadding;
3712
3713 /** Internal data. */
3714 union
3715 {
3716#ifdef PDMDEVINSINT_DECLARED
3717 PDMDEVINSINT s;
3718#endif
3719 uint8_t padding[HC_ARCH_BITS == 32 ? 64 + 0 : 112 + 0x28];
3720 } Internal;
3721
3722 /** Device instance data. The size of this area is defined
3723 * in the PDMDEVREG::cbInstanceData field. */
3724 char achInstanceData[8];
3725} PDMDEVINS;
3726
3727/** Current PDMDEVINS version number. */
3728#define PDM_DEVINS_VERSION PDM_VERSION_MAKE(0xffe4, 2, 0)
3729
3730/** Converts a pointer to the PDMDEVINS::IBase to a pointer to PDMDEVINS. */
3731#define PDMIBASE_2_PDMDEV(pInterface) ( (PPDMDEVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDEVINS, IBase)) )
3732
3733/**
3734 * Checks the structure versions of the device instance and device helpers,
3735 * returning if they are incompatible.
3736 *
3737 * This is for use in the constructor.
3738 *
3739 * @param pDevIns The device instance pointer.
3740 */
3741#define PDMDEV_CHECK_VERSIONS_RETURN(pDevIns) \
3742 do \
3743 { \
3744 PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
3745 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION), \
3746 ("DevIns=%#x mine=%#x\n", (pDevIns)->u32Version, PDM_DEVINS_VERSION), \
3747 VERR_VERSION_MISMATCH); \
3748 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION), \
3749 ("DevHlp=%#x mine=%#x\n", (pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION), \
3750 VERR_VERSION_MISMATCH); \
3751 } while (0)
3752
3753/**
3754 * Quietly checks the structure versions of the device instance and device
3755 * helpers, returning if they are incompatible.
3756 *
3757 * This is for use in the destructor.
3758 *
3759 * @param pDevIns The device instance pointer.
3760 */
3761#define PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns) \
3762 do \
3763 { \
3764 PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
3765 if (RT_UNLIKELY( !PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION) \
3766 || !PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION) )) \
3767 return VERR_VERSION_MISMATCH; \
3768 } while (0)
3769
3770/**
3771 * Wrapper around CFGMR3ValidateConfig for the root config for use in the
3772 * constructor - returns on failure.
3773 *
3774 * This should be invoked after having initialized the instance data
3775 * sufficiently for the correct operation of the destructor. The destructor is
3776 * always called!
3777 *
3778 * @param pDevIns Pointer to the PDM device instance.
3779 * @param pszValidValues Patterns describing the valid value names. See
3780 * RTStrSimplePatternMultiMatch for details on the
3781 * pattern syntax.
3782 * @param pszValidNodes Patterns describing the valid node (key) names.
3783 * Pass empty string if no valid nodess.
3784 */
3785#define PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, pszValidValues, pszValidNodes) \
3786 do \
3787 { \
3788 int rcValCfg = CFGMR3ValidateConfig((pDevIns)->pCfg, "/", pszValidValues, pszValidNodes, \
3789 (pDevIns)->pReg->szName, (pDevIns)->iInstance); \
3790 if (RT_FAILURE(rcValCfg)) \
3791 return rcValCfg; \
3792 } while (0)
3793
3794/** @def PDMDEV_ASSERT_EMT
3795 * Assert that the current thread is the emulation thread.
3796 */
3797#ifdef VBOX_STRICT
3798# define PDMDEV_ASSERT_EMT(pDevIns) pDevIns->pHlpR3->pfnAssertEMT(pDevIns, __FILE__, __LINE__, __FUNCTION__)
3799#else
3800# define PDMDEV_ASSERT_EMT(pDevIns) do { } while (0)
3801#endif
3802
3803/** @def PDMDEV_ASSERT_OTHER
3804 * Assert that the current thread is NOT the emulation thread.
3805 */
3806#ifdef VBOX_STRICT
3807# define PDMDEV_ASSERT_OTHER(pDevIns) pDevIns->pHlpR3->pfnAssertOther(pDevIns, __FILE__, __LINE__, __FUNCTION__)
3808#else
3809# define PDMDEV_ASSERT_OTHER(pDevIns) do { } while (0)
3810#endif
3811
3812/** @def PDMDEV_ASSERT_VMLOCK_OWNER
3813 * Assert that the current thread is owner of the VM lock.
3814 */
3815#ifdef VBOX_STRICT
3816# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) pDevIns->pHlpR3->pfnAssertVMLock(pDevIns, __FILE__, __LINE__, __FUNCTION__)
3817#else
3818# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) do { } while (0)
3819#endif
3820
3821/** @def PDMDEV_SET_ERROR
3822 * Set the VM error. See PDMDevHlpVMSetError() for printf like message formatting.
3823 */
3824#define PDMDEV_SET_ERROR(pDevIns, rc, pszError) \
3825 PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, "%s", pszError)
3826
3827/** @def PDMDEV_SET_RUNTIME_ERROR
3828 * Set the VM runtime error. See PDMDevHlpVMSetRuntimeError() for printf like message formatting.
3829 */
3830#define PDMDEV_SET_RUNTIME_ERROR(pDevIns, fFlags, pszErrorId, pszError) \
3831 PDMDevHlpVMSetRuntimeError(pDevIns, fFlags, pszErrorId, "%s", pszError)
3832
3833/** @def PDMDEVINS_2_RCPTR
3834 * Converts a PDM Device instance pointer a RC PDM Device instance pointer.
3835 */
3836#define PDMDEVINS_2_RCPTR(pDevIns) ( (RCPTRTYPE(PPDMDEVINS))((RTGCUINTPTR)(pDevIns)->pvInstanceDataRC - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
3837
3838/** @def PDMDEVINS_2_R3PTR
3839 * Converts a PDM Device instance pointer a R3 PDM Device instance pointer.
3840 */
3841#define PDMDEVINS_2_R3PTR(pDevIns) ( (R3PTRTYPE(PPDMDEVINS))((RTHCUINTPTR)(pDevIns)->pvInstanceDataR3 - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
3842
3843/** @def PDMDEVINS_2_R0PTR
3844 * Converts a PDM Device instance pointer a R0 PDM Device instance pointer.
3845 */
3846#define PDMDEVINS_2_R0PTR(pDevIns) ( (R0PTRTYPE(PPDMDEVINS))((RTR0UINTPTR)(pDevIns)->pvInstanceDataR0 - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
3847
3848
3849#ifdef IN_RING3
3850
3851/**
3852 * @copydoc PDMDEVHLPR3::pfnIOPortRegister
3853 */
3854DECLINLINE(int) PDMDevHlpIOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser,
3855 PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
3856 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc)
3857{
3858 return pDevIns->pHlpR3->pfnIOPortRegister(pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc);
3859}
3860
3861/**
3862 * @copydoc PDMDEVHLPR3::pfnIOPortRegisterRC
3863 */
3864DECLINLINE(int) PDMDevHlpIOPortRegisterRC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser,
3865 const char *pszOut, const char *pszIn, const char *pszOutStr,
3866 const char *pszInStr, const char *pszDesc)
3867{
3868 return pDevIns->pHlpR3->pfnIOPortRegisterRC(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
3869}
3870
3871/**
3872 * @copydoc PDMDEVHLPR3::pfnIOPortRegisterR0
3873 */
3874DECLINLINE(int) PDMDevHlpIOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser,
3875 const char *pszOut, const char *pszIn, const char *pszOutStr,
3876 const char *pszInStr, const char *pszDesc)
3877{
3878 return pDevIns->pHlpR3->pfnIOPortRegisterR0(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
3879}
3880
3881/**
3882 * @copydoc PDMDEVHLPR3::pfnIOPortDeregister
3883 */
3884DECLINLINE(int) PDMDevHlpIOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts)
3885{
3886 return pDevIns->pHlpR3->pfnIOPortDeregister(pDevIns, Port, cPorts);
3887}
3888
3889/**
3890 * @copydoc PDMDEVHLPR3::pfnMMIORegister
3891 */
3892DECLINLINE(int) PDMDevHlpMMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,
3893 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
3894 const char *pszDesc)
3895{
3896 return pDevIns->pHlpR3->pfnMMIORegister(pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc);
3897}
3898
3899/**
3900 * @copydoc PDMDEVHLPR3::pfnMMIORegisterRC
3901 */
3902DECLINLINE(int) PDMDevHlpMMIORegisterRC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,
3903 const char *pszWrite, const char *pszRead, const char *pszFill)
3904{
3905 return pDevIns->pHlpR3->pfnMMIORegisterRC(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill, NULL);
3906}
3907
3908/**
3909 * @copydoc PDMDEVHLPR3::pfnMMIORegisterR0
3910 */
3911DECLINLINE(int) PDMDevHlpMMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,
3912 const char *pszWrite, const char *pszRead, const char *pszFill)
3913{
3914 return pDevIns->pHlpR3->pfnMMIORegisterR0(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill, NULL);
3915}
3916
3917/**
3918 * @copydoc PDMDEVHLPR3::pfnMMIODeregister
3919 */
3920DECLINLINE(int) PDMDevHlpMMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
3921{
3922 return pDevIns->pHlpR3->pfnMMIODeregister(pDevIns, GCPhysStart, cbRange);
3923}
3924
3925/**
3926 * @copydoc PDMDEVHLPR3::pfnMMIO2Register
3927 */
3928DECLINLINE(int) PDMDevHlpMMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
3929{
3930 return pDevIns->pHlpR3->pfnMMIO2Register(pDevIns, iRegion, cb, fFlags, ppv, pszDesc);
3931}
3932
3933/**
3934 * @copydoc PDMDEVHLPR3::pfnMMIO2Deregister
3935 */
3936DECLINLINE(int) PDMDevHlpMMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)
3937{
3938 return pDevIns->pHlpR3->pfnMMIO2Deregister(pDevIns, iRegion);
3939}
3940
3941/**
3942 * @copydoc PDMDEVHLPR3::pfnMMIO2Map
3943 */
3944DECLINLINE(int) PDMDevHlpMMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
3945{
3946 return pDevIns->pHlpR3->pfnMMIO2Map(pDevIns, iRegion, GCPhys);
3947}
3948
3949/**
3950 * @copydoc PDMDEVHLPR3::pfnMMIO2Unmap
3951 */
3952DECLINLINE(int) PDMDevHlpMMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
3953{
3954 return pDevIns->pHlpR3->pfnMMIO2Unmap(pDevIns, iRegion, GCPhys);
3955}
3956
3957/**
3958 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2
3959 */
3960DECLINLINE(int) PDMDevHlpMMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
3961 const char *pszDesc, PRTRCPTR pRCPtr)
3962{
3963 return pDevIns->pHlpR3->pfnMMHyperMapMMIO2(pDevIns, iRegion, off, cb, pszDesc, pRCPtr);
3964}
3965
3966/**
3967 * @copydoc PDMDEVHLPR3::pfnMMIO2MapKernel
3968 */
3969DECLINLINE(int) PDMDevHlpMMIO2MapKernel(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
3970 const char *pszDesc, PRTR0PTR pR0Ptr)
3971{
3972 return pDevIns->pHlpR3->pfnMMIO2MapKernel(pDevIns, iRegion, off, cb, pszDesc, pR0Ptr);
3973}
3974
3975/**
3976 * @copydoc PDMDEVHLPR3::pfnROMRegister
3977 */
3978DECLINLINE(int) PDMDevHlpROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, uint32_t fFlags, const char *pszDesc)
3979{
3980 return pDevIns->pHlpR3->pfnROMRegister(pDevIns, GCPhysStart, cbRange, pvBinary, fFlags, pszDesc);
3981}
3982
3983/**
3984 * @copydoc PDMDEVHLPR3::pfnROMProtectShadow
3985 */
3986DECLINLINE(int) PDMDevHlpROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, PGMROMPROT enmProt)
3987{
3988 return pDevIns->pHlpR3->pfnROMProtectShadow(pDevIns, GCPhysStart, cbRange, enmProt);
3989}
3990
3991/**
3992 * Register a save state data unit.
3993 *
3994 * @returns VBox status.
3995 * @param pDevIns The device instance.
3996 * @param uVersion Data layout version number.
3997 * @param cbGuess The approximate amount of data in the unit.
3998 * Only for progress indicators.
3999 * @param pfnSaveExec Execute save callback, optional.
4000 * @param pfnLoadExec Execute load callback, optional.
4001 */
4002DECLINLINE(int) PDMDevHlpSSMRegister(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
4003 PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
4004{
4005 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
4006 NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveDone*/,
4007 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
4008 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
4009}
4010
4011/**
4012 * Register a save state data unit with a live save callback as well.
4013 *
4014 * @returns VBox status.
4015 * @param pDevIns The device instance.
4016 * @param uVersion Data layout version number.
4017 * @param cbGuess The approximate amount of data in the unit.
4018 * Only for progress indicators.
4019 * @param pfnLiveExec Execute live callback, optional.
4020 * @param pfnSaveExec Execute save callback, optional.
4021 * @param pfnLoadExec Execute load callback, optional.
4022 */
4023DECLINLINE(int) PDMDevHlpSSMRegister3(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
4024 FNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
4025{
4026 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
4027 NULL /*pfnLivePrep*/, pfnLiveExec, NULL /*pfnLiveDone*/,
4028 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
4029 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
4030}
4031
4032/**
4033 * @copydoc PDMDEVHLPR3::pfnSSMRegister
4034 */
4035DECLINLINE(int) PDMDevHlpSSMRegisterEx(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
4036 PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
4037 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
4038 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
4039{
4040 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, pszBefore,
4041 pfnLivePrep, pfnLiveExec, pfnLiveVote,
4042 pfnSavePrep, pfnSaveExec, pfnSaveDone,
4043 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
4044}
4045
4046/**
4047 * @copydoc PDMDEVHLPR3::pfnTMTimerCreate
4048 */
4049DECLINLINE(int) PDMDevHlpTMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags,
4050 const char *pszDesc, PPTMTIMERR3 ppTimer)
4051{
4052 return pDevIns->pHlpR3->pfnTMTimerCreate(pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
4053}
4054
4055/**
4056 * @copydoc PDMDEVHLPR3::pfnTMUtcNow
4057 */
4058DECLINLINE(PRTTIMESPEC) PDMDevHlpTMUtcNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
4059{
4060 return pDevIns->pHlpR3->pfnTMUtcNow(pDevIns, pTime);
4061}
4062
4063#endif /* IN_RING3 */
4064
4065/**
4066 * @copydoc PDMDEVHLPR3::pfnPhysRead
4067 */
4068DECLINLINE(int) PDMDevHlpPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
4069{
4070 return pDevIns->CTX_SUFF(pHlp)->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
4071}
4072
4073/**
4074 * @copydoc PDMDEVHLPR3::pfnPhysWrite
4075 */
4076DECLINLINE(int) PDMDevHlpPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
4077{
4078 return pDevIns->CTX_SUFF(pHlp)->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
4079}
4080
4081#ifdef IN_RING3
4082
4083/**
4084 * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtr
4085 */
4086DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtr(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock)
4087{
4088 return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtr(pDevIns, GCPhys, fFlags, ppv, pLock);
4089}
4090
4091/**
4092 * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtrReadOnly
4093 */
4094DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock)
4095{
4096 return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhys, fFlags, ppv, pLock);
4097}
4098
4099/**
4100 * @copydoc PDMDEVHLPR3::pfnPhysReleasePageMappingLock
4101 */
4102DECLINLINE(void) PDMDevHlpPhysReleasePageMappingLock(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock)
4103{
4104 pDevIns->CTX_SUFF(pHlp)->pfnPhysReleasePageMappingLock(pDevIns, pLock);
4105}
4106
4107/**
4108 * @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt
4109 */
4110DECLINLINE(int) PDMDevHlpPhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
4111{
4112 return pDevIns->pHlpR3->pfnPhysReadGCVirt(pDevIns, pvDst, GCVirtSrc, cb);
4113}
4114
4115/**
4116 * @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt
4117 */
4118DECLINLINE(int) PDMDevHlpPhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
4119{
4120 return pDevIns->pHlpR3->pfnPhysWriteGCVirt(pDevIns, GCVirtDst, pvSrc, cb);
4121}
4122
4123/**
4124 * @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys
4125 */
4126DECLINLINE(int) PDMDevHlpPhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
4127{
4128 return pDevIns->pHlpR3->pfnPhysGCPtr2GCPhys(pDevIns, GCPtr, pGCPhys);
4129}
4130
4131/**
4132 * @copydoc PDMDEVHLPR3::pfnMMHeapAlloc
4133 */
4134DECLINLINE(void *) PDMDevHlpMMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
4135{
4136 return pDevIns->pHlpR3->pfnMMHeapAlloc(pDevIns, cb);
4137}
4138
4139/**
4140 * @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ
4141 */
4142DECLINLINE(void *) PDMDevHlpMMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
4143{
4144 return pDevIns->pHlpR3->pfnMMHeapAllocZ(pDevIns, cb);
4145}
4146
4147/**
4148 * @copydoc PDMDEVHLPR3::pfnMMHeapFree
4149 */
4150DECLINLINE(void) PDMDevHlpMMHeapFree(PPDMDEVINS pDevIns, void *pv)
4151{
4152 pDevIns->pHlpR3->pfnMMHeapFree(pDevIns, pv);
4153}
4154#endif /* IN_RING3 */
4155
4156/**
4157 * @copydoc PDMDEVHLPR3::pfnVMState
4158 */
4159DECLINLINE(VMSTATE) PDMDevHlpVMState(PPDMDEVINS pDevIns)
4160{
4161 return pDevIns->CTX_SUFF(pHlp)->pfnVMState(pDevIns);
4162}
4163
4164#ifdef IN_RING3
4165/**
4166 * @copydoc PDMDEVHLPR3::pfnVMTeleportedAndNotFullyResumedYet
4167 */
4168DECLINLINE(bool) PDMDevHlpVMTeleportedAndNotFullyResumedYet(PPDMDEVINS pDevIns)
4169{
4170 return pDevIns->pHlpR3->pfnVMTeleportedAndNotFullyResumedYet(pDevIns);
4171}
4172#endif /* IN_RING3 */
4173
4174/**
4175 * @copydoc PDMDEVHLPR3::pfnVMSetError
4176 */
4177DECLINLINE(int) PDMDevHlpVMSetError(PPDMDEVINS pDevIns, const int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
4178{
4179 va_list va;
4180 va_start(va, pszFormat);
4181 pDevIns->CTX_SUFF(pHlp)->pfnVMSetErrorV(pDevIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
4182 va_end(va);
4183 return rc;
4184}
4185
4186/**
4187 * @copydoc PDMDEVHLPR3::pfnVMSetRuntimeError
4188 */
4189DECLINLINE(int) PDMDevHlpVMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
4190{
4191 va_list va;
4192 int rc;
4193 va_start(va, pszFormat);
4194 rc = pDevIns->CTX_SUFF(pHlp)->pfnVMSetRuntimeErrorV(pDevIns, fFlags, pszErrorId, pszFormat, va);
4195 va_end(va);
4196 return rc;
4197}
4198
4199/**
4200 * VBOX_STRICT wrapper for pHlp->pfnDBGFStopV.
4201 *
4202 * @returns VBox status code which must be passed up to the VMM. This will be
4203 * VINF_SUCCESS in non-strict builds.
4204 * @param pDevIns The device instance.
4205 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
4206 * @param pszFormat Message. (optional)
4207 * @param ... Message parameters.
4208 */
4209DECLINLINE(int) PDMDevHlpDBGFStop(PPDMDEVINS pDevIns, RT_SRC_POS_DECL, const char *pszFormat, ...)
4210{
4211#ifdef VBOX_STRICT
4212# ifdef IN_RING3
4213 int rc;
4214 va_list args;
4215 va_start(args, pszFormat);
4216 rc = pDevIns->pHlpR3->pfnDBGFStopV(pDevIns, RT_SRC_POS_ARGS, pszFormat, args);
4217 va_end(args);
4218 return rc;
4219# else
4220 return VINF_EM_DBG_STOP;
4221# endif
4222#else
4223 NOREF(pDevIns);
4224 NOREF(pszFile);
4225 NOREF(iLine);
4226 NOREF(pszFunction);
4227 NOREF(pszFormat);
4228 return VINF_SUCCESS;
4229#endif
4230}
4231
4232#ifdef IN_RING3
4233
4234/**
4235 * @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister
4236 */
4237DECLINLINE(int) PDMDevHlpDBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
4238{
4239 return pDevIns->pHlpR3->pfnDBGFInfoRegister(pDevIns, pszName, pszDesc, pfnHandler);
4240}
4241
4242/**
4243 * @copydoc PDMDEVHLPR3::pfnSTAMRegister
4244 */
4245DECLINLINE(void) PDMDevHlpSTAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
4246{
4247 pDevIns->pHlpR3->pfnSTAMRegister(pDevIns, pvSample, enmType, pszName, enmUnit, pszDesc);
4248}
4249
4250/**
4251 * @copydoc PDMDEVHLPR3::pfnSTAMRegisterF
4252 */
4253DECLINLINE(void) PDMDevHlpSTAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
4254 const char *pszDesc, const char *pszName, ...)
4255{
4256 va_list va;
4257 va_start(va, pszName);
4258 pDevIns->pHlpR3->pfnSTAMRegisterV(pDevIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, va);
4259 va_end(va);
4260}
4261
4262/**
4263 * @copydoc PDMDEVHLPR3::pfnPCIRegister
4264 */
4265DECLINLINE(int) PDMDevHlpPCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev)
4266{
4267 return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev);
4268}
4269
4270/**
4271 * @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister
4272 */
4273DECLINLINE(int) PDMDevHlpPCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
4274{
4275 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, iRegion, cbRegion, enmType, pfnCallback);
4276}
4277
4278/**
4279 * @copydoc PDMDEVHLPR3::pfnPCIRegisterMsi
4280 */
4281DECLINLINE(int) PDMDevHlpPCIRegisterMsi(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg)
4282{
4283 return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, pMsiReg);
4284}
4285
4286
4287/**
4288 * @copydoc PDMDEVHLPR3::pfnPCISetConfigCallbacks
4289 */
4290DECLINLINE(void) PDMDevHlpPCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
4291 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)
4292{
4293 pDevIns->pHlpR3->pfnPCISetConfigCallbacks(pDevIns, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld);
4294}
4295
4296#endif /* IN_RING3 */
4297
4298/**
4299 * @copydoc PDMDEVHLPR3::pfnPCISetIrq
4300 */
4301DECLINLINE(void) PDMDevHlpPCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4302{
4303 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, iIrq, iLevel);
4304}
4305
4306/**
4307 * @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait
4308 */
4309DECLINLINE(void) PDMDevHlpPCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4310{
4311 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, iIrq, iLevel);
4312}
4313
4314/**
4315 * @copydoc PDMDEVHLPR3::pfnISASetIrq
4316 */
4317DECLINLINE(void) PDMDevHlpISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4318{
4319 pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
4320}
4321
4322/**
4323 * @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait
4324 */
4325DECLINLINE(void) PDMDevHlpISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4326{
4327 pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
4328}
4329
4330#ifdef IN_RING3
4331
4332/**
4333 * @copydoc PDMDEVHLPR3::pfnDriverAttach
4334 */
4335DECLINLINE(int) PDMDevHlpDriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
4336{
4337 return pDevIns->pHlpR3->pfnDriverAttach(pDevIns, iLun, pBaseInterface, ppBaseInterface, pszDesc);
4338}
4339
4340/**
4341 * @copydoc PDMDEVHLPR3::pfnQueueCreate
4342 */
4343DECLINLINE(int) PDMDevHlpQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
4344 PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, const char *pszName, PPDMQUEUE *ppQueue)
4345{
4346 return pDevIns->pHlpR3->pfnQueueCreate(pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, pszName, ppQueue);
4347}
4348
4349/**
4350 * Initializes a PDM critical section.
4351 *
4352 * The PDM critical sections are derived from the IPRT critical sections, but
4353 * works in RC and R0 as well.
4354 *
4355 * @returns VBox status code.
4356 * @param pDevIns The device instance.
4357 * @param pCritSect Pointer to the critical section.
4358 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
4359 * @param pszNameFmt Format string for naming the critical section.
4360 * For statistics and lock validation.
4361 * @param ... Arguments for the format string.
4362 */
4363DECLINLINE(int) PDMDevHlpCritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...)
4364{
4365 int rc;
4366 va_list va;
4367 va_start(va, pszNameFmt);
4368 rc = pDevIns->pHlpR3->pfnCritSectInit(pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
4369 va_end(va);
4370 return rc;
4371}
4372
4373/**
4374 * @copydoc PDMDEVHLPR3::pfnThreadCreate
4375 */
4376DECLINLINE(int) PDMDevHlpThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
4377 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
4378{
4379 return pDevIns->pHlpR3->pfnThreadCreate(pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
4380}
4381
4382/**
4383 * @copydoc PDMDEVHLPR3::pfnSetAsyncNotification
4384 */
4385DECLINLINE(int) PDMDevHlpSetAsyncNotification(PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)
4386{
4387 return pDevIns->pHlpR3->pfnSetAsyncNotification(pDevIns, pfnAsyncNotify);
4388}
4389
4390/**
4391 * @copydoc PDMDEVHLPR3::pfnAsyncNotificationCompleted
4392 */
4393DECLINLINE(void) PDMDevHlpAsyncNotificationCompleted(PPDMDEVINS pDevIns)
4394{
4395 pDevIns->pHlpR3->pfnAsyncNotificationCompleted(pDevIns);
4396}
4397
4398/**
4399 * @copydoc PDMDEVHLPR3::pfnA20Set
4400 */
4401DECLINLINE(void) PDMDevHlpA20Set(PPDMDEVINS pDevIns, bool fEnable)
4402{
4403 pDevIns->pHlpR3->pfnA20Set(pDevIns, fEnable);
4404}
4405
4406/**
4407 * @copydoc PDMDEVHLPR3::pfnRTCRegister
4408 */
4409DECLINLINE(int) PDMDevHlpRTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
4410{
4411 return pDevIns->pHlpR3->pfnRTCRegister(pDevIns, pRtcReg, ppRtcHlp);
4412}
4413
4414/**
4415 * @copydoc PDMDEVHLPR3::pfnPCIBusRegister
4416 */
4417DECLINLINE(int) PDMDevHlpPCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)
4418{
4419 return pDevIns->pHlpR3->pfnPCIBusRegister(pDevIns, pPciBusReg, ppPciHlpR3);
4420}
4421
4422/**
4423 * @copydoc PDMDEVHLPR3::pfnPICRegister
4424 */
4425DECLINLINE(int) PDMDevHlpPICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
4426{
4427 return pDevIns->pHlpR3->pfnPICRegister(pDevIns, pPicReg, ppPicHlpR3);
4428}
4429
4430/**
4431 * @copydoc PDMDEVHLPR3::pfnAPICRegister
4432 */
4433DECLINLINE(int) PDMDevHlpAPICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)
4434{
4435 return pDevIns->pHlpR3->pfnAPICRegister(pDevIns, pApicReg, ppApicHlpR3);
4436}
4437
4438/**
4439 * @copydoc PDMDEVHLPR3::pfn
4440 */
4441DECLINLINE(int) PDMDevHlpIOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
4442{
4443 return pDevIns->pHlpR3->pfnIOAPICRegister(pDevIns, pIoApicReg, ppIoApicHlpR3);
4444}
4445
4446/**
4447 * @copydoc PDMDEVHLPR3::pfnHPETRegister
4448 */
4449DECLINLINE(int) PDMDevHlpHPETRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
4450{
4451 return pDevIns->pHlpR3->pfnHPETRegister(pDevIns, pHpetReg, ppHpetHlpR3);
4452}
4453
4454/**
4455 * @copydoc PDMDEVHLPR3::pfnDMACRegister
4456 */
4457DECLINLINE(int) PDMDevHlpDMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
4458{
4459 return pDevIns->pHlpR3->pfnDMACRegister(pDevIns, pDmacReg, ppDmacHlp);
4460}
4461
4462/**
4463 * @copydoc PDMDEVHLPR3::pfnDMARegister
4464 */
4465DECLINLINE(int) PDMDevHlpDMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
4466{
4467 return pDevIns->pHlpR3->pfnDMARegister(pDevIns, uChannel, pfnTransferHandler, pvUser);
4468}
4469
4470/**
4471 * @copydoc PDMDEVHLPR3::pfnDMAReadMemory
4472 */
4473DECLINLINE(int) PDMDevHlpDMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
4474{
4475 return pDevIns->pHlpR3->pfnDMAReadMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbRead);
4476}
4477
4478/**
4479 * @copydoc PDMDEVHLPR3::pfnDMAWriteMemory
4480 */
4481DECLINLINE(int) PDMDevHlpDMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
4482{
4483 return pDevIns->pHlpR3->pfnDMAWriteMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbWritten);
4484}
4485
4486/**
4487 * @copydoc PDMDEVHLPR3::pfnDMASetDREQ
4488 */
4489DECLINLINE(int) PDMDevHlpDMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
4490{
4491 return pDevIns->pHlpR3->pfnDMASetDREQ(pDevIns, uChannel, uLevel);
4492}
4493
4494/**
4495 * @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode
4496 */
4497DECLINLINE(uint8_t) PDMDevHlpDMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
4498{
4499 return pDevIns->pHlpR3->pfnDMAGetChannelMode(pDevIns, uChannel);
4500}
4501
4502/**
4503 * @copydoc PDMDEVHLPR3::pfnDMASchedule
4504 */
4505DECLINLINE(void) PDMDevHlpDMASchedule(PPDMDEVINS pDevIns)
4506{
4507 pDevIns->pHlpR3->pfnDMASchedule(pDevIns);
4508}
4509
4510/**
4511 * @copydoc PDMDEVHLPR3::pfnCMOSWrite
4512 */
4513DECLINLINE(int) PDMDevHlpCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
4514{
4515 return pDevIns->pHlpR3->pfnCMOSWrite(pDevIns, iReg, u8Value);
4516}
4517
4518/**
4519 * @copydoc PDMDEVHLPR3::pfnCMOSRead
4520 */
4521DECLINLINE(int) PDMDevHlpCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
4522{
4523 return pDevIns->pHlpR3->pfnCMOSRead(pDevIns, iReg, pu8Value);
4524}
4525
4526/**
4527 * @copydoc PDMDEVHLP::pfnCallR0
4528 */
4529DECLINLINE(int) PDMDevHlpCallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)
4530{
4531 return pDevIns->pHlpR3->pfnCallR0(pDevIns, uOperation, u64Arg);
4532}
4533
4534#endif /* IN_RING3 */
4535
4536/**
4537 * @copydoc PDMDEVHLPR3::pfnGetVM
4538 */
4539DECLINLINE(PVM) PDMDevHlpGetVM(PPDMDEVINS pDevIns)
4540{
4541 return pDevIns->CTX_SUFF(pHlp)->pfnGetVM(pDevIns);
4542}
4543
4544/**
4545 * @copydoc PDMDEVHLPR3::pfnGetVMCPU
4546 */
4547DECLINLINE(PVMCPU) PDMDevHlpGetVMCPU(PPDMDEVINS pDevIns)
4548{
4549 return pDevIns->CTX_SUFF(pHlp)->pfnGetVMCPU(pDevIns);
4550}
4551
4552/**
4553 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGet
4554 */
4555DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGet(PPDMDEVINS pDevIns)
4556{
4557 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGet(pDevIns);
4558}
4559
4560/**
4561 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
4562 */
4563DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetFreq(PPDMDEVINS pDevIns)
4564{
4565 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetFreq(pDevIns);
4566}
4567
4568/**
4569 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
4570 */
4571DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetNano(PPDMDEVINS pDevIns)
4572{
4573 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetNano(pDevIns);
4574}
4575
4576#ifdef IN_RING3
4577
4578/**
4579 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap
4580 */
4581DECLINLINE(int) PDMDevHlpRegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize)
4582{
4583 return pDevIns->pHlpR3->pfnRegisterVMMDevHeap(pDevIns, GCPhys, pvHeap, cbSize);
4584}
4585
4586/**
4587 * @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap
4588 */
4589DECLINLINE(int) PDMDevHlpUnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
4590{
4591 return pDevIns->pHlpR3->pfnUnregisterVMMDevHeap(pDevIns, GCPhys);
4592}
4593
4594/**
4595 * @copydoc PDMDEVHLPR3::pfnVMReset
4596 */
4597DECLINLINE(int) PDMDevHlpVMReset(PPDMDEVINS pDevIns)
4598{
4599 return pDevIns->pHlpR3->pfnVMReset(pDevIns);
4600}
4601
4602/**
4603 * @copydoc PDMDEVHLPR3::pfnVMSuspend
4604 */
4605DECLINLINE(int) PDMDevHlpVMSuspend(PPDMDEVINS pDevIns)
4606{
4607 return pDevIns->pHlpR3->pfnVMSuspend(pDevIns);
4608}
4609
4610/**
4611 * @copydoc PDMDEVHLPR3::pfnVMSuspendSaveAndPowerOff
4612 */
4613DECLINLINE(int) PDMDevHlpVMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
4614{
4615 return pDevIns->pHlpR3->pfnVMSuspendSaveAndPowerOff(pDevIns);
4616}
4617
4618/**
4619 * @copydoc PDMDEVHLPR3::pfnVMPowerOff
4620 */
4621DECLINLINE(int) PDMDevHlpVMPowerOff(PPDMDEVINS pDevIns)
4622{
4623 return pDevIns->pHlpR3->pfnVMPowerOff(pDevIns);
4624}
4625
4626#endif /* IN_RING3 */
4627
4628/**
4629 * @copydoc PDMDEVHLPR3::pfnA20IsEnabled
4630 */
4631DECLINLINE(bool) PDMDevHlpA20IsEnabled(PPDMDEVINS pDevIns)
4632{
4633 return pDevIns->CTX_SUFF(pHlp)->pfnA20IsEnabled(pDevIns);
4634}
4635
4636#ifdef IN_RING3
4637
4638/**
4639 * @copydoc PDMDEVHLPR3::pfnGetCpuId
4640 */
4641DECLINLINE(void) PDMDevHlpGetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
4642{
4643 pDevIns->pHlpR3->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx);
4644}
4645
4646#endif /* IN_RING3 */
4647#ifdef IN_RING0
4648
4649/**
4650 * @copydoc PDMDEVHLPR0::pfnCanEmulateIoBlock
4651 */
4652DECLINLINE(bool) PDMDevHlpCanEmulateIoBlock(PPDMDEVINS pDevIns)
4653{
4654 return pDevIns->CTX_SUFF(pHlp)->pfnCanEmulateIoBlock(pDevIns);
4655}
4656
4657#endif /* IN_RING0 */
4658
4659
4660
4661
4662/** Pointer to callbacks provided to the VBoxDeviceRegister() call. */
4663typedef struct PDMDEVREGCB *PPDMDEVREGCB;
4664
4665/**
4666 * Callbacks for VBoxDeviceRegister().
4667 */
4668typedef struct PDMDEVREGCB
4669{
4670 /** Interface version.
4671 * This is set to PDM_DEVREG_CB_VERSION. */
4672 uint32_t u32Version;
4673
4674 /**
4675 * Registers a device with the current VM instance.
4676 *
4677 * @returns VBox status code.
4678 * @param pCallbacks Pointer to the callback table.
4679 * @param pReg Pointer to the device registration record.
4680 * This data must be permanent and readonly.
4681 */
4682 DECLR3CALLBACKMEMBER(int, pfnRegister,(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pReg));
4683} PDMDEVREGCB;
4684
4685/** Current version of the PDMDEVREGCB structure. */
4686#define PDM_DEVREG_CB_VERSION PDM_VERSION_MAKE(0xffe3, 1, 0)
4687
4688
4689/**
4690 * The VBoxDevicesRegister callback function.
4691 *
4692 * PDM will invoke this function after loading a device module and letting
4693 * the module decide which devices to register and how to handle conflicts.
4694 *
4695 * @returns VBox status code.
4696 * @param pCallbacks Pointer to the callback table.
4697 * @param u32Version VBox version number.
4698 */
4699typedef DECLCALLBACK(int) FNPDMVBOXDEVICESREGISTER(PPDMDEVREGCB pCallbacks, uint32_t u32Version);
4700
4701/** @} */
4702
4703RT_C_DECLS_END
4704
4705#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