Index: /trunk/include/VBox/pdmcommon.h
===================================================================
--- /trunk/include/VBox/pdmcommon.h	(revision 26000)
+++ /trunk/include/VBox/pdmcommon.h	(revision 26001)
@@ -41,4 +41,37 @@
  * @{
  */
+
+/** Makes a PDM structure version out of an unique magic value and major &
+ * minor version numbers.
+ *
+ * @returns 32-bit structure version number.
+ *
+ * @param   uMagic      16-bit magic value.  This must be unique.
+ * @param   uMajor      12-bit major version number.  Structures with different
+ *                      major numbers are not compatible.
+ * @param   uMinor      4-bit minor version number.  When only the minor version
+ *                      differs, the structures will be 100% backwards
+ *                      compatible.
+ */
+#define PDM_VERSION_MAKE(uMagic, uMajor, uMinor) \
+    ( ((uint32_t)(uMagic) << 16) | ((uint32_t)((uMajor) & 0xff) << 4) | ((uint32_t)((uMinor) & 0xf) << 0) )
+
+/** Checks if @a uVerMagic1 is compatible with @a uVerMagic2.
+ *
+ * @returns true / false.
+ * @param   uVerMagic1  Typically the runtime version of the struct.  This must
+ *                      have the same magic and major version as @a uVerMagic2
+ *                      and the minor version must be greater or equal to that
+ *                      of @a uVerMagic2.
+ * @param   uVerMagic2  Typically the version the code was compiled against.
+ *
+ * @remarks The parameters will be referenced more than once.
+ */
+#define PDM_VERSION_ARE_COMPATIBLE(uVerMagic1, uVerMagic2) \
+    (    (uVerMagic1) == (uVerMagic2) \
+      || (   (uVerMagic1) >= (uVerMagic2) \
+          && ((uVerMagic1) & UINT32_C(0xfffffff0)) == ((uVerMagic2) & UINT32_C(0xfffffff0)) ) \
+    )
+
 
 /** PDM Attach/Detach Callback Flags.
Index: /trunk/include/VBox/pdmdev.h
===================================================================
--- /trunk/include/VBox/pdmdev.h	(revision 26000)
+++ /trunk/include/VBox/pdmdev.h	(revision 26001)
@@ -4,5 +4,5 @@
 
 /*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -305,5 +305,5 @@
 
 /** Current DEVREG version number. */
-#define PDM_DEVREG_VERSION                      0xc0020000
+#define PDM_DEVREG_VERSION                      PDM_VERSION_MAKE(0xffff, 1, 0)
 
 /** PDM Device Flags.
@@ -519,5 +519,5 @@
 
 /** Current PDMPCIBUSREG version number. */
-#define PDM_PCIBUSREG_VERSION   0xd0020000
+#define PDM_PCIBUSREG_VERSION                   PDM_VERSION_MAKE(0xfffe, 1, 0)
 
 /**
@@ -575,5 +575,5 @@
 
 /** Current PDMPCIHLPR3 version number. */
-#define PDM_PCIHLPRC_VERSION  0xe1010000
+#define PDM_PCIHLPRC_VERSION                    PDM_VERSION_MAKE(0xfffd, 1, 0)
 
 
@@ -632,5 +632,5 @@
 
 /** Current PDMPCIHLPR0 version number. */
-#define PDM_PCIHLPR0_VERSION  0xe1010000
+#define PDM_PCIHLPR0_VERSION                    PDM_VERSION_MAKE(0xfffc, 1, 0)
 
 /**
@@ -722,5 +722,5 @@
 
 /** Current PDMPCIHLPR3 version number. */
-#define PDM_PCIHLPR3_VERSION  0xf1020000
+#define PDM_PCIHLPR3_VERSION                    PDM_VERSION_MAKE(0xfffb, 1, 0)
 
 
@@ -764,5 +764,5 @@
 
 /** Current PDMPICREG version number. */
-#define PDM_PICREG_VERSION      0xe0020000
+#define PDM_PICREG_VERSION                      PDM_VERSION_MAKE(0xfffa, 1, 0)
 
 /**
@@ -815,5 +815,5 @@
 
 /** Current PDMPICHLPRC version number. */
-#define PDM_PICHLPRC_VERSION  0xfc010000
+#define PDM_PICHLPRC_VERSION                    PDM_VERSION_MAKE(0xfff9, 1, 0)
 
 
@@ -867,5 +867,5 @@
 
 /** Current PDMPICHLPR0 version number. */
-#define PDM_PICHLPR0_VERSION  0xfc010000
+#define PDM_PICHLPR0_VERSION                    PDM_VERSION_MAKE(0xfff8, 1, 0)
 
 /**
@@ -940,5 +940,5 @@
 
 /** Current PDMPICHLPR3 version number. */
-#define PDM_PICHLPR3_VERSION  0xf0010000
+#define PDM_PICHLPR3_VERSION                    PDM_VERSION_MAKE(0xfff7, 1, 0)
 
 
@@ -1102,5 +1102,5 @@
 
 /** Current PDMAPICREG version number. */
-#define PDM_APICREG_VERSION     0x70010000
+#define PDM_APICREG_VERSION                     PDM_VERSION_MAKE(0xfff6, 1, 0)
 
 
@@ -1209,5 +1209,5 @@
 
 /** Current PDMAPICHLPRC version number. */
-#define PDM_APICHLPRC_VERSION   0x60020000
+#define PDM_APICHLPRC_VERSION                   PDM_VERSION_MAKE(0xfff5, 1, 0)
 
 
@@ -1279,5 +1279,5 @@
 
 /** Current PDMAPICHLPR0 version number. */
-#define PDM_APICHLPR0_VERSION   0x60020000
+#define PDM_APICHLPR0_VERSION                   PDM_VERSION_MAKE(0xfff4, 1, 0)
 
 /**
@@ -1395,5 +1395,5 @@
 
 /** Current PDMAPICHLP version number. */
-#define PDM_APICHLPR3_VERSION  0xfd030000
+#define PDM_APICHLPR3_VERSION                   PDM_VERSION_MAKE(0xfff3, 1, 0)
 
 
@@ -1425,5 +1425,5 @@
 
 /** Current PDMAPICREG version number. */
-#define PDM_IOAPICREG_VERSION     0x50010000
+#define PDM_IOAPICREG_VERSION                   PDM_VERSION_MAKE(0xfff2, 1, 0)
 
 
@@ -1479,5 +1479,5 @@
 
 /** Current PDMIOAPICHLPRC version number. */
-#define PDM_IOAPICHLPRC_VERSION   0xfe010000
+#define PDM_IOAPICHLPRC_VERSION                 PDM_VERSION_MAKE(0xfff1, 1, 0)
 
 
@@ -1533,5 +1533,5 @@
 
 /** Current PDMIOAPICHLPR0 version number. */
-#define PDM_IOAPICHLPR0_VERSION   0xfe010000
+#define PDM_IOAPICHLPR0_VERSION                 PDM_VERSION_MAKE(0xfff0, 1, 0)
 
 /**
@@ -1608,5 +1608,5 @@
 
 /** Current PDMIOAPICHLPR3 version number. */
-#define PDM_IOAPICHLPR3_VERSION   0xff010000
+#define PDM_IOAPICHLPR3_VERSION                 PDM_VERSION_MAKE(0xffef, 1, 0)
 
 
@@ -1661,5 +1661,5 @@
 
 /** Current PDMHPETHLPRC version number. */
-#define PDM_HPETHLPRC_VERSION  0xe1010000
+#define PDM_HPETHLPRC_VERSION                   PDM_VERSION_MAKE(0xffee, 1, 0)
 
 
@@ -1699,5 +1699,5 @@
 
 /** Current PDMHPETHLPR0 version number. */
-#define PDM_HPETHLPR0_VERSION  0xe1010000
+#define PDM_HPETHLPR0_VERSION                   PDM_VERSION_MAKE(0xffed, 1, 0)
 
 /**
@@ -1708,5 +1708,4 @@
     /** Structure version. PDM_HPETHLP_VERSION defines the current version. */
     uint32_t                u32Version;
-
 
     /**
@@ -1769,5 +1768,6 @@
 
 /** Current PDMHPETHLPR3 version number. */
-#define PDM_HPETHLPR3_VERSION  0x1e010000
+#define PDM_HPETHLPR3_VERSION                   PDM_VERSION_MAKE(0xffec, 1, 0)
+
 
 
@@ -1859,5 +1859,5 @@
 
 /** Current PDMDMACREG version number. */
-#define PDM_DMACREG_VERSION     0xf5010000
+#define PDM_DMACREG_VERSION                     PDM_VERSION_MAKE(0xffeb, 1, 0)
 
 
@@ -1879,5 +1879,5 @@
 
 /** Current PDMDMACHLP version number. */
-#define PDM_DMACHLP_VERSION  0xf6010000
+#define PDM_DMACHLP_VERSION                     PDM_VERSION_MAKE(0xffea, 1, 0)
 
 #endif /* IN_RING3 */
@@ -1921,5 +1921,5 @@
 
 /** Current PDMRTCREG version number. */
-#define PDM_RTCREG_VERSION     0xfa010000
+#define PDM_RTCREG_VERSION                      PDM_VERSION_MAKE(0xffe9, 1, 0)
 
 
@@ -1941,5 +1941,5 @@
 
 /** Current PDMRTCHLP version number. */
-#define PDM_RTCHLP_VERSION  0xf6010000
+#define PDM_RTCHLP_VERSION                      PDM_VERSION_MAKE(0xffe8, 1, 0)
 
 
@@ -3118,5 +3118,5 @@
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLP_VERSION  0xf20c0001
+#define PDM_DEVHLP_VERSION                      PDM_VERSION_MAKE(0xffe7, 1, 0)
 
 
@@ -3264,5 +3264,5 @@
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPRC_VERSION  0xfb020000
+#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 1, 0)
 
 
@@ -3418,5 +3418,5 @@
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPR0_VERSION  0xfb030000
+#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 1, 0)
 
 
@@ -3475,9 +3475,45 @@
 
 /** Current PDMDEVINS version number. */
-#define PDM_DEVINS_VERSION  0xf3020000
+#define PDM_DEVINS_VERSION                      PDM_VERSION_MAKE(0xffe4, 1, 0)
 
 /** Converts a pointer to the PDMDEVINS::IBase to a pointer to PDMDEVINS. */
 #define PDMIBASE_2_PDMDEV(pInterface) ( (PPDMDEVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDEVINS, IBase)) )
 
+/**
+ * Checks the structure versions of the device instance and device helpers,
+ * returning if they are incompatible.
+ *
+ * This is for use in the constructor.
+ *
+ * @param   pDevIns     The device instance pointer.
+ */
+#define PDMDEV_CHECK_VERSIONS_RETURN(pDevIns) \
+    do \
+    { \
+        PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
+        AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION), \
+                              ("DevIns=%#x  mine=%#x\n", (pDevIns)->u32Version, PDM_DEVINS_VERSION), \
+                              VERR_VERSION_MISMATCH); \
+        AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pDevHlpR3->u32Version, PDM_DEVHLP_VERSION), \
+                              ("DevHlp=%#x  mine=%#x\n", (pDevIns)->pDevHlpR3->u32Version, PDM_DEVHLP_VERSION), \
+                              VERR_VERSION_MISMATCH); \
+    } while (0)
+
+/**
+ * Quietly checks the structure versions of the device instance and device
+ * helpers, returning if they are incompatible.
+ *
+ * This is for use in the destructor.
+ *
+ * @param   pDevIns     The device instance pointer.
+ */
+#define PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns) \
+    do \
+    { \
+        PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
+        if (RT_UNLIKELY(   !PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION) \
+                        || !PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pDevHlpR3->u32Version, PDM_DEVHLP_VERSION) )) \
+            return VERR_VERSION_MISMATCH; \
+    } while (0)
 
 /** @def PDMDEV_ASSERT_EMT
@@ -4249,5 +4285,5 @@
 
 /** Current version of the PDMDEVREGCB structure.  */
-#define PDM_DEVREG_CB_VERSION 0xf4010000
+#define PDM_DEVREG_CB_VERSION                   PDM_VERSION_MAKE(0xffe3, 1, 0)
 
 
Index: /trunk/include/VBox/pdmdrv.h
===================================================================
--- /trunk/include/VBox/pdmdrv.h	(revision 26000)
+++ /trunk/include/VBox/pdmdrv.h	(revision 26001)
@@ -279,5 +279,5 @@
 
 /** Current DRVREG version number. */
-#define PDM_DRVREG_VERSION                      UINT32_C(0x80030000)
+#define PDM_DRVREG_VERSION                      PDM_VERSION_MAKE(0xf0ff, 1, 0)
 
 /** PDM Driver Flags.
@@ -397,8 +397,45 @@
 
 /** Current DRVREG version number. */
-#define PDM_DRVINS_VERSION      UINT32_C(0xa0020000)
+#define PDM_DRVINS_VERSION                      PDM_VERSION_MAKE(0xf0fe, 1, 0)
 
 /** Converts a pointer to the PDMDRVINS::IBase to a pointer to PDMDRVINS. */
 #define PDMIBASE_2_PDMDRV(pInterface) ( (PPDMDRVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDRVINS, IBase)) )
+
+/**
+ * Checks the structure versions of the drive instance and driver helpers,
+ * returning if they are incompatible.
+ *
+ * Intended for the constructor.
+ *
+ * @param   pDrvIns     The drvice instance pointer.
+ */
+#define PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns) \
+    do \
+    { \
+        PPDMDRVINS pDrvInsTypeCheck = (pDrvIns); NOREF(pDrvInsTypeCheck); \
+        AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->u32Version, PDM_DRVINS_VERSION), \
+                              ("DrvIns=%#x  mine=%#x\n", (pDrvIns)->u32Version, PDM_DRVINS_VERSION), \
+                              VERR_VERSION_MISMATCH); \
+        AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->pDrvHlpR3->u32Version, PDM_DRVHLPR3_VERSION), \
+                              ("DrvHlp=%#x  mine=%#x\n", (pDrvIns)->pDrvHlpR3->u32Version, PDM_DRVHLPR3_VERSION), \
+                              VERR_VERSION_MISMATCH); \
+    } while (0)
+
+/**
+ * Quietly checks the structure versions of the drive instance and driver
+ * helpers, returning if they are incompatible.
+ *
+ * Intended for the destructor.
+ *
+ * @param   pDrvIns     The drvice instance pointer.
+ */
+#define PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns) \
+    do \
+    { \
+        PPDMDRVINS pDrvInsTypeCheck = (pDrvIns); NOREF(pDrvInsTypeCheck); \
+        if (RT_UNLIKELY(   !PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->u32Version, PDM_DRVINS_VERSION) \
+                        || !PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->pDrvHlpR3->u32Version, PDM_DRVHLPR3_VERSION)) ) \
+            return; \
+    } while (0)
 
 
@@ -446,5 +483,5 @@
 
 /** Current PDMUSBHUBREG version number. */
-#define PDM_USBHUBREG_VERSION       UINT32_C(0xeb010000)
+#define PDM_USBHUBREG_VERSION                   PDM_VERSION_MAKE(0xf0fd, 1, 0)
 
 
@@ -469,5 +506,5 @@
 
 /** Current PDMUSBHUBHLP version number. */
-#define PDM_USBHUBHLP_VERSION       UINT32_C(0xea010000)
+#define PDM_USBHUBHLP_VERSION                   PDM_VERSION_MAKE(0xf0fc, 1, 0)
 
 
@@ -478,5 +515,5 @@
 typedef struct PDMDRVHLPR3
 {
-    /** Structure version. PDM_DRVHLP_VERSION defines the current version. */
+    /** Structure version. PDM_DRVHLPR3_VERSION defines the current version. */
     uint32_t                    u32Version;
 
@@ -860,5 +897,5 @@
 } PDMDRVHLPR3;
 /** Current DRVHLP version number. */
-#define PDM_DRVHLPR3_VERSION    UINT32_C(0x90050000)
+#define PDM_DRVHLPR3_VERSION                    PDM_VERSION_MAKE(0xf0fb, 1, 0)
 
 
@@ -1189,5 +1226,5 @@
 
 /** Current version of the PDMDRVREGCB structure.  */
-#define PDM_DRVREG_CB_VERSION   UINT32_C(0xb0010000)
+#define PDM_DRVREG_CB_VERSION                   PDM_VERSION_MAKE(0xf0fa, 1, 0)
 
 
Index: /trunk/include/VBox/pdmsrv.h
===================================================================
--- /trunk/include/VBox/pdmsrv.h	(revision 26000)
+++ /trunk/include/VBox/pdmsrv.h	(revision 26001)
@@ -247,5 +247,5 @@
 
 /** Current SRVHLP version number. */
-#define PDM_SRVHLP_VERSION  0xf9010000
+#define PDM_SRVHLP_VERSION                      PDM_VERSION_MAKE(0xdfff, 1, 0)
 
 
@@ -286,5 +286,5 @@
 
 /** Current PDMSRVREG version number. */
-#define PDM_SRVINS_VERSION  0xf7010000
+#define PDM_SRVINS_VERSION                      PDM_VERSION_MAKE(0xdffe, 1, 0)
 
 /** Converts a pointer to the PDMSRVINS::IBase to a pointer to PDMSRVINS. */
@@ -317,5 +317,5 @@
 
 /** Current version of the PDMSRVREGCB structure. */
-#define PDM_SRVREG_CB_VERSION 0xf8010000
+#define PDM_SRVREG_CB_VERSION                   PDM_VERSION_MAKE(0xdffd, 1, 0)
 
 
Index: /trunk/include/VBox/pdmthread.h
===================================================================
--- /trunk/include/VBox/pdmthread.h	(revision 26000)
+++ /trunk/include/VBox/pdmthread.h	(revision 26001)
@@ -4,5 +4,5 @@
 
 /*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -281,5 +281,5 @@
 
 /** PDMTHREAD::u32Version value. */
-#define PDMTHREAD_VERSION   0xef010000
+#define PDMTHREAD_VERSION                       PDM_VERSION_MAKE(0xefff, 1, 0)
 
 #ifdef IN_RING3
Index: /trunk/include/VBox/pdmusb.h
===================================================================
--- /trunk/include/VBox/pdmusb.h	(revision 26000)
+++ /trunk/include/VBox/pdmusb.h	(revision 26001)
@@ -4,5 +4,5 @@
 
 /*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -368,5 +368,5 @@
 
 /** Current USBREG version number. */
-#define PDM_USBREG_VERSION  0xed010000
+#define PDM_USBREG_VERSION                      PDM_VERSION_MAKE(0xeeff, 1, 0)
 
 /** PDM USB Device Flags.
@@ -607,5 +607,5 @@
 
 /** Current USBHLP version number. */
-#define PDM_USBHLP_VERSION  0xec020001
+#define PDM_USBHLP_VERSION                      PDM_VERSION_MAKE(0xeefe, 1, 0)
 
 #endif /* IN_RING3 */
@@ -662,5 +662,5 @@
 
 /** Current USBINS version number. */
-#define PDM_USBINS_VERSION  0xf3010000
+#define PDM_USBINS_VERSION                      PDM_VERSION_MAKE(0xeefd, 1, 0)
 
 /** Converts a pointer to the PDMUSBINS::IBase to a pointer to PDMUSBINS. */
@@ -793,5 +793,5 @@
 
 /** Current version of the PDMUSBREGCB structure.  */
-#define PDM_USBREG_CB_VERSION 0xee010000
+#define PDM_USBREG_CB_VERSION                   PDM_VERSION_MAKE(0xeefc, 1, 0)
 
 
Index: /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 26001)
@@ -1576,4 +1576,5 @@
 
     Assert(iInstance == 0);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
Index: /trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 26001)
@@ -1794,4 +1794,5 @@
      */
     Assert(iInstance == 0);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
     if (!CFGMR3AreValuesValid(pCfgHandle,
                               "IRQ\0"
Index: /trunk/src/VBox/Devices/Audio/audio.c
===================================================================
--- /trunk/src/VBox/Devices/Audio/audio.c	(revision 26000)
+++ /trunk/src/VBox/Devices/Audio/audio.c	(revision 26001)
@@ -1962,4 +1962,5 @@
 {
     LogFlow(("drvAUDIODestruct:\n"));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
 
     audio_atexit ();
@@ -1978,4 +1979,5 @@
 
     LogFlow(("drvAUDIOConstruct:\n"));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/Audio/audiosniffer.c
===================================================================
--- /trunk/src/VBox/Devices/Audio/audiosniffer.c	(revision 26000)
+++ /trunk/src/VBox/Devices/Audio/audiosniffer.c	(revision 26001)
@@ -128,4 +128,23 @@
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMIAUDIOSNIFFERPORT, &pThis->IPort);
     return NULL;
+}
+
+/**
+ * Destruct a device instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that any non-VM
+ * resources can be freed correctly.
+ *
+ * @returns VBox status.
+ * @param   pDevIns     The device instance data.
+ */
+static DECLCALLBACK(int) audioSnifferR3Destruct(PPDMDEVINS pDevIns)
+{
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
+
+    /* Zero the global pointer. */
+    g_pData = NULL;
+
+    return VINF_SUCCESS;
 }
 
@@ -145,9 +164,9 @@
 static DECLCALLBACK(int) audioSnifferR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
 {
-    int rc = VINF_SUCCESS;
-
+    int                rc    = VINF_SUCCESS;
     AUDIOSNIFFERSTATE *pThis = PDMINS_2_DATA(pDevIns, AUDIOSNIFFERSTATE *);
 
     Assert(iInstance == 0);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
@@ -208,21 +227,4 @@
 
     return rc;
-}
-
-/**
- * Destruct a device instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that any non-VM
- * resources can be freed correctly.
- *
- * @returns VBox status.
- * @param   pDevIns     The device instance data.
- */
-static DECLCALLBACK(int) audioSnifferR3Destruct(PPDMDEVINS pDevIns)
-{
-    /* Zero the global pointer. */
-    g_pData = NULL;
-
-    return VINF_SUCCESS;
 }
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 26001)
@@ -5810,4 +5810,36 @@
 }
 
+
+/**
+ * Destruct a device instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that any non-VM
+ * resources can be freed correctly.
+ *
+ * @param   pDevIns     The device instance data.
+ */
+static DECLCALLBACK(int) vgaR3Destruct(PPDMDEVINS pDevIns)
+{
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
+
+#ifdef VBE_NEW_DYN_LIST
+    PVGASTATE   pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+    LogFlow(("vgaR3Destruct:\n"));
+
+    /*
+     * Free MM heap pointers.
+     */
+    if (pThis->pu8VBEExtraData)
+    {
+        MMR3HeapFree(pThis->pu8VBEExtraData);
+        pThis->pu8VBEExtraData = NULL;
+    }
+#endif
+
+    PDMR3CritSectDelete(&pThis->lock);
+    return VINF_SUCCESS;
+}
+
+
 /**
  * Construct a VGA device instance for a VM.
@@ -5825,9 +5857,8 @@
 static DECLCALLBACK(int)   vgaR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
 {
+
     static bool s_fExpandDone = false;
     int         rc;
-    unsigned i;
-    PVGASTATE   pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
-    PVM         pVM = PDMDevHlpGetVM(pDevIns);
+    unsigned    i;
 #ifdef VBE_NEW_DYN_LIST
     uint32_t    cCustomModes;
@@ -5837,4 +5868,8 @@
     unsigned    cb;
 #endif
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
+    PVGASTATE   pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
+    PVM         pVM   = PDMDevHlpGetVM(pDevIns);
+
     Assert(iInstance == 0);
     Assert(pVM);
@@ -6558,33 +6593,4 @@
     pThis->uMaskLatchAccess = 0x3ff;
     return rc;
-}
-
-
-/**
- * Destruct a device instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that any non-VM
- * resources can be freed correctly.
- *
- * @param   pDevIns     The device instance data.
- */
-static DECLCALLBACK(int) vgaR3Destruct(PPDMDEVINS pDevIns)
-{
-#ifdef VBE_NEW_DYN_LIST
-    PVGASTATE   pThis = PDMINS_2_DATA(pDevIns, PVGASTATE);
-    LogFlow(("vgaR3Destruct:\n"));
-
-    /*
-     * Free MM heap pointers.
-     */
-    if (pThis->pu8VBEExtraData)
-    {
-        MMR3HeapFree(pThis->pu8VBEExtraData);
-        pThis->pu8VBEExtraData = NULL;
-    }
-#endif
-
-    PDMR3CritSectDelete(&pThis->lock);
-    return VINF_SUCCESS;
 }
 
Index: /trunk/src/VBox/Devices/Input/DevPS2.cpp
===================================================================
--- /trunk/src/VBox/Devices/Input/DevPS2.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Input/DevPS2.cpp	(revision 26001)
@@ -1572,4 +1572,6 @@
 {
     KBDState   *pThis = PDMINS_2_DATA(pDevIns, KBDState *);
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
+
     PDMR3CritSectDelete(&pThis->CritSect);
 
@@ -1598,4 +1600,6 @@
     bool        fR0Enabled;
     Assert(iInstance == 0);
+
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
Index: /trunk/src/VBox/Devices/Input/DrvKeyboardQueue.cpp
===================================================================
--- /trunk/src/VBox/Devices/Input/DrvKeyboardQueue.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Input/DrvKeyboardQueue.cpp	(revision 26001)
@@ -238,4 +238,5 @@
     PDRVKBDQUEUE pDrv = PDMINS_2_DATA(pDrvIns, PDRVKBDQUEUE);
     LogFlow(("drvKbdQueueConstruct: iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/Input/DrvMouseQueue.cpp
===================================================================
--- /trunk/src/VBox/Devices/Input/DrvMouseQueue.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Input/DrvMouseQueue.cpp	(revision 26001)
@@ -227,4 +227,5 @@
     PDRVMOUSEQUEUE pDrv = PDMINS_2_DATA(pDrvIns, PDRVMOUSEQUEUE);
     LogFlow(("drvMouseQueueConstruct: iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/Network/DevE1000.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevE1000.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Network/DevE1000.cpp	(revision 26001)
@@ -4724,4 +4724,197 @@
 }
 
+/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
+
+#ifdef VBOX_DYNAMIC_NET_ATTACH
+
+/**
+ * Detach notification.
+ *
+ * One port on the network card has been disconnected from the network.
+ *
+ * @param   pDevIns     The device instance.
+ * @param   iLUN        The logical unit which is being detached.
+ * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
+ */
+static DECLCALLBACK(void) e1kDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
+{
+    E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
+    Log(("%s e1kDetach:\n", INSTANCE(pState)));
+
+    AssertLogRelReturnVoid(iLUN == 0);
+
+    PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
+
+    /** @todo: r=pritesh still need to check if i missed
+     * to clean something in this function
+     */
+
+    /*
+     * Zero some important members.
+     */
+    pState->pDrvBase = NULL;
+    pState->pDrv = NULL;
+
+    PDMCritSectLeave(&pState->cs);
+}
+
+
+/**
+ * Attach the Network attachment.
+ *
+ * One port on the network card has been connected to a network.
+ *
+ * @returns VBox status code.
+ * @param   pDevIns     The device instance.
+ * @param   iLUN        The logical unit which is being attached.
+ * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
+ *
+ * @remarks This code path is not used during construction.
+ */
+static DECLCALLBACK(int) e1kAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
+{
+    E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
+    LogFlow(("%s e1kAttach:\n",  INSTANCE(pState)));
+
+    AssertLogRelReturn(iLUN == 0, VERR_PDM_NO_SUCH_LUN);
+
+    PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
+
+    /*
+     * Attach the driver.
+     */
+    int rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->IBase, &pState->pDrvBase, "Network Port");
+    if (RT_SUCCESS(rc))
+    {
+        if (rc == VINF_NAT_DNS)
+        {
+#ifdef RT_OS_LINUX
+            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
+                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Please check your /etc/resolv.conf for <tt>nameserver</tt> entries. Either add one manually (<i>man resolv.conf</i>) or ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
+#else
+            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
+                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
+#endif
+        }
+        pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
+        AssertMsgStmt(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
+                      rc = VERR_PDM_MISSING_INTERFACE_BELOW);
+    }
+    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
+        Log(("%s No attached driver!\n", INSTANCE(pState)));
+
+
+    /*
+     * Temporary set the link down if it was up so that the guest
+     * will know that we have change the configuration of the
+     * network card
+     */
+    if ((STATUS & STATUS_LU) && RT_SUCCESS(rc))
+    {
+        STATUS &= ~STATUS_LU;
+        Phy::setLinkStatus(&pState->phy, false);
+        e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_LSC);
+        /* Restore the link back in 5 second. */
+        e1kArmTimer(pState, pState->pLUTimer, 5000000);
+    }
+
+    PDMCritSectLeave(&pState->cs);
+    return rc;
+
+}
+
+#endif /* VBOX_DYNAMIC_NET_ATTACH */
+
+/**
+ * @copydoc FNPDMDEVPOWEROFF
+ */
+static DECLCALLBACK(void) e1kPowerOff(PPDMDEVINS pDevIns)
+{
+    /* Poke thread waiting for buffer space. */
+    e1kWakeupReceive(pDevIns);
+}
+
+/**
+ * @copydoc FNPDMDEVSUSPEND
+ */
+static DECLCALLBACK(void) e1kSuspend(PPDMDEVINS pDevIns)
+{
+    /* Poke thread waiting for buffer space. */
+    e1kWakeupReceive(pDevIns);
+}
+
+/**
+ * Device relocation callback.
+ *
+ * When this callback is called the device instance data, and if the
+ * device have a GC component, is being relocated, or/and the selectors
+ * have been changed. The device must use the chance to perform the
+ * necessary pointer relocations and data updates.
+ *
+ * Before the GC code is executed the first time, this function will be
+ * called with a 0 delta so GC pointer calculations can be one in one place.
+ *
+ * @param   pDevIns     Pointer to the device instance.
+ * @param   offDelta    The relocation delta relative to the old location.
+ *
+ * @remark  A relocation CANNOT fail.
+ */
+static DECLCALLBACK(void) e1kRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
+{
+    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
+    pState->pDevInsRC     = PDMDEVINS_2_RCPTR(pDevIns);
+    pState->pTxQueueRC    = PDMQueueRCPtr(pState->pTxQueueR3);
+    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
+#ifdef E1K_USE_RX_TIMERS
+    pState->pRIDTimerRC   = TMTimerRCPtr(pState->pRIDTimerR3);
+    pState->pRADTimerRC   = TMTimerRCPtr(pState->pRADTimerR3);
+#endif /* E1K_USE_RX_TIMERS */
+#ifdef E1K_USE_TX_TIMERS
+    pState->pTIDTimerRC   = TMTimerRCPtr(pState->pTIDTimerR3);
+# ifndef E1K_NO_TAD
+    pState->pTADTimerRC   = TMTimerRCPtr(pState->pTADTimerR3);
+# endif /* E1K_NO_TAD */
+#endif /* E1K_USE_TX_TIMERS */
+    pState->pIntTimerRC   = TMTimerRCPtr(pState->pIntTimerR3);
+}
+
+/**
+ * Destruct a device instance.
+ *
+ * We need to free non-VM resources only.
+ *
+ * @returns VBox status.
+ * @param   pDevIns     The device instance data.
+ * @thread  EMT
+ */
+static DECLCALLBACK(int) e1kDestruct(PPDMDEVINS pDevIns)
+{
+    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
+
+    e1kDumpState(pState);
+    E1kLog(("%s Destroying instance\n", INSTANCE(pState)));
+    if (PDMCritSectIsInitialized(&pState->cs))
+    {
+        if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
+        {
+            RTSemEventSignal(pState->hEventMoreRxDescAvail);
+            RTSemEventDestroy(pState->hEventMoreRxDescAvail);
+            pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
+        }
+        if (pState->hTxSem != NIL_RTSEMEVENT)
+        {
+            RTSemEventDestroy(pState->hTxSem);
+            pState->hTxSem = NIL_RTSEMEVENT;
+        }
+#ifndef E1K_GLOBAL_MUTEX
+        PDMR3CritSectDelete(&pState->csRx);
+        //PDMR3CritSectDelete(&pState->csTx);
+#endif
+        PDMR3CritSectDelete(&pState->cs);
+    }
+    return VINF_SUCCESS;
+}
+
 /**
  * Sets 8-bit register in PCI configuration space.
@@ -4847,4 +5040,5 @@
     E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
     int       rc;
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /* Init handles and log related stuff. */
@@ -5129,194 +5323,4 @@
 
     return VINF_SUCCESS;
-}
-
-/**
- * Destruct a device instance.
- *
- * We need to free non-VM resources only.
- *
- * @returns VBox status.
- * @param   pDevIns     The device instance data.
- * @thread  EMT
- */
-static DECLCALLBACK(int) e1kDestruct(PPDMDEVINS pDevIns)
-{
-    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
-
-    e1kDumpState(pState);
-    E1kLog(("%s Destroying instance\n", INSTANCE(pState)));
-    if (PDMCritSectIsInitialized(&pState->cs))
-    {
-        if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
-        {
-            RTSemEventSignal(pState->hEventMoreRxDescAvail);
-            RTSemEventDestroy(pState->hEventMoreRxDescAvail);
-            pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
-        }
-        if (pState->hTxSem != NIL_RTSEMEVENT)
-        {
-            RTSemEventDestroy(pState->hTxSem);
-            pState->hTxSem = NIL_RTSEMEVENT;
-        }
-#ifndef E1K_GLOBAL_MUTEX
-        PDMR3CritSectDelete(&pState->csRx);
-        //PDMR3CritSectDelete(&pState->csTx);
-#endif
-        PDMR3CritSectDelete(&pState->cs);
-    }
-    return VINF_SUCCESS;
-}
-
-/**
- * Device relocation callback.
- *
- * When this callback is called the device instance data, and if the
- * device have a GC component, is being relocated, or/and the selectors
- * have been changed. The device must use the chance to perform the
- * necessary pointer relocations and data updates.
- *
- * Before the GC code is executed the first time, this function will be
- * called with a 0 delta so GC pointer calculations can be one in one place.
- *
- * @param   pDevIns     Pointer to the device instance.
- * @param   offDelta    The relocation delta relative to the old location.
- *
- * @remark  A relocation CANNOT fail.
- */
-static DECLCALLBACK(void) e1kRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
-{
-    E1KSTATE* pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
-    pState->pDevInsRC     = PDMDEVINS_2_RCPTR(pDevIns);
-    pState->pTxQueueRC    = PDMQueueRCPtr(pState->pTxQueueR3);
-    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
-#ifdef E1K_USE_RX_TIMERS
-    pState->pRIDTimerRC   = TMTimerRCPtr(pState->pRIDTimerR3);
-    pState->pRADTimerRC   = TMTimerRCPtr(pState->pRADTimerR3);
-#endif /* E1K_USE_RX_TIMERS */
-#ifdef E1K_USE_TX_TIMERS
-    pState->pTIDTimerRC   = TMTimerRCPtr(pState->pTIDTimerR3);
-# ifndef E1K_NO_TAD
-    pState->pTADTimerRC   = TMTimerRCPtr(pState->pTADTimerR3);
-# endif /* E1K_NO_TAD */
-#endif /* E1K_USE_TX_TIMERS */
-    pState->pIntTimerRC   = TMTimerRCPtr(pState->pIntTimerR3);
-}
-
-/**
- * @copydoc FNPDMDEVSUSPEND
- */
-static DECLCALLBACK(void) e1kSuspend(PPDMDEVINS pDevIns)
-{
-    /* Poke thread waiting for buffer space. */
-    e1kWakeupReceive(pDevIns);
-}
-
-
-#ifdef VBOX_DYNAMIC_NET_ATTACH
-/**
- * Detach notification.
- *
- * One port on the network card has been disconnected from the network.
- *
- * @param   pDevIns     The device instance.
- * @param   iLUN        The logical unit which is being detached.
- * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
- */
-static DECLCALLBACK(void) e1kDetach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
-{
-    E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
-    Log(("%s e1kDetach:\n", INSTANCE(pState)));
-
-    AssertLogRelReturnVoid(iLUN == 0);
-
-    PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
-
-    /** @todo: r=pritesh still need to check if i missed
-     * to clean something in this function
-     */
-
-    /*
-     * Zero some important members.
-     */
-    pState->pDrvBase = NULL;
-    pState->pDrv = NULL;
-
-    PDMCritSectLeave(&pState->cs);
-}
-
-
-/**
- * Attach the Network attachment.
- *
- * One port on the network card has been connected to a network.
- *
- * @returns VBox status code.
- * @param   pDevIns     The device instance.
- * @param   iLUN        The logical unit which is being attached.
- * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
- *
- * @remarks This code path is not used during construction.
- */
-static DECLCALLBACK(int) e1kAttach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
-{
-    E1KSTATE *pState = PDMINS_2_DATA(pDevIns, E1KSTATE*);
-    LogFlow(("%s e1kAttach:\n",  INSTANCE(pState)));
-
-    AssertLogRelReturn(iLUN == 0, VERR_PDM_NO_SUCH_LUN);
-
-    PDMCritSectEnter(&pState->cs, VERR_SEM_BUSY);
-
-    /*
-     * Attach the driver.
-     */
-    int rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->IBase, &pState->pDrvBase, "Network Port");
-    if (RT_SUCCESS(rc))
-    {
-        if (rc == VINF_NAT_DNS)
-        {
-#ifdef RT_OS_LINUX
-            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
-                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Please check your /etc/resolv.conf for <tt>nameserver</tt> entries. Either add one manually (<i>man resolv.conf</i>) or ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
-#else
-            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
-                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
-#endif
-        }
-        pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
-        AssertMsgStmt(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
-                      rc = VERR_PDM_MISSING_INTERFACE_BELOW);
-    }
-    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
-        Log(("%s No attached driver!\n", INSTANCE(pState)));
-
-
-    /*
-     * Temporary set the link down if it was up so that the guest
-     * will know that we have change the configuration of the
-     * network card
-     */
-    if ((STATUS & STATUS_LU) && RT_SUCCESS(rc))
-    {
-        STATUS &= ~STATUS_LU;
-        Phy::setLinkStatus(&pState->phy, false);
-        e1kRaiseInterrupt(pState, VERR_SEM_BUSY, ICR_LSC);
-        /* Restore the link back in 5 second. */
-        e1kArmTimer(pState, pState->pLUTimer, 5000000);
-    }
-
-    PDMCritSectLeave(&pState->cs);
-    return rc;
-
-}
-#endif /* VBOX_DYNAMIC_NET_ATTACH */
-
-
-/**
- * @copydoc FNPDMDEVPOWEROFF
- */
-static DECLCALLBACK(void) e1kPowerOff(PPDMDEVINS pDevIns)
-{
-    /* Poke thread waiting for buffer space. */
-    e1kWakeupReceive(pDevIns);
 }
 
Index: /trunk/src/VBox/Devices/Network/DevINIP.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevINIP.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Network/DevINIP.cpp	(revision 26001)
@@ -389,4 +389,5 @@
 }
 
+/* -=-=-=-=- PDMIBASE -=-=-=-=- */
 
 /**
@@ -400,4 +401,42 @@
     PDMIBASE_RETURN_INTERFACE(pszIID, PDMINETWORKPORT, &pThis->INetworkPort);
     return NULL;
+}
+
+/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
+
+/**
+ * Destruct a device instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that any non-VM
+ * resources can be freed correctly.
+ *
+ * @returns VBox status.
+ * @param   pDevIns     The device instance data.
+ */
+static DECLCALLBACK(int) devINIPDestruct(PPDMDEVINS pDevIns)
+{
+    PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
+
+    LogFlow(("%s: pDevIns=%p\n", __FUNCTION__, pDevIns));
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
+
+    if (g_pDevINIPData != NULL)
+    {
+        netif_set_down(&pThis->IntNetIF);
+        netif_remove(&pThis->IntNetIF);
+        tcpip_terminate();
+        lwip_sys_sem_wait(pThis->LWIPTcpInitSem);
+        lwip_sys_sem_free(pThis->LWIPTcpInitSem);
+    }
+
+    if (pThis->pszIP)
+        MMR3HeapFree(pThis->pszIP);
+    if (pThis->pszNetmask)
+        MMR3HeapFree(pThis->pszNetmask);
+    if (pThis->pszGateway)
+        MMR3HeapFree(pThis->pszGateway);
+
+    LogFlow(("%s: success\n", __FUNCTION__));
+    return VINF_SUCCESS;
 }
 
@@ -426,4 +465,5 @@
 
     Assert(iInstance == 0);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
@@ -631,40 +671,4 @@
 
 /**
- * Destruct a device instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that any non-VM
- * resources can be freed correctly.
- *
- * @returns VBox status.
- * @param   pDevIns     The device instance data.
- */
-static DECLCALLBACK(int) devINIPDestruct(PPDMDEVINS pDevIns)
-{
-    PDEVINTNETIP pThis = PDMINS_2_DATA(pDevIns, PDEVINTNETIP);
-
-    LogFlow(("%s: pDevIns=%p\n", __FUNCTION__, pDevIns));
-
-    if (g_pDevINIPData != NULL)
-    {
-        netif_set_down(&pThis->IntNetIF);
-        netif_remove(&pThis->IntNetIF);
-        tcpip_terminate();
-        lwip_sys_sem_wait(pThis->LWIPTcpInitSem);
-        lwip_sys_sem_free(pThis->LWIPTcpInitSem);
-    }
-
-    if (pThis->pszIP)
-        MMR3HeapFree(pThis->pszIP);
-    if (pThis->pszNetmask)
-        MMR3HeapFree(pThis->pszNetmask);
-    if (pThis->pszGateway)
-        MMR3HeapFree(pThis->pszGateway);
-
-    LogFlow(("%s: success\n", __FUNCTION__));
-    return VINF_SUCCESS;
-}
-
-
-/**
  * Query whether lwIP is initialized or not. Since there is only a single
  * instance of this device ever for a VM, it can be a global function.
Index: /trunk/src/VBox/Devices/Network/DevPCNet.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 26001)
@@ -4906,4 +4906,5 @@
 {
     PCNetState *pThis = PDMINS_2_DATA(pDevIns, PCNetState *);
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
 
     if (PDMCritSectIsInitialized(&pThis->CritSect))
@@ -4952,4 +4953,5 @@
     Assert((iInstance >= 0) && (iInstance < 8));
 
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
     Assert(RT_ELEMENTS(pThis->aBCR) == BCR_MAX_RAP);
     Assert(RT_ELEMENTS(pThis->aMII) == MII_MAX_REG);
Index: /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp	(revision 26001)
@@ -1434,235 +1434,8 @@
 }
 
-/**
- * Construct a device instance for a VM.
- *
- * @returns VBox status.
- * @param   pDevIns     The device instance data.
- *                      If the registration structure is needed, pDevIns->pDevReg points to it.
- * @param   iInstance   Instance number. Use this to figure out which registers and such to use.
- *                      The device number is also found in pDevIns->iInstance, but since it's
- *                      likely to be freqently used PDM passes it as parameter.
- * @param   pCfgHandle  Configuration node handle for the device. Use this to obtain the configuration
- *                      of the device instance. It's also found in pDevIns->pCfgHandle, but like
- *                      iInstance it's expected to be used a bit in this function.
- * @thread  EMT
- */
-static DECLCALLBACK(int) vnetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
-{
-    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
-    int        rc;
-
-    /* Initialize PCI part first. */
-    pState->VPCI.IBase.pfnQueryInterface    = vnetQueryInterface;
-    rc = vpciConstruct(pDevIns, &pState->VPCI, iInstance,
-                       VNET_NAME_FMT, VNET_PCI_SUBSYSTEM_ID,
-                       VNET_PCI_CLASS, VNET_N_QUEUES);
-    pState->pRxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueReceive,  "RX ");
-    pState->pTxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueTransmit, "TX ");
-    pState->pCtlQueue = vpciAddQueue(&pState->VPCI, 16,  vnetQueueControl,  "CTL");
-
-    Log(("%s Constructing new instance\n", INSTANCE(pState)));
-
-    pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
-
-    /*
-     * Validate configuration.
-     */
-    if (!CFGMR3AreValuesValid(pCfgHandle, "MAC\0" "CableConnected\0" "LineSpeed\0"))
-                    return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
-                                            N_("Invalid configuration for VirtioNet device"));
-
-    /* Get config params */
-    rc = CFGMR3QueryBytes(pCfgHandle, "MAC", pState->macConfigured.au8,
-                          sizeof(pState->macConfigured));
-    if (RT_FAILURE(rc))
-        return PDMDEV_SET_ERROR(pDevIns, rc,
-                                N_("Configuration error: Failed to get MAC address"));
-    rc = CFGMR3QueryBool(pCfgHandle, "CableConnected", &pState->fCableConnected);
-    if (RT_FAILURE(rc))
-        return PDMDEV_SET_ERROR(pDevIns, rc,
-                                N_("Configuration error: Failed to get the value of 'CableConnected'"));
-
-    /* Initialize PCI config space */
-    memcpy(pState->config.mac.au8, pState->macConfigured.au8, sizeof(pState->config.mac.au8));
-    pState->config.uStatus = 0;
-
-    /* Initialize state structure */
-    pState->u32PktNo     = 1;
-
-    /* Interfaces */
-    pState->INetworkPort.pfnWaitReceiveAvail = vnetWaitReceiveAvail;
-    pState->INetworkPort.pfnReceive          = vnetReceive;
-    pState->INetworkConfig.pfnGetMac         = vnetGetMac;
-    pState->INetworkConfig.pfnGetLinkState   = vnetGetLinkState;
-    pState->INetworkConfig.pfnSetLinkState   = vnetSetLinkState;
-
-    pState->pTxBuf = (uint8_t *)RTMemAllocZ(VNET_MAX_FRAME_SIZE);
-    AssertMsgReturn(pState->pTxBuf,
-                    ("Cannot allocate TX buffer for virtio-net device\n"), VERR_NO_MEMORY);
-
-    /* Initialize critical section. */
-    // char szTmp[sizeof(pState->VPCI.szInstance) + 2];
-    // RTStrPrintf(szTmp, sizeof(szTmp), "%sRX", pState->VPCI.szInstance);
-    // rc = PDMDevHlpCritSectInit(pDevIns, &pState->csRx, szTmp);
-    // if (RT_FAILURE(rc))
-    //     return rc;
-
-    /* Map our ports to IO space. */
-    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0,
-                                      VPCI_CONFIG + sizeof(VNetPCIConfig),
-                                      PCI_ADDRESS_SPACE_IO, vnetMap);
-    if (RT_FAILURE(rc))
-        return rc;
-
-
-    /* Register save/restore state handlers. */
-    rc = PDMDevHlpSSMRegisterEx(pDevIns, VIRTIO_SAVEDSTATE_VERSION, sizeof(VNETSTATE), NULL,
-                                NULL,         vnetLiveExec, NULL,
-                                vnetSavePrep, vnetSaveExec, NULL,
-                                vnetLoadPrep, vnetLoadExec, vnetLoadDone);
-    if (RT_FAILURE(rc))
-        return rc;
-
-    /* Create the RX notifier signaller. */
-    rc = PDMDevHlpPDMQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 1, 0,
-                                 vnetCanRxQueueConsumer, true, "VNet-Rcv", &pState->pCanRxQueueR3);
-    if (RT_FAILURE(rc))
-        return rc;
-    pState->pCanRxQueueR0 = PDMQueueR0Ptr(pState->pCanRxQueueR3);
-    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
-
-    /* Create Link Up Timer */
-    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetLinkUpTimer, pState,
-                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
-                                "VirtioNet Link Up Timer", &pState->pLinkUpTimer);
-    if (RT_FAILURE(rc))
-        return rc;
-
-#ifdef VNET_TX_DELAY
-    /* Create Transmit Delay Timer */
-    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetTxTimer, pState,
-                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
-                                "VirtioNet TX Delay Timer", &pState->pTxTimerR3);
-    if (RT_FAILURE(rc))
-        return rc;
-    pState->pTxTimerR0 = TMTimerR0Ptr(pState->pTxTimerR3);
-    pState->pTxTimerRC = TMTimerRCPtr(pState->pTxTimerR3);
-
-    pState->u32i = pState->u32AvgDiff = pState->u32MaxDiff = 0;
-    pState->u32MinDiff = ~0;
-#endif /* VNET_TX_DELAY */
-
-    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->VPCI.IBase, &pState->pDrvBase, "Network Port");
-    if (RT_SUCCESS(rc))
-    {
-        if (rc == VINF_NAT_DNS)
-        {
-            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
-                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
-        }
-        pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
-        AssertMsgReturn(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
-                        VERR_PDM_MISSING_INTERFACE_BELOW);
-    }
-    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
-    {
-        Log(("%s This adapter is not attached to any network!\n", INSTANCE(pState)));
-    }
-    else
-        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the network LUN"));
-
-    rc = RTSemEventCreate(&pState->hEventMoreRxDescAvail);
-    if (RT_FAILURE(rc))
-        return rc;
-
-    vnetReset(pState);
-
-    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveBytes,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data received",            "/Devices/VNet%d/ReceiveBytes", iInstance);
-    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitBytes,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data transmitted",         "/Devices/VNet%d/TransmitBytes", iInstance);
-#if defined(VBOX_WITH_STATISTICS)
-    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceive,            STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive",                  "/Devices/VNet%d/Receive/Total", iInstance);
-    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveStore,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive storing",          "/Devices/VNet%d/Receive/Store", iInstance);
-    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflow,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling RX overflows",        "/Devices/VNet%d/RxOverflow", iInstance);
-    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflowWakeup,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of RX overflow wakeups",          "/Devices/VNet%d/RxOverflowWakeup", iInstance);
-    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmit,           STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in HC",          "/Devices/VNet%d/Transmit/Total", iInstance);
-    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitSend,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling send transmit in HC",      "/Devices/VNet%d/Transmit/Send", iInstance);
-#endif /* VBOX_WITH_STATISTICS */
-
-    return VINF_SUCCESS;
-}
-
-/**
- * Destruct a device instance.
- *
- * We need to free non-VM resources only.
- *
- * @returns VBox status.
- * @param   pDevIns     The device instance data.
- * @thread  EMT
- */
-static DECLCALLBACK(int) vnetDestruct(PPDMDEVINS pDevIns)
-{
-    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
-
-    LogRel(("TxTimer stats (avg/min/max): %7d usec %7d usec %7d usec\n",
-            pState->u32AvgDiff, pState->u32MinDiff, pState->u32MaxDiff));
-    Log(("%s Destroying instance\n", INSTANCE(pState)));
-    if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
-    {
-        RTSemEventSignal(pState->hEventMoreRxDescAvail);
-        RTSemEventDestroy(pState->hEventMoreRxDescAvail);
-        pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
-    }
-
-    if (pState->pTxBuf)
-    {
-        RTMemFree(pState->pTxBuf);
-        pState->pTxBuf = NULL;
-    }
-    // if (PDMCritSectIsInitialized(&pState->csRx))
-    //     PDMR3CritSectDelete(&pState->csRx);
-
-    return vpciDestruct(&pState->VPCI);
-}
-
-/**
- * Device relocation callback.
- *
- * When this callback is called the device instance data, and if the
- * device have a GC component, is being relocated, or/and the selectors
- * have been changed. The device must use the chance to perform the
- * necessary pointer relocations and data updates.
- *
- * Before the GC code is executed the first time, this function will be
- * called with a 0 delta so GC pointer calculations can be one in one place.
- *
- * @param   pDevIns     Pointer to the device instance.
- * @param   offDelta    The relocation delta relative to the old location.
- *
- * @remark  A relocation CANNOT fail.
- */
-static DECLCALLBACK(void) vnetRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
-{
-    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
-    vpciRelocate(pDevIns, offDelta);
-    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
-#ifdef VNET_TX_DELAY
-    pState->pTxTimerRC    = TMTimerRCPtr(pState->pTxTimerR3);
-#endif /* VNET_TX_DELAY */
-    // TBD
-}
-
-/**
- * @copydoc FNPDMDEVSUSPEND
- */
-static DECLCALLBACK(void) vnetSuspend(PPDMDEVINS pDevIns)
-{
-    /* Poke thread waiting for buffer space. */
-    vnetWakeupReceive(pDevIns);
-}
-
+/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
 
 #ifdef VBOX_DYNAMIC_NET_ATTACH
+
 /**
  * Detach notification.
@@ -1760,14 +1533,245 @@
 
 }
+
 #endif /* VBOX_DYNAMIC_NET_ATTACH */
 
-
-/**
- * @copydoc FNPDMDEVPOWEROFF
- */
-static DECLCALLBACK(void) vnetPowerOff(PPDMDEVINS pDevIns)
+/**
+ * @copydoc FNPDMDEVSUSPEND
+ */
+static DECLCALLBACK(void) vnetSuspend(PPDMDEVINS pDevIns)
 {
     /* Poke thread waiting for buffer space. */
     vnetWakeupReceive(pDevIns);
+}
+
+/**
+ * @copydoc FNPDMDEVPOWEROFF
+ */
+static DECLCALLBACK(void) vnetPowerOff(PPDMDEVINS pDevIns)
+{
+    /* Poke thread waiting for buffer space. */
+    vnetWakeupReceive(pDevIns);
+}
+
+/**
+ * Device relocation callback.
+ *
+ * When this callback is called the device instance data, and if the
+ * device have a GC component, is being relocated, or/and the selectors
+ * have been changed. The device must use the chance to perform the
+ * necessary pointer relocations and data updates.
+ *
+ * Before the GC code is executed the first time, this function will be
+ * called with a 0 delta so GC pointer calculations can be one in one place.
+ *
+ * @param   pDevIns     Pointer to the device instance.
+ * @param   offDelta    The relocation delta relative to the old location.
+ *
+ * @remark  A relocation CANNOT fail.
+ */
+static DECLCALLBACK(void) vnetRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
+{
+    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
+    vpciRelocate(pDevIns, offDelta);
+    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
+#ifdef VNET_TX_DELAY
+    pState->pTxTimerRC    = TMTimerRCPtr(pState->pTxTimerR3);
+#endif /* VNET_TX_DELAY */
+    // TBD
+}
+
+/**
+ * Destruct a device instance.
+ *
+ * We need to free non-VM resources only.
+ *
+ * @returns VBox status.
+ * @param   pDevIns     The device instance data.
+ * @thread  EMT
+ */
+static DECLCALLBACK(int) vnetDestruct(PPDMDEVINS pDevIns)
+{
+    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
+
+    LogRel(("TxTimer stats (avg/min/max): %7d usec %7d usec %7d usec\n",
+            pState->u32AvgDiff, pState->u32MinDiff, pState->u32MaxDiff));
+    Log(("%s Destroying instance\n", INSTANCE(pState)));
+    if (pState->hEventMoreRxDescAvail != NIL_RTSEMEVENT)
+    {
+        RTSemEventSignal(pState->hEventMoreRxDescAvail);
+        RTSemEventDestroy(pState->hEventMoreRxDescAvail);
+        pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
+    }
+
+    if (pState->pTxBuf)
+    {
+        RTMemFree(pState->pTxBuf);
+        pState->pTxBuf = NULL;
+    }
+    // if (PDMCritSectIsInitialized(&pState->csRx))
+    //     PDMR3CritSectDelete(&pState->csRx);
+
+    return vpciDestruct(&pState->VPCI);
+}
+
+/**
+ * Construct a device instance for a VM.
+ *
+ * @returns VBox status.
+ * @param   pDevIns     The device instance data.
+ *                      If the registration structure is needed, pDevIns->pDevReg points to it.
+ * @param   iInstance   Instance number. Use this to figure out which registers and such to use.
+ *                      The device number is also found in pDevIns->iInstance, but since it's
+ *                      likely to be freqently used PDM passes it as parameter.
+ * @param   pCfgHandle  Configuration node handle for the device. Use this to obtain the configuration
+ *                      of the device instance. It's also found in pDevIns->pCfgHandle, but like
+ *                      iInstance it's expected to be used a bit in this function.
+ * @thread  EMT
+ */
+static DECLCALLBACK(int) vnetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
+{
+    VNETSTATE* pState = PDMINS_2_DATA(pDevIns, VNETSTATE*);
+    int        rc;
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
+
+    /* Initialize PCI part first. */
+    pState->VPCI.IBase.pfnQueryInterface    = vnetQueryInterface;
+    rc = vpciConstruct(pDevIns, &pState->VPCI, iInstance,
+                       VNET_NAME_FMT, VNET_PCI_SUBSYSTEM_ID,
+                       VNET_PCI_CLASS, VNET_N_QUEUES);
+    pState->pRxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueReceive,  "RX ");
+    pState->pTxQueue  = vpciAddQueue(&pState->VPCI, 256, vnetQueueTransmit, "TX ");
+    pState->pCtlQueue = vpciAddQueue(&pState->VPCI, 16,  vnetQueueControl,  "CTL");
+
+    Log(("%s Constructing new instance\n", INSTANCE(pState)));
+
+    pState->hEventMoreRxDescAvail = NIL_RTSEMEVENT;
+
+    /*
+     * Validate configuration.
+     */
+    if (!CFGMR3AreValuesValid(pCfgHandle, "MAC\0" "CableConnected\0" "LineSpeed\0"))
+                    return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
+                                            N_("Invalid configuration for VirtioNet device"));
+
+    /* Get config params */
+    rc = CFGMR3QueryBytes(pCfgHandle, "MAC", pState->macConfigured.au8,
+                          sizeof(pState->macConfigured));
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("Configuration error: Failed to get MAC address"));
+    rc = CFGMR3QueryBool(pCfgHandle, "CableConnected", &pState->fCableConnected);
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("Configuration error: Failed to get the value of 'CableConnected'"));
+
+    /* Initialize PCI config space */
+    memcpy(pState->config.mac.au8, pState->macConfigured.au8, sizeof(pState->config.mac.au8));
+    pState->config.uStatus = 0;
+
+    /* Initialize state structure */
+    pState->u32PktNo     = 1;
+
+    /* Interfaces */
+    pState->INetworkPort.pfnWaitReceiveAvail = vnetWaitReceiveAvail;
+    pState->INetworkPort.pfnReceive          = vnetReceive;
+    pState->INetworkConfig.pfnGetMac         = vnetGetMac;
+    pState->INetworkConfig.pfnGetLinkState   = vnetGetLinkState;
+    pState->INetworkConfig.pfnSetLinkState   = vnetSetLinkState;
+
+    pState->pTxBuf = (uint8_t *)RTMemAllocZ(VNET_MAX_FRAME_SIZE);
+    AssertMsgReturn(pState->pTxBuf,
+                    ("Cannot allocate TX buffer for virtio-net device\n"), VERR_NO_MEMORY);
+
+    /* Initialize critical section. */
+    // char szTmp[sizeof(pState->VPCI.szInstance) + 2];
+    // RTStrPrintf(szTmp, sizeof(szTmp), "%sRX", pState->VPCI.szInstance);
+    // rc = PDMDevHlpCritSectInit(pDevIns, &pState->csRx, szTmp);
+    // if (RT_FAILURE(rc))
+    //     return rc;
+
+    /* Map our ports to IO space. */
+    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 0,
+                                      VPCI_CONFIG + sizeof(VNetPCIConfig),
+                                      PCI_ADDRESS_SPACE_IO, vnetMap);
+    if (RT_FAILURE(rc))
+        return rc;
+
+
+    /* Register save/restore state handlers. */
+    rc = PDMDevHlpSSMRegisterEx(pDevIns, VIRTIO_SAVEDSTATE_VERSION, sizeof(VNETSTATE), NULL,
+                                NULL,         vnetLiveExec, NULL,
+                                vnetSavePrep, vnetSaveExec, NULL,
+                                vnetLoadPrep, vnetLoadExec, vnetLoadDone);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    /* Create the RX notifier signaller. */
+    rc = PDMDevHlpPDMQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 1, 0,
+                                 vnetCanRxQueueConsumer, true, "VNet-Rcv", &pState->pCanRxQueueR3);
+    if (RT_FAILURE(rc))
+        return rc;
+    pState->pCanRxQueueR0 = PDMQueueR0Ptr(pState->pCanRxQueueR3);
+    pState->pCanRxQueueRC = PDMQueueRCPtr(pState->pCanRxQueueR3);
+
+    /* Create Link Up Timer */
+    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetLinkUpTimer, pState,
+                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
+                                "VirtioNet Link Up Timer", &pState->pLinkUpTimer);
+    if (RT_FAILURE(rc))
+        return rc;
+
+#ifdef VNET_TX_DELAY
+    /* Create Transmit Delay Timer */
+    rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, vnetTxTimer, pState,
+                                TMTIMER_FLAGS_DEFAULT_CRIT_SECT, /** @todo check locking here. */
+                                "VirtioNet TX Delay Timer", &pState->pTxTimerR3);
+    if (RT_FAILURE(rc))
+        return rc;
+    pState->pTxTimerR0 = TMTimerR0Ptr(pState->pTxTimerR3);
+    pState->pTxTimerRC = TMTimerRCPtr(pState->pTxTimerR3);
+
+    pState->u32i = pState->u32AvgDiff = pState->u32MaxDiff = 0;
+    pState->u32MinDiff = ~0;
+#endif /* VNET_TX_DELAY */
+
+    rc = PDMDevHlpDriverAttach(pDevIns, 0, &pState->VPCI.IBase, &pState->pDrvBase, "Network Port");
+    if (RT_SUCCESS(rc))
+    {
+        if (rc == VINF_NAT_DNS)
+        {
+            PDMDevHlpVMSetRuntimeError(pDevIns, 0 /*fFlags*/, "NoDNSforNAT",
+                                       N_("A Domain Name Server (DNS) for NAT networking could not be determined. Ensure that your host is correctly connected to an ISP. If you ignore this warning the guest will not be able to perform nameserver lookups and it will probably observe delays if trying so"));
+        }
+        pState->pDrv = PDMIBASE_QUERY_INTERFACE(pState->pDrvBase, PDMINETWORKCONNECTOR);
+        AssertMsgReturn(pState->pDrv, ("Failed to obtain the PDMINETWORKCONNECTOR interface!\n"),
+                        VERR_PDM_MISSING_INTERFACE_BELOW);
+    }
+    else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
+    {
+        Log(("%s This adapter is not attached to any network!\n", INSTANCE(pState)));
+    }
+    else
+        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach the network LUN"));
+
+    rc = RTSemEventCreate(&pState->hEventMoreRxDescAvail);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    vnetReset(pState);
+
+    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveBytes,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data received",            "/Devices/VNet%d/ReceiveBytes", iInstance);
+    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitBytes,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,          "Amount of data transmitted",         "/Devices/VNet%d/TransmitBytes", iInstance);
+#if defined(VBOX_WITH_STATISTICS)
+    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceive,            STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive",                  "/Devices/VNet%d/Receive/Total", iInstance);
+    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatReceiveStore,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive storing",          "/Devices/VNet%d/Receive/Store", iInstance);
+    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflow,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling RX overflows",        "/Devices/VNet%d/RxOverflow", iInstance);
+    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatRxOverflowWakeup,   STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES,     "Nr of RX overflow wakeups",          "/Devices/VNet%d/RxOverflowWakeup", iInstance);
+    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmit,           STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in HC",          "/Devices/VNet%d/Transmit/Total", iInstance);
+    PDMDevHlpSTAMRegisterF(pDevIns, &pState->StatTransmitSend,       STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling send transmit in HC",      "/Devices/VNet%d/Transmit/Send", iInstance);
+#endif /* VBOX_WITH_STATISTICS */
+
+    return VINF_SUCCESS;
 }
 
Index: /trunk/src/VBox/Devices/Network/DrvIntNet.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DrvIntNet.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Network/DrvIntNet.cpp	(revision 26001)
@@ -711,4 +711,5 @@
     LogFlow(("drvR3IntNetDestruct\n"));
     PDRVINTNET pThis = PDMINS_2_DATA(pDrvIns, PDRVINTNET);
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
 
     /*
@@ -778,4 +779,5 @@
     PDRVINTNET pThis = PDMINS_2_DATA(pDrvIns, PDRVINTNET);
     bool f;
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/Network/DrvNAT.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DrvNAT.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Network/DrvNAT.cpp	(revision 26001)
@@ -947,6 +947,6 @@
 {
     PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
-
     LogFlow(("drvNATDestruct:\n"));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
 
     slirp_term(pThis->pNATState);
@@ -969,6 +969,6 @@
 {
     PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
-
     LogFlow(("drvNATConstruct:\n"));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/Network/DrvNetSniffer.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DrvNetSniffer.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Network/DrvNetSniffer.cpp	(revision 26001)
@@ -332,4 +332,5 @@
 {
     PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
 
     if (RTCritSectIsInitialized(&pThis->Lock))
@@ -353,4 +354,5 @@
     PDRVNETSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVNETSNIFFER);
     LogFlow(("drvNetSnifferConstruct:\n"));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/Network/DrvTAP.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DrvTAP.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Network/DrvTAP.cpp	(revision 26001)
@@ -775,4 +775,5 @@
 #endif  /* RT_OS_SOLARIS */
 
+/* -=-=-=-=- PDMIBASE -=-=-=-=- */
 
 /**
@@ -789,4 +790,5 @@
 }
 
+/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
 
 /**
@@ -802,4 +804,5 @@
     LogFlow(("drvTAPDestruct\n"));
     PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
 
     /*
@@ -879,4 +882,5 @@
 {
     PDRVTAP pThis = PDMINS_2_DATA(pDrvIns, PDRVTAP);
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/PC/DevACPI.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 26001)
@@ -2266,4 +2266,5 @@
     ACPIState *s   = PDMINS_2_DATA(pDevIns, ACPIState *);
     PCIDevice *dev = &s->dev;
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /* Validate and read the configuration. */
@@ -2399,6 +2400,6 @@
     s->uPmIoPortBase = PM_PORT_BASE;
 
-    /* 
-     * FDC and SMC try to use the same non-shareable interrupt (6), 
+    /*
+     * FDC and SMC try to use the same non-shareable interrupt (6),
      * enable only one device.
      */
Index: /trunk/src/VBox/Devices/PC/DevPcBios.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevPcBios.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/PC/DevPcBios.cpp	(revision 26001)
@@ -797,4 +797,5 @@
     PDEVPCBIOS  pThis = PDMINS_2_DATA(pDevIns, PDEVPCBIOS);
     LogFlow(("pcbiosDestruct:\n"));
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
 
     /*
@@ -887,4 +888,5 @@
 
     Assert(iInstance == 0);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
Index: /trunk/src/VBox/Devices/PC/DrvACPI.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DrvACPI.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/PC/DrvACPI.cpp	(revision 26001)
@@ -712,4 +712,5 @@
 {
     LogFlow(("drvACPIDestruct\n"));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
 }
 
@@ -722,4 +723,5 @@
 {
     PDRVACPI pThis = PDMINS_2_DATA(pDrvIns, PDRVACPI);
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/PC/DrvAcpiCpu.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DrvAcpiCpu.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/PC/DrvAcpiCpu.cpp	(revision 26001)
@@ -55,4 +55,5 @@
 {
     LogFlow(("drvACPICpuDestruct\n"));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
 }
 
@@ -64,4 +65,6 @@
 static DECLCALLBACK(int) drvACPICpuConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
 {
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
+
     /*
      * Init the static parts.
Index: /trunk/src/VBox/Devices/Parallel/DevParallel.cpp
===================================================================
--- /trunk/src/VBox/Devices/Parallel/DevParallel.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Parallel/DevParallel.cpp	(revision 26001)
@@ -673,4 +673,5 @@
 {
     ParallelState *pThis = PDMINS_2_DATA(pDevIns, ParallelState *);
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
 
     PDMR3CritSectDelete(&pThis->CritSect);
@@ -702,4 +703,5 @@
 
     Assert(iInstance < 4);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
Index: /trunk/src/VBox/Devices/Parallel/DrvHostParallel.cpp
===================================================================
--- /trunk/src/VBox/Devices/Parallel/DrvHostParallel.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Parallel/DrvHostParallel.cpp	(revision 26001)
@@ -249,12 +249,49 @@
 
 /**
- * Construct a host parallel driver instance.
- *
- * @copydoc FNPDMDRVCONSTRUCT
- */
-static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
+ * Destruct a host parallel driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that
+ * any non-VM resources can be freed correctly.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvHostParallelDestruct(PPDMDRVINS pDrvIns)
 {
     PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
     LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
+    ioctl(pThis->FileDevice, PPRELEASE);
+
+    if (pThis->WakeupPipeW != NIL_RTFILE)
+    {
+        int rc = RTFileClose(pThis->WakeupPipeW);
+        AssertRC(rc);
+        pThis->WakeupPipeW = NIL_RTFILE;
+    }
+    if (pThis->WakeupPipeR != NIL_RTFILE)
+    {
+        int rc = RTFileClose(pThis->WakeupPipeR);
+        AssertRC(rc);
+        pThis->WakeupPipeR = NIL_RTFILE;
+    }
+    if (pThis->FileDevice != NIL_RTFILE)
+    {
+        int rc = RTFileClose(pThis->FileDevice);
+        AssertRC(rc);
+        pThis->FileDevice = NIL_RTFILE;
+    }
+}
+
+/**
+ * Construct a host parallel driver instance.
+ *
+ * @copydoc FNPDMDRVCONSTRUCT
+ */
+static DECLCALLBACK(int) drvHostParallelConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
+{
+    PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
+    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
@@ -348,41 +385,4 @@
 
     return VINF_SUCCESS;
-}
-
-
-/**
- * Destruct a host parallel driver instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that
- * any non-VM resources can be freed correctly.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvHostParallelDestruct(PPDMDRVINS pDrvIns)
-{
-    PDRVHOSTPARALLEL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTPARALLEL);
-
-    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
-
-    ioctl(pThis->FileDevice, PPRELEASE);
-
-    if (pThis->WakeupPipeW != NIL_RTFILE)
-    {
-        int rc = RTFileClose(pThis->WakeupPipeW);
-        AssertRC(rc);
-        pThis->WakeupPipeW = NIL_RTFILE;
-    }
-    if (pThis->WakeupPipeR != NIL_RTFILE)
-    {
-        int rc = RTFileClose(pThis->WakeupPipeR);
-        AssertRC(rc);
-        pThis->WakeupPipeR = NIL_RTFILE;
-    }
-    if (pThis->FileDevice != NIL_RTFILE)
-    {
-        int rc = RTFileClose(pThis->FileDevice);
-        AssertRC(rc);
-        pThis->FileDevice = NIL_RTFILE;
-    }
 }
 
Index: /trunk/src/VBox/Devices/Serial/DevSerial.cpp
===================================================================
--- /trunk/src/VBox/Devices/Serial/DevSerial.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Serial/DevSerial.cpp	(revision 26001)
@@ -755,4 +755,5 @@
 {
     SerialState *pThis = PDMINS_2_DATA(pDevIns, SerialState *);
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
 
     RTSemEventDestroy(pThis->ReceiveSem);
@@ -787,4 +788,5 @@
 
     Assert(iInstance < 4);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
Index: /trunk/src/VBox/Devices/Serial/DrvChar.cpp
===================================================================
--- /trunk/src/VBox/Devices/Serial/DrvChar.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Serial/DrvChar.cpp	(revision 26001)
@@ -299,12 +299,51 @@
 
 /**
- * Construct a char driver instance.
- *
- * @copydoc FNPDMDRVCONSTRUCT
- */
-static DECLCALLBACK(int) drvCharConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
+ * Destruct a char driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that
+ * any non-VM resources can be freed correctly.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvCharDestruct(PPDMDRVINS pDrvIns)
 {
     PDRVCHAR pThis = PDMINS_2_DATA(pDrvIns, PDRVCHAR);
     LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
+    pThis->fShutdown = true;
+    if (pThis->ReceiveThread)
+    {
+        RTThreadWait(pThis->ReceiveThread, 1000, NULL);
+        if (pThis->ReceiveThread != NIL_RTTHREAD)
+            LogRel(("Char%d: receive thread did not terminate\n", pDrvIns->iInstance));
+    }
+
+    /* Empty the send queue */
+    pThis->iSendQueueTail = pThis->iSendQueueHead = 0;
+
+    RTSemEventSignal(pThis->SendSem);
+    RTSemEventDestroy(pThis->SendSem);
+    pThis->SendSem = NIL_RTSEMEVENT;
+
+    if (pThis->SendThread)
+    {
+        RTThreadWait(pThis->SendThread, 1000, NULL);
+        if (pThis->SendThread != NIL_RTTHREAD)
+            LogRel(("Char%d: send thread did not terminate\n", pDrvIns->iInstance));
+    }
+}
+
+
+/**
+ * Construct a char driver instance.
+ *
+ * @copydoc FNPDMDRVCONSTRUCT
+ */
+static DECLCALLBACK(int) drvCharConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
+{
+    PDRVCHAR pThis = PDMINS_2_DATA(pDrvIns, PDRVCHAR);
+    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
@@ -363,41 +402,4 @@
 }
 
-
-/**
- * Destruct a char driver instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that
- * any non-VM resources can be freed correctly.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvCharDestruct(PPDMDRVINS pDrvIns)
-{
-    PDRVCHAR     pThis = PDMINS_2_DATA(pDrvIns, PDRVCHAR);
-
-    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
-
-    pThis->fShutdown = true;
-    if (pThis->ReceiveThread)
-    {
-        RTThreadWait(pThis->ReceiveThread, 1000, NULL);
-        if (pThis->ReceiveThread != NIL_RTTHREAD)
-            LogRel(("Char%d: receive thread did not terminate\n", pDrvIns->iInstance));
-    }
-
-    /* Empty the send queue */
-    pThis->iSendQueueTail = pThis->iSendQueueHead = 0;
-
-    RTSemEventSignal(pThis->SendSem);
-    RTSemEventDestroy(pThis->SendSem);
-    pThis->SendSem = NIL_RTSEMEVENT;
-
-    if (pThis->SendThread)
-    {
-        RTThreadWait(pThis->SendThread, 1000, NULL);
-        if (pThis->SendThread != NIL_RTTHREAD)
-            LogRel(("Char%d: send thread did not terminate\n", pDrvIns->iInstance));
-    }
-}
 
 /**
Index: /trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp
===================================================================
--- /trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp	(revision 26001)
@@ -1203,4 +1203,66 @@
 
 /**
+ * Destruct a char driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that
+ * any non-VM resources can be freed correctly.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvHostSerialDestruct(PPDMDRVINS pDrvIns)
+{
+    PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
+    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
+    /* Empty the send queue */
+    pThis->iSendQueueTail = pThis->iSendQueueHead = 0;
+
+    RTSemEventDestroy(pThis->SendSem);
+    pThis->SendSem = NIL_RTSEMEVENT;
+
+#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
+
+    if (pThis->WakeupPipeW != NIL_RTFILE)
+    {
+        int rc = RTFileClose(pThis->WakeupPipeW);
+        AssertRC(rc);
+        pThis->WakeupPipeW = NIL_RTFILE;
+    }
+    if (pThis->WakeupPipeR != NIL_RTFILE)
+    {
+        int rc = RTFileClose(pThis->WakeupPipeR);
+        AssertRC(rc);
+        pThis->WakeupPipeR = NIL_RTFILE;
+    }
+# if defined(RT_OS_DARWIN)
+    if (pThis->DeviceFileR != NIL_RTFILE)
+    {
+        if (pThis->DeviceFileR != pThis->DeviceFile)
+        {
+            int rc = RTFileClose(pThis->DeviceFileR);
+            AssertRC(rc);
+        }
+        pThis->DeviceFileR = NIL_RTFILE;
+    }
+# endif
+    if (pThis->DeviceFile != NIL_RTFILE)
+    {
+        int rc = RTFileClose(pThis->DeviceFile);
+        AssertRC(rc);
+        pThis->DeviceFile = NIL_RTFILE;
+    }
+
+#elif defined(RT_OS_WINDOWS)
+
+    CloseHandle(pThis->hEventRecv);
+    CloseHandle(pThis->hEventSend);
+    CancelIo(pThis->hDeviceFile);
+    CloseHandle(pThis->hDeviceFile);
+
+#endif
+}
+
+/**
  * Construct a char driver instance.
  *
@@ -1211,4 +1273,5 @@
     PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
     LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
@@ -1387,67 +1450,4 @@
 
     return VINF_SUCCESS;
-}
-
-
-/**
- * Destruct a char driver instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that
- * any non-VM resources can be freed correctly.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvHostSerialDestruct(PPDMDRVINS pDrvIns)
-{
-    PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
-
-    LogFlow(("%s: iInstance=%d\n", __FUNCTION__, pDrvIns->iInstance));
-
-    /* Empty the send queue */
-    pThis->iSendQueueTail = pThis->iSendQueueHead = 0;
-
-    RTSemEventDestroy(pThis->SendSem);
-    pThis->SendSem = NIL_RTSEMEVENT;
-
-#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
-
-    if (pThis->WakeupPipeW != NIL_RTFILE)
-    {
-        int rc = RTFileClose(pThis->WakeupPipeW);
-        AssertRC(rc);
-        pThis->WakeupPipeW = NIL_RTFILE;
-    }
-    if (pThis->WakeupPipeR != NIL_RTFILE)
-    {
-        int rc = RTFileClose(pThis->WakeupPipeR);
-        AssertRC(rc);
-        pThis->WakeupPipeR = NIL_RTFILE;
-    }
-# if defined(RT_OS_DARWIN)
-    if (pThis->DeviceFileR != NIL_RTFILE)
-    {
-        if (pThis->DeviceFileR != pThis->DeviceFile)
-        {
-            int rc = RTFileClose(pThis->DeviceFileR);
-            AssertRC(rc);
-        }
-        pThis->DeviceFileR = NIL_RTFILE;
-    }
-# endif
-    if (pThis->DeviceFile != NIL_RTFILE)
-    {
-        int rc = RTFileClose(pThis->DeviceFile);
-        AssertRC(rc);
-        pThis->DeviceFile = NIL_RTFILE;
-    }
-
-#elif defined(RT_OS_WINDOWS)
-
-    CloseHandle(pThis->hEventRecv);
-    CloseHandle(pThis->hEventSend);
-    CancelIo(pThis->hDeviceFile);
-    CloseHandle(pThis->hDeviceFile);
-
-#endif
 }
 
Index: /trunk/src/VBox/Devices/Serial/DrvNamedPipe.cpp
===================================================================
--- /trunk/src/VBox/Devices/Serial/DrvNamedPipe.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Serial/DrvNamedPipe.cpp	(revision 26001)
@@ -383,4 +383,81 @@
 }
 
+/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
+
+/**
+ * Power off a named pipe stream driver instance.
+ *
+ * This does most of the destruction work, to avoid ordering dependencies.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvNamedPipePowerOff(PPDMDRVINS pDrvIns)
+{
+    PDRVNAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);
+    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
+
+    pThis->fShutdown = true;
+
+#ifdef RT_OS_WINDOWS
+    if (pThis->NamedPipe != INVALID_HANDLE_VALUE)
+    {
+        if (pThis->fIsServer)
+        {
+            FlushFileBuffers(pThis->NamedPipe);
+            DisconnectNamedPipe(pThis->NamedPipe);
+        }
+
+        CloseHandle(pThis->NamedPipe);
+        pThis->NamedPipe = INVALID_HANDLE_VALUE;
+        CloseHandle(pThis->OverlappedRead.hEvent);
+        CloseHandle(pThis->OverlappedWrite.hEvent);
+    }
+    if (pThis->fIsServer)
+    {
+        /* Wake up listen thread */
+        RTSemEventSignal(pThis->ListenSem);
+        RTSemEventDestroy(pThis->ListenSem);
+    }
+#else /* !RT_OS_WINDOWS */
+    if (pThis->fIsServer)
+    {
+        if (pThis->LocalSocketServer != NIL_RTSOCKET)
+            close(pThis->LocalSocketServer);
+        if (pThis->pszLocation)
+            RTFileDelete(pThis->pszLocation);
+    }
+    else
+    {
+        if (pThis->LocalSocket != NIL_RTSOCKET)
+            close(pThis->LocalSocket);
+    }
+#endif /* !RT_OS_WINDOWS */
+}
+
+
+/**
+ * Destruct a named pipe stream driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that
+ * any non-VM resources can be freed correctly.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvNamedPipeDestruct(PPDMDRVINS pDrvIns)
+{
+    PDRVNAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);
+    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
+    if (pThis->ListenThread)
+    {   RTThreadWait(pThis->ListenThread, 250, NULL);
+        if (pThis->ListenThread != NIL_RTTHREAD)
+            LogRel(("NamedPipe%d: listen thread did not terminate\n", pDrvIns->iInstance));
+    }
+
+    if (pThis->pszLocation)
+        MMR3HeapFree(pThis->pszLocation);
+}
+
 
 /**
@@ -394,4 +471,5 @@
     char *pszLocation = NULL;
     PDRVNAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
@@ -421,5 +499,5 @@
     {
         rc = VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
-        goto out;
+        goto l_out;
     }
 
@@ -428,5 +506,5 @@
     {
         AssertMsgFailed(("Configuration error: query \"Location\" resulted in %Rrc.\n", rc));
-        goto out;
+        goto l_out;
     }
     pThis->pszLocation = pszLocation;
@@ -437,5 +515,5 @@
     {
         AssertMsgFailed(("Configuration error: query \"IsServer\" resulted in %Rrc.\n", rc));
-        goto out;
+        goto l_out;
     }
     pThis->fIsServer = fIsServer;
@@ -509,5 +587,5 @@
 #endif /* !RT_OS_WINDOWS */
 
-out:
+l_out:
     if (RT_FAILURE(rc))
     {
@@ -520,80 +598,4 @@
     LogRel(("NamedPipe: location %s, %s\n", pszLocation, fIsServer ? "server" : "client"));
     return VINF_SUCCESS;
-}
-
-
-/**
- * Destruct a named pipe stream driver instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that
- * any non-VM resources can be freed correctly.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvNamedPipeDestruct(PPDMDRVINS pDrvIns)
-{
-    PDRVNAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);
-    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
-
-    if (pThis->ListenThread)
-    {
-        RTThreadWait(pThis->ListenThread, 250, NULL);
-        if (pThis->ListenThread != NIL_RTTHREAD)
-            LogRel(("NamedPipe%d: listen thread did not terminate\n", pDrvIns->iInstance));
-    }
-
-    if (pThis->pszLocation)
-        MMR3HeapFree(pThis->pszLocation);
-}
-
-
-/**
- * Power off a named pipe stream driver instance.
- *
- * This does most of the destruction work, to avoid ordering dependencies.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvNamedPipePowerOff(PPDMDRVINS pDrvIns)
-{
-    PDRVNAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);
-    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
-
-    pThis->fShutdown = true;
-
-#ifdef RT_OS_WINDOWS
-    if (pThis->NamedPipe != INVALID_HANDLE_VALUE)
-    {
-        if (pThis->fIsServer)
-        {
-            FlushFileBuffers(pThis->NamedPipe);
-            DisconnectNamedPipe(pThis->NamedPipe);
-        }
-
-        CloseHandle(pThis->NamedPipe);
-        pThis->NamedPipe = INVALID_HANDLE_VALUE;
-        CloseHandle(pThis->OverlappedRead.hEvent);
-        CloseHandle(pThis->OverlappedWrite.hEvent);
-    }
-    if (pThis->fIsServer)
-    {
-        /* Wake up listen thread */
-        RTSemEventSignal(pThis->ListenSem);
-        RTSemEventDestroy(pThis->ListenSem);
-    }
-#else /* !RT_OS_WINDOWS */
-    if (pThis->fIsServer)
-    {
-        if (pThis->LocalSocketServer != NIL_RTSOCKET)
-            close(pThis->LocalSocketServer);
-        if (pThis->pszLocation)
-            RTFileDelete(pThis->pszLocation);
-    }
-    else
-    {
-        if (pThis->LocalSocket != NIL_RTSOCKET)
-            close(pThis->LocalSocket);
-    }
-#endif /* !RT_OS_WINDOWS */
 }
 
Index: /trunk/src/VBox/Devices/Serial/DrvRawFile.cpp
===================================================================
--- /trunk/src/VBox/Devices/Serial/DrvRawFile.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Serial/DrvRawFile.cpp	(revision 26001)
@@ -69,4 +69,5 @@
 
 
+/* -=-=-=-=- PDMISTREAM -=-=-=-=- */
 
 /** @copydoc PDMISTREAM::pfnWrite */
@@ -94,4 +95,5 @@
 }
 
+/* -=-=-=-=- PDMIBASE -=-=-=-=- */
 
 /**
@@ -108,4 +110,51 @@
 }
 
+/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
+
+
+/**
+ * Power off a raw output stream driver instance.
+ *
+ * This does most of the destruction work, to avoid ordering dependencies.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvRawFilePowerOff(PPDMDRVINS pDrvIns)
+{
+    PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
+    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
+
+    if (pThis->OutputFile != NIL_RTFILE)
+    {
+        RTFileClose(pThis->OutputFile);
+        pThis->OutputFile = NIL_RTFILE;
+    }
+}
+
+
+/**
+ * Destruct a raw output stream driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that
+ * any non-VM resources can be freed correctly.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvRawFileDestruct(PPDMDRVINS pDrvIns)
+{
+    PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
+    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
+    if (pThis->pszLocation)
+        MMR3HeapFree(pThis->pszLocation);
+
+    if (pThis->OutputFile != NIL_RTFILE)
+    {
+        RTFileClose(pThis->OutputFile);
+        pThis->OutputFile = NIL_RTFILE;
+    }
+}
+
 
 /**
@@ -117,4 +166,5 @@
 {
     PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
@@ -152,48 +202,4 @@
     LogRel(("RawFile#%u: location %s\n", pDrvIns->iInstance, pThis->pszLocation));
     return VINF_SUCCESS;
-}
-
-
-/**
- * Destruct a raw output stream driver instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that
- * any non-VM resources can be freed correctly.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvRawFileDestruct(PPDMDRVINS pDrvIns)
-{
-    PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
-    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
-
-    if (pThis->pszLocation)
-        MMR3HeapFree(pThis->pszLocation);
-
-    if (pThis->OutputFile != NIL_RTFILE)
-    {
-        RTFileClose(pThis->OutputFile);
-        pThis->OutputFile = NIL_RTFILE;
-    }
-}
-
-
-/**
- * Power off a raw output stream driver instance.
- *
- * This does most of the destruction work, to avoid ordering dependencies.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvRawFilePowerOff(PPDMDRVINS pDrvIns)
-{
-    PDRVRAWFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWFILE);
-    LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation));
-
-    if (pThis->OutputFile != NIL_RTFILE)
-    {
-        RTFileClose(pThis->OutputFile);
-        pThis->OutputFile = NIL_RTFILE;
-    }
 }
 
Index: /trunk/src/VBox/Devices/Storage/DevAHCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevAHCI.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/DevAHCI.cpp	(revision 26001)
@@ -6059,7 +6059,8 @@
 static DECLCALLBACK(int) ahciR3Destruct(PPDMDEVINS pDevIns)
 {
-    PAHCI pAhci = PDMINS_2_DATA(pDevIns, PAHCI);
-    int rc = VINF_SUCCESS;
-    unsigned iActPort = 0;
+    PAHCI       pAhci    = PDMINS_2_DATA(pDevIns, PAHCI);
+    int         rc       = VINF_SUCCESS;
+    unsigned    iActPort = 0;
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
 
     /*
@@ -6479,4 +6480,5 @@
     bool       fR0Enabled = false;
     uint32_t   cbTotalBufferSize = 0;
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
Index: /trunk/src/VBox/Devices/Storage/DevATA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 26001)
@@ -1158,5 +1158,5 @@
       count--;
     }
-           
+
     return (uint8_t)-(int32_t)sum;
 }
@@ -1314,14 +1314,14 @@
     p[93] = RT_H2LE_U16((1 | 1 << 1) << ((s->iLUN & 1) == 0 ? 0 : 8) | 1 << 13 | 1 << 14);
     /* According to ATAPI-5 spec:
-     * 
-     * The use of this word is optional. 
-     * If bits 7:0 of this word contain the signature A5h, bits 15:8 
+     *
+     * The use of this word is optional.
+     * If bits 7:0 of this word contain the signature A5h, bits 15:8
      * contain the data
-     * structure checksum. 
-     * The data structure checksum is the twos complement of the sum of 
-     * all bytes in words 0 through 254 and the byte consisting of 
-     * bits 7:0 in word 255. 
-     * Each byte shall be added with unsigned arithmetic, 
-     * and overflow shall be ignored. 
+     * structure checksum.
+     * The data structure checksum is the twos complement of the sum of
+     * all bytes in words 0 through 254 and the byte consisting of
+     * bits 7:0 in word 255.
+     * Each byte shall be added with unsigned arithmetic,
+     * and overflow shall be ignored.
      * The sum of all 512 bytes is zero when the checksum is correct.
      */
@@ -5582,4 +5582,5 @@
 
     Log(("ataR3Destruct\n"));
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
 
     /*
@@ -6526,4 +6527,5 @@
 
     Assert(iInstance == 0);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
Index: /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp	(revision 26001)
@@ -2508,8 +2508,8 @@
 static DECLCALLBACK(int) buslogicDestruct(PPDMDEVINS pDevIns)
 {
-    int rc = VINF_SUCCESS;
     PBUSLOGIC  pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
-
-    rc = RTCacheDestroy(pThis->pTaskCache);
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
+
+    int rc = RTCacheDestroy(pThis->pTaskCache);
     AssertMsgRC(rc, ("Destroying task cache failed rc=%Rrc\n", rc));
 
@@ -2534,4 +2534,5 @@
     PBUSLOGIC  pThis = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
     int        rc = VINF_SUCCESS;
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
Index: /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 26001)
@@ -4354,5 +4354,5 @@
 {
     PLSILOGICSCSI pThis = PDMINS_2_DATA(pDevIns, PLSILOGICSCSI);
-    int rc = VINF_SUCCESS;
+    PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
 
     PDMR3CritSectDelete(&pThis->ReplyFreeQueueCritSect);
@@ -4363,4 +4363,5 @@
 
     /* Destroy task cache. */
+    int rc = VINF_SUCCESS;
     if (pThis->pTaskCache)
         rc = RTCacheDestroy(pThis->pTaskCache);
@@ -4380,4 +4381,5 @@
     char *pszCtrlType = NULL;
     PVM pVM = PDMDevHlpGetVM(pDevIns);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
Index: /trunk/src/VBox/Devices/Storage/DrvBlock.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DrvBlock.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/DrvBlock.cpp	(revision 26001)
@@ -701,4 +701,5 @@
     PDRVBLOCK pThis = PDMINS_2_DATA(pDrvIns, PDRVBLOCK);
     LogFlow(("drvblockConstruct: iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/Storage/DrvMediaISO.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DrvMediaISO.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/DrvMediaISO.cpp	(revision 26001)
@@ -69,21 +69,159 @@
 
 
-/*******************************************************************************
-*   Internal Functions                                                         *
-*******************************************************************************/
-static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead);
-static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite);
-static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface);
-static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface);
-static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface);
-static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid);
-static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry);
-static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry);
-static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry);
-static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry);
-
-static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, const char *pszIID);
-
-
+/* -=-=-=-=- PDMIMEDIA -=-=-=-=- */
+
+/** @copydoc PDMIMEDIA::pfnGetSize */
+static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface)
+{
+    PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
+    LogFlow(("drvMediaISOGetSize: '%s'\n", pThis->pszFilename));
+
+    uint64_t cbFile;
+    int rc = RTFileGetSize(pThis->File, &cbFile);
+    if (RT_SUCCESS(rc))
+    {
+        LogFlow(("drvMediaISOGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
+        return cbFile;
+    }
+
+    AssertMsgFailed(("Error querying ISO file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
+    return 0;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
+static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
+static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
+static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
+static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * Read bits.
+ *
+ * @see PDMIMEDIA::pfnRead for details.
+ */
+static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
+{
+    PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
+    LogFlow(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
+
+    Assert(pThis->File);
+    Assert(pvBuf);
+
+    /*
+     * Seek to the position and read.
+     */
+    int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
+        if (RT_SUCCESS(rc))
+        {
+            Log2(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
+                  "%16.*Rhxd\n",
+                  off, pvBuf, cbRead, pThis->pszFilename,
+                  cbRead, pvBuf));
+        }
+        else
+            AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
+                             pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
+    }
+    else
+        AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
+    LogFlow(("drvMediaISORead: returns %Rrc\n", rc));
+    return rc;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnWrite */
+static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
+{
+    AssertMsgFailed(("Attempt to write to an ISO file!\n"));
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnFlush */
+static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface)
+{
+    /* No buffered data that still needs to be written. */
+    return VINF_SUCCESS;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnGetUuid */
+static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
+{
+    LogFlow(("drvMediaISOGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnIsReadOnly */
+static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface)
+{
+    return true;
+}
+
+/* -=-=-=-=- PDMIBASE -=-=-=-=- */
+
+/**
+ * @interface_method_impl{PDMIBASE,pfnQueryInterface}
+ */
+static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, const char *pszIID)
+{
+    PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
+    PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
+    return NULL;
+}
+
+/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
+
+/**
+ * Destruct a driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that any non-VM
+ * resources can be freed correctly.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvMediaISODestruct(PPDMDRVINS pDrvIns)
+{
+    PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
+    LogFlow(("drvMediaISODestruct: '%s'\n", pThis->pszFilename));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
+    if (pThis->File != NIL_RTFILE)
+    {
+        RTFileClose(pThis->File);
+        pThis->File = NIL_RTFILE;
+    }
+    if (pThis->pszFilename)
+        MMR3HeapFree(pThis->pszFilename);
+}
 
 
@@ -96,4 +234,5 @@
 {
     PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
@@ -144,156 +283,4 @@
 
     return rc;
-}
-
-
-/**
- * Destruct a driver instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that any non-VM
- * resources can be freed correctly.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvMediaISODestruct(PPDMDRVINS pDrvIns)
-{
-    PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
-    LogFlow(("drvMediaISODestruct: '%s'\n", pThis->pszFilename));
-
-    if (pThis->File != NIL_RTFILE)
-    {
-        RTFileClose(pThis->File);
-        pThis->File = NIL_RTFILE;
-    }
-    if (pThis->pszFilename)
-        MMR3HeapFree(pThis->pszFilename);
-}
-
-
-/** @copydoc PDMIMEDIA::pfnGetSize */
-static DECLCALLBACK(uint64_t) drvMediaISOGetSize(PPDMIMEDIA pInterface)
-{
-    PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
-    LogFlow(("drvMediaISOGetSize: '%s'\n", pThis->pszFilename));
-
-    uint64_t cbFile;
-    int rc = RTFileGetSize(pThis->File, &cbFile);
-    if (RT_SUCCESS(rc))
-    {
-        LogFlow(("drvMediaISOGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
-        return cbFile;
-    }
-
-    AssertMsgFailed(("Error querying ISO file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
-    return 0;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
-static DECLCALLBACK(int) drvMediaISOBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
-static DECLCALLBACK(int) drvMediaISOBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
-static DECLCALLBACK(int) drvMediaISOBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
-static DECLCALLBACK(int) drvMediaISOBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/**
- * Read bits.
- *
- * @see PDMIMEDIA::pfnRead for details.
- */
-static DECLCALLBACK(int) drvMediaISORead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
-{
-    PDRVMEDIAISO pThis = PDMIMEDIA_2_DRVMEDIAISO(pInterface);
-    LogFlow(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
-
-    Assert(pThis->File);
-    Assert(pvBuf);
-
-    /*
-     * Seek to the position and read.
-     */
-    int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
-        if (RT_SUCCESS(rc))
-        {
-            Log2(("drvMediaISORead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
-                  "%16.*Rhxd\n",
-                  off, pvBuf, cbRead, pThis->pszFilename,
-                  cbRead, pvBuf));
-        }
-        else
-            AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
-                             pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
-    }
-    else
-        AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
-    LogFlow(("drvMediaISORead: returns %Rrc\n", rc));
-    return rc;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnWrite */
-static DECLCALLBACK(int) drvMediaISOWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
-{
-    AssertMsgFailed(("Attempt to write to an ISO file!\n"));
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnFlush */
-static DECLCALLBACK(int) drvMediaISOFlush(PPDMIMEDIA pInterface)
-{
-    /* No buffered data that still needs to be written. */
-    return VINF_SUCCESS;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnGetUuid */
-static DECLCALLBACK(int) drvMediaISOGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
-{
-    LogFlow(("drvMediaISOGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnIsReadOnly */
-static DECLCALLBACK(bool) drvMediaISOIsReadOnly(PPDMIMEDIA pInterface)
-{
-    return true;
-}
-
-
-/**
- * @interface_method_impl{PDMIBASE,pfnQueryInterface}
- */
-static DECLCALLBACK(void *) drvMediaISOQueryInterface(PPDMIBASE pInterface, const char *pszIID)
-{
-    PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
-    PDRVMEDIAISO pThis = PDMINS_2_DATA(pDrvIns, PDRVMEDIAISO);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
-    return NULL;
 }
 
Index: /trunk/src/VBox/Devices/Storage/DrvRawImage.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DrvRawImage.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/DrvRawImage.cpp	(revision 26001)
@@ -72,21 +72,193 @@
 
 
-/*******************************************************************************
-*   Internal Functions                                                         *
-*******************************************************************************/
-static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead);
-static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite);
-static DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface);
-static DECLCALLBACK(bool) drvRawImageIsReadOnly(PPDMIMEDIA pInterface);
-static DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface);
-static DECLCALLBACK(int) drvRawImageGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid);
-static DECLCALLBACK(int) drvRawImageBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry);
-static DECLCALLBACK(int) drvRawImageBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry);
-static DECLCALLBACK(int) drvRawImageBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry);
-static DECLCALLBACK(int) drvRawImageBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry);
-
-static DECLCALLBACK(void *) drvRawImageQueryInterface(PPDMIBASE pInterface, const char *pszIID);
-
-
+/* -=-=-=-=- PDMIMEDIA -=-=-=-=- */
+
+/** @copydoc PDMIMEDIA::pfnGetSize */
+static DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface)
+{
+    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
+    LogFlow(("drvRawImageGetSize: '%s'\n", pThis->pszFilename));
+
+    uint64_t cbFile;
+    int rc = RTFileGetSize(pThis->File, &cbFile);
+    if (RT_SUCCESS(rc))
+    {
+        LogFlow(("drvRawImageGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
+        return cbFile;
+    }
+
+    AssertMsgFailed(("Error querying Raw image file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
+    return 0;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
+static DECLCALLBACK(int) drvRawImageBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
+static DECLCALLBACK(int) drvRawImageBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
+static DECLCALLBACK(int) drvRawImageBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
+static DECLCALLBACK(int) drvRawImageBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/**
+ * Read bits.
+ *
+ * @see PDMIMEDIA::pfnRead for details.
+ */
+static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
+{
+    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
+    LogFlow(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
+
+    Assert(pThis->File);
+    Assert(pvBuf);
+
+    /*
+     * Seek to the position and read.
+     */
+    int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
+        if (RT_SUCCESS(rc))
+        {
+            Log2(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
+                  "%16.*Rhxd\n",
+                  off, pvBuf, cbRead, pThis->pszFilename,
+                  cbRead, pvBuf));
+        }
+        else
+            AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
+                             pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
+    }
+    else
+        AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
+    LogFlow(("drvRawImageRead: returns %Rrc\n", rc));
+    return rc;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnWrite */
+static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
+{
+    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
+    LogFlow(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n", off, pvBuf, cbWrite, pThis->pszFilename));
+
+    Assert(pThis->File);
+    Assert(pvBuf);
+
+    /*
+     * Seek to the position and write.
+     */
+    int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
+    if (RT_SUCCESS(rc))
+    {
+        rc = RTFileWrite(pThis->File, pvBuf, cbWrite, NULL);
+        if (RT_SUCCESS(rc))
+        {
+            Log2(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n"
+                  "%16.*Rhxd\n",
+                  off, pvBuf, cbWrite, pThis->pszFilename,
+                  cbWrite, pvBuf));
+        }
+        else
+            AssertMsgFailed(("RTFileWrite(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
+                             pThis->File, pvBuf, cbWrite, rc, off, pThis->pszFilename));
+    }
+    else
+        AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
+    LogFlow(("drvRawImageWrite: returns %Rrc\n", rc));
+    return rc;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnFlush */
+static DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface)
+{
+    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
+    LogFlow(("drvRawImageFlush: (%s)\n", pThis->pszFilename));
+
+    Assert(pThis->File != NIL_RTFILE);
+    int rc = RTFileFlush(pThis->File);
+    LogFlow(("drvRawImageFlush: returns %Rrc\n", rc));
+    return rc;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnGetUuid */
+static DECLCALLBACK(int) drvRawImageGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
+{
+    LogFlow(("drvRawImageGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @copydoc PDMIMEDIA::pfnIsReadOnly */
+static DECLCALLBACK(bool) drvRawImageIsReadOnly(PPDMIMEDIA pInterface)
+{
+    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
+    return pThis->fReadOnly;
+}
+
+
+/* -=-=-=-=- PDMIBASE -=-=-=-=- */
+
+/**
+ * @interface_method_impl{PDMIBASE,pfnQueryInterface}
+ */
+static DECLCALLBACK(void *) drvRawImageQueryInterface(PPDMIBASE pInterface, const char *pszIID)
+{
+    PPDMDRVINS      pDrvIns = PDMIBASE_2_DRVINS(pInterface);
+    PDRVRAWIMAGE    pThis   = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
+
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
+    return NULL;
+}
+
+/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
+
+/**
+ * Destruct a driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that any non-VM
+ * resources can be freed correctly.
+ *
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) drvRawImageDestruct(PPDMDRVINS pDrvIns)
+{
+    PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
+    LogFlow(("drvRawImageDestruct: '%s'\n", pThis->pszFilename));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
+    if (pThis->File != NIL_RTFILE)
+    {
+        RTFileClose(pThis->File);
+        pThis->File = NIL_RTFILE;
+    }
+    if (pThis->pszFilename)
+        MMR3HeapFree(pThis->pszFilename);
+}
 
 
@@ -99,4 +271,5 @@
 {
     PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
@@ -162,189 +335,4 @@
 
     return rc;
-}
-
-
-/**
- * Destruct a driver instance.
- *
- * Most VM resources are freed by the VM. This callback is provided so that any non-VM
- * resources can be freed correctly.
- *
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) drvRawImageDestruct(PPDMDRVINS pDrvIns)
-{
-    PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
-    LogFlow(("drvRawImageDestruct: '%s'\n", pThis->pszFilename));
-
-    if (pThis->File != NIL_RTFILE)
-    {
-        RTFileClose(pThis->File);
-        pThis->File = NIL_RTFILE;
-    }
-    if (pThis->pszFilename)
-        MMR3HeapFree(pThis->pszFilename);
-}
-
-
-/** @copydoc PDMIMEDIA::pfnGetSize */
-static DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface)
-{
-    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
-    LogFlow(("drvRawImageGetSize: '%s'\n", pThis->pszFilename));
-
-    uint64_t cbFile;
-    int rc = RTFileGetSize(pThis->File, &cbFile);
-    if (RT_SUCCESS(rc))
-    {
-        LogFlow(("drvRawImageGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
-        return cbFile;
-    }
-
-    AssertMsgFailed(("Error querying Raw image file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
-    return 0;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
-static DECLCALLBACK(int) drvRawImageBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
-static DECLCALLBACK(int) drvRawImageBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
-static DECLCALLBACK(int) drvRawImageBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
-static DECLCALLBACK(int) drvRawImageBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
-{
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/**
- * Read bits.
- *
- * @see PDMIMEDIA::pfnRead for details.
- */
-static DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
-{
-    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
-    LogFlow(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
-
-    Assert(pThis->File);
-    Assert(pvBuf);
-
-    /*
-     * Seek to the position and read.
-     */
-    int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTFileRead(pThis->File, pvBuf, cbRead, NULL);
-        if (RT_SUCCESS(rc))
-        {
-            Log2(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
-                  "%16.*Rhxd\n",
-                  off, pvBuf, cbRead, pThis->pszFilename,
-                  cbRead, pvBuf));
-        }
-        else
-            AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
-                             pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
-    }
-    else
-        AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
-    LogFlow(("drvRawImageRead: returns %Rrc\n", rc));
-    return rc;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnWrite */
-static DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
-{
-    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
-    LogFlow(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n", off, pvBuf, cbWrite, pThis->pszFilename));
-
-    Assert(pThis->File);
-    Assert(pvBuf);
-
-    /*
-     * Seek to the position and write.
-     */
-    int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTFileWrite(pThis->File, pvBuf, cbWrite, NULL);
-        if (RT_SUCCESS(rc))
-        {
-            Log2(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n"
-                  "%16.*Rhxd\n",
-                  off, pvBuf, cbWrite, pThis->pszFilename,
-                  cbWrite, pvBuf));
-        }
-        else
-            AssertMsgFailed(("RTFileWrite(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
-                             pThis->File, pvBuf, cbWrite, rc, off, pThis->pszFilename));
-    }
-    else
-        AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
-    LogFlow(("drvRawImageWrite: returns %Rrc\n", rc));
-    return rc;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnFlush */
-static DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface)
-{
-    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
-    LogFlow(("drvRawImageFlush: (%s)\n", pThis->pszFilename));
-
-    Assert(pThis->File != NIL_RTFILE);
-    int rc = RTFileFlush(pThis->File);
-    LogFlow(("drvRawImageFlush: returns %Rrc\n", rc));
-    return rc;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnGetUuid */
-static DECLCALLBACK(int) drvRawImageGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
-{
-    LogFlow(("drvRawImageGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
-    return VERR_NOT_IMPLEMENTED;
-}
-
-
-/** @copydoc PDMIMEDIA::pfnIsReadOnly */
-static DECLCALLBACK(bool) drvRawImageIsReadOnly(PPDMIMEDIA pInterface)
-{
-    PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
-    return pThis->fReadOnly;
-}
-
-
-/**
- * @interface_method_impl{PDMIBASE,pfnQueryInterface}
- */
-static DECLCALLBACK(void *) drvRawImageQueryInterface(PPDMIBASE pInterface, const char *pszIID)
-{
-    PPDMDRVINS      pDrvIns = PDMIBASE_2_DRVINS(pInterface);
-    PDRVRAWIMAGE    pThis   = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
-
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
-    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
-    return NULL;
 }
 
Index: /trunk/src/VBox/Devices/Storage/DrvSCSI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DrvSCSI.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/DrvSCSI.cpp	(revision 26001)
@@ -914,6 +914,6 @@
 static DECLCALLBACK(void) drvscsiDestruct(PPDMDRVINS pDrvIns)
 {
-    int rc;
     PDRVSCSI pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSI);
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
 
     if (pThis->pQueueRequests)
@@ -922,8 +922,7 @@
             LogRel(("drvscsiDestruct#%u: previous dummy request is still pending\n", pDrvIns->iInstance));
 
-        rc = RTReqDestroyQueue(pThis->pQueueRequests);
+        int rc = RTReqDestroyQueue(pThis->pQueueRequests);
         AssertMsgRC(rc, ("Failed to destroy queue rc=%Rrc\n", rc));
     }
-
 }
 
@@ -936,6 +935,6 @@
 {
     PDRVSCSI pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSI);
-
     LogFlowFunc(("pDrvIns=%#p pCfgHandle=%#p\n", pDrvIns, pCfgHandle));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/Storage/DrvSCSIHost.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DrvSCSIHost.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/DrvSCSIHost.cpp	(revision 26001)
@@ -394,5 +394,5 @@
 }
 
-/* -=-=-=-=- IBase -=-=-=-=- */
+/* -=-=-=-=- PDMIBASE -=-=-=-=- */
 
 /**
@@ -409,4 +409,6 @@
 }
 
+/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
+
 /**
  * Destruct a driver instance.
@@ -419,6 +421,6 @@
 static DECLCALLBACK(void) drvscsihostDestruct(PPDMDRVINS pDrvIns)
 {
-    int rc;
     PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST);
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
 
     if (pThis->DeviceFile != NIL_RTFILE)
@@ -430,5 +432,5 @@
     if (pThis->pQueueRequests)
     {
-        rc = RTReqDestroyQueue(pThis->pQueueRequests);
+        int rc = RTReqDestroyQueue(pThis->pQueueRequests);
         AssertMsgRC(rc, ("Failed to destroy queue rc=%Rrc\n", rc));
     }
@@ -444,6 +446,6 @@
 {
     PDRVSCSIHOST pThis = PDMINS_2_DATA(pDrvIns, PDRVSCSIHOST);
-
     LogFlowFunc(("pDrvIns=%#p pCfgHandle=%#p\n", pDrvIns, pCfgHandle));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/Storage/DrvVD.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DrvVD.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/DrvVD.cpp	(revision 26001)
@@ -951,4 +951,5 @@
     PVBOXDISK pThis = PDMINS_2_DATA(pDrvIns, PVBOXDISK);
     LogFlow(("%s:\n", __FUNCTION__));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
 
     if (VALID_PTR(pThis->pDisk))
@@ -976,4 +977,5 @@
     bool fReadOnly;         /**< True if the media is read-only. */
     bool fHonorZeroWrites;  /**< True if zero blocks should be written. */
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Devices/Storage/fdc.c
===================================================================
--- /trunk/src/VBox/Devices/Storage/fdc.c	(revision 26000)
+++ /trunk/src/VBox/Devices/Storage/fdc.c	(revision 26001)
@@ -2764,4 +2764,5 @@
 
     Assert(iInstance == 0);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
Index: /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
===================================================================
--- /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 26000)
+++ /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 26001)
@@ -2404,4 +2404,6 @@
 }
 
+/* -=-=-=-=- PDMDEVREG -=-=-=-=- */
+
 /**
  * (Re-)initializes the MMIO2 data.
@@ -2415,4 +2417,99 @@
     pThis->pVMMDevRAMR3->u32Version = VMMDEV_MEMORY_VERSION;
 }
+
+/**
+ * Reset notification.
+ *
+ * @returns VBox status.
+ * @param   pDrvIns     The driver instance data.
+ */
+static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns)
+{
+    VMMDevState *pThis = PDMINS_2_DATA(pDevIns, VMMDevState*);
+
+    /*
+     * Reset the mouse integration feature bits
+     */
+    if (pThis->mouseCapabilities & VMMDEV_MOUSE_GUEST_MASK)
+    {
+        pThis->mouseCapabilities &= ~VMMDEV_MOUSE_GUEST_MASK;
+        /* notify the connector */
+        Log(("vmmdevReset: capabilities changed (%x), informing connector\n", pThis->mouseCapabilities));
+        pThis->pDrv->pfnUpdateMouseCapabilities(pThis->pDrv, pThis->mouseCapabilities);
+    }
+    pThis->fHostCursorRequested = false;
+
+    pThis->hypervisorSize = 0;
+
+    pThis->u32HostEventFlags = 0;
+
+    /* re-initialize the VMMDev memory */
+    if (pThis->pVMMDevRAMR3)
+        vmmdevInitRam(pThis);
+
+    /* credentials have to go away (by default) */
+    if (!pThis->fKeepCredentials)
+    {
+        memset(pThis->credentialsLogon.szUserName, '\0', VMMDEV_CREDENTIALS_STRLEN);
+        memset(pThis->credentialsLogon.szPassword, '\0', VMMDEV_CREDENTIALS_STRLEN);
+        memset(pThis->credentialsLogon.szDomain, '\0', VMMDEV_CREDENTIALS_STRLEN);
+    }
+    memset(pThis->credentialsJudge.szUserName, '\0', VMMDEV_CREDENTIALS_STRLEN);
+    memset(pThis->credentialsJudge.szPassword, '\0', VMMDEV_CREDENTIALS_STRLEN);
+    memset(pThis->credentialsJudge.szDomain, '\0', VMMDEV_CREDENTIALS_STRLEN);
+
+    /* Reset means that additions will report again. */
+    const bool fVersionChanged = pThis->fu32AdditionsOk
+                              || pThis->guestInfo.additionsVersion
+                              || pThis->guestInfo.osType != VBOXOSTYPE_Unknown;
+    if (fVersionChanged)
+        Log(("vmmdevReset: fu32AdditionsOk=%d additionsVersion=%x osType=%#x\n",
+             pThis->fu32AdditionsOk, pThis->guestInfo.additionsVersion, pThis->guestInfo.osType));
+    pThis->fu32AdditionsOk = false;
+    memset (&pThis->guestInfo, 0, sizeof (pThis->guestInfo));
+
+    /* clear pending display change request. */
+    memset (&pThis->lastReadDisplayChangeRequest, 0, sizeof (pThis->lastReadDisplayChangeRequest));
+    pThis->fGuestSentChangeEventAck = false;
+
+    /* disable seamless mode */
+    pThis->fLastSeamlessEnabled = false;
+
+    /* disabled memory ballooning */
+    pThis->u32LastMemoryBalloonSize = 0;
+
+    /* disabled statistics updating */
+    pThis->u32LastStatIntervalSize = 0;
+
+    /* Clear the "HGCM event enabled" flag so the event can be automatically reenabled.  */
+    pThis->u32HGCMEnabled = 0;
+
+    /*
+     * Clear the event variables.
+     *
+     *   Note: The pThis->u32HostEventFlags is not cleared.
+     *         It is designed that way so host events do not
+     *         depend on guest resets.
+     */
+    pThis->u32GuestFilterMask    = 0;
+    pThis->u32NewGuestFilterMask = 0;
+    pThis->fNewGuestFilterMask   = 0;
+
+    /* This is the default, as Windows and OS/2 guests take this for granted. (Actually, neither does...) */
+    /** @todo change this when we next bump the interface version */
+    const bool fCapsChanged = pThis->guestCaps != VMMDEV_GUEST_SUPPORTS_GRAPHICS;
+    if (fCapsChanged)
+        Log(("vmmdevReset: fCapsChanged=%#x -> %#x\n", pThis->guestCaps, VMMDEV_GUEST_SUPPORTS_GRAPHICS));
+    pThis->guestCaps = VMMDEV_GUEST_SUPPORTS_GRAPHICS; /** @todo r=bird: why? I cannot see this being done at construction?*/
+
+    /*
+     * Call the update functions as required.
+     */
+    if (fVersionChanged)
+        pThis->pDrv->pfnUpdateGuestVersion(pThis->pDrv, &pThis->guestInfo);
+    if (fCapsChanged)
+        pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps);
+}
+
 
 /**
@@ -2435,4 +2532,5 @@
 
     Assert(iInstance == 0);
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
 
     /*
@@ -2637,98 +2735,4 @@
 
     return rc;
-}
-
-/**
- * Reset notification.
- *
- * @returns VBox status.
- * @param   pDrvIns     The driver instance data.
- */
-static DECLCALLBACK(void) vmmdevReset(PPDMDEVINS pDevIns)
-{
-    VMMDevState *pThis = PDMINS_2_DATA(pDevIns, VMMDevState*);
-
-    /*
-     * Reset the mouse integration feature bits
-     */
-    if (pThis->mouseCapabilities & VMMDEV_MOUSE_GUEST_MASK)
-    {
-        pThis->mouseCapabilities &= ~VMMDEV_MOUSE_GUEST_MASK;
-        /* notify the connector */
-        Log(("vmmdevReset: capabilities changed (%x), informing connector\n", pThis->mouseCapabilities));
-        pThis->pDrv->pfnUpdateMouseCapabilities(pThis->pDrv, pThis->mouseCapabilities);
-    }
-    pThis->fHostCursorRequested = false;
-
-    pThis->hypervisorSize = 0;
-
-    pThis->u32HostEventFlags = 0;
-
-    /* re-initialize the VMMDev memory */
-    if (pThis->pVMMDevRAMR3)
-        vmmdevInitRam(pThis);
-
-    /* credentials have to go away (by default) */
-    if (!pThis->fKeepCredentials)
-    {
-        memset(pThis->credentialsLogon.szUserName, '\0', VMMDEV_CREDENTIALS_STRLEN);
-        memset(pThis->credentialsLogon.szPassword, '\0', VMMDEV_CREDENTIALS_STRLEN);
-        memset(pThis->credentialsLogon.szDomain, '\0', VMMDEV_CREDENTIALS_STRLEN);
-    }
-    memset(pThis->credentialsJudge.szUserName, '\0', VMMDEV_CREDENTIALS_STRLEN);
-    memset(pThis->credentialsJudge.szPassword, '\0', VMMDEV_CREDENTIALS_STRLEN);
-    memset(pThis->credentialsJudge.szDomain, '\0', VMMDEV_CREDENTIALS_STRLEN);
-
-    /* Reset means that additions will report again. */
-    const bool fVersionChanged = pThis->fu32AdditionsOk
-                              || pThis->guestInfo.additionsVersion
-                              || pThis->guestInfo.osType != VBOXOSTYPE_Unknown;
-    if (fVersionChanged)
-        Log(("vmmdevReset: fu32AdditionsOk=%d additionsVersion=%x osType=%#x\n",
-             pThis->fu32AdditionsOk, pThis->guestInfo.additionsVersion, pThis->guestInfo.osType));
-    pThis->fu32AdditionsOk = false;
-    memset (&pThis->guestInfo, 0, sizeof (pThis->guestInfo));
-
-    /* clear pending display change request. */
-    memset (&pThis->lastReadDisplayChangeRequest, 0, sizeof (pThis->lastReadDisplayChangeRequest));
-    pThis->fGuestSentChangeEventAck = false;
-
-    /* disable seamless mode */
-    pThis->fLastSeamlessEnabled = false;
-
-    /* disabled memory ballooning */
-    pThis->u32LastMemoryBalloonSize = 0;
-
-    /* disabled statistics updating */
-    pThis->u32LastStatIntervalSize = 0;
-
-    /* Clear the "HGCM event enabled" flag so the event can be automatically reenabled.  */
-    pThis->u32HGCMEnabled = 0;
-
-    /*
-     * Clear the event variables.
-     *
-     *   Note: The pThis->u32HostEventFlags is not cleared.
-     *         It is designed that way so host events do not
-     *         depend on guest resets.
-     */
-    pThis->u32GuestFilterMask    = 0;
-    pThis->u32NewGuestFilterMask = 0;
-    pThis->fNewGuestFilterMask   = 0;
-
-    /* This is the default, as Windows and OS/2 guests take this for granted. (Actually, neither does...) */
-    /** @todo change this when we next bump the interface version */
-    const bool fCapsChanged = pThis->guestCaps != VMMDEV_GUEST_SUPPORTS_GRAPHICS;
-    if (fCapsChanged)
-        Log(("vmmdevReset: fCapsChanged=%#x -> %#x\n", pThis->guestCaps, VMMDEV_GUEST_SUPPORTS_GRAPHICS));
-    pThis->guestCaps = VMMDEV_GUEST_SUPPORTS_GRAPHICS; /** @todo r=bird: why? I cannot see this being done at construction?*/
-
-    /*
-     * Call the update functions as required.
-     */
-    if (fVersionChanged)
-        pThis->pDrv->pfnUpdateGuestVersion(pThis->pDrv, &pThis->guestInfo);
-    if (fCapsChanged)
-        pThis->pDrv->pfnUpdateGuestCapabilities(pThis->pDrv, pThis->guestCaps);
 }
 
Index: /trunk/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp	(revision 26000)
+++ /trunk/src/VBox/Frontends/VBoxBFE/DisplayImpl.cpp	(revision 26001)
@@ -1171,5 +1171,5 @@
     PDRVMAINDISPLAY pData = PDMINS_2_DATA(pDrvIns, PDRVMAINDISPLAY);
     LogFlow(("VMDisplay::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
-
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Main/AudioSnifferInterface.cpp
===================================================================
--- /trunk/src/VBox/Main/AudioSnifferInterface.cpp	(revision 26000)
+++ /trunk/src/VBox/Main/AudioSnifferInterface.cpp	(revision 26001)
@@ -140,4 +140,6 @@
     PDRVAUDIOSNIFFER pThis = PDMINS_2_DATA(pDrvIns, PDRVAUDIOSNIFFER);
     LogFlow(("AudioSniffer::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
     if (pThis->pAudioSniffer)
     {
@@ -157,4 +159,5 @@
 
     LogFlow(("AudioSniffer::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Main/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 26000)
+++ /trunk/src/VBox/Main/ConsoleImpl.cpp	(revision 26001)
@@ -8146,4 +8146,6 @@
     PDRVMAINSTATUS pData = PDMINS_2_DATA(pDrvIns, PDRVMAINSTATUS);
     LogFlowFunc(("iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
     if (pData->papLeds)
     {
@@ -8164,4 +8166,5 @@
     PDRVMAINSTATUS pData = PDMINS_2_DATA(pDrvIns, PDRVMAINSTATUS);
     LogFlowFunc(("iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Main/DisplayImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/DisplayImpl.cpp	(revision 26000)
+++ /trunk/src/VBox/Main/DisplayImpl.cpp	(revision 26001)
@@ -3385,4 +3385,6 @@
     PDRVMAINDISPLAY pData = PDMINS_2_DATA(pDrvIns, PDRVMAINDISPLAY);
     LogFlowFunc (("iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
+
     if (pData->pDisplay)
     {
@@ -3408,4 +3410,5 @@
     PDRVMAINDISPLAY pData = PDMINS_2_DATA(pDrvIns, PDRVMAINDISPLAY);
     LogFlowFunc (("iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Main/KeyboardImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/KeyboardImpl.cpp	(revision 26000)
+++ /trunk/src/VBox/Main/KeyboardImpl.cpp	(revision 26001)
@@ -242,4 +242,6 @@
     PDRVMAINKEYBOARD pData = PDMINS_2_DATA(pDrvIns, PDRVMAINKEYBOARD);
     LogFlow(("Keyboard::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
     if (pData->pKeyboard)
     {
@@ -267,4 +269,5 @@
     PDRVMAINKEYBOARD pData = PDMINS_2_DATA (pDrvIns, PDRVMAINKEYBOARD);
     LogFlow(("Keyboard::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/Main/MouseImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MouseImpl.cpp	(revision 26000)
+++ /trunk/src/VBox/Main/MouseImpl.cpp	(revision 26001)
@@ -377,4 +377,6 @@
     PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
     LogFlow(("Mouse::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns);
+
     if (pData->pMouse)
     {
@@ -394,4 +396,5 @@
     PDRVMAINMOUSE pData = PDMINS_2_DATA(pDrvIns, PDRVMAINMOUSE);
     LogFlow(("drvMainMouse_Construct: iInstance=%d\n", pDrvIns->iInstance));
+    PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
 
     /*
Index: /trunk/src/VBox/VMM/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDMDevHlp.cpp	(revision 26000)
+++ /trunk/src/VBox/VMM/PDMDevHlp.cpp	(revision 26001)
@@ -1955,4 +1955,6 @@
     return VINF_SUCCESS;
 }
+
+
 /** @copydoc PDMDEVHLPR3::pfnHPETRegister */
 static DECLCALLBACK(int) pdmR3DevHlp_HPETRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
@@ -1984,4 +1986,5 @@
     return VINF_SUCCESS;
 }
+
 
 /** @copydoc PDMDEVHLPR3::pfnDMACRegister */
@@ -2928,4 +2931,5 @@
 }
 
+
 /** @copydoc PDMDEVHLPR3::pfnHPETRegister */
 static DECLCALLBACK(int) pdmR3DevHlp_Untrusted_HPETRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
@@ -2937,4 +2941,5 @@
     return VERR_ACCESS_DENIED;
 }
+
 
 /** @copydoc PDMDEVHLPR3::pfnDMACRegister */
@@ -3386,2 +3391,3 @@
 
 /** @} */
+
Index: /trunk/src/VBox/VMM/PDMDevMiscHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/PDMDevMiscHlp.cpp	(revision 26000)
+++ /trunk/src/VBox/VMM/PDMDevMiscHlp.cpp	(revision 26001)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -39,5 +39,5 @@
 
 
-/** @name HC PIC Helpers
+/** @name Ring-3 PIC Helpers
  * @{
  */
@@ -365,5 +365,5 @@
 
 
-/** @name HC I/O APIC Helpers
+/** @name Ring-3 I/O APIC Helpers
  * @{
  */
@@ -450,5 +450,5 @@
 
 
-/** @name HC PCI Bus Helpers
+/** @name Ring-3 PCI Bus Helpers
  * @{
  */
@@ -530,57 +530,4 @@
 }
 
-
-/** @copydoc PDMHPETHLPR3::pfnSetLegacyMode */
-static DECLCALLBACK(int) pdmR3HpetHlp_SetLegacyMode(PPDMDEVINS pDevIns, bool fActivate)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivate=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fActivate));
-    return 0;
-}
-
-/** @copydoc PDMHPETHLPR3::pfnLock */
-static DECLCALLBACK(int) pdmR3HpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR3HpetHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
-    return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
-}
-
-
-/** @copydoc PDMHPETHLPR3::pfnUnlock */
-static DECLCALLBACK(void) pdmR3HpetHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR3HpetHlp_Unlock: caller='%s'/%d:\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
-    pdmUnlock(pDevIns->Internal.s.pVMR3);
-}
-
-/** @copydoc PDMHPETHLPR3::pfnGetRCHelpers */
-static DECLCALLBACK(PCPDMHPETHLPRC) pdmR3HpetHlp_GetRCHelpers(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
-    RTRCPTR pRCHelpers = 0;
-    int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCHpetHlp", &pRCHelpers);
-    AssertReleaseRC(rc);
-    AssertRelease(pRCHelpers);
-    LogFlow(("pdmR3HpetHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
-             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
-    return pRCHelpers;
-}
-
-/** @copydoc PDMHPETHLPR3::pfnGetR0Helpers */
-static DECLCALLBACK(PCPDMHPETHLPR0) pdmR3HpetHlp_GetR0Helpers(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
-    PCPDMHPETHLPR0 pR0Helpers = 0;
-    int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0HpetHlp", &pR0Helpers);
-    AssertReleaseRC(rc);
-    AssertRelease(pR0Helpers);
-    LogFlow(("pdmR3HpetHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
-             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
-    return pR0Helpers;
-}
 
 /**
@@ -602,4 +549,68 @@
 /** @} */
 
+
+
+
+/** @name Ring-3 HPET Helpers
+ * {@
+ */
+
+/** @copydoc PDMHPETHLPR3::pfnSetLegacyMode */
+static DECLCALLBACK(int) pdmR3HpetHlp_SetLegacyMode(PPDMDEVINS pDevIns, bool fActivate)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivate=%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, fActivate));
+    return 0;
+}
+
+
+/** @copydoc PDMHPETHLPR3::pfnLock */
+static DECLCALLBACK(int) pdmR3HpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR3HpetHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
+    return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
+}
+
+
+/** @copydoc PDMHPETHLPR3::pfnUnlock */
+static DECLCALLBACK(void) pdmR3HpetHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR3HpetHlp_Unlock: caller='%s'/%d:\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
+    pdmUnlock(pDevIns->Internal.s.pVMR3);
+}
+
+
+/** @copydoc PDMHPETHLPR3::pfnGetRCHelpers */
+static DECLCALLBACK(PCPDMHPETHLPRC) pdmR3HpetHlp_GetRCHelpers(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
+    RTRCPTR pRCHelpers = 0;
+    int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCHpetHlp", &pRCHelpers);
+    AssertReleaseRC(rc);
+    AssertRelease(pRCHelpers);
+    LogFlow(("pdmR3HpetHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
+             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
+    return pRCHelpers;
+}
+
+
+/** @copydoc PDMHPETHLPR3::pfnGetR0Helpers */
+static DECLCALLBACK(PCPDMHPETHLPR0) pdmR3HpetHlp_GetR0Helpers(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
+    PCPDMHPETHLPR0 pR0Helpers = 0;
+    int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0HpetHlp", &pR0Helpers);
+    AssertReleaseRC(rc);
+    AssertRelease(pR0Helpers);
+    LogFlow(("pdmR3HpetHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
+             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
+    return pR0Helpers;
+}
+
+
 /**
  * HPET Device Helpers.
@@ -608,5 +619,5 @@
 {
     PDM_HPETHLPR3_VERSION,
-    pdmR3HpetHlp_SetLegacyMode,    
+    pdmR3HpetHlp_SetLegacyMode,
     pdmR3HpetHlp_Lock,
     pdmR3HpetHlp_Unlock,
Index: /trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp	(revision 26000)
+++ /trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp	(revision 26001)
@@ -1,9 +1,9 @@
 /* $Id$ */
 /** @file
- * PDM - Pluggable Device and Driver Manager, GC Device parts.
+ * PDM - Pluggable Device and Driver Manager, RC Device parts.
  */
 
 /*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -56,79 +56,179 @@
 *   Internal Functions                                                         *
 *******************************************************************************/
-/** @name GC Device Helpers
+static void pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel);
+static void pdmRCIoApicSetIrq(PVM pVM, int iIrq, int iLevel);
+
+
+
+
+/** @name Raw-Mode Context Device Helpers
  * @{
  */
-static DECLCALLBACK(void) pdmGCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
-static DECLCALLBACK(void) pdmGCDevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
-static DECLCALLBACK(int)  pdmGCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
-static DECLCALLBACK(int)  pdmGCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
-static DECLCALLBACK(bool) pdmGCDevHlp_A20IsEnabled(PPDMDEVINS pDevIns);
-static DECLCALLBACK(int)  pdmGCDevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
-static DECLCALLBACK(int)  pdmGCDevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
-static DECLCALLBACK(int)  pdmGCDevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...);
-static DECLCALLBACK(int)  pdmGCDevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va);
-static DECLCALLBACK(int)  pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData);
-static DECLCALLBACK(PVM)  pdmGCDevHlp_GetVM(PPDMDEVINS pDevIns);
-static DECLCALLBACK(PVMCPU)  pdmGCDevHlp_GetVMCPU(PPDMDEVINS pDevIns);
-/** @} */
-
-
-/** @name PIC GC Helpers
- * @{
- */
-static DECLCALLBACK(void) pdmRCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
-static DECLCALLBACK(void) pdmRCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
-static DECLCALLBACK(int)  pdmRCPicHlp_Lock(PPDMDEVINS pDevIns, int rc);
-static DECLCALLBACK(void) pdmRCPicHlp_Unlock(PPDMDEVINS pDevIns);
-/** @} */
-
-
-/** @name APIC RC Helpers
- * @{
- */
-static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
-static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
-static DECLCALLBACK(void) pdmRCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion);
-static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
-static DECLCALLBACK(void) pdmRCApicHlp_Unlock(PPDMDEVINS pDevIns);
-static DECLCALLBACK(VMCPUID) pdmRCApicHlp_GetCpuId(PPDMDEVINS pDevIns);
-/** @} */
-
-
-/** @name I/O APIC RC Helpers
- * @{
- */
-static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                        uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);
-static DECLCALLBACK(int) pdmRCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
-static DECLCALLBACK(void) pdmRCIoApicHlp_Unlock(PPDMDEVINS pDevIns);
-/** @} */
-
-
-/** @name PCI Bus RC Helpers
- * @{
- */
-static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
-static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
-static DECLCALLBACK(int) pdmRCPciHlp_Lock(PPDMDEVINS pDevIns, int rc);
-static DECLCALLBACK(void) pdmRCPciHlp_Unlock(PPDMDEVINS pDevIns);
-/** @} */
-
-
-/** @name HPET RC Helpers
- * @{
- */
-static DECLCALLBACK(int) pdmRCHpetHlp_Lock(PPDMDEVINS pDevIns, int rc);
-static DECLCALLBACK(void) pdmRCHpetHlp_Unlock(PPDMDEVINS pDevIns);
-/** @} */
-
-
-static void pdmGCIsaSetIrq(PVM pVM, int iIrq, int iLevel);
-static void pdmGCIoApicSetIrq(PVM pVM, int iIrq, int iLevel);
-
-
-
-/**
- * The Guest Context Device Helper Callbacks.
+
+/** @copydoc PDMDEVHLPRC::pfnPCISetIrq */
+static DECLCALLBACK(void) pdmGCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
+
+    PVM         pVM     = pDevIns->Internal.s.pVMRC;
+    PPCIDEVICE  pPciDev = pDevIns->Internal.s.pPciDeviceRC;
+    PPDMPCIBUS  pPciBus = pDevIns->Internal.s.pPciBusRC;
+    if (    pPciDev
+        &&  pPciBus
+        &&  pPciBus->pDevInsRC)
+    {
+        pdmLock(pVM);
+        pPciBus->pfnSetIrqRC(pPciBus->pDevInsRC, pPciDev, iIrq, iLevel);
+        pdmUnlock(pVM);
+    }
+    else
+    {
+        /* queue for ring-3 execution. */
+        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC);
+        if (pTask)
+        {
+            pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
+            pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
+            pTask->u.SetIRQ.iIrq = iIrq;
+            pTask->u.SetIRQ.iLevel = iLevel;
+
+            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
+        }
+        else
+            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
+    }
+
+    LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnPCISetIrq */
+static DECLCALLBACK(void) pdmGCDevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
+
+    pdmRCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
+
+    LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnPhysRead */
+static DECLCALLBACK(int) pdmGCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmGCDevHlp_PhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
+             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
+
+    int rc = PGMPhysRead(pDevIns->Internal.s.pVMRC, GCPhys, pvBuf, cbRead);
+    AssertRC(rc); /** @todo track down the users for this bugger. */
+
+    Log(("pdmGCDevHlp_PhysRead: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnPhysWrite */
+static DECLCALLBACK(int) pdmGCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmGCDevHlp_PhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
+             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
+
+    int rc = PGMPhysWrite(pDevIns->Internal.s.pVMRC, GCPhys, pvBuf, cbWrite);
+    AssertRC(rc); /** @todo track down the users for this bugger. */
+
+    Log(("pdmGCDevHlp_PhysWrite: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnA20IsEnabled */
+static DECLCALLBACK(bool) pdmGCDevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
+
+    bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu0(pDevIns->Internal.s.pVMRC));
+
+    Log(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
+    return fEnabled;
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnVMSetError */
+static DECLCALLBACK(int) pdmGCDevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    va_list args;
+    va_start(args, pszFormat);
+    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMRC, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
+    va_end(args);
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnVMSetErrorV */
+static DECLCALLBACK(int) pdmGCDevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMRC, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnVMSetRuntimeError */
+static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    va_list va;
+    va_start(va, pszFormat);
+    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMRC, fFlags, pszErrorId, pszFormat, va);
+    va_end(va);
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnVMSetErrorV */
+static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMRC, fFlags, pszErrorId, pszFormat, va);
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnPATMSetMMIOPatchInfo */
+static DECLCALLBACK(int) pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmGCDevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
+
+    return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMRC, GCPhys, (RTRCPTR)pCachedData);
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnGetVM */
+static DECLCALLBACK(PVM)  pdmGCDevHlp_GetVM(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmGCDevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
+    return pDevIns->Internal.s.pVMRC;
+}
+
+
+/** @copydoc PDMDEVHLPRC::pfnGetVMCPU */
+static DECLCALLBACK(PVMCPU) pdmGCDevHlp_GetVMCPU(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmGCDevHlp_GetVMCPU: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
+    return VMMGetCpu(pDevIns->Internal.s.pVMRC);
+}
+
+
+/**
+ * The Raw-Mode Context Device Helper Callbacks.
  */
 extern DECLEXPORT(const PDMDEVHLPRC) g_pdmRCDevHlp =
@@ -150,4 +250,78 @@
 };
 
+/** @} */
+
+
+
+
+/** @name PIC RC Helpers
+ * @{
+ */
+
+/** @copydoc PDMPICHLPGC::pfnSetInterruptFF */
+static DECLCALLBACK(void) pdmRCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+
+    if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
+    {
+        LogFlow(("pdmRCPicHlp_SetInterruptFF: caller='%p'/%d: Setting local interrupt on LAPIC\n",
+                 pDevIns, pDevIns->iInstance));
+        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
+        pVM->pdm.s.Apic.pfnLocalInterruptRC(pVM->pdm.s.Apic.pDevInsRC, 0, 1);
+        return;
+    }
+
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+
+    LogFlow(("pdmRCPicHlp_SetInterruptFF: caller=%p/%d: VMMCPU_FF_INTERRUPT_PIC %d -> 1\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
+
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+}
+
+
+/** @copydoc PDMPICHLPGC::pfnClearInterruptFF */
+static DECLCALLBACK(void) pdmRCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.CTX_SUFF(pVM);
+
+    if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
+    {
+        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
+        LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
+                 pDevIns, pDevIns->iInstance));
+        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
+        pVM->pdm.s.Apic.pfnLocalInterruptRC(pVM->pdm.s.Apic.pDevInsRC, 0, 0);
+        return;
+    }
+
+    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+
+    LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
+
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+}
+
+
+/** @copydoc PDMPICHLPGC::pfnLock */
+static DECLCALLBACK(int) pdmRCPicHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
+}
+
+
+/** @copydoc PDMPICHLPGC::pfnUnlock */
+static DECLCALLBACK(void) pdmRCPicHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    pdmUnlock(pDevIns->Internal.s.pVMRC);
+}
+
+
 /**
  * The Raw-Mode Context PIC Helper Callbacks.
@@ -162,4 +336,121 @@
     PDM_PICHLPRC_VERSION
 };
+
+/** @} */
+
+
+
+
+/** @name APIC RC Helpers
+ * @{
+ */
+
+/** @copydoc PDMAPICHLPRC::pfnSetInterruptFF */
+static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+    AssertReturnVoid(idCpu < pVM->cCpus);
+
+    LogFlow(("pdmRCApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
+    switch (enmType)
+    {
+        case PDMAPICIRQ_HARDWARE:
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+            break;
+        case PDMAPICIRQ_NMI:
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
+            break;
+        case PDMAPICIRQ_SMI:
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
+            break;
+        case PDMAPICIRQ_EXTINT:
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+            break;
+        default:
+            AssertMsgFailed(("enmType=%d\n", enmType));
+            break;
+    }
+}
+
+
+/** @copydoc PDMAPICHLPRC::pfnClearInterruptFF */
+static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+    AssertReturnVoid(idCpu < pVM->cCpus);
+
+    LogFlow(("pdmRCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
+
+    /* Note: NMI/SMI can't be cleared. */
+    switch (enmType)
+    {
+        case PDMAPICIRQ_HARDWARE:
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+            break;
+        case PDMAPICIRQ_EXTINT:
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+            break;
+        default:
+            AssertMsgFailed(("enmType=%d\n", enmType));
+            break;
+    }
+}
+
+
+/** @copydoc PDMAPICHLPRC::pfnChangeFeature */
+static DECLCALLBACK(void) pdmRCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmRCApicHlp_ChangeFeature: caller=%p/%d: version=%d\n", pDevIns, pDevIns->iInstance, (int)enmVersion));
+    switch (enmVersion)
+    {
+        case PDMAPICVERSION_NONE:
+            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
+            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
+            break;
+        case PDMAPICVERSION_APIC:
+            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
+            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
+            break;
+        case PDMAPICVERSION_X2APIC:
+            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
+            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
+            break;
+        default:
+            AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
+    }
+}
+
+
+/** @copydoc PDMAPICHLPRC::pfnLock */
+static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
+}
+
+
+/** @copydoc PDMAPICHLPRC::pfnUnlock */
+static DECLCALLBACK(void) pdmRCApicHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    pdmUnlock(pDevIns->Internal.s.pVMRC);
+}
+
+
+/** @copydoc PDMAPICHLPRC::pfnGetCpuId */
+static DECLCALLBACK(VMCPUID) pdmRCApicHlp_GetCpuId(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return VMMGetCpuId(pDevIns->Internal.s.pVMRC);
+}
 
 
@@ -179,4 +470,42 @@
 };
 
+/** @} */
+
+
+
+
+/** @name I/O APIC RC Helpers
+ * @{
+ */
+
+/** @copydoc PDMIOAPICHLPRC::pfnApicBusDeliver */
+static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+                                                       uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMRC;
+    LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
+             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
+    if (pVM->pdm.s.Apic.pfnBusDeliverRC)
+        return pVM->pdm.s.Apic.pfnBusDeliverRC(pVM->pdm.s.Apic.pDevInsRC, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+    return VINF_SUCCESS;
+}
+
+
+/** @copydoc PDMIOAPICHLPRC::pfnLock */
+static DECLCALLBACK(int) pdmRCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
+}
+
+
+/** @copydoc PDMIOAPICHLPRC::pfnUnlock */
+static DECLCALLBACK(void) pdmRCIoApicHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    pdmUnlock(pDevIns->Internal.s.pVMRC);
+}
+
 
 /**
@@ -191,4 +520,46 @@
     PDM_IOAPICHLPRC_VERSION
 };
+
+/** @} */
+
+
+
+
+/** @name PCI Bus RC Helpers
+ * @{
+ */
+
+/** @copydoc PDMPCIHLPRC::pfnIsaSetIrq */
+static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
+    pdmRCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
+}
+
+
+/** @copydoc PDMPCIHLPRC::pfnIoApicSetIrq */
+static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
+    pdmRCIoApicSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
+}
+
+
+/** @copydoc PDMPCIHLPRC::pfnLock */
+static DECLCALLBACK(int) pdmRCPciHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
+}
+
+
+/** @copydoc PDMPCIHLPRC::pfnUnlock */
+static DECLCALLBACK(void) pdmRCPciHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    pdmUnlock(pDevIns->Internal.s.pVMRC);
+}
 
 
@@ -206,4 +577,29 @@
 };
 
+/** @} */
+
+
+
+
+/** @name HPET RC Helpers
+ * @{
+ */
+
+/** @copydoc PDMHPETHLPRC::pfnLock */
+static DECLCALLBACK(int) pdmRCHpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
+}
+
+
+/** @copydoc PDMHPETHLPRC::pfnUnlock */
+static DECLCALLBACK(void) pdmRCHpetHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    pdmUnlock(pDevIns->Internal.s.pVMRC);
+}
+
+
 /**
  * The Raw-Mode Context HPET Helper Callbacks.
@@ -217,412 +613,5 @@
 };
 
-
-/** @copydoc PDMDEVHLPRC::pfnPCISetIrq */
-static DECLCALLBACK(void) pdmGCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
-
-    PVM         pVM     = pDevIns->Internal.s.pVMRC;
-    PPCIDEVICE  pPciDev = pDevIns->Internal.s.pPciDeviceRC;
-    PPDMPCIBUS  pPciBus = pDevIns->Internal.s.pPciBusRC;
-    if (    pPciDev
-        &&  pPciBus
-        &&  pPciBus->pDevInsRC)
-    {
-        pdmLock(pVM);
-        pPciBus->pfnSetIrqRC(pPciBus->pDevInsRC, pPciDev, iIrq, iLevel);
-        pdmUnlock(pVM);
-    }
-    else
-    {
-        /* queue for ring-3 execution. */
-        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueRC);
-        if (pTask)
-        {
-            pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
-            pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
-            pTask->u.SetIRQ.iIrq = iIrq;
-            pTask->u.SetIRQ.iLevel = iLevel;
-
-            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueRC, &pTask->Core, 0);
-        }
-        else
-            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
-    }
-
-    LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnPCISetIrq */
-static DECLCALLBACK(void) pdmGCDevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
-
-    pdmGCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
-
-    LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnPhysRead */
-static DECLCALLBACK(int) pdmGCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmGCDevHlp_PhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
-             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
-
-    int rc = PGMPhysRead(pDevIns->Internal.s.pVMRC, GCPhys, pvBuf, cbRead);
-    AssertRC(rc); /** @todo track down the users for this bugger. */
-
-    Log(("pdmGCDevHlp_PhysRead: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnPhysWrite */
-static DECLCALLBACK(int) pdmGCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmGCDevHlp_PhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
-             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
-
-    int rc = PGMPhysWrite(pDevIns->Internal.s.pVMRC, GCPhys, pvBuf, cbWrite);
-    AssertRC(rc); /** @todo track down the users for this bugger. */
-
-    Log(("pdmGCDevHlp_PhysWrite: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnA20IsEnabled */
-static DECLCALLBACK(bool) pdmGCDevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
-
-    bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu0(pDevIns->Internal.s.pVMRC));
-
-    Log(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
-    return fEnabled;
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnVMSetError */
-static DECLCALLBACK(int) pdmGCDevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    va_list args;
-    va_start(args, pszFormat);
-    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMRC, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
-    va_end(args);
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnVMSetErrorV */
-static DECLCALLBACK(int) pdmGCDevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMRC, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnVMSetRuntimeError */
-static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    va_list va;
-    va_start(va, pszFormat);
-    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMRC, fFlags, pszErrorId, pszFormat, va);
-    va_end(va);
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnVMSetErrorV */
-static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMRC, fFlags, pszErrorId, pszFormat, va);
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnPATMSetMMIOPatchInfo */
-static DECLCALLBACK(int) pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmGCDevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
-
-    return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMRC, GCPhys, (RTRCPTR)pCachedData);
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnGetVM */
-static DECLCALLBACK(PVM)  pdmGCDevHlp_GetVM(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmGCDevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return pDevIns->Internal.s.pVMRC;
-}
-
-
-/** @copydoc PDMDEVHLPRC::pfnGetVMCPU */
-static DECLCALLBACK(PVMCPU) pdmGCDevHlp_GetVMCPU(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmGCDevHlp_GetVMCPU: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return VMMGetCpu(pDevIns->Internal.s.pVMRC);
-}
-
-
-
-
-/** @copydoc PDMPICHLPGC::pfnSetInterruptFF */
-static DECLCALLBACK(void) pdmRCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMRC;
-
-    if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
-    {
-        LogFlow(("pdmRCPicHlp_SetInterruptFF: caller='%p'/%d: Setting local interrupt on LAPIC\n",
-                 pDevIns, pDevIns->iInstance));
-        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        pVM->pdm.s.Apic.pfnLocalInterruptRC(pVM->pdm.s.Apic.pDevInsRC, 0, 1);
-        return;
-    }
-
-    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
-
-    LogFlow(("pdmRCPicHlp_SetInterruptFF: caller=%p/%d: VMMCPU_FF_INTERRUPT_PIC %d -> 1\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
-
-    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
-}
-
-
-/** @copydoc PDMPICHLPGC::pfnClearInterruptFF */
-static DECLCALLBACK(void) pdmRCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.CTX_SUFF(pVM);
-
-    if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
-    {
-        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
-                 pDevIns, pDevIns->iInstance));
-        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        pVM->pdm.s.Apic.pfnLocalInterruptRC(pVM->pdm.s.Apic.pDevInsRC, 0, 0);
-        return;
-    }
-
-    PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
-
-    LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
-
-    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
-}
-
-
-/** @copydoc PDMPICHLPGC::pfnLock */
-static DECLCALLBACK(int) pdmRCPicHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
-}
-
-
-/** @copydoc PDMPICHLPGC::pfnUnlock */
-static DECLCALLBACK(void) pdmRCPicHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMRC);
-}
-
-
-
-
-/** @copydoc PDMAPICHLPRC::pfnSetInterruptFF */
-static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMRC;
-    PVMCPU pVCpu = &pVM->aCpus[idCpu];
-
-    AssertReturnVoid(idCpu < pVM->cCpus);
-
-    LogFlow(("pdmRCApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
-    switch (enmType)
-    {
-        case PDMAPICIRQ_HARDWARE:
-            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
-            break;
-        case PDMAPICIRQ_NMI:
-            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
-            break;
-        case PDMAPICIRQ_SMI:
-            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
-            break;
-        case PDMAPICIRQ_EXTINT:
-            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
-            break;
-        default:
-            AssertMsgFailed(("enmType=%d\n", enmType));
-            break;
-    }
-}
-
-
-/** @copydoc PDMAPICHLPRC::pfnClearInterruptFF */
-static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMRC;
-    PVMCPU pVCpu = &pVM->aCpus[idCpu];
-
-    AssertReturnVoid(idCpu < pVM->cCpus);
-
-    LogFlow(("pdmRCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
-
-    /* Note: NMI/SMI can't be cleared. */
-    switch (enmType)
-    {
-        case PDMAPICIRQ_HARDWARE:
-            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
-            break;
-        case PDMAPICIRQ_EXTINT:
-            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
-            break;
-        default:
-            AssertMsgFailed(("enmType=%d\n", enmType));
-            break;
-    }
-}
-
-
-/** @copydoc PDMAPICHLPRC::pfnChangeFeature */
-static DECLCALLBACK(void) pdmRCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmRCApicHlp_ChangeFeature: caller=%p/%d: version=%d\n", pDevIns, pDevIns->iInstance, (int)enmVersion));
-    switch (enmVersion)
-    {
-        case PDMAPICVERSION_NONE:
-            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
-            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
-            break;
-        case PDMAPICVERSION_APIC:
-            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
-            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
-            break;
-        case PDMAPICVERSION_X2APIC:
-            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_X2APIC);
-            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
-            break;
-        default:
-            AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
-    }
-}
-
-
-/** @copydoc PDMAPICHLPRC::pfnLock */
-static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
-}
-
-
-/** @copydoc PDMAPICHLPRC::pfnUnlock */
-static DECLCALLBACK(void) pdmRCApicHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMRC);
-}
-
-
-/** @copydoc PDMAPICHLPRC::pfnGetCpuId */
-static DECLCALLBACK(VMCPUID) pdmRCApicHlp_GetCpuId(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return VMMGetCpuId(pDevIns->Internal.s.pVMRC);
-}
-
-
-
-
-/** @copydoc PDMIOAPICHLPRC::pfnApicBusDeliver */
-static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                        uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMRC;
-    LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
-             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
-    if (pVM->pdm.s.Apic.pfnBusDeliverRC)
-        return pVM->pdm.s.Apic.pfnBusDeliverRC(pVM->pdm.s.Apic.pDevInsRC, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
-    return VINF_SUCCESS;
-}
-
-
-/** @copydoc PDMIOAPICHLPRC::pfnLock */
-static DECLCALLBACK(int) pdmRCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
-}
-
-
-/** @copydoc PDMIOAPICHLPRC::pfnUnlock */
-static DECLCALLBACK(void) pdmRCIoApicHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMRC);
-}
-
-
-
-
-/** @copydoc PDMPCIHLPRC::pfnIsaSetIrq */
-static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    pdmGCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
-}
-
-
-/** @copydoc PDMPCIHLPRC::pfnIoApicSetIrq */
-static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    pdmGCIoApicSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
-}
-
-
-/** @copydoc PDMPCIHLPRC::pfnLock */
-static DECLCALLBACK(int) pdmRCPciHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
-}
-
-
-/** @copydoc PDMPCIHLPRC::pfnUnlock */
-static DECLCALLBACK(void) pdmRCPciHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMRC);
-}
+/** @} */
 
 
@@ -636,5 +625,5 @@
  * @param   iLevel  The new level.
  */
-static void pdmGCIsaSetIrq(PVM pVM, int iIrq, int iLevel)
+static void pdmRCIsaSetIrq(PVM pVM, int iIrq, int iLevel)
 {
     if (    (   pVM->pdm.s.IoApic.pDevInsRC
@@ -676,5 +665,5 @@
  * @param   iLevel  The new level.
  */
-static void pdmGCIoApicSetIrq(PVM pVM, int iIrq, int iLevel)
+static void pdmRCIoApicSetIrq(PVM pVM, int iIrq, int iLevel)
 {
     if (pVM->pdm.s.IoApic.pDevInsRC)
@@ -702,17 +691,2 @@
 }
 
-
-/** @copydoc PDMHPETHLPRC::pfnLock */
-static DECLCALLBACK(int) pdmRCHpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
-}
-
-
-/** @copydoc PDMHPETHLPRC::pfnUnlock */
-static DECLCALLBACK(void) pdmRCHpetHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMRC);
-}
Index: /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 26000)
+++ /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 26001)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -58,72 +58,4 @@
 *   Internal Functions                                                         *
 *******************************************************************************/
-/** @name GC Device Helpers
- * @{
- */
-static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
-static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
-static DECLCALLBACK(int)  pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
-static DECLCALLBACK(int)  pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
-static DECLCALLBACK(bool) pdmR0DevHlp_A20IsEnabled(PPDMDEVINS pDevIns);
-static DECLCALLBACK(int)  pdmR0DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
-static DECLCALLBACK(int)  pdmR0DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
-static DECLCALLBACK(int)  pdmR0DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...);
-static DECLCALLBACK(int)  pdmR0DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va);
-static DECLCALLBACK(int)  pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData);
-static DECLCALLBACK(PVM)  pdmR0DevHlp_GetVM(PPDMDEVINS pDevIns);
-static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns);
-static DECLCALLBACK(PVMCPU) pdmR0DevHlp_GetVMCPU(PPDMDEVINS pDevIns);
-/** @} */
-
-
-/** @name PIC GC Helpers
- * @{
- */
-static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
-static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
-static DECLCALLBACK(int)  pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc);
-static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns);
-/** @} */
-
-
-/** @name APIC GC Helpers
- * @{
- */
-static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
-static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu);
-static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion);
-static DECLCALLBACK(int)  pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
-static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns);
-static DECLCALLBACK(VMCPUID) pdmR0ApicHlp_GetCpuId(PPDMDEVINS pDevIns);
-/** @} */
-
-
-/** @name I/O APIC GC Helpers
- * @{
- */
-static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                        uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);
-static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
-static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns);
-/** @} */
-
-
-/** @name PCI Bus GC Helpers
- * @{
- */
-static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
-static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
-static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc);
-static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns);
-/** @} */
-
-/** @name HPET GC Helpers
- * @{
- */
-static DECLCALLBACK(int) pdmR0HpetHlp_Lock(PPDMDEVINS pDevIns, int rc);
-static DECLCALLBACK(void) pdmR0HpetHlp_Unlock(PPDMDEVINS pDevIns);
-/** @} */
-
-
 static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel);
 static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel);
@@ -131,6 +63,186 @@
 
 
+
+/** @name Ring-0 Device Helpers
+ * @{
+ */
+
+/** @copydoc PDMDEVHLPR0::pfnPCISetIrq */
+static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
+
+    PVM          pVM     = pDevIns->Internal.s.pVMR0;
+    PPCIDEVICE   pPciDev = pDevIns->Internal.s.pPciDeviceR0;
+    PPDMPCIBUS   pPciBus = pDevIns->Internal.s.pPciBusR0;
+    if (    pPciDev
+        &&  pPciBus
+        &&  pPciBus->pDevInsR0)
+    {
+        pdmLock(pVM);
+        pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel);
+        pdmUnlock(pVM);
+    }
+    else
+    {
+        /* queue for ring-3 execution. */
+        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0);
+        if (pTask)
+        {
+            pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
+            pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
+            pTask->u.SetIRQ.iIrq = iIrq;
+            pTask->u.SetIRQ.iLevel = iLevel;
+
+            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
+        }
+        else
+            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
+    }
+
+    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnPCISetIrq */
+static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
+
+    pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
+
+    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnPhysRead */
+static DECLCALLBACK(int) pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_PhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
+             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
+
+    int rc = PGMPhysRead(pDevIns->Internal.s.pVMR0, GCPhys, pvBuf, cbRead);
+    AssertRC(rc); /** @todo track down the users for this bugger. */
+
+    Log(("pdmR0DevHlp_PhysRead: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnPhysWrite */
+static DECLCALLBACK(int) pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_PhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
+             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
+
+    int rc = PGMPhysWrite(pDevIns->Internal.s.pVMR0, GCPhys, pvBuf, cbWrite);
+    AssertRC(rc); /** @todo track down the users for this bugger. */
+
+    Log(("pdmR0DevHlp_PhysWrite: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnA20IsEnabled */
+static DECLCALLBACK(bool) pdmR0DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
+
+    bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu(pDevIns->Internal.s.pVMR0));
+
+    Log(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
+    return fEnabled;
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnVMSetError */
+static DECLCALLBACK(int) pdmR0DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    va_list args;
+    va_start(args, pszFormat);
+    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
+    va_end(args);
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnVMSetErrorV */
+static DECLCALLBACK(int) pdmR0DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnVMSetRuntimeError */
+static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    va_list va;
+    va_start(va, pszFormat);
+    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
+    va_end(va);
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnVMSetRuntimeErrorV */
+static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
+    return rc;
+}
+
+
+/** @copydoc PDMDEVHLPR0::pdmR0DevHlp_PATMSetMMIOPatchInfo*/
+static DECLCALLBACK(int) pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
+
+    AssertFailed();
+
+/*    return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMR0, GCPhys, pCachedData); */
+    return VINF_SUCCESS;
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnGetVM */
+static DECLCALLBACK(PVM)  pdmR0DevHlp_GetVM(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
+    return pDevIns->Internal.s.pVMR0;
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnCanEmulateIoBlock */
+static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
+    return HWACCMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0));
+}
+
+
+/** @copydoc PDMDEVHLPR0::pfnGetVMCPU */
+static DECLCALLBACK(PVMCPU) pdmR0DevHlp_GetVMCPU(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_GetVMCPU: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
+    return VMMGetCpu(pDevIns->Internal.s.pVMR0);
+}
+
+
 /**
- * The Guest Context Device Helper Callbacks.
+ * The Ring-0 Device Helper Callbacks.
  */
 extern DECLEXPORT(const PDMDEVHLPR0) g_pdmR0DevHlp =
@@ -153,6 +265,80 @@
 };
 
+/** @} */
+
+
+
+
+/** @name PIC Ring-0 Helpers
+ * @{
+ */
+
+/** @copydoc PDMPICHLPR0::pfnSetInterruptFF */
+static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM    pVM   = pDevIns->Internal.s.pVMR0;
+
+    if (pVM->pdm.s.Apic.pfnLocalInterruptR0)
+    {
+        LogFlow(("pdmR0PicHlp_SetInterruptFF: caller='%p'/%d: Setting local interrupt on LAPIC\n",
+                 pDevIns, pDevIns->iInstance));
+        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
+        pVM->pdm.s.Apic.pfnLocalInterruptR0(pVM->pdm.s.Apic.pDevInsR0, 0, 1);
+        return;
+    }
+
+    PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
+
+    LogFlow(("pdmR0PicHlp_SetInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
+
+    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+}
+
+
+/** @copydoc PDMPICHLPR0::pfnClearInterruptFF */
+static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM    pVM   = pDevIns->Internal.s.pVMR0;
+
+    if (pVM->pdm.s.Apic.pfnLocalInterruptR0)
+    {
+        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
+        LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
+                 pDevIns, pDevIns->iInstance));
+        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
+        pVM->pdm.s.Apic.pfnLocalInterruptR0(pVM->pdm.s.Apic.pDevInsR0, 0, 0);
+        return;
+    }
+
+    PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
+
+    LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
+
+    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+}
+
+
+/** @copydoc PDMPICHLPR0::pfnLock */
+static DECLCALLBACK(int) pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
+}
+
+
+/** @copydoc PDMPICHLPR0::pfnUnlock */
+static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    pdmUnlock(pDevIns->Internal.s.pVMR0);
+}
+
+
 /**
- * The Guest Context PIC Helper Callbacks.
+ * The Ring-0 PIC Helper Callbacks.
  */
 extern DECLEXPORT(const PDMPICHLPR0) g_pdmR0PicHlp =
@@ -166,7 +352,143 @@
 };
 
+/** @} */
+
+
+
+
+/** @name APIC Ring-0 Helpers
+ * @{
+ */
+
+/** @copydoc PDMAPICHLPR0::pfnSetInterruptFF */
+static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM    pVM   = pDevIns->Internal.s.pVMR0;
+    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+    AssertReturnVoid(idCpu < pVM->cCpus);
+
+    LogFlow(("pdmR0ApicHlp_SetInterruptFF: CPU%d=caller=%p/%d: VM_FF_INTERRUPT %d -> 1 (CPU%d)\n",
+             VMMGetCpuId(pVM), pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC), idCpu));
+
+    switch (enmType)
+    {
+        case PDMAPICIRQ_HARDWARE:
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+            break;
+        case PDMAPICIRQ_NMI:
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
+            break;
+        case PDMAPICIRQ_SMI:
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
+            break;
+        case PDMAPICIRQ_EXTINT:
+            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+            break;
+        default:
+            AssertMsgFailed(("enmType=%d\n", enmType));
+            break;
+    }
+
+    /* We need to wait up the target CPU. */
+    if (VMMGetCpuId(pVM) != idCpu)
+    {
+        switch (VMCPU_GET_STATE(pVCpu))
+        {
+            case VMCPUSTATE_STARTED_EXEC:
+                GVMMR0SchedPokeEx(pVM, pVCpu->idCpu, false /* don't take the used lock */);
+                break;
+
+            case VMCPUSTATE_STARTED_HALTED:
+                GVMMR0SchedWakeUpEx(pVM, pVCpu->idCpu, false /* don't take the used lock */);
+                break;
+
+            default:
+                break; /* nothing to do in other states. */
+        }
+    }
+}
+
+
+/** @copydoc PDMAPICHLPR0::pfnClearInterruptFF */
+static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM    pVM   = pDevIns->Internal.s.pVMR0;
+    PVMCPU pVCpu = &pVM->aCpus[idCpu];
+
+    AssertReturnVoid(idCpu < pVM->cCpus);
+
+    LogFlow(("pdmR0ApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
+             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
+
+    /* Note: NMI/SMI can't be cleared. */
+    switch (enmType)
+    {
+        case PDMAPICIRQ_HARDWARE:
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
+            break;
+        case PDMAPICIRQ_EXTINT:
+            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+            break;
+        default:
+            AssertMsgFailed(("enmType=%d\n", enmType));
+            break;
+    }
+}
+
+
+/** @copydoc PDMAPICHLPR0::pfnChangeFeature */
+static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0ApicHlp_ChangeFeature: caller=%p/%d: version=%d\n", pDevIns, pDevIns->iInstance, (int)enmVersion));
+    switch (enmVersion)
+    {
+        case PDMAPICVERSION_NONE:
+            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
+            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
+            break;
+        case PDMAPICVERSION_APIC:
+            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
+            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
+            break;
+        case PDMAPICVERSION_X2APIC:
+            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
+            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
+            break;
+        default:
+            AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
+    }
+}
+
+
+/** @copydoc PDMAPICHLPR0::pfnLock */
+static DECLCALLBACK(int) pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
+}
+
+
+/** @copydoc PDMAPICHLPR0::pfnUnlock */
+static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    pdmUnlock(pDevIns->Internal.s.pVMR0);
+}
+
+
+/** @copydoc PDMAPICHLPR0::pfnGetCpuId */
+static DECLCALLBACK(VMCPUID) pdmR0ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return VMMGetCpuId(pDevIns->Internal.s.pVMR0);
+}
+
 
 /**
- * The Guest Context APIC Helper Callbacks.
+ * The Ring-0 APIC Helper Callbacks.
  */
 extern DECLEXPORT(const PDMAPICHLPR0) g_pdmR0ApicHlp =
@@ -182,7 +504,46 @@
 };
 
+/** @} */
+
+
+
+
+/** @name I/O APIC Ring-0 Helpers
+ * @{
+ */
+
+/** @copydoc PDMIOAPICHLPR0::pfnApicBusDeliver */
+static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+                                                       uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMR0;
+    LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
+             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
+    Assert(pVM->pdm.s.Apic.pDevInsR0);
+    if (pVM->pdm.s.Apic.pfnBusDeliverR0)
+        return pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
+    return VINF_SUCCESS;
+}
+
+
+/** @copydoc PDMIOAPICHLPR0::pfnLock */
+static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
+}
+
+
+/** @copydoc PDMIOAPICHLPR0::pfnUnlock */
+static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    pdmUnlock(pDevIns->Internal.s.pVMR0);
+}
+
 
 /**
- * The Guest Context I/O APIC Helper Callbacks.
+ * The Ring-0 I/O APIC Helper Callbacks.
  */
 extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp =
@@ -195,7 +556,49 @@
 };
 
+/** @} */
+
+
+
+
+/** @name PCI Bus Ring-0 Helpers
+ * @{
+ */
+
+/** @copydoc PDMPCIHLPR0::pfnIsaSetIrq */
+static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
+    pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
+}
+
+
+/** @copydoc PDMPCIHLPR0::pfnIoApicSetIrq */
+static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    Log4(("pdmR0PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
+    pdmR0IoApicSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
+}
+
+
+/** @copydoc PDMPCIHLPR0::pfnLock */
+static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
+}
+
+
+/** @copydoc PDMPCIHLPR0::pfnUnlock */
+static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    pdmUnlock(pDevIns->Internal.s.pVMR0);
+}
+
 
 /**
- * The Guest Context PCI Bus Helper Callbacks.
+ * The Ring-0 PCI Bus Helper Callbacks.
  */
 extern DECLEXPORT(const PDMPCIHLPR0) g_pdmR0PciHlp =
@@ -209,6 +612,31 @@
 };
 
+/** @} */
+
+
+
+
+/** @name HPET Ring-0 Helpers
+ * @{
+ */
+
+/** @copydoc PDMHPETHLPR0::pfnLock */
+static DECLCALLBACK(int) pdmR0HpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
+}
+
+
+/** @copydoc PDMHPETHLPR0::pfnUnlock */
+static DECLCALLBACK(void) pdmR0HpetHlp_Unlock(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    pdmUnlock(pDevIns->Internal.s.pVMR0);
+}
+
+
 /**
- * The Guest Context HPET Helper Callbacks.
+ * The Ring-0 HPET Helper Callbacks.
  */
 extern DECLEXPORT(const PDMHPETHLPR0) g_pdmR0HpetHlp =
@@ -220,446 +648,5 @@
 };
 
-
-/** @copydoc PDMDEVHLPR0::pfnPCISetIrq */
-static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
-
-    PVM          pVM     = pDevIns->Internal.s.pVMR0;
-    PPCIDEVICE   pPciDev = pDevIns->Internal.s.pPciDeviceR0;
-    PPDMPCIBUS   pPciBus = pDevIns->Internal.s.pPciBusR0;
-    if (    pPciDev
-        &&  pPciBus
-        &&  pPciBus->pDevInsR0)
-    {
-        pdmLock(pVM);
-        pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel);
-        pdmUnlock(pVM);
-    }
-    else
-    {
-        /* queue for ring-3 execution. */
-        PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueR0);
-        if (pTask)
-        {
-            pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
-            pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
-            pTask->u.SetIRQ.iIrq = iIrq;
-            pTask->u.SetIRQ.iLevel = iLevel;
-
-            PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
-        }
-        else
-            AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
-    }
-
-    LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnPCISetIrq */
-static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
-
-    pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
-
-    LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnPhysRead */
-static DECLCALLBACK(int) pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0DevHlp_PhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
-             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
-
-    int rc = PGMPhysRead(pDevIns->Internal.s.pVMR0, GCPhys, pvBuf, cbRead);
-    AssertRC(rc); /** @todo track down the users for this bugger. */
-
-    Log(("pdmR0DevHlp_PhysRead: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnPhysWrite */
-static DECLCALLBACK(int) pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0DevHlp_PhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
-             pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
-
-    int rc = PGMPhysWrite(pDevIns->Internal.s.pVMR0, GCPhys, pvBuf, cbWrite);
-    AssertRC(rc); /** @todo track down the users for this bugger. */
-
-    Log(("pdmR0DevHlp_PhysWrite: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, rc));
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnA20IsEnabled */
-static DECLCALLBACK(bool) pdmR0DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
-
-    bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu(pDevIns->Internal.s.pVMR0));
-
-    Log(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
-    return fEnabled;
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnVMSetError */
-static DECLCALLBACK(int) pdmR0DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    va_list args;
-    va_start(args, pszFormat);
-    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
-    va_end(args);
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnVMSetErrorV */
-static DECLCALLBACK(int) pdmR0DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnVMSetRuntimeError */
-static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    va_list va;
-    va_start(va, pszFormat);
-    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
-    va_end(va);
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnVMSetRuntimeErrorV */
-static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
-    return rc;
-}
-
-
-/** @copydoc PDMDEVHLPR0::pdmR0DevHlp_PATMSetMMIOPatchInfo*/
-static DECLCALLBACK(int) pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0DevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
-
-    AssertFailed();
-
-/*    return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMR0, GCPhys, pCachedData); */
-    return VINF_SUCCESS;
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnGetVM */
-static DECLCALLBACK(PVM)  pdmR0DevHlp_GetVM(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return pDevIns->Internal.s.pVMR0;
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnCanEmulateIoBlock */
-static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return HWACCMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0));
-}
-
-
-/** @copydoc PDMDEVHLPR0::pfnGetVMCPU */
-static DECLCALLBACK(PVMCPU) pdmR0DevHlp_GetVMCPU(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0DevHlp_GetVMCPU: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return VMMGetCpu(pDevIns->Internal.s.pVMR0);
-}
-
-
-
-
-/** @copydoc PDMPICHLPR0::pfnSetInterruptFF */
-static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM    pVM   = pDevIns->Internal.s.pVMR0;
-
-    if (pVM->pdm.s.Apic.pfnLocalInterruptR0)
-    {
-        LogFlow(("pdmR0PicHlp_SetInterruptFF: caller='%p'/%d: Setting local interrupt on LAPIC\n",
-                 pDevIns, pDevIns->iInstance));
-        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        pVM->pdm.s.Apic.pfnLocalInterruptR0(pVM->pdm.s.Apic.pDevInsR0, 0, 1);
-        return;
-    }
-
-    PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
-
-    LogFlow(("pdmR0PicHlp_SetInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
-
-    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
-}
-
-
-/** @copydoc PDMPICHLPR0::pfnClearInterruptFF */
-static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM    pVM   = pDevIns->Internal.s.pVMR0;
-
-    if (pVM->pdm.s.Apic.pfnLocalInterruptR0)
-    {
-        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
-                 pDevIns, pDevIns->iInstance));
-        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        pVM->pdm.s.Apic.pfnLocalInterruptR0(pVM->pdm.s.Apic.pDevInsR0, 0, 0);
-        return;
-    }
-
-    PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
-
-    LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
-
-    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
-}
-
-
-/** @copydoc PDMPICHLPR0::pfnLock */
-static DECLCALLBACK(int) pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
-}
-
-
-/** @copydoc PDMPICHLPR0::pfnUnlock */
-static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMR0);
-}
-
-
-
-/** @copydoc PDMAPICHLPR0::pfnSetInterruptFF */
-static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM    pVM   = pDevIns->Internal.s.pVMR0;
-    PVMCPU pVCpu = &pVM->aCpus[idCpu];
-
-    AssertReturnVoid(idCpu < pVM->cCpus);
-
-    LogFlow(("pdmR0ApicHlp_SetInterruptFF: CPU%d=caller=%p/%d: VM_FF_INTERRUPT %d -> 1 (CPU%d)\n",
-             VMMGetCpuId(pVM), pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC), idCpu));
-
-    switch (enmType)
-    {
-        case PDMAPICIRQ_HARDWARE:
-            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
-            break;
-        case PDMAPICIRQ_NMI:
-            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
-            break;
-        case PDMAPICIRQ_SMI:
-            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
-            break;
-        case PDMAPICIRQ_EXTINT:
-            VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
-            break;
-        default:
-            AssertMsgFailed(("enmType=%d\n", enmType));
-            break;
-    }
-
-    /* We need to wait up the target CPU. */
-    if (VMMGetCpuId(pVM) != idCpu)
-    {
-        switch (VMCPU_GET_STATE(pVCpu))
-        {
-            case VMCPUSTATE_STARTED_EXEC:
-                GVMMR0SchedPokeEx(pVM, pVCpu->idCpu, false /* don't take the used lock */);
-                break;
-
-            case VMCPUSTATE_STARTED_HALTED:
-                GVMMR0SchedWakeUpEx(pVM, pVCpu->idCpu, false /* don't take the used lock */);
-                break;
-
-            default:
-                break; /* nothing to do in other states. */
-        }
-    }
-}
-
-
-/** @copydoc PDMAPICHLPR0::pfnClearInterruptFF */
-static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM    pVM   = pDevIns->Internal.s.pVMR0;
-    PVMCPU pVCpu = &pVM->aCpus[idCpu];
-
-    AssertReturnVoid(idCpu < pVM->cCpus);
-
-    LogFlow(("pdmR0ApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
-
-    /* Note: NMI/SMI can't be cleared. */
-    switch (enmType)
-    {
-        case PDMAPICIRQ_HARDWARE:
-            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
-            break;
-        case PDMAPICIRQ_EXTINT:
-            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
-            break;
-        default:
-            AssertMsgFailed(("enmType=%d\n", enmType));
-            break;
-    }
-}
-
-
-/** @copydoc PDMAPICHLPR0::pfnChangeFeature */
-static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    LogFlow(("pdmR0ApicHlp_ChangeFeature: caller=%p/%d: version=%d\n", pDevIns, pDevIns->iInstance, (int)enmVersion));
-    switch (enmVersion)
-    {
-        case PDMAPICVERSION_NONE:
-            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
-            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
-            break;
-        case PDMAPICVERSION_APIC:
-            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
-            CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
-            break;
-        case PDMAPICVERSION_X2APIC:
-            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_X2APIC);
-            CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR0, CPUMCPUIDFEATURE_APIC);
-            break;
-        default:
-            AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
-    }
-}
-
-
-/** @copydoc PDMAPICHLPR0::pfnLock */
-static DECLCALLBACK(int) pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
-}
-
-
-/** @copydoc PDMAPICHLPR0::pfnUnlock */
-static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMR0);
-}
-
-
-/** @copydoc PDMAPICHLPR0::pfnGetCpuId */
-static DECLCALLBACK(VMCPUID) pdmR0ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return VMMGetCpuId(pDevIns->Internal.s.pVMR0);
-}
-
-
-
-
-
-/** @copydoc PDMIOAPICHLPR0::pfnApicBusDeliver */
-static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                        uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMR0;
-    LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
-             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
-    Assert(pVM->pdm.s.Apic.pDevInsR0);
-    if (pVM->pdm.s.Apic.pfnBusDeliverR0)
-        return pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
-    return VINF_SUCCESS;
-}
-
-
-/** @copydoc PDMIOAPICHLPR0::pfnLock */
-static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
-}
-
-
-/** @copydoc PDMIOAPICHLPR0::pfnUnlock */
-static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMR0);
-}
-
-
-
-
-
-/** @copydoc PDMPCIHLPR0::pfnIsaSetIrq */
-static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    pdmR0IsaSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
-}
-
-
-/** @copydoc PDMPCIHLPR0::pfnIoApicSetIrq */
-static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
-    pdmR0IoApicSetIrq(pDevIns->Internal.s.pVMR0, iIrq, iLevel);
-}
-
-
-/** @copydoc PDMPCIHLPR0::pfnLock */
-static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
-}
-
-
-/** @copydoc PDMPCIHLPR0::pfnUnlock */
-static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMR0);
-}
-
+/** @} */
 
 
@@ -738,16 +725,2 @@
 }
 
-/** @copydoc PDMHPETHLPR0::pfnLock */
-static DECLCALLBACK(int) pdmR0HpetHlp_Lock(PPDMDEVINS pDevIns, int rc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
-}
-
-
-/** @copydoc PDMHPETHLPR0::pfnUnlock */
-static DECLCALLBACK(void) pdmR0HpetHlp_Unlock(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMR0);
-}
