VirtualBox

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

Last change on this file since 102829 was 101617, checked in by vboxsync, 16 months ago

Devices/Gpio/DevPL061: Updates to the code, bugref:10453

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 407.4 KB
Line 
1/** @file
2 * PDM - Pluggable Device Manager, Devices.
3 */
4
5/*
6 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
7 *
8 * This file is part of VirtualBox base platform packages, as
9 * available from https://www.virtualbox.org.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation, in version 3 of the
14 * License.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses>.
23 *
24 * The contents of this file may alternatively be used under the terms
25 * of the Common Development and Distribution License Version 1.0
26 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
27 * in the VirtualBox distribution, in which case the provisions of the
28 * CDDL are applicable instead of those of the GPL.
29 *
30 * You may elect to license modified versions of this file under the
31 * terms and conditions of either the GPL or the CDDL or both.
32 *
33 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
34 */
35
36#ifndef VBOX_INCLUDED_vmm_pdmdev_h
37#define VBOX_INCLUDED_vmm_pdmdev_h
38#ifndef RT_WITHOUT_PRAGMA_ONCE
39# pragma once
40#endif
41
42#include <VBox/vmm/pdmcritsect.h>
43#include <VBox/vmm/pdmcritsectrw.h>
44#include <VBox/vmm/pdmqueue.h>
45#include <VBox/vmm/pdmtask.h>
46#ifdef IN_RING3
47# include <VBox/vmm/pdmthread.h>
48#endif
49#include <VBox/vmm/pdmifs.h>
50#include <VBox/vmm/pdmins.h>
51#include <VBox/vmm/pdmcommon.h>
52#include <VBox/vmm/pdmpcidev.h>
53#include <VBox/vmm/iom.h>
54#include <VBox/vmm/mm.h>
55#include <VBox/vmm/tm.h>
56#include <VBox/vmm/ssm.h>
57#include <VBox/vmm/cfgm.h>
58#include <VBox/vmm/cpum.h>
59#include <VBox/vmm/dbgf.h>
60#include <VBox/vmm/pgm.h> /* PGMR3HandlerPhysicalTypeRegister() argument types. */
61#include <VBox/vmm/gim.h>
62#include <VBox/err.h> /* VINF_EM_DBG_STOP, also 120+ source files expecting this. */
63#include <VBox/msi.h>
64#include <iprt/stdarg.h>
65#include <iprt/list.h>
66
67
68RT_C_DECLS_BEGIN
69
70/** @defgroup grp_pdm_device The PDM Devices API
71 * @ingroup grp_pdm
72 * @{
73 */
74
75/**
76 * Construct a device instance for a VM.
77 *
78 * @returns VBox status.
79 * @param pDevIns The device instance data. If the registration structure
80 * is needed, it can be accessed thru pDevIns->pReg.
81 * @param iInstance Instance number. Use this to figure out which registers
82 * and such to use. The instance number is also found in
83 * pDevIns->iInstance, but since it's likely to be
84 * frequently used PDM passes it as parameter.
85 * @param pCfg Configuration node handle for the driver. This is
86 * expected to be in high demand in the constructor and is
87 * therefore passed as an argument. When using it at other
88 * times, it can be found in pDevIns->pCfg.
89 */
90typedef DECLCALLBACKTYPE(int, FNPDMDEVCONSTRUCT,(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg));
91/** Pointer to a FNPDMDEVCONSTRUCT() function. */
92typedef FNPDMDEVCONSTRUCT *PFNPDMDEVCONSTRUCT;
93
94/**
95 * Destruct a device instance.
96 *
97 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
98 * resources can be freed correctly.
99 *
100 * @returns VBox status.
101 * @param pDevIns The device instance data.
102 *
103 * @remarks The device critical section is not entered. The routine may delete
104 * the critical section, so the caller cannot exit it.
105 */
106typedef DECLCALLBACKTYPE(int, FNPDMDEVDESTRUCT,(PPDMDEVINS pDevIns));
107/** Pointer to a FNPDMDEVDESTRUCT() function. */
108typedef FNPDMDEVDESTRUCT *PFNPDMDEVDESTRUCT;
109
110/**
111 * Device relocation callback.
112 *
113 * This is called when the instance data has been relocated in raw-mode context
114 * (RC). It is also called when the RC hypervisor selects changes. The device
115 * must fixup all necessary pointers and re-query all interfaces to other RC
116 * devices and drivers.
117 *
118 * Before the RC code is executed the first time, this function will be called
119 * with a 0 delta so RC pointer calculations can be one in one place.
120 *
121 * @param pDevIns Pointer to the device instance.
122 * @param offDelta The relocation delta relative to the old location.
123 *
124 * @remarks A relocation CANNOT fail.
125 *
126 * @remarks The device critical section is not entered. The relocations should
127 * not normally require any locking.
128 */
129typedef DECLCALLBACKTYPE(void, FNPDMDEVRELOCATE,(PPDMDEVINS pDevIns, RTGCINTPTR offDelta));
130/** Pointer to a FNPDMDEVRELOCATE() function. */
131typedef FNPDMDEVRELOCATE *PFNPDMDEVRELOCATE;
132
133/**
134 * Power On notification.
135 *
136 * @param pDevIns The device instance data.
137 *
138 * @remarks Caller enters the device critical section.
139 */
140typedef DECLCALLBACKTYPE(void, FNPDMDEVPOWERON,(PPDMDEVINS pDevIns));
141/** Pointer to a FNPDMDEVPOWERON() function. */
142typedef FNPDMDEVPOWERON *PFNPDMDEVPOWERON;
143
144/**
145 * Reset notification.
146 *
147 * @param pDevIns The device instance data.
148 *
149 * @remarks Caller enters the device critical section.
150 */
151typedef DECLCALLBACKTYPE(void, FNPDMDEVRESET,(PPDMDEVINS pDevIns));
152/** Pointer to a FNPDMDEVRESET() function. */
153typedef FNPDMDEVRESET *PFNPDMDEVRESET;
154
155/**
156 * Soft reset notification.
157 *
158 * This is mainly for emulating the 286 style protected mode exits, in which
159 * most devices should remain in their current state.
160 *
161 * @param pDevIns The device instance data.
162 * @param fFlags PDMVMRESET_F_XXX (only bits relevant to soft resets).
163 *
164 * @remarks Caller enters the device critical section.
165 */
166typedef DECLCALLBACKTYPE(void, FNPDMDEVSOFTRESET,(PPDMDEVINS pDevIns, uint32_t fFlags));
167/** Pointer to a FNPDMDEVSOFTRESET() function. */
168typedef FNPDMDEVSOFTRESET *PFNPDMDEVSOFTRESET;
169
170/** @name PDMVMRESET_F_XXX - VM reset flags.
171 * These flags are used both for FNPDMDEVSOFTRESET and for hardware signalling
172 * reset via PDMDevHlpVMReset.
173 * @{ */
174/** Unknown reason. */
175#define PDMVMRESET_F_UNKNOWN UINT32_C(0x00000000)
176/** GIM triggered reset. */
177#define PDMVMRESET_F_GIM UINT32_C(0x00000001)
178/** The last source always causing hard resets. */
179#define PDMVMRESET_F_LAST_ALWAYS_HARD PDMVMRESET_F_GIM
180/** ACPI triggered reset. */
181#define PDMVMRESET_F_ACPI UINT32_C(0x0000000c)
182/** PS/2 system port A (92h) reset. */
183#define PDMVMRESET_F_PORT_A UINT32_C(0x0000000d)
184/** Keyboard reset. */
185#define PDMVMRESET_F_KBD UINT32_C(0x0000000e)
186/** Tripple fault. */
187#define PDMVMRESET_F_TRIPLE_FAULT UINT32_C(0x0000000f)
188/** Reset source mask. */
189#define PDMVMRESET_F_SRC_MASK UINT32_C(0x0000000f)
190/** @} */
191
192/**
193 * Suspend notification.
194 *
195 * @param pDevIns The device instance data.
196 * @thread EMT(0)
197 *
198 * @remarks Caller enters the device critical section.
199 */
200typedef DECLCALLBACKTYPE(void, FNPDMDEVSUSPEND,(PPDMDEVINS pDevIns));
201/** Pointer to a FNPDMDEVSUSPEND() function. */
202typedef FNPDMDEVSUSPEND *PFNPDMDEVSUSPEND;
203
204/**
205 * Resume notification.
206 *
207 * @param pDevIns The device instance data.
208 *
209 * @remarks Caller enters the device critical section.
210 */
211typedef DECLCALLBACKTYPE(void, FNPDMDEVRESUME,(PPDMDEVINS pDevIns));
212/** Pointer to a FNPDMDEVRESUME() function. */
213typedef FNPDMDEVRESUME *PFNPDMDEVRESUME;
214
215/**
216 * Power Off notification.
217 *
218 * This is always called when VMR3PowerOff is called.
219 * There will be no callback when hot plugging devices.
220 *
221 * @param pDevIns The device instance data.
222 * @thread EMT(0)
223 *
224 * @remarks Caller enters the device critical section.
225 */
226typedef DECLCALLBACKTYPE(void, FNPDMDEVPOWEROFF,(PPDMDEVINS pDevIns));
227/** Pointer to a FNPDMDEVPOWEROFF() function. */
228typedef FNPDMDEVPOWEROFF *PFNPDMDEVPOWEROFF;
229
230/**
231 * Attach command.
232 *
233 * This is called to let the device attach to a driver for a specified LUN
234 * at runtime. This is not called during VM construction, the device
235 * constructor has to attach to all the available drivers.
236 *
237 * This is like plugging in the keyboard or mouse after turning on the PC.
238 *
239 * @returns VBox status code.
240 * @param pDevIns The device instance.
241 * @param iLUN The logical unit which is being attached.
242 * @param fFlags Flags, combination of the PDM_TACH_FLAGS_* \#defines.
243 *
244 * @remarks Caller enters the device critical section.
245 */
246typedef DECLCALLBACKTYPE(int, FNPDMDEVATTACH,(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags));
247/** Pointer to a FNPDMDEVATTACH() function. */
248typedef FNPDMDEVATTACH *PFNPDMDEVATTACH;
249
250/**
251 * Detach notification.
252 *
253 * This is called when a driver is detaching itself from a LUN of the device.
254 * The device should adjust its state to reflect this.
255 *
256 * This is like unplugging the network cable to use it for the laptop or
257 * something while the PC is still running.
258 *
259 * @param pDevIns The device instance.
260 * @param iLUN The logical unit which is being detached.
261 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
262 *
263 * @remarks Caller enters the device critical section.
264 */
265typedef DECLCALLBACKTYPE(void, FNPDMDEVDETACH,(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags));
266/** Pointer to a FNPDMDEVDETACH() function. */
267typedef FNPDMDEVDETACH *PFNPDMDEVDETACH;
268
269/**
270 * Query the base interface of a logical unit.
271 *
272 * @returns VBOX status code.
273 * @param pDevIns The device instance.
274 * @param iLUN The logicial unit to query.
275 * @param ppBase Where to store the pointer to the base interface of the LUN.
276 *
277 * @remarks The device critical section is not entered.
278 */
279typedef DECLCALLBACKTYPE(int, FNPDMDEVQUERYINTERFACE,(PPDMDEVINS pDevIns, unsigned iLUN, PPDMIBASE *ppBase));
280/** Pointer to a FNPDMDEVQUERYINTERFACE() function. */
281typedef FNPDMDEVQUERYINTERFACE *PFNPDMDEVQUERYINTERFACE;
282
283/**
284 * Init complete notification (after ring-0 & RC init since 5.1).
285 *
286 * This can be done to do communication with other devices and other
287 * initialization which requires everything to be in place.
288 *
289 * @returns VBOX status code.
290 * @param pDevIns The device instance.
291 *
292 * @remarks Caller enters the device critical section.
293 */
294typedef DECLCALLBACKTYPE(int, FNPDMDEVINITCOMPLETE,(PPDMDEVINS pDevIns));
295/** Pointer to a FNPDMDEVINITCOMPLETE() function. */
296typedef FNPDMDEVINITCOMPLETE *PFNPDMDEVINITCOMPLETE;
297
298
299/**
300 * The context of a pfnMemSetup call.
301 */
302typedef enum PDMDEVMEMSETUPCTX
303{
304 /** Invalid zero value. */
305 PDMDEVMEMSETUPCTX_INVALID = 0,
306 /** After construction. */
307 PDMDEVMEMSETUPCTX_AFTER_CONSTRUCTION,
308 /** After reset. */
309 PDMDEVMEMSETUPCTX_AFTER_RESET,
310 /** Type size hack. */
311 PDMDEVMEMSETUPCTX_32BIT_HACK = 0x7fffffff
312} PDMDEVMEMSETUPCTX;
313
314
315/**
316 * PDM Device Registration Structure.
317 *
318 * This structure is used when registering a device from VBoxInitDevices() in HC
319 * Ring-3. PDM will continue use till the VM is terminated.
320 *
321 * @note The first part is the same in every context.
322 */
323typedef struct PDMDEVREGR3
324{
325 /** Structure version. PDM_DEVREGR3_VERSION defines the current version. */
326 uint32_t u32Version;
327 /** Reserved, must be zero. */
328 uint32_t uReserved0;
329 /** Device name, must match the ring-3 one. */
330 char szName[32];
331 /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
332 uint32_t fFlags;
333 /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
334 uint32_t fClass;
335 /** Maximum number of instances (per VM). */
336 uint32_t cMaxInstances;
337 /** The shared data structure version number. */
338 uint32_t uSharedVersion;
339 /** Size of the instance data. */
340 uint32_t cbInstanceShared;
341 /** Size of the ring-0 instance data. */
342 uint32_t cbInstanceCC;
343 /** Size of the raw-mode instance data. */
344 uint32_t cbInstanceRC;
345 /** Max number of PCI devices. */
346 uint16_t cMaxPciDevices;
347 /** Max number of MSI-X vectors in any of the PCI devices. */
348 uint16_t cMaxMsixVectors;
349 /** The description of the device. The UTF-8 string pointed to shall, like this structure,
350 * remain unchanged from registration till VM destruction. */
351 const char *pszDescription;
352
353 /** Name of the raw-mode context module (no path).
354 * Only evalutated if PDM_DEVREG_FLAGS_RC is set. */
355 const char *pszRCMod;
356 /** Name of the ring-0 module (no path).
357 * Only evalutated if PDM_DEVREG_FLAGS_R0 is set. */
358 const char *pszR0Mod;
359
360 /** Construct instance - required. */
361 PFNPDMDEVCONSTRUCT pfnConstruct;
362 /** Destruct instance - optional.
363 * Critical section NOT entered (will be destroyed). */
364 PFNPDMDEVDESTRUCT pfnDestruct;
365 /** Relocation command - optional.
366 * Critical section NOT entered. */
367 PFNPDMDEVRELOCATE pfnRelocate;
368 /**
369 * Memory setup callback.
370 *
371 * @param pDevIns The device instance data.
372 * @param enmCtx Indicates the context of the call.
373 * @remarks The critical section is entered prior to calling this method.
374 */
375 DECLR3CALLBACKMEMBER(void, pfnMemSetup, (PPDMDEVINS pDevIns, PDMDEVMEMSETUPCTX enmCtx));
376 /** Power on notification - optional.
377 * Critical section is entered. */
378 PFNPDMDEVPOWERON pfnPowerOn;
379 /** Reset notification - optional.
380 * Critical section is entered. */
381 PFNPDMDEVRESET pfnReset;
382 /** Suspend notification - optional.
383 * Critical section is entered. */
384 PFNPDMDEVSUSPEND pfnSuspend;
385 /** Resume notification - optional.
386 * Critical section is entered. */
387 PFNPDMDEVRESUME pfnResume;
388 /** Attach command - optional.
389 * Critical section is entered. */
390 PFNPDMDEVATTACH pfnAttach;
391 /** Detach notification - optional.
392 * Critical section is entered. */
393 PFNPDMDEVDETACH pfnDetach;
394 /** Query a LUN base interface - optional.
395 * Critical section is NOT entered. */
396 PFNPDMDEVQUERYINTERFACE pfnQueryInterface;
397 /** Init complete notification - optional.
398 * Critical section is entered. */
399 PFNPDMDEVINITCOMPLETE pfnInitComplete;
400 /** Power off notification - optional.
401 * Critical section is entered. */
402 PFNPDMDEVPOWEROFF pfnPowerOff;
403 /** Software system reset notification - optional.
404 * Critical section is entered. */
405 PFNPDMDEVSOFTRESET pfnSoftReset;
406
407 /** @name Reserved for future extensions, must be zero.
408 * @{ */
409 DECLR3CALLBACKMEMBER(int, pfnReserved0, (PPDMDEVINS pDevIns));
410 DECLR3CALLBACKMEMBER(int, pfnReserved1, (PPDMDEVINS pDevIns));
411 DECLR3CALLBACKMEMBER(int, pfnReserved2, (PPDMDEVINS pDevIns));
412 DECLR3CALLBACKMEMBER(int, pfnReserved3, (PPDMDEVINS pDevIns));
413 DECLR3CALLBACKMEMBER(int, pfnReserved4, (PPDMDEVINS pDevIns));
414 DECLR3CALLBACKMEMBER(int, pfnReserved5, (PPDMDEVINS pDevIns));
415 DECLR3CALLBACKMEMBER(int, pfnReserved6, (PPDMDEVINS pDevIns));
416 DECLR3CALLBACKMEMBER(int, pfnReserved7, (PPDMDEVINS pDevIns));
417 /** @} */
418
419 /** Initialization safty marker. */
420 uint32_t u32VersionEnd;
421} PDMDEVREGR3;
422/** Pointer to a PDM Device Structure. */
423typedef PDMDEVREGR3 *PPDMDEVREGR3;
424/** Const pointer to a PDM Device Structure. */
425typedef PDMDEVREGR3 const *PCPDMDEVREGR3;
426/** Current DEVREGR3 version number. */
427#define PDM_DEVREGR3_VERSION PDM_VERSION_MAKE(0xffff, 4, 0)
428
429
430/** PDM Device Flags.
431 * @{ */
432/** This flag is used to indicate that the device has a R0 component. */
433#define PDM_DEVREG_FLAGS_R0 UINT32_C(0x00000001)
434/** Requires the ring-0 component, ignore configuration values. */
435#define PDM_DEVREG_FLAGS_REQUIRE_R0 UINT32_C(0x00000002)
436/** Requires the ring-0 component, ignore configuration values. */
437#define PDM_DEVREG_FLAGS_OPT_IN_R0 UINT32_C(0x00000004)
438
439/** This flag is used to indicate that the device has a RC component. */
440#define PDM_DEVREG_FLAGS_RC UINT32_C(0x00000010)
441/** Requires the raw-mode component, ignore configuration values. */
442#define PDM_DEVREG_FLAGS_REQUIRE_RC UINT32_C(0x00000020)
443/** Requires the raw-mode component, ignore configuration values. */
444#define PDM_DEVREG_FLAGS_OPT_IN_RC UINT32_C(0x00000040)
445
446/** Convenience: PDM_DEVREG_FLAGS_R0 + PDM_DEVREG_FLAGS_RC */
447#define PDM_DEVREG_FLAGS_RZ (PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC)
448
449/** @def PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT
450 * The bit count for the current host.
451 * @note Superfluous, but still around for hysterical raisins. */
452#if HC_ARCH_BITS == 32
453# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT UINT32_C(0x00000100)
454#elif HC_ARCH_BITS == 64
455# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT UINT32_C(0x00000200)
456#else
457# error Unsupported HC_ARCH_BITS value.
458#endif
459/** The host bit count mask. */
460#define PDM_DEVREG_FLAGS_HOST_BITS_MASK UINT32_C(0x00000300)
461
462/** The device support only 32-bit guests. */
463#define PDM_DEVREG_FLAGS_GUEST_BITS_32 UINT32_C(0x00001000)
464/** The device support only 64-bit guests. */
465#define PDM_DEVREG_FLAGS_GUEST_BITS_64 UINT32_C(0x00002000)
466/** The device support both 32-bit & 64-bit guests. */
467#define PDM_DEVREG_FLAGS_GUEST_BITS_32_64 UINT32_C(0x00003000)
468/** @def PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT
469 * The guest bit count for the current compilation. */
470#if GC_ARCH_BITS == 32
471# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT PDM_DEVREG_FLAGS_GUEST_BITS_32
472#elif GC_ARCH_BITS == 64
473# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT PDM_DEVREG_FLAGS_GUEST_BITS_32_64
474#else
475# error Unsupported GC_ARCH_BITS value.
476#endif
477/** The guest bit count mask. */
478#define PDM_DEVREG_FLAGS_GUEST_BITS_MASK UINT32_C(0x00003000)
479
480/** A convenience. */
481#define PDM_DEVREG_FLAGS_DEFAULT_BITS (PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT)
482
483/** Indicates that the device needs to be notified before the drivers when suspending. */
484#define PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION UINT32_C(0x00010000)
485/** Indicates that the device needs to be notified before the drivers when powering off. */
486#define PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION UINT32_C(0x00020000)
487/** Indicates that the device needs to be notified before the drivers when resetting. */
488#define PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION UINT32_C(0x00040000)
489
490/** This flag is used to indicate that the device has been converted to the
491 * new device style. */
492#define PDM_DEVREG_FLAGS_NEW_STYLE UINT32_C(0x80000000)
493
494/** @} */
495
496
497/** PDM Device Classes.
498 * The order is important, lower bit earlier instantiation.
499 * @{ */
500/** Architecture device. */
501#define PDM_DEVREG_CLASS_ARCH RT_BIT(0)
502/** Architecture BIOS device. */
503#define PDM_DEVREG_CLASS_ARCH_BIOS RT_BIT(1)
504/** PCI bus brigde. */
505#define PDM_DEVREG_CLASS_BUS_PCI RT_BIT(2)
506/** PCI built-in device (e.g. PCI root complex devices). */
507#define PDM_DEVREG_CLASS_PCI_BUILTIN RT_BIT(3)
508/** Input device (mouse, keyboard, joystick, HID, ...). */
509#define PDM_DEVREG_CLASS_INPUT RT_BIT(4)
510/** Interrupt controller (PIC). */
511#define PDM_DEVREG_CLASS_PIC RT_BIT(5)
512/** Interval controoler (PIT). */
513#define PDM_DEVREG_CLASS_PIT RT_BIT(6)
514/** RTC/CMOS. */
515#define PDM_DEVREG_CLASS_RTC RT_BIT(7)
516/** DMA controller. */
517#define PDM_DEVREG_CLASS_DMA RT_BIT(8)
518/** VMM Device. */
519#define PDM_DEVREG_CLASS_VMM_DEV RT_BIT(9)
520/** Graphics device, like VGA. */
521#define PDM_DEVREG_CLASS_GRAPHICS RT_BIT(10)
522/** Storage controller device. */
523#define PDM_DEVREG_CLASS_STORAGE RT_BIT(11)
524/** Network interface controller. */
525#define PDM_DEVREG_CLASS_NETWORK RT_BIT(12)
526/** Audio. */
527#define PDM_DEVREG_CLASS_AUDIO RT_BIT(13)
528/** USB HIC. */
529#define PDM_DEVREG_CLASS_BUS_USB RT_BIT(14)
530/** ACPI. */
531#define PDM_DEVREG_CLASS_ACPI RT_BIT(15)
532/** Serial controller device. */
533#define PDM_DEVREG_CLASS_SERIAL RT_BIT(16)
534/** Parallel controller device */
535#define PDM_DEVREG_CLASS_PARALLEL RT_BIT(17)
536/** Host PCI pass-through device */
537#define PDM_DEVREG_CLASS_HOST_DEV RT_BIT(18)
538/** GPIO device */
539#define PDM_DEVREG_CLASS_GPIO RT_BIT(19)
540/** Misc devices (always last). */
541#define PDM_DEVREG_CLASS_MISC RT_BIT(31)
542/** @} */
543
544
545/**
546 * PDM Device Registration Structure, ring-0.
547 *
548 * This structure is used when registering a device from VBoxInitDevices() in HC
549 * Ring-0. PDM will continue use till the VM is terminated.
550 */
551typedef struct PDMDEVREGR0
552{
553 /** Structure version. PDM_DEVREGR0_VERSION defines the current version. */
554 uint32_t u32Version;
555 /** Reserved, must be zero. */
556 uint32_t uReserved0;
557 /** Device name, must match the ring-3 one. */
558 char szName[32];
559 /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
560 uint32_t fFlags;
561 /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
562 uint32_t fClass;
563 /** Maximum number of instances (per VM). */
564 uint32_t cMaxInstances;
565 /** The shared data structure version number. */
566 uint32_t uSharedVersion;
567 /** Size of the instance data. */
568 uint32_t cbInstanceShared;
569 /** Size of the ring-0 instance data. */
570 uint32_t cbInstanceCC;
571 /** Size of the raw-mode instance data. */
572 uint32_t cbInstanceRC;
573 /** Max number of PCI devices. */
574 uint16_t cMaxPciDevices;
575 /** Max number of MSI-X vectors in any of the PCI devices. */
576 uint16_t cMaxMsixVectors;
577 /** The description of the device. The UTF-8 string pointed to shall, like this structure,
578 * remain unchanged from registration till VM destruction. */
579 const char *pszDescription;
580
581 /**
582 * Early construction callback (optional).
583 *
584 * This is called right after the device instance structure has been allocated
585 * and before the ring-3 constructor gets called.
586 *
587 * @returns VBox status code.
588 * @param pDevIns The device instance data.
589 * @note The destructure is always called, regardless of the return status.
590 */
591 DECLR0CALLBACKMEMBER(int, pfnEarlyConstruct, (PPDMDEVINS pDevIns));
592
593 /**
594 * Regular construction callback (optional).
595 *
596 * This is called after (or during) the ring-3 constructor.
597 *
598 * @returns VBox status code.
599 * @param pDevIns The device instance data.
600 * @note The destructure is always called, regardless of the return status.
601 */
602 DECLR0CALLBACKMEMBER(int, pfnConstruct, (PPDMDEVINS pDevIns));
603
604 /**
605 * Destructor (optional).
606 *
607 * This is called after the ring-3 destruction. This is not called if ring-3
608 * fails to trigger it (e.g. process is killed or crashes).
609 *
610 * @param pDevIns The device instance data.
611 */
612 DECLR0CALLBACKMEMBER(void, pfnDestruct, (PPDMDEVINS pDevIns));
613
614 /**
615 * Final destructor (optional).
616 *
617 * This is called right before the memory is freed, which happens when the
618 * VM/GVM object is destroyed. This is always called.
619 *
620 * @param pDevIns The device instance data.
621 */
622 DECLR0CALLBACKMEMBER(void, pfnFinalDestruct, (PPDMDEVINS pDevIns));
623
624 /**
625 * Generic request handler (optional).
626 *
627 * @param pDevIns The device instance data.
628 * @param uReq Device specific request.
629 * @param uArg Request argument.
630 */
631 DECLR0CALLBACKMEMBER(int, pfnRequest, (PPDMDEVINS pDevIns, uint32_t uReq, uint64_t uArg));
632
633 /** @name Reserved for future extensions, must be zero.
634 * @{ */
635 DECLR0CALLBACKMEMBER(int, pfnReserved0, (PPDMDEVINS pDevIns));
636 DECLR0CALLBACKMEMBER(int, pfnReserved1, (PPDMDEVINS pDevIns));
637 DECLR0CALLBACKMEMBER(int, pfnReserved2, (PPDMDEVINS pDevIns));
638 DECLR0CALLBACKMEMBER(int, pfnReserved3, (PPDMDEVINS pDevIns));
639 DECLR0CALLBACKMEMBER(int, pfnReserved4, (PPDMDEVINS pDevIns));
640 DECLR0CALLBACKMEMBER(int, pfnReserved5, (PPDMDEVINS pDevIns));
641 DECLR0CALLBACKMEMBER(int, pfnReserved6, (PPDMDEVINS pDevIns));
642 DECLR0CALLBACKMEMBER(int, pfnReserved7, (PPDMDEVINS pDevIns));
643 /** @} */
644
645 /** Initialization safty marker. */
646 uint32_t u32VersionEnd;
647} PDMDEVREGR0;
648/** Pointer to a ring-0 PDM device registration structure. */
649typedef PDMDEVREGR0 *PPDMDEVREGR0;
650/** Pointer to a const ring-0 PDM device registration structure. */
651typedef PDMDEVREGR0 const *PCPDMDEVREGR0;
652/** Current DEVREGR0 version number. */
653#define PDM_DEVREGR0_VERSION PDM_VERSION_MAKE(0xff80, 1, 0)
654
655
656/**
657 * PDM Device Registration Structure, raw-mode
658 *
659 * At the moment, this structure is mostly here to match the other two contexts.
660 */
661typedef struct PDMDEVREGRC
662{
663 /** Structure version. PDM_DEVREGRC_VERSION defines the current version. */
664 uint32_t u32Version;
665 /** Reserved, must be zero. */
666 uint32_t uReserved0;
667 /** Device name, must match the ring-3 one. */
668 char szName[32];
669 /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
670 uint32_t fFlags;
671 /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
672 uint32_t fClass;
673 /** Maximum number of instances (per VM). */
674 uint32_t cMaxInstances;
675 /** The shared data structure version number. */
676 uint32_t uSharedVersion;
677 /** Size of the instance data. */
678 uint32_t cbInstanceShared;
679 /** Size of the ring-0 instance data. */
680 uint32_t cbInstanceCC;
681 /** Size of the raw-mode instance data. */
682 uint32_t cbInstanceRC;
683 /** Max number of PCI devices. */
684 uint16_t cMaxPciDevices;
685 /** Max number of MSI-X vectors in any of the PCI devices. */
686 uint16_t cMaxMsixVectors;
687 /** The description of the device. The UTF-8 string pointed to shall, like this structure,
688 * remain unchanged from registration till VM destruction. */
689 const char *pszDescription;
690
691 /**
692 * Constructor callback.
693 *
694 * This is called much later than both the ring-0 and ring-3 constructors, since
695 * raw-mode v2 require a working VMM to run actual code.
696 *
697 * @returns VBox status code.
698 * @param pDevIns The device instance data.
699 * @note The destructure is always called, regardless of the return status.
700 */
701 DECLRGCALLBACKMEMBER(int, pfnConstruct, (PPDMDEVINS pDevIns));
702
703 /** @name Reserved for future extensions, must be zero.
704 * @{ */
705 DECLRCCALLBACKMEMBER(int, pfnReserved0, (PPDMDEVINS pDevIns));
706 DECLRCCALLBACKMEMBER(int, pfnReserved1, (PPDMDEVINS pDevIns));
707 DECLRCCALLBACKMEMBER(int, pfnReserved2, (PPDMDEVINS pDevIns));
708 DECLRCCALLBACKMEMBER(int, pfnReserved3, (PPDMDEVINS pDevIns));
709 DECLRCCALLBACKMEMBER(int, pfnReserved4, (PPDMDEVINS pDevIns));
710 DECLRCCALLBACKMEMBER(int, pfnReserved5, (PPDMDEVINS pDevIns));
711 DECLRCCALLBACKMEMBER(int, pfnReserved6, (PPDMDEVINS pDevIns));
712 DECLRCCALLBACKMEMBER(int, pfnReserved7, (PPDMDEVINS pDevIns));
713 /** @} */
714
715 /** Initialization safty marker. */
716 uint32_t u32VersionEnd;
717} PDMDEVREGRC;
718/** Pointer to a raw-mode PDM device registration structure. */
719typedef PDMDEVREGRC *PPDMDEVREGRC;
720/** Pointer to a const raw-mode PDM device registration structure. */
721typedef PDMDEVREGRC const *PCPDMDEVREGRC;
722/** Current DEVREGRC version number. */
723#define PDM_DEVREGRC_VERSION PDM_VERSION_MAKE(0xff81, 1, 0)
724
725
726
727/** @def PDM_DEVREG_VERSION
728 * Current DEVREG version number. */
729/** @typedef PDMDEVREGR3
730 * A current context PDM device registration structure. */
731/** @typedef PPDMDEVREGR3
732 * Pointer to a current context PDM device registration structure. */
733/** @typedef PCPDMDEVREGR3
734 * Pointer to a const current context PDM device registration structure. */
735#if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
736# define PDM_DEVREG_VERSION PDM_DEVREGR3_VERSION
737typedef PDMDEVREGR3 PDMDEVREG;
738typedef PPDMDEVREGR3 PPDMDEVREG;
739typedef PCPDMDEVREGR3 PCPDMDEVREG;
740#elif defined(IN_RING0)
741# define PDM_DEVREG_VERSION PDM_DEVREGR0_VERSION
742typedef PDMDEVREGR0 PDMDEVREG;
743typedef PPDMDEVREGR0 PPDMDEVREG;
744typedef PCPDMDEVREGR0 PCPDMDEVREG;
745#elif defined(IN_RC)
746# define PDM_DEVREG_VERSION PDM_DEVREGRC_VERSION
747typedef PDMDEVREGRC PDMDEVREG;
748typedef PPDMDEVREGRC PPDMDEVREG;
749typedef PCPDMDEVREGRC PCPDMDEVREG;
750#else
751# error "Not IN_RING3, IN_RING0 or IN_RC"
752#endif
753
754
755/**
756 * Device registrations for ring-0 modules.
757 *
758 * This structure is used directly and must therefore reside in persistent
759 * memory (i.e. the data section).
760 */
761typedef struct PDMDEVMODREGR0
762{
763 /** The structure version (PDM_DEVMODREGR0_VERSION). */
764 uint32_t u32Version;
765 /** Number of devices in the array papDevRegs points to. */
766 uint32_t cDevRegs;
767 /** Pointer to device registration structures. */
768 PCPDMDEVREGR0 *papDevRegs;
769 /** The ring-0 module handle - PDM internal, fingers off. */
770 void *hMod;
771 /** List entry - PDM internal, fingers off. */
772 RTLISTNODE ListEntry;
773} PDMDEVMODREGR0;
774/** Pointer to device registriations for a ring-0 module. */
775typedef PDMDEVMODREGR0 *PPDMDEVMODREGR0;
776/** Current PDMDEVMODREGR0 version number. */
777#define PDM_DEVMODREGR0_VERSION PDM_VERSION_MAKE(0xff85, 1, 0)
778
779
780/** @name IRQ Level for use with the *SetIrq APIs.
781 * @{
782 */
783/** Assert the IRQ (can assume value 1). */
784#define PDM_IRQ_LEVEL_HIGH RT_BIT(0)
785/** Deassert the IRQ (can assume value 0). */
786#define PDM_IRQ_LEVEL_LOW 0
787/** flip-flop - deassert and then assert the IRQ again immediately (PIC) /
788 * automatically deasserts it after delivery to the APIC (IOAPIC).
789 * @note Only suitable for edge trigger interrupts. */
790#define PDM_IRQ_LEVEL_FLIP_FLOP (RT_BIT(1) | PDM_IRQ_LEVEL_HIGH)
791/** @} */
792
793/**
794 * Registration record for MSI/MSI-X emulation.
795 */
796typedef struct PDMMSIREG
797{
798 /** Number of MSI interrupt vectors, 0 if MSI not supported */
799 uint16_t cMsiVectors;
800 /** Offset of MSI capability */
801 uint8_t iMsiCapOffset;
802 /** Offset of next capability to MSI */
803 uint8_t iMsiNextOffset;
804 /** If we support 64-bit MSI addressing */
805 bool fMsi64bit;
806 /** If we do not support per-vector masking */
807 bool fMsiNoMasking;
808
809 /** Number of MSI-X interrupt vectors, 0 if MSI-X not supported */
810 uint16_t cMsixVectors;
811 /** Offset of MSI-X capability */
812 uint8_t iMsixCapOffset;
813 /** Offset of next capability to MSI-X */
814 uint8_t iMsixNextOffset;
815 /** Value of PCI BAR (base addresss register) assigned by device for MSI-X page access */
816 uint8_t iMsixBar;
817} PDMMSIREG;
818typedef PDMMSIREG *PPDMMSIREG;
819
820/**
821 * PCI Bus registration structure.
822 * All the callbacks, except the PCIBIOS hack, are working on PCI devices.
823 */
824typedef struct PDMPCIBUSREGR3
825{
826 /** Structure version number. PDM_PCIBUSREGR3_VERSION defines the current version. */
827 uint32_t u32Version;
828
829 /**
830 * Registers the device with the default PCI bus.
831 *
832 * @returns VBox status code.
833 * @param pDevIns Device instance of the PCI Bus.
834 * @param pPciDev The PCI device structure.
835 * @param fFlags Reserved for future use, PDMPCIDEVREG_F_MBZ.
836 * @param uPciDevNo PDMPCIDEVREG_DEV_NO_FIRST_UNUSED, or a specific
837 * device number (0-31).
838 * @param uPciFunNo PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, or a specific
839 * function number (0-7).
840 * @param pszName Device name (static but not unique).
841 *
842 * @remarks Caller enters the PDM critical section.
843 */
844 DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
845 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName));
846
847 /**
848 * Initialize MSI or MSI-X emulation support in a PCI device.
849 *
850 * This cannot handle all corner cases of the MSI/MSI-X spec, but for the
851 * vast majority of device emulation it covers everything necessary. It's
852 * fully automatic, taking care of all BAR and config space requirements,
853 * and interrupt delivery is done using PDMDevHlpPCISetIrq and friends.
854 * When MSI/MSI-X is enabled then the iIrq parameter is redefined to take
855 * the vector number (otherwise it has the usual INTA-D meaning for PCI).
856 *
857 * A device not using this can still offer MSI/MSI-X. In this case it's
858 * completely up to the device (in the MSI-X case) to create/register the
859 * necessary MMIO BAR, handle all config space/BAR updating and take care
860 * of delivering the interrupts appropriately.
861 *
862 * @returns VBox status code.
863 * @param pDevIns Device instance of the PCI Bus.
864 * @param pPciDev The PCI device structure.
865 * @param pMsiReg MSI emulation registration structure
866 * @remarks Caller enters the PDM critical section.
867 */
868 DECLR3CALLBACKMEMBER(int, pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg));
869
870 /**
871 * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
872 *
873 * @returns VBox status code.
874 * @param pDevIns Device instance of the PCI Bus.
875 * @param pPciDev The PCI device structure.
876 * @param iRegion The region number.
877 * @param cbRegion Size of the region.
878 * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or
879 * PCI_ADDRESS_SPACE_MEM_PREFETCH, optionally with
880 * PCI_ADDRESS_SPACE_BAR64 or'ed in.
881 * @param fFlags PDMPCIDEV_IORGN_F_XXX.
882 * @param hHandle An I/O port, MMIO or MMIO2 handle according to
883 * @a fFlags, UINT64_MAX if no handle is passed
884 * (old style).
885 * @param pfnMapUnmap Callback for doing the mapping. Optional if a handle
886 * is given.
887 * @remarks Caller enters the PDM critical section.
888 */
889 DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
890 RTGCPHYS cbRegion, PCIADDRESSSPACE enmType, uint32_t fFlags,
891 uint64_t hHandle, PFNPCIIOREGIONMAP pfnMapUnmap));
892
893 /**
894 * Register PCI configuration space read/write intercept callbacks.
895 *
896 * @param pDevIns Device instance of the PCI Bus.
897 * @param pPciDev The PCI device structure.
898 * @param pfnRead Pointer to the user defined PCI config read function.
899 * @param pfnWrite Pointer to the user defined PCI config write function.
900 * to call default PCI config write function. Can be NULL.
901 * @remarks Caller enters the PDM critical section.
902 * @thread EMT
903 */
904 DECLR3CALLBACKMEMBER(void, pfnInterceptConfigAccesses,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
905 PFNPCICONFIGREAD pfnRead, PFNPCICONFIGWRITE pfnWrite));
906
907 /**
908 * Perform a PCI configuration space write, bypassing interception.
909 *
910 * This is for devices that make use of PDMDevHlpPCIInterceptConfigAccesses().
911 *
912 * @returns Strict VBox status code (mainly DBGFSTOP).
913 * @param pDevIns Device instance of the PCI Bus.
914 * @param pPciDev The PCI device which config space is being read.
915 * @param uAddress The config space address.
916 * @param cb The size of the read: 1, 2 or 4 bytes.
917 * @param u32Value The value to write.
918 * @note The caller (PDM) does not enter the PDM critsect, but it is possible
919 * that the (root) bus will have done that already.
920 */
921 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnConfigWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
922 uint32_t uAddress, unsigned cb, uint32_t u32Value));
923
924 /**
925 * Perform a PCI configuration space read, bypassing interception.
926 *
927 * This is for devices that make use of PDMDevHlpPCIInterceptConfigAccesses().
928 *
929 * @returns Strict VBox status code (mainly DBGFSTOP).
930 * @param pDevIns Device instance of the PCI Bus.
931 * @param pPciDev The PCI device which config space is being read.
932 * @param uAddress The config space address.
933 * @param cb The size of the read: 1, 2 or 4 bytes.
934 * @param pu32Value Where to return the value.
935 * @note The caller (PDM) does not enter the PDM critsect, but it is possible
936 * that the (root) bus will have done that already.
937 */
938 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnConfigRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
939 uint32_t uAddress, unsigned cb, uint32_t *pu32Value));
940
941 /**
942 * Set the IRQ for a PCI device.
943 *
944 * @param pDevIns Device instance of the PCI Bus.
945 * @param pPciDev The PCI device structure.
946 * @param iIrq IRQ number to set.
947 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
948 * @param uTagSrc The IRQ tag and source (for tracing).
949 * @remarks Caller enters the PDM critical section.
950 */
951 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
952
953 /** Marks the end of the structure with PDM_PCIBUSREGR3_VERSION. */
954 uint32_t u32EndVersion;
955} PDMPCIBUSREGR3;
956/** Pointer to a PCI bus registration structure. */
957typedef PDMPCIBUSREGR3 *PPDMPCIBUSREGR3;
958/** Current PDMPCIBUSREGR3 version number. */
959#define PDM_PCIBUSREGR3_VERSION PDM_VERSION_MAKE(0xff86, 2, 0)
960
961/**
962 * PCI Bus registration structure for ring-0.
963 */
964typedef struct PDMPCIBUSREGR0
965{
966 /** Structure version number. PDM_PCIBUSREGR0_VERSION defines the current version. */
967 uint32_t u32Version;
968 /** The PCI bus number (from ring-3 registration). */
969 uint32_t iBus;
970 /**
971 * Set the IRQ for a PCI device.
972 *
973 * @param pDevIns Device instance of the PCI Bus.
974 * @param pPciDev The PCI device structure.
975 * @param iIrq IRQ number to set.
976 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
977 * @param uTagSrc The IRQ tag and source (for tracing).
978 * @remarks Caller enters the PDM critical section.
979 */
980 DECLR0CALLBACKMEMBER(void, pfnSetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
981 /** Marks the end of the structure with PDM_PCIBUSREGR0_VERSION. */
982 uint32_t u32EndVersion;
983} PDMPCIBUSREGR0;
984/** Pointer to a PCI bus ring-0 registration structure. */
985typedef PDMPCIBUSREGR0 *PPDMPCIBUSREGR0;
986/** Current PDMPCIBUSREGR0 version number. */
987#define PDM_PCIBUSREGR0_VERSION PDM_VERSION_MAKE(0xff87, 1, 0)
988
989/**
990 * PCI Bus registration structure for raw-mode.
991 */
992typedef struct PDMPCIBUSREGRC
993{
994 /** Structure version number. PDM_PCIBUSREGRC_VERSION defines the current version. */
995 uint32_t u32Version;
996 /** The PCI bus number (from ring-3 registration). */
997 uint32_t iBus;
998 /**
999 * Set the IRQ for a PCI device.
1000 *
1001 * @param pDevIns Device instance of the PCI Bus.
1002 * @param pPciDev The PCI device structure.
1003 * @param iIrq IRQ number to set.
1004 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1005 * @param uTagSrc The IRQ tag and source (for tracing).
1006 * @remarks Caller enters the PDM critical section.
1007 */
1008 DECLRCCALLBACKMEMBER(void, pfnSetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
1009 /** Marks the end of the structure with PDM_PCIBUSREGRC_VERSION. */
1010 uint32_t u32EndVersion;
1011} PDMPCIBUSREGRC;
1012/** Pointer to a PCI bus raw-mode registration structure. */
1013typedef PDMPCIBUSREGRC *PPDMPCIBUSREGRC;
1014/** Current PDMPCIBUSREGRC version number. */
1015#define PDM_PCIBUSREGRC_VERSION PDM_VERSION_MAKE(0xff88, 1, 0)
1016
1017/** PCI bus registration structure for the current context. */
1018typedef CTX_SUFF(PDMPCIBUSREG) PDMPCIBUSREGCC;
1019/** Pointer to a PCI bus registration structure for the current context. */
1020typedef CTX_SUFF(PPDMPCIBUSREG) PPDMPCIBUSREGCC;
1021/** PCI bus registration structure version for the current context. */
1022#define PDM_PCIBUSREGCC_VERSION CTX_MID(PDM_PCIBUSREG,_VERSION)
1023
1024
1025/**
1026 * PCI Bus RC helpers.
1027 */
1028typedef struct PDMPCIHLPRC
1029{
1030 /** Structure version. PDM_PCIHLPRC_VERSION defines the current version. */
1031 uint32_t u32Version;
1032
1033 /**
1034 * Set an ISA IRQ.
1035 *
1036 * @param pDevIns PCI device instance.
1037 * @param iIrq IRQ number to set.
1038 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1039 * @param uTagSrc The IRQ tag and source (for tracing).
1040 * @thread EMT only.
1041 */
1042 DECLRCCALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1043
1044 /**
1045 * Set an I/O-APIC IRQ.
1046 *
1047 * @param pDevIns PCI device instance.
1048 * @param uBusDevFn The bus:device:function of the device initiating the
1049 * IRQ. Pass NIL_PCIBDF when it's not a PCI device or
1050 * interrupt.
1051 * @param iIrq IRQ number to set.
1052 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1053 * @param uTagSrc The IRQ tag and source (for tracing).
1054 * @thread EMT only.
1055 */
1056 DECLRCCALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, int iIrq, int iLevel, uint32_t uTagSrc));
1057
1058 /**
1059 * Send an MSI.
1060 *
1061 * @param pDevIns PCI device instance.
1062 * @param uBusDevFn The bus:device:function of the device initiating the
1063 * MSI. Cannot be NIL_PCIBDF.
1064 * @param pMsi The MSI to send.
1065 * @param uTagSrc The IRQ tag and source (for tracing).
1066 * @thread EMT only.
1067 */
1068 DECLRCCALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc));
1069
1070
1071 /**
1072 * Acquires the PDM lock.
1073 *
1074 * @returns VINF_SUCCESS on success.
1075 * @returns rc if we failed to acquire the lock.
1076 * @param pDevIns The PCI device instance.
1077 * @param rc What to return if we fail to acquire the lock.
1078 *
1079 * @sa PDMCritSectEnter
1080 */
1081 DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1082
1083 /**
1084 * Releases the PDM lock.
1085 *
1086 * @param pDevIns The PCI device instance.
1087 */
1088 DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1089
1090 /**
1091 * Gets a bus by it's PDM ordinal (typically the parent bus).
1092 *
1093 * @returns Pointer to the device instance of the bus.
1094 * @param pDevIns The PCI bus device instance.
1095 * @param idxPdmBus The PDM ordinal value of the bus to get.
1096 */
1097 DECLRCCALLBACKMEMBER(PPDMDEVINS, pfnGetBusByNo,(PPDMDEVINS pDevIns, uint32_t idxPdmBus));
1098
1099 /** Just a safety precaution. */
1100 uint32_t u32TheEnd;
1101} PDMPCIHLPRC;
1102/** Pointer to PCI helpers. */
1103typedef RCPTRTYPE(PDMPCIHLPRC *) PPDMPCIHLPRC;
1104/** Pointer to const PCI helpers. */
1105typedef RCPTRTYPE(const PDMPCIHLPRC *) PCPDMPCIHLPRC;
1106
1107/** Current PDMPCIHLPRC version number. */
1108#define PDM_PCIHLPRC_VERSION PDM_VERSION_MAKE(0xfffd, 4, 0)
1109
1110
1111/**
1112 * PCI Bus R0 helpers.
1113 */
1114typedef struct PDMPCIHLPR0
1115{
1116 /** Structure version. PDM_PCIHLPR0_VERSION defines the current version. */
1117 uint32_t u32Version;
1118
1119 /**
1120 * Set an ISA IRQ.
1121 *
1122 * @param pDevIns PCI device instance.
1123 * @param iIrq IRQ number to set.
1124 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1125 * @param uTagSrc The IRQ tag and source (for tracing).
1126 * @thread EMT only.
1127 */
1128 DECLR0CALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1129
1130 /**
1131 * Set an I/O-APIC IRQ.
1132 *
1133 * @param pDevIns PCI device instance.
1134 * @param uBusDevFn The bus:device:function of the device initiating the
1135 * IRQ. Pass NIL_PCIBDF when it's not a PCI device or
1136 * interrupt.
1137 * @param iIrq IRQ number to set.
1138 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1139 * @param uTagSrc The IRQ tag and source (for tracing).
1140 * @thread EMT only.
1141 */
1142 DECLR0CALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, int iIrq, int iLevel, uint32_t uTagSrc));
1143
1144 /**
1145 * Send an MSI.
1146 *
1147 * @param pDevIns PCI device instance.
1148 * @param uBusDevFn The bus:device:function of the device initiating the
1149 * MSI. Cannot be NIL_PCIBDF.
1150 * @param pMsi The MSI to send.
1151 * @param uTagSrc The IRQ tag and source (for tracing).
1152 * @thread EMT only.
1153 */
1154 DECLR0CALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc));
1155
1156 /**
1157 * Acquires the PDM lock.
1158 *
1159 * @returns VINF_SUCCESS on success.
1160 * @returns rc if we failed to acquire the lock.
1161 * @param pDevIns The PCI device instance.
1162 * @param rc What to return if we fail to acquire the lock.
1163 *
1164 * @sa PDMCritSectEnter
1165 */
1166 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1167
1168 /**
1169 * Releases the PDM lock.
1170 *
1171 * @param pDevIns The PCI device instance.
1172 */
1173 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1174
1175 /**
1176 * Gets a bus by it's PDM ordinal (typically the parent bus).
1177 *
1178 * @returns Pointer to the device instance of the bus.
1179 * @param pDevIns The PCI bus device instance.
1180 * @param idxPdmBus The PDM ordinal value of the bus to get.
1181 */
1182 DECLR0CALLBACKMEMBER(PPDMDEVINS, pfnGetBusByNo,(PPDMDEVINS pDevIns, uint32_t idxPdmBus));
1183
1184 /** Just a safety precaution. */
1185 uint32_t u32TheEnd;
1186} PDMPCIHLPR0;
1187/** Pointer to PCI helpers. */
1188typedef R0PTRTYPE(PDMPCIHLPR0 *) PPDMPCIHLPR0;
1189/** Pointer to const PCI helpers. */
1190typedef R0PTRTYPE(const PDMPCIHLPR0 *) PCPDMPCIHLPR0;
1191
1192/** Current PDMPCIHLPR0 version number. */
1193#define PDM_PCIHLPR0_VERSION PDM_VERSION_MAKE(0xfffc, 6, 0)
1194
1195/**
1196 * PCI device helpers.
1197 */
1198typedef struct PDMPCIHLPR3
1199{
1200 /** Structure version. PDM_PCIHLPR3_VERSION defines the current version. */
1201 uint32_t u32Version;
1202
1203 /**
1204 * Set an ISA IRQ.
1205 *
1206 * @param pDevIns The PCI device instance.
1207 * @param iIrq IRQ number to set.
1208 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1209 * @param uTagSrc The IRQ tag and source (for tracing).
1210 */
1211 DECLR3CALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1212
1213 /**
1214 * Set an I/O-APIC IRQ.
1215 *
1216 * @param pDevIns The PCI device instance.
1217 * @param uBusDevFn The bus:device:function of the device initiating the
1218 * IRQ. Pass NIL_PCIBDF when it's not a PCI device or
1219 * interrupt.
1220 * @param iIrq IRQ number to set.
1221 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1222 * @param uTagSrc The IRQ tag and source (for tracing).
1223 */
1224 DECLR3CALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, int iIrq, int iLevel, uint32_t uTagSrc));
1225
1226 /**
1227 * Send an MSI.
1228 *
1229 * @param pDevIns PCI device instance.
1230 * @param uBusDevFn The bus:device:function of the device initiating the
1231 * MSI. Cannot be NIL_PCIBDF.
1232 * @param pMsi The MSI to send.
1233 * @param uTagSrc The IRQ tag and source (for tracing).
1234 */
1235 DECLR3CALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc));
1236
1237 /**
1238 * Acquires the PDM lock.
1239 *
1240 * @returns VINF_SUCCESS on success.
1241 * @returns Fatal error on failure.
1242 * @param pDevIns The PCI device instance.
1243 * @param rc Dummy for making the interface identical to the RC and R0 versions.
1244 *
1245 * @sa PDMCritSectEnter
1246 */
1247 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1248
1249 /**
1250 * Releases the PDM lock.
1251 *
1252 * @param pDevIns The PCI device instance.
1253 */
1254 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1255
1256 /**
1257 * Gets a bus by it's PDM ordinal (typically the parent bus).
1258 *
1259 * @returns Pointer to the device instance of the bus.
1260 * @param pDevIns The PCI bus device instance.
1261 * @param idxPdmBus The PDM ordinal value of the bus to get.
1262 */
1263 DECLR3CALLBACKMEMBER(PPDMDEVINS, pfnGetBusByNo,(PPDMDEVINS pDevIns, uint32_t idxPdmBus));
1264
1265 /** Just a safety precaution. */
1266 uint32_t u32TheEnd;
1267} PDMPCIHLPR3;
1268/** Pointer to PCI helpers. */
1269typedef R3PTRTYPE(PDMPCIHLPR3 *) PPDMPCIHLPR3;
1270/** Pointer to const PCI helpers. */
1271typedef R3PTRTYPE(const PDMPCIHLPR3 *) PCPDMPCIHLPR3;
1272
1273/** Current PDMPCIHLPR3 version number. */
1274#define PDM_PCIHLPR3_VERSION PDM_VERSION_MAKE(0xfffb, 5, 0)
1275
1276
1277/** @name PDMIOMMU_MEM_F_XXX - IOMMU memory access transaction flags.
1278 * These flags are used for memory access transactions via the IOMMU interface.
1279 * @{ */
1280/** Memory read. */
1281#define PDMIOMMU_MEM_F_READ RT_BIT_32(0)
1282/** Memory write. */
1283#define PDMIOMMU_MEM_F_WRITE RT_BIT_32(1)
1284/** Valid flag mask. */
1285#define PDMIOMMU_MEM_F_VALID_MASK (PDMIOMMU_MEM_F_READ | PDMIOMMU_MEM_F_WRITE)
1286/** @} */
1287
1288/**
1289 * IOMMU registration structure for ring-0.
1290 */
1291typedef struct PDMIOMMUREGR0
1292{
1293 /** Structure version number. PDM_IOMMUREG_VERSION defines the current
1294 * version. */
1295 uint32_t u32Version;
1296 /** Index into the PDM IOMMU array (PDM::aIommus) from ring-3. */
1297 uint32_t idxIommu;
1298
1299 /**
1300 * Translates the physical address for a memory transaction through the IOMMU.
1301 *
1302 * @returns VBox status code.
1303 * @param pDevIns The IOMMU device instance.
1304 * @param idDevice The device identifier (bus, device, function).
1305 * @param uIova The I/O virtual address being accessed.
1306 * @param cbIova The size of the access.
1307 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX.
1308 * @param pGCPhysSpa Where to store the translated system physical address.
1309 * @param pcbContiguous Where to store the number of contiguous bytes translated
1310 * and permission-checked.
1311 *
1312 * @thread Any.
1313 */
1314 DECLR0CALLBACKMEMBER(int, pfnMemAccess,(PPDMDEVINS pDevIns, uint16_t idDevice, uint64_t uIova, size_t cbIova,
1315 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContiguous));
1316
1317 /**
1318 * Translates in bulk physical page addresses for memory transactions through the
1319 * IOMMU.
1320 *
1321 * @returns VBox status code.
1322 * @param pDevIns The IOMMU device instance.
1323 * @param idDevice The device identifier (bus, device, function).
1324 * @param cIovas The number of I/O virtual addresses being accessed.
1325 * @param pauIovas The I/O virtual addresses being accessed.
1326 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX.
1327 * @param paGCPhysSpa Where to store the translated system physical page
1328 * addresses.
1329 *
1330 * @thread Any.
1331 */
1332 DECLR0CALLBACKMEMBER(int, pfnMemBulkAccess,(PPDMDEVINS pDevIns, uint16_t idDevice, size_t cIovas, uint64_t const *pauIovas,
1333 uint32_t fFlags, PRTGCPHYS paGCPhysSpa));
1334
1335 /**
1336 * Performs an interrupt remap request through the IOMMU.
1337 *
1338 * @returns VBox status code.
1339 * @param pDevIns The IOMMU device instance.
1340 * @param idDevice The device identifier (bus, device, function).
1341 * @param pMsiIn The source MSI.
1342 * @param pMsiOut Where to store the remapped MSI.
1343 *
1344 * @thread Any.
1345 */
1346 DECLR0CALLBACKMEMBER(int, pfnMsiRemap,(PPDMDEVINS pDevIns, uint16_t idDevice, PCMSIMSG pMsiIn, PMSIMSG pMsiOut));
1347
1348 /** Just a safety precaution. */
1349 uint32_t u32TheEnd;
1350} PDMIOMMUREGR0;
1351/** Pointer to a IOMMU registration structure. */
1352typedef PDMIOMMUREGR0 *PPDMIOMMUREGR0;
1353
1354/** Current PDMIOMMUREG version number. */
1355#define PDM_IOMMUREGR0_VERSION PDM_VERSION_MAKE(0xff10, 3, 0)
1356
1357
1358/**
1359 * IOMMU registration structure for raw-mode.
1360 */
1361typedef struct PDMIOMMUREGRC
1362{
1363 /** Structure version number. PDM_IOMMUREG_VERSION defines the current
1364 * version. */
1365 uint32_t u32Version;
1366 /** Index into the PDM IOMMU array (PDM::aIommus) from ring-3. */
1367 uint32_t idxIommu;
1368
1369 /**
1370 * Translates the physical address for a memory transaction through the IOMMU.
1371 *
1372 * @returns VBox status code.
1373 * @param pDevIns The IOMMU device instance.
1374 * @param idDevice The device identifier (bus, device, function).
1375 * @param uIova The I/O virtual address being accessed.
1376 * @param cbIova The size of the access.
1377 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX.
1378 * @param pGCPhysSpa Where to store the translated system physical address.
1379 * @param pcbContiguous Where to store the number of contiguous bytes translated
1380 * and permission-checked.
1381 *
1382 * @thread Any.
1383 */
1384 DECLRCCALLBACKMEMBER(int, pfnMemAccess,(PPDMDEVINS pDevIns, uint16_t idDevice, uint64_t uIova, size_t cbIova,
1385 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContiguous));
1386
1387 /**
1388 * Translates in bulk physical page addresses for memory transactions through the
1389 * IOMMU.
1390 *
1391 * @returns VBox status code.
1392 * @param pDevIns The IOMMU device instance.
1393 * @param idDevice The device identifier (bus, device, function).
1394 * @param cIovas The number of I/O virtual addresses being accessed.
1395 * @param pauIovas The I/O virtual addresses being accessed.
1396 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX.
1397 * @param paGCPhysSpa Where to store the translated system physical page
1398 * addresses.
1399 *
1400 * @thread Any.
1401 */
1402 DECLRCCALLBACKMEMBER(int, pfnMemBulkAccess,(PPDMDEVINS pDevIns, uint16_t idDevice, size_t cIovas, uint64_t const *pauIovas,
1403 uint32_t fFlags, PRTGCPHYS paGCPhysSpa));
1404
1405 /**
1406 * Performs an interrupt remap request through the IOMMU.
1407 *
1408 * @returns VBox status code.
1409 * @param pDevIns The IOMMU device instance.
1410 * @param idDevice The device identifier (bus, device, function).
1411 * @param pMsiIn The source MSI.
1412 * @param pMsiOut Where to store the remapped MSI.
1413 *
1414 * @thread Any.
1415 */
1416 DECLRCCALLBACKMEMBER(int, pfnMsiRemap,(PPDMDEVINS pDevIns, uint16_t idDevice, PCMSIMSG pMsiIn, PMSIMSG pMsiOut));
1417
1418 /** Just a safety precaution. */
1419 uint32_t u32TheEnd;
1420} PDMIOMMUREGRC;
1421/** Pointer to a IOMMU registration structure. */
1422typedef PDMIOMMUREGRC *PPDMIOMMUREGRC;
1423
1424/** Current PDMIOMMUREG version number. */
1425#define PDM_IOMMUREGRC_VERSION PDM_VERSION_MAKE(0xff11, 3, 0)
1426
1427
1428/**
1429 * IOMMU registration structure for ring-3.
1430 */
1431typedef struct PDMIOMMUREGR3
1432{
1433 /** Structure version number. PDM_IOMMUREG_VERSION defines the current
1434 * version. */
1435 uint32_t u32Version;
1436 /** Padding. */
1437 uint32_t uPadding0;
1438
1439 /**
1440 * Translates the physical address for a memory transaction through the IOMMU.
1441 *
1442 * @returns VBox status code.
1443 * @param pDevIns The IOMMU device instance.
1444 * @param idDevice The device identifier (bus, device, function).
1445 * @param uIova The I/O virtual address being accessed.
1446 * @param cbIova The size of the access.
1447 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX.
1448 * @param pGCPhysSpa Where to store the translated system physical address.
1449 * @param pcbContiguous Where to store the number of contiguous bytes translated
1450 * and permission-checked.
1451 *
1452 * @thread Any.
1453 */
1454 DECLR3CALLBACKMEMBER(int, pfnMemAccess,(PPDMDEVINS pDevIns, uint16_t idDevice, uint64_t uIova, size_t cbIova,
1455 uint32_t fFlags, PRTGCPHYS pGCPhysSpa, size_t *pcbContiguous));
1456
1457 /**
1458 * Translates in bulk physical page addresses for memory transactions through the
1459 * IOMMU.
1460 *
1461 * @returns VBox status code.
1462 * @param pDevIns The IOMMU device instance.
1463 * @param idDevice The device identifier (bus, device, function).
1464 * @param cIovas The number of I/O virtual addresses being accessed.
1465 * @param pauIovas The I/O virtual addresses being accessed.
1466 * @param fFlags Access flags, see PDMIOMMU_MEM_F_XXX.
1467 * @param paGCPhysSpa Where to store the translated system physical page
1468 * addresses.
1469 *
1470 * @thread Any.
1471 */
1472 DECLR3CALLBACKMEMBER(int, pfnMemBulkAccess,(PPDMDEVINS pDevIns, uint16_t idDevice, size_t cIovas, uint64_t const *pauIovas,
1473 uint32_t fFlags, PRTGCPHYS paGCPhysSpa));
1474
1475 /**
1476 * Performs an interrupt remap request through the IOMMU.
1477 *
1478 * @returns VBox status code.
1479 * @param pDevIns The IOMMU device instance.
1480 * @param idDevice The device identifier (bus, device, function).
1481 * @param pMsiIn The source MSI.
1482 * @param pMsiOut Where to store the remapped MSI.
1483 *
1484 * @thread Any.
1485 */
1486 DECLR3CALLBACKMEMBER(int, pfnMsiRemap,(PPDMDEVINS pDevIns, uint16_t idDevice, PCMSIMSG pMsiIn, PMSIMSG pMsiOut));
1487
1488 /** Just a safety precaution. */
1489 uint32_t u32TheEnd;
1490} PDMIOMMUREGR3;
1491/** Pointer to a IOMMU registration structure. */
1492typedef PDMIOMMUREGR3 *PPDMIOMMUREGR3;
1493
1494/** Current PDMIOMMUREG version number. */
1495#define PDM_IOMMUREGR3_VERSION PDM_VERSION_MAKE(0xff12, 3, 0)
1496
1497/** IOMMU registration structure for the current context. */
1498typedef CTX_SUFF(PDMIOMMUREG) PDMIOMMUREGCC;
1499/** Pointer to an IOMMU registration structure for the current context. */
1500typedef CTX_SUFF(PPDMIOMMUREG) PPDMIOMMUREGCC;
1501/** IOMMU registration structure version for the current context. */
1502#define PDM_IOMMUREGCC_VERSION CTX_MID(PDM_IOMMUREG,_VERSION)
1503
1504
1505/**
1506 * IOMMU helpers for ring-0.
1507 */
1508typedef struct PDMIOMMUHLPR0
1509{
1510 /** Structure version. PDM_IOMMUHLP_VERSION defines the current version. */
1511 uint32_t u32Version;
1512
1513 /**
1514 * Acquires the PDM lock.
1515 *
1516 * @returns VINF_SUCCESS on success.
1517 * @returns rc if we failed to acquire the lock.
1518 * @param pDevIns The PCI device instance.
1519 * @param rc What to return if we fail to acquire the lock.
1520 *
1521 * @sa PDMCritSectEnter
1522 */
1523 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1524
1525 /**
1526 * Releases the PDM lock.
1527 *
1528 * @param pDevIns The PCI device instance.
1529 */
1530 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1531
1532 /**
1533 * Check whether the calling thread owns the PDM lock.
1534 *
1535 * @returns @c true if the PDM lock is owned, @c false otherwise.
1536 * @param pDevIns The PCI device instance.
1537 */
1538 DECLR0CALLBACKMEMBER(bool, pfnLockIsOwner,(PPDMDEVINS pDevIns));
1539
1540 /**
1541 * Send an MSI (when generated by the IOMMU device itself).
1542 *
1543 * @param pDevIns PCI device instance.
1544 * @param pMsi The MSI to send.
1545 * @param uTagSrc The IRQ tag and source (for tracing).
1546 */
1547 DECLR0CALLBACKMEMBER(void, pfnSendMsi,(PPDMDEVINS pDevIns, PCMSIMSG pMsi, uint32_t uTagSrc));
1548
1549 /** Just a safety precaution. */
1550 uint32_t u32TheEnd;
1551} PDMIOMMUHLPR0;
1552/** Pointer to IOMMU helpers for ring-0. */
1553typedef PDMIOMMUHLPR0 *PPDMIOMMUHLPR0;
1554/** Pointer to const IOMMU helpers for ring-0. */
1555typedef const PDMIOMMUHLPR0 *PCPDMIOMMUHLPR0;
1556
1557/** Current PDMIOMMUHLPR0 version number. */
1558#define PDM_IOMMUHLPR0_VERSION PDM_VERSION_MAKE(0xff13, 5, 0)
1559
1560
1561/**
1562 * IOMMU helpers for raw-mode.
1563 */
1564typedef struct PDMIOMMUHLPRC
1565{
1566 /** Structure version. PDM_IOMMUHLP_VERSION defines the current version. */
1567 uint32_t u32Version;
1568
1569 /**
1570 * Acquires the PDM lock.
1571 *
1572 * @returns VINF_SUCCESS on success.
1573 * @returns rc if we failed to acquire the lock.
1574 * @param pDevIns The PCI device instance.
1575 * @param rc What to return if we fail to acquire the lock.
1576 *
1577 * @sa PDMCritSectEnter
1578 */
1579 DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1580
1581 /**
1582 * Releases the PDM lock.
1583 *
1584 * @param pDevIns The PCI device instance.
1585 */
1586 DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1587
1588 /**
1589 * Check whether the threads owns the PDM lock.
1590 *
1591 * @returns @c true if the PDM lock is owned, @c false otherwise.
1592 * @param pDevIns The PCI device instance.
1593 */
1594 DECLRCCALLBACKMEMBER(bool, pfnLockIsOwner,(PPDMDEVINS pDevIns));
1595
1596 /**
1597 * Send an MSI (when generated by the IOMMU device itself).
1598 *
1599 * @param pDevIns PCI device instance.
1600 * @param pMsi The MSI to send.
1601 * @param uTagSrc The IRQ tag and source (for tracing).
1602 */
1603 DECLRCCALLBACKMEMBER(void, pfnSendMsi,(PPDMDEVINS pDevIns, PCMSIMSG pMsi, uint32_t uTagSrc));
1604
1605 /** Just a safety precaution. */
1606 uint32_t u32TheEnd;
1607} PDMIOMMUHLPRC;
1608/** Pointer to IOMMU helpers for raw-mode. */
1609typedef PDMIOMMUHLPRC *PPDMIOMMUHLPRC;
1610/** Pointer to const IOMMU helpers for raw-mode. */
1611typedef const PDMIOMMUHLPRC *PCPDMIOMMUHLPRC;
1612
1613/** Current PDMIOMMUHLPRC version number. */
1614#define PDM_IOMMUHLPRC_VERSION PDM_VERSION_MAKE(0xff14, 5, 0)
1615
1616
1617/**
1618 * IOMMU helpers for ring-3.
1619 */
1620typedef struct PDMIOMMUHLPR3
1621{
1622 /** Structure version. PDM_IOMMUHLP_VERSION defines the current version. */
1623 uint32_t u32Version;
1624
1625 /**
1626 * Acquires the PDM lock.
1627 *
1628 * @returns VINF_SUCCESS on success.
1629 * @returns rc if we failed to acquire the lock.
1630 * @param pDevIns The PCI device instance.
1631 * @param rc What to return if we fail to acquire the lock.
1632 *
1633 * @sa PDMCritSectEnter
1634 */
1635 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1636
1637 /**
1638 * Releases the PDM lock.
1639 *
1640 * @param pDevIns The PCI device instance.
1641 */
1642 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1643
1644 /**
1645 * Check whether the threads owns the PDM lock.
1646 *
1647 * @returns @c true if the PDM lock is owned, @c false otherwise.
1648 * @param pDevIns The PCI device instance.
1649 */
1650 DECLR3CALLBACKMEMBER(bool, pfnLockIsOwner,(PPDMDEVINS pDevIns));
1651
1652 /**
1653 * Send an MSI (when generated by the IOMMU device itself).
1654 *
1655 * @param pDevIns PCI device instance.
1656 * @param pMsi The MSI to send.
1657 * @param uTagSrc The IRQ tag and source (for tracing).
1658 */
1659 DECLR3CALLBACKMEMBER(void, pfnSendMsi,(PPDMDEVINS pDevIns, PCMSIMSG pMsi, uint32_t uTagSrc));
1660
1661 /** Just a safety precaution. */
1662 uint32_t u32TheEnd;
1663} PDMIOMMUHLPR3;
1664/** Pointer to IOMMU helpers for raw-mode. */
1665typedef PDMIOMMUHLPR3 *PPDMIOMMUHLPR3;
1666/** Pointer to const IOMMU helpers for raw-mode. */
1667typedef const PDMIOMMUHLPR3 *PCPDMIOMMUHLPR3;
1668
1669/** Current PDMIOMMUHLPR3 version number. */
1670#define PDM_IOMMUHLPR3_VERSION PDM_VERSION_MAKE(0xff15, 5, 0)
1671
1672
1673/**
1674 * Programmable Interrupt Controller registration structure (all contexts).
1675 */
1676typedef struct PDMPICREG
1677{
1678 /** Structure version number. PDM_PICREG_VERSION defines the current version. */
1679 uint32_t u32Version;
1680
1681 /**
1682 * Set the an IRQ.
1683 *
1684 * @param pDevIns Device instance of the PIC.
1685 * @param iIrq IRQ number to set.
1686 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1687 * @param uTagSrc The IRQ tag and source (for tracing).
1688 * @remarks Caller enters the PDM critical section.
1689 */
1690 DECLCALLBACKMEMBER(void, pfnSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1691
1692 /**
1693 * Get a pending interrupt.
1694 *
1695 * @returns Pending interrupt number.
1696 * @param pDevIns Device instance of the PIC.
1697 * @param puTagSrc Where to return the IRQ tag and source.
1698 * @remarks Caller enters the PDM critical section.
1699 */
1700 DECLCALLBACKMEMBER(int, pfnGetInterrupt,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
1701
1702 /** Just a safety precaution. */
1703 uint32_t u32TheEnd;
1704} PDMPICREG;
1705/** Pointer to a PIC registration structure. */
1706typedef PDMPICREG *PPDMPICREG;
1707
1708/** Current PDMPICREG version number. */
1709#define PDM_PICREG_VERSION PDM_VERSION_MAKE(0xfffa, 3, 0)
1710
1711/**
1712 * PIC helpers, same in all contexts.
1713 */
1714typedef struct PDMPICHLP
1715{
1716 /** Structure version. PDM_PICHLP_VERSION defines the current version. */
1717 uint32_t u32Version;
1718
1719 /**
1720 * Set the interrupt force action flag.
1721 *
1722 * @param pDevIns Device instance of the PIC.
1723 */
1724 DECLCALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
1725
1726 /**
1727 * Clear the interrupt force action flag.
1728 *
1729 * @param pDevIns Device instance of the PIC.
1730 */
1731 DECLCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
1732
1733 /**
1734 * Acquires the PDM lock.
1735 *
1736 * @returns VINF_SUCCESS on success.
1737 * @returns rc if we failed to acquire the lock.
1738 * @param pDevIns The PIC device instance.
1739 * @param rc What to return if we fail to acquire the lock.
1740 *
1741 * @sa PDMCritSectEnter
1742 */
1743 DECLCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1744
1745 /**
1746 * Releases the PDM lock.
1747 *
1748 * @param pDevIns The PIC device instance.
1749 */
1750 DECLCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1751
1752 /** Just a safety precaution. */
1753 uint32_t u32TheEnd;
1754} PDMPICHLP;
1755/** Pointer to PIC helpers. */
1756typedef PDMPICHLP *PPDMPICHLP;
1757/** Pointer to const PIC helpers. */
1758typedef const PDMPICHLP *PCPDMPICHLP;
1759
1760/** Current PDMPICHLP version number. */
1761#define PDM_PICHLP_VERSION PDM_VERSION_MAKE(0xfff9, 3, 0)
1762
1763
1764/**
1765 * Firmware registration structure.
1766 */
1767typedef struct PDMFWREG
1768{
1769 /** Struct version+magic number (PDM_FWREG_VERSION). */
1770 uint32_t u32Version;
1771
1772 /**
1773 * Checks whether this is a hard or soft reset.
1774 *
1775 * The current definition of soft reset is what the PC BIOS does when CMOS[0xF]
1776 * is 5, 9 or 0xA.
1777 *
1778 * @returns true if hard reset, false if soft.
1779 * @param pDevIns Device instance of the firmware.
1780 * @param fFlags PDMRESET_F_XXX passed to the PDMDevHlpVMReset API.
1781 */
1782 DECLR3CALLBACKMEMBER(bool, pfnIsHardReset,(PPDMDEVINS pDevIns, uint32_t fFlags));
1783
1784 /** Just a safety precaution. */
1785 uint32_t u32TheEnd;
1786} PDMFWREG;
1787/** Pointer to a FW registration structure. */
1788typedef PDMFWREG *PPDMFWREG;
1789/** Pointer to a const FW registration structure. */
1790typedef PDMFWREG const *PCPDMFWREG;
1791
1792/** Current PDMFWREG version number. */
1793#define PDM_FWREG_VERSION PDM_VERSION_MAKE(0xffdd, 1, 0)
1794
1795/**
1796 * Firmware R3 helpers.
1797 */
1798typedef struct PDMFWHLPR3
1799{
1800 /** Structure version. PDM_FWHLP_VERSION defines the current version. */
1801 uint32_t u32Version;
1802
1803 /** Just a safety precaution. */
1804 uint32_t u32TheEnd;
1805} PDMFWHLPR3;
1806
1807/** Pointer to FW R3 helpers. */
1808typedef R3PTRTYPE(PDMFWHLPR3 *) PPDMFWHLPR3;
1809/** Pointer to const FW R3 helpers. */
1810typedef R3PTRTYPE(const PDMFWHLPR3 *) PCPDMFWHLPR3;
1811
1812/** Current PDMFWHLPR3 version number. */
1813#define PDM_FWHLPR3_VERSION PDM_VERSION_MAKE(0xffdb, 1, 0)
1814
1815
1816/**
1817 * APIC mode argument for apicR3SetCpuIdFeatureLevel.
1818 *
1819 * Also used in saved-states, CFGM don't change existing values.
1820 */
1821typedef enum PDMAPICMODE
1822{
1823 /** Invalid 0 entry. */
1824 PDMAPICMODE_INVALID = 0,
1825 /** No APIC. */
1826 PDMAPICMODE_NONE,
1827 /** Standard APIC (X86_CPUID_FEATURE_EDX_APIC). */
1828 PDMAPICMODE_APIC,
1829 /** Intel X2APIC (X86_CPUID_FEATURE_ECX_X2APIC). */
1830 PDMAPICMODE_X2APIC,
1831 /** The usual 32-bit paranoia. */
1832 PDMAPICMODE_32BIT_HACK = 0x7fffffff
1833} PDMAPICMODE;
1834
1835/**
1836 * APIC irq argument for pfnSetInterruptFF and pfnClearInterruptFF.
1837 */
1838typedef enum PDMAPICIRQ
1839{
1840 /** Invalid 0 entry. */
1841 PDMAPICIRQ_INVALID = 0,
1842 /** Normal hardware interrupt. */
1843 PDMAPICIRQ_HARDWARE,
1844 /** NMI. */
1845 PDMAPICIRQ_NMI,
1846 /** SMI. */
1847 PDMAPICIRQ_SMI,
1848 /** ExtINT (HW interrupt via PIC). */
1849 PDMAPICIRQ_EXTINT,
1850 /** Interrupt arrived, needs to be updated to the IRR. */
1851 PDMAPICIRQ_UPDATE_PENDING,
1852 /** The usual 32-bit paranoia. */
1853 PDMAPICIRQ_32BIT_HACK = 0x7fffffff
1854} PDMAPICIRQ;
1855
1856
1857/**
1858 * I/O APIC registration structure (all contexts).
1859 */
1860typedef struct PDMIOAPICREG
1861{
1862 /** Struct version+magic number (PDM_IOAPICREG_VERSION). */
1863 uint32_t u32Version;
1864
1865 /**
1866 * Set an IRQ.
1867 *
1868 * @param pDevIns Device instance of the I/O APIC.
1869 * @param uBusDevFn The bus:device:function of the device initiating the
1870 * IRQ. Can be NIL_PCIBDF.
1871 * @param iIrq IRQ number to set.
1872 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1873 * @param uTagSrc The IRQ tag and source (for tracing).
1874 *
1875 * @remarks Caller enters the PDM critical section
1876 * Actually, as per 2018-07-21 this isn't true (bird).
1877 */
1878 DECLCALLBACKMEMBER(void, pfnSetIrq,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, int iIrq, int iLevel, uint32_t uTagSrc));
1879
1880 /**
1881 * Send a MSI.
1882 *
1883 * @param pDevIns Device instance of the I/O APIC.
1884 * @param uBusDevFn The bus:device:function of the device initiating the
1885 * MSI. Cannot be NIL_PCIBDF.
1886 * @param pMsi The MSI to send.
1887 * @param uTagSrc The IRQ tag and source (for tracing).
1888 *
1889 * @remarks Caller enters the PDM critical section
1890 * Actually, as per 2018-07-21 this isn't true (bird).
1891 */
1892 DECLCALLBACKMEMBER(void, pfnSendMsi,(PPDMDEVINS pDevIns, PCIBDF uBusDevFn, PCMSIMSG pMsi, uint32_t uTagSrc));
1893
1894 /**
1895 * Set the EOI for an interrupt vector.
1896 *
1897 * @param pDevIns Device instance of the I/O APIC.
1898 * @param u8Vector The vector.
1899 *
1900 * @remarks Caller enters the PDM critical section
1901 * Actually, as per 2018-07-21 this isn't true (bird).
1902 */
1903 DECLCALLBACKMEMBER(void, pfnSetEoi,(PPDMDEVINS pDevIns, uint8_t u8Vector));
1904
1905 /** Just a safety precaution. */
1906 uint32_t u32TheEnd;
1907} PDMIOAPICREG;
1908/** Pointer to an APIC registration structure. */
1909typedef PDMIOAPICREG *PPDMIOAPICREG;
1910
1911/** Current PDMAPICREG version number. */
1912#define PDM_IOAPICREG_VERSION PDM_VERSION_MAKE(0xfff2, 8, 0)
1913
1914
1915/**
1916 * IOAPIC helpers, same in all contexts.
1917 */
1918typedef struct PDMIOAPICHLP
1919{
1920 /** Structure version. PDM_IOAPICHLP_VERSION defines the current version. */
1921 uint32_t u32Version;
1922
1923 /**
1924 * Private interface between the IOAPIC and APIC.
1925 *
1926 * @returns status code.
1927 * @param pDevIns Device instance of the IOAPIC.
1928 * @param u8Dest See APIC implementation.
1929 * @param u8DestMode See APIC implementation.
1930 * @param u8DeliveryMode See APIC implementation.
1931 * @param uVector See APIC implementation.
1932 * @param u8Polarity See APIC implementation.
1933 * @param u8TriggerMode See APIC implementation.
1934 * @param uTagSrc The IRQ tag and source (for tracing).
1935 *
1936 * @sa APICBusDeliver()
1937 */
1938 DECLCALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1939 uint8_t uVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
1940
1941 /**
1942 * Acquires the PDM lock.
1943 *
1944 * @returns VINF_SUCCESS on success.
1945 * @returns rc if we failed to acquire the lock.
1946 * @param pDevIns The IOAPIC device instance.
1947 * @param rc What to return if we fail to acquire the lock.
1948 *
1949 * @sa PDMCritSectEnter
1950 */
1951 DECLCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1952
1953 /**
1954 * Releases the PDM lock.
1955 *
1956 * @param pDevIns The IOAPIC device instance.
1957 */
1958 DECLCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1959
1960 /**
1961 * Checks if the calling thread owns the PDM lock.
1962 *
1963 * @param pDevIns The IOAPIC device instance.
1964 */
1965 DECLCALLBACKMEMBER(bool, pfnLockIsOwner,(PPDMDEVINS pDevIns));
1966
1967 /**
1968 * Private interface between the IOAPIC and IOMMU.
1969 *
1970 * @returns status code.
1971 * @param pDevIns Device instance of the IOAPIC.
1972 * @param idDevice The device identifier (bus, device, function).
1973 * @param pMsiIn The source MSI.
1974 * @param pMsiOut Where to store the remapped MSI (only updated when
1975 * VINF_SUCCESS is returned).
1976 */
1977 DECLCALLBACKMEMBER(int, pfnIommuMsiRemap,(PPDMDEVINS pDevIns, uint16_t idDevice, PCMSIMSG pMsiIn, PMSIMSG pMsiOut));
1978
1979 /** Just a safety precaution. */
1980 uint32_t u32TheEnd;
1981} PDMIOAPICHLP;
1982/** Pointer to IOAPIC helpers. */
1983typedef PDMIOAPICHLP * PPDMIOAPICHLP;
1984/** Pointer to const IOAPIC helpers. */
1985typedef const PDMIOAPICHLP * PCPDMIOAPICHLP;
1986
1987/** Current PDMIOAPICHLP version number. */
1988#define PDM_IOAPICHLP_VERSION PDM_VERSION_MAKE(0xfff0, 3, 1)
1989
1990
1991/**
1992 * HPET registration structure.
1993 */
1994typedef struct PDMHPETREG
1995{
1996 /** Struct version+magic number (PDM_HPETREG_VERSION). */
1997 uint32_t u32Version;
1998} PDMHPETREG;
1999/** Pointer to an HPET registration structure. */
2000typedef PDMHPETREG *PPDMHPETREG;
2001
2002/** Current PDMHPETREG version number. */
2003#define PDM_HPETREG_VERSION PDM_VERSION_MAKE(0xffe2, 1, 0)
2004
2005/**
2006 * HPET RC helpers.
2007 *
2008 * @remarks Keep this around in case HPET will need PDM interaction in again RC
2009 * at some later point.
2010 */
2011typedef struct PDMHPETHLPRC
2012{
2013 /** Structure version. PDM_HPETHLPRC_VERSION defines the current version. */
2014 uint32_t u32Version;
2015
2016 /** Just a safety precaution. */
2017 uint32_t u32TheEnd;
2018} PDMHPETHLPRC;
2019
2020/** Pointer to HPET RC helpers. */
2021typedef RCPTRTYPE(PDMHPETHLPRC *) PPDMHPETHLPRC;
2022/** Pointer to const HPET RC helpers. */
2023typedef RCPTRTYPE(const PDMHPETHLPRC *) PCPDMHPETHLPRC;
2024
2025/** Current PDMHPETHLPRC version number. */
2026#define PDM_HPETHLPRC_VERSION PDM_VERSION_MAKE(0xffee, 2, 0)
2027
2028
2029/**
2030 * HPET R0 helpers.
2031 *
2032 * @remarks Keep this around in case HPET will need PDM interaction in again R0
2033 * at some later point.
2034 */
2035typedef struct PDMHPETHLPR0
2036{
2037 /** Structure version. PDM_HPETHLPR0_VERSION defines the current version. */
2038 uint32_t u32Version;
2039
2040 /** Just a safety precaution. */
2041 uint32_t u32TheEnd;
2042} PDMHPETHLPR0;
2043
2044/** Pointer to HPET R0 helpers. */
2045typedef R0PTRTYPE(PDMHPETHLPR0 *) PPDMHPETHLPR0;
2046/** Pointer to const HPET R0 helpers. */
2047typedef R0PTRTYPE(const PDMHPETHLPR0 *) PCPDMHPETHLPR0;
2048
2049/** Current PDMHPETHLPR0 version number. */
2050#define PDM_HPETHLPR0_VERSION PDM_VERSION_MAKE(0xffed, 2, 0)
2051
2052/**
2053 * HPET R3 helpers.
2054 */
2055typedef struct PDMHPETHLPR3
2056{
2057 /** Structure version. PDM_HPETHLP_VERSION defines the current version. */
2058 uint32_t u32Version;
2059
2060 /**
2061 * Set legacy mode on PIT and RTC.
2062 *
2063 * @returns VINF_SUCCESS on success.
2064 * @returns rc if we failed to set legacy mode.
2065 * @param pDevIns Device instance of the HPET.
2066 * @param fActivated Whether legacy mode is activated or deactivated.
2067 */
2068 DECLR3CALLBACKMEMBER(int, pfnSetLegacyMode,(PPDMDEVINS pDevIns, bool fActivated));
2069
2070
2071 /**
2072 * Set IRQ, bypassing ISA bus override rules.
2073 *
2074 * @returns VINF_SUCCESS on success.
2075 * @returns rc if we failed to set legacy mode.
2076 * @param pDevIns Device instance of the HPET.
2077 * @param iIrq IRQ number to set.
2078 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2079 */
2080 DECLR3CALLBACKMEMBER(int, pfnSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2081
2082 /** Just a safety precaution. */
2083 uint32_t u32TheEnd;
2084} PDMHPETHLPR3;
2085
2086/** Pointer to HPET R3 helpers. */
2087typedef R3PTRTYPE(PDMHPETHLPR3 *) PPDMHPETHLPR3;
2088/** Pointer to const HPET R3 helpers. */
2089typedef R3PTRTYPE(const PDMHPETHLPR3 *) PCPDMHPETHLPR3;
2090
2091/** Current PDMHPETHLPR3 version number. */
2092#define PDM_HPETHLPR3_VERSION PDM_VERSION_MAKE(0xffec, 3, 0)
2093
2094
2095/**
2096 * Raw PCI device registration structure.
2097 */
2098typedef struct PDMPCIRAWREG
2099{
2100 /** Struct version+magic number (PDM_PCIRAWREG_VERSION). */
2101 uint32_t u32Version;
2102 /** Just a safety precaution. */
2103 uint32_t u32TheEnd;
2104} PDMPCIRAWREG;
2105/** Pointer to a raw PCI registration structure. */
2106typedef PDMPCIRAWREG *PPDMPCIRAWREG;
2107
2108/** Current PDMPCIRAWREG version number. */
2109#define PDM_PCIRAWREG_VERSION PDM_VERSION_MAKE(0xffe1, 1, 0)
2110
2111/**
2112 * Raw PCI device raw-mode context helpers.
2113 */
2114typedef struct PDMPCIRAWHLPRC
2115{
2116 /** Structure version and magic number (PDM_PCIRAWHLPRC_VERSION). */
2117 uint32_t u32Version;
2118 /** Just a safety precaution. */
2119 uint32_t u32TheEnd;
2120} PDMPCIRAWHLPRC;
2121/** Pointer to a raw PCI deviec raw-mode context helper structure. */
2122typedef RCPTRTYPE(PDMPCIRAWHLPRC *) PPDMPCIRAWHLPRC;
2123/** Pointer to a const raw PCI deviec raw-mode context helper structure. */
2124typedef RCPTRTYPE(const PDMPCIRAWHLPRC *) PCPDMPCIRAWHLPRC;
2125
2126/** Current PDMPCIRAWHLPRC version number. */
2127#define PDM_PCIRAWHLPRC_VERSION PDM_VERSION_MAKE(0xffe0, 1, 0)
2128
2129/**
2130 * Raw PCI device ring-0 context helpers.
2131 */
2132typedef struct PDMPCIRAWHLPR0
2133{
2134 /** Structure version and magic number (PDM_PCIRAWHLPR0_VERSION). */
2135 uint32_t u32Version;
2136 /** Just a safety precaution. */
2137 uint32_t u32TheEnd;
2138} PDMPCIRAWHLPR0;
2139/** Pointer to a raw PCI deviec ring-0 context helper structure. */
2140typedef R0PTRTYPE(PDMPCIRAWHLPR0 *) PPDMPCIRAWHLPR0;
2141/** Pointer to a const raw PCI deviec ring-0 context helper structure. */
2142typedef R0PTRTYPE(const PDMPCIRAWHLPR0 *) PCPDMPCIRAWHLPR0;
2143
2144/** Current PDMPCIRAWHLPR0 version number. */
2145#define PDM_PCIRAWHLPR0_VERSION PDM_VERSION_MAKE(0xffdf, 1, 0)
2146
2147
2148/**
2149 * Raw PCI device ring-3 context helpers.
2150 */
2151typedef struct PDMPCIRAWHLPR3
2152{
2153 /** Undefined structure version and magic number. */
2154 uint32_t u32Version;
2155
2156 /**
2157 * Gets the address of the RC raw PCI device helpers.
2158 *
2159 * This should be called at both construction and relocation time to obtain
2160 * the correct address of the RC helpers.
2161 *
2162 * @returns RC pointer to the raw PCI device helpers.
2163 * @param pDevIns Device instance of the raw PCI device.
2164 */
2165 DECLR3CALLBACKMEMBER(PCPDMPCIRAWHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
2166
2167 /**
2168 * Gets the address of the R0 raw PCI device helpers.
2169 *
2170 * This should be called at both construction and relocation time to obtain
2171 * the correct address of the R0 helpers.
2172 *
2173 * @returns R0 pointer to the raw PCI device helpers.
2174 * @param pDevIns Device instance of the raw PCI device.
2175 */
2176 DECLR3CALLBACKMEMBER(PCPDMPCIRAWHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
2177
2178 /** Just a safety precaution. */
2179 uint32_t u32TheEnd;
2180} PDMPCIRAWHLPR3;
2181/** Pointer to raw PCI R3 helpers. */
2182typedef R3PTRTYPE(PDMPCIRAWHLPR3 *) PPDMPCIRAWHLPR3;
2183/** Pointer to const raw PCI R3 helpers. */
2184typedef R3PTRTYPE(const PDMPCIRAWHLPR3 *) PCPDMPCIRAWHLPR3;
2185
2186/** Current PDMPCIRAWHLPR3 version number. */
2187#define PDM_PCIRAWHLPR3_VERSION PDM_VERSION_MAKE(0xffde, 1, 0)
2188
2189
2190#ifdef IN_RING3
2191
2192/**
2193 * DMA Transfer Handler.
2194 *
2195 * @returns Number of bytes transferred.
2196 * @param pDevIns The device instance that registered the handler.
2197 * @param pvUser User pointer.
2198 * @param uChannel Channel number.
2199 * @param off DMA position.
2200 * @param cb Block size.
2201 * @remarks The device lock is take before the callback (in fact, the locks of
2202 * DMA devices and the DMA controller itself are taken).
2203 */
2204typedef DECLCALLBACKTYPE(uint32_t, FNDMATRANSFERHANDLER,(PPDMDEVINS pDevIns, void *pvUser, unsigned uChannel,
2205 uint32_t off, uint32_t cb));
2206/** Pointer to a FNDMATRANSFERHANDLER(). */
2207typedef FNDMATRANSFERHANDLER *PFNDMATRANSFERHANDLER;
2208
2209/**
2210 * DMA Controller registration structure.
2211 */
2212typedef struct PDMDMAREG
2213{
2214 /** Structure version number. PDM_DMACREG_VERSION defines the current version. */
2215 uint32_t u32Version;
2216
2217 /**
2218 * Execute pending transfers.
2219 *
2220 * @returns A more work indiciator. I.e. 'true' if there is more to be done, and 'false' if all is done.
2221 * @param pDevIns Device instance of the DMAC.
2222 * @remarks No locks held, called on EMT(0) as a form of serialization.
2223 */
2224 DECLR3CALLBACKMEMBER(bool, pfnRun,(PPDMDEVINS pDevIns));
2225
2226 /**
2227 * Register transfer function for DMA channel.
2228 *
2229 * @param pDevIns Device instance of the DMAC.
2230 * @param uChannel Channel number.
2231 * @param pDevInsHandler The device instance of the device making the
2232 * regstration (will be passed to the callback).
2233 * @param pfnTransferHandler Device specific transfer function.
2234 * @param pvUser User pointer to be passed to the callback.
2235 * @remarks No locks held, called on an EMT.
2236 */
2237 DECLR3CALLBACKMEMBER(void, pfnRegister,(PPDMDEVINS pDevIns, unsigned uChannel, PPDMDEVINS pDevInsHandler,
2238 PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
2239
2240 /**
2241 * Read memory
2242 *
2243 * @returns Number of bytes read.
2244 * @param pDevIns Device instance of the DMAC.
2245 * @param uChannel Channel number.
2246 * @param pvBuffer Pointer to target buffer.
2247 * @param off DMA position.
2248 * @param cbBlock Block size.
2249 * @remarks No locks held, called on an EMT.
2250 */
2251 DECLR3CALLBACKMEMBER(uint32_t, pfnReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock));
2252
2253 /**
2254 * Write memory
2255 *
2256 * @returns Number of bytes written.
2257 * @param pDevIns Device instance of the DMAC.
2258 * @param uChannel Channel number.
2259 * @param pvBuffer Memory to write.
2260 * @param off DMA position.
2261 * @param cbBlock Block size.
2262 * @remarks No locks held, called on an EMT.
2263 */
2264 DECLR3CALLBACKMEMBER(uint32_t, pfnWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock));
2265
2266 /**
2267 * Set the DREQ line.
2268 *
2269 * @param pDevIns Device instance of the DMAC.
2270 * @param uChannel Channel number.
2271 * @param uLevel Level of the line.
2272 * @remarks No locks held, called on an EMT.
2273 */
2274 DECLR3CALLBACKMEMBER(void, pfnSetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
2275
2276 /**
2277 * Get channel mode
2278 *
2279 * @returns Channel mode.
2280 * @param pDevIns Device instance of the DMAC.
2281 * @param uChannel Channel number.
2282 * @remarks No locks held, called on an EMT.
2283 */
2284 DECLR3CALLBACKMEMBER(uint8_t, pfnGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
2285
2286} PDMDMACREG;
2287/** Pointer to a DMAC registration structure. */
2288typedef PDMDMACREG *PPDMDMACREG;
2289
2290/** Current PDMDMACREG version number. */
2291#define PDM_DMACREG_VERSION PDM_VERSION_MAKE(0xffeb, 2, 0)
2292
2293
2294/**
2295 * DMA Controller device helpers.
2296 */
2297typedef struct PDMDMACHLP
2298{
2299 /** Structure version. PDM_DMACHLP_VERSION defines the current version. */
2300 uint32_t u32Version;
2301
2302 /* to-be-defined */
2303
2304} PDMDMACHLP;
2305/** Pointer to DMAC helpers. */
2306typedef PDMDMACHLP *PPDMDMACHLP;
2307/** Pointer to const DMAC helpers. */
2308typedef const PDMDMACHLP *PCPDMDMACHLP;
2309
2310/** Current PDMDMACHLP version number. */
2311#define PDM_DMACHLP_VERSION PDM_VERSION_MAKE(0xffea, 1, 0)
2312
2313#endif /* IN_RING3 */
2314
2315
2316
2317/**
2318 * RTC registration structure.
2319 */
2320typedef struct PDMRTCREG
2321{
2322 /** Structure version number. PDM_RTCREG_VERSION defines the current version. */
2323 uint32_t u32Version;
2324 uint32_t u32Alignment; /**< structure size alignment. */
2325
2326 /**
2327 * Write to a CMOS register and update the checksum if necessary.
2328 *
2329 * @returns VBox status code.
2330 * @param pDevIns Device instance of the RTC.
2331 * @param iReg The CMOS register index.
2332 * @param u8Value The CMOS register value.
2333 * @remarks Caller enters the device critical section.
2334 */
2335 DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
2336
2337 /**
2338 * Read a CMOS register.
2339 *
2340 * @returns VBox status code.
2341 * @param pDevIns Device instance of the RTC.
2342 * @param iReg The CMOS register index.
2343 * @param pu8Value Where to store the CMOS register value.
2344 * @remarks Caller enters the device critical section.
2345 */
2346 DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
2347
2348} PDMRTCREG;
2349/** Pointer to a RTC registration structure. */
2350typedef PDMRTCREG *PPDMRTCREG;
2351/** Pointer to a const RTC registration structure. */
2352typedef const PDMRTCREG *PCPDMRTCREG;
2353
2354/** Current PDMRTCREG version number. */
2355#define PDM_RTCREG_VERSION PDM_VERSION_MAKE(0xffe9, 2, 0)
2356
2357
2358/**
2359 * RTC device helpers.
2360 */
2361typedef struct PDMRTCHLP
2362{
2363 /** Structure version. PDM_RTCHLP_VERSION defines the current version. */
2364 uint32_t u32Version;
2365
2366 /* to-be-defined */
2367
2368} PDMRTCHLP;
2369/** Pointer to RTC helpers. */
2370typedef PDMRTCHLP *PPDMRTCHLP;
2371/** Pointer to const RTC helpers. */
2372typedef const PDMRTCHLP *PCPDMRTCHLP;
2373
2374/** Current PDMRTCHLP version number. */
2375#define PDM_RTCHLP_VERSION PDM_VERSION_MAKE(0xffe8, 1, 0)
2376
2377
2378
2379/** @name Flags for PCI I/O region registration
2380 * @{ */
2381/** No handle is passed. */
2382#define PDMPCIDEV_IORGN_F_NO_HANDLE UINT32_C(0x00000000)
2383/** An I/O port handle is passed. */
2384#define PDMPCIDEV_IORGN_F_IOPORT_HANDLE UINT32_C(0x00000001)
2385/** An MMIO range handle is passed. */
2386#define PDMPCIDEV_IORGN_F_MMIO_HANDLE UINT32_C(0x00000002)
2387/** An MMIO2 handle is passed. */
2388#define PDMPCIDEV_IORGN_F_MMIO2_HANDLE UINT32_C(0x00000003)
2389/** Handle type mask. */
2390#define PDMPCIDEV_IORGN_F_HANDLE_MASK UINT32_C(0x00000003)
2391/** New-style (mostly wrt callbacks). */
2392#define PDMPCIDEV_IORGN_F_NEW_STYLE UINT32_C(0x00000004)
2393/** Mask of valid flags. */
2394#define PDMPCIDEV_IORGN_F_VALID_MASK UINT32_C(0x00000007)
2395/** @} */
2396
2397
2398/** @name Flags for the guest physical read/write helpers
2399 * @{ */
2400/** Default flag with no indication whether the data is processed by the device or just passed through. */
2401#define PDM_DEVHLP_PHYS_RW_F_DEFAULT UINT32_C(0x00000000)
2402/** The data is user data which is just passed through between the guest and the source or destination and not processed
2403 * by the device in any way. */
2404#define PDM_DEVHLP_PHYS_RW_F_DATA_USER RT_BIT_32(0)
2405/** The data is metadata and being processed by the device in some way. */
2406#define PDM_DEVHLP_PHYS_RW_F_DATA_META RT_BIT_32(1)
2407/** @} */
2408
2409
2410#ifdef IN_RING3
2411
2412/** @name Special values for PDMDEVHLPR3::pfnPCIRegister parameters.
2413 * @{ */
2414/** Same device number (and bus) as the previous PCI device registered with the PDM device.
2415 * This is handy when registering multiple PCI device functions and the device
2416 * number is left up to the PCI bus. In order to facilitate one PDM device
2417 * instance for each PCI function, this searches earlier PDM device
2418 * instances as well. */
2419# define PDMPCIDEVREG_DEV_NO_SAME_AS_PREV UINT8_C(0xfd)
2420/** Use the first unused device number (all functions must be unused). */
2421# define PDMPCIDEVREG_DEV_NO_FIRST_UNUSED UINT8_C(0xfe)
2422/** Use the first unused device function. */
2423# define PDMPCIDEVREG_FUN_NO_FIRST_UNUSED UINT8_C(0xff)
2424
2425/** The device and function numbers are not mandatory, just suggestions. */
2426# define PDMPCIDEVREG_F_NOT_MANDATORY_NO RT_BIT_32(0)
2427/** Registering a PCI bridge device. */
2428# define PDMPCIDEVREG_F_PCI_BRIDGE RT_BIT_32(1)
2429/** Valid flag mask. */
2430# define PDMPCIDEVREG_F_VALID_MASK UINT32_C(0x00000003)
2431/** @} */
2432
2433/** Current PDMDEVHLPR3 version number. */
2434#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE_PP(0xffe7, 66, 0)
2435
2436/**
2437 * PDM Device API.
2438 */
2439typedef struct PDMDEVHLPR3
2440{
2441 /** Structure version. PDM_DEVHLPR3_VERSION defines the current version. */
2442 uint32_t u32Version;
2443
2444 /** @name I/O ports
2445 * @{ */
2446 /**
2447 * Creates a range of I/O ports for a device.
2448 *
2449 * The I/O port range must be mapped in a separately call. Any ring-0 and
2450 * raw-mode context callback handlers needs to be set up in the respective
2451 * contexts.
2452 *
2453 * @returns VBox status.
2454 * @param pDevIns The device instance to register the ports with.
2455 * @param cPorts Number of ports to register.
2456 * @param fFlags IOM_IOPORT_F_XXX.
2457 * @param pPciDev The PCI device the range is associated with, if
2458 * applicable.
2459 * @param iPciRegion The PCI device region in the high 16-bit word and
2460 * sub-region in the low 16-bit word. UINT32_MAX if NA.
2461 * @param pfnOut Pointer to function which is gonna handle OUT
2462 * operations. Optional.
2463 * @param pfnIn Pointer to function which is gonna handle IN operations.
2464 * Optional.
2465 * @param pfnOutStr Pointer to function which is gonna handle string OUT
2466 * operations. Optional.
2467 * @param pfnInStr Pointer to function which is gonna handle string IN
2468 * operations. Optional.
2469 * @param pvUser User argument to pass to the callbacks.
2470 * @param pszDesc Pointer to description string. This must not be freed.
2471 * @param paExtDescs Extended per-port descriptions, optional. Partial range
2472 * coverage is allowed. This must not be freed.
2473 * @param phIoPorts Where to return the I/O port range handle.
2474 *
2475 * @remarks Caller enters the device critical section prior to invoking the
2476 * registered callback methods.
2477 *
2478 * @sa PDMDevHlpIoPortSetUpContext, PDMDevHlpIoPortMap,
2479 * PDMDevHlpIoPortUnmap.
2480 */
2481 DECLR3CALLBACKMEMBER(int, pfnIoPortCreateEx,(PPDMDEVINS pDevIns, RTIOPORT cPorts, uint32_t fFlags, PPDMPCIDEV pPciDev,
2482 uint32_t iPciRegion, PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
2483 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, RTR3PTR pvUser,
2484 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts));
2485
2486 /**
2487 * Maps an I/O port range.
2488 *
2489 * @returns VBox status.
2490 * @param pDevIns The device instance to register the ports with.
2491 * @param hIoPorts The I/O port range handle.
2492 * @param Port Where to map the range.
2493 * @sa PDMDevHlpIoPortUnmap, PDMDevHlpIoPortSetUpContext,
2494 * PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx.
2495 */
2496 DECLR3CALLBACKMEMBER(int, pfnIoPortMap,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT Port));
2497
2498 /**
2499 * Unmaps an I/O port range.
2500 *
2501 * @returns VBox status.
2502 * @param pDevIns The device instance to register the ports with.
2503 * @param hIoPorts The I/O port range handle.
2504 * @sa PDMDevHlpIoPortMap, PDMDevHlpIoPortSetUpContext,
2505 * PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx.
2506 */
2507 DECLR3CALLBACKMEMBER(int, pfnIoPortUnmap,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts));
2508
2509 /**
2510 * Gets the mapping address of the I/O port range @a hIoPorts.
2511 *
2512 * @returns Mapping address (0..65535) or UINT32_MAX if not mapped (or invalid
2513 * parameters).
2514 * @param pDevIns The device instance to register the ports with.
2515 * @param hIoPorts The I/O port range handle.
2516 */
2517 DECLR3CALLBACKMEMBER(uint32_t, pfnIoPortGetMappingAddress,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts));
2518
2519 /**
2520 * Reads from an I/O port register.
2521 *
2522 * @returns Strict VBox status code. Informational status codes other than the one documented
2523 * here are to be treated as internal failure. Use IOM_SUCCESS() to check for success.
2524 * @retval VINF_SUCCESS Success.
2525 * @retval VINF_EM_FIRST-VINF_EM_LAST Success with some exceptions (see IOM_SUCCESS()), the
2526 * status code must be passed on to EM.
2527 *
2528 * @param pDevIns The device instance to register the ports with.
2529 * @param Port The port to read from.
2530 * @param pu32Value Where to store the read value.
2531 * @param cbValue The size of the register to read in bytes. 1, 2 or 4 bytes.
2532 *
2533 * @thread EMT
2534 *
2535 * @note This is required for the ARM platform in order to emulate PIO accesses through a dedicated MMIO region.
2536 */
2537 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnIoPortRead,(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue));
2538
2539 /**
2540 * Writes to an I/O port register.
2541 *
2542 * @returns Strict VBox status code. Informational status codes other than the one documented
2543 * here are to be treated as internal failure. Use IOM_SUCCESS() to check for success.
2544 * @retval VINF_SUCCESS Success.
2545 * @retval VINF_EM_FIRST-VINF_EM_LAST Success with some exceptions (see IOM_SUCCESS()), the
2546 * status code must be passed on to EM.
2547 *
2548 * @param pDevIns The device instance to register the ports with.
2549 * @param Port The port to write to.
2550 * @param u32Value The value to write.
2551 * @param cbValue The size of the register to write in bytes. 1, 2 or 4 bytes.
2552 *
2553 * @thread EMT
2554 *
2555 * @note This is required for the ARM platform in order to emulate PIO accesses through a dedicated MMIO region.
2556 */
2557 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnIoPortWrite,(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t u32Value, size_t cbValue));
2558 /** @} */
2559
2560 /** @name MMIO
2561 * @{ */
2562 /**
2563 * Creates a memory mapped I/O (MMIO) region for a device.
2564 *
2565 * The MMIO region must be mapped in a separately call. Any ring-0 and
2566 * raw-mode context callback handlers needs to be set up in the respective
2567 * contexts.
2568 *
2569 * @returns VBox status.
2570 * @param pDevIns The device instance to register the ports with.
2571 * @param cbRegion The size of the region in bytes.
2572 * @param fFlags Flags, IOMMMIO_FLAGS_XXX.
2573 * @param pPciDev The PCI device the range is associated with, if
2574 * applicable.
2575 * @param iPciRegion The PCI device region in the high 16-bit word and
2576 * sub-region in the low 16-bit word. UINT32_MAX if NA.
2577 * @param pfnWrite Pointer to function which is gonna handle Write
2578 * operations.
2579 * @param pfnRead Pointer to function which is gonna handle Read
2580 * operations.
2581 * @param pfnFill Pointer to function which is gonna handle Fill/memset
2582 * operations. (optional)
2583 * @param pvUser User argument to pass to the callbacks.
2584 * @param pszDesc Pointer to description string. This must not be freed.
2585 * @param phRegion Where to return the MMIO region handle.
2586 *
2587 * @remarks Caller enters the device critical section prior to invoking the
2588 * registered callback methods.
2589 *
2590 * @sa PDMDevHlpMmioSetUpContext, PDMDevHlpMmioMap, PDMDevHlpMmioUnmap.
2591 */
2592 DECLR3CALLBACKMEMBER(int, pfnMmioCreateEx,(PPDMDEVINS pDevIns, RTGCPHYS cbRegion,
2593 uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
2594 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill,
2595 void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion));
2596
2597 /**
2598 * Maps a memory mapped I/O (MMIO) region (into the guest physical address space).
2599 *
2600 * @returns VBox status.
2601 * @param pDevIns The device instance the region is associated with.
2602 * @param hRegion The MMIO region handle.
2603 * @param GCPhys Where to map the region.
2604 * @note An MMIO range may overlap with base memory if a lot of RAM is
2605 * configured for the VM, in which case we'll drop the base memory
2606 * pages. Presently we will make no attempt to preserve anything that
2607 * happens to be present in the base memory that is replaced, this is
2608 * technically incorrect but it's just not worth the effort to do
2609 * right, at least not at this point.
2610 * @sa PDMDevHlpMmioUnmap, PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx,
2611 * PDMDevHlpMmioSetUpContext
2612 */
2613 DECLR3CALLBACKMEMBER(int, pfnMmioMap,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys));
2614
2615 /**
2616 * Unmaps a memory mapped I/O (MMIO) region.
2617 *
2618 * @returns VBox status.
2619 * @param pDevIns The device instance the region is associated with.
2620 * @param hRegion The MMIO region handle.
2621 * @sa PDMDevHlpMmioMap, PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx,
2622 * PDMDevHlpMmioSetUpContext
2623 */
2624 DECLR3CALLBACKMEMBER(int, pfnMmioUnmap,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion));
2625
2626 /**
2627 * Reduces the length of a MMIO range.
2628 *
2629 * This is for implementations of PDMPCIDEV::pfnRegionLoadChangeHookR3 and will
2630 * only work during saved state restore. It will not call the PCI bus code, as
2631 * that is expected to restore the saved resource configuration.
2632 *
2633 * It just adjusts the mapping length of the region so that when pfnMmioMap is
2634 * called it will only map @a cbRegion bytes and not the value set during
2635 * registration.
2636 *
2637 * @return VBox status code.
2638 * @param pDevIns The device owning the range.
2639 * @param hRegion The MMIO region handle.
2640 * @param cbRegion The new size, must be smaller.
2641 */
2642 DECLR3CALLBACKMEMBER(int, pfnMmioReduce,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS cbRegion));
2643
2644 /**
2645 * Gets the mapping address of the MMIO region @a hRegion.
2646 *
2647 * @returns Mapping address, NIL_RTGCPHYS if not mapped (or invalid parameters).
2648 * @param pDevIns The device instance to register the ports with.
2649 * @param hRegion The MMIO region handle.
2650 */
2651 DECLR3CALLBACKMEMBER(RTGCPHYS, pfnMmioGetMappingAddress,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion));
2652 /** @} */
2653
2654 /** @name MMIO2
2655 * @{ */
2656 /**
2657 * Creates a MMIO2 region.
2658 *
2659 * As mentioned elsewhere, MMIO2 is just RAM spelled differently. It's RAM
2660 * associated with a device. It is also non-shared memory with a permanent
2661 * ring-3 mapping and page backing (presently).
2662 *
2663 * @returns VBox status.
2664 * @param pDevIns The device instance.
2665 * @param pPciDev The PCI device the region is associated with, or
2666 * NULL if no PCI device association.
2667 * @param iPciRegion The region number. Use the PCI region number as
2668 * this must be known to the PCI bus device too. If
2669 * it's not associated with the PCI device, then
2670 * any number up to UINT8_MAX is fine.
2671 * @param cbRegion The size (in bytes) of the region.
2672 * @param fFlags PGMPHYS_MMIO2_FLAGS_XXX (see pgm.h).
2673 * @param pszDesc Pointer to description string. This must not be
2674 * freed.
2675 * @param ppvMapping Where to store the address of the ring-3 mapping
2676 * of the memory.
2677 * @param phRegion Where to return the MMIO2 region handle.
2678 *
2679 * @thread EMT(0)
2680 */
2681 DECLR3CALLBACKMEMBER(int, pfnMmio2Create,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iPciRegion, RTGCPHYS cbRegion,
2682 uint32_t fFlags, const char *pszDesc, void **ppvMapping, PPGMMMIO2HANDLE phRegion));
2683
2684 /**
2685 * Destroys a MMIO2 region, unmapping it and freeing the memory.
2686 *
2687 * Any physical access handlers registered for the region must be deregistered
2688 * before calling this function.
2689 *
2690 * @returns VBox status code.
2691 * @param pDevIns The device instance.
2692 * @param hRegion The MMIO2 region handle.
2693 * @thread EMT.
2694 */
2695 DECLR3CALLBACKMEMBER(int, pfnMmio2Destroy,(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion));
2696
2697 /**
2698 * Maps a MMIO2 region (into the guest physical address space).
2699 *
2700 * @returns VBox status.
2701 * @param pDevIns The device instance the region is associated with.
2702 * @param hRegion The MMIO2 region handle.
2703 * @param GCPhys Where to map the region.
2704 * @note A MMIO2 region overlap with base memory if a lot of RAM is
2705 * configured for the VM, in which case we'll drop the base memory
2706 * pages. Presently we will make no attempt to preserve anything that
2707 * happens to be present in the base memory that is replaced, this is
2708 * technically incorrect but it's just not worth the effort to do
2709 * right, at least not at this point.
2710 * @sa PDMDevHlpMmio2Unmap, PDMDevHlpMmio2Create, PDMDevHlpMmio2SetUpContext
2711 */
2712 DECLR3CALLBACKMEMBER(int, pfnMmio2Map,(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, RTGCPHYS GCPhys));
2713
2714 /**
2715 * Unmaps a MMIO2 region.
2716 *
2717 * @returns VBox status.
2718 * @param pDevIns The device instance the region is associated with.
2719 * @param hRegion The MMIO2 region handle.
2720 * @sa PDMDevHlpMmio2Map, PDMDevHlpMmio2Create, PDMDevHlpMmio2SetUpContext
2721 */
2722 DECLR3CALLBACKMEMBER(int, pfnMmio2Unmap,(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion));
2723
2724 /**
2725 * Reduces the length of a MMIO range.
2726 *
2727 * This is for implementations of PDMPCIDEV::pfnRegionLoadChangeHookR3 and will
2728 * only work during saved state restore. It will not call the PCI bus code, as
2729 * that is expected to restore the saved resource configuration.
2730 *
2731 * It just adjusts the mapping length of the region so that when pfnMmioMap is
2732 * called it will only map @a cbRegion bytes and not the value set during
2733 * registration.
2734 *
2735 * @return VBox status code.
2736 * @param pDevIns The device owning the range.
2737 * @param hRegion The MMIO2 region handle.
2738 * @param cbRegion The new size, must be smaller.
2739 */
2740 DECLR3CALLBACKMEMBER(int, pfnMmio2Reduce,(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, RTGCPHYS cbRegion));
2741
2742 /**
2743 * Gets the mapping address of the MMIO region @a hRegion.
2744 *
2745 * @returns Mapping address, NIL_RTGCPHYS if not mapped (or invalid parameters).
2746 * @param pDevIns The device instance to register the ports with.
2747 * @param hRegion The MMIO2 region handle.
2748 */
2749 DECLR3CALLBACKMEMBER(RTGCPHYS, pfnMmio2GetMappingAddress,(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion));
2750
2751 /**
2752 * Queries and resets the dirty bitmap for an MMIO2 region.
2753 *
2754 * The MMIO2 region must have been created with the
2755 * PGMPHYS_MMIO2_FLAGS_TRACK_DIRTY_PAGES flag for this to work.
2756 *
2757 * @returns VBox status code.
2758 * @param pDevIns The device instance.
2759 * @param hRegion The MMIO2 region handle.
2760 * @param pvBitmap Where to return the bitmap. Must be 8-byte aligned.
2761 * Can be NULL if only resetting the tracking is desired.
2762 * @param cbBitmap The bitmap size. One bit per page in the region,
2763 * rounded up to 8-bytes. If pvBitmap is NULL this must
2764 * also be zero.
2765 */
2766 DECLR3CALLBACKMEMBER(int, pfnMmio2QueryAndResetDirtyBitmap, (PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion,
2767 void *pvBitmap, size_t cbBitmap));
2768
2769 /**
2770 * Controls the dirty page tracking for an MMIO2 region.
2771 *
2772 * The MMIO2 region must have been created with the
2773 * PGMPHYS_MMIO2_FLAGS_TRACK_DIRTY_PAGES flag for this to work.
2774 *
2775 * @returns VBox status code.
2776 * @param pDevIns The device instance.
2777 * @param hRegion The MMIO2 region handle.
2778 * @param fEnabled When set to @c true the dirty page tracking will be
2779 * enabled if currently disabled (bitmap is reset). When
2780 * set to @c false the dirty page tracking will be
2781 * disabled.
2782 */
2783 DECLR3CALLBACKMEMBER(int, pfnMmio2ControlDirtyPageTracking, (PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, bool fEnabled));
2784
2785 /**
2786 * Changes the number of an MMIO2 or pre-registered MMIO region.
2787 *
2788 * This should only be used to deal with saved state problems, so there is no
2789 * convenience inline wrapper for this method.
2790 *
2791 * @returns VBox status code.
2792 * @param pDevIns The device instance.
2793 * @param hRegion The MMIO2 region handle.
2794 * @param iNewRegion The new region index.
2795 *
2796 * @sa @bugref{9359}
2797 */
2798 DECLR3CALLBACKMEMBER(int, pfnMmio2ChangeRegionNo,(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, uint32_t iNewRegion));
2799
2800 /**
2801 * Mapping an MMIO2 page in place of an MMIO page for direct access.
2802 *
2803 * This is a special optimization used by the VGA device. Call
2804 * PDMDevHlpMmioResetRegion() to undo the mapping.
2805 *
2806 * @returns VBox status code. This API may return VINF_SUCCESS even if no
2807 * remapping is made.
2808 * @retval VERR_SEM_BUSY in ring-0 if we cannot get the IOM lock.
2809 *
2810 * @param pDevIns The device instance @a hRegion and @a hMmio2 are
2811 * associated with.
2812 * @param hRegion The handle to the MMIO region.
2813 * @param offRegion The offset into @a hRegion of the page to be
2814 * remapped.
2815 * @param hMmio2 The MMIO2 handle.
2816 * @param offMmio2 Offset into @a hMmio2 of the page to be use for the
2817 * mapping.
2818 * @param fPageFlags Page flags to set. Must be (X86_PTE_RW | X86_PTE_P)
2819 * for the time being.
2820 */
2821 DECLR3CALLBACKMEMBER(int, pfnMmioMapMmio2Page,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS offRegion,
2822 uint64_t hMmio2, RTGCPHYS offMmio2, uint64_t fPageFlags));
2823
2824 /**
2825 * Reset a previously modified MMIO region; restore the access flags.
2826 *
2827 * This undoes the effects of PDMDevHlpMmioMapMmio2Page() and is currently only
2828 * intended for some ancient VGA hack. However, it would be great to extend it
2829 * beyond VT-x and/or nested-paging.
2830 *
2831 * @returns VBox status code.
2832 *
2833 * @param pDevIns The device instance @a hRegion is associated with.
2834 * @param hRegion The handle to the MMIO region.
2835 */
2836 DECLR3CALLBACKMEMBER(int, pfnMmioResetRegion, (PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion));
2837 /** @} */
2838
2839 /**
2840 * Register a ROM (BIOS) region.
2841 *
2842 * It goes without saying that this is read-only memory. The memory region must be
2843 * in unassigned memory. I.e. from the top of the address space or on the PC in
2844 * the 0xa0000-0xfffff range.
2845 *
2846 * @returns VBox status.
2847 * @param pDevIns The device instance owning the ROM region.
2848 * @param GCPhysStart First physical address in the range.
2849 * Must be page aligned!
2850 * @param cbRange The size of the range (in bytes).
2851 * Must be page aligned!
2852 * @param pvBinary Pointer to the binary data backing the ROM image.
2853 * @param cbBinary The size of the binary pointer. This must
2854 * be equal or smaller than @a cbRange.
2855 * @param fFlags PGMPHYS_ROM_FLAGS_XXX (see pgm.h).
2856 * @param pszDesc Pointer to description string. This must not be freed.
2857 *
2858 * @remark There is no way to remove the rom, automatically on device cleanup or
2859 * manually from the device yet. At present I doubt we need such features...
2860 */
2861 DECLR3CALLBACKMEMBER(int, pfnROMRegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
2862 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc));
2863
2864 /**
2865 * Changes the protection of shadowed ROM mapping.
2866 *
2867 * This is intented for use by the system BIOS, chipset or device in question to
2868 * change the protection of shadowed ROM code after init and on reset.
2869 *
2870 * @param pDevIns The device instance.
2871 * @param GCPhysStart Where the mapping starts.
2872 * @param cbRange The size of the mapping.
2873 * @param enmProt The new protection type.
2874 */
2875 DECLR3CALLBACKMEMBER(int, pfnROMProtectShadow,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt));
2876
2877 /**
2878 * Register a save state data unit.
2879 *
2880 * @returns VBox status.
2881 * @param pDevIns The device instance.
2882 * @param uVersion Data layout version number.
2883 * @param cbGuess The approximate amount of data in the unit.
2884 * Only for progress indicators.
2885 * @param pszBefore Name of data unit which we should be put in
2886 * front of. Optional (NULL).
2887 *
2888 * @param pfnLivePrep Prepare live save callback, optional.
2889 * @param pfnLiveExec Execute live save callback, optional.
2890 * @param pfnLiveVote Vote live save callback, optional.
2891 *
2892 * @param pfnSavePrep Prepare save callback, optional.
2893 * @param pfnSaveExec Execute save callback, optional.
2894 * @param pfnSaveDone Done save callback, optional.
2895 *
2896 * @param pfnLoadPrep Prepare load callback, optional.
2897 * @param pfnLoadExec Execute load callback, optional.
2898 * @param pfnLoadDone Done load callback, optional.
2899 * @remarks Caller enters the device critical section prior to invoking the
2900 * registered callback methods.
2901 */
2902 DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
2903 PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
2904 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
2905 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone));
2906
2907 /**
2908 * Register a save state data unit for backward compatibility.
2909 *
2910 * This is for migrating from an old device name to a new one or for merging
2911 * devices. It will only help loading old saved states.
2912 *
2913 * @returns VBox status.
2914 * @param pDevIns The device instance.
2915 * @param pszOldName The old unit name.
2916 * @param pfnLoadPrep Prepare load callback, optional.
2917 * @param pfnLoadExec Execute load callback, optional.
2918 * @param pfnLoadDone Done load callback, optional.
2919 * @remarks Caller enters the device critical section prior to invoking the
2920 * registered callback methods.
2921 */
2922 DECLR3CALLBACKMEMBER(int, pfnSSMRegisterLegacy,(PPDMDEVINS pDevIns, const char *pszOldName, PFNSSMDEVLOADPREP pfnLoadPrep,
2923 PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone));
2924
2925 /** @name Exported SSM Functions
2926 * @{ */
2927 DECLR3CALLBACKMEMBER(int, pfnSSMPutStruct,(PSSMHANDLE pSSM, const void *pvStruct, PCSSMFIELD paFields));
2928 DECLR3CALLBACKMEMBER(int, pfnSSMPutStructEx,(PSSMHANDLE pSSM, const void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser));
2929 DECLR3CALLBACKMEMBER(int, pfnSSMPutBool,(PSSMHANDLE pSSM, bool fBool));
2930 DECLR3CALLBACKMEMBER(int, pfnSSMPutU8,(PSSMHANDLE pSSM, uint8_t u8));
2931 DECLR3CALLBACKMEMBER(int, pfnSSMPutS8,(PSSMHANDLE pSSM, int8_t i8));
2932 DECLR3CALLBACKMEMBER(int, pfnSSMPutU16,(PSSMHANDLE pSSM, uint16_t u16));
2933 DECLR3CALLBACKMEMBER(int, pfnSSMPutS16,(PSSMHANDLE pSSM, int16_t i16));
2934 DECLR3CALLBACKMEMBER(int, pfnSSMPutU32,(PSSMHANDLE pSSM, uint32_t u32));
2935 DECLR3CALLBACKMEMBER(int, pfnSSMPutS32,(PSSMHANDLE pSSM, int32_t i32));
2936 DECLR3CALLBACKMEMBER(int, pfnSSMPutU64,(PSSMHANDLE pSSM, uint64_t u64));
2937 DECLR3CALLBACKMEMBER(int, pfnSSMPutS64,(PSSMHANDLE pSSM, int64_t i64));
2938 DECLR3CALLBACKMEMBER(int, pfnSSMPutU128,(PSSMHANDLE pSSM, uint128_t u128));
2939 DECLR3CALLBACKMEMBER(int, pfnSSMPutS128,(PSSMHANDLE pSSM, int128_t i128));
2940 DECLR3CALLBACKMEMBER(int, pfnSSMPutUInt,(PSSMHANDLE pSSM, RTUINT u));
2941 DECLR3CALLBACKMEMBER(int, pfnSSMPutSInt,(PSSMHANDLE pSSM, RTINT i));
2942 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCUInt,(PSSMHANDLE pSSM, RTGCUINT u));
2943 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCUIntReg,(PSSMHANDLE pSSM, RTGCUINTREG u));
2944 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCPhys32,(PSSMHANDLE pSSM, RTGCPHYS32 GCPhys));
2945 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCPhys64,(PSSMHANDLE pSSM, RTGCPHYS64 GCPhys));
2946 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCPhys,(PSSMHANDLE pSSM, RTGCPHYS GCPhys));
2947 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCPtr,(PSSMHANDLE pSSM, RTGCPTR GCPtr));
2948 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCUIntPtr,(PSSMHANDLE pSSM, RTGCUINTPTR GCPtr));
2949 DECLR3CALLBACKMEMBER(int, pfnSSMPutRCPtr,(PSSMHANDLE pSSM, RTRCPTR RCPtr));
2950 DECLR3CALLBACKMEMBER(int, pfnSSMPutIOPort,(PSSMHANDLE pSSM, RTIOPORT IOPort));
2951 DECLR3CALLBACKMEMBER(int, pfnSSMPutSel,(PSSMHANDLE pSSM, RTSEL Sel));
2952 DECLR3CALLBACKMEMBER(int, pfnSSMPutMem,(PSSMHANDLE pSSM, const void *pv, size_t cb));
2953 DECLR3CALLBACKMEMBER(int, pfnSSMPutStrZ,(PSSMHANDLE pSSM, const char *psz));
2954 DECLR3CALLBACKMEMBER(int, pfnSSMGetStruct,(PSSMHANDLE pSSM, void *pvStruct, PCSSMFIELD paFields));
2955 DECLR3CALLBACKMEMBER(int, pfnSSMGetStructEx,(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser));
2956 DECLR3CALLBACKMEMBER(int, pfnSSMGetBool,(PSSMHANDLE pSSM, bool *pfBool));
2957 DECLR3CALLBACKMEMBER(int, pfnSSMGetBoolV,(PSSMHANDLE pSSM, bool volatile *pfBool));
2958 DECLR3CALLBACKMEMBER(int, pfnSSMGetU8,(PSSMHANDLE pSSM, uint8_t *pu8));
2959 DECLR3CALLBACKMEMBER(int, pfnSSMGetU8V,(PSSMHANDLE pSSM, uint8_t volatile *pu8));
2960 DECLR3CALLBACKMEMBER(int, pfnSSMGetS8,(PSSMHANDLE pSSM, int8_t *pi8));
2961 DECLR3CALLBACKMEMBER(int, pfnSSMGetS8V,(PSSMHANDLE pSSM, int8_t volatile *pi8));
2962 DECLR3CALLBACKMEMBER(int, pfnSSMGetU16,(PSSMHANDLE pSSM, uint16_t *pu16));
2963 DECLR3CALLBACKMEMBER(int, pfnSSMGetU16V,(PSSMHANDLE pSSM, uint16_t volatile *pu16));
2964 DECLR3CALLBACKMEMBER(int, pfnSSMGetS16,(PSSMHANDLE pSSM, int16_t *pi16));
2965 DECLR3CALLBACKMEMBER(int, pfnSSMGetS16V,(PSSMHANDLE pSSM, int16_t volatile *pi16));
2966 DECLR3CALLBACKMEMBER(int, pfnSSMGetU32,(PSSMHANDLE pSSM, uint32_t *pu32));
2967 DECLR3CALLBACKMEMBER(int, pfnSSMGetU32V,(PSSMHANDLE pSSM, uint32_t volatile *pu32));
2968 DECLR3CALLBACKMEMBER(int, pfnSSMGetS32,(PSSMHANDLE pSSM, int32_t *pi32));
2969 DECLR3CALLBACKMEMBER(int, pfnSSMGetS32V,(PSSMHANDLE pSSM, int32_t volatile *pi32));
2970 DECLR3CALLBACKMEMBER(int, pfnSSMGetU64,(PSSMHANDLE pSSM, uint64_t *pu64));
2971 DECLR3CALLBACKMEMBER(int, pfnSSMGetU64V,(PSSMHANDLE pSSM, uint64_t volatile *pu64));
2972 DECLR3CALLBACKMEMBER(int, pfnSSMGetS64,(PSSMHANDLE pSSM, int64_t *pi64));
2973 DECLR3CALLBACKMEMBER(int, pfnSSMGetS64V,(PSSMHANDLE pSSM, int64_t volatile *pi64));
2974 DECLR3CALLBACKMEMBER(int, pfnSSMGetU128,(PSSMHANDLE pSSM, uint128_t *pu128));
2975 DECLR3CALLBACKMEMBER(int, pfnSSMGetU128V,(PSSMHANDLE pSSM, uint128_t volatile *pu128));
2976 DECLR3CALLBACKMEMBER(int, pfnSSMGetS128,(PSSMHANDLE pSSM, int128_t *pi128));
2977 DECLR3CALLBACKMEMBER(int, pfnSSMGetS128V,(PSSMHANDLE pSSM, int128_t volatile *pi128));
2978 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPhys32,(PSSMHANDLE pSSM, PRTGCPHYS32 pGCPhys));
2979 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPhys32V,(PSSMHANDLE pSSM, RTGCPHYS32 volatile *pGCPhys));
2980 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPhys64,(PSSMHANDLE pSSM, PRTGCPHYS64 pGCPhys));
2981 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPhys64V,(PSSMHANDLE pSSM, RTGCPHYS64 volatile *pGCPhys));
2982 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPhys,(PSSMHANDLE pSSM, PRTGCPHYS pGCPhys));
2983 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPhysV,(PSSMHANDLE pSSM, RTGCPHYS volatile *pGCPhys));
2984 DECLR3CALLBACKMEMBER(int, pfnSSMGetUInt,(PSSMHANDLE pSSM, PRTUINT pu));
2985 DECLR3CALLBACKMEMBER(int, pfnSSMGetSInt,(PSSMHANDLE pSSM, PRTINT pi));
2986 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCUInt,(PSSMHANDLE pSSM, PRTGCUINT pu));
2987 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCUIntReg,(PSSMHANDLE pSSM, PRTGCUINTREG pu));
2988 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPtr,(PSSMHANDLE pSSM, PRTGCPTR pGCPtr));
2989 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCUIntPtr,(PSSMHANDLE pSSM, PRTGCUINTPTR pGCPtr));
2990 DECLR3CALLBACKMEMBER(int, pfnSSMGetRCPtr,(PSSMHANDLE pSSM, PRTRCPTR pRCPtr));
2991 DECLR3CALLBACKMEMBER(int, pfnSSMGetIOPort,(PSSMHANDLE pSSM, PRTIOPORT pIOPort));
2992 DECLR3CALLBACKMEMBER(int, pfnSSMGetSel,(PSSMHANDLE pSSM, PRTSEL pSel));
2993 DECLR3CALLBACKMEMBER(int, pfnSSMGetMem,(PSSMHANDLE pSSM, void *pv, size_t cb));
2994 DECLR3CALLBACKMEMBER(int, pfnSSMGetStrZ,(PSSMHANDLE pSSM, char *psz, size_t cbMax));
2995 DECLR3CALLBACKMEMBER(int, pfnSSMGetStrZEx,(PSSMHANDLE pSSM, char *psz, size_t cbMax, size_t *pcbStr));
2996 DECLR3CALLBACKMEMBER(int, pfnSSMSkip,(PSSMHANDLE pSSM, size_t cb));
2997 DECLR3CALLBACKMEMBER(int, pfnSSMSkipToEndOfUnit,(PSSMHANDLE pSSM));
2998 DECLR3CALLBACKMEMBER(int, pfnSSMSetLoadError,(PSSMHANDLE pSSM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(6, 7));
2999 DECLR3CALLBACKMEMBER(int, pfnSSMSetLoadErrorV,(PSSMHANDLE pSSM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
3000 DECLR3CALLBACKMEMBER(int, pfnSSMSetCfgError,(PSSMHANDLE pSSM, RT_SRC_POS_DECL, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(5, 6));
3001 DECLR3CALLBACKMEMBER(int, pfnSSMSetCfgErrorV,(PSSMHANDLE pSSM, RT_SRC_POS_DECL, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(5, 0));
3002 DECLR3CALLBACKMEMBER(int, pfnSSMHandleGetStatus,(PSSMHANDLE pSSM));
3003 DECLR3CALLBACKMEMBER(SSMAFTER, pfnSSMHandleGetAfter,(PSSMHANDLE pSSM));
3004 DECLR3CALLBACKMEMBER(bool, pfnSSMHandleIsLiveSave,(PSSMHANDLE pSSM));
3005 DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleMaxDowntime,(PSSMHANDLE pSSM));
3006 DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleHostBits,(PSSMHANDLE pSSM));
3007 DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleRevision,(PSSMHANDLE pSSM));
3008 DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleVersion,(PSSMHANDLE pSSM));
3009 DECLR3CALLBACKMEMBER(const char *, pfnSSMHandleHostOSAndArch,(PSSMHANDLE pSSM));
3010 /** @} */
3011
3012 /**
3013 * Creates a timer w/ a cross context handle.
3014 *
3015 * @returns VBox status.
3016 * @param pDevIns The device instance.
3017 * @param enmClock The clock to use on this timer.
3018 * @param pfnCallback Callback function.
3019 * @param pvUser User argument for the callback.
3020 * @param fFlags Flags, see TMTIMER_FLAGS_*.
3021 * @param pszDesc Pointer to description string which must stay around
3022 * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
3023 * @param phTimer Where to store the timer handle on success.
3024 * @remarks Caller enters the device critical section prior to invoking the
3025 * callback.
3026 */
3027 DECLR3CALLBACKMEMBER(int, pfnTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
3028 void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer));
3029
3030 /** @name Timer handle method wrappers
3031 * @{ */
3032 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerFromMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs));
3033 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerFromMilli,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs));
3034 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerFromNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs));
3035 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerGet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
3036 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerGetFreq,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
3037 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerGetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
3038 DECLR3CALLBACKMEMBER(bool, pfnTimerIsActive,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
3039 DECLR3CALLBACKMEMBER(bool, pfnTimerIsLockOwner,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
3040 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnTimerLockClock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy));
3041 /** Takes the clock lock then enters the specified critical section. */
3042 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnTimerLockClock2,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect, int rcBusy));
3043 DECLR3CALLBACKMEMBER(int, pfnTimerSet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire));
3044 DECLR3CALLBACKMEMBER(int, pfnTimerSetFrequencyHint,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz));
3045 DECLR3CALLBACKMEMBER(int, pfnTimerSetMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext));
3046 DECLR3CALLBACKMEMBER(int, pfnTimerSetMillies,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext));
3047 DECLR3CALLBACKMEMBER(int, pfnTimerSetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext));
3048 DECLR3CALLBACKMEMBER(int, pfnTimerSetRelative,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now));
3049 DECLR3CALLBACKMEMBER(int, pfnTimerStop,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
3050 DECLR3CALLBACKMEMBER(void, pfnTimerUnlockClock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
3051 DECLR3CALLBACKMEMBER(void, pfnTimerUnlockClock2,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect));
3052 DECLR3CALLBACKMEMBER(int, pfnTimerSetCritSect,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect));
3053 DECLR3CALLBACKMEMBER(int, pfnTimerSave,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM));
3054 DECLR3CALLBACKMEMBER(int, pfnTimerLoad,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM));
3055 DECLR3CALLBACKMEMBER(int, pfnTimerDestroy,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
3056 /** @sa TMR3TimerSkip */
3057 DECLR3CALLBACKMEMBER(int, pfnTimerSkipLoad,(PSSMHANDLE pSSM, bool *pfActive));
3058 /** @} */
3059
3060 /**
3061 * Get the real world UTC time adjusted for VM lag, user offset and warpdrive.
3062 *
3063 * @returns pTime.
3064 * @param pDevIns The device instance.
3065 * @param pTime Where to store the time.
3066 */
3067 DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnTMUtcNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime));
3068
3069 /** @name Exported CFGM Functions.
3070 * @{ */
3071 DECLR3CALLBACKMEMBER(bool, pfnCFGMExists,( PCFGMNODE pNode, const char *pszName));
3072 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryType,( PCFGMNODE pNode, const char *pszName, PCFGMVALUETYPE penmType));
3073 DECLR3CALLBACKMEMBER(int, pfnCFGMQuerySize,( PCFGMNODE pNode, const char *pszName, size_t *pcb));
3074 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryInteger,( PCFGMNODE pNode, const char *pszName, uint64_t *pu64));
3075 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryIntegerDef,( PCFGMNODE pNode, const char *pszName, uint64_t *pu64, uint64_t u64Def));
3076 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryString,( PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString));
3077 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryStringDef,( PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString, const char *pszDef));
3078 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryPassword,( PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString));
3079 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryPasswordDef,( PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString, const char *pszDef));
3080 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryBytes,( PCFGMNODE pNode, const char *pszName, void *pvData, size_t cbData));
3081 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU64,( PCFGMNODE pNode, const char *pszName, uint64_t *pu64));
3082 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU64Def,( PCFGMNODE pNode, const char *pszName, uint64_t *pu64, uint64_t u64Def));
3083 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS64,( PCFGMNODE pNode, const char *pszName, int64_t *pi64));
3084 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS64Def,( PCFGMNODE pNode, const char *pszName, int64_t *pi64, int64_t i64Def));
3085 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU32,( PCFGMNODE pNode, const char *pszName, uint32_t *pu32));
3086 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU32Def,( PCFGMNODE pNode, const char *pszName, uint32_t *pu32, uint32_t u32Def));
3087 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS32,( PCFGMNODE pNode, const char *pszName, int32_t *pi32));
3088 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS32Def,( PCFGMNODE pNode, const char *pszName, int32_t *pi32, int32_t i32Def));
3089 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU16,( PCFGMNODE pNode, const char *pszName, uint16_t *pu16));
3090 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU16Def,( PCFGMNODE pNode, const char *pszName, uint16_t *pu16, uint16_t u16Def));
3091 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS16,( PCFGMNODE pNode, const char *pszName, int16_t *pi16));
3092 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS16Def,( PCFGMNODE pNode, const char *pszName, int16_t *pi16, int16_t i16Def));
3093 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU8,( PCFGMNODE pNode, const char *pszName, uint8_t *pu8));
3094 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU8Def,( PCFGMNODE pNode, const char *pszName, uint8_t *pu8, uint8_t u8Def));
3095 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS8,( PCFGMNODE pNode, const char *pszName, int8_t *pi8));
3096 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS8Def,( PCFGMNODE pNode, const char *pszName, int8_t *pi8, int8_t i8Def));
3097 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryBool,( PCFGMNODE pNode, const char *pszName, bool *pf));
3098 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryBoolDef,( PCFGMNODE pNode, const char *pszName, bool *pf, bool fDef));
3099 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryPort,( PCFGMNODE pNode, const char *pszName, PRTIOPORT pPort));
3100 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryPortDef,( PCFGMNODE pNode, const char *pszName, PRTIOPORT pPort, RTIOPORT PortDef));
3101 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryUInt,( PCFGMNODE pNode, const char *pszName, unsigned int *pu));
3102 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryUIntDef,( PCFGMNODE pNode, const char *pszName, unsigned int *pu, unsigned int uDef));
3103 DECLR3CALLBACKMEMBER(int, pfnCFGMQuerySInt,( PCFGMNODE pNode, const char *pszName, signed int *pi));
3104 DECLR3CALLBACKMEMBER(int, pfnCFGMQuerySIntDef,( PCFGMNODE pNode, const char *pszName, signed int *pi, signed int iDef));
3105 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtr,( PCFGMNODE pNode, const char *pszName, PRTGCPTR pGCPtr));
3106 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtrDef,( PCFGMNODE pNode, const char *pszName, PRTGCPTR pGCPtr, RTGCPTR GCPtrDef));
3107 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtrU,( PCFGMNODE pNode, const char *pszName, PRTGCUINTPTR pGCPtr));
3108 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtrUDef,( PCFGMNODE pNode, const char *pszName, PRTGCUINTPTR pGCPtr, RTGCUINTPTR GCPtrDef));
3109 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtrS,( PCFGMNODE pNode, const char *pszName, PRTGCINTPTR pGCPtr));
3110 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtrSDef,( PCFGMNODE pNode, const char *pszName, PRTGCINTPTR pGCPtr, RTGCINTPTR GCPtrDef));
3111 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryStringAlloc,( PCFGMNODE pNode, const char *pszName, char **ppszString));
3112 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryStringAllocDef,(PCFGMNODE pNode, const char *pszName, char **ppszString, const char *pszDef));
3113 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetParent,(PCFGMNODE pNode));
3114 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetChild,(PCFGMNODE pNode, const char *pszPath));
3115 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetChildF,(PCFGMNODE pNode, const char *pszPathFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3));
3116 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetChildFV,(PCFGMNODE pNode, const char *pszPathFormat, va_list Args) RT_IPRT_FORMAT_ATTR(3, 0));
3117 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetFirstChild,(PCFGMNODE pNode));
3118 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetNextChild,(PCFGMNODE pCur));
3119 DECLR3CALLBACKMEMBER(int, pfnCFGMGetName,(PCFGMNODE pCur, char *pszName, size_t cchName));
3120 DECLR3CALLBACKMEMBER(size_t, pfnCFGMGetNameLen,(PCFGMNODE pCur));
3121 DECLR3CALLBACKMEMBER(bool, pfnCFGMAreChildrenValid,(PCFGMNODE pNode, const char *pszzValid));
3122 DECLR3CALLBACKMEMBER(PCFGMLEAF, pfnCFGMGetFirstValue,(PCFGMNODE pCur));
3123 DECLR3CALLBACKMEMBER(PCFGMLEAF, pfnCFGMGetNextValue,(PCFGMLEAF pCur));
3124 DECLR3CALLBACKMEMBER(int, pfnCFGMGetValueName,(PCFGMLEAF pCur, char *pszName, size_t cchName));
3125 DECLR3CALLBACKMEMBER(size_t, pfnCFGMGetValueNameLen,(PCFGMLEAF pCur));
3126 DECLR3CALLBACKMEMBER(CFGMVALUETYPE, pfnCFGMGetValueType,(PCFGMLEAF pCur));
3127 DECLR3CALLBACKMEMBER(bool, pfnCFGMAreValuesValid,(PCFGMNODE pNode, const char *pszzValid));
3128 DECLR3CALLBACKMEMBER(int, pfnCFGMValidateConfig,(PCFGMNODE pNode, const char *pszNode,
3129 const char *pszValidValues, const char *pszValidNodes,
3130 const char *pszWho, uint32_t uInstance));
3131 /** @} */
3132
3133 /**
3134 * Read physical memory.
3135 *
3136 * @returns VINF_SUCCESS (for now).
3137 * @param pDevIns The device instance.
3138 * @param GCPhys Physical address start reading from.
3139 * @param pvBuf Where to put the read bits.
3140 * @param cbRead How many bytes to read.
3141 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
3142 * @thread Any thread, but the call may involve the emulation thread.
3143 */
3144 DECLR3CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags));
3145
3146 /**
3147 * Write to physical memory.
3148 *
3149 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
3150 * @param pDevIns The device instance.
3151 * @param GCPhys Physical address to write to.
3152 * @param pvBuf What to write.
3153 * @param cbWrite How many bytes to write.
3154 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
3155 * @thread Any thread, but the call may involve the emulation thread.
3156 */
3157 DECLR3CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags));
3158
3159 /**
3160 * Requests the mapping of a guest page into ring-3.
3161 *
3162 * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
3163 * release it.
3164 *
3165 * This API will assume your intention is to write to the page, and will
3166 * therefore replace shared and zero pages. If you do not intend to modify the
3167 * page, use the pfnPhysGCPhys2CCPtrReadOnly() API.
3168 *
3169 * @returns VBox status code.
3170 * @retval VINF_SUCCESS on success.
3171 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
3172 * backing or if the page has any active access handlers. The caller
3173 * must fall back on using PGMR3PhysWriteExternal.
3174 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
3175 *
3176 * @param pDevIns The device instance.
3177 * @param GCPhys The guest physical address of the page that
3178 * should be mapped.
3179 * @param fFlags Flags reserved for future use, MBZ.
3180 * @param ppv Where to store the address corresponding to
3181 * GCPhys.
3182 * @param pLock Where to store the lock information that
3183 * pfnPhysReleasePageMappingLock needs.
3184 *
3185 * @remark Avoid calling this API from within critical sections (other than the
3186 * PGM one) because of the deadlock risk when we have to delegating the
3187 * task to an EMT.
3188 * @thread Any.
3189 */
3190 DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtr,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv,
3191 PPGMPAGEMAPLOCK pLock));
3192
3193 /**
3194 * Requests the mapping of a guest page into ring-3, external threads.
3195 *
3196 * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
3197 * release it.
3198 *
3199 * @returns VBox status code.
3200 * @retval VINF_SUCCESS on success.
3201 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
3202 * backing or if the page as an active ALL access handler. The caller
3203 * must fall back on using PGMPhysRead.
3204 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
3205 *
3206 * @param pDevIns The device instance.
3207 * @param GCPhys The guest physical address of the page that
3208 * should be mapped.
3209 * @param fFlags Flags reserved for future use, MBZ.
3210 * @param ppv Where to store the address corresponding to
3211 * GCPhys.
3212 * @param pLock Where to store the lock information that
3213 * pfnPhysReleasePageMappingLock needs.
3214 *
3215 * @remark Avoid calling this API from within critical sections.
3216 * @thread Any.
3217 */
3218 DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags,
3219 void const **ppv, PPGMPAGEMAPLOCK pLock));
3220
3221 /**
3222 * Release the mapping of a guest page.
3223 *
3224 * This is the counter part of pfnPhysGCPhys2CCPtr and
3225 * pfnPhysGCPhys2CCPtrReadOnly.
3226 *
3227 * @param pDevIns The device instance.
3228 * @param pLock The lock structure initialized by the mapping
3229 * function.
3230 */
3231 DECLR3CALLBACKMEMBER(void, pfnPhysReleasePageMappingLock,(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock));
3232
3233 /**
3234 * Read guest physical memory by virtual address.
3235 *
3236 * @param pDevIns The device instance.
3237 * @param pvDst Where to put the read bits.
3238 * @param GCVirtSrc Guest virtual address to start reading from.
3239 * @param cb How many bytes to read.
3240 * @thread The emulation thread.
3241 */
3242 DECLR3CALLBACKMEMBER(int, pfnPhysReadGCVirt,(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb));
3243
3244 /**
3245 * Write to guest physical memory by virtual address.
3246 *
3247 * @param pDevIns The device instance.
3248 * @param GCVirtDst Guest virtual address to write to.
3249 * @param pvSrc What to write.
3250 * @param cb How many bytes to write.
3251 * @thread The emulation thread.
3252 */
3253 DECLR3CALLBACKMEMBER(int, pfnPhysWriteGCVirt,(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb));
3254
3255 /**
3256 * Convert a guest virtual address to a guest physical address.
3257 *
3258 * @returns VBox status code.
3259 * @param pDevIns The device instance.
3260 * @param GCPtr Guest virtual address.
3261 * @param pGCPhys Where to store the GC physical address
3262 * corresponding to GCPtr.
3263 * @thread The emulation thread.
3264 * @remark Careful with page boundaries.
3265 */
3266 DECLR3CALLBACKMEMBER(int, pfnPhysGCPtr2GCPhys, (PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys));
3267
3268 /**
3269 * Checks if a GC physical address is a normal page,
3270 * i.e. not ROM, MMIO or reserved.
3271 *
3272 * @returns true if normal.
3273 * @returns false if invalid, ROM, MMIO or reserved page.
3274 * @param pDevIns The device instance.
3275 * @param GCPhys The physical address to check.
3276 */
3277 DECLR3CALLBACKMEMBER(bool, pfnPhysIsGCPhysNormal,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys));
3278
3279 /**
3280 * Inflate or deflate a memory balloon
3281 *
3282 * @returns VBox status code.
3283 * @param pDevIns The device instance.
3284 * @param fInflate Inflate or deflate memory balloon
3285 * @param cPages Number of pages to free
3286 * @param paPhysPage Array of guest physical addresses
3287 */
3288 DECLR3CALLBACKMEMBER(int, pfnPhysChangeMemBalloon,(PPDMDEVINS pDevIns, bool fInflate, unsigned cPages, RTGCPHYS *paPhysPage));
3289
3290 /**
3291 * Allocate memory which is associated with current VM instance
3292 * and automatically freed on it's destruction.
3293 *
3294 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
3295 * @param pDevIns The device instance.
3296 * @param cb Number of bytes to allocate.
3297 */
3298 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAlloc,(PPDMDEVINS pDevIns, size_t cb));
3299
3300 /**
3301 * Allocate memory which is associated with current VM instance
3302 * and automatically freed on it's destruction. The memory is ZEROed.
3303 *
3304 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
3305 * @param pDevIns The device instance.
3306 * @param cb Number of bytes to allocate.
3307 */
3308 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAllocZ,(PPDMDEVINS pDevIns, size_t cb));
3309
3310 /**
3311 * Allocating string printf.
3312 *
3313 * @returns Pointer to the string.
3314 * @param pDevIns The device instance.
3315 * @param enmTag The statistics tag.
3316 * @param pszFormat The format string.
3317 * @param va Format arguments.
3318 */
3319 DECLR3CALLBACKMEMBER(char *, pfnMMHeapAPrintfV,(PPDMDEVINS pDevIns, MMTAG enmTag, const char *pszFormat, va_list va));
3320
3321 /**
3322 * Free memory allocated with pfnMMHeapAlloc() and pfnMMHeapAllocZ().
3323 *
3324 * @param pDevIns The device instance.
3325 * @param pv Pointer to the memory to free.
3326 */
3327 DECLR3CALLBACKMEMBER(void, pfnMMHeapFree,(PPDMDEVINS pDevIns, void *pv));
3328
3329 /**
3330 * Returns the physical RAM size of the VM.
3331 *
3332 * @returns RAM size in bytes.
3333 * @param pDevIns The device instance.
3334 */
3335 DECLR3CALLBACKMEMBER(uint64_t, pfnMMPhysGetRamSize,(PPDMDEVINS pDevIns));
3336
3337 /**
3338 * Returns the physical RAM size of the VM below the 4GB boundary.
3339 *
3340 * @returns RAM size in bytes.
3341 * @param pDevIns The device instance.
3342 */
3343 DECLR3CALLBACKMEMBER(uint32_t, pfnMMPhysGetRamSizeBelow4GB,(PPDMDEVINS pDevIns));
3344
3345 /**
3346 * Returns the physical RAM size of the VM above the 4GB boundary.
3347 *
3348 * @returns RAM size in bytes.
3349 * @param pDevIns The device instance.
3350 */
3351 DECLR3CALLBACKMEMBER(uint64_t, pfnMMPhysGetRamSizeAbove4GB,(PPDMDEVINS pDevIns));
3352
3353 /**
3354 * Gets the VM state.
3355 *
3356 * @returns VM state.
3357 * @param pDevIns The device instance.
3358 * @thread Any thread (just keep in mind that it's volatile info).
3359 */
3360 DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
3361
3362 /**
3363 * Checks if the VM was teleported and hasn't been fully resumed yet.
3364 *
3365 * @returns true / false.
3366 * @param pDevIns The device instance.
3367 * @thread Any thread.
3368 */
3369 DECLR3CALLBACKMEMBER(bool, pfnVMTeleportedAndNotFullyResumedYet,(PPDMDEVINS pDevIns));
3370
3371 /**
3372 * Set the VM error message
3373 *
3374 * @returns rc.
3375 * @param pDevIns The device instance.
3376 * @param rc VBox status code.
3377 * @param SRC_POS Use RT_SRC_POS.
3378 * @param pszFormat Error message format string.
3379 * @param va Error message arguments.
3380 */
3381 DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
3382 const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
3383
3384 /**
3385 * Set the VM runtime error message
3386 *
3387 * @returns VBox status code.
3388 * @param pDevIns The device instance.
3389 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3390 * @param pszErrorId Error ID string.
3391 * @param pszFormat Error message format string.
3392 * @param va Error message arguments.
3393 */
3394 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
3395 const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(4, 0));
3396
3397 /**
3398 * Special interface for implementing a HLT-like port on a device.
3399 *
3400 * This can be called directly from device code, provide the device is trusted
3401 * to access the VMM directly. Since we may not have an accurate register set
3402 * and the caller certainly shouldn't (device code does not access CPU
3403 * registers), this function will return when interrupts are pending regardless
3404 * of the actual EFLAGS.IF state.
3405 *
3406 * @returns VBox error status (never informational statuses).
3407 * @param pDevIns The device instance.
3408 * @param idCpu The id of the calling EMT.
3409 */
3410 DECLR3CALLBACKMEMBER(int, pfnVMWaitForDeviceReady,(PPDMDEVINS pDevIns, VMCPUID idCpu));
3411
3412 /**
3413 * Wakes up a CPU that has called PDMDEVHLPR3::pfnVMWaitForDeviceReady.
3414 *
3415 * @returns VBox error status (never informational statuses).
3416 * @param pDevIns The device instance.
3417 * @param idCpu The id of the calling EMT.
3418 */
3419 DECLR3CALLBACKMEMBER(int, pfnVMNotifyCpuDeviceReady,(PPDMDEVINS pDevIns, VMCPUID idCpu));
3420
3421 /**
3422 * Convenience wrapper for VMR3ReqCallU.
3423 *
3424 * This assumes (1) you're calling a function that returns an VBox status code
3425 * and that you do not wish to wait for it to complete.
3426 *
3427 * @returns VBox status code returned by VMR3ReqCallVU.
3428 *
3429 * @param pDevIns The device instance.
3430 * @param idDstCpu The destination CPU(s). Either a specific CPU ID or
3431 * one of the following special values:
3432 * VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
3433 * @param pfnFunction Pointer to the function to call.
3434 * @param cArgs Number of arguments following in the ellipsis.
3435 * @param Args Argument vector.
3436 *
3437 * @remarks See remarks on VMR3ReqCallVU.
3438 */
3439 DECLR3CALLBACKMEMBER(int, pfnVMReqCallNoWaitV,(PPDMDEVINS pDevIns, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, va_list Args));
3440
3441 /**
3442 * Convenience wrapper for VMR3ReqCallU.
3443 *
3444 * This assumes (1) you're calling a function that returns void, (2) that you
3445 * wish to wait for ever for it to return, and (3) that it's priority request
3446 * that can be safely be handled during async suspend and power off.
3447 *
3448 * @returns VBox status code of VMR3ReqCallVU.
3449 *
3450 * @param pDevIns The device instance.
3451 * @param idDstCpu The destination CPU(s). Either a specific CPU ID or
3452 * one of the following special values:
3453 * VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
3454 * @param pfnFunction Pointer to the function to call.
3455 * @param cArgs Number of arguments following in the ellipsis.
3456 * @param Args Argument vector.
3457 *
3458 * @remarks See remarks on VMR3ReqCallVU.
3459 */
3460 DECLR3CALLBACKMEMBER(int, pfnVMReqPriorityCallWaitV,(PPDMDEVINS pDevIns, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, va_list Args));
3461
3462 /**
3463 * Stops the VM and enters the debugger to look at the guest state.
3464 *
3465 * Use the PDMDeviceDBGFStop() inline function with the RT_SRC_POS macro instead of
3466 * invoking this function directly.
3467 *
3468 * @returns VBox status code which must be passed up to the VMM.
3469 * @param pDevIns The device instance.
3470 * @param pszFile Filename of the assertion location.
3471 * @param iLine The linenumber of the assertion location.
3472 * @param pszFunction Function of the assertion location.
3473 * @param pszFormat Message. (optional)
3474 * @param args Message parameters.
3475 */
3476 DECLR3CALLBACKMEMBER(int, pfnDBGFStopV,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction,
3477 const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(5, 0));
3478
3479 /**
3480 * Register a info handler with DBGF.
3481 *
3482 * @returns VBox status code.
3483 * @param pDevIns The device instance.
3484 * @param pszName The identifier of the info.
3485 * @param pszDesc The description of the info and any arguments
3486 * the handler may take.
3487 * @param pfnHandler The handler function to be called to display the
3488 * info.
3489 */
3490 DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler));
3491
3492 /**
3493 * Register a info handler with DBGF, argv style.
3494 *
3495 * @returns VBox status code.
3496 * @param pDevIns The device instance.
3497 * @param pszName The identifier of the info.
3498 * @param pszDesc The description of the info and any arguments
3499 * the handler may take.
3500 * @param pfnHandler The handler function to be called to display the
3501 * info.
3502 */
3503 DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegisterArgv,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVDEV pfnHandler));
3504
3505 /**
3506 * Registers a set of registers for a device.
3507 *
3508 * The @a pvUser argument of the getter and setter callbacks will be
3509 * @a pDevIns. The register names will be prefixed by the device name followed
3510 * immediately by the instance number.
3511 *
3512 * @returns VBox status code.
3513 * @param pDevIns The device instance.
3514 * @param paRegisters The register descriptors.
3515 *
3516 * @remarks The device critical section is NOT entered prior to working the
3517 * callbacks registered via this helper!
3518 */
3519 DECLR3CALLBACKMEMBER(int, pfnDBGFRegRegister,(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters));
3520
3521 /**
3522 * Gets the trace buffer handle.
3523 *
3524 * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
3525 * really inteded for direct usage, thus no inline wrapper function.
3526 *
3527 * @returns Trace buffer handle or NIL_RTTRACEBUF.
3528 * @param pDevIns The device instance.
3529 */
3530 DECLR3CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
3531
3532 /**
3533 * Report a bug check.
3534 *
3535 * @returns
3536 * @param pDevIns The device instance.
3537 * @param enmEvent The kind of BSOD event this is.
3538 * @param uBugCheck The bug check number.
3539 * @param uP1 The bug check parameter \#1.
3540 * @param uP2 The bug check parameter \#2.
3541 * @param uP3 The bug check parameter \#3.
3542 * @param uP4 The bug check parameter \#4.
3543 *
3544 * @thread EMT
3545 */
3546 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnDBGFReportBugCheck,(PPDMDEVINS pDevIns, DBGFEVENTTYPE enmEvent, uint64_t uBugCheck,
3547 uint64_t uP1, uint64_t uP2, uint64_t uP3, uint64_t uP4));
3548
3549 /**
3550 * Write core dump of the guest.
3551 *
3552 * @returns VBox status code.
3553 * @param pDevIns The device instance.
3554 * @param pszFilename The name of the file to which the guest core
3555 * dump should be written.
3556 * @param fReplaceFile Whether to replace the file or not.
3557 *
3558 * @remarks The VM may need to be suspended before calling this function in
3559 * order to truly stop all device threads and drivers. This function
3560 * only synchronizes EMTs.
3561 */
3562 DECLR3CALLBACKMEMBER(int, pfnDBGFCoreWrite,(PPDMDEVINS pDevIns, const char *pszFilename, bool fReplaceFile));
3563
3564 /**
3565 * Gets the logger info helper.
3566 * The returned info helper will unconditionally write all output to the log.
3567 *
3568 * @returns Pointer to the logger info helper.
3569 * @param pDevIns The device instance.
3570 */
3571 DECLR3CALLBACKMEMBER(PCDBGFINFOHLP, pfnDBGFInfoLogHlp,(PPDMDEVINS pDevIns));
3572
3573 /**
3574 * Queries a 64-bit register value.
3575 *
3576 * @retval VINF_SUCCESS
3577 * @retval VERR_INVALID_VM_HANDLE
3578 * @retval VERR_INVALID_CPU_ID
3579 * @retval VERR_DBGF_REGISTER_NOT_FOUND
3580 * @retval VERR_DBGF_UNSUPPORTED_CAST
3581 * @retval VINF_DBGF_TRUNCATED_REGISTER
3582 * @retval VINF_DBGF_ZERO_EXTENDED_REGISTER
3583 *
3584 * @param pDevIns The device instance.
3585 * @param idDefCpu The default target CPU ID, VMCPUID_ANY if not
3586 * applicable. Can be OR'ed with
3587 * DBGFREG_HYPER_VMCPUID.
3588 * @param pszReg The register that's being queried. Except for
3589 * CPU registers, this must be on the form
3590 * "set.reg[.sub]".
3591 * @param pu64 Where to store the register value.
3592 */
3593 DECLR3CALLBACKMEMBER(int, pfnDBGFRegNmQueryU64,(PPDMDEVINS pDevIns, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64));
3594
3595 /**
3596 * Format a set of registers.
3597 *
3598 * This is restricted to registers from one CPU, that specified by @a idCpu.
3599 *
3600 * @returns VBox status code.
3601 * @param pDevIns The device instance.
3602 * @param idCpu The CPU ID of any CPU registers that may be
3603 * printed, pass VMCPUID_ANY if not applicable.
3604 * @param pszBuf The output buffer.
3605 * @param cbBuf The size of the output buffer.
3606 * @param pszFormat The format string. Register names are given by
3607 * %VR{name}, they take no arguments.
3608 * @param va Other format arguments.
3609 */
3610 DECLR3CALLBACKMEMBER(int, pfnDBGFRegPrintfV,(PPDMDEVINS pDevIns, VMCPUID idCpu, char *pszBuf, size_t cbBuf,
3611 const char *pszFormat, va_list va));
3612
3613 /**
3614 * Registers a statistics sample.
3615 *
3616 * @param pDevIns Device instance of the DMA.
3617 * @param pvSample Pointer to the sample.
3618 * @param enmType Sample type. This indicates what pvSample is
3619 * pointing at.
3620 * @param pszName Sample name, unix path style. If this does not
3621 * start with a '/', the default prefix will be
3622 * prepended, otherwise it will be used as-is.
3623 * @param enmUnit Sample unit.
3624 * @param pszDesc Sample description.
3625 */
3626 DECLR3CALLBACKMEMBER(void, pfnSTAMRegister,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc));
3627
3628 /**
3629 * Same as pfnSTAMRegister except that the name is specified in a
3630 * RTStrPrintfV like fashion.
3631 *
3632 * @param pDevIns Device instance of the DMA.
3633 * @param pvSample Pointer to the sample.
3634 * @param enmType Sample type. This indicates what pvSample is
3635 * pointing at.
3636 * @param enmVisibility Visibility type specifying whether unused
3637 * statistics should be visible or not.
3638 * @param enmUnit Sample unit.
3639 * @param pszDesc Sample description.
3640 * @param pszName Sample name format string, unix path style. If
3641 * this does not start with a '/', the default
3642 * prefix will be prepended, otherwise it will be
3643 * used as-is.
3644 * @param args Arguments to the format string.
3645 */
3646 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType,
3647 STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc,
3648 const char *pszName, va_list args) RT_IPRT_FORMAT_ATTR(7, 0));
3649
3650 /**
3651 * Registers a PCI device with the default PCI bus.
3652 *
3653 * If a PDM device has more than one PCI device, they must be registered in the
3654 * order of PDMDEVINSR3::apPciDevs.
3655 *
3656 * @returns VBox status code.
3657 * @param pDevIns The device instance.
3658 * @param pPciDev The PCI device structure.
3659 * This must be kept in the instance data.
3660 * The PCI configuration must be initialized before registration.
3661 * @param fFlags 0, PDMPCIDEVREG_F_PCI_BRIDGE or
3662 * PDMPCIDEVREG_F_NOT_MANDATORY_NO.
3663 * @param uPciDevNo PDMPCIDEVREG_DEV_NO_FIRST_UNUSED,
3664 * PDMPCIDEVREG_DEV_NO_SAME_AS_PREV, or a specific
3665 * device number (0-31). This will be ignored if
3666 * the CFGM configuration contains a PCIDeviceNo
3667 * value.
3668 * @param uPciFunNo PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, or a specific
3669 * function number (0-7). This will be ignored if
3670 * the CFGM configuration contains a PCIFunctionNo
3671 * value.
3672 * @param pszName Device name, if NULL PDMDEVREG::szName is used.
3673 * The pointer is saved, so don't free or changed.
3674 * @note The PCI device configuration is now implicit from the apPciDevs
3675 * index, meaning that the zero'th entry is the primary one and
3676 * subsequent uses CFGM subkeys "PciDev1", "PciDev2" and so on.
3677 */
3678 DECLR3CALLBACKMEMBER(int, pfnPCIRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
3679 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName));
3680
3681 /**
3682 * Initialize MSI or MSI-X emulation support for the given PCI device.
3683 *
3684 * @see PDMPCIBUSREG::pfnRegisterMsiR3 for details.
3685 *
3686 * @returns VBox status code.
3687 * @param pDevIns The device instance.
3688 * @param pPciDev The PCI device. NULL is an alias for the first
3689 * one registered.
3690 * @param pMsiReg MSI emulation registration structure.
3691 */
3692 DECLR3CALLBACKMEMBER(int, pfnPCIRegisterMsi,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg));
3693
3694 /**
3695 * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
3696 *
3697 * @returns VBox status code.
3698 * @param pDevIns The device instance.
3699 * @param pPciDev The PCI device structure. If NULL the default
3700 * PCI device for this device instance is used.
3701 * @param iRegion The region number.
3702 * @param cbRegion Size of the region.
3703 * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
3704 * @param fFlags PDMPCIDEV_IORGN_F_XXX.
3705 * @param hHandle An I/O port, MMIO or MMIO2 handle according to
3706 * @a fFlags, UINT64_MAX if no handle is passed
3707 * (old style).
3708 * @param pfnMapUnmap Callback for doing the mapping, optional when a
3709 * handle is specified. The callback will be
3710 * invoked holding only the PDM lock. The device
3711 * lock will _not_ be taken (due to lock order).
3712 */
3713 DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
3714 RTGCPHYS cbRegion, PCIADDRESSSPACE enmType, uint32_t fFlags,
3715 uint64_t hHandle, PFNPCIIOREGIONMAP pfnMapUnmap));
3716
3717 /**
3718 * Register PCI configuration space read/write callbacks.
3719 *
3720 * @returns VBox status code.
3721 * @param pDevIns The device instance.
3722 * @param pPciDev The PCI device structure. If NULL the default
3723 * PCI device for this device instance is used.
3724 * @param pfnRead Pointer to the user defined PCI config read function.
3725 * to call default PCI config read function. Can be NULL.
3726 * @param pfnWrite Pointer to the user defined PCI config write function.
3727 * @remarks The callbacks will be invoked holding the PDM lock. The device lock
3728 * is NOT take because that is very likely be a lock order violation.
3729 * @thread EMT(0)
3730 * @note Only callable during VM creation.
3731 * @sa PDMDevHlpPCIConfigRead, PDMDevHlpPCIConfigWrite
3732 */
3733 DECLR3CALLBACKMEMBER(int, pfnPCIInterceptConfigAccesses,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
3734 PFNPCICONFIGREAD pfnRead, PFNPCICONFIGWRITE pfnWrite));
3735
3736 /**
3737 * Perform a PCI configuration space write.
3738 *
3739 * This is for devices that make use of PDMDevHlpPCIInterceptConfigAccesses().
3740 *
3741 * @returns Strict VBox status code (mainly DBGFSTOP).
3742 * @param pDevIns The device instance.
3743 * @param pPciDev The PCI device which config space is being read.
3744 * @param uAddress The config space address.
3745 * @param cb The size of the read: 1, 2 or 4 bytes.
3746 * @param u32Value The value to write.
3747 */
3748 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnPCIConfigWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
3749 uint32_t uAddress, unsigned cb, uint32_t u32Value));
3750
3751 /**
3752 * Perform a PCI configuration space read.
3753 *
3754 * This is for devices that make use of PDMDevHlpPCIInterceptConfigAccesses().
3755 *
3756 * @returns Strict VBox status code (mainly DBGFSTOP).
3757 * @param pDevIns The device instance.
3758 * @param pPciDev The PCI device which config space is being read.
3759 * @param uAddress The config space address.
3760 * @param cb The size of the read: 1, 2 or 4 bytes.
3761 * @param pu32Value Where to return the value.
3762 */
3763 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnPCIConfigRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
3764 uint32_t uAddress, unsigned cb, uint32_t *pu32Value));
3765
3766 /**
3767 * Bus master physical memory read.
3768 *
3769 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
3770 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
3771 * @param pDevIns The device instance.
3772 * @param pPciDev The PCI device structure. If NULL the default
3773 * PCI device for this device instance is used.
3774 * @param GCPhys Physical address start reading from.
3775 * @param pvBuf Where to put the read bits.
3776 * @param cbRead How many bytes to read.
3777 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
3778 * @thread Any thread, but the call may involve the emulation thread.
3779 */
3780 DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags));
3781
3782 /**
3783 * Bus master physical memory write.
3784 *
3785 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
3786 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
3787 * @param pDevIns The device instance.
3788 * @param pPciDev The PCI device structure. If NULL the default
3789 * PCI device for this device instance is used.
3790 * @param GCPhys Physical address to write to.
3791 * @param pvBuf What to write.
3792 * @param cbWrite How many bytes to write.
3793 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
3794 * @thread Any thread, but the call may involve the emulation thread.
3795 */
3796 DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags));
3797
3798 /**
3799 * Requests the mapping of a guest page into ring-3 in preparation for a bus master
3800 * physical memory write operation.
3801 *
3802 * Refer pfnPhysGCPhys2CCPtr() for further details.
3803 *
3804 * @returns VBox status code.
3805 * @param pDevIns The device instance.
3806 * @param pPciDev The PCI device structure. If NULL the default
3807 * PCI device for this device instance is used.
3808 * @param GCPhys The guest physical address of the page that should be
3809 * mapped.
3810 * @param fFlags Flags reserved for future use, MBZ.
3811 * @param ppv Where to store the address corresponding to GCPhys.
3812 * @param pLock Where to store the lock information that
3813 * pfnPhysReleasePageMappingLock needs.
3814 *
3815 * @remarks Avoid calling this API from within critical sections (other than the PGM
3816 * one) because of the deadlock risk when we have to delegating the task to
3817 * an EMT.
3818 * @thread Any.
3819 */
3820 DECLR3CALLBACKMEMBER(int, pfnPCIPhysGCPhys2CCPtr,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, uint32_t fFlags,
3821 void **ppv, PPGMPAGEMAPLOCK pLock));
3822
3823 /**
3824 * Requests the mapping of a guest page into ring-3, external threads, in prepartion
3825 * for a bus master physical memory read operation.
3826 *
3827 * Refer pfnPhysGCPhys2CCPtrReadOnly() for further details.
3828 *
3829 * @returns VBox status code.
3830 * @param pDevIns The device instance.
3831 * @param pPciDev The PCI device structure. If NULL the default
3832 * PCI device for this device instance is used.
3833 * @param GCPhys The guest physical address of the page that
3834 * should be mapped.
3835 * @param fFlags Flags reserved for future use, MBZ.
3836 * @param ppv Where to store the address corresponding to
3837 * GCPhys.
3838 * @param pLock Where to store the lock information that
3839 * pfnPhysReleasePageMappingLock needs.
3840 *
3841 * @remarks Avoid calling this API from within critical sections.
3842 * @thread Any.
3843 */
3844 DECLR3CALLBACKMEMBER(int, pfnPCIPhysGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
3845 uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock));
3846
3847 /**
3848 * Requests the mapping of multiple guest pages into ring-3 in prepartion for a bus
3849 * master physical memory write operation.
3850 *
3851 * When you're done with the pages, call pfnPhysBulkReleasePageMappingLocks()
3852 * ASAP to release them.
3853 *
3854 * Refer pfnPhysBulkGCPhys2CCPtr() for further details.
3855 *
3856 * @returns VBox status code.
3857 * @param pDevIns The device instance.
3858 * @param pPciDev The PCI device structure. If NULL the default
3859 * PCI device for this device instance is used.
3860 * @param cPages Number of pages to lock.
3861 * @param paGCPhysPages The guest physical address of the pages that
3862 * should be mapped (@a cPages entries).
3863 * @param fFlags Flags reserved for future use, MBZ.
3864 * @param papvPages Where to store the ring-3 mapping addresses
3865 * corresponding to @a paGCPhysPages.
3866 * @param paLocks Where to store the locking information that
3867 * pfnPhysBulkReleasePageMappingLock needs (@a cPages
3868 * in length).
3869 */
3870 DECLR3CALLBACKMEMBER(int, pfnPCIPhysBulkGCPhys2CCPtr,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t cPages,
3871 PCRTGCPHYS paGCPhysPages, uint32_t fFlags, void **papvPages,
3872 PPGMPAGEMAPLOCK paLocks));
3873
3874 /**
3875 * Requests the mapping of multiple guest pages into ring-3 in preparation for a bus
3876 * master physical memory read operation.
3877 *
3878 * When you're done with the pages, call pfnPhysBulkReleasePageMappingLocks()
3879 * ASAP to release them.
3880 *
3881 * Refer pfnPhysBulkGCPhys2CCPtrReadOnly() for further details.
3882 *
3883 * @returns VBox status code.
3884 * @param pDevIns The device instance.
3885 * @param pPciDev The PCI device structure. If NULL the default
3886 * PCI device for this device instance is used.
3887 * @param cPages Number of pages to lock.
3888 * @param paGCPhysPages The guest physical address of the pages that
3889 * should be mapped (@a cPages entries).
3890 * @param fFlags Flags reserved for future use, MBZ.
3891 * @param papvPages Where to store the ring-3 mapping addresses
3892 * corresponding to @a paGCPhysPages.
3893 * @param paLocks Where to store the lock information that
3894 * pfnPhysReleasePageMappingLock needs (@a cPages
3895 * in length).
3896 */
3897 DECLR3CALLBACKMEMBER(int, pfnPCIPhysBulkGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t cPages,
3898 PCRTGCPHYS paGCPhysPages, uint32_t fFlags,
3899 void const **papvPages, PPGMPAGEMAPLOCK paLocks));
3900
3901 /**
3902 * Sets the IRQ for the given PCI device.
3903 *
3904 * @param pDevIns The device instance.
3905 * @param pPciDev The PCI device structure. If NULL the default
3906 * PCI device for this device instance is used.
3907 * @param iIrq IRQ number to set.
3908 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3909 * @thread Any thread, but will involve the emulation thread.
3910 */
3911 DECLR3CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
3912
3913 /**
3914 * Sets the IRQ for the given PCI device, but doesn't wait for EMT to process
3915 * the request when not called from EMT.
3916 *
3917 * @param pDevIns The device instance.
3918 * @param pPciDev The PCI device structure. If NULL the default
3919 * PCI device for this device instance is used.
3920 * @param iIrq IRQ number to set.
3921 * @param iLevel IRQ level.
3922 * @thread Any thread, but will involve the emulation thread.
3923 */
3924 DECLR3CALLBACKMEMBER(void, pfnPCISetIrqNoWait,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
3925
3926 /**
3927 * Set ISA IRQ for a device.
3928 *
3929 * @param pDevIns The device instance.
3930 * @param iIrq IRQ number to set.
3931 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3932 * @thread Any thread, but will involve the emulation thread.
3933 */
3934 DECLR3CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3935
3936 /**
3937 * Set the ISA IRQ for a device, but don't wait for EMT to process
3938 * the request when not called from EMT.
3939 *
3940 * @param pDevIns The device instance.
3941 * @param iIrq IRQ number to set.
3942 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3943 * @thread Any thread, but will involve the emulation thread.
3944 */
3945 DECLR3CALLBACKMEMBER(void, pfnISASetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3946
3947 /**
3948 * Attaches a driver (chain) to the device.
3949 *
3950 * The first call for a LUN this will serve as a registration of the LUN. The pBaseInterface and
3951 * the pszDesc string will be registered with that LUN and kept around for PDMR3QueryDeviceLun().
3952 *
3953 * @returns VBox status code.
3954 * @param pDevIns The device instance.
3955 * @param iLun The logical unit to attach.
3956 * @param pBaseInterface Pointer to the base interface for that LUN. (device side / down)
3957 * @param ppBaseInterface Where to store the pointer to the base interface. (driver side / up)
3958 * @param pszDesc Pointer to a string describing the LUN. This string must remain valid
3959 * for the live of the device instance.
3960 */
3961 DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface,
3962 PPDMIBASE *ppBaseInterface, const char *pszDesc));
3963
3964 /**
3965 * Detaches an attached driver (chain) from the device again.
3966 *
3967 * @returns VBox status code.
3968 * @param pDevIns The device instance.
3969 * @param pDrvIns The driver instance to detach.
3970 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
3971 */
3972 DECLR3CALLBACKMEMBER(int, pfnDriverDetach,(PPDMDEVINS pDevIns, PPDMDRVINS pDrvIns, uint32_t fFlags));
3973
3974 /**
3975 * Reconfigures the driver chain for a LUN, detaching any driver currently
3976 * present there.
3977 *
3978 * Caller will have attach it, of course.
3979 *
3980 * @returns VBox status code.
3981 * @param pDevIns The device instance.
3982 * @param iLun The logical unit to reconfigure.
3983 * @param cDepth The depth of the driver chain. Determins the
3984 * size of @a papszDrivers and @a papConfigs.
3985 * @param papszDrivers The names of the drivers to configure in the
3986 * chain, first entry is the one immediately
3987 * below the device/LUN
3988 * @param papConfigs The configurations for each of the drivers
3989 * in @a papszDrivers array. NULL entries
3990 * corresponds to empty 'Config' nodes. This
3991 * function will take ownership of non-NULL
3992 * CFGM sub-trees and set the array member to
3993 * NULL, so the caller can do cleanups on
3994 * failure. This parameter is optional.
3995 * @param fFlags Reserved, MBZ.
3996 */
3997 DECLR3CALLBACKMEMBER(int, pfnDriverReconfigure,(PPDMDEVINS pDevIns, uint32_t iLun, uint32_t cDepth,
3998 const char * const *papszDrivers, PCFGMNODE *papConfigs, uint32_t fFlags));
3999
4000 /** @name Exported PDM Queue Functions
4001 * @{ */
4002 /**
4003 * Create a queue.
4004 *
4005 * @returns VBox status code.
4006 * @param pDevIns The device instance.
4007 * @param cbItem The size of a queue item.
4008 * @param cItems The number of items in the queue.
4009 * @param cMilliesInterval The number of milliseconds between polling the queue.
4010 * If 0 then the emulation thread will be notified whenever an item arrives.
4011 * @param pfnCallback The consumer function.
4012 * @param fRZEnabled Set if the queue should work in RC and R0.
4013 * @param pszName The queue base name. The instance number will be
4014 * appended automatically.
4015 * @param phQueue Where to store the queue handle on success.
4016 * @thread EMT(0)
4017 * @remarks The device critical section will NOT be entered before calling the
4018 * callback. No locks will be held, but for now it's safe to assume
4019 * that only one EMT will do queue callbacks at any one time.
4020 */
4021 DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
4022 PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName,
4023 PDMQUEUEHANDLE *phQueue));
4024
4025 DECLR3CALLBACKMEMBER(PPDMQUEUEITEMCORE, pfnQueueAlloc,(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue));
4026 DECLR3CALLBACKMEMBER(int, pfnQueueInsert,(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue, PPDMQUEUEITEMCORE pItem));
4027 DECLR3CALLBACKMEMBER(bool, pfnQueueFlushIfNecessary,(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue));
4028 /** @} */
4029
4030 /** @name PDM Task
4031 * @{ */
4032 /**
4033 * Create an asynchronous ring-3 task.
4034 *
4035 * @returns VBox status code.
4036 * @param pDevIns The device instance.
4037 * @param fFlags PDMTASK_F_XXX
4038 * @param pszName The function name or similar. Used for statistics,
4039 * so no slashes.
4040 * @param pfnCallback The task function.
4041 * @param pvUser User argument for the task function.
4042 * @param phTask Where to return the task handle.
4043 * @thread EMT(0)
4044 */
4045 DECLR3CALLBACKMEMBER(int, pfnTaskCreate,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszName,
4046 PFNPDMTASKDEV pfnCallback, void *pvUser, PDMTASKHANDLE *phTask));
4047 /**
4048 * Triggers the running the given task.
4049 *
4050 * @returns VBox status code.
4051 * @retval VINF_ALREADY_POSTED is the task is already pending.
4052 * @param pDevIns The device instance.
4053 * @param hTask The task to trigger.
4054 * @thread Any thread.
4055 */
4056 DECLR3CALLBACKMEMBER(int, pfnTaskTrigger,(PPDMDEVINS pDevIns, PDMTASKHANDLE hTask));
4057 /** @} */
4058
4059 /** @name SUP Event Semaphore Wrappers (single release / auto reset)
4060 * These semaphores can be signalled from ring-0.
4061 * @{ */
4062 /** @sa SUPSemEventCreate */
4063 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventCreate,(PPDMDEVINS pDevIns, PSUPSEMEVENT phEvent));
4064 /** @sa SUPSemEventClose */
4065 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventClose,(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent));
4066 /** @sa SUPSemEventSignal */
4067 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventSignal,(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent));
4068 /** @sa SUPSemEventWaitNoResume */
4069 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventWaitNoResume,(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint32_t cMillies));
4070 /** @sa SUPSemEventWaitNsAbsIntr */
4071 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventWaitNsAbsIntr,(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t uNsTimeout));
4072 /** @sa SUPSemEventWaitNsRelIntr */
4073 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventWaitNsRelIntr,(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t cNsTimeout));
4074 /** @sa SUPSemEventGetResolution */
4075 DECLR3CALLBACKMEMBER(uint32_t, pfnSUPSemEventGetResolution,(PPDMDEVINS pDevIns));
4076 /** @} */
4077
4078 /** @name SUP Multi Event Semaphore Wrappers (multiple release / manual reset)
4079 * These semaphores can be signalled from ring-0.
4080 * @{ */
4081 /** @sa SUPSemEventMultiCreate */
4082 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventMultiCreate,(PPDMDEVINS pDevIns, PSUPSEMEVENTMULTI phEventMulti));
4083 /** @sa SUPSemEventMultiClose */
4084 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventMultiClose,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti));
4085 /** @sa SUPSemEventMultiSignal */
4086 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventMultiSignal,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti));
4087 /** @sa SUPSemEventMultiReset */
4088 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventMultiReset,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti));
4089 /** @sa SUPSemEventMultiWaitNoResume */
4090 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventMultiWaitNoResume,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies));
4091 /** @sa SUPSemEventMultiWaitNsAbsIntr */
4092 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventMultiWaitNsAbsIntr,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout));
4093 /** @sa SUPSemEventMultiWaitNsRelIntr */
4094 DECLR3CALLBACKMEMBER(int, pfnSUPSemEventMultiWaitNsRelIntr,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout));
4095 /** @sa SUPSemEventMultiGetResolution */
4096 DECLR3CALLBACKMEMBER(uint32_t, pfnSUPSemEventMultiGetResolution,(PPDMDEVINS pDevIns));
4097 /** @} */
4098
4099 /**
4100 * Initializes a PDM critical section.
4101 *
4102 * The PDM critical sections are derived from the IPRT critical sections, but
4103 * works in RC and R0 as well.
4104 *
4105 * @returns VBox status code.
4106 * @param pDevIns The device instance.
4107 * @param pCritSect Pointer to the critical section.
4108 * @param SRC_POS Use RT_SRC_POS.
4109 * @param pszNameFmt Format string for naming the critical section.
4110 * For statistics and lock validation.
4111 * @param va Arguments for the format string.
4112 */
4113 DECLR3CALLBACKMEMBER(int, pfnCritSectInit,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
4114 const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
4115
4116 /**
4117 * Gets the NOP critical section.
4118 *
4119 * @returns The ring-3 address of the NOP critical section.
4120 * @param pDevIns The device instance.
4121 */
4122 DECLR3CALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
4123
4124 /**
4125 * Changes the device level critical section from the automatically created
4126 * default to one desired by the device constructor.
4127 *
4128 * For ring-0 and raw-mode capable devices, the call must be repeated in each of
4129 * the additional contexts.
4130 *
4131 * @returns VBox status code.
4132 * @param pDevIns The device instance.
4133 * @param pCritSect The critical section to use. NULL is not
4134 * valid, instead use the NOP critical
4135 * section.
4136 */
4137 DECLR3CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
4138
4139 /** @name Exported PDM Critical Section Functions
4140 * @{ */
4141 DECLR3CALLBACKMEMBER(bool, pfnCritSectYield,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
4142 DECLR3CALLBACKMEMBER(int, pfnCritSectEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy));
4143 DECLR3CALLBACKMEMBER(int, pfnCritSectEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
4144 DECLR3CALLBACKMEMBER(int, pfnCritSectTryEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
4145 DECLR3CALLBACKMEMBER(int, pfnCritSectTryEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
4146 DECLR3CALLBACKMEMBER(int, pfnCritSectLeave,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
4147 DECLR3CALLBACKMEMBER(bool, pfnCritSectIsOwner,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
4148 DECLR3CALLBACKMEMBER(bool, pfnCritSectIsInitialized,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
4149 DECLR3CALLBACKMEMBER(bool, pfnCritSectHasWaiters,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
4150 DECLR3CALLBACKMEMBER(uint32_t, pfnCritSectGetRecursion,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
4151 DECLR3CALLBACKMEMBER(int, pfnCritSectScheduleExitEvent,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, SUPSEMEVENT hEventToSignal));
4152 DECLR3CALLBACKMEMBER(int, pfnCritSectDelete,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
4153 /** @} */
4154
4155 /** @name Exported PDM Read/Write Critical Section Functions
4156 * @{ */
4157 DECLR3CALLBACKMEMBER(int, pfnCritSectRwInit,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
4158 const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
4159 DECLR3CALLBACKMEMBER(int, pfnCritSectRwDelete,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
4160
4161 DECLR3CALLBACKMEMBER(int, pfnCritSectRwEnterShared,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy));
4162 DECLR3CALLBACKMEMBER(int, pfnCritSectRwEnterSharedDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
4163 DECLR3CALLBACKMEMBER(int, pfnCritSectRwTryEnterShared,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
4164 DECLR3CALLBACKMEMBER(int, pfnCritSectRwTryEnterSharedDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
4165 DECLR3CALLBACKMEMBER(int, pfnCritSectRwLeaveShared,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
4166
4167 DECLR3CALLBACKMEMBER(int, pfnCritSectRwEnterExcl,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy));
4168 DECLR3CALLBACKMEMBER(int, pfnCritSectRwEnterExclDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
4169 DECLR3CALLBACKMEMBER(int, pfnCritSectRwTryEnterExcl,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
4170 DECLR3CALLBACKMEMBER(int, pfnCritSectRwTryEnterExclDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
4171 DECLR3CALLBACKMEMBER(int, pfnCritSectRwLeaveExcl,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
4172
4173 DECLR3CALLBACKMEMBER(bool, pfnCritSectRwIsWriteOwner,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
4174 DECLR3CALLBACKMEMBER(bool, pfnCritSectRwIsReadOwner,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, bool fWannaHear));
4175 DECLR3CALLBACKMEMBER(uint32_t, pfnCritSectRwGetWriteRecursion,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
4176 DECLR3CALLBACKMEMBER(uint32_t, pfnCritSectRwGetWriterReadRecursion,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
4177 DECLR3CALLBACKMEMBER(uint32_t, pfnCritSectRwGetReadCount,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
4178 DECLR3CALLBACKMEMBER(bool, pfnCritSectRwIsInitialized,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
4179 /** @} */
4180
4181 /**
4182 * Creates a PDM thread.
4183 *
4184 * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
4185 * resuming, and destroying the thread as the VM state changes.
4186 *
4187 * @returns VBox status code.
4188 * @param pDevIns The device instance.
4189 * @param ppThread Where to store the thread 'handle'.
4190 * @param pvUser The user argument to the thread function.
4191 * @param pfnThread The thread function.
4192 * @param pfnWakeup The wakup callback. This is called on the EMT
4193 * thread when a state change is pending.
4194 * @param cbStack See RTThreadCreate.
4195 * @param enmType See RTThreadCreate.
4196 * @param pszName See RTThreadCreate.
4197 * @remarks The device critical section will NOT be entered prior to invoking
4198 * the function pointers.
4199 */
4200 DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
4201 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
4202
4203 /** @name Exported PDM Thread Functions
4204 * @{ */
4205 DECLR3CALLBACKMEMBER(int, pfnThreadDestroy,(PPDMTHREAD pThread, int *pRcThread));
4206 DECLR3CALLBACKMEMBER(int, pfnThreadIAmSuspending,(PPDMTHREAD pThread));
4207 DECLR3CALLBACKMEMBER(int, pfnThreadIAmRunning,(PPDMTHREAD pThread));
4208 DECLR3CALLBACKMEMBER(int, pfnThreadSleep,(PPDMTHREAD pThread, RTMSINTERVAL cMillies));
4209 DECLR3CALLBACKMEMBER(int, pfnThreadSuspend,(PPDMTHREAD pThread));
4210 DECLR3CALLBACKMEMBER(int, pfnThreadResume,(PPDMTHREAD pThread));
4211 /** @} */
4212
4213 /**
4214 * Set up asynchronous handling of a suspend, reset or power off notification.
4215 *
4216 * This shall only be called when getting the notification. It must be called
4217 * for each one.
4218 *
4219 * @returns VBox status code.
4220 * @param pDevIns The device instance.
4221 * @param pfnAsyncNotify The callback.
4222 * @thread EMT(0)
4223 * @remarks The caller will enter the device critical section prior to invoking
4224 * the callback.
4225 */
4226 DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify));
4227
4228 /**
4229 * Notify EMT(0) that the device has completed the asynchronous notification
4230 * handling.
4231 *
4232 * This can be called at any time, spurious calls will simply be ignored.
4233 *
4234 * @param pDevIns The device instance.
4235 * @thread Any
4236 */
4237 DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMDEVINS pDevIns));
4238
4239 /**
4240 * Register the RTC device.
4241 *
4242 * @returns VBox status code.
4243 * @param pDevIns The device instance.
4244 * @param pRtcReg Pointer to a RTC registration structure.
4245 * @param ppRtcHlp Where to store the pointer to the helper
4246 * functions.
4247 */
4248 DECLR3CALLBACKMEMBER(int, pfnRTCRegister,(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp));
4249
4250 /**
4251 * Register a PCI Bus.
4252 *
4253 * @returns VBox status code, but the positive values 0..31 are used to indicate
4254 * bus number rather than informational status codes.
4255 * @param pDevIns The device instance.
4256 * @param pPciBusReg Pointer to PCI bus registration structure.
4257 * @param ppPciHlp Where to store the pointer to the PCI Bus
4258 * helpers.
4259 * @param piBus Where to return the PDM bus number. Optional.
4260 */
4261 DECLR3CALLBACKMEMBER(int, pfnPCIBusRegister,(PPDMDEVINS pDevIns, PPDMPCIBUSREGR3 pPciBusReg,
4262 PCPDMPCIHLPR3 *ppPciHlp, uint32_t *piBus));
4263
4264 /**
4265 * Register the IOMMU device.
4266 *
4267 * @returns VBox status code.
4268 * @param pDevIns The device instance.
4269 * @param pIommuReg Pointer to a IOMMU registration structure.
4270 * @param ppIommuHlp Where to store the pointer to the ring-3 IOMMU
4271 * helpers.
4272 * @param pidxIommu Where to return the IOMMU index. Optional.
4273 */
4274 DECLR3CALLBACKMEMBER(int, pfnIommuRegister,(PPDMDEVINS pDevIns, PPDMIOMMUREGR3 pIommuReg, PCPDMIOMMUHLPR3 *ppIommuHlp,
4275 uint32_t *pidxIommu));
4276
4277 /**
4278 * Register the PIC device.
4279 *
4280 * @returns VBox status code.
4281 * @param pDevIns The device instance.
4282 * @param pPicReg Pointer to a PIC registration structure.
4283 * @param ppPicHlp Where to store the pointer to the ring-3 PIC
4284 * helpers.
4285 * @sa PDMDevHlpPICSetUpContext
4286 */
4287 DECLR3CALLBACKMEMBER(int, pfnPICRegister,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp));
4288
4289 /**
4290 * Register the APIC device.
4291 *
4292 * @returns VBox status code.
4293 * @param pDevIns The device instance.
4294 */
4295 DECLR3CALLBACKMEMBER(int, pfnApicRegister,(PPDMDEVINS pDevIns));
4296
4297 /**
4298 * Register the I/O APIC device.
4299 *
4300 * @returns VBox status code.
4301 * @param pDevIns The device instance.
4302 * @param pIoApicReg Pointer to a I/O APIC registration structure.
4303 * @param ppIoApicHlp Where to store the pointer to the IOAPIC
4304 * helpers.
4305 */
4306 DECLR3CALLBACKMEMBER(int, pfnIoApicRegister,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp));
4307
4308 /**
4309 * Register the HPET device.
4310 *
4311 * @returns VBox status code.
4312 * @param pDevIns The device instance.
4313 * @param pHpetReg Pointer to a HPET registration structure.
4314 * @param ppHpetHlpR3 Where to store the pointer to the HPET
4315 * helpers.
4316 */
4317 DECLR3CALLBACKMEMBER(int, pfnHpetRegister,(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3));
4318
4319 /**
4320 * Register a raw PCI device.
4321 *
4322 * @returns VBox status code.
4323 * @param pDevIns The device instance.
4324 * @param pPciRawReg Pointer to a raw PCI registration structure.
4325 * @param ppPciRawHlpR3 Where to store the pointer to the raw PCI
4326 * device helpers.
4327 */
4328 DECLR3CALLBACKMEMBER(int, pfnPciRawRegister,(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3));
4329
4330 /**
4331 * Register the DMA device.
4332 *
4333 * @returns VBox status code.
4334 * @param pDevIns The device instance.
4335 * @param pDmacReg Pointer to a DMAC registration structure.
4336 * @param ppDmacHlp Where to store the pointer to the DMA helpers.
4337 */
4338 DECLR3CALLBACKMEMBER(int, pfnDMACRegister,(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp));
4339
4340 /**
4341 * Register transfer function for DMA channel.
4342 *
4343 * @returns VBox status code.
4344 * @param pDevIns The device instance.
4345 * @param uChannel Channel number.
4346 * @param pfnTransferHandler Device specific transfer callback function.
4347 * @param pvUser User pointer to pass to the callback.
4348 * @thread EMT
4349 */
4350 DECLR3CALLBACKMEMBER(int, pfnDMARegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
4351
4352 /**
4353 * Read memory.
4354 *
4355 * @returns VBox status code.
4356 * @param pDevIns The device instance.
4357 * @param uChannel Channel number.
4358 * @param pvBuffer Pointer to target buffer.
4359 * @param off DMA position.
4360 * @param cbBlock Block size.
4361 * @param pcbRead Where to store the number of bytes which was
4362 * read. optional.
4363 * @thread EMT
4364 */
4365 DECLR3CALLBACKMEMBER(int, pfnDMAReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead));
4366
4367 /**
4368 * Write memory.
4369 *
4370 * @returns VBox status code.
4371 * @param pDevIns The device instance.
4372 * @param uChannel Channel number.
4373 * @param pvBuffer Memory to write.
4374 * @param off DMA position.
4375 * @param cbBlock Block size.
4376 * @param pcbWritten Where to store the number of bytes which was
4377 * written. optional.
4378 * @thread EMT
4379 */
4380 DECLR3CALLBACKMEMBER(int, pfnDMAWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten));
4381
4382 /**
4383 * Set the DREQ line.
4384 *
4385 * @returns VBox status code.
4386 * @param pDevIns Device instance.
4387 * @param uChannel Channel number.
4388 * @param uLevel Level of the line.
4389 * @thread EMT
4390 */
4391 DECLR3CALLBACKMEMBER(int, pfnDMASetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
4392
4393 /**
4394 * Get channel mode.
4395 *
4396 * @returns Channel mode. See specs.
4397 * @param pDevIns The device instance.
4398 * @param uChannel Channel number.
4399 * @thread EMT
4400 */
4401 DECLR3CALLBACKMEMBER(uint8_t, pfnDMAGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
4402
4403 /**
4404 * Schedule DMA execution.
4405 *
4406 * @param pDevIns The device instance.
4407 * @thread Any thread.
4408 */
4409 DECLR3CALLBACKMEMBER(void, pfnDMASchedule,(PPDMDEVINS pDevIns));
4410
4411 /**
4412 * Write CMOS value and update the checksum(s).
4413 *
4414 * @returns VBox status code.
4415 * @param pDevIns The device instance.
4416 * @param iReg The CMOS register index.
4417 * @param u8Value The CMOS register value.
4418 * @thread EMT
4419 */
4420 DECLR3CALLBACKMEMBER(int, pfnCMOSWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
4421
4422 /**
4423 * Read CMOS value.
4424 *
4425 * @returns VBox status code.
4426 * @param pDevIns The device instance.
4427 * @param iReg The CMOS register index.
4428 * @param pu8Value Where to store the CMOS register value.
4429 * @thread EMT
4430 */
4431 DECLR3CALLBACKMEMBER(int, pfnCMOSRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
4432
4433 /**
4434 * Assert that the current thread is the emulation thread.
4435 *
4436 * @returns True if correct.
4437 * @returns False if wrong.
4438 * @param pDevIns The device instance.
4439 * @param pszFile Filename of the assertion location.
4440 * @param iLine The linenumber of the assertion location.
4441 * @param pszFunction Function of the assertion location.
4442 */
4443 DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
4444
4445 /**
4446 * Assert that the current thread is NOT the emulation thread.
4447 *
4448 * @returns True if correct.
4449 * @returns False if wrong.
4450 * @param pDevIns The device instance.
4451 * @param pszFile Filename of the assertion location.
4452 * @param iLine The linenumber of the assertion location.
4453 * @param pszFunction Function of the assertion location.
4454 */
4455 DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
4456
4457 /**
4458 * Resolves the symbol for a raw-mode context interface.
4459 *
4460 * @returns VBox status code.
4461 * @param pDevIns The device instance.
4462 * @param pvInterface The interface structure.
4463 * @param cbInterface The size of the interface structure.
4464 * @param pszSymPrefix What to prefix the symbols in the list with
4465 * before resolving them. This must start with
4466 * 'dev' and contain the driver name.
4467 * @param pszSymList List of symbols corresponding to the interface.
4468 * There is generally a there is generally a define
4469 * holding this list associated with the interface
4470 * definition (INTERFACE_SYM_LIST). For more
4471 * details see PDMR3LdrGetInterfaceSymbols.
4472 * @thread EMT
4473 */
4474 DECLR3CALLBACKMEMBER(int, pfnLdrGetRCInterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
4475 const char *pszSymPrefix, const char *pszSymList));
4476
4477 /**
4478 * Resolves the symbol for a ring-0 context interface.
4479 *
4480 * @returns VBox status code.
4481 * @param pDevIns The device instance.
4482 * @param pvInterface The interface structure.
4483 * @param cbInterface The size of the interface structure.
4484 * @param pszSymPrefix What to prefix the symbols in the list with
4485 * before resolving them. This must start with
4486 * 'dev' and contain the driver name.
4487 * @param pszSymList List of symbols corresponding to the interface.
4488 * There is generally a there is generally a define
4489 * holding this list associated with the interface
4490 * definition (INTERFACE_SYM_LIST). For more
4491 * details see PDMR3LdrGetInterfaceSymbols.
4492 * @thread EMT
4493 */
4494 DECLR3CALLBACKMEMBER(int, pfnLdrGetR0InterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
4495 const char *pszSymPrefix, const char *pszSymList));
4496
4497 /**
4498 * Calls the PDMDEVREGR0::pfnRequest callback (in ring-0 context).
4499 *
4500 * @returns VBox status code.
4501 * @retval VERR_INVALID_FUNCTION if the callback member is NULL.
4502 * @retval VERR_ACCESS_DENIED if the device isn't ring-0 capable.
4503 *
4504 * @param pDevIns The device instance.
4505 * @param uOperation The operation to perform.
4506 * @param u64Arg 64-bit integer argument.
4507 * @thread EMT
4508 */
4509 DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg));
4510
4511 /**
4512 * Gets the reason for the most recent VM suspend.
4513 *
4514 * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no
4515 * suspend has been made or if the pDevIns is invalid.
4516 * @param pDevIns The device instance.
4517 */
4518 DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMDEVINS pDevIns));
4519
4520 /**
4521 * Gets the reason for the most recent VM resume.
4522 *
4523 * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no
4524 * resume has been made or if the pDevIns is invalid.
4525 * @param pDevIns The device instance.
4526 */
4527 DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMDEVINS pDevIns));
4528
4529 /**
4530 * Requests the mapping of multiple guest page into ring-3.
4531 *
4532 * When you're done with the pages, call pfnPhysBulkReleasePageMappingLocks()
4533 * ASAP to release them.
4534 *
4535 * This API will assume your intention is to write to the pages, and will
4536 * therefore replace shared and zero pages. If you do not intend to modify the
4537 * pages, use the pfnPhysBulkGCPhys2CCPtrReadOnly() API.
4538 *
4539 * @returns VBox status code.
4540 * @retval VINF_SUCCESS on success.
4541 * @retval VERR_PGM_PHYS_PAGE_RESERVED if any of the pages has no physical
4542 * backing or if any of the pages the page has any active access
4543 * handlers. The caller must fall back on using PGMR3PhysWriteExternal.
4544 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if @a paGCPhysPages contains
4545 * an invalid physical address.
4546 *
4547 * @param pDevIns The device instance.
4548 * @param cPages Number of pages to lock.
4549 * @param paGCPhysPages The guest physical address of the pages that
4550 * should be mapped (@a cPages entries).
4551 * @param fFlags Flags reserved for future use, MBZ.
4552 * @param papvPages Where to store the ring-3 mapping addresses
4553 * corresponding to @a paGCPhysPages.
4554 * @param paLocks Where to store the locking information that
4555 * pfnPhysBulkReleasePageMappingLock needs (@a cPages
4556 * in length).
4557 *
4558 * @remark Avoid calling this API from within critical sections (other than the
4559 * PGM one) because of the deadlock risk when we have to delegating the
4560 * task to an EMT.
4561 * @thread Any.
4562 * @since 6.0.6
4563 */
4564 DECLR3CALLBACKMEMBER(int, pfnPhysBulkGCPhys2CCPtr,(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
4565 uint32_t fFlags, void **papvPages, PPGMPAGEMAPLOCK paLocks));
4566
4567 /**
4568 * Requests the mapping of multiple guest page into ring-3, for reading only.
4569 *
4570 * When you're done with the pages, call pfnPhysBulkReleasePageMappingLocks()
4571 * ASAP to release them.
4572 *
4573 * @returns VBox status code.
4574 * @retval VINF_SUCCESS on success.
4575 * @retval VERR_PGM_PHYS_PAGE_RESERVED if any of the pages has no physical
4576 * backing or if any of the pages the page has an active ALL access
4577 * handler. The caller must fall back on using PGMR3PhysWriteExternal.
4578 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if @a paGCPhysPages contains
4579 * an invalid physical address.
4580 *
4581 * @param pDevIns The device instance.
4582 * @param cPages Number of pages to lock.
4583 * @param paGCPhysPages The guest physical address of the pages that
4584 * should be mapped (@a cPages entries).
4585 * @param fFlags Flags reserved for future use, MBZ.
4586 * @param papvPages Where to store the ring-3 mapping addresses
4587 * corresponding to @a paGCPhysPages.
4588 * @param paLocks Where to store the lock information that
4589 * pfnPhysReleasePageMappingLock needs (@a cPages
4590 * in length).
4591 *
4592 * @remark Avoid calling this API from within critical sections.
4593 * @thread Any.
4594 * @since 6.0.6
4595 */
4596 DECLR3CALLBACKMEMBER(int, pfnPhysBulkGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
4597 uint32_t fFlags, void const **papvPages, PPGMPAGEMAPLOCK paLocks));
4598
4599 /**
4600 * Release the mappings of multiple guest pages.
4601 *
4602 * This is the counter part of pfnPhysBulkGCPhys2CCPtr and
4603 * pfnPhysBulkGCPhys2CCPtrReadOnly.
4604 *
4605 * @param pDevIns The device instance.
4606 * @param cPages Number of pages to unlock.
4607 * @param paLocks The lock structures initialized by the mapping
4608 * function (@a cPages in length).
4609 * @thread Any.
4610 * @since 6.0.6
4611 */
4612 DECLR3CALLBACKMEMBER(void, pfnPhysBulkReleasePageMappingLocks,(PPDMDEVINS pDevIns, uint32_t cPages, PPGMPAGEMAPLOCK paLocks));
4613
4614 /**
4615 * Returns the architecture used for the guest.
4616 *
4617 * @returns CPU architecture enum.
4618 * @param pDevIns The device instance.
4619 */
4620 DECLR3CALLBACKMEMBER(CPUMARCH, pfnCpuGetGuestArch,(PPDMDEVINS pDevIns));
4621
4622 /**
4623 * Returns the micro architecture used for the guest.
4624 *
4625 * @returns CPU micro architecture enum.
4626 * @param pDevIns The device instance.
4627 */
4628 DECLR3CALLBACKMEMBER(CPUMMICROARCH, pfnCpuGetGuestMicroarch,(PPDMDEVINS pDevIns));
4629
4630 /**
4631 * Get the number of physical and linear address bits supported by the guest.
4632 *
4633 * @param pDevIns The device instance.
4634 * @param pcPhysAddrWidth Where to store the number of physical address bits
4635 * supported by the guest.
4636 * @param pcLinearAddrWidth Where to store the number of linear address bits
4637 * supported by the guest.
4638 */
4639 DECLR3CALLBACKMEMBER(void, pfnCpuGetGuestAddrWidths,(PPDMDEVINS pDevIns, uint8_t *pcPhysAddrWidth,
4640 uint8_t *pcLinearAddrWidth));
4641
4642 /**
4643 * Gets the scalable bus frequency.
4644 *
4645 * The bus frequency is used as a base in several MSRs that gives the CPU and
4646 * other frequency ratios.
4647 *
4648 * @returns Scalable bus frequency in Hz. Will not return CPUM_SBUSFREQ_UNKNOWN.
4649 * @param pDevIns The device instance.
4650 */
4651 DECLR3CALLBACKMEMBER(uint64_t, pfnCpuGetGuestScalableBusFrequency,(PPDMDEVINS pDevIns));
4652
4653 /** Space reserved for future members.
4654 * @{ */
4655 /**
4656 * Deregister zero or more samples given their name prefix.
4657 *
4658 * @returns VBox status code.
4659 * @param pDevIns The device instance.
4660 * @param pszPrefix The name prefix of the samples to remove. If this does
4661 * not start with a '/', the default prefix will be
4662 * prepended, otherwise it will be used as-is.
4663 */
4664 DECLR3CALLBACKMEMBER(int, pfnSTAMDeregisterByPrefix,(PPDMDEVINS pDevIns, const char *pszPrefix));
4665 DECLR3CALLBACKMEMBER(void, pfnReserved2,(void));
4666 DECLR3CALLBACKMEMBER(void, pfnReserved3,(void));
4667 DECLR3CALLBACKMEMBER(void, pfnReserved4,(void));
4668 DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
4669 DECLR3CALLBACKMEMBER(void, pfnReserved6,(void));
4670 DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
4671 DECLR3CALLBACKMEMBER(void, pfnReserved8,(void));
4672 DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));
4673 DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));
4674 /** @} */
4675
4676
4677 /** API available to trusted devices only.
4678 *
4679 * These APIs are providing unrestricted access to the guest and the VM,
4680 * or they are interacting intimately with PDM.
4681 *
4682 * @{
4683 */
4684
4685 /**
4686 * Gets the user mode VM handle. Restricted API.
4687 *
4688 * @returns User mode VM Handle.
4689 * @param pDevIns The device instance.
4690 */
4691 DECLR3CALLBACKMEMBER(PUVM, pfnGetUVM,(PPDMDEVINS pDevIns));
4692
4693 /**
4694 * Gets the global VM handle. Restricted API.
4695 *
4696 * @returns VM Handle.
4697 * @param pDevIns The device instance.
4698 */
4699 DECLR3CALLBACKMEMBER(PVMCC, pfnGetVM,(PPDMDEVINS pDevIns));
4700
4701 /**
4702 * Gets the VMCPU handle. Restricted API.
4703 *
4704 * @returns VMCPU Handle.
4705 * @param pDevIns The device instance.
4706 */
4707 DECLR3CALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
4708
4709 /**
4710 * The the VM CPU ID of the current thread (restricted API).
4711 *
4712 * @returns The VMCPUID of the calling thread, NIL_VMCPUID if not EMT.
4713 * @param pDevIns The device instance.
4714 */
4715 DECLR3CALLBACKMEMBER(VMCPUID, pfnGetCurrentCpuId,(PPDMDEVINS pDevIns));
4716
4717 /**
4718 * Registers the VMM device heap or notifies about mapping/unmapping.
4719 *
4720 * This interface serves three purposes:
4721 *
4722 * -# Register the VMM device heap during device construction
4723 * for the HM to use.
4724 * -# Notify PDM/HM that it's mapped into guest address
4725 * space (i.e. usable).
4726 * -# Notify PDM/HM that it is being unmapped from the guest
4727 * address space (i.e. not usable).
4728 *
4729 * @returns VBox status code.
4730 * @param pDevIns The device instance.
4731 * @param GCPhys The physical address if mapped, NIL_RTGCPHYS if
4732 * not mapped.
4733 * @param pvHeap Ring 3 heap pointer.
4734 * @param cbHeap Size of the heap.
4735 * @thread EMT.
4736 */
4737 DECLR3CALLBACKMEMBER(int, pfnRegisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbHeap));
4738
4739 /**
4740 * Registers the firmware (BIOS, EFI) device with PDM.
4741 *
4742 * The firmware provides a callback table and gets a special PDM helper table.
4743 * There can only be one firmware device for a VM.
4744 *
4745 * @returns VBox status code.
4746 * @param pDevIns The device instance.
4747 * @param pFwReg Firmware registration structure.
4748 * @param ppFwHlp Where to return the firmware helper structure.
4749 * @remarks Only valid during device construction.
4750 * @thread EMT(0)
4751 */
4752 DECLR3CALLBACKMEMBER(int, pfnFirmwareRegister,(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp));
4753
4754 /**
4755 * Resets the VM.
4756 *
4757 * @returns The appropriate VBox status code to pass around on reset.
4758 * @param pDevIns The device instance.
4759 * @param fFlags PDMVMRESET_F_XXX flags.
4760 * @thread The emulation thread.
4761 */
4762 DECLR3CALLBACKMEMBER(int, pfnVMReset,(PPDMDEVINS pDevIns, uint32_t fFlags));
4763
4764 /**
4765 * Suspends the VM.
4766 *
4767 * @returns The appropriate VBox status code to pass around on suspend.
4768 * @param pDevIns The device instance.
4769 * @thread The emulation thread.
4770 */
4771 DECLR3CALLBACKMEMBER(int, pfnVMSuspend,(PPDMDEVINS pDevIns));
4772
4773 /**
4774 * Suspends, saves and powers off the VM.
4775 *
4776 * @returns The appropriate VBox status code to pass around.
4777 * @param pDevIns The device instance.
4778 * @thread An emulation thread.
4779 */
4780 DECLR3CALLBACKMEMBER(int, pfnVMSuspendSaveAndPowerOff,(PPDMDEVINS pDevIns));
4781
4782 /**
4783 * Power off the VM.
4784 *
4785 * @returns The appropriate VBox status code to pass around on power off.
4786 * @param pDevIns The device instance.
4787 * @thread The emulation thread.
4788 */
4789 DECLR3CALLBACKMEMBER(int, pfnVMPowerOff,(PPDMDEVINS pDevIns));
4790
4791 /**
4792 * Checks if the Gate A20 is enabled or not.
4793 *
4794 * @returns true if A20 is enabled.
4795 * @returns false if A20 is disabled.
4796 * @param pDevIns The device instance.
4797 * @thread The emulation thread.
4798 */
4799 DECLR3CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
4800
4801 /**
4802 * Enables or disables the Gate A20.
4803 *
4804 * @param pDevIns The device instance.
4805 * @param fEnable Set this flag to enable the Gate A20; clear it
4806 * to disable.
4807 * @thread The emulation thread.
4808 */
4809 DECLR3CALLBACKMEMBER(void, pfnA20Set,(PPDMDEVINS pDevIns, bool fEnable));
4810
4811 /**
4812 * Get the specified CPUID leaf for the virtual CPU associated with the calling
4813 * thread.
4814 *
4815 * @param pDevIns The device instance.
4816 * @param iLeaf The CPUID leaf to get.
4817 * @param pEax Where to store the EAX value.
4818 * @param pEbx Where to store the EBX value.
4819 * @param pEcx Where to store the ECX value.
4820 * @param pEdx Where to store the EDX value.
4821 * @thread EMT.
4822 */
4823 DECLR3CALLBACKMEMBER(void, pfnGetCpuId,(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx));
4824
4825 /**
4826 * Gets the main execution engine for the VM.
4827 *
4828 * @returns VM_EXEC_ENGINE_XXX
4829 * @param pDevIns The device instance.
4830 */
4831 DECLR3CALLBACKMEMBER(uint8_t, pfnGetMainExecutionEngine,(PPDMDEVINS pDevIns));
4832
4833 /**
4834 * Get the current virtual clock time in a VM. The clock frequency must be
4835 * queried separately.
4836 *
4837 * @returns Current clock time.
4838 * @param pDevIns The device instance.
4839 */
4840 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
4841
4842 /**
4843 * Get the frequency of the virtual clock.
4844 *
4845 * @returns The clock frequency (not variable at run-time).
4846 * @param pDevIns The device instance.
4847 */
4848 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
4849
4850 /**
4851 * Get the current virtual clock time in a VM, in nanoseconds.
4852 *
4853 * @returns Current clock time (in ns).
4854 * @param pDevIns The device instance.
4855 */
4856 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
4857
4858 /**
4859 * Get the timestamp frequency.
4860 *
4861 * @returns Number of ticks per second.
4862 * @param pDevIns The device instance.
4863 */
4864 DECLR3CALLBACKMEMBER(uint64_t, pfnTMCpuTicksPerSecond,(PPDMDEVINS pDevIns));
4865
4866 /**
4867 * Gets the support driver session.
4868 *
4869 * This is intended for working with the semaphore API.
4870 *
4871 * @returns Support driver session handle.
4872 * @param pDevIns The device instance.
4873 */
4874 DECLR3CALLBACKMEMBER(PSUPDRVSESSION, pfnGetSupDrvSession,(PPDMDEVINS pDevIns));
4875
4876 /**
4877 * Queries a generic object from the VMM user.
4878 *
4879 * @returns Pointer to the object if found, NULL if not.
4880 * @param pDevIns The device instance.
4881 * @param pUuid The UUID of what's being queried. The UUIDs and
4882 * the usage conventions are defined by the user.
4883 *
4884 * @note It is strictly forbidden to call this internally in VBox! This
4885 * interface is exclusively for hacks in externally developed devices.
4886 */
4887 DECLR3CALLBACKMEMBER(void *, pfnQueryGenericUserObject,(PPDMDEVINS pDevIns, PCRTUUID pUuid));
4888
4889 /**
4890 * Register a physical page access handler type.
4891 *
4892 * @returns VBox status code.
4893 * @param pDevIns The device instance.
4894 * @param enmKind The kind of access handler.
4895 * @param pfnHandler Pointer to the ring-3 handler callback.
4896 * @param pszDesc The type description.
4897 * @param phType Where to return the type handle (cross context safe).
4898 * @sa PDMDevHlpPGMHandlerPhysicalTypeSetUpContext
4899 */
4900 DECLR3CALLBACKMEMBER(int, pfnPGMHandlerPhysicalTypeRegister, (PPDMDEVINS pDevIns, PGMPHYSHANDLERKIND enmKind,
4901 PFNPGMPHYSHANDLER pfnHandler,
4902 const char *pszDesc, PPGMPHYSHANDLERTYPE phType));
4903
4904 /**
4905 * Register a access handler for a physical range.
4906 *
4907 * @returns VBox status code.
4908 * @retval VINF_SUCCESS when successfully installed.
4909 * @retval VINF_PGM_GCPHYS_ALIASED when the shadow PTs could be updated because
4910 * the guest page aliased or/and mapped by multiple PTs. A CR3 sync has been
4911 * flagged together with a pool clearing.
4912 * @retval VERR_PGM_HANDLER_PHYSICAL_CONFLICT if the range conflicts with an existing
4913 * one. A debug assertion is raised.
4914 *
4915 * @param pDevIns The device instance.
4916 * @param GCPhys Start physical address.
4917 * @param GCPhysLast Last physical address. (inclusive)
4918 * @param hType The handler type registration handle.
4919 * @param pszDesc Description of this handler. If NULL, the type
4920 * description will be used instead.
4921 * @note There is no @a uUser argument, because it will be set to the pDevIns
4922 * in the context the handler is called.
4923 */
4924 DECLR3CALLBACKMEMBER(int, pfnPGMHandlerPhysicalRegister, (PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
4925 PGMPHYSHANDLERTYPE hType, R3PTRTYPE(const char *) pszDesc));
4926
4927 /**
4928 * Deregister a physical page access handler.
4929 *
4930 * @returns VBox status code.
4931 * @param pDevIns The device instance.
4932 * @param GCPhys Start physical address.
4933 */
4934 DECLR3CALLBACKMEMBER(int, pfnPGMHandlerPhysicalDeregister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys));
4935
4936 /**
4937 * Temporarily turns off the access monitoring of a page within a monitored
4938 * physical write/all page access handler region.
4939 *
4940 * Use this when no further \#PFs are required for that page. Be aware that
4941 * a page directory sync might reset the flags, and turn on access monitoring
4942 * for the page.
4943 *
4944 * The caller must do required page table modifications.
4945 *
4946 * @returns VBox status code.
4947 * @param pDevIns The device instance.
4948 * @param GCPhys The start address of the access handler. This
4949 * must be a fully page aligned range or we risk
4950 * messing up other handlers installed for the
4951 * start and end pages.
4952 * @param GCPhysPage The physical address of the page to turn off
4953 * access monitoring for.
4954 */
4955 DECLR3CALLBACKMEMBER(int, pfnPGMHandlerPhysicalPageTempOff,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage));
4956
4957 /**
4958 * Resets any modifications to individual pages in a physical page access
4959 * handler region.
4960 *
4961 * This is used in pair with PGMHandlerPhysicalPageTempOff(),
4962 * PGMHandlerPhysicalPageAliasMmio2() or PGMHandlerPhysicalPageAliasHC().
4963 *
4964 * @returns VBox status code.
4965 * @param pDevIns The device instance.
4966 * @param GCPhys The start address of the handler regions, i.e. what you
4967 * passed to PGMR3HandlerPhysicalRegister(),
4968 * PGMHandlerPhysicalRegisterEx() or
4969 * PGMHandlerPhysicalModify().
4970 */
4971 DECLR3CALLBACKMEMBER(int, pfnPGMHandlerPhysicalReset,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys));
4972
4973 /**
4974 * Registers the guest memory range that can be used for patching.
4975 *
4976 * @returns VBox status code.
4977 * @param pDevIns The device instance.
4978 * @param GCPtrPatchMem Patch memory range.
4979 * @param cbPatchMem Size of the memory range.
4980 */
4981 DECLR3CALLBACKMEMBER(int, pfnVMMRegisterPatchMemory, (PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem));
4982
4983 /**
4984 * Deregisters the guest memory range that can be used for patching.
4985 *
4986 * @returns VBox status code.
4987 * @param pDevIns The device instance.
4988 * @param GCPtrPatchMem Patch memory range.
4989 * @param cbPatchMem Size of the memory range.
4990 */
4991 DECLR3CALLBACKMEMBER(int, pfnVMMDeregisterPatchMemory, (PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem));
4992
4993 /**
4994 * Registers a new shared module for the VM
4995 *
4996 * @returns VBox status code.
4997 * @param pDevIns The device instance.
4998 * @param enmGuestOS Guest OS type.
4999 * @param pszModuleName Module name.
5000 * @param pszVersion Module version.
5001 * @param GCBaseAddr Module base address.
5002 * @param cbModule Module size.
5003 * @param cRegions Number of shared region descriptors.
5004 * @param paRegions Shared region(s).
5005 */
5006 DECLR3CALLBACKMEMBER(int, pfnSharedModuleRegister,(PPDMDEVINS pDevIns, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion,
5007 RTGCPTR GCBaseAddr, uint32_t cbModule,
5008 uint32_t cRegions, VMMDEVSHAREDREGIONDESC const *paRegions));
5009
5010 /**
5011 * Unregisters a shared module for the VM
5012 *
5013 * @returns VBox status code.
5014 * @param pDevIns The device instance.
5015 * @param pszModuleName Module name.
5016 * @param pszVersion Module version.
5017 * @param GCBaseAddr Module base address.
5018 * @param cbModule Module size.
5019 */
5020 DECLR3CALLBACKMEMBER(int, pfnSharedModuleUnregister,(PPDMDEVINS pDevIns, char *pszModuleName, char *pszVersion,
5021 RTGCPTR GCBaseAddr, uint32_t cbModule));
5022
5023 /**
5024 * Query the state of a page in a shared module
5025 *
5026 * @returns VBox status code.
5027 * @param pDevIns The device instance.
5028 * @param GCPtrPage Page address.
5029 * @param pfShared Shared status (out).
5030 * @param pfPageFlags Page flags (out).
5031 */
5032 DECLR3CALLBACKMEMBER(int, pfnSharedModuleGetPageState, (PPDMDEVINS pDevIns, RTGCPTR GCPtrPage, bool *pfShared, uint64_t *pfPageFlags));
5033
5034 /**
5035 * Check all registered modules for changes.
5036 *
5037 * @returns VBox status code.
5038 * @param pDevIns The device instance.
5039 */
5040 DECLR3CALLBACKMEMBER(int, pfnSharedModuleCheckAll,(PPDMDEVINS pDevIns));
5041
5042 /**
5043 * Query the interface of the top level driver on a LUN.
5044 *
5045 * @returns VBox status code.
5046 * @param pDevIns The device instance.
5047 * @param pszDevice Device name.
5048 * @param iInstance Device instance.
5049 * @param iLun The Logical Unit to obtain the interface of.
5050 * @param ppBase Where to store the base interface pointer.
5051 *
5052 * @remark We're not doing any locking ATM, so don't try call this at times when the
5053 * device chain is known to be updated.
5054 */
5055 DECLR3CALLBACKMEMBER(int, pfnQueryLun,(PPDMDEVINS pDevIns, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase));
5056
5057 /**
5058 * Registers the GIM device with VMM.
5059 *
5060 * @param pDevIns Pointer to the GIM device instance.
5061 * @param pDbg Pointer to the GIM device debug structure, can be
5062 * NULL.
5063 */
5064 DECLR3CALLBACKMEMBER(void, pfnGIMDeviceRegister,(PPDMDEVINS pDevIns, PGIMDEBUG pDbg));
5065
5066 /**
5067 * Gets debug setup specified by the provider.
5068 *
5069 * @returns VBox status code.
5070 * @param pDevIns Pointer to the GIM device instance.
5071 * @param pDbgSetup Where to store the debug setup details.
5072 */
5073 DECLR3CALLBACKMEMBER(int, pfnGIMGetDebugSetup,(PPDMDEVINS pDevIns, PGIMDEBUGSETUP pDbgSetup));
5074
5075 /**
5076 * Returns the array of MMIO2 regions that are expected to be registered and
5077 * later mapped into the guest-physical address space for the GIM provider
5078 * configured for the VM.
5079 *
5080 * @returns Pointer to an array of GIM MMIO2 regions, may return NULL.
5081 * @param pDevIns Pointer to the GIM device instance.
5082 * @param pcRegions Where to store the number of items in the array.
5083 *
5084 * @remarks The caller does not own and therefore must -NOT- try to free the
5085 * returned pointer.
5086 */
5087 DECLR3CALLBACKMEMBER(PGIMMMIO2REGION, pfnGIMGetMmio2Regions,(PPDMDEVINS pDevIns, uint32_t *pcRegions));
5088
5089 /** @} */
5090
5091 /** Just a safety precaution. (PDM_DEVHLPR3_VERSION) */
5092 uint32_t u32TheEnd;
5093} PDMDEVHLPR3;
5094#endif /* !IN_RING3 || DOXYGEN_RUNNING */
5095/** Pointer to the R3 PDM Device API. */
5096typedef R3PTRTYPE(struct PDMDEVHLPR3 *) PPDMDEVHLPR3;
5097/** Pointer to the R3 PDM Device API, const variant. */
5098typedef R3PTRTYPE(const struct PDMDEVHLPR3 *) PCPDMDEVHLPR3;
5099
5100
5101/**
5102 * PDM Device API - RC Variant.
5103 */
5104typedef struct PDMDEVHLPRC
5105{
5106 /** Structure version. PDM_DEVHLPRC_VERSION defines the current version. */
5107 uint32_t u32Version;
5108
5109 /**
5110 * Sets up raw-mode context callback handlers for an I/O port range.
5111 *
5112 * The range must have been registered in ring-3 first using
5113 * PDMDevHlpIoPortCreate() or PDMDevHlpIoPortCreateEx().
5114 *
5115 * @returns VBox status.
5116 * @param pDevIns The device instance to register the ports with.
5117 * @param hIoPorts The I/O port range handle.
5118 * @param pfnOut Pointer to function which is gonna handle OUT
5119 * operations. Optional.
5120 * @param pfnIn Pointer to function which is gonna handle IN operations.
5121 * Optional.
5122 * @param pfnOutStr Pointer to function which is gonna handle string OUT
5123 * operations. Optional.
5124 * @param pfnInStr Pointer to function which is gonna handle string IN
5125 * operations. Optional.
5126 * @param pvUser User argument to pass to the callbacks.
5127 *
5128 * @remarks Caller enters the device critical section prior to invoking the
5129 * registered callback methods.
5130 *
5131 * @sa PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx, PDMDevHlpIoPortMap,
5132 * PDMDevHlpIoPortUnmap.
5133 */
5134 DECLRCCALLBACKMEMBER(int, pfnIoPortSetUpContextEx,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
5135 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
5136 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr,
5137 void *pvUser));
5138
5139 /**
5140 * Sets up raw-mode context callback handlers for an MMIO region.
5141 *
5142 * The region must have been registered in ring-3 first using
5143 * PDMDevHlpMmioCreate() or PDMDevHlpMmioCreateEx().
5144 *
5145 * @returns VBox status.
5146 * @param pDevIns The device instance to register the ports with.
5147 * @param hRegion The MMIO region handle.
5148 * @param pfnWrite Pointer to function which is gonna handle Write
5149 * operations.
5150 * @param pfnRead Pointer to function which is gonna handle Read
5151 * operations.
5152 * @param pfnFill Pointer to function which is gonna handle Fill/memset
5153 * operations. (optional)
5154 * @param pvUser User argument to pass to the callbacks.
5155 *
5156 * @remarks Caller enters the device critical section prior to invoking the
5157 * registered callback methods.
5158 *
5159 * @sa PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx, PDMDevHlpMmioMap,
5160 * PDMDevHlpMmioUnmap.
5161 */
5162 DECLRCCALLBACKMEMBER(int, pfnMmioSetUpContextEx,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIONEWWRITE pfnWrite,
5163 PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill, void *pvUser));
5164
5165 /**
5166 * Sets up a raw-mode mapping for an MMIO2 region.
5167 *
5168 * The region must have been created in ring-3 first using
5169 * PDMDevHlpMmio2Create().
5170 *
5171 * @returns VBox status.
5172 * @param pDevIns The device instance to register the ports with.
5173 * @param hRegion The MMIO2 region handle.
5174 * @param offSub Start of what to map into raw-mode. Must be page aligned.
5175 * @param cbSub Number of bytes to map into raw-mode. Must be page
5176 * aligned. Zero is an alias for everything.
5177 * @param ppvMapping Where to return the mapping corresponding to @a offSub.
5178 * @thread EMT(0)
5179 * @note Only available at VM creation time.
5180 *
5181 * @sa PDMDevHlpMmio2Create().
5182 */
5183 DECLRCCALLBACKMEMBER(int, pfnMmio2SetUpContext,(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion,
5184 size_t offSub, size_t cbSub, void **ppvMapping));
5185
5186 /**
5187 * Bus master physical memory read from the given PCI device.
5188 *
5189 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
5190 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
5191 * @param pDevIns The device instance.
5192 * @param pPciDev The PCI device structure. If NULL the default
5193 * PCI device for this device instance is used.
5194 * @param GCPhys Physical address start reading from.
5195 * @param pvBuf Where to put the read bits.
5196 * @param cbRead How many bytes to read.
5197 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
5198 * @thread Any thread, but the call may involve the emulation thread.
5199 */
5200 DECLRCCALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
5201 void *pvBuf, size_t cbRead, uint32_t fFlags));
5202
5203 /**
5204 * Bus master physical memory write from the given PCI device.
5205 *
5206 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
5207 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
5208 * @param pDevIns The device instance.
5209 * @param pPciDev The PCI device structure. If NULL the default
5210 * PCI device for this device instance is used.
5211 * @param GCPhys Physical address to write to.
5212 * @param pvBuf What to write.
5213 * @param cbWrite How many bytes to write.
5214 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
5215 * @thread Any thread, but the call may involve the emulation thread.
5216 */
5217 DECLRCCALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
5218 const void *pvBuf, size_t cbWrite, uint32_t fFlags));
5219
5220 /**
5221 * Set the IRQ for the given PCI device.
5222 *
5223 * @param pDevIns Device instance.
5224 * @param pPciDev The PCI device structure. If NULL the default
5225 * PCI device for this device instance is used.
5226 * @param iIrq IRQ number to set.
5227 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
5228 * @thread Any thread, but will involve the emulation thread.
5229 */
5230 DECLRCCALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
5231
5232 /**
5233 * Set ISA IRQ for a device.
5234 *
5235 * @param pDevIns Device instance.
5236 * @param iIrq IRQ number to set.
5237 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
5238 * @thread Any thread, but will involve the emulation thread.
5239 */
5240 DECLRCCALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
5241
5242 /**
5243 * Read physical memory.
5244 *
5245 * @returns VINF_SUCCESS (for now).
5246 * @param pDevIns Device instance.
5247 * @param GCPhys Physical address start reading from.
5248 * @param pvBuf Where to put the read bits.
5249 * @param cbRead How many bytes to read.
5250 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
5251 */
5252 DECLRCCALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags));
5253
5254 /**
5255 * Write to physical memory.
5256 *
5257 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
5258 * @param pDevIns Device instance.
5259 * @param GCPhys Physical address to write to.
5260 * @param pvBuf What to write.
5261 * @param cbWrite How many bytes to write.
5262 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
5263 */
5264 DECLRCCALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags));
5265
5266 /**
5267 * Checks if the Gate A20 is enabled or not.
5268 *
5269 * @returns true if A20 is enabled.
5270 * @returns false if A20 is disabled.
5271 * @param pDevIns Device instance.
5272 * @thread The emulation thread.
5273 */
5274 DECLRCCALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
5275
5276 /**
5277 * Gets the VM state.
5278 *
5279 * @returns VM state.
5280 * @param pDevIns The device instance.
5281 * @thread Any thread (just keep in mind that it's volatile info).
5282 */
5283 DECLRCCALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
5284
5285 /**
5286 * Gets the VM handle. Restricted API.
5287 *
5288 * @returns VM Handle.
5289 * @param pDevIns Device instance.
5290 */
5291 DECLRCCALLBACKMEMBER(PVMCC, pfnGetVM,(PPDMDEVINS pDevIns));
5292
5293 /**
5294 * Gets the VMCPU handle. Restricted API.
5295 *
5296 * @returns VMCPU Handle.
5297 * @param pDevIns The device instance.
5298 */
5299 DECLRCCALLBACKMEMBER(PVMCPUCC, pfnGetVMCPU,(PPDMDEVINS pDevIns));
5300
5301 /**
5302 * The the VM CPU ID of the current thread (restricted API).
5303 *
5304 * @returns The VMCPUID of the calling thread, NIL_VMCPUID if not EMT.
5305 * @param pDevIns The device instance.
5306 */
5307 DECLRCCALLBACKMEMBER(VMCPUID, pfnGetCurrentCpuId,(PPDMDEVINS pDevIns));
5308
5309 /**
5310 * Gets the main execution engine for the VM.
5311 *
5312 * @returns VM_EXEC_ENGINE_XXX
5313 * @param pDevIns The device instance.
5314 */
5315 DECLRCCALLBACKMEMBER(uint8_t, pfnGetMainExecutionEngine,(PPDMDEVINS pDevIns));
5316
5317 /**
5318 * Get the current virtual clock time in a VM. The clock frequency must be
5319 * queried separately.
5320 *
5321 * @returns Current clock time.
5322 * @param pDevIns The device instance.
5323 */
5324 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
5325
5326 /**
5327 * Get the frequency of the virtual clock.
5328 *
5329 * @returns The clock frequency (not variable at run-time).
5330 * @param pDevIns The device instance.
5331 */
5332 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
5333
5334 /**
5335 * Get the current virtual clock time in a VM, in nanoseconds.
5336 *
5337 * @returns Current clock time (in ns).
5338 * @param pDevIns The device instance.
5339 */
5340 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
5341
5342 /**
5343 * Gets the NOP critical section.
5344 *
5345 * @returns The ring-3 address of the NOP critical section.
5346 * @param pDevIns The device instance.
5347 */
5348 DECLRCCALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
5349
5350 /**
5351 * Changes the device level critical section from the automatically created
5352 * default to one desired by the device constructor.
5353 *
5354 * Must first be done in ring-3.
5355 *
5356 * @returns VBox status code.
5357 * @param pDevIns The device instance.
5358 * @param pCritSect The critical section to use. NULL is not
5359 * valid, instead use the NOP critical
5360 * section.
5361 */
5362 DECLRCCALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
5363
5364 /** @name Exported PDM Critical Section Functions
5365 * @{ */
5366 DECLRCCALLBACKMEMBER(int, pfnCritSectEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy));
5367 DECLRCCALLBACKMEMBER(int, pfnCritSectEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5368 DECLRCCALLBACKMEMBER(int, pfnCritSectTryEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
5369 DECLRCCALLBACKMEMBER(int, pfnCritSectTryEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5370 DECLRCCALLBACKMEMBER(int, pfnCritSectLeave,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
5371 DECLRCCALLBACKMEMBER(bool, pfnCritSectIsOwner,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5372 DECLRCCALLBACKMEMBER(bool, pfnCritSectIsInitialized,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5373 DECLRCCALLBACKMEMBER(bool, pfnCritSectHasWaiters,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5374 DECLRCCALLBACKMEMBER(uint32_t, pfnCritSectGetRecursion,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5375 /** @} */
5376
5377 /** @name Exported PDM Read/Write Critical Section Functions
5378 * @{ */
5379 DECLRCCALLBACKMEMBER(int, pfnCritSectRwEnterShared,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy));
5380 DECLRCCALLBACKMEMBER(int, pfnCritSectRwEnterSharedDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5381 DECLRCCALLBACKMEMBER(int, pfnCritSectRwTryEnterShared,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5382 DECLRCCALLBACKMEMBER(int, pfnCritSectRwTryEnterSharedDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5383 DECLRCCALLBACKMEMBER(int, pfnCritSectRwLeaveShared,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5384
5385 DECLRCCALLBACKMEMBER(int, pfnCritSectRwEnterExcl,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy));
5386 DECLRCCALLBACKMEMBER(int, pfnCritSectRwEnterExclDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5387 DECLRCCALLBACKMEMBER(int, pfnCritSectRwTryEnterExcl,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5388 DECLRCCALLBACKMEMBER(int, pfnCritSectRwTryEnterExclDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5389 DECLRCCALLBACKMEMBER(int, pfnCritSectRwLeaveExcl,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5390
5391 DECLRCCALLBACKMEMBER(bool, pfnCritSectRwIsWriteOwner,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5392 DECLRCCALLBACKMEMBER(bool, pfnCritSectRwIsReadOwner,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, bool fWannaHear));
5393 DECLRCCALLBACKMEMBER(uint32_t, pfnCritSectRwGetWriteRecursion,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5394 DECLRCCALLBACKMEMBER(uint32_t, pfnCritSectRwGetWriterReadRecursion,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5395 DECLRCCALLBACKMEMBER(uint32_t, pfnCritSectRwGetReadCount,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5396 DECLRCCALLBACKMEMBER(bool, pfnCritSectRwIsInitialized,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5397 /** @} */
5398
5399 /**
5400 * Gets the trace buffer handle.
5401 *
5402 * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
5403 * really inteded for direct usage, thus no inline wrapper function.
5404 *
5405 * @returns Trace buffer handle or NIL_RTTRACEBUF.
5406 * @param pDevIns The device instance.
5407 */
5408 DECLRCCALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
5409
5410 /**
5411 * Sets up the PCI bus for the raw-mode context.
5412 *
5413 * This must be called after ring-3 has registered the PCI bus using
5414 * PDMDevHlpPCIBusRegister().
5415 *
5416 * @returns VBox status code.
5417 * @param pDevIns The device instance.
5418 * @param pPciBusReg The PCI bus registration information for raw-mode,
5419 * considered volatile.
5420 * @param ppPciHlp Where to return the raw-mode PCI bus helpers.
5421 */
5422 DECLRCCALLBACKMEMBER(int, pfnPCIBusSetUpContext,(PPDMDEVINS pDevIns, PPDMPCIBUSREGRC pPciBusReg, PCPDMPCIHLPRC *ppPciHlp));
5423
5424 /**
5425 * Sets up the IOMMU for the raw-mode context.
5426 *
5427 * This must be called after ring-3 has registered the IOMMU using
5428 * PDMDevHlpIommuRegister().
5429 *
5430 * @returns VBox status code.
5431 * @param pDevIns The device instance.
5432 * @param pIommuReg The IOMMU registration information for raw-mode,
5433 * considered volatile.
5434 * @param ppIommuHlp Where to return the raw-mode IOMMU helpers.
5435 */
5436 DECLRCCALLBACKMEMBER(int, pfnIommuSetUpContext,(PPDMDEVINS pDevIns, PPDMIOMMUREGRC pIommuReg, PCPDMIOMMUHLPRC *ppIommuHlp));
5437
5438 /**
5439 * Sets up the PIC for the ring-0 context.
5440 *
5441 * This must be called after ring-3 has registered the PIC using
5442 * PDMDevHlpPICRegister().
5443 *
5444 * @returns VBox status code.
5445 * @param pDevIns The device instance.
5446 * @param pPicReg The PIC registration information for ring-0,
5447 * considered volatile and copied.
5448 * @param ppPicHlp Where to return the ring-0 PIC helpers.
5449 */
5450 DECLRCCALLBACKMEMBER(int, pfnPICSetUpContext,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp));
5451
5452 /**
5453 * Sets up the APIC for the raw-mode context.
5454 *
5455 * This must be called after ring-3 has registered the APIC using
5456 * PDMDevHlpApicRegister().
5457 *
5458 * @returns VBox status code.
5459 * @param pDevIns The device instance.
5460 */
5461 DECLRCCALLBACKMEMBER(int, pfnApicSetUpContext,(PPDMDEVINS pDevIns));
5462
5463 /**
5464 * Sets up the IOAPIC for the ring-0 context.
5465 *
5466 * This must be called after ring-3 has registered the PIC using
5467 * PDMDevHlpIoApicRegister().
5468 *
5469 * @returns VBox status code.
5470 * @param pDevIns The device instance.
5471 * @param pIoApicReg The PIC registration information for ring-0,
5472 * considered volatile and copied.
5473 * @param ppIoApicHlp Where to return the ring-0 IOAPIC helpers.
5474 */
5475 DECLRCCALLBACKMEMBER(int, pfnIoApicSetUpContext,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp));
5476
5477 /**
5478 * Sets up the HPET for the raw-mode context.
5479 *
5480 * This must be called after ring-3 has registered the PIC using
5481 * PDMDevHlpHpetRegister().
5482 *
5483 * @returns VBox status code.
5484 * @param pDevIns The device instance.
5485 * @param pHpetReg The PIC registration information for raw-mode,
5486 * considered volatile and copied.
5487 * @param ppHpetHlp Where to return the raw-mode HPET helpers.
5488 */
5489 DECLRCCALLBACKMEMBER(int, pfnHpetSetUpContext,(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPRC *ppHpetHlp));
5490
5491 /** Space reserved for future members.
5492 * @{ */
5493 DECLRCCALLBACKMEMBER(void, pfnReserved1,(void));
5494 DECLRCCALLBACKMEMBER(void, pfnReserved2,(void));
5495 DECLRCCALLBACKMEMBER(void, pfnReserved3,(void));
5496 DECLRCCALLBACKMEMBER(void, pfnReserved4,(void));
5497 DECLRCCALLBACKMEMBER(void, pfnReserved5,(void));
5498 DECLRCCALLBACKMEMBER(void, pfnReserved6,(void));
5499 DECLRCCALLBACKMEMBER(void, pfnReserved7,(void));
5500 DECLRCCALLBACKMEMBER(void, pfnReserved8,(void));
5501 DECLRCCALLBACKMEMBER(void, pfnReserved9,(void));
5502 DECLRCCALLBACKMEMBER(void, pfnReserved10,(void));
5503 /** @} */
5504
5505 /** Just a safety precaution. */
5506 uint32_t u32TheEnd;
5507} PDMDEVHLPRC;
5508/** Pointer PDM Device RC API. */
5509typedef RGPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC;
5510/** Pointer PDM Device RC API. */
5511typedef RGPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC;
5512
5513/** Current PDMDEVHLP version number. */
5514#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 19, 0)
5515
5516
5517/**
5518 * PDM Device API - R0 Variant.
5519 */
5520typedef struct PDMDEVHLPR0
5521{
5522 /** Structure version. PDM_DEVHLPR0_VERSION defines the current version. */
5523 uint32_t u32Version;
5524
5525 /**
5526 * Sets up ring-0 callback handlers for an I/O port range.
5527 *
5528 * The range must have been created in ring-3 first using
5529 * PDMDevHlpIoPortCreate() or PDMDevHlpIoPortCreateEx().
5530 *
5531 * @returns VBox status.
5532 * @param pDevIns The device instance to register the ports with.
5533 * @param hIoPorts The I/O port range handle.
5534 * @param pfnOut Pointer to function which is gonna handle OUT
5535 * operations. Optional.
5536 * @param pfnIn Pointer to function which is gonna handle IN operations.
5537 * Optional.
5538 * @param pfnOutStr Pointer to function which is gonna handle string OUT
5539 * operations. Optional.
5540 * @param pfnInStr Pointer to function which is gonna handle string IN
5541 * operations. Optional.
5542 * @param pvUser User argument to pass to the callbacks.
5543 *
5544 * @remarks Caller enters the device critical section prior to invoking the
5545 * registered callback methods.
5546 *
5547 * @sa PDMDevHlpIoPortCreate(), PDMDevHlpIoPortCreateEx(),
5548 * PDMDevHlpIoPortMap(), PDMDevHlpIoPortUnmap().
5549 */
5550 DECLR0CALLBACKMEMBER(int, pfnIoPortSetUpContextEx,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
5551 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
5552 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr,
5553 void *pvUser));
5554
5555 /**
5556 * Sets up ring-0 callback handlers for an MMIO region.
5557 *
5558 * The region must have been created in ring-3 first using
5559 * PDMDevHlpMmioCreate(), PDMDevHlpMmioCreateEx(), PDMDevHlpMmioCreateAndMap(),
5560 * PDMDevHlpMmioCreateExAndMap() or PDMDevHlpPCIIORegionCreateMmio().
5561 *
5562 * @returns VBox status.
5563 * @param pDevIns The device instance to register the ports with.
5564 * @param hRegion The MMIO region handle.
5565 * @param pfnWrite Pointer to function which is gonna handle Write
5566 * operations.
5567 * @param pfnRead Pointer to function which is gonna handle Read
5568 * operations.
5569 * @param pfnFill Pointer to function which is gonna handle Fill/memset
5570 * operations. (optional)
5571 * @param pvUser User argument to pass to the callbacks.
5572 *
5573 * @remarks Caller enters the device critical section prior to invoking the
5574 * registered callback methods.
5575 *
5576 * @sa PDMDevHlpMmioCreate(), PDMDevHlpMmioCreateEx(), PDMDevHlpMmioMap(),
5577 * PDMDevHlpMmioUnmap().
5578 */
5579 DECLR0CALLBACKMEMBER(int, pfnMmioSetUpContextEx,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIONEWWRITE pfnWrite,
5580 PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill, void *pvUser));
5581
5582 /**
5583 * Sets up a ring-0 mapping for an MMIO2 region.
5584 *
5585 * The region must have been created in ring-3 first using
5586 * PDMDevHlpMmio2Create().
5587 *
5588 * @returns VBox status.
5589 * @param pDevIns The device instance to register the ports with.
5590 * @param hRegion The MMIO2 region handle.
5591 * @param offSub Start of what to map into ring-0. Must be page aligned.
5592 * @param cbSub Number of bytes to map into ring-0. Must be page
5593 * aligned. Zero is an alias for everything.
5594 * @param ppvMapping Where to return the mapping corresponding to @a offSub.
5595 *
5596 * @thread EMT(0)
5597 * @note Only available at VM creation time.
5598 *
5599 * @sa PDMDevHlpMmio2Create().
5600 */
5601 DECLR0CALLBACKMEMBER(int, pfnMmio2SetUpContext,(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, size_t offSub, size_t cbSub,
5602 void **ppvMapping));
5603
5604 /**
5605 * Bus master physical memory read from the given PCI device.
5606 *
5607 * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe
5608 * VERR_EM_MEMORY.
5609 * @param pDevIns The device instance.
5610 * @param pPciDev The PCI device structure. If NULL the default
5611 * PCI device for this device instance is used.
5612 * @param GCPhys Physical address start reading from.
5613 * @param pvBuf Where to put the read bits.
5614 * @param cbRead How many bytes to read.
5615 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
5616 * @thread Any thread, but the call may involve the emulation thread.
5617 */
5618 DECLR0CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
5619 void *pvBuf, size_t cbRead, uint32_t fFlags));
5620
5621 /**
5622 * Bus master physical memory write from the given PCI device.
5623 *
5624 * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe
5625 * VERR_EM_MEMORY.
5626 * @param pDevIns The device instance.
5627 * @param pPciDev The PCI device structure. If NULL the default
5628 * PCI device for this device instance is used.
5629 * @param GCPhys Physical address to write to.
5630 * @param pvBuf What to write.
5631 * @param cbWrite How many bytes to write.
5632 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
5633 * @thread Any thread, but the call may involve the emulation thread.
5634 */
5635 DECLR0CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
5636 const void *pvBuf, size_t cbWrite, uint32_t fFlags));
5637
5638 /**
5639 * Set the IRQ for the given PCI device.
5640 *
5641 * @param pDevIns Device instance.
5642 * @param pPciDev The PCI device structure. If NULL the default
5643 * PCI device for this device instance is used.
5644 * @param iIrq IRQ number to set.
5645 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
5646 * @thread Any thread, but will involve the emulation thread.
5647 */
5648 DECLR0CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
5649
5650 /**
5651 * Set ISA IRQ for a device.
5652 *
5653 * @param pDevIns Device instance.
5654 * @param iIrq IRQ number to set.
5655 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
5656 * @thread Any thread, but will involve the emulation thread.
5657 */
5658 DECLR0CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
5659
5660 /**
5661 * Read physical memory.
5662 *
5663 * @returns VINF_SUCCESS (for now).
5664 * @param pDevIns Device instance.
5665 * @param GCPhys Physical address start reading from.
5666 * @param pvBuf Where to put the read bits.
5667 * @param cbRead How many bytes to read.
5668 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
5669 */
5670 DECLR0CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags));
5671
5672 /**
5673 * Write to physical memory.
5674 *
5675 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
5676 * @param pDevIns Device instance.
5677 * @param GCPhys Physical address to write to.
5678 * @param pvBuf What to write.
5679 * @param cbWrite How many bytes to write.
5680 * @param fFlags Combination of PDM_DEVHLP_PHYS_RW_F_XXX.
5681 */
5682 DECLR0CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags));
5683
5684 /**
5685 * Checks if the Gate A20 is enabled or not.
5686 *
5687 * @returns true if A20 is enabled.
5688 * @returns false if A20 is disabled.
5689 * @param pDevIns Device instance.
5690 * @thread The emulation thread.
5691 */
5692 DECLR0CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
5693
5694 /**
5695 * Gets the VM state.
5696 *
5697 * @returns VM state.
5698 * @param pDevIns The device instance.
5699 * @thread Any thread (just keep in mind that it's volatile info).
5700 */
5701 DECLR0CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
5702
5703 /**
5704 * Gets the VM handle. Restricted API.
5705 *
5706 * @returns VM Handle.
5707 * @param pDevIns Device instance.
5708 */
5709 DECLR0CALLBACKMEMBER(PVMCC, pfnGetVM,(PPDMDEVINS pDevIns));
5710
5711 /**
5712 * Gets the VMCPU handle. Restricted API.
5713 *
5714 * @returns VMCPU Handle.
5715 * @param pDevIns The device instance.
5716 */
5717 DECLR0CALLBACKMEMBER(PVMCPUCC, pfnGetVMCPU,(PPDMDEVINS pDevIns));
5718
5719 /**
5720 * The the VM CPU ID of the current thread (restricted API).
5721 *
5722 * @returns The VMCPUID of the calling thread, NIL_VMCPUID if not EMT.
5723 * @param pDevIns The device instance.
5724 */
5725 DECLR0CALLBACKMEMBER(VMCPUID, pfnGetCurrentCpuId,(PPDMDEVINS pDevIns));
5726
5727 /**
5728 * Gets the main execution engine for the VM.
5729 *
5730 * @returns VM_EXEC_ENGINE_XXX
5731 * @param pDevIns The device instance.
5732 */
5733 DECLR0CALLBACKMEMBER(uint8_t, pfnGetMainExecutionEngine,(PPDMDEVINS pDevIns));
5734
5735 /** @name Timer handle method wrappers
5736 * @{ */
5737 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerFromMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs));
5738 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerFromMilli,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs));
5739 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerFromNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs));
5740 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerGet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5741 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerGetFreq,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5742 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerGetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5743 DECLR0CALLBACKMEMBER(bool, pfnTimerIsActive,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5744 DECLR0CALLBACKMEMBER(bool, pfnTimerIsLockOwner,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5745 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnTimerLockClock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy));
5746 /** Takes the clock lock then enters the specified critical section. */
5747 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnTimerLockClock2,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect, int rcBusy));
5748 DECLR0CALLBACKMEMBER(int, pfnTimerSet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire));
5749 DECLR0CALLBACKMEMBER(int, pfnTimerSetFrequencyHint,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz));
5750 DECLR0CALLBACKMEMBER(int, pfnTimerSetMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext));
5751 DECLR0CALLBACKMEMBER(int, pfnTimerSetMillies,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext));
5752 DECLR0CALLBACKMEMBER(int, pfnTimerSetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext));
5753 DECLR0CALLBACKMEMBER(int, pfnTimerSetRelative,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now));
5754 DECLR0CALLBACKMEMBER(int, pfnTimerStop,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5755 DECLR0CALLBACKMEMBER(void, pfnTimerUnlockClock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5756 DECLR0CALLBACKMEMBER(void, pfnTimerUnlockClock2,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect));
5757 /** @} */
5758
5759 /**
5760 * Get the current virtual clock time in a VM. The clock frequency must be
5761 * queried separately.
5762 *
5763 * @returns Current clock time.
5764 * @param pDevIns The device instance.
5765 */
5766 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
5767
5768 /**
5769 * Get the frequency of the virtual clock.
5770 *
5771 * @returns The clock frequency (not variable at run-time).
5772 * @param pDevIns The device instance.
5773 */
5774 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
5775
5776 /**
5777 * Get the current virtual clock time in a VM, in nanoseconds.
5778 *
5779 * @returns Current clock time (in ns).
5780 * @param pDevIns The device instance.
5781 */
5782 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
5783
5784 /** @name Exported PDM Queue Functions
5785 * @{ */
5786 DECLR0CALLBACKMEMBER(PPDMQUEUEITEMCORE, pfnQueueAlloc,(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue));
5787 DECLR0CALLBACKMEMBER(int, pfnQueueInsert,(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue, PPDMQUEUEITEMCORE pItem));
5788 DECLR0CALLBACKMEMBER(bool, pfnQueueFlushIfNecessary,(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue));
5789 /** @} */
5790
5791 /** @name PDM Task
5792 * @{ */
5793 /**
5794 * Triggers the running the given task.
5795 *
5796 * @returns VBox status code.
5797 * @retval VINF_ALREADY_POSTED is the task is already pending.
5798 * @param pDevIns The device instance.
5799 * @param hTask The task to trigger.
5800 * @thread Any thread.
5801 */
5802 DECLR0CALLBACKMEMBER(int, pfnTaskTrigger,(PPDMDEVINS pDevIns, PDMTASKHANDLE hTask));
5803 /** @} */
5804
5805 /** @name SUP Event Semaphore Wrappers (single release / auto reset)
5806 * These semaphores can be signalled from ring-0.
5807 * @{ */
5808 /** @sa SUPSemEventSignal */
5809 DECLR0CALLBACKMEMBER(int, pfnSUPSemEventSignal,(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent));
5810 /** @sa SUPSemEventWaitNoResume */
5811 DECLR0CALLBACKMEMBER(int, pfnSUPSemEventWaitNoResume,(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint32_t cMillies));
5812 /** @sa SUPSemEventWaitNsAbsIntr */
5813 DECLR0CALLBACKMEMBER(int, pfnSUPSemEventWaitNsAbsIntr,(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t uNsTimeout));
5814 /** @sa SUPSemEventWaitNsRelIntr */
5815 DECLR0CALLBACKMEMBER(int, pfnSUPSemEventWaitNsRelIntr,(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t cNsTimeout));
5816 /** @sa SUPSemEventGetResolution */
5817 DECLR0CALLBACKMEMBER(uint32_t, pfnSUPSemEventGetResolution,(PPDMDEVINS pDevIns));
5818 /** @} */
5819
5820 /** @name SUP Multi Event Semaphore Wrappers (multiple release / manual reset)
5821 * These semaphores can be signalled from ring-0.
5822 * @{ */
5823 /** @sa SUPSemEventMultiSignal */
5824 DECLR0CALLBACKMEMBER(int, pfnSUPSemEventMultiSignal,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti));
5825 /** @sa SUPSemEventMultiReset */
5826 DECLR0CALLBACKMEMBER(int, pfnSUPSemEventMultiReset,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti));
5827 /** @sa SUPSemEventMultiWaitNoResume */
5828 DECLR0CALLBACKMEMBER(int, pfnSUPSemEventMultiWaitNoResume,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies));
5829 /** @sa SUPSemEventMultiWaitNsAbsIntr */
5830 DECLR0CALLBACKMEMBER(int, pfnSUPSemEventMultiWaitNsAbsIntr,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout));
5831 /** @sa SUPSemEventMultiWaitNsRelIntr */
5832 DECLR0CALLBACKMEMBER(int, pfnSUPSemEventMultiWaitNsRelIntr,(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout));
5833 /** @sa SUPSemEventMultiGetResolution */
5834 DECLR0CALLBACKMEMBER(uint32_t, pfnSUPSemEventMultiGetResolution,(PPDMDEVINS pDevIns));
5835 /** @} */
5836
5837 /**
5838 * Gets the NOP critical section.
5839 *
5840 * @returns The ring-3 address of the NOP critical section.
5841 * @param pDevIns The device instance.
5842 */
5843 DECLR0CALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
5844
5845 /**
5846 * Changes the device level critical section from the automatically created
5847 * default to one desired by the device constructor.
5848 *
5849 * Must first be done in ring-3.
5850 *
5851 * @returns VBox status code.
5852 * @param pDevIns The device instance.
5853 * @param pCritSect The critical section to use. NULL is not
5854 * valid, instead use the NOP critical
5855 * section.
5856 */
5857 DECLR0CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
5858
5859 /** @name Exported PDM Critical Section Functions
5860 * @{ */
5861 DECLR0CALLBACKMEMBER(int, pfnCritSectEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy));
5862 DECLR0CALLBACKMEMBER(int, pfnCritSectEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5863 DECLR0CALLBACKMEMBER(int, pfnCritSectTryEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
5864 DECLR0CALLBACKMEMBER(int, pfnCritSectTryEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5865 DECLR0CALLBACKMEMBER(int, pfnCritSectLeave,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
5866 DECLR0CALLBACKMEMBER(bool, pfnCritSectIsOwner,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5867 DECLR0CALLBACKMEMBER(bool, pfnCritSectIsInitialized,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5868 DECLR0CALLBACKMEMBER(bool, pfnCritSectHasWaiters,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5869 DECLR0CALLBACKMEMBER(uint32_t, pfnCritSectGetRecursion,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5870 DECLR0CALLBACKMEMBER(int, pfnCritSectScheduleExitEvent,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, SUPSEMEVENT hEventToSignal));
5871 /** @} */
5872
5873 /** @name Exported PDM Read/Write Critical Section Functions
5874 * @{ */
5875 DECLR0CALLBACKMEMBER(int, pfnCritSectRwEnterShared,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy));
5876 DECLR0CALLBACKMEMBER(int, pfnCritSectRwEnterSharedDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5877 DECLR0CALLBACKMEMBER(int, pfnCritSectRwTryEnterShared,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5878 DECLR0CALLBACKMEMBER(int, pfnCritSectRwTryEnterSharedDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5879 DECLR0CALLBACKMEMBER(int, pfnCritSectRwLeaveShared,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5880
5881 DECLR0CALLBACKMEMBER(int, pfnCritSectRwEnterExcl,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy));
5882 DECLR0CALLBACKMEMBER(int, pfnCritSectRwEnterExclDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5883 DECLR0CALLBACKMEMBER(int, pfnCritSectRwTryEnterExcl,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5884 DECLR0CALLBACKMEMBER(int, pfnCritSectRwTryEnterExclDebug,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5885 DECLR0CALLBACKMEMBER(int, pfnCritSectRwLeaveExcl,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5886
5887 DECLR0CALLBACKMEMBER(bool, pfnCritSectRwIsWriteOwner,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5888 DECLR0CALLBACKMEMBER(bool, pfnCritSectRwIsReadOwner,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, bool fWannaHear));
5889 DECLR0CALLBACKMEMBER(uint32_t, pfnCritSectRwGetWriteRecursion,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5890 DECLR0CALLBACKMEMBER(uint32_t, pfnCritSectRwGetWriterReadRecursion,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5891 DECLR0CALLBACKMEMBER(uint32_t, pfnCritSectRwGetReadCount,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5892 DECLR0CALLBACKMEMBER(bool, pfnCritSectRwIsInitialized,(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect));
5893 /** @} */
5894
5895 /**
5896 * Gets the trace buffer handle.
5897 *
5898 * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
5899 * really inteded for direct usage, thus no inline wrapper function.
5900 *
5901 * @returns Trace buffer handle or NIL_RTTRACEBUF.
5902 * @param pDevIns The device instance.
5903 */
5904 DECLR0CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
5905
5906 /**
5907 * Sets up the PCI bus for the ring-0 context.
5908 *
5909 * This must be called after ring-3 has registered the PCI bus using
5910 * PDMDevHlpPCIBusRegister().
5911 *
5912 * @returns VBox status code.
5913 * @param pDevIns The device instance.
5914 * @param pPciBusReg The PCI bus registration information for ring-0,
5915 * considered volatile and copied.
5916 * @param ppPciHlp Where to return the ring-0 PCI bus helpers.
5917 */
5918 DECLR0CALLBACKMEMBER(int, pfnPCIBusSetUpContext,(PPDMDEVINS pDevIns, PPDMPCIBUSREGR0 pPciBusReg, PCPDMPCIHLPR0 *ppPciHlp));
5919
5920 /**
5921 * Sets up the IOMMU for the ring-0 context.
5922 *
5923 * This must be called after ring-3 has registered the IOMMU using
5924 * PDMDevHlpIommuRegister().
5925 *
5926 * @returns VBox status code.
5927 * @param pDevIns The device instance.
5928 * @param pIommuReg The IOMMU registration information for ring-0,
5929 * considered volatile and copied.
5930 * @param ppIommuHlp Where to return the ring-0 IOMMU helpers.
5931 */
5932 DECLR0CALLBACKMEMBER(int, pfnIommuSetUpContext,(PPDMDEVINS pDevIns, PPDMIOMMUREGR0 pIommuReg, PCPDMIOMMUHLPR0 *ppIommuHlp));
5933
5934 /**
5935 * Sets up the PIC for the ring-0 context.
5936 *
5937 * This must be called after ring-3 has registered the PIC using
5938 * PDMDevHlpPICRegister().
5939 *
5940 * @returns VBox status code.
5941 * @param pDevIns The device instance.
5942 * @param pPicReg The PIC registration information for ring-0,
5943 * considered volatile and copied.
5944 * @param ppPicHlp Where to return the ring-0 PIC helpers.
5945 */
5946 DECLR0CALLBACKMEMBER(int, pfnPICSetUpContext,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp));
5947
5948 /**
5949 * Sets up the APIC for the ring-0 context.
5950 *
5951 * This must be called after ring-3 has registered the APIC using
5952 * PDMDevHlpApicRegister().
5953 *
5954 * @returns VBox status code.
5955 * @param pDevIns The device instance.
5956 */
5957 DECLR0CALLBACKMEMBER(int, pfnApicSetUpContext,(PPDMDEVINS pDevIns));
5958
5959 /**
5960 * Sets up the IOAPIC for the ring-0 context.
5961 *
5962 * This must be called after ring-3 has registered the PIC using
5963 * PDMDevHlpIoApicRegister().
5964 *
5965 * @returns VBox status code.
5966 * @param pDevIns The device instance.
5967 * @param pIoApicReg The PIC registration information for ring-0,
5968 * considered volatile and copied.
5969 * @param ppIoApicHlp Where to return the ring-0 IOAPIC helpers.
5970 */
5971 DECLR0CALLBACKMEMBER(int, pfnIoApicSetUpContext,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp));
5972
5973 /**
5974 * Sets up the HPET for the ring-0 context.
5975 *
5976 * This must be called after ring-3 has registered the PIC using
5977 * PDMDevHlpHpetRegister().
5978 *
5979 * @returns VBox status code.
5980 * @param pDevIns The device instance.
5981 * @param pHpetReg The PIC registration information for ring-0,
5982 * considered volatile and copied.
5983 * @param ppHpetHlp Where to return the ring-0 HPET helpers.
5984 */
5985 DECLR0CALLBACKMEMBER(int, pfnHpetSetUpContext,(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR0 *ppHpetHlp));
5986
5987 /**
5988 * Sets up a physical page access handler type for ring-0 callbacks.
5989 *
5990 * @returns VBox status code.
5991 * @param pDevIns The device instance.
5992 * @param enmKind The kind of access handler.
5993 * @param pfnHandler Pointer to the ring-0 handler callback. NULL if
5994 * the ring-3 handler should be called.
5995 * @param pfnPfHandler The name of the ring-0 \#PF handler, NULL if the
5996 * ring-3 handler should be called.
5997 * @param pszDesc The type description.
5998 * @param hType The type handle registered in ring-3 already.
5999 * @sa PDMDevHlpPGMHandlerPhysicalTypeRegister
6000 */
6001 DECLR0CALLBACKMEMBER(int, pfnPGMHandlerPhysicalTypeSetUpContext, (PPDMDEVINS pDevIns, PGMPHYSHANDLERKIND enmKind,
6002 PFNPGMPHYSHANDLER pfnHandler,
6003 PFNPGMRZPHYSPFHANDLER pfnPfHandler,
6004 const char *pszDesc, PGMPHYSHANDLERTYPE hType));
6005
6006 /**
6007 * Temporarily turns off the access monitoring of a page within a monitored
6008 * physical write/all page access handler region.
6009 *
6010 * Use this when no further \#PFs are required for that page. Be aware that
6011 * a page directory sync might reset the flags, and turn on access monitoring
6012 * for the page.
6013 *
6014 * The caller must do required page table modifications.
6015 *
6016 * @returns VBox status code.
6017 * @param pDevIns The device instance.
6018 * @param GCPhys The start address of the access handler. This
6019 * must be a fully page aligned range or we risk
6020 * messing up other handlers installed for the
6021 * start and end pages.
6022 * @param GCPhysPage The physical address of the page to turn off
6023 * access monitoring for.
6024 */
6025 DECLR0CALLBACKMEMBER(int, pfnPGMHandlerPhysicalPageTempOff,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage));
6026
6027 /**
6028 * Mapping an MMIO2 page in place of an MMIO page for direct access.
6029 *
6030 * This is a special optimization used by the VGA device. Call
6031 * PDMDevHlpMmioResetRegion() to undo the mapping.
6032 *
6033 * @returns VBox status code. This API may return VINF_SUCCESS even if no
6034 * remapping is made.
6035 * @retval VERR_SEM_BUSY in ring-0 if we cannot get the IOM lock.
6036 *
6037 * @param pDevIns The device instance @a hRegion and @a hMmio2 are
6038 * associated with.
6039 * @param hRegion The handle to the MMIO region.
6040 * @param offRegion The offset into @a hRegion of the page to be
6041 * remapped.
6042 * @param hMmio2 The MMIO2 handle.
6043 * @param offMmio2 Offset into @a hMmio2 of the page to be use for the
6044 * mapping.
6045 * @param fPageFlags Page flags to set. Must be (X86_PTE_RW | X86_PTE_P)
6046 * for the time being.
6047 */
6048 DECLR0CALLBACKMEMBER(int, pfnMmioMapMmio2Page,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS offRegion,
6049 uint64_t hMmio2, RTGCPHYS offMmio2, uint64_t fPageFlags));
6050
6051 /**
6052 * Reset a previously modified MMIO region; restore the access flags.
6053 *
6054 * This undoes the effects of PDMDevHlpMmioMapMmio2Page() and is currently only
6055 * intended for some ancient VGA hack. However, it would be great to extend it
6056 * beyond VT-x and/or nested-paging.
6057 *
6058 * @returns VBox status code.
6059 *
6060 * @param pDevIns The device instance @a hRegion is associated with.
6061 * @param hRegion The handle to the MMIO region.
6062 */
6063 DECLR0CALLBACKMEMBER(int, pfnMmioResetRegion, (PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion));
6064
6065 /**
6066 * Returns the array of MMIO2 regions that are expected to be registered and
6067 * later mapped into the guest-physical address space for the GIM provider
6068 * configured for the VM.
6069 *
6070 * @returns Pointer to an array of GIM MMIO2 regions, may return NULL.
6071 * @param pDevIns Pointer to the GIM device instance.
6072 * @param pcRegions Where to store the number of items in the array.
6073 *
6074 * @remarks The caller does not own and therefore must -NOT- try to free the
6075 * returned pointer.
6076 */
6077 DECLR0CALLBACKMEMBER(PGIMMMIO2REGION, pfnGIMGetMmio2Regions,(PPDMDEVINS pDevIns, uint32_t *pcRegions));
6078
6079 /** Space reserved for future members.
6080 * @{ */
6081 DECLR0CALLBACKMEMBER(void, pfnReserved1,(void));
6082 DECLR0CALLBACKMEMBER(void, pfnReserved2,(void));
6083 DECLR0CALLBACKMEMBER(void, pfnReserved3,(void));
6084 DECLR0CALLBACKMEMBER(void, pfnReserved4,(void));
6085 DECLR0CALLBACKMEMBER(void, pfnReserved5,(void));
6086 DECLR0CALLBACKMEMBER(void, pfnReserved6,(void));
6087 DECLR0CALLBACKMEMBER(void, pfnReserved7,(void));
6088 DECLR0CALLBACKMEMBER(void, pfnReserved8,(void));
6089 DECLR0CALLBACKMEMBER(void, pfnReserved9,(void));
6090 DECLR0CALLBACKMEMBER(void, pfnReserved10,(void));
6091 /** @} */
6092
6093 /** Just a safety precaution. */
6094 uint32_t u32TheEnd;
6095} PDMDEVHLPR0;
6096/** Pointer PDM Device R0 API. */
6097typedef R0PTRTYPE(struct PDMDEVHLPR0 *) PPDMDEVHLPR0;
6098/** Pointer PDM Device GC API. */
6099typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0;
6100
6101/** Current PDMDEVHLP version number. */
6102#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 27, 0)
6103
6104
6105/**
6106 * PDM Device Instance.
6107 */
6108typedef struct PDMDEVINSR3
6109{
6110 /** Structure version. PDM_DEVINSR3_VERSION defines the current version. */
6111 uint32_t u32Version;
6112 /** Device instance number. */
6113 uint32_t iInstance;
6114 /** Size of the ring-3, raw-mode and shared bits. */
6115 uint32_t cbRing3;
6116 /** Set if ring-0 context is enabled. */
6117 bool fR0Enabled;
6118 /** Set if raw-mode context is enabled. */
6119 bool fRCEnabled;
6120 /** Alignment padding. */
6121 bool afReserved[2];
6122 /** Pointer the HC PDM Device API. */
6123 PCPDMDEVHLPR3 pHlpR3;
6124 /** Pointer to the shared device instance data. */
6125 RTR3PTR pvInstanceDataR3;
6126 /** Pointer to the device instance data for ring-3. */
6127 RTR3PTR pvInstanceDataForR3;
6128 /** The critical section for the device.
6129 *
6130 * TM and IOM will enter this critical section before calling into the device
6131 * code. PDM will when doing power on, power off, reset, suspend and resume
6132 * notifications. SSM will currently not, but this will be changed later on.
6133 *
6134 * The device gets a critical section automatically assigned to it before
6135 * the constructor is called. If the constructor wishes to use a different
6136 * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
6137 * very early on.
6138 */
6139 R3PTRTYPE(PPDMCRITSECT) pCritSectRoR3;
6140 /** Pointer to device registration structure. */
6141 R3PTRTYPE(PCPDMDEVREG) pReg;
6142 /** Configuration handle. */
6143 R3PTRTYPE(PCFGMNODE) pCfg;
6144 /** The base interface of the device.
6145 *
6146 * The device constructor initializes this if it has any
6147 * device level interfaces to export. To obtain this interface
6148 * call PDMR3QueryDevice(). */
6149 PDMIBASE IBase;
6150
6151 /** Tracing indicator. */
6152 uint32_t fTracing;
6153 /** The tracing ID of this device. */
6154 uint32_t idTracing;
6155
6156 /** Ring-3 pointer to the raw-mode device instance. */
6157 R3PTRTYPE(struct PDMDEVINSRC *) pDevInsForRCR3;
6158 /** Raw-mode address of the raw-mode device instance. */
6159 RTRGPTR pDevInsForRC;
6160 /** Ring-3 pointer to the raw-mode instance data. */
6161 RTR3PTR pvInstanceDataForRCR3;
6162
6163 /** PCI device structure size. */
6164 uint32_t cbPciDev;
6165 /** Number of PCI devices in apPciDevs. */
6166 uint32_t cPciDevs;
6167 /** Pointer to the PCI devices for this device.
6168 * (Allocated after the shared instance data.)
6169 * @note If we want to extend this beyond 8 sub-functions/devices, those 1 or
6170 * two devices ever needing it can use cbPciDev and do the address
6171 * calculations that for entries 8+. */
6172 R3PTRTYPE(struct PDMPCIDEV *) apPciDevs[8];
6173
6174 /** Temporarily. */
6175 R0PTRTYPE(struct PDMDEVINSR0 *) pDevInsR0RemoveMe;
6176 /** Temporarily. */
6177 RTR0PTR pvInstanceDataR0;
6178 /** Temporarily. */
6179 RTRCPTR pvInstanceDataRC;
6180 /** Align the internal data more naturally. */
6181 uint32_t au32Padding[HC_ARCH_BITS == 32 ? 13 : 11];
6182
6183 /** Internal data. */
6184 union
6185 {
6186#ifdef PDMDEVINSINT_DECLARED
6187 PDMDEVINSINTR3 s;
6188#endif
6189 uint8_t padding[HC_ARCH_BITS == 32 ? 0x40 : 0x90];
6190 } Internal;
6191
6192 /** Device instance data for ring-3. The size of this area is defined
6193 * in the PDMDEVREG::cbInstanceR3 field. */
6194 char achInstanceData[8];
6195} PDMDEVINSR3;
6196
6197/** Current PDMDEVINSR3 version number. */
6198#define PDM_DEVINSR3_VERSION PDM_VERSION_MAKE(0xff82, 4, 0)
6199
6200/** Converts a pointer to the PDMDEVINSR3::IBase to a pointer to PDMDEVINS. */
6201#define PDMIBASE_2_PDMDEV(pInterface) ( (PPDMDEVINS)((char *)(pInterface) - RT_UOFFSETOF(PDMDEVINS, IBase)) )
6202
6203
6204/**
6205 * PDM ring-0 device instance.
6206 */
6207typedef struct PDMDEVINSR0
6208{
6209 /** Structure version. PDM_DEVINSR0_VERSION defines the current version. */
6210 uint32_t u32Version;
6211 /** Device instance number. */
6212 uint32_t iInstance;
6213
6214 /** Pointer the HC PDM Device API. */
6215 PCPDMDEVHLPR0 pHlpR0;
6216 /** Pointer to the shared device instance data. */
6217 RTR0PTR pvInstanceDataR0;
6218 /** Pointer to the device instance data for ring-0. */
6219 RTR0PTR pvInstanceDataForR0;
6220 /** The critical section for the device.
6221 *
6222 * TM and IOM will enter this critical section before calling into the device
6223 * code. PDM will when doing power on, power off, reset, suspend and resume
6224 * notifications. SSM will currently not, but this will be changed later on.
6225 *
6226 * The device gets a critical section automatically assigned to it before
6227 * the constructor is called. If the constructor wishes to use a different
6228 * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
6229 * very early on.
6230 */
6231 R0PTRTYPE(PPDMCRITSECT) pCritSectRoR0;
6232 /** Pointer to the ring-0 device registration structure. */
6233 R0PTRTYPE(PCPDMDEVREGR0) pReg;
6234 /** Ring-3 address of the ring-3 device instance. */
6235 R3PTRTYPE(struct PDMDEVINSR3 *) pDevInsForR3;
6236 /** Ring-0 pointer to the ring-3 device instance. */
6237 R0PTRTYPE(struct PDMDEVINSR3 *) pDevInsForR3R0;
6238 /** Ring-0 pointer to the ring-3 instance data. */
6239 RTR0PTR pvInstanceDataForR3R0;
6240 /** Raw-mode address of the raw-mode device instance. */
6241 RGPTRTYPE(struct PDMDEVINSRC *) pDevInsForRC;
6242 /** Ring-0 pointer to the raw-mode device instance. */
6243 R0PTRTYPE(struct PDMDEVINSRC *) pDevInsForRCR0;
6244 /** Ring-0 pointer to the raw-mode instance data. */
6245 RTR0PTR pvInstanceDataForRCR0;
6246
6247 /** PCI device structure size. */
6248 uint32_t cbPciDev;
6249 /** Number of PCI devices in apPciDevs. */
6250 uint32_t cPciDevs;
6251 /** Pointer to the PCI devices for this device.
6252 * (Allocated after the shared instance data.)
6253 * @note If we want to extend this beyond 8 sub-functions/devices, those 1 or
6254 * two devices ever needing it can use cbPciDev and do the address
6255 * calculations that for entries 8+. */
6256 R0PTRTYPE(struct PDMPCIDEV *) apPciDevs[8];
6257
6258 /** Align the internal data more naturally. */
6259 uint32_t au32Padding[HC_ARCH_BITS == 32 ? 3 : 2 + 4];
6260
6261 /** Internal data. */
6262 union
6263 {
6264#ifdef PDMDEVINSINT_DECLARED
6265 PDMDEVINSINTR0 s;
6266#endif
6267 uint8_t padding[HC_ARCH_BITS == 32 ? 0x40 : 0x80];
6268 } Internal;
6269
6270 /** Device instance data for ring-0. The size of this area is defined
6271 * in the PDMDEVREG::cbInstanceR0 field. */
6272 char achInstanceData[8];
6273} PDMDEVINSR0;
6274
6275/** Current PDMDEVINSR0 version number. */
6276#define PDM_DEVINSR0_VERSION PDM_VERSION_MAKE(0xff83, 4, 0)
6277
6278
6279/**
6280 * PDM raw-mode device instance.
6281 */
6282typedef struct PDMDEVINSRC
6283{
6284 /** Structure version. PDM_DEVINSRC_VERSION defines the current version. */
6285 uint32_t u32Version;
6286 /** Device instance number. */
6287 uint32_t iInstance;
6288
6289 /** Pointer the HC PDM Device API. */
6290 PCPDMDEVHLPRC pHlpRC;
6291 /** Pointer to the shared device instance data. */
6292 RTRGPTR pvInstanceDataRC;
6293 /** Pointer to the device instance data for raw-mode. */
6294 RTRGPTR pvInstanceDataForRC;
6295 /** The critical section for the device.
6296 *
6297 * TM and IOM will enter this critical section before calling into the device
6298 * code. PDM will when doing power on, power off, reset, suspend and resume
6299 * notifications. SSM will currently not, but this will be changed later on.
6300 *
6301 * The device gets a critical section automatically assigned to it before
6302 * the constructor is called. If the constructor wishes to use a different
6303 * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
6304 * very early on.
6305 */
6306 RGPTRTYPE(PPDMCRITSECT) pCritSectRoRC;
6307 /** Pointer to the raw-mode device registration structure. */
6308 RGPTRTYPE(PCPDMDEVREGRC) pReg;
6309
6310 /** PCI device structure size. */
6311 uint32_t cbPciDev;
6312 /** Number of PCI devices in apPciDevs. */
6313 uint32_t cPciDevs;
6314 /** Pointer to the PCI devices for this device.
6315 * (Allocated after the shared instance data.) */
6316 RGPTRTYPE(struct PDMPCIDEV *) apPciDevs[8];
6317
6318 /** Align the internal data more naturally. */
6319 uint32_t au32Padding[14];
6320
6321 /** Internal data. */
6322 union
6323 {
6324#ifdef PDMDEVINSINT_DECLARED
6325 PDMDEVINSINTRC s;
6326#endif
6327 uint8_t padding[0x10];
6328 } Internal;
6329
6330 /** Device instance data for ring-0. The size of this area is defined
6331 * in the PDMDEVREG::cbInstanceR0 field. */
6332 char achInstanceData[8];
6333} PDMDEVINSRC;
6334
6335/** Current PDMDEVINSR0 version number. */
6336#define PDM_DEVINSRC_VERSION PDM_VERSION_MAKE(0xff84, 4, 0)
6337
6338
6339/** @def PDM_DEVINS_VERSION
6340 * Current PDMDEVINS version number. */
6341/** @typedef PDMDEVINS
6342 * The device instance structure for the current context. */
6343#ifdef IN_RING3
6344# define PDM_DEVINS_VERSION PDM_DEVINSR3_VERSION
6345typedef PDMDEVINSR3 PDMDEVINS;
6346#elif defined(IN_RING0)
6347# define PDM_DEVINS_VERSION PDM_DEVINSR0_VERSION
6348typedef PDMDEVINSR0 PDMDEVINS;
6349#elif defined(IN_RC)
6350# define PDM_DEVINS_VERSION PDM_DEVINSRC_VERSION
6351typedef PDMDEVINSRC PDMDEVINS;
6352#else
6353# error "Missing context defines: IN_RING0, IN_RING3, IN_RC"
6354#endif
6355
6356/**
6357 * Get the pointer to an PCI device.
6358 * @note Returns NULL if @a a_idxPciDev is out of bounds.
6359 */
6360#define PDMDEV_GET_PPCIDEV(a_pDevIns, a_idxPciDev) \
6361 ( (uintptr_t)(a_idxPciDev) < RT_ELEMENTS((a_pDevIns)->apPciDevs) ? (a_pDevIns)->apPciDevs[(uintptr_t)(a_idxPciDev)] \
6362 : PDMDEV_CALC_PPCIDEV(a_pDevIns, a_idxPciDev) )
6363
6364/**
6365 * Calc the pointer to of a given PCI device.
6366 * @note Returns NULL if @a a_idxPciDev is out of bounds.
6367 */
6368#define PDMDEV_CALC_PPCIDEV(a_pDevIns, a_idxPciDev) \
6369 ( (uintptr_t)(a_idxPciDev) < (a_pDevIns)->cPciDevs \
6370 ? (PPDMPCIDEV)((uint8_t *)((a_pDevIns)->apPciDevs[0]) + (a_pDevIns->cbPciDev) * (uintptr_t)(a_idxPciDev)) \
6371 : (PPDMPCIDEV)NULL )
6372
6373
6374/**
6375 * Checks the structure versions of the device instance and device helpers,
6376 * returning if they are incompatible.
6377 *
6378 * This is for use in the constructor.
6379 *
6380 * @param pDevIns The device instance pointer.
6381 */
6382#define PDMDEV_CHECK_VERSIONS_RETURN(pDevIns) \
6383 do \
6384 { \
6385 PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
6386 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION), \
6387 ("DevIns=%#x mine=%#x\n", (pDevIns)->u32Version, PDM_DEVINS_VERSION), \
6388 VERR_PDM_DEVINS_VERSION_MISMATCH); \
6389 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->CTX_SUFF(pHlp)->u32Version, CTX_MID(PDM_DEVHLP,_VERSION)), \
6390 ("DevHlp=%#x mine=%#x\n", (pDevIns)->CTX_SUFF(pHlp)->u32Version, CTX_MID(PDM_DEVHLP,_VERSION)), \
6391 VERR_PDM_DEVHLP_VERSION_MISMATCH); \
6392 } while (0)
6393
6394/**
6395 * Quietly checks the structure versions of the device instance and device
6396 * helpers, returning if they are incompatible.
6397 *
6398 * This is for use in the destructor.
6399 *
6400 * @param pDevIns The device instance pointer.
6401 */
6402#define PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns) \
6403 do \
6404 { \
6405 PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
6406 if (RT_LIKELY(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION) )) \
6407 { /* likely */ } else return VERR_PDM_DEVINS_VERSION_MISMATCH; \
6408 if (RT_LIKELY(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->CTX_SUFF(pHlp)->u32Version, CTX_MID(PDM_DEVHLP,_VERSION)) )) \
6409 { /* likely */ } else return VERR_PDM_DEVHLP_VERSION_MISMATCH; \
6410 } while (0)
6411
6412/**
6413 * Wrapper around CFGMR3ValidateConfig for the root config for use in the
6414 * constructor - returns on failure.
6415 *
6416 * This should be invoked after having initialized the instance data
6417 * sufficiently for the correct operation of the destructor. The destructor is
6418 * always called!
6419 *
6420 * @param pDevIns Pointer to the PDM device instance.
6421 * @param pszValidValues Patterns describing the valid value names. See
6422 * RTStrSimplePatternMultiMatch for details on the
6423 * pattern syntax.
6424 * @param pszValidNodes Patterns describing the valid node (key) names.
6425 * Pass empty string if no valid nodes.
6426 */
6427#define PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, pszValidValues, pszValidNodes) \
6428 do \
6429 { \
6430 int rcValCfg = pDevIns->pHlpR3->pfnCFGMValidateConfig((pDevIns)->pCfg, "/", pszValidValues, pszValidNodes, \
6431 (pDevIns)->pReg->szName, (pDevIns)->iInstance); \
6432 if (RT_SUCCESS(rcValCfg)) \
6433 { /* likely */ } else return rcValCfg; \
6434 } while (0)
6435
6436/** @def PDMDEV_ASSERT_EMT
6437 * Assert that the current thread is the emulation thread.
6438 */
6439#ifdef VBOX_STRICT
6440# define PDMDEV_ASSERT_EMT(pDevIns) pDevIns->pHlpR3->pfnAssertEMT(pDevIns, __FILE__, __LINE__, __FUNCTION__)
6441#else
6442# define PDMDEV_ASSERT_EMT(pDevIns) do { } while (0)
6443#endif
6444
6445/** @def PDMDEV_ASSERT_OTHER
6446 * Assert that the current thread is NOT the emulation thread.
6447 */
6448#ifdef VBOX_STRICT
6449# define PDMDEV_ASSERT_OTHER(pDevIns) pDevIns->pHlpR3->pfnAssertOther(pDevIns, __FILE__, __LINE__, __FUNCTION__)
6450#else
6451# define PDMDEV_ASSERT_OTHER(pDevIns) do { } while (0)
6452#endif
6453
6454/** @def PDMDEV_ASSERT_VMLOCK_OWNER
6455 * Assert that the current thread is owner of the VM lock.
6456 */
6457#ifdef VBOX_STRICT
6458# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) pDevIns->pHlpR3->pfnAssertVMLock(pDevIns, __FILE__, __LINE__, __FUNCTION__)
6459#else
6460# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) do { } while (0)
6461#endif
6462
6463/** @def PDMDEV_SET_ERROR
6464 * Set the VM error. See PDMDevHlpVMSetError() for printf like message formatting.
6465 */
6466#define PDMDEV_SET_ERROR(pDevIns, rc, pszError) \
6467 PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, "%s", pszError)
6468
6469/** @def PDMDEV_SET_RUNTIME_ERROR
6470 * Set the VM runtime error. See PDMDevHlpVMSetRuntimeError() for printf like message formatting.
6471 */
6472#define PDMDEV_SET_RUNTIME_ERROR(pDevIns, fFlags, pszErrorId, pszError) \
6473 PDMDevHlpVMSetRuntimeError(pDevIns, fFlags, pszErrorId, "%s", pszError)
6474
6475/** @def PDMDEVINS_2_RCPTR
6476 * Converts a PDM Device instance pointer to a RC PDM Device instance pointer.
6477 */
6478#ifdef IN_RC
6479# define PDMDEVINS_2_RCPTR(pDevIns) (pDevIns)
6480#else
6481# define PDMDEVINS_2_RCPTR(pDevIns) ( (pDevIns)->pDevInsForRC )
6482#endif
6483
6484/** @def PDMDEVINS_2_R3PTR
6485 * Converts a PDM Device instance pointer to a R3 PDM Device instance pointer.
6486 */
6487#ifdef IN_RING3
6488# define PDMDEVINS_2_R3PTR(pDevIns) (pDevIns)
6489#else
6490# define PDMDEVINS_2_R3PTR(pDevIns) ( (pDevIns)->pDevInsForR3 )
6491#endif
6492
6493/** @def PDMDEVINS_2_R0PTR
6494 * Converts a PDM Device instance pointer to a R0 PDM Device instance pointer.
6495 */
6496#ifdef IN_RING0
6497# define PDMDEVINS_2_R0PTR(pDevIns) (pDevIns)
6498#else
6499# define PDMDEVINS_2_R0PTR(pDevIns) ( (pDevIns)->pDevInsR0RemoveMe )
6500#endif
6501
6502/** @def PDMDEVINS_DATA_2_R0_REMOVE_ME
6503 * Converts a PDM device instance data pointer to a ring-0 one.
6504 * @deprecated
6505 */
6506#ifdef IN_RING0
6507# define PDMDEVINS_DATA_2_R0_REMOVE_ME(pDevIns, pvCC) (pvCC)
6508#else
6509# define PDMDEVINS_DATA_2_R0_REMOVE_ME(pDevIns, pvCC) ( (pDevIns)->pvInstanceDataR0 + (uintptr_t)(pvCC) - (uintptr_t)(pDevIns)->CTX_SUFF(pvInstanceData) )
6510#endif
6511
6512
6513/** @def PDMDEVINS_2_DATA
6514 * This is a safer edition of PDMINS_2_DATA that checks that the size of the
6515 * target type is same as PDMDEVREG::cbInstanceShared in strict builds.
6516 *
6517 * @note Do no use this macro in common code working on a core structure which
6518 * device specific code has expanded.
6519 */
6520#if defined(VBOX_STRICT) && defined(RT_COMPILER_SUPPORTS_LAMBDA)
6521# define PDMDEVINS_2_DATA(a_pDevIns, a_PtrType) \
6522 ([](PPDMDEVINS a_pLambdaDevIns) -> a_PtrType \
6523 { \
6524 a_PtrType pLambdaRet = (a_PtrType)(a_pLambdaDevIns)->CTX_SUFF(pvInstanceData); \
6525 Assert(sizeof(*pLambdaRet) == a_pLambdaDevIns->pReg->cbInstanceShared); \
6526 return pLambdaRet; \
6527 }(a_pDevIns))
6528#else
6529# define PDMDEVINS_2_DATA(a_pDevIns, a_PtrType) ( (a_PtrType)(a_pDevIns)->CTX_SUFF(pvInstanceData) )
6530#endif
6531
6532/** @def PDMDEVINS_2_DATA_CC
6533 * This is a safer edition of PDMINS_2_DATA_CC that checks that the size of the
6534 * target type is same as PDMDEVREG::cbInstanceCC in strict builds.
6535 *
6536 * @note Do no use this macro in common code working on a core structure which
6537 * device specific code has expanded.
6538 */
6539#if defined(VBOX_STRICT) && defined(RT_COMPILER_SUPPORTS_LAMBDA)
6540# define PDMDEVINS_2_DATA_CC(a_pDevIns, a_PtrType) \
6541 ([](PPDMDEVINS a_pLambdaDevIns) -> a_PtrType \
6542 { \
6543 a_PtrType pLambdaRet = (a_PtrType)&(a_pLambdaDevIns)->achInstanceData[0]; \
6544 Assert(sizeof(*pLambdaRet) == a_pLambdaDevIns->pReg->cbInstanceCC); \
6545 return pLambdaRet; \
6546 }(a_pDevIns))
6547#else
6548# define PDMDEVINS_2_DATA_CC(a_pDevIns, a_PtrType) ( (a_PtrType)(void *)&(a_pDevIns)->achInstanceData[0] )
6549#endif
6550
6551
6552#ifdef IN_RING3
6553
6554/**
6555 * Combines PDMDevHlpIoPortCreate() & PDMDevHlpIoPortMap().
6556 */
6557DECLINLINE(int) PDMDevHlpIoPortCreateAndMap(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, PFNIOMIOPORTNEWOUT pfnOut,
6558 PFNIOMIOPORTNEWIN pfnIn, const char *pszDesc, PCIOMIOPORTDESC paExtDescs,
6559 PIOMIOPORTHANDLE phIoPorts)
6560{
6561 int rc = pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, 0, NULL, UINT32_MAX,
6562 pfnOut, pfnIn, NULL, NULL, NULL, pszDesc, paExtDescs, phIoPorts);
6563 if (RT_SUCCESS(rc))
6564 rc = pDevIns->pHlpR3->pfnIoPortMap(pDevIns, *phIoPorts, Port);
6565 return rc;
6566}
6567
6568/**
6569 * Combines PDMDevHlpIoPortCreate() & PDMDevHlpIoPortMap(), but with pvUser.
6570 */
6571DECLINLINE(int) PDMDevHlpIoPortCreateUAndMap(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, PFNIOMIOPORTNEWOUT pfnOut,
6572 PFNIOMIOPORTNEWIN pfnIn, void *pvUser,
6573 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
6574{
6575 int rc = pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, 0, NULL, UINT32_MAX,
6576 pfnOut, pfnIn, NULL, NULL, pvUser, pszDesc, paExtDescs, phIoPorts);
6577 if (RT_SUCCESS(rc))
6578 rc = pDevIns->pHlpR3->pfnIoPortMap(pDevIns, *phIoPorts, Port);
6579 return rc;
6580}
6581
6582/**
6583 * Combines PDMDevHlpIoPortCreate() & PDMDevHlpIoPortMap(), but with flags.
6584 */
6585DECLINLINE(int) PDMDevHlpIoPortCreateFlagsAndMap(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, uint32_t fFlags,
6586 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
6587 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
6588{
6589 int rc = pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, fFlags, NULL, UINT32_MAX,
6590 pfnOut, pfnIn, NULL, NULL, NULL, pszDesc, paExtDescs, phIoPorts);
6591 if (RT_SUCCESS(rc))
6592 rc = pDevIns->pHlpR3->pfnIoPortMap(pDevIns, *phIoPorts, Port);
6593 return rc;
6594}
6595
6596/**
6597 * Combines PDMDevHlpIoPortCreateEx() & PDMDevHlpIoPortMap().
6598 */
6599DECLINLINE(int) PDMDevHlpIoPortCreateExAndMap(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, uint32_t fFlags,
6600 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
6601 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, void *pvUser,
6602 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
6603{
6604 int rc = pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, fFlags, NULL, UINT32_MAX,
6605 pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser, pszDesc, paExtDescs, phIoPorts);
6606 if (RT_SUCCESS(rc))
6607 rc = pDevIns->pHlpR3->pfnIoPortMap(pDevIns, *phIoPorts, Port);
6608 return rc;
6609}
6610
6611/**
6612 * @sa PDMDevHlpIoPortCreateEx
6613 */
6614DECLINLINE(int) PDMDevHlpIoPortCreate(PPDMDEVINS pDevIns, RTIOPORT cPorts, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
6615 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn, void *pvUser, const char *pszDesc,
6616 PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
6617{
6618 return pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, 0, pPciDev, iPciRegion,
6619 pfnOut, pfnIn, NULL, NULL, pvUser, pszDesc, paExtDescs, phIoPorts);
6620}
6621
6622
6623/**
6624 * @sa PDMDevHlpIoPortCreateEx
6625 */
6626DECLINLINE(int) PDMDevHlpIoPortCreateIsa(PPDMDEVINS pDevIns, RTIOPORT cPorts, PFNIOMIOPORTNEWOUT pfnOut,
6627 PFNIOMIOPORTNEWIN pfnIn, void *pvUser, const char *pszDesc,
6628 PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
6629{
6630 return pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, 0, NULL, UINT32_MAX,
6631 pfnOut, pfnIn, NULL, NULL, pvUser, pszDesc, paExtDescs, phIoPorts);
6632}
6633
6634/**
6635 * @copydoc PDMDEVHLPR3::pfnIoPortCreateEx
6636 */
6637DECLINLINE(int) PDMDevHlpIoPortCreateEx(PPDMDEVINS pDevIns, RTIOPORT cPorts, uint32_t fFlags, PPDMPCIDEV pPciDev,
6638 uint32_t iPciRegion, PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
6639 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, void *pvUser,
6640 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
6641{
6642 return pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, fFlags, pPciDev, iPciRegion,
6643 pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser, pszDesc, paExtDescs, phIoPorts);
6644}
6645
6646/**
6647 * @copydoc PDMDEVHLPR3::pfnIoPortMap
6648 */
6649DECLINLINE(int) PDMDevHlpIoPortMap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT Port)
6650{
6651 return pDevIns->pHlpR3->pfnIoPortMap(pDevIns, hIoPorts, Port);
6652}
6653
6654/**
6655 * @copydoc PDMDEVHLPR3::pfnIoPortUnmap
6656 */
6657DECLINLINE(int) PDMDevHlpIoPortUnmap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)
6658{
6659 return pDevIns->pHlpR3->pfnIoPortUnmap(pDevIns, hIoPorts);
6660}
6661
6662/**
6663 * @copydoc PDMDEVHLPR3::pfnIoPortGetMappingAddress
6664 */
6665DECLINLINE(uint32_t) PDMDevHlpIoPortGetMappingAddress(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)
6666{
6667 return pDevIns->pHlpR3->pfnIoPortGetMappingAddress(pDevIns, hIoPorts);
6668}
6669
6670/**
6671 * @copydoc PDMDEVHLPR3::pfnIoPortRead
6672 */
6673DECLINLINE(VBOXSTRICTRC) PDMDevHlpIoPortRead(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)
6674{
6675 return pDevIns->pHlpR3->pfnIoPortRead(pDevIns, Port, pu32Value, cbValue);
6676}
6677
6678/**
6679 * @copydoc PDMDEVHLPR3::pfnIoPortWrite
6680 */
6681DECLINLINE(VBOXSTRICTRC) PDMDevHlpIoPortWrite(PPDMDEVINS pDevIns, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
6682{
6683 return pDevIns->pHlpR3->pfnIoPortWrite(pDevIns, Port, u32Value, cbValue);
6684}
6685
6686
6687#endif /* IN_RING3 */
6688#if !defined(IN_RING3) || defined(DOXYGEN_RUNNING)
6689
6690/**
6691 * @sa PDMDevHlpIoPortSetUpContextEx
6692 */
6693DECLINLINE(int) PDMDevHlpIoPortSetUpContext(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
6694 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn, void *pvUser)
6695{
6696 return pDevIns->CTX_SUFF(pHlp)->pfnIoPortSetUpContextEx(pDevIns, hIoPorts, pfnOut, pfnIn, NULL, NULL, pvUser);
6697}
6698
6699/**
6700 * @copydoc PDMDEVHLPR0::pfnIoPortSetUpContextEx
6701 */
6702DECLINLINE(int) PDMDevHlpIoPortSetUpContextEx(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
6703 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
6704 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, void *pvUser)
6705{
6706 return pDevIns->CTX_SUFF(pHlp)->pfnIoPortSetUpContextEx(pDevIns, hIoPorts, pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser);
6707}
6708
6709#endif /* !IN_RING3 || DOXYGEN_RUNNING */
6710#ifdef IN_RING3
6711
6712/**
6713 * @sa PDMDevHlpMmioCreateEx
6714 */
6715DECLINLINE(int) PDMDevHlpMmioCreate(PPDMDEVINS pDevIns, RTGCPHYS cbRegion, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
6716 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, void *pvUser,
6717 uint32_t fFlags, const char *pszDesc, PIOMMMIOHANDLE phRegion)
6718{
6719 return pDevIns->pHlpR3->pfnMmioCreateEx(pDevIns, cbRegion, fFlags, pPciDev, iPciRegion,
6720 pfnWrite, pfnRead, NULL, pvUser, pszDesc, phRegion);
6721}
6722
6723/**
6724 * @copydoc PDMDEVHLPR3::pfnMmioCreateEx
6725 */
6726DECLINLINE(int) PDMDevHlpMmioCreateEx(PPDMDEVINS pDevIns, RTGCPHYS cbRegion,
6727 uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
6728 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill,
6729 void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion)
6730{
6731 return pDevIns->pHlpR3->pfnMmioCreateEx(pDevIns, cbRegion, fFlags, pPciDev, iPciRegion,
6732 pfnWrite, pfnRead, pfnFill, pvUser, pszDesc, phRegion);
6733}
6734
6735/**
6736 * @sa PDMDevHlpMmioCreate and PDMDevHlpMmioMap
6737 */
6738DECLINLINE(int) PDMDevHlpMmioCreateAndMap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cbRegion,
6739 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead,
6740 uint32_t fFlags, const char *pszDesc, PIOMMMIOHANDLE phRegion)
6741{
6742 int rc = pDevIns->pHlpR3->pfnMmioCreateEx(pDevIns, cbRegion, fFlags, NULL /*pPciDev*/, UINT32_MAX /*iPciRegion*/,
6743 pfnWrite, pfnRead, NULL /*pfnFill*/, NULL /*pvUser*/, pszDesc, phRegion);
6744 if (RT_SUCCESS(rc))
6745 rc = pDevIns->pHlpR3->pfnMmioMap(pDevIns, *phRegion, GCPhys);
6746 return rc;
6747}
6748
6749/**
6750 * @sa PDMDevHlpMmioCreateEx and PDMDevHlpMmioMap
6751 */
6752DECLINLINE(int) PDMDevHlpMmioCreateExAndMap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cbRegion, uint32_t fFlags,
6753 PPDMPCIDEV pPciDev, uint32_t iPciRegion, PFNIOMMMIONEWWRITE pfnWrite,
6754 PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill, void *pvUser,
6755 const char *pszDesc, PIOMMMIOHANDLE phRegion)
6756{
6757 int rc = pDevIns->pHlpR3->pfnMmioCreateEx(pDevIns, cbRegion, fFlags, pPciDev, iPciRegion,
6758 pfnWrite, pfnRead, pfnFill, pvUser, pszDesc, phRegion);
6759 if (RT_SUCCESS(rc))
6760 rc = pDevIns->pHlpR3->pfnMmioMap(pDevIns, *phRegion, GCPhys);
6761 return rc;
6762}
6763
6764/**
6765 * @copydoc PDMDEVHLPR3::pfnMmioMap
6766 */
6767DECLINLINE(int) PDMDevHlpMmioMap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys)
6768{
6769 return pDevIns->pHlpR3->pfnMmioMap(pDevIns, hRegion, GCPhys);
6770}
6771
6772/**
6773 * @copydoc PDMDEVHLPR3::pfnMmioUnmap
6774 */
6775DECLINLINE(int) PDMDevHlpMmioUnmap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
6776{
6777 return pDevIns->pHlpR3->pfnMmioUnmap(pDevIns, hRegion);
6778}
6779
6780/**
6781 * @copydoc PDMDEVHLPR3::pfnMmioReduce
6782 */
6783DECLINLINE(int) PDMDevHlpMmioReduce(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS cbRegion)
6784{
6785 return pDevIns->pHlpR3->pfnMmioReduce(pDevIns, hRegion, cbRegion);
6786}
6787
6788/**
6789 * @copydoc PDMDEVHLPR3::pfnMmioGetMappingAddress
6790 */
6791DECLINLINE(RTGCPHYS) PDMDevHlpMmioGetMappingAddress(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
6792{
6793 return pDevIns->pHlpR3->pfnMmioGetMappingAddress(pDevIns, hRegion);
6794}
6795
6796#endif /* IN_RING3 */
6797#if !defined(IN_RING3) || defined(DOXYGEN_RUNNING)
6798
6799/**
6800 * @sa PDMDevHlpMmioSetUpContextEx
6801 */
6802DECLINLINE(int) PDMDevHlpMmioSetUpContext(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion,
6803 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, void *pvUser)
6804{
6805 return pDevIns->CTX_SUFF(pHlp)->pfnMmioSetUpContextEx(pDevIns, hRegion, pfnWrite, pfnRead, NULL, pvUser);
6806}
6807
6808/**
6809 * @copydoc PDMDEVHLPR0::pfnMmioSetUpContextEx
6810 */
6811DECLINLINE(int) PDMDevHlpMmioSetUpContextEx(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIONEWWRITE pfnWrite,
6812 PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill, void *pvUser)
6813{
6814 return pDevIns->CTX_SUFF(pHlp)->pfnMmioSetUpContextEx(pDevIns, hRegion, pfnWrite, pfnRead, pfnFill, pvUser);
6815}
6816
6817#endif /* !IN_RING3 || DOXYGEN_RUNNING */
6818#ifdef IN_RING3
6819
6820/**
6821 * @copydoc PDMDEVHLPR3::pfnMmio2Create
6822 */
6823DECLINLINE(int) PDMDevHlpMmio2Create(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iPciRegion, RTGCPHYS cbRegion,
6824 uint32_t fFlags, const char *pszDesc, void **ppvMapping, PPGMMMIO2HANDLE phRegion)
6825{
6826 return pDevIns->pHlpR3->pfnMmio2Create(pDevIns, pPciDev, iPciRegion, cbRegion, fFlags, pszDesc, ppvMapping, phRegion);
6827}
6828
6829/**
6830 * @copydoc PDMDEVHLPR3::pfnMmio2Map
6831 */
6832DECLINLINE(int) PDMDevHlpMmio2Map(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, RTGCPHYS GCPhys)
6833{
6834 return pDevIns->pHlpR3->pfnMmio2Map(pDevIns, hRegion, GCPhys);
6835}
6836
6837/**
6838 * @copydoc PDMDEVHLPR3::pfnMmio2Unmap
6839 */
6840DECLINLINE(int) PDMDevHlpMmio2Unmap(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion)
6841{
6842 return pDevIns->pHlpR3->pfnMmio2Unmap(pDevIns, hRegion);
6843}
6844
6845/**
6846 * @copydoc PDMDEVHLPR3::pfnMmio2Reduce
6847 */
6848DECLINLINE(int) PDMDevHlpMmio2Reduce(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, RTGCPHYS cbRegion)
6849{
6850 return pDevIns->pHlpR3->pfnMmio2Reduce(pDevIns, hRegion, cbRegion);
6851}
6852
6853/**
6854 * @copydoc PDMDEVHLPR3::pfnMmio2GetMappingAddress
6855 */
6856DECLINLINE(RTGCPHYS) PDMDevHlpMmio2GetMappingAddress(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion)
6857{
6858 return pDevIns->pHlpR3->pfnMmio2GetMappingAddress(pDevIns, hRegion);
6859}
6860
6861/**
6862 * @copydoc PDMDEVHLPR3::pfnMmio2QueryAndResetDirtyBitmap
6863 */
6864DECLINLINE(int) PDMDevHlpMmio2QueryAndResetDirtyBitmap(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion,
6865 void *pvBitmap, size_t cbBitmap)
6866{
6867 return pDevIns->pHlpR3->pfnMmio2QueryAndResetDirtyBitmap(pDevIns, hRegion, pvBitmap, cbBitmap);
6868}
6869
6870/**
6871 * Reset the dirty bitmap tracking for an MMIO2 region.
6872 *
6873 * The MMIO2 region must have been created with the
6874 * PGMPHYS_MMIO2_FLAGS_TRACK_DIRTY_PAGES flag for this to work.
6875 *
6876 * @returns VBox status code.
6877 * @param pDevIns The device instance.
6878 * @param hRegion The MMIO2 region handle.
6879 */
6880DECLINLINE(int) PDMDevHlpMmio2ResetDirtyBitmap(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion)
6881{
6882 return pDevIns->pHlpR3->pfnMmio2QueryAndResetDirtyBitmap(pDevIns, hRegion, NULL, 0);
6883}
6884
6885/**
6886 * @copydoc PDMDEVHLPR3::pfnMmio2ControlDirtyPageTracking
6887 */
6888DECLINLINE(int) PDMDevHlpMmio2ControlDirtyPageTracking(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion, bool fEnabled)
6889{
6890 return pDevIns->pHlpR3->pfnMmio2ControlDirtyPageTracking(pDevIns, hRegion, fEnabled);
6891}
6892
6893#endif /* IN_RING3 */
6894
6895/**
6896 * @copydoc PDMDEVHLPR3::pfnMmioMapMmio2Page
6897 */
6898DECLINLINE(int) PDMDevHlpMmioMapMmio2Page(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS offRegion,
6899 uint64_t hMmio2, RTGCPHYS offMmio2, uint64_t fPageFlags)
6900{
6901 return pDevIns->CTX_SUFF(pHlp)->pfnMmioMapMmio2Page(pDevIns, hRegion, offRegion, hMmio2, offMmio2, fPageFlags);
6902}
6903
6904/**
6905 * @copydoc PDMDEVHLPR3::pfnMmioResetRegion
6906 */
6907DECLINLINE(int) PDMDevHlpMmioResetRegion(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
6908{
6909 return pDevIns->CTX_SUFF(pHlp)->pfnMmioResetRegion(pDevIns, hRegion);
6910}
6911
6912#if !defined(IN_RING3) || defined(DOXYGEN_RUNNING)
6913
6914/**
6915 * @copydoc PDMDEVHLPR0::pfnMmio2SetUpContext
6916 */
6917DECLINLINE(int) PDMDevHlpMmio2SetUpContext(PPDMDEVINS pDevIns, PGMMMIO2HANDLE hRegion,
6918 size_t offSub, size_t cbSub, void **ppvMapping)
6919{
6920 return pDevIns->CTX_SUFF(pHlp)->pfnMmio2SetUpContext(pDevIns, hRegion, offSub, cbSub, ppvMapping);
6921}
6922
6923#endif /* !IN_RING3 || DOXYGEN_RUNNING */
6924#ifdef IN_RING3
6925
6926/**
6927 * @copydoc PDMDEVHLPR3::pfnROMRegister
6928 */
6929DECLINLINE(int) PDMDevHlpROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
6930 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
6931{
6932 return pDevIns->pHlpR3->pfnROMRegister(pDevIns, GCPhysStart, cbRange, pvBinary, cbBinary, fFlags, pszDesc);
6933}
6934
6935/**
6936 * @copydoc PDMDEVHLPR3::pfnROMProtectShadow
6937 */
6938DECLINLINE(int) PDMDevHlpROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt)
6939{
6940 return pDevIns->pHlpR3->pfnROMProtectShadow(pDevIns, GCPhysStart, cbRange, enmProt);
6941}
6942
6943/**
6944 * Register a save state data unit.
6945 *
6946 * @returns VBox status.
6947 * @param pDevIns The device instance.
6948 * @param uVersion Data layout version number.
6949 * @param cbGuess The approximate amount of data in the unit.
6950 * Only for progress indicators.
6951 * @param pfnSaveExec Execute save callback, optional.
6952 * @param pfnLoadExec Execute load callback, optional.
6953 */
6954DECLINLINE(int) PDMDevHlpSSMRegister(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
6955 PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
6956{
6957 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
6958 NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveDone*/,
6959 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
6960 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
6961}
6962
6963/**
6964 * Register a save state data unit with a live save callback as well.
6965 *
6966 * @returns VBox status.
6967 * @param pDevIns The device instance.
6968 * @param uVersion Data layout version number.
6969 * @param cbGuess The approximate amount of data in the unit.
6970 * Only for progress indicators.
6971 * @param pfnLiveExec Execute live callback, optional.
6972 * @param pfnSaveExec Execute save callback, optional.
6973 * @param pfnLoadExec Execute load callback, optional.
6974 */
6975DECLINLINE(int) PDMDevHlpSSMRegister3(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
6976 PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
6977{
6978 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
6979 NULL /*pfnLivePrep*/, pfnLiveExec, NULL /*pfnLiveDone*/,
6980 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
6981 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
6982}
6983
6984/**
6985 * @copydoc PDMDEVHLPR3::pfnSSMRegister
6986 */
6987DECLINLINE(int) PDMDevHlpSSMRegisterEx(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
6988 PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
6989 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
6990 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
6991{
6992 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, pszBefore,
6993 pfnLivePrep, pfnLiveExec, pfnLiveVote,
6994 pfnSavePrep, pfnSaveExec, pfnSaveDone,
6995 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
6996}
6997
6998/**
6999 * @copydoc PDMDEVHLPR3::pfnSSMRegisterLegacy
7000 */
7001DECLINLINE(int) PDMDevHlpSSMRegisterLegacy(PPDMDEVINS pDevIns, const char *pszOldName, PFNSSMDEVLOADPREP pfnLoadPrep,
7002 PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
7003{
7004 return pDevIns->pHlpR3->pfnSSMRegisterLegacy(pDevIns, pszOldName, pfnLoadPrep, pfnLoadExec, pfnLoadDone);
7005}
7006
7007/**
7008 * @copydoc PDMDEVHLPR3::pfnTimerCreate
7009 */
7010DECLINLINE(int) PDMDevHlpTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser,
7011 uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
7012{
7013 return pDevIns->pHlpR3->pfnTimerCreate(pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, phTimer);
7014}
7015
7016#endif /* IN_RING3 */
7017
7018/**
7019 * @copydoc PDMDEVHLPR3::pfnTimerFromMicro
7020 */
7021DECLINLINE(uint64_t) PDMDevHlpTimerFromMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
7022{
7023 return pDevIns->CTX_SUFF(pHlp)->pfnTimerFromMicro(pDevIns, hTimer, cMicroSecs);
7024}
7025
7026/**
7027 * @copydoc PDMDEVHLPR3::pfnTimerFromMilli
7028 */
7029DECLINLINE(uint64_t) PDMDevHlpTimerFromMilli(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs)
7030{
7031 return pDevIns->CTX_SUFF(pHlp)->pfnTimerFromMilli(pDevIns, hTimer, cMilliSecs);
7032}
7033
7034/**
7035 * @copydoc PDMDEVHLPR3::pfnTimerFromNano
7036 */
7037DECLINLINE(uint64_t) PDMDevHlpTimerFromNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
7038{
7039 return pDevIns->CTX_SUFF(pHlp)->pfnTimerFromNano(pDevIns, hTimer, cNanoSecs);
7040}
7041
7042/**
7043 * @copydoc PDMDEVHLPR3::pfnTimerGet
7044 */
7045DECLINLINE(uint64_t) PDMDevHlpTimerGet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
7046{
7047 return pDevIns->CTX_SUFF(pHlp)->pfnTimerGet(pDevIns, hTimer);
7048}
7049
7050/**
7051 * @copydoc PDMDEVHLPR3::pfnTimerGetFreq
7052 */
7053DECLINLINE(uint64_t) PDMDevHlpTimerGetFreq(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
7054{
7055 return pDevIns->CTX_SUFF(pHlp)->pfnTimerGetFreq(pDevIns, hTimer);
7056}
7057
7058/**
7059 * @copydoc PDMDEVHLPR3::pfnTimerGetNano
7060 */
7061DECLINLINE(uint64_t) PDMDevHlpTimerGetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
7062{
7063 return pDevIns->CTX_SUFF(pHlp)->pfnTimerGetNano(pDevIns, hTimer);
7064}
7065
7066/**
7067 * @copydoc PDMDEVHLPR3::pfnTimerIsActive
7068 */
7069DECLINLINE(bool) PDMDevHlpTimerIsActive(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
7070{
7071 return pDevIns->CTX_SUFF(pHlp)->pfnTimerIsActive(pDevIns, hTimer);
7072}
7073
7074/**
7075 * @copydoc PDMDEVHLPR3::pfnTimerIsLockOwner
7076 */
7077DECLINLINE(bool) PDMDevHlpTimerIsLockOwner(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
7078{
7079 return pDevIns->CTX_SUFF(pHlp)->pfnTimerIsLockOwner(pDevIns, hTimer);
7080}
7081
7082/**
7083 * @copydoc PDMDEVHLPR3::pfnTimerLockClock
7084 */
7085DECLINLINE(VBOXSTRICTRC) PDMDevHlpTimerLockClock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy)
7086{
7087 return pDevIns->CTX_SUFF(pHlp)->pfnTimerLockClock(pDevIns, hTimer, rcBusy);
7088}
7089
7090/**
7091 * @copydoc PDMDEVHLPR3::pfnTimerLockClock2
7092 */
7093DECLINLINE(VBOXSTRICTRC) PDMDevHlpTimerLockClock2(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect, int rcBusy)
7094{
7095 return pDevIns->CTX_SUFF(pHlp)->pfnTimerLockClock2(pDevIns, hTimer, pCritSect, rcBusy);
7096}
7097
7098/**
7099 * @copydoc PDMDEVHLPR3::pfnTimerSet
7100 */
7101DECLINLINE(int) PDMDevHlpTimerSet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire)
7102{
7103 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSet(pDevIns, hTimer, uExpire);
7104}
7105
7106/**
7107 * @copydoc PDMDEVHLPR3::pfnTimerSetFrequencyHint
7108 */
7109DECLINLINE(int) PDMDevHlpTimerSetFrequencyHint(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz)
7110{
7111 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetFrequencyHint(pDevIns, hTimer, uHz);
7112}
7113
7114/**
7115 * @copydoc PDMDEVHLPR3::pfnTimerSetMicro
7116 */
7117DECLINLINE(int) PDMDevHlpTimerSetMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
7118{
7119 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetMicro(pDevIns, hTimer, cMicrosToNext);
7120}
7121
7122/**
7123 * @copydoc PDMDEVHLPR3::pfnTimerSetMillies
7124 */
7125DECLINLINE(int) PDMDevHlpTimerSetMillies(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext)
7126{
7127 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetMillies(pDevIns, hTimer, cMilliesToNext);
7128}
7129
7130/**
7131 * @copydoc PDMDEVHLPR3::pfnTimerSetNano
7132 */
7133DECLINLINE(int) PDMDevHlpTimerSetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
7134{
7135 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetNano(pDevIns, hTimer, cNanosToNext);
7136}
7137
7138/**
7139 * @copydoc PDMDEVHLPR3::pfnTimerSetRelative
7140 */
7141DECLINLINE(int) PDMDevHlpTimerSetRelative(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
7142{
7143 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetRelative(pDevIns, hTimer, cTicksToNext, pu64Now);
7144}
7145
7146/**
7147 * @copydoc PDMDEVHLPR3::pfnTimerStop
7148 */
7149DECLINLINE(int) PDMDevHlpTimerStop(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
7150{
7151 return pDevIns->CTX_SUFF(pHlp)->pfnTimerStop(pDevIns, hTimer);
7152}
7153
7154/**
7155 * @copydoc PDMDEVHLPR3::pfnTimerUnlockClock
7156 */
7157DECLINLINE(void) PDMDevHlpTimerUnlockClock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
7158{
7159 pDevIns->CTX_SUFF(pHlp)->pfnTimerUnlockClock(pDevIns, hTimer);
7160}
7161
7162/**
7163 * @copydoc PDMDEVHLPR3::pfnTimerUnlockClock2
7164 */
7165DECLINLINE(void) PDMDevHlpTimerUnlockClock2(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
7166{
7167 pDevIns->CTX_SUFF(pHlp)->pfnTimerUnlockClock2(pDevIns, hTimer, pCritSect);
7168}
7169
7170#ifdef IN_RING3
7171
7172/**
7173 * @copydoc PDMDEVHLPR3::pfnTimerSetCritSect
7174 */
7175DECLINLINE(int) PDMDevHlpTimerSetCritSect(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PPDMCRITSECT pCritSect)
7176{
7177 return pDevIns->pHlpR3->pfnTimerSetCritSect(pDevIns, hTimer, pCritSect);
7178}
7179
7180/**
7181 * @copydoc PDMDEVHLPR3::pfnTimerSave
7182 */
7183DECLINLINE(int) PDMDevHlpTimerSave(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
7184{
7185 return pDevIns->pHlpR3->pfnTimerSave(pDevIns, hTimer, pSSM);
7186}
7187
7188/**
7189 * @copydoc PDMDEVHLPR3::pfnTimerLoad
7190 */
7191DECLINLINE(int) PDMDevHlpTimerLoad(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
7192{
7193 return pDevIns->pHlpR3->pfnTimerLoad(pDevIns, hTimer, pSSM);
7194}
7195
7196/**
7197 * @copydoc PDMDEVHLPR3::pfnTimerDestroy
7198 */
7199DECLINLINE(int) PDMDevHlpTimerDestroy(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
7200{
7201 return pDevIns->pHlpR3->pfnTimerDestroy(pDevIns, hTimer);
7202}
7203
7204/**
7205 * @copydoc PDMDEVHLPR3::pfnTMUtcNow
7206 */
7207DECLINLINE(PRTTIMESPEC) PDMDevHlpTMUtcNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
7208{
7209 return pDevIns->pHlpR3->pfnTMUtcNow(pDevIns, pTime);
7210}
7211
7212#endif
7213
7214/**
7215 * Read physical memory - unknown data usage.
7216 *
7217 * @returns VINF_SUCCESS (for now).
7218 * @param pDevIns The device instance.
7219 * @param GCPhys Physical address start reading from.
7220 * @param pvBuf Where to put the read bits.
7221 * @param cbRead How many bytes to read.
7222 * @thread Any thread, but the call may involve the emulation thread.
7223 */
7224DECLINLINE(int) PDMDevHlpPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
7225{
7226 return pDevIns->CTX_SUFF(pHlp)->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead, PDM_DEVHLP_PHYS_RW_F_DEFAULT);
7227}
7228
7229/**
7230 * Write to physical memory - unknown data usage.
7231 *
7232 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
7233 * @param pDevIns The device instance.
7234 * @param GCPhys Physical address to write to.
7235 * @param pvBuf What to write.
7236 * @param cbWrite How many bytes to write.
7237 * @thread Any thread, but the call may involve the emulation thread.
7238 */
7239DECLINLINE(int) PDMDevHlpPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
7240{
7241 return pDevIns->CTX_SUFF(pHlp)->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite, PDM_DEVHLP_PHYS_RW_F_DEFAULT);
7242}
7243
7244/**
7245 * Read physical memory - reads meta data processed by the device.
7246 *
7247 * @returns VINF_SUCCESS (for now).
7248 * @param pDevIns The device instance.
7249 * @param GCPhys Physical address start reading from.
7250 * @param pvBuf Where to put the read bits.
7251 * @param cbRead How many bytes to read.
7252 * @thread Any thread, but the call may involve the emulation thread.
7253 */
7254DECLINLINE(int) PDMDevHlpPhysReadMeta(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
7255{
7256 return pDevIns->CTX_SUFF(pHlp)->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead, PDM_DEVHLP_PHYS_RW_F_DATA_META);
7257}
7258
7259/**
7260 * Write to physical memory - written data was created/altered by the device.
7261 *
7262 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
7263 * @param pDevIns The device instance.
7264 * @param GCPhys Physical address to write to.
7265 * @param pvBuf What to write.
7266 * @param cbWrite How many bytes to write.
7267 * @thread Any thread, but the call may involve the emulation thread.
7268 */
7269DECLINLINE(int) PDMDevHlpPhysWriteMeta(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
7270{
7271 return pDevIns->CTX_SUFF(pHlp)->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite, PDM_DEVHLP_PHYS_RW_F_DATA_META);
7272}
7273
7274/**
7275 * Read physical memory - read data will not be touched by the device.
7276 *
7277 * @returns VINF_SUCCESS (for now).
7278 * @param pDevIns The device instance.
7279 * @param GCPhys Physical address start reading from.
7280 * @param pvBuf Where to put the read bits.
7281 * @param cbRead How many bytes to read.
7282 * @thread Any thread, but the call may involve the emulation thread.
7283 */
7284DECLINLINE(int) PDMDevHlpPhysReadUser(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
7285{
7286 return pDevIns->CTX_SUFF(pHlp)->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead, PDM_DEVHLP_PHYS_RW_F_DATA_USER);
7287}
7288
7289/**
7290 * Write to physical memory - written data was not touched/created by the device.
7291 *
7292 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
7293 * @param pDevIns The device instance.
7294 * @param GCPhys Physical address to write to.
7295 * @param pvBuf What to write.
7296 * @param cbWrite How many bytes to write.
7297 * @thread Any thread, but the call may involve the emulation thread.
7298 */
7299DECLINLINE(int) PDMDevHlpPhysWriteUser(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
7300{
7301 return pDevIns->CTX_SUFF(pHlp)->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite, PDM_DEVHLP_PHYS_RW_F_DATA_USER);
7302}
7303
7304#ifdef IN_RING3
7305
7306/**
7307 * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtr
7308 */
7309DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtr(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock)
7310{
7311 return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtr(pDevIns, GCPhys, fFlags, ppv, pLock);
7312}
7313
7314/**
7315 * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtrReadOnly
7316 */
7317DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void const **ppv,
7318 PPGMPAGEMAPLOCK pLock)
7319{
7320 return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhys, fFlags, ppv, pLock);
7321}
7322
7323/**
7324 * @copydoc PDMDEVHLPR3::pfnPhysReleasePageMappingLock
7325 */
7326DECLINLINE(void) PDMDevHlpPhysReleasePageMappingLock(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock)
7327{
7328 pDevIns->CTX_SUFF(pHlp)->pfnPhysReleasePageMappingLock(pDevIns, pLock);
7329}
7330
7331/**
7332 * @copydoc PDMDEVHLPR3::pfnPhysBulkGCPhys2CCPtr
7333 */
7334DECLINLINE(int) PDMDevHlpPhysBulkGCPhys2CCPtr(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
7335 uint32_t fFlags, void **papvPages, PPGMPAGEMAPLOCK paLocks)
7336{
7337 return pDevIns->CTX_SUFF(pHlp)->pfnPhysBulkGCPhys2CCPtr(pDevIns, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
7338}
7339
7340/**
7341 * @copydoc PDMDEVHLPR3::pfnPhysBulkGCPhys2CCPtrReadOnly
7342 */
7343DECLINLINE(int) PDMDevHlpPhysBulkGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
7344 uint32_t fFlags, void const **papvPages, PPGMPAGEMAPLOCK paLocks)
7345{
7346 return pDevIns->CTX_SUFF(pHlp)->pfnPhysBulkGCPhys2CCPtrReadOnly(pDevIns, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
7347}
7348
7349/**
7350 * @copydoc PDMDEVHLPR3::pfnPhysBulkReleasePageMappingLocks
7351 */
7352DECLINLINE(void) PDMDevHlpPhysBulkReleasePageMappingLocks(PPDMDEVINS pDevIns, uint32_t cPages, PPGMPAGEMAPLOCK paLocks)
7353{
7354 pDevIns->CTX_SUFF(pHlp)->pfnPhysBulkReleasePageMappingLocks(pDevIns, cPages, paLocks);
7355}
7356
7357/**
7358 * @copydoc PDMDEVHLPR3::pfnPhysIsGCPhysNormal
7359 */
7360DECLINLINE(bool) PDMDevHlpPhysIsGCPhysNormal(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
7361{
7362 return pDevIns->CTX_SUFF(pHlp)->pfnPhysIsGCPhysNormal(pDevIns, GCPhys);
7363}
7364
7365/**
7366 * @copydoc PDMDEVHLPR3::pfnPhysChangeMemBalloon
7367 */
7368DECLINLINE(int) PDMDevHlpPhysChangeMemBalloon(PPDMDEVINS pDevIns, bool fInflate, unsigned cPages, RTGCPHYS *paPhysPage)
7369{
7370 return pDevIns->CTX_SUFF(pHlp)->pfnPhysChangeMemBalloon(pDevIns, fInflate, cPages, paPhysPage);
7371}
7372
7373/**
7374 * @copydoc PDMDEVHLPR3::pfnCpuGetGuestArch
7375 */
7376DECLINLINE(CPUMARCH) PDMDevHlpCpuGetGuestArch(PPDMDEVINS pDevIns)
7377{
7378 return pDevIns->CTX_SUFF(pHlp)->pfnCpuGetGuestArch(pDevIns);
7379}
7380
7381/**
7382 * Returns a flag whether the current guest CPU architecture is x86.
7383 *
7384 * @returns Flag whether the current guest architecture is x86.
7385 * @param pDevIns The device instance.
7386 */
7387DECLINLINE(bool) PDMDevHlpCpuIsGuestArchX86(PPDMDEVINS pDevIns)
7388{
7389 return pDevIns->CTX_SUFF(pHlp)->pfnCpuGetGuestArch(pDevIns) == kCpumArch_X86;
7390}
7391
7392/**
7393 * Returns a flag whether the current guest CPU architecture is ARM.
7394 *
7395 * @returns Flag whether the current guest architecture is ARM.
7396 * @param pDevIns The device instance.
7397 */
7398DECLINLINE(bool) PDMDevHlpCpuIsGuestArchArm(PPDMDEVINS pDevIns)
7399{
7400 return pDevIns->CTX_SUFF(pHlp)->pfnCpuGetGuestArch(pDevIns) == kCpumArch_Arm;
7401}
7402
7403/**
7404 * @copydoc PDMDEVHLPR3::pfnCpuGetGuestMicroarch
7405 */
7406DECLINLINE(CPUMMICROARCH) PDMDevHlpCpuGetGuestMicroarch(PPDMDEVINS pDevIns)
7407{
7408 return pDevIns->CTX_SUFF(pHlp)->pfnCpuGetGuestMicroarch(pDevIns);
7409}
7410
7411/**
7412 * @copydoc PDMDEVHLPR3::pfnCpuGetGuestScalableBusFrequency
7413 */
7414DECLINLINE(uint64_t) PDMDevHlpCpuGetGuestScalableBusFrequency(PPDMDEVINS pDevIns)
7415{
7416 return pDevIns->CTX_SUFF(pHlp)->pfnCpuGetGuestScalableBusFrequency(pDevIns);
7417}
7418
7419/**
7420 * @copydoc PDMDEVHLPR3::pfnCpuGetGuestAddrWidths
7421 */
7422DECLINLINE(void) PDMDevHlpCpuGetGuestAddrWidths(PPDMDEVINS pDevIns, uint8_t *pcPhysAddrWidth, uint8_t *pcLinearAddrWidth)
7423{
7424 pDevIns->CTX_SUFF(pHlp)->pfnCpuGetGuestAddrWidths(pDevIns, pcPhysAddrWidth, pcLinearAddrWidth);
7425}
7426
7427/**
7428 * @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt
7429 */
7430DECLINLINE(int) PDMDevHlpPhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
7431{
7432 return pDevIns->pHlpR3->pfnPhysReadGCVirt(pDevIns, pvDst, GCVirtSrc, cb);
7433}
7434
7435/**
7436 * @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt
7437 */
7438DECLINLINE(int) PDMDevHlpPhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
7439{
7440 return pDevIns->pHlpR3->pfnPhysWriteGCVirt(pDevIns, GCVirtDst, pvSrc, cb);
7441}
7442
7443/**
7444 * @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys
7445 */
7446DECLINLINE(int) PDMDevHlpPhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
7447{
7448 return pDevIns->pHlpR3->pfnPhysGCPtr2GCPhys(pDevIns, GCPtr, pGCPhys);
7449}
7450
7451/**
7452 * @copydoc PDMDEVHLPR3::pfnMMHeapAlloc
7453 */
7454DECLINLINE(void *) PDMDevHlpMMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
7455{
7456 return pDevIns->pHlpR3->pfnMMHeapAlloc(pDevIns, cb);
7457}
7458
7459/**
7460 * @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ
7461 */
7462DECLINLINE(void *) PDMDevHlpMMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
7463{
7464 return pDevIns->pHlpR3->pfnMMHeapAllocZ(pDevIns, cb);
7465}
7466
7467/**
7468 * Allocating string printf.
7469 *
7470 * @returns Pointer to the string.
7471 * @param pDevIns The device instance.
7472 * @param enmTag The statistics tag.
7473 * @param pszFormat The format string.
7474 * @param ... Format arguments.
7475 */
7476DECLINLINE(char *) RT_IPRT_FORMAT_ATTR(2, 3) PDMDevHlpMMHeapAPrintf(PPDMDEVINS pDevIns, MMTAG enmTag, const char *pszFormat, ...)
7477{
7478 va_list va;
7479 va_start(va, pszFormat);
7480 char *psz = pDevIns->pHlpR3->pfnMMHeapAPrintfV(pDevIns, enmTag, pszFormat, va);
7481 va_end(va);
7482
7483 return psz;
7484}
7485
7486/**
7487 * @copydoc PDMDEVHLPR3::pfnMMHeapFree
7488 */
7489DECLINLINE(void) PDMDevHlpMMHeapFree(PPDMDEVINS pDevIns, void *pv)
7490{
7491 pDevIns->pHlpR3->pfnMMHeapFree(pDevIns, pv);
7492}
7493
7494/**
7495 * @copydoc PDMDEVHLPR3::pfnMMPhysGetRamSize
7496 */
7497DECLINLINE(uint64_t) PDMDevHlpMMPhysGetRamSize(PPDMDEVINS pDevIns)
7498{
7499 return pDevIns->pHlpR3->pfnMMPhysGetRamSize(pDevIns);
7500}
7501
7502/**
7503 * @copydoc PDMDEVHLPR3::pfnMMPhysGetRamSizeBelow4GB
7504 */
7505DECLINLINE(uint32_t) PDMDevHlpMMPhysGetRamSizeBelow4GB(PPDMDEVINS pDevIns)
7506{
7507 return pDevIns->pHlpR3->pfnMMPhysGetRamSizeBelow4GB(pDevIns);
7508}
7509
7510/**
7511 * @copydoc PDMDEVHLPR3::pfnMMPhysGetRamSizeAbove4GB
7512 */
7513DECLINLINE(uint64_t) PDMDevHlpMMPhysGetRamSizeAbove4GB(PPDMDEVINS pDevIns)
7514{
7515 return pDevIns->pHlpR3->pfnMMPhysGetRamSizeAbove4GB(pDevIns);
7516}
7517#endif /* IN_RING3 */
7518
7519/**
7520 * @copydoc PDMDEVHLPR3::pfnVMState
7521 */
7522DECLINLINE(VMSTATE) PDMDevHlpVMState(PPDMDEVINS pDevIns)
7523{
7524 return pDevIns->CTX_SUFF(pHlp)->pfnVMState(pDevIns);
7525}
7526
7527#ifdef IN_RING3
7528
7529/**
7530 * @copydoc PDMDEVHLPR3::pfnVMTeleportedAndNotFullyResumedYet
7531 */
7532DECLINLINE(bool) PDMDevHlpVMTeleportedAndNotFullyResumedYet(PPDMDEVINS pDevIns)
7533{
7534 return pDevIns->pHlpR3->pfnVMTeleportedAndNotFullyResumedYet(pDevIns);
7535}
7536
7537/**
7538 * Set the VM error message
7539 *
7540 * @returns rc.
7541 * @param pDevIns The device instance.
7542 * @param rc VBox status code.
7543 * @param SRC_POS Use RT_SRC_POS.
7544 * @param pszFormat Error message format string.
7545 * @param ... Error message arguments.
7546 * @sa VMSetError
7547 */
7548DECLINLINE(int) RT_IPRT_FORMAT_ATTR(6, 7) PDMDevHlpVMSetError(PPDMDEVINS pDevIns, const int rc, RT_SRC_POS_DECL,
7549 const char *pszFormat, ...)
7550{
7551 va_list va;
7552 va_start(va, pszFormat);
7553 pDevIns->CTX_SUFF(pHlp)->pfnVMSetErrorV(pDevIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
7554 va_end(va);
7555 return rc;
7556}
7557
7558/**
7559 * Set the VM runtime error message
7560 *
7561 * @returns VBox status code.
7562 * @param pDevIns The device instance.
7563 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
7564 * @param pszErrorId Error ID string.
7565 * @param pszFormat Error message format string.
7566 * @param ... Error message arguments.
7567 * @sa VMSetRuntimeError
7568 */
7569DECLINLINE(int) RT_IPRT_FORMAT_ATTR(4, 5) PDMDevHlpVMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
7570 const char *pszFormat, ...)
7571{
7572 va_list va;
7573 int rc;
7574 va_start(va, pszFormat);
7575 rc = pDevIns->CTX_SUFF(pHlp)->pfnVMSetRuntimeErrorV(pDevIns, fFlags, pszErrorId, pszFormat, va);
7576 va_end(va);
7577 return rc;
7578}
7579
7580/**
7581 * @copydoc PDMDEVHLPR3::pfnVMWaitForDeviceReady
7582 */
7583DECLINLINE(int) PDMDevHlpVMWaitForDeviceReady(PPDMDEVINS pDevIns, VMCPUID idCpu)
7584{
7585 return pDevIns->CTX_SUFF(pHlp)->pfnVMWaitForDeviceReady(pDevIns, idCpu);
7586}
7587
7588/**
7589 * @copydoc PDMDEVHLPR3::pfnVMNotifyCpuDeviceReady
7590 */
7591DECLINLINE(int) PDMDevHlpVMNotifyCpuDeviceReady(PPDMDEVINS pDevIns, VMCPUID idCpu)
7592{
7593 return pDevIns->CTX_SUFF(pHlp)->pfnVMNotifyCpuDeviceReady(pDevIns, idCpu);
7594}
7595
7596/**
7597 * Convenience wrapper for VMR3ReqCallU.
7598 *
7599 * This assumes (1) you're calling a function that returns an VBox status code
7600 * and that you do not wish to wait for it to complete.
7601 *
7602 * @returns VBox status code returned by VMR3ReqCallVU.
7603 *
7604 * @param pDevIns The device instance.
7605 * @param idDstCpu The destination CPU(s). Either a specific CPU ID or
7606 * one of the following special values:
7607 * VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
7608 * @param pfnFunction Pointer to the function to call.
7609 * @param cArgs Number of arguments following in the ellipsis.
7610 * @param ... Argument list.
7611 *
7612 * @remarks See remarks on VMR3ReqCallVU.
7613 */
7614DECLINLINE(int) PDMDevHlpVMReqCallNoWait(PPDMDEVINS pDevIns, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...)
7615{
7616 va_list Args;
7617 va_start(Args, cArgs);
7618 int rc = pDevIns->CTX_SUFF(pHlp)->pfnVMReqCallNoWaitV(pDevIns, idDstCpu, pfnFunction, cArgs, Args);
7619 va_end(Args);
7620 return rc;
7621}
7622
7623/**
7624 * Convenience wrapper for VMR3ReqCallU.
7625 *
7626 * This assumes (1) you're calling a function that returns void, (2) that you
7627 * wish to wait for ever for it to return, and (3) that it's priority request
7628 * that can be safely be handled during async suspend and power off.
7629 *
7630 * @returns VBox status code of VMR3ReqCallVU.
7631 *
7632 * @param pDevIns The device instance.
7633 * @param idDstCpu The destination CPU(s). Either a specific CPU ID or
7634 * one of the following special values:
7635 * VMCPUID_ANY, VMCPUID_ANY_QUEUE, VMCPUID_ALL or VMCPUID_ALL_REVERSE.
7636 * @param pfnFunction Pointer to the function to call.
7637 * @param cArgs Number of arguments following in the ellipsis.
7638 * @param ... Argument list.
7639 *
7640 * @remarks See remarks on VMR3ReqCallVU.
7641 */
7642DECLINLINE(int) PDMDevHlpVMReqPriorityCallWait(PPDMDEVINS pDevIns, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...)
7643{
7644 va_list Args;
7645 va_start(Args, cArgs);
7646 int rc = pDevIns->CTX_SUFF(pHlp)->pfnVMReqPriorityCallWaitV(pDevIns, idDstCpu, pfnFunction, cArgs, Args);
7647 va_end(Args);
7648 return rc;
7649}
7650
7651#endif /* IN_RING3 */
7652
7653/**
7654 * VBOX_STRICT wrapper for pHlp->pfnDBGFStopV.
7655 *
7656 * @returns VBox status code which must be passed up to the VMM. This will be
7657 * VINF_SUCCESS in non-strict builds.
7658 * @param pDevIns The device instance.
7659 * @param SRC_POS Use RT_SRC_POS.
7660 * @param pszFormat Message. (optional)
7661 * @param ... Message parameters.
7662 */
7663DECLINLINE(int) RT_IPRT_FORMAT_ATTR(5, 6) PDMDevHlpDBGFStop(PPDMDEVINS pDevIns, RT_SRC_POS_DECL, const char *pszFormat, ...)
7664{
7665#ifdef VBOX_STRICT
7666# ifdef IN_RING3
7667 int rc;
7668 va_list args;
7669 va_start(args, pszFormat);
7670 rc = pDevIns->pHlpR3->pfnDBGFStopV(pDevIns, RT_SRC_POS_ARGS, pszFormat, args);
7671 va_end(args);
7672 return rc;
7673# else
7674 NOREF(pDevIns);
7675 NOREF(pszFile);
7676 NOREF(iLine);
7677 NOREF(pszFunction);
7678 NOREF(pszFormat);
7679 return VINF_EM_DBG_STOP;
7680# endif
7681#else
7682 NOREF(pDevIns);
7683 NOREF(pszFile);
7684 NOREF(iLine);
7685 NOREF(pszFunction);
7686 NOREF(pszFormat);
7687 return VINF_SUCCESS;
7688#endif
7689}
7690
7691#ifdef IN_RING3
7692
7693/**
7694 * @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister
7695 */
7696DECLINLINE(int) PDMDevHlpDBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
7697{
7698 return pDevIns->pHlpR3->pfnDBGFInfoRegister(pDevIns, pszName, pszDesc, pfnHandler);
7699}
7700
7701/**
7702 * @copydoc PDMDEVHLPR3::pfnDBGFInfoRegisterArgv
7703 */
7704DECLINLINE(int) PDMDevHlpDBGFInfoRegisterArgv(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVDEV pfnHandler)
7705{
7706 return pDevIns->pHlpR3->pfnDBGFInfoRegisterArgv(pDevIns, pszName, pszDesc, pfnHandler);
7707}
7708
7709/**
7710 * @copydoc PDMDEVHLPR3::pfnDBGFRegRegister
7711 */
7712DECLINLINE(int) PDMDevHlpDBGFRegRegister(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters)
7713{
7714 return pDevIns->pHlpR3->pfnDBGFRegRegister(pDevIns, paRegisters);
7715}
7716
7717/**
7718 * @copydoc PDMDEVHLPR3::pfnDBGFReportBugCheck
7719 */
7720DECLINLINE(VBOXSTRICTRC) PDMDevHlpDBGFReportBugCheck(PPDMDEVINS pDevIns, DBGFEVENTTYPE enmEvent, uint64_t uBugCheck,
7721 uint64_t uP1, uint64_t uP2, uint64_t uP3, uint64_t uP4)
7722{
7723 return pDevIns->pHlpR3->pfnDBGFReportBugCheck(pDevIns, enmEvent, uBugCheck, uP1, uP2, uP3, uP4);
7724}
7725
7726/**
7727 * @copydoc PDMDEVHLPR3::pfnDBGFCoreWrite
7728 */
7729DECLINLINE(int) PDMDevHlpDBGFCoreWrite(PPDMDEVINS pDevIns, const char *pszFilename, bool fReplaceFile)
7730{
7731 return pDevIns->pHlpR3->pfnDBGFCoreWrite(pDevIns, pszFilename, fReplaceFile);
7732}
7733
7734/**
7735 * @copydoc PDMDEVHLPR3::pfnDBGFInfoLogHlp
7736 */
7737DECLINLINE(PCDBGFINFOHLP) PDMDevHlpDBGFInfoLogHlp(PPDMDEVINS pDevIns)
7738{
7739 return pDevIns->pHlpR3->pfnDBGFInfoLogHlp(pDevIns);
7740}
7741
7742/**
7743 * @copydoc PDMDEVHLPR3::pfnDBGFRegNmQueryU64
7744 */
7745DECLINLINE(int) PDMDevHlpDBGFRegNmQueryU64(PPDMDEVINS pDevIns, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64)
7746{
7747 return pDevIns->pHlpR3->pfnDBGFRegNmQueryU64(pDevIns, idDefCpu, pszReg, pu64);
7748}
7749
7750 /**
7751 * Format a set of registers.
7752 *
7753 * This is restricted to registers from one CPU, that specified by @a idCpu.
7754 *
7755 * @returns VBox status code.
7756 * @param pDevIns The device instance.
7757 * @param idCpu The CPU ID of any CPU registers that may be
7758 * printed, pass VMCPUID_ANY if not applicable.
7759 * @param pszBuf The output buffer.
7760 * @param cbBuf The size of the output buffer.
7761 * @param pszFormat The format string. Register names are given by
7762 * %VR{name}, they take no arguments.
7763 * @param ... Argument list.
7764 */
7765DECLINLINE(int) RT_IPRT_FORMAT_ATTR(4, 5) PDMDevHlpDBGFRegPrintf(PPDMDEVINS pDevIns, VMCPUID idCpu, char *pszBuf, size_t cbBuf,
7766 const char *pszFormat, ...)
7767{
7768 va_list Args;
7769 va_start(Args, pszFormat);
7770 int rc = pDevIns->pHlpR3->pfnDBGFRegPrintfV(pDevIns, idCpu, pszBuf, cbBuf, pszFormat, Args);
7771 va_end(Args);
7772 return rc;
7773}
7774
7775/**
7776 * @copydoc PDMDEVHLPR3::pfnSTAMRegister
7777 */
7778DECLINLINE(void) PDMDevHlpSTAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
7779{
7780 pDevIns->pHlpR3->pfnSTAMRegister(pDevIns, pvSample, enmType, pszName, enmUnit, pszDesc);
7781}
7782
7783/**
7784 * Same as pfnSTAMRegister except that the name is specified in a
7785 * RTStrPrintf like fashion.
7786 *
7787 * @param pDevIns Device instance of the DMA.
7788 * @param pvSample Pointer to the sample.
7789 * @param enmType Sample type. This indicates what pvSample is
7790 * pointing at.
7791 * @param enmVisibility Visibility type specifying whether unused
7792 * statistics should be visible or not.
7793 * @param enmUnit Sample unit.
7794 * @param pszDesc Sample description.
7795 * @param pszName Sample name format string, unix path style. If
7796 * this does not start with a '/', the default
7797 * prefix will be prepended, otherwise it will be
7798 * used as-is.
7799 * @param ... Arguments to the format string.
7800 */
7801DECLINLINE(void) RT_IPRT_FORMAT_ATTR(7, 8) PDMDevHlpSTAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType,
7802 STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
7803 const char *pszDesc, const char *pszName, ...)
7804{
7805 va_list va;
7806 va_start(va, pszName);
7807 pDevIns->pHlpR3->pfnSTAMRegisterV(pDevIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, va);
7808 va_end(va);
7809}
7810
7811/**
7812 * @copydoc PDMDEVHLPR3::pfnSTAMDeregisterByPrefix
7813 */
7814DECLINLINE(int) PDMDevHlpSTAMDeregisterByPrefix(PPDMDEVINS pDevIns, const char *pszPrefix)
7815{
7816 return pDevIns->pHlpR3->pfnSTAMDeregisterByPrefix(pDevIns, pszPrefix);
7817}
7818
7819/**
7820 * Registers the device with the default PCI bus.
7821 *
7822 * @returns VBox status code.
7823 * @param pDevIns The device instance.
7824 * @param pPciDev The PCI device structure.
7825 * This must be kept in the instance data.
7826 * The PCI configuration must be initialized before registration.
7827 */
7828DECLINLINE(int) PDMDevHlpPCIRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev)
7829{
7830 return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev, 0 /*fFlags*/,
7831 PDMPCIDEVREG_DEV_NO_FIRST_UNUSED, PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, NULL);
7832}
7833
7834/**
7835 * @copydoc PDMDEVHLPR3::pfnPCIRegister
7836 */
7837DECLINLINE(int) PDMDevHlpPCIRegisterEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
7838 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName)
7839{
7840 return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName);
7841}
7842
7843/**
7844 * Initialize MSI emulation support for the first PCI device.
7845 *
7846 * @returns VBox status code.
7847 * @param pDevIns The device instance.
7848 * @param pMsiReg MSI emulation registration structure.
7849 */
7850DECLINLINE(int) PDMDevHlpPCIRegisterMsi(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg)
7851{
7852 return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, NULL, pMsiReg);
7853}
7854
7855/**
7856 * @copydoc PDMDEVHLPR3::pfnPCIRegisterMsi
7857 */
7858DECLINLINE(int) PDMDevHlpPCIRegisterMsiEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg)
7859{
7860 return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, pPciDev, pMsiReg);
7861}
7862
7863/**
7864 * Registers a I/O port region for the default PCI device.
7865 *
7866 * @returns VBox status code.
7867 * @param pDevIns The device instance.
7868 * @param iRegion The region number.
7869 * @param cbRegion Size of the region.
7870 * @param hIoPorts Handle to the I/O port region.
7871 */
7872DECLINLINE(int) PDMDevHlpPCIIORegionRegisterIo(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRegion, IOMIOPORTHANDLE hIoPorts)
7873{
7874 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, NULL, iRegion, cbRegion, PCI_ADDRESS_SPACE_IO,
7875 PDMPCIDEV_IORGN_F_IOPORT_HANDLE | PDMPCIDEV_IORGN_F_NEW_STYLE, hIoPorts, NULL);
7876}
7877
7878/**
7879 * Registers a I/O port region for the default PCI device, custom map/unmap.
7880 *
7881 * @returns VBox status code.
7882 * @param pDevIns The device instance.
7883 * @param iRegion The region number.
7884 * @param cbRegion Size of the region.
7885 * @param pfnMapUnmap Callback for doing the mapping, optional. The
7886 * callback will be invoked holding only the PDM lock.
7887 * The device lock will _not_ be taken (due to lock
7888 * order).
7889 */
7890DECLINLINE(int) PDMDevHlpPCIIORegionRegisterIoCustom(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRegion,
7891 PFNPCIIOREGIONMAP pfnMapUnmap)
7892{
7893 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, NULL, iRegion, cbRegion, PCI_ADDRESS_SPACE_IO,
7894 PDMPCIDEV_IORGN_F_NO_HANDLE | PDMPCIDEV_IORGN_F_NEW_STYLE,
7895 UINT64_MAX, pfnMapUnmap);
7896}
7897
7898/**
7899 * Combines PDMDevHlpIoPortCreate and PDMDevHlpPCIIORegionRegisterIo, creating
7900 * and registering an I/O port region for the default PCI device.
7901 *
7902 * @returns VBox status code.
7903 * @param pDevIns The device instance to register the ports with.
7904 * @param cPorts The count of I/O ports in the region (the size).
7905 * @param iPciRegion The PCI device region.
7906 * @param pfnOut Pointer to function which is gonna handle OUT
7907 * operations. Optional.
7908 * @param pfnIn Pointer to function which is gonna handle IN operations.
7909 * Optional.
7910 * @param pvUser User argument to pass to the callbacks.
7911 * @param pszDesc Pointer to description string. This must not be freed.
7912 * @param paExtDescs Extended per-port descriptions, optional. Partial range
7913 * coverage is allowed. This must not be freed.
7914 * @param phIoPorts Where to return the I/O port range handle.
7915 *
7916 */
7917DECLINLINE(int) PDMDevHlpPCIIORegionCreateIo(PPDMDEVINS pDevIns, uint32_t iPciRegion, RTIOPORT cPorts,
7918 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn, void *pvUser,
7919 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
7920
7921{
7922 int rc = pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, 0 /*fFlags*/, pDevIns->apPciDevs[0], iPciRegion << 16,
7923 pfnOut, pfnIn, NULL, NULL, pvUser, pszDesc, paExtDescs, phIoPorts);
7924 if (RT_SUCCESS(rc))
7925 rc = pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, pDevIns->apPciDevs[0], iPciRegion, cPorts, PCI_ADDRESS_SPACE_IO,
7926 PDMPCIDEV_IORGN_F_IOPORT_HANDLE | PDMPCIDEV_IORGN_F_NEW_STYLE,
7927 *phIoPorts, NULL /*pfnMapUnmap*/);
7928 return rc;
7929}
7930
7931/**
7932 * Registers an MMIO region for the default PCI device.
7933 *
7934 * @returns VBox status code.
7935 * @param pDevIns The device instance.
7936 * @param iRegion The region number.
7937 * @param cbRegion Size of the region.
7938 * @param enmType PCI_ADDRESS_SPACE_MEM or
7939 * PCI_ADDRESS_SPACE_MEM_PREFETCH, optionally or-ing in
7940 * PCI_ADDRESS_SPACE_BAR64 or PCI_ADDRESS_SPACE_BAR32.
7941 * @param hMmioRegion Handle to the MMIO region.
7942 * @param pfnMapUnmap Callback for doing the mapping, optional. The
7943 * callback will be invoked holding only the PDM lock.
7944 * The device lock will _not_ be taken (due to lock
7945 * order).
7946 */
7947DECLINLINE(int) PDMDevHlpPCIIORegionRegisterMmio(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRegion, PCIADDRESSSPACE enmType,
7948 IOMMMIOHANDLE hMmioRegion, PFNPCIIOREGIONMAP pfnMapUnmap)
7949{
7950 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, NULL, iRegion, cbRegion, enmType,
7951 PDMPCIDEV_IORGN_F_MMIO_HANDLE | PDMPCIDEV_IORGN_F_NEW_STYLE,
7952 hMmioRegion, pfnMapUnmap);
7953}
7954
7955/**
7956 * Registers an MMIO region for the default PCI device, extended version.
7957 *
7958 * @returns VBox status code.
7959 * @param pDevIns The device instance.
7960 * @param pPciDev The PCI device structure.
7961 * @param iRegion The region number.
7962 * @param cbRegion Size of the region.
7963 * @param enmType PCI_ADDRESS_SPACE_MEM or
7964 * PCI_ADDRESS_SPACE_MEM_PREFETCH, optionally or-ing in
7965 * PCI_ADDRESS_SPACE_BAR64 or PCI_ADDRESS_SPACE_BAR32.
7966 * @param hMmioRegion Handle to the MMIO region.
7967 * @param pfnMapUnmap Callback for doing the mapping, optional. The
7968 * callback will be invoked holding only the PDM lock.
7969 * The device lock will _not_ be taken (due to lock
7970 * order).
7971 */
7972DECLINLINE(int) PDMDevHlpPCIIORegionRegisterMmioEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
7973 RTGCPHYS cbRegion, PCIADDRESSSPACE enmType, IOMMMIOHANDLE hMmioRegion,
7974 PFNPCIIOREGIONMAP pfnMapUnmap)
7975{
7976 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, pPciDev, iRegion, cbRegion, enmType,
7977 PDMPCIDEV_IORGN_F_MMIO_HANDLE | PDMPCIDEV_IORGN_F_NEW_STYLE,
7978 hMmioRegion, pfnMapUnmap);
7979}
7980
7981/**
7982 * Combines PDMDevHlpMmioCreate and PDMDevHlpPCIIORegionRegisterMmio, creating
7983 * and registering an MMIO region for the default PCI device.
7984 *
7985 * @returns VBox status code.
7986 * @param pDevIns The device instance to register the ports with.
7987 * @param cbRegion The size of the region in bytes.
7988 * @param iPciRegion The PCI device region.
7989 * @param enmType PCI_ADDRESS_SPACE_MEM or
7990 * PCI_ADDRESS_SPACE_MEM_PREFETCH, optionally or-ing in
7991 * PCI_ADDRESS_SPACE_BAR64 or PCI_ADDRESS_SPACE_BAR32.
7992 * @param fFlags Flags, IOMMMIO_FLAGS_XXX.
7993 * @param pfnWrite Pointer to function which is gonna handle Write
7994 * operations.
7995 * @param pfnRead Pointer to function which is gonna handle Read
7996 * operations.
7997 * @param pvUser User argument to pass to the callbacks.
7998 * @param pszDesc Pointer to description string. This must not be freed.
7999 * @param phRegion Where to return the MMIO region handle.
8000 *
8001 */
8002DECLINLINE(int) PDMDevHlpPCIIORegionCreateMmio(PPDMDEVINS pDevIns, uint32_t iPciRegion, RTGCPHYS cbRegion, PCIADDRESSSPACE enmType,
8003 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, void *pvUser,
8004 uint32_t fFlags, const char *pszDesc, PIOMMMIOHANDLE phRegion)
8005
8006{
8007 int rc = pDevIns->pHlpR3->pfnMmioCreateEx(pDevIns, cbRegion, fFlags, pDevIns->apPciDevs[0], iPciRegion << 16,
8008 pfnWrite, pfnRead, NULL /*pfnFill*/, pvUser, pszDesc, phRegion);
8009 if (RT_SUCCESS(rc))
8010 rc = pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, pDevIns->apPciDevs[0], iPciRegion, cbRegion, enmType,
8011 PDMPCIDEV_IORGN_F_MMIO_HANDLE | PDMPCIDEV_IORGN_F_NEW_STYLE,
8012 *phRegion, NULL /*pfnMapUnmap*/);
8013 return rc;
8014}
8015
8016
8017/**
8018 * Registers an MMIO2 region for the default PCI device.
8019 *
8020 * @returns VBox status code.
8021 * @param pDevIns The device instance.
8022 * @param iRegion The region number.
8023 * @param cbRegion Size of the region.
8024 * @param enmType PCI_ADDRESS_SPACE_MEM or
8025 * PCI_ADDRESS_SPACE_MEM_PREFETCH, optionally or-ing in
8026 * PCI_ADDRESS_SPACE_BAR64 or PCI_ADDRESS_SPACE_BAR32.
8027 * @param hMmio2Region Handle to the MMIO2 region.
8028 */
8029DECLINLINE(int) PDMDevHlpPCIIORegionRegisterMmio2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRegion,
8030 PCIADDRESSSPACE enmType, PGMMMIO2HANDLE hMmio2Region)
8031{
8032 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, NULL, iRegion, cbRegion, enmType,
8033 PDMPCIDEV_IORGN_F_MMIO2_HANDLE | PDMPCIDEV_IORGN_F_NEW_STYLE,
8034 hMmio2Region, NULL);
8035}
8036
8037/**
8038 * Combines PDMDevHlpMmio2Create and PDMDevHlpPCIIORegionRegisterMmio2, creating
8039 * and registering an MMIO2 region for the default PCI device, extended edition.
8040 *
8041 * @returns VBox status code.
8042 * @param pDevIns The device instance to register the ports with.
8043 * @param cbRegion The size of the region in bytes.
8044 * @param iPciRegion The PCI device region.
8045 * @param enmType PCI_ADDRESS_SPACE_MEM or
8046 * PCI_ADDRESS_SPACE_MEM_PREFETCH, optionally or-ing in
8047 * PCI_ADDRESS_SPACE_BAR64 or PCI_ADDRESS_SPACE_BAR32.
8048 * @param pszDesc Pointer to description string. This must not be freed.
8049 * @param ppvMapping Where to store the address of the ring-3 mapping of
8050 * the memory.
8051 * @param phRegion Where to return the MMIO2 region handle.
8052 *
8053 */
8054DECLINLINE(int) PDMDevHlpPCIIORegionCreateMmio2(PPDMDEVINS pDevIns, uint32_t iPciRegion, RTGCPHYS cbRegion,
8055 PCIADDRESSSPACE enmType, const char *pszDesc,
8056 void **ppvMapping, PPGMMMIO2HANDLE phRegion)
8057
8058{
8059 int rc = pDevIns->pHlpR3->pfnMmio2Create(pDevIns, pDevIns->apPciDevs[0], iPciRegion << 16, cbRegion, 0 /*fFlags*/,
8060 pszDesc, ppvMapping, phRegion);
8061 if (RT_SUCCESS(rc))
8062 rc = pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, pDevIns->apPciDevs[0], iPciRegion, cbRegion, enmType,
8063 PDMPCIDEV_IORGN_F_MMIO2_HANDLE | PDMPCIDEV_IORGN_F_NEW_STYLE,
8064 *phRegion, NULL /*pfnCallback*/);
8065 return rc;
8066}
8067
8068/**
8069 * Combines PDMDevHlpMmio2Create and PDMDevHlpPCIIORegionRegisterMmio2, creating
8070 * and registering an MMIO2 region for the default PCI device.
8071 *
8072 * @returns VBox status code.
8073 * @param pDevIns The device instance to register the ports with.
8074 * @param cbRegion The size of the region in bytes.
8075 * @param iPciRegion The PCI device region.
8076 * @param enmType PCI_ADDRESS_SPACE_MEM or
8077 * PCI_ADDRESS_SPACE_MEM_PREFETCH, optionally or-ing in
8078 * PCI_ADDRESS_SPACE_BAR64 or PCI_ADDRESS_SPACE_BAR32.
8079 * @param fMmio2Flags PGMPHYS_MMIO2_FLAGS_XXX (see pgm.h).
8080 * @param pfnMapUnmap Callback for doing the mapping, optional. The
8081 * callback will be invoked holding only the PDM lock.
8082 * The device lock will _not_ be taken (due to lock
8083 * order).
8084 * @param pszDesc Pointer to description string. This must not be freed.
8085 * @param ppvMapping Where to store the address of the ring-3 mapping of
8086 * the memory.
8087 * @param phRegion Where to return the MMIO2 region handle.
8088 *
8089 */
8090DECLINLINE(int) PDMDevHlpPCIIORegionCreateMmio2Ex(PPDMDEVINS pDevIns, uint32_t iPciRegion, RTGCPHYS cbRegion,
8091 PCIADDRESSSPACE enmType, uint32_t fMmio2Flags, PFNPCIIOREGIONMAP pfnMapUnmap,
8092 const char *pszDesc, void **ppvMapping, PPGMMMIO2HANDLE phRegion)
8093
8094{
8095 int rc = pDevIns->pHlpR3->pfnMmio2Create(pDevIns, pDevIns->apPciDevs[0], iPciRegion << 16, cbRegion, fMmio2Flags,
8096 pszDesc, ppvMapping, phRegion);
8097 if (RT_SUCCESS(rc))
8098 rc = pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, pDevIns->apPciDevs[0], iPciRegion, cbRegion, enmType,
8099 PDMPCIDEV_IORGN_F_MMIO2_HANDLE | PDMPCIDEV_IORGN_F_NEW_STYLE,
8100 *phRegion, pfnMapUnmap);
8101 return rc;
8102}
8103
8104/**
8105 * @copydoc PDMDEVHLPR3::pfnPCIInterceptConfigAccesses
8106 */
8107DECLINLINE(int) PDMDevHlpPCIInterceptConfigAccesses(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
8108 PFNPCICONFIGREAD pfnRead, PFNPCICONFIGWRITE pfnWrite)
8109{
8110 return pDevIns->pHlpR3->pfnPCIInterceptConfigAccesses(pDevIns, pPciDev, pfnRead, pfnWrite);
8111}
8112
8113/**
8114 * @copydoc PDMDEVHLPR3::pfnPCIConfigRead
8115 */
8116DECLINLINE(VBOXSTRICTRC) PDMDevHlpPCIConfigRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t uAddress,
8117 unsigned cb, uint32_t *pu32Value)
8118{
8119 return pDevIns->pHlpR3->pfnPCIConfigRead(pDevIns, pPciDev, uAddress, cb, pu32Value);
8120}
8121
8122/**
8123 * @copydoc PDMDEVHLPR3::pfnPCIConfigWrite
8124 */
8125DECLINLINE(VBOXSTRICTRC) PDMDevHlpPCIConfigWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t uAddress,
8126 unsigned cb, uint32_t u32Value)
8127{
8128 return pDevIns->pHlpR3->pfnPCIConfigWrite(pDevIns, pPciDev, uAddress, cb, u32Value);
8129}
8130
8131#endif /* IN_RING3 */
8132
8133/**
8134 * Bus master physical memory read from the default PCI device.
8135 *
8136 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
8137 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8138 * @param pDevIns The device instance.
8139 * @param GCPhys Physical address start reading from.
8140 * @param pvBuf Where to put the read bits.
8141 * @param cbRead How many bytes to read.
8142 * @thread Any thread, but the call may involve the emulation thread.
8143 */
8144DECLINLINE(int) PDMDevHlpPCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
8145{
8146 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, NULL, GCPhys, pvBuf, cbRead, PDM_DEVHLP_PHYS_RW_F_DEFAULT);
8147}
8148
8149/**
8150 * Bus master physical memory read - unknown data usage.
8151 *
8152 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
8153 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8154 * @param pDevIns The device instance.
8155 * @param pPciDev The PCI device structure. If NULL the default
8156 * PCI device for this device instance is used.
8157 * @param GCPhys Physical address start reading from.
8158 * @param pvBuf Where to put the read bits.
8159 * @param cbRead How many bytes to read.
8160 * @thread Any thread, but the call may involve the emulation thread.
8161 */
8162DECLINLINE(int) PDMDevHlpPCIPhysReadEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
8163{
8164 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, pPciDev, GCPhys, pvBuf, cbRead, PDM_DEVHLP_PHYS_RW_F_DEFAULT);
8165}
8166
8167/**
8168 * Bus master physical memory read from the default PCI device.
8169 *
8170 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
8171 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8172 * @param pDevIns The device instance.
8173 * @param GCPhys Physical address start reading from.
8174 * @param pvBuf Where to put the read bits.
8175 * @param cbRead How many bytes to read.
8176 * @thread Any thread, but the call may involve the emulation thread.
8177 */
8178DECLINLINE(int) PDMDevHlpPCIPhysReadMeta(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
8179{
8180 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, NULL, GCPhys, pvBuf, cbRead, PDM_DEVHLP_PHYS_RW_F_DATA_META);
8181}
8182
8183/**
8184 * Bus master physical memory read - reads meta data processed by the device.
8185 *
8186 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
8187 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8188 * @param pDevIns The device instance.
8189 * @param pPciDev The PCI device structure. If NULL the default
8190 * PCI device for this device instance is used.
8191 * @param GCPhys Physical address start reading from.
8192 * @param pvBuf Where to put the read bits.
8193 * @param cbRead How many bytes to read.
8194 * @thread Any thread, but the call may involve the emulation thread.
8195 */
8196DECLINLINE(int) PDMDevHlpPCIPhysReadMetaEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
8197{
8198 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, pPciDev, GCPhys, pvBuf, cbRead, PDM_DEVHLP_PHYS_RW_F_DATA_META);
8199}
8200
8201/**
8202 * Bus master physical memory read from the default PCI device - read data will not be touched by the device.
8203 *
8204 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
8205 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8206 * @param pDevIns The device instance.
8207 * @param GCPhys Physical address start reading from.
8208 * @param pvBuf Where to put the read bits.
8209 * @param cbRead How many bytes to read.
8210 * @thread Any thread, but the call may involve the emulation thread.
8211 */
8212DECLINLINE(int) PDMDevHlpPCIPhysReadUser(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
8213{
8214 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, NULL, GCPhys, pvBuf, cbRead, PDM_DEVHLP_PHYS_RW_F_DATA_USER);
8215}
8216
8217/**
8218 * Bus master physical memory read - read data will not be touched by the device.
8219 *
8220 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
8221 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8222 * @param pDevIns The device instance.
8223 * @param pPciDev The PCI device structure. If NULL the default
8224 * PCI device for this device instance is used.
8225 * @param GCPhys Physical address start reading from.
8226 * @param pvBuf Where to put the read bits.
8227 * @param cbRead How many bytes to read.
8228 * @thread Any thread, but the call may involve the emulation thread.
8229 */
8230DECLINLINE(int) PDMDevHlpPCIPhysReadUserEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
8231{
8232 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, pPciDev, GCPhys, pvBuf, cbRead, PDM_DEVHLP_PHYS_RW_F_DATA_USER);
8233}
8234
8235/**
8236 * Bus master physical memory write from the default PCI device - unknown data usage.
8237 *
8238 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
8239 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8240 * @param pDevIns The device instance.
8241 * @param GCPhys Physical address to write to.
8242 * @param pvBuf What to write.
8243 * @param cbWrite How many bytes to write.
8244 * @thread Any thread, but the call may involve the emulation thread.
8245 */
8246DECLINLINE(int) PDMDevHlpPCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
8247{
8248 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, NULL, GCPhys, pvBuf, cbWrite, PDM_DEVHLP_PHYS_RW_F_DEFAULT);
8249}
8250
8251/**
8252 * Bus master physical memory write - unknown data usage.
8253 *
8254 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
8255 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8256 * @param pDevIns The device instance.
8257 * @param pPciDev The PCI device structure. If NULL the default
8258 * PCI device for this device instance is used.
8259 * @param GCPhys Physical address to write to.
8260 * @param pvBuf What to write.
8261 * @param cbWrite How many bytes to write.
8262 * @thread Any thread, but the call may involve the emulation thread.
8263 */
8264DECLINLINE(int) PDMDevHlpPCIPhysWriteEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
8265{
8266 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, pPciDev, GCPhys, pvBuf, cbWrite, PDM_DEVHLP_PHYS_RW_F_DEFAULT);
8267}
8268
8269/**
8270 * Bus master physical memory write from the default PCI device.
8271 *
8272 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
8273 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8274 * @param pDevIns The device instance.
8275 * @param GCPhys Physical address to write to.
8276 * @param pvBuf What to write.
8277 * @param cbWrite How many bytes to write.
8278 * @thread Any thread, but the call may involve the emulation thread.
8279 */
8280DECLINLINE(int) PDMDevHlpPCIPhysWriteMeta(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
8281{
8282 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, NULL, GCPhys, pvBuf, cbWrite, PDM_DEVHLP_PHYS_RW_F_DATA_META);
8283}
8284
8285/**
8286 * Bus master physical memory write - written data was created/altered by the device.
8287 *
8288 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
8289 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8290 * @param pDevIns The device instance.
8291 * @param pPciDev The PCI device structure. If NULL the default
8292 * PCI device for this device instance is used.
8293 * @param GCPhys Physical address to write to.
8294 * @param pvBuf What to write.
8295 * @param cbWrite How many bytes to write.
8296 * @thread Any thread, but the call may involve the emulation thread.
8297 */
8298DECLINLINE(int) PDMDevHlpPCIPhysWriteMetaEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
8299{
8300 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, pPciDev, GCPhys, pvBuf, cbWrite, PDM_DEVHLP_PHYS_RW_F_DATA_META);
8301}
8302
8303/**
8304 * Bus master physical memory write from the default PCI device.
8305 *
8306 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
8307 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8308 * @param pDevIns The device instance.
8309 * @param GCPhys Physical address to write to.
8310 * @param pvBuf What to write.
8311 * @param cbWrite How many bytes to write.
8312 * @thread Any thread, but the call may involve the emulation thread.
8313 */
8314DECLINLINE(int) PDMDevHlpPCIPhysWriteUser(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
8315{
8316 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, NULL, GCPhys, pvBuf, cbWrite, PDM_DEVHLP_PHYS_RW_F_DATA_USER);
8317}
8318
8319/**
8320 * Bus master physical memory write - written data was not touched/created by the device.
8321 *
8322 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
8323 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
8324 * @param pDevIns The device instance.
8325 * @param pPciDev The PCI device structure. If NULL the default
8326 * PCI device for this device instance is used.
8327 * @param GCPhys Physical address to write to.
8328 * @param pvBuf What to write.
8329 * @param cbWrite How many bytes to write.
8330 * @thread Any thread, but the call may involve the emulation thread.
8331 */
8332DECLINLINE(int) PDMDevHlpPCIPhysWriteUserEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
8333{
8334 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, pPciDev, GCPhys, pvBuf, cbWrite, PDM_DEVHLP_PHYS_RW_F_DATA_USER);
8335}
8336
8337#ifdef IN_RING3
8338/**
8339 * @copydoc PDMDEVHLPR3::pfnPCIPhysGCPhys2CCPtr
8340 */
8341DECLINLINE(int) PDMDevHlpPCIPhysGCPhys2CCPtr(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, uint32_t fFlags,
8342 void **ppv, PPGMPAGEMAPLOCK pLock)
8343{
8344 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysGCPhys2CCPtr(pDevIns, pPciDev, GCPhys, fFlags, ppv, pLock);
8345}
8346
8347/**
8348 * @copydoc PDMDEVHLPR3::pfnPCIPhysGCPhys2CCPtrReadOnly
8349 */
8350DECLINLINE(int) PDMDevHlpPCIPhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, uint32_t fFlags,
8351 void const **ppv, PPGMPAGEMAPLOCK pLock)
8352{
8353 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysGCPhys2CCPtrReadOnly(pDevIns, pPciDev, GCPhys, fFlags, ppv, pLock);
8354}
8355
8356/**
8357 * @copydoc PDMDEVHLPR3::pfnPCIPhysBulkGCPhys2CCPtr
8358 */
8359DECLINLINE(int) PDMDevHlpPCIPhysBulkGCPhys2CCPtr(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t cPages,
8360 PCRTGCPHYS paGCPhysPages, uint32_t fFlags, void **papvPages,
8361 PPGMPAGEMAPLOCK paLocks)
8362{
8363 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysBulkGCPhys2CCPtr(pDevIns, pPciDev, cPages, paGCPhysPages, fFlags, papvPages,
8364 paLocks);
8365}
8366
8367/**
8368 * @copydoc PDMDEVHLPR3::pfnPCIPhysBulkGCPhys2CCPtrReadOnly
8369 */
8370DECLINLINE(int) PDMDevHlpPCIPhysBulkGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t cPages,
8371 PCRTGCPHYS paGCPhysPages, uint32_t fFlags, void const **papvPages,
8372 PPGMPAGEMAPLOCK paLocks)
8373{
8374 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysBulkGCPhys2CCPtrReadOnly(pDevIns, pPciDev, cPages, paGCPhysPages, fFlags,
8375 papvPages, paLocks);
8376}
8377#endif /* IN_RING3 */
8378
8379/**
8380 * Sets the IRQ for the default PCI device.
8381 *
8382 * @param pDevIns The device instance.
8383 * @param iIrq IRQ number to set.
8384 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
8385 * @thread Any thread, but will involve the emulation thread.
8386 */
8387DECLINLINE(void) PDMDevHlpPCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
8388{
8389 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, NULL, iIrq, iLevel);
8390}
8391
8392/**
8393 * @copydoc PDMDEVHLPR3::pfnPCISetIrq
8394 */
8395DECLINLINE(void) PDMDevHlpPCISetIrqEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
8396{
8397 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, pPciDev, iIrq, iLevel);
8398}
8399
8400/**
8401 * Sets the IRQ for the given PCI device, but doesn't wait for EMT to process
8402 * the request when not called from EMT.
8403 *
8404 * @param pDevIns The device instance.
8405 * @param iIrq IRQ number to set.
8406 * @param iLevel IRQ level.
8407 * @thread Any thread, but will involve the emulation thread.
8408 */
8409DECLINLINE(void) PDMDevHlpPCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
8410{
8411 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, NULL, iIrq, iLevel);
8412}
8413
8414/**
8415 * @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait
8416 */
8417DECLINLINE(void) PDMDevHlpPCISetIrqNoWaitEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
8418{
8419 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, pPciDev, iIrq, iLevel);
8420}
8421
8422/**
8423 * @copydoc PDMDEVHLPR3::pfnISASetIrq
8424 */
8425DECLINLINE(void) PDMDevHlpISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
8426{
8427 pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
8428}
8429
8430/**
8431 * @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait
8432 */
8433DECLINLINE(void) PDMDevHlpISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
8434{
8435 pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
8436}
8437
8438#ifdef IN_RING3
8439
8440/**
8441 * @copydoc PDMDEVHLPR3::pfnDriverAttach
8442 */
8443DECLINLINE(int) PDMDevHlpDriverAttach(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
8444{
8445 return pDevIns->pHlpR3->pfnDriverAttach(pDevIns, iLun, pBaseInterface, ppBaseInterface, pszDesc);
8446}
8447
8448/**
8449 * @copydoc PDMDEVHLPR3::pfnDriverDetach
8450 */
8451DECLINLINE(int) PDMDevHlpDriverDetach(PPDMDEVINS pDevIns, PPDMDRVINS pDrvIns, uint32_t fFlags)
8452{
8453 return pDevIns->pHlpR3->pfnDriverDetach(pDevIns, pDrvIns, fFlags);
8454}
8455
8456/**
8457 * @copydoc PDMDEVHLPR3::pfnDriverReconfigure
8458 */
8459DECLINLINE(int) PDMDevHlpDriverReconfigure(PPDMDEVINS pDevIns, uint32_t iLun, uint32_t cDepth,
8460 const char * const *papszDrivers, PCFGMNODE *papConfigs, uint32_t fFlags)
8461{
8462 return pDevIns->pHlpR3->pfnDriverReconfigure(pDevIns, iLun, cDepth, papszDrivers, papConfigs, fFlags);
8463}
8464
8465/**
8466 * Reconfigures with a single driver reattachement, no config, noflags.
8467 * @sa PDMDevHlpDriverReconfigure
8468 */
8469DECLINLINE(int) PDMDevHlpDriverReconfigure1(PPDMDEVINS pDevIns, uint32_t iLun, const char *pszDriver0)
8470{
8471 return pDevIns->pHlpR3->pfnDriverReconfigure(pDevIns, iLun, 1, &pszDriver0, NULL, 0);
8472}
8473
8474/**
8475 * Reconfigures with a two drivers reattachement, no config, noflags.
8476 * @sa PDMDevHlpDriverReconfigure
8477 */
8478DECLINLINE(int) PDMDevHlpDriverReconfigure2(PPDMDEVINS pDevIns, uint32_t iLun, const char *pszDriver0, const char *pszDriver1)
8479{
8480 char const * apszDrivers[2];
8481 apszDrivers[0] = pszDriver0;
8482 apszDrivers[1] = pszDriver1;
8483 return pDevIns->pHlpR3->pfnDriverReconfigure(pDevIns, iLun, 2, apszDrivers, NULL, 0);
8484}
8485
8486/**
8487 * @copydoc PDMDEVHLPR3::pfnQueueCreate
8488 */
8489DECLINLINE(int) PDMDevHlpQueueCreate(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
8490 PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PDMQUEUEHANDLE *phQueue)
8491{
8492 return pDevIns->pHlpR3->pfnQueueCreate(pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fRZEnabled, pszName, phQueue);
8493}
8494
8495#endif /* IN_RING3 */
8496
8497/**
8498 * @copydoc PDMDEVHLPR3::pfnQueueAlloc
8499 */
8500DECLINLINE(PPDMQUEUEITEMCORE) PDMDevHlpQueueAlloc(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue)
8501{
8502 return pDevIns->CTX_SUFF(pHlp)->pfnQueueAlloc(pDevIns, hQueue);
8503}
8504
8505/**
8506 * @copydoc PDMDEVHLPR3::pfnQueueInsert
8507 */
8508DECLINLINE(int) PDMDevHlpQueueInsert(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue, PPDMQUEUEITEMCORE pItem)
8509{
8510 return pDevIns->CTX_SUFF(pHlp)->pfnQueueInsert(pDevIns, hQueue, pItem);
8511}
8512
8513/**
8514 * @copydoc PDMDEVHLPR3::pfnQueueFlushIfNecessary
8515 */
8516DECLINLINE(bool) PDMDevHlpQueueFlushIfNecessary(PPDMDEVINS pDevIns, PDMQUEUEHANDLE hQueue)
8517{
8518 return pDevIns->CTX_SUFF(pHlp)->pfnQueueFlushIfNecessary(pDevIns, hQueue);
8519}
8520
8521#ifdef IN_RING3
8522/**
8523 * @copydoc PDMDEVHLPR3::pfnTaskCreate
8524 */
8525DECLINLINE(int) PDMDevHlpTaskCreate(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszName,
8526 PFNPDMTASKDEV pfnCallback, void *pvUser, PDMTASKHANDLE *phTask)
8527{
8528 return pDevIns->pHlpR3->pfnTaskCreate(pDevIns, fFlags, pszName, pfnCallback, pvUser, phTask);
8529}
8530#endif
8531
8532/**
8533 * @copydoc PDMDEVHLPR3::pfnTaskTrigger
8534 */
8535DECLINLINE(int) PDMDevHlpTaskTrigger(PPDMDEVINS pDevIns, PDMTASKHANDLE hTask)
8536{
8537 return pDevIns->CTX_SUFF(pHlp)->pfnTaskTrigger(pDevIns, hTask);
8538}
8539
8540#ifdef IN_RING3
8541
8542/**
8543 * @copydoc PDMDEVHLPR3::pfnSUPSemEventCreate
8544 */
8545DECLINLINE(int) PDMDevHlpSUPSemEventCreate(PPDMDEVINS pDevIns, PSUPSEMEVENT phEvent)
8546{
8547 return pDevIns->pHlpR3->pfnSUPSemEventCreate(pDevIns, phEvent);
8548}
8549
8550/**
8551 * @copydoc PDMDEVHLPR3::pfnSUPSemEventClose
8552 */
8553DECLINLINE(int) PDMDevHlpSUPSemEventClose(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent)
8554{
8555 return pDevIns->pHlpR3->pfnSUPSemEventClose(pDevIns, hEvent);
8556}
8557
8558#endif /* IN_RING3 */
8559
8560/**
8561 * @copydoc PDMDEVHLPR3::pfnSUPSemEventSignal
8562 */
8563DECLINLINE(int) PDMDevHlpSUPSemEventSignal(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent)
8564{
8565 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventSignal(pDevIns, hEvent);
8566}
8567
8568/**
8569 * @copydoc PDMDEVHLPR3::pfnSUPSemEventWaitNoResume
8570 */
8571DECLINLINE(int) PDMDevHlpSUPSemEventWaitNoResume(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint32_t cMillies)
8572{
8573 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventWaitNoResume(pDevIns, hEvent, cMillies);
8574}
8575
8576/**
8577 * @copydoc PDMDEVHLPR3::pfnSUPSemEventWaitNsAbsIntr
8578 */
8579DECLINLINE(int) PDMDevHlpSUPSemEventWaitNsAbsIntr(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t uNsTimeout)
8580{
8581 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventWaitNsAbsIntr(pDevIns, hEvent, uNsTimeout);
8582}
8583
8584/**
8585 * @copydoc PDMDEVHLPR3::pfnSUPSemEventWaitNsRelIntr
8586 */
8587DECLINLINE(int) PDMDevHlpSUPSemEventWaitNsRelIntr(PPDMDEVINS pDevIns, SUPSEMEVENT hEvent, uint64_t cNsTimeout)
8588{
8589 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventWaitNsRelIntr(pDevIns, hEvent, cNsTimeout);
8590}
8591
8592/**
8593 * @copydoc PDMDEVHLPR3::pfnSUPSemEventGetResolution
8594 */
8595DECLINLINE(uint32_t) PDMDevHlpSUPSemEventGetResolution(PPDMDEVINS pDevIns)
8596{
8597 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventGetResolution(pDevIns);
8598}
8599
8600#ifdef IN_RING3
8601
8602/**
8603 * @copydoc PDMDEVHLPR3::pfnSUPSemEventMultiCreate
8604 */
8605DECLINLINE(int) PDMDevHlpSUPSemEventMultiCreate(PPDMDEVINS pDevIns, PSUPSEMEVENTMULTI phEventMulti)
8606{
8607 return pDevIns->pHlpR3->pfnSUPSemEventMultiCreate(pDevIns, phEventMulti);
8608}
8609
8610/**
8611 * @copydoc PDMDEVHLPR3::pfnSUPSemEventMultiClose
8612 */
8613DECLINLINE(int) PDMDevHlpSUPSemEventMultiClose(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
8614{
8615 return pDevIns->pHlpR3->pfnSUPSemEventMultiClose(pDevIns, hEventMulti);
8616}
8617
8618#endif /* IN_RING3 */
8619
8620/**
8621 * @copydoc PDMDEVHLPR3::pfnSUPSemEventMultiSignal
8622 */
8623DECLINLINE(int) PDMDevHlpSUPSemEventMultiSignal(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
8624{
8625 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventMultiSignal(pDevIns, hEventMulti);
8626}
8627
8628/**
8629 * @copydoc PDMDEVHLPR3::pfnSUPSemEventMultiReset
8630 */
8631DECLINLINE(int) PDMDevHlpSUPSemEventMultiReset(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti)
8632{
8633 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventMultiReset(pDevIns, hEventMulti);
8634}
8635
8636/**
8637 * @copydoc PDMDEVHLPR3::pfnSUPSemEventMultiWaitNoResume
8638 */
8639DECLINLINE(int) PDMDevHlpSUPSemEventMultiWaitNoResume(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies)
8640{
8641 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventMultiWaitNsRelIntr(pDevIns, hEventMulti, cMillies);
8642}
8643
8644/**
8645 * @copydoc PDMDEVHLPR3::pfnSUPSemEventMultiWaitNsAbsIntr
8646 */
8647DECLINLINE(int) PDMDevHlpSUPSemEventMultiWaitNsAbsIntr(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout)
8648{
8649 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventMultiWaitNsAbsIntr(pDevIns, hEventMulti, uNsTimeout);
8650}
8651
8652/**
8653 * @copydoc PDMDEVHLPR3::pfnSUPSemEventMultiWaitNsRelIntr
8654 */
8655DECLINLINE(int) PDMDevHlpSUPSemEventMultiWaitNsRelIntr(PPDMDEVINS pDevIns, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout)
8656{
8657 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventMultiWaitNsRelIntr(pDevIns, hEventMulti, cNsTimeout);
8658}
8659
8660/**
8661 * @copydoc PDMDEVHLPR3::pfnSUPSemEventMultiGetResolution
8662 */
8663DECLINLINE(uint32_t) PDMDevHlpSUPSemEventMultiGetResolution(PPDMDEVINS pDevIns)
8664{
8665 return pDevIns->CTX_SUFF(pHlp)->pfnSUPSemEventMultiGetResolution(pDevIns);
8666}
8667
8668#ifdef IN_RING3
8669
8670/**
8671 * Initializes a PDM critical section.
8672 *
8673 * The PDM critical sections are derived from the IPRT critical sections, but
8674 * works in RC and R0 as well.
8675 *
8676 * @returns VBox status code.
8677 * @param pDevIns The device instance.
8678 * @param pCritSect Pointer to the critical section.
8679 * @param SRC_POS Use RT_SRC_POS.
8680 * @param pszNameFmt Format string for naming the critical section.
8681 * For statistics and lock validation.
8682 * @param ... Arguments for the format string.
8683 */
8684DECLINLINE(int) RT_IPRT_FORMAT_ATTR(6, 7) PDMDevHlpCritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
8685 const char *pszNameFmt, ...)
8686{
8687 int rc;
8688 va_list va;
8689 va_start(va, pszNameFmt);
8690 rc = pDevIns->pHlpR3->pfnCritSectInit(pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
8691 va_end(va);
8692 return rc;
8693}
8694
8695#endif /* IN_RING3 */
8696
8697/**
8698 * @copydoc PDMDEVHLPR3::pfnCritSectGetNop
8699 */
8700DECLINLINE(PPDMCRITSECT) PDMDevHlpCritSectGetNop(PPDMDEVINS pDevIns)
8701{
8702 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectGetNop(pDevIns);
8703}
8704
8705/**
8706 * @copydoc PDMDEVHLPR3::pfnSetDeviceCritSect
8707 */
8708DECLINLINE(int) PDMDevHlpSetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
8709{
8710 return pDevIns->CTX_SUFF(pHlp)->pfnSetDeviceCritSect(pDevIns, pCritSect);
8711}
8712
8713/**
8714 * Enters a PDM critical section.
8715 *
8716 * @returns VINF_SUCCESS if entered successfully.
8717 * @returns rcBusy when encountering a busy critical section in RC/R0.
8718 * @retval VERR_SEM_DESTROYED if the critical section is delete before or
8719 * during the operation.
8720 *
8721 * @param pDevIns The device instance.
8722 * @param pCritSect The PDM critical section to enter.
8723 * @param rcBusy The status code to return when we're in RC or R0
8724 * and the section is busy. Pass VINF_SUCCESS to
8725 * acquired the critical section thru a ring-3
8726 * call if necessary.
8727 *
8728 * @note Even callers setting @a rcBusy to VINF_SUCCESS must either handle
8729 * possible failures in ring-0 or at least apply
8730 * PDM_CRITSECT_RELEASE_ASSERT_RC_DEV() to the return value of this
8731 * function.
8732 *
8733 * @sa PDMCritSectEnter
8734 */
8735DECLINLINE(DECL_CHECK_RETURN(int)) PDMDevHlpCritSectEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy)
8736{
8737 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectEnter(pDevIns, pCritSect, rcBusy);
8738}
8739
8740/**
8741 * Enters a PDM critical section, with location information for debugging.
8742 *
8743 * @returns VINF_SUCCESS if entered successfully.
8744 * @returns rcBusy when encountering a busy critical section in RC/R0.
8745 * @retval VERR_SEM_DESTROYED if the critical section is delete before or
8746 * during the operation.
8747 *
8748 * @param pDevIns The device instance.
8749 * @param pCritSect The PDM critical section to enter.
8750 * @param rcBusy The status code to return when we're in RC or R0
8751 * and the section is busy. Pass VINF_SUCCESS to
8752 * acquired the critical section thru a ring-3
8753 * call if necessary.
8754 * @param uId Some kind of locking location ID. Typically a
8755 * return address up the stack. Optional (0).
8756 * @param SRC_POS The source position where to lock is being
8757 * acquired from. Optional.
8758 * @sa PDMCritSectEnterDebug
8759 */
8760DECLINLINE(DECL_CHECK_RETURN(int))
8761PDMDevHlpCritSectEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL)
8762{
8763 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectEnterDebug(pDevIns, pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
8764}
8765
8766/**
8767 * Try enter a critical section.
8768 *
8769 * @retval VINF_SUCCESS on success.
8770 * @retval VERR_SEM_BUSY if the critsect was owned.
8771 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
8772 * @retval VERR_SEM_DESTROYED if the critical section is delete before or
8773 * during the operation.
8774 *
8775 * @param pDevIns The device instance.
8776 * @param pCritSect The critical section.
8777 * @sa PDMCritSectTryEnter
8778 */
8779DECLINLINE(DECL_CHECK_RETURN(int))
8780PDMDevHlpCritSectTryEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
8781{
8782 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectTryEnter(pDevIns, pCritSect);
8783}
8784
8785/**
8786 * Try enter a critical section, with location information for debugging.
8787 *
8788 * @retval VINF_SUCCESS on success.
8789 * @retval VERR_SEM_BUSY if the critsect was owned.
8790 * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
8791 * @retval VERR_SEM_DESTROYED if the critical section is delete before or
8792 * during the operation.
8793 *
8794 * @param pDevIns The device instance.
8795 * @param pCritSect The critical section.
8796 * @param uId Some kind of locking location ID. Typically a
8797 * return address up the stack. Optional (0).
8798 * @param SRC_POS The source position where to lock is being
8799 * acquired from. Optional.
8800 * @sa PDMCritSectTryEnterDebug
8801 */
8802DECLINLINE(DECL_CHECK_RETURN(int))
8803PDMDevHlpCritSectTryEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL)
8804{
8805 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectTryEnterDebug(pDevIns, pCritSect, uId, RT_SRC_POS_ARGS);
8806}
8807
8808/**
8809 * Leaves a critical section entered with PDMCritSectEnter().
8810 *
8811 * @returns Indication whether we really exited the critical section.
8812 * @retval VINF_SUCCESS if we really exited.
8813 * @retval VINF_SEM_NESTED if we only reduced the nesting count.
8814 * @retval VERR_NOT_OWNER if you somehow ignore release assertions.
8815 *
8816 * @param pDevIns The device instance.
8817 * @param pCritSect The PDM critical section to leave.
8818 * @sa PDMCritSectLeave
8819 */
8820DECLINLINE(int) PDMDevHlpCritSectLeave(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
8821{
8822 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectLeave(pDevIns, pCritSect);
8823}
8824
8825/**
8826 * @see PDMCritSectIsOwner
8827 */
8828DECLINLINE(bool) PDMDevHlpCritSectIsOwner(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
8829{
8830 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectIsOwner(pDevIns, pCritSect);
8831}
8832
8833/**
8834 * @see PDMCritSectIsInitialized
8835 */
8836DECLINLINE(bool) PDMDevHlpCritSectIsInitialized(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
8837{
8838 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectIsInitialized(pDevIns, pCritSect);
8839}
8840
8841/**
8842 * @see PDMCritSectHasWaiters
8843 */
8844DECLINLINE(bool) PDMDevHlpCritSectHasWaiters(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
8845{
8846 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectHasWaiters(pDevIns, pCritSect);
8847}
8848
8849/**
8850 * @see PDMCritSectGetRecursion
8851 */
8852DECLINLINE(uint32_t) PDMDevHlpCritSectGetRecursion(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
8853{
8854 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectGetRecursion(pDevIns, pCritSect);
8855}
8856
8857#if defined(IN_RING3) || defined(IN_RING0)
8858/**
8859 * @see PDMHCCritSectScheduleExitEvent
8860 */
8861DECLINLINE(int) PDMDevHlpCritSectScheduleExitEvent(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, SUPSEMEVENT hEventToSignal)
8862{
8863 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectScheduleExitEvent(pDevIns, pCritSect, hEventToSignal);
8864}
8865#endif
8866
8867/* Strict build: Remap the two enter calls to the debug versions. */
8868#ifdef VBOX_STRICT
8869# ifdef IPRT_INCLUDED_asm_h
8870# define PDMDevHlpCritSectEnter(pDevIns, pCritSect, rcBusy) PDMDevHlpCritSectEnterDebug((pDevIns), (pCritSect), (rcBusy), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
8871# define PDMDevHlpCritSectTryEnter(pDevIns, pCritSect) PDMDevHlpCritSectTryEnterDebug((pDevIns), (pCritSect), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
8872# else
8873# define PDMDevHlpCritSectEnter(pDevIns, pCritSect, rcBusy) PDMDevHlpCritSectEnterDebug((pDevIns), (pCritSect), (rcBusy), 0, RT_SRC_POS)
8874# define PDMDevHlpCritSectTryEnter(pDevIns, pCritSect) PDMDevHlpCritSectTryEnterDebug((pDevIns), (pCritSect), 0, RT_SRC_POS)
8875# endif
8876#endif
8877
8878#if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
8879
8880/**
8881 * Deletes the critical section.
8882 *
8883 * @returns VBox status code.
8884 * @param pDevIns The device instance.
8885 * @param pCritSect The PDM critical section to destroy.
8886 * @sa PDMR3CritSectDelete
8887 */
8888DECLINLINE(int) PDMDevHlpCritSectDelete(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
8889{
8890 return pDevIns->pHlpR3->pfnCritSectDelete(pDevIns, pCritSect);
8891}
8892
8893/**
8894 * Initializes a PDM read/write critical section.
8895 *
8896 * The PDM read/write critical sections are derived from the IPRT critical
8897 * sections, but works in RC and R0 as well.
8898 *
8899 * @returns VBox status code.
8900 * @param pDevIns The device instance.
8901 * @param pCritSect Pointer to the read/write critical section.
8902 * @param SRC_POS Use RT_SRC_POS.
8903 * @param pszNameFmt Format string for naming the critical section.
8904 * For statistics and lock validation.
8905 * @param ... Arguments for the format string.
8906 */
8907DECLINLINE(int) RT_IPRT_FORMAT_ATTR(6, 7) PDMDevHlpCritSectRwInit(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL,
8908 const char *pszNameFmt, ...)
8909{
8910 int rc;
8911 va_list va;
8912 va_start(va, pszNameFmt);
8913 rc = pDevIns->pHlpR3->pfnCritSectRwInit(pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
8914 va_end(va);
8915 return rc;
8916}
8917
8918/**
8919 * Deletes the read/write critical section.
8920 *
8921 * @returns VBox status code.
8922 * @param pDevIns The device instance.
8923 * @param pCritSect The PDM read/write critical section to destroy.
8924 * @sa PDMR3CritSectRwDelete
8925 */
8926DECLINLINE(int) PDMDevHlpCritSectRwDelete(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
8927{
8928 return pDevIns->pHlpR3->pfnCritSectRwDelete(pDevIns, pCritSect);
8929}
8930
8931#endif /* IN_RING3 */
8932
8933/**
8934 * @sa PDMCritSectRwEnterShared, PDM_CRITSECT_RELEASE_ASSERT_RC_DEV
8935 */
8936DECLINLINE(DECL_CHECK_RETURN(int)) PDMDevHlpCritSectRwEnterShared(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy)
8937{
8938 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwEnterShared(pDevIns, pCritSect, rcBusy);
8939}
8940
8941/**
8942 * @sa PDMCritSectRwEnterSharedDebug, PDM_CRITSECT_RELEASE_ASSERT_RC_DEV
8943 */
8944DECLINLINE(DECL_CHECK_RETURN(int))
8945PDMDevHlpCritSectRwEnterSharedDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL)
8946{
8947 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwEnterSharedDebug(pDevIns, pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
8948}
8949
8950/**
8951 * @sa PDMCritSectRwTryEnterShared
8952 */
8953DECLINLINE(DECL_CHECK_RETURN(int))
8954PDMDevHlpCritSectRwTryEnterShared(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
8955{
8956 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwTryEnterShared(pDevIns, pCritSect);
8957}
8958
8959/**
8960 * @sa PDMCritSectRwTryEnterSharedDebug
8961 */
8962DECLINLINE(DECL_CHECK_RETURN(int))
8963PDMDevHlpCritSectRwTryEnterSharedDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL)
8964{
8965 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwTryEnterSharedDebug(pDevIns, pCritSect, uId, RT_SRC_POS_ARGS);
8966}
8967
8968/**
8969 * @sa PDMCritSectRwLeaveShared
8970 */
8971DECLINLINE(int) PDMDevHlpCritSectRwLeaveShared(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
8972{
8973 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwLeaveShared(pDevIns, pCritSect);
8974}
8975
8976/**
8977 * @sa PDMCritSectRwEnterExcl, PDM_CRITSECT_RELEASE_ASSERT_RC_DEV
8978 */
8979DECLINLINE(DECL_CHECK_RETURN(int)) PDMDevHlpCritSectRwEnterExcl(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy)
8980{
8981 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwEnterExcl(pDevIns, pCritSect, rcBusy);
8982}
8983
8984/**
8985 * @sa PDMCritSectRwEnterExclDebug, PDM_CRITSECT_RELEASE_ASSERT_RC_DEV
8986 */
8987DECLINLINE(DECL_CHECK_RETURN(int))
8988PDMDevHlpCritSectRwEnterExclDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL)
8989{
8990 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwEnterExclDebug(pDevIns, pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
8991}
8992
8993/**
8994 * @sa PDMCritSectRwTryEnterExcl
8995 */
8996DECLINLINE(DECL_CHECK_RETURN(int))
8997PDMDevHlpCritSectRwTryEnterExcl(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
8998{
8999 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwTryEnterExcl(pDevIns, pCritSect);
9000}
9001
9002/**
9003 * @sa PDMCritSectRwTryEnterExclDebug
9004 */
9005DECLINLINE(DECL_CHECK_RETURN(int))
9006PDMDevHlpCritSectRwTryEnterExclDebug(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL)
9007{
9008 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwTryEnterExclDebug(pDevIns, pCritSect, uId, RT_SRC_POS_ARGS);
9009}
9010
9011/**
9012 * @sa PDMCritSectRwLeaveExcl
9013 */
9014DECLINLINE(int) PDMDevHlpCritSectRwLeaveExcl(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
9015{
9016 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwLeaveExcl(pDevIns, pCritSect);
9017}
9018
9019/**
9020 * @see PDMCritSectRwIsWriteOwner
9021 */
9022DECLINLINE(bool) PDMDevHlpCritSectRwIsWriteOwner(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
9023{
9024 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwIsWriteOwner(pDevIns, pCritSect);
9025}
9026
9027/**
9028 * @see PDMCritSectRwIsReadOwner
9029 */
9030DECLINLINE(bool) PDMDevHlpCritSectRwIsReadOwner(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, bool fWannaHear)
9031{
9032 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwIsReadOwner(pDevIns, pCritSect, fWannaHear);
9033}
9034
9035/**
9036 * @see PDMCritSectRwGetWriteRecursion
9037 */
9038DECLINLINE(uint32_t) PDMDevHlpCritSectRwGetWriteRecursion(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
9039{
9040 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwGetWriteRecursion(pDevIns, pCritSect);
9041}
9042
9043/**
9044 * @see PDMCritSectRwGetWriterReadRecursion
9045 */
9046DECLINLINE(uint32_t) PDMDevHlpCritSectRwGetWriterReadRecursion(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
9047{
9048 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwGetWriterReadRecursion(pDevIns, pCritSect);
9049}
9050
9051/**
9052 * @see PDMCritSectRwGetReadCount
9053 */
9054DECLINLINE(uint32_t) PDMDevHlpCritSectRwGetReadCount(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
9055{
9056 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwGetReadCount(pDevIns, pCritSect);
9057}
9058
9059/**
9060 * @see PDMCritSectRwIsInitialized
9061 */
9062DECLINLINE(bool) PDMDevHlpCritSectRwIsInitialized(PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect)
9063{
9064 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectRwIsInitialized(pDevIns, pCritSect);
9065}
9066
9067/* Strict build: Remap the two enter calls to the debug versions. */
9068#ifdef VBOX_STRICT
9069# ifdef IPRT_INCLUDED_asm_h
9070# define PDMDevHlpCritSectRwEnterShared(pDevIns, pCritSect, rcBusy) PDMDevHlpCritSectRwEnterSharedDebug((pDevIns), (pCritSect), (rcBusy), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
9071# define PDMDevHlpCritSectRwTryEnterShared(pDevIns, pCritSect) PDMDevHlpCritSectRwTryEnterSharedDebug((pDevIns), (pCritSect), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
9072# define PDMDevHlpCritSectRwEnterExcl(pDevIns, pCritSect, rcBusy) PDMDevHlpCritSectRwEnterExclDebug((pDevIns), (pCritSect), (rcBusy), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
9073# define PDMDevHlpCritSectRwTryEnterExcl(pDevIns, pCritSect) PDMDevHlpCritSectRwTryEnterExclDebug((pDevIns), (pCritSect), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
9074# else
9075# define PDMDevHlpCritSectRwEnterShared(pDevIns, pCritSect, rcBusy) PDMDevHlpCritSectRwEnterSharedDebug((pDevIns), (pCritSect), (rcBusy), 0, RT_SRC_POS)
9076# define PDMDevHlpCritSectRwTryEnterShared(pDevIns, pCritSect) PDMDevHlpCritSectRwTryEnterSharedDebug((pDevIns), (pCritSect), 0, RT_SRC_POS)
9077# define PDMDevHlpCritSectRwEnterExcl(pDevIns, pCritSect, rcBusy) PDMDevHlpCritSectRwEnterExclDebug((pDevIns), (pCritSect), (rcBusy), 0, RT_SRC_POS)
9078# define PDMDevHlpCritSectRwTryEnterExcl(pDevIns, pCritSect) PDMDevHlpCritSectRwTryEnterExclDebug((pDevIns), (pCritSect), 0, RT_SRC_POS)
9079# endif
9080#endif
9081
9082#if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
9083
9084/**
9085 * @copydoc PDMDEVHLPR3::pfnThreadCreate
9086 */
9087DECLINLINE(int) PDMDevHlpThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
9088 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
9089{
9090 return pDevIns->pHlpR3->pfnThreadCreate(pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
9091}
9092
9093/**
9094 * @copydoc PDMR3ThreadDestroy
9095 * @param pDevIns The device instance.
9096 */
9097DECLINLINE(int) PDMDevHlpThreadDestroy(PPDMDEVINS pDevIns, PPDMTHREAD pThread, int *pRcThread)
9098{
9099 return pDevIns->pHlpR3->pfnThreadDestroy(pThread, pRcThread);
9100}
9101
9102/**
9103 * @copydoc PDMR3ThreadIAmSuspending
9104 * @param pDevIns The device instance.
9105 */
9106DECLINLINE(int) PDMDevHlpThreadIAmSuspending(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
9107{
9108 return pDevIns->pHlpR3->pfnThreadIAmSuspending(pThread);
9109}
9110
9111/**
9112 * @copydoc PDMR3ThreadIAmRunning
9113 * @param pDevIns The device instance.
9114 */
9115DECLINLINE(int) PDMDevHlpThreadIAmRunning(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
9116{
9117 return pDevIns->pHlpR3->pfnThreadIAmRunning(pThread);
9118}
9119
9120/**
9121 * @copydoc PDMR3ThreadSleep
9122 * @param pDevIns The device instance.
9123 */
9124DECLINLINE(int) PDMDevHlpThreadSleep(PPDMDEVINS pDevIns, PPDMTHREAD pThread, RTMSINTERVAL cMillies)
9125{
9126 return pDevIns->pHlpR3->pfnThreadSleep(pThread, cMillies);
9127}
9128
9129/**
9130 * @copydoc PDMR3ThreadSuspend
9131 * @param pDevIns The device instance.
9132 */
9133DECLINLINE(int) PDMDevHlpThreadSuspend(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
9134{
9135 return pDevIns->pHlpR3->pfnThreadSuspend(pThread);
9136}
9137
9138/**
9139 * @copydoc PDMR3ThreadResume
9140 * @param pDevIns The device instance.
9141 */
9142DECLINLINE(int) PDMDevHlpThreadResume(PPDMDEVINS pDevIns, PPDMTHREAD pThread)
9143{
9144 return pDevIns->pHlpR3->pfnThreadResume(pThread);
9145}
9146
9147/**
9148 * @copydoc PDMDEVHLPR3::pfnSetAsyncNotification
9149 */
9150DECLINLINE(int) PDMDevHlpSetAsyncNotification(PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)
9151{
9152 return pDevIns->pHlpR3->pfnSetAsyncNotification(pDevIns, pfnAsyncNotify);
9153}
9154
9155/**
9156 * @copydoc PDMDEVHLPR3::pfnAsyncNotificationCompleted
9157 */
9158DECLINLINE(void) PDMDevHlpAsyncNotificationCompleted(PPDMDEVINS pDevIns)
9159{
9160 pDevIns->pHlpR3->pfnAsyncNotificationCompleted(pDevIns);
9161}
9162
9163/**
9164 * @copydoc PDMDEVHLPR3::pfnA20Set
9165 */
9166DECLINLINE(void) PDMDevHlpA20Set(PPDMDEVINS pDevIns, bool fEnable)
9167{
9168 pDevIns->pHlpR3->pfnA20Set(pDevIns, fEnable);
9169}
9170
9171/**
9172 * @copydoc PDMDEVHLPR3::pfnRTCRegister
9173 */
9174DECLINLINE(int) PDMDevHlpRTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
9175{
9176 return pDevIns->pHlpR3->pfnRTCRegister(pDevIns, pRtcReg, ppRtcHlp);
9177}
9178
9179/**
9180 * @copydoc PDMDEVHLPR3::pfnPCIBusRegister
9181 */
9182DECLINLINE(int) PDMDevHlpPCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREGR3 pPciBusReg, PCPDMPCIHLPR3 *ppPciHlp, uint32_t *piBus)
9183{
9184 return pDevIns->pHlpR3->pfnPCIBusRegister(pDevIns, pPciBusReg, ppPciHlp, piBus);
9185}
9186
9187/**
9188 * @copydoc PDMDEVHLPR3::pfnIommuRegister
9189 */
9190DECLINLINE(int) PDMDevHlpIommuRegister(PPDMDEVINS pDevIns, PPDMIOMMUREGR3 pIommuReg, PCPDMIOMMUHLPR3 *ppIommuHlp, uint32_t *pidxIommu)
9191{
9192 return pDevIns->pHlpR3->pfnIommuRegister(pDevIns, pIommuReg, ppIommuHlp, pidxIommu);
9193}
9194
9195/**
9196 * @copydoc PDMDEVHLPR3::pfnPICRegister
9197 */
9198DECLINLINE(int) PDMDevHlpPICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp)
9199{
9200 return pDevIns->pHlpR3->pfnPICRegister(pDevIns, pPicReg, ppPicHlp);
9201}
9202
9203/**
9204 * @copydoc PDMDEVHLPR3::pfnApicRegister
9205 */
9206DECLINLINE(int) PDMDevHlpApicRegister(PPDMDEVINS pDevIns)
9207{
9208 return pDevIns->pHlpR3->pfnApicRegister(pDevIns);
9209}
9210
9211/**
9212 * @copydoc PDMDEVHLPR3::pfnIoApicRegister
9213 */
9214DECLINLINE(int) PDMDevHlpIoApicRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp)
9215{
9216 return pDevIns->pHlpR3->pfnIoApicRegister(pDevIns, pIoApicReg, ppIoApicHlp);
9217}
9218
9219/**
9220 * @copydoc PDMDEVHLPR3::pfnHpetRegister
9221 */
9222DECLINLINE(int) PDMDevHlpHpetRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
9223{
9224 return pDevIns->pHlpR3->pfnHpetRegister(pDevIns, pHpetReg, ppHpetHlpR3);
9225}
9226
9227/**
9228 * @copydoc PDMDEVHLPR3::pfnPciRawRegister
9229 */
9230DECLINLINE(int) PDMDevHlpPciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
9231{
9232 return pDevIns->pHlpR3->pfnPciRawRegister(pDevIns, pPciRawReg, ppPciRawHlpR3);
9233}
9234
9235/**
9236 * @copydoc PDMDEVHLPR3::pfnDMACRegister
9237 */
9238DECLINLINE(int) PDMDevHlpDMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
9239{
9240 return pDevIns->pHlpR3->pfnDMACRegister(pDevIns, pDmacReg, ppDmacHlp);
9241}
9242
9243/**
9244 * @copydoc PDMDEVHLPR3::pfnDMARegister
9245 */
9246DECLINLINE(int) PDMDevHlpDMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
9247{
9248 return pDevIns->pHlpR3->pfnDMARegister(pDevIns, uChannel, pfnTransferHandler, pvUser);
9249}
9250
9251/**
9252 * @copydoc PDMDEVHLPR3::pfnDMAReadMemory
9253 */
9254DECLINLINE(int) PDMDevHlpDMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
9255{
9256 return pDevIns->pHlpR3->pfnDMAReadMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbRead);
9257}
9258
9259/**
9260 * @copydoc PDMDEVHLPR3::pfnDMAWriteMemory
9261 */
9262DECLINLINE(int) PDMDevHlpDMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
9263{
9264 return pDevIns->pHlpR3->pfnDMAWriteMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbWritten);
9265}
9266
9267/**
9268 * @copydoc PDMDEVHLPR3::pfnDMASetDREQ
9269 */
9270DECLINLINE(int) PDMDevHlpDMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
9271{
9272 return pDevIns->pHlpR3->pfnDMASetDREQ(pDevIns, uChannel, uLevel);
9273}
9274
9275/**
9276 * @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode
9277 */
9278DECLINLINE(uint8_t) PDMDevHlpDMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
9279{
9280 return pDevIns->pHlpR3->pfnDMAGetChannelMode(pDevIns, uChannel);
9281}
9282
9283/**
9284 * @copydoc PDMDEVHLPR3::pfnDMASchedule
9285 */
9286DECLINLINE(void) PDMDevHlpDMASchedule(PPDMDEVINS pDevIns)
9287{
9288 pDevIns->pHlpR3->pfnDMASchedule(pDevIns);
9289}
9290
9291/**
9292 * @copydoc PDMDEVHLPR3::pfnCMOSWrite
9293 */
9294DECLINLINE(int) PDMDevHlpCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
9295{
9296 return pDevIns->pHlpR3->pfnCMOSWrite(pDevIns, iReg, u8Value);
9297}
9298
9299/**
9300 * @copydoc PDMDEVHLPR3::pfnCMOSRead
9301 */
9302DECLINLINE(int) PDMDevHlpCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
9303{
9304 return pDevIns->pHlpR3->pfnCMOSRead(pDevIns, iReg, pu8Value);
9305}
9306
9307/**
9308 * @copydoc PDMDEVHLPR3::pfnCallR0
9309 */
9310DECLINLINE(int) PDMDevHlpCallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)
9311{
9312 return pDevIns->pHlpR3->pfnCallR0(pDevIns, uOperation, u64Arg);
9313}
9314
9315/**
9316 * @copydoc PDMDEVHLPR3::pfnVMGetSuspendReason
9317 */
9318DECLINLINE(VMSUSPENDREASON) PDMDevHlpVMGetSuspendReason(PPDMDEVINS pDevIns)
9319{
9320 return pDevIns->pHlpR3->pfnVMGetSuspendReason(pDevIns);
9321}
9322
9323/**
9324 * @copydoc PDMDEVHLPR3::pfnVMGetResumeReason
9325 */
9326DECLINLINE(VMRESUMEREASON) PDMDevHlpVMGetResumeReason(PPDMDEVINS pDevIns)
9327{
9328 return pDevIns->pHlpR3->pfnVMGetResumeReason(pDevIns);
9329}
9330
9331/**
9332 * @copydoc PDMDEVHLPR3::pfnGetUVM
9333 */
9334DECLINLINE(PUVM) PDMDevHlpGetUVM(PPDMDEVINS pDevIns)
9335{
9336 return pDevIns->CTX_SUFF(pHlp)->pfnGetUVM(pDevIns);
9337}
9338
9339#endif /* IN_RING3 || DOXYGEN_RUNNING */
9340
9341#if !defined(IN_RING3) || defined(DOXYGEN_RUNNING)
9342
9343/**
9344 * @copydoc PDMDEVHLPR0::pfnPCIBusSetUpContext
9345 */
9346DECLINLINE(int) PDMDevHlpPCIBusSetUpContext(PPDMDEVINS pDevIns, CTX_SUFF(PPDMPCIBUSREG) pPciBusReg, CTX_SUFF(PCPDMPCIHLP) *ppPciHlp)
9347{
9348 return pDevIns->CTX_SUFF(pHlp)->pfnPCIBusSetUpContext(pDevIns, pPciBusReg, ppPciHlp);
9349}
9350
9351/**
9352 * @copydoc PDMDEVHLPR0::pfnIommuSetUpContext
9353 */
9354DECLINLINE(int) PDMDevHlpIommuSetUpContext(PPDMDEVINS pDevIns, CTX_SUFF(PPDMIOMMUREG) pIommuReg, CTX_SUFF(PCPDMIOMMUHLP) *ppIommuHlp)
9355{
9356 return pDevIns->CTX_SUFF(pHlp)->pfnIommuSetUpContext(pDevIns, pIommuReg, ppIommuHlp);
9357}
9358
9359/**
9360 * @copydoc PDMDEVHLPR0::pfnPICSetUpContext
9361 */
9362DECLINLINE(int) PDMDevHlpPICSetUpContext(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp)
9363{
9364 return pDevIns->CTX_SUFF(pHlp)->pfnPICSetUpContext(pDevIns, pPicReg, ppPicHlp);
9365}
9366
9367/**
9368 * @copydoc PDMDEVHLPR0::pfnApicSetUpContext
9369 */
9370DECLINLINE(int) PDMDevHlpApicSetUpContext(PPDMDEVINS pDevIns)
9371{
9372 return pDevIns->CTX_SUFF(pHlp)->pfnApicSetUpContext(pDevIns);
9373}
9374
9375/**
9376 * @copydoc PDMDEVHLPR0::pfnIoApicSetUpContext
9377 */
9378DECLINLINE(int) PDMDevHlpIoApicSetUpContext(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLP *ppIoApicHlp)
9379{
9380 return pDevIns->CTX_SUFF(pHlp)->pfnIoApicSetUpContext(pDevIns, pIoApicReg, ppIoApicHlp);
9381}
9382
9383/**
9384 * @copydoc PDMDEVHLPR0::pfnHpetSetUpContext
9385 */
9386DECLINLINE(int) PDMDevHlpHpetSetUpContext(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, CTX_SUFF(PCPDMHPETHLP) *ppHpetHlp)
9387{
9388 return pDevIns->CTX_SUFF(pHlp)->pfnHpetSetUpContext(pDevIns, pHpetReg, ppHpetHlp);
9389}
9390
9391#endif /* !IN_RING3 || DOXYGEN_RUNNING */
9392
9393/**
9394 * @copydoc PDMDEVHLPR3::pfnGetVM
9395 */
9396DECLINLINE(PVMCC) PDMDevHlpGetVM(PPDMDEVINS pDevIns)
9397{
9398 return pDevIns->CTX_SUFF(pHlp)->pfnGetVM(pDevIns);
9399}
9400
9401/**
9402 * @copydoc PDMDEVHLPR3::pfnGetVMCPU
9403 */
9404DECLINLINE(PVMCPUCC) PDMDevHlpGetVMCPU(PPDMDEVINS pDevIns)
9405{
9406 return pDevIns->CTX_SUFF(pHlp)->pfnGetVMCPU(pDevIns);
9407}
9408
9409/**
9410 * @copydoc PDMDEVHLPR3::pfnGetCurrentCpuId
9411 */
9412DECLINLINE(VMCPUID) PDMDevHlpGetCurrentCpuId(PPDMDEVINS pDevIns)
9413{
9414 return pDevIns->CTX_SUFF(pHlp)->pfnGetCurrentCpuId(pDevIns);
9415}
9416
9417/**
9418 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGet
9419 */
9420DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGet(PPDMDEVINS pDevIns)
9421{
9422 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGet(pDevIns);
9423}
9424
9425/**
9426 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
9427 */
9428DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetFreq(PPDMDEVINS pDevIns)
9429{
9430 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetFreq(pDevIns);
9431}
9432
9433/**
9434 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
9435 */
9436DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetNano(PPDMDEVINS pDevIns)
9437{
9438 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetNano(pDevIns);
9439}
9440
9441#ifdef IN_RING3
9442/**
9443 * @copydoc PDMDEVHLPR3::pfnTMCpuTicksPerSecond
9444 */
9445DECLINLINE(uint64_t) PDMDevHlpTMCpuTicksPerSecond(PPDMDEVINS pDevIns)
9446{
9447 return pDevIns->CTX_SUFF(pHlp)->pfnTMCpuTicksPerSecond(pDevIns);
9448}
9449
9450/**
9451 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap
9452 */
9453DECLINLINE(int) PDMDevHlpRegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbHeap)
9454{
9455 return pDevIns->pHlpR3->pfnRegisterVMMDevHeap(pDevIns, GCPhys, pvHeap, cbHeap);
9456}
9457
9458/**
9459 * @copydoc PDMDEVHLPR3::pfnFirmwareRegister
9460 */
9461DECLINLINE(int) PDMDevHlpFirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp)
9462{
9463 return pDevIns->pHlpR3->pfnFirmwareRegister(pDevIns, pFwReg, ppFwHlp);
9464}
9465
9466/**
9467 * @copydoc PDMDEVHLPR3::pfnVMReset
9468 */
9469DECLINLINE(int) PDMDevHlpVMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
9470{
9471 return pDevIns->pHlpR3->pfnVMReset(pDevIns, fFlags);
9472}
9473
9474/**
9475 * @copydoc PDMDEVHLPR3::pfnVMSuspend
9476 */
9477DECLINLINE(int) PDMDevHlpVMSuspend(PPDMDEVINS pDevIns)
9478{
9479 return pDevIns->pHlpR3->pfnVMSuspend(pDevIns);
9480}
9481
9482/**
9483 * @copydoc PDMDEVHLPR3::pfnVMSuspendSaveAndPowerOff
9484 */
9485DECLINLINE(int) PDMDevHlpVMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
9486{
9487 return pDevIns->pHlpR3->pfnVMSuspendSaveAndPowerOff(pDevIns);
9488}
9489
9490/**
9491 * @copydoc PDMDEVHLPR3::pfnVMPowerOff
9492 */
9493DECLINLINE(int) PDMDevHlpVMPowerOff(PPDMDEVINS pDevIns)
9494{
9495 return pDevIns->pHlpR3->pfnVMPowerOff(pDevIns);
9496}
9497
9498#endif /* IN_RING3 */
9499
9500/**
9501 * @copydoc PDMDEVHLPR3::pfnA20IsEnabled
9502 */
9503DECLINLINE(bool) PDMDevHlpA20IsEnabled(PPDMDEVINS pDevIns)
9504{
9505 return pDevIns->CTX_SUFF(pHlp)->pfnA20IsEnabled(pDevIns);
9506}
9507
9508#ifdef IN_RING3
9509/**
9510 * @copydoc PDMDEVHLPR3::pfnGetCpuId
9511 */
9512DECLINLINE(void) PDMDevHlpGetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
9513{
9514 pDevIns->pHlpR3->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx);
9515}
9516#endif
9517
9518/**
9519 * @copydoc PDMDEVHLPR3::pfnGetMainExecutionEngine
9520 */
9521DECLINLINE(uint8_t) PDMDevHlpGetMainExecutionEngine(PPDMDEVINS pDevIns)
9522{
9523 return pDevIns->CTX_SUFF(pHlp)->pfnGetMainExecutionEngine(pDevIns);
9524}
9525
9526#ifdef IN_RING3
9527
9528/**
9529 * @copydoc PDMDEVHLPR3::pfnGetSupDrvSession
9530 */
9531DECLINLINE(PSUPDRVSESSION) PDMDevHlpGetSupDrvSession(PPDMDEVINS pDevIns)
9532{
9533 return pDevIns->pHlpR3->pfnGetSupDrvSession(pDevIns);
9534}
9535
9536/**
9537 * @copydoc PDMDEVHLPR3::pfnQueryGenericUserObject
9538 */
9539DECLINLINE(void *) PDMDevHlpQueryGenericUserObject(PPDMDEVINS pDevIns, PCRTUUID pUuid)
9540{
9541 return pDevIns->pHlpR3->pfnQueryGenericUserObject(pDevIns, pUuid);
9542}
9543
9544/**
9545 * @copydoc PDMDEVHLPR3::pfnPGMHandlerPhysicalTypeRegister
9546 */
9547DECLINLINE(int) PDMDevHlpPGMHandlerPhysicalTypeRegister(PPDMDEVINS pDevIns, PGMPHYSHANDLERKIND enmKind,
9548 PFNPGMPHYSHANDLER pfnHandler, const char *pszDesc,
9549 PPGMPHYSHANDLERTYPE phType)
9550{
9551 return pDevIns->pHlpR3->pfnPGMHandlerPhysicalTypeRegister(pDevIns, enmKind, pfnHandler, pszDesc, phType);
9552}
9553
9554#elif defined(IN_RING0)
9555
9556/**
9557 * @copydoc PDMDEVHLPR0::pfnPGMHandlerPhysicalTypeSetUpContext
9558 */
9559DECLINLINE(int) PDMDevHlpPGMHandlerPhysicalTypeSetUpContext(PPDMDEVINS pDevIns, PGMPHYSHANDLERKIND enmKind,
9560 PFNPGMPHYSHANDLER pfnHandler, PFNPGMRZPHYSPFHANDLER pfnPfHandler,
9561 const char *pszDesc, PGMPHYSHANDLERTYPE hType)
9562{
9563 return pDevIns->pHlpR0->pfnPGMHandlerPhysicalTypeSetUpContext(pDevIns, enmKind, pfnHandler, pfnPfHandler, pszDesc, hType);
9564}
9565
9566#endif
9567#ifdef IN_RING3
9568
9569/**
9570 * @copydoc PDMDEVHLPR3::pfnPGMHandlerPhysicalRegister
9571 */
9572DECLINLINE(int) PDMDevHlpPGMHandlerPhysicalRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
9573 PGMPHYSHANDLERTYPE hType, R3PTRTYPE(const char *) pszDesc)
9574{
9575 return pDevIns->pHlpR3->pfnPGMHandlerPhysicalRegister(pDevIns, GCPhys, GCPhysLast, hType, pszDesc);
9576}
9577
9578/**
9579 * @copydoc PDMDEVHLPR3::pfnPGMHandlerPhysicalDeregister
9580 */
9581DECLINLINE(int) PDMDevHlpPGMHandlerPhysicalDeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
9582{
9583 return pDevIns->pHlpR3->pfnPGMHandlerPhysicalDeregister(pDevIns, GCPhys);
9584}
9585
9586#endif /* IN_RING3 */
9587
9588/**
9589 * @copydoc PDMDEVHLPR3::pfnPGMHandlerPhysicalPageTempOff
9590 */
9591DECLINLINE(int) PDMDevHlpPGMHandlerPhysicalPageTempOff(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage)
9592{
9593 return pDevIns->CTX_SUFF(pHlp)->pfnPGMHandlerPhysicalPageTempOff(pDevIns, GCPhys, GCPhysPage);
9594}
9595
9596#ifdef IN_RING3
9597
9598/**
9599 * @copydoc PDMDEVHLPR3::pfnPGMHandlerPhysicalReset
9600 */
9601DECLINLINE(int) PDMDevHlpPGMHandlerPhysicalReset(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
9602{
9603 return pDevIns->pHlpR3->pfnPGMHandlerPhysicalReset(pDevIns, GCPhys);
9604}
9605
9606/**
9607 * @copydoc PDMDEVHLPR3::pfnVMMRegisterPatchMemory
9608 */
9609DECLINLINE(int) PDMDevHlpVMMRegisterPatchMemory(PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem)
9610{
9611 return pDevIns->pHlpR3->pfnVMMRegisterPatchMemory(pDevIns, GCPtrPatchMem, cbPatchMem);
9612}
9613
9614/**
9615 * @copydoc PDMDEVHLPR3::pfnVMMDeregisterPatchMemory
9616 */
9617DECLINLINE(int) PDMDevHlpVMMDeregisterPatchMemory(PPDMDEVINS pDevIns, RTGCPTR GCPtrPatchMem, uint32_t cbPatchMem)
9618{
9619 return pDevIns->pHlpR3->pfnVMMDeregisterPatchMemory(pDevIns, GCPtrPatchMem, cbPatchMem);
9620}
9621
9622/**
9623 * @copydoc PDMDEVHLPR3::pfnSharedModuleRegister
9624 */
9625DECLINLINE(int) PDMDevHlpSharedModuleRegister(PPDMDEVINS pDevIns, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion,
9626 RTGCPTR GCBaseAddr, uint32_t cbModule,
9627 uint32_t cRegions, VMMDEVSHAREDREGIONDESC const *paRegions)
9628{
9629 return pDevIns->pHlpR3->pfnSharedModuleRegister(pDevIns, enmGuestOS, pszModuleName, pszVersion,
9630 GCBaseAddr, cbModule, cRegions, paRegions);
9631}
9632
9633/**
9634 * @copydoc PDMDEVHLPR3::pfnSharedModuleUnregister
9635 */
9636DECLINLINE(int) PDMDevHlpSharedModuleUnregister(PPDMDEVINS pDevIns, char *pszModuleName, char *pszVersion,
9637 RTGCPTR GCBaseAddr, uint32_t cbModule)
9638{
9639 return pDevIns->pHlpR3->pfnSharedModuleUnregister(pDevIns, pszModuleName, pszVersion, GCBaseAddr, cbModule);
9640}
9641
9642/**
9643 * @copydoc PDMDEVHLPR3::pfnSharedModuleGetPageState
9644 */
9645DECLINLINE(int) PDMDevHlpSharedModuleGetPageState(PPDMDEVINS pDevIns, RTGCPTR GCPtrPage, bool *pfShared,
9646 uint64_t *pfPageFlags)
9647{
9648 return pDevIns->pHlpR3->pfnSharedModuleGetPageState(pDevIns, GCPtrPage, pfShared, pfPageFlags);
9649}
9650
9651/**
9652 * @copydoc PDMDEVHLPR3::pfnSharedModuleCheckAll
9653 */
9654DECLINLINE(int) PDMDevHlpSharedModuleCheckAll(PPDMDEVINS pDevIns)
9655{
9656 return pDevIns->pHlpR3->pfnSharedModuleCheckAll(pDevIns);
9657}
9658
9659/**
9660 * @copydoc PDMDEVHLPR3::pfnQueryLun
9661 */
9662DECLINLINE(int) PDMDevHlpQueryLun(PPDMDEVINS pDevIns, const char *pszDevice, unsigned iInstance, unsigned iLun, PPDMIBASE *ppBase)
9663{
9664 return pDevIns->pHlpR3->pfnQueryLun(pDevIns, pszDevice, iInstance, iLun, ppBase);
9665}
9666
9667/**
9668 * @copydoc PDMDEVHLPR3::pfnGIMDeviceRegister
9669 */
9670DECLINLINE(void) PDMDevHlpGIMDeviceRegister(PPDMDEVINS pDevIns, PGIMDEBUG pDbg)
9671{
9672 pDevIns->pHlpR3->pfnGIMDeviceRegister(pDevIns, pDbg);
9673}
9674
9675/**
9676 * @copydoc PDMDEVHLPR3::pfnGIMGetDebugSetup
9677 */
9678DECLINLINE(int) PDMDevHlpGIMGetDebugSetup(PPDMDEVINS pDevIns, PGIMDEBUGSETUP pDbgSetup)
9679{
9680 return pDevIns->pHlpR3->pfnGIMGetDebugSetup(pDevIns, pDbgSetup);
9681}
9682
9683#endif /* IN_RING3 */
9684
9685/**
9686 * @copydoc PDMDEVHLPR3::pfnGIMGetMmio2Regions
9687 */
9688DECLINLINE(PGIMMMIO2REGION) PDMDevHlpGIMGetMmio2Regions(PPDMDEVINS pDevIns, uint32_t *pcRegions)
9689{
9690 return pDevIns->CTX_SUFF(pHlp)->pfnGIMGetMmio2Regions(pDevIns, pcRegions);
9691}
9692
9693#ifdef IN_RING3
9694
9695/** Wrapper around SSMR3GetU32 for simplifying getting enum values saved as uint32_t. */
9696# define PDMDEVHLP_SSM_GET_ENUM32_RET(a_pHlp, a_pSSM, a_enmDst, a_EnumType) \
9697 do { \
9698 uint32_t u32GetEnumTmp = 0; \
9699 int rcGetEnum32Tmp = (a_pHlp)->pfnSSMGetU32((a_pSSM), &u32GetEnumTmp); \
9700 AssertRCReturn(rcGetEnum32Tmp, rcGetEnum32Tmp); \
9701 (a_enmDst) = (a_EnumType)u32GetEnumTmp; \
9702 AssertCompile(sizeof(a_EnumType) == sizeof(u32GetEnumTmp)); \
9703 } while (0)
9704
9705/** Wrapper around SSMR3GetU8 for simplifying getting enum values saved as uint8_t. */
9706# define PDMDEVHLP_SSM_GET_ENUM8_RET(a_pHlp, a_pSSM, a_enmDst, a_EnumType) \
9707 do { \
9708 uint8_t bGetEnumTmp = 0; \
9709 int rcGetEnum32Tmp = (a_pHlp)->pfnSSMGetU8((a_pSSM), &bGetEnumTmp); \
9710 AssertRCReturn(rcGetEnum32Tmp, rcGetEnum32Tmp); \
9711 (a_enmDst) = (a_EnumType)bGetEnumTmp; \
9712 } while (0)
9713
9714#endif /* IN_RING3 */
9715
9716/** Pointer to callbacks provided to the VBoxDeviceRegister() call. */
9717typedef struct PDMDEVREGCB *PPDMDEVREGCB;
9718
9719/**
9720 * Callbacks for VBoxDeviceRegister().
9721 */
9722typedef struct PDMDEVREGCB
9723{
9724 /** Interface version.
9725 * This is set to PDM_DEVREG_CB_VERSION. */
9726 uint32_t u32Version;
9727
9728 /**
9729 * Registers a device with the current VM instance.
9730 *
9731 * @returns VBox status code.
9732 * @param pCallbacks Pointer to the callback table.
9733 * @param pReg Pointer to the device registration record.
9734 * This data must be permanent and readonly.
9735 */
9736 DECLR3CALLBACKMEMBER(int, pfnRegister,(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pReg));
9737} PDMDEVREGCB;
9738
9739/** Current version of the PDMDEVREGCB structure. */
9740#define PDM_DEVREG_CB_VERSION PDM_VERSION_MAKE(0xffe3, 1, 0)
9741
9742
9743/**
9744 * The VBoxDevicesRegister callback function.
9745 *
9746 * PDM will invoke this function after loading a device module and letting
9747 * the module decide which devices to register and how to handle conflicts.
9748 *
9749 * @returns VBox status code.
9750 * @param pCallbacks Pointer to the callback table.
9751 * @param u32Version VBox version number.
9752 */
9753typedef DECLCALLBACKTYPE(int, FNPDMVBOXDEVICESREGISTER,(PPDMDEVREGCB pCallbacks, uint32_t u32Version));
9754
9755/** @} */
9756
9757RT_C_DECLS_END
9758
9759#endif /* !VBOX_INCLUDED_vmm_pdmdev_h */
Note: See TracBrowser for help on using the repository browser.

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