VirtualBox

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

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

PIC: Reversed IRQ flip-flop polarity.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 175.3 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 - deassert and then assert the IRQ 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 * @param cbBinary The size of the binary pointer. This must
2282 * be equal or smaller than @a cbRange.
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,
2290 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc));
2291
2292 /**
2293 * Changes the protection of shadowed ROM mapping.
2294 *
2295 * This is intented for use by the system BIOS, chipset or device in question to
2296 * change the protection of shadowed ROM code after init and on reset.
2297 *
2298 * @param pDevIns The device instance.
2299 * @param GCPhysStart Where the mapping starts.
2300 * @param cbRange The size of the mapping.
2301 * @param enmProt The new protection type.
2302 */
2303 DECLR3CALLBACKMEMBER(int, pfnROMProtectShadow,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, PGMROMPROT enmProt));
2304
2305 /**
2306 * Register a save state data unit.
2307 *
2308 * @returns VBox status.
2309 * @param pDevIns The device instance.
2310 * @param pszName Data unit name.
2311 * @param uInstance The instance identifier of the data unit.
2312 * This must together with the name be unique.
2313 * @param uVersion Data layout version number.
2314 * @param cbGuess The approximate amount of data in the unit.
2315 * Only for progress indicators.
2316 * @param pszBefore Name of data unit which we should be put in
2317 * front of. Optional (NULL).
2318 *
2319 * @param pfnLivePrep Prepare live save callback, optional.
2320 * @param pfnLiveExec Execute live save callback, optional.
2321 * @param pfnLiveVote Vote live save callback, optional.
2322 *
2323 * @param pfnSavePrep Prepare save callback, optional.
2324 * @param pfnSaveExec Execute save callback, optional.
2325 * @param pfnSaveDone Done save callback, optional.
2326 *
2327 * @param pfnLoadPrep Prepare load callback, optional.
2328 * @param pfnLoadExec Execute load callback, optional.
2329 * @param pfnLoadDone Done load callback, optional.
2330 */
2331 DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
2332 PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
2333 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
2334 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone));
2335
2336 /**
2337 * Creates a timer.
2338 *
2339 * @returns VBox status.
2340 * @param pDevIns The device instance.
2341 * @param enmClock The clock to use on this timer.
2342 * @param pfnCallback Callback function.
2343 * @param pvUser User argument for the callback.
2344 * @param fFlags Flags, see TMTIMER_FLAGS_*.
2345 * @param pszDesc Pointer to description string which must stay around
2346 * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
2347 * @param ppTimer Where to store the timer on success.
2348 */
2349 DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
2350
2351 /**
2352 * Get the real world UTC time adjusted for VM lag, user offset and warpdrive.
2353 *
2354 * @returns pTime.
2355 * @param pDevIns The device instance.
2356 * @param pTime Where to store the time.
2357 */
2358 DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnTMUtcNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime));
2359
2360 /**
2361 * Read physical memory.
2362 *
2363 * @returns VINF_SUCCESS (for now).
2364 * @param pDevIns The device instance.
2365 * @param GCPhys Physical address start reading from.
2366 * @param pvBuf Where to put the read bits.
2367 * @param cbRead How many bytes to read.
2368 * @thread Any thread, but the call may involve the emulation thread.
2369 */
2370 DECLR3CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
2371
2372 /**
2373 * Write to physical memory.
2374 *
2375 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
2376 * @param pDevIns The device instance.
2377 * @param GCPhys Physical address to write to.
2378 * @param pvBuf What to write.
2379 * @param cbWrite How many bytes to write.
2380 * @thread Any thread, but the call may involve the emulation thread.
2381 */
2382 DECLR3CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
2383
2384 /**
2385 * Requests the mapping of a guest page into ring-3.
2386 *
2387 * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
2388 * release it.
2389 *
2390 * This API will assume your intention is to write to the page, and will
2391 * therefore replace shared and zero pages. If you do not intend to modify the
2392 * page, use the pfnPhysGCPhys2CCPtrReadOnly() API.
2393 *
2394 * @returns VBox status code.
2395 * @retval VINF_SUCCESS on success.
2396 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
2397 * backing or if the page has any active access handlers. The caller
2398 * must fall back on using PGMR3PhysWriteExternal.
2399 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
2400 *
2401 * @param pVM The VM handle.
2402 * @param GCPhys The guest physical address of the page that
2403 * should be mapped.
2404 * @param fFlags Flags reserved for future use, MBZ.
2405 * @param ppv Where to store the address corresponding to
2406 * GCPhys.
2407 * @param pLock Where to store the lock information that
2408 * pfnPhysReleasePageMappingLock needs.
2409 *
2410 * @remark Avoid calling this API from within critical sections (other than the
2411 * PGM one) because of the deadlock risk when we have to delegating the
2412 * task to an EMT.
2413 * @thread Any.
2414 */
2415 DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtr,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock));
2416
2417 /**
2418 * Requests the mapping of a guest page into ring-3, external threads.
2419 *
2420 * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
2421 * release it.
2422 *
2423 * @returns VBox status code.
2424 * @retval VINF_SUCCESS on success.
2425 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
2426 * backing or if the page as an active ALL access handler. The caller
2427 * must fall back on using PGMPhysRead.
2428 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
2429 *
2430 * @param pDevIns The device instance.
2431 * @param GCPhys The guest physical address of the page that
2432 * should be mapped.
2433 * @param fFlags Flags reserved for future use, MBZ.
2434 * @param ppv Where to store the address corresponding to
2435 * GCPhys.
2436 * @param pLock Where to store the lock information that
2437 * pfnPhysReleasePageMappingLock needs.
2438 *
2439 * @remark Avoid calling this API from within critical sections.
2440 * @thread Any.
2441 */
2442 DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock));
2443
2444 /**
2445 * Release the mapping of a guest page.
2446 *
2447 * This is the counter part of pfnPhysGCPhys2CCPtr and
2448 * pfnPhysGCPhys2CCPtrReadOnly.
2449 *
2450 * @param pDevIns The device instance.
2451 * @param pLock The lock structure initialized by the mapping
2452 * function.
2453 */
2454 DECLR3CALLBACKMEMBER(void, pfnPhysReleasePageMappingLock,(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock));
2455
2456 /**
2457 * Read guest physical memory by virtual address.
2458 *
2459 * @param pDevIns The device instance.
2460 * @param pvDst Where to put the read bits.
2461 * @param GCVirtSrc Guest virtual address to start reading from.
2462 * @param cb How many bytes to read.
2463 * @thread The emulation thread.
2464 */
2465 DECLR3CALLBACKMEMBER(int, pfnPhysReadGCVirt,(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb));
2466
2467 /**
2468 * Write to guest physical memory by virtual address.
2469 *
2470 * @param pDevIns The device instance.
2471 * @param GCVirtDst Guest virtual address to write to.
2472 * @param pvSrc What to write.
2473 * @param cb How many bytes to write.
2474 * @thread The emulation thread.
2475 */
2476 DECLR3CALLBACKMEMBER(int, pfnPhysWriteGCVirt,(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb));
2477
2478 /**
2479 * Convert a guest virtual address to a guest physical address.
2480 *
2481 * @returns VBox status code.
2482 * @param pDevIns The device instance.
2483 * @param GCPtr Guest virtual address.
2484 * @param pGCPhys Where to store the GC physical address
2485 * corresponding to GCPtr.
2486 * @thread The emulation thread.
2487 * @remark Careful with page boundaries.
2488 */
2489 DECLR3CALLBACKMEMBER(int, pfnPhysGCPtr2GCPhys, (PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys));
2490
2491 /**
2492 * Allocate memory which is associated with current VM instance
2493 * and automatically freed on it's destruction.
2494 *
2495 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
2496 * @param pDevIns The device instance.
2497 * @param cb Number of bytes to allocate.
2498 */
2499 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAlloc,(PPDMDEVINS pDevIns, size_t cb));
2500
2501 /**
2502 * Allocate memory which is associated with current VM instance
2503 * and automatically freed on it's destruction. The memory is ZEROed.
2504 *
2505 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
2506 * @param pDevIns The device instance.
2507 * @param cb Number of bytes to allocate.
2508 */
2509 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAllocZ,(PPDMDEVINS pDevIns, size_t cb));
2510
2511 /**
2512 * Free memory allocated with pfnMMHeapAlloc() and pfnMMHeapAllocZ().
2513 *
2514 * @param pDevIns The device instance.
2515 * @param pv Pointer to the memory to free.
2516 */
2517 DECLR3CALLBACKMEMBER(void, pfnMMHeapFree,(PPDMDEVINS pDevIns, void *pv));
2518
2519 /**
2520 * Gets the VM state.
2521 *
2522 * @returns VM state.
2523 * @param pDevIns The device instance.
2524 * @thread Any thread (just keep in mind that it's volatile info).
2525 */
2526 DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
2527
2528 /**
2529 * Checks if the VM was teleported and hasn't been fully resumed yet.
2530 *
2531 * @returns true / false.
2532 * @param pDevIns The device instance.
2533 * @thread Any thread.
2534 */
2535 DECLR3CALLBACKMEMBER(bool, pfnVMTeleportedAndNotFullyResumedYet,(PPDMDEVINS pDevIns));
2536
2537 /**
2538 * Set the VM error message
2539 *
2540 * @returns rc.
2541 * @param pDevIns The device instance.
2542 * @param rc VBox status code.
2543 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2544 * @param pszFormat Error message format string.
2545 * @param ... Error message arguments.
2546 */
2547 DECLR3CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
2548
2549 /**
2550 * Set the VM error message
2551 *
2552 * @returns rc.
2553 * @param pDevIns The device instance.
2554 * @param rc VBox status code.
2555 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2556 * @param pszFormat Error message format string.
2557 * @param va Error message arguments.
2558 */
2559 DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
2560
2561 /**
2562 * Set the VM runtime error message
2563 *
2564 * @returns VBox status code.
2565 * @param pDevIns The device instance.
2566 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
2567 * @param pszErrorId Error ID string.
2568 * @param pszFormat Error message format string.
2569 * @param ... Error message arguments.
2570 */
2571 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
2572
2573 /**
2574 * Set the VM runtime error message
2575 *
2576 * @returns VBox status code.
2577 * @param pDevIns The device instance.
2578 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
2579 * @param pszErrorId Error ID string.
2580 * @param pszFormat Error message format string.
2581 * @param va Error message arguments.
2582 */
2583 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
2584
2585 /**
2586 * Stops the VM and enters the debugger to look at the guest state.
2587 *
2588 * Use the PDMDeviceDBGFStop() inline function with the RT_SRC_POS macro instead of
2589 * invoking this function directly.
2590 *
2591 * @returns VBox status code which must be passed up to the VMM.
2592 * @param pDevIns The device instance.
2593 * @param pszFile Filename of the assertion location.
2594 * @param iLine The linenumber of the assertion location.
2595 * @param pszFunction Function of the assertion location.
2596 * @param pszFormat Message. (optional)
2597 * @param args Message parameters.
2598 */
2599 DECLR3CALLBACKMEMBER(int, pfnDBGFStopV,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args));
2600
2601 /**
2602 * Register a info handler with DBGF,
2603 *
2604 * @returns VBox status code.
2605 * @param pDevIns The device instance.
2606 * @param pszName The identifier of the info.
2607 * @param pszDesc The description of the info and any arguments
2608 * the handler may take.
2609 * @param pfnHandler The handler function to be called to display the
2610 * info.
2611 */
2612 DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler));
2613
2614 /**
2615 * Registers a statistics sample if statistics are enabled.
2616 *
2617 * @param pDevIns Device instance of the DMA.
2618 * @param pvSample Pointer to the sample.
2619 * @param enmType Sample type. This indicates what pvSample is
2620 * pointing at.
2621 * @param pszName Sample name. The name is on this form
2622 * "/<component>/<sample>". Further nesting is
2623 * possible.
2624 * @param enmUnit Sample unit.
2625 * @param pszDesc Sample description.
2626 */
2627 DECLR3CALLBACKMEMBER(void, pfnSTAMRegister,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc));
2628
2629 /**
2630 * Same as pfnSTAMRegister except that the name is specified in a
2631 * RTStrPrintf like fashion.
2632 *
2633 * @returns VBox status.
2634 * @param pDevIns Device instance of the DMA.
2635 * @param pvSample Pointer to the sample.
2636 * @param enmType Sample type. This indicates what pvSample is
2637 * pointing at.
2638 * @param enmVisibility Visibility type specifying whether unused
2639 * statistics should be visible or not.
2640 * @param enmUnit Sample unit.
2641 * @param pszDesc Sample description.
2642 * @param pszName The sample name format string.
2643 * @param ... Arguments to the format string.
2644 */
2645 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterF,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
2646 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...));
2647
2648 /**
2649 * Same as pfnSTAMRegister except that the name is specified in a
2650 * RTStrPrintfV like fashion.
2651 *
2652 * @returns VBox status.
2653 * @param pDevIns Device instance of the DMA.
2654 * @param pvSample Pointer to the sample.
2655 * @param enmType Sample type. This indicates what pvSample is
2656 * pointing at.
2657 * @param enmVisibility Visibility type specifying whether unused
2658 * statistics should be visible or not.
2659 * @param enmUnit Sample unit.
2660 * @param pszDesc Sample description.
2661 * @param pszName The sample name format string.
2662 * @param args Arguments to the format string.
2663 */
2664 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
2665 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args));
2666
2667 /**
2668 * Registers the device with the default PCI bus.
2669 *
2670 * @returns VBox status code.
2671 * @param pDevIns The device instance.
2672 * @param pPciDev The PCI device structure.
2673 * Any PCI enabled device must keep this in it's instance data!
2674 * Fill in the PCI data config before registration, please.
2675 * @remark This is the simple interface, a Ex interface will be created if
2676 * more features are needed later.
2677 */
2678 DECLR3CALLBACKMEMBER(int, pfnPCIRegister,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev));
2679
2680 /**
2681 * Initialize MSI support in a PCI device.
2682 *
2683 * @returns VBox status code.
2684 * @param pDevIns The device instance.
2685 * @param pMsiReg MSI registartion structure.
2686 */
2687 DECLR3CALLBACKMEMBER(int, pfnPCIRegisterMsi,(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg));
2688
2689 /**
2690 * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
2691 *
2692 * @returns VBox status code.
2693 * @param pDevIns The device instance.
2694 * @param iRegion The region number.
2695 * @param cbRegion Size of the region.
2696 * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
2697 * @param pfnCallback Callback for doing the mapping.
2698 */
2699 DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
2700
2701 /**
2702 * Register PCI configuration space read/write callbacks.
2703 *
2704 * @param pDevIns The device instance.
2705 * @param pPciDev The PCI device structure.
2706 * If NULL the default PCI device for this device instance is used.
2707 * @param pfnRead Pointer to the user defined PCI config read function.
2708 * @param ppfnReadOld Pointer to function pointer which will receive the old (default)
2709 * PCI config read function. This way, user can decide when (and if)
2710 * to call default PCI config read function. Can be NULL.
2711 * @param pfnWrite Pointer to the user defined PCI config write function.
2712 * @param pfnWriteOld Pointer to function pointer which will receive the old (default)
2713 * PCI config write function. This way, user can decide when (and if)
2714 * to call default PCI config write function. Can be NULL.
2715 * @thread EMT
2716 */
2717 DECLR3CALLBACKMEMBER(void, pfnPCISetConfigCallbacks,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
2718 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
2719
2720 /**
2721 * Set the IRQ for a PCI device.
2722 *
2723 * @param pDevIns The device instance.
2724 * @param iIrq IRQ number to set.
2725 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2726 * @thread Any thread, but will involve the emulation thread.
2727 */
2728 DECLR3CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2729
2730 /**
2731 * Set the IRQ for a PCI device, but don't wait for EMT to process
2732 * the request when not called from EMT.
2733 *
2734 * @param pDevIns The device instance.
2735 * @param iIrq IRQ number to set.
2736 * @param iLevel IRQ level.
2737 * @thread Any thread, but will involve the emulation thread.
2738 */
2739 DECLR3CALLBACKMEMBER(void, pfnPCISetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2740
2741 /**
2742 * Set ISA IRQ for a device.
2743 *
2744 * @param pDevIns The device instance.
2745 * @param iIrq IRQ number to set.
2746 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2747 * @thread Any thread, but will involve the emulation thread.
2748 */
2749 DECLR3CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2750
2751 /**
2752 * Set the ISA IRQ for a device, but don't wait for EMT to process
2753 * the request when not called from EMT.
2754 *
2755 * @param pDevIns The device instance.
2756 * @param iIrq IRQ number to set.
2757 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2758 * @thread Any thread, but will involve the emulation thread.
2759 */
2760 DECLR3CALLBACKMEMBER(void, pfnISASetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2761
2762 /**
2763 * Attaches a driver (chain) to the device.
2764 *
2765 * The first call for a LUN this will serve as a registartion of the LUN. The pBaseInterface and
2766 * the pszDesc string will be registered with that LUN and kept around for PDMR3QueryDeviceLun().
2767 *
2768 * @returns VBox status code.
2769 * @param pDevIns The device instance.
2770 * @param iLun The logical unit to attach.
2771 * @param pBaseInterface Pointer to the base interface for that LUN. (device side / down)
2772 * @param ppBaseInterface Where to store the pointer to the base interface. (driver side / up)
2773 * @param pszDesc Pointer to a string describing the LUN. This string must remain valid
2774 * for the live of the device instance.
2775 */
2776 DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc));
2777
2778 /**
2779 * Create a queue.
2780 *
2781 * @returns VBox status code.
2782 * @param pDevIns The device instance.
2783 * @param cbItem The size of a queue item.
2784 * @param cItems The number of items in the queue.
2785 * @param cMilliesInterval The number of milliseconds between polling the queue.
2786 * If 0 then the emulation thread will be notified whenever an item arrives.
2787 * @param pfnCallback The consumer function.
2788 * @param fRZEnabled Set if the queue should work in RC and R0.
2789 * @param pszName The queue base name. The instance number will be
2790 * appended automatically.
2791 * @param ppQueue Where to store the queue handle on success.
2792 * @thread The emulation thread.
2793 */
2794 DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
2795 PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue));
2796
2797 /**
2798 * Initializes a PDM critical section.
2799 *
2800 * The PDM critical sections are derived from the IPRT critical sections, but
2801 * works in RC and R0 as well.
2802 *
2803 * @returns VBox status code.
2804 * @param pDevIns The device instance.
2805 * @param pCritSect Pointer to the critical section.
2806 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2807 * @param pszNameFmt Format string for naming the critical section.
2808 * For statistics and lock validation.
2809 * @param va Arguments for the format string.
2810 */
2811 DECLR3CALLBACKMEMBER(int, pfnCritSectInit,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
2812 const char *pszNameFmt, va_list va));
2813
2814 /**
2815 * Creates a PDM thread.
2816 *
2817 * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
2818 * resuming, and destroying the thread as the VM state changes.
2819 *
2820 * @returns VBox status code.
2821 * @param pDevIns The device instance.
2822 * @param ppThread Where to store the thread 'handle'.
2823 * @param pvUser The user argument to the thread function.
2824 * @param pfnThread The thread function.
2825 * @param pfnWakeup The wakup callback. This is called on the EMT
2826 * thread when a state change is pending.
2827 * @param cbStack See RTThreadCreate.
2828 * @param enmType See RTThreadCreate.
2829 * @param pszName See RTThreadCreate.
2830 */
2831 DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
2832 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
2833
2834 /**
2835 * Set up asynchronous handling of a suspend, reset or power off notification.
2836 *
2837 * This shall only be called when getting the notification. It must be called
2838 * for each one.
2839 *
2840 * @returns VBox status code.
2841 * @param pDevIns The device instance.
2842 * @param pfnAsyncNotify The callback.
2843 * @thread EMT(0)
2844 */
2845 DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify));
2846
2847 /**
2848 * Notify EMT(0) that the device has completed the asynchronous notification
2849 * handling.
2850 *
2851 * This can be called at any time, spurious calls will simply be ignored.
2852 *
2853 * @param pDevIns The device instance.
2854 * @thread Any
2855 */
2856 DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMDEVINS pDevIns));
2857
2858 /**
2859 * Register the RTC device.
2860 *
2861 * @returns VBox status code.
2862 * @param pDevIns The device instance.
2863 * @param pRtcReg Pointer to a RTC registration structure.
2864 * @param ppRtcHlp Where to store the pointer to the helper
2865 * functions.
2866 */
2867 DECLR3CALLBACKMEMBER(int, pfnRTCRegister,(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp));
2868
2869 /**
2870 * Register the PCI Bus.
2871 *
2872 * @returns VBox status code.
2873 * @param pDevIns The device instance.
2874 * @param pPciBusReg Pointer to PCI bus registration structure.
2875 * @param ppPciHlpR3 Where to store the pointer to the PCI Bus
2876 * helpers.
2877 */
2878 DECLR3CALLBACKMEMBER(int, pfnPCIBusRegister,(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3));
2879
2880 /**
2881 * Register the PIC device.
2882 *
2883 * @returns VBox status code.
2884 * @param pDevIns The device instance.
2885 * @param pPicReg Pointer to a PIC registration structure.
2886 * @param ppPicHlpR3 Where to store the pointer to the PIC HC
2887 * helpers.
2888 */
2889 DECLR3CALLBACKMEMBER(int, pfnPICRegister,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3));
2890
2891 /**
2892 * Register the APIC device.
2893 *
2894 * @returns VBox status code.
2895 * @param pDevIns The device instance.
2896 * @param pApicReg Pointer to a APIC registration structure.
2897 * @param ppApicHlpR3 Where to store the pointer to the APIC helpers.
2898 */
2899 DECLR3CALLBACKMEMBER(int, pfnAPICRegister,(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3));
2900
2901 /**
2902 * Register the I/O APIC device.
2903 *
2904 * @returns VBox status code.
2905 * @param pDevIns The device instance.
2906 * @param pIoApicReg Pointer to a I/O APIC registration structure.
2907 * @param ppIoApicHlpR3 Where to store the pointer to the IOAPIC
2908 * helpers.
2909 */
2910 DECLR3CALLBACKMEMBER(int, pfnIOAPICRegister,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3));
2911
2912 /**
2913 * Register the HPET device.
2914 *
2915 * @returns VBox status code.
2916 * @param pDevIns The device instance.
2917 * @param pHpetReg Pointer to a HPET registration structure.
2918 * @param ppHpetHlpR3 Where to store the pointer to the HPET
2919 * helpers.
2920 */
2921 DECLR3CALLBACKMEMBER(int, pfnHPETRegister,(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3));
2922
2923 /**
2924 * Register the DMA device.
2925 *
2926 * @returns VBox status code.
2927 * @param pDevIns The device instance.
2928 * @param pDmacReg Pointer to a DMAC registration structure.
2929 * @param ppDmacHlp Where to store the pointer to the DMA helpers.
2930 */
2931 DECLR3CALLBACKMEMBER(int, pfnDMACRegister,(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp));
2932
2933 /**
2934 * Register transfer function for DMA channel.
2935 *
2936 * @returns VBox status code.
2937 * @param pDevIns The device instance.
2938 * @param uChannel Channel number.
2939 * @param pfnTransferHandler Device specific transfer callback function.
2940 * @param pvUser User pointer to pass to the callback.
2941 * @thread EMT
2942 */
2943 DECLR3CALLBACKMEMBER(int, pfnDMARegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
2944
2945 /**
2946 * Read memory.
2947 *
2948 * @returns VBox status code.
2949 * @param pDevIns The device instance.
2950 * @param uChannel Channel number.
2951 * @param pvBuffer Pointer to target buffer.
2952 * @param off DMA position.
2953 * @param cbBlock Block size.
2954 * @param pcbRead Where to store the number of bytes which was
2955 * read. optional.
2956 * @thread EMT
2957 */
2958 DECLR3CALLBACKMEMBER(int, pfnDMAReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead));
2959
2960 /**
2961 * Write memory.
2962 *
2963 * @returns VBox status code.
2964 * @param pDevIns The device instance.
2965 * @param uChannel Channel number.
2966 * @param pvBuffer Memory to write.
2967 * @param off DMA position.
2968 * @param cbBlock Block size.
2969 * @param pcbWritten Where to store the number of bytes which was
2970 * written. optional.
2971 * @thread EMT
2972 */
2973 DECLR3CALLBACKMEMBER(int, pfnDMAWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten));
2974
2975 /**
2976 * Set the DREQ line.
2977 *
2978 * @returns VBox status code.
2979 * @param pDevIns Device instance.
2980 * @param uChannel Channel number.
2981 * @param uLevel Level of the line.
2982 * @thread EMT
2983 */
2984 DECLR3CALLBACKMEMBER(int, pfnDMASetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
2985
2986 /**
2987 * Get channel mode.
2988 *
2989 * @returns Channel mode. See specs.
2990 * @param pDevIns The device instance.
2991 * @param uChannel Channel number.
2992 * @thread EMT
2993 */
2994 DECLR3CALLBACKMEMBER(uint8_t, pfnDMAGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
2995
2996 /**
2997 * Schedule DMA execution.
2998 *
2999 * @param pDevIns The device instance.
3000 * @thread Any thread.
3001 */
3002 DECLR3CALLBACKMEMBER(void, pfnDMASchedule,(PPDMDEVINS pDevIns));
3003
3004 /**
3005 * Write CMOS value and update the checksum(s).
3006 *
3007 * @returns VBox status code.
3008 * @param pDevIns The device instance.
3009 * @param iReg The CMOS register index.
3010 * @param u8Value The CMOS register value.
3011 * @thread EMT
3012 */
3013 DECLR3CALLBACKMEMBER(int, pfnCMOSWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
3014
3015 /**
3016 * Read CMOS value.
3017 *
3018 * @returns VBox status code.
3019 * @param pDevIns The device instance.
3020 * @param iReg The CMOS register index.
3021 * @param pu8Value Where to store the CMOS register value.
3022 * @thread EMT
3023 */
3024 DECLR3CALLBACKMEMBER(int, pfnCMOSRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
3025
3026 /**
3027 * Assert that the current thread is the emulation thread.
3028 *
3029 * @returns True if correct.
3030 * @returns False if wrong.
3031 * @param pDevIns The device instance.
3032 * @param pszFile Filename of the assertion location.
3033 * @param iLine The linenumber of the assertion location.
3034 * @param pszFunction Function of the assertion location.
3035 */
3036 DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
3037
3038 /**
3039 * Assert that the current thread is NOT the emulation thread.
3040 *
3041 * @returns True if correct.
3042 * @returns False if wrong.
3043 * @param pDevIns The device instance.
3044 * @param pszFile Filename of the assertion location.
3045 * @param iLine The linenumber of the assertion location.
3046 * @param pszFunction Function of the assertion location.
3047 */
3048 DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
3049
3050 /**
3051 * Resolves the symbol for a raw-mode context interface.
3052 *
3053 * @returns VBox status code.
3054 * @param pDevIns The device instance.
3055 * @param pvInterface The interface structure.
3056 * @param cbInterface The size of the interface structure.
3057 * @param pszSymPrefix What to prefix the symbols in the list with
3058 * before resolving them. This must start with
3059 * 'dev' and contain the driver name.
3060 * @param pszSymList List of symbols corresponding to the interface.
3061 * There is generally a there is generally a define
3062 * holding this list associated with the interface
3063 * definition (INTERFACE_SYM_LIST). For more
3064 * details see PDMR3LdrGetInterfaceSymbols.
3065 * @thread EMT
3066 */
3067 DECLR3CALLBACKMEMBER(int, pfnLdrGetRCInterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
3068 const char *pszSymPrefix, const char *pszSymList));
3069
3070 /**
3071 * Resolves the symbol for a ring-0 context interface.
3072 *
3073 * @returns VBox status code.
3074 * @param pDevIns The device instance.
3075 * @param pvInterface The interface structure.
3076 * @param cbInterface The size of the interface structure.
3077 * @param pszSymPrefix What to prefix the symbols in the list with
3078 * before resolving them. This must start with
3079 * 'dev' and contain the driver name.
3080 * @param pszSymList List of symbols corresponding to the interface.
3081 * There is generally a there is generally a define
3082 * holding this list associated with the interface
3083 * definition (INTERFACE_SYM_LIST). For more
3084 * details see PDMR3LdrGetInterfaceSymbols.
3085 * @thread EMT
3086 */
3087 DECLR3CALLBACKMEMBER(int, pfnLdrGetR0InterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
3088 const char *pszSymPrefix, const char *pszSymList));
3089
3090 /**
3091 * Call the ring-0 request handler routine of the device.
3092 *
3093 * For this to work, the device must be ring-0 enabled and export a request
3094 * handler function. The name of the function must be the device name in
3095 * the PDMDRVREG struct prefixed with 'drvR0' and suffixed with
3096 * 'ReqHandler'. The device name will be captialized. It shall take the
3097 * exact same arguments as this function and be declared using
3098 * PDMBOTHCBDECL. See FNPDMDEVREQHANDLERR0.
3099 *
3100 * Unlike PDMDrvHlpCallR0, this is current unsuitable for more than a call
3101 * or two as the handler address will be resolved on each invocation. This
3102 * is the reason for the EMT only restriction as well.
3103 *
3104 * @returns VBox status code.
3105 * @retval VERR_SYMBOL_NOT_FOUND if the device doesn't export the required
3106 * handler function.
3107 * @retval VERR_ACCESS_DENIED if the device isn't ring-0 capable.
3108 *
3109 * @param pDevIns The device instance.
3110 * @param uOperation The operation to perform.
3111 * @param u64Arg 64-bit integer argument.
3112 * @thread EMT
3113 */
3114 DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg));
3115
3116 /** Space reserved for future members.
3117 * @{ */
3118 DECLR3CALLBACKMEMBER(void, pfnReserved1,(void));
3119 DECLR3CALLBACKMEMBER(void, pfnReserved2,(void));
3120 DECLR3CALLBACKMEMBER(void, pfnReserved3,(void));
3121 DECLR3CALLBACKMEMBER(void, pfnReserved4,(void));
3122 DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
3123 DECLR3CALLBACKMEMBER(void, pfnReserved6,(void));
3124 DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
3125 DECLR3CALLBACKMEMBER(void, pfnReserved8,(void));
3126 DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));
3127 DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));
3128 /** @} */
3129
3130
3131 /** API available to trusted devices only.
3132 *
3133 * These APIs are providing unrestricted access to the guest and the VM,
3134 * or they are interacting intimately with PDM.
3135 *
3136 * @{
3137 */
3138 /**
3139 * Gets the VM handle. Restricted API.
3140 *
3141 * @returns VM Handle.
3142 * @param pDevIns The device instance.
3143 */
3144 DECLR3CALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
3145
3146 /**
3147 * Gets the VMCPU handle. Restricted API.
3148 *
3149 * @returns VMCPU Handle.
3150 * @param pDevIns The device instance.
3151 */
3152 DECLR3CALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
3153
3154 /**
3155 * Registers the VMM device heap
3156 *
3157 * @returns VBox status code.
3158 * @param pDevIns The device instance.
3159 * @param GCPhys The physical address.
3160 * @param pvHeap Ring 3 heap pointer.
3161 * @param cbSize Size of the heap.
3162 * @thread EMT.
3163 */
3164 DECLR3CALLBACKMEMBER(int, pfnRegisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize));
3165
3166 /**
3167 * Unregisters the VMM device heap
3168 *
3169 * @returns VBox status code.
3170 * @param pDevIns The device instance.
3171 * @param GCPhys The physical address.
3172 * @thread EMT.
3173 */
3174 DECLR3CALLBACKMEMBER(int, pfnUnregisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys));
3175
3176 /**
3177 * Resets the VM.
3178 *
3179 * @returns The appropriate VBox status code to pass around on reset.
3180 * @param pDevIns The device instance.
3181 * @thread The emulation thread.
3182 */
3183 DECLR3CALLBACKMEMBER(int, pfnVMReset,(PPDMDEVINS pDevIns));
3184
3185 /**
3186 * Suspends the VM.
3187 *
3188 * @returns The appropriate VBox status code to pass around on suspend.
3189 * @param pDevIns The device instance.
3190 * @thread The emulation thread.
3191 */
3192 DECLR3CALLBACKMEMBER(int, pfnVMSuspend,(PPDMDEVINS pDevIns));
3193
3194 /**
3195 * Suspends, saves and powers off the VM.
3196 *
3197 * @returns The appropriate VBox status code to pass around.
3198 * @param pDevIns The device instance.
3199 * @thread An emulation thread.
3200 */
3201 DECLR3CALLBACKMEMBER(int, pfnVMSuspendSaveAndPowerOff,(PPDMDEVINS pDevIns));
3202
3203 /**
3204 * Power off the VM.
3205 *
3206 * @returns The appropriate VBox status code to pass around on power off.
3207 * @param pDevIns The device instance.
3208 * @thread The emulation thread.
3209 */
3210 DECLR3CALLBACKMEMBER(int, pfnVMPowerOff,(PPDMDEVINS pDevIns));
3211
3212 /**
3213 * Checks if the Gate A20 is enabled or not.
3214 *
3215 * @returns true if A20 is enabled.
3216 * @returns false if A20 is disabled.
3217 * @param pDevIns The device instance.
3218 * @thread The emulation thread.
3219 */
3220 DECLR3CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
3221
3222 /**
3223 * Enables or disables the Gate A20.
3224 *
3225 * @param pDevIns The device instance.
3226 * @param fEnable Set this flag to enable the Gate A20; clear it
3227 * to disable.
3228 * @thread The emulation thread.
3229 */
3230 DECLR3CALLBACKMEMBER(void, pfnA20Set,(PPDMDEVINS pDevIns, bool fEnable));
3231
3232 /**
3233 * Get the specified CPUID leaf for the virtual CPU associated with the calling
3234 * thread.
3235 *
3236 * @param pDevIns The device instance.
3237 * @param iLeaf The CPUID leaf to get.
3238 * @param pEax Where to store the EAX value.
3239 * @param pEbx Where to store the EBX value.
3240 * @param pEcx Where to store the ECX value.
3241 * @param pEdx Where to store the EDX value.
3242 * @thread EMT.
3243 */
3244 DECLR3CALLBACKMEMBER(void, pfnGetCpuId,(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx));
3245
3246 /**
3247 * Get the current virtual clock time in a VM. The clock frequency must be
3248 * queried separately.
3249 *
3250 * @returns Current clock time.
3251 * @param pDevIns The device instance.
3252 */
3253 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
3254
3255 /**
3256 * Get the frequency of the virtual clock.
3257 *
3258 * @returns The clock frequency (not variable at run-time).
3259 * @param pDevIns The device instance.
3260 */
3261 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
3262
3263 /**
3264 * Get the current virtual clock time in a VM, in nanoseconds.
3265 *
3266 * @returns Current clock time (in ns).
3267 * @param pDevIns The device instance.
3268 */
3269 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
3270
3271 /** @} */
3272
3273 /** Just a safety precaution. (PDM_DEVHLP_VERSION) */
3274 uint32_t u32TheEnd;
3275} PDMDEVHLPR3;
3276#endif /* !IN_RING3 */
3277/** Pointer to the R3 PDM Device API. */
3278typedef R3PTRTYPE(struct PDMDEVHLPR3 *) PPDMDEVHLPR3;
3279/** Pointer to the R3 PDM Device API, const variant. */
3280typedef R3PTRTYPE(const struct PDMDEVHLPR3 *) PCPDMDEVHLPR3;
3281
3282/** Current PDMDEVHLPR3 version number. */
3283#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE(0xffe7, 3, 0)
3284
3285
3286/**
3287 * PDM Device API - RC Variant.
3288 */
3289typedef struct PDMDEVHLPRC
3290{
3291 /** Structure version. PDM_DEVHLPRC_VERSION defines the current version. */
3292 uint32_t u32Version;
3293
3294 /**
3295 * Set the IRQ for a PCI device.
3296 *
3297 * @param pDevIns Device instance.
3298 * @param iIrq IRQ number to set.
3299 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3300 * @thread Any thread, but will involve the emulation thread.
3301 */
3302 DECLRCCALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3303
3304 /**
3305 * Set ISA IRQ for a device.
3306 *
3307 * @param pDevIns Device instance.
3308 * @param iIrq IRQ number to set.
3309 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3310 * @thread Any thread, but will involve the emulation thread.
3311 */
3312 DECLRCCALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3313
3314 /**
3315 * Read physical memory.
3316 *
3317 * @returns VINF_SUCCESS (for now).
3318 * @param pDevIns Device instance.
3319 * @param GCPhys Physical address start reading from.
3320 * @param pvBuf Where to put the read bits.
3321 * @param cbRead How many bytes to read.
3322 */
3323 DECLRCCALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
3324
3325 /**
3326 * Write to physical memory.
3327 *
3328 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
3329 * @param pDevIns Device instance.
3330 * @param GCPhys Physical address to write to.
3331 * @param pvBuf What to write.
3332 * @param cbWrite How many bytes to write.
3333 */
3334 DECLRCCALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
3335
3336 /**
3337 * Checks if the Gate A20 is enabled or not.
3338 *
3339 * @returns true if A20 is enabled.
3340 * @returns false if A20 is disabled.
3341 * @param pDevIns Device instance.
3342 * @thread The emulation thread.
3343 */
3344 DECLRCCALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
3345
3346 /**
3347 * Gets the VM state.
3348 *
3349 * @returns VM state.
3350 * @param pDevIns The device instance.
3351 * @thread Any thread (just keep in mind that it's volatile info).
3352 */
3353 DECLRCCALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
3354
3355 /**
3356 * Set the VM error message
3357 *
3358 * @returns rc.
3359 * @param pDrvIns Driver instance.
3360 * @param rc VBox status code.
3361 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3362 * @param pszFormat Error message format string.
3363 * @param ... Error message arguments.
3364 */
3365 DECLRCCALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
3366
3367 /**
3368 * Set the VM error message
3369 *
3370 * @returns rc.
3371 * @param pDrvIns Driver instance.
3372 * @param rc VBox status code.
3373 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3374 * @param pszFormat Error message format string.
3375 * @param va Error message arguments.
3376 */
3377 DECLRCCALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
3378
3379 /**
3380 * Set the VM runtime error message
3381 *
3382 * @returns VBox status code.
3383 * @param pDevIns Device instance.
3384 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3385 * @param pszErrorId Error ID string.
3386 * @param pszFormat Error message format string.
3387 * @param ... Error message arguments.
3388 */
3389 DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
3390
3391 /**
3392 * Set the VM runtime error message
3393 *
3394 * @returns VBox status code.
3395 * @param pDevIns Device instance.
3396 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3397 * @param pszErrorId Error ID string.
3398 * @param pszFormat Error message format string.
3399 * @param va Error message arguments.
3400 */
3401 DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
3402
3403 /**
3404 * Set parameters for pending MMIO patch operation
3405 *
3406 * @returns VBox status code.
3407 * @param pDevIns Device instance.
3408 * @param GCPhys MMIO physical address
3409 * @param pCachedData GC pointer to cached data
3410 */
3411 DECLRCCALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
3412
3413 /**
3414 * Gets the VM handle. Restricted API.
3415 *
3416 * @returns VM Handle.
3417 * @param pDevIns Device instance.
3418 */
3419 DECLRCCALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
3420
3421 /**
3422 * Gets the VMCPU handle. Restricted API.
3423 *
3424 * @returns VMCPU Handle.
3425 * @param pDevIns The device instance.
3426 */
3427 DECLRCCALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
3428
3429 /**
3430 * Get the current virtual clock time in a VM. The clock frequency must be
3431 * queried separately.
3432 *
3433 * @returns Current clock time.
3434 * @param pDevIns The device instance.
3435 */
3436 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
3437
3438 /**
3439 * Get the frequency of the virtual clock.
3440 *
3441 * @returns The clock frequency (not variable at run-time).
3442 * @param pDevIns The device instance.
3443 */
3444 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
3445
3446 /**
3447 * Get the current virtual clock time in a VM, in nanoseconds.
3448 *
3449 * @returns Current clock time (in ns).
3450 * @param pDevIns The device instance.
3451 */
3452 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
3453
3454 /** Just a safety precaution. */
3455 uint32_t u32TheEnd;
3456} PDMDEVHLPRC;
3457/** Pointer PDM Device RC API. */
3458typedef RCPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC;
3459/** Pointer PDM Device RC API. */
3460typedef RCPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC;
3461
3462/** Current PDMDEVHLP version number. */
3463#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 1, 0)
3464
3465
3466/**
3467 * PDM Device API - R0 Variant.
3468 */
3469typedef struct PDMDEVHLPR0
3470{
3471 /** Structure version. PDM_DEVHLPR0_VERSION defines the current version. */
3472 uint32_t u32Version;
3473
3474 /**
3475 * Set the IRQ for a PCI device.
3476 *
3477 * @param pDevIns Device instance.
3478 * @param iIrq IRQ number to set.
3479 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3480 * @thread Any thread, but will involve the emulation thread.
3481 */
3482 DECLR0CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3483
3484 /**
3485 * Set ISA IRQ for a device.
3486 *
3487 * @param pDevIns Device instance.
3488 * @param iIrq IRQ number to set.
3489 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3490 * @thread Any thread, but will involve the emulation thread.
3491 */
3492 DECLR0CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3493
3494 /**
3495 * Read physical memory.
3496 *
3497 * @returns VINF_SUCCESS (for now).
3498 * @param pDevIns Device instance.
3499 * @param GCPhys Physical address start reading from.
3500 * @param pvBuf Where to put the read bits.
3501 * @param cbRead How many bytes to read.
3502 */
3503 DECLR0CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
3504
3505 /**
3506 * Write to physical memory.
3507 *
3508 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
3509 * @param pDevIns Device instance.
3510 * @param GCPhys Physical address to write to.
3511 * @param pvBuf What to write.
3512 * @param cbWrite How many bytes to write.
3513 */
3514 DECLR0CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
3515
3516 /**
3517 * Checks if the Gate A20 is enabled or not.
3518 *
3519 * @returns true if A20 is enabled.
3520 * @returns false if A20 is disabled.
3521 * @param pDevIns Device instance.
3522 * @thread The emulation thread.
3523 */
3524 DECLR0CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
3525
3526 /**
3527 * Gets the VM state.
3528 *
3529 * @returns VM state.
3530 * @param pDevIns The device instance.
3531 * @thread Any thread (just keep in mind that it's volatile info).
3532 */
3533 DECLR0CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
3534
3535 /**
3536 * Set the VM error message
3537 *
3538 * @returns rc.
3539 * @param pDrvIns Driver instance.
3540 * @param rc VBox status code.
3541 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3542 * @param pszFormat Error message format string.
3543 * @param ... Error message arguments.
3544 */
3545 DECLR0CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
3546
3547 /**
3548 * Set the VM error message
3549 *
3550 * @returns rc.
3551 * @param pDrvIns Driver instance.
3552 * @param rc VBox status code.
3553 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3554 * @param pszFormat Error message format string.
3555 * @param va Error message arguments.
3556 */
3557 DECLR0CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
3558
3559 /**
3560 * Set the VM runtime error message
3561 *
3562 * @returns VBox status code.
3563 * @param pDevIns Device instance.
3564 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3565 * @param pszErrorId Error ID string.
3566 * @param pszFormat Error message format string.
3567 * @param ... Error message arguments.
3568 */
3569 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
3570
3571 /**
3572 * Set the VM runtime error message
3573 *
3574 * @returns VBox status code.
3575 * @param pDevIns Device instance.
3576 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3577 * @param pszErrorId Error ID string.
3578 * @param pszFormat Error message format string.
3579 * @param va Error message arguments.
3580 */
3581 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
3582
3583 /**
3584 * Set parameters for pending MMIO patch operation
3585 *
3586 * @returns rc.
3587 * @param pDevIns Device instance.
3588 * @param GCPhys MMIO physical address
3589 * @param pCachedData GC pointer to cached data
3590 */
3591 DECLR0CALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
3592
3593 /**
3594 * Gets the VM handle. Restricted API.
3595 *
3596 * @returns VM Handle.
3597 * @param pDevIns Device instance.
3598 */
3599 DECLR0CALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
3600
3601 /**
3602 * Checks if our current CPU state allows for IO block emulation fallback to the recompiler
3603 *
3604 * @returns true = yes, false = no
3605 * @param pDevIns Device instance.
3606 */
3607 DECLR0CALLBACKMEMBER(bool, pfnCanEmulateIoBlock,(PPDMDEVINS pDevIns));
3608
3609 /**
3610 * Gets the VMCPU handle. Restricted API.
3611 *
3612 * @returns VMCPU Handle.
3613 * @param pDevIns The device instance.
3614 */
3615 DECLR0CALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
3616
3617 /**
3618 * Get the current virtual clock time in a VM. The clock frequency must be
3619 * queried separately.
3620 *
3621 * @returns Current clock time.
3622 * @param pDevIns The device instance.
3623 */
3624 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
3625
3626 /**
3627 * Get the frequency of the virtual clock.
3628 *
3629 * @returns The clock frequency (not variable at run-time).
3630 * @param pDevIns The device instance.
3631 */
3632 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
3633
3634 /**
3635 * Get the current virtual clock time in a VM, in nanoseconds.
3636 *
3637 * @returns Current clock time (in ns).
3638 * @param pDevIns The device instance.
3639 */
3640 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
3641
3642 /** Just a safety precaution. */
3643 uint32_t u32TheEnd;
3644} PDMDEVHLPR0;
3645/** Pointer PDM Device R0 API. */
3646typedef R0PTRTYPE(struct PDMDEVHLPR0 *) PPDMDEVHLPR0;
3647/** Pointer PDM Device GC API. */
3648typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0;
3649
3650/** Current PDMDEVHLP version number. */
3651#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 1, 0)
3652
3653
3654
3655/**
3656 * PDM Device Instance.
3657 */
3658typedef struct PDMDEVINS
3659{
3660 /** Structure version. PDM_DEVINS_VERSION defines the current version. */
3661 uint32_t u32Version;
3662 /** Device instance number. */
3663 uint32_t iInstance;
3664
3665 /** Pointer the GC PDM Device API. */
3666 PCPDMDEVHLPRC pHlpRC;
3667 /** Pointer to device instance data. */
3668 RTRCPTR pvInstanceDataRC;
3669 /** The critical section for the device, see pCritSectR3.
3670 * This is automatically resolved by PDM when pCritSectR3 is set by the
3671 * constructor. */
3672 RCPTRTYPE(PPDMCRITSECT) pCritSectRC;
3673 /** Alignment padding. */
3674 RTRCPTR pAlignmentRC;
3675
3676 /** Pointer the R0 PDM Device API. */
3677 PCPDMDEVHLPR0 pHlpR0;
3678 /** Pointer to device instance data (R0). */
3679 RTR0PTR pvInstanceDataR0;
3680 /** The critical section for the device, see pCritSectR3.
3681 * This is automatically resolved by PDM when pCritSectR3 is set by the
3682 * constructor. */
3683 R0PTRTYPE(PPDMCRITSECT) pCritSectR0;
3684
3685 /** Pointer the HC PDM Device API. */
3686 PCPDMDEVHLPR3 pHlpR3;
3687 /** Pointer to device instance data. */
3688 RTR3PTR pvInstanceDataR3;
3689 /** The critical section for the device. (Optional)
3690 *
3691 * The device constructor initializes this if it has a critical section for
3692 * the device and desires it to be taken automatically by MMIO, I/O port
3693 * and timer callbacks to the device. The advantages using this locking
3694 * approach is both less code and avoiding the global IOM lock.
3695 *
3696 * @remarks Will not yet be taken by SSM.
3697 */
3698 R3PTRTYPE(PPDMCRITSECT) pCritSectR3;
3699
3700 /** Pointer to device registration structure. */
3701 R3PTRTYPE(PCPDMDEVREG) pReg;
3702 /** Configuration handle. */
3703 R3PTRTYPE(PCFGMNODE) pCfg;
3704
3705 /** The base interface of the device.
3706 *
3707 * The device constructor initializes this if it has any
3708 * device level interfaces to export. To obtain this interface
3709 * call PDMR3QueryDevice(). */
3710 PDMIBASE IBase;
3711 /** Align the internal data more naturally. */
3712 RTR3PTR R3PtrPadding;
3713
3714 /** Internal data. */
3715 union
3716 {
3717#ifdef PDMDEVINSINT_DECLARED
3718 PDMDEVINSINT s;
3719#endif
3720 uint8_t padding[HC_ARCH_BITS == 32 ? 64 + 0 : 112 + 0x28];
3721 } Internal;
3722
3723 /** Device instance data. The size of this area is defined
3724 * in the PDMDEVREG::cbInstanceData field. */
3725 char achInstanceData[8];
3726} PDMDEVINS;
3727
3728/** Current PDMDEVINS version number. */
3729#define PDM_DEVINS_VERSION PDM_VERSION_MAKE(0xffe4, 2, 0)
3730
3731/** Converts a pointer to the PDMDEVINS::IBase to a pointer to PDMDEVINS. */
3732#define PDMIBASE_2_PDMDEV(pInterface) ( (PPDMDEVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDEVINS, IBase)) )
3733
3734/**
3735 * Checks the structure versions of the device instance and device helpers,
3736 * returning if they are incompatible.
3737 *
3738 * This is for use in the constructor.
3739 *
3740 * @param pDevIns The device instance pointer.
3741 */
3742#define PDMDEV_CHECK_VERSIONS_RETURN(pDevIns) \
3743 do \
3744 { \
3745 PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
3746 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION), \
3747 ("DevIns=%#x mine=%#x\n", (pDevIns)->u32Version, PDM_DEVINS_VERSION), \
3748 VERR_VERSION_MISMATCH); \
3749 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION), \
3750 ("DevHlp=%#x mine=%#x\n", (pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION), \
3751 VERR_VERSION_MISMATCH); \
3752 } while (0)
3753
3754/**
3755 * Quietly checks the structure versions of the device instance and device
3756 * helpers, returning if they are incompatible.
3757 *
3758 * This is for use in the destructor.
3759 *
3760 * @param pDevIns The device instance pointer.
3761 */
3762#define PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns) \
3763 do \
3764 { \
3765 PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
3766 if (RT_UNLIKELY( !PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION) \
3767 || !PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION) )) \
3768 return VERR_VERSION_MISMATCH; \
3769 } while (0)
3770
3771/**
3772 * Wrapper around CFGMR3ValidateConfig for the root config for use in the
3773 * constructor - returns on failure.
3774 *
3775 * This should be invoked after having initialized the instance data
3776 * sufficiently for the correct operation of the destructor. The destructor is
3777 * always called!
3778 *
3779 * @param pDevIns Pointer to the PDM device instance.
3780 * @param pszValidValues Patterns describing the valid value names. See
3781 * RTStrSimplePatternMultiMatch for details on the
3782 * pattern syntax.
3783 * @param pszValidNodes Patterns describing the valid node (key) names.
3784 * Pass empty string if no valid nodess.
3785 */
3786#define PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, pszValidValues, pszValidNodes) \
3787 do \
3788 { \
3789 int rcValCfg = CFGMR3ValidateConfig((pDevIns)->pCfg, "/", pszValidValues, pszValidNodes, \
3790 (pDevIns)->pReg->szName, (pDevIns)->iInstance); \
3791 if (RT_FAILURE(rcValCfg)) \
3792 return rcValCfg; \
3793 } while (0)
3794
3795/** @def PDMDEV_ASSERT_EMT
3796 * Assert that the current thread is the emulation thread.
3797 */
3798#ifdef VBOX_STRICT
3799# define PDMDEV_ASSERT_EMT(pDevIns) pDevIns->pHlpR3->pfnAssertEMT(pDevIns, __FILE__, __LINE__, __FUNCTION__)
3800#else
3801# define PDMDEV_ASSERT_EMT(pDevIns) do { } while (0)
3802#endif
3803
3804/** @def PDMDEV_ASSERT_OTHER
3805 * Assert that the current thread is NOT the emulation thread.
3806 */
3807#ifdef VBOX_STRICT
3808# define PDMDEV_ASSERT_OTHER(pDevIns) pDevIns->pHlpR3->pfnAssertOther(pDevIns, __FILE__, __LINE__, __FUNCTION__)
3809#else
3810# define PDMDEV_ASSERT_OTHER(pDevIns) do { } while (0)
3811#endif
3812
3813/** @def PDMDEV_ASSERT_VMLOCK_OWNER
3814 * Assert that the current thread is owner of the VM lock.
3815 */
3816#ifdef VBOX_STRICT
3817# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) pDevIns->pHlpR3->pfnAssertVMLock(pDevIns, __FILE__, __LINE__, __FUNCTION__)
3818#else
3819# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) do { } while (0)
3820#endif
3821
3822/** @def PDMDEV_SET_ERROR
3823 * Set the VM error. See PDMDevHlpVMSetError() for printf like message formatting.
3824 */
3825#define PDMDEV_SET_ERROR(pDevIns, rc, pszError) \
3826 PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, "%s", pszError)
3827
3828/** @def PDMDEV_SET_RUNTIME_ERROR
3829 * Set the VM runtime error. See PDMDevHlpVMSetRuntimeError() for printf like message formatting.
3830 */
3831#define PDMDEV_SET_RUNTIME_ERROR(pDevIns, fFlags, pszErrorId, pszError) \
3832 PDMDevHlpVMSetRuntimeError(pDevIns, fFlags, pszErrorId, "%s", pszError)
3833
3834/** @def PDMDEVINS_2_RCPTR
3835 * Converts a PDM Device instance pointer a RC PDM Device instance pointer.
3836 */
3837#define PDMDEVINS_2_RCPTR(pDevIns) ( (RCPTRTYPE(PPDMDEVINS))((RTGCUINTPTR)(pDevIns)->pvInstanceDataRC - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
3838
3839/** @def PDMDEVINS_2_R3PTR
3840 * Converts a PDM Device instance pointer a R3 PDM Device instance pointer.
3841 */
3842#define PDMDEVINS_2_R3PTR(pDevIns) ( (R3PTRTYPE(PPDMDEVINS))((RTHCUINTPTR)(pDevIns)->pvInstanceDataR3 - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
3843
3844/** @def PDMDEVINS_2_R0PTR
3845 * Converts a PDM Device instance pointer a R0 PDM Device instance pointer.
3846 */
3847#define PDMDEVINS_2_R0PTR(pDevIns) ( (R0PTRTYPE(PPDMDEVINS))((RTR0UINTPTR)(pDevIns)->pvInstanceDataR0 - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
3848
3849
3850#ifdef IN_RING3
3851
3852/**
3853 * @copydoc PDMDEVHLPR3::pfnIOPortRegister
3854 */
3855DECLINLINE(int) PDMDevHlpIOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser,
3856 PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
3857 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc)
3858{
3859 return pDevIns->pHlpR3->pfnIOPortRegister(pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc);
3860}
3861
3862/**
3863 * @copydoc PDMDEVHLPR3::pfnIOPortRegisterRC
3864 */
3865DECLINLINE(int) PDMDevHlpIOPortRegisterRC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser,
3866 const char *pszOut, const char *pszIn, const char *pszOutStr,
3867 const char *pszInStr, const char *pszDesc)
3868{
3869 return pDevIns->pHlpR3->pfnIOPortRegisterRC(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
3870}
3871
3872/**
3873 * @copydoc PDMDEVHLPR3::pfnIOPortRegisterR0
3874 */
3875DECLINLINE(int) PDMDevHlpIOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser,
3876 const char *pszOut, const char *pszIn, const char *pszOutStr,
3877 const char *pszInStr, const char *pszDesc)
3878{
3879 return pDevIns->pHlpR3->pfnIOPortRegisterR0(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
3880}
3881
3882/**
3883 * @copydoc PDMDEVHLPR3::pfnIOPortDeregister
3884 */
3885DECLINLINE(int) PDMDevHlpIOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts)
3886{
3887 return pDevIns->pHlpR3->pfnIOPortDeregister(pDevIns, Port, cPorts);
3888}
3889
3890/**
3891 * @copydoc PDMDEVHLPR3::pfnMMIORegister
3892 */
3893DECLINLINE(int) PDMDevHlpMMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,
3894 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
3895 const char *pszDesc)
3896{
3897 return pDevIns->pHlpR3->pfnMMIORegister(pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc);
3898}
3899
3900/**
3901 * @copydoc PDMDEVHLPR3::pfnMMIORegisterRC
3902 */
3903DECLINLINE(int) PDMDevHlpMMIORegisterRC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,
3904 const char *pszWrite, const char *pszRead, const char *pszFill)
3905{
3906 return pDevIns->pHlpR3->pfnMMIORegisterRC(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill, NULL);
3907}
3908
3909/**
3910 * @copydoc PDMDEVHLPR3::pfnMMIORegisterR0
3911 */
3912DECLINLINE(int) PDMDevHlpMMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,
3913 const char *pszWrite, const char *pszRead, const char *pszFill)
3914{
3915 return pDevIns->pHlpR3->pfnMMIORegisterR0(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill, NULL);
3916}
3917
3918/**
3919 * @copydoc PDMDEVHLPR3::pfnMMIODeregister
3920 */
3921DECLINLINE(int) PDMDevHlpMMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
3922{
3923 return pDevIns->pHlpR3->pfnMMIODeregister(pDevIns, GCPhysStart, cbRange);
3924}
3925
3926/**
3927 * @copydoc PDMDEVHLPR3::pfnMMIO2Register
3928 */
3929DECLINLINE(int) PDMDevHlpMMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
3930{
3931 return pDevIns->pHlpR3->pfnMMIO2Register(pDevIns, iRegion, cb, fFlags, ppv, pszDesc);
3932}
3933
3934/**
3935 * @copydoc PDMDEVHLPR3::pfnMMIO2Deregister
3936 */
3937DECLINLINE(int) PDMDevHlpMMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)
3938{
3939 return pDevIns->pHlpR3->pfnMMIO2Deregister(pDevIns, iRegion);
3940}
3941
3942/**
3943 * @copydoc PDMDEVHLPR3::pfnMMIO2Map
3944 */
3945DECLINLINE(int) PDMDevHlpMMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
3946{
3947 return pDevIns->pHlpR3->pfnMMIO2Map(pDevIns, iRegion, GCPhys);
3948}
3949
3950/**
3951 * @copydoc PDMDEVHLPR3::pfnMMIO2Unmap
3952 */
3953DECLINLINE(int) PDMDevHlpMMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
3954{
3955 return pDevIns->pHlpR3->pfnMMIO2Unmap(pDevIns, iRegion, GCPhys);
3956}
3957
3958/**
3959 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2
3960 */
3961DECLINLINE(int) PDMDevHlpMMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
3962 const char *pszDesc, PRTRCPTR pRCPtr)
3963{
3964 return pDevIns->pHlpR3->pfnMMHyperMapMMIO2(pDevIns, iRegion, off, cb, pszDesc, pRCPtr);
3965}
3966
3967/**
3968 * @copydoc PDMDEVHLPR3::pfnMMIO2MapKernel
3969 */
3970DECLINLINE(int) PDMDevHlpMMIO2MapKernel(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
3971 const char *pszDesc, PRTR0PTR pR0Ptr)
3972{
3973 return pDevIns->pHlpR3->pfnMMIO2MapKernel(pDevIns, iRegion, off, cb, pszDesc, pR0Ptr);
3974}
3975
3976/**
3977 * @copydoc PDMDEVHLPR3::pfnROMRegister
3978 */
3979DECLINLINE(int) PDMDevHlpROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange,
3980 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
3981{
3982 return pDevIns->pHlpR3->pfnROMRegister(pDevIns, GCPhysStart, cbRange, pvBinary, cbBinary, fFlags, pszDesc);
3983}
3984
3985/**
3986 * @copydoc PDMDEVHLPR3::pfnROMProtectShadow
3987 */
3988DECLINLINE(int) PDMDevHlpROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, PGMROMPROT enmProt)
3989{
3990 return pDevIns->pHlpR3->pfnROMProtectShadow(pDevIns, GCPhysStart, cbRange, enmProt);
3991}
3992
3993/**
3994 * Register a save state data unit.
3995 *
3996 * @returns VBox status.
3997 * @param pDevIns The device instance.
3998 * @param uVersion Data layout version number.
3999 * @param cbGuess The approximate amount of data in the unit.
4000 * Only for progress indicators.
4001 * @param pfnSaveExec Execute save callback, optional.
4002 * @param pfnLoadExec Execute load callback, optional.
4003 */
4004DECLINLINE(int) PDMDevHlpSSMRegister(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
4005 PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
4006{
4007 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
4008 NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveDone*/,
4009 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
4010 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
4011}
4012
4013/**
4014 * Register a save state data unit with a live save callback as well.
4015 *
4016 * @returns VBox status.
4017 * @param pDevIns The device instance.
4018 * @param uVersion Data layout version number.
4019 * @param cbGuess The approximate amount of data in the unit.
4020 * Only for progress indicators.
4021 * @param pfnLiveExec Execute live callback, optional.
4022 * @param pfnSaveExec Execute save callback, optional.
4023 * @param pfnLoadExec Execute load callback, optional.
4024 */
4025DECLINLINE(int) PDMDevHlpSSMRegister3(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
4026 FNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
4027{
4028 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
4029 NULL /*pfnLivePrep*/, pfnLiveExec, NULL /*pfnLiveDone*/,
4030 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
4031 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
4032}
4033
4034/**
4035 * @copydoc PDMDEVHLPR3::pfnSSMRegister
4036 */
4037DECLINLINE(int) PDMDevHlpSSMRegisterEx(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
4038 PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
4039 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
4040 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
4041{
4042 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, pszBefore,
4043 pfnLivePrep, pfnLiveExec, pfnLiveVote,
4044 pfnSavePrep, pfnSaveExec, pfnSaveDone,
4045 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
4046}
4047
4048/**
4049 * @copydoc PDMDEVHLPR3::pfnTMTimerCreate
4050 */
4051DECLINLINE(int) PDMDevHlpTMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags,
4052 const char *pszDesc, PPTMTIMERR3 ppTimer)
4053{
4054 return pDevIns->pHlpR3->pfnTMTimerCreate(pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
4055}
4056
4057/**
4058 * @copydoc PDMDEVHLPR3::pfnTMUtcNow
4059 */
4060DECLINLINE(PRTTIMESPEC) PDMDevHlpTMUtcNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
4061{
4062 return pDevIns->pHlpR3->pfnTMUtcNow(pDevIns, pTime);
4063}
4064
4065#endif /* IN_RING3 */
4066
4067/**
4068 * @copydoc PDMDEVHLPR3::pfnPhysRead
4069 */
4070DECLINLINE(int) PDMDevHlpPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
4071{
4072 return pDevIns->CTX_SUFF(pHlp)->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
4073}
4074
4075/**
4076 * @copydoc PDMDEVHLPR3::pfnPhysWrite
4077 */
4078DECLINLINE(int) PDMDevHlpPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
4079{
4080 return pDevIns->CTX_SUFF(pHlp)->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
4081}
4082
4083#ifdef IN_RING3
4084
4085/**
4086 * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtr
4087 */
4088DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtr(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock)
4089{
4090 return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtr(pDevIns, GCPhys, fFlags, ppv, pLock);
4091}
4092
4093/**
4094 * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtrReadOnly
4095 */
4096DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock)
4097{
4098 return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhys, fFlags, ppv, pLock);
4099}
4100
4101/**
4102 * @copydoc PDMDEVHLPR3::pfnPhysReleasePageMappingLock
4103 */
4104DECLINLINE(void) PDMDevHlpPhysReleasePageMappingLock(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock)
4105{
4106 pDevIns->CTX_SUFF(pHlp)->pfnPhysReleasePageMappingLock(pDevIns, pLock);
4107}
4108
4109/**
4110 * @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt
4111 */
4112DECLINLINE(int) PDMDevHlpPhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
4113{
4114 return pDevIns->pHlpR3->pfnPhysReadGCVirt(pDevIns, pvDst, GCVirtSrc, cb);
4115}
4116
4117/**
4118 * @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt
4119 */
4120DECLINLINE(int) PDMDevHlpPhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
4121{
4122 return pDevIns->pHlpR3->pfnPhysWriteGCVirt(pDevIns, GCVirtDst, pvSrc, cb);
4123}
4124
4125/**
4126 * @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys
4127 */
4128DECLINLINE(int) PDMDevHlpPhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
4129{
4130 return pDevIns->pHlpR3->pfnPhysGCPtr2GCPhys(pDevIns, GCPtr, pGCPhys);
4131}
4132
4133/**
4134 * @copydoc PDMDEVHLPR3::pfnMMHeapAlloc
4135 */
4136DECLINLINE(void *) PDMDevHlpMMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
4137{
4138 return pDevIns->pHlpR3->pfnMMHeapAlloc(pDevIns, cb);
4139}
4140
4141/**
4142 * @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ
4143 */
4144DECLINLINE(void *) PDMDevHlpMMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
4145{
4146 return pDevIns->pHlpR3->pfnMMHeapAllocZ(pDevIns, cb);
4147}
4148
4149/**
4150 * @copydoc PDMDEVHLPR3::pfnMMHeapFree
4151 */
4152DECLINLINE(void) PDMDevHlpMMHeapFree(PPDMDEVINS pDevIns, void *pv)
4153{
4154 pDevIns->pHlpR3->pfnMMHeapFree(pDevIns, pv);
4155}
4156#endif /* IN_RING3 */
4157
4158/**
4159 * @copydoc PDMDEVHLPR3::pfnVMState
4160 */
4161DECLINLINE(VMSTATE) PDMDevHlpVMState(PPDMDEVINS pDevIns)
4162{
4163 return pDevIns->CTX_SUFF(pHlp)->pfnVMState(pDevIns);
4164}
4165
4166#ifdef IN_RING3
4167/**
4168 * @copydoc PDMDEVHLPR3::pfnVMTeleportedAndNotFullyResumedYet
4169 */
4170DECLINLINE(bool) PDMDevHlpVMTeleportedAndNotFullyResumedYet(PPDMDEVINS pDevIns)
4171{
4172 return pDevIns->pHlpR3->pfnVMTeleportedAndNotFullyResumedYet(pDevIns);
4173}
4174#endif /* IN_RING3 */
4175
4176/**
4177 * @copydoc PDMDEVHLPR3::pfnVMSetError
4178 */
4179DECLINLINE(int) PDMDevHlpVMSetError(PPDMDEVINS pDevIns, const int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
4180{
4181 va_list va;
4182 va_start(va, pszFormat);
4183 pDevIns->CTX_SUFF(pHlp)->pfnVMSetErrorV(pDevIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
4184 va_end(va);
4185 return rc;
4186}
4187
4188/**
4189 * @copydoc PDMDEVHLPR3::pfnVMSetRuntimeError
4190 */
4191DECLINLINE(int) PDMDevHlpVMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
4192{
4193 va_list va;
4194 int rc;
4195 va_start(va, pszFormat);
4196 rc = pDevIns->CTX_SUFF(pHlp)->pfnVMSetRuntimeErrorV(pDevIns, fFlags, pszErrorId, pszFormat, va);
4197 va_end(va);
4198 return rc;
4199}
4200
4201/**
4202 * VBOX_STRICT wrapper for pHlp->pfnDBGFStopV.
4203 *
4204 * @returns VBox status code which must be passed up to the VMM. This will be
4205 * VINF_SUCCESS in non-strict builds.
4206 * @param pDevIns The device instance.
4207 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
4208 * @param pszFormat Message. (optional)
4209 * @param ... Message parameters.
4210 */
4211DECLINLINE(int) PDMDevHlpDBGFStop(PPDMDEVINS pDevIns, RT_SRC_POS_DECL, const char *pszFormat, ...)
4212{
4213#ifdef VBOX_STRICT
4214# ifdef IN_RING3
4215 int rc;
4216 va_list args;
4217 va_start(args, pszFormat);
4218 rc = pDevIns->pHlpR3->pfnDBGFStopV(pDevIns, RT_SRC_POS_ARGS, pszFormat, args);
4219 va_end(args);
4220 return rc;
4221# else
4222 return VINF_EM_DBG_STOP;
4223# endif
4224#else
4225 NOREF(pDevIns);
4226 NOREF(pszFile);
4227 NOREF(iLine);
4228 NOREF(pszFunction);
4229 NOREF(pszFormat);
4230 return VINF_SUCCESS;
4231#endif
4232}
4233
4234#ifdef IN_RING3
4235
4236/**
4237 * @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister
4238 */
4239DECLINLINE(int) PDMDevHlpDBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
4240{
4241 return pDevIns->pHlpR3->pfnDBGFInfoRegister(pDevIns, pszName, pszDesc, pfnHandler);
4242}
4243
4244/**
4245 * @copydoc PDMDEVHLPR3::pfnSTAMRegister
4246 */
4247DECLINLINE(void) PDMDevHlpSTAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
4248{
4249 pDevIns->pHlpR3->pfnSTAMRegister(pDevIns, pvSample, enmType, pszName, enmUnit, pszDesc);
4250}
4251
4252/**
4253 * @copydoc PDMDEVHLPR3::pfnSTAMRegisterF
4254 */
4255DECLINLINE(void) PDMDevHlpSTAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
4256 const char *pszDesc, const char *pszName, ...)
4257{
4258 va_list va;
4259 va_start(va, pszName);
4260 pDevIns->pHlpR3->pfnSTAMRegisterV(pDevIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, va);
4261 va_end(va);
4262}
4263
4264/**
4265 * @copydoc PDMDEVHLPR3::pfnPCIRegister
4266 */
4267DECLINLINE(int) PDMDevHlpPCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev)
4268{
4269 return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev);
4270}
4271
4272/**
4273 * @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister
4274 */
4275DECLINLINE(int) PDMDevHlpPCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
4276{
4277 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, iRegion, cbRegion, enmType, pfnCallback);
4278}
4279
4280/**
4281 * @copydoc PDMDEVHLPR3::pfnPCIRegisterMsi
4282 */
4283DECLINLINE(int) PDMDevHlpPCIRegisterMsi(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg)
4284{
4285 return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, pMsiReg);
4286}
4287
4288
4289/**
4290 * @copydoc PDMDEVHLPR3::pfnPCISetConfigCallbacks
4291 */
4292DECLINLINE(void) PDMDevHlpPCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
4293 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)
4294{
4295 pDevIns->pHlpR3->pfnPCISetConfigCallbacks(pDevIns, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld);
4296}
4297
4298#endif /* IN_RING3 */
4299
4300/**
4301 * @copydoc PDMDEVHLPR3::pfnPCISetIrq
4302 */
4303DECLINLINE(void) PDMDevHlpPCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4304{
4305 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, iIrq, iLevel);
4306}
4307
4308/**
4309 * @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait
4310 */
4311DECLINLINE(void) PDMDevHlpPCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4312{
4313 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, iIrq, iLevel);
4314}
4315
4316/**
4317 * @copydoc PDMDEVHLPR3::pfnISASetIrq
4318 */
4319DECLINLINE(void) PDMDevHlpISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4320{
4321 pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
4322}
4323
4324/**
4325 * @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait
4326 */
4327DECLINLINE(void) PDMDevHlpISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4328{
4329 pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
4330}
4331
4332#ifdef IN_RING3
4333
4334/**
4335 * @copydoc PDMDEVHLPR3::pfnDriverAttach
4336 */
4337DECLINLINE(int) PDMDevHlpDriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
4338{
4339 return pDevIns->pHlpR3->pfnDriverAttach(pDevIns, iLun, pBaseInterface, ppBaseInterface, pszDesc);
4340}
4341
4342/**
4343 * @copydoc PDMDEVHLPR3::pfnQueueCreate
4344 */
4345DECLINLINE(int) PDMDevHlpQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
4346 PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, const char *pszName, PPDMQUEUE *ppQueue)
4347{
4348 return pDevIns->pHlpR3->pfnQueueCreate(pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, pszName, ppQueue);
4349}
4350
4351/**
4352 * Initializes a PDM critical section.
4353 *
4354 * The PDM critical sections are derived from the IPRT critical sections, but
4355 * works in RC and R0 as well.
4356 *
4357 * @returns VBox status code.
4358 * @param pDevIns The device instance.
4359 * @param pCritSect Pointer to the critical section.
4360 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
4361 * @param pszNameFmt Format string for naming the critical section.
4362 * For statistics and lock validation.
4363 * @param ... Arguments for the format string.
4364 */
4365DECLINLINE(int) PDMDevHlpCritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...)
4366{
4367 int rc;
4368 va_list va;
4369 va_start(va, pszNameFmt);
4370 rc = pDevIns->pHlpR3->pfnCritSectInit(pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
4371 va_end(va);
4372 return rc;
4373}
4374
4375/**
4376 * @copydoc PDMDEVHLPR3::pfnThreadCreate
4377 */
4378DECLINLINE(int) PDMDevHlpThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
4379 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
4380{
4381 return pDevIns->pHlpR3->pfnThreadCreate(pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
4382}
4383
4384/**
4385 * @copydoc PDMDEVHLPR3::pfnSetAsyncNotification
4386 */
4387DECLINLINE(int) PDMDevHlpSetAsyncNotification(PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)
4388{
4389 return pDevIns->pHlpR3->pfnSetAsyncNotification(pDevIns, pfnAsyncNotify);
4390}
4391
4392/**
4393 * @copydoc PDMDEVHLPR3::pfnAsyncNotificationCompleted
4394 */
4395DECLINLINE(void) PDMDevHlpAsyncNotificationCompleted(PPDMDEVINS pDevIns)
4396{
4397 pDevIns->pHlpR3->pfnAsyncNotificationCompleted(pDevIns);
4398}
4399
4400/**
4401 * @copydoc PDMDEVHLPR3::pfnA20Set
4402 */
4403DECLINLINE(void) PDMDevHlpA20Set(PPDMDEVINS pDevIns, bool fEnable)
4404{
4405 pDevIns->pHlpR3->pfnA20Set(pDevIns, fEnable);
4406}
4407
4408/**
4409 * @copydoc PDMDEVHLPR3::pfnRTCRegister
4410 */
4411DECLINLINE(int) PDMDevHlpRTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
4412{
4413 return pDevIns->pHlpR3->pfnRTCRegister(pDevIns, pRtcReg, ppRtcHlp);
4414}
4415
4416/**
4417 * @copydoc PDMDEVHLPR3::pfnPCIBusRegister
4418 */
4419DECLINLINE(int) PDMDevHlpPCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)
4420{
4421 return pDevIns->pHlpR3->pfnPCIBusRegister(pDevIns, pPciBusReg, ppPciHlpR3);
4422}
4423
4424/**
4425 * @copydoc PDMDEVHLPR3::pfnPICRegister
4426 */
4427DECLINLINE(int) PDMDevHlpPICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
4428{
4429 return pDevIns->pHlpR3->pfnPICRegister(pDevIns, pPicReg, ppPicHlpR3);
4430}
4431
4432/**
4433 * @copydoc PDMDEVHLPR3::pfnAPICRegister
4434 */
4435DECLINLINE(int) PDMDevHlpAPICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)
4436{
4437 return pDevIns->pHlpR3->pfnAPICRegister(pDevIns, pApicReg, ppApicHlpR3);
4438}
4439
4440/**
4441 * @copydoc PDMDEVHLPR3::pfn
4442 */
4443DECLINLINE(int) PDMDevHlpIOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
4444{
4445 return pDevIns->pHlpR3->pfnIOAPICRegister(pDevIns, pIoApicReg, ppIoApicHlpR3);
4446}
4447
4448/**
4449 * @copydoc PDMDEVHLPR3::pfnHPETRegister
4450 */
4451DECLINLINE(int) PDMDevHlpHPETRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
4452{
4453 return pDevIns->pHlpR3->pfnHPETRegister(pDevIns, pHpetReg, ppHpetHlpR3);
4454}
4455
4456/**
4457 * @copydoc PDMDEVHLPR3::pfnDMACRegister
4458 */
4459DECLINLINE(int) PDMDevHlpDMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
4460{
4461 return pDevIns->pHlpR3->pfnDMACRegister(pDevIns, pDmacReg, ppDmacHlp);
4462}
4463
4464/**
4465 * @copydoc PDMDEVHLPR3::pfnDMARegister
4466 */
4467DECLINLINE(int) PDMDevHlpDMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
4468{
4469 return pDevIns->pHlpR3->pfnDMARegister(pDevIns, uChannel, pfnTransferHandler, pvUser);
4470}
4471
4472/**
4473 * @copydoc PDMDEVHLPR3::pfnDMAReadMemory
4474 */
4475DECLINLINE(int) PDMDevHlpDMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
4476{
4477 return pDevIns->pHlpR3->pfnDMAReadMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbRead);
4478}
4479
4480/**
4481 * @copydoc PDMDEVHLPR3::pfnDMAWriteMemory
4482 */
4483DECLINLINE(int) PDMDevHlpDMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
4484{
4485 return pDevIns->pHlpR3->pfnDMAWriteMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbWritten);
4486}
4487
4488/**
4489 * @copydoc PDMDEVHLPR3::pfnDMASetDREQ
4490 */
4491DECLINLINE(int) PDMDevHlpDMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
4492{
4493 return pDevIns->pHlpR3->pfnDMASetDREQ(pDevIns, uChannel, uLevel);
4494}
4495
4496/**
4497 * @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode
4498 */
4499DECLINLINE(uint8_t) PDMDevHlpDMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
4500{
4501 return pDevIns->pHlpR3->pfnDMAGetChannelMode(pDevIns, uChannel);
4502}
4503
4504/**
4505 * @copydoc PDMDEVHLPR3::pfnDMASchedule
4506 */
4507DECLINLINE(void) PDMDevHlpDMASchedule(PPDMDEVINS pDevIns)
4508{
4509 pDevIns->pHlpR3->pfnDMASchedule(pDevIns);
4510}
4511
4512/**
4513 * @copydoc PDMDEVHLPR3::pfnCMOSWrite
4514 */
4515DECLINLINE(int) PDMDevHlpCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
4516{
4517 return pDevIns->pHlpR3->pfnCMOSWrite(pDevIns, iReg, u8Value);
4518}
4519
4520/**
4521 * @copydoc PDMDEVHLPR3::pfnCMOSRead
4522 */
4523DECLINLINE(int) PDMDevHlpCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
4524{
4525 return pDevIns->pHlpR3->pfnCMOSRead(pDevIns, iReg, pu8Value);
4526}
4527
4528/**
4529 * @copydoc PDMDEVHLP::pfnCallR0
4530 */
4531DECLINLINE(int) PDMDevHlpCallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)
4532{
4533 return pDevIns->pHlpR3->pfnCallR0(pDevIns, uOperation, u64Arg);
4534}
4535
4536#endif /* IN_RING3 */
4537
4538/**
4539 * @copydoc PDMDEVHLPR3::pfnGetVM
4540 */
4541DECLINLINE(PVM) PDMDevHlpGetVM(PPDMDEVINS pDevIns)
4542{
4543 return pDevIns->CTX_SUFF(pHlp)->pfnGetVM(pDevIns);
4544}
4545
4546/**
4547 * @copydoc PDMDEVHLPR3::pfnGetVMCPU
4548 */
4549DECLINLINE(PVMCPU) PDMDevHlpGetVMCPU(PPDMDEVINS pDevIns)
4550{
4551 return pDevIns->CTX_SUFF(pHlp)->pfnGetVMCPU(pDevIns);
4552}
4553
4554/**
4555 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGet
4556 */
4557DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGet(PPDMDEVINS pDevIns)
4558{
4559 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGet(pDevIns);
4560}
4561
4562/**
4563 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
4564 */
4565DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetFreq(PPDMDEVINS pDevIns)
4566{
4567 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetFreq(pDevIns);
4568}
4569
4570/**
4571 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
4572 */
4573DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetNano(PPDMDEVINS pDevIns)
4574{
4575 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetNano(pDevIns);
4576}
4577
4578#ifdef IN_RING3
4579
4580/**
4581 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap
4582 */
4583DECLINLINE(int) PDMDevHlpRegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize)
4584{
4585 return pDevIns->pHlpR3->pfnRegisterVMMDevHeap(pDevIns, GCPhys, pvHeap, cbSize);
4586}
4587
4588/**
4589 * @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap
4590 */
4591DECLINLINE(int) PDMDevHlpUnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
4592{
4593 return pDevIns->pHlpR3->pfnUnregisterVMMDevHeap(pDevIns, GCPhys);
4594}
4595
4596/**
4597 * @copydoc PDMDEVHLPR3::pfnVMReset
4598 */
4599DECLINLINE(int) PDMDevHlpVMReset(PPDMDEVINS pDevIns)
4600{
4601 return pDevIns->pHlpR3->pfnVMReset(pDevIns);
4602}
4603
4604/**
4605 * @copydoc PDMDEVHLPR3::pfnVMSuspend
4606 */
4607DECLINLINE(int) PDMDevHlpVMSuspend(PPDMDEVINS pDevIns)
4608{
4609 return pDevIns->pHlpR3->pfnVMSuspend(pDevIns);
4610}
4611
4612/**
4613 * @copydoc PDMDEVHLPR3::pfnVMSuspendSaveAndPowerOff
4614 */
4615DECLINLINE(int) PDMDevHlpVMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
4616{
4617 return pDevIns->pHlpR3->pfnVMSuspendSaveAndPowerOff(pDevIns);
4618}
4619
4620/**
4621 * @copydoc PDMDEVHLPR3::pfnVMPowerOff
4622 */
4623DECLINLINE(int) PDMDevHlpVMPowerOff(PPDMDEVINS pDevIns)
4624{
4625 return pDevIns->pHlpR3->pfnVMPowerOff(pDevIns);
4626}
4627
4628#endif /* IN_RING3 */
4629
4630/**
4631 * @copydoc PDMDEVHLPR3::pfnA20IsEnabled
4632 */
4633DECLINLINE(bool) PDMDevHlpA20IsEnabled(PPDMDEVINS pDevIns)
4634{
4635 return pDevIns->CTX_SUFF(pHlp)->pfnA20IsEnabled(pDevIns);
4636}
4637
4638#ifdef IN_RING3
4639
4640/**
4641 * @copydoc PDMDEVHLPR3::pfnGetCpuId
4642 */
4643DECLINLINE(void) PDMDevHlpGetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
4644{
4645 pDevIns->pHlpR3->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx);
4646}
4647
4648#endif /* IN_RING3 */
4649#ifdef IN_RING0
4650
4651/**
4652 * @copydoc PDMDEVHLPR0::pfnCanEmulateIoBlock
4653 */
4654DECLINLINE(bool) PDMDevHlpCanEmulateIoBlock(PPDMDEVINS pDevIns)
4655{
4656 return pDevIns->CTX_SUFF(pHlp)->pfnCanEmulateIoBlock(pDevIns);
4657}
4658
4659#endif /* IN_RING0 */
4660
4661
4662
4663
4664/** Pointer to callbacks provided to the VBoxDeviceRegister() call. */
4665typedef struct PDMDEVREGCB *PPDMDEVREGCB;
4666
4667/**
4668 * Callbacks for VBoxDeviceRegister().
4669 */
4670typedef struct PDMDEVREGCB
4671{
4672 /** Interface version.
4673 * This is set to PDM_DEVREG_CB_VERSION. */
4674 uint32_t u32Version;
4675
4676 /**
4677 * Registers a device with the current VM instance.
4678 *
4679 * @returns VBox status code.
4680 * @param pCallbacks Pointer to the callback table.
4681 * @param pReg Pointer to the device registration record.
4682 * This data must be permanent and readonly.
4683 */
4684 DECLR3CALLBACKMEMBER(int, pfnRegister,(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pReg));
4685} PDMDEVREGCB;
4686
4687/** Current version of the PDMDEVREGCB structure. */
4688#define PDM_DEVREG_CB_VERSION PDM_VERSION_MAKE(0xffe3, 1, 0)
4689
4690
4691/**
4692 * The VBoxDevicesRegister callback function.
4693 *
4694 * PDM will invoke this function after loading a device module and letting
4695 * the module decide which devices to register and how to handle conflicts.
4696 *
4697 * @returns VBox status code.
4698 * @param pCallbacks Pointer to the callback table.
4699 * @param u32Version VBox version number.
4700 */
4701typedef DECLCALLBACK(int) FNPDMVBOXDEVICESREGISTER(PPDMDEVREGCB pCallbacks, uint32_t u32Version);
4702
4703/** @} */
4704
4705RT_C_DECLS_END
4706
4707#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