VirtualBox

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

Last change on this file since 68675 was 68594, checked in by vboxsync, 8 years ago

PDM: Address the todos for cleaning up the PDMDEVHLP structure, bring the reserved slots back to the nominal numver and bump the major version (20 ended up being used by 5.1). Eliminate redundant PDMDEVHLP version dependent conditional compilation

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