VirtualBox

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

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

PDM,++: Change APIs used by Main from PVM to PUVM.

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