VirtualBox

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

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

PDM takes the RTC cirtical section before calling the PDMRTCREG callbacks. Documented DMA and IOAPIC locking.

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

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