VirtualBox

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

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

VMM: APIC refactor. Moved APIC base MSR to the VCPU (where it belongs) for lockless accesses.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 193.6 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 * Gets the VM handle. Restricted API.
3403 *
3404 * @returns VM Handle.
3405 * @param pDevIns The device instance.
3406 */
3407 DECLR3CALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
3408
3409 /**
3410 * Gets the VMCPU handle. Restricted API.
3411 *
3412 * @returns VMCPU Handle.
3413 * @param pDevIns The device instance.
3414 */
3415 DECLR3CALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
3416
3417 /**
3418 * Registers the VMM device heap
3419 *
3420 * @returns VBox status code.
3421 * @param pDevIns The device instance.
3422 * @param GCPhys The physical address.
3423 * @param pvHeap Ring 3 heap pointer.
3424 * @param cbSize Size of the heap.
3425 * @thread EMT.
3426 */
3427 DECLR3CALLBACKMEMBER(int, pfnRegisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize));
3428
3429 /**
3430 * Unregisters the VMM device heap
3431 *
3432 * @returns VBox status code.
3433 * @param pDevIns The device instance.
3434 * @param GCPhys The physical address.
3435 * @thread EMT.
3436 */
3437 DECLR3CALLBACKMEMBER(int, pfnUnregisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys));
3438
3439 /**
3440 * Resets the VM.
3441 *
3442 * @returns The appropriate VBox status code to pass around on reset.
3443 * @param pDevIns The device instance.
3444 * @thread The emulation thread.
3445 */
3446 DECLR3CALLBACKMEMBER(int, pfnVMReset,(PPDMDEVINS pDevIns));
3447
3448 /**
3449 * Suspends the VM.
3450 *
3451 * @returns The appropriate VBox status code to pass around on suspend.
3452 * @param pDevIns The device instance.
3453 * @thread The emulation thread.
3454 */
3455 DECLR3CALLBACKMEMBER(int, pfnVMSuspend,(PPDMDEVINS pDevIns));
3456
3457 /**
3458 * Suspends, saves and powers off the VM.
3459 *
3460 * @returns The appropriate VBox status code to pass around.
3461 * @param pDevIns The device instance.
3462 * @thread An emulation thread.
3463 */
3464 DECLR3CALLBACKMEMBER(int, pfnVMSuspendSaveAndPowerOff,(PPDMDEVINS pDevIns));
3465
3466 /**
3467 * Power off the VM.
3468 *
3469 * @returns The appropriate VBox status code to pass around on power off.
3470 * @param pDevIns The device instance.
3471 * @thread The emulation thread.
3472 */
3473 DECLR3CALLBACKMEMBER(int, pfnVMPowerOff,(PPDMDEVINS pDevIns));
3474
3475 /**
3476 * Checks if the Gate A20 is enabled or not.
3477 *
3478 * @returns true if A20 is enabled.
3479 * @returns false if A20 is disabled.
3480 * @param pDevIns The device instance.
3481 * @thread The emulation thread.
3482 */
3483 DECLR3CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
3484
3485 /**
3486 * Enables or disables the Gate A20.
3487 *
3488 * @param pDevIns The device instance.
3489 * @param fEnable Set this flag to enable the Gate A20; clear it
3490 * to disable.
3491 * @thread The emulation thread.
3492 */
3493 DECLR3CALLBACKMEMBER(void, pfnA20Set,(PPDMDEVINS pDevIns, bool fEnable));
3494
3495 /**
3496 * Get the specified CPUID leaf for the virtual CPU associated with the calling
3497 * thread.
3498 *
3499 * @param pDevIns The device instance.
3500 * @param iLeaf The CPUID leaf to get.
3501 * @param pEax Where to store the EAX value.
3502 * @param pEbx Where to store the EBX value.
3503 * @param pEcx Where to store the ECX value.
3504 * @param pEdx Where to store the EDX value.
3505 * @thread EMT.
3506 */
3507 DECLR3CALLBACKMEMBER(void, pfnGetCpuId,(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx));
3508
3509 /**
3510 * Get the current virtual clock time in a VM. The clock frequency must be
3511 * queried separately.
3512 *
3513 * @returns Current clock time.
3514 * @param pDevIns The device instance.
3515 */
3516 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
3517
3518 /**
3519 * Get the frequency of the virtual clock.
3520 *
3521 * @returns The clock frequency (not variable at run-time).
3522 * @param pDevIns The device instance.
3523 */
3524 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
3525
3526 /**
3527 * Get the current virtual clock time in a VM, in nanoseconds.
3528 *
3529 * @returns Current clock time (in ns).
3530 * @param pDevIns The device instance.
3531 */
3532 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
3533
3534 /** @} */
3535
3536 /** Just a safety precaution. (PDM_DEVHLPR3_VERSION) */
3537 uint32_t u32TheEnd;
3538} PDMDEVHLPR3;
3539#endif /* !IN_RING3 */
3540/** Pointer to the R3 PDM Device API. */
3541typedef R3PTRTYPE(struct PDMDEVHLPR3 *) PPDMDEVHLPR3;
3542/** Pointer to the R3 PDM Device API, const variant. */
3543typedef R3PTRTYPE(const struct PDMDEVHLPR3 *) PCPDMDEVHLPR3;
3544
3545/** Current PDMDEVHLPR3 version number. */
3546#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE(0xffe7, 9, 0)
3547
3548
3549/**
3550 * PDM Device API - RC Variant.
3551 */
3552typedef struct PDMDEVHLPRC
3553{
3554 /** Structure version. PDM_DEVHLPRC_VERSION defines the current version. */
3555 uint32_t u32Version;
3556
3557 /**
3558 * Reads data via bus mastering, if enabled. If no bus mastering is available,
3559 * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
3560 *
3561 * @return IPRT status code.
3562 */
3563 DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
3564
3565 /**
3566 * Writes data via bus mastering, if enabled. If no bus mastering is available,
3567 * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
3568 *
3569 * @return IPRT status code.
3570 */
3571 DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
3572
3573 /**
3574 * Set the IRQ for a PCI device.
3575 *
3576 * @param pDevIns Device instance.
3577 * @param iIrq IRQ number to set.
3578 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3579 * @thread Any thread, but will involve the emulation thread.
3580 */
3581 DECLRCCALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3582
3583 /**
3584 * Set ISA IRQ for a device.
3585 *
3586 * @param pDevIns Device instance.
3587 * @param iIrq IRQ number to set.
3588 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3589 * @thread Any thread, but will involve the emulation thread.
3590 */
3591 DECLRCCALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3592
3593 /**
3594 * Read physical memory.
3595 *
3596 * @returns VINF_SUCCESS (for now).
3597 * @param pDevIns Device instance.
3598 * @param GCPhys Physical address start reading from.
3599 * @param pvBuf Where to put the read bits.
3600 * @param cbRead How many bytes to read.
3601 */
3602 DECLRCCALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
3603
3604 /**
3605 * Write to physical memory.
3606 *
3607 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
3608 * @param pDevIns Device instance.
3609 * @param GCPhys Physical address to write to.
3610 * @param pvBuf What to write.
3611 * @param cbWrite How many bytes to write.
3612 */
3613 DECLRCCALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
3614
3615 /**
3616 * Checks if the Gate A20 is enabled or not.
3617 *
3618 * @returns true if A20 is enabled.
3619 * @returns false if A20 is disabled.
3620 * @param pDevIns Device instance.
3621 * @thread The emulation thread.
3622 */
3623 DECLRCCALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
3624
3625 /**
3626 * Gets the VM state.
3627 *
3628 * @returns VM state.
3629 * @param pDevIns The device instance.
3630 * @thread Any thread (just keep in mind that it's volatile info).
3631 */
3632 DECLRCCALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
3633
3634 /**
3635 * Set the VM error message
3636 *
3637 * @returns rc.
3638 * @param pDrvIns Driver instance.
3639 * @param rc VBox status code.
3640 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3641 * @param pszFormat Error message format string.
3642 * @param ... Error message arguments.
3643 */
3644 DECLRCCALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
3645
3646 /**
3647 * Set the VM error message
3648 *
3649 * @returns rc.
3650 * @param pDrvIns Driver instance.
3651 * @param rc VBox status code.
3652 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3653 * @param pszFormat Error message format string.
3654 * @param va Error message arguments.
3655 */
3656 DECLRCCALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
3657
3658 /**
3659 * Set the VM runtime error message
3660 *
3661 * @returns VBox status code.
3662 * @param pDevIns Device instance.
3663 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3664 * @param pszErrorId Error ID string.
3665 * @param pszFormat Error message format string.
3666 * @param ... Error message arguments.
3667 */
3668 DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
3669
3670 /**
3671 * Set the VM runtime error message
3672 *
3673 * @returns VBox status code.
3674 * @param pDevIns Device instance.
3675 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3676 * @param pszErrorId Error ID string.
3677 * @param pszFormat Error message format string.
3678 * @param va Error message arguments.
3679 */
3680 DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
3681
3682 /**
3683 * Set parameters for pending MMIO patch operation
3684 *
3685 * @returns VBox status code.
3686 * @param pDevIns Device instance.
3687 * @param GCPhys MMIO physical address
3688 * @param pCachedData GC pointer to cached data
3689 */
3690 DECLRCCALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
3691
3692 /**
3693 * Gets the VM handle. Restricted API.
3694 *
3695 * @returns VM Handle.
3696 * @param pDevIns Device instance.
3697 */
3698 DECLRCCALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
3699
3700 /**
3701 * Gets the VMCPU handle. Restricted API.
3702 *
3703 * @returns VMCPU Handle.
3704 * @param pDevIns The device instance.
3705 */
3706 DECLRCCALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
3707
3708 /**
3709 * Get the current virtual clock time in a VM. The clock frequency must be
3710 * queried separately.
3711 *
3712 * @returns Current clock time.
3713 * @param pDevIns The device instance.
3714 */
3715 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
3716
3717 /**
3718 * Get the frequency of the virtual clock.
3719 *
3720 * @returns The clock frequency (not variable at run-time).
3721 * @param pDevIns The device instance.
3722 */
3723 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
3724
3725 /**
3726 * Get the current virtual clock time in a VM, in nanoseconds.
3727 *
3728 * @returns Current clock time (in ns).
3729 * @param pDevIns The device instance.
3730 */
3731 DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
3732
3733 /**
3734 * Gets the trace buffer handle.
3735 *
3736 * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
3737 * really inteded for direct usage, thus no inline wrapper function.
3738 *
3739 * @returns Trace buffer handle or NIL_RTTRACEBUF.
3740 * @param pDevIns The device instance.
3741 */
3742 DECLRCCALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
3743
3744 /** Just a safety precaution. */
3745 uint32_t u32TheEnd;
3746} PDMDEVHLPRC;
3747/** Pointer PDM Device RC API. */
3748typedef RCPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC;
3749/** Pointer PDM Device RC API. */
3750typedef RCPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC;
3751
3752/** Current PDMDEVHLP version number. */
3753#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 3, 0)
3754
3755
3756/**
3757 * PDM Device API - R0 Variant.
3758 */
3759typedef struct PDMDEVHLPR0
3760{
3761 /** Structure version. PDM_DEVHLPR0_VERSION defines the current version. */
3762 uint32_t u32Version;
3763
3764 /**
3765 * Reads data via bus mastering, if enabled. If no bus mastering is available,
3766 * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
3767 *
3768 * @return IPRT status code.
3769 */
3770 DECLR0CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
3771
3772 /**
3773 * Writes data via bus mastering, if enabled. If no bus mastering is available,
3774 * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
3775 *
3776 * @return IPRT status code.
3777 */
3778 DECLR0CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
3779
3780 /**
3781 * Set the IRQ for a PCI device.
3782 *
3783 * @param pDevIns Device instance.
3784 * @param iIrq IRQ number to set.
3785 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3786 * @thread Any thread, but will involve the emulation thread.
3787 */
3788 DECLR0CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3789
3790 /**
3791 * Set ISA IRQ for a device.
3792 *
3793 * @param pDevIns Device instance.
3794 * @param iIrq IRQ number to set.
3795 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
3796 * @thread Any thread, but will involve the emulation thread.
3797 */
3798 DECLR0CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
3799
3800 /**
3801 * Read physical memory.
3802 *
3803 * @returns VINF_SUCCESS (for now).
3804 * @param pDevIns Device instance.
3805 * @param GCPhys Physical address start reading from.
3806 * @param pvBuf Where to put the read bits.
3807 * @param cbRead How many bytes to read.
3808 */
3809 DECLR0CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
3810
3811 /**
3812 * Write to physical memory.
3813 *
3814 * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
3815 * @param pDevIns Device instance.
3816 * @param GCPhys Physical address to write to.
3817 * @param pvBuf What to write.
3818 * @param cbWrite How many bytes to write.
3819 */
3820 DECLR0CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
3821
3822 /**
3823 * Checks if the Gate A20 is enabled or not.
3824 *
3825 * @returns true if A20 is enabled.
3826 * @returns false if A20 is disabled.
3827 * @param pDevIns Device instance.
3828 * @thread The emulation thread.
3829 */
3830 DECLR0CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
3831
3832 /**
3833 * Gets the VM state.
3834 *
3835 * @returns VM state.
3836 * @param pDevIns The device instance.
3837 * @thread Any thread (just keep in mind that it's volatile info).
3838 */
3839 DECLR0CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
3840
3841 /**
3842 * Set the VM error message
3843 *
3844 * @returns rc.
3845 * @param pDrvIns Driver instance.
3846 * @param rc VBox status code.
3847 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3848 * @param pszFormat Error message format string.
3849 * @param ... Error message arguments.
3850 */
3851 DECLR0CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
3852
3853 /**
3854 * Set the VM error message
3855 *
3856 * @returns rc.
3857 * @param pDrvIns Driver instance.
3858 * @param rc VBox status code.
3859 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3860 * @param pszFormat Error message format string.
3861 * @param va Error message arguments.
3862 */
3863 DECLR0CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
3864
3865 /**
3866 * Set the VM runtime error message
3867 *
3868 * @returns VBox status code.
3869 * @param pDevIns Device instance.
3870 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3871 * @param pszErrorId Error ID string.
3872 * @param pszFormat Error message format string.
3873 * @param ... Error message arguments.
3874 */
3875 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
3876
3877 /**
3878 * Set the VM runtime error message
3879 *
3880 * @returns VBox status code.
3881 * @param pDevIns Device instance.
3882 * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
3883 * @param pszErrorId Error ID string.
3884 * @param pszFormat Error message format string.
3885 * @param va Error message arguments.
3886 */
3887 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
3888
3889 /**
3890 * Set parameters for pending MMIO patch operation
3891 *
3892 * @returns rc.
3893 * @param pDevIns Device instance.
3894 * @param GCPhys MMIO physical address
3895 * @param pCachedData GC pointer to cached data
3896 */
3897 DECLR0CALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
3898
3899 /**
3900 * Gets the VM handle. Restricted API.
3901 *
3902 * @returns VM Handle.
3903 * @param pDevIns Device instance.
3904 */
3905 DECLR0CALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
3906
3907 /**
3908 * Checks if our current CPU state allows for IO block emulation fallback to the recompiler
3909 *
3910 * @returns true = yes, false = no
3911 * @param pDevIns Device instance.
3912 */
3913 DECLR0CALLBACKMEMBER(bool, pfnCanEmulateIoBlock,(PPDMDEVINS pDevIns));
3914
3915 /**
3916 * Gets the VMCPU handle. Restricted API.
3917 *
3918 * @returns VMCPU Handle.
3919 * @param pDevIns The device instance.
3920 */
3921 DECLR0CALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
3922
3923 /**
3924 * Get the current virtual clock time in a VM. The clock frequency must be
3925 * queried separately.
3926 *
3927 * @returns Current clock time.
3928 * @param pDevIns The device instance.
3929 */
3930 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
3931
3932 /**
3933 * Get the frequency of the virtual clock.
3934 *
3935 * @returns The clock frequency (not variable at run-time).
3936 * @param pDevIns The device instance.
3937 */
3938 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
3939
3940 /**
3941 * Get the current virtual clock time in a VM, in nanoseconds.
3942 *
3943 * @returns Current clock time (in ns).
3944 * @param pDevIns The device instance.
3945 */
3946 DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
3947
3948 /**
3949 * Gets the trace buffer handle.
3950 *
3951 * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
3952 * really inteded for direct usage, thus no inline wrapper function.
3953 *
3954 * @returns Trace buffer handle or NIL_RTTRACEBUF.
3955 * @param pDevIns The device instance.
3956 */
3957 DECLR0CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
3958
3959 /** Just a safety precaution. */
3960 uint32_t u32TheEnd;
3961} PDMDEVHLPR0;
3962/** Pointer PDM Device R0 API. */
3963typedef R0PTRTYPE(struct PDMDEVHLPR0 *) PPDMDEVHLPR0;
3964/** Pointer PDM Device GC API. */
3965typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0;
3966
3967/** Current PDMDEVHLP version number. */
3968#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 3, 0)
3969
3970
3971
3972/**
3973 * PDM Device Instance.
3974 */
3975typedef struct PDMDEVINS
3976{
3977 /** Structure version. PDM_DEVINS_VERSION defines the current version. */
3978 uint32_t u32Version;
3979 /** Device instance number. */
3980 uint32_t iInstance;
3981
3982 /** Pointer the GC PDM Device API. */
3983 PCPDMDEVHLPRC pHlpRC;
3984 /** Pointer to device instance data. */
3985 RTRCPTR pvInstanceDataRC;
3986 /** The critical section for the device, see pCritSectXR3. */
3987 RCPTRTYPE(PPDMCRITSECT) pCritSectRoRC;
3988 /** Alignment padding. */
3989 RTRCPTR pAlignmentRC;
3990
3991 /** Pointer the R0 PDM Device API. */
3992 PCPDMDEVHLPR0 pHlpR0;
3993 /** Pointer to device instance data (R0). */
3994 RTR0PTR pvInstanceDataR0;
3995 /** The critical section for the device, see pCritSectXR3. */
3996 R0PTRTYPE(PPDMCRITSECT) pCritSectRoR0;
3997
3998 /** Pointer the HC PDM Device API. */
3999 PCPDMDEVHLPR3 pHlpR3;
4000 /** Pointer to device instance data. */
4001 RTR3PTR pvInstanceDataR3;
4002 /** The critical section for the device.
4003 *
4004 * TM and IOM will enter this critical section before calling into the device
4005 * code. PDM will when doing power on, power off, reset, suspend and resume
4006 * notifications. SSM will currently not, but this will be changed later on.
4007 *
4008 * The device gets a critical section automatically assigned to it before
4009 * the constructor is called. If the constructor wishes to use a different
4010 * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
4011 * very early on.
4012 */
4013 R3PTRTYPE(PPDMCRITSECT) pCritSectRoR3;
4014
4015 /** Pointer to device registration structure. */
4016 R3PTRTYPE(PCPDMDEVREG) pReg;
4017 /** Configuration handle. */
4018 R3PTRTYPE(PCFGMNODE) pCfg;
4019
4020 /** The base interface of the device.
4021 *
4022 * The device constructor initializes this if it has any
4023 * device level interfaces to export. To obtain this interface
4024 * call PDMR3QueryDevice(). */
4025 PDMIBASE IBase;
4026
4027 /** Tracing indicator. */
4028 uint32_t fTracing;
4029 /** The tracing ID of this device. */
4030 uint32_t idTracing;
4031#if HC_ARCH_BITS == 32
4032 /** Align the internal data more naturally. */
4033 uint32_t au32Padding[HC_ARCH_BITS == 32 ? 13 : 0];
4034#endif
4035
4036 /** Internal data. */
4037 union
4038 {
4039#ifdef PDMDEVINSINT_DECLARED
4040 PDMDEVINSINT s;
4041#endif
4042 uint8_t padding[HC_ARCH_BITS == 32 ? 72 : 112 + 0x28];
4043 } Internal;
4044
4045 /** Device instance data. The size of this area is defined
4046 * in the PDMDEVREG::cbInstanceData field. */
4047 char achInstanceData[8];
4048} PDMDEVINS;
4049
4050/** Current PDMDEVINS version number. */
4051#define PDM_DEVINS_VERSION PDM_VERSION_MAKE(0xffe4, 3, 0)
4052
4053/** Converts a pointer to the PDMDEVINS::IBase to a pointer to PDMDEVINS. */
4054#define PDMIBASE_2_PDMDEV(pInterface) ( (PPDMDEVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDEVINS, IBase)) )
4055
4056/**
4057 * Checks the structure versions of the device instance and device helpers,
4058 * returning if they are incompatible.
4059 *
4060 * This is for use in the constructor.
4061 *
4062 * @param pDevIns The device instance pointer.
4063 */
4064#define PDMDEV_CHECK_VERSIONS_RETURN(pDevIns) \
4065 do \
4066 { \
4067 PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
4068 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION), \
4069 ("DevIns=%#x mine=%#x\n", (pDevIns)->u32Version, PDM_DEVINS_VERSION), \
4070 VERR_PDM_DEVINS_VERSION_MISMATCH); \
4071 AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION), \
4072 ("DevHlp=%#x mine=%#x\n", (pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION), \
4073 VERR_PDM_DEVHLPR3_VERSION_MISMATCH); \
4074 } while (0)
4075
4076/**
4077 * Quietly checks the structure versions of the device instance and device
4078 * helpers, returning if they are incompatible.
4079 *
4080 * This is for use in the destructor.
4081 *
4082 * @param pDevIns The device instance pointer.
4083 */
4084#define PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns) \
4085 do \
4086 { \
4087 PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
4088 if (RT_UNLIKELY(!PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION) )) \
4089 return VERR_PDM_DEVINS_VERSION_MISMATCH; \
4090 if (RT_UNLIKELY(!PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION) )) \
4091 return VERR_PDM_DEVHLPR3_VERSION_MISMATCH; \
4092 } while (0)
4093
4094/**
4095 * Wrapper around CFGMR3ValidateConfig for the root config for use in the
4096 * constructor - returns on failure.
4097 *
4098 * This should be invoked after having initialized the instance data
4099 * sufficiently for the correct operation of the destructor. The destructor is
4100 * always called!
4101 *
4102 * @param pDevIns Pointer to the PDM device instance.
4103 * @param pszValidValues Patterns describing the valid value names. See
4104 * RTStrSimplePatternMultiMatch for details on the
4105 * pattern syntax.
4106 * @param pszValidNodes Patterns describing the valid node (key) names.
4107 * Pass empty string if no valid nodes.
4108 */
4109#define PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, pszValidValues, pszValidNodes) \
4110 do \
4111 { \
4112 int rcValCfg = CFGMR3ValidateConfig((pDevIns)->pCfg, "/", pszValidValues, pszValidNodes, \
4113 (pDevIns)->pReg->szName, (pDevIns)->iInstance); \
4114 if (RT_FAILURE(rcValCfg)) \
4115 return rcValCfg; \
4116 } while (0)
4117
4118/** @def PDMDEV_ASSERT_EMT
4119 * Assert that the current thread is the emulation thread.
4120 */
4121#ifdef VBOX_STRICT
4122# define PDMDEV_ASSERT_EMT(pDevIns) pDevIns->pHlpR3->pfnAssertEMT(pDevIns, __FILE__, __LINE__, __FUNCTION__)
4123#else
4124# define PDMDEV_ASSERT_EMT(pDevIns) do { } while (0)
4125#endif
4126
4127/** @def PDMDEV_ASSERT_OTHER
4128 * Assert that the current thread is NOT the emulation thread.
4129 */
4130#ifdef VBOX_STRICT
4131# define PDMDEV_ASSERT_OTHER(pDevIns) pDevIns->pHlpR3->pfnAssertOther(pDevIns, __FILE__, __LINE__, __FUNCTION__)
4132#else
4133# define PDMDEV_ASSERT_OTHER(pDevIns) do { } while (0)
4134#endif
4135
4136/** @def PDMDEV_ASSERT_VMLOCK_OWNER
4137 * Assert that the current thread is owner of the VM lock.
4138 */
4139#ifdef VBOX_STRICT
4140# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) pDevIns->pHlpR3->pfnAssertVMLock(pDevIns, __FILE__, __LINE__, __FUNCTION__)
4141#else
4142# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) do { } while (0)
4143#endif
4144
4145/** @def PDMDEV_SET_ERROR
4146 * Set the VM error. See PDMDevHlpVMSetError() for printf like message formatting.
4147 */
4148#define PDMDEV_SET_ERROR(pDevIns, rc, pszError) \
4149 PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, "%s", pszError)
4150
4151/** @def PDMDEV_SET_RUNTIME_ERROR
4152 * Set the VM runtime error. See PDMDevHlpVMSetRuntimeError() for printf like message formatting.
4153 */
4154#define PDMDEV_SET_RUNTIME_ERROR(pDevIns, fFlags, pszErrorId, pszError) \
4155 PDMDevHlpVMSetRuntimeError(pDevIns, fFlags, pszErrorId, "%s", pszError)
4156
4157/** @def PDMDEVINS_2_RCPTR
4158 * Converts a PDM Device instance pointer a RC PDM Device instance pointer.
4159 */
4160#define PDMDEVINS_2_RCPTR(pDevIns) ( (RCPTRTYPE(PPDMDEVINS))((RTGCUINTPTR)(pDevIns)->pvInstanceDataRC - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
4161
4162/** @def PDMDEVINS_2_R3PTR
4163 * Converts a PDM Device instance pointer a R3 PDM Device instance pointer.
4164 */
4165#define PDMDEVINS_2_R3PTR(pDevIns) ( (R3PTRTYPE(PPDMDEVINS))((RTHCUINTPTR)(pDevIns)->pvInstanceDataR3 - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
4166
4167/** @def PDMDEVINS_2_R0PTR
4168 * Converts a PDM Device instance pointer a R0 PDM Device instance pointer.
4169 */
4170#define PDMDEVINS_2_R0PTR(pDevIns) ( (R0PTRTYPE(PPDMDEVINS))((RTR0UINTPTR)(pDevIns)->pvInstanceDataR0 - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
4171
4172
4173#ifdef IN_RING3
4174
4175/**
4176 * @copydoc PDMDEVHLPR3::pfnIOPortRegister
4177 */
4178DECLINLINE(int) PDMDevHlpIOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTHCPTR pvUser,
4179 PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
4180 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc)
4181{
4182 return pDevIns->pHlpR3->pfnIOPortRegister(pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc);
4183}
4184
4185/**
4186 * @copydoc PDMDEVHLPR3::pfnIOPortRegisterRC
4187 */
4188DECLINLINE(int) PDMDevHlpIOPortRegisterRC(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTRCPTR pvUser,
4189 const char *pszOut, const char *pszIn, const char *pszOutStr,
4190 const char *pszInStr, const char *pszDesc)
4191{
4192 return pDevIns->pHlpR3->pfnIOPortRegisterRC(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
4193}
4194
4195/**
4196 * @copydoc PDMDEVHLPR3::pfnIOPortRegisterR0
4197 */
4198DECLINLINE(int) PDMDevHlpIOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTR0PTR pvUser,
4199 const char *pszOut, const char *pszIn, const char *pszOutStr,
4200 const char *pszInStr, const char *pszDesc)
4201{
4202 return pDevIns->pHlpR3->pfnIOPortRegisterR0(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
4203}
4204
4205/**
4206 * @copydoc PDMDEVHLPR3::pfnIOPortDeregister
4207 */
4208DECLINLINE(int) PDMDevHlpIOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts)
4209{
4210 return pDevIns->pHlpR3->pfnIOPortDeregister(pDevIns, Port, cPorts);
4211}
4212
4213/**
4214 * Register a Memory Mapped I/O (MMIO) region.
4215 *
4216 * These callbacks are of course for the ring-3 context (R3). Register HC
4217 * handlers before raw-mode context (RC) and ring-0 context (R0) handlers! There
4218 * must be a R3 handler for every RC and R0 handler!
4219 *
4220 * @returns VBox status.
4221 * @param pDevIns The device instance to register the MMIO with.
4222 * @param GCPhysStart First physical address in the range.
4223 * @param cbRange The size of the range (in bytes).
4224 * @param pvUser User argument.
4225 * @param fFlags Flags, IOMMMIO_FLAGS_XXX.
4226 * @param pfnWrite Pointer to function which is gonna handle Write operations.
4227 * @param pfnRead Pointer to function which is gonna handle Read operations.
4228 * @param pszDesc Pointer to description string. This must not be freed.
4229 */
4230DECLINLINE(int) PDMDevHlpMMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTHCPTR pvUser,
4231 uint32_t fFlags, PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, const char *pszDesc)
4232{
4233 return pDevIns->pHlpR3->pfnMMIORegister(pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, NULL /*pfnFill*/,
4234 fFlags, pszDesc);
4235}
4236
4237/**
4238 * Register a Memory Mapped I/O (MMIO) region for GC.
4239 *
4240 * These callbacks are for the raw-mode context (RC). Register ring-3 context
4241 * (R3) handlers before guest context handlers! There must be a R3 handler for
4242 * every RC handler!
4243 *
4244 * @returns VBox status.
4245 * @param pDevIns The device instance to register the MMIO with.
4246 * @param GCPhysStart First physical address in the range.
4247 * @param cbRange The size of the range (in bytes).
4248 * @param pvUser User argument.
4249 * @param pszWrite Name of the RC function which is gonna handle Write operations.
4250 * @param pszRead Name of the RC function which is gonna handle Read operations.
4251 */
4252DECLINLINE(int) PDMDevHlpMMIORegisterRC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTRCPTR pvUser,
4253 const char *pszWrite, const char *pszRead)
4254{
4255 return pDevIns->pHlpR3->pfnMMIORegisterRC(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, NULL /*pszFill*/);
4256}
4257
4258/**
4259 * @copydoc PDMDEVHLPR3::pfnMMIORegisterR0
4260 */
4261DECLINLINE(int) PDMDevHlpMMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTR0PTR pvUser,
4262 const char *pszWrite, const char *pszRead)
4263{
4264 return pDevIns->pHlpR3->pfnMMIORegisterR0(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, NULL /*pszFill*/);
4265}
4266
4267/**
4268 * @copydoc PDMDEVHLPR3::pfnMMIORegister
4269 */
4270DECLINLINE(int) PDMDevHlpMMIORegisterEx(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTHCPTR pvUser,
4271 uint32_t fFlags, PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead,
4272 PFNIOMMMIOFILL pfnFill, const char *pszDesc)
4273{
4274 return pDevIns->pHlpR3->pfnMMIORegister(pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill,
4275 fFlags, pszDesc);
4276}
4277
4278/**
4279 * @copydoc PDMDEVHLPR3::pfnMMIORegisterRC
4280 */
4281DECLINLINE(int) PDMDevHlpMMIORegisterRCEx(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTRCPTR pvUser,
4282 const char *pszWrite, const char *pszRead, const char *pszFill)
4283{
4284 return pDevIns->pHlpR3->pfnMMIORegisterRC(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill);
4285}
4286
4287/**
4288 * @copydoc PDMDEVHLPR3::pfnMMIORegisterR0
4289 */
4290DECLINLINE(int) PDMDevHlpMMIORegisterR0Ex(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTR0PTR pvUser,
4291 const char *pszWrite, const char *pszRead, const char *pszFill)
4292{
4293 return pDevIns->pHlpR3->pfnMMIORegisterR0(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill);
4294}
4295
4296/**
4297 * @copydoc PDMDEVHLPR3::pfnMMIODeregister
4298 */
4299DECLINLINE(int) PDMDevHlpMMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange)
4300{
4301 return pDevIns->pHlpR3->pfnMMIODeregister(pDevIns, GCPhysStart, cbRange);
4302}
4303
4304/**
4305 * @copydoc PDMDEVHLPR3::pfnMMIO2Register
4306 */
4307DECLINLINE(int) PDMDevHlpMMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
4308{
4309 return pDevIns->pHlpR3->pfnMMIO2Register(pDevIns, iRegion, cb, fFlags, ppv, pszDesc);
4310}
4311
4312/**
4313 * @copydoc PDMDEVHLPR3::pfnMMIO2Deregister
4314 */
4315DECLINLINE(int) PDMDevHlpMMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)
4316{
4317 return pDevIns->pHlpR3->pfnMMIO2Deregister(pDevIns, iRegion);
4318}
4319
4320/**
4321 * @copydoc PDMDEVHLPR3::pfnMMIO2Map
4322 */
4323DECLINLINE(int) PDMDevHlpMMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
4324{
4325 return pDevIns->pHlpR3->pfnMMIO2Map(pDevIns, iRegion, GCPhys);
4326}
4327
4328/**
4329 * @copydoc PDMDEVHLPR3::pfnMMIO2Unmap
4330 */
4331DECLINLINE(int) PDMDevHlpMMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
4332{
4333 return pDevIns->pHlpR3->pfnMMIO2Unmap(pDevIns, iRegion, GCPhys);
4334}
4335
4336/**
4337 * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2
4338 */
4339DECLINLINE(int) PDMDevHlpMMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
4340 const char *pszDesc, PRTRCPTR pRCPtr)
4341{
4342 return pDevIns->pHlpR3->pfnMMHyperMapMMIO2(pDevIns, iRegion, off, cb, pszDesc, pRCPtr);
4343}
4344
4345/**
4346 * @copydoc PDMDEVHLPR3::pfnMMIO2MapKernel
4347 */
4348DECLINLINE(int) PDMDevHlpMMIO2MapKernel(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
4349 const char *pszDesc, PRTR0PTR pR0Ptr)
4350{
4351 return pDevIns->pHlpR3->pfnMMIO2MapKernel(pDevIns, iRegion, off, cb, pszDesc, pR0Ptr);
4352}
4353
4354/**
4355 * @copydoc PDMDEVHLPR3::pfnROMRegister
4356 */
4357DECLINLINE(int) PDMDevHlpROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
4358 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
4359{
4360 return pDevIns->pHlpR3->pfnROMRegister(pDevIns, GCPhysStart, cbRange, pvBinary, cbBinary, fFlags, pszDesc);
4361}
4362
4363/**
4364 * @copydoc PDMDEVHLPR3::pfnROMProtectShadow
4365 */
4366DECLINLINE(int) PDMDevHlpROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt)
4367{
4368 return pDevIns->pHlpR3->pfnROMProtectShadow(pDevIns, GCPhysStart, cbRange, enmProt);
4369}
4370
4371/**
4372 * Register a save state data unit.
4373 *
4374 * @returns VBox status.
4375 * @param pDevIns The device instance.
4376 * @param uVersion Data layout version number.
4377 * @param cbGuess The approximate amount of data in the unit.
4378 * Only for progress indicators.
4379 * @param pfnSaveExec Execute save callback, optional.
4380 * @param pfnLoadExec Execute load callback, optional.
4381 */
4382DECLINLINE(int) PDMDevHlpSSMRegister(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
4383 PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
4384{
4385 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
4386 NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveDone*/,
4387 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
4388 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
4389}
4390
4391/**
4392 * Register a save state data unit with a live save callback as well.
4393 *
4394 * @returns VBox status.
4395 * @param pDevIns The device instance.
4396 * @param uVersion Data layout version number.
4397 * @param cbGuess The approximate amount of data in the unit.
4398 * Only for progress indicators.
4399 * @param pfnLiveExec Execute live callback, optional.
4400 * @param pfnSaveExec Execute save callback, optional.
4401 * @param pfnLoadExec Execute load callback, optional.
4402 */
4403DECLINLINE(int) PDMDevHlpSSMRegister3(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
4404 FNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
4405{
4406 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
4407 NULL /*pfnLivePrep*/, pfnLiveExec, NULL /*pfnLiveDone*/,
4408 NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
4409 NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
4410}
4411
4412/**
4413 * @copydoc PDMDEVHLPR3::pfnSSMRegister
4414 */
4415DECLINLINE(int) PDMDevHlpSSMRegisterEx(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
4416 PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
4417 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
4418 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
4419{
4420 return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, pszBefore,
4421 pfnLivePrep, pfnLiveExec, pfnLiveVote,
4422 pfnSavePrep, pfnSaveExec, pfnSaveDone,
4423 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
4424}
4425
4426/**
4427 * @copydoc PDMDEVHLPR3::pfnTMTimerCreate
4428 */
4429DECLINLINE(int) PDMDevHlpTMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags,
4430 const char *pszDesc, PPTMTIMERR3 ppTimer)
4431{
4432 return pDevIns->pHlpR3->pfnTMTimerCreate(pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
4433}
4434
4435/**
4436 * @copydoc PDMDEVHLPR3::pfnTMUtcNow
4437 */
4438DECLINLINE(PRTTIMESPEC) PDMDevHlpTMUtcNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
4439{
4440 return pDevIns->pHlpR3->pfnTMUtcNow(pDevIns, pTime);
4441}
4442
4443#endif /* IN_RING3 */
4444
4445/**
4446 * @copydoc PDMDEVHLPR3::pfnPhysRead
4447 */
4448DECLINLINE(int) PDMDevHlpPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
4449{
4450 return pDevIns->CTX_SUFF(pHlp)->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
4451}
4452
4453/**
4454 * @copydoc PDMDEVHLPR3::pfnPhysWrite
4455 */
4456DECLINLINE(int) PDMDevHlpPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
4457{
4458 return pDevIns->CTX_SUFF(pHlp)->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
4459}
4460
4461#ifdef IN_RING3
4462
4463/**
4464 * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtr
4465 */
4466DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtr(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock)
4467{
4468 return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtr(pDevIns, GCPhys, fFlags, ppv, pLock);
4469}
4470
4471/**
4472 * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtrReadOnly
4473 */
4474DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock)
4475{
4476 return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhys, fFlags, ppv, pLock);
4477}
4478
4479/**
4480 * @copydoc PDMDEVHLPR3::pfnPhysReleasePageMappingLock
4481 */
4482DECLINLINE(void) PDMDevHlpPhysReleasePageMappingLock(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock)
4483{
4484 pDevIns->CTX_SUFF(pHlp)->pfnPhysReleasePageMappingLock(pDevIns, pLock);
4485}
4486
4487/**
4488 * @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt
4489 */
4490DECLINLINE(int) PDMDevHlpPhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
4491{
4492 return pDevIns->pHlpR3->pfnPhysReadGCVirt(pDevIns, pvDst, GCVirtSrc, cb);
4493}
4494
4495/**
4496 * @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt
4497 */
4498DECLINLINE(int) PDMDevHlpPhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
4499{
4500 return pDevIns->pHlpR3->pfnPhysWriteGCVirt(pDevIns, GCVirtDst, pvSrc, cb);
4501}
4502
4503/**
4504 * @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys
4505 */
4506DECLINLINE(int) PDMDevHlpPhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
4507{
4508 return pDevIns->pHlpR3->pfnPhysGCPtr2GCPhys(pDevIns, GCPtr, pGCPhys);
4509}
4510
4511/**
4512 * @copydoc PDMDEVHLPR3::pfnMMHeapAlloc
4513 */
4514DECLINLINE(void *) PDMDevHlpMMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
4515{
4516 return pDevIns->pHlpR3->pfnMMHeapAlloc(pDevIns, cb);
4517}
4518
4519/**
4520 * @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ
4521 */
4522DECLINLINE(void *) PDMDevHlpMMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
4523{
4524 return pDevIns->pHlpR3->pfnMMHeapAllocZ(pDevIns, cb);
4525}
4526
4527/**
4528 * @copydoc PDMDEVHLPR3::pfnMMHeapFree
4529 */
4530DECLINLINE(void) PDMDevHlpMMHeapFree(PPDMDEVINS pDevIns, void *pv)
4531{
4532 pDevIns->pHlpR3->pfnMMHeapFree(pDevIns, pv);
4533}
4534#endif /* IN_RING3 */
4535
4536/**
4537 * @copydoc PDMDEVHLPR3::pfnVMState
4538 */
4539DECLINLINE(VMSTATE) PDMDevHlpVMState(PPDMDEVINS pDevIns)
4540{
4541 return pDevIns->CTX_SUFF(pHlp)->pfnVMState(pDevIns);
4542}
4543
4544#ifdef IN_RING3
4545/**
4546 * @copydoc PDMDEVHLPR3::pfnVMTeleportedAndNotFullyResumedYet
4547 */
4548DECLINLINE(bool) PDMDevHlpVMTeleportedAndNotFullyResumedYet(PPDMDEVINS pDevIns)
4549{
4550 return pDevIns->pHlpR3->pfnVMTeleportedAndNotFullyResumedYet(pDevIns);
4551}
4552#endif /* IN_RING3 */
4553
4554/**
4555 * @copydoc PDMDEVHLPR3::pfnVMSetError
4556 */
4557DECLINLINE(int) PDMDevHlpVMSetError(PPDMDEVINS pDevIns, const int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
4558{
4559 va_list va;
4560 va_start(va, pszFormat);
4561 pDevIns->CTX_SUFF(pHlp)->pfnVMSetErrorV(pDevIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
4562 va_end(va);
4563 return rc;
4564}
4565
4566/**
4567 * @copydoc PDMDEVHLPR3::pfnVMSetRuntimeError
4568 */
4569DECLINLINE(int) PDMDevHlpVMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
4570{
4571 va_list va;
4572 int rc;
4573 va_start(va, pszFormat);
4574 rc = pDevIns->CTX_SUFF(pHlp)->pfnVMSetRuntimeErrorV(pDevIns, fFlags, pszErrorId, pszFormat, va);
4575 va_end(va);
4576 return rc;
4577}
4578
4579/**
4580 * VBOX_STRICT wrapper for pHlp->pfnDBGFStopV.
4581 *
4582 * @returns VBox status code which must be passed up to the VMM. This will be
4583 * VINF_SUCCESS in non-strict builds.
4584 * @param pDevIns The device instance.
4585 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
4586 * @param pszFormat Message. (optional)
4587 * @param ... Message parameters.
4588 */
4589DECLINLINE(int) PDMDevHlpDBGFStop(PPDMDEVINS pDevIns, RT_SRC_POS_DECL, const char *pszFormat, ...)
4590{
4591#ifdef VBOX_STRICT
4592# ifdef IN_RING3
4593 int rc;
4594 va_list args;
4595 va_start(args, pszFormat);
4596 rc = pDevIns->pHlpR3->pfnDBGFStopV(pDevIns, RT_SRC_POS_ARGS, pszFormat, args);
4597 va_end(args);
4598 return rc;
4599# else
4600 NOREF(pDevIns);
4601 NOREF(pszFile);
4602 NOREF(iLine);
4603 NOREF(pszFunction);
4604 NOREF(pszFormat);
4605 return VINF_EM_DBG_STOP;
4606# endif
4607#else
4608 NOREF(pDevIns);
4609 NOREF(pszFile);
4610 NOREF(iLine);
4611 NOREF(pszFunction);
4612 NOREF(pszFormat);
4613 return VINF_SUCCESS;
4614#endif
4615}
4616
4617#ifdef IN_RING3
4618
4619/**
4620 * @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister
4621 */
4622DECLINLINE(int) PDMDevHlpDBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
4623{
4624 return pDevIns->pHlpR3->pfnDBGFInfoRegister(pDevIns, pszName, pszDesc, pfnHandler);
4625}
4626
4627/**
4628 * @copydoc PDMDEVHLPR3::pfnSTAMRegister
4629 */
4630DECLINLINE(void) PDMDevHlpSTAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
4631{
4632 pDevIns->pHlpR3->pfnSTAMRegister(pDevIns, pvSample, enmType, pszName, enmUnit, pszDesc);
4633}
4634
4635/**
4636 * @copydoc PDMDEVHLPR3::pfnSTAMRegisterF
4637 */
4638DECLINLINE(void) PDMDevHlpSTAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
4639 const char *pszDesc, const char *pszName, ...)
4640{
4641 va_list va;
4642 va_start(va, pszName);
4643 pDevIns->pHlpR3->pfnSTAMRegisterV(pDevIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, va);
4644 va_end(va);
4645}
4646
4647/**
4648 * @copydoc PDMDEVHLPR3::pfnPCIRegister
4649 */
4650DECLINLINE(int) PDMDevHlpPCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev)
4651{
4652 return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev);
4653}
4654
4655/**
4656 * @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister
4657 */
4658DECLINLINE(int) PDMDevHlpPCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
4659{
4660 return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, iRegion, cbRegion, enmType, pfnCallback);
4661}
4662
4663/**
4664 * @copydoc PDMDEVHLPR3::pfnPCIRegisterMsi
4665 */
4666DECLINLINE(int) PDMDevHlpPCIRegisterMsi(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg)
4667{
4668 return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, pMsiReg);
4669}
4670
4671/**
4672 * @copydoc PDMDEVHLPR3::pfnPCISetConfigCallbacks
4673 */
4674DECLINLINE(void) PDMDevHlpPCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
4675 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)
4676{
4677 pDevIns->pHlpR3->pfnPCISetConfigCallbacks(pDevIns, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld);
4678}
4679
4680/**
4681 * Reads data via bus mastering, if enabled. If no bus mastering is available,
4682 * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
4683 *
4684 * @return IPRT status code.
4685 */
4686DECLINLINE(int) PDMDevHlpPCIDevPhysRead(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
4687{
4688 AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
4689 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
4690 AssertReturn(cbRead, VERR_INVALID_PARAMETER);
4691
4692 if (!PCIDevIsBusmaster(pPciDev))
4693 {
4694#ifdef DEBUG
4695 Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping read %p (%z)\n", __FUNCTION__,
4696 PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbRead));
4697#endif
4698 return VINF_PDM_PCI_PHYS_READ_BM_DISABLED;
4699 }
4700
4701 return PDMDevHlpPhysRead(pPciDev->pDevIns, GCPhys, pvBuf, cbRead);
4702}
4703
4704/**
4705 * Writes data via bus mastering, if enabled. If no bus mastering is available,
4706 * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
4707 *
4708 * @return IPRT status code.
4709 */
4710DECLINLINE(int) PDMDevHlpPCIDevPhysWrite(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
4711{
4712 AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
4713 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
4714 AssertReturn(cbWrite, VERR_INVALID_PARAMETER);
4715
4716 if (!PCIDevIsBusmaster(pPciDev))
4717 {
4718#ifdef DEBUG
4719 Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping write %p (%z)\n", __FUNCTION__,
4720 PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbWrite));
4721#endif
4722 return VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED;
4723 }
4724
4725 return PDMDevHlpPhysWrite(pPciDev->pDevIns, GCPhys, pvBuf, cbWrite);
4726}
4727
4728#endif /* IN_RING3 */
4729
4730/**
4731 * @copydoc PDMDEVHLPR3::pfnPCISetIrq
4732 */
4733DECLINLINE(void) PDMDevHlpPCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4734{
4735 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, iIrq, iLevel);
4736}
4737
4738/**
4739 * @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait
4740 */
4741DECLINLINE(void) PDMDevHlpPCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4742{
4743 pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, iIrq, iLevel);
4744}
4745
4746/**
4747 * @copydoc PDMDEVHLPR3::pfnISASetIrq
4748 */
4749DECLINLINE(void) PDMDevHlpISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4750{
4751 pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
4752}
4753
4754/**
4755 * @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait
4756 */
4757DECLINLINE(void) PDMDevHlpISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
4758{
4759 pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
4760}
4761
4762#ifdef IN_RING3
4763
4764/**
4765 * @copydoc PDMDEVHLPR3::pfnDriverAttach
4766 */
4767DECLINLINE(int) PDMDevHlpDriverAttach(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
4768{
4769 return pDevIns->pHlpR3->pfnDriverAttach(pDevIns, iLun, pBaseInterface, ppBaseInterface, pszDesc);
4770}
4771
4772/**
4773 * @copydoc PDMDEVHLPR3::pfnQueueCreate
4774 */
4775DECLINLINE(int) PDMDevHlpQueueCreate(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
4776 PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue)
4777{
4778 return pDevIns->pHlpR3->pfnQueueCreate(pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fRZEnabled, pszName, ppQueue);
4779}
4780
4781/**
4782 * Initializes a PDM critical section.
4783 *
4784 * The PDM critical sections are derived from the IPRT critical sections, but
4785 * works in RC and R0 as well.
4786 *
4787 * @returns VBox status code.
4788 * @param pDevIns The device instance.
4789 * @param pCritSect Pointer to the critical section.
4790 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
4791 * @param pszNameFmt Format string for naming the critical section.
4792 * For statistics and lock validation.
4793 * @param ... Arguments for the format string.
4794 */
4795DECLINLINE(int) PDMDevHlpCritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...)
4796{
4797 int rc;
4798 va_list va;
4799 va_start(va, pszNameFmt);
4800 rc = pDevIns->pHlpR3->pfnCritSectInit(pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
4801 va_end(va);
4802 return rc;
4803}
4804
4805/**
4806 * @copydoc PDMDEVHLPR3::pfnCritSectGetNop
4807 */
4808DECLINLINE(PPDMCRITSECT) PDMDevHlpCritSectGetNop(PPDMDEVINS pDevIns)
4809{
4810 return pDevIns->pHlpR3->pfnCritSectGetNop(pDevIns);
4811}
4812
4813/**
4814 * @copydoc PDMDEVHLPR3::pfnCritSectGetNopR0
4815 */
4816DECLINLINE(R0PTRTYPE(PPDMCRITSECT)) PDMDevHlpCritSectGetNopR0(PPDMDEVINS pDevIns)
4817{
4818 return pDevIns->pHlpR3->pfnCritSectGetNopR0(pDevIns);
4819}
4820
4821/**
4822 * @copydoc PDMDEVHLPR3::pfnCritSectGetNopRC
4823 */
4824DECLINLINE(RCPTRTYPE(PPDMCRITSECT)) PDMDevHlpCritSectGetNopRC(PPDMDEVINS pDevIns)
4825{
4826 return pDevIns->pHlpR3->pfnCritSectGetNopRC(pDevIns);
4827}
4828
4829/**
4830 * @copydoc PDMDEVHLPR3::pfnSetDeviceCritSect
4831 */
4832DECLINLINE(int) PDMDevHlpSetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
4833{
4834 return pDevIns->pHlpR3->pfnSetDeviceCritSect(pDevIns, pCritSect);
4835}
4836
4837/**
4838 * @copydoc PDMDEVHLPR3::pfnThreadCreate
4839 */
4840DECLINLINE(int) PDMDevHlpThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
4841 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
4842{
4843 return pDevIns->pHlpR3->pfnThreadCreate(pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
4844}
4845
4846/**
4847 * @copydoc PDMDEVHLPR3::pfnSetAsyncNotification
4848 */
4849DECLINLINE(int) PDMDevHlpSetAsyncNotification(PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)
4850{
4851 return pDevIns->pHlpR3->pfnSetAsyncNotification(pDevIns, pfnAsyncNotify);
4852}
4853
4854/**
4855 * @copydoc PDMDEVHLPR3::pfnAsyncNotificationCompleted
4856 */
4857DECLINLINE(void) PDMDevHlpAsyncNotificationCompleted(PPDMDEVINS pDevIns)
4858{
4859 pDevIns->pHlpR3->pfnAsyncNotificationCompleted(pDevIns);
4860}
4861
4862/**
4863 * @copydoc PDMDEVHLPR3::pfnA20Set
4864 */
4865DECLINLINE(void) PDMDevHlpA20Set(PPDMDEVINS pDevIns, bool fEnable)
4866{
4867 pDevIns->pHlpR3->pfnA20Set(pDevIns, fEnable);
4868}
4869
4870/**
4871 * @copydoc PDMDEVHLPR3::pfnRTCRegister
4872 */
4873DECLINLINE(int) PDMDevHlpRTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
4874{
4875 return pDevIns->pHlpR3->pfnRTCRegister(pDevIns, pRtcReg, ppRtcHlp);
4876}
4877
4878/**
4879 * @copydoc PDMDEVHLPR3::pfnPCIBusRegister
4880 */
4881DECLINLINE(int) PDMDevHlpPCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)
4882{
4883 return pDevIns->pHlpR3->pfnPCIBusRegister(pDevIns, pPciBusReg, ppPciHlpR3);
4884}
4885
4886/**
4887 * @copydoc PDMDEVHLPR3::pfnPICRegister
4888 */
4889DECLINLINE(int) PDMDevHlpPICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
4890{
4891 return pDevIns->pHlpR3->pfnPICRegister(pDevIns, pPicReg, ppPicHlpR3);
4892}
4893
4894/**
4895 * @copydoc PDMDEVHLPR3::pfnAPICRegister
4896 */
4897DECLINLINE(int) PDMDevHlpAPICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)
4898{
4899 return pDevIns->pHlpR3->pfnAPICRegister(pDevIns, pApicReg, ppApicHlpR3);
4900}
4901
4902/**
4903 * @copydoc PDMDEVHLPR3::pfn
4904 */
4905DECLINLINE(int) PDMDevHlpIOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
4906{
4907 return pDevIns->pHlpR3->pfnIOAPICRegister(pDevIns, pIoApicReg, ppIoApicHlpR3);
4908}
4909
4910/**
4911 * @copydoc PDMDEVHLPR3::pfnHPETRegister
4912 */
4913DECLINLINE(int) PDMDevHlpHPETRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
4914{
4915 return pDevIns->pHlpR3->pfnHPETRegister(pDevIns, pHpetReg, ppHpetHlpR3);
4916}
4917
4918/**
4919 * @copydoc PDMDEVHLPR3::pfnPciRawRegister
4920 */
4921DECLINLINE(int) PDMDevHlpPciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
4922{
4923 return pDevIns->pHlpR3->pfnPciRawRegister(pDevIns, pPciRawReg, ppPciRawHlpR3);
4924}
4925
4926/**
4927 * @copydoc PDMDEVHLPR3::pfnDMACRegister
4928 */
4929DECLINLINE(int) PDMDevHlpDMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
4930{
4931 return pDevIns->pHlpR3->pfnDMACRegister(pDevIns, pDmacReg, ppDmacHlp);
4932}
4933
4934/**
4935 * @copydoc PDMDEVHLPR3::pfnDMARegister
4936 */
4937DECLINLINE(int) PDMDevHlpDMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
4938{
4939 return pDevIns->pHlpR3->pfnDMARegister(pDevIns, uChannel, pfnTransferHandler, pvUser);
4940}
4941
4942/**
4943 * @copydoc PDMDEVHLPR3::pfnDMAReadMemory
4944 */
4945DECLINLINE(int) PDMDevHlpDMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
4946{
4947 return pDevIns->pHlpR3->pfnDMAReadMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbRead);
4948}
4949
4950/**
4951 * @copydoc PDMDEVHLPR3::pfnDMAWriteMemory
4952 */
4953DECLINLINE(int) PDMDevHlpDMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
4954{
4955 return pDevIns->pHlpR3->pfnDMAWriteMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbWritten);
4956}
4957
4958/**
4959 * @copydoc PDMDEVHLPR3::pfnDMASetDREQ
4960 */
4961DECLINLINE(int) PDMDevHlpDMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
4962{
4963 return pDevIns->pHlpR3->pfnDMASetDREQ(pDevIns, uChannel, uLevel);
4964}
4965
4966/**
4967 * @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode
4968 */
4969DECLINLINE(uint8_t) PDMDevHlpDMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
4970{
4971 return pDevIns->pHlpR3->pfnDMAGetChannelMode(pDevIns, uChannel);
4972}
4973
4974/**
4975 * @copydoc PDMDEVHLPR3::pfnDMASchedule
4976 */
4977DECLINLINE(void) PDMDevHlpDMASchedule(PPDMDEVINS pDevIns)
4978{
4979 pDevIns->pHlpR3->pfnDMASchedule(pDevIns);
4980}
4981
4982/**
4983 * @copydoc PDMDEVHLPR3::pfnCMOSWrite
4984 */
4985DECLINLINE(int) PDMDevHlpCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
4986{
4987 return pDevIns->pHlpR3->pfnCMOSWrite(pDevIns, iReg, u8Value);
4988}
4989
4990/**
4991 * @copydoc PDMDEVHLPR3::pfnCMOSRead
4992 */
4993DECLINLINE(int) PDMDevHlpCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
4994{
4995 return pDevIns->pHlpR3->pfnCMOSRead(pDevIns, iReg, pu8Value);
4996}
4997
4998/**
4999 * @copydoc PDMDEVHLP::pfnCallR0
5000 */
5001DECLINLINE(int) PDMDevHlpCallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)
5002{
5003 return pDevIns->pHlpR3->pfnCallR0(pDevIns, uOperation, u64Arg);
5004}
5005
5006#endif /* IN_RING3 */
5007
5008/**
5009 * @copydoc PDMDEVHLPR3::pfnGetVM
5010 */
5011DECLINLINE(PVM) PDMDevHlpGetVM(PPDMDEVINS pDevIns)
5012{
5013 return pDevIns->CTX_SUFF(pHlp)->pfnGetVM(pDevIns);
5014}
5015
5016/**
5017 * @copydoc PDMDEVHLPR3::pfnGetVMCPU
5018 */
5019DECLINLINE(PVMCPU) PDMDevHlpGetVMCPU(PPDMDEVINS pDevIns)
5020{
5021 return pDevIns->CTX_SUFF(pHlp)->pfnGetVMCPU(pDevIns);
5022}
5023
5024/**
5025 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGet
5026 */
5027DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGet(PPDMDEVINS pDevIns)
5028{
5029 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGet(pDevIns);
5030}
5031
5032/**
5033 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
5034 */
5035DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetFreq(PPDMDEVINS pDevIns)
5036{
5037 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetFreq(pDevIns);
5038}
5039
5040/**
5041 * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
5042 */
5043DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetNano(PPDMDEVINS pDevIns)
5044{
5045 return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetNano(pDevIns);
5046}
5047
5048#ifdef IN_RING3
5049
5050/**
5051 * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap
5052 */
5053DECLINLINE(int) PDMDevHlpRegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize)
5054{
5055 return pDevIns->pHlpR3->pfnRegisterVMMDevHeap(pDevIns, GCPhys, pvHeap, cbSize);
5056}
5057
5058/**
5059 * @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap
5060 */
5061DECLINLINE(int) PDMDevHlpUnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
5062{
5063 return pDevIns->pHlpR3->pfnUnregisterVMMDevHeap(pDevIns, GCPhys);
5064}
5065
5066/**
5067 * @copydoc PDMDEVHLPR3::pfnVMReset
5068 */
5069DECLINLINE(int) PDMDevHlpVMReset(PPDMDEVINS pDevIns)
5070{
5071 return pDevIns->pHlpR3->pfnVMReset(pDevIns);
5072}
5073
5074/**
5075 * @copydoc PDMDEVHLPR3::pfnVMSuspend
5076 */
5077DECLINLINE(int) PDMDevHlpVMSuspend(PPDMDEVINS pDevIns)
5078{
5079 return pDevIns->pHlpR3->pfnVMSuspend(pDevIns);
5080}
5081
5082/**
5083 * @copydoc PDMDEVHLPR3::pfnVMSuspendSaveAndPowerOff
5084 */
5085DECLINLINE(int) PDMDevHlpVMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
5086{
5087 return pDevIns->pHlpR3->pfnVMSuspendSaveAndPowerOff(pDevIns);
5088}
5089
5090/**
5091 * @copydoc PDMDEVHLPR3::pfnVMPowerOff
5092 */
5093DECLINLINE(int) PDMDevHlpVMPowerOff(PPDMDEVINS pDevIns)
5094{
5095 return pDevIns->pHlpR3->pfnVMPowerOff(pDevIns);
5096}
5097
5098#endif /* IN_RING3 */
5099
5100/**
5101 * @copydoc PDMDEVHLPR3::pfnA20IsEnabled
5102 */
5103DECLINLINE(bool) PDMDevHlpA20IsEnabled(PPDMDEVINS pDevIns)
5104{
5105 return pDevIns->CTX_SUFF(pHlp)->pfnA20IsEnabled(pDevIns);
5106}
5107
5108#ifdef IN_RING3
5109
5110/**
5111 * @copydoc PDMDEVHLPR3::pfnGetCpuId
5112 */
5113DECLINLINE(void) PDMDevHlpGetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
5114{
5115 pDevIns->pHlpR3->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx);
5116}
5117
5118#endif /* IN_RING3 */
5119#ifdef IN_RING0
5120
5121/**
5122 * @copydoc PDMDEVHLPR0::pfnCanEmulateIoBlock
5123 */
5124DECLINLINE(bool) PDMDevHlpCanEmulateIoBlock(PPDMDEVINS pDevIns)
5125{
5126 return pDevIns->CTX_SUFF(pHlp)->pfnCanEmulateIoBlock(pDevIns);
5127}
5128
5129#endif /* IN_RING0 */
5130
5131
5132
5133
5134/** Pointer to callbacks provided to the VBoxDeviceRegister() call. */
5135typedef struct PDMDEVREGCB *PPDMDEVREGCB;
5136
5137/**
5138 * Callbacks for VBoxDeviceRegister().
5139 */
5140typedef struct PDMDEVREGCB
5141{
5142 /** Interface version.
5143 * This is set to PDM_DEVREG_CB_VERSION. */
5144 uint32_t u32Version;
5145
5146 /**
5147 * Registers a device with the current VM instance.
5148 *
5149 * @returns VBox status code.
5150 * @param pCallbacks Pointer to the callback table.
5151 * @param pReg Pointer to the device registration record.
5152 * This data must be permanent and readonly.
5153 */
5154 DECLR3CALLBACKMEMBER(int, pfnRegister,(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pReg));
5155} PDMDEVREGCB;
5156
5157/** Current version of the PDMDEVREGCB structure. */
5158#define PDM_DEVREG_CB_VERSION PDM_VERSION_MAKE(0xffe3, 1, 0)
5159
5160
5161/**
5162 * The VBoxDevicesRegister callback function.
5163 *
5164 * PDM will invoke this function after loading a device module and letting
5165 * the module decide which devices to register and how to handle conflicts.
5166 *
5167 * @returns VBox status code.
5168 * @param pCallbacks Pointer to the callback table.
5169 * @param u32Version VBox version number.
5170 */
5171typedef DECLCALLBACK(int) FNPDMVBOXDEVICESREGISTER(PPDMDEVREGCB pCallbacks, uint32_t u32Version);
5172
5173/** @} */
5174
5175RT_C_DECLS_END
5176
5177#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