VirtualBox

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

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

VMM,Devices: Some PDM device model refactoring. [doxyfix] bugref:9218

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