VirtualBox

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

Last change on this file since 81375 was 81375, checked in by vboxsync, 5 years ago

IOM,PDM,PCI: Making new MMIO code work with PCI. bugref:9218

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 300.3 KB
Line 
1/** @file
2 * PDM - Pluggable Device Manager, Devices.
3 */
4
5/*
6 * Copyright (C) 2006-2019 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef VBOX_INCLUDED_vmm_pdmdev_h
27#define VBOX_INCLUDED_vmm_pdmdev_h
28#ifndef RT_WITHOUT_PRAGMA_ONCE
29# pragma once
30#endif
31
32#include <VBox/vmm/pdmqueue.h>
33#include <VBox/vmm/pdmcritsect.h>
34#ifdef IN_RING3
35# include <VBox/vmm/pdmthread.h>
36#endif
37#include <VBox/vmm/pdmifs.h>
38#include <VBox/vmm/pdmins.h>
39#include <VBox/vmm/pdmcommon.h>
40#include <VBox/vmm/pdmpcidev.h>
41#include <VBox/vmm/iom.h>
42#include <VBox/vmm/tm.h>
43#include <VBox/vmm/ssm.h>
44#include <VBox/vmm/cfgm.h>
45#include <VBox/vmm/dbgf.h>
46#include <VBox/err.h> /* VINF_EM_DBG_STOP, also 120+ source files expecting this. */
47#include <iprt/stdarg.h>
48#include <iprt/list.h>
49
50
51RT_C_DECLS_BEGIN
52
53/** @defgroup grp_pdm_device The PDM Devices API
54 * @ingroup grp_pdm
55 * @{
56 */
57
58/**
59 * Construct a device instance for a VM.
60 *
61 * @returns VBox status.
62 * @param pDevIns The device instance data. If the registration structure
63 * is needed, it can be accessed thru pDevIns->pReg.
64 * @param iInstance Instance number. Use this to figure out which registers
65 * and such to use. The instance number is also found in
66 * pDevIns->iInstance, but since it's likely to be
67 * frequently used PDM passes it as parameter.
68 * @param pCfg Configuration node handle for the driver. This is
69 * expected to be in high demand in the constructor and is
70 * therefore passed as an argument. When using it at other
71 * times, it can be found in pDevIns->pCfg.
72 */
73typedef DECLCALLBACK(int) FNPDMDEVCONSTRUCT(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg);
74/** Pointer to a FNPDMDEVCONSTRUCT() function. */
75typedef FNPDMDEVCONSTRUCT *PFNPDMDEVCONSTRUCT;
76
77/**
78 * Destruct a device instance.
79 *
80 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
81 * resources can be freed correctly.
82 *
83 * @returns VBox status.
84 * @param pDevIns The device instance data.
85 *
86 * @remarks The device critical section is not entered. The routine may delete
87 * the critical section, so the caller cannot exit it.
88 */
89typedef DECLCALLBACK(int) FNPDMDEVDESTRUCT(PPDMDEVINS pDevIns);
90/** Pointer to a FNPDMDEVDESTRUCT() function. */
91typedef FNPDMDEVDESTRUCT *PFNPDMDEVDESTRUCT;
92
93/**
94 * Device relocation callback.
95 *
96 * This is called when the instance data has been relocated in raw-mode context
97 * (RC). It is also called when the RC hypervisor selects changes. The device
98 * must fixup all necessary pointers and re-query all interfaces to other RC
99 * devices and drivers.
100 *
101 * Before the RC code is executed the first time, this function will be called
102 * with a 0 delta so RC pointer calculations can be one in one place.
103 *
104 * @param pDevIns Pointer to the device instance.
105 * @param offDelta The relocation delta relative to the old location.
106 *
107 * @remarks A relocation CANNOT fail.
108 *
109 * @remarks The device critical section is not entered. The relocations should
110 * not normally require any locking.
111 */
112typedef DECLCALLBACK(void) FNPDMDEVRELOCATE(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
113/** Pointer to a FNPDMDEVRELOCATE() function. */
114typedef FNPDMDEVRELOCATE *PFNPDMDEVRELOCATE;
115
116/**
117 * Power On notification.
118 *
119 * @returns VBox status.
120 * @param pDevIns The device instance data.
121 *
122 * @remarks Caller enters the device critical section.
123 */
124typedef DECLCALLBACK(void) FNPDMDEVPOWERON(PPDMDEVINS pDevIns);
125/** Pointer to a FNPDMDEVPOWERON() function. */
126typedef FNPDMDEVPOWERON *PFNPDMDEVPOWERON;
127
128/**
129 * Reset notification.
130 *
131 * @returns VBox status.
132 * @param pDevIns The device instance data.
133 *
134 * @remarks Caller enters the device critical section.
135 */
136typedef DECLCALLBACK(void) FNPDMDEVRESET(PPDMDEVINS pDevIns);
137/** Pointer to a FNPDMDEVRESET() function. */
138typedef FNPDMDEVRESET *PFNPDMDEVRESET;
139
140/**
141 * Soft reset notification.
142 *
143 * This is mainly for emulating the 286 style protected mode exits, in which
144 * most devices should remain in their current state.
145 *
146 * @returns VBox status.
147 * @param pDevIns The device instance data.
148 * @param fFlags PDMVMRESET_F_XXX (only bits relevant to soft resets).
149 *
150 * @remarks Caller enters the device critical section.
151 */
152typedef DECLCALLBACK(void) FNPDMDEVSOFTRESET(PPDMDEVINS pDevIns, uint32_t fFlags);
153/** Pointer to a FNPDMDEVSOFTRESET() function. */
154typedef FNPDMDEVSOFTRESET *PFNPDMDEVSOFTRESET;
155
156/** @name PDMVMRESET_F_XXX - VM reset flags.
157 * These flags are used both for FNPDMDEVSOFTRESET and for hardware signalling
158 * reset via PDMDevHlpVMReset.
159 * @{ */
160/** Unknown reason. */
161#define PDMVMRESET_F_UNKNOWN UINT32_C(0x00000000)
162/** GIM triggered reset. */
163#define PDMVMRESET_F_GIM UINT32_C(0x00000001)
164/** The last source always causing hard resets. */
165#define PDMVMRESET_F_LAST_ALWAYS_HARD PDMVMRESET_F_GIM
166/** ACPI triggered reset. */
167#define PDMVMRESET_F_ACPI UINT32_C(0x0000000c)
168/** PS/2 system port A (92h) reset. */
169#define PDMVMRESET_F_PORT_A UINT32_C(0x0000000d)
170/** Keyboard reset. */
171#define PDMVMRESET_F_KBD UINT32_C(0x0000000e)
172/** Tripple fault. */
173#define PDMVMRESET_F_TRIPLE_FAULT UINT32_C(0x0000000f)
174/** Reset source mask. */
175#define PDMVMRESET_F_SRC_MASK UINT32_C(0x0000000f)
176/** @} */
177
178/**
179 * Suspend notification.
180 *
181 * @returns VBox status.
182 * @param pDevIns The device instance data.
183 * @thread EMT(0)
184 *
185 * @remarks Caller enters the device critical section.
186 */
187typedef DECLCALLBACK(void) FNPDMDEVSUSPEND(PPDMDEVINS pDevIns);
188/** Pointer to a FNPDMDEVSUSPEND() function. */
189typedef FNPDMDEVSUSPEND *PFNPDMDEVSUSPEND;
190
191/**
192 * Resume notification.
193 *
194 * @returns VBox status.
195 * @param pDevIns The device instance data.
196 *
197 * @remarks Caller enters the device critical section.
198 */
199typedef DECLCALLBACK(void) FNPDMDEVRESUME(PPDMDEVINS pDevIns);
200/** Pointer to a FNPDMDEVRESUME() function. */
201typedef FNPDMDEVRESUME *PFNPDMDEVRESUME;
202
203/**
204 * Power Off notification.
205 *
206 * This is always called when VMR3PowerOff is called.
207 * There will be no callback when hot plugging devices.
208 *
209 * @param pDevIns The device instance data.
210 * @thread EMT(0)
211 *
212 * @remarks Caller enters the device critical section.
213 */
214typedef DECLCALLBACK(void) FNPDMDEVPOWEROFF(PPDMDEVINS pDevIns);
215/** Pointer to a FNPDMDEVPOWEROFF() function. */
216typedef FNPDMDEVPOWEROFF *PFNPDMDEVPOWEROFF;
217
218/**
219 * Attach command.
220 *
221 * This is called to let the device attach to a driver for a specified LUN
222 * at runtime. This is not called during VM construction, the device
223 * constructor has to attach to all the available drivers.
224 *
225 * This is like plugging in the keyboard or mouse after turning on the PC.
226 *
227 * @returns VBox status code.
228 * @param pDevIns The device instance.
229 * @param iLUN The logical unit which is being attached.
230 * @param fFlags Flags, combination of the PDM_TACH_FLAGS_* \#defines.
231 *
232 * @remarks Caller enters the device critical section.
233 */
234typedef DECLCALLBACK(int) FNPDMDEVATTACH(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags);
235/** Pointer to a FNPDMDEVATTACH() function. */
236typedef FNPDMDEVATTACH *PFNPDMDEVATTACH;
237
238/**
239 * Detach notification.
240 *
241 * This is called when a driver is detaching itself from a LUN of the device.
242 * The device should adjust its state to reflect this.
243 *
244 * This is like unplugging the network cable to use it for the laptop or
245 * something while the PC is still running.
246 *
247 * @param pDevIns The device instance.
248 * @param iLUN The logical unit which is being detached.
249 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
250 *
251 * @remarks Caller enters the device critical section.
252 */
253typedef DECLCALLBACK(void) FNPDMDEVDETACH(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags);
254/** Pointer to a FNPDMDEVDETACH() function. */
255typedef FNPDMDEVDETACH *PFNPDMDEVDETACH;
256
257/**
258 * Query the base interface of a logical unit.
259 *
260 * @returns VBOX status code.
261 * @param pDevIns The device instance.
262 * @param iLUN The logicial unit to query.
263 * @param ppBase Where to store the pointer to the base interface of the LUN.
264 *
265 * @remarks The device critical section is not entered.
266 */
267typedef DECLCALLBACK(int) FNPDMDEVQUERYINTERFACE(PPDMDEVINS pDevIns, unsigned iLUN, PPDMIBASE *ppBase);
268/** Pointer to a FNPDMDEVQUERYINTERFACE() function. */
269typedef FNPDMDEVQUERYINTERFACE *PFNPDMDEVQUERYINTERFACE;
270
271/**
272 * Init complete notification (after ring-0 & RC init since 5.1).
273 *
274 * This can be done to do communication with other devices and other
275 * initialization which requires everything to be in place.
276 *
277 * @returns VBOX status code.
278 * @param pDevIns The device instance.
279 *
280 * @remarks Caller enters the device critical section.
281 */
282typedef DECLCALLBACK(int) FNPDMDEVINITCOMPLETE(PPDMDEVINS pDevIns);
283/** Pointer to a FNPDMDEVINITCOMPLETE() function. */
284typedef FNPDMDEVINITCOMPLETE *PFNPDMDEVINITCOMPLETE;
285
286
287/**
288 * The context of a pfnMemSetup call.
289 */
290typedef enum PDMDEVMEMSETUPCTX
291{
292 /** Invalid zero value. */
293 PDMDEVMEMSETUPCTX_INVALID = 0,
294 /** After construction. */
295 PDMDEVMEMSETUPCTX_AFTER_CONSTRUCTION,
296 /** After reset. */
297 PDMDEVMEMSETUPCTX_AFTER_RESET,
298 /** Type size hack. */
299 PDMDEVMEMSETUPCTX_32BIT_HACK = 0x7fffffff
300} PDMDEVMEMSETUPCTX;
301
302
303/**
304 * PDM Device Registration Structure.
305 *
306 * This structure is used when registering a device from VBoxInitDevices() in HC
307 * Ring-3. PDM will continue use till the VM is terminated.
308 *
309 * @note The first part is the same in every context.
310 */
311typedef struct PDMDEVREGR3
312{
313 /** Structure version. PDM_DEVREGR3_VERSION defines the current version. */
314 uint32_t u32Version;
315 /** Reserved, must be zero. */
316 uint32_t uReserved0;
317 /** Device name, must match the ring-3 one. */
318 char szName[32];
319 /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
320 uint32_t fFlags;
321 /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
322 uint32_t fClass;
323 /** Maximum number of instances (per VM). */
324 uint32_t cMaxInstances;
325 /** The shared data structure version number. */
326 uint32_t uSharedVersion;
327 /** Size of the instance data. */
328 uint32_t cbInstanceShared;
329 /** Size of the ring-0 instance data. */
330 uint32_t cbInstanceCC;
331 /** Size of the raw-mode instance data. */
332 uint32_t cbInstanceRC;
333 /** Max number of PCI devices. */
334 uint16_t cMaxPciDevices;
335 /** Max number of MSI-X vectors in any of the PCI devices. */
336 uint16_t cMaxMsixVectors;
337 /** The description of the device. The UTF-8 string pointed to shall, like this structure,
338 * remain unchanged from registration till VM destruction. */
339 const char *pszDescription;
340
341 /** Name of the raw-mode context module (no path).
342 * Only evalutated if PDM_DEVREG_FLAGS_RC is set. */
343 const char *pszRCMod;
344 /** Name of the ring-0 module (no path).
345 * Only evalutated if PDM_DEVREG_FLAGS_R0 is set. */
346 const char *pszR0Mod;
347
348 /** Construct instance - required. */
349 PFNPDMDEVCONSTRUCT pfnConstruct;
350 /** Destruct instance - optional.
351 * Critical section NOT entered (will be destroyed). */
352 PFNPDMDEVDESTRUCT pfnDestruct;
353 /** Relocation command - optional.
354 * Critical section NOT entered. */
355 PFNPDMDEVRELOCATE pfnRelocate;
356 /**
357 * Memory setup callback.
358 *
359 * @param pDevIns The device instance data.
360 * @param enmCtx Indicates the context of the call.
361 * @remarks The critical section is entered prior to calling this method.
362 */
363 DECLR3CALLBACKMEMBER(void, pfnMemSetup, (PPDMDEVINS pDevIns, PDMDEVMEMSETUPCTX enmCtx));
364 /** Power on notification - optional.
365 * Critical section is entered. */
366 PFNPDMDEVPOWERON pfnPowerOn;
367 /** Reset notification - optional.
368 * Critical section is entered. */
369 PFNPDMDEVRESET pfnReset;
370 /** Suspend notification - optional.
371 * Critical section is entered. */
372 PFNPDMDEVSUSPEND pfnSuspend;
373 /** Resume notification - optional.
374 * Critical section is entered. */
375 PFNPDMDEVRESUME pfnResume;
376 /** Attach command - optional.
377 * Critical section is entered. */
378 PFNPDMDEVATTACH pfnAttach;
379 /** Detach notification - optional.
380 * Critical section is entered. */
381 PFNPDMDEVDETACH pfnDetach;
382 /** Query a LUN base interface - optional.
383 * Critical section is NOT entered. */
384 PFNPDMDEVQUERYINTERFACE pfnQueryInterface;
385 /** Init complete notification - optional.
386 * Critical section is entered. */
387 PFNPDMDEVINITCOMPLETE pfnInitComplete;
388 /** Power off notification - optional.
389 * Critical section is entered. */
390 PFNPDMDEVPOWEROFF pfnPowerOff;
391 /** Software system reset notification - optional.
392 * Critical section is entered. */
393 PFNPDMDEVSOFTRESET pfnSoftReset;
394
395 /** @name Reserved for future extensions, must be zero.
396 * @{ */
397 DECLR3CALLBACKMEMBER(int, pfnReserved0, (PPDMDEVINS pDevIns));
398 DECLR3CALLBACKMEMBER(int, pfnReserved1, (PPDMDEVINS pDevIns));
399 DECLR3CALLBACKMEMBER(int, pfnReserved2, (PPDMDEVINS pDevIns));
400 DECLR3CALLBACKMEMBER(int, pfnReserved3, (PPDMDEVINS pDevIns));
401 DECLR3CALLBACKMEMBER(int, pfnReserved4, (PPDMDEVINS pDevIns));
402 DECLR3CALLBACKMEMBER(int, pfnReserved5, (PPDMDEVINS pDevIns));
403 DECLR3CALLBACKMEMBER(int, pfnReserved6, (PPDMDEVINS pDevIns));
404 DECLR3CALLBACKMEMBER(int, pfnReserved7, (PPDMDEVINS pDevIns));
405 /** @} */
406
407 /** Initialization safty marker. */
408 uint32_t u32VersionEnd;
409} PDMDEVREGR3;
410/** Pointer to a PDM Device Structure. */
411typedef PDMDEVREGR3 *PPDMDEVREGR3;
412/** Const pointer to a PDM Device Structure. */
413typedef PDMDEVREGR3 const *PCPDMDEVREGR3;
414/** Current DEVREGR3 version number. */
415#define PDM_DEVREGR3_VERSION PDM_VERSION_MAKE(0xffff, 4, 0)
416
417
418/** PDM Device Flags.
419 * @{ */
420/** This flag is used to indicate that the device has a R0 component. */
421#define PDM_DEVREG_FLAGS_R0 UINT32_C(0x00000001)
422/** Requires the ring-0 component, ignore configuration values. */
423#define PDM_DEVREG_FLAGS_REQUIRE_R0 UINT32_C(0x00000002)
424/** Requires the ring-0 component, ignore configuration values. */
425#define PDM_DEVREG_FLAGS_OPT_IN_R0 UINT32_C(0x00000004)
426
427/** This flag is used to indicate that the device has a RC component. */
428#define PDM_DEVREG_FLAGS_RC UINT32_C(0x00000010)
429/** Requires the raw-mode component, ignore configuration values. */
430#define PDM_DEVREG_FLAGS_REQUIRE_RC UINT32_C(0x00000020)
431/** Requires the raw-mode component, ignore configuration values. */
432#define PDM_DEVREG_FLAGS_OPT_IN_RC UINT32_C(0x00000040)
433
434/** @def PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT
435 * The bit count for the current host.
436 * @note Superfluous, but still around for hysterical raisins. */
437#if HC_ARCH_BITS == 32
438# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT UINT32_C(0x00000100)
439#elif HC_ARCH_BITS == 64
440# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT UINT32_C(0x00000200)
441#else
442# error Unsupported HC_ARCH_BITS value.
443#endif
444/** The host bit count mask. */
445#define PDM_DEVREG_FLAGS_HOST_BITS_MASK UINT32_C(0x00000300)
446
447/** The device support only 32-bit guests. */
448#define PDM_DEVREG_FLAGS_GUEST_BITS_32 UINT32_C(0x00001000)
449/** The device support only 64-bit guests. */
450#define PDM_DEVREG_FLAGS_GUEST_BITS_64 UINT32_C(0x00002000)
451/** The device support both 32-bit & 64-bit guests. */
452#define PDM_DEVREG_FLAGS_GUEST_BITS_32_64 UINT32_C(0x00003000)
453/** @def PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT
454 * The guest bit count for the current compilation. */
455#if GC_ARCH_BITS == 32
456# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT PDM_DEVREG_FLAGS_GUEST_BITS_32
457#elif GC_ARCH_BITS == 64
458# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT PDM_DEVREG_FLAGS_GUEST_BITS_32_64
459#else
460# error Unsupported GC_ARCH_BITS value.
461#endif
462/** The guest bit count mask. */
463#define PDM_DEVREG_FLAGS_GUEST_BITS_MASK UINT32_C(0x00003000)
464
465/** A convenience. */
466#define PDM_DEVREG_FLAGS_DEFAULT_BITS (PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT)
467
468/** Indicates that the device needs to be notified before the drivers when suspending. */
469#define PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION UINT32_C(0x00010000)
470/** Indicates that the device needs to be notified before the drivers when powering off. */
471#define PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION UINT32_C(0x00020000)
472/** Indicates that the device needs to be notified before the drivers when resetting. */
473#define PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION UINT32_C(0x00040000)
474
475/** This flag is used to indicate that the device has been converted to the
476 * new device style. */
477#define PDM_DEVREG_FLAGS_NEW_STYLE UINT32_C(0x80000000)
478
479/** @} */
480
481
482/** PDM Device Classes.
483 * The order is important, lower bit earlier instantiation.
484 * @{ */
485/** Architecture device. */
486#define PDM_DEVREG_CLASS_ARCH RT_BIT(0)
487/** Architecture BIOS device. */
488#define PDM_DEVREG_CLASS_ARCH_BIOS RT_BIT(1)
489/** PCI bus brigde. */
490#define PDM_DEVREG_CLASS_BUS_PCI RT_BIT(2)
491/** ISA bus brigde. */
492#define PDM_DEVREG_CLASS_BUS_ISA RT_BIT(3)
493/** Input device (mouse, keyboard, joystick, HID, ...). */
494#define PDM_DEVREG_CLASS_INPUT RT_BIT(4)
495/** Interrupt controller (PIC). */
496#define PDM_DEVREG_CLASS_PIC RT_BIT(5)
497/** Interval controoler (PIT). */
498#define PDM_DEVREG_CLASS_PIT RT_BIT(6)
499/** RTC/CMOS. */
500#define PDM_DEVREG_CLASS_RTC RT_BIT(7)
501/** DMA controller. */
502#define PDM_DEVREG_CLASS_DMA RT_BIT(8)
503/** VMM Device. */
504#define PDM_DEVREG_CLASS_VMM_DEV RT_BIT(9)
505/** Graphics device, like VGA. */
506#define PDM_DEVREG_CLASS_GRAPHICS RT_BIT(10)
507/** Storage controller device. */
508#define PDM_DEVREG_CLASS_STORAGE RT_BIT(11)
509/** Network interface controller. */
510#define PDM_DEVREG_CLASS_NETWORK RT_BIT(12)
511/** Audio. */
512#define PDM_DEVREG_CLASS_AUDIO RT_BIT(13)
513/** USB HIC. */
514#define PDM_DEVREG_CLASS_BUS_USB RT_BIT(14)
515/** ACPI. */
516#define PDM_DEVREG_CLASS_ACPI RT_BIT(15)
517/** Serial controller device. */
518#define PDM_DEVREG_CLASS_SERIAL RT_BIT(16)
519/** Parallel controller device */
520#define PDM_DEVREG_CLASS_PARALLEL RT_BIT(17)
521/** Host PCI pass-through device */
522#define PDM_DEVREG_CLASS_HOST_DEV RT_BIT(18)
523/** Misc devices (always last). */
524#define PDM_DEVREG_CLASS_MISC RT_BIT(31)
525/** @} */
526
527
528/**
529 * PDM Device Registration Structure, ring-0.
530 *
531 * This structure is used when registering a device from VBoxInitDevices() in HC
532 * Ring-0. PDM will continue use till the VM is terminated.
533 */
534typedef struct PDMDEVREGR0
535{
536 /** Structure version. PDM_DEVREGR0_VERSION defines the current version. */
537 uint32_t u32Version;
538 /** Reserved, must be zero. */
539 uint32_t uReserved0;
540 /** Device name, must match the ring-3 one. */
541 char szName[32];
542 /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
543 uint32_t fFlags;
544 /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
545 uint32_t fClass;
546 /** Maximum number of instances (per VM). */
547 uint32_t cMaxInstances;
548 /** The shared data structure version number. */
549 uint32_t uSharedVersion;
550 /** Size of the instance data. */
551 uint32_t cbInstanceShared;
552 /** Size of the ring-0 instance data. */
553 uint32_t cbInstanceCC;
554 /** Size of the raw-mode instance data. */
555 uint32_t cbInstanceRC;
556 /** Max number of PCI devices. */
557 uint16_t cMaxPciDevices;
558 /** Max number of MSI-X vectors in any of the PCI devices. */
559 uint16_t cMaxMsixVectors;
560 /** The description of the device. The UTF-8 string pointed to shall, like this structure,
561 * remain unchanged from registration till VM destruction. */
562 const char *pszDescription;
563
564 /**
565 * Early construction callback (optional).
566 *
567 * This is called right after the device instance structure has been allocated
568 * and before the ring-3 constructor gets called.
569 *
570 * @returns VBox status code.
571 * @param pDevIns The device instance data.
572 * @note The destructure is always called, regardless of the return status.
573 */
574 DECLR0CALLBACKMEMBER(int, pfnEarlyConstruct, (PPDMDEVINS pDevIns));
575
576 /**
577 * Regular construction callback (optional).
578 *
579 * This is called after (or during) the ring-3 constructor.
580 *
581 * @returns VBox status code.
582 * @param pDevIns The device instance data.
583 * @note The destructure is always called, regardless of the return status.
584 */
585 DECLR0CALLBACKMEMBER(int, pfnConstruct, (PPDMDEVINS pDevIns));
586
587 /**
588 * Destructor (optional).
589 *
590 * This is called after the ring-3 destruction. This is not called if ring-3
591 * fails to trigger it (e.g. process is killed or crashes).
592 *
593 * @param pDevIns The device instance data.
594 */
595 DECLR0CALLBACKMEMBER(void, pfnDestruct, (PPDMDEVINS pDevIns));
596
597 /**
598 * Final destructor (optional).
599 *
600 * This is called right before the memory is freed, which happens when the
601 * VM/GVM object is destroyed. This is always called.
602 *
603 * @param pDevIns The device instance data.
604 */
605 DECLR0CALLBACKMEMBER(void, pfnFinalDestruct, (PPDMDEVINS pDevIns));
606
607 /**
608 * Generic request handler (optional).
609 *
610 * @param pDevIns The device instance data.
611 * @param uReq Device specific request.
612 * @param uArg Request argument.
613 */
614 DECLR0CALLBACKMEMBER(int, pfnRequest, (PPDMDEVINS pDevIns, uint32_t uReq, uint64_t uArg));
615
616 /** @name Reserved for future extensions, must be zero.
617 * @{ */
618 DECLR0CALLBACKMEMBER(int, pfnReserved0, (PPDMDEVINS pDevIns));
619 DECLR0CALLBACKMEMBER(int, pfnReserved1, (PPDMDEVINS pDevIns));
620 DECLR0CALLBACKMEMBER(int, pfnReserved2, (PPDMDEVINS pDevIns));
621 DECLR0CALLBACKMEMBER(int, pfnReserved3, (PPDMDEVINS pDevIns));
622 DECLR0CALLBACKMEMBER(int, pfnReserved4, (PPDMDEVINS pDevIns));
623 DECLR0CALLBACKMEMBER(int, pfnReserved5, (PPDMDEVINS pDevIns));
624 DECLR0CALLBACKMEMBER(int, pfnReserved6, (PPDMDEVINS pDevIns));
625 DECLR0CALLBACKMEMBER(int, pfnReserved7, (PPDMDEVINS pDevIns));
626 /** @} */
627
628 /** Initialization safty marker. */
629 uint32_t u32VersionEnd;
630} PDMDEVREGR0;
631/** Pointer to a ring-0 PDM device registration structure. */
632typedef PDMDEVREGR0 *PPDMDEVREGR0;
633/** Pointer to a const ring-0 PDM device registration structure. */
634typedef PDMDEVREGR0 const *PCPDMDEVREGR0;
635/** Current DEVREGR0 version number. */
636#define PDM_DEVREGR0_VERSION PDM_VERSION_MAKE(0xff80, 1, 0)
637
638
639/**
640 * PDM Device Registration Structure, raw-mode
641 *
642 * At the moment, this structure is mostly here to match the other two contexts.
643 */
644typedef struct PDMDEVREGRC
645{
646 /** Structure version. PDM_DEVREGRC_VERSION defines the current version. */
647 uint32_t u32Version;
648 /** Reserved, must be zero. */
649 uint32_t uReserved0;
650 /** Device name, must match the ring-3 one. */
651 char szName[32];
652 /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
653 uint32_t fFlags;
654 /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
655 uint32_t fClass;
656 /** Maximum number of instances (per VM). */
657 uint32_t cMaxInstances;
658 /** The shared data structure version number. */
659 uint32_t uSharedVersion;
660 /** Size of the instance data. */
661 uint32_t cbInstanceShared;
662 /** Size of the ring-0 instance data. */
663 uint32_t cbInstanceCC;
664 /** Size of the raw-mode instance data. */
665 uint32_t cbInstanceRC;
666 /** Max number of PCI devices. */
667 uint16_t cMaxPciDevices;
668 /** Max number of MSI-X vectors in any of the PCI devices. */
669 uint16_t cMaxMsixVectors;
670 /** The description of the device. The UTF-8 string pointed to shall, like this structure,
671 * remain unchanged from registration till VM destruction. */
672 const char *pszDescription;
673
674 /**
675 * Constructor callback.
676 *
677 * This is called much later than both the ring-0 and ring-3 constructors, since
678 * raw-mode v2 require a working VMM to run actual code.
679 *
680 * @returns VBox status code.
681 * @param pDevIns The device instance data.
682 * @note The destructure is always called, regardless of the return status.
683 */
684 DECLRGCALLBACKMEMBER(int, pfnConstruct, (PPDMDEVINS pDevIns));
685
686 /** @name Reserved for future extensions, must be zero.
687 * @{ */
688 DECLRCCALLBACKMEMBER(int, pfnReserved0, (PPDMDEVINS pDevIns));
689 DECLRCCALLBACKMEMBER(int, pfnReserved1, (PPDMDEVINS pDevIns));
690 DECLRCCALLBACKMEMBER(int, pfnReserved2, (PPDMDEVINS pDevIns));
691 DECLRCCALLBACKMEMBER(int, pfnReserved3, (PPDMDEVINS pDevIns));
692 DECLRCCALLBACKMEMBER(int, pfnReserved4, (PPDMDEVINS pDevIns));
693 DECLRCCALLBACKMEMBER(int, pfnReserved5, (PPDMDEVINS pDevIns));
694 DECLRCCALLBACKMEMBER(int, pfnReserved6, (PPDMDEVINS pDevIns));
695 DECLRCCALLBACKMEMBER(int, pfnReserved7, (PPDMDEVINS pDevIns));
696 /** @} */
697
698 /** Initialization safty marker. */
699 uint32_t u32VersionEnd;
700} PDMDEVREGRC;
701/** Pointer to a raw-mode PDM device registration structure. */
702typedef PDMDEVREGRC *PPDMDEVREGRC;
703/** Pointer to a const raw-mode PDM device registration structure. */
704typedef PDMDEVREGRC const *PCPDMDEVREGRC;
705/** Current DEVREGRC version number. */
706#define PDM_DEVREGRC_VERSION PDM_VERSION_MAKE(0xff81, 1, 0)
707
708
709
710/** @def PDM_DEVREG_VERSION
711 * Current DEVREG version number. */
712/** @typedef PDMDEVREGR3
713 * A current context PDM device registration structure. */
714/** @typedef PPDMDEVREGR3
715 * Pointer to a current context PDM device registration structure. */
716/** @typedef PCPDMDEVREGR3
717 * Pointer to a const current context PDM device registration structure. */
718#if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
719# define PDM_DEVREG_VERSION PDM_DEVREGR3_VERSION
720typedef PDMDEVREGR3 PDMDEVREG;
721typedef PPDMDEVREGR3 PPDMDEVREG;
722typedef PCPDMDEVREGR3 PCPDMDEVREG;
723#elif defined(IN_RING0)
724# define PDM_DEVREG_VERSION PDM_DEVREGR0_VERSION
725typedef PDMDEVREGR0 PDMDEVREG;
726typedef PPDMDEVREGR0 PPDMDEVREG;
727typedef PCPDMDEVREGR0 PCPDMDEVREG;
728#elif defined(IN_RC)
729# define PDM_DEVREG_VERSION PDM_DEVREGRC_VERSION
730typedef PDMDEVREGRC PDMDEVREG;
731typedef PPDMDEVREGRC PPDMDEVREG;
732typedef PCPDMDEVREGRC PCPDMDEVREG;
733#else
734# error "Not IN_RING3, IN_RING0 or IN_RC"
735#endif
736
737
738/**
739 * Device registrations for ring-0 modules.
740 *
741 * This structure is used directly and must therefore reside in persistent
742 * memory (i.e. the data section).
743 */
744typedef struct PDMDEVMODREGR0
745{
746 /** The structure version (PDM_DEVMODREGR0_VERSION). */
747 uint32_t u32Version;
748 /** Number of devices in the array papDevRegs points to. */
749 uint32_t cDevRegs;
750 /** Pointer to device registration structures. */
751 PCPDMDEVREGR0 *papDevRegs;
752 /** The ring-0 module handle - PDM internal, fingers off. */
753 void *hMod;
754 /** List entry - PDM internal, fingers off. */
755 RTLISTNODE ListEntry;
756} PDMDEVMODREGR0;
757/** Pointer to device registriations for a ring-0 module. */
758typedef PDMDEVMODREGR0 *PPDMDEVMODREGR0;
759/** Current PDMDEVMODREGR0 version number. */
760#define PDM_DEVMODREGR0_VERSION PDM_VERSION_MAKE(0xff85, 1, 0)
761
762
763/** @name IRQ Level for use with the *SetIrq APIs.
764 * @{
765 */
766/** Assert the IRQ (can assume value 1). */
767#define PDM_IRQ_LEVEL_HIGH RT_BIT(0)
768/** Deassert the IRQ (can assume value 0). */
769#define PDM_IRQ_LEVEL_LOW 0
770/** flip-flop - deassert and then assert the IRQ again immediately. */
771#define PDM_IRQ_LEVEL_FLIP_FLOP (RT_BIT(1) | PDM_IRQ_LEVEL_HIGH)
772/** @} */
773
774/**
775 * Registration record for MSI/MSI-X emulation.
776 */
777typedef struct PDMMSIREG
778{
779 /** Number of MSI interrupt vectors, 0 if MSI not supported */
780 uint16_t cMsiVectors;
781 /** Offset of MSI capability */
782 uint8_t iMsiCapOffset;
783 /** Offset of next capability to MSI */
784 uint8_t iMsiNextOffset;
785 /** If we support 64-bit MSI addressing */
786 bool fMsi64bit;
787 /** If we do not support per-vector masking */
788 bool fMsiNoMasking;
789
790 /** Number of MSI-X interrupt vectors, 0 if MSI-X not supported */
791 uint16_t cMsixVectors;
792 /** Offset of MSI-X capability */
793 uint8_t iMsixCapOffset;
794 /** Offset of next capability to MSI-X */
795 uint8_t iMsixNextOffset;
796 /** Value of PCI BAR (base addresss register) assigned by device for MSI-X page access */
797 uint8_t iMsixBar;
798} PDMMSIREG;
799typedef PDMMSIREG *PPDMMSIREG;
800
801/**
802 * PCI Bus registration structure.
803 * All the callbacks, except the PCIBIOS hack, are working on PCI devices.
804 */
805typedef struct PDMPCIBUSREGR3
806{
807 /** Structure version number. PDM_PCIBUSREGR3_VERSION defines the current version. */
808 uint32_t u32Version;
809
810 /**
811 * Registers the device with the default PCI bus.
812 *
813 * @returns VBox status code.
814 * @param pDevIns Device instance of the PCI Bus.
815 * @param pPciDev The PCI device structure.
816 * @param fFlags Reserved for future use, PDMPCIDEVREG_F_MBZ.
817 * @param uPciDevNo PDMPCIDEVREG_DEV_NO_FIRST_UNUSED, or a specific
818 * device number (0-31).
819 * @param uPciFunNo PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, or a specific
820 * function number (0-7).
821 * @param pszName Device name (static but not unique).
822 *
823 * @remarks Caller enters the PDM critical section.
824 */
825 DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
826 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName));
827
828 /**
829 * Initialize MSI or MSI-X emulation support in a PCI device.
830 *
831 * This cannot handle all corner cases of the MSI/MSI-X spec, but for the
832 * vast majority of device emulation it covers everything necessary. It's
833 * fully automatic, taking care of all BAR and config space requirements,
834 * and interrupt delivery is done using PDMDevHlpPCISetIrq and friends.
835 * When MSI/MSI-X is enabled then the iIrq parameter is redefined to take
836 * the vector number (otherwise it has the usual INTA-D meaning for PCI).
837 *
838 * A device not using this can still offer MSI/MSI-X. In this case it's
839 * completely up to the device (in the MSI-X case) to create/register the
840 * necessary MMIO BAR, handle all config space/BAR updating and take care
841 * of delivering the interrupts appropriately.
842 *
843 * @returns VBox status code.
844 * @param pDevIns Device instance of the PCI Bus.
845 * @param pPciDev The PCI device structure.
846 * @param pMsiReg MSI emulation registration structure
847 * @remarks Caller enters the PDM critical section.
848 */
849 DECLR3CALLBACKMEMBER(int, pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg));
850
851 /**
852 * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
853 *
854 * @returns VBox status code.
855 * @param pDevIns Device instance of the PCI Bus.
856 * @param pPciDev The PCI device structure.
857 * @param iRegion The region number.
858 * @param cbRegion Size of the region.
859 * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or
860 * PCI_ADDRESS_SPACE_MEM_PREFETCH, optionally with
861 * PCI_ADDRESS_SPACE_BAR64 or'ed in.
862 * @param fFlags PDMPCIDEV_IORGN_F_XXX.
863 * @param hHandle An I/O port, MMIO or MMIO2 handle according to
864 * @a fFlags, UINT64_MAX if no handle is passed
865 * (old style).
866 * @param pfnCallback Callback for doing the mapping. Optional if a handle
867 * is given.
868 * @remarks Caller enters the PDM critical section.
869 */
870 DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
871 RTGCPHYS cbRegion, PCIADDRESSSPACE enmType, uint32_t fFlags,
872 uint64_t hHandle, PFNPCIIOREGIONMAP pfnCallback));
873
874 /**
875 * Register PCI configuration space read/write intercept callbacks.
876 *
877 * @param pDevIns Device instance of the PCI Bus.
878 * @param pPciDev The PCI device structure.
879 * @param pfnRead Pointer to the user defined PCI config read function.
880 * @param pfnWrite Pointer to the user defined PCI config write function.
881 * to call default PCI config write function. Can be NULL.
882 * @remarks Caller enters the PDM critical section.
883 * @thread EMT
884 */
885 DECLR3CALLBACKMEMBER(void, pfnInterceptConfigAccesses,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
886 PFNPCICONFIGREAD pfnRead, PFNPCICONFIGWRITE pfnWrite));
887
888 /**
889 * Perform a PCI configuration space write, bypassing interception.
890 *
891 * This is for devices that make use of PDMDevHlpPCIInterceptConfigAccesses().
892 *
893 * @returns Strict VBox status code (mainly DBGFSTOP).
894 * @param pDevIns Device instance of the PCI Bus.
895 * @param pPciDev The PCI device which config space is being read.
896 * @param uAddress The config space address.
897 * @param cb The size of the read: 1, 2 or 4 bytes.
898 * @param u32Value The value to write.
899 * @note The caller (PDM) does not enter the PDM critsect, but it is possible
900 * that the (root) bus will have done that already.
901 */
902 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnConfigWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
903 uint32_t uAddress, unsigned cb, uint32_t u32Value));
904
905 /**
906 * Perform a PCI configuration space read, bypassing interception.
907 *
908 * This is for devices that make use of PDMDevHlpPCIInterceptConfigAccesses().
909 *
910 * @returns Strict VBox status code (mainly DBGFSTOP).
911 * @param pDevIns Device instance of the PCI Bus.
912 * @param pPciDev The PCI device which config space is being read.
913 * @param uAddress The config space address.
914 * @param cb The size of the read: 1, 2 or 4 bytes.
915 * @param pu32Value Where to return the value.
916 * @note The caller (PDM) does not enter the PDM critsect, but it is possible
917 * that the (root) bus will have done that already.
918 */
919 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnConfigRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
920 uint32_t uAddress, unsigned cb, uint32_t *pu32Value));
921
922 /**
923 * Set the IRQ for a PCI device.
924 *
925 * @param pDevIns Device instance of the PCI Bus.
926 * @param pPciDev The PCI device structure.
927 * @param iIrq IRQ number to set.
928 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
929 * @param uTagSrc The IRQ tag and source (for tracing).
930 * @remarks Caller enters the PDM critical section.
931 */
932 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
933
934 /** Marks the end of the structure with PDM_PCIBUSREGR3_VERSION. */
935 uint32_t u32EndVersion;
936} PDMPCIBUSREGR3;
937/** Pointer to a PCI bus registration structure. */
938typedef PDMPCIBUSREGR3 *PPDMPCIBUSREGR3;
939/** Current PDMPCIBUSREGR3 version number. */
940#define PDM_PCIBUSREGR3_VERSION PDM_VERSION_MAKE(0xff86, 2, 0)
941
942/**
943 * PCI Bus registration structure for ring-0.
944 */
945typedef struct PDMPCIBUSREGR0
946{
947 /** Structure version number. PDM_PCIBUSREGR0_VERSION defines the current version. */
948 uint32_t u32Version;
949 /** The PCI bus number (from ring-3 registration). */
950 uint32_t iBus;
951 /**
952 * Set the IRQ for a PCI device.
953 *
954 * @param pDevIns Device instance of the PCI Bus.
955 * @param pPciDev The PCI device structure.
956 * @param iIrq IRQ number to set.
957 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
958 * @param uTagSrc The IRQ tag and source (for tracing).
959 * @remarks Caller enters the PDM critical section.
960 */
961 DECLR0CALLBACKMEMBER(void, pfnSetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
962 /** Marks the end of the structure with PDM_PCIBUSREGR0_VERSION. */
963 uint32_t u32EndVersion;
964} PDMPCIBUSREGR0;
965/** Pointer to a PCI bus ring-0 registration structure. */
966typedef PDMPCIBUSREGR0 *PPDMPCIBUSREGR0;
967/** Current PDMPCIBUSREGR0 version number. */
968#define PDM_PCIBUSREGR0_VERSION PDM_VERSION_MAKE(0xff87, 1, 0)
969
970/**
971 * PCI Bus registration structure for raw-mode.
972 */
973typedef struct PDMPCIBUSREGRC
974{
975 /** Structure version number. PDM_PCIBUSREGRC_VERSION defines the current version. */
976 uint32_t u32Version;
977 /** The PCI bus number (from ring-3 registration). */
978 uint32_t iBus;
979 /**
980 * Set the IRQ for a PCI device.
981 *
982 * @param pDevIns Device instance of the PCI Bus.
983 * @param pPciDev The PCI device structure.
984 * @param iIrq IRQ number to set.
985 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
986 * @param uTagSrc The IRQ tag and source (for tracing).
987 * @remarks Caller enters the PDM critical section.
988 */
989 DECLRCCALLBACKMEMBER(void, pfnSetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
990 /** Marks the end of the structure with PDM_PCIBUSREGRC_VERSION. */
991 uint32_t u32EndVersion;
992} PDMPCIBUSREGRC;
993/** Pointer to a PCI bus raw-mode registration structure. */
994typedef PDMPCIBUSREGRC *PPDMPCIBUSREGRC;
995/** Current PDMPCIBUSREGRC version number. */
996#define PDM_PCIBUSREGRC_VERSION PDM_VERSION_MAKE(0xff88, 1, 0)
997
998/** PCI bus registration structure for the current context. */
999typedef CTX_SUFF(PDMPCIBUSREG) PDMPCIBUSREGCC;
1000/** Pointer to a PCI bus registration structure for the current context. */
1001typedef CTX_SUFF(PPDMPCIBUSREG) PPDMPCIBUSREGCC;
1002/** PCI bus registration structure version for the current context. */
1003#define PDM_PCIBUSREGCC_VERSION CTX_MID(PDM_PCIBUSREG,_VERSION)
1004
1005
1006/**
1007 * PCI Bus RC helpers.
1008 */
1009typedef struct PDMPCIHLPRC
1010{
1011 /** Structure version. PDM_PCIHLPRC_VERSION defines the current version. */
1012 uint32_t u32Version;
1013
1014 /**
1015 * Set an ISA IRQ.
1016 *
1017 * @param pDevIns PCI device instance.
1018 * @param iIrq IRQ number to set.
1019 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1020 * @param uTagSrc The IRQ tag and source (for tracing).
1021 * @thread EMT only.
1022 */
1023 DECLRCCALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1024
1025 /**
1026 * Set an I/O-APIC IRQ.
1027 *
1028 * @param pDevIns PCI device instance.
1029 * @param iIrq IRQ number to set.
1030 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1031 * @param uTagSrc The IRQ tag and source (for tracing).
1032 * @thread EMT only.
1033 */
1034 DECLRCCALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1035
1036 /**
1037 * Send an MSI.
1038 *
1039 * @param pDevIns PCI device instance.
1040 * @param GCPhys Physical address MSI request was written.
1041 * @param uValue Value written.
1042 * @param uTagSrc The IRQ tag and source (for tracing).
1043 * @thread EMT only.
1044 */
1045 DECLRCCALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
1046
1047
1048 /**
1049 * Acquires the PDM lock.
1050 *
1051 * @returns VINF_SUCCESS on success.
1052 * @returns rc if we failed to acquire the lock.
1053 * @param pDevIns The PCI device instance.
1054 * @param rc What to return if we fail to acquire the lock.
1055 */
1056 DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1057
1058 /**
1059 * Releases the PDM lock.
1060 *
1061 * @param pDevIns The PCI device instance.
1062 */
1063 DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1064
1065 /**
1066 * Gets a bus by it's PDM ordinal (typically the parent bus).
1067 *
1068 * @returns Pointer to the device instance of the bus.
1069 * @param pDevIns The PCI bus device instance.
1070 * @param idxPdmBus The PDM ordinal value of the bus to get.
1071 */
1072 DECLRCCALLBACKMEMBER(PPDMDEVINS, pfnGetBusByNo,(PPDMDEVINS pDevIns, uint32_t idxPdmBus));
1073
1074 /** Just a safety precaution. */
1075 uint32_t u32TheEnd;
1076} PDMPCIHLPRC;
1077/** Pointer to PCI helpers. */
1078typedef RCPTRTYPE(PDMPCIHLPRC *) PPDMPCIHLPRC;
1079/** Pointer to const PCI helpers. */
1080typedef RCPTRTYPE(const PDMPCIHLPRC *) PCPDMPCIHLPRC;
1081
1082/** Current PDMPCIHLPRC version number. */
1083#define PDM_PCIHLPRC_VERSION PDM_VERSION_MAKE(0xfffd, 3, 0)
1084
1085
1086/**
1087 * PCI Bus R0 helpers.
1088 */
1089typedef struct PDMPCIHLPR0
1090{
1091 /** Structure version. PDM_PCIHLPR0_VERSION defines the current version. */
1092 uint32_t u32Version;
1093
1094 /**
1095 * Set an ISA IRQ.
1096 *
1097 * @param pDevIns PCI device instance.
1098 * @param iIrq IRQ number to set.
1099 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1100 * @param uTagSrc The IRQ tag and source (for tracing).
1101 * @thread EMT only.
1102 */
1103 DECLR0CALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1104
1105 /**
1106 * Set an I/O-APIC IRQ.
1107 *
1108 * @param pDevIns PCI device instance.
1109 * @param iIrq IRQ number to set.
1110 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1111 * @param uTagSrc The IRQ tag and source (for tracing).
1112 * @thread EMT only.
1113 */
1114 DECLR0CALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1115
1116 /**
1117 * Send an MSI.
1118 *
1119 * @param pDevIns PCI device instance.
1120 * @param GCPhys Physical address MSI request was written.
1121 * @param uValue Value written.
1122 * @param uTagSrc The IRQ tag and source (for tracing).
1123 * @thread EMT only.
1124 */
1125 DECLR0CALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
1126
1127 /**
1128 * Acquires the PDM lock.
1129 *
1130 * @returns VINF_SUCCESS on success.
1131 * @returns rc if we failed to acquire the lock.
1132 * @param pDevIns The PCI device instance.
1133 * @param rc What to return if we fail to acquire the lock.
1134 */
1135 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1136
1137 /**
1138 * Releases the PDM lock.
1139 *
1140 * @param pDevIns The PCI device instance.
1141 */
1142 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1143
1144 /**
1145 * Gets a bus by it's PDM ordinal (typically the parent bus).
1146 *
1147 * @returns Pointer to the device instance of the bus.
1148 * @param pDevIns The PCI bus device instance.
1149 * @param idxPdmBus The PDM ordinal value of the bus to get.
1150 */
1151 DECLR0CALLBACKMEMBER(PPDMDEVINS, pfnGetBusByNo,(PPDMDEVINS pDevIns, uint32_t idxPdmBus));
1152
1153 /** Just a safety precaution. */
1154 uint32_t u32TheEnd;
1155} PDMPCIHLPR0;
1156/** Pointer to PCI helpers. */
1157typedef R0PTRTYPE(PDMPCIHLPR0 *) PPDMPCIHLPR0;
1158/** Pointer to const PCI helpers. */
1159typedef R0PTRTYPE(const PDMPCIHLPR0 *) PCPDMPCIHLPR0;
1160
1161/** Current PDMPCIHLPR0 version number. */
1162#define PDM_PCIHLPR0_VERSION PDM_VERSION_MAKE(0xfffc, 4, 0)
1163
1164/**
1165 * PCI device helpers.
1166 */
1167typedef struct PDMPCIHLPR3
1168{
1169 /** Structure version. PDM_PCIHLPR3_VERSION defines the current version. */
1170 uint32_t u32Version;
1171
1172 /**
1173 * Set an ISA IRQ.
1174 *
1175 * @param pDevIns The PCI device instance.
1176 * @param iIrq IRQ number to set.
1177 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1178 * @param uTagSrc The IRQ tag and source (for tracing).
1179 */
1180 DECLR3CALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1181
1182 /**
1183 * Set an I/O-APIC IRQ.
1184 *
1185 * @param pDevIns The PCI device instance.
1186 * @param iIrq IRQ number to set.
1187 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1188 * @param uTagSrc The IRQ tag and source (for tracing).
1189 */
1190 DECLR3CALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1191
1192 /**
1193 * Send an MSI.
1194 *
1195 * @param pDevIns PCI device instance.
1196 * @param GCPhys Physical address MSI request was written.
1197 * @param uValue Value written.
1198 * @param uTagSrc The IRQ tag and source (for tracing).
1199 */
1200 DECLR3CALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
1201
1202 /**
1203 * Checks if the given address is an MMIO2 or pre-registered MMIO base address.
1204 *
1205 * @returns true/false accordingly.
1206 * @param pDevIns The PCI device instance.
1207 * @param pOwner The owner of the memory, optional.
1208 * @param GCPhys The address to check.
1209 * @sa PGMR3PhysMMIOExIsBase
1210 */
1211 DECLR3CALLBACKMEMBER(bool, pfnIsMMIOExBase,(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys));
1212
1213 /**
1214 * Acquires the PDM lock.
1215 *
1216 * @returns VINF_SUCCESS on success.
1217 * @returns Fatal error on failure.
1218 * @param pDevIns The PCI device instance.
1219 * @param rc Dummy for making the interface identical to the RC and R0 versions.
1220 */
1221 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1222
1223 /**
1224 * Releases the PDM lock.
1225 *
1226 * @param pDevIns The PCI device instance.
1227 */
1228 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1229
1230 /**
1231 * Gets a bus by it's PDM ordinal (typically the parent bus).
1232 *
1233 * @returns Pointer to the device instance of the bus.
1234 * @param pDevIns The PCI bus device instance.
1235 * @param idxPdmBus The PDM ordinal value of the bus to get.
1236 */
1237 DECLR3CALLBACKMEMBER(PPDMDEVINS, pfnGetBusByNo,(PPDMDEVINS pDevIns, uint32_t idxPdmBus));
1238
1239 /** Just a safety precaution. */
1240 uint32_t u32TheEnd;
1241} PDMPCIHLPR3;
1242/** Pointer to PCI helpers. */
1243typedef R3PTRTYPE(PDMPCIHLPR3 *) PPDMPCIHLPR3;
1244/** Pointer to const PCI helpers. */
1245typedef R3PTRTYPE(const PDMPCIHLPR3 *) PCPDMPCIHLPR3;
1246
1247/** Current PDMPCIHLPR3 version number. */
1248#define PDM_PCIHLPR3_VERSION PDM_VERSION_MAKE(0xfffb, 4, 0)
1249
1250
1251/**
1252 * Programmable Interrupt Controller registration structure.
1253 */
1254typedef struct PDMPICREG
1255{
1256 /** Structure version number. PDM_PICREG_VERSION defines the current version. */
1257 uint32_t u32Version;
1258
1259 /**
1260 * Set the an IRQ.
1261 *
1262 * @param pDevIns Device instance of the PIC.
1263 * @param iIrq IRQ number to set.
1264 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1265 * @param uTagSrc The IRQ tag and source (for tracing).
1266 * @remarks Caller enters the PDM critical section.
1267 */
1268 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1269
1270 /**
1271 * Get a pending interrupt.
1272 *
1273 * @returns Pending interrupt number.
1274 * @param pDevIns Device instance of the PIC.
1275 * @param puTagSrc Where to return the IRQ tag and source.
1276 * @remarks Caller enters the PDM critical section.
1277 */
1278 DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
1279
1280 /** The name of the RC SetIrq entry point. */
1281 const char *pszSetIrqRC;
1282 /** The name of the RC GetInterrupt entry point. */
1283 const char *pszGetInterruptRC;
1284
1285 /** The name of the R0 SetIrq entry point. */
1286 const char *pszSetIrqR0;
1287 /** The name of the R0 GetInterrupt entry point. */
1288 const char *pszGetInterruptR0;
1289} PDMPICREG;
1290/** Pointer to a PIC registration structure. */
1291typedef PDMPICREG *PPDMPICREG;
1292
1293/** Current PDMPICREG version number. */
1294#define PDM_PICREG_VERSION PDM_VERSION_MAKE(0xfffa, 2, 0)
1295
1296/**
1297 * PIC RC helpers.
1298 */
1299typedef struct PDMPICHLPRC
1300{
1301 /** Structure version. PDM_PICHLPRC_VERSION defines the current version. */
1302 uint32_t u32Version;
1303
1304 /**
1305 * Set the interrupt force action flag.
1306 *
1307 * @param pDevIns Device instance of the PIC.
1308 */
1309 DECLRCCALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
1310
1311 /**
1312 * Clear the interrupt force action flag.
1313 *
1314 * @param pDevIns Device instance of the PIC.
1315 */
1316 DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
1317
1318 /**
1319 * Acquires the PDM lock.
1320 *
1321 * @returns VINF_SUCCESS on success.
1322 * @returns rc if we failed to acquire the lock.
1323 * @param pDevIns The PIC device instance.
1324 * @param rc What to return if we fail to acquire the lock.
1325 */
1326 DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1327
1328 /**
1329 * Releases the PDM lock.
1330 *
1331 * @param pDevIns The PIC device instance.
1332 */
1333 DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1334
1335 /** Just a safety precaution. */
1336 uint32_t u32TheEnd;
1337} PDMPICHLPRC;
1338
1339/** Pointer to PIC RC helpers. */
1340typedef RCPTRTYPE(PDMPICHLPRC *) PPDMPICHLPRC;
1341/** Pointer to const PIC RC helpers. */
1342typedef RCPTRTYPE(const PDMPICHLPRC *) PCPDMPICHLPRC;
1343
1344/** Current PDMPICHLPRC version number. */
1345#define PDM_PICHLPRC_VERSION PDM_VERSION_MAKE(0xfff9, 2, 0)
1346
1347
1348/**
1349 * PIC R0 helpers.
1350 */
1351typedef struct PDMPICHLPR0
1352{
1353 /** Structure version. PDM_PICHLPR0_VERSION defines the current version. */
1354 uint32_t u32Version;
1355
1356 /**
1357 * Set the interrupt force action flag.
1358 *
1359 * @param pDevIns Device instance of the PIC.
1360 */
1361 DECLR0CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
1362
1363 /**
1364 * Clear the interrupt force action flag.
1365 *
1366 * @param pDevIns Device instance of the PIC.
1367 */
1368 DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
1369
1370 /**
1371 * Acquires the PDM lock.
1372 *
1373 * @returns VINF_SUCCESS on success.
1374 * @returns rc if we failed to acquire the lock.
1375 * @param pDevIns The PIC device instance.
1376 * @param rc What to return if we fail to acquire the lock.
1377 */
1378 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1379
1380 /**
1381 * Releases the PDM lock.
1382 *
1383 * @param pDevIns The PCI device instance.
1384 */
1385 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1386
1387 /** Just a safety precaution. */
1388 uint32_t u32TheEnd;
1389} PDMPICHLPR0;
1390
1391/** Pointer to PIC R0 helpers. */
1392typedef R0PTRTYPE(PDMPICHLPR0 *) PPDMPICHLPR0;
1393/** Pointer to const PIC R0 helpers. */
1394typedef R0PTRTYPE(const PDMPICHLPR0 *) PCPDMPICHLPR0;
1395
1396/** Current PDMPICHLPR0 version number. */
1397#define PDM_PICHLPR0_VERSION PDM_VERSION_MAKE(0xfff8, 1, 0)
1398
1399/**
1400 * PIC R3 helpers.
1401 */
1402typedef struct PDMPICHLPR3
1403{
1404 /** Structure version. PDM_PICHLP_VERSION defines the current version. */
1405 uint32_t u32Version;
1406
1407 /**
1408 * Set the interrupt force action flag.
1409 *
1410 * @param pDevIns Device instance of the PIC.
1411 */
1412 DECLR3CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
1413
1414 /**
1415 * Clear the interrupt force action flag.
1416 *
1417 * @param pDevIns Device instance of the PIC.
1418 */
1419 DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
1420
1421 /**
1422 * Acquires the PDM lock.
1423 *
1424 * @returns VINF_SUCCESS on success.
1425 * @returns Fatal error on failure.
1426 * @param pDevIns The PIC device instance.
1427 * @param rc Dummy for making the interface identical to the RC and R0 versions.
1428 */
1429 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1430
1431 /**
1432 * Releases the PDM lock.
1433 *
1434 * @param pDevIns The PIC device instance.
1435 */
1436 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1437
1438 /**
1439 * Gets the address of the RC PIC helpers.
1440 *
1441 * This should be called at both construction and relocation time
1442 * to obtain the correct address of the RC helpers.
1443 *
1444 * @returns RC pointer to the PIC helpers.
1445 * @param pDevIns Device instance of the PIC.
1446 */
1447 DECLR3CALLBACKMEMBER(PCPDMPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
1448
1449 /**
1450 * Gets the address of the R0 PIC helpers.
1451 *
1452 * This should be called at both construction and relocation time
1453 * to obtain the correct address of the R0 helpers.
1454 *
1455 * @returns R0 pointer to the PIC helpers.
1456 * @param pDevIns Device instance of the PIC.
1457 */
1458 DECLR3CALLBACKMEMBER(PCPDMPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
1459
1460 /** Just a safety precaution. */
1461 uint32_t u32TheEnd;
1462} PDMPICHLPR3;
1463
1464/** Pointer to PIC R3 helpers. */
1465typedef R3PTRTYPE(PDMPICHLPR3 *) PPDMPICHLPR3;
1466/** Pointer to const PIC R3 helpers. */
1467typedef R3PTRTYPE(const PDMPICHLPR3 *) PCPDMPICHLPR3;
1468
1469/** Current PDMPICHLPR3 version number. */
1470#define PDM_PICHLPR3_VERSION PDM_VERSION_MAKE(0xfff7, 1, 0)
1471
1472
1473
1474/**
1475 * Firmware registration structure.
1476 */
1477typedef struct PDMFWREG
1478{
1479 /** Struct version+magic number (PDM_FWREG_VERSION). */
1480 uint32_t u32Version;
1481
1482 /**
1483 * Checks whether this is a hard or soft reset.
1484 *
1485 * The current definition of soft reset is what the PC BIOS does when CMOS[0xF]
1486 * is 5, 9 or 0xA.
1487 *
1488 * @returns true if hard reset, false if soft.
1489 * @param pDevIns Device instance of the firmware.
1490 * @param fFlags PDMRESET_F_XXX passed to the PDMDevHlpVMReset API.
1491 */
1492 DECLR3CALLBACKMEMBER(bool, pfnIsHardReset,(PPDMDEVINS pDevIns, uint32_t fFlags));
1493
1494 /** Just a safety precaution. */
1495 uint32_t u32TheEnd;
1496} PDMFWREG;
1497/** Pointer to a FW registration structure. */
1498typedef PDMFWREG *PPDMFWREG;
1499/** Pointer to a const FW registration structure. */
1500typedef PDMFWREG const *PCPDMFWREG;
1501
1502/** Current PDMFWREG version number. */
1503#define PDM_FWREG_VERSION PDM_VERSION_MAKE(0xffdd, 1, 0)
1504
1505/**
1506 * Firmware R3 helpers.
1507 */
1508typedef struct PDMFWHLPR3
1509{
1510 /** Structure version. PDM_FWHLP_VERSION defines the current version. */
1511 uint32_t u32Version;
1512
1513 /** Just a safety precaution. */
1514 uint32_t u32TheEnd;
1515} PDMFWHLPR3;
1516
1517/** Pointer to FW R3 helpers. */
1518typedef R3PTRTYPE(PDMFWHLPR3 *) PPDMFWHLPR3;
1519/** Pointer to const FW R3 helpers. */
1520typedef R3PTRTYPE(const PDMFWHLPR3 *) PCPDMFWHLPR3;
1521
1522/** Current PDMFWHLPR3 version number. */
1523#define PDM_FWHLPR3_VERSION PDM_VERSION_MAKE(0xffdb, 1, 0)
1524
1525
1526/**
1527 * APIC mode argument for apicR3SetCpuIdFeatureLevel.
1528 *
1529 * Also used in saved-states, CFGM don't change existing values.
1530 */
1531typedef enum PDMAPICMODE
1532{
1533 /** Invalid 0 entry. */
1534 PDMAPICMODE_INVALID = 0,
1535 /** No APIC. */
1536 PDMAPICMODE_NONE,
1537 /** Standard APIC (X86_CPUID_FEATURE_EDX_APIC). */
1538 PDMAPICMODE_APIC,
1539 /** Intel X2APIC (X86_CPUID_FEATURE_ECX_X2APIC). */
1540 PDMAPICMODE_X2APIC,
1541 /** The usual 32-bit paranoia. */
1542 PDMAPICMODE_32BIT_HACK = 0x7fffffff
1543} PDMAPICMODE;
1544
1545/**
1546 * APIC irq argument for pfnSetInterruptFF and pfnClearInterruptFF.
1547 */
1548typedef enum PDMAPICIRQ
1549{
1550 /** Invalid 0 entry. */
1551 PDMAPICIRQ_INVALID = 0,
1552 /** Normal hardware interrupt. */
1553 PDMAPICIRQ_HARDWARE,
1554 /** NMI. */
1555 PDMAPICIRQ_NMI,
1556 /** SMI. */
1557 PDMAPICIRQ_SMI,
1558 /** ExtINT (HW interrupt via PIC). */
1559 PDMAPICIRQ_EXTINT,
1560 /** Interrupt arrived, needs to be updated to the IRR. */
1561 PDMAPICIRQ_UPDATE_PENDING,
1562 /** The usual 32-bit paranoia. */
1563 PDMAPICIRQ_32BIT_HACK = 0x7fffffff
1564} PDMAPICIRQ;
1565
1566
1567/**
1568 * I/O APIC registration structure.
1569 */
1570typedef struct PDMIOAPICREG
1571{
1572 /** Struct version+magic number (PDM_IOAPICREG_VERSION). */
1573 uint32_t u32Version;
1574
1575 /**
1576 * Set an IRQ.
1577 *
1578 * @param pDevIns Device instance of the I/O APIC.
1579 * @param iIrq IRQ number to set.
1580 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1581 * @param uTagSrc The IRQ tag and source (for tracing).
1582 *
1583 * @remarks Caller enters the PDM critical section
1584 * Actually, as per 2018-07-21 this isn't true (bird).
1585 */
1586 DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
1587
1588 /** The name of the RC SetIrq entry point. */
1589 const char *pszSetIrqRC;
1590
1591 /** The name of the R0 SetIrq entry point. */
1592 const char *pszSetIrqR0;
1593
1594 /**
1595 * Send a MSI.
1596 *
1597 * @param pDevIns Device instance of the I/O APIC.
1598 * @param GCPhys Request address.
1599 * @param uValue Request value.
1600 * @param uTagSrc The IRQ tag and source (for tracing).
1601 *
1602 * @remarks Caller enters the PDM critical section
1603 * Actually, as per 2018-07-21 this isn't true (bird).
1604 */
1605 DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
1606
1607 /** The name of the RC SendMsi entry point. */
1608 const char *pszSendMsiRC;
1609
1610 /** The name of the R0 SendMsi entry point. */
1611 const char *pszSendMsiR0;
1612
1613 /**
1614 * Set the EOI for an interrupt vector.
1615 *
1616 * @returns Strict VBox status code - only the following informational status codes:
1617 * @retval VINF_IOM_R3_MMIO_WRITE if the I/O APIC lock is contenteded and we're in R0 or RC.2
1618 * @retval VINF_SUCCESS
1619 *
1620 * @param pDevIns Device instance of the I/O APIC.
1621 * @param u8Vector The vector.
1622 *
1623 * @remarks Caller enters the PDM critical section
1624 * Actually, as per 2018-07-21 this isn't true (bird).
1625 */
1626 DECLR3CALLBACKMEMBER(int, pfnSetEoiR3,(PPDMDEVINS pDevIns, uint8_t u8Vector));
1627
1628 /** The name of the RC SetEoi entry point. */
1629 const char *pszSetEoiRC;
1630
1631 /** The name of the R0 SetEoi entry point. */
1632 const char *pszSetEoiR0;
1633} PDMIOAPICREG;
1634/** Pointer to an APIC registration structure. */
1635typedef PDMIOAPICREG *PPDMIOAPICREG;
1636
1637/** Current PDMAPICREG version number. */
1638#define PDM_IOAPICREG_VERSION PDM_VERSION_MAKE(0xfff2, 5, 0)
1639
1640
1641/**
1642 * IOAPIC RC helpers.
1643 */
1644typedef struct PDMIOAPICHLPRC
1645{
1646 /** Structure version. PDM_IOAPICHLPRC_VERSION defines the current version. */
1647 uint32_t u32Version;
1648
1649 /**
1650 * Private interface between the IOAPIC and APIC.
1651 *
1652 * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
1653 *
1654 * @returns status code.
1655 * @param pDevIns Device instance of the IOAPIC.
1656 * @param u8Dest See APIC implementation.
1657 * @param u8DestMode See APIC implementation.
1658 * @param u8DeliveryMode See APIC implementation.
1659 * @param uVector See APIC implementation.
1660 * @param u8Polarity See APIC implementation.
1661 * @param u8TriggerMode See APIC implementation.
1662 * @param uTagSrc The IRQ tag and source (for tracing).
1663 */
1664 DECLRCCALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1665 uint8_t uVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
1666
1667 /**
1668 * Acquires the PDM lock.
1669 *
1670 * @returns VINF_SUCCESS on success.
1671 * @returns rc if we failed to acquire the lock.
1672 * @param pDevIns The IOAPIC device instance.
1673 * @param rc What to return if we fail to acquire the lock.
1674 */
1675 DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1676
1677 /**
1678 * Releases the PDM lock.
1679 *
1680 * @param pDevIns The IOAPIC device instance.
1681 */
1682 DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1683
1684 /** Just a safety precaution. */
1685 uint32_t u32TheEnd;
1686} PDMIOAPICHLPRC;
1687/** Pointer to IOAPIC RC helpers. */
1688typedef RCPTRTYPE(PDMIOAPICHLPRC *) PPDMIOAPICHLPRC;
1689/** Pointer to const IOAPIC helpers. */
1690typedef RCPTRTYPE(const PDMIOAPICHLPRC *) PCPDMIOAPICHLPRC;
1691
1692/** Current PDMIOAPICHLPRC version number. */
1693#define PDM_IOAPICHLPRC_VERSION PDM_VERSION_MAKE(0xfff1, 2, 0)
1694
1695
1696/**
1697 * IOAPIC R0 helpers.
1698 */
1699typedef struct PDMIOAPICHLPR0
1700{
1701 /** Structure version. PDM_IOAPICHLPR0_VERSION defines the current version. */
1702 uint32_t u32Version;
1703
1704 /**
1705 * Private interface between the IOAPIC and APIC.
1706 *
1707 * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
1708 *
1709 * @returns status code.
1710 * @param pDevIns Device instance of the IOAPIC.
1711 * @param u8Dest See APIC implementation.
1712 * @param u8DestMode See APIC implementation.
1713 * @param u8DeliveryMode See APIC implementation.
1714 * @param uVector See APIC implementation.
1715 * @param u8Polarity See APIC implementation.
1716 * @param u8TriggerMode See APIC implementation.
1717 * @param uTagSrc The IRQ tag and source (for tracing).
1718 */
1719 DECLR0CALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1720 uint8_t uVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
1721
1722 /**
1723 * Acquires the PDM lock.
1724 *
1725 * @returns VINF_SUCCESS on success.
1726 * @returns rc if we failed to acquire the lock.
1727 * @param pDevIns The IOAPIC device instance.
1728 * @param rc What to return if we fail to acquire the lock.
1729 */
1730 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1731
1732 /**
1733 * Releases the PDM lock.
1734 *
1735 * @param pDevIns The IOAPIC device instance.
1736 */
1737 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1738
1739 /** Just a safety precaution. */
1740 uint32_t u32TheEnd;
1741} PDMIOAPICHLPR0;
1742/** Pointer to IOAPIC R0 helpers. */
1743typedef R0PTRTYPE(PDMIOAPICHLPR0 *) PPDMIOAPICHLPR0;
1744/** Pointer to const IOAPIC helpers. */
1745typedef R0PTRTYPE(const PDMIOAPICHLPR0 *) PCPDMIOAPICHLPR0;
1746
1747/** Current PDMIOAPICHLPR0 version number. */
1748#define PDM_IOAPICHLPR0_VERSION PDM_VERSION_MAKE(0xfff0, 2, 0)
1749
1750/**
1751 * IOAPIC R3 helpers.
1752 */
1753typedef struct PDMIOAPICHLPR3
1754{
1755 /** Structure version. PDM_IOAPICHLPR3_VERSION defines the current version. */
1756 uint32_t u32Version;
1757
1758 /**
1759 * Private interface between the IOAPIC and APIC.
1760 *
1761 * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
1762 *
1763 * @returns status code
1764 * @param pDevIns Device instance of the IOAPIC.
1765 * @param u8Dest See APIC implementation.
1766 * @param u8DestMode See APIC implementation.
1767 * @param u8DeliveryMode See APIC implementation.
1768 * @param uVector See APIC implementation.
1769 * @param u8Polarity See APIC implementation.
1770 * @param u8TriggerMode See APIC implementation.
1771 * @param uTagSrc The IRQ tag and source (for tracing).
1772 */
1773 DECLR3CALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1774 uint8_t uVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
1775
1776 /**
1777 * Acquires the PDM lock.
1778 *
1779 * @returns VINF_SUCCESS on success.
1780 * @returns Fatal error on failure.
1781 * @param pDevIns The IOAPIC device instance.
1782 * @param rc Dummy for making the interface identical to the GC and R0 versions.
1783 */
1784 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1785
1786 /**
1787 * Releases the PDM lock.
1788 *
1789 * @param pDevIns The IOAPIC device instance.
1790 */
1791 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1792
1793 /**
1794 * Gets the address of the RC IOAPIC helpers.
1795 *
1796 * This should be called at both construction and relocation time
1797 * to obtain the correct address of the RC helpers.
1798 *
1799 * @returns RC pointer to the IOAPIC helpers.
1800 * @param pDevIns Device instance of the IOAPIC.
1801 */
1802 DECLR3CALLBACKMEMBER(PCPDMIOAPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
1803
1804 /**
1805 * Gets the address of the R0 IOAPIC helpers.
1806 *
1807 * This should be called at both construction and relocation time
1808 * to obtain the correct address of the R0 helpers.
1809 *
1810 * @returns R0 pointer to the IOAPIC helpers.
1811 * @param pDevIns Device instance of the IOAPIC.
1812 */
1813 DECLR3CALLBACKMEMBER(PCPDMIOAPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
1814
1815 /** Just a safety precaution. */
1816 uint32_t u32TheEnd;
1817} PDMIOAPICHLPR3;
1818/** Pointer to IOAPIC R3 helpers. */
1819typedef R3PTRTYPE(PDMIOAPICHLPR3 *) PPDMIOAPICHLPR3;
1820/** Pointer to const IOAPIC helpers. */
1821typedef R3PTRTYPE(const PDMIOAPICHLPR3 *) PCPDMIOAPICHLPR3;
1822
1823/** Current PDMIOAPICHLPR3 version number. */
1824#define PDM_IOAPICHLPR3_VERSION PDM_VERSION_MAKE(0xffef, 2, 0)
1825
1826
1827/**
1828 * HPET registration structure.
1829 */
1830typedef struct PDMHPETREG
1831{
1832 /** Struct version+magic number (PDM_HPETREG_VERSION). */
1833 uint32_t u32Version;
1834
1835} PDMHPETREG;
1836/** Pointer to an HPET registration structure. */
1837typedef PDMHPETREG *PPDMHPETREG;
1838
1839/** Current PDMHPETREG version number. */
1840#define PDM_HPETREG_VERSION PDM_VERSION_MAKE(0xffe2, 1, 0)
1841
1842/**
1843 * HPET RC helpers.
1844 *
1845 * @remarks Keep this around in case HPET will need PDM interaction in again RC
1846 * at some later point.
1847 */
1848typedef struct PDMHPETHLPRC
1849{
1850 /** Structure version. PDM_HPETHLPRC_VERSION defines the current version. */
1851 uint32_t u32Version;
1852
1853 /** Just a safety precaution. */
1854 uint32_t u32TheEnd;
1855} PDMHPETHLPRC;
1856
1857/** Pointer to HPET RC helpers. */
1858typedef RCPTRTYPE(PDMHPETHLPRC *) PPDMHPETHLPRC;
1859/** Pointer to const HPET RC helpers. */
1860typedef RCPTRTYPE(const PDMHPETHLPRC *) PCPDMHPETHLPRC;
1861
1862/** Current PDMHPETHLPRC version number. */
1863#define PDM_HPETHLPRC_VERSION PDM_VERSION_MAKE(0xffee, 2, 0)
1864
1865
1866/**
1867 * HPET R0 helpers.
1868 *
1869 * @remarks Keep this around in case HPET will need PDM interaction in again R0
1870 * at some later point.
1871 */
1872typedef struct PDMHPETHLPR0
1873{
1874 /** Structure version. PDM_HPETHLPR0_VERSION defines the current version. */
1875 uint32_t u32Version;
1876
1877 /** Just a safety precaution. */
1878 uint32_t u32TheEnd;
1879} PDMHPETHLPR0;
1880
1881/** Pointer to HPET R0 helpers. */
1882typedef R0PTRTYPE(PDMHPETHLPR0 *) PPDMHPETHLPR0;
1883/** Pointer to const HPET R0 helpers. */
1884typedef R0PTRTYPE(const PDMHPETHLPR0 *) PCPDMHPETHLPR0;
1885
1886/** Current PDMHPETHLPR0 version number. */
1887#define PDM_HPETHLPR0_VERSION PDM_VERSION_MAKE(0xffed, 2, 0)
1888
1889/**
1890 * HPET R3 helpers.
1891 */
1892typedef struct PDMHPETHLPR3
1893{
1894 /** Structure version. PDM_HPETHLP_VERSION defines the current version. */
1895 uint32_t u32Version;
1896
1897 /**
1898 * Gets the address of the RC HPET helpers.
1899 *
1900 * This should be called at both construction and relocation time
1901 * to obtain the correct address of the RC helpers.
1902 *
1903 * @returns RC pointer to the HPET helpers.
1904 * @param pDevIns Device instance of the HPET.
1905 */
1906 DECLR3CALLBACKMEMBER(PCPDMHPETHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
1907
1908 /**
1909 * Gets the address of the R0 HPET helpers.
1910 *
1911 * This should be called at both construction and relocation time
1912 * to obtain the correct address of the R0 helpers.
1913 *
1914 * @returns R0 pointer to the HPET helpers.
1915 * @param pDevIns Device instance of the HPET.
1916 */
1917 DECLR3CALLBACKMEMBER(PCPDMHPETHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
1918
1919 /**
1920 * Set legacy mode on PIT and RTC.
1921 *
1922 * @returns VINF_SUCCESS on success.
1923 * @returns rc if we failed to set legacy mode.
1924 * @param pDevIns Device instance of the HPET.
1925 * @param fActivated Whether legacy mode is activated or deactivated.
1926 */
1927 DECLR3CALLBACKMEMBER(int, pfnSetLegacyMode,(PPDMDEVINS pDevIns, bool fActivated));
1928
1929
1930 /**
1931 * Set IRQ, bypassing ISA bus override rules.
1932 *
1933 * @returns VINF_SUCCESS on success.
1934 * @returns rc if we failed to set legacy mode.
1935 * @param pDevIns Device instance of the HPET.
1936 * @param iIrq IRQ number to set.
1937 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1938 */
1939 DECLR3CALLBACKMEMBER(int, pfnSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
1940
1941 /** Just a safety precaution. */
1942 uint32_t u32TheEnd;
1943} PDMHPETHLPR3;
1944
1945/** Pointer to HPET R3 helpers. */
1946typedef R3PTRTYPE(PDMHPETHLPR3 *) PPDMHPETHLPR3;
1947/** Pointer to const HPET R3 helpers. */
1948typedef R3PTRTYPE(const PDMHPETHLPR3 *) PCPDMHPETHLPR3;
1949
1950/** Current PDMHPETHLPR3 version number. */
1951#define PDM_HPETHLPR3_VERSION PDM_VERSION_MAKE(0xffec, 2, 0)
1952
1953
1954/**
1955 * Raw PCI device registration structure.
1956 */
1957typedef struct PDMPCIRAWREG
1958{
1959 /** Struct version+magic number (PDM_PCIRAWREG_VERSION). */
1960 uint32_t u32Version;
1961 /** Just a safety precaution. */
1962 uint32_t u32TheEnd;
1963} PDMPCIRAWREG;
1964/** Pointer to a raw PCI registration structure. */
1965typedef PDMPCIRAWREG *PPDMPCIRAWREG;
1966
1967/** Current PDMPCIRAWREG version number. */
1968#define PDM_PCIRAWREG_VERSION PDM_VERSION_MAKE(0xffe1, 1, 0)
1969
1970/**
1971 * Raw PCI device raw-mode context helpers.
1972 */
1973typedef struct PDMPCIRAWHLPRC
1974{
1975 /** Structure version and magic number (PDM_PCIRAWHLPRC_VERSION). */
1976 uint32_t u32Version;
1977 /** Just a safety precaution. */
1978 uint32_t u32TheEnd;
1979} PDMPCIRAWHLPRC;
1980/** Pointer to a raw PCI deviec raw-mode context helper structure. */
1981typedef RCPTRTYPE(PDMPCIRAWHLPRC *) PPDMPCIRAWHLPRC;
1982/** Pointer to a const raw PCI deviec raw-mode context helper structure. */
1983typedef RCPTRTYPE(const PDMPCIRAWHLPRC *) PCPDMPCIRAWHLPRC;
1984
1985/** Current PDMPCIRAWHLPRC version number. */
1986#define PDM_PCIRAWHLPRC_VERSION PDM_VERSION_MAKE(0xffe0, 1, 0)
1987
1988/**
1989 * Raw PCI device ring-0 context helpers.
1990 */
1991typedef struct PDMPCIRAWHLPR0
1992{
1993 /** Structure version and magic number (PDM_PCIRAWHLPR0_VERSION). */
1994 uint32_t u32Version;
1995 /** Just a safety precaution. */
1996 uint32_t u32TheEnd;
1997} PDMPCIRAWHLPR0;
1998/** Pointer to a raw PCI deviec ring-0 context helper structure. */
1999typedef R0PTRTYPE(PDMPCIRAWHLPR0 *) PPDMPCIRAWHLPR0;
2000/** Pointer to a const raw PCI deviec ring-0 context helper structure. */
2001typedef R0PTRTYPE(const PDMPCIRAWHLPR0 *) PCPDMPCIRAWHLPR0;
2002
2003/** Current PDMPCIRAWHLPR0 version number. */
2004#define PDM_PCIRAWHLPR0_VERSION PDM_VERSION_MAKE(0xffdf, 1, 0)
2005
2006
2007/**
2008 * Raw PCI device ring-3 context helpers.
2009 */
2010typedef struct PDMPCIRAWHLPR3
2011{
2012 /** Undefined structure version and magic number. */
2013 uint32_t u32Version;
2014
2015 /**
2016 * Gets the address of the RC raw PCI device helpers.
2017 *
2018 * This should be called at both construction and relocation time to obtain
2019 * the correct address of the RC helpers.
2020 *
2021 * @returns RC pointer to the raw PCI device helpers.
2022 * @param pDevIns Device instance of the raw PCI device.
2023 */
2024 DECLR3CALLBACKMEMBER(PCPDMPCIRAWHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
2025
2026 /**
2027 * Gets the address of the R0 raw PCI device helpers.
2028 *
2029 * This should be called at both construction and relocation time to obtain
2030 * the correct address of the R0 helpers.
2031 *
2032 * @returns R0 pointer to the raw PCI device helpers.
2033 * @param pDevIns Device instance of the raw PCI device.
2034 */
2035 DECLR3CALLBACKMEMBER(PCPDMPCIRAWHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
2036
2037 /** Just a safety precaution. */
2038 uint32_t u32TheEnd;
2039} PDMPCIRAWHLPR3;
2040/** Pointer to raw PCI R3 helpers. */
2041typedef R3PTRTYPE(PDMPCIRAWHLPR3 *) PPDMPCIRAWHLPR3;
2042/** Pointer to const raw PCI R3 helpers. */
2043typedef R3PTRTYPE(const PDMPCIRAWHLPR3 *) PCPDMPCIRAWHLPR3;
2044
2045/** Current PDMPCIRAWHLPR3 version number. */
2046#define PDM_PCIRAWHLPR3_VERSION PDM_VERSION_MAKE(0xffde, 1, 0)
2047
2048
2049#ifdef IN_RING3
2050
2051/**
2052 * DMA Transfer Handler.
2053 *
2054 * @returns Number of bytes transferred.
2055 * @param pDevIns Device instance of the DMA.
2056 * @param pvUser User pointer.
2057 * @param uChannel Channel number.
2058 * @param off DMA position.
2059 * @param cb Block size.
2060 * @remarks The device lock is not taken, however, the DMA device lock is held.
2061 */
2062typedef DECLCALLBACK(uint32_t) FNDMATRANSFERHANDLER(PPDMDEVINS pDevIns, void *pvUser, unsigned uChannel, uint32_t off, uint32_t cb);
2063/** Pointer to a FNDMATRANSFERHANDLER(). */
2064typedef FNDMATRANSFERHANDLER *PFNDMATRANSFERHANDLER;
2065
2066/**
2067 * DMA Controller registration structure.
2068 */
2069typedef struct PDMDMAREG
2070{
2071 /** Structure version number. PDM_DMACREG_VERSION defines the current version. */
2072 uint32_t u32Version;
2073
2074 /**
2075 * Execute pending transfers.
2076 *
2077 * @returns A more work indiciator. I.e. 'true' if there is more to be done, and 'false' if all is done.
2078 * @param pDevIns Device instance of the DMAC.
2079 * @remarks No locks held, called on EMT(0) as a form of serialization.
2080 */
2081 DECLR3CALLBACKMEMBER(bool, pfnRun,(PPDMDEVINS pDevIns));
2082
2083 /**
2084 * Register transfer function for DMA channel.
2085 *
2086 * @param pDevIns Device instance of the DMAC.
2087 * @param uChannel Channel number.
2088 * @param pfnTransferHandler Device specific transfer function.
2089 * @param pvUser User pointer to be passed to the callback.
2090 * @remarks No locks held, called on an EMT.
2091 */
2092 DECLR3CALLBACKMEMBER(void, pfnRegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
2093
2094 /**
2095 * Read memory
2096 *
2097 * @returns Number of bytes read.
2098 * @param pDevIns Device instance of the DMAC.
2099 * @param uChannel Channel number.
2100 * @param pvBuffer Pointer to target buffer.
2101 * @param off DMA position.
2102 * @param cbBlock Block size.
2103 * @remarks No locks held, called on an EMT.
2104 */
2105 DECLR3CALLBACKMEMBER(uint32_t, pfnReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock));
2106
2107 /**
2108 * Write memory
2109 *
2110 * @returns Number of bytes written.
2111 * @param pDevIns Device instance of the DMAC.
2112 * @param uChannel Channel number.
2113 * @param pvBuffer Memory to write.
2114 * @param off DMA position.
2115 * @param cbBlock Block size.
2116 * @remarks No locks held, called on an EMT.
2117 */
2118 DECLR3CALLBACKMEMBER(uint32_t, pfnWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock));
2119
2120 /**
2121 * Set the DREQ line.
2122 *
2123 * @param pDevIns Device instance of the DMAC.
2124 * @param uChannel Channel number.
2125 * @param uLevel Level of the line.
2126 * @remarks No locks held, called on an EMT.
2127 */
2128 DECLR3CALLBACKMEMBER(void, pfnSetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
2129
2130 /**
2131 * Get channel mode
2132 *
2133 * @returns Channel mode.
2134 * @param pDevIns Device instance of the DMAC.
2135 * @param uChannel Channel number.
2136 * @remarks No locks held, called on an EMT.
2137 */
2138 DECLR3CALLBACKMEMBER(uint8_t, pfnGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
2139
2140} PDMDMACREG;
2141/** Pointer to a DMAC registration structure. */
2142typedef PDMDMACREG *PPDMDMACREG;
2143
2144/** Current PDMDMACREG version number. */
2145#define PDM_DMACREG_VERSION PDM_VERSION_MAKE(0xffeb, 1, 0)
2146
2147
2148/**
2149 * DMA Controller device helpers.
2150 */
2151typedef struct PDMDMACHLP
2152{
2153 /** Structure version. PDM_DMACHLP_VERSION defines the current version. */
2154 uint32_t u32Version;
2155
2156 /* to-be-defined */
2157
2158} PDMDMACHLP;
2159/** Pointer to DMAC helpers. */
2160typedef PDMDMACHLP *PPDMDMACHLP;
2161/** Pointer to const DMAC helpers. */
2162typedef const PDMDMACHLP *PCPDMDMACHLP;
2163
2164/** Current PDMDMACHLP version number. */
2165#define PDM_DMACHLP_VERSION PDM_VERSION_MAKE(0xffea, 1, 0)
2166
2167#endif /* IN_RING3 */
2168
2169
2170
2171/**
2172 * RTC registration structure.
2173 */
2174typedef struct PDMRTCREG
2175{
2176 /** Structure version number. PDM_RTCREG_VERSION defines the current version. */
2177 uint32_t u32Version;
2178 uint32_t u32Alignment; /**< structure size alignment. */
2179
2180 /**
2181 * Write to a CMOS register and update the checksum if necessary.
2182 *
2183 * @returns VBox status code.
2184 * @param pDevIns Device instance of the RTC.
2185 * @param iReg The CMOS register index.
2186 * @param u8Value The CMOS register value.
2187 * @remarks Caller enters the device critical section.
2188 */
2189 DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
2190
2191 /**
2192 * Read a CMOS register.
2193 *
2194 * @returns VBox status code.
2195 * @param pDevIns Device instance of the RTC.
2196 * @param iReg The CMOS register index.
2197 * @param pu8Value Where to store the CMOS register value.
2198 * @remarks Caller enters the device critical section.
2199 */
2200 DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
2201
2202} PDMRTCREG;
2203/** Pointer to a RTC registration structure. */
2204typedef PDMRTCREG *PPDMRTCREG;
2205/** Pointer to a const RTC registration structure. */
2206typedef const PDMRTCREG *PCPDMRTCREG;
2207
2208/** Current PDMRTCREG version number. */
2209#define PDM_RTCREG_VERSION PDM_VERSION_MAKE(0xffe9, 2, 0)
2210
2211
2212/**
2213 * RTC device helpers.
2214 */
2215typedef struct PDMRTCHLP
2216{
2217 /** Structure version. PDM_RTCHLP_VERSION defines the current version. */
2218 uint32_t u32Version;
2219
2220 /* to-be-defined */
2221
2222} PDMRTCHLP;
2223/** Pointer to RTC helpers. */
2224typedef PDMRTCHLP *PPDMRTCHLP;
2225/** Pointer to const RTC helpers. */
2226typedef const PDMRTCHLP *PCPDMRTCHLP;
2227
2228/** Current PDMRTCHLP version number. */
2229#define PDM_RTCHLP_VERSION PDM_VERSION_MAKE(0xffe8, 1, 0)
2230
2231
2232
2233/** @name Flags for PCI I/O region registration
2234 * @{ */
2235/** No handle is passed. */
2236#define PDMPCIDEV_IORGN_F_NO_HANDLE UINT32_C(0x00000000)
2237/** An I/O port handle is passed. */
2238#define PDMPCIDEV_IORGN_F_IOPORT_HANDLE UINT32_C(0x00000001)
2239/** An MMIO range handle is passed. */
2240#define PDMPCIDEV_IORGN_F_MMIO_HANDLE UINT32_C(0x00000002)
2241/** An MMIO2 handle is passed. */
2242#define PDMPCIDEV_IORGN_F_MMIO2_HANDLE UINT32_C(0x00000003)
2243/** Handle type mask. */
2244#define PDMPCIDEV_IORGN_F_HANDLE_MASK UINT32_C(0x00000003)
2245/** Mask of valid flags. */
2246#define PDMPCIDEV_IORGN_F_VALID_MASK UINT32_C(0x00000003)
2247/** @} */
2248
2249
2250#ifdef IN_RING3
2251
2252/** @name Special values for PDMDEVHLPR3::pfnPCIRegister parameters.
2253 * @{ */
2254/** Same device number (and bus) as the previous PCI device registered with the PDM device.
2255 * This is handy when registering multiple PCI device functions and the device
2256 * number is left up to the PCI bus. In order to facilitate one PDM device
2257 * instance for each PCI function, this searches earlier PDM device
2258 * instances as well. */
2259# define PDMPCIDEVREG_DEV_NO_SAME_AS_PREV UINT8_C(0xfd)
2260/** Use the first unused device number (all functions must be unused). */
2261# define PDMPCIDEVREG_DEV_NO_FIRST_UNUSED UINT8_C(0xfe)
2262/** Use the first unused device function. */
2263# define PDMPCIDEVREG_FUN_NO_FIRST_UNUSED UINT8_C(0xff)
2264
2265/** The device and function numbers are not mandatory, just suggestions. */
2266# define PDMPCIDEVREG_F_NOT_MANDATORY_NO RT_BIT_32(0)
2267/** Registering a PCI bridge device. */
2268# define PDMPCIDEVREG_F_PCI_BRIDGE RT_BIT_32(1)
2269/** Valid flag mask. */
2270# define PDMPCIDEVREG_F_VALID_MASK UINT32_C(0x00000003)
2271/** @} */
2272
2273/** Current PDMDEVHLPR3 version number. */
2274#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE_PP(0xffe7, 25, 0)
2275
2276/**
2277 * PDM Device API.
2278 */
2279typedef struct PDMDEVHLPR3
2280{
2281 /** Structure version. PDM_DEVHLPR3_VERSION defines the current version. */
2282 uint32_t u32Version;
2283
2284 /**
2285 * Creates a range of I/O ports for a device.
2286 *
2287 * The I/O port range must be mapped in a separately call. Any ring-0 and
2288 * raw-mode context callback handlers needs to be set up in the respective
2289 * contexts.
2290 *
2291 * @returns VBox status.
2292 * @param pDevIns The device instance to register the ports with.
2293 * @param cPorts Number of ports to register.
2294 * @param fFlags IOM_IOPORT_F_XXX.
2295 * @param pPciDev The PCI device the range is associated with, if
2296 * applicable.
2297 * @param iPciRegion The PCI device region in the high 16-bit word and
2298 * sub-region in the low 16-bit word. UINT32_MAX if NA.
2299 * @param pfnOut Pointer to function which is gonna handle OUT
2300 * operations. Optional.
2301 * @param pfnIn Pointer to function which is gonna handle IN operations.
2302 * Optional.
2303 * @param pfnOutStr Pointer to function which is gonna handle string OUT
2304 * operations. Optional.
2305 * @param pfnInStr Pointer to function which is gonna handle string IN
2306 * operations. Optional.
2307 * @param pvUser User argument to pass to the callbacks.
2308 * @param pszDesc Pointer to description string. This must not be freed.
2309 * @param paExtDescs Extended per-port descriptions, optional. Partial range
2310 * coverage is allowed. This must not be freed.
2311 * @param phIoPorts Where to return the I/O port range handle.
2312 *
2313 * @remarks Caller enters the device critical section prior to invoking the
2314 * registered callback methods.
2315 *
2316 * @sa PDMDevHlpIoPortSetUpContext, PDMDevHlpIoPortMap,
2317 * PDMDevHlpIoPortUnmap.
2318 */
2319 DECLR3CALLBACKMEMBER(int, pfnIoPortCreateEx,(PPDMDEVINS pDevIns, RTIOPORT cPorts, uint32_t fFlags, PPDMPCIDEV pPciDev,
2320 uint32_t iPciRegion, PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
2321 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, RTR3PTR pvUser,
2322 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts));
2323
2324 /**
2325 * Maps an I/O port range.
2326 *
2327 * @returns VBox status.
2328 * @param pDevIns The device instance to register the ports with.
2329 * @param hIoPorts The I/O port range handle.
2330 * @param Port Where to map the range.
2331 * @sa PDMDevHlpIoPortUnmap, PDMDevHlpIoPortSetUpContext,
2332 * PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx.
2333 */
2334 DECLR3CALLBACKMEMBER(int, pfnIoPortMap,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT Port));
2335
2336 /**
2337 * Unmaps an I/O port range.
2338 *
2339 * @returns VBox status.
2340 * @param pDevIns The device instance to register the ports with.
2341 * @param hIoPorts The I/O port range handle.
2342 * @sa PDMDevHlpIoPortMap, PDMDevHlpIoPortSetUpContext,
2343 * PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx.
2344 */
2345 DECLR3CALLBACKMEMBER(int, pfnIoPortUnmap,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts));
2346
2347 /**
2348 * Register a number of I/O ports with a device.
2349 *
2350 * These callbacks are of course for the host context (HC).
2351 * Register HC handlers before guest context (GC) handlers! There must be a
2352 * HC handler for every GC handler!
2353 *
2354 * @returns VBox status.
2355 * @param pDevIns The device instance to register the ports with.
2356 * @param Port First port number in the range.
2357 * @param cPorts Number of ports to register.
2358 * @param pvUser User argument.
2359 * @param pfnOut Pointer to function which is gonna handle OUT operations.
2360 * @param pfnIn Pointer to function which is gonna handle IN operations.
2361 * @param pfnOutStr Pointer to function which is gonna handle string OUT operations.
2362 * @param pfnInStr Pointer to function which is gonna handle string IN operations.
2363 * @param pszDesc Pointer to description string. This must not be freed.
2364 * @remarks Caller enters the device critical section prior to invoking the
2365 * registered callback methods.
2366 * @deprecated
2367 */
2368 DECLR3CALLBACKMEMBER(int, pfnIOPortRegister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTHCPTR pvUser,
2369 PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
2370 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc));
2371
2372 /**
2373 * Register a number of I/O ports with a device for RC.
2374 *
2375 * These callbacks are for the raw-mode context (RC). Register ring-3 context
2376 * (R3) handlers before raw-mode context handlers! There must be a R3 handler
2377 * for every RC handler!
2378 *
2379 * @returns VBox status.
2380 * @param pDevIns The device instance to register the ports with
2381 * and which RC module to resolve the names
2382 * against.
2383 * @param Port First port number in the range.
2384 * @param cPorts Number of ports to register.
2385 * @param pvUser User argument.
2386 * @param pszOut Name of the RC function which is gonna handle OUT operations.
2387 * @param pszIn Name of the RC function which is gonna handle IN operations.
2388 * @param pszOutStr Name of the RC function which is gonna handle string OUT operations.
2389 * @param pszInStr Name of the RC function which is gonna handle string IN operations.
2390 * @param pszDesc Pointer to description string. This must not be freed.
2391 * @remarks Caller enters the device critical section prior to invoking the
2392 * registered callback methods.
2393 * @deprecated
2394 */
2395 DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterRC,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTRCPTR pvUser,
2396 const char *pszOut, const char *pszIn,
2397 const char *pszOutStr, const char *pszInStr, const char *pszDesc));
2398
2399 /**
2400 * Register a number of I/O ports with a device.
2401 *
2402 * These callbacks are of course for the ring-0 host context (R0).
2403 * Register R3 (HC) handlers before R0 (R0) handlers! There must be a R3 (HC) handler for every R0 handler!
2404 *
2405 * @returns VBox status.
2406 * @param pDevIns The device instance to register the ports with.
2407 * @param Port First port number in the range.
2408 * @param cPorts Number of ports to register.
2409 * @param pvUser User argument. (if pointer, then it must be in locked memory!)
2410 * @param pszOut Name of the R0 function which is gonna handle OUT operations.
2411 * @param pszIn Name of the R0 function which is gonna handle IN operations.
2412 * @param pszOutStr Name of the R0 function which is gonna handle string OUT operations.
2413 * @param pszInStr Name of the R0 function which is gonna handle string IN operations.
2414 * @param pszDesc Pointer to description string. This must not be freed.
2415 * @remarks Caller enters the device critical section prior to invoking the
2416 * registered callback methods.
2417 * @deprecated
2418 */
2419 DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterR0,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTR0PTR pvUser,
2420 const char *pszOut, const char *pszIn,
2421 const char *pszOutStr, const char *pszInStr, const char *pszDesc));
2422
2423 /**
2424 * Deregister I/O ports.
2425 *
2426 * This naturally affects both guest context (GC), ring-0 (R0) and ring-3 (R3/HC) handlers.
2427 *
2428 * @returns VBox status.
2429 * @param pDevIns The device instance owning the ports.
2430 * @param Port First port number in the range.
2431 * @param cPorts Number of ports to deregister.
2432 */
2433 DECLR3CALLBACKMEMBER(int, pfnIOPortDeregister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts));
2434
2435 /**
2436 * Creates a memory mapped I/O (MMIO) region for a device.
2437 *
2438 * The MMIO region must be mapped in a separately call. Any ring-0 and
2439 * raw-mode context callback handlers needs to be set up in the respective
2440 * contexts.
2441 *
2442 * @returns VBox status.
2443 * @param pDevIns The device instance to register the ports with.
2444 * @param cbRegion The size of the region in bytes.
2445 * @param fFlags Flags, IOMMMIO_FLAGS_XXX.
2446 * @param pPciDev The PCI device the range is associated with, if
2447 * applicable.
2448 * @param iPciRegion The PCI device region in the high 16-bit word and
2449 * sub-region in the low 16-bit word. UINT32_MAX if NA.
2450 * @param pfnWrite Pointer to function which is gonna handle Write
2451 * operations.
2452 * @param pfnRead Pointer to function which is gonna handle Read
2453 * operations.
2454 * @param pfnFill Pointer to function which is gonna handle Fill/memset
2455 * operations. (optional)
2456 * @param pvUser User argument to pass to the callbacks.
2457 * @param pszDesc Pointer to description string. This must not be freed.
2458 * @param phRegion Where to return the MMIO region handle.
2459 *
2460 * @remarks Caller enters the device critical section prior to invoking the
2461 * registered callback methods.
2462 *
2463 * @sa PDMDevHlpMmioSetUpContext, PDMDevHlpMmioMap, PDMDevHlpMmioUnmap.
2464 */
2465 DECLR3CALLBACKMEMBER(int, pfnMmioCreateEx,(PPDMDEVINS pDevIns, RTGCPHYS cbRegion,
2466 uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
2467 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill,
2468 void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion));
2469
2470 /**
2471 * Maps a memory mapped I/O (MMIO) region.
2472 *
2473 * @returns VBox status.
2474 * @param pDevIns The device instance the region is associated with.
2475 * @param hRegion The MMIO region handle.
2476 * @param GCPhys Where to map the region.
2477 * @sa PDMDevHlpMmioUnmap, PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx,
2478 * PDMDevHlpMmioSetUpContext
2479 */
2480 DECLR3CALLBACKMEMBER(int, pfnMmioMap,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys));
2481
2482 /**
2483 * Maps a memory mapped I/O (MMIO) region.
2484 *
2485 * @returns VBox status.
2486 * @param pDevIns The device instance the region is associated with.
2487 * @param hRegion The MMIO region handle.
2488 * @sa PDMDevHlpMmioMap, PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx,
2489 * PDMDevHlpMmioSetUpContext
2490 */
2491 DECLR3CALLBACKMEMBER(int, pfnMmioUnmap,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion));
2492
2493 /**
2494 * Reduces the length of a MMIO range.
2495 *
2496 * This is for implementations of PDMPCIDEV::pfnRegionLoadChangeHookR3 and will
2497 * only work during saved state restore. It will not call the PCI bus code, as
2498 * that is expected to restore the saved resource configuration.
2499 *
2500 * It just adjusts the mapping length of the region so that when pfnMmioMap is
2501 * called it will only map @a cbRegion bytes and not the value set during
2502 * registration.
2503 *
2504 * @return VBox status code.
2505 * @param pDevIns The device owning the range.
2506 * @param hRegion The MMIO region handle.
2507 * @param cbRegion The new size, must be smaller.
2508 */
2509 DECLR3CALLBACKMEMBER(int, pfnMmioReduce,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS cbRegion));
2510
2511 /**
2512 * Register a Memory Mapped I/O (MMIO) region.
2513 *
2514 * These callbacks are of course for the ring-3 context (R3). Register HC
2515 * handlers before raw-mode context (RC) and ring-0 context (R0) handlers! There
2516 * must be a R3 handler for every RC and R0 handler!
2517 *
2518 * @returns VBox status.
2519 * @param pDevIns The device instance to register the MMIO with.
2520 * @param GCPhysStart First physical address in the range.
2521 * @param cbRange The size of the range (in bytes).
2522 * @param pvUser User argument.
2523 * @param pfnWrite Pointer to function which is gonna handle Write operations.
2524 * @param pfnRead Pointer to function which is gonna handle Read operations.
2525 * @param pfnFill Pointer to function which is gonna handle Fill/memset operations. (optional)
2526 * @param fFlags Flags, IOMMMIO_FLAGS_XXX.
2527 * @param pszDesc Pointer to description string. This must not be freed.
2528 * @remarks Caller enters the device critical section prior to invoking the
2529 * registered callback methods.
2530 * @deprecated
2531 */
2532 DECLR3CALLBACKMEMBER(int, pfnMMIORegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTHCPTR pvUser,
2533 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
2534 uint32_t fFlags, const char *pszDesc));
2535
2536 /**
2537 * Register a Memory Mapped I/O (MMIO) region for RC.
2538 *
2539 * These callbacks are for the raw-mode context (RC). Register ring-3 context
2540 * (R3) handlers before guest context handlers! There must be a R3 handler for
2541 * every RC handler!
2542 *
2543 * @returns VBox status.
2544 * @param pDevIns The device instance to register the MMIO with.
2545 * @param GCPhysStart First physical address in the range.
2546 * @param cbRange The size of the range (in bytes).
2547 * @param pvUser User argument.
2548 * @param pszWrite Name of the RC function which is gonna handle Write operations.
2549 * @param pszRead Name of the RC function which is gonna handle Read operations.
2550 * @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional)
2551 * @remarks Caller enters the device critical section prior to invoking the
2552 * registered callback methods.
2553 * @deprecated
2554 */
2555 DECLR3CALLBACKMEMBER(int, pfnMMIORegisterRC,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTRCPTR pvUser,
2556 const char *pszWrite, const char *pszRead, const char *pszFill));
2557
2558 /**
2559 * Register a Memory Mapped I/O (MMIO) region for R0.
2560 *
2561 * These callbacks are for the ring-0 host context (R0). Register ring-3
2562 * constext (R3) handlers before R0 handlers! There must be a R3 handler for
2563 * every R0 handler!
2564 *
2565 * @returns VBox status.
2566 * @param pDevIns The device instance to register the MMIO with.
2567 * @param GCPhysStart First physical address in the range.
2568 * @param cbRange The size of the range (in bytes).
2569 * @param pvUser User argument. (if pointer, then it must be in locked memory!)
2570 * @param pszWrite Name of the RC function which is gonna handle Write operations.
2571 * @param pszRead Name of the RC function which is gonna handle Read operations.
2572 * @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional)
2573 * @remarks Caller enters the device critical section prior to invoking the
2574 * registered callback methods.
2575 * @deprecated
2576 */
2577 DECLR3CALLBACKMEMBER(int, pfnMMIORegisterR0,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTR0PTR pvUser,
2578 const char *pszWrite, const char *pszRead, const char *pszFill));
2579
2580 /**
2581 * Deregister a Memory Mapped I/O (MMIO) region.
2582 *
2583 * This naturally affects both guest context (GC), ring-0 (R0) and ring-3 (R3/HC) handlers.
2584 *
2585 * @returns VBox status.
2586 * @param pDevIns The device instance owning the MMIO region(s).
2587 * @param GCPhysStart First physical address in the range.
2588 * @param cbRange The size of the range (in bytes).
2589 * @deprecated
2590 */
2591 DECLR3CALLBACKMEMBER(int, pfnMMIODeregister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange));
2592
2593 /**
2594 * Allocate and register a MMIO2 region.
2595 *
2596 * As mentioned elsewhere, MMIO2 is just RAM spelled differently. It's RAM
2597 * associated with a device. It is also non-shared memory with a permanent
2598 * ring-3 mapping and page backing (presently).
2599 *
2600 * @returns VBox status.
2601 * @param pDevIns The device instance.
2602 * @param pPciDev The PCI device the region is associated with, or
2603 * NULL if no PCI device association.
2604 * @param iRegion The region number. Use the PCI region number as
2605 * this must be known to the PCI bus device too. If
2606 * it's not associated with the PCI device, then
2607 * any number up to UINT8_MAX is fine.
2608 * @param cb The size (in bytes) of the region.
2609 * @param fFlags Reserved for future use, must be zero.
2610 * @param ppv Where to store the address of the ring-3 mapping
2611 * of the memory.
2612 * @param pszDesc Pointer to description string. This must not be
2613 * freed.
2614 * @thread EMT.
2615 */
2616 DECLR3CALLBACKMEMBER(int, pfnMMIO2Register,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cb,
2617 uint32_t fFlags, void **ppv, const char *pszDesc));
2618
2619 /**
2620 * Pre-register a Memory Mapped I/O (MMIO) region.
2621 *
2622 * This API must be used for large PCI MMIO regions, as it handles these much
2623 * more efficiently and with greater flexibility when it comes to heap usage.
2624 * It is only available during device construction.
2625 *
2626 * To map and unmap the pre-registered region into and our of guest address
2627 * space, use the PDMDevHlpMMIOExMap and PDMDevHlpMMIOExUnmap helpers.
2628 *
2629 * You may call PDMDevHlpMMIOExDeregister from the destructor to free the region
2630 * for reasons of symmetry, but it will be automatically deregistered by PDM
2631 * once the destructor returns.
2632 *
2633 * @returns VBox status.
2634 * @param pDevIns The device instance to register the MMIO with.
2635 * @param pPciDev The PCI device to associate the region with, use
2636 * NULL to not associate it with any device.
2637 * @param iRegion The PCI region number. When @a pPciDev is NULL,
2638 * this is a unique number between 0 and UINT8_MAX.
2639 * @param cbRegion The size of the range (in bytes).
2640 * @param fFlags Flags, IOMMMIO_FLAGS_XXX.
2641 * @param pszDesc Pointer to description string. This must not be freed.
2642 * @param pvUser Ring-3 user argument.
2643 * @param pfnWrite Pointer to function which is gonna handle Write operations.
2644 * @param pfnRead Pointer to function which is gonna handle Read operations.
2645 * @param pfnFill Pointer to function which is gonna handle Fill/memset operations. (optional)
2646 * @param pvUserR0 Ring-0 user argument. Optional.
2647 * @param pszWriteR0 The name of the ring-0 write handler method. Optional.
2648 * @param pszReadR0 The name of the ring-0 read handler method. Optional.
2649 * @param pszFillR0 The name of the ring-0 fill/memset handler method. Optional.
2650 * @param pvUserRC Raw-mode context user argument. Optional. If
2651 * unsigned value is 0x10000 or higher, it will be
2652 * automatically relocated with the hypervisor
2653 * guest mapping.
2654 * @param pszWriteRC The name of the raw-mode context write handler method. Optional.
2655 * @param pszReadRC The name of the raw-mode context read handler method. Optional.
2656 * @param pszFillRC The name of the raw-mode context fill/memset handler method. Optional.
2657 * @thread EMT
2658 *
2659 * @remarks Caller enters the device critical section prior to invoking the
2660 * registered callback methods.
2661 * @sa PDMDevHlpMMIOExMap, PDMDevHlpMMIOExUnmap, PDMDevHlpMMIOExDeregister,
2662 * PDMDevHlpMMIORegisterEx
2663 * @deprecated
2664 */
2665 DECLR3CALLBACKMEMBER(int, pfnMMIOExPreRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion,
2666 uint32_t fFlags, const char *pszDesc, RTHCPTR pvUser,
2667 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
2668 RTR0PTR pvUserR0, const char *pszWriteR0, const char *pszReadR0, const char *pszFillR0,
2669 RTRCPTR pvUserRC, const char *pszWriteRC, const char *pszReadRC, const char *pszFillRC));
2670
2671 /**
2672 * Deregisters and frees a MMIO or MMIO2 region.
2673 *
2674 * Any physical (and virtual) access handlers registered for the region must
2675 * be deregistered before calling this function (MMIO2 only).
2676 *
2677 * @returns VBox status code.
2678 * @param pDevIns The device instance.
2679 * @param pPciDev The PCI device the region is associated with, or
2680 * NULL if not associated with any.
2681 * @param iRegion The region number used during registration.
2682 * @thread EMT.
2683 * @deprecated for MMIO
2684 */
2685 DECLR3CALLBACKMEMBER(int, pfnMMIOExDeregister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion));
2686
2687 /**
2688 * Maps a MMIO or MMIO2 region into the physical memory space.
2689 *
2690 * A MMIO2 range or a pre-registered MMIO range may overlap with base memory if
2691 * a lot of RAM is configured for the VM, in which case we'll drop the base
2692 * memory pages. Presently we will make no attempt to preserve anything that
2693 * happens to be present in the base memory that is replaced, this is of course
2694 * incorrect but it's too much effort.
2695 *
2696 * @returns VBox status code.
2697 * @param pDevIns The device instance.
2698 * @param pPciDev The PCI device the region is associated with, or
2699 * NULL if not associated with any.
2700 * @param iRegion The region number used during registration.
2701 * @param GCPhys The physical address to map it at.
2702 * @thread EMT.
2703 * @deprecated for MMIO
2704 */
2705 DECLR3CALLBACKMEMBER(int, pfnMMIOExMap,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys));
2706
2707 /**
2708 * Unmaps a MMIO or MMIO2 region previously mapped using pfnMMIOExMap.
2709 *
2710 * @returns VBox status code.
2711 * @param pDevIns The device instance.
2712 * @param pPciDev The PCI device the region is associated with, or
2713 * NULL if not associated with any.
2714 * @param iRegion The region number used during registration.
2715 * @param GCPhys The physical address it's currently mapped at.
2716 * @thread EMT.
2717 * @deprecated for MMIO
2718 */
2719 DECLR3CALLBACKMEMBER(int, pfnMMIOExUnmap,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys));
2720
2721 /**
2722 * Reduces the length of a MMIO2 or pre-registered MMIO range.
2723 *
2724 * This is for implementations of PDMPCIDEV::pfnRegionLoadChangeHookR3 and will
2725 * only work during saved state restore. It will not call the PCI bus code, as
2726 * that is expected to restore the saved resource configuration.
2727 *
2728 * It just adjusts the mapping length of the region so that when pfnMMIOExMap is
2729 * called it will only map @a cbRegion bytes and not the value set during
2730 * registration.
2731 *
2732 * @return VBox status code.
2733 * @param pDevIns The device owning the range.
2734 * @param pPciDev The PCI device the region is associated with, or
2735 * NULL if not associated with any.
2736 * @param iRegion The region.
2737 * @param cbRegion The new size, must be smaller.
2738 */
2739 DECLR3CALLBACKMEMBER(int, pfnMMIOExReduce,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion));
2740
2741 /**
2742 * Maps a portion of an MMIO2 region into the hypervisor region.
2743 *
2744 * Callers of this API must never deregister the MMIO2 region before the
2745 * VM is powered off.
2746 *
2747 * @return VBox status code.
2748 * @param pDevIns The device owning the MMIO2 memory.
2749 * @param pPciDev The PCI device the region is associated with, or
2750 * NULL if not associated with any.
2751 * @param iRegion The region.
2752 * @param off The offset into the region. Will be rounded down
2753 * to closest page boundary.
2754 * @param cb The number of bytes to map. Will be rounded up
2755 * to the closest page boundary.
2756 * @param pszDesc Mapping description.
2757 * @param pRCPtr Where to store the RC address.
2758 */
2759 DECLR3CALLBACKMEMBER(int, pfnMMHyperMapMMIO2,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS off,
2760 RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr));
2761
2762 /**
2763 * Maps a portion of an MMIO2 region into kernel space (host).
2764 *
2765 * The kernel mapping will become invalid when the MMIO2 memory is deregistered
2766 * or the VM is terminated.
2767 *
2768 * @return VBox status code.
2769 * @param pDevIns The device owning the MMIO2 memory.
2770 * @param pPciDev The PCI device the region is associated with, or
2771 * NULL if not associated with any.
2772 * @param iRegion The region.
2773 * @param off The offset into the region. Must be page
2774 * aligned.
2775 * @param cb The number of bytes to map. Must be page
2776 * aligned.
2777 * @param pszDesc Mapping description.
2778 * @param pR0Ptr Where to store the R0 address.
2779 */
2780 DECLR3CALLBACKMEMBER(int, pfnMMIO2MapKernel,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS off,
2781 RTGCPHYS cb, const char *pszDesc, PRTR0PTR pR0Ptr));
2782
2783 /**
2784 * Register a ROM (BIOS) region.
2785 *
2786 * It goes without saying that this is read-only memory. The memory region must be
2787 * in unassigned memory. I.e. from the top of the address space or on the PC in
2788 * the 0xa0000-0xfffff range.
2789 *
2790 * @returns VBox status.
2791 * @param pDevIns The device instance owning the ROM region.
2792 * @param GCPhysStart First physical address in the range.
2793 * Must be page aligned!
2794 * @param cbRange The size of the range (in bytes).
2795 * Must be page aligned!
2796 * @param pvBinary Pointer to the binary data backing the ROM image.
2797 * @param cbBinary The size of the binary pointer. This must
2798 * be equal or smaller than @a cbRange.
2799 * @param fFlags Shadow ROM flags, PGMPHYS_ROM_FLAGS_* in pgm.h.
2800 * @param pszDesc Pointer to description string. This must not be freed.
2801 *
2802 * @remark There is no way to remove the rom, automatically on device cleanup or
2803 * manually from the device yet. At present I doubt we need such features...
2804 */
2805 DECLR3CALLBACKMEMBER(int, pfnROMRegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
2806 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc));
2807
2808 /**
2809 * Changes the protection of shadowed ROM mapping.
2810 *
2811 * This is intented for use by the system BIOS, chipset or device in question to
2812 * change the protection of shadowed ROM code after init and on reset.
2813 *
2814 * @param pDevIns The device instance.
2815 * @param GCPhysStart Where the mapping starts.
2816 * @param cbRange The size of the mapping.
2817 * @param enmProt The new protection type.
2818 */
2819 DECLR3CALLBACKMEMBER(int, pfnROMProtectShadow,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt));
2820
2821 /**
2822 * Register a save state data unit.
2823 *
2824 * @returns VBox status.
2825 * @param pDevIns The device instance.
2826 * @param uVersion Data layout version number.
2827 * @param cbGuess The approximate amount of data in the unit.
2828 * Only for progress indicators.
2829 * @param pszBefore Name of data unit which we should be put in
2830 * front of. Optional (NULL).
2831 *
2832 * @param pfnLivePrep Prepare live save callback, optional.
2833 * @param pfnLiveExec Execute live save callback, optional.
2834 * @param pfnLiveVote Vote live save callback, optional.
2835 *
2836 * @param pfnSavePrep Prepare save callback, optional.
2837 * @param pfnSaveExec Execute save callback, optional.
2838 * @param pfnSaveDone Done save callback, optional.
2839 *
2840 * @param pfnLoadPrep Prepare load callback, optional.
2841 * @param pfnLoadExec Execute load callback, optional.
2842 * @param pfnLoadDone Done load callback, optional.
2843 * @remarks Caller enters the device critical section prior to invoking the
2844 * registered callback methods.
2845 */
2846 DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
2847 PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
2848 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
2849 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone));
2850
2851 /** @name Exported SSM Functions
2852 * @{ */
2853 DECLR3CALLBACKMEMBER(int, pfnSSMPutStruct,(PSSMHANDLE pSSM, const void *pvStruct, PCSSMFIELD paFields));
2854 DECLR3CALLBACKMEMBER(int, pfnSSMPutStructEx,(PSSMHANDLE pSSM, const void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser));
2855 DECLR3CALLBACKMEMBER(int, pfnSSMPutBool,(PSSMHANDLE pSSM, bool fBool));
2856 DECLR3CALLBACKMEMBER(int, pfnSSMPutU8,(PSSMHANDLE pSSM, uint8_t u8));
2857 DECLR3CALLBACKMEMBER(int, pfnSSMPutS8,(PSSMHANDLE pSSM, int8_t i8));
2858 DECLR3CALLBACKMEMBER(int, pfnSSMPutU16,(PSSMHANDLE pSSM, uint16_t u16));
2859 DECLR3CALLBACKMEMBER(int, pfnSSMPutS16,(PSSMHANDLE pSSM, int16_t i16));
2860 DECLR3CALLBACKMEMBER(int, pfnSSMPutU32,(PSSMHANDLE pSSM, uint32_t u32));
2861 DECLR3CALLBACKMEMBER(int, pfnSSMPutS32,(PSSMHANDLE pSSM, int32_t i32));
2862 DECLR3CALLBACKMEMBER(int, pfnSSMPutU64,(PSSMHANDLE pSSM, uint64_t u64));
2863 DECLR3CALLBACKMEMBER(int, pfnSSMPutS64,(PSSMHANDLE pSSM, int64_t i64));
2864 DECLR3CALLBACKMEMBER(int, pfnSSMPutU128,(PSSMHANDLE pSSM, uint128_t u128));
2865 DECLR3CALLBACKMEMBER(int, pfnSSMPutS128,(PSSMHANDLE pSSM, int128_t i128));
2866 DECLR3CALLBACKMEMBER(int, pfnSSMPutUInt,(PSSMHANDLE pSSM, RTUINT u));
2867 DECLR3CALLBACKMEMBER(int, pfnSSMPutSInt,(PSSMHANDLE pSSM, RTINT i));
2868 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCUInt,(PSSMHANDLE pSSM, RTGCUINT u));
2869 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCUIntReg,(PSSMHANDLE pSSM, RTGCUINTREG u));
2870 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCPhys32,(PSSMHANDLE pSSM, RTGCPHYS32 GCPhys));
2871 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCPhys64,(PSSMHANDLE pSSM, RTGCPHYS64 GCPhys));
2872 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCPhys,(PSSMHANDLE pSSM, RTGCPHYS GCPhys));
2873 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCPtr,(PSSMHANDLE pSSM, RTGCPTR GCPtr));
2874 DECLR3CALLBACKMEMBER(int, pfnSSMPutGCUIntPtr,(PSSMHANDLE pSSM, RTGCUINTPTR GCPtr));
2875 DECLR3CALLBACKMEMBER(int, pfnSSMPutRCPtr,(PSSMHANDLE pSSM, RTRCPTR RCPtr));
2876 DECLR3CALLBACKMEMBER(int, pfnSSMPutIOPort,(PSSMHANDLE pSSM, RTIOPORT IOPort));
2877 DECLR3CALLBACKMEMBER(int, pfnSSMPutSel,(PSSMHANDLE pSSM, RTSEL Sel));
2878 DECLR3CALLBACKMEMBER(int, pfnSSMPutMem,(PSSMHANDLE pSSM, const void *pv, size_t cb));
2879 DECLR3CALLBACKMEMBER(int, pfnSSMPutStrZ,(PSSMHANDLE pSSM, const char *psz));
2880 DECLR3CALLBACKMEMBER(int, pfnSSMGetStruct,(PSSMHANDLE pSSM, void *pvStruct, PCSSMFIELD paFields));
2881 DECLR3CALLBACKMEMBER(int, pfnSSMGetStructEx,(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser));
2882 DECLR3CALLBACKMEMBER(int, pfnSSMGetBool,(PSSMHANDLE pSSM, bool *pfBool));
2883 DECLR3CALLBACKMEMBER(int, pfnSSMGetU8,(PSSMHANDLE pSSM, uint8_t *pu8));
2884 DECLR3CALLBACKMEMBER(int, pfnSSMGetS8,(PSSMHANDLE pSSM, int8_t *pi8));
2885 DECLR3CALLBACKMEMBER(int, pfnSSMGetU16,(PSSMHANDLE pSSM, uint16_t *pu16));
2886 DECLR3CALLBACKMEMBER(int, pfnSSMGetS16,(PSSMHANDLE pSSM, int16_t *pi16));
2887 DECLR3CALLBACKMEMBER(int, pfnSSMGetU32,(PSSMHANDLE pSSM, uint32_t *pu32));
2888 DECLR3CALLBACKMEMBER(int, pfnSSMGetS32,(PSSMHANDLE pSSM, int32_t *pi32));
2889 DECLR3CALLBACKMEMBER(int, pfnSSMGetU64,(PSSMHANDLE pSSM, uint64_t *pu64));
2890 DECLR3CALLBACKMEMBER(int, pfnSSMGetS64,(PSSMHANDLE pSSM, int64_t *pi64));
2891 DECLR3CALLBACKMEMBER(int, pfnSSMGetU128,(PSSMHANDLE pSSM, uint128_t *pu128));
2892 DECLR3CALLBACKMEMBER(int, pfnSSMGetS128,(PSSMHANDLE pSSM, int128_t *pi128));
2893 DECLR3CALLBACKMEMBER(int, pfnSSMGetUInt,(PSSMHANDLE pSSM, PRTUINT pu));
2894 DECLR3CALLBACKMEMBER(int, pfnSSMGetSInt,(PSSMHANDLE pSSM, PRTINT pi));
2895 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCUInt,(PSSMHANDLE pSSM, PRTGCUINT pu));
2896 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCUIntReg,(PSSMHANDLE pSSM, PRTGCUINTREG pu));
2897 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPhys32,(PSSMHANDLE pSSM, PRTGCPHYS32 pGCPhys));
2898 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPhys64,(PSSMHANDLE pSSM, PRTGCPHYS64 pGCPhys));
2899 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPhys,(PSSMHANDLE pSSM, PRTGCPHYS pGCPhys));
2900 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCPtr,(PSSMHANDLE pSSM, PRTGCPTR pGCPtr));
2901 DECLR3CALLBACKMEMBER(int, pfnSSMGetGCUIntPtr,(PSSMHANDLE pSSM, PRTGCUINTPTR pGCPtr));
2902 DECLR3CALLBACKMEMBER(int, pfnSSMGetRCPtr,(PSSMHANDLE pSSM, PRTRCPTR pRCPtr));
2903 DECLR3CALLBACKMEMBER(int, pfnSSMGetIOPort,(PSSMHANDLE pSSM, PRTIOPORT pIOPort));
2904 DECLR3CALLBACKMEMBER(int, pfnSSMGetSel,(PSSMHANDLE pSSM, PRTSEL pSel));
2905 DECLR3CALLBACKMEMBER(int, pfnSSMGetMem,(PSSMHANDLE pSSM, void *pv, size_t cb));
2906 DECLR3CALLBACKMEMBER(int, pfnSSMGetStrZ,(PSSMHANDLE pSSM, char *psz, size_t cbMax));
2907 DECLR3CALLBACKMEMBER(int, pfnSSMGetStrZEx,(PSSMHANDLE pSSM, char *psz, size_t cbMax, size_t *pcbStr));
2908 DECLR3CALLBACKMEMBER(int, pfnSSMSkip,(PSSMHANDLE pSSM, size_t cb));
2909 DECLR3CALLBACKMEMBER(int, pfnSSMSkipToEndOfUnit,(PSSMHANDLE pSSM));
2910 DECLR3CALLBACKMEMBER(int, pfnSSMSetLoadError,(PSSMHANDLE pSSM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(6, 7));
2911 DECLR3CALLBACKMEMBER(int, pfnSSMSetLoadErrorV,(PSSMHANDLE pSSM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
2912 DECLR3CALLBACKMEMBER(int, pfnSSMSetCfgError,(PSSMHANDLE pSSM, RT_SRC_POS_DECL, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(5, 6));
2913 DECLR3CALLBACKMEMBER(int, pfnSSMSetCfgErrorV,(PSSMHANDLE pSSM, RT_SRC_POS_DECL, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(5, 0));
2914 DECLR3CALLBACKMEMBER(int, pfnSSMHandleGetStatus,(PSSMHANDLE pSSM));
2915 DECLR3CALLBACKMEMBER(SSMAFTER, pfnSSMHandleGetAfter,(PSSMHANDLE pSSM));
2916 DECLR3CALLBACKMEMBER(bool, pfnSSMHandleIsLiveSave,(PSSMHANDLE pSSM));
2917 DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleMaxDowntime,(PSSMHANDLE pSSM));
2918 DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleHostBits,(PSSMHANDLE pSSM));
2919 DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleRevision,(PSSMHANDLE pSSM));
2920 DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleVersion,(PSSMHANDLE pSSM));
2921 /** @} */
2922
2923 /**
2924 * Creates a timer.
2925 *
2926 * @returns VBox status.
2927 * @param pDevIns The device instance.
2928 * @param enmClock The clock to use on this timer.
2929 * @param pfnCallback Callback function.
2930 * @param pvUser User argument for the callback.
2931 * @param fFlags Flags, see TMTIMER_FLAGS_*.
2932 * @param pszDesc Pointer to description string which must stay around
2933 * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
2934 * @param ppTimer Where to store the timer on success.
2935 * @remarks Caller enters the device critical section prior to invoking the
2936 * callback.
2937 */
2938 DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
2939 void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
2940
2941 /**
2942 * Creates a timer w/ a cross context handle.
2943 *
2944 * @returns VBox status.
2945 * @param pDevIns The device instance.
2946 * @param enmClock The clock to use on this timer.
2947 * @param pfnCallback Callback function.
2948 * @param pvUser User argument for the callback.
2949 * @param fFlags Flags, see TMTIMER_FLAGS_*.
2950 * @param pszDesc Pointer to description string which must stay around
2951 * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
2952 * @param phTimer Where to store the timer handle on success.
2953 * @remarks Caller enters the device critical section prior to invoking the
2954 * callback.
2955 */
2956 DECLR3CALLBACKMEMBER(int, pfnTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
2957 void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer));
2958
2959 /**
2960 * Translates a timer handle to a pointer.
2961 *
2962 * @returns The time address.
2963 * @param pDevIns The device instance.
2964 * @param hTimer The timer handle.
2965 */
2966 DECLR3CALLBACKMEMBER(PTMTIMERR3, pfnTimerToPtr,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
2967
2968 /** @name Timer handle method wrappers
2969 * @{ */
2970 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerFromMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs));
2971 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerFromMilli,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs));
2972 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerFromNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs));
2973 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerGet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
2974 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerGetFreq,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
2975 DECLR3CALLBACKMEMBER(uint64_t, pfnTimerGetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
2976 DECLR3CALLBACKMEMBER(bool, pfnTimerIsActive,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
2977 DECLR3CALLBACKMEMBER(bool, pfnTimerIsLockOwner,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
2978 DECLR3CALLBACKMEMBER(int, pfnTimerLock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy));
2979 DECLR3CALLBACKMEMBER(int, pfnTimerSet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire));
2980 DECLR3CALLBACKMEMBER(int, pfnTimerSetFrequencyHint,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz));
2981 DECLR3CALLBACKMEMBER(int, pfnTimerSetMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext));
2982 DECLR3CALLBACKMEMBER(int, pfnTimerSetMillies,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext));
2983 DECLR3CALLBACKMEMBER(int, pfnTimerSetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext));
2984 DECLR3CALLBACKMEMBER(int, pfnTimerSetRelative,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now));
2985 DECLR3CALLBACKMEMBER(int, pfnTimerStop,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
2986 DECLR3CALLBACKMEMBER(void, pfnTimerUnlock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
2987 DECLR3CALLBACKMEMBER(int, pfnTimerSave,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM));
2988 DECLR3CALLBACKMEMBER(int, pfnTimerLoad,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM));
2989 /** @} */
2990
2991 /**
2992 * Get the real world UTC time adjusted for VM lag, user offset and warpdrive.
2993 *
2994 * @returns pTime.
2995 * @param pDevIns The device instance.
2996 * @param pTime Where to store the time.
2997 */
2998 DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnTMUtcNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime));
2999
3000 /** @name Exported CFGM Functions.
3001 * @{ */
3002 DECLR3CALLBACKMEMBER(bool, pfnCFGMExists,( PCFGMNODE pNode, const char *pszName));
3003 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryType,( PCFGMNODE pNode, const char *pszName, PCFGMVALUETYPE penmType));
3004 DECLR3CALLBACKMEMBER(int, pfnCFGMQuerySize,( PCFGMNODE pNode, const char *pszName, size_t *pcb));
3005 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryInteger,( PCFGMNODE pNode, const char *pszName, uint64_t *pu64));
3006 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryIntegerDef,( PCFGMNODE pNode, const char *pszName, uint64_t *pu64, uint64_t u64Def));
3007 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryString,( PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString));
3008 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryStringDef,( PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString, const char *pszDef));
3009 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryBytes,( PCFGMNODE pNode, const char *pszName, void *pvData, size_t cbData));
3010 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU64,( PCFGMNODE pNode, const char *pszName, uint64_t *pu64));
3011 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU64Def,( PCFGMNODE pNode, const char *pszName, uint64_t *pu64, uint64_t u64Def));
3012 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS64,( PCFGMNODE pNode, const char *pszName, int64_t *pi64));
3013 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS64Def,( PCFGMNODE pNode, const char *pszName, int64_t *pi64, int64_t i64Def));
3014 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU32,( PCFGMNODE pNode, const char *pszName, uint32_t *pu32));
3015 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU32Def,( PCFGMNODE pNode, const char *pszName, uint32_t *pu32, uint32_t u32Def));
3016 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS32,( PCFGMNODE pNode, const char *pszName, int32_t *pi32));
3017 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS32Def,( PCFGMNODE pNode, const char *pszName, int32_t *pi32, int32_t i32Def));
3018 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU16,( PCFGMNODE pNode, const char *pszName, uint16_t *pu16));
3019 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU16Def,( PCFGMNODE pNode, const char *pszName, uint16_t *pu16, uint16_t u16Def));
3020 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS16,( PCFGMNODE pNode, const char *pszName, int16_t *pi16));
3021 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS16Def,( PCFGMNODE pNode, const char *pszName, int16_t *pi16, int16_t i16Def));
3022 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU8,( PCFGMNODE pNode, const char *pszName, uint8_t *pu8));
3023 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryU8Def,( PCFGMNODE pNode, const char *pszName, uint8_t *pu8, uint8_t u8Def));
3024 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS8,( PCFGMNODE pNode, const char *pszName, int8_t *pi8));
3025 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryS8Def,( PCFGMNODE pNode, const char *pszName, int8_t *pi8, int8_t i8Def));
3026 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryBool,( PCFGMNODE pNode, const char *pszName, bool *pf));
3027 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryBoolDef,( PCFGMNODE pNode, const char *pszName, bool *pf, bool fDef));
3028 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryPort,( PCFGMNODE pNode, const char *pszName, PRTIOPORT pPort));
3029 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryPortDef,( PCFGMNODE pNode, const char *pszName, PRTIOPORT pPort, RTIOPORT PortDef));
3030 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryUInt,( PCFGMNODE pNode, const char *pszName, unsigned int *pu));
3031 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryUIntDef,( PCFGMNODE pNode, const char *pszName, unsigned int *pu, unsigned int uDef));
3032 DECLR3CALLBACKMEMBER(int, pfnCFGMQuerySInt,( PCFGMNODE pNode, const char *pszName, signed int *pi));
3033 DECLR3CALLBACKMEMBER(int, pfnCFGMQuerySIntDef,( PCFGMNODE pNode, const char *pszName, signed int *pi, signed int iDef));
3034 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryPtr,( PCFGMNODE pNode, const char *pszName, void **ppv));
3035 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryPtrDef,( PCFGMNODE pNode, const char *pszName, void **ppv, void *pvDef));
3036 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtr,( PCFGMNODE pNode, const char *pszName, PRTGCPTR pGCPtr));
3037 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtrDef,( PCFGMNODE pNode, const char *pszName, PRTGCPTR pGCPtr, RTGCPTR GCPtrDef));
3038 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtrU,( PCFGMNODE pNode, const char *pszName, PRTGCUINTPTR pGCPtr));
3039 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtrUDef,( PCFGMNODE pNode, const char *pszName, PRTGCUINTPTR pGCPtr, RTGCUINTPTR GCPtrDef));
3040 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtrS,( PCFGMNODE pNode, const char *pszName, PRTGCINTPTR pGCPtr));
3041 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryGCPtrSDef,( PCFGMNODE pNode, const char *pszName, PRTGCINTPTR pGCPtr, RTGCINTPTR GCPtrDef));
3042 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryStringAlloc,( PCFGMNODE pNode, const char *pszName, char **ppszString));
3043 DECLR3CALLBACKMEMBER(int, pfnCFGMQueryStringAllocDef,(PCFGMNODE pNode, const char *pszName, char **ppszString, const char *pszDef));
3044 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetParent,(PCFGMNODE pNode));
3045 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetChild,(PCFGMNODE pNode, const char *pszPath));
3046 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetChildF,(PCFGMNODE pNode, const char *pszPathFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3));
3047 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetChildFV,(PCFGMNODE pNode, const char *pszPathFormat, va_list Args) RT_IPRT_FORMAT_ATTR(3, 0));
3048 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetFirstChild,(PCFGMNODE pNode));
3049 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetNextChild,(PCFGMNODE pCur));
3050 DECLR3CALLBACKMEMBER(int, pfnCFGMGetName,(PCFGMNODE pCur, char *pszName, size_t cchName));
3051 DECLR3CALLBACKMEMBER(size_t, pfnCFGMGetNameLen,(PCFGMNODE pCur));
3052 DECLR3CALLBACKMEMBER(bool, pfnCFGMAreChildrenValid,(PCFGMNODE pNode, const char *pszzValid));
3053 DECLR3CALLBACKMEMBER(PCFGMLEAF, pfnCFGMGetFirstValue,(PCFGMNODE pCur));
3054 DECLR3CALLBACKMEMBER(PCFGMLEAF, pfnCFGMGetNextValue,(PCFGMLEAF pCur));
3055 DECLR3CALLBACKMEMBER(int, pfnCFGMGetValueName,(PCFGMLEAF pCur, char *pszName, size_t cchName));
3056 DECLR3CALLBACKMEMBER(size_t, pfnCFGMGetValueNameLen,(PCFGMLEAF pCur));
3057 DECLR3CALLBACKMEMBER(CFGMVALUETYPE, pfnCFGMGetValueType,(PCFGMLEAF pCur));
3058 DECLR3CALLBACKMEMBER(bool, pfnCFGMAreValuesValid,(PCFGMNODE pNode, const char *pszzValid));
3059 DECLR3CALLBACKMEMBER(int, pfnCFGMValidateConfig,(PCFGMNODE pNode, const char *pszNode,
3060 const char *pszValidValues, const char *pszValidNodes,
3061 const char *pszWho, uint32_t uInstance));
3062 /** @} */
3063
3064 /**
3065 * Read physical memory.
3066 *
3067 * @returns VINF_SUCCESS (for now).
3068 * @param pDevIns The device instance.
3069 * @param GCPhys Physical address start reading from.
3070 * @param pvBuf Where to put the read bits.
3071 * @param cbRead How many bytes to read.
3072 * @thread Any thread, but the call may involve the emulation thread.
3073 */
3074 DECLR3CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
3075
3076 /**
3077 * Write to physical memory.
3078 *
3079 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
3080 * @param pDevIns The device instance.
3081 * @param GCPhys Physical address to write to.
3082 * @param pvBuf What to write.
3083 * @param cbWrite How many bytes to write.
3084 * @thread Any thread, but the call may involve the emulation thread.
3085 */
3086 DECLR3CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
3087
3088 /**
3089 * Requests the mapping of a guest page into ring-3.
3090 *
3091 * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
3092 * release it.
3093 *
3094 * This API will assume your intention is to write to the page, and will
3095 * therefore replace shared and zero pages. If you do not intend to modify the
3096 * page, use the pfnPhysGCPhys2CCPtrReadOnly() API.
3097 *
3098 * @returns VBox status code.
3099 * @retval VINF_SUCCESS on success.
3100 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
3101 * backing or if the page has any active access handlers. The caller
3102 * must fall back on using PGMR3PhysWriteExternal.
3103 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
3104 *
3105 * @param pDevIns The device instance.
3106 * @param GCPhys The guest physical address of the page that
3107 * should be mapped.
3108 * @param fFlags Flags reserved for future use, MBZ.
3109 * @param ppv Where to store the address corresponding to
3110 * GCPhys.
3111 * @param pLock Where to store the lock information that
3112 * pfnPhysReleasePageMappingLock needs.
3113 *
3114 * @remark Avoid calling this API from within critical sections (other than the
3115 * PGM one) because of the deadlock risk when we have to delegating the
3116 * task to an EMT.
3117 * @thread Any.
3118 */
3119 DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtr,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv,
3120 PPGMPAGEMAPLOCK pLock));
3121
3122 /**
3123 * Requests the mapping of a guest page into ring-3, external threads.
3124 *
3125 * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
3126 * release it.
3127 *
3128 * @returns VBox status code.
3129 * @retval VINF_SUCCESS on success.
3130 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
3131 * backing or if the page as an active ALL access handler. The caller
3132 * must fall back on using PGMPhysRead.
3133 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
3134 *
3135 * @param pDevIns The device instance.
3136 * @param GCPhys The guest physical address of the page that
3137 * should be mapped.
3138 * @param fFlags Flags reserved for future use, MBZ.
3139 * @param ppv Where to store the address corresponding to
3140 * GCPhys.
3141 * @param pLock Where to store the lock information that
3142 * pfnPhysReleasePageMappingLock needs.
3143 *
3144 * @remark Avoid calling this API from within critical sections.
3145 * @thread Any.
3146 */
3147 DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags,
3148 void const **ppv, PPGMPAGEMAPLOCK pLock));
3149
3150 /**
3151 * Release the mapping of a guest page.
3152 *
3153 * This is the counter part of pfnPhysGCPhys2CCPtr and
3154 * pfnPhysGCPhys2CCPtrReadOnly.
3155 *
3156 * @param pDevIns The device instance.
3157 * @param pLock The lock structure initialized by the mapping
3158 * function.
3159 */
3160 DECLR3CALLBACKMEMBER(void, pfnPhysReleasePageMappingLock,(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock));
3161
3162 /**
3163 * Read guest physical memory by virtual address.
3164 *
3165 * @param pDevIns The device instance.
3166 * @param pvDst Where to put the read bits.
3167 * @param GCVirtSrc Guest virtual address to start reading from.
3168 * @param cb How many bytes to read.
3169 * @thread The emulation thread.
3170 */
3171 DECLR3CALLBACKMEMBER(int, pfnPhysReadGCVirt,(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb));
3172
3173 /**
3174 * Write to guest physical memory by virtual address.
3175 *
3176 * @param pDevIns The device instance.
3177 * @param GCVirtDst Guest virtual address to write to.
3178 * @param pvSrc What to write.
3179 * @param cb How many bytes to write.
3180 * @thread The emulation thread.
3181 */
3182 DECLR3CALLBACKMEMBER(int, pfnPhysWriteGCVirt,(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb));
3183
3184 /**
3185 * Convert a guest virtual address to a guest physical address.
3186 *
3187 * @returns VBox status code.
3188 * @param pDevIns The device instance.
3189 * @param GCPtr Guest virtual address.
3190 * @param pGCPhys Where to store the GC physical address
3191 * corresponding to GCPtr.
3192 * @thread The emulation thread.
3193 * @remark Careful with page boundaries.
3194 */
3195 DECLR3CALLBACKMEMBER(int, pfnPhysGCPtr2GCPhys, (PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys));
3196
3197 /**
3198 * Allocate memory which is associated with current VM instance
3199 * and automatically freed on it's destruction.
3200 *
3201 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
3202 * @param pDevIns The device instance.
3203 * @param cb Number of bytes to allocate.
3204 */
3205 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAlloc,(PPDMDEVINS pDevIns, size_t cb));
3206
3207 /**
3208 * Allocate memory which is associated with current VM instance
3209 * and automatically freed on it's destruction. The memory is ZEROed.
3210 *
3211 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
3212 * @param pDevIns The device instance.
3213 * @param cb Number of bytes to allocate.
3214 */
3215 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAllocZ,(PPDMDEVINS pDevIns, size_t cb));
3216
3217 /**
3218 * Free memory allocated with pfnMMHeapAlloc() and pfnMMHeapAllocZ().
3219 *
3220 * @param pDevIns The device instance.
3221 * @param pv Pointer to the memory to free.
3222 */
3223 DECLR3CALLBACKMEMBER(void, pfnMMHeapFree,(PPDMDEVINS pDevIns, void *pv));
3224
3225 /**
3226 * Gets the VM state.
3227 *
3228 * @returns VM state.
3229 * @param pDevIns The device instance.
3230 * @thread Any thread (just keep in mind that it's volatile info).
3231 */
3232 DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
3233
3234 /**
3235 * Checks if the VM was teleported and hasn't been fully resumed yet.
3236 *
3237 * @returns true / false.
3238 * @param pDevIns The device instance.
3239 * @thread Any thread.
3240 */
3241 DECLR3CALLBACKMEMBER(bool, pfnVMTeleportedAndNotFullyResumedYet,(PPDMDEVINS pDevIns));
3242
3243 /**
3244 * Set the VM error message
3245 *
3246 * @returns rc.
3247 * @param pDevIns The device instance.
3248 * @param rc VBox status code.
3249 * @param SRC_POS Use RT_SRC_POS.
3250 * @param pszFormat Error message format string.
3251 * @param ... Error message arguments.
3252 */
3253 DECLR3CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
3254 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(6, 7));
3255
3256 /**
3257 * Set the VM error message
3258 *
3259 * @returns rc.
3260 * @param pDevIns The device instance.
3261 * @param rc VBox status code.
3262 * @param SRC_POS Use RT_SRC_POS.
3263 * @param pszFormat Error message format string.
3264 * @param va Error message arguments.
3265 */
3266 DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
3267 const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
3268
3269 /**
3270 * Set the VM runtime error message
3271 *
3272 * @returns VBox status code.
3273 * @param pDevIns The device instance.
3274 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3275 * @param pszErrorId Error ID string.
3276 * @param pszFormat Error message format string.
3277 * @param ... Error message arguments.
3278 */
3279 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
3280 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5));
3281
3282 /**
3283 * Set the VM runtime error message
3284 *
3285 * @returns VBox status code.
3286 * @param pDevIns The device instance.
3287 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3288 * @param pszErrorId Error ID string.
3289 * @param pszFormat Error message format string.
3290 * @param va Error message arguments.
3291 */
3292 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
3293 const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(4, 0));
3294
3295 /**
3296 * Stops the VM and enters the debugger to look at the guest state.
3297 *
3298 * Use the PDMDeviceDBGFStop() inline function with the RT_SRC_POS macro instead of
3299 * invoking this function directly.
3300 *
3301 * @returns VBox status code which must be passed up to the VMM.
3302 * @param pDevIns The device instance.
3303 * @param pszFile Filename of the assertion location.
3304 * @param iLine The linenumber of the assertion location.
3305 * @param pszFunction Function of the assertion location.
3306 * @param pszFormat Message. (optional)
3307 * @param args Message parameters.
3308 */
3309 DECLR3CALLBACKMEMBER(int, pfnDBGFStopV,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction,
3310 const char *pszFormat, va_list args) RT_IPRT_FORMAT_ATTR(5, 0));
3311
3312 /**
3313 * Register a info handler with DBGF.
3314 *
3315 * @returns VBox status code.
3316 * @param pDevIns The device instance.
3317 * @param pszName The identifier of the info.
3318 * @param pszDesc The description of the info and any arguments
3319 * the handler may take.
3320 * @param pfnHandler The handler function to be called to display the
3321 * info.
3322 */
3323 DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler));
3324
3325 /**
3326 * Register a info handler with DBGF, argv style.
3327 *
3328 * @returns VBox status code.
3329 * @param pDevIns The device instance.
3330 * @param pszName The identifier of the info.
3331 * @param pszDesc The description of the info and any arguments
3332 * the handler may take.
3333 * @param pfnHandler The handler function to be called to display the
3334 * info.
3335 */
3336 DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegisterArgv,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVDEV pfnHandler));
3337
3338 /**
3339 * Registers a set of registers for a device.
3340 *
3341 * The @a pvUser argument of the getter and setter callbacks will be
3342 * @a pDevIns. The register names will be prefixed by the device name followed
3343 * immediately by the instance number.
3344 *
3345 * @returns VBox status code.
3346 * @param pDevIns The device instance.
3347 * @param paRegisters The register descriptors.
3348 *
3349 * @remarks The device critical section is NOT entered prior to working the
3350 * callbacks registered via this helper!
3351 */
3352 DECLR3CALLBACKMEMBER(int, pfnDBGFRegRegister,(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters));
3353
3354 /**
3355 * Gets the trace buffer handle.
3356 *
3357 * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
3358 * really inteded for direct usage, thus no inline wrapper function.
3359 *
3360 * @returns Trace buffer handle or NIL_RTTRACEBUF.
3361 * @param pDevIns The device instance.
3362 */
3363 DECLR3CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
3364
3365 /**
3366 * Registers a statistics sample if statistics are enabled.
3367 *
3368 * @param pDevIns Device instance of the DMA.
3369 * @param pvSample Pointer to the sample.
3370 * @param enmType Sample type. This indicates what pvSample is
3371 * pointing at.
3372 * @param pszName Sample name. The name is on this form
3373 * "/<component>/<sample>". Further nesting is
3374 * possible.
3375 * @param enmUnit Sample unit.
3376 * @param pszDesc Sample description.
3377 */
3378 DECLR3CALLBACKMEMBER(void, pfnSTAMRegister,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc));
3379
3380 /**
3381 * Same as pfnSTAMRegister except that the name is specified in a
3382 * RTStrPrintf like fashion.
3383 *
3384 * @returns VBox status.
3385 * @param pDevIns Device instance of the DMA.
3386 * @param pvSample Pointer to the sample.
3387 * @param enmType Sample type. This indicates what pvSample is
3388 * pointing at.
3389 * @param enmVisibility Visibility type specifying whether unused
3390 * statistics should be visible or not.
3391 * @param enmUnit Sample unit.
3392 * @param pszDesc Sample description.
3393 * @param pszName The sample name format string.
3394 * @param ... Arguments to the format string.
3395 */
3396 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterF,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType,
3397 STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc,
3398 const char *pszName, ...) RT_IPRT_FORMAT_ATTR(7, 8));
3399
3400 /**
3401 * Same as pfnSTAMRegister except that the name is specified in a
3402 * RTStrPrintfV like fashion.
3403 *
3404 * @returns VBox status.
3405 * @param pDevIns Device instance of the DMA.
3406 * @param pvSample Pointer to the sample.
3407 * @param enmType Sample type. This indicates what pvSample is
3408 * pointing at.
3409 * @param enmVisibility Visibility type specifying whether unused
3410 * statistics should be visible or not.
3411 * @param enmUnit Sample unit.
3412 * @param pszDesc Sample description.
3413 * @param pszName The sample name format string.
3414 * @param args Arguments to the format string.
3415 */
3416 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType,
3417 STAMVISIBILITY enmVisibility, STAMUNIT enmUnit, const char *pszDesc,
3418 const char *pszName, va_list args) RT_IPRT_FORMAT_ATTR(7, 0));
3419
3420 /**
3421 * Registers a PCI device with the default PCI bus.
3422 *
3423 * If a PDM device has more than one PCI device, they must be registered in the
3424 * order of PDMDEVINSR3::apPciDevs.
3425 *
3426 * @returns VBox status code.
3427 * @param pDevIns The device instance.
3428 * @param pPciDev The PCI device structure.
3429 * This must be kept in the instance data.
3430 * The PCI configuration must be initialized before registration.
3431 * @param fFlags Reserved for future use, PDMPCIDEVREG_F_MBZ.
3432 * @param uPciDevNo PDMPCIDEVREG_DEV_NO_FIRST_UNUSED,
3433 * PDMPCIDEVREG_DEV_NO_SAME_AS_PREV, or a specific
3434 * device number (0-31). This will be ignored if
3435 * the CFGM configuration contains a PCIDeviceNo
3436 * value.
3437 * @param uPciFunNo PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, or a specific
3438 * function number (0-7). This will be ignored if
3439 * the CFGM configuration contains a PCIFunctionNo
3440 * value.
3441 * @param pszName Device name, if NULL PDMDEVREG::szName is used.
3442 * The pointer is saved, so don't free or changed.
3443 * @note The PCI device configuration is now implicit from the apPciDevs
3444 * index, meaning that the zero'th entry is the primary one and
3445 * subsequent uses CFGM subkeys "PciDev1", "PciDev2" and so on.
3446 */
3447 DECLR3CALLBACKMEMBER(int, pfnPCIRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
3448 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName));
3449
3450 /**
3451 * Initialize MSI or MSI-X emulation support for the given PCI device.
3452 *
3453 * @see PDMPCIBUSREG::pfnRegisterMsiR3 for details.
3454 *
3455 * @returns VBox status code.
3456 * @param pDevIns The device instance.
3457 * @param pPciDev The PCI device. NULL is an alias for the first
3458 * one registered.
3459 * @param pMsiReg MSI emulation registration structure.
3460 */
3461 DECLR3CALLBACKMEMBER(int, pfnPCIRegisterMsi,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg));
3462
3463 /**
3464 * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
3465 *
3466 * @returns VBox status code.
3467 * @param pDevIns The device instance.
3468 * @param pPciDev The PCI device structure. If NULL the default
3469 * PCI device for this device instance is used.
3470 * @param iRegion The region number.
3471 * @param cbRegion Size of the region.
3472 * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
3473 * @param fFlags PDMPCIDEV_IORGN_F_XXX.
3474 * @param hHandle An I/O port, MMIO or MMIO2 handle according to
3475 * @a fFlags, UINT64_MAX if no handle is passed
3476 * (old style).
3477 * @param pfnCallback Callback for doing the mapping, optional when a
3478 * handle is specified. The callback will be
3479 * invoked holding only the PDM lock. The device
3480 * lock will _not_ be taken (due to lock order).
3481 */
3482 DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
3483 RTGCPHYS cbRegion, PCIADDRESSSPACE enmType, uint32_t fFlags,
3484 uint64_t hHandle, PFNPCIIOREGIONMAP pfnCallback));
3485
3486 /**
3487 * Register PCI configuration space read/write callbacks.
3488 *
3489 * @returns VBox status code.
3490 * @param pDevIns The device instance.
3491 * @param pPciDev The PCI device structure. If NULL the default
3492 * PCI device for this device instance is used.
3493 * @param pfnRead Pointer to the user defined PCI config read function.
3494 * to call default PCI config read function. Can be NULL.
3495 * @param pfnWrite Pointer to the user defined PCI config write function.
3496 * @remarks The callbacks will be invoked holding the PDM lock. The device lock
3497 * is NOT take because that is very likely be a lock order violation.
3498 * @thread EMT(0)
3499 * @note Only callable during VM creation.
3500 * @sa PDMDevHlpPCIConfigRead, PDMDevHlpPCIConfigWrite
3501 */
3502 DECLR3CALLBACKMEMBER(int, pfnPCIInterceptConfigAccesses,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
3503 PFNPCICONFIGREAD pfnRead, PFNPCICONFIGWRITE pfnWrite));
3504
3505 /**
3506 * Perform a PCI configuration space write.
3507 *
3508 * This is for devices that make use of PDMDevHlpPCIInterceptConfigAccesses().
3509 *
3510 * @returns Strict VBox status code (mainly DBGFSTOP).
3511 * @param pDevIns The device instance.
3512 * @param pPciDev The PCI device which config space is being read.
3513 * @param uAddress The config space address.
3514 * @param cb The size of the read: 1, 2 or 4 bytes.
3515 * @param u32Value The value to write.
3516 */
3517 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnPCIConfigWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
3518 uint32_t uAddress, unsigned cb, uint32_t u32Value));
3519
3520 /**
3521 * Perform a PCI configuration space read.
3522 *
3523 * This is for devices that make use of PDMDevHlpPCIInterceptConfigAccesses().
3524 *
3525 * @returns Strict VBox status code (mainly DBGFSTOP).
3526 * @param pDevIns The device instance.
3527 * @param pPciDev The PCI device which config space is being read.
3528 * @param uAddress The config space address.
3529 * @param cb The size of the read: 1, 2 or 4 bytes.
3530 * @param pu32Value Where to return the value.
3531 */
3532 DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnPCIConfigRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
3533 uint32_t uAddress, unsigned cb, uint32_t *pu32Value));
3534
3535 /**
3536 * Bus master physical memory read.
3537 *
3538 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
3539 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
3540 * @param pDevIns The device instance.
3541 * @param pPciDev The PCI device structure. If NULL the default
3542 * PCI device for this device instance is used.
3543 * @param GCPhys Physical address start reading from.
3544 * @param pvBuf Where to put the read bits.
3545 * @param cbRead How many bytes to read.
3546 * @thread Any thread, but the call may involve the emulation thread.
3547 */
3548 DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
3549
3550 /**
3551 * Bus master physical memory write.
3552 *
3553 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
3554 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
3555 * @param pDevIns The device instance.
3556 * @param pPciDev The PCI device structure. If NULL the default
3557 * PCI device for this device instance is used.
3558 * @param GCPhys Physical address to write to.
3559 * @param pvBuf What to write.
3560 * @param cbWrite How many bytes to write.
3561 * @thread Any thread, but the call may involve the emulation thread.
3562 */
3563 DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
3564
3565 /**
3566 * Sets the IRQ for the given PCI device.
3567 *
3568 * @param pDevIns The device instance.
3569 * @param pPciDev The PCI device structure. If NULL the default
3570 * PCI device for this device instance is used.
3571 * @param iIrq IRQ number to set.
3572 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3573 * @thread Any thread, but will involve the emulation thread.
3574 */
3575 DECLR3CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
3576
3577 /**
3578 * Sets the IRQ for the given PCI device, but doesn't wait for EMT to process
3579 * the request when not called from EMT.
3580 *
3581 * @param pDevIns The device instance.
3582 * @param pPciDev The PCI device structure. If NULL the default
3583 * PCI device for this device instance is used.
3584 * @param iIrq IRQ number to set.
3585 * @param iLevel IRQ level.
3586 * @thread Any thread, but will involve the emulation thread.
3587 */
3588 DECLR3CALLBACKMEMBER(void, pfnPCISetIrqNoWait,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
3589
3590 /**
3591 * Set ISA IRQ for a device.
3592 *
3593 * @param pDevIns The device instance.
3594 * @param iIrq IRQ number to set.
3595 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3596 * @thread Any thread, but will involve the emulation thread.
3597 */
3598 DECLR3CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3599
3600 /**
3601 * Set the ISA IRQ for a device, but don't wait for EMT to process
3602 * the request when not called from EMT.
3603 *
3604 * @param pDevIns The device instance.
3605 * @param iIrq IRQ number to set.
3606 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3607 * @thread Any thread, but will involve the emulation thread.
3608 */
3609 DECLR3CALLBACKMEMBER(void, pfnISASetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3610
3611 /**
3612 * Send an MSI straight to the I/O APIC.
3613 *
3614 * @param pDevIns PCI device instance.
3615 * @param GCPhys Physical address MSI request was written.
3616 * @param uValue Value written.
3617 * @thread Any thread, but will involve the emulation thread.
3618 */
3619 DECLR3CALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue));
3620
3621 /**
3622 * Attaches a driver (chain) to the device.
3623 *
3624 * The first call for a LUN this will serve as a registration of the LUN. The pBaseInterface and
3625 * the pszDesc string will be registered with that LUN and kept around for PDMR3QueryDeviceLun().
3626 *
3627 * @returns VBox status code.
3628 * @param pDevIns The device instance.
3629 * @param iLun The logical unit to attach.
3630 * @param pBaseInterface Pointer to the base interface for that LUN. (device side / down)
3631 * @param ppBaseInterface Where to store the pointer to the base interface. (driver side / up)
3632 * @param pszDesc Pointer to a string describing the LUN. This string must remain valid
3633 * for the live of the device instance.
3634 */
3635 DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface,
3636 PPDMIBASE *ppBaseInterface, const char *pszDesc));
3637
3638 /**
3639 * Detaches an attached driver (chain) from the device again.
3640 *
3641 * @returns VBox status code.
3642 * @param pDevIns The device instance.
3643 * @param pDrvIns The driver instance to detach.
3644 * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
3645 */
3646 DECLR3CALLBACKMEMBER(int, pfnDriverDetach,(PPDMDEVINS pDevIns, PPDMDRVINS pDrvIns, uint32_t fFlags));
3647
3648 /**
3649 * Create a queue.
3650 *
3651 * @returns VBox status code.
3652 * @param pDevIns The device instance.
3653 * @param cbItem The size of a queue item.
3654 * @param cItems The number of items in the queue.
3655 * @param cMilliesInterval The number of milliseconds between polling the queue.
3656 * If 0 then the emulation thread will be notified whenever an item arrives.
3657 * @param pfnCallback The consumer function.
3658 * @param fRZEnabled Set if the queue should work in RC and R0.
3659 * @param pszName The queue base name. The instance number will be
3660 * appended automatically.
3661 * @param ppQueue Where to store the queue handle on success.
3662 * @thread The emulation thread.
3663 * @remarks The device critical section will NOT be entered before calling the
3664 * callback. No locks will be held, but for now it's safe to assume
3665 * that only one EMT will do queue callbacks at any one time.
3666 */
3667 DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
3668 PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue));
3669
3670 /**
3671 * Initializes a PDM critical section.
3672 *
3673 * The PDM critical sections are derived from the IPRT critical sections, but
3674 * works in RC and R0 as well.
3675 *
3676 * @returns VBox status code.
3677 * @param pDevIns The device instance.
3678 * @param pCritSect Pointer to the critical section.
3679 * @param SRC_POS Use RT_SRC_POS.
3680 * @param pszNameFmt Format string for naming the critical section.
3681 * For statistics and lock validation.
3682 * @param va Arguments for the format string.
3683 */
3684 DECLR3CALLBACKMEMBER(int, pfnCritSectInit,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
3685 const char *pszNameFmt, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
3686
3687 /**
3688 * Gets the NOP critical section.
3689 *
3690 * @returns The ring-3 address of the NOP critical section.
3691 * @param pDevIns The device instance.
3692 */
3693 DECLR3CALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
3694
3695 /**
3696 * Gets the NOP critical section.
3697 *
3698 * @returns The ring-0 address of the NOP critical section.
3699 * @param pDevIns The device instance.
3700 * @deprecated
3701 */
3702 DECLR3CALLBACKMEMBER(R0PTRTYPE(PPDMCRITSECT), pfnCritSectGetNopR0,(PPDMDEVINS pDevIns));
3703
3704 /**
3705 * Gets the NOP critical section.
3706 *
3707 * @returns The raw-mode context address of the NOP critical section.
3708 * @param pDevIns The device instance.
3709 * @deprecated
3710 */
3711 DECLR3CALLBACKMEMBER(RCPTRTYPE(PPDMCRITSECT), pfnCritSectGetNopRC,(PPDMDEVINS pDevIns));
3712
3713 /**
3714 * Changes the device level critical section from the automatically created
3715 * default to one desired by the device constructor.
3716 *
3717 * For ring-0 and raw-mode capable devices, the call must be repeated in each of
3718 * the additional contexts.
3719 *
3720 * @returns VBox status code.
3721 * @param pDevIns The device instance.
3722 * @param pCritSect The critical section to use. NULL is not
3723 * valid, instead use the NOP critical
3724 * section.
3725 */
3726 DECLR3CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
3727
3728 /** @name Exported PDM Critical Section Functions
3729 * @{ */
3730 DECLR3CALLBACKMEMBER(bool, pfnCritSectYield,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
3731 DECLR3CALLBACKMEMBER(int, pfnCritSectEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy));
3732 DECLR3CALLBACKMEMBER(int, pfnCritSectEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
3733 DECLR3CALLBACKMEMBER(int, pfnCritSectTryEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
3734 DECLR3CALLBACKMEMBER(int, pfnCritSectTryEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
3735 DECLR3CALLBACKMEMBER(int, pfnCritSectLeave,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
3736 DECLR3CALLBACKMEMBER(bool, pfnCritSectIsOwner,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
3737 DECLR3CALLBACKMEMBER(bool, pfnCritSectIsInitialized,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
3738 DECLR3CALLBACKMEMBER(bool, pfnCritSectHasWaiters,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
3739 DECLR3CALLBACKMEMBER(uint32_t, pfnCritSectGetRecursion,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
3740 /** @} */
3741
3742 /**
3743 * Creates a PDM thread.
3744 *
3745 * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
3746 * resuming, and destroying the thread as the VM state changes.
3747 *
3748 * @returns VBox status code.
3749 * @param pDevIns The device instance.
3750 * @param ppThread Where to store the thread 'handle'.
3751 * @param pvUser The user argument to the thread function.
3752 * @param pfnThread The thread function.
3753 * @param pfnWakeup The wakup callback. This is called on the EMT
3754 * thread when a state change is pending.
3755 * @param cbStack See RTThreadCreate.
3756 * @param enmType See RTThreadCreate.
3757 * @param pszName See RTThreadCreate.
3758 * @remarks The device critical section will NOT be entered prior to invoking
3759 * the function pointers.
3760 */
3761 DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
3762 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
3763
3764 /**
3765 * Set up asynchronous handling of a suspend, reset or power off notification.
3766 *
3767 * This shall only be called when getting the notification. It must be called
3768 * for each one.
3769 *
3770 * @returns VBox status code.
3771 * @param pDevIns The device instance.
3772 * @param pfnAsyncNotify The callback.
3773 * @thread EMT(0)
3774 * @remarks The caller will enter the device critical section prior to invoking
3775 * the callback.
3776 */
3777 DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify));
3778
3779 /**
3780 * Notify EMT(0) that the device has completed the asynchronous notification
3781 * handling.
3782 *
3783 * This can be called at any time, spurious calls will simply be ignored.
3784 *
3785 * @param pDevIns The device instance.
3786 * @thread Any
3787 */
3788 DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMDEVINS pDevIns));
3789
3790 /**
3791 * Register the RTC device.
3792 *
3793 * @returns VBox status code.
3794 * @param pDevIns The device instance.
3795 * @param pRtcReg Pointer to a RTC registration structure.
3796 * @param ppRtcHlp Where to store the pointer to the helper
3797 * functions.
3798 */
3799 DECLR3CALLBACKMEMBER(int, pfnRTCRegister,(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp));
3800
3801 /**
3802 * Register a PCI Bus.
3803 *
3804 * @returns VBox status code, but the positive values 0..31 are used to indicate
3805 * bus number rather than informational status codes.
3806 * @param pDevIns The device instance.
3807 * @param pPciBusReg Pointer to PCI bus registration structure.
3808 * @param ppPciHlp Where to store the pointer to the PCI Bus
3809 * helpers.
3810 * @param piBus Where to return the PDM bus number. Optional.
3811 */
3812 DECLR3CALLBACKMEMBER(int, pfnPCIBusRegister,(PPDMDEVINS pDevIns, PPDMPCIBUSREGR3 pPciBusReg,
3813 PCPDMPCIHLPR3 *ppPciHlp, uint32_t *piBus));
3814
3815 /**
3816 * Register the PIC device.
3817 *
3818 * @returns VBox status code.
3819 * @param pDevIns The device instance.
3820 * @param pPicReg Pointer to a PIC registration structure.
3821 * @param ppPicHlpR3 Where to store the pointer to the PIC HC
3822 * helpers.
3823 */
3824 DECLR3CALLBACKMEMBER(int, pfnPICRegister,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3));
3825
3826 /**
3827 * Register the APIC device.
3828 *
3829 * @returns VBox status code.
3830 * @param pDevIns The device instance.
3831 */
3832 DECLR3CALLBACKMEMBER(int, pfnAPICRegister,(PPDMDEVINS pDevIns));
3833
3834 /**
3835 * Register the I/O APIC device.
3836 *
3837 * @returns VBox status code.
3838 * @param pDevIns The device instance.
3839 * @param pIoApicReg Pointer to a I/O APIC registration structure.
3840 * @param ppIoApicHlpR3 Where to store the pointer to the IOAPIC
3841 * helpers.
3842 */
3843 DECLR3CALLBACKMEMBER(int, pfnIOAPICRegister,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3));
3844
3845 /**
3846 * Register the HPET device.
3847 *
3848 * @returns VBox status code.
3849 * @param pDevIns The device instance.
3850 * @param pHpetReg Pointer to a HPET registration structure.
3851 * @param ppHpetHlpR3 Where to store the pointer to the HPET
3852 * helpers.
3853 */
3854 DECLR3CALLBACKMEMBER(int, pfnHPETRegister,(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3));
3855
3856 /**
3857 * Register a raw PCI device.
3858 *
3859 * @returns VBox status code.
3860 * @param pDevIns The device instance.
3861 * @param pPciRawReg Pointer to a raw PCI registration structure.
3862 * @param ppPciRawHlpR3 Where to store the pointer to the raw PCI
3863 * device helpers.
3864 */
3865 DECLR3CALLBACKMEMBER(int, pfnPciRawRegister,(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3));
3866
3867 /**
3868 * Register the DMA device.
3869 *
3870 * @returns VBox status code.
3871 * @param pDevIns The device instance.
3872 * @param pDmacReg Pointer to a DMAC registration structure.
3873 * @param ppDmacHlp Where to store the pointer to the DMA helpers.
3874 */
3875 DECLR3CALLBACKMEMBER(int, pfnDMACRegister,(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp));
3876
3877 /**
3878 * Register transfer function for DMA channel.
3879 *
3880 * @returns VBox status code.
3881 * @param pDevIns The device instance.
3882 * @param uChannel Channel number.
3883 * @param pfnTransferHandler Device specific transfer callback function.
3884 * @param pvUser User pointer to pass to the callback.
3885 * @thread EMT
3886 */
3887 DECLR3CALLBACKMEMBER(int, pfnDMARegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
3888
3889 /**
3890 * Read memory.
3891 *
3892 * @returns VBox status code.
3893 * @param pDevIns The device instance.
3894 * @param uChannel Channel number.
3895 * @param pvBuffer Pointer to target buffer.
3896 * @param off DMA position.
3897 * @param cbBlock Block size.
3898 * @param pcbRead Where to store the number of bytes which was
3899 * read. optional.
3900 * @thread EMT
3901 */
3902 DECLR3CALLBACKMEMBER(int, pfnDMAReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead));
3903
3904 /**
3905 * Write memory.
3906 *
3907 * @returns VBox status code.
3908 * @param pDevIns The device instance.
3909 * @param uChannel Channel number.
3910 * @param pvBuffer Memory to write.
3911 * @param off DMA position.
3912 * @param cbBlock Block size.
3913 * @param pcbWritten Where to store the number of bytes which was
3914 * written. optional.
3915 * @thread EMT
3916 */
3917 DECLR3CALLBACKMEMBER(int, pfnDMAWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten));
3918
3919 /**
3920 * Set the DREQ line.
3921 *
3922 * @returns VBox status code.
3923 * @param pDevIns Device instance.
3924 * @param uChannel Channel number.
3925 * @param uLevel Level of the line.
3926 * @thread EMT
3927 */
3928 DECLR3CALLBACKMEMBER(int, pfnDMASetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
3929
3930 /**
3931 * Get channel mode.
3932 *
3933 * @returns Channel mode. See specs.
3934 * @param pDevIns The device instance.
3935 * @param uChannel Channel number.
3936 * @thread EMT
3937 */
3938 DECLR3CALLBACKMEMBER(uint8_t, pfnDMAGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
3939
3940 /**
3941 * Schedule DMA execution.
3942 *
3943 * @param pDevIns The device instance.
3944 * @thread Any thread.
3945 */
3946 DECLR3CALLBACKMEMBER(void, pfnDMASchedule,(PPDMDEVINS pDevIns));
3947
3948 /**
3949 * Write CMOS value and update the checksum(s).
3950 *
3951 * @returns VBox status code.
3952 * @param pDevIns The device instance.
3953 * @param iReg The CMOS register index.
3954 * @param u8Value The CMOS register value.
3955 * @thread EMT
3956 */
3957 DECLR3CALLBACKMEMBER(int, pfnCMOSWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
3958
3959 /**
3960 * Read CMOS value.
3961 *
3962 * @returns VBox status code.
3963 * @param pDevIns The device instance.
3964 * @param iReg The CMOS register index.
3965 * @param pu8Value Where to store the CMOS register value.
3966 * @thread EMT
3967 */
3968 DECLR3CALLBACKMEMBER(int, pfnCMOSRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
3969
3970 /**
3971 * Assert that the current thread is the emulation thread.
3972 *
3973 * @returns True if correct.
3974 * @returns False if wrong.
3975 * @param pDevIns The device instance.
3976 * @param pszFile Filename of the assertion location.
3977 * @param iLine The linenumber of the assertion location.
3978 * @param pszFunction Function of the assertion location.
3979 */
3980 DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
3981
3982 /**
3983 * Assert that the current thread is NOT the emulation thread.
3984 *
3985 * @returns True if correct.
3986 * @returns False if wrong.
3987 * @param pDevIns The device instance.
3988 * @param pszFile Filename of the assertion location.
3989 * @param iLine The linenumber of the assertion location.
3990 * @param pszFunction Function of the assertion location.
3991 */
3992 DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
3993
3994 /**
3995 * Resolves the symbol for a raw-mode context interface.
3996 *
3997 * @returns VBox status code.
3998 * @param pDevIns The device instance.
3999 * @param pvInterface The interface structure.
4000 * @param cbInterface The size of the interface structure.
4001 * @param pszSymPrefix What to prefix the symbols in the list with
4002 * before resolving them. This must start with
4003 * 'dev' and contain the driver name.
4004 * @param pszSymList List of symbols corresponding to the interface.
4005 * There is generally a there is generally a define
4006 * holding this list associated with the interface
4007 * definition (INTERFACE_SYM_LIST). For more
4008 * details see PDMR3LdrGetInterfaceSymbols.
4009 * @thread EMT
4010 */
4011 DECLR3CALLBACKMEMBER(int, pfnLdrGetRCInterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
4012 const char *pszSymPrefix, const char *pszSymList));
4013
4014 /**
4015 * Resolves the symbol for a ring-0 context interface.
4016 *
4017 * @returns VBox status code.
4018 * @param pDevIns The device instance.
4019 * @param pvInterface The interface structure.
4020 * @param cbInterface The size of the interface structure.
4021 * @param pszSymPrefix What to prefix the symbols in the list with
4022 * before resolving them. This must start with
4023 * 'dev' and contain the driver name.
4024 * @param pszSymList List of symbols corresponding to the interface.
4025 * There is generally a there is generally a define
4026 * holding this list associated with the interface
4027 * definition (INTERFACE_SYM_LIST). For more
4028 * details see PDMR3LdrGetInterfaceSymbols.
4029 * @thread EMT
4030 */
4031 DECLR3CALLBACKMEMBER(int, pfnLdrGetR0InterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
4032 const char *pszSymPrefix, const char *pszSymList));
4033
4034 /**
4035 * Call the ring-0 request handler routine of the device.
4036 *
4037 * For this to work, the device must be ring-0 enabled and export a request
4038 * handler function. The name of the function must be the device name in
4039 * the PDMDRVREG struct prefixed with 'drvR0' and suffixed with
4040 * 'ReqHandler'. The device name will be captialized. It shall take the
4041 * exact same arguments as this function and be declared using
4042 * PDMBOTHCBDECL. See FNPDMDEVREQHANDLERR0.
4043 *
4044 * Unlike PDMDrvHlpCallR0, this is current unsuitable for more than a call
4045 * or two as the handler address will be resolved on each invocation. This
4046 * is the reason for the EMT only restriction as well.
4047 *
4048 * @returns VBox status code.
4049 * @retval VERR_SYMBOL_NOT_FOUND if the device doesn't export the required
4050 * handler function.
4051 * @retval VERR_ACCESS_DENIED if the device isn't ring-0 capable.
4052 *
4053 * @param pDevIns The device instance.
4054 * @param uOperation The operation to perform.
4055 * @param u64Arg 64-bit integer argument.
4056 * @thread EMT
4057 */
4058 DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg));
4059
4060 /**
4061 * Gets the reason for the most recent VM suspend.
4062 *
4063 * @returns The suspend reason. VMSUSPENDREASON_INVALID is returned if no
4064 * suspend has been made or if the pDevIns is invalid.
4065 * @param pDevIns The device instance.
4066 */
4067 DECLR3CALLBACKMEMBER(VMSUSPENDREASON, pfnVMGetSuspendReason,(PPDMDEVINS pDevIns));
4068
4069 /**
4070 * Gets the reason for the most recent VM resume.
4071 *
4072 * @returns The resume reason. VMRESUMEREASON_INVALID is returned if no
4073 * resume has been made or if the pDevIns is invalid.
4074 * @param pDevIns The device instance.
4075 */
4076 DECLR3CALLBACKMEMBER(VMRESUMEREASON, pfnVMGetResumeReason,(PPDMDEVINS pDevIns));
4077
4078 /**
4079 * Requests the mapping of multiple guest page into ring-3.
4080 *
4081 * When you're done with the pages, call pfnPhysBulkReleasePageMappingLocks()
4082 * ASAP to release them.
4083 *
4084 * This API will assume your intention is to write to the pages, and will
4085 * therefore replace shared and zero pages. If you do not intend to modify the
4086 * pages, use the pfnPhysBulkGCPhys2CCPtrReadOnly() API.
4087 *
4088 * @returns VBox status code.
4089 * @retval VINF_SUCCESS on success.
4090 * @retval VERR_PGM_PHYS_PAGE_RESERVED if any of the pages has no physical
4091 * backing or if any of the pages the page has any active access
4092 * handlers. The caller must fall back on using PGMR3PhysWriteExternal.
4093 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if @a paGCPhysPages contains
4094 * an invalid physical address.
4095 *
4096 * @param pDevIns The device instance.
4097 * @param cPages Number of pages to lock.
4098 * @param paGCPhysPages The guest physical address of the pages that
4099 * should be mapped (@a cPages entries).
4100 * @param fFlags Flags reserved for future use, MBZ.
4101 * @param papvPages Where to store the ring-3 mapping addresses
4102 * corresponding to @a paGCPhysPages.
4103 * @param paLocks Where to store the locking information that
4104 * pfnPhysBulkReleasePageMappingLock needs (@a cPages
4105 * in length).
4106 *
4107 * @remark Avoid calling this API from within critical sections (other than the
4108 * PGM one) because of the deadlock risk when we have to delegating the
4109 * task to an EMT.
4110 * @thread Any.
4111 * @since 6.0.6
4112 */
4113 DECLR3CALLBACKMEMBER(int, pfnPhysBulkGCPhys2CCPtr,(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
4114 uint32_t fFlags, void **papvPages, PPGMPAGEMAPLOCK paLocks));
4115
4116 /**
4117 * Requests the mapping of multiple guest page into ring-3, for reading only.
4118 *
4119 * When you're done with the pages, call pfnPhysBulkReleasePageMappingLocks()
4120 * ASAP to release them.
4121 *
4122 * @returns VBox status code.
4123 * @retval VINF_SUCCESS on success.
4124 * @retval VERR_PGM_PHYS_PAGE_RESERVED if any of the pages has no physical
4125 * backing or if any of the pages the page has an active ALL access
4126 * handler. The caller must fall back on using PGMR3PhysWriteExternal.
4127 * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if @a paGCPhysPages contains
4128 * an invalid physical address.
4129 *
4130 * @param pDevIns The device instance.
4131 * @param cPages Number of pages to lock.
4132 * @param paGCPhysPages The guest physical address of the pages that
4133 * should be mapped (@a cPages entries).
4134 * @param fFlags Flags reserved for future use, MBZ.
4135 * @param papvPages Where to store the ring-3 mapping addresses
4136 * corresponding to @a paGCPhysPages.
4137 * @param paLocks Where to store the lock information that
4138 * pfnPhysReleasePageMappingLock needs (@a cPages
4139 * in length).
4140 *
4141 * @remark Avoid calling this API from within critical sections.
4142 * @thread Any.
4143 * @since 6.0.6
4144 */
4145 DECLR3CALLBACKMEMBER(int, pfnPhysBulkGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
4146 uint32_t fFlags, void const **papvPages, PPGMPAGEMAPLOCK paLocks));
4147
4148 /**
4149 * Release the mappings of multiple guest pages.
4150 *
4151 * This is the counter part of pfnPhysBulkGCPhys2CCPtr and
4152 * pfnPhysBulkGCPhys2CCPtrReadOnly.
4153 *
4154 * @param pDevIns The device instance.
4155 * @param cPages Number of pages to unlock.
4156 * @param paLocks The lock structures initialized by the mapping
4157 * function (@a cPages in length).
4158 * @thread Any.
4159 * @since 6.0.6
4160 */
4161 DECLR3CALLBACKMEMBER(void, pfnPhysBulkReleasePageMappingLocks,(PPDMDEVINS pDevIns, uint32_t cPages, PPGMPAGEMAPLOCK paLocks));
4162
4163 /**
4164 * Changes the number of an MMIO2 or pre-registered MMIO region.
4165 *
4166 * This should only be used to deal with saved state problems, so there is no
4167 * convenience inline wrapper for this method.
4168 *
4169 * @returns VBox status code.
4170 * @param pDevIns The device instance.
4171 * @param pPciDev The PCI device the region is associated with, or
4172 * NULL if not associated with any.
4173 * @param iRegion The region.
4174 * @param iNewRegion The new region index.
4175 *
4176 * @sa @bugref{9359}
4177 */
4178 DECLR3CALLBACKMEMBER(int, pfnMMIOExChangeRegionNo,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion,
4179 uint32_t iNewRegion));
4180
4181 /** Space reserved for future members.
4182 * @{ */
4183 DECLR3CALLBACKMEMBER(void, pfnReserved1,(void));
4184 DECLR3CALLBACKMEMBER(void, pfnReserved2,(void));
4185 DECLR3CALLBACKMEMBER(void, pfnReserved3,(void));
4186 DECLR3CALLBACKMEMBER(void, pfnReserved4,(void));
4187 DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
4188 DECLR3CALLBACKMEMBER(void, pfnReserved6,(void));
4189 DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
4190 DECLR3CALLBACKMEMBER(void, pfnReserved8,(void));
4191 DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));
4192 DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));
4193 /** @} */
4194
4195
4196 /** API available to trusted devices only.
4197 *
4198 * These APIs are providing unrestricted access to the guest and the VM,
4199 * or they are interacting intimately with PDM.
4200 *
4201 * @{
4202 */
4203
4204 /**
4205 * Gets the user mode VM handle. Restricted API.
4206 *
4207 * @returns User mode VM Handle.
4208 * @param pDevIns The device instance.
4209 */
4210 DECLR3CALLBACKMEMBER(PUVM, pfnGetUVM,(PPDMDEVINS pDevIns));
4211
4212 /**
4213 * Gets the global VM handle. Restricted API.
4214 *
4215 * @returns VM Handle.
4216 * @param pDevIns The device instance.
4217 */
4218 DECLR3CALLBACKMEMBER(PVMCC, pfnGetVM,(PPDMDEVINS pDevIns));
4219
4220 /**
4221 * Gets the VMCPU handle. Restricted API.
4222 *
4223 * @returns VMCPU Handle.
4224 * @param pDevIns The device instance.
4225 */
4226 DECLR3CALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
4227
4228 /**
4229 * The the VM CPU ID of the current thread (restricted API).
4230 *
4231 * @returns The VMCPUID of the calling thread, NIL_VMCPUID if not EMT.
4232 * @param pDevIns The device instance.
4233 */
4234 DECLR3CALLBACKMEMBER(VMCPUID, pfnGetCurrentCpuId,(PPDMDEVINS pDevIns));
4235
4236 /**
4237 * Registers the VMM device heap or notifies about mapping/unmapping.
4238 *
4239 * This interface serves three purposes:
4240 *
4241 * -# Register the VMM device heap during device construction
4242 * for the HM to use.
4243 * -# Notify PDM/HM that it's mapped into guest address
4244 * space (i.e. usable).
4245 * -# Notify PDM/HM that it is being unmapped from the guest
4246 * address space (i.e. not usable).
4247 *
4248 * @returns VBox status code.
4249 * @param pDevIns The device instance.
4250 * @param GCPhys The physical address if mapped, NIL_RTGCPHYS if
4251 * not mapped.
4252 * @param pvHeap Ring 3 heap pointer.
4253 * @param cbHeap Size of the heap.
4254 * @thread EMT.
4255 */
4256 DECLR3CALLBACKMEMBER(int, pfnRegisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbHeap));
4257
4258 /**
4259 * Registers the firmware (BIOS, EFI) device with PDM.
4260 *
4261 * The firmware provides a callback table and gets a special PDM helper table.
4262 * There can only be one firmware device for a VM.
4263 *
4264 * @returns VBox status code.
4265 * @param pDevIns The device instance.
4266 * @param pFwReg Firmware registration structure.
4267 * @param ppFwHlp Where to return the firmware helper structure.
4268 * @remarks Only valid during device construction.
4269 * @thread EMT(0)
4270 */
4271 DECLR3CALLBACKMEMBER(int, pfnFirmwareRegister,(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp));
4272
4273 /**
4274 * Resets the VM.
4275 *
4276 * @returns The appropriate VBox status code to pass around on reset.
4277 * @param pDevIns The device instance.
4278 * @param fFlags PDMVMRESET_F_XXX flags.
4279 * @thread The emulation thread.
4280 */
4281 DECLR3CALLBACKMEMBER(int, pfnVMReset,(PPDMDEVINS pDevIns, uint32_t fFlags));
4282
4283 /**
4284 * Suspends the VM.
4285 *
4286 * @returns The appropriate VBox status code to pass around on suspend.
4287 * @param pDevIns The device instance.
4288 * @thread The emulation thread.
4289 */
4290 DECLR3CALLBACKMEMBER(int, pfnVMSuspend,(PPDMDEVINS pDevIns));
4291
4292 /**
4293 * Suspends, saves and powers off the VM.
4294 *
4295 * @returns The appropriate VBox status code to pass around.
4296 * @param pDevIns The device instance.
4297 * @thread An emulation thread.
4298 */
4299 DECLR3CALLBACKMEMBER(int, pfnVMSuspendSaveAndPowerOff,(PPDMDEVINS pDevIns));
4300
4301 /**
4302 * Power off the VM.
4303 *
4304 * @returns The appropriate VBox status code to pass around on power off.
4305 * @param pDevIns The device instance.
4306 * @thread The emulation thread.
4307 */
4308 DECLR3CALLBACKMEMBER(int, pfnVMPowerOff,(PPDMDEVINS pDevIns));
4309
4310 /**
4311 * Checks if the Gate A20 is enabled or not.
4312 *
4313 * @returns true if A20 is enabled.
4314 * @returns false if A20 is disabled.
4315 * @param pDevIns The device instance.
4316 * @thread The emulation thread.
4317 */
4318 DECLR3CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
4319
4320 /**
4321 * Enables or disables the Gate A20.
4322 *
4323 * @param pDevIns The device instance.
4324 * @param fEnable Set this flag to enable the Gate A20; clear it
4325 * to disable.
4326 * @thread The emulation thread.
4327 */
4328 DECLR3CALLBACKMEMBER(void, pfnA20Set,(PPDMDEVINS pDevIns, bool fEnable));
4329
4330 /**
4331 * Get the specified CPUID leaf for the virtual CPU associated with the calling
4332 * thread.
4333 *
4334 * @param pDevIns The device instance.
4335 * @param iLeaf The CPUID leaf to get.
4336 * @param pEax Where to store the EAX value.
4337 * @param pEbx Where to store the EBX value.
4338 * @param pEcx Where to store the ECX value.
4339 * @param pEdx Where to store the EDX value.
4340 * @thread EMT.
4341 */
4342 DECLR3CALLBACKMEMBER(void, pfnGetCpuId,(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx));
4343
4344 /**
4345 * Get the current virtual clock time in a VM. The clock frequency must be
4346 * queried separately.
4347 *
4348 * @returns Current clock time.
4349 * @param pDevIns The device instance.
4350 */
4351 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
4352
4353 /**
4354 * Get the frequency of the virtual clock.
4355 *
4356 * @returns The clock frequency (not variable at run-time).
4357 * @param pDevIns The device instance.
4358 */
4359 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
4360
4361 /**
4362 * Get the current virtual clock time in a VM, in nanoseconds.
4363 *
4364 * @returns Current clock time (in ns).
4365 * @param pDevIns The device instance.
4366 */
4367 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
4368
4369 /**
4370 * Gets the support driver session.
4371 *
4372 * This is intended for working with the semaphore API.
4373 *
4374 * @returns Support driver session handle.
4375 * @param pDevIns The device instance.
4376 */
4377 DECLR3CALLBACKMEMBER(PSUPDRVSESSION, pfnGetSupDrvSession,(PPDMDEVINS pDevIns));
4378
4379 /**
4380 * Queries a generic object from the VMM user.
4381 *
4382 * @returns Pointer to the object if found, NULL if not.
4383 * @param pDevIns The device instance.
4384 * @param pUuid The UUID of what's being queried. The UUIDs and
4385 * the usage conventions are defined by the user.
4386 *
4387 * @note It is strictly forbidden to call this internally in VBox! This
4388 * interface is exclusively for hacks in externally developed devices.
4389 */
4390 DECLR3CALLBACKMEMBER(void *, pfnQueryGenericUserObject,(PPDMDEVINS pDevIns, PCRTUUID pUuid));
4391
4392 /** @} */
4393
4394 /** Just a safety precaution. (PDM_DEVHLPR3_VERSION) */
4395 uint32_t u32TheEnd;
4396} PDMDEVHLPR3;
4397#endif /* !IN_RING3 */
4398/** Pointer to the R3 PDM Device API. */
4399typedef R3PTRTYPE(struct PDMDEVHLPR3 *) PPDMDEVHLPR3;
4400/** Pointer to the R3 PDM Device API, const variant. */
4401typedef R3PTRTYPE(const struct PDMDEVHLPR3 *) PCPDMDEVHLPR3;
4402
4403
4404/**
4405 * PDM Device API - RC Variant.
4406 */
4407typedef struct PDMDEVHLPRC
4408{
4409 /** Structure version. PDM_DEVHLPRC_VERSION defines the current version. */
4410 uint32_t u32Version;
4411
4412 /**
4413 * Sets up raw-mode context callback handlers for an I/O port range.
4414 *
4415 * The range must have been registered in ring-3 first using
4416 * PDMDevHlpIoPortCreate() or PDMDevHlpIoPortCreateEx().
4417 *
4418 * @returns VBox status.
4419 * @param pDevIns The device instance to register the ports with.
4420 * @param hIoPorts The I/O port range handle.
4421 * @param pfnOut Pointer to function which is gonna handle OUT
4422 * operations. Optional.
4423 * @param pfnIn Pointer to function which is gonna handle IN operations.
4424 * Optional.
4425 * @param pfnOutStr Pointer to function which is gonna handle string OUT
4426 * operations. Optional.
4427 * @param pfnInStr Pointer to function which is gonna handle string IN
4428 * operations. Optional.
4429 * @param pvUser User argument to pass to the callbacks.
4430 *
4431 * @remarks Caller enters the device critical section prior to invoking the
4432 * registered callback methods.
4433 *
4434 * @sa PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx, PDMDevHlpIoPortMap,
4435 * PDMDevHlpIoPortUnmap.
4436 */
4437 DECLRCCALLBACKMEMBER(int, pfnIoPortSetUpContextEx,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
4438 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
4439 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr,
4440 void *pvUser));
4441
4442 /**
4443 * Sets up raw-mode context callback handlers for an MMIO region.
4444 *
4445 * The region must have been registered in ring-3 first using
4446 * PDMDevHlpMmioCreate() or PDMDevHlpMmioCreateEx().
4447 *
4448 * @returns VBox status.
4449 * @param pDevIns The device instance to register the ports with.
4450 * @param hRegion The MMIO region handle.
4451 * @param pfnWrite Pointer to function which is gonna handle Write
4452 * operations.
4453 * @param pfnRead Pointer to function which is gonna handle Read
4454 * operations.
4455 * @param pfnFill Pointer to function which is gonna handle Fill/memset
4456 * operations. (optional)
4457 * @param pvUser User argument to pass to the callbacks.
4458 *
4459 * @remarks Caller enters the device critical section prior to invoking the
4460 * registered callback methods.
4461 *
4462 * @sa PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx, PDMDevHlpMmioMap,
4463 * PDMDevHlpMmioUnmap.
4464 */
4465 DECLRCCALLBACKMEMBER(int, pfnMmioSetUpContextEx,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIONEWWRITE pfnWrite,
4466 PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill, void *pvUser));
4467
4468 /**
4469 * Bus master physical memory read from the given PCI device.
4470 *
4471 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
4472 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
4473 * @param pDevIns The device instance.
4474 * @param pPciDev The PCI device structure. If NULL the default
4475 * PCI device for this device instance is used.
4476 * @param GCPhys Physical address start reading from.
4477 * @param pvBuf Where to put the read bits.
4478 * @param cbRead How many bytes to read.
4479 * @thread Any thread, but the call may involve the emulation thread.
4480 */
4481 DECLRCCALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
4482 void *pvBuf, size_t cbRead));
4483
4484 /**
4485 * Bus master physical memory write from the given PCI device.
4486 *
4487 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
4488 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
4489 * @param pDevIns The device instance.
4490 * @param pPciDev The PCI device structure. If NULL the default
4491 * PCI device for this device instance is used.
4492 * @param GCPhys Physical address to write to.
4493 * @param pvBuf What to write.
4494 * @param cbWrite How many bytes to write.
4495 * @thread Any thread, but the call may involve the emulation thread.
4496 */
4497 DECLRCCALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
4498 const void *pvBuf, size_t cbWrite));
4499
4500 /**
4501 * Set the IRQ for the given PCI device.
4502 *
4503 * @param pDevIns Device instance.
4504 * @param pPciDev The PCI device structure. If NULL the default
4505 * PCI device for this device instance is used.
4506 * @param iIrq IRQ number to set.
4507 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
4508 * @thread Any thread, but will involve the emulation thread.
4509 */
4510 DECLRCCALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
4511
4512 /**
4513 * Set ISA IRQ for a device.
4514 *
4515 * @param pDevIns Device instance.
4516 * @param iIrq IRQ number to set.
4517 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
4518 * @thread Any thread, but will involve the emulation thread.
4519 */
4520 DECLRCCALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
4521
4522 /**
4523 * Send an MSI straight to the I/O APIC.
4524 *
4525 * @param pDevIns PCI device instance.
4526 * @param GCPhys Physical address MSI request was written.
4527 * @param uValue Value written.
4528 * @thread Any thread, but will involve the emulation thread.
4529 */
4530 DECLRCCALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue));
4531
4532 /**
4533 * Read physical memory.
4534 *
4535 * @returns VINF_SUCCESS (for now).
4536 * @param pDevIns Device instance.
4537 * @param GCPhys Physical address start reading from.
4538 * @param pvBuf Where to put the read bits.
4539 * @param cbRead How many bytes to read.
4540 */
4541 DECLRCCALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
4542
4543 /**
4544 * Write to physical memory.
4545 *
4546 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
4547 * @param pDevIns Device instance.
4548 * @param GCPhys Physical address to write to.
4549 * @param pvBuf What to write.
4550 * @param cbWrite How many bytes to write.
4551 */
4552 DECLRCCALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
4553
4554 /**
4555 * Checks if the Gate A20 is enabled or not.
4556 *
4557 * @returns true if A20 is enabled.
4558 * @returns false if A20 is disabled.
4559 * @param pDevIns Device instance.
4560 * @thread The emulation thread.
4561 */
4562 DECLRCCALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
4563
4564 /**
4565 * Gets the VM state.
4566 *
4567 * @returns VM state.
4568 * @param pDevIns The device instance.
4569 * @thread Any thread (just keep in mind that it's volatile info).
4570 */
4571 DECLRCCALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
4572
4573 /**
4574 * Set the VM error message
4575 *
4576 * @returns rc.
4577 * @param pDevIns Driver instance.
4578 * @param rc VBox status code.
4579 * @param SRC_POS Use RT_SRC_POS.
4580 * @param pszFormat Error message format string.
4581 * @param ... Error message arguments.
4582 */
4583 DECLRCCALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
4584 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(6, 7));
4585
4586 /**
4587 * Set the VM error message
4588 *
4589 * @returns rc.
4590 * @param pDevIns Driver instance.
4591 * @param rc VBox status code.
4592 * @param SRC_POS Use RT_SRC_POS.
4593 * @param pszFormat Error message format string.
4594 * @param va Error message arguments.
4595 */
4596 DECLRCCALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
4597 const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
4598
4599 /**
4600 * Set the VM runtime error message
4601 *
4602 * @returns VBox status code.
4603 * @param pDevIns Device instance.
4604 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
4605 * @param pszErrorId Error ID string.
4606 * @param pszFormat Error message format string.
4607 * @param ... Error message arguments.
4608 */
4609 DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
4610 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5));
4611
4612 /**
4613 * Set the VM runtime error message
4614 *
4615 * @returns VBox status code.
4616 * @param pDevIns Device instance.
4617 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
4618 * @param pszErrorId Error ID string.
4619 * @param pszFormat Error message format string.
4620 * @param va Error message arguments.
4621 */
4622 DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
4623 const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(4, 0));
4624
4625 /**
4626 * Gets the VM handle. Restricted API.
4627 *
4628 * @returns VM Handle.
4629 * @param pDevIns Device instance.
4630 */
4631 DECLRCCALLBACKMEMBER(PVMCC, pfnGetVM,(PPDMDEVINS pDevIns));
4632
4633 /**
4634 * Gets the VMCPU handle. Restricted API.
4635 *
4636 * @returns VMCPU Handle.
4637 * @param pDevIns The device instance.
4638 */
4639 DECLRCCALLBACKMEMBER(PVMCPUCC, pfnGetVMCPU,(PPDMDEVINS pDevIns));
4640
4641 /**
4642 * The the VM CPU ID of the current thread (restricted API).
4643 *
4644 * @returns The VMCPUID of the calling thread, NIL_VMCPUID if not EMT.
4645 * @param pDevIns The device instance.
4646 */
4647 DECLRCCALLBACKMEMBER(VMCPUID, pfnGetCurrentCpuId,(PPDMDEVINS pDevIns));
4648
4649 /**
4650 * Get the current virtual clock time in a VM. The clock frequency must be
4651 * queried separately.
4652 *
4653 * @returns Current clock time.
4654 * @param pDevIns The device instance.
4655 */
4656 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
4657
4658 /**
4659 * Get the frequency of the virtual clock.
4660 *
4661 * @returns The clock frequency (not variable at run-time).
4662 * @param pDevIns The device instance.
4663 */
4664 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
4665
4666 /**
4667 * Get the current virtual clock time in a VM, in nanoseconds.
4668 *
4669 * @returns Current clock time (in ns).
4670 * @param pDevIns The device instance.
4671 */
4672 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
4673
4674 /**
4675 * Gets the NOP critical section.
4676 *
4677 * @returns The ring-3 address of the NOP critical section.
4678 * @param pDevIns The device instance.
4679 */
4680 DECLRCCALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
4681
4682 /**
4683 * Changes the device level critical section from the automatically created
4684 * default to one desired by the device constructor.
4685 *
4686 * Must first be done in ring-3.
4687 *
4688 * @returns VBox status code.
4689 * @param pDevIns The device instance.
4690 * @param pCritSect The critical section to use. NULL is not
4691 * valid, instead use the NOP critical
4692 * section.
4693 */
4694 DECLRCCALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
4695
4696 /** @name Exported PDM Critical Section Functions
4697 * @{ */
4698 DECLRCCALLBACKMEMBER(int, pfnCritSectEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy));
4699 DECLRCCALLBACKMEMBER(int, pfnCritSectEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
4700 DECLRCCALLBACKMEMBER(int, pfnCritSectTryEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
4701 DECLRCCALLBACKMEMBER(int, pfnCritSectTryEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
4702 DECLRCCALLBACKMEMBER(int, pfnCritSectLeave,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
4703 DECLRCCALLBACKMEMBER(bool, pfnCritSectIsOwner,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
4704 DECLRCCALLBACKMEMBER(bool, pfnCritSectIsInitialized,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
4705 DECLRCCALLBACKMEMBER(bool, pfnCritSectHasWaiters,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
4706 DECLRCCALLBACKMEMBER(uint32_t, pfnCritSectGetRecursion,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
4707 /** @} */
4708
4709 /**
4710 * Gets the trace buffer handle.
4711 *
4712 * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
4713 * really inteded for direct usage, thus no inline wrapper function.
4714 *
4715 * @returns Trace buffer handle or NIL_RTTRACEBUF.
4716 * @param pDevIns The device instance.
4717 */
4718 DECLRCCALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
4719
4720 /**
4721 * Sets up the PCI bus for the raw-mode context.
4722 *
4723 * This must be called after ring-3 has registered the PCI bus using
4724 * PDMDevHlpPCIBusRegister().
4725 *
4726 * @returns VBox status code.
4727 * @param pDevIns The device instance.
4728 * @param pPciBusReg The PCI bus registration information for raw-mode,
4729 * considered volatile.
4730 * @param ppPciHlp Where to return the raw-mode PCI bus helpers.
4731 */
4732 DECLRCCALLBACKMEMBER(int, pfnPCIBusSetUpContext,(PPDMDEVINS pDevIns, PPDMPCIBUSREGRC pPciBusReg, PCPDMPCIHLPRC *ppPciHlp));
4733
4734 /** Space reserved for future members.
4735 * @{ */
4736 DECLRCCALLBACKMEMBER(void, pfnReserved1,(void));
4737 DECLRCCALLBACKMEMBER(void, pfnReserved2,(void));
4738 DECLRCCALLBACKMEMBER(void, pfnReserved3,(void));
4739 DECLRCCALLBACKMEMBER(void, pfnReserved4,(void));
4740 DECLRCCALLBACKMEMBER(void, pfnReserved5,(void));
4741 DECLRCCALLBACKMEMBER(void, pfnReserved6,(void));
4742 DECLRCCALLBACKMEMBER(void, pfnReserved7,(void));
4743 DECLRCCALLBACKMEMBER(void, pfnReserved8,(void));
4744 DECLRCCALLBACKMEMBER(void, pfnReserved9,(void));
4745 DECLRCCALLBACKMEMBER(void, pfnReserved10,(void));
4746 /** @} */
4747
4748 /** Just a safety precaution. */
4749 uint32_t u32TheEnd;
4750} PDMDEVHLPRC;
4751/** Pointer PDM Device RC API. */
4752typedef RGPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC;
4753/** Pointer PDM Device RC API. */
4754typedef RGPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC;
4755
4756/** Current PDMDEVHLP version number. */
4757#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 8, 0)
4758
4759
4760/**
4761 * PDM Device API - R0 Variant.
4762 */
4763typedef struct PDMDEVHLPR0
4764{
4765 /** Structure version. PDM_DEVHLPR0_VERSION defines the current version. */
4766 uint32_t u32Version;
4767
4768 /**
4769 * Sets up ring-0 callback handlers for an I/O port range.
4770 *
4771 * The range must have been registered in ring-3 first using
4772 * PDMDevHlpIoPortCreate() or PDMDevHlpIoPortCreateEx().
4773 *
4774 * @returns VBox status.
4775 * @param pDevIns The device instance to register the ports with.
4776 * @param hIoPorts The I/O port range handle.
4777 * @param pfnOut Pointer to function which is gonna handle OUT
4778 * operations. Optional.
4779 * @param pfnIn Pointer to function which is gonna handle IN operations.
4780 * Optional.
4781 * @param pfnOutStr Pointer to function which is gonna handle string OUT
4782 * operations. Optional.
4783 * @param pfnInStr Pointer to function which is gonna handle string IN
4784 * operations. Optional.
4785 * @param pvUser User argument to pass to the callbacks.
4786 *
4787 * @remarks Caller enters the device critical section prior to invoking the
4788 * registered callback methods.
4789 *
4790 * @sa PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx, PDMDevHlpIoPortMap,
4791 * PDMDevHlpIoPortUnmap.
4792 */
4793 DECLR0CALLBACKMEMBER(int, pfnIoPortSetUpContextEx,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
4794 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
4795 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr,
4796 void *pvUser));
4797
4798 /**
4799 * Sets up ring-0 callback handlers for an MMIO region.
4800 *
4801 * The region must have been registered in ring-3 first using
4802 * PDMDevHlpMmioCreate() or PDMDevHlpMmioCreateEx().
4803 *
4804 * @returns VBox status.
4805 * @param pDevIns The device instance to register the ports with.
4806 * @param hRegion The MMIO region handle.
4807 * @param pfnWrite Pointer to function which is gonna handle Write
4808 * operations.
4809 * @param pfnRead Pointer to function which is gonna handle Read
4810 * operations.
4811 * @param pfnFill Pointer to function which is gonna handle Fill/memset
4812 * operations. (optional)
4813 * @param pvUser User argument to pass to the callbacks.
4814 *
4815 * @remarks Caller enters the device critical section prior to invoking the
4816 * registered callback methods.
4817 *
4818 * @sa PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx, PDMDevHlpMmioMap,
4819 * PDMDevHlpMmioUnmap.
4820 */
4821 DECLR0CALLBACKMEMBER(int, pfnMmioSetUpContextEx,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIONEWWRITE pfnWrite,
4822 PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill, void *pvUser));
4823
4824 /**
4825 * Bus master physical memory read from the given PCI device.
4826 *
4827 * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe
4828 * VERR_EM_MEMORY.
4829 * @param pDevIns The device instance.
4830 * @param pPciDev The PCI device structure. If NULL the default
4831 * PCI device for this device instance is used.
4832 * @param GCPhys Physical address start reading from.
4833 * @param pvBuf Where to put the read bits.
4834 * @param cbRead How many bytes to read.
4835 * @thread Any thread, but the call may involve the emulation thread.
4836 */
4837 DECLR0CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
4838 void *pvBuf, size_t cbRead));
4839
4840 /**
4841 * Bus master physical memory write from the given PCI device.
4842 *
4843 * @returns VINF_SUCCESS or VERR_PDM_NOT_PCI_BUS_MASTER, later maybe
4844 * VERR_EM_MEMORY.
4845 * @param pDevIns The device instance.
4846 * @param pPciDev The PCI device structure. If NULL the default
4847 * PCI device for this device instance is used.
4848 * @param GCPhys Physical address to write to.
4849 * @param pvBuf What to write.
4850 * @param cbWrite How many bytes to write.
4851 * @thread Any thread, but the call may involve the emulation thread.
4852 */
4853 DECLR0CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys,
4854 const void *pvBuf, size_t cbWrite));
4855
4856 /**
4857 * Set the IRQ for the given PCI device.
4858 *
4859 * @param pDevIns Device instance.
4860 * @param pPciDev The PCI device structure. If NULL the default
4861 * PCI device for this device instance is used.
4862 * @param iIrq IRQ number to set.
4863 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
4864 * @thread Any thread, but will involve the emulation thread.
4865 */
4866 DECLR0CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel));
4867
4868 /**
4869 * Set ISA IRQ for a device.
4870 *
4871 * @param pDevIns Device instance.
4872 * @param iIrq IRQ number to set.
4873 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
4874 * @thread Any thread, but will involve the emulation thread.
4875 */
4876 DECLR0CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
4877
4878 /**
4879 * Send an MSI straight to the I/O APIC.
4880 *
4881 * @param pDevIns PCI device instance.
4882 * @param GCPhys Physical address MSI request was written.
4883 * @param uValue Value written.
4884 * @thread Any thread, but will involve the emulation thread.
4885 */
4886 DECLR0CALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue));
4887
4888 /**
4889 * Read physical memory.
4890 *
4891 * @returns VINF_SUCCESS (for now).
4892 * @param pDevIns Device instance.
4893 * @param GCPhys Physical address start reading from.
4894 * @param pvBuf Where to put the read bits.
4895 * @param cbRead How many bytes to read.
4896 */
4897 DECLR0CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
4898
4899 /**
4900 * Write to physical memory.
4901 *
4902 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
4903 * @param pDevIns Device instance.
4904 * @param GCPhys Physical address to write to.
4905 * @param pvBuf What to write.
4906 * @param cbWrite How many bytes to write.
4907 */
4908 DECLR0CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
4909
4910 /**
4911 * Checks if the Gate A20 is enabled or not.
4912 *
4913 * @returns true if A20 is enabled.
4914 * @returns false if A20 is disabled.
4915 * @param pDevIns Device instance.
4916 * @thread The emulation thread.
4917 */
4918 DECLR0CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
4919
4920 /**
4921 * Gets the VM state.
4922 *
4923 * @returns VM state.
4924 * @param pDevIns The device instance.
4925 * @thread Any thread (just keep in mind that it's volatile info).
4926 */
4927 DECLR0CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
4928
4929 /**
4930 * Set the VM error message
4931 *
4932 * @returns rc.
4933 * @param pDevIns Driver instance.
4934 * @param rc VBox status code.
4935 * @param SRC_POS Use RT_SRC_POS.
4936 * @param pszFormat Error message format string.
4937 * @param ... Error message arguments.
4938 */
4939 DECLR0CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
4940 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(6, 7));
4941
4942 /**
4943 * Set the VM error message
4944 *
4945 * @returns rc.
4946 * @param pDevIns Driver instance.
4947 * @param rc VBox status code.
4948 * @param SRC_POS Use RT_SRC_POS.
4949 * @param pszFormat Error message format string.
4950 * @param va Error message arguments.
4951 */
4952 DECLR0CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL,
4953 const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
4954
4955 /**
4956 * Set the VM runtime error message
4957 *
4958 * @returns VBox status code.
4959 * @param pDevIns Device instance.
4960 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
4961 * @param pszErrorId Error ID string.
4962 * @param pszFormat Error message format string.
4963 * @param ... Error message arguments.
4964 */
4965 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
4966 const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(4, 5));
4967
4968 /**
4969 * Set the VM runtime error message
4970 *
4971 * @returns VBox status code.
4972 * @param pDevIns Device instance.
4973 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
4974 * @param pszErrorId Error ID string.
4975 * @param pszFormat Error message format string.
4976 * @param va Error message arguments.
4977 */
4978 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
4979 const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(4, 0));
4980
4981 /**
4982 * Gets the VM handle. Restricted API.
4983 *
4984 * @returns VM Handle.
4985 * @param pDevIns Device instance.
4986 */
4987 DECLR0CALLBACKMEMBER(PVMCC, pfnGetVM,(PPDMDEVINS pDevIns));
4988
4989 /**
4990 * Gets the VMCPU handle. Restricted API.
4991 *
4992 * @returns VMCPU Handle.
4993 * @param pDevIns The device instance.
4994 */
4995 DECLR0CALLBACKMEMBER(PVMCPUCC, pfnGetVMCPU,(PPDMDEVINS pDevIns));
4996
4997 /**
4998 * The the VM CPU ID of the current thread (restricted API).
4999 *
5000 * @returns The VMCPUID of the calling thread, NIL_VMCPUID if not EMT.
5001 * @param pDevIns The device instance.
5002 */
5003 DECLR0CALLBACKMEMBER(VMCPUID, pfnGetCurrentCpuId,(PPDMDEVINS pDevIns));
5004
5005 /**
5006 * Translates a timer handle to a pointer.
5007 *
5008 * @returns The time address.
5009 * @param pDevIns The device instance.
5010 * @param hTimer The timer handle.
5011 */
5012 DECLR0CALLBACKMEMBER(PTMTIMERR0, pfnTimerToPtr,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5013
5014 /** @name Timer handle method wrappers
5015 * @{ */
5016 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerFromMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs));
5017 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerFromMilli,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs));
5018 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerFromNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs));
5019 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerGet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5020 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerGetFreq,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5021 DECLR0CALLBACKMEMBER(uint64_t, pfnTimerGetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5022 DECLR0CALLBACKMEMBER(bool, pfnTimerIsActive,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5023 DECLR0CALLBACKMEMBER(bool, pfnTimerIsLockOwner,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5024 DECLR0CALLBACKMEMBER(int, pfnTimerLock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy));
5025 DECLR0CALLBACKMEMBER(int, pfnTimerSet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire));
5026 DECLR0CALLBACKMEMBER(int, pfnTimerSetFrequencyHint,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz));
5027 DECLR0CALLBACKMEMBER(int, pfnTimerSetMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext));
5028 DECLR0CALLBACKMEMBER(int, pfnTimerSetMillies,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext));
5029 DECLR0CALLBACKMEMBER(int, pfnTimerSetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext));
5030 DECLR0CALLBACKMEMBER(int, pfnTimerSetRelative,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now));
5031 DECLR0CALLBACKMEMBER(int, pfnTimerStop,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5032 DECLR0CALLBACKMEMBER(void, pfnTimerUnlock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
5033 /** @} */
5034
5035 /**
5036 * Get the current virtual clock time in a VM. The clock frequency must be
5037 * queried separately.
5038 *
5039 * @returns Current clock time.
5040 * @param pDevIns The device instance.
5041 */
5042 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
5043
5044 /**
5045 * Get the frequency of the virtual clock.
5046 *
5047 * @returns The clock frequency (not variable at run-time).
5048 * @param pDevIns The device instance.
5049 */
5050 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
5051
5052 /**
5053 * Get the current virtual clock time in a VM, in nanoseconds.
5054 *
5055 * @returns Current clock time (in ns).
5056 * @param pDevIns The device instance.
5057 */
5058 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
5059
5060 /**
5061 * Gets the NOP critical section.
5062 *
5063 * @returns The ring-3 address of the NOP critical section.
5064 * @param pDevIns The device instance.
5065 */
5066 DECLR0CALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
5067
5068 /**
5069 * Changes the device level critical section from the automatically created
5070 * default to one desired by the device constructor.
5071 *
5072 * Must first be done in ring-3.
5073 *
5074 * @returns VBox status code.
5075 * @param pDevIns The device instance.
5076 * @param pCritSect The critical section to use. NULL is not
5077 * valid, instead use the NOP critical
5078 * section.
5079 */
5080 DECLR0CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
5081
5082 /** @name Exported PDM Critical Section Functions
5083 * @{ */
5084 DECLR0CALLBACKMEMBER(int, pfnCritSectEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy));
5085 DECLR0CALLBACKMEMBER(int, pfnCritSectEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5086 DECLR0CALLBACKMEMBER(int, pfnCritSectTryEnter,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
5087 DECLR0CALLBACKMEMBER(int, pfnCritSectTryEnterDebug,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
5088 DECLR0CALLBACKMEMBER(int, pfnCritSectLeave,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
5089 DECLR0CALLBACKMEMBER(bool, pfnCritSectIsOwner,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5090 DECLR0CALLBACKMEMBER(bool, pfnCritSectIsInitialized,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5091 DECLR0CALLBACKMEMBER(bool, pfnCritSectHasWaiters,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5092 DECLR0CALLBACKMEMBER(uint32_t, pfnCritSectGetRecursion,(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect));
5093 /** @} */
5094
5095 /**
5096 * Gets the trace buffer handle.
5097 *
5098 * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
5099 * really inteded for direct usage, thus no inline wrapper function.
5100 *
5101 * @returns Trace buffer handle or NIL_RTTRACEBUF.
5102 * @param pDevIns The device instance.
5103 */
5104 DECLR0CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
5105
5106 /**
5107 * Sets up the PCI bus for the ring-0 context.
5108 *
5109 * This must be called after ring-3 has registered the PCI bus using
5110 * PDMDevHlpPCIBusRegister().
5111 *
5112 * @returns VBox status code.
5113 * @param pDevIns The device instance.
5114 * @param pPciBusReg The PCI bus registration information for ring-0,
5115 * considered volatile.
5116 * @param ppPciHlp Where to return the ring-0 PCI bus helpers.
5117 */
5118 DECLR0CALLBACKMEMBER(int, pfnPCIBusSetUpContext,(PPDMDEVINS pDevIns, PPDMPCIBUSREGR0 pPciBusReg, PCPDMPCIHLPR0 *ppPciHlp));
5119
5120 /** Space reserved for future members.
5121 * @{ */
5122 DECLR0CALLBACKMEMBER(void, pfnReserved1,(void));
5123 DECLR0CALLBACKMEMBER(void, pfnReserved2,(void));
5124 DECLR0CALLBACKMEMBER(void, pfnReserved3,(void));
5125 DECLR0CALLBACKMEMBER(void, pfnReserved4,(void));
5126 DECLR0CALLBACKMEMBER(void, pfnReserved5,(void));
5127 DECLR0CALLBACKMEMBER(void, pfnReserved6,(void));
5128 DECLR0CALLBACKMEMBER(void, pfnReserved7,(void));
5129 DECLR0CALLBACKMEMBER(void, pfnReserved8,(void));
5130 DECLR0CALLBACKMEMBER(void, pfnReserved9,(void));
5131 DECLR0CALLBACKMEMBER(void, pfnReserved10,(void));
5132 /** @} */
5133
5134 /** Just a safety precaution. */
5135 uint32_t u32TheEnd;
5136} PDMDEVHLPR0;
5137/** Pointer PDM Device R0 API. */
5138typedef R0PTRTYPE(struct PDMDEVHLPR0 *) PPDMDEVHLPR0;
5139/** Pointer PDM Device GC API. */
5140typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0;
5141
5142/** Current PDMDEVHLP version number. */
5143#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 9, 0)
5144
5145
5146/**
5147 * PDM Device Instance.
5148 */
5149typedef struct PDMDEVINSR3
5150{
5151 /** Structure version. PDM_DEVINSR3_VERSION defines the current version. */
5152 uint32_t u32Version;
5153 /** Device instance number. */
5154 uint32_t iInstance;
5155 /** Size of the ring-3, raw-mode and shared bits. */
5156 uint32_t cbRing3;
5157 /** Set if ring-0 context is enabled. */
5158 bool fR0Enabled;
5159 /** Set if raw-mode context is enabled. */
5160 bool fRCEnabled;
5161 /** Alignment padding. */
5162 bool afReserved[2];
5163 /** Pointer the HC PDM Device API. */
5164 PCPDMDEVHLPR3 pHlpR3;
5165 /** Pointer to the shared device instance data. */
5166 RTR3PTR pvInstanceDataR3;
5167 /** Pointer to the device instance data for ring-3. */
5168 RTR3PTR pvInstanceDataForR3;
5169 /** The critical section for the device.
5170 *
5171 * TM and IOM will enter this critical section before calling into the device
5172 * code. PDM will when doing power on, power off, reset, suspend and resume
5173 * notifications. SSM will currently not, but this will be changed later on.
5174 *
5175 * The device gets a critical section automatically assigned to it before
5176 * the constructor is called. If the constructor wishes to use a different
5177 * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
5178 * very early on.
5179 */
5180 R3PTRTYPE(PPDMCRITSECT) pCritSectRoR3;
5181 /** Pointer to device registration structure. */
5182 R3PTRTYPE(PCPDMDEVREG) pReg;
5183 /** Configuration handle. */
5184 R3PTRTYPE(PCFGMNODE) pCfg;
5185 /** The base interface of the device.
5186 *
5187 * The device constructor initializes this if it has any
5188 * device level interfaces to export. To obtain this interface
5189 * call PDMR3QueryDevice(). */
5190 PDMIBASE IBase;
5191
5192 /** Tracing indicator. */
5193 uint32_t fTracing;
5194 /** The tracing ID of this device. */
5195 uint32_t idTracing;
5196
5197 /** Ring-3 pointer to the raw-mode device instance. */
5198 R3PTRTYPE(struct PDMDEVINSRC *) pDevInsForRCR3;
5199 /** Raw-mode address of the raw-mode device instance. */
5200 RTRGPTR pDevInsForRC;
5201 /** Ring-3 pointer to the raw-mode instance data. */
5202 RTR3PTR pvInstanceDataForRCR3;
5203
5204 /** PCI device structure size. */
5205 uint32_t cbPciDev;
5206 /** Number of PCI devices in apPciDevs. */
5207 uint32_t cPciDevs;
5208 /** Pointer to the PCI devices for this device.
5209 * (Allocated after the shared instance data.)
5210 * @note If we want to extend this beyond 8 sub-functions/devices, those 1 or
5211 * two devices ever needing it can use cbPciDev and do the address
5212 * calculations that for entries 8+. */
5213 R3PTRTYPE(struct PDMPCIDEV *) apPciDevs[8];
5214
5215 /** Temporarily. */
5216 R0PTRTYPE(struct PDMDEVINSR0 *) pDevInsR0RemoveMe;
5217 /** Temporarily. */
5218 RTR0PTR pvInstanceDataR0;
5219 /** Temporarily. */
5220 RTRCPTR pvInstanceDataRC;
5221 /** Align the internal data more naturally. */
5222 uint32_t au32Padding[HC_ARCH_BITS == 32 ? 13 : 11];
5223
5224 /** Internal data. */
5225 union
5226 {
5227#ifdef PDMDEVINSINT_DECLARED
5228 PDMDEVINSINTR3 s;
5229#endif
5230 uint8_t padding[HC_ARCH_BITS == 32 ? 0x30 : 0x50];
5231 } Internal;
5232
5233 /** Device instance data for ring-3. The size of this area is defined
5234 * in the PDMDEVREG::cbInstanceR3 field. */
5235 char achInstanceData[8];
5236} PDMDEVINSR3;
5237
5238/** Current PDMDEVINSR3 version number. */
5239#define PDM_DEVINSR3_VERSION PDM_VERSION_MAKE(0xff82, 4, 0)
5240
5241/** Converts a pointer to the PDMDEVINSR3::IBase to a pointer to PDMDEVINS. */
5242#define PDMIBASE_2_PDMDEV(pInterface) ( (PPDMDEVINS)((char *)(pInterface) - RT_UOFFSETOF(PDMDEVINS, IBase)) )
5243
5244
5245/**
5246 * PDM ring-0 device instance.
5247 */
5248typedef struct PDMDEVINSR0
5249{
5250 /** Structure version. PDM_DEVINSR0_VERSION defines the current version. */
5251 uint32_t u32Version;
5252 /** Device instance number. */
5253 uint32_t iInstance;
5254
5255 /** Pointer the HC PDM Device API. */
5256 PCPDMDEVHLPR0 pHlpR0;
5257 /** Pointer to the shared device instance data. */
5258 RTR0PTR pvInstanceDataR0;
5259 /** Pointer to the device instance data for ring-0. */
5260 RTR0PTR pvInstanceDataForR0;
5261 /** The critical section for the device.
5262 *
5263 * TM and IOM will enter this critical section before calling into the device
5264 * code. PDM will when doing power on, power off, reset, suspend and resume
5265 * notifications. SSM will currently not, but this will be changed later on.
5266 *
5267 * The device gets a critical section automatically assigned to it before
5268 * the constructor is called. If the constructor wishes to use a different
5269 * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
5270 * very early on.
5271 */
5272 R0PTRTYPE(PPDMCRITSECT) pCritSectRoR0;
5273 /** Pointer to the ring-0 device registration structure. */
5274 R0PTRTYPE(PCPDMDEVREGR0) pReg;
5275 /** Ring-3 address of the ring-3 device instance. */
5276 R3PTRTYPE(struct PDMDEVINSR3 *) pDevInsForR3;
5277 /** Ring-0 pointer to the ring-3 device instance. */
5278 R0PTRTYPE(struct PDMDEVINSR3 *) pDevInsForR3R0;
5279 /** Ring-0 pointer to the ring-3 instance data. */
5280 RTR0PTR pvInstanceDataForR3R0;
5281 /** Raw-mode address of the raw-mode device instance. */
5282 RGPTRTYPE(struct PDMDEVINSRC *) pDevInsForRC;
5283 /** Ring-0 pointer to the raw-mode device instance. */
5284 R0PTRTYPE(struct PDMDEVINSRC *) pDevInsForRCR0;
5285 /** Ring-0 pointer to the raw-mode instance data. */
5286 RTR0PTR pvInstanceDataForRCR0;
5287
5288 /** PCI device structure size. */
5289 uint32_t cbPciDev;
5290 /** Number of PCI devices in apPciDevs. */
5291 uint32_t cPciDevs;
5292 /** Pointer to the PCI devices for this device.
5293 * (Allocated after the shared instance data.)
5294 * @note If we want to extend this beyond 8 sub-functions/devices, those 1 or
5295 * two devices ever needing it can use cbPciDev and do the address
5296 * calculations that for entries 8+. */
5297 R0PTRTYPE(struct PDMPCIDEV *) apPciDevs[8];
5298
5299 /** Align the internal data more naturally. */
5300 uint32_t au32Padding[HC_ARCH_BITS == 32 ? 3 : 2 + 4];
5301
5302 /** Internal data. */
5303 union
5304 {
5305#ifdef PDMDEVINSINT_DECLARED
5306 PDMDEVINSINTR0 s;
5307#endif
5308 uint8_t padding[HC_ARCH_BITS == 32 ? 0x20 : 0x40];
5309 } Internal;
5310
5311 /** Device instance data for ring-0. The size of this area is defined
5312 * in the PDMDEVREG::cbInstanceR0 field. */
5313 char achInstanceData[8];
5314} PDMDEVINSR0;
5315
5316/** Current PDMDEVINSR0 version number. */
5317#define PDM_DEVINSR0_VERSION PDM_VERSION_MAKE(0xff83, 4, 0)
5318
5319
5320/**
5321 * PDM raw-mode device instance.
5322 */
5323typedef struct PDMDEVINSRC
5324{
5325 /** Structure version. PDM_DEVINSRC_VERSION defines the current version. */
5326 uint32_t u32Version;
5327 /** Device instance number. */
5328 uint32_t iInstance;
5329
5330 /** Pointer the HC PDM Device API. */
5331 PCPDMDEVHLPRC pHlpRC;
5332 /** Pointer to the shared device instance data. */
5333 RTRGPTR pvInstanceDataRC;
5334 /** Pointer to the device instance data for raw-mode. */
5335 RTRGPTR pvInstanceDataForRC;
5336 /** The critical section for the device.
5337 *
5338 * TM and IOM will enter this critical section before calling into the device
5339 * code. PDM will when doing power on, power off, reset, suspend and resume
5340 * notifications. SSM will currently not, but this will be changed later on.
5341 *
5342 * The device gets a critical section automatically assigned to it before
5343 * the constructor is called. If the constructor wishes to use a different
5344 * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
5345 * very early on.
5346 */
5347 RGPTRTYPE(PPDMCRITSECT) pCritSectRoRC;
5348 /** Pointer to the raw-mode device registration structure. */
5349 RGPTRTYPE(PCPDMDEVREGRC) pReg;
5350
5351 /** PCI device structure size. */
5352 uint32_t cbPciDev;
5353 /** Number of PCI devices in apPciDevs. */
5354 uint32_t cPciDevs;
5355 /** Pointer to the PCI devices for this device.
5356 * (Allocated after the shared instance data.) */
5357 RGPTRTYPE(struct PDMPCIDEV *) apPciDevs[8];
5358
5359 /** Align the internal data more naturally. */
5360 uint32_t au32Padding[14];
5361
5362 /** Internal data. */
5363 union
5364 {
5365#ifdef PDMDEVINSINT_DECLARED
5366 PDMDEVINSINTRC s;
5367#endif
5368 uint8_t padding[0x10];
5369 } Internal;
5370
5371 /** Device instance data for ring-0. The size of this area is defined
5372 * in the PDMDEVREG::cbInstanceR0 field. */
5373 char achInstanceData[8];
5374} PDMDEVINSRC;
5375
5376/** Current PDMDEVINSR0 version number. */
5377#define PDM_DEVINSRC_VERSION PDM_VERSION_MAKE(0xff84, 4, 0)
5378
5379
5380/** @def PDM_DEVINS_VERSION
5381 * Current PDMDEVINS version number. */
5382/** @typedef PDMDEVINS
5383 * The device instance structure for the current context. */
5384#ifdef IN_RING3
5385# define PDM_DEVINS_VERSION PDM_DEVINSR3_VERSION
5386typedef PDMDEVINSR3 PDMDEVINS;
5387#elif defined(IN_RING0)
5388# define PDM_DEVINS_VERSION PDM_DEVINSR0_VERSION
5389typedef PDMDEVINSR0 PDMDEVINS;
5390#elif defined(IN_RC)
5391# define PDM_DEVINS_VERSION PDM_DEVINSRC_VERSION
5392typedef PDMDEVINSRC PDMDEVINS;
5393#else
5394# error "Missing context defines: IN_RING0, IN_RING3, IN_RC"
5395#endif
5396
5397/**
5398 * Get the pointer to an PCI device.
5399 * @note Returns NULL if @a a_idxPciDev is out of bounds.
5400 */
5401#define PDMDEV_GET_PPCIDEV(a_pDevIns, a_idxPciDev) \
5402 ( (uintptr_t)(a_idxPciDev) < RT_ELEMENTS((a_pDevIns)->apPciDevs) ? (a_pDevIns)->apPciDevs[(uintptr_t)(a_idxPciDev)] \
5403 : PDMDEV_CALC_PPCIDEV(a_pDevIns, a_idxPciDev) )
5404
5405/**
5406 * Calc the pointer to of a given PCI device.
5407 * @note Returns NULL if @a a_idxPciDev is out of bounds.
5408 */
5409#define PDMDEV_CALC_PPCIDEV(a_pDevIns, a_idxPciDev) \
5410 ( (uintptr_t)(a_idxPciDev) < (a_pDevIns)->cPciDevs \
5411 ? (PPDMPCIDEV)((uint8_t *)((a_pDevIns)->apPciDevs[0]) + (a_pDevIns->cbPciDev) * (uintptr_t)(a_idxPciDev)) \
5412 : (PPDMPCIDEV)NULL )
5413
5414
5415/**
5416 * Checks the structure versions of the device instance and device helpers,
5417 * returning if they are incompatible.
5418 *
5419 * This is for use in the constructor.
5420 *
5421 * @param pDevIns The device instance pointer.
5422 */
5423#define PDMDEV_CHECK_VERSIONS_RETURN(pDevIns) \
5424 do \
5425 { \
5426 PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
5427 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION), \
5428 ("DevIns=%#x mine=%#x\n", (pDevIns)->u32Version, PDM_DEVINS_VERSION), \
5429 VERR_PDM_DEVINS_VERSION_MISMATCH); \
5430 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->CTX_SUFF(pHlp)->u32Version, CTX_MID(PDM_DEVHLP,_VERSION)), \
5431 ("DevHlp=%#x mine=%#x\n", (pDevIns)->CTX_SUFF(pHlp)->u32Version, CTX_MID(PDM_DEVHLP,_VERSION)), \
5432 VERR_PDM_DEVHLP_VERSION_MISMATCH); \
5433 } while (0)
5434
5435/**
5436 * Quietly checks the structure versions of the device instance and device
5437 * helpers, returning if they are incompatible.
5438 *
5439 * This is for use in the destructor.
5440 *
5441 * @param pDevIns The device instance pointer.
5442 */
5443#define PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns) \
5444 do \
5445 { \
5446 PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
5447 if (RT_LIKELY(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION) )) \
5448 { /* likely */ } else return VERR_PDM_DEVINS_VERSION_MISMATCH; \
5449 if (RT_LIKELY(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->CTX_SUFF(pHlp)->u32Version, CTX_MID(PDM_DEVHLP,_VERSION)) )) \
5450 { /* likely */ } else return VERR_PDM_DEVHLP_VERSION_MISMATCH; \
5451 } while (0)
5452
5453/**
5454 * Wrapper around CFGMR3ValidateConfig for the root config for use in the
5455 * constructor - returns on failure.
5456 *
5457 * This should be invoked after having initialized the instance data
5458 * sufficiently for the correct operation of the destructor. The destructor is
5459 * always called!
5460 *
5461 * @param pDevIns Pointer to the PDM device instance.
5462 * @param pszValidValues Patterns describing the valid value names. See
5463 * RTStrSimplePatternMultiMatch for details on the
5464 * pattern syntax.
5465 * @param pszValidNodes Patterns describing the valid node (key) names.
5466 * Pass empty string if no valid nodes.
5467 */
5468#define PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, pszValidValues, pszValidNodes) \
5469 do \
5470 { \
5471 int rcValCfg = pDevIns->pHlpR3->pfnCFGMValidateConfig((pDevIns)->pCfg, "/", pszValidValues, pszValidNodes, \
5472 (pDevIns)->pReg->szName, (pDevIns)->iInstance); \
5473 if (RT_SUCCESS(rcValCfg)) \
5474 { /* likely */ } else return rcValCfg; \
5475 } while (0)
5476
5477/** @def PDMDEV_ASSERT_EMT
5478 * Assert that the current thread is the emulation thread.
5479 */
5480#ifdef VBOX_STRICT
5481# define PDMDEV_ASSERT_EMT(pDevIns) pDevIns->pHlpR3->pfnAssertEMT(pDevIns, __FILE__, __LINE__, __FUNCTION__)
5482#else
5483# define PDMDEV_ASSERT_EMT(pDevIns) do { } while (0)
5484#endif
5485
5486/** @def PDMDEV_ASSERT_OTHER
5487 * Assert that the current thread is NOT the emulation thread.
5488 */
5489#ifdef VBOX_STRICT
5490# define PDMDEV_ASSERT_OTHER(pDevIns) pDevIns->pHlpR3->pfnAssertOther(pDevIns, __FILE__, __LINE__, __FUNCTION__)
5491#else
5492# define PDMDEV_ASSERT_OTHER(pDevIns) do { } while (0)
5493#endif
5494
5495/** @def PDMDEV_ASSERT_VMLOCK_OWNER
5496 * Assert that the current thread is owner of the VM lock.
5497 */
5498#ifdef VBOX_STRICT
5499# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) pDevIns->pHlpR3->pfnAssertVMLock(pDevIns, __FILE__, __LINE__, __FUNCTION__)
5500#else
5501# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) do { } while (0)
5502#endif
5503
5504/** @def PDMDEV_SET_ERROR
5505 * Set the VM error. See PDMDevHlpVMSetError() for printf like message formatting.
5506 */
5507#define PDMDEV_SET_ERROR(pDevIns, rc, pszError) \
5508 PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, "%s", pszError)
5509
5510/** @def PDMDEV_SET_RUNTIME_ERROR
5511 * Set the VM runtime error. See PDMDevHlpVMSetRuntimeError() for printf like message formatting.
5512 */
5513#define PDMDEV_SET_RUNTIME_ERROR(pDevIns, fFlags, pszErrorId, pszError) \
5514 PDMDevHlpVMSetRuntimeError(pDevIns, fFlags, pszErrorId, "%s", pszError)
5515
5516/** @def PDMDEVINS_2_RCPTR
5517 * Converts a PDM Device instance pointer a RC PDM Device instance pointer.
5518 */
5519#ifdef IN_RC
5520# define PDMDEVINS_2_RCPTR(pDevIns) (pDevIns)
5521#else
5522# define PDMDEVINS_2_RCPTR(pDevIns) ( (pDevIns)->pDevInsForRC )
5523#endif
5524
5525/** @def PDMDEVINS_2_R3PTR
5526 * Converts a PDM Device instance pointer a R3 PDM Device instance pointer.
5527 */
5528#ifdef IN_RING3
5529# define PDMDEVINS_2_R3PTR(pDevIns) (pDevIns)
5530#else
5531# define PDMDEVINS_2_R3PTR(pDevIns) ( (pDevIns)->pDevInsForR3 )
5532#endif
5533
5534/** @def PDMDEVINS_2_R0PTR
5535 * Converts a PDM Device instance pointer a R0 PDM Device instance pointer.
5536 */
5537#ifdef IN_RING0
5538# define PDMDEVINS_2_R0PTR(pDevIns) (pDevIns)
5539#else
5540# define PDMDEVINS_2_R0PTR(pDevIns) ( (pDevIns)->pDevInsR0RemoveMe )
5541#endif
5542
5543/** @def PDMDEVINS_DATA_2_R0_REMOVE_ME
5544 * Converts a PDM device instance data pointer to a ring-0 one.
5545 * @deprecated
5546 */
5547#ifdef IN_RING0
5548# define PDMDEVINS_DATA_2_R0_REMOVE_ME(pDevIns, pvCC) (pvCC)
5549#else
5550# define PDMDEVINS_DATA_2_R0_REMOVE_ME(pDevIns, pvCC) ( (pDevIns)->pvInstanceDataR0 + (uintptr_t)(pvCC) - (uintptr_t)(pDevIns)->CTX_SUFF(pvInstanceData) )
5551#endif
5552
5553
5554#ifdef IN_RING3
5555
5556/**
5557 * @copydoc PDMDEVHLPR3::pfnIOPortRegister
5558 */
5559DECLINLINE(int) PDMDevHlpIOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTHCPTR pvUser,
5560 PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
5561 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc)
5562{
5563 return pDevIns->pHlpR3->pfnIOPortRegister(pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc);
5564}
5565
5566/**
5567 * @copydoc PDMDEVHLPR3::pfnIOPortRegisterRC
5568 */
5569DECLINLINE(int) PDMDevHlpIOPortRegisterRC(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTRCPTR pvUser,
5570 const char *pszOut, const char *pszIn, const char *pszOutStr,
5571 const char *pszInStr, const char *pszDesc)
5572{
5573 return pDevIns->pHlpR3->pfnIOPortRegisterRC(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
5574}
5575
5576/**
5577 * @copydoc PDMDEVHLPR3::pfnIOPortRegisterR0
5578 */
5579DECLINLINE(int) PDMDevHlpIOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTR0PTR pvUser,
5580 const char *pszOut, const char *pszIn, const char *pszOutStr,
5581 const char *pszInStr, const char *pszDesc)
5582{
5583 return pDevIns->pHlpR3->pfnIOPortRegisterR0(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
5584}
5585
5586/**
5587 * @copydoc PDMDEVHLPR3::pfnIOPortDeregister
5588 */
5589DECLINLINE(int) PDMDevHlpIOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts)
5590{
5591 return pDevIns->pHlpR3->pfnIOPortDeregister(pDevIns, Port, cPorts);
5592}
5593
5594/**
5595 * Combines PDMDevHlpIoPortCreate() & PDMDevHlpIoPortMap().
5596 */
5597DECLINLINE(int) PDMDevHlpIoPortCreateAndMap(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, PFNIOMIOPORTNEWOUT pfnOut,
5598 PFNIOMIOPORTNEWIN pfnIn, const char *pszDesc, PCIOMIOPORTDESC paExtDescs,
5599 PIOMIOPORTHANDLE phIoPorts)
5600{
5601 int rc = pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, 0, NULL, UINT32_MAX,
5602 pfnOut, pfnIn, NULL, NULL, NULL, pszDesc, paExtDescs, phIoPorts);
5603 if (RT_SUCCESS(rc))
5604 rc = pDevIns->pHlpR3->pfnIoPortMap(pDevIns, *phIoPorts, Port);
5605 return rc;
5606}
5607
5608/**
5609 * @sa PDMDevHlpIoPortCreateEx
5610 */
5611DECLINLINE(int) PDMDevHlpIoPortCreate(PPDMDEVINS pDevIns, RTIOPORT cPorts, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
5612 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn, void *pvUser, const char *pszDesc,
5613 PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
5614{
5615 return pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, 0, pPciDev, iPciRegion,
5616 pfnOut, pfnIn, NULL, NULL, pvUser, pszDesc, paExtDescs, phIoPorts);
5617}
5618
5619/**
5620 * @copydoc PDMDEVHLPR3::pfnIoPortCreateEx
5621 */
5622DECLINLINE(int) PDMDevHlpIoPortCreateEx(PPDMDEVINS pDevIns, RTIOPORT cPorts, uint32_t fFlags, PPDMPCIDEV pPciDev,
5623 uint32_t iPciRegion, PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
5624 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, void *pvUser,
5625 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
5626{
5627 return pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, fFlags, pPciDev, iPciRegion,
5628 pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser, pszDesc, paExtDescs, phIoPorts);
5629}
5630
5631/**
5632 * @copydoc PDMDEVHLPR3::pfnIoPortMap
5633 */
5634DECLINLINE(int) PDMDevHlpIoPortMap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT Port)
5635{
5636 return pDevIns->pHlpR3->pfnIoPortMap(pDevIns, hIoPorts, Port);
5637}
5638
5639/**
5640 * @copydoc PDMDEVHLPR3::pfnIoPortUnmap
5641 */
5642DECLINLINE(int) PDMDevHlpIoPortUnmap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)
5643{
5644 return pDevIns->pHlpR3->pfnIoPortUnmap(pDevIns, hIoPorts);
5645}
5646
5647#endif /* IN_RING3 */
5648#ifndef IN_RING3
5649
5650/**
5651 * @sa PDMDevHlpIoPortSetUpContextEx
5652 */
5653DECLINLINE(int) PDMDevHlpIoPortSetUpContext(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
5654 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn, void *pvUser)
5655{
5656 return pDevIns->CTX_SUFF(pHlp)->pfnIoPortSetUpContextEx(pDevIns, hIoPorts, pfnOut, pfnIn, NULL, NULL, pvUser);
5657}
5658
5659/**
5660 * @copydoc PDMDEVHLPR3::pfnIoPortCreateEx
5661 */
5662DECLINLINE(int) PDMDevHlpIoPortSetUpContextEx(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
5663 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
5664 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, void *pvUser)
5665{
5666 return pDevIns->CTX_SUFF(pHlp)->pfnIoPortSetUpContextEx(pDevIns, hIoPorts, pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser);
5667}
5668
5669#endif /* !IN_RING3 */
5670#ifdef IN_RING3
5671
5672
5673/**
5674 * @sa PDMDevHlpMmioCreateEx
5675 */
5676DECLINLINE(int) PDMDevHlpMmioCreate(PPDMDEVINS pDevIns, RTGCPHYS cbRegion, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
5677 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, void *pvUser,
5678 const char *pszDesc, PIOMMMIOHANDLE phRegion)
5679{
5680 return pDevIns->pHlpR3->pfnMmioCreateEx(pDevIns, cbRegion, 0, pPciDev, iPciRegion,
5681 pfnWrite, pfnRead, NULL, pvUser, pszDesc, phRegion);
5682}
5683
5684/**
5685 * @copydoc PDMDEVHLPR3::pfnMmioCreateEx
5686 */
5687DECLINLINE(int) PDMDevHlpMmioCreateEx(PPDMDEVINS pDevIns, RTGCPHYS cbRegion,
5688 uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
5689 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill,
5690 void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion)
5691{
5692 return pDevIns->pHlpR3->pfnMmioCreateEx(pDevIns, cbRegion, fFlags, pPciDev, iPciRegion,
5693 pfnWrite, pfnRead, pfnFill, pvUser, pszDesc, phRegion);
5694}
5695
5696/**
5697 * @copydoc PDMDEVHLPR3::pfnMmioMap
5698 */
5699DECLINLINE(int) PDMDevHlpMmioMap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys)
5700{
5701 return pDevIns->pHlpR3->pfnMmioMap(pDevIns, hRegion, GCPhys);
5702}
5703
5704/**
5705 * @copydoc PDMDEVHLPR3::pfnMmioUnmap
5706 */
5707DECLINLINE(int) PDMDevHlpMmioUnmap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
5708{
5709 return pDevIns->pHlpR3->pfnMmioUnmap(pDevIns, hRegion);
5710}
5711
5712/**
5713 * @copydoc PDMDEVHLPR3::pfnMmioReduce
5714 */
5715DECLINLINE(int) PDMDevHlpMmioReduce(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS cbRegion)
5716{
5717 return pDevIns->pHlpR3->pfnMmioReduce(pDevIns, hRegion, cbRegion);
5718}
5719
5720#endif /* IN_RING3 */
5721#ifndef IN_RING3
5722
5723/**
5724 * @sa PDMDevHlpMmioSetUpContextEx
5725 */
5726DECLINLINE(int) PDMDevHlpMmioSetUpContext(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion,
5727 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, void *pvUser)
5728{
5729 return pDevIns->CTX_SUFF(pHlp)->pfnMmioSetUpContextEx(pDevIns, hRegion, pfnWrite, pfnRead, NULL, pvUser);
5730}
5731
5732/**
5733 * @copydoc PDMDEVHLPR0::pfnMmioSetUpContextEx
5734 */
5735DECLINLINE(int) PDMDevHlpMmioSetUpContextEx(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIONEWWRITE pfnWrite,
5736 PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill, void *pvUser)
5737{
5738 return pDevIns->CTX_SUFF(pHlp)->pfnMmioSetUpContextEx(pDevIns, hRegion, pfnWrite, pfnRead, pfnFill, pvUser);
5739}
5740
5741#endif /* !IN_RING3 */
5742#ifdef IN_RING3
5743
5744/**
5745 * Register a Memory Mapped I/O (MMIO) region.
5746 *
5747 * These callbacks are of course for the ring-3 context (R3). Register HC
5748 * handlers before raw-mode context (RC) and ring-0 context (R0) handlers! There
5749 * must be a R3 handler for every RC and R0 handler!
5750 *
5751 * @returns VBox status.
5752 * @param pDevIns The device instance to register the MMIO with.
5753 * @param GCPhysStart First physical address in the range.
5754 * @param cbRange The size of the range (in bytes).
5755 * @param pvUser User argument.
5756 * @param fFlags Flags, IOMMMIO_FLAGS_XXX.
5757 * @param pfnWrite Pointer to function which is gonna handle Write operations.
5758 * @param pfnRead Pointer to function which is gonna handle Read operations.
5759 * @param pszDesc Pointer to description string. This must not be freed.
5760 */
5761DECLINLINE(int) PDMDevHlpMMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTHCPTR pvUser,
5762 uint32_t fFlags, PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, const char *pszDesc)
5763{
5764 return pDevIns->pHlpR3->pfnMMIORegister(pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, NULL /*pfnFill*/,
5765 fFlags, pszDesc);
5766}
5767
5768/**
5769 * Register a Memory Mapped I/O (MMIO) region for RC.
5770 *
5771 * These callbacks are for the raw-mode context (RC). Register ring-3 context
5772 * (R3) handlers before guest context handlers! There must be a R3 handler for
5773 * every RC handler!
5774 *
5775 * @returns VBox status.
5776 * @param pDevIns The device instance to register the MMIO with.
5777 * @param GCPhysStart First physical address in the range.
5778 * @param cbRange The size of the range (in bytes).
5779 * @param pvUser User argument.
5780 * @param pszWrite Name of the RC function which is gonna handle Write operations.
5781 * @param pszRead Name of the RC function which is gonna handle Read operations.
5782 */
5783DECLINLINE(int) PDMDevHlpMMIORegisterRC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTRCPTR pvUser,
5784 const char *pszWrite, const char *pszRead)
5785{
5786 return pDevIns->pHlpR3->pfnMMIORegisterRC(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, NULL /*pszFill*/);
5787}
5788
5789/**
5790 * Register a Memory Mapped I/O (MMIO) region for R0.
5791 *
5792 * These callbacks are for the ring-0 host context (R0). Register ring-3
5793 * constext (R3) handlers before R0 handlers! There must be a R3 handler for
5794 * every R0 handler!
5795 *
5796 * @returns VBox status.
5797 * @param pDevIns The device instance to register the MMIO with.
5798 * @param GCPhysStart First physical address in the range.
5799 * @param cbRange The size of the range (in bytes).
5800 * @param pvUser User argument. (if pointer, then it must be in locked memory!)
5801 * @param pszWrite Name of the RC function which is gonna handle Write operations.
5802 * @param pszRead Name of the RC function which is gonna handle Read operations.
5803 * @remarks Caller enters the device critical section prior to invoking the
5804 * registered callback methods.
5805 */
5806DECLINLINE(int) PDMDevHlpMMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTR0PTR pvUser,
5807 const char *pszWrite, const char *pszRead)
5808{
5809 return pDevIns->pHlpR3->pfnMMIORegisterR0(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, NULL /*pszFill*/);
5810}
5811
5812/**
5813 * @copydoc PDMDEVHLPR3::pfnMMIORegister
5814 */
5815DECLINLINE(int) PDMDevHlpMMIORegisterEx(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTHCPTR pvUser,
5816 uint32_t fFlags, PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead,
5817 PFNIOMMMIOFILL pfnFill, const char *pszDesc)
5818{
5819 return pDevIns->pHlpR3->pfnMMIORegister(pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill,
5820 fFlags, pszDesc);
5821}
5822
5823/**
5824 * @copydoc PDMDEVHLPR3::pfnMMIORegisterRC
5825 */
5826DECLINLINE(int) PDMDevHlpMMIORegisterRCEx(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTRCPTR pvUser,
5827 const char *pszWrite, const char *pszRead, const char *pszFill)
5828{
5829 return pDevIns->pHlpR3->pfnMMIORegisterRC(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill);
5830}
5831
5832/**
5833 * @copydoc PDMDEVHLPR3::pfnMMIORegisterR0
5834 */
5835DECLINLINE(int) PDMDevHlpMMIORegisterR0Ex(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTR0PTR pvUser,
5836 const char *pszWrite, const char *pszRead, const char *pszFill)
5837{
5838 return pDevIns->pHlpR3->pfnMMIORegisterR0(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill);
5839}
5840
5841/**
5842 * @copydoc PDMDEVHLPR3::pfnMMIODeregister
5843 */
5844DECLINLINE(int) PDMDevHlpMMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange)
5845{
5846 return pDevIns->pHlpR3->pfnMMIODeregister(pDevIns, GCPhysStart, cbRange);
5847}
5848
5849/**
5850 * @copydoc PDMDEVHLPR3::pfnMMIO2Register
5851 */
5852DECLINLINE(int) PDMDevHlpMMIO2Register(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cb,
5853 uint32_t fFlags, void **ppv, const char *pszDesc)
5854{
5855 return pDevIns->pHlpR3->pfnMMIO2Register(pDevIns, pPciDev, iRegion, cb, fFlags, ppv, pszDesc);
5856}
5857
5858/**
5859 * @copydoc PDMDEVHLPR3::pfnMMIOExPreRegister
5860 */
5861DECLINLINE(int) PDMDevHlpMMIOExPreRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion,
5862 uint32_t fFlags, const char *pszDesc, RTHCPTR pvUser,
5863 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
5864 RTR0PTR pvUserR0, const char *pszWriteR0, const char *pszReadR0, const char *pszFillR0,
5865 RTRCPTR pvUserRC, const char *pszWriteRC, const char *pszReadRC, const char *pszFillRC)
5866{
5867 return pDevIns->pHlpR3->pfnMMIOExPreRegister(pDevIns, pPciDev, iRegion, cbRegion, fFlags, pszDesc,
5868 pvUser, pfnWrite, pfnRead, pfnFill,
5869 pvUserR0, pszWriteR0, pszReadR0, pszFillR0,
5870 pvUserRC, pszWriteRC, pszReadRC, pszFillRC);
5871}
5872
5873/**
5874 * @copydoc PDMDEVHLPR3::pfnMMIOExDeregister
5875 * @param pPciDev The PCI device the region is associated with, use
5876 * NULL to indicate it is not associated with a device.
5877 */
5878DECLINLINE(int) PDMDevHlpMMIOExDeregister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion)
5879{
5880 return pDevIns->pHlpR3->pfnMMIOExDeregister(pDevIns, pPciDev, iRegion);
5881}
5882
5883/**
5884 * @copydoc PDMDEVHLPR3::pfnMMIOExMap
5885 * @param pPciDev The PCI device the region is associated with, use
5886 * NULL to indicate it is not associated with a device.
5887 */
5888DECLINLINE(int) PDMDevHlpMMIOExMap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys)
5889{
5890 return pDevIns->pHlpR3->pfnMMIOExMap(pDevIns, pPciDev, iRegion, GCPhys);
5891}
5892
5893/**
5894 * @copydoc PDMDEVHLPR3::pfnMMIOExUnmap
5895 * @param pPciDev The PCI device the region is associated with, use
5896 * NULL to indicate it is not associated with a device.
5897 */
5898DECLINLINE(int) PDMDevHlpMMIOExUnmap(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys)
5899{
5900 return pDevIns->pHlpR3->pfnMMIOExUnmap(pDevIns, pPciDev, iRegion, GCPhys);
5901}
5902
5903/**
5904 * @copydoc PDMDEVHLPR3::pfnMMIOExReduce
5905 */
5906DECLINLINE(int) PDMDevHlpMMIOExReduce(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion)
5907{
5908 return pDevIns->pHlpR3->pfnMMIOExReduce(pDevIns, pPciDev, iRegion, cbRegion);
5909}
5910
5911#ifdef VBOX_WITH_RAW_MODE_KEEP
5912/**
5913 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2
5914 */
5915DECLINLINE(int) PDMDevHlpMMHyperMapMMIO2(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
5916 const char *pszDesc, PRTRCPTR pRCPtr)
5917{
5918 return pDevIns->pHlpR3->pfnMMHyperMapMMIO2(pDevIns, pPciDev, iRegion, off, cb, pszDesc, pRCPtr);
5919}
5920#endif
5921
5922/**
5923 * @copydoc PDMDEVHLPR3::pfnMMIO2MapKernel
5924 */
5925DECLINLINE(int) PDMDevHlpMMIO2MapKernel(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
5926 const char *pszDesc, PRTR0PTR pR0Ptr)
5927{
5928 return pDevIns->pHlpR3->pfnMMIO2MapKernel(pDevIns, pPciDev, iRegion, off, cb, pszDesc, pR0Ptr);
5929}
5930
5931/**
5932 * @copydoc PDMDEVHLPR3::pfnROMRegister
5933 */
5934DECLINLINE(int) PDMDevHlpROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
5935 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
5936{
5937 return pDevIns->pHlpR3->pfnROMRegister(pDevIns, GCPhysStart, cbRange, pvBinary, cbBinary, fFlags, pszDesc);
5938}
5939
5940/**
5941 * @copydoc PDMDEVHLPR3::pfnROMProtectShadow
5942 */
5943DECLINLINE(int) PDMDevHlpROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt)
5944{
5945 return pDevIns->pHlpR3->pfnROMProtectShadow(pDevIns, GCPhysStart, cbRange, enmProt);
5946}
5947
5948/**
5949 * Register a save state data unit.
5950 *
5951 * @returns VBox status.
5952 * @param pDevIns The device instance.
5953 * @param uVersion Data layout version number.
5954 * @param cbGuess The approximate amount of data in the unit.
5955 * Only for progress indicators.
5956 * @param pfnSaveExec Execute save callback, optional.
5957 * @param pfnLoadExec Execute load callback, optional.
5958 */
5959DECLINLINE(int) PDMDevHlpSSMRegister(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
5960 PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
5961{
5962 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
5963 NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveDone*/,
5964 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
5965 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
5966}
5967
5968/**
5969 * Register a save state data unit with a live save callback as well.
5970 *
5971 * @returns VBox status.
5972 * @param pDevIns The device instance.
5973 * @param uVersion Data layout version number.
5974 * @param cbGuess The approximate amount of data in the unit.
5975 * Only for progress indicators.
5976 * @param pfnLiveExec Execute live callback, optional.
5977 * @param pfnSaveExec Execute save callback, optional.
5978 * @param pfnLoadExec Execute load callback, optional.
5979 */
5980DECLINLINE(int) PDMDevHlpSSMRegister3(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
5981 PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
5982{
5983 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
5984 NULL /*pfnLivePrep*/, pfnLiveExec, NULL /*pfnLiveDone*/,
5985 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
5986 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
5987}
5988
5989/**
5990 * @copydoc PDMDEVHLPR3::pfnSSMRegister
5991 */
5992DECLINLINE(int) PDMDevHlpSSMRegisterEx(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
5993 PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
5994 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
5995 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
5996{
5997 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, pszBefore,
5998 pfnLivePrep, pfnLiveExec, pfnLiveVote,
5999 pfnSavePrep, pfnSaveExec, pfnSaveDone,
6000 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
6001}
6002
6003/**
6004 * @copydoc PDMDEVHLPR3::pfnTMTimerCreate
6005 */
6006DECLINLINE(int) PDMDevHlpTMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags,
6007 const char *pszDesc, PPTMTIMERR3 ppTimer)
6008{
6009 return pDevIns->pHlpR3->pfnTMTimerCreate(pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
6010}
6011
6012/**
6013 * @copydoc PDMDEVHLPR3::pfnTimerCreate
6014 */
6015DECLINLINE(int) PDMDevHlpTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser,
6016 uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
6017{
6018 return pDevIns->pHlpR3->pfnTimerCreate(pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, phTimer);
6019}
6020
6021#endif /* IN_RING3 */
6022
6023/**
6024 * @copydoc PDMDEVHLPR3::pfnTimerToPtr
6025 */
6026DECLINLINE(PTMTIMER) PDMDevHlpTimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
6027{
6028 return pDevIns->CTX_SUFF(pHlp)->pfnTimerToPtr(pDevIns, hTimer);
6029}
6030
6031/**
6032 * @copydoc PDMDEVHLPR3::pfnTimerFromMicro
6033 */
6034DECLINLINE(uint64_t) PDMDevHlpTimerFromMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
6035{
6036 return pDevIns->CTX_SUFF(pHlp)->pfnTimerFromMicro(pDevIns, hTimer, cMicroSecs);
6037}
6038
6039/**
6040 * @copydoc PDMDEVHLPR3::pfnTimerFromMilli
6041 */
6042DECLINLINE(uint64_t) PDMDevHlpTimerFromMilli(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs)
6043{
6044 return pDevIns->CTX_SUFF(pHlp)->pfnTimerFromMilli(pDevIns, hTimer, cMilliSecs);
6045}
6046
6047/**
6048 * @copydoc PDMDEVHLPR3::pfnTimerFromNano
6049 */
6050DECLINLINE(uint64_t) PDMDevHlpTimerFromNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
6051{
6052 return pDevIns->CTX_SUFF(pHlp)->pfnTimerFromNano(pDevIns, hTimer, cNanoSecs);
6053}
6054
6055/**
6056 * @copydoc PDMDEVHLPR3::pfnTimerGet
6057 */
6058DECLINLINE(uint64_t) PDMDevHlpTimerGet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
6059{
6060 return pDevIns->CTX_SUFF(pHlp)->pfnTimerGet(pDevIns, hTimer);
6061}
6062
6063/**
6064 * @copydoc PDMDEVHLPR3::pfnTimerGetFreq
6065 */
6066DECLINLINE(uint64_t) PDMDevHlpTimerGetFreq(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
6067{
6068 return pDevIns->CTX_SUFF(pHlp)->pfnTimerGetFreq(pDevIns, hTimer);
6069}
6070
6071/**
6072 * @copydoc PDMDEVHLPR3::pfnTimerGetNano
6073 */
6074DECLINLINE(uint64_t) PDMDevHlpTimerGetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
6075{
6076 return pDevIns->CTX_SUFF(pHlp)->pfnTimerGetNano(pDevIns, hTimer);
6077}
6078
6079/**
6080 * @copydoc PDMDEVHLPR3::pfnTimerIsActive
6081 */
6082DECLINLINE(bool) PDMDevHlpTimerIsActive(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
6083{
6084 return pDevIns->CTX_SUFF(pHlp)->pfnTimerIsActive(pDevIns, hTimer);
6085}
6086
6087/**
6088 * @copydoc PDMDEVHLPR3::pfnTimerIsLockOwner
6089 */
6090DECLINLINE(bool) PDMDevHlpTimerIsLockOwner(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
6091{
6092 return pDevIns->CTX_SUFF(pHlp)->pfnTimerIsLockOwner(pDevIns, hTimer);
6093}
6094
6095/**
6096 * @copydoc PDMDEVHLPR3::pfnTimerLock
6097 */
6098DECLINLINE(int) PDMDevHlpTimerLock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy)
6099{
6100 return pDevIns->CTX_SUFF(pHlp)->pfnTimerLock(pDevIns, hTimer, rcBusy);
6101}
6102
6103/**
6104 * @copydoc PDMDEVHLPR3::pfnTimerSet
6105 */
6106DECLINLINE(int) PDMDevHlpTimerSet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire)
6107{
6108 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSet(pDevIns, hTimer, uExpire);
6109}
6110
6111/**
6112 * @copydoc PDMDEVHLPR3::pfnTimerSetFrequencyHint
6113 */
6114DECLINLINE(int) PDMDevHlpTimerSetFrequencyHint(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz)
6115{
6116 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetFrequencyHint(pDevIns, hTimer, uHz);
6117}
6118
6119/**
6120 * @copydoc PDMDEVHLPR3::pfnTimerSetMicro
6121 */
6122DECLINLINE(int) PDMDevHlpTimerSetMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
6123{
6124 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetMicro(pDevIns, hTimer, cMicrosToNext);
6125}
6126
6127/**
6128 * @copydoc PDMDEVHLPR3::pfnTimerSetMillies
6129 */
6130DECLINLINE(int) PDMDevHlpTimerSetMillies(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext)
6131{
6132 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetMillies(pDevIns, hTimer, cMilliesToNext);
6133}
6134
6135/**
6136 * @copydoc PDMDEVHLPR3::pfnTimerSetNano
6137 */
6138DECLINLINE(int) PDMDevHlpTimerSetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
6139{
6140 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetNano(pDevIns, hTimer, cNanosToNext);
6141}
6142
6143/**
6144 * @copydoc PDMDEVHLPR3::pfnTimerSetRelative
6145 */
6146DECLINLINE(int) PDMDevHlpTimerSetRelative(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
6147{
6148 return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetRelative(pDevIns, hTimer, cTicksToNext, pu64Now);
6149}
6150
6151/**
6152 * @copydoc PDMDEVHLPR3::pfnTimerStop
6153 */
6154DECLINLINE(int) PDMDevHlpTimerStop(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
6155{
6156 return pDevIns->CTX_SUFF(pHlp)->pfnTimerStop(pDevIns, hTimer);
6157}
6158
6159/**
6160 * @copydoc PDMDEVHLPR3::pfnTimerUnlock
6161 */
6162DECLINLINE(void) PDMDevHlpTimerUnlock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
6163{
6164 pDevIns->CTX_SUFF(pHlp)->pfnTimerUnlock(pDevIns, hTimer);
6165}
6166
6167#ifdef IN_RING3
6168
6169/**
6170 * @copydoc PDMDEVHLPR3::pfnTimerSave
6171 */
6172DECLINLINE(int) PDMDevHlpTimerSave(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
6173{
6174 return pDevIns->pHlpR3->pfnTimerSave(pDevIns, hTimer, pSSM);
6175}
6176
6177/**
6178 * @copydoc PDMDEVHLPR3::pfnTimerLoad
6179 */
6180DECLINLINE(int) PDMDevHlpTimerLoad(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
6181{
6182 return pDevIns->pHlpR3->pfnTimerLoad(pDevIns, hTimer, pSSM);
6183}
6184
6185/**
6186 * @copydoc PDMDEVHLPR3::pfnTMUtcNow
6187 */
6188DECLINLINE(PRTTIMESPEC) PDMDevHlpTMUtcNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
6189{
6190 return pDevIns->pHlpR3->pfnTMUtcNow(pDevIns, pTime);
6191}
6192
6193#endif
6194
6195/**
6196 * @copydoc PDMDEVHLPR3::pfnPhysRead
6197 */
6198DECLINLINE(int) PDMDevHlpPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
6199{
6200 return pDevIns->CTX_SUFF(pHlp)->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
6201}
6202
6203/**
6204 * @copydoc PDMDEVHLPR3::pfnPhysWrite
6205 */
6206DECLINLINE(int) PDMDevHlpPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
6207{
6208 return pDevIns->CTX_SUFF(pHlp)->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
6209}
6210
6211#ifdef IN_RING3
6212
6213/**
6214 * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtr
6215 */
6216DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtr(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock)
6217{
6218 return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtr(pDevIns, GCPhys, fFlags, ppv, pLock);
6219}
6220
6221/**
6222 * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtrReadOnly
6223 */
6224DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void const **ppv,
6225 PPGMPAGEMAPLOCK pLock)
6226{
6227 return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhys, fFlags, ppv, pLock);
6228}
6229
6230/**
6231 * @copydoc PDMDEVHLPR3::pfnPhysReleasePageMappingLock
6232 */
6233DECLINLINE(void) PDMDevHlpPhysReleasePageMappingLock(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock)
6234{
6235 pDevIns->CTX_SUFF(pHlp)->pfnPhysReleasePageMappingLock(pDevIns, pLock);
6236}
6237
6238/**
6239 * @copydoc PDMDEVHLPR3::pfnPhysBulkGCPhys2CCPtr
6240 */
6241DECLINLINE(int) PDMDevHlpPhysBulkGCPhys2CCPtr(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
6242 uint32_t fFlags, void **papvPages, PPGMPAGEMAPLOCK paLocks)
6243{
6244 return pDevIns->CTX_SUFF(pHlp)->pfnPhysBulkGCPhys2CCPtr(pDevIns, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
6245}
6246
6247/**
6248 * @copydoc PDMDEVHLPR3::pfnPhysBulkGCPhys2CCPtrReadOnly
6249 */
6250DECLINLINE(int) PDMDevHlpPhysBulkGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, uint32_t cPages, PCRTGCPHYS paGCPhysPages,
6251 uint32_t fFlags, void const **papvPages, PPGMPAGEMAPLOCK paLocks)
6252{
6253 return pDevIns->CTX_SUFF(pHlp)->pfnPhysBulkGCPhys2CCPtrReadOnly(pDevIns, cPages, paGCPhysPages, fFlags, papvPages, paLocks);
6254}
6255
6256/**
6257 * @copydoc PDMDEVHLPR3::pfnPhysBulkReleasePageMappingLocks
6258 */
6259DECLINLINE(void) PDMDevHlpPhysBulkReleasePageMappingLocks(PPDMDEVINS pDevIns, uint32_t cPages, PPGMPAGEMAPLOCK paLocks)
6260{
6261 pDevIns->CTX_SUFF(pHlp)->pfnPhysBulkReleasePageMappingLocks(pDevIns, cPages, paLocks);
6262}
6263
6264/**
6265 * @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt
6266 */
6267DECLINLINE(int) PDMDevHlpPhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
6268{
6269 return pDevIns->pHlpR3->pfnPhysReadGCVirt(pDevIns, pvDst, GCVirtSrc, cb);
6270}
6271
6272/**
6273 * @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt
6274 */
6275DECLINLINE(int) PDMDevHlpPhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
6276{
6277 return pDevIns->pHlpR3->pfnPhysWriteGCVirt(pDevIns, GCVirtDst, pvSrc, cb);
6278}
6279
6280/**
6281 * @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys
6282 */
6283DECLINLINE(int) PDMDevHlpPhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
6284{
6285 return pDevIns->pHlpR3->pfnPhysGCPtr2GCPhys(pDevIns, GCPtr, pGCPhys);
6286}
6287
6288/**
6289 * @copydoc PDMDEVHLPR3::pfnMMHeapAlloc
6290 */
6291DECLINLINE(void *) PDMDevHlpMMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
6292{
6293 return pDevIns->pHlpR3->pfnMMHeapAlloc(pDevIns, cb);
6294}
6295
6296/**
6297 * @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ
6298 */
6299DECLINLINE(void *) PDMDevHlpMMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
6300{
6301 return pDevIns->pHlpR3->pfnMMHeapAllocZ(pDevIns, cb);
6302}
6303
6304/**
6305 * @copydoc PDMDEVHLPR3::pfnMMHeapFree
6306 */
6307DECLINLINE(void) PDMDevHlpMMHeapFree(PPDMDEVINS pDevIns, void *pv)
6308{
6309 pDevIns->pHlpR3->pfnMMHeapFree(pDevIns, pv);
6310}
6311#endif /* IN_RING3 */
6312
6313/**
6314 * @copydoc PDMDEVHLPR3::pfnVMState
6315 */
6316DECLINLINE(VMSTATE) PDMDevHlpVMState(PPDMDEVINS pDevIns)
6317{
6318 return pDevIns->CTX_SUFF(pHlp)->pfnVMState(pDevIns);
6319}
6320
6321#ifdef IN_RING3
6322/**
6323 * @copydoc PDMDEVHLPR3::pfnVMTeleportedAndNotFullyResumedYet
6324 */
6325DECLINLINE(bool) PDMDevHlpVMTeleportedAndNotFullyResumedYet(PPDMDEVINS pDevIns)
6326{
6327 return pDevIns->pHlpR3->pfnVMTeleportedAndNotFullyResumedYet(pDevIns);
6328}
6329#endif /* IN_RING3 */
6330
6331/**
6332 * @copydoc PDMDEVHLPR3::pfnVMSetError
6333 */
6334DECLINLINE(int) RT_IPRT_FORMAT_ATTR(6, 7) PDMDevHlpVMSetError(PPDMDEVINS pDevIns, const int rc, RT_SRC_POS_DECL,
6335 const char *pszFormat, ...)
6336{
6337 va_list va;
6338 va_start(va, pszFormat);
6339 pDevIns->CTX_SUFF(pHlp)->pfnVMSetErrorV(pDevIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
6340 va_end(va);
6341 return rc;
6342}
6343
6344/**
6345 * @copydoc PDMDEVHLPR3::pfnVMSetRuntimeError
6346 */
6347DECLINLINE(int) RT_IPRT_FORMAT_ATTR(4, 5) PDMDevHlpVMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId,
6348 const char *pszFormat, ...)
6349{
6350 va_list va;
6351 int rc;
6352 va_start(va, pszFormat);
6353 rc = pDevIns->CTX_SUFF(pHlp)->pfnVMSetRuntimeErrorV(pDevIns, fFlags, pszErrorId, pszFormat, va);
6354 va_end(va);
6355 return rc;
6356}
6357
6358/**
6359 * VBOX_STRICT wrapper for pHlp->pfnDBGFStopV.
6360 *
6361 * @returns VBox status code which must be passed up to the VMM. This will be
6362 * VINF_SUCCESS in non-strict builds.
6363 * @param pDevIns The device instance.
6364 * @param SRC_POS Use RT_SRC_POS.
6365 * @param pszFormat Message. (optional)
6366 * @param ... Message parameters.
6367 */
6368DECLINLINE(int) RT_IPRT_FORMAT_ATTR(5, 6) PDMDevHlpDBGFStop(PPDMDEVINS pDevIns, RT_SRC_POS_DECL, const char *pszFormat, ...)
6369{
6370#ifdef VBOX_STRICT
6371# ifdef IN_RING3
6372 int rc;
6373 va_list args;
6374 va_start(args, pszFormat);
6375 rc = pDevIns->pHlpR3->pfnDBGFStopV(pDevIns, RT_SRC_POS_ARGS, pszFormat, args);
6376 va_end(args);
6377 return rc;
6378# else
6379 NOREF(pDevIns);
6380 NOREF(pszFile);
6381 NOREF(iLine);
6382 NOREF(pszFunction);
6383 NOREF(pszFormat);
6384 return VINF_EM_DBG_STOP;
6385# endif
6386#else
6387 NOREF(pDevIns);
6388 NOREF(pszFile);
6389 NOREF(iLine);
6390 NOREF(pszFunction);
6391 NOREF(pszFormat);
6392 return VINF_SUCCESS;
6393#endif
6394}
6395
6396#ifdef IN_RING3
6397
6398/**
6399 * @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister
6400 */
6401DECLINLINE(int) PDMDevHlpDBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
6402{
6403 return pDevIns->pHlpR3->pfnDBGFInfoRegister(pDevIns, pszName, pszDesc, pfnHandler);
6404}
6405
6406/**
6407 * @copydoc PDMDEVHLPR3::pfnDBGFInfoRegisterArgv
6408 */
6409DECLINLINE(int) PDMDevHlpDBGFInfoRegisterArgv(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFINFOARGVDEV pfnHandler)
6410{
6411 return pDevIns->pHlpR3->pfnDBGFInfoRegisterArgv(pDevIns, pszName, pszDesc, pfnHandler);
6412}
6413
6414/**
6415 * @copydoc PDMDEVHLPR3::pfnDBGFRegRegister
6416 */
6417DECLINLINE(int) PDMDevHlpDBGFRegRegister(PPDMDEVINS pDevIns, PCDBGFREGDESC paRegisters)
6418{
6419 return pDevIns->pHlpR3->pfnDBGFRegRegister(pDevIns, paRegisters);
6420}
6421
6422/**
6423 * @copydoc PDMDEVHLPR3::pfnSTAMRegister
6424 */
6425DECLINLINE(void) PDMDevHlpSTAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
6426{
6427 pDevIns->pHlpR3->pfnSTAMRegister(pDevIns, pvSample, enmType, pszName, enmUnit, pszDesc);
6428}
6429
6430/**
6431 * @copydoc PDMDEVHLPR3::pfnSTAMRegisterF
6432 */
6433DECLINLINE(void) RT_IPRT_FORMAT_ATTR(7, 8) PDMDevHlpSTAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType,
6434 STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
6435 const char *pszDesc, const char *pszName, ...)
6436{
6437 va_list va;
6438 va_start(va, pszName);
6439 pDevIns->pHlpR3->pfnSTAMRegisterV(pDevIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, va);
6440 va_end(va);
6441}
6442
6443/**
6444 * Registers the device with the default PCI bus.
6445 *
6446 * @returns VBox status code.
6447 * @param pDevIns The device instance.
6448 * @param pPciDev The PCI device structure.
6449 * This must be kept in the instance data.
6450 * The PCI configuration must be initialized before registration.
6451 */
6452DECLINLINE(int) PDMDevHlpPCIRegister(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev)
6453{
6454 return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev, 0 /*fFlags*/,
6455 PDMPCIDEVREG_DEV_NO_FIRST_UNUSED, PDMPCIDEVREG_FUN_NO_FIRST_UNUSED, NULL);
6456}
6457
6458/**
6459 * @copydoc PDMDEVHLPR3::pfnPCIRegister
6460 */
6461DECLINLINE(int) PDMDevHlpPCIRegisterEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t fFlags,
6462 uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName)
6463{
6464 return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName);
6465}
6466
6467/**
6468 * Initialize MSI emulation support for the first PCI device.
6469 *
6470 * @returns VBox status code.
6471 * @param pDevIns The device instance.
6472 * @param pMsiReg MSI emulation registration structure.
6473 */
6474DECLINLINE(int) PDMDevHlpPCIRegisterMsi(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg)
6475{
6476 return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, NULL, pMsiReg);
6477}
6478
6479/**
6480 * @copydoc PDMDEVHLPR3::pfnPCIRegisterMsi
6481 */
6482DECLINLINE(int) PDMDevHlpPCIRegisterMsiEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, PPDMMSIREG pMsiReg)
6483{
6484 return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, pPciDev, pMsiReg);
6485}
6486
6487/**
6488 * Registers a I/O region (memory mapped or I/O ports) for the default PCI
6489 * device.
6490 *
6491 * @returns VBox status code.
6492 * @param pDevIns The device instance.
6493 * @param iRegion The region number.
6494 * @param cbRegion Size of the region.
6495 * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
6496 * @param pfnCallback Callback for doing the mapping.
6497 * @remarks The callback will be invoked holding the PDM lock. The device lock
6498 * is NOT take because that is very likely be a lock order violation.
6499 */
6500DECLINLINE(int) PDMDevHlpPCIIORegionRegister(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRegion,
6501 PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
6502{
6503 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, NULL, iRegion, cbRegion, enmType,
6504 PDMPCIDEV_IORGN_F_NO_HANDLE, UINT64_MAX, pfnCallback);
6505}
6506
6507/**
6508 * @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister
6509 */
6510DECLINLINE(int) PDMDevHlpPCIIORegionRegisterEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion,
6511 PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
6512{
6513 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, pPciDev, iRegion, cbRegion, enmType,
6514 PDMPCIDEV_IORGN_F_NO_HANDLE, UINT64_MAX, pfnCallback);
6515}
6516
6517/**
6518 * Registers a I/O port region for the default PCI device.
6519 *
6520 * @returns VBox status code.
6521 * @param pDevIns The device instance.
6522 * @param iRegion The region number.
6523 * @param cbRegion Size of the region.
6524 * @param hIoPorts Handle to the I/O port region.
6525 * @param pfnCallback Callback for doing the mapping, optional. The
6526 * callback will be invoked holding only the PDM lock.
6527 * The device lock will _not_ be taken (due to lock
6528 * order).
6529 */
6530DECLINLINE(int) PDMDevHlpPCIIORegionRegisterIo(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRegion,
6531 IOMIOPORTHANDLE hIoPorts, PFNPCIIOREGIONMAP pfnCallback)
6532{
6533 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, NULL, iRegion, cbRegion, PCI_ADDRESS_SPACE_IO,
6534 PDMPCIDEV_IORGN_F_IOPORT_HANDLE, hIoPorts, pfnCallback);
6535}
6536
6537/**
6538 * Registers an MMIO port region for the default PCI device.
6539 *
6540 * @returns VBox status code.
6541 * @param pDevIns The device instance.
6542 * @param iRegion The region number.
6543 * @param cbRegion Size of the region.
6544 * @param enmType PCI_ADDRESS_SPACE_MEM or
6545 * PCI_ADDRESS_SPACE_MEM_PREFETCH, optionally or-ing in
6546 * PCI_ADDRESS_SPACE_BAR64 or PCI_ADDRESS_SPACE_BAR32.
6547 * @param hMmioRegion Handle to the MMIO region.
6548 * @param pfnCallback Callback for doing the mapping, optional. The
6549 * callback will be invoked holding only the PDM lock.
6550 * The device lock will _not_ be taken (due to lock
6551 * order).
6552 */
6553DECLINLINE(int) PDMDevHlpPCIIORegionRegisterMmio(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cbRegion, PCIADDRESSSPACE enmType,
6554 IOMMMIOHANDLE hMmioRegion, PFNPCIIOREGIONMAP pfnCallback)
6555{
6556 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, NULL, iRegion, cbRegion, enmType,
6557 PDMPCIDEV_IORGN_F_MMIO_HANDLE, hMmioRegion, pfnCallback);
6558}
6559
6560
6561/**
6562 * @copydoc PDMDEVHLPR3::pfnPCIInterceptConfigAccesses
6563 */
6564DECLINLINE(int) PDMDevHlpPCIInterceptConfigAccesses(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev,
6565 PFNPCICONFIGREAD pfnRead, PFNPCICONFIGWRITE pfnWrite)
6566{
6567 return pDevIns->pHlpR3->pfnPCIInterceptConfigAccesses(pDevIns, pPciDev, pfnRead, pfnWrite);
6568}
6569
6570/**
6571 * @copydoc PDMDEVHLPR3::pfnPCIConfigRead
6572 */
6573DECLINLINE(VBOXSTRICTRC) PDMDevHlpPCIConfigRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t uAddress,
6574 unsigned cb, uint32_t *pu32Value)
6575{
6576 return pDevIns->pHlpR3->pfnPCIConfigRead(pDevIns, pPciDev, uAddress, cb, pu32Value);
6577}
6578
6579/**
6580 * @copydoc PDMDEVHLPR3::pfnPCIConfigWrite
6581 */
6582DECLINLINE(VBOXSTRICTRC) PDMDevHlpPCIConfigWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t uAddress,
6583 unsigned cb, uint32_t u32Value)
6584{
6585 return pDevIns->pHlpR3->pfnPCIConfigWrite(pDevIns, pPciDev, uAddress, cb, u32Value);
6586}
6587
6588#endif /* IN_RING3 */
6589
6590/**
6591 * Bus master physical memory read from the default PCI device.
6592 *
6593 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_READ_BM_DISABLED, later maybe
6594 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
6595 * @param pDevIns The device instance.
6596 * @param GCPhys Physical address start reading from.
6597 * @param pvBuf Where to put the read bits.
6598 * @param cbRead How many bytes to read.
6599 * @thread Any thread, but the call may involve the emulation thread.
6600 */
6601DECLINLINE(int) PDMDevHlpPCIPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
6602{
6603 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, NULL, GCPhys, pvBuf, cbRead);
6604}
6605
6606/**
6607 * @copydoc PDMDEVHLPR3::pfnPCIPhysRead
6608 */
6609DECLINLINE(int) PDMDevHlpPCIPhysReadEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
6610{
6611 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysRead(pDevIns, pPciDev, GCPhys, pvBuf, cbRead);
6612}
6613
6614/**
6615 * Bus master physical memory write from the default PCI device.
6616 *
6617 * @returns VINF_SUCCESS or VERR_PGM_PCI_PHYS_WRITE_BM_DISABLED, later maybe
6618 * VERR_EM_MEMORY. The informational status shall NOT be propagated!
6619 * @param pDevIns The device instance.
6620 * @param GCPhys Physical address to write to.
6621 * @param pvBuf What to write.
6622 * @param cbWrite How many bytes to write.
6623 * @thread Any thread, but the call may involve the emulation thread.
6624 */
6625DECLINLINE(int) PDMDevHlpPCIPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
6626{
6627 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, NULL, GCPhys, pvBuf, cbWrite);
6628}
6629
6630/**
6631 * @copydoc PDMDEVHLPR3::pfnPCIPhysWrite
6632 */
6633DECLINLINE(int) PDMDevHlpPCIPhysWriteEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
6634{
6635 return pDevIns->CTX_SUFF(pHlp)->pfnPCIPhysWrite(pDevIns, pPciDev, GCPhys, pvBuf, cbWrite);
6636}
6637
6638/**
6639 * Sets the IRQ for the default PCI device.
6640 *
6641 * @param pDevIns The device instance.
6642 * @param iIrq IRQ number to set.
6643 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
6644 * @thread Any thread, but will involve the emulation thread.
6645 */
6646DECLINLINE(void) PDMDevHlpPCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
6647{
6648 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, NULL, iIrq, iLevel);
6649}
6650
6651/**
6652 * @copydoc PDMDEVHLPR3::pfnPCISetIrq
6653 */
6654DECLINLINE(void) PDMDevHlpPCISetIrqEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
6655{
6656 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, pPciDev, iIrq, iLevel);
6657}
6658
6659/**
6660 * Sets the IRQ for the given PCI device, but doesn't wait for EMT to process
6661 * the request when not called from EMT.
6662 *
6663 * @param pDevIns The device instance.
6664 * @param iIrq IRQ number to set.
6665 * @param iLevel IRQ level.
6666 * @thread Any thread, but will involve the emulation thread.
6667 */
6668DECLINLINE(void) PDMDevHlpPCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
6669{
6670 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, NULL, iIrq, iLevel);
6671}
6672
6673/**
6674 * @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait
6675 */
6676DECLINLINE(void) PDMDevHlpPCISetIrqNoWaitEx(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
6677{
6678 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, pPciDev, iIrq, iLevel);
6679}
6680
6681/**
6682 * @copydoc PDMDEVHLPR3::pfnISASetIrq
6683 */
6684DECLINLINE(void) PDMDevHlpISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
6685{
6686 pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
6687}
6688
6689/**
6690 * @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait
6691 */
6692DECLINLINE(void) PDMDevHlpISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
6693{
6694 pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
6695}
6696
6697/**
6698 * @copydoc PDMDEVHLPR3::pfnIoApicSendMsi
6699 */
6700DECLINLINE(void) PDMDevHlpIoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue)
6701{
6702 pDevIns->CTX_SUFF(pHlp)->pfnIoApicSendMsi(pDevIns, GCPhys, uValue);
6703}
6704
6705#ifdef IN_RING3
6706
6707/**
6708 * @copydoc PDMDEVHLPR3::pfnDriverAttach
6709 */
6710DECLINLINE(int) PDMDevHlpDriverAttach(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
6711{
6712 return pDevIns->pHlpR3->pfnDriverAttach(pDevIns, iLun, pBaseInterface, ppBaseInterface, pszDesc);
6713}
6714
6715/**
6716 * @copydoc PDMDEVHLPR3::pfnDriverDetach
6717 */
6718DECLINLINE(int) PDMDevHlpDriverDetach(PPDMDEVINS pDevIns, PPDMDRVINS pDrvIns, uint32_t fFlags)
6719{
6720 return pDevIns->pHlpR3->pfnDriverDetach(pDevIns, pDrvIns, fFlags);
6721}
6722
6723/**
6724 * @copydoc PDMDEVHLPR3::pfnQueueCreate
6725 */
6726DECLINLINE(int) PDMDevHlpQueueCreate(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
6727 PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue)
6728{
6729 return pDevIns->pHlpR3->pfnQueueCreate(pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fRZEnabled, pszName, ppQueue);
6730}
6731
6732/**
6733 * Initializes a PDM critical section.
6734 *
6735 * The PDM critical sections are derived from the IPRT critical sections, but
6736 * works in RC and R0 as well.
6737 *
6738 * @returns VBox status code.
6739 * @param pDevIns The device instance.
6740 * @param pCritSect Pointer to the critical section.
6741 * @param SRC_POS Use RT_SRC_POS.
6742 * @param pszNameFmt Format string for naming the critical section.
6743 * For statistics and lock validation.
6744 * @param ... Arguments for the format string.
6745 */
6746DECLINLINE(int) RT_IPRT_FORMAT_ATTR(6, 7) PDMDevHlpCritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
6747 const char *pszNameFmt, ...)
6748{
6749 int rc;
6750 va_list va;
6751 va_start(va, pszNameFmt);
6752 rc = pDevIns->pHlpR3->pfnCritSectInit(pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
6753 va_end(va);
6754 return rc;
6755}
6756
6757#endif /* IN_RING3 */
6758
6759/**
6760 * @copydoc PDMDEVHLPR3::pfnCritSectGetNop
6761 */
6762DECLINLINE(PPDMCRITSECT) PDMDevHlpCritSectGetNop(PPDMDEVINS pDevIns)
6763{
6764 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectGetNop(pDevIns);
6765}
6766
6767#ifdef IN_RING3
6768
6769/**
6770 * @copydoc PDMDEVHLPR3::pfnCritSectGetNopR0
6771 */
6772DECLINLINE(R0PTRTYPE(PPDMCRITSECT)) PDMDevHlpCritSectGetNopR0(PPDMDEVINS pDevIns)
6773{
6774 return pDevIns->pHlpR3->pfnCritSectGetNopR0(pDevIns);
6775}
6776
6777/**
6778 * @copydoc PDMDEVHLPR3::pfnCritSectGetNopRC
6779 */
6780DECLINLINE(RCPTRTYPE(PPDMCRITSECT)) PDMDevHlpCritSectGetNopRC(PPDMDEVINS pDevIns)
6781{
6782 return pDevIns->pHlpR3->pfnCritSectGetNopRC(pDevIns);
6783}
6784
6785#endif /* IN_RING3 */
6786
6787/**
6788 * @copydoc PDMDEVHLPR3::pfnSetDeviceCritSect
6789 */
6790DECLINLINE(int) PDMDevHlpSetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
6791{
6792 return pDevIns->CTX_SUFF(pHlp)->pfnSetDeviceCritSect(pDevIns, pCritSect);
6793}
6794
6795/**
6796 * @copydoc PDMCritSectEnter
6797 * @param pDevIns The device instance.
6798 */
6799DECLINLINE(int) PDMDevHlpCritSectEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy)
6800{
6801 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectEnter(pDevIns, pCritSect, rcBusy);
6802}
6803
6804/**
6805 * @copydoc PDMCritSectEnterDebug
6806 * @param pDevIns The device instance.
6807 */
6808DECLINLINE(int) PDMDevHlpCritSectEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL)
6809{
6810 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectEnterDebug(pDevIns, pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
6811}
6812
6813/**
6814 * @copydoc PDMCritSectTryEnter
6815 * @param pDevIns The device instance.
6816 */
6817DECLINLINE(int) PDMDevHlpCritSectTryEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
6818{
6819 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectTryEnter(pDevIns, pCritSect);
6820}
6821
6822/**
6823 * @copydoc PDMCritSectTryEnterDebug
6824 * @param pDevIns The device instance.
6825 */
6826DECLINLINE(int) PDMDevHlpCritSectTryEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL)
6827{
6828 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectTryEnterDebug(pDevIns, pCritSect, uId, RT_SRC_POS_ARGS);
6829}
6830
6831/**
6832 * @copydoc PDMCritSectLeave
6833 * @param pDevIns The device instance.
6834 */
6835DECLINLINE(int) PDMDevHlpCritSectLeave(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
6836{
6837 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectLeave(pDevIns, pCritSect);
6838}
6839
6840/**
6841 * @copydoc PDMCritSectIsOwner
6842 * @param pDevIns The device instance.
6843 */
6844DECLINLINE(bool) PDMDevHlpCritSectIsOwner(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
6845{
6846 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectIsOwner(pDevIns, pCritSect);
6847}
6848
6849/**
6850 * @copydoc PDMCritSectIsInitialized
6851 * @param pDevIns The device instance.
6852 */
6853DECLINLINE(bool) PDMDevHlpCritSectIsInitialized(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
6854{
6855 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectIsInitialized(pDevIns, pCritSect);
6856}
6857
6858/**
6859 * @copydoc PDMCritSectHasWaiters
6860 * @param pDevIns The device instance.
6861 */
6862DECLINLINE(bool) PDMDevHlpCritSectHasWaiters(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
6863{
6864 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectHasWaiters(pDevIns, pCritSect);
6865}
6866
6867/**
6868 * @copydoc PDMCritSectGetRecursion
6869 * @param pDevIns The device instance.
6870 */
6871DECLINLINE(uint32_t) PDMDevHlpCritSectGetRecursion(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
6872{
6873 return pDevIns->CTX_SUFF(pHlp)->pfnCritSectGetRecursion(pDevIns, pCritSect);
6874}
6875
6876/* Strict build: Remap the two enter calls to the debug versions. */
6877#ifdef VBOX_STRICT
6878# ifdef IPRT_INCLUDED_asm_h
6879# define PDMDevHlpCritSectEnter(pDevIns, pCritSect, rcBusy) PDMDevHlpCritSectEnterDebug((pDevIns), (pCritSect), (rcBusy), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
6880# define PDMDevHlpCritSectTryEnter(pDevIns, pCritSect) PDMDevHlpCritSectTryEnterDebug((pDevIns), (pCritSect), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
6881# else
6882# define PDMDevHlpCritSectEnter(pDevIns, pCritSect, rcBusy) PDMDevHlpCritSectEnterDebug((pDevIns), (pCritSect), (rcBusy), 0, RT_SRC_POS)
6883# define PDMDevHlpCritSectTryEnter(pDevIns, pCritSect) PDMDevHlpCritSectTryEnterDebug((pDevIns), (pCritSect), 0, RT_SRC_POS)
6884# endif
6885#endif
6886
6887#ifdef IN_RING3
6888
6889/**
6890 * @copydoc PDMDEVHLPR3::pfnThreadCreate
6891 */
6892DECLINLINE(int) PDMDevHlpThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
6893 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
6894{
6895 return pDevIns->pHlpR3->pfnThreadCreate(pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
6896}
6897
6898/**
6899 * @copydoc PDMDEVHLPR3::pfnSetAsyncNotification
6900 */
6901DECLINLINE(int) PDMDevHlpSetAsyncNotification(PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)
6902{
6903 return pDevIns->pHlpR3->pfnSetAsyncNotification(pDevIns, pfnAsyncNotify);
6904}
6905
6906/**
6907 * @copydoc PDMDEVHLPR3::pfnAsyncNotificationCompleted
6908 */
6909DECLINLINE(void) PDMDevHlpAsyncNotificationCompleted(PPDMDEVINS pDevIns)
6910{
6911 pDevIns->pHlpR3->pfnAsyncNotificationCompleted(pDevIns);
6912}
6913
6914/**
6915 * @copydoc PDMDEVHLPR3::pfnA20Set
6916 */
6917DECLINLINE(void) PDMDevHlpA20Set(PPDMDEVINS pDevIns, bool fEnable)
6918{
6919 pDevIns->pHlpR3->pfnA20Set(pDevIns, fEnable);
6920}
6921
6922/**
6923 * @copydoc PDMDEVHLPR3::pfnRTCRegister
6924 */
6925DECLINLINE(int) PDMDevHlpRTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
6926{
6927 return pDevIns->pHlpR3->pfnRTCRegister(pDevIns, pRtcReg, ppRtcHlp);
6928}
6929
6930/**
6931 * @copydoc PDMDEVHLPR3::pfnPCIBusRegister
6932 */
6933DECLINLINE(int) PDMDevHlpPCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREGR3 pPciBusReg, PCPDMPCIHLPR3 *ppPciHlp, uint32_t *piBus)
6934{
6935 return pDevIns->pHlpR3->pfnPCIBusRegister(pDevIns, pPciBusReg, ppPciHlp, piBus);
6936}
6937
6938/**
6939 * @copydoc PDMDEVHLPR3::pfnPICRegister
6940 */
6941DECLINLINE(int) PDMDevHlpPICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
6942{
6943 return pDevIns->pHlpR3->pfnPICRegister(pDevIns, pPicReg, ppPicHlpR3);
6944}
6945
6946/**
6947 * @copydoc PDMDEVHLPR3::pfnAPICRegister
6948 */
6949DECLINLINE(int) PDMDevHlpAPICRegister(PPDMDEVINS pDevIns)
6950{
6951 return pDevIns->pHlpR3->pfnAPICRegister(pDevIns);
6952}
6953
6954/**
6955 * @copydoc PDMDEVHLPR3::pfnIOAPICRegister
6956 */
6957DECLINLINE(int) PDMDevHlpIOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
6958{
6959 return pDevIns->pHlpR3->pfnIOAPICRegister(pDevIns, pIoApicReg, ppIoApicHlpR3);
6960}
6961
6962/**
6963 * @copydoc PDMDEVHLPR3::pfnHPETRegister
6964 */
6965DECLINLINE(int) PDMDevHlpHPETRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
6966{
6967 return pDevIns->pHlpR3->pfnHPETRegister(pDevIns, pHpetReg, ppHpetHlpR3);
6968}
6969
6970/**
6971 * @copydoc PDMDEVHLPR3::pfnPciRawRegister
6972 */
6973DECLINLINE(int) PDMDevHlpPciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
6974{
6975 return pDevIns->pHlpR3->pfnPciRawRegister(pDevIns, pPciRawReg, ppPciRawHlpR3);
6976}
6977
6978/**
6979 * @copydoc PDMDEVHLPR3::pfnDMACRegister
6980 */
6981DECLINLINE(int) PDMDevHlpDMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
6982{
6983 return pDevIns->pHlpR3->pfnDMACRegister(pDevIns, pDmacReg, ppDmacHlp);
6984}
6985
6986/**
6987 * @copydoc PDMDEVHLPR3::pfnDMARegister
6988 */
6989DECLINLINE(int) PDMDevHlpDMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
6990{
6991 return pDevIns->pHlpR3->pfnDMARegister(pDevIns, uChannel, pfnTransferHandler, pvUser);
6992}
6993
6994/**
6995 * @copydoc PDMDEVHLPR3::pfnDMAReadMemory
6996 */
6997DECLINLINE(int) PDMDevHlpDMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
6998{
6999 return pDevIns->pHlpR3->pfnDMAReadMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbRead);
7000}
7001
7002/**
7003 * @copydoc PDMDEVHLPR3::pfnDMAWriteMemory
7004 */
7005DECLINLINE(int) PDMDevHlpDMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
7006{
7007 return pDevIns->pHlpR3->pfnDMAWriteMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbWritten);
7008}
7009
7010/**
7011 * @copydoc PDMDEVHLPR3::pfnDMASetDREQ
7012 */
7013DECLINLINE(int) PDMDevHlpDMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
7014{
7015 return pDevIns->pHlpR3->pfnDMASetDREQ(pDevIns, uChannel, uLevel);
7016}
7017
7018/**
7019 * @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode
7020 */
7021DECLINLINE(uint8_t) PDMDevHlpDMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
7022{
7023 return pDevIns->pHlpR3->pfnDMAGetChannelMode(pDevIns, uChannel);
7024}
7025
7026/**
7027 * @copydoc PDMDEVHLPR3::pfnDMASchedule
7028 */
7029DECLINLINE(void) PDMDevHlpDMASchedule(PPDMDEVINS pDevIns)
7030{
7031 pDevIns->pHlpR3->pfnDMASchedule(pDevIns);
7032}
7033
7034/**
7035 * @copydoc PDMDEVHLPR3::pfnCMOSWrite
7036 */
7037DECLINLINE(int) PDMDevHlpCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
7038{
7039 return pDevIns->pHlpR3->pfnCMOSWrite(pDevIns, iReg, u8Value);
7040}
7041
7042/**
7043 * @copydoc PDMDEVHLPR3::pfnCMOSRead
7044 */
7045DECLINLINE(int) PDMDevHlpCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
7046{
7047 return pDevIns->pHlpR3->pfnCMOSRead(pDevIns, iReg, pu8Value);
7048}
7049
7050/**
7051 * @copydoc PDMDEVHLPR3::pfnCallR0
7052 */
7053DECLINLINE(int) PDMDevHlpCallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)
7054{
7055 return pDevIns->pHlpR3->pfnCallR0(pDevIns, uOperation, u64Arg);
7056}
7057
7058/**
7059 * @copydoc PDMDEVHLPR3::pfnVMGetSuspendReason
7060 */
7061DECLINLINE(VMSUSPENDREASON) PDMDevHlpVMGetSuspendReason(PPDMDEVINS pDevIns)
7062{
7063 return pDevIns->pHlpR3->pfnVMGetSuspendReason(pDevIns);
7064}
7065
7066/**
7067 * @copydoc PDMDEVHLPR3::pfnVMGetResumeReason
7068 */
7069DECLINLINE(VMRESUMEREASON) PDMDevHlpVMGetResumeReason(PPDMDEVINS pDevIns)
7070{
7071 return pDevIns->pHlpR3->pfnVMGetResumeReason(pDevIns);
7072}
7073
7074/**
7075 * @copydoc PDMDEVHLPR3::pfnGetUVM
7076 */
7077DECLINLINE(PUVM) PDMDevHlpGetUVM(PPDMDEVINS pDevIns)
7078{
7079 return pDevIns->CTX_SUFF(pHlp)->pfnGetUVM(pDevIns);
7080}
7081
7082#else /* !IN_RING3 */
7083
7084/**
7085 * @copydoc PDMDEVHLPR0::pfnPCIBusSetUp
7086 */
7087DECLINLINE(int) PDMDevHlpPCIBusSetUpContext(PPDMDEVINS pDevIns, CTX_SUFF(PPDMPCIBUSREG) pPciBusReg, CTX_SUFF(PCPDMPCIHLP) *ppPciHlp)
7088{
7089 return pDevIns->CTX_SUFF(pHlp)->pfnPCIBusSetUpContext(pDevIns, pPciBusReg, ppPciHlp);
7090}
7091
7092#endif /* !IN_RING3 */
7093
7094/**
7095 * @copydoc PDMDEVHLPR3::pfnGetVM
7096 */
7097DECLINLINE(PVMCC) PDMDevHlpGetVM(PPDMDEVINS pDevIns)
7098{
7099 return pDevIns->CTX_SUFF(pHlp)->pfnGetVM(pDevIns);
7100}
7101
7102/**
7103 * @copydoc PDMDEVHLPR3::pfnGetVMCPU
7104 */
7105DECLINLINE(PVMCPUCC) PDMDevHlpGetVMCPU(PPDMDEVINS pDevIns)
7106{
7107 return pDevIns->CTX_SUFF(pHlp)->pfnGetVMCPU(pDevIns);
7108}
7109
7110/**
7111 * @copydoc PDMDEVHLPR3::pfnGetCurrentCpuId
7112 */
7113DECLINLINE(VMCPUID) PDMDevHlpGetCurrentCpuId(PPDMDEVINS pDevIns)
7114{
7115 return pDevIns->CTX_SUFF(pHlp)->pfnGetCurrentCpuId(pDevIns);
7116}
7117
7118/**
7119 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGet
7120 */
7121DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGet(PPDMDEVINS pDevIns)
7122{
7123 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGet(pDevIns);
7124}
7125
7126/**
7127 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
7128 */
7129DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetFreq(PPDMDEVINS pDevIns)
7130{
7131 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetFreq(pDevIns);
7132}
7133
7134/**
7135 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
7136 */
7137DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetNano(PPDMDEVINS pDevIns)
7138{
7139 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetNano(pDevIns);
7140}
7141
7142#ifdef IN_RING3
7143
7144/**
7145 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap
7146 */
7147DECLINLINE(int) PDMDevHlpRegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbHeap)
7148{
7149 return pDevIns->pHlpR3->pfnRegisterVMMDevHeap(pDevIns, GCPhys, pvHeap, cbHeap);
7150}
7151
7152/**
7153 * @copydoc PDMDEVHLPR3::pfnFirmwareRegister
7154 */
7155DECLINLINE(int) PDMDevHlpFirmwareRegister(PPDMDEVINS pDevIns, PCPDMFWREG pFwReg, PCPDMFWHLPR3 *ppFwHlp)
7156{
7157 return pDevIns->pHlpR3->pfnFirmwareRegister(pDevIns, pFwReg, ppFwHlp);
7158}
7159
7160/**
7161 * @copydoc PDMDEVHLPR3::pfnVMReset
7162 */
7163DECLINLINE(int) PDMDevHlpVMReset(PPDMDEVINS pDevIns, uint32_t fFlags)
7164{
7165 return pDevIns->pHlpR3->pfnVMReset(pDevIns, fFlags);
7166}
7167
7168/**
7169 * @copydoc PDMDEVHLPR3::pfnVMSuspend
7170 */
7171DECLINLINE(int) PDMDevHlpVMSuspend(PPDMDEVINS pDevIns)
7172{
7173 return pDevIns->pHlpR3->pfnVMSuspend(pDevIns);
7174}
7175
7176/**
7177 * @copydoc PDMDEVHLPR3::pfnVMSuspendSaveAndPowerOff
7178 */
7179DECLINLINE(int) PDMDevHlpVMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
7180{
7181 return pDevIns->pHlpR3->pfnVMSuspendSaveAndPowerOff(pDevIns);
7182}
7183
7184/**
7185 * @copydoc PDMDEVHLPR3::pfnVMPowerOff
7186 */
7187DECLINLINE(int) PDMDevHlpVMPowerOff(PPDMDEVINS pDevIns)
7188{
7189 return pDevIns->pHlpR3->pfnVMPowerOff(pDevIns);
7190}
7191
7192#endif /* IN_RING3 */
7193
7194/**
7195 * @copydoc PDMDEVHLPR3::pfnA20IsEnabled
7196 */
7197DECLINLINE(bool) PDMDevHlpA20IsEnabled(PPDMDEVINS pDevIns)
7198{
7199 return pDevIns->CTX_SUFF(pHlp)->pfnA20IsEnabled(pDevIns);
7200}
7201
7202#ifdef IN_RING3
7203
7204/**
7205 * @copydoc PDMDEVHLPR3::pfnGetCpuId
7206 */
7207DECLINLINE(void) PDMDevHlpGetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
7208{
7209 pDevIns->pHlpR3->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx);
7210}
7211
7212/**
7213 * @copydoc PDMDEVHLPR3::pfnGetSupDrvSession
7214 */
7215DECLINLINE(PSUPDRVSESSION) PDMDevHlpGetSupDrvSession(PPDMDEVINS pDevIns)
7216{
7217 return pDevIns->pHlpR3->pfnGetSupDrvSession(pDevIns);
7218}
7219
7220/**
7221 * @copydoc PDMDEVHLPR3::pfnQueryGenericUserObject
7222 */
7223DECLINLINE(void *) PDMDevHlpQueryGenericUserObject(PPDMDEVINS pDevIns, PCRTUUID pUuid)
7224{
7225 return pDevIns->pHlpR3->pfnQueryGenericUserObject(pDevIns, pUuid);
7226}
7227
7228#endif /* IN_RING3 */
7229
7230/** Pointer to callbacks provided to the VBoxDeviceRegister() call. */
7231typedef struct PDMDEVREGCB *PPDMDEVREGCB;
7232
7233/**
7234 * Callbacks for VBoxDeviceRegister().
7235 */
7236typedef struct PDMDEVREGCB
7237{
7238 /** Interface version.
7239 * This is set to PDM_DEVREG_CB_VERSION. */
7240 uint32_t u32Version;
7241
7242 /**
7243 * Registers a device with the current VM instance.
7244 *
7245 * @returns VBox status code.
7246 * @param pCallbacks Pointer to the callback table.
7247 * @param pReg Pointer to the device registration record.
7248 * This data must be permanent and readonly.
7249 */
7250 DECLR3CALLBACKMEMBER(int, pfnRegister,(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pReg));
7251} PDMDEVREGCB;
7252
7253/** Current version of the PDMDEVREGCB structure. */
7254#define PDM_DEVREG_CB_VERSION PDM_VERSION_MAKE(0xffe3, 1, 0)
7255
7256
7257/**
7258 * The VBoxDevicesRegister callback function.
7259 *
7260 * PDM will invoke this function after loading a device module and letting
7261 * the module decide which devices to register and how to handle conflicts.
7262 *
7263 * @returns VBox status code.
7264 * @param pCallbacks Pointer to the callback table.
7265 * @param u32Version VBox version number.
7266 */
7267typedef DECLCALLBACK(int) FNPDMVBOXDEVICESREGISTER(PPDMDEVREGCB pCallbacks, uint32_t u32Version);
7268
7269/** @} */
7270
7271RT_C_DECLS_END
7272
7273#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