VirtualBox

source: vbox/trunk/include/VBox/pdmdev.h@ 10868

Last change on this file since 10868 was 10661, checked in by vboxsync, 17 years ago

Reduce the number of world switches caused by cr8 writes by checking if we really need to be notified. (only when
an interrupt is pending and masked by the TRP value)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 135.1 KB
Line 
1/** @file
2 * PDM - Pluggable Device Manager, Devices.
3 */
4
5/*
6 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26 * Clara, CA 95054 USA or visit http://www.sun.com if you need
27 * additional information or have any questions.
28 */
29
30#ifndef ___VBox_pdmdev_h
31#define ___VBox_pdmdev_h
32
33#include <VBox/pdmqueue.h>
34#include <VBox/pdmcritsect.h>
35#include <VBox/pdmthread.h>
36#include <VBox/pdmifs.h>
37#include <VBox/pdmins.h>
38#include <VBox/iom.h>
39#include <VBox/tm.h>
40#include <VBox/ssm.h>
41#include <VBox/cfgm.h>
42#include <VBox/dbgf.h>
43#include <VBox/mm.h>
44#include <VBox/err.h>
45#include <VBox/pci.h>
46#include <iprt/stdarg.h>
47
48__BEGIN_DECLS
49
50/** @defgroup grp_pdm_device Devices
51 * @ingroup grp_pdm
52 * @{
53 */
54
55/**
56 * Construct a device instance for a VM.
57 *
58 * @returns VBox status.
59 * @param pDevIns The device instance data.
60 * If the registration structure is needed, pDevIns->pDevReg points to it.
61 * @param iInstance Instance number. Use this to figure out which registers and such to use.
62 * The instance number is also found in pDevIns->iInstance, but since it's
63 * likely to be freqently used PDM passes it as parameter.
64 * @param pCfgHandle Configuration node handle for the device. Use this to obtain the configuration
65 * of the device instance. It's also found in pDevIns->pCfgHandle, but since it's
66 * primary usage will in this function it's passed as a parameter.
67 */
68typedef DECLCALLBACK(int) FNPDMDEVCONSTRUCT(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle);
69/** Pointer to a FNPDMDEVCONSTRUCT() function. */
70typedef FNPDMDEVCONSTRUCT *PFNPDMDEVCONSTRUCT;
71
72/**
73 * Destruct a device instance.
74 *
75 * Most VM resources are freed by the VM. This callback is provided so that any non-VM
76 * resources can be freed correctly.
77 *
78 * @returns VBox status.
79 * @param pDevIns The device instance data.
80 */
81typedef DECLCALLBACK(int) FNPDMDEVDESTRUCT(PPDMDEVINS pDevIns);
82/** Pointer to a FNPDMDEVDESTRUCT() function. */
83typedef FNPDMDEVDESTRUCT *PFNPDMDEVDESTRUCT;
84
85/**
86 * Device relocation callback.
87 *
88 * When this callback is called the device instance data, and if the
89 * device have a GC component, is being relocated, or/and the selectors
90 * have been changed. The device must use the chance to perform the
91 * necessary pointer relocations and data updates.
92 *
93 * Before the GC code is executed the first time, this function will be
94 * called with a 0 delta so GC pointer calculations can be one in one place.
95 *
96 * @param pDevIns Pointer to the device instance.
97 * @param offDelta The relocation delta relative to the old location.
98 *
99 * @remark A relocation CANNOT fail.
100 */
101typedef DECLCALLBACK(void) FNPDMDEVRELOCATE(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
102/** Pointer to a FNPDMDEVRELOCATE() function. */
103typedef FNPDMDEVRELOCATE *PFNPDMDEVRELOCATE;
104
105
106/**
107 * Device I/O Control interface.
108 *
109 * This is used by external components, such as the COM interface, to
110 * communicate with devices using a class wide interface or a device
111 * specific interface.
112 *
113 * @returns VBox status code.
114 * @param pDevIns Pointer to the device instance.
115 * @param uFunction Function to perform.
116 * @param pvIn Pointer to input data.
117 * @param cbIn Size of input data.
118 * @param pvOut Pointer to output data.
119 * @param cbOut Size of output data.
120 * @param pcbOut Where to store the actual size of the output data.
121 */
122typedef DECLCALLBACK(int) FNPDMDEVIOCTL(PPDMDEVINS pDevIns, RTUINT uFunction,
123 void *pvIn, RTUINT cbIn,
124 void *pvOut, RTUINT cbOut, PRTUINT pcbOut);
125/** Pointer to a FNPDMDEVIOCTL() function. */
126typedef FNPDMDEVIOCTL *PFNPDMDEVIOCTL;
127
128/**
129 * Power On notification.
130 *
131 * @returns VBox status.
132 * @param pDevIns The device instance data.
133 */
134typedef DECLCALLBACK(void) FNPDMDEVPOWERON(PPDMDEVINS pDevIns);
135/** Pointer to a FNPDMDEVPOWERON() function. */
136typedef FNPDMDEVPOWERON *PFNPDMDEVPOWERON;
137
138/**
139 * Reset notification.
140 *
141 * @returns VBox status.
142 * @param pDevIns The device instance data.
143 */
144typedef DECLCALLBACK(void) FNPDMDEVRESET(PPDMDEVINS pDevIns);
145/** Pointer to a FNPDMDEVRESET() function. */
146typedef FNPDMDEVRESET *PFNPDMDEVRESET;
147
148/**
149 * Suspend notification.
150 *
151 * @returns VBox status.
152 * @param pDevIns The device instance data.
153 */
154typedef DECLCALLBACK(void) FNPDMDEVSUSPEND(PPDMDEVINS pDevIns);
155/** Pointer to a FNPDMDEVSUSPEND() function. */
156typedef FNPDMDEVSUSPEND *PFNPDMDEVSUSPEND;
157
158/**
159 * Resume notification.
160 *
161 * @returns VBox status.
162 * @param pDevIns The device instance data.
163 */
164typedef DECLCALLBACK(void) FNPDMDEVRESUME(PPDMDEVINS pDevIns);
165/** Pointer to a FNPDMDEVRESUME() function. */
166typedef FNPDMDEVRESUME *PFNPDMDEVRESUME;
167
168/**
169 * Power Off notification.
170 *
171 * @param pDevIns The device instance data.
172 */
173typedef DECLCALLBACK(void) FNPDMDEVPOWEROFF(PPDMDEVINS pDevIns);
174/** Pointer to a FNPDMDEVPOWEROFF() function. */
175typedef FNPDMDEVPOWEROFF *PFNPDMDEVPOWEROFF;
176
177/**
178 * Attach command.
179 *
180 * This is called to let the device attach to a driver for a specified LUN
181 * at runtime. This is not called during VM construction, the device
182 * constructor have to attach to all the available drivers.
183 *
184 * This is like plugging in the keyboard or mouse after turning on the PC.
185 *
186 * @returns VBox status code.
187 * @param pDevIns The device instance.
188 * @param iLUN The logical unit which is being detached.
189 */
190typedef DECLCALLBACK(int) FNPDMDEVATTACH(PPDMDEVINS pDevIns, unsigned iLUN);
191/** Pointer to a FNPDMDEVATTACH() function. */
192typedef FNPDMDEVATTACH *PFNPDMDEVATTACH;
193
194/**
195 * Detach notification.
196 *
197 * This is called when a driver is detaching itself from a LUN of the device.
198 * The device should adjust it's state to reflect this.
199 *
200 * This is like unplugging the network cable to use it for the laptop or
201 * something while the PC is still running.
202 *
203 * @param pDevIns The device instance.
204 * @param iLUN The logical unit which is being detached.
205 */
206typedef DECLCALLBACK(void) FNPDMDEVDETACH(PPDMDEVINS pDevIns, unsigned iLUN);
207/** Pointer to a FNPDMDEVDETACH() function. */
208typedef FNPDMDEVDETACH *PFNPDMDEVDETACH;
209
210/**
211 * Query the base interface of a logical unit.
212 *
213 * @returns VBOX status code.
214 * @param pDevIns The device instance.
215 * @param iLUN The logicial unit to query.
216 * @param ppBase Where to store the pointer to the base interface of the LUN.
217 */
218typedef DECLCALLBACK(int) FNPDMDEVQUERYINTERFACE(PPDMDEVINS pDevIns, unsigned iLUN, PPDMIBASE *ppBase);
219/** Pointer to a FNPDMDEVQUERYINTERFACE() function. */
220typedef FNPDMDEVQUERYINTERFACE *PFNPDMDEVQUERYINTERFACE;
221
222/**
223 * Init complete notification.
224 * This can be done to do communication with other devices and other
225 * initialization which requires everything to be in place.
226 *
227 * @returns VBOX status code.
228 * @param pDevIns The device instance.
229 */
230typedef DECLCALLBACK(int) FNPDMDEVINITCOMPLETE(PPDMDEVINS pDevIns);
231/** Pointer to a FNPDMDEVINITCOMPLETE() function. */
232typedef FNPDMDEVINITCOMPLETE *PFNPDMDEVINITCOMPLETE;
233
234
235
236/** PDM Device Registration Structure,
237 * This structure is used when registering a device from
238 * VBoxInitDevices() in HC Ring-3. PDM will continue use till
239 * the VM is terminated.
240 */
241typedef struct PDMDEVREG
242{
243 /** Structure version. PDM_DEVREG_VERSION defines the current version. */
244 uint32_t u32Version;
245 /** Device name. */
246 char szDeviceName[32];
247 /** Name of guest context module (no path).
248 * Only evalutated if PDM_DEVREG_FLAGS_GC is set. */
249 char szGCMod[32];
250 /** Name of guest context module (no path).
251 * Only evalutated if PDM_DEVREG_FLAGS_GC is set. */
252 char szR0Mod[32];
253 /** The description of the device. The UTF-8 string pointed to shall, like this structure,
254 * remain unchanged from registration till VM destruction. */
255 const char *pszDescription;
256
257 /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
258 RTUINT fFlags;
259 /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
260 RTUINT fClass;
261 /** Maximum number of instances (per VM). */
262 RTUINT cMaxInstances;
263 /** Size of the instance data. */
264 RTUINT cbInstance;
265
266 /** Construct instance - required. */
267 PFNPDMDEVCONSTRUCT pfnConstruct;
268 /** Destruct instance - optional. */
269 PFNPDMDEVDESTRUCT pfnDestruct;
270 /** Relocation command - optional. */
271 PFNPDMDEVRELOCATE pfnRelocate;
272 /** I/O Control interface - optional. */
273 PFNPDMDEVIOCTL pfnIOCtl;
274 /** Power on notification - optional. */
275 PFNPDMDEVPOWERON pfnPowerOn;
276 /** Reset notification - optional. */
277 PFNPDMDEVRESET pfnReset;
278 /** Suspend notification - optional. */
279 PFNPDMDEVSUSPEND pfnSuspend;
280 /** Resume notification - optional. */
281 PFNPDMDEVRESUME pfnResume;
282 /** Attach command - optional. */
283 PFNPDMDEVATTACH pfnAttach;
284 /** Detach notification - optional. */
285 PFNPDMDEVDETACH pfnDetach;
286 /** Query a LUN base interface - optional. */
287 PFNPDMDEVQUERYINTERFACE pfnQueryInterface;
288 /** Init complete notification - optional. */
289 PFNPDMDEVINITCOMPLETE pfnInitComplete;
290 /** Power off notification - optional. */
291 PFNPDMDEVPOWEROFF pfnPowerOff;
292} PDMDEVREG;
293/** Pointer to a PDM Device Structure. */
294typedef PDMDEVREG *PPDMDEVREG;
295/** Const pointer to a PDM Device Structure. */
296typedef PDMDEVREG const *PCPDMDEVREG;
297
298/** Current DEVREG version number. */
299#define PDM_DEVREG_VERSION 0xc0010000
300
301/** PDM Device Flags.
302 * @{ */
303/** This flag is used to indicate that the device has a GC component. */
304#define PDM_DEVREG_FLAGS_GC 0x00000001
305/** This flag is used to indicate that the device has a R0 component. */
306#define PDM_DEVREG_FLAGS_R0 0x00010000
307
308/** @def PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT
309 * The bit count for the current host. */
310#if HC_ARCH_BITS == 32
311# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT 0x00000002
312#elif HC_ARCH_BITS == 64
313# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT 0x00000004
314#else
315# error Unsupported HC_ARCH_BITS value.
316#endif
317/** The host bit count mask. */
318#define PDM_DEVREG_FLAGS_HOST_BITS_MASK 0x00000006
319
320/** The device support only 32-bit guests. */
321#define PDM_DEVREG_FLAGS_GUEST_BITS_32 0x00000008
322/** The device support only 64-bit guests. */
323#define PDM_DEVREG_FLAGS_GUEST_BITS_64 0x00000010
324/** The device support both 32-bit & 64-bit guests. */
325#define PDM_DEVREG_FLAGS_GUEST_BITS_32_64 0x00000018
326/** @def PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT
327 * The guest bit count for the current compilation. */
328#if GC_ARCH_BITS == 32
329# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT PDM_DEVREG_FLAGS_GUEST_BITS_32
330#elif GC_ARCH_BITS == 64
331# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT PDM_DEVREG_FLAGS_GUEST_BITS_32_64
332#else
333# error Unsupported GC_ARCH_BITS value.
334#endif
335/** The guest bit count mask. */
336#define PDM_DEVREG_FLAGS_GUEST_BITS_MASK 0x00000018
337
338/** Indicates that the devices support PAE36 on a 32-bit guest. */
339#define PDM_DEVREG_FLAGS_PAE36 0x00000020
340/** @} */
341
342
343/** PDM Device Classes.
344 * The order is important, lower bit earlier instantiation.
345 * @{ */
346/** Architecture device. */
347#define PDM_DEVREG_CLASS_ARCH RT_BIT(0)
348/** Architecture BIOS device. */
349#define PDM_DEVREG_CLASS_ARCH_BIOS RT_BIT(1)
350/** PCI bus brigde. */
351#define PDM_DEVREG_CLASS_BUS_PCI RT_BIT(2)
352/** ISA bus brigde. */
353#define PDM_DEVREG_CLASS_BUS_ISA RT_BIT(3)
354/** Input device (mouse, keyboard, joystick,..). */
355#define PDM_DEVREG_CLASS_INPUT RT_BIT(4)
356/** Interrupt controller (PIC). */
357#define PDM_DEVREG_CLASS_PIC RT_BIT(5)
358/** Interval controoler (PIT). */
359#define PDM_DEVREG_CLASS_PIT RT_BIT(6)
360/** RTC/CMOS. */
361#define PDM_DEVREG_CLASS_RTC RT_BIT(7)
362/** DMA controller. */
363#define PDM_DEVREG_CLASS_DMA RT_BIT(8)
364/** VMM Device. */
365#define PDM_DEVREG_CLASS_VMM_DEV RT_BIT(9)
366/** Graphics device, like VGA. */
367#define PDM_DEVREG_CLASS_GRAPHICS RT_BIT(10)
368/** Storage controller device. */
369#define PDM_DEVREG_CLASS_STORAGE RT_BIT(11)
370/** Network interface controller. */
371#define PDM_DEVREG_CLASS_NETWORK RT_BIT(12)
372/** Audio. */
373#define PDM_DEVREG_CLASS_AUDIO RT_BIT(13)
374/** USB HIC. */
375#define PDM_DEVREG_CLASS_BUS_USB RT_BIT(14)
376/** ACPI. */
377#define PDM_DEVREG_CLASS_ACPI RT_BIT(15)
378/** Serial controller device. */
379#define PDM_DEVREG_CLASS_SERIAL RT_BIT(16)
380/** Parallel controller device */
381#define PDM_DEVREG_CLASS_PARALLEL RT_BIT(17)
382/** Misc devices (always last). */
383#define PDM_DEVREG_CLASS_MISC RT_BIT(31)
384/** @} */
385
386
387/** @name IRQ Level for use with the *SetIrq APIs.
388 * @{
389 */
390/** Assert the IRQ (can assume value 1). */
391#define PDM_IRQ_LEVEL_HIGH RT_BIT(0)
392/** Deassert the IRQ (can assume value 0). */
393#define PDM_IRQ_LEVEL_LOW 0
394/** flip-flop - assert and then deassert it again immediately. */
395#define PDM_IRQ_LEVEL_FLIP_FLOP (RT_BIT(1) | PDM_IRQ_LEVEL_HIGH)
396/** @} */
397
398
399/**
400 * PCI Bus registration structure.
401 * All the callbacks, except the PCIBIOS hack, are working on PCI devices.
402 */
403typedef struct PDMPCIBUSREG
404{
405 /** Structure version number. PDM_PCIBUSREG_VERSION defines the current version. */
406 uint32_t u32Version;
407
408 /**
409 * Registers the device with the default PCI bus.
410 *
411 * @returns VBox status code.
412 * @param pDevIns Device instance of the PCI Bus.
413 * @param pPciDev The PCI device structure.
414 * Any PCI enabled device must keep this in it's instance data!
415 * Fill in the PCI data config before registration, please.
416 * @param pszName Pointer to device name (permanent, readonly). For debugging, not unique.
417 * @param iDev The device number ((dev << 3) | function) the device should have on the bus.
418 * If negative, the pci bus device will assign one.
419 */
420 DECLR3CALLBACKMEMBER(int, pfnRegisterHC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev));
421
422 /**
423 * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
424 *
425 * @returns VBox status code.
426 * @param pDevIns Device instance of the PCI Bus.
427 * @param pPciDev The PCI device structure.
428 * @param iRegion The region number.
429 * @param cbRegion Size of the region.
430 * @param iType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
431 * @param pfnCallback Callback for doing the mapping.
432 */
433 DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterHC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
434
435 /**
436 * Register PCI configuration space read/write callbacks.
437 *
438 * @param pDevIns Device instance of the PCI Bus.
439 * @param pPciDev The PCI device structure.
440 * @param pfnRead Pointer to the user defined PCI config read function.
441 * @param ppfnReadOld Pointer to function pointer which will receive the old (default)
442 * PCI config read function. This way, user can decide when (and if)
443 * to call default PCI config read function. Can be NULL.
444 * @param pfnWrite Pointer to the user defined PCI config write function.
445 * @param pfnWriteOld Pointer to function pointer which will receive the old (default)
446 * PCI config write function. This way, user can decide when (and if)
447 * to call default PCI config write function. Can be NULL.
448 * @thread EMT
449 */
450 DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksHC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
451 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
452
453 /**
454 * Set the IRQ for a PCI device.
455 *
456 * @param pDevIns Device instance of the PCI Bus.
457 * @param pPciDev The PCI device structure.
458 * @param iIrq IRQ number to set.
459 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
460 */
461 DECLR3CALLBACKMEMBER(void, pfnSetIrqHC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel));
462
463 /**
464 * Saves a state of the PCI device.
465 *
466 * @returns VBox status code.
467 * @param pDevIns Device instance of the PCI Bus.
468 * @param pPciDev Pointer to PCI device.
469 * @param pSSMHandle The handle to save the state to.
470 */
471 DECLR3CALLBACKMEMBER(int, pfnSaveExecHC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
472
473 /**
474 * Loads a saved PCI device state.
475 *
476 * @returns VBox status code.
477 * @param pDevIns Device instance of the PCI Bus.
478 * @param pPciDev Pointer to PCI device.
479 * @param pSSMHandle The handle to the saved state.
480 */
481 DECLR3CALLBACKMEMBER(int, pfnLoadExecHC,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
482
483 /**
484 * Called to perform the job of the bios.
485 * This is only called for the first PCI Bus - it is expected to
486 * service all the PCI buses.
487 *
488 * @returns VBox status.
489 * @param pDevIns Device instance of the first bus.
490 */
491 DECLR3CALLBACKMEMBER(int, pfnFakePCIBIOSHC,(PPDMDEVINS pDevIns));
492
493 /** The name of the SetIrq GC entry point. */
494 const char *pszSetIrqGC;
495
496 /** The name of the SetIrq R0 entry point. */
497 const char *pszSetIrqR0;
498
499} PDMPCIBUSREG;
500/** Pointer to a PCI bus registration structure. */
501typedef PDMPCIBUSREG *PPDMPCIBUSREG;
502
503/** Current PDMPCIBUSREG version number. */
504#define PDM_PCIBUSREG_VERSION 0xd0020000
505
506/**
507 * PCI Bus GC helpers.
508 */
509typedef struct PDMPCIHLPGC
510{
511 /** Structure version. PDM_PCIHLPGC_VERSION defines the current version. */
512 uint32_t u32Version;
513
514 /**
515 * Set an ISA IRQ.
516 *
517 * @param pDevIns PCI device instance.
518 * @param iIrq IRQ number to set.
519 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
520 * @thread EMT only.
521 */
522 DECLGCCALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
523
524 /**
525 * Set an I/O-APIC IRQ.
526 *
527 * @param pDevIns PCI device instance.
528 * @param iIrq IRQ number to set.
529 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
530 * @thread EMT only.
531 */
532 DECLGCCALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
533
534 /**
535 * Acquires the PDM lock.
536 *
537 * @returns VINF_SUCCESS on success.
538 * @returns rc if we failed to acquire the lock.
539 * @param pDevIns The PCI device instance.
540 * @param rc What to return if we fail to acquire the lock.
541 */
542 DECLGCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
543
544 /**
545 * Releases the PDM lock.
546 *
547 * @param pDevIns The PCI device instance.
548 */
549 DECLGCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
550
551 /** Just a safety precaution. */
552 uint32_t u32TheEnd;
553} PDMPCIHLPGC;
554/** Pointer to PCI helpers. */
555typedef RCPTRTYPE(PDMPCIHLPGC *) PPDMPCIHLPGC;
556/** Pointer to const PCI helpers. */
557typedef RCPTRTYPE(const PDMPCIHLPGC *) PCPDMPCIHLPGC;
558
559/** Current PDMPCIHLPR3 version number. */
560#define PDM_PCIHLPGC_VERSION 0xe1010000
561
562
563/**
564 * PCI Bus R0 helpers.
565 */
566typedef struct PDMPCIHLPR0
567{
568 /** Structure version. PDM_PCIHLPR0_VERSION defines the current version. */
569 uint32_t u32Version;
570
571 /**
572 * Set an ISA IRQ.
573 *
574 * @param pDevIns PCI device instance.
575 * @param iIrq IRQ number to set.
576 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
577 * @thread EMT only.
578 */
579 DECLR0CALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
580
581 /**
582 * Set an I/O-APIC IRQ.
583 *
584 * @param pDevIns PCI device instance.
585 * @param iIrq IRQ number to set.
586 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
587 * @thread EMT only.
588 */
589 DECLR0CALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
590
591 /**
592 * Acquires the PDM lock.
593 *
594 * @returns VINF_SUCCESS on success.
595 * @returns rc if we failed to acquire the lock.
596 * @param pDevIns The PCI device instance.
597 * @param rc What to return if we fail to acquire the lock.
598 */
599 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
600
601 /**
602 * Releases the PDM lock.
603 *
604 * @param pDevIns The PCI device instance.
605 */
606 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
607
608 /** Just a safety precaution. */
609 uint32_t u32TheEnd;
610} PDMPCIHLPR0;
611/** Pointer to PCI helpers. */
612typedef R0PTRTYPE(PDMPCIHLPR0 *) PPDMPCIHLPR0;
613/** Pointer to const PCI helpers. */
614typedef R0PTRTYPE(const PDMPCIHLPR0 *) PCPDMPCIHLPR0;
615
616/** Current PDMPCIHLPR0 version number. */
617#define PDM_PCIHLPR0_VERSION 0xe1010000
618
619/**
620 * PCI device helpers.
621 */
622typedef struct PDMPCIHLPR3
623{
624 /** Structure version. PDM_PCIHLPR3_VERSION defines the current version. */
625 uint32_t u32Version;
626
627 /**
628 * Set an ISA IRQ.
629 *
630 * @param pDevIns The PCI device instance.
631 * @param iIrq IRQ number to set.
632 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
633 * @thread EMT only.
634 */
635 DECLR3CALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
636
637 /**
638 * Set an I/O-APIC IRQ.
639 *
640 * @param pDevIns The PCI device instance.
641 * @param iIrq IRQ number to set.
642 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
643 * @thread EMT only.
644 */
645 DECLR3CALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
646
647 /**
648 * Checks if the given address is an MMIO2 base address or not.
649 *
650 * @returns true/false accordingly.
651 * @param pDevIns The PCI device instance.
652 * @param pOwner The owner of the memory, optional.
653 * @param GCPhys The address to check.
654 */
655 DECLR3CALLBACKMEMBER(bool, pfnIsMMIO2Base,(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys));
656
657 /**
658 * Gets the address of the GC PCI Bus helpers.
659 *
660 * This should be called at both construction and relocation time
661 * to obtain the correct address of the GC helpers.
662 *
663 * @returns GC pointer to the PCI Bus helpers.
664 * @param pDevIns Device instance of the PCI Bus.
665 * @thread EMT only.
666 */
667 DECLR3CALLBACKMEMBER(PCPDMPCIHLPGC, pfnGetGCHelpers,(PPDMDEVINS pDevIns));
668
669 /**
670 * Gets the address of the R0 PCI Bus helpers.
671 *
672 * This should be called at both construction and relocation time
673 * to obtain the correct address of the GC helpers.
674 *
675 * @returns R0 pointer to the PCI Bus helpers.
676 * @param pDevIns Device instance of the PCI Bus.
677 * @thread EMT only.
678 */
679 DECLR3CALLBACKMEMBER(PCPDMPCIHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
680
681 /**
682 * Acquires the PDM lock.
683 *
684 * @returns VINF_SUCCESS on success.
685 * @returns Fatal error on failure.
686 * @param pDevIns The PCI device instance.
687 * @param rc Dummy for making the interface identical to the GC and R0 versions.
688 */
689 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
690
691 /**
692 * Releases the PDM lock.
693 *
694 * @param pDevIns The PCI device instance.
695 */
696 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
697
698 /** Just a safety precaution. */
699 uint32_t u32TheEnd;
700} PDMPCIHLPR3;
701/** Pointer to PCI helpers. */
702typedef R3PTRTYPE(PDMPCIHLPR3 *) PPDMPCIHLPR3;
703/** Pointer to const PCI helpers. */
704typedef R3PTRTYPE(const PDMPCIHLPR3 *) PCPDMPCIHLPR3;
705
706/** Current PDMPCIHLPR3 version number. */
707#define PDM_PCIHLPR3_VERSION 0xf1020000
708
709
710/**
711 * Programmable Interrupt Controller registration structure.
712 */
713typedef struct PDMPICREG
714{
715 /** Structure version number. PDM_PICREG_VERSION defines the current version. */
716 uint32_t u32Version;
717
718 /**
719 * Set the an IRQ.
720 *
721 * @param pDevIns Device instance of the PIC.
722 * @param iIrq IRQ number to set.
723 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
724 */
725 DECLR3CALLBACKMEMBER(void, pfnSetIrqHC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
726
727 /**
728 * Get a pending interrupt.
729 *
730 * @returns Pending interrupt number.
731 * @param pDevIns Device instance of the PIC.
732 */
733 DECLR3CALLBACKMEMBER(int, pfnGetInterruptHC,(PPDMDEVINS pDevIns));
734
735 /** The name of the GC SetIrq entry point. */
736 const char *pszSetIrqGC;
737 /** The name of the GC GetInterrupt entry point. */
738 const char *pszGetInterruptGC;
739
740 /** The name of the R0 SetIrq entry point. */
741 const char *pszSetIrqR0;
742 /** The name of the R0 GetInterrupt entry point. */
743 const char *pszGetInterruptR0;
744} PDMPICREG;
745/** Pointer to a PIC registration structure. */
746typedef PDMPICREG *PPDMPICREG;
747
748/** Current PDMPICREG version number. */
749#define PDM_PICREG_VERSION 0xe0020000
750
751/**
752 * PIC GC helpers.
753 */
754typedef struct PDMPICHLPGC
755{
756 /** Structure version. PDM_PICHLPGC_VERSION defines the current version. */
757 uint32_t u32Version;
758
759 /**
760 * Set the interrupt force action flag.
761 *
762 * @param pDevIns Device instance of the PIC.
763 */
764 DECLGCCALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
765
766 /**
767 * Clear the interrupt force action flag.
768 *
769 * @param pDevIns Device instance of the PIC.
770 */
771 DECLGCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
772
773 /**
774 * Acquires the PDM lock.
775 *
776 * @returns VINF_SUCCESS on success.
777 * @returns rc if we failed to acquire the lock.
778 * @param pDevIns The PIC device instance.
779 * @param rc What to return if we fail to acquire the lock.
780 */
781 DECLGCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
782
783 /**
784 * Releases the PDM lock.
785 *
786 * @param pDevIns The PIC device instance.
787 */
788 DECLGCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
789
790 /** Just a safety precaution. */
791 uint32_t u32TheEnd;
792} PDMPICHLPGC;
793
794/** Pointer to PIC GC helpers. */
795typedef RCPTRTYPE(PDMPICHLPGC *) PPDMPICHLPGC;
796/** Pointer to const PIC GC helpers. */
797typedef RCPTRTYPE(const PDMPICHLPGC *) PCPDMPICHLPGC;
798
799/** Current PDMPICHLPGC version number. */
800#define PDM_PICHLPGC_VERSION 0xfc010000
801
802
803/**
804 * PIC R0 helpers.
805 */
806typedef struct PDMPICHLPR0
807{
808 /** Structure version. PDM_PICHLPR0_VERSION defines the current version. */
809 uint32_t u32Version;
810
811 /**
812 * Set the interrupt force action flag.
813 *
814 * @param pDevIns Device instance of the PIC.
815 */
816 DECLR0CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
817
818 /**
819 * Clear the interrupt force action flag.
820 *
821 * @param pDevIns Device instance of the PIC.
822 */
823 DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
824
825 /**
826 * Acquires the PDM lock.
827 *
828 * @returns VINF_SUCCESS on success.
829 * @returns rc if we failed to acquire the lock.
830 * @param pDevIns The PIC device instance.
831 * @param rc What to return if we fail to acquire the lock.
832 */
833 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
834
835 /**
836 * Releases the PDM lock.
837 *
838 * @param pDevIns The PCI device instance.
839 */
840 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
841
842 /** Just a safety precaution. */
843 uint32_t u32TheEnd;
844} PDMPICHLPR0;
845
846/** Pointer to PIC R0 helpers. */
847typedef R0PTRTYPE(PDMPICHLPR0 *) PPDMPICHLPR0;
848/** Pointer to const PIC R0 helpers. */
849typedef R0PTRTYPE(const PDMPICHLPR0 *) PCPDMPICHLPR0;
850
851/** Current PDMPICHLPR0 version number. */
852#define PDM_PICHLPR0_VERSION 0xfc010000
853
854/**
855 * PIC HC helpers.
856 */
857typedef struct PDMPICHLPR3
858{
859 /** Structure version. PDM_PICHLP_VERSION defines the current version. */
860 uint32_t u32Version;
861
862 /**
863 * Set the interrupt force action flag.
864 *
865 * @param pDevIns Device instance of the PIC.
866 */
867 DECLR3CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
868
869 /**
870 * Clear the interrupt force action flag.
871 *
872 * @param pDevIns Device instance of the PIC.
873 */
874 DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
875
876 /**
877 * Acquires the PDM lock.
878 *
879 * @returns VINF_SUCCESS on success.
880 * @returns Fatal error on failure.
881 * @param pDevIns The PIC device instance.
882 * @param rc Dummy for making the interface identical to the GC and R0 versions.
883 */
884 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
885
886 /**
887 * Releases the PDM lock.
888 *
889 * @param pDevIns The PIC device instance.
890 */
891 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
892
893 /**
894 * Gets the address of the GC PIC helpers.
895 *
896 * This should be called at both construction and relocation time
897 * to obtain the correct address of the GC helpers.
898 *
899 * @returns GC pointer to the PIC helpers.
900 * @param pDevIns Device instance of the PIC.
901 */
902 DECLR3CALLBACKMEMBER(PCPDMPICHLPGC, pfnGetGCHelpers,(PPDMDEVINS pDevIns));
903
904 /**
905 * Gets the address of the R0 PIC helpers.
906 *
907 * This should be called at both construction and relocation time
908 * to obtain the correct address of the GC helpers.
909 *
910 * @returns R0 pointer to the PIC helpers.
911 * @param pDevIns Device instance of the PIC.
912 */
913 DECLR3CALLBACKMEMBER(PCPDMPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
914
915 /** Just a safety precaution. */
916 uint32_t u32TheEnd;
917} PDMPICHLPR3;
918
919/** Pointer to PIC HC helpers. */
920typedef R3PTRTYPE(PDMPICHLPR3 *) PPDMPICHLPR3;
921/** Pointer to const PIC HC helpers. */
922typedef R3PTRTYPE(const PDMPICHLPR3 *) PCPDMPICHLPR3;
923
924/** Current PDMPICHLPR3 version number. */
925#define PDM_PICHLPR3_VERSION 0xf0010000
926
927
928
929/**
930 * Advanced Programmable Interrupt Controller registration structure.
931 */
932typedef struct PDMAPICREG
933{
934 /** Structure version number. PDM_APICREG_VERSION defines the current version. */
935 uint32_t u32Version;
936
937 /**
938 * Get a pending interrupt.
939 *
940 * @returns Pending interrupt number.
941 * @param pDevIns Device instance of the APIC.
942 */
943 DECLR3CALLBACKMEMBER(int, pfnGetInterruptHC,(PPDMDEVINS pDevIns));
944
945 /**
946 * Check if the APIC has a pending interrupt/if a TPR change would active one
947 *
948 * @returns Pending interrupt yes/no
949 * @param pDevIns Device instance of the APIC.
950 */
951 DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqHC,(PPDMDEVINS pDevIns));
952
953 /**
954 * Set the APIC base.
955 *
956 * @param pDevIns Device instance of the APIC.
957 * @param u64Base The new base.
958 */
959 DECLR3CALLBACKMEMBER(void, pfnSetBaseHC,(PPDMDEVINS pDevIns, uint64_t u64Base));
960
961 /**
962 * Get the APIC base.
963 *
964 * @returns Current base.
965 * @param pDevIns Device instance of the APIC.
966 */
967 DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseHC,(PPDMDEVINS pDevIns));
968
969 /**
970 * Set the TPR (task priority register).
971 *
972 * @param pDevIns Device instance of the APIC.
973 * @param u8TPR The new TPR.
974 */
975 DECLR3CALLBACKMEMBER(void, pfnSetTPRHC,(PPDMDEVINS pDevIns, uint8_t u8TPR));
976
977 /**
978 * Get the TPR (task priority register).
979 *
980 * @returns The current TPR.
981 * @param pDevIns Device instance of the APIC.
982 * @param pfPending Pending interrupt state (out).
983 */
984 DECLR3CALLBACKMEMBER(uint8_t, pfnGetTPRHC,(PPDMDEVINS pDevIns));
985
986 /**
987 * Private interface between the IOAPIC and APIC.
988 *
989 * This is a low-level, APIC/IOAPIC implementation specific interface
990 * which is registered with PDM only because it makes life so much
991 * simpler right now (GC bits). This is a bad bad hack! The correct
992 * way of doing this would involve some way of querying GC interfaces
993 * and relocating them. Perhaps doing some kind of device init in GC...
994 *
995 * @returns The current TPR.
996 * @param pDevIns Device instance of the APIC.
997 * @param u8Dest See APIC implementation.
998 * @param u8DestMode See APIC implementation.
999 * @param u8DeliveryMode See APIC implementation.
1000 * @param iVector See APIC implementation.
1001 * @param u8Polarity See APIC implementation.
1002 * @param u8TriggerMode See APIC implementation.
1003 */
1004 DECLR3CALLBACKMEMBER(void, pfnBusDeliverHC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1005 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
1006
1007 /** The name of the GC GetInterrupt entry point. */
1008 const char *pszGetInterruptGC;
1009 /** The name of the GC HasPendingIrq entry point. */
1010 const char *pszHasPendingIrqGC;
1011 /** The name of the GC SetBase entry point. */
1012 const char *pszSetBaseGC;
1013 /** The name of the GC GetBase entry point. */
1014 const char *pszGetBaseGC;
1015 /** The name of the GC SetTPR entry point. */
1016 const char *pszSetTPRGC;
1017 /** The name of the GC GetTPR entry point. */
1018 const char *pszGetTPRGC;
1019 /** The name of the GC BusDeliver entry point. */
1020 const char *pszBusDeliverGC;
1021
1022 /** The name of the R0 GetInterrupt entry point. */
1023 const char *pszGetInterruptR0;
1024 /** The name of the R0 HasPendingIrq entry point. */
1025 const char *pszHasPendingIrqR0;
1026 /** The name of the R0 SetBase entry point. */
1027 const char *pszSetBaseR0;
1028 /** The name of the R0 GetBase entry point. */
1029 const char *pszGetBaseR0;
1030 /** The name of the R0 SetTPR entry point. */
1031 const char *pszSetTPRR0;
1032 /** The name of the R0 GetTPR entry point. */
1033 const char *pszGetTPRR0;
1034 /** The name of the R0 BusDeliver entry point. */
1035 const char *pszBusDeliverR0;
1036
1037} PDMAPICREG;
1038/** Pointer to an APIC registration structure. */
1039typedef PDMAPICREG *PPDMAPICREG;
1040
1041/** Current PDMAPICREG version number. */
1042#define PDM_APICREG_VERSION 0x70010000
1043
1044
1045/**
1046 * APIC GC helpers.
1047 */
1048typedef struct PDMAPICHLPGC
1049{
1050 /** Structure version. PDM_APICHLPGC_VERSION defines the current version. */
1051 uint32_t u32Version;
1052
1053 /**
1054 * Set the interrupt force action flag.
1055 *
1056 * @param pDevIns Device instance of the APIC.
1057 */
1058 DECLGCCALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
1059
1060 /**
1061 * Clear the interrupt force action flag.
1062 *
1063 * @param pDevIns Device instance of the APIC.
1064 */
1065 DECLGCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
1066
1067 /**
1068 * Sets or clears the APIC bit in the CPUID feature masks.
1069 *
1070 * @param pDevIns Device instance of the APIC.
1071 * @param fEnabled If true the bit is set, else cleared.
1072 */
1073 DECLGCCALLBACKMEMBER(void, pfnChangeFeature,(PPDMDEVINS pDevIns, bool fEnabled));
1074
1075 /**
1076 * Acquires the PDM lock.
1077 *
1078 * @returns VINF_SUCCESS on success.
1079 * @returns rc if we failed to acquire the lock.
1080 * @param pDevIns The APIC device instance.
1081 * @param rc What to return if we fail to acquire the lock.
1082 */
1083 DECLGCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1084
1085 /**
1086 * Releases the PDM lock.
1087 *
1088 * @param pDevIns The APIC device instance.
1089 */
1090 DECLGCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1091
1092 /** Just a safety precaution. */
1093 uint32_t u32TheEnd;
1094} PDMAPICHLPGC;
1095/** Pointer to APIC GC helpers. */
1096typedef RCPTRTYPE(PDMAPICHLPGC *) PPDMAPICHLPGC;
1097/** Pointer to const APIC helpers. */
1098typedef RCPTRTYPE(const PDMAPICHLPGC *) PCPDMAPICHLPGC;
1099
1100/** Current PDMAPICHLPGC version number. */
1101#define PDM_APICHLPGC_VERSION 0x60010000
1102
1103
1104/**
1105 * APIC R0 helpers.
1106 */
1107typedef struct PDMAPICHLPR0
1108{
1109 /** Structure version. PDM_APICHLPR0_VERSION defines the current version. */
1110 uint32_t u32Version;
1111
1112 /**
1113 * Set the interrupt force action flag.
1114 *
1115 * @param pDevIns Device instance of the APIC.
1116 */
1117 DECLR0CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
1118
1119 /**
1120 * Clear the interrupt force action flag.
1121 *
1122 * @param pDevIns Device instance of the APIC.
1123 */
1124 DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
1125
1126 /**
1127 * Sets or clears the APIC bit in the CPUID feature masks.
1128 *
1129 * @param pDevIns Device instance of the APIC.
1130 * @param fEnabled If true the bit is set, else cleared.
1131 */
1132 DECLR0CALLBACKMEMBER(void, pfnChangeFeature,(PPDMDEVINS pDevIns, bool fEnabled));
1133
1134 /**
1135 * Acquires the PDM lock.
1136 *
1137 * @returns VINF_SUCCESS on success.
1138 * @returns rc if we failed to acquire the lock.
1139 * @param pDevIns The APIC device instance.
1140 * @param rc What to return if we fail to acquire the lock.
1141 */
1142 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1143
1144 /**
1145 * Releases the PDM lock.
1146 *
1147 * @param pDevIns The APIC device instance.
1148 */
1149 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1150
1151 /** Just a safety precaution. */
1152 uint32_t u32TheEnd;
1153} PDMAPICHLPR0;
1154/** Pointer to APIC GC helpers. */
1155typedef RCPTRTYPE(PDMAPICHLPR0 *) PPDMAPICHLPR0;
1156/** Pointer to const APIC helpers. */
1157typedef R0PTRTYPE(const PDMAPICHLPR0 *) PCPDMAPICHLPR0;
1158
1159/** Current PDMAPICHLPR0 version number. */
1160#define PDM_APICHLPR0_VERSION 0x60010000
1161
1162/**
1163 * APIC HC helpers.
1164 */
1165typedef struct PDMAPICHLPR3
1166{
1167 /** Structure version. PDM_APICHLPR3_VERSION defines the current version. */
1168 uint32_t u32Version;
1169
1170 /**
1171 * Set the interrupt force action flag.
1172 *
1173 * @param pDevIns Device instance of the APIC.
1174 */
1175 DECLR3CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
1176
1177 /**
1178 * Clear the interrupt force action flag.
1179 *
1180 * @param pDevIns Device instance of the APIC.
1181 */
1182 DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
1183
1184 /**
1185 * Sets or clears the APIC bit in the CPUID feature masks.
1186 *
1187 * @param pDevIns Device instance of the APIC.
1188 * @param fEnabled If true the bit is set, else cleared.
1189 */
1190 DECLR3CALLBACKMEMBER(void, pfnChangeFeature,(PPDMDEVINS pDevIns, bool fEnabled));
1191
1192 /**
1193 * Acquires the PDM lock.
1194 *
1195 * @returns VINF_SUCCESS on success.
1196 * @returns Fatal error on failure.
1197 * @param pDevIns The APIC device instance.
1198 * @param rc Dummy for making the interface identical to the GC and R0 versions.
1199 */
1200 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1201
1202 /**
1203 * Releases the PDM lock.
1204 *
1205 * @param pDevIns The APIC device instance.
1206 */
1207 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1208
1209 /**
1210 * Gets the address of the GC APIC helpers.
1211 *
1212 * This should be called at both construction and relocation time
1213 * to obtain the correct address of the GC helpers.
1214 *
1215 * @returns GC pointer to the APIC helpers.
1216 * @param pDevIns Device instance of the APIC.
1217 */
1218 DECLR3CALLBACKMEMBER(PCPDMAPICHLPGC, pfnGetGCHelpers,(PPDMDEVINS pDevIns));
1219
1220 /**
1221 * Gets the address of the R0 APIC helpers.
1222 *
1223 * This should be called at both construction and relocation time
1224 * to obtain the correct address of the R0 helpers.
1225 *
1226 * @returns R0 pointer to the APIC helpers.
1227 * @param pDevIns Device instance of the APIC.
1228 */
1229 DECLR3CALLBACKMEMBER(PCPDMAPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
1230
1231 /** Just a safety precaution. */
1232 uint32_t u32TheEnd;
1233} PDMAPICHLPR3;
1234/** Pointer to APIC helpers. */
1235typedef R3PTRTYPE(PDMAPICHLPR3 *) PPDMAPICHLPR3;
1236/** Pointer to const APIC helpers. */
1237typedef R3PTRTYPE(const PDMAPICHLPR3 *) PCPDMAPICHLPR3;
1238
1239/** Current PDMAPICHLP version number. */
1240#define PDM_APICHLPR3_VERSION 0xfd010000
1241
1242
1243/**
1244 * I/O APIC registration structure.
1245 */
1246typedef struct PDMIOAPICREG
1247{
1248 /** Struct version+magic number (PDM_IOAPICREG_VERSION). */
1249 uint32_t u32Version;
1250
1251 /**
1252 * Set the an IRQ.
1253 *
1254 * @param pDevIns Device instance of the I/O APIC.
1255 * @param iIrq IRQ number to set.
1256 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1257 */
1258 DECLR3CALLBACKMEMBER(void, pfnSetIrqHC,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
1259
1260 /** The name of the GC SetIrq entry point. */
1261 const char *pszSetIrqGC;
1262
1263 /** The name of the R0 SetIrq entry point. */
1264 const char *pszSetIrqR0;
1265} PDMIOAPICREG;
1266/** Pointer to an APIC registration structure. */
1267typedef PDMIOAPICREG *PPDMIOAPICREG;
1268
1269/** Current PDMAPICREG version number. */
1270#define PDM_IOAPICREG_VERSION 0x50010000
1271
1272
1273/**
1274 * IOAPIC GC helpers.
1275 */
1276typedef struct PDMIOAPICHLPGC
1277{
1278 /** Structure version. PDM_IOAPICHLPGC_VERSION defines the current version. */
1279 uint32_t u32Version;
1280
1281 /**
1282 * Private interface between the IOAPIC and APIC.
1283 *
1284 * See comments about this hack on PDMAPICREG::pfnBusDeliverHC.
1285 *
1286 * @returns The current TPR.
1287 * @param pDevIns Device instance of the IOAPIC.
1288 * @param u8Dest See APIC implementation.
1289 * @param u8DestMode See APIC implementation.
1290 * @param u8DeliveryMode See APIC implementation.
1291 * @param iVector See APIC implementation.
1292 * @param u8Polarity See APIC implementation.
1293 * @param u8TriggerMode See APIC implementation.
1294 */
1295 DECLGCCALLBACKMEMBER(void, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1296 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
1297
1298 /**
1299 * Acquires the PDM lock.
1300 *
1301 * @returns VINF_SUCCESS on success.
1302 * @returns rc if we failed to acquire the lock.
1303 * @param pDevIns The IOAPIC device instance.
1304 * @param rc What to return if we fail to acquire the lock.
1305 */
1306 DECLGCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1307
1308 /**
1309 * Releases the PDM lock.
1310 *
1311 * @param pDevIns The IOAPIC device instance.
1312 */
1313 DECLGCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1314
1315 /** Just a safety precaution. */
1316 uint32_t u32TheEnd;
1317} PDMIOAPICHLPGC;
1318/** Pointer to IOAPIC GC helpers. */
1319typedef RCPTRTYPE(PDMAPICHLPGC *)PPDMIOAPICHLPGC;
1320/** Pointer to const IOAPIC helpers. */
1321typedef RCPTRTYPE(const PDMIOAPICHLPGC *) PCPDMIOAPICHLPGC;
1322
1323/** Current PDMIOAPICHLPGC version number. */
1324#define PDM_IOAPICHLPGC_VERSION 0xfe010000
1325
1326
1327/**
1328 * IOAPIC R0 helpers.
1329 */
1330typedef struct PDMIOAPICHLPR0
1331{
1332 /** Structure version. PDM_IOAPICHLPR0_VERSION defines the current version. */
1333 uint32_t u32Version;
1334
1335 /**
1336 * Private interface between the IOAPIC and APIC.
1337 *
1338 * See comments about this hack on PDMAPICREG::pfnBusDeliverHC.
1339 *
1340 * @returns The current TPR.
1341 * @param pDevIns Device instance of the IOAPIC.
1342 * @param u8Dest See APIC implementation.
1343 * @param u8DestMode See APIC implementation.
1344 * @param u8DeliveryMode See APIC implementation.
1345 * @param iVector See APIC implementation.
1346 * @param u8Polarity See APIC implementation.
1347 * @param u8TriggerMode See APIC implementation.
1348 */
1349 DECLR0CALLBACKMEMBER(void, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1350 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
1351
1352 /**
1353 * Acquires the PDM lock.
1354 *
1355 * @returns VINF_SUCCESS on success.
1356 * @returns rc if we failed to acquire the lock.
1357 * @param pDevIns The IOAPIC device instance.
1358 * @param rc What to return if we fail to acquire the lock.
1359 */
1360 DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1361
1362 /**
1363 * Releases the PDM lock.
1364 *
1365 * @param pDevIns The IOAPIC device instance.
1366 */
1367 DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1368
1369 /** Just a safety precaution. */
1370 uint32_t u32TheEnd;
1371} PDMIOAPICHLPR0;
1372/** Pointer to IOAPIC R0 helpers. */
1373typedef R0PTRTYPE(PDMAPICHLPGC *) PPDMIOAPICHLPR0;
1374/** Pointer to const IOAPIC helpers. */
1375typedef R0PTRTYPE(const PDMIOAPICHLPR0 *) PCPDMIOAPICHLPR0;
1376
1377/** Current PDMIOAPICHLPR0 version number. */
1378#define PDM_IOAPICHLPR0_VERSION 0xfe010000
1379
1380/**
1381 * IOAPIC HC helpers.
1382 */
1383typedef struct PDMIOAPICHLPR3
1384{
1385 /** Structure version. PDM_IOAPICHLPR3_VERSION defines the current version. */
1386 uint32_t u32Version;
1387
1388 /**
1389 * Private interface between the IOAPIC and APIC.
1390 *
1391 * See comments about this hack on PDMAPICREG::pfnBusDeliverHC.
1392 *
1393 * @returns The current TPR.
1394 * @param pDevIns Device instance of the IOAPIC.
1395 * @param u8Dest See APIC implementation.
1396 * @param u8DestMode See APIC implementation.
1397 * @param u8DeliveryMode See APIC implementation.
1398 * @param iVector See APIC implementation.
1399 * @param u8Polarity See APIC implementation.
1400 * @param u8TriggerMode See APIC implementation.
1401 */
1402 DECLR3CALLBACKMEMBER(void, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
1403 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode));
1404
1405 /**
1406 * Acquires the PDM lock.
1407 *
1408 * @returns VINF_SUCCESS on success.
1409 * @returns Fatal error on failure.
1410 * @param pDevIns The IOAPIC device instance.
1411 * @param rc Dummy for making the interface identical to the GC and R0 versions.
1412 */
1413 DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
1414
1415 /**
1416 * Releases the PDM lock.
1417 *
1418 * @param pDevIns The IOAPIC device instance.
1419 */
1420 DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
1421
1422 /**
1423 * Gets the address of the GC IOAPIC helpers.
1424 *
1425 * This should be called at both construction and relocation time
1426 * to obtain the correct address of the GC helpers.
1427 *
1428 * @returns GC pointer to the IOAPIC helpers.
1429 * @param pDevIns Device instance of the IOAPIC.
1430 */
1431 DECLR3CALLBACKMEMBER(PCPDMIOAPICHLPGC, pfnGetGCHelpers,(PPDMDEVINS pDevIns));
1432
1433 /**
1434 * Gets the address of the R0 IOAPIC helpers.
1435 *
1436 * This should be called at both construction and relocation time
1437 * to obtain the correct address of the R0 helpers.
1438 *
1439 * @returns R0 pointer to the IOAPIC helpers.
1440 * @param pDevIns Device instance of the IOAPIC.
1441 */
1442 DECLR3CALLBACKMEMBER(PCPDMIOAPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
1443
1444 /** Just a safety precaution. */
1445 uint32_t u32TheEnd;
1446} PDMIOAPICHLPR3;
1447/** Pointer to IOAPIC HC helpers. */
1448typedef R3PTRTYPE(PDMIOAPICHLPR3 *) PPDMIOAPICHLPR3;
1449/** Pointer to const IOAPIC helpers. */
1450typedef R3PTRTYPE(const PDMIOAPICHLPR3 *) PCPDMIOAPICHLPR3;
1451
1452/** Current PDMIOAPICHLPR3 version number. */
1453#define PDM_IOAPICHLPR3_VERSION 0xff010000
1454
1455
1456
1457#ifdef IN_RING3
1458
1459/**
1460 * DMA Transfer Handler.
1461 *
1462 * @returns Number of bytes transferred.
1463 * @param pDevIns Device instance of the DMA.
1464 * @param pvUser User pointer.
1465 * @param uChannel Channel number.
1466 * @param off DMA position.
1467 * @param cb Block size.
1468 */
1469typedef DECLCALLBACK(uint32_t) FNDMATRANSFERHANDLER(PPDMDEVINS pDevIns, void *pvUser, unsigned uChannel, uint32_t off, uint32_t cb);
1470/** Pointer to a FNDMATRANSFERHANDLER(). */
1471typedef FNDMATRANSFERHANDLER *PFNDMATRANSFERHANDLER;
1472
1473/**
1474 * DMA Controller registration structure.
1475 */
1476typedef struct PDMDMAREG
1477{
1478 /** Structure version number. PDM_DMACREG_VERSION defines the current version. */
1479 uint32_t u32Version;
1480
1481 /**
1482 * Execute pending transfers.
1483 *
1484 * @returns A more work indiciator. I.e. 'true' if there is more to be done, and 'false' if all is done.
1485 * @param pDevIns Device instance of the DMAC.
1486 */
1487 DECLR3CALLBACKMEMBER(bool, pfnRun,(PPDMDEVINS pDevIns));
1488
1489 /**
1490 * Register transfer function for DMA channel.
1491 *
1492 * @param pDevIns Device instance of the DMAC.
1493 * @param uChannel Channel number.
1494 * @param pfnTransferHandler Device specific transfer function.
1495 * @param pvUSer User pointer to be passed to the callback.
1496 */
1497 DECLR3CALLBACKMEMBER(void, pfnRegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
1498
1499 /**
1500 * Read memory
1501 *
1502 * @returns Number of bytes read.
1503 * @param pDevIns Device instance of the DMAC.
1504 * @param pvBuffer Pointer to target buffer.
1505 * @param off DMA position.
1506 * @param cbBlock Block size.
1507 */
1508 DECLR3CALLBACKMEMBER(uint32_t, pfnReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock));
1509
1510 /**
1511 * Write memory
1512 *
1513 * @returns Number of bytes written.
1514 * @param pDevIns Device instance of the DMAC.
1515 * @param pvBuffer Memory to write.
1516 * @param off DMA position.
1517 * @param cbBlock Block size.
1518 */
1519 DECLR3CALLBACKMEMBER(uint32_t, pfnWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock));
1520
1521 /**
1522 * Set the DREQ line.
1523 *
1524 * @param pDevIns Device instance of the DMAC.
1525 * @param uChannel Channel number.
1526 * @param uLevel Level of the line.
1527 */
1528 DECLR3CALLBACKMEMBER(void, pfnSetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
1529
1530 /**
1531 * Get channel mode
1532 *
1533 * @returns Channel mode.
1534 * @param pDevIns Device instance of the DMAC.
1535 * @param uChannel Channel number.
1536 */
1537 DECLR3CALLBACKMEMBER(uint8_t, pfnGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
1538
1539} PDMDMACREG;
1540/** Pointer to a DMAC registration structure. */
1541typedef PDMDMACREG *PPDMDMACREG;
1542
1543/** Current PDMDMACREG version number. */
1544#define PDM_DMACREG_VERSION 0xf5010000
1545
1546
1547/**
1548 * DMA Controller device helpers.
1549 */
1550typedef struct PDMDMACHLP
1551{
1552 /** Structure version. PDM_DMACHLP_VERSION defines the current version. */
1553 uint32_t u32Version;
1554
1555 /* to-be-defined */
1556
1557} PDMDMACHLP;
1558/** Pointer to DMAC helpers. */
1559typedef PDMDMACHLP *PPDMDMACHLP;
1560/** Pointer to const DMAC helpers. */
1561typedef const PDMDMACHLP *PCPDMDMACHLP;
1562
1563/** Current PDMDMACHLP version number. */
1564#define PDM_DMACHLP_VERSION 0xf6010000
1565
1566#endif /* IN_RING3 */
1567
1568
1569
1570/**
1571 * RTC registration structure.
1572 */
1573typedef struct PDMRTCREG
1574{
1575 /** Structure version number. PDM_RTCREG_VERSION defines the current version. */
1576 uint32_t u32Version;
1577 uint32_t u32Alignment; /**< structure size alignment. */
1578
1579 /**
1580 * Write to a CMOS register and update the checksum if necessary.
1581 *
1582 * @returns VBox status code.
1583 * @param pDevIns Device instance of the RTC.
1584 * @param iReg The CMOS register index.
1585 * @param u8Value The CMOS register value.
1586 */
1587 DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
1588
1589 /**
1590 * Read a CMOS register.
1591 *
1592 * @returns VBox status code.
1593 * @param pDevIns Device instance of the RTC.
1594 * @param iReg The CMOS register index.
1595 * @param pu8Value Where to store the CMOS register value.
1596 */
1597 DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
1598
1599} PDMRTCREG;
1600/** Pointer to a RTC registration structure. */
1601typedef PDMRTCREG *PPDMRTCREG;
1602/** Pointer to a const RTC registration structure. */
1603typedef const PDMRTCREG *PCPDMRTCREG;
1604
1605/** Current PDMRTCREG version number. */
1606#define PDM_RTCREG_VERSION 0xfa010000
1607
1608
1609/**
1610 * RTC device helpers.
1611 */
1612typedef struct PDMRTCHLP
1613{
1614 /** Structure version. PDM_RTCHLP_VERSION defines the current version. */
1615 uint32_t u32Version;
1616
1617 /* to-be-defined */
1618
1619} PDMRTCHLP;
1620/** Pointer to RTC helpers. */
1621typedef PDMRTCHLP *PPDMRTCHLP;
1622/** Pointer to const RTC helpers. */
1623typedef const PDMRTCHLP *PCPDMRTCHLP;
1624
1625/** Current PDMRTCHLP version number. */
1626#define PDM_RTCHLP_VERSION 0xf6010000
1627
1628
1629
1630#ifdef IN_RING3
1631
1632/**
1633 * PDM Device API.
1634 */
1635typedef struct PDMDEVHLP
1636{
1637 /** Structure version. PDM_DEVHLP_VERSION defines the current version. */
1638 uint32_t u32Version;
1639
1640 /**
1641 * Register a number of I/O ports with a device.
1642 *
1643 * These callbacks are of course for the host context (HC).
1644 * Register HC handlers before guest context (GC) handlers! There must be a
1645 * HC handler for every GC handler!
1646 *
1647 * @returns VBox status.
1648 * @param pDevIns The device instance to register the ports with.
1649 * @param Port First port number in the range.
1650 * @param cPorts Number of ports to register.
1651 * @param pvUser User argument.
1652 * @param pfnOut Pointer to function which is gonna handle OUT operations.
1653 * @param pfnIn Pointer to function which is gonna handle IN operations.
1654 * @param pfnOutStr Pointer to function which is gonna handle string OUT operations.
1655 * @param pfnInStr Pointer to function which is gonna handle string IN operations.
1656 * @param pszDesc Pointer to description string. This must not be freed.
1657 */
1658 DECLR3CALLBACKMEMBER(int, pfnIOPortRegister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser,
1659 PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
1660 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc));
1661
1662 /**
1663 * Register a number of I/O ports with a device for GC.
1664 *
1665 * These callbacks are for the host context (GC).
1666 * Register host context (HC) handlers before guest context handlers! There must be a
1667 * HC handler for every GC handler!
1668 *
1669 * @returns VBox status.
1670 * @param pDevIns The device instance to register the ports with and which GC module
1671 * to resolve the names against.
1672 * @param Port First port number in the range.
1673 * @param cPorts Number of ports to register.
1674 * @param pvUser User argument.
1675 * @param pszOut Name of the GC function which is gonna handle OUT operations.
1676 * @param pszIn Name of the GC function which is gonna handle IN operations.
1677 * @param pszOutStr Name of the GC function which is gonna handle string OUT operations.
1678 * @param pszInStr Name of the GC function which is gonna handle string IN operations.
1679 * @param pszDesc Pointer to description string. This must not be freed.
1680 */
1681 DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterGC,(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser,
1682 const char *pszOut, const char *pszIn,
1683 const char *pszOutStr, const char *pszInStr, const char *pszDesc));
1684
1685 /**
1686 * Register a number of I/O ports with a device.
1687 *
1688 * These callbacks are of course for the ring-0 host context (R0).
1689 * Register R3 (HC) handlers before R0 (R0) handlers! There must be a R3 (HC) handler for every R0 handler!
1690 *
1691 * @returns VBox status.
1692 * @param pDevIns The device instance to register the ports with.
1693 * @param Port First port number in the range.
1694 * @param cPorts Number of ports to register.
1695 * @param pvUser User argument. (if pointer, then it must be in locked memory!)
1696 * @param pszOut Name of the R0 function which is gonna handle OUT operations.
1697 * @param pszIn Name of the R0 function which is gonna handle IN operations.
1698 * @param pszOutStr Name of the R0 function which is gonna handle string OUT operations.
1699 * @param pszInStr Name of the R0 function which is gonna handle string IN operations.
1700 * @param pszDesc Pointer to description string. This must not be freed.
1701 */
1702 DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterR0,(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser,
1703 const char *pszOut, const char *pszIn,
1704 const char *pszOutStr, const char *pszInStr, const char *pszDesc));
1705
1706 /**
1707 * Deregister I/O ports.
1708 *
1709 * This naturally affects both guest context (GC), ring-0 (R0) and ring-3 (R3/HC) handlers.
1710 *
1711 * @returns VBox status.
1712 * @param pDevIns The device instance owning the ports.
1713 * @param Port First port number in the range.
1714 * @param cPorts Number of ports to deregister.
1715 */
1716 DECLR3CALLBACKMEMBER(int, pfnIOPortDeregister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts));
1717
1718 /**
1719 * Register a Memory Mapped I/O (MMIO) region.
1720 *
1721 * These callbacks are of course for the host context (HC).
1722 * Register HC handlers before guest context (GC) handlers! There must be a
1723 * HC handler for every GC handler!
1724 *
1725 * @returns VBox status.
1726 * @param pDevIns The device instance to register the MMIO with.
1727 * @param GCPhysStart First physical address in the range.
1728 * @param cbRange The size of the range (in bytes).
1729 * @param pvUser User argument.
1730 * @param pfnWrite Pointer to function which is gonna handle Write operations.
1731 * @param pfnRead Pointer to function which is gonna handle Read operations.
1732 * @param pfnFill Pointer to function which is gonna handle Fill/memset operations. (optional)
1733 * @param pszDesc Pointer to description string. This must not be freed.
1734 */
1735 DECLR3CALLBACKMEMBER(int, pfnMMIORegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,
1736 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
1737 const char *pszDesc));
1738
1739 /**
1740 * Register a Memory Mapped I/O (MMIO) region for GC.
1741 *
1742 * These callbacks are for the guest context (GC).
1743 * Register host context (HC) handlers before guest context handlers! There must be a
1744 * HC handler for every GC handler!
1745 *
1746 * @returns VBox status.
1747 * @param pDevIns The device instance to register the MMIO with.
1748 * @param GCPhysStart First physical address in the range.
1749 * @param cbRange The size of the range (in bytes).
1750 * @param pvUser User argument.
1751 * @param pszWrite Name of the GC function which is gonna handle Write operations.
1752 * @param pszRead Name of the GC function which is gonna handle Read operations.
1753 * @param pszFill Name of the GC function which is gonna handle Fill/memset operations. (optional)
1754 * @param pszDesc Obsolete. NULL is fine.
1755 * @todo Remove pszDesc in the next major revision of PDMDEVHLP.
1756 */
1757 DECLR3CALLBACKMEMBER(int, pfnMMIORegisterGC,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,
1758 const char *pszWrite, const char *pszRead, const char *pszFill,
1759 const char *pszDesc));
1760
1761 /**
1762 * Register a Memory Mapped I/O (MMIO) region for R0.
1763 *
1764 * These callbacks are for the ring-0 host context (R0).
1765 * Register R3 (HC) handlers before R0 handlers! There must be a R3 handler for every R0 handler!
1766 *
1767 * @returns VBox status.
1768 * @param pDevIns The device instance to register the MMIO with.
1769 * @param GCPhysStart First physical address in the range.
1770 * @param cbRange The size of the range (in bytes).
1771 * @param pvUser User argument. (if pointer, then it must be in locked memory!)
1772 * @param pszWrite Name of the GC function which is gonna handle Write operations.
1773 * @param pszRead Name of the GC function which is gonna handle Read operations.
1774 * @param pszFill Name of the GC function which is gonna handle Fill/memset operations. (optional)
1775 * @param pszDesc Obsolete. NULL is fine.
1776 * @todo Remove pszDesc in the next major revision of PDMDEVHLP.
1777 */
1778 DECLR3CALLBACKMEMBER(int, pfnMMIORegisterR0,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,
1779 const char *pszWrite, const char *pszRead, const char *pszFill,
1780 const char *pszDesc));
1781
1782 /**
1783 * Deregister a Memory Mapped I/O (MMIO) region.
1784 *
1785 * This naturally affects both guest context (GC), ring-0 (R0) and ring-3 (R3/HC) handlers.
1786 *
1787 * @returns VBox status.
1788 * @param pDevIns The device instance owning the MMIO region(s).
1789 * @param GCPhysStart First physical address in the range.
1790 * @param cbRange The size of the range (in bytes).
1791 */
1792 DECLR3CALLBACKMEMBER(int, pfnMMIODeregister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange));
1793
1794 /**
1795 * Register a ROM (BIOS) region.
1796 *
1797 * It goes without saying that this is read-only memory. The memory region must be
1798 * in unassigned memory. I.e. from the top of the address space or on the PC in
1799 * the 0xa0000-0xfffff range.
1800 *
1801 * @returns VBox status.
1802 * @param pDevIns The device instance owning the ROM region.
1803 * @param GCPhysStart First physical address in the range.
1804 * Must be page aligned!
1805 * @param cbRange The size of the range (in bytes).
1806 * Must be page aligned!
1807 * @param pvBinary Pointer to the binary data backing the ROM image.
1808 * This must be cbRange bytes big.
1809 * It will be copied and doesn't have to stick around if fShadow is clear.
1810 * @param fShadow Whether to emulate ROM shadowing. This involves leaving
1811 * the ROM writable for a while during the POST and refreshing
1812 * it at reset. When this flag is set, the memory pointed to by
1813 * pvBinary has to stick around for the lifespan of the VM.
1814 * @param pszDesc Pointer to description string. This must not be freed.
1815 *
1816 * @remark There is no way to remove the rom, automatically on device cleanup or
1817 * manually from the device yet. At present I doubt we need such features...
1818 */
1819 DECLR3CALLBACKMEMBER(int, pfnROMRegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc));
1820
1821 /**
1822 * Register a save state data unit.
1823 *
1824 * @returns VBox status.
1825 * @param pDevIns Device instance.
1826 * @param pszName Data unit name.
1827 * @param u32Instance The instance identifier of the data unit.
1828 * This must together with the name be unique.
1829 * @param u32Version Data layout version number.
1830 * @param cbGuess The approximate amount of data in the unit.
1831 * Only for progress indicators.
1832 * @param pfnSavePrep Prepare save callback, optional.
1833 * @param pfnSaveExec Execute save callback, optional.
1834 * @param pfnSaveDone Done save callback, optional.
1835 * @param pfnLoadPrep Prepare load callback, optional.
1836 * @param pfnLoadExec Execute load callback, optional.
1837 * @param pfnLoadDone Done load callback, optional.
1838 */
1839 DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,
1840 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
1841 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone));
1842
1843 /**
1844 * Creates a timer.
1845 *
1846 * @returns VBox status.
1847 * @param pDevIns Device instance.
1848 * @param enmClock The clock to use on this timer.
1849 * @param pfnCallback Callback function.
1850 * @param pszDesc Pointer to description string which must stay around
1851 * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
1852 * @param ppTimer Where to store the timer on success.
1853 */
1854 DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer));
1855
1856 /**
1857 * Creates an external timer.
1858 *
1859 * @returns timer pointer
1860 * @param pDevIns Device instance.
1861 * @param enmClock The clock to use on this timer.
1862 * @param pfnCallback Callback function.
1863 * @param pvUser User pointer
1864 * @param pszDesc Pointer to description string which must stay around
1865 * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
1866 */
1867 DECLR3CALLBACKMEMBER(PTMTIMERR3, pfnTMTimerCreateExternal,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc));
1868
1869 /**
1870 * Registers the device with the default PCI bus.
1871 *
1872 * @returns VBox status code.
1873 * @param pDevIns Device instance.
1874 * @param pPciDev The PCI device structure.
1875 * Any PCI enabled device must keep this in it's instance data!
1876 * Fill in the PCI data config before registration, please.
1877 * @remark This is the simple interface, a Ex interface will be created if
1878 * more features are needed later.
1879 */
1880 DECLR3CALLBACKMEMBER(int, pfnPCIRegister,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev));
1881
1882 /**
1883 * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
1884 *
1885 * @returns VBox status code.
1886 * @param pDevIns Device instance.
1887 * @param iRegion The region number.
1888 * @param cbRegion Size of the region.
1889 * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
1890 * @param pfnCallback Callback for doing the mapping.
1891 */
1892 DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
1893
1894 /**
1895 * Register PCI configuration space read/write callbacks.
1896 *
1897 * @param pDevIns Device instance.
1898 * @param pPciDev The PCI device structure.
1899 * If NULL the default PCI device for this device instance is used.
1900 * @param pfnRead Pointer to the user defined PCI config read function.
1901 * @param ppfnReadOld Pointer to function pointer which will receive the old (default)
1902 * PCI config read function. This way, user can decide when (and if)
1903 * to call default PCI config read function. Can be NULL.
1904 * @param pfnWrite Pointer to the user defined PCI config write function.
1905 * @param pfnWriteOld Pointer to function pointer which will receive the old (default)
1906 * PCI config write function. This way, user can decide when (and if)
1907 * to call default PCI config write function. Can be NULL.
1908 * @thread EMT
1909 */
1910 DECLR3CALLBACKMEMBER(void, pfnPCISetConfigCallbacks,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
1911 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
1912
1913 /**
1914 * Set the IRQ for a PCI device.
1915 *
1916 * @param pDevIns Device instance.
1917 * @param iIrq IRQ number to set.
1918 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1919 * @thread Any thread, but will involve the emulation thread.
1920 */
1921 DECLR3CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
1922
1923 /**
1924 * Set the IRQ for a PCI device, but don't wait for EMT to process
1925 * the request when not called from EMT.
1926 *
1927 * @param pDevIns Device instance.
1928 * @param iIrq IRQ number to set.
1929 * @param iLevel IRQ level.
1930 * @thread Any thread, but will involve the emulation thread.
1931 */
1932 DECLR3CALLBACKMEMBER(void, pfnPCISetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
1933
1934 /**
1935 * Set ISA IRQ for a device.
1936 *
1937 * @param pDevIns Device instance.
1938 * @param iIrq IRQ number to set.
1939 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1940 * @thread Any thread, but will involve the emulation thread.
1941 */
1942 DECLR3CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
1943
1944 /**
1945 * Set the ISA IRQ for a device, but don't wait for EMT to process
1946 * the request when not called from EMT.
1947 *
1948 * @param pDevIns Device instance.
1949 * @param iIrq IRQ number to set.
1950 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
1951 * @thread Any thread, but will involve the emulation thread.
1952 */
1953 DECLR3CALLBACKMEMBER(void, pfnISASetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
1954
1955 /**
1956 * Attaches a driver (chain) to the device.
1957 *
1958 * The first call for a LUN this will serve as a registartion of the LUN. The pBaseInterface and
1959 * the pszDesc string will be registered with that LUN and kept around for PDMR3QueryDeviceLun().
1960 *
1961 * @returns VBox status code.
1962 * @param pDevIns Device instance.
1963 * @param iLun The logical unit to attach.
1964 * @param pBaseInterface Pointer to the base interface for that LUN. (device side / down)
1965 * @param ppBaseInterface Where to store the pointer to the base interface. (driver side / up)
1966 * @param pszDesc Pointer to a string describing the LUN. This string must remain valid
1967 * for the live of the device instance.
1968 */
1969 DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc));
1970
1971 /**
1972 * Allocate memory which is associated with current VM instance
1973 * and automatically freed on it's destruction.
1974 *
1975 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
1976 * @param pDevIns Device instance.
1977 * @param cb Number of bytes to allocate.
1978 */
1979 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAlloc,(PPDMDEVINS pDevIns, size_t cb));
1980
1981 /**
1982 * Allocate memory which is associated with current VM instance
1983 * and automatically freed on it's destruction. The memory is ZEROed.
1984 *
1985 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
1986 * @param pDevIns Device instance.
1987 * @param cb Number of bytes to allocate.
1988 */
1989 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAllocZ,(PPDMDEVINS pDevIns, size_t cb));
1990
1991 /**
1992 * Free memory allocated with pfnMMHeapAlloc() and pfnMMHeapAllocZ().
1993 *
1994 * @param pDevIns Device instance.
1995 * @param pv Pointer to the memory to free.
1996 */
1997 DECLR3CALLBACKMEMBER(void, pfnMMHeapFree,(PPDMDEVINS pDevIns, void *pv));
1998
1999 /**
2000 * Set the VM error message
2001 *
2002 * @returns rc.
2003 * @param pDevIns Device instance.
2004 * @param rc VBox status code.
2005 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2006 * @param pszFormat Error message format string.
2007 * @param ... Error message arguments.
2008 */
2009 DECLR3CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
2010
2011 /**
2012 * Set the VM error message
2013 *
2014 * @returns rc.
2015 * @param pDevIns Device instance.
2016 * @param rc VBox status code.
2017 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2018 * @param pszFormat Error message format string.
2019 * @param va Error message arguments.
2020 */
2021 DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
2022
2023 /**
2024 * Set the VM runtime error message
2025 *
2026 * @returns VBox status code.
2027 * @param pDevIns Device instance.
2028 * @param fFatal Whether it is a fatal error or not.
2029 * @param pszErrorID Error ID string.
2030 * @param pszFormat Error message format string.
2031 * @param ... Error message arguments.
2032 */
2033 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...));
2034
2035 /**
2036 * Set the VM runtime error message
2037 *
2038 * @returns VBox status code.
2039 * @param pDevIns Device instance.
2040 * @param fFatal Whether it is a fatal error or not.
2041 * @param pszErrorID Error ID string.
2042 * @param pszFormat Error message format string.
2043 * @param va Error message arguments.
2044 */
2045 DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va));
2046
2047 /**
2048 * Assert that the current thread is the emulation thread.
2049 *
2050 * @returns True if correct.
2051 * @returns False if wrong.
2052 * @param pDevIns Device instance.
2053 * @param pszFile Filename of the assertion location.
2054 * @param iLine The linenumber of the assertion location.
2055 * @param pszFunction Function of the assertion location.
2056 */
2057 DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
2058
2059 /**
2060 * Assert that the current thread is NOT the emulation thread.
2061 *
2062 * @returns True if correct.
2063 * @returns False if wrong.
2064 * @param pDevIns Device instance.
2065 * @param pszFile Filename of the assertion location.
2066 * @param iLine The linenumber of the assertion location.
2067 * @param pszFunction Function of the assertion location.
2068 */
2069 DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
2070
2071 /**
2072 * Stops the VM and enters the debugger to look at the guest state.
2073 *
2074 * Use the PDMDeviceDBGFStop() inline function with the RT_SRC_POS macro instead of
2075 * invoking this function directly.
2076 *
2077 * @returns VBox status code which must be passed up to the VMM.
2078 * @param pDevIns Device instance.
2079 * @param pszFile Filename of the assertion location.
2080 * @param iLine The linenumber of the assertion location.
2081 * @param pszFunction Function of the assertion location.
2082 * @param pszFormat Message. (optional)
2083 * @param args Message parameters.
2084 */
2085 DECLR3CALLBACKMEMBER(int, pfnDBGFStopV,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args));
2086
2087 /**
2088 * Register a info handler with DBGF,
2089 *
2090 * @returns VBox status code.
2091 * @param pDevIns Device instance.
2092 * @param pszName The identifier of the info.
2093 * @param pszDesc The description of the info and any arguments the handler may take.
2094 * @param pfnHandler The handler function to be called to display the info.
2095 */
2096 DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler));
2097
2098 /**
2099 * Registers a statistics sample if statistics are enabled.
2100 *
2101 * @param pDevIns Device instance of the DMA.
2102 * @param pvSample Pointer to the sample.
2103 * @param enmType Sample type. This indicates what pvSample is pointing at.
2104 * @param pszName Sample name. The name is on this form "/<component>/<sample>".
2105 * Further nesting is possible.
2106 * @param enmUnit Sample unit.
2107 * @param pszDesc Sample description.
2108 */
2109 DECLR3CALLBACKMEMBER(void, pfnSTAMRegister,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc));
2110
2111 /**
2112 * Same as pfnSTAMRegister except that the name is specified in a
2113 * RTStrPrintf like fashion.
2114 *
2115 * @returns VBox status.
2116 * @param pDevIns Device instance of the DMA.
2117 * @param pvSample Pointer to the sample.
2118 * @param enmType Sample type. This indicates what pvSample is pointing at.
2119 * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
2120 * @param enmUnit Sample unit.
2121 * @param pszDesc Sample description.
2122 * @param pszName The sample name format string.
2123 * @param ... Arguments to the format string.
2124 */
2125 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterF,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
2126 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...));
2127
2128 /**
2129 * Same as pfnSTAMRegister except that the name is specified in a
2130 * RTStrPrintfV like fashion.
2131 *
2132 * @returns VBox status.
2133 * @param pDevIns Device instance of the DMA.
2134 * @param pvSample Pointer to the sample.
2135 * @param enmType Sample type. This indicates what pvSample is pointing at.
2136 * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
2137 * @param enmUnit Sample unit.
2138 * @param pszDesc Sample description.
2139 * @param pszName The sample name format string.
2140 * @param args Arguments to the format string.
2141 */
2142 DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
2143 STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args));
2144
2145 /**
2146 * Register the RTC device.
2147 *
2148 * @returns VBox status code.
2149 * @param pDevIns Device instance.
2150 * @param pRtcReg Pointer to a RTC registration structure.
2151 * @param ppRtcHlp Where to store the pointer to the helper functions.
2152 */
2153 DECLR3CALLBACKMEMBER(int, pfnRTCRegister,(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp));
2154
2155 /**
2156 * Create a queue.
2157 *
2158 * @returns VBox status code.
2159 * @param pDevIns The device instance.
2160 * @param cbItem The size of a queue item.
2161 * @param cItems The number of items in the queue.
2162 * @param cMilliesInterval The number of milliseconds between polling the queue.
2163 * If 0 then the emulation thread will be notified whenever an item arrives.
2164 * @param pfnCallback The consumer function.
2165 * @param fGCEnabled Set if the queue should work in GC too.
2166 * @param ppQueue Where to store the queue handle on success.
2167 * @thread The emulation thread.
2168 */
2169 DECLR3CALLBACKMEMBER(int, pfnPDMQueueCreate,(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
2170 PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue));
2171
2172 /**
2173 * Initializes a PDM critical section.
2174 *
2175 * The PDM critical sections are derived from the IPRT critical sections, but
2176 * works in GC as well.
2177 *
2178 * @returns VBox status code.
2179 * @param pDevIns Device instance.
2180 * @param pCritSect Pointer to the critical section.
2181 * @param pszName The name of the critical section (for statistics).
2182 */
2183 DECLR3CALLBACKMEMBER(int, pfnCritSectInit,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName));
2184
2185 /**
2186 * Get the real world UTC time adjusted for VM lag, user offset and warpdrive.
2187 *
2188 * @returns pTime.
2189 * @param pDevIns Device instance.
2190 * @param pTime Where to store the time.
2191 */
2192 DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnUTCNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime));
2193
2194 /**
2195 * Creates a PDM thread.
2196 *
2197 * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
2198 * resuming, and destroying the thread as the VM state changes.
2199 *
2200 * @returns VBox status code.
2201 * @param pDevIns The device instance.
2202 * @param ppThread Where to store the thread 'handle'.
2203 * @param pvUser The user argument to the thread function.
2204 * @param pfnThread The thread function.
2205 * @param pfnWakeup The wakup callback. This is called on the EMT thread when
2206 * a state change is pending.
2207 * @param cbStack See RTThreadCreate.
2208 * @param enmType See RTThreadCreate.
2209 * @param pszName See RTThreadCreate.
2210 */
2211 DECLR3CALLBACKMEMBER(int, pfnPDMThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
2212 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
2213
2214 /**
2215 * Convert a guest virtual address to a guest physical address.
2216 *
2217 * @returns VBox status code.
2218 * @param pDevIns Device instance.
2219 * @param GCPtr Guest virtual address.
2220 * @param pGCPhys Where to store the GC physical address corresponding to GCPtr.
2221 * @thread The emulation thread.
2222 * @remark Careful with page boundraries.
2223 */
2224 DECLR3CALLBACKMEMBER(int, pfnPhysGCPtr2GCPhys, (PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys));
2225
2226 /**
2227 * Gets the VM state.
2228 *
2229 * @returns VM state.
2230 * @param pDevIns The device instance.
2231 * @thread Any thread (just keep in mind that it's volatile info).
2232 */
2233 DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
2234
2235 /** Space reserved for future members.
2236 * @{ */
2237 DECLR3CALLBACKMEMBER(void, pfnReserved4,(void));
2238 DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
2239 DECLR3CALLBACKMEMBER(void, pfnReserved6,(void));
2240 DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
2241 DECLR3CALLBACKMEMBER(void, pfnReserved8,(void));
2242 DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));
2243 DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));
2244 /** @} */
2245
2246
2247 /** API available to trusted devices only.
2248 *
2249 * These APIs are providing unrestricted access to the guest and the VM,
2250 * or they are interacting intimately with PDM.
2251 *
2252 * @{
2253 */
2254 /**
2255 * Gets the VM handle. Restricted API.
2256 *
2257 * @returns VM Handle.
2258 * @param pDevIns Device instance.
2259 */
2260 DECLR3CALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
2261
2262 /**
2263 * Register the PCI Bus.
2264 *
2265 * @returns VBox status code.
2266 * @param pDevIns Device instance.
2267 * @param pPciBusReg Pointer to PCI bus registration structure.
2268 * @param ppPciHlpR3 Where to store the pointer to the PCI Bus helpers.
2269 */
2270 DECLR3CALLBACKMEMBER(int, pfnPCIBusRegister,(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3));
2271
2272 /**
2273 * Register the PIC device.
2274 *
2275 * @returns VBox status code.
2276 * @param pDevIns Device instance.
2277 * @param pPicReg Pointer to a PIC registration structure.
2278 * @param ppPicHlpR3 Where to store the pointer to the PIC HC helpers.
2279 */
2280 DECLR3CALLBACKMEMBER(int, pfnPICRegister,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3));
2281
2282 /**
2283 * Register the APIC device.
2284 *
2285 * @returns VBox status code.
2286 * @param pDevIns Device instance.
2287 * @param pApicReg Pointer to a APIC registration structure.
2288 * @param ppApicHlpR3 Where to store the pointer to the APIC helpers.
2289 */
2290 DECLR3CALLBACKMEMBER(int, pfnAPICRegister,(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3));
2291
2292 /**
2293 * Register the I/O APIC device.
2294 *
2295 * @returns VBox status code.
2296 * @param pDevIns Device instance.
2297 * @param pIoApicReg Pointer to a I/O APIC registration structure.
2298 * @param ppIoApicHlpR3 Where to store the pointer to the IOAPIC helpers.
2299 */
2300 DECLR3CALLBACKMEMBER(int, pfnIOAPICRegister,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3));
2301
2302 /**
2303 * Register the DMA device.
2304 *
2305 * @returns VBox status code.
2306 * @param pDevIns Device instance.
2307 * @param pDmacReg Pointer to a DMAC registration structure.
2308 * @param ppDmacHlp Where to store the pointer to the DMA helpers.
2309 */
2310 DECLR3CALLBACKMEMBER(int, pfnDMACRegister,(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp));
2311
2312 /**
2313 * Read physical memory.
2314 *
2315 * @param pDevIns Device instance.
2316 * @param GCPhys Physical address start reading from.
2317 * @param pvBuf Where to put the read bits.
2318 * @param cbRead How many bytes to read.
2319 * @thread Any thread, but the call may involve the emulation thread.
2320 */
2321 DECLR3CALLBACKMEMBER(void, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
2322
2323 /**
2324 * Write to physical memory.
2325 *
2326 * @param pDevIns Device instance.
2327 * @param GCPhys Physical address to write to.
2328 * @param pvBuf What to write.
2329 * @param cbWrite How many bytes to write.
2330 * @thread Any thread, but the call may involve the emulation thread.
2331 */
2332 DECLR3CALLBACKMEMBER(void, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
2333
2334 /**
2335 * Read guest physical memory by virtual address.
2336 *
2337 * @param pDevIns Device instance.
2338 * @param pvDst Where to put the read bits.
2339 * @param GCVirtSrc Guest virtual address to start reading from.
2340 * @param cb How many bytes to read.
2341 * @thread The emulation thread.
2342 */
2343 DECLR3CALLBACKMEMBER(int, pfnPhysReadGCVirt,(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb));
2344
2345 /**
2346 * Write to guest physical memory by virtual address.
2347 *
2348 * @param pDevIns Device instance.
2349 * @param GCVirtDst Guest virtual address to write to.
2350 * @param pvSrc What to write.
2351 * @param cb How many bytes to write.
2352 * @thread The emulation thread.
2353 */
2354 DECLR3CALLBACKMEMBER(int, pfnPhysWriteGCVirt,(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb));
2355
2356 /**
2357 * Reserve physical address space for ROM and MMIO ranges.
2358 *
2359 * @returns VBox status code.
2360 * @param pDevIns Device instance.
2361 * @param GCPhys Start physical address.
2362 * @param cbRange The size of the range.
2363 * @param pszDesc Description string.
2364 * @thread The emulation thread.
2365 */
2366 DECLR3CALLBACKMEMBER(int, pfnPhysReserve,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc));
2367
2368 /**
2369 * Convert a guest physical address to a host virtual address. (OBSOLETE)
2370 *
2371 * @returns VBox status code.
2372 * @param pDevIns Device instance.
2373 * @param GCPhys Start physical address.
2374 * @param cbRange The size of the range. Use 0 if you don't care about the range.
2375 * @param ppvHC Where to store the HC pointer corresponding to GCPhys.
2376 * @thread The emulation thread.
2377 *
2378 * @remark Careful with page boundraries.
2379 * @remark Do not use the mapping after you return to the caller! (it could get invalidated/changed)
2380 */
2381 DECLR3CALLBACKMEMBER(int, pfnObsoletePhys2HCVirt,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, PRTHCPTR ppvHC));
2382
2383 /**
2384 * Convert a guest virtual address to a host virtual address. (OBSOLETE)
2385 *
2386 * @returns VBox status code.
2387 * @param pDevIns Device instance.
2388 * @param GCPtr Guest virtual address.
2389 * @param pHCPtr Where to store the HC pointer corresponding to GCPtr.
2390 * @thread The emulation thread.
2391 *
2392 * @remark Careful with page boundraries.
2393 * @remark Do not use the mapping after you return to the caller! (it could get invalidated/changed)
2394 */
2395 DECLR3CALLBACKMEMBER(int, pfnObsoletePhysGCPtr2HCPtr,(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTHCPTR pHCPtr));
2396
2397 /**
2398 * Checks if the Gate A20 is enabled or not.
2399 *
2400 * @returns true if A20 is enabled.
2401 * @returns false if A20 is disabled.
2402 * @param pDevIns Device instance.
2403 * @thread The emulation thread.
2404 */
2405 DECLR3CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
2406
2407 /**
2408 * Enables or disables the Gate A20.
2409 *
2410 * @param pDevIns Device instance.
2411 * @param fEnable Set this flag to enable the Gate A20; clear it to disable.
2412 * @thread The emulation thread.
2413 */
2414 DECLR3CALLBACKMEMBER(void, pfnA20Set,(PPDMDEVINS pDevIns, bool fEnable));
2415
2416 /**
2417 * Resets the VM.
2418 *
2419 * @returns The appropriate VBox status code to pass around on reset.
2420 * @param pDevIns Device instance.
2421 * @thread The emulation thread.
2422 */
2423 DECLR3CALLBACKMEMBER(int, pfnVMReset,(PPDMDEVINS pDevIns));
2424
2425 /**
2426 * Suspends the VM.
2427 *
2428 * @returns The appropriate VBox status code to pass around on suspend.
2429 * @param pDevIns Device instance.
2430 * @thread The emulation thread.
2431 */
2432 DECLR3CALLBACKMEMBER(int, pfnVMSuspend,(PPDMDEVINS pDevIns));
2433
2434 /**
2435 * Power off the VM.
2436 *
2437 * @returns The appropriate VBox status code to pass around on power off.
2438 * @param pDevIns Device instance.
2439 * @thread The emulation thread.
2440 */
2441 DECLR3CALLBACKMEMBER(int, pfnVMPowerOff,(PPDMDEVINS pDevIns));
2442
2443 /**
2444 * Acquire global VM lock
2445 *
2446 * @returns VBox status code
2447 * @param pDevIns Device instance.
2448 */
2449 DECLR3CALLBACKMEMBER(int , pfnLockVM,(PPDMDEVINS pDevIns));
2450
2451 /**
2452 * Release global VM lock
2453 *
2454 * @returns VBox status code
2455 * @param pDevIns Device instance.
2456 */
2457 DECLR3CALLBACKMEMBER(int, pfnUnlockVM,(PPDMDEVINS pDevIns));
2458
2459 /**
2460 * Check that the current thread owns the global VM lock.
2461 *
2462 * @returns boolean
2463 * @param pDevIns Device instance.
2464 * @param pszFile Filename of the assertion location.
2465 * @param iLine Linenumber of the assertion location.
2466 * @param pszFunction Function of the assertion location.
2467 */
2468 DECLR3CALLBACKMEMBER(bool, pfnAssertVMLock,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
2469
2470 /**
2471 * Register transfer function for DMA channel.
2472 *
2473 * @returns VBox status code.
2474 * @param pDevIns Device instance.
2475 * @param uChannel Channel number.
2476 * @param pfnTransferHandler Device specific transfer callback function.
2477 * @param pvUser User pointer to pass to the callback.
2478 * @thread EMT
2479 */
2480 DECLR3CALLBACKMEMBER(int, pfnDMARegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
2481
2482 /**
2483 * Read memory.
2484 *
2485 * @returns VBox status code.
2486 * @param pDevIns Device instance.
2487 * @param uChannel Channel number.
2488 * @param pvBuffer Pointer to target buffer.
2489 * @param off DMA position.
2490 * @param cbBlock Block size.
2491 * @param pcbRead Where to store the number of bytes which was read. optional.
2492 * @thread EMT
2493 */
2494 DECLR3CALLBACKMEMBER(int, pfnDMAReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead));
2495
2496 /**
2497 * Write memory.
2498 *
2499 * @returns VBox status code.
2500 * @param pDevIns Device instance.
2501 * @param uChannel Channel number.
2502 * @param pvBuffer Memory to write.
2503 * @param off DMA position.
2504 * @param cbBlock Block size.
2505 * @param pcbWritten Where to store the number of bytes which was written. optional.
2506 * @thread EMT
2507 */
2508 DECLR3CALLBACKMEMBER(int, pfnDMAWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten));
2509
2510 /**
2511 * Set the DREQ line.
2512 *
2513 * @returns VBox status code.
2514 * @param pDevIns Device instance.
2515 * @param uChannel Channel number.
2516 * @param uLevel Level of the line.
2517 * @thread EMT
2518 */
2519 DECLR3CALLBACKMEMBER(int, pfnDMASetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
2520
2521 /**
2522 * Get channel mode.
2523 *
2524 * @returns Channel mode. See specs.
2525 * @param pDevIns Device instance.
2526 * @param uChannel Channel number.
2527 * @thread EMT
2528 */
2529 DECLR3CALLBACKMEMBER(uint8_t, pfnDMAGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
2530
2531 /**
2532 * Schedule DMA execution.
2533 *
2534 * @param pDevIns Device instance.
2535 * @thread Any thread.
2536 */
2537 DECLR3CALLBACKMEMBER(void, pfnDMASchedule,(PPDMDEVINS pDevIns));
2538
2539 /**
2540 * Write CMOS value and update the checksum(s).
2541 *
2542 * @returns VBox status code.
2543 * @param pDevIns Device instance.
2544 * @param iReg The CMOS register index.
2545 * @param u8Value The CMOS register value.
2546 * @thread EMT
2547 */
2548 DECLR3CALLBACKMEMBER(int, pfnCMOSWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
2549
2550 /**
2551 * Read CMOS value.
2552 *
2553 * @returns VBox status code.
2554 * @param pDevIns Device instance.
2555 * @param iReg The CMOS register index.
2556 * @param pu8Value Where to store the CMOS register value.
2557 * @thread EMT
2558 */
2559 DECLR3CALLBACKMEMBER(int, pfnCMOSRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
2560
2561 /**
2562 * Query CPUID.
2563 *
2564 * @param pDevIns Device instance.
2565 * @param iLeaf The CPUID leaf to get.
2566 * @param pEax Where to store the EAX value.
2567 * @param pEbx Where to store the EBX value.
2568 * @param pEcx Where to store the ECX value.
2569 * @param pEdx Where to store the EDX value.
2570 */
2571 DECLR3CALLBACKMEMBER(void, pfnGetCpuId,(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx));
2572
2573 /**
2574 * Write protects a shadow ROM mapping.
2575 *
2576 * This is intented for use by the system BIOS or by the device that
2577 * employs a shadow ROM BIOS, so that the shadow ROM mapping can be
2578 * write protected once the POST is over.
2579 *
2580 * @param pDevIns Device instance.
2581 * @param GCPhysStart Where the shadow ROM mapping starts.
2582 * @param cbRange The size of the shadow ROM mapping.
2583 */
2584 DECLR3CALLBACKMEMBER(int, pfnROMProtectShadow,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange));
2585
2586 /**
2587 * Allocate and register a MMIO2 region.
2588 *
2589 * As mentioned elsewhere, MMIO2 is just RAM spelled differently. It's
2590 * RAM associated with a device. It is also non-shared memory with a
2591 * permanent ring-3 mapping and page backing (presently).
2592 *
2593 * @returns VBox status.
2594 * @param pDevIns The device instance.
2595 * @param iRegion The region number. Use the PCI region number as
2596 * this must be known to the PCI bus device too. If it's not associated
2597 * with the PCI device, then any number up to UINT8_MAX is fine.
2598 * @param cb The size (in bytes) of the region.
2599 * @param fFlags Reserved for future use, must be zero.
2600 * @param ppv Where to store the address of the ring-3 mapping of the memory.
2601 * @param pszDesc Pointer to description string. This must not be freed.
2602 * @thread EMT.
2603 */
2604 DECLR3CALLBACKMEMBER(int, pfnMMIO2Register,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc));
2605
2606 /**
2607 * Deregisters and frees a MMIO2 region.
2608 *
2609 * Any physical (and virtual) access handlers registered for the region must
2610 * be deregistered before calling this function.
2611 *
2612 * @returns VBox status code.
2613 * @param pDevIns The device instance.
2614 * @param iRegion The region number used during registration.
2615 * @thread EMT.
2616 */
2617 DECLR3CALLBACKMEMBER(int, pfnMMIO2Deregister,(PPDMDEVINS pDevIns, uint32_t iRegion));
2618
2619 /**
2620 * Maps a MMIO2 region into the physical memory space.
2621 *
2622 * A MMIO2 range may overlap with base memory if a lot of RAM
2623 * is configured for the VM, in which case we'll drop the base
2624 * memory pages. Presently we will make no attempt to preserve
2625 * anything that happens to be present in the base memory that
2626 * is replaced, this is of course incorrectly but it's too much
2627 * effort.
2628 *
2629 * @returns VBox status code.
2630 * @param pDevIns The device instance.
2631 * @param iRegion The region number used during registration.
2632 * @param GCPhys The physical address to map it at.
2633 * @thread EMT.
2634 */
2635 DECLR3CALLBACKMEMBER(int, pfnMMIO2Map,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys));
2636
2637 /**
2638 * Unmaps a MMIO2 region previously mapped using pfnMMIO2Map.
2639 *
2640 * @returns VBox status code.
2641 * @param pDevIns The device instance.
2642 * @param iRegion The region number used during registration.
2643 * @param GCPhys The physical address it's currently mapped at.
2644 * @thread EMT.
2645 */
2646 DECLR3CALLBACKMEMBER(int, pfnMMIO2Unmap,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys));
2647
2648 /**
2649 * Maps a portion of an MMIO2 region into the hypervisor region.
2650 *
2651 * Callers of this API must never deregister the MMIO2 region before the
2652 * VM is powered off.
2653 *
2654 * @return VBox status code.
2655 * @param pDevIns The device owning the MMIO2 memory.
2656 * @param iRegion The region.
2657 * @param off The offset into the region. Will be rounded down to closest page boundrary.
2658 * @param cb The number of bytes to map. Will be rounded up to the closest page boundrary.
2659 * @param pszDesc Mapping description.
2660 * @param pGCPtr Where to store the GC address.
2661 */
2662 DECLR3CALLBACKMEMBER(int, pfnMMHyperMapMMIO2,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
2663 const char *pszDesc, PRTGCPTR pGCPtr));
2664
2665 /** @} */
2666
2667 /** Just a safety precaution. (PDM_DEVHLP_VERSION) */
2668 uint32_t u32TheEnd;
2669} PDMDEVHLP;
2670#endif /* !IN_RING3 */
2671/** Pointer PDM Device API. */
2672typedef R3PTRTYPE(struct PDMDEVHLP *) PPDMDEVHLP;
2673/** Pointer PDM Device API. */
2674typedef R3PTRTYPE(const struct PDMDEVHLP *) PCPDMDEVHLP;
2675
2676/** Current PDMDEVHLP version number. */
2677#define PDM_DEVHLP_VERSION 0xf2050002
2678
2679
2680/**
2681 * PDM Device API - GC Variant.
2682 */
2683typedef struct PDMDEVHLPGC
2684{
2685 /** Structure version. PDM_DEVHLPGC_VERSION defines the current version. */
2686 uint32_t u32Version;
2687
2688 /**
2689 * Set the IRQ for a PCI device.
2690 *
2691 * @param pDevIns Device instance.
2692 * @param iIrq IRQ number to set.
2693 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2694 * @thread Any thread, but will involve the emulation thread.
2695 */
2696 DECLGCCALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2697
2698 /**
2699 * Set ISA IRQ for a device.
2700 *
2701 * @param pDevIns Device instance.
2702 * @param iIrq IRQ number to set.
2703 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2704 * @thread Any thread, but will involve the emulation thread.
2705 */
2706 DECLGCCALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2707
2708 /**
2709 * Read physical memory.
2710 *
2711 * @param pDevIns Device instance.
2712 * @param GCPhys Physical address start reading from.
2713 * @param pvBuf Where to put the read bits.
2714 * @param cbRead How many bytes to read.
2715 */
2716 DECLGCCALLBACKMEMBER(void, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
2717
2718 /**
2719 * Write to physical memory.
2720 *
2721 * @param pDevIns Device instance.
2722 * @param GCPhys Physical address to write to.
2723 * @param pvBuf What to write.
2724 * @param cbWrite How many bytes to write.
2725 */
2726 DECLGCCALLBACKMEMBER(void, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
2727
2728 /**
2729 * Checks if the Gate A20 is enabled or not.
2730 *
2731 * @returns true if A20 is enabled.
2732 * @returns false if A20 is disabled.
2733 * @param pDevIns Device instance.
2734 * @thread The emulation thread.
2735 */
2736 DECLGCCALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
2737
2738 /**
2739 * Set the VM error message
2740 *
2741 * @returns rc.
2742 * @param pDrvIns Driver 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 ... Error message arguments.
2747 */
2748 DECLGCCALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
2749
2750 /**
2751 * Set the VM error message
2752 *
2753 * @returns rc.
2754 * @param pDrvIns Driver instance.
2755 * @param rc VBox status code.
2756 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2757 * @param pszFormat Error message format string.
2758 * @param va Error message arguments.
2759 */
2760 DECLGCCALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
2761
2762 /**
2763 * Set the VM runtime error message
2764 *
2765 * @returns VBox status code.
2766 * @param pDevIns Device instance.
2767 * @param fFatal Whether it is a fatal error or not.
2768 * @param pszErrorID Error ID string.
2769 * @param pszFormat Error message format string.
2770 * @param ... Error message arguments.
2771 */
2772 DECLGCCALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...));
2773
2774 /**
2775 * Set the VM runtime error message
2776 *
2777 * @returns VBox status code.
2778 * @param pDevIns Device instance.
2779 * @param fFatal Whether it is a fatal error or not.
2780 * @param pszErrorID Error ID string.
2781 * @param pszFormat Error message format string.
2782 * @param va Error message arguments.
2783 */
2784 DECLGCCALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va));
2785
2786 /**
2787 * Set parameters for pending MMIO patch operation
2788 *
2789 * @returns VBox status code.
2790 * @param pDevIns Device instance.
2791 * @param GCPhys MMIO physical address
2792 * @param pCachedData GC pointer to cached data
2793 */
2794 DECLGCCALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
2795
2796 /** Just a safety precaution. */
2797 uint32_t u32TheEnd;
2798} PDMDEVHLPGC;
2799/** Pointer PDM Device GC API. */
2800typedef RCPTRTYPE(struct PDMDEVHLPGC *) PPDMDEVHLPGC;
2801/** Pointer PDM Device GC API. */
2802typedef RCPTRTYPE(const struct PDMDEVHLPGC *) PCPDMDEVHLPGC;
2803
2804/** Current PDMDEVHLP version number. */
2805#define PDM_DEVHLPGC_VERSION 0xfb010000
2806
2807
2808/**
2809 * PDM Device API - R0 Variant.
2810 */
2811typedef struct PDMDEVHLPR0
2812{
2813 /** Structure version. PDM_DEVHLPR0_VERSION defines the current version. */
2814 uint32_t u32Version;
2815
2816 /**
2817 * Set the IRQ for a PCI device.
2818 *
2819 * @param pDevIns Device instance.
2820 * @param iIrq IRQ number to set.
2821 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2822 * @thread Any thread, but will involve the emulation thread.
2823 */
2824 DECLR0CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2825
2826 /**
2827 * Set ISA IRQ for a device.
2828 *
2829 * @param pDevIns Device instance.
2830 * @param iIrq IRQ number to set.
2831 * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
2832 * @thread Any thread, but will involve the emulation thread.
2833 */
2834 DECLR0CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
2835
2836 /**
2837 * Read physical memory.
2838 *
2839 * @param pDevIns Device instance.
2840 * @param GCPhys Physical address start reading from.
2841 * @param pvBuf Where to put the read bits.
2842 * @param cbRead How many bytes to read.
2843 */
2844 DECLR0CALLBACKMEMBER(void, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
2845
2846 /**
2847 * Write to physical memory.
2848 *
2849 * @param pDevIns Device instance.
2850 * @param GCPhys Physical address to write to.
2851 * @param pvBuf What to write.
2852 * @param cbWrite How many bytes to write.
2853 */
2854 DECLR0CALLBACKMEMBER(void, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
2855
2856 /**
2857 * Checks if the Gate A20 is enabled or not.
2858 *
2859 * @returns true if A20 is enabled.
2860 * @returns false if A20 is disabled.
2861 * @param pDevIns Device instance.
2862 * @thread The emulation thread.
2863 */
2864 DECLR0CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
2865
2866 /**
2867 * Set the VM error message
2868 *
2869 * @returns rc.
2870 * @param pDrvIns Driver instance.
2871 * @param rc VBox status code.
2872 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2873 * @param pszFormat Error message format string.
2874 * @param ... Error message arguments.
2875 */
2876 DECLR0CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
2877
2878 /**
2879 * Set the VM error message
2880 *
2881 * @returns rc.
2882 * @param pDrvIns Driver instance.
2883 * @param rc VBox status code.
2884 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
2885 * @param pszFormat Error message format string.
2886 * @param va Error message arguments.
2887 */
2888 DECLR0CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
2889
2890 /**
2891 * Set the VM runtime error message
2892 *
2893 * @returns VBox status code.
2894 * @param pDevIns Device instance.
2895 * @param fFatal Whether it is a fatal error or not.
2896 * @param pszErrorID Error ID string.
2897 * @param pszFormat Error message format string.
2898 * @param ... Error message arguments.
2899 */
2900 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...));
2901
2902 /**
2903 * Set the VM runtime error message
2904 *
2905 * @returns VBox status code.
2906 * @param pDevIns Device instance.
2907 * @param fFatal Whether it is a fatal error or not.
2908 * @param pszErrorID Error ID string.
2909 * @param pszFormat Error message format string.
2910 * @param va Error message arguments.
2911 */
2912 DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va));
2913
2914 /**
2915 * Set parameters for pending MMIO patch operation
2916 *
2917 * @returns rc.
2918 * @param pDevIns Device instance.
2919 * @param GCPhys MMIO physical address
2920 * @param pCachedData GC pointer to cached data
2921 */
2922 DECLR0CALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
2923
2924 /** Just a safety precaution. */
2925 uint32_t u32TheEnd;
2926} PDMDEVHLPR0;
2927/** Pointer PDM Device R0 API. */
2928typedef R0PTRTYPE(struct PDMDEVHLPR0 *) PPDMDEVHLPR0;
2929/** Pointer PDM Device GC API. */
2930typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0;
2931
2932/** Current PDMDEVHLP version number. */
2933#define PDM_DEVHLPR0_VERSION 0xfb010000
2934
2935
2936
2937/**
2938 * PDM Device Instance.
2939 */
2940typedef struct PDMDEVINS
2941{
2942 /** Structure version. PDM_DEVINS_VERSION defines the current version. */
2943 uint32_t u32Version;
2944 /** Device instance number. */
2945 RTUINT iInstance;
2946 /** The base interface of the device.
2947 * The device constructor initializes this if it has any
2948 * device level interfaces to export. To obtain this interface
2949 * call PDMR3QueryDevice(). */
2950 PDMIBASE IBase;
2951
2952 /** Internal data. */
2953 union
2954 {
2955#ifdef PDMDEVINSINT_DECLARED
2956 PDMDEVINSINT s;
2957#endif
2958 uint8_t padding[HC_ARCH_BITS == 32 ? 48 : 96];
2959 } Internal;
2960
2961 /** Pointer the HC PDM Device API. */
2962 R3PTRTYPE(PCPDMDEVHLP) pDevHlp;
2963 /** Pointer the R0 PDM Device API. */
2964 R0PTRTYPE(PCPDMDEVHLPR0) pDevHlpR0;
2965 /** Pointer to device registration structure. */
2966 R3PTRTYPE(PCPDMDEVREG) pDevReg;
2967 /** Configuration handle. */
2968 R3PTRTYPE(PCFGMNODE) pCfgHandle;
2969 /** Pointer to device instance data. */
2970 R3PTRTYPE(void *) pvInstanceDataR3;
2971 /** Pointer to device instance data. */
2972 R0PTRTYPE(void *) pvInstanceDataR0;
2973 /** Pointer the GC PDM Device API. */
2974 RCPTRTYPE(PCPDMDEVHLPGC) pDevHlpGC;
2975 /** Pointer to device instance data. */
2976 RCPTRTYPE(void *) pvInstanceDataGC;
2977 /* padding to make achInstanceData aligned at 32 byte boundrary. */
2978 uint32_t au32Padding[HC_ARCH_BITS == 32 ? 1 : 6];
2979 /** Device instance data. The size of this area is defined
2980 * in the PDMDEVREG::cbInstanceData field. */
2981 char achInstanceData[8];
2982} PDMDEVINS;
2983
2984/** Current DEVREG version number. */
2985#define PDM_DEVINS_VERSION 0xf3010000
2986
2987/** Converts a pointer to the PDMDEVINS::IBase to a pointer to PDMDEVINS. */
2988#define PDMIBASE_2_PDMDEV(pInterface) ( (PPDMDEVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDEVINS, IBase)) )
2989
2990
2991/** @def PDMDEV_ASSERT_EMT
2992 * Assert that the current thread is the emulation thread.
2993 */
2994#ifdef VBOX_STRICT
2995# define PDMDEV_ASSERT_EMT(pDevIns) pDevIns->pDevHlp->pfnAssertEMT(pDevIns, __FILE__, __LINE__, __FUNCTION__)
2996#else
2997# define PDMDEV_ASSERT_EMT(pDevIns) do { } while (0)
2998#endif
2999
3000/** @def PDMDEV_ASSERT_OTHER
3001 * Assert that the current thread is NOT the emulation thread.
3002 */
3003#ifdef VBOX_STRICT
3004# define PDMDEV_ASSERT_OTHER(pDevIns) pDevIns->pDevHlp->pfnAssertOther(pDevIns, __FILE__, __LINE__, __FUNCTION__)
3005#else
3006# define PDMDEV_ASSERT_OTHER(pDevIns) do { } while (0)
3007#endif
3008
3009/** @def PDMDEV_ASSERT_VMLOCK_OWNER
3010 * Assert that the current thread is owner of the VM lock.
3011 */
3012#ifdef VBOX_STRICT
3013# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) pDevIns->pDevHlp->pfnAssertVMLock(pDevIns, __FILE__, __LINE__, __FUNCTION__)
3014#else
3015# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) do { } while (0)
3016#endif
3017
3018/** @def PDMDEV_SET_ERROR
3019 * Set the VM error. See PDMDevHlpVMSetError() for printf like message formatting.
3020 */
3021#define PDMDEV_SET_ERROR(pDevIns, rc, pszError) \
3022 PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, "%s", pszError)
3023
3024/** @def PDMDEV_SET_RUNTIME_ERROR
3025 * Set the VM runtime error. See PDMDevHlpVMSetRuntimeError() for printf like message formatting.
3026 */
3027#define PDMDEV_SET_RUNTIME_ERROR(pDevIns, fFatal, pszErrorID, pszError) \
3028 PDMDevHlpVMSetRuntimeError(pDevIns, fFatal, pszErrorID, "%s", pszError)
3029
3030/** @def PDMDEVINS_2_GCPTR
3031 * Converts a PDM Device instance pointer a GC PDM Device instance pointer.
3032 */
3033#define PDMDEVINS_2_GCPTR(pDevIns) ( (RCPTRTYPE(PPDMDEVINS))((RTGCUINTPTR)(pDevIns)->pvInstanceDataGC - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
3034
3035/** @def PDMDEVINS_2_R3PTR
3036 * Converts a PDM Device instance pointer a HC PDM Device instance pointer.
3037 */
3038#define PDMDEVINS_2_R3PTR(pDevIns) ( (R3PTRTYPE(PPDMDEVINS))((RTHCUINTPTR)(pDevIns)->pvInstanceDataR3 - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
3039
3040/** @def PDMDEVINS_2_R0PTR
3041 * Converts a PDM Device instance pointer a R0 PDM Device instance pointer.
3042 */
3043#define PDMDEVINS_2_R0PTR(pDevIns) ( (R0PTRTYPE(PPDMDEVINS))((RTR0UINTPTR)(pDevIns)->pvInstanceDataR0 - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
3044
3045
3046/**
3047 * VBOX_STRICT wrapper for pDevHlp->pfnDBGFStopV.
3048 *
3049 * @returns VBox status code which must be passed up to the VMM.
3050 * @param pDevIns Device instance.
3051 * @param RT_SRC_POS_DECL Use RT_SRC_POS.
3052 * @param pszFormat Message. (optional)
3053 * @param ... Message parameters.
3054 */
3055DECLINLINE(int) PDMDeviceDBGFStop(PPDMDEVINS pDevIns, RT_SRC_POS_DECL, const char *pszFormat, ...)
3056{
3057#ifdef VBOX_STRICT
3058# ifdef IN_RING3
3059 int rc;
3060 va_list args;
3061 va_start(args, pszFormat);
3062 rc = pDevIns->pDevHlp->pfnDBGFStopV(pDevIns, RT_SRC_POS_ARGS, pszFormat, args);
3063 va_end(args);
3064 return rc;
3065# else
3066 return VINF_EM_DBG_STOP;
3067# endif
3068#else
3069 return VINF_SUCCESS;
3070#endif
3071}
3072
3073
3074#ifdef IN_RING3
3075/**
3076 * @copydoc PDMDEVHLP::pfnIOPortRegister
3077 */
3078DECLINLINE(int) PDMDevHlpIOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTHCPTR pvUser,
3079 PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
3080 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc)
3081{
3082 return pDevIns->pDevHlp->pfnIOPortRegister(pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc);
3083}
3084
3085/**
3086 * @copydoc PDMDEVHLP::pfnIOPortRegisterGC
3087 */
3088DECLINLINE(int) PDMDevHlpIOPortRegisterGC(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTRCPTR pvUser,
3089 const char *pszOut, const char *pszIn, const char *pszOutStr,
3090 const char *pszInStr, const char *pszDesc)
3091{
3092 return pDevIns->pDevHlp->pfnIOPortRegisterGC(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
3093}
3094
3095/**
3096 * @copydoc PDMDEVHLP::pfnIOPortRegisterR0
3097 */
3098DECLINLINE(int) PDMDevHlpIOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTUINT cPorts, RTR0PTR pvUser,
3099 const char *pszOut, const char *pszIn, const char *pszOutStr,
3100 const char *pszInStr, const char *pszDesc)
3101{
3102 return pDevIns->pDevHlp->pfnIOPortRegisterR0(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
3103}
3104
3105/**
3106 * @copydoc PDMDEVHLP::pfnMMIORegister
3107 */
3108DECLINLINE(int) PDMDevHlpMMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTHCPTR pvUser,
3109 PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
3110 const char *pszDesc)
3111{
3112 return pDevIns->pDevHlp->pfnMMIORegister(pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill, pszDesc);
3113}
3114
3115/**
3116 * @copydoc PDMDEVHLP::pfnMMIORegisterGC
3117 */
3118DECLINLINE(int) PDMDevHlpMMIORegisterGC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTGCPTR pvUser,
3119 const char *pszWrite, const char *pszRead, const char *pszFill)
3120{
3121 return pDevIns->pDevHlp->pfnMMIORegisterGC(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill, NULL);
3122}
3123
3124/**
3125 * @copydoc PDMDEVHLP::pfnMMIORegisterR0
3126 */
3127DECLINLINE(int) PDMDevHlpMMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, RTR0PTR pvUser,
3128 const char *pszWrite, const char *pszRead, const char *pszFill)
3129{
3130 return pDevIns->pDevHlp->pfnMMIORegisterR0(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill, NULL);
3131}
3132
3133/**
3134 * @copydoc PDMDEVHLP::pfnROMRegister
3135 */
3136DECLINLINE(int) PDMDevHlpROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange, const void *pvBinary, bool fShadow, const char *pszDesc)
3137{
3138 return pDevIns->pDevHlp->pfnROMRegister(pDevIns, GCPhysStart, cbRange, pvBinary, fShadow, pszDesc);
3139}
3140/**
3141 * @copydoc PDMDEVHLP::pfnROMProtectShadow
3142 */
3143DECLINLINE(int) PDMDevHlpROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTUINT cbRange)
3144{
3145 return pDevIns->pDevHlp->pfnROMProtectShadow(pDevIns, GCPhysStart, cbRange);
3146}
3147
3148/**
3149 * @copydoc PDMDEVHLP::pfnMMIO2Register
3150 */
3151DECLINLINE(int) PDMDevHlpMMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
3152{
3153 return pDevIns->pDevHlp->pfnMMIO2Register(pDevIns, iRegion, cb, fFlags, ppv, pszDesc);
3154}
3155
3156/**
3157 * @copydoc PDMDEVHLP::pfnMMIO2Deregister
3158 */
3159DECLINLINE(int) PDMDevHlpMMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)
3160{
3161 return pDevIns->pDevHlp->pfnMMIO2Deregister(pDevIns, iRegion);
3162}
3163
3164/**
3165 * @copydoc PDMDEVHLP::pfnMMIO2Map
3166 */
3167DECLINLINE(int) PDMDevHlpMMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
3168{
3169 return pDevIns->pDevHlp->pfnMMIO2Map(pDevIns, iRegion, GCPhys);
3170}
3171
3172/**
3173 * @copydoc PDMDEVHLP::pfnMMIO2Unmap
3174 */
3175DECLINLINE(int) PDMDevHlpMMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
3176{
3177 return pDevIns->pDevHlp->pfnMMIO2Unmap(pDevIns, iRegion, GCPhys);
3178}
3179
3180/**
3181 * @copydoc PDMDEVHLP::pfnMMHyperMapMMIO2
3182 */
3183DECLINLINE(int) PDMDevHlpMMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
3184 const char *pszDesc, PRTGCPTR pGCPtr)
3185{
3186 return pDevIns->pDevHlp->pfnMMHyperMapMMIO2(pDevIns, iRegion, off, cb, pszDesc, pGCPtr);
3187}
3188
3189/**
3190 * @copydoc PDMDEVHLP::pfnSSMRegister
3191 */
3192DECLINLINE(int) PDMDevHlpSSMRegister(PPDMDEVINS pDevIns, const char *pszName, uint32_t u32Instance, uint32_t u32Version, size_t cbGuess,
3193 PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
3194 PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
3195{
3196 return pDevIns->pDevHlp->pfnSSMRegister(pDevIns, pszName, u32Instance, u32Version, cbGuess,
3197 pfnSavePrep, pfnSaveExec, pfnSaveDone,
3198 pfnLoadPrep, pfnLoadExec, pfnLoadDone);
3199}
3200
3201/**
3202 * @copydoc PDMDEVHLP::pfnTMTimerCreate
3203 */
3204DECLINLINE(int) PDMDevHlpTMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer)
3205{
3206 return pDevIns->pDevHlp->pfnTMTimerCreate(pDevIns, enmClock, pfnCallback, pszDesc, ppTimer);
3207}
3208
3209/**
3210 * @copydoc PDMDEVHLP::pfnPCIRegister
3211 */
3212DECLINLINE(int) PDMDevHlpPCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev)
3213{
3214 return pDevIns->pDevHlp->pfnPCIRegister(pDevIns, pPciDev);
3215}
3216
3217/**
3218 * @copydoc PDMDEVHLP::pfnPCIIORegionRegister
3219 */
3220DECLINLINE(int) PDMDevHlpPCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
3221{
3222 return pDevIns->pDevHlp->pfnPCIIORegionRegister(pDevIns, iRegion, cbRegion, enmType, pfnCallback);
3223}
3224
3225/**
3226 * @copydoc PDMDEVHLP::pfnPCISetConfigCallbacks
3227 */
3228DECLINLINE(void) PDMDevHlpPCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
3229 PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)
3230{
3231 pDevIns->pDevHlp->pfnPCISetConfigCallbacks(pDevIns, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld);
3232}
3233
3234/**
3235 * @copydoc PDMDEVHLP::pfnDriverAttach
3236 */
3237DECLINLINE(int) PDMDevHlpDriverAttach(PPDMDEVINS pDevIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
3238{
3239 return pDevIns->pDevHlp->pfnDriverAttach(pDevIns, iLun, pBaseInterface, ppBaseInterface, pszDesc);
3240}
3241
3242/**
3243 * @copydoc PDMDEVHLP::pfnMMHeapAlloc
3244 */
3245DECLINLINE(void *) PDMDevHlpMMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
3246{
3247 return pDevIns->pDevHlp->pfnMMHeapAlloc(pDevIns, cb);
3248}
3249
3250/**
3251 * @copydoc PDMDEVHLP::pfnMMHeapAllocZ
3252 */
3253DECLINLINE(void *) PDMDevHlpMMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
3254{
3255 return pDevIns->pDevHlp->pfnMMHeapAllocZ(pDevIns, cb);
3256}
3257
3258/**
3259 * @copydoc PDMDEVHLP::pfnMMHeapFree
3260 */
3261DECLINLINE(void) PDMDevHlpMMHeapFree(PPDMDEVINS pDevIns, void *pv)
3262{
3263 pDevIns->pDevHlp->pfnMMHeapFree(pDevIns, pv);
3264}
3265
3266/**
3267 * @copydoc PDMDEVHLP::pfnDBGFInfoRegister
3268 */
3269DECLINLINE(int) PDMDevHlpDBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
3270{
3271 return pDevIns->pDevHlp->pfnDBGFInfoRegister(pDevIns, pszName, pszDesc, pfnHandler);
3272}
3273
3274/**
3275 * @copydoc PDMDEVHLP::pfnSTAMRegister
3276 */
3277DECLINLINE(void) PDMDevHlpSTAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
3278{
3279 pDevIns->pDevHlp->pfnSTAMRegister(pDevIns, pvSample, enmType, pszName, enmUnit, pszDesc);
3280}
3281
3282/**
3283 * @copydoc PDMDEVHLP::pfnSTAMRegisterF
3284 */
3285DECLINLINE(void) PDMDevHlpSTAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
3286 const char *pszDesc, const char *pszName, ...)
3287{
3288 va_list va;
3289 va_start(va, pszName);
3290 pDevIns->pDevHlp->pfnSTAMRegisterV(pDevIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, va);
3291 va_end(va);
3292}
3293
3294/**
3295 * @copydoc PDMDEVHLP::pfnPDMQueueCreate
3296 */
3297DECLINLINE(int) PDMDevHlpPDMQueueCreate(PPDMDEVINS pDevIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
3298 PFNPDMQUEUEDEV pfnCallback, bool fGCEnabled, PPDMQUEUE *ppQueue)
3299{
3300 return pDevIns->pDevHlp->pfnPDMQueueCreate(pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fGCEnabled, ppQueue);
3301}
3302
3303/**
3304 * @copydoc PDMDEVHLP::pfnCritSectInit
3305 */
3306DECLINLINE(int) PDMDevHlpCritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName)
3307{
3308 return pDevIns->pDevHlp->pfnCritSectInit(pDevIns, pCritSect, pszName);
3309}
3310
3311/**
3312 * @copydoc PDMDEVHLP::pfnUTCNow
3313 */
3314DECLINLINE(PRTTIMESPEC) PDMDevHlpUTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
3315{
3316 return pDevIns->pDevHlp->pfnUTCNow(pDevIns, pTime);
3317}
3318
3319/**
3320 * @copydoc PDMDEVHLP::pfnGetVM
3321 */
3322DECLINLINE(PVM) PDMDevHlpGetVM(PPDMDEVINS pDevIns)
3323{
3324 return pDevIns->pDevHlp->pfnGetVM(pDevIns);
3325}
3326
3327/**
3328 * @copydoc PDMDEVHLP::pfnPhysReadGCVirt
3329 */
3330DECLINLINE(int) PDMDevHlpPhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
3331{
3332 return pDevIns->pDevHlp->pfnPhysReadGCVirt(pDevIns, pvDst, GCVirtSrc, cb);
3333}
3334
3335/**
3336 * @copydoc PDMDEVHLP::pfnPhysWriteGCVirt
3337 */
3338DECLINLINE(int) PDMDevHlpPhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
3339{
3340 return pDevIns->pDevHlp->pfnPhysWriteGCVirt(pDevIns, GCVirtDst, pvSrc, cb);
3341}
3342
3343/**
3344 * @copydoc PDMDEVHLP::pfnPhysReserve
3345 */
3346DECLINLINE(int) PDMDevHlpPhysReserve(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTUINT cbRange, const char *pszDesc)
3347{
3348 return pDevIns->pDevHlp->pfnPhysReserve(pDevIns, GCPhys, cbRange, pszDesc);
3349}
3350
3351/**
3352 * @copydoc PDMDEVHLP::pfnPhysGCPtr2GCPhys
3353 */
3354DECLINLINE(int) PDMDevHlpPhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
3355{
3356 return pDevIns->pDevHlp->pfnPhysGCPtr2GCPhys(pDevIns, GCPtr, pGCPhys);
3357}
3358
3359/**
3360 * @copydoc PDMDEVHLP::pfnVMState
3361 */
3362DECLINLINE(VMSTATE) PDMDevHlpVMState(PPDMDEVINS pDevIns)
3363{
3364 return pDevIns->pDevHlp->pfnVMState(pDevIns);
3365}
3366
3367/**
3368 * @copydoc PDMDEVHLP::pfnA20Set
3369 */
3370DECLINLINE(void) PDMDevHlpA20Set(PPDMDEVINS pDevIns, bool fEnable)
3371{
3372 pDevIns->pDevHlp->pfnA20Set(pDevIns, fEnable);
3373}
3374
3375/**
3376 * @copydoc PDMDEVHLP::pfnVMReset
3377 */
3378DECLINLINE(int) PDMDevHlpVMReset(PPDMDEVINS pDevIns)
3379{
3380 return pDevIns->pDevHlp->pfnVMReset(pDevIns);
3381}
3382
3383/**
3384 * @copydoc PDMDEVHLP::pfnVMSuspend
3385 */
3386DECLINLINE(int) PDMDevHlpVMSuspend(PPDMDEVINS pDevIns)
3387{
3388 return pDevIns->pDevHlp->pfnVMSuspend(pDevIns);
3389}
3390
3391/**
3392 * @copydoc PDMDEVHLP::pfnVMPowerOff
3393 */
3394DECLINLINE(int) PDMDevHlpVMPowerOff(PPDMDEVINS pDevIns)
3395{
3396 return pDevIns->pDevHlp->pfnVMPowerOff(pDevIns);
3397}
3398
3399/**
3400 * @copydoc PDMDEVHLP::pfnDMARegister
3401 */
3402DECLINLINE(int) PDMDevHlpDMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
3403{
3404 return pDevIns->pDevHlp->pfnDMARegister(pDevIns, uChannel, pfnTransferHandler, pvUser);
3405}
3406
3407/**
3408 * @copydoc PDMDEVHLP::pfnDMAReadMemory
3409 */
3410DECLINLINE(int) PDMDevHlpDMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
3411{
3412 return pDevIns->pDevHlp->pfnDMAReadMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbRead);
3413}
3414
3415/**
3416 * @copydoc PDMDEVHLP::pfnDMAWriteMemory
3417 */
3418DECLINLINE(int) PDMDevHlpDMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
3419{
3420 return pDevIns->pDevHlp->pfnDMAWriteMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbWritten);
3421}
3422
3423/**
3424 * @copydoc PDMDEVHLP::pfnDMASetDREQ
3425 */
3426DECLINLINE(int) PDMDevHlpDMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
3427{
3428 return pDevIns->pDevHlp->pfnDMASetDREQ(pDevIns, uChannel, uLevel);
3429}
3430
3431/**
3432 * @copydoc PDMDEVHLP::pfnDMAGetChannelMode
3433 */
3434DECLINLINE(uint8_t) PDMDevHlpDMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
3435{
3436 return pDevIns->pDevHlp->pfnDMAGetChannelMode(pDevIns, uChannel);
3437}
3438
3439/**
3440 * @copydoc PDMDEVHLP::pfnDMASchedule
3441 */
3442DECLINLINE(void) PDMDevHlpDMASchedule(PPDMDEVINS pDevIns)
3443{
3444 pDevIns->pDevHlp->pfnDMASchedule(pDevIns);
3445}
3446
3447/**
3448 * @copydoc PDMDEVHLP::pfnCMOSWrite
3449 */
3450DECLINLINE(int) PDMDevHlpCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
3451{
3452 return pDevIns->pDevHlp->pfnCMOSWrite(pDevIns, iReg, u8Value);
3453}
3454
3455/**
3456 * @copydoc PDMDEVHLP::pfnCMOSRead
3457 */
3458DECLINLINE(int) PDMDevHlpCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
3459{
3460 return pDevIns->pDevHlp->pfnCMOSRead(pDevIns, iReg, pu8Value);
3461}
3462
3463/**
3464 * @copydoc PDMDEVHLP::pfnGetCpuId
3465 */
3466DECLINLINE(void) PDMDevHlpGetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
3467{
3468 pDevIns->pDevHlp->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx);
3469}
3470
3471/**
3472 * @copydoc PDMDEVHLP::pfnPDMThreadCreate
3473 */
3474DECLINLINE(int) PDMDevHlpPDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
3475 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
3476{
3477 return pDevIns->pDevHlp->pfnPDMThreadCreate(pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
3478}
3479#endif /* IN_RING3 */
3480
3481
3482/**
3483 * @copydoc PDMDEVHLP::pfnPCISetIrq
3484 */
3485DECLINLINE(void) PDMDevHlpPCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
3486{
3487#ifdef IN_GC
3488 pDevIns->pDevHlpGC->pfnPCISetIrq(pDevIns, iIrq, iLevel);
3489#elif defined(IN_RING0)
3490 pDevIns->pDevHlpR0->pfnPCISetIrq(pDevIns, iIrq, iLevel);
3491#else
3492 pDevIns->pDevHlp->pfnPCISetIrq(pDevIns, iIrq, iLevel);
3493#endif
3494}
3495
3496/**
3497 * @copydoc PDMDEVHLP::pfnPCISetIrqNoWait
3498 */
3499DECLINLINE(void) PDMDevHlpPCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
3500{
3501#ifdef IN_GC
3502 pDevIns->pDevHlpGC->pfnPCISetIrq(pDevIns, iIrq, iLevel);
3503#elif defined(IN_RING0)
3504 pDevIns->pDevHlpR0->pfnPCISetIrq(pDevIns, iIrq, iLevel);
3505#else
3506 pDevIns->pDevHlp->pfnPCISetIrqNoWait(pDevIns, iIrq, iLevel);
3507#endif
3508}
3509
3510/**
3511 * @copydoc PDMDEVHLP::pfnISASetIrq
3512 */
3513DECLINLINE(void) PDMDevHlpISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
3514{
3515#ifdef IN_GC
3516 pDevIns->pDevHlpGC->pfnISASetIrq(pDevIns, iIrq, iLevel);
3517#elif defined(IN_RING0)
3518 pDevIns->pDevHlpR0->pfnISASetIrq(pDevIns, iIrq, iLevel);
3519#else
3520 pDevIns->pDevHlp->pfnISASetIrq(pDevIns, iIrq, iLevel);
3521#endif
3522}
3523
3524/**
3525 * @copydoc PDMDEVHLP::pfnISASetIrqNoWait
3526 */
3527DECLINLINE(void) PDMDevHlpISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
3528{
3529#ifdef IN_GC
3530 pDevIns->pDevHlpGC->pfnISASetIrq(pDevIns, iIrq, iLevel);
3531#elif defined(IN_RING0)
3532 pDevIns->pDevHlpR0->pfnISASetIrq(pDevIns, iIrq, iLevel);
3533#else
3534 pDevIns->pDevHlp->pfnISASetIrqNoWait(pDevIns, iIrq, iLevel);
3535#endif
3536}
3537
3538/**
3539 * @copydoc PDMDEVHLP::pfnPhysRead
3540 */
3541DECLINLINE(void) PDMDevHlpPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
3542{
3543#ifdef IN_GC
3544 pDevIns->pDevHlpGC->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
3545#elif defined(IN_RING0)
3546 pDevIns->pDevHlpR0->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
3547#else
3548 pDevIns->pDevHlp->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
3549#endif
3550}
3551
3552/**
3553 * @copydoc PDMDEVHLP::pfnPhysWrite
3554 */
3555DECLINLINE(void) PDMDevHlpPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
3556{
3557#ifdef IN_GC
3558 pDevIns->pDevHlpGC->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
3559#elif defined(IN_RING0)
3560 pDevIns->pDevHlpR0->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
3561#else
3562 pDevIns->pDevHlp->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
3563#endif
3564}
3565
3566/**
3567 * @copydoc PDMDEVHLP::pfnA20IsEnabled
3568 */
3569DECLINLINE(bool) PDMDevHlpA20IsEnabled(PPDMDEVINS pDevIns)
3570{
3571#ifdef IN_GC
3572 return pDevIns->pDevHlpGC->pfnA20IsEnabled(pDevIns);
3573#elif defined(IN_RING0)
3574 return pDevIns->pDevHlpR0->pfnA20IsEnabled(pDevIns);
3575#else
3576 return pDevIns->pDevHlp->pfnA20IsEnabled(pDevIns);
3577#endif
3578}
3579
3580/**
3581 * @copydoc PDMDEVHLP::pfnVMSetError
3582 */
3583DECLINLINE(int) PDMDevHlpVMSetError(PPDMDEVINS pDevIns, const int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
3584{
3585 va_list va;
3586 va_start(va, pszFormat);
3587#ifdef IN_GC
3588 pDevIns->pDevHlpGC->pfnVMSetErrorV(pDevIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
3589#elif defined(IN_RING0)
3590 pDevIns->pDevHlpR0->pfnVMSetErrorV(pDevIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
3591#else
3592 pDevIns->pDevHlp->pfnVMSetErrorV(pDevIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
3593#endif
3594 va_end(va);
3595 return rc;
3596}
3597
3598/**
3599 * @copydoc PDMDEVHLP::pfnVMSetRuntimeError
3600 */
3601DECLINLINE(int) PDMDevHlpVMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...)
3602{
3603 va_list va;
3604 int rc;
3605 va_start(va, pszFormat);
3606#ifdef IN_GC
3607 rc = pDevIns->pDevHlpGC->pfnVMSetRuntimeErrorV(pDevIns, fFatal, pszErrorID, pszFormat, va);
3608#elif defined(IN_RING0)
3609 rc = pDevIns->pDevHlpR0->pfnVMSetRuntimeErrorV(pDevIns, fFatal, pszErrorID, pszFormat, va);
3610#else
3611 rc = pDevIns->pDevHlp->pfnVMSetRuntimeErrorV(pDevIns, fFatal, pszErrorID, pszFormat, va);
3612#endif
3613 va_end(va);
3614 return rc;
3615}
3616
3617
3618
3619/** Pointer to callbacks provided to the VBoxDeviceRegister() call. */
3620typedef struct PDMDEVREGCB *PPDMDEVREGCB;
3621
3622/**
3623 * Callbacks for VBoxDeviceRegister().
3624 */
3625typedef struct PDMDEVREGCB
3626{
3627 /** Interface version.
3628 * This is set to PDM_DEVREG_CB_VERSION. */
3629 uint32_t u32Version;
3630
3631 /**
3632 * Registers a device with the current VM instance.
3633 *
3634 * @returns VBox status code.
3635 * @param pCallbacks Pointer to the callback table.
3636 * @param pDevReg Pointer to the device registration record.
3637 * This data must be permanent and readonly.
3638 */
3639 DECLR3CALLBACKMEMBER(int, pfnRegister,(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pDevReg));
3640
3641 /**
3642 * Allocate memory which is associated with current VM instance
3643 * and automatically freed on it's destruction.
3644 *
3645 * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
3646 * @param pCallbacks Pointer to the callback table.
3647 * @param cb Number of bytes to allocate.
3648 */
3649 DECLR3CALLBACKMEMBER(void *, pfnMMHeapAlloc,(PPDMDEVREGCB pCallbacks, size_t cb));
3650} PDMDEVREGCB;
3651
3652/** Current version of the PDMDEVREGCB structure. */
3653#define PDM_DEVREG_CB_VERSION 0xf4010000
3654
3655
3656/**
3657 * The VBoxDevicesRegister callback function.
3658 *
3659 * PDM will invoke this function after loading a device module and letting
3660 * the module decide which devices to register and how to handle conflicts.
3661 *
3662 * @returns VBox status code.
3663 * @param pCallbacks Pointer to the callback table.
3664 * @param u32Version VBox version number.
3665 */
3666typedef DECLCALLBACK(int) FNPDMVBOXDEVICESREGISTER(PPDMDEVREGCB pCallbacks, uint32_t u32Version);
3667
3668/** @} */
3669
3670__END_DECLS
3671
3672#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