VirtualBox

source: vbox/trunk/include/VBox/vmm/pdmdev.h@ 44508

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

Drop the pfnSaveExecR3 and pfnLoadExecR3 interfaces of the PCI buses (never used). Synced pciR3CommonRestoreConfig between the two PCI buses, dropping the constants in the table as they make double checking sizes and offsets harder. Also removing the pfnIOCtl device registration structure member, putting a pfnReserved in it's place.

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