Index: /trunk/include/VBox/sup.h
===================================================================
--- /trunk/include/VBox/sup.h	(revision 80530)
+++ /trunk/include/VBox/sup.h	(revision 80531)
@@ -1977,4 +1977,10 @@
 SUPR0DECL(int) SUPR0PageFree(PSUPDRVSESSION pSession, RTR3PTR pvR3);
 SUPR0DECL(int) SUPR0GipMap(PSUPDRVSESSION pSession, PRTR3PTR ppGipR3, PRTHCPHYS pHCPhysGip);
+SUPR0DECL(int) SUPR0LdrLock(PSUPDRVSESSION pSession);
+SUPR0DECL(int) SUPR0LdrUnlock(PSUPDRVSESSION pSession);
+SUPR0DECL(bool) SUPR0LdrIsLockOwnerByMod(void *hMod, bool fWantToHear);
+SUPR0DECL(int) SUPR0LdrModByName(PSUPDRVSESSION pSession, const char *pszName, void **phMod);
+SUPR0DECL(int) SUPR0LdrModRetain(PSUPDRVSESSION pSession, void *hMod);
+SUPR0DECL(int) SUPR0LdrModRelease(PSUPDRVSESSION pSession, void *hMod);
 SUPR0DECL(int) SUPR0GetVTSupport(uint32_t *pfCaps);
 SUPR0DECL(int) SUPR0GetHwvirtMsrs(PSUPHWVIRTMSRS pMsrs, uint32_t fCaps, bool fForce);
Index: /trunk/include/VBox/types.h
===================================================================
--- /trunk/include/VBox/types.h	(revision 80530)
+++ /trunk/include/VBox/types.h	(revision 80531)
@@ -365,4 +365,18 @@
 
 
+/** A cross context I/O port range handle. */
+typedef uint64_t                IOMIOPORTHANDLE;
+/** Pointer to a cross context I/O port handle. */
+typedef IOMIOPORTHANDLE        *PIOMIOPORTHANDLE;
+/** A NIL I/O port handle. */
+#define NIL_IOMIOPORTHANDLE     ((uint64_t)UINT64_MAX)
+
+/** A cross context MMIO range handle. */
+typedef uint64_t                IOMMMIOHANDLE;
+/** Pointer to a cross context MMIO handle. */
+typedef IOMMMIOHANDLE          *PIOMMMIOHANDLE;
+/** A NIL MMIO handle. */
+#define NIL_IOMMMIOHANDLE       ((uint64_t)UINT64_MAX)
+
 /** Pointer to a PDM Base Interface. */
 typedef struct PDMIBASE *PPDMIBASE;
@@ -370,14 +384,20 @@
 typedef PPDMIBASE *PPPDMIBASE;
 
-/** Pointer to a PDM Device Instance. */
-typedef struct PDMDEVINS *PPDMDEVINS;
-/** Pointer to a pointer to a PDM Device Instance. */
+/** Pointer to a PDM device instance for the current context. */
+#ifdef IN_RING3
+typedef struct PDMDEVINSR3 *PPDMDEVINS;
+#elif defined(IN_RING0) || defined(DOXYGEN_RUNNING)
+typedef struct PDMDEVINSR0 *PPDMDEVINS;
+#else
+typedef struct PDMDEVINSRC *PPDMDEVINS;
+#endif
+/** Pointer to a pointer a PDM device instance for the current context. */
 typedef PPDMDEVINS *PPPDMDEVINS;
-/** R3 pointer to a PDM Device Instance. */
-typedef R3PTRTYPE(PPDMDEVINS) PPDMDEVINSR3;
-/** R0 pointer to a PDM Device Instance. */
-typedef R0PTRTYPE(PPDMDEVINS) PPDMDEVINSR0;
-/** RC pointer to a PDM Device Instance. */
-typedef RCPTRTYPE(PPDMDEVINS) PPDMDEVINSRC;
+/** R3 pointer to a PDM device instance. */
+typedef R3PTRTYPE(struct PDMDEVINSR3 *) PPDMDEVINSR3;
+/** R0 pointer to a PDM device instance. */
+typedef R0PTRTYPE(struct PDMDEVINSR0 *) PPDMDEVINSR0;
+/** RC pointer to a PDM device instance. */
+typedef RCPTRTYPE(struct PDMDEVINSRC *) PPDMDEVINSRC;
 
 /** Pointer to a PDM PCI device structure. */
@@ -431,7 +451,14 @@
 
 /** Pointer to a timer. */
-typedef CTX_SUFF(PTMTIMER)     PTMTIMER;
+typedef CTX_SUFF(PTMTIMER) PTMTIMER;
 /** Pointer to a pointer to a timer. */
-typedef PTMTIMER              *PPTMTIMER;
+typedef PTMTIMER *PPTMTIMER;
+
+/** A cross context timer handle. */
+typedef uint64_t TMTIMERHANDLE;
+/** Pointer to a cross context timer handle. */
+typedef TMTIMERHANDLE *PTMTIMERHANDLE;
+/** A NIL timer handle. */
+#define NIL_TMTIMERHANDLE ((uint64_t)UINT64_MAX)
 
 /** SSM Operation handle. */
Index: /trunk/include/VBox/vmm/apic.h
===================================================================
--- /trunk/include/VBox/vmm/apic.h	(revision 80530)
+++ /trunk/include/VBox/vmm/apic.h	(revision 80531)
@@ -157,13 +157,7 @@
 RT_C_DECLS_BEGIN
 
-#ifdef IN_RING3
-/** @defgroup grp_apic_r3  The APIC Host Context Ring-3 API
- * @{
- */
-VMMR3_INT_DECL(int)         APICR3RegisterDevice(struct PDMDEVREGCB *pCallbacks);
-VMMR3_INT_DECL(void)        APICR3InitIpi(PVMCPU pVCpu);
-VMMR3_INT_DECL(void)        APICR3HvEnable(PVM pVM);
-/** @} */
-#endif /* IN_RING3 */
+#ifdef VBOX_INCLUDED_vmm_pdmdev_h
+extern const PDMDEVREG g_DeviceAPIC;
+#endif
 
 /* These functions are exported as they are called from external modules (recompiler). */
@@ -202,4 +196,14 @@
 /** @} */
 
+#ifdef IN_RING3
+/** @defgroup grp_apic_r3  The APIC Host Context Ring-3 API
+ * @{
+ */
+VMMR3_INT_DECL(int)         APICR3RegisterDevice(struct PDMDEVREGCB *pCallbacks);
+VMMR3_INT_DECL(void)        APICR3InitIpi(PVMCPU pVCpu);
+VMMR3_INT_DECL(void)        APICR3HvEnable(PVM pVM);
+/** @} */
+#endif /* IN_RING3 */
+
 RT_C_DECLS_END
 
Index: /trunk/include/VBox/vmm/gvm.h
===================================================================
--- /trunk/include/VBox/vmm/gvm.h	(revision 80530)
+++ /trunk/include/VBox/vmm/gvm.h	(revision 80531)
@@ -197,9 +197,17 @@
     } rawpci;
 
+    union
+    {
+#if defined(VMM_INCLUDED_SRC_include_PDMInternal_h) && defined(IN_RING0)
+        struct PDMR0PERVM   s;
+#endif
+        uint8_t             padding[1536];
+    } pdmr0;
+
     /** Padding so aCpus starts on a page boundrary.  */
 #ifdef VBOX_WITH_NEM_R0
-    uint8_t         abPadding2[4096 - 64 - 256 - 512 - 256 - 64 - sizeof(PGVMCPU) * VMM_MAX_CPU_COUNT];
-#else
-    uint8_t         abPadding2[4096 - 64 - 256 - 512       - 64 - sizeof(PGVMCPU) * VMM_MAX_CPU_COUNT];
+    uint8_t         abPadding2[4096 - 64 - 256 - 512 - 256 - 64 - 1536 - sizeof(PGVMCPU) * VMM_MAX_CPU_COUNT];
+#else
+    uint8_t         abPadding2[4096 - 64 - 256 - 512       - 64 - 1536 - sizeof(PGVMCPU) * VMM_MAX_CPU_COUNT];
 #endif
 
@@ -223,4 +231,5 @@
 #endif
 AssertCompileMemberAlignment(GVM, rawpci,   64);
+AssertCompileMemberAlignment(GVM, pdmr0,    64);
 AssertCompileMemberAlignment(GVM, aCpus,    4096);
 AssertCompileSizeAlignment(GVM,             4096);
Index: /trunk/include/VBox/vmm/pdmapi.h
===================================================================
--- /trunk/include/VBox/vmm/pdmapi.h	(revision 80530)
+++ /trunk/include/VBox/vmm/pdmapi.h	(revision 80531)
@@ -131,4 +131,5 @@
 VMMR3DECL(int)          PDMR3LdrEnumModules(PVM pVM, PFNPDMR3ENUM pfnCallback, void *pvArg);
 VMMR3_INT_DECL(void)    PDMR3LdrRelocateU(PUVM pUVM, RTGCINTPTR offDelta);
+VMMR3_INT_DECL(int)     PDMR3LdrLoadR0(PUVM pUVM, const char *pszModule);
 VMMR3_INT_DECL(int)     PDMR3LdrGetSymbolR3(PVM pVM, const char *pszModule, const char *pszSymbol, void **ppvValue);
 VMMR3DECL(int)          PDMR3LdrGetSymbolR0(PVM pVM, const char *pszModule, const char *pszSymbol, PRTR0PTR ppvValue);
@@ -190,4 +191,10 @@
  * @{
  */
+VMMR0_INT_DECL(void)    PDMR0Init(void *hMod);
+VMMR0DECL(int)          PDMR0DeviceRegisterModule(void *hMod, struct PDMDEVMODREGR0 *pModReg);
+VMMR0DECL(int)          PDMR0DeviceDeregisterModule(void *hMod, struct PDMDEVMODREGR0 *pModReg);
+
+VMMR0_INT_DECL(void)    PDMR0InitPerVMData(PGVM pGVM);
+VMMR0_INT_DECL(void)    PDMR0CleanupVM(PGVM pGVM);
 
 /**
@@ -239,4 +246,124 @@
 VMMR0_INT_DECL(int) PDMR0DeviceCallReqHandler(PGVM pGVM, PPDMDEVICECALLREQHANDLERREQ pReq);
 
+
+/**
+ * Request buffer for PDMR0DeviceCreateReqHandler / VMMR0_DO_PDM_DEVICE_CREATE.
+ * @see PDMR0DeviceCreateReqHandler.
+ */
+typedef struct PDMDEVICECREATEREQ
+{
+    /** The header. */
+    SUPVMMR0REQHDR          Hdr;
+    /** Out: Where to return the address of the ring-3 device instance. */
+    PPDMDEVINSR3            pDevInsR3;
+
+    /** Copy of PDMDEVREGR3::fFlags for matching with PDMDEVREGR0::fFlags. */
+    uint32_t                fFlags;
+    /** Copy of PDMDEVREGR3::fClass for matching with PDMDEVREGR0::fFlags. */
+    uint32_t                fClass;
+    /** Copy of PDMDEVREGR3::cMaxInstances for matching with
+     *  PDMDEVREGR0::cMaxInstances. */
+    uint32_t                cMaxInstances;
+    /** Copy of PDMDEVREGR3::uSharedVersion for matching with
+     *  PDMDEVREGR0::uSharedVersion. */
+    uint32_t                uSharedVersion;
+    /** Copy of PDMDEVREGR3::cbInstanceShared for matching with
+     *  PDMDEVREGR0::cbInstanceShared. */
+    uint32_t                cbInstanceShared;
+    /** Copy of PDMDEVREGR3::cbInstanceCC. */
+    uint32_t                cbInstanceR3;
+    /** Copy of PDMDEVREGR3::cbInstanceRC for matching with
+     *  PDMDEVREGR0::cbInstanceRC. */
+    uint32_t                cbInstanceRC;
+
+    /** The device instance ordinal. */
+    uint32_t                iInstance;
+    /** Set if the raw-mode component is desired. */
+    bool                    fRCEnabled;
+    /** Explicit padding. */
+    bool                    afReserved[3];
+
+    /** In: Device name. */
+    char                    szDevName[32];
+    /** In: The module name (no path). */
+    char                    szModName[32];
+} PDMDEVICECREATEREQ;
+/** Pointer to a PDMR0DeviceCreate / VMMR0_DO_PDM_DEVICE_CREATE request buffer. */
+typedef PDMDEVICECREATEREQ *PPDMDEVICECREATEREQ;
+
+VMMR0_INT_DECL(int) PDMR0DeviceCreateReqHandler(PGVM pGVM, PPDMDEVICECREATEREQ pReq);
+
+/**
+ * The ring-0 device call to make.
+ */
+typedef enum PDMDEVICEGENCALL
+{
+    PDMDEVICEGENCALL_INVALID = 0,
+    PDMDEVICEGENCALL_CONSTRUCT,
+    PDMDEVICEGENCALL_DESTRUCT,
+    PDMDEVICEGENCALL_END,
+    PDMDEVICEGENCALL_32BIT_HACK = 0x7fffffff
+} PDMDEVICEGENCALL;
+
+/**
+ * Request buffer for PDMR0DeviceGenCallReqHandler / VMMR0_DO_PDM_DEVICE_GEN_CALL.
+ * @see PDMR0DeviceGenCallReqHandler.
+ */
+typedef struct PDMDEVICEGENCALLREQ
+{
+    /** The header. */
+    SUPVMMR0REQHDR          Hdr;
+    /** The ring-3 device instance. */
+    PPDMDEVINSR3            pDevInsR3;
+    /** The ring-0 device handle. */
+    uint32_t                idxR0Device;
+    /** The call to make. */
+    PDMDEVICEGENCALL        enmCall;
+} PDMDEVICEGENCALLREQ;
+/** Pointer to a PDMR0DeviceGenCallReqHandler / VMMR0_DO_PDM_DEVICE_GEN_CALL request buffer. */
+typedef PDMDEVICEGENCALLREQ *PPDMDEVICEGENCALLREQ;
+
+VMMR0_INT_DECL(int) PDMR0DeviceGenCallReqHandler(PGVM pGVM, PPDMDEVICEGENCALLREQ pReq);
+
+/**
+ * Request buffer for PDMR0DeviceCompatSetCritSectReqHandler / VMMR0_DO_PDM_DEVICE_COMPAT_SET_CRITSECT
+ * @see PDMR0DeviceCompatSetCritSectReqHandler.
+ */
+typedef struct PDMDEVICECOMPATSETCRITSECTREQ
+{
+    /** The header. */
+    SUPVMMR0REQHDR          Hdr;
+    /** The ring-3 device instance. */
+    PPDMDEVINSR3            pDevInsR3;
+    /** The ring-0 device handle. */
+    uint32_t                idxR0Device;
+    /** The critical section address (ring-3). */
+    R3PTRTYPE(PPDMCRITSECT) pCritSectR3;
+} PDMDEVICECOMPATSETCRITSECTREQ;
+/** Pointer to a PDMR0DeviceGenCallReqHandler / VMMR0_DO_PDM_DEVICE_GEN_CALL request buffer. */
+typedef PDMDEVICECOMPATSETCRITSECTREQ *PPDMDEVICECOMPATSETCRITSECTREQ;
+
+VMMR0_INT_DECL(int) PDMR0DeviceCompatSetCritSectReqHandler(PGVM pGVM, PPDMDEVICECOMPATSETCRITSECTREQ pReq);
+
+/**
+ * Request buffer for PDMR0DeviceCompatRegPciDevReqHandler / VMMR0_DO_PDM_DEVICE_COMPAT_REG_PCIDEV
+ * @see PDMR0DeviceCompatRegPciDevReqHandler.
+ */
+typedef struct PDMDEVICECOMPATREGPCIDEVREQ
+{
+    /** The header. */
+    SUPVMMR0REQHDR          Hdr;
+    /** The ring-3 device instance. */
+    PPDMDEVINSR3            pDevInsR3;
+    /** The ring-0 device handle. */
+    uint32_t                idxR0Device;
+    /** The PCI device address (ring-3). */
+    R3PTRTYPE(PPDMPCIDEV)   pPciDevR3;
+} PDMDEVICECOMPATREGPCIDEVREQ;
+/** Pointer to a PDMR0DeviceGenCallReqHandler / VMMR0_DO_PDM_DEVICE_GEN_CALL request buffer. */
+typedef PDMDEVICECOMPATREGPCIDEVREQ *PPDMDEVICECOMPATREGPCIDEVREQ;
+
+VMMR0_INT_DECL(int) PDMR0DeviceCompatRegPciDevReqHandler(PGVM pGVM, PPDMDEVICECOMPATREGPCIDEVREQ pReq);
+
 /** @} */
 
Index: /trunk/include/VBox/vmm/pdmdev.h
===================================================================
--- /trunk/include/VBox/vmm/pdmdev.h	(revision 80530)
+++ /trunk/include/VBox/vmm/pdmdev.h	(revision 80531)
@@ -46,4 +46,5 @@
 #include <VBox/err.h>  /* VINF_EM_DBG_STOP, also 120+ source files expecting this. */
 #include <iprt/stdarg.h>
+#include <iprt/list.h>
 
 
@@ -305,21 +306,15 @@
  * This structure is used when registering a device from VBoxInitDevices() in HC
  * Ring-3.  PDM will continue use till the VM is terminated.
- */
-typedef struct PDMDEVREG
-{
-    /** Structure version. PDM_DEVREG_VERSION defines the current version. */
+ *
+ * @note The first part is the same in every context.
+ */
+typedef struct PDMDEVREGR3
+{
+    /** Structure version.  PDM_DEVREGR3_VERSION defines the current version. */
     uint32_t            u32Version;
-    /** Device name. */
+    /** Reserved, must be zero. */
+    uint32_t            uReserved0;
+    /** Device name, must match the ring-3 one. */
     char                szName[32];
-    /** Name of the raw-mode context module (no path).
-     * Only evalutated if PDM_DEVREG_FLAGS_RC is set. */
-    char                szRCMod[32];
-    /** Name of the ring-0 module (no path).
-     * Only evalutated if PDM_DEVREG_FLAGS_R0 is set. */
-    char                szR0Mod[32];
-    /** The description of the device. The UTF-8 string pointed to shall, like this structure,
-     * remain unchanged from registration till VM destruction. */
-    const char         *pszDescription;
-
     /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
     uint32_t            fFlags;
@@ -328,6 +323,24 @@
     /** Maximum number of instances (per VM). */
     uint32_t            cMaxInstances;
+    /** The shared data structure version number. */
+    uint32_t            uSharedVersion;
     /** Size of the instance data. */
-    uint32_t            cbInstance;
+    uint32_t            cbInstanceShared;
+    /** Size of the ring-0 instance data. */
+    uint32_t            cbInstanceCC;
+    /** Size of the raw-mode instance data. */
+    uint32_t            cbInstanceRC;
+    /** Reserved, must be zero. */
+    uint32_t            uReserved1;
+    /** The description of the device. The UTF-8 string pointed to shall, like this structure,
+     * remain unchanged from registration till VM destruction. */
+    const char         *pszDescription;
+
+    /** Name of the raw-mode context module (no path).
+     * Only evalutated if PDM_DEVREG_FLAGS_RC is set. */
+    const char         *pszRCMod;
+    /** Name of the ring-0 module (no path).
+     * Only evalutated if PDM_DEVREG_FLAGS_R0 is set. */
+    const char         *pszR0Mod;
 
     /** Construct instance - required. */
@@ -339,5 +352,4 @@
      * Critical section NOT entered. */
     PFNPDMDEVRELOCATE   pfnRelocate;
-
     /**
      * Memory setup callback.
@@ -348,5 +360,4 @@
      */
     DECLR3CALLBACKMEMBER(void, pfnMemSetup, (PPDMDEVINS pDevIns, PDMDEVMEMSETUPCTX enmCtx));
-
     /** Power on notification - optional.
      * Critical section is entered. */
@@ -379,66 +390,89 @@
      * Critical section is entered. */
     PFNPDMDEVSOFTRESET  pfnSoftReset;
+
+    /** @name Reserved for future extensions, must be zero.
+     * @{ */
+    DECLR3CALLBACKMEMBER(int, pfnReserved0, (PPDMDEVINS pDevIns));
+    DECLR3CALLBACKMEMBER(int, pfnReserved1, (PPDMDEVINS pDevIns));
+    DECLR3CALLBACKMEMBER(int, pfnReserved2, (PPDMDEVINS pDevIns));
+    DECLR3CALLBACKMEMBER(int, pfnReserved3, (PPDMDEVINS pDevIns));
+    DECLR3CALLBACKMEMBER(int, pfnReserved4, (PPDMDEVINS pDevIns));
+    DECLR3CALLBACKMEMBER(int, pfnReserved5, (PPDMDEVINS pDevIns));
+    DECLR3CALLBACKMEMBER(int, pfnReserved6, (PPDMDEVINS pDevIns));
+    DECLR3CALLBACKMEMBER(int, pfnReserved7, (PPDMDEVINS pDevIns));
+    /** @} */
+
     /** Initialization safty marker. */
     uint32_t            u32VersionEnd;
-} PDMDEVREG;
+} PDMDEVREGR3;
 /** Pointer to a PDM Device Structure. */
-typedef PDMDEVREG *PPDMDEVREG;
+typedef PDMDEVREGR3 *PPDMDEVREGR3;
 /** Const pointer to a PDM Device Structure. */
-typedef PDMDEVREG const *PCPDMDEVREG;
-
-/** Current DEVREG version number. */
-#define PDM_DEVREG_VERSION                      PDM_VERSION_MAKE(0xffff, 2, 1)
+typedef PDMDEVREGR3 const *PCPDMDEVREGR3;
+/** Current DEVREGR3 version number. */
+#define PDM_DEVREGR3_VERSION                    PDM_VERSION_MAKE(0xffff, 3, 0)
+
 
 /** PDM Device Flags.
  * @{ */
+/** This flag is used to indicate that the device has a R0 component. */
+#define PDM_DEVREG_FLAGS_R0                             UINT32_C(0x00000001)
+/** Requires the ring-0 component, ignore configuration values. */
+#define PDM_DEVREG_FLAGS_REQUIRE_R0                     UINT32_C(0x00000002)
+/** Requires the ring-0 component, ignore configuration values. */
+#define PDM_DEVREG_FLAGS_OPT_IN_R0                      UINT32_C(0x00000004)
+
 /** This flag is used to indicate that the device has a RC component. */
-#define PDM_DEVREG_FLAGS_RC                     0x00000001
-/** This flag is used to indicate that the device has a R0 component. */
-#define PDM_DEVREG_FLAGS_R0                     0x00000002
+#define PDM_DEVREG_FLAGS_RC                             UINT32_C(0x00000010)
+/** Requires the raw-mode component, ignore configuration values. */
+#define PDM_DEVREG_FLAGS_REQUIRE_RC                     UINT32_C(0x00000020)
+/** Requires the raw-mode component, ignore configuration values. */
+#define PDM_DEVREG_FLAGS_OPT_IN_RC                      UINT32_C(0x00000040)
 
 /** @def PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT
- * The bit count for the current host. */
+ * The bit count for the current host.
+ * @note Superfluous, but still around for hysterical raisins.  */
 #if HC_ARCH_BITS == 32
-# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT     0x00000010
+# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT             UINT32_C(0x00000100)
 #elif HC_ARCH_BITS == 64
-# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT     0x00000020
+# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT             UINT32_C(0x00000200)
 #else
 # error Unsupported HC_ARCH_BITS value.
 #endif
 /** The host bit count mask. */
-#define PDM_DEVREG_FLAGS_HOST_BITS_MASK         0x00000030
+#define PDM_DEVREG_FLAGS_HOST_BITS_MASK                 UINT32_C(0x00000300)
 
 /** The device support only 32-bit guests. */
-#define PDM_DEVREG_FLAGS_GUEST_BITS_32          0x00000100
+#define PDM_DEVREG_FLAGS_GUEST_BITS_32                  UINT32_C(0x00001000)
 /** The device support only 64-bit guests. */
-#define PDM_DEVREG_FLAGS_GUEST_BITS_64          0x00000200
+#define PDM_DEVREG_FLAGS_GUEST_BITS_64                  UINT32_C(0x00002000)
 /** The device support both 32-bit & 64-bit guests. */
-#define PDM_DEVREG_FLAGS_GUEST_BITS_32_64       0x00000300
+#define PDM_DEVREG_FLAGS_GUEST_BITS_32_64               UINT32_C(0x00003000)
 /** @def PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT
  * The guest bit count for the current compilation. */
 #if GC_ARCH_BITS == 32
-# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT    PDM_DEVREG_FLAGS_GUEST_BITS_32
+# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT            PDM_DEVREG_FLAGS_GUEST_BITS_32
 #elif GC_ARCH_BITS == 64
-# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT    PDM_DEVREG_FLAGS_GUEST_BITS_32_64
+# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT            PDM_DEVREG_FLAGS_GUEST_BITS_32_64
 #else
 # error Unsupported GC_ARCH_BITS value.
 #endif
 /** The guest bit count mask. */
-#define PDM_DEVREG_FLAGS_GUEST_BITS_MASK        0x00000300
+#define PDM_DEVREG_FLAGS_GUEST_BITS_MASK                UINT32_C(0x00003000)
 
 /** A convenience. */
-#define PDM_DEVREG_FLAGS_DEFAULT_BITS           (PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT)
-
-/** Indicates that the devices support PAE36 on a 32-bit guest. */
-#define PDM_DEVREG_FLAGS_PAE36                  0x00001000
+#define PDM_DEVREG_FLAGS_DEFAULT_BITS                   (PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT)
 
 /** Indicates that the device needs to be notified before the drivers when suspending. */
-#define PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION 0x00002000
-
+#define PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION     UINT32_C(0x00010000)
 /** Indicates that the device needs to be notified before the drivers when powering off. */
-#define PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION 0x00004000
-
+#define PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION    UINT32_C(0x00020000)
 /** Indicates that the device needs to be notified before the drivers when resetting. */
-#define PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION 0x00008000
+#define PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION       UINT32_C(0x00040000)
+
+/** This flag is used to indicate that the device has been converted to the
+ *  new device style. */
+#define PDM_DEVREG_FLAGS_NEW_STYLE                      UINT32_C(0x80000000)
+
 /** @} */
 
@@ -490,4 +524,235 @@
 
 
+/**
+ * PDM Device Registration Structure, ring-0.
+ *
+ * This structure is used when registering a device from VBoxInitDevices() in HC
+ * Ring-0.  PDM will continue use till the VM is terminated.
+ */
+typedef struct PDMDEVREGR0
+{
+    /** Structure version. PDM_DEVREGR0_VERSION defines the current version. */
+    uint32_t            u32Version;
+    /** Reserved, must be zero. */
+    uint32_t            uReserved0;
+    /** Device name, must match the ring-3 one. */
+    char                szName[32];
+    /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
+    uint32_t            fFlags;
+    /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
+    uint32_t            fClass;
+    /** Maximum number of instances (per VM). */
+    uint32_t            cMaxInstances;
+    /** The shared data structure version number. */
+    uint32_t            uSharedVersion;
+    /** Size of the instance data. */
+    uint32_t            cbInstanceShared;
+    /** Size of the ring-0 instance data. */
+    uint32_t            cbInstanceCC;
+    /** Size of the raw-mode instance data. */
+    uint32_t            cbInstanceRC;
+    /** Reserved, must be zero. */
+    uint32_t            uReserved1;
+    /** The description of the device. The UTF-8 string pointed to shall, like this structure,
+     * remain unchanged from registration till VM destruction. */
+    const char         *pszDescription;
+
+    /**
+     * Early construction callback (optional).
+     *
+     * This is called right after the device instance structure has been allocated
+     * and before the ring-3 constructor gets called.
+     *
+     * @returns VBox status code.
+     * @param   pDevIns         The device instance data.
+     * @note    The destructure is always called, regardless of the return status.
+     */
+    DECLR0CALLBACKMEMBER(int, pfnEarlyConstruct, (PPDMDEVINS pDevIns));
+
+    /**
+     * Regular construction callback (optional).
+     *
+     * This is called after (or during) the ring-3 constructor.
+     *
+     * @returns VBox status code.
+     * @param   pDevIns         The device instance data.
+     * @note    The destructure is always called, regardless of the return status.
+     */
+    DECLR0CALLBACKMEMBER(int, pfnConstruct, (PPDMDEVINS pDevIns));
+
+    /**
+     * Destructor (optional).
+     *
+     * This is called after the ring-3 destruction.  This is not called if ring-3
+     * fails to trigger it (e.g. process is killed or crashes).
+     *
+     * @param   pDevIns         The device instance data.
+     */
+    DECLR0CALLBACKMEMBER(void, pfnDestruct, (PPDMDEVINS pDevIns));
+
+    /**
+     * Final destructor (optional).
+     *
+     * This is called right before the memory is freed, which happens when the
+     * VM/GVM object is destroyed.  This is always called.
+     *
+     * @param   pDevIns         The device instance data.
+     */
+    DECLR0CALLBACKMEMBER(void, pfnFinalDestruct, (PPDMDEVINS pDevIns));
+
+    /**
+     * Generic request handler (optional).
+     *
+     * @param   pDevIns         The device instance data.
+     * @param   uReq            Device specific request.
+     * @param   uArg            Request argument.
+     */
+    DECLR0CALLBACKMEMBER(int, pfnRequest, (PPDMDEVINS pDevIns, uint32_t uReq, uint64_t uArg));
+
+    /** @name Reserved for future extensions, must be zero.
+     * @{ */
+    DECLR0CALLBACKMEMBER(int, pfnReserved0, (PPDMDEVINS pDevIns));
+    DECLR0CALLBACKMEMBER(int, pfnReserved1, (PPDMDEVINS pDevIns));
+    DECLR0CALLBACKMEMBER(int, pfnReserved2, (PPDMDEVINS pDevIns));
+    DECLR0CALLBACKMEMBER(int, pfnReserved3, (PPDMDEVINS pDevIns));
+    DECLR0CALLBACKMEMBER(int, pfnReserved4, (PPDMDEVINS pDevIns));
+    DECLR0CALLBACKMEMBER(int, pfnReserved5, (PPDMDEVINS pDevIns));
+    DECLR0CALLBACKMEMBER(int, pfnReserved6, (PPDMDEVINS pDevIns));
+    DECLR0CALLBACKMEMBER(int, pfnReserved7, (PPDMDEVINS pDevIns));
+    /** @} */
+
+    /** Initialization safty marker. */
+    uint32_t            u32VersionEnd;
+} PDMDEVREGR0;
+/** Pointer to a ring-0 PDM device registration structure. */
+typedef PDMDEVREGR0 *PPDMDEVREGR0;
+/** Pointer to a const ring-0 PDM device registration structure. */
+typedef PDMDEVREGR0 const *PCPDMDEVREGR0;
+/** Current DEVREGR0 version number. */
+#define PDM_DEVREGR0_VERSION                    PDM_VERSION_MAKE(0xff80, 1, 0)
+
+
+/**
+ * PDM Device Registration Structure, raw-mode
+ *
+ * At the moment, this structure is mostly here to match the other two contexts.
+ */
+typedef struct PDMDEVREGRC
+{
+    /** Structure version. PDM_DEVREGRC_VERSION defines the current version. */
+    uint32_t            u32Version;
+    /** Reserved, must be zero. */
+    uint32_t            uReserved0;
+    /** Device name, must match the ring-3 one. */
+    char                szName[32];
+    /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
+    uint32_t            fFlags;
+    /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
+    uint32_t            fClass;
+    /** Maximum number of instances (per VM). */
+    uint32_t            cMaxInstances;
+    /** The shared data structure version number. */
+    uint32_t            uSharedVersion;
+    /** Size of the instance data. */
+    uint32_t            cbInstanceShared;
+    /** Size of the ring-0 instance data. */
+    uint32_t            cbInstanceCC;
+    /** Size of the raw-mode instance data. */
+    uint32_t            cbInstanceRC;
+    /** Reserved, must be zero. */
+    uint32_t            uReserved1;
+    /** The description of the device. The UTF-8 string pointed to shall, like this structure,
+     * remain unchanged from registration till VM destruction. */
+    const char         *pszDescription;
+
+    /**
+     * Constructor callback.
+     *
+     * This is called much later than both the ring-0 and ring-3 constructors, since
+     * raw-mode v2 require a working VMM to run actual code.
+     *
+     * @returns VBox status code.
+     * @param   pDevIns         The device instance data.
+     * @note    The destructure is always called, regardless of the return status.
+     */
+    DECLRGCALLBACKMEMBER(int, pfnConstruct, (PPDMDEVINS pDevIns));
+
+    /** @name Reserved for future extensions, must be zero.
+     * @{ */
+    DECLRCCALLBACKMEMBER(int, pfnReserved0, (PPDMDEVINS pDevIns));
+    DECLRCCALLBACKMEMBER(int, pfnReserved1, (PPDMDEVINS pDevIns));
+    DECLRCCALLBACKMEMBER(int, pfnReserved2, (PPDMDEVINS pDevIns));
+    DECLRCCALLBACKMEMBER(int, pfnReserved3, (PPDMDEVINS pDevIns));
+    DECLRCCALLBACKMEMBER(int, pfnReserved4, (PPDMDEVINS pDevIns));
+    DECLRCCALLBACKMEMBER(int, pfnReserved5, (PPDMDEVINS pDevIns));
+    DECLRCCALLBACKMEMBER(int, pfnReserved6, (PPDMDEVINS pDevIns));
+    DECLRCCALLBACKMEMBER(int, pfnReserved7, (PPDMDEVINS pDevIns));
+    /** @} */
+
+    /** Initialization safty marker. */
+    uint32_t            u32VersionEnd;
+} PDMDEVREGRC;
+/** Pointer to a raw-mode PDM device registration structure. */
+typedef PDMDEVREGRC *PPDMDEVREGRC;
+/** Pointer to a const raw-mode PDM device registration structure. */
+typedef PDMDEVREGRC const *PCPDMDEVREGRC;
+/** Current DEVREGRC version number. */
+#define PDM_DEVREGRC_VERSION                    PDM_VERSION_MAKE(0xff81, 1, 0)
+
+
+
+/** @def PDM_DEVREG_VERSION
+ * Current DEVREG version number. */
+/** @typedef PDMDEVREGR3
+ * A current context PDM device registration structure. */
+/** @typedef PPDMDEVREGR3
+ * Pointer to a current context PDM device registration structure. */
+/** @typedef PCPDMDEVREGR3
+ * Pointer to a const current context PDM device registration structure. */
+#if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
+# define PDM_DEVREG_VERSION                     PDM_DEVREGR3_VERSION
+typedef PDMDEVREGR3                             PDMDEVREG;
+typedef PPDMDEVREGR3                            PPDMDEVREG;
+typedef PCPDMDEVREGR3                           PCPDMDEVREG;
+#elif defined(IN_RING0)
+# define PDM_DEVREG_VERSION                     PDM_DEVREGR0_VERSION
+typedef PDMDEVREGR0                             PDMDEVREG;
+typedef PPDMDEVREGR0                            PPDMDEVREG;
+typedef PCPDMDEVREGR0                           PCPDMDEVREG;
+#elif defined(IN_RC)
+# define PDM_DEVREG_VERSION                     PDM_DEVREGRC_VERSION
+typedef PDMDEVREGRC                             PDMDEVREG;
+typedef PPDMDEVREGRC                            PPDMDEVREG;
+typedef PCPDMDEVREGRC                           PCPDMDEVREG;
+#else
+# error "Not IN_RING3, IN_RING0 or IN_RC"
+#endif
+
+
+/**
+ * Device registrations for ring-0 modules.
+ *
+ * This structure is used directly and must therefore reside in persistent
+ * memory (i.e. the data section).
+ */
+typedef struct PDMDEVMODREGR0
+{
+    /** The structure version (PDM_DEVMODREGR0_VERSION). */
+    uint32_t            u32Version;
+    /** Number of devices in the array papDevRegs points to. */
+    uint32_t            cDevRegs;
+    /** Pointer to device registration structures. */
+    PCPDMDEVREGR0      *papDevRegs;
+    /** The ring-0 module handle - PDM internal, fingers off. */
+    void               *hMod;
+    /** List entry - PDM internal, fingers off. */
+    RTLISTNODE          ListEntry;
+} PDMDEVMODREGR0;
+/** Pointer to device registriations for a ring-0 module. */
+typedef PDMDEVMODREGR0 *PPDMDEVMODREGR0;
+/** Current PDMDEVMODREGR0 version number. */
+#define PDM_DEVMODREGR0_VERSION                 PDM_VERSION_MAKE(0xff85, 1, 0)
+
+
 /** @name IRQ Level for use with the *SetIrq APIs.
  * @{
@@ -1890,5 +2155,5 @@
 
 /** Current PDMDEVHLPR3 version number. */
-#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 23, 0)
+#define PDM_DEVHLPR3_VERSION                    PDM_VERSION_MAKE_PP(0xffe7, 24, 0)
 
 /**
@@ -1899,4 +2164,66 @@
     /** Structure version. PDM_DEVHLPR3_VERSION defines the current version. */
     uint32_t                        u32Version;
+
+    /**
+     * Creates a range of I/O ports for a device.
+     *
+     * The I/O port range must be mapped in a separately call.  Any ring-0 and
+     * raw-mode context callback handlers needs to be set up in the respective
+     * contexts.
+     *
+     * @returns VBox status.
+     * @param   pDevIns     The device instance to register the ports with.
+     * @param   cPorts      Number of ports to register.
+     * @param   fFlag       Reserved, MBZ.
+     * @param   pPciDev     The PCI device the range is associated with, if
+     *                      applicable.
+     * @param   iPciRegion  The PCI device region in the high 16-bit word and
+     *                      sub-region in the low 16-bit word.  UINT32_MAX if NA.
+     * @param   pfnOut      Pointer to function which is gonna handle OUT
+     *                      operations. Optional.
+     * @param   pfnIn       Pointer to function which is gonna handle IN operations.
+     *                      Optional.
+     * @param   pfnOutStr   Pointer to function which is gonna handle string OUT
+     *                      operations.  Optional.
+     * @param   pfnInStr    Pointer to function which is gonna handle string IN
+     *                      operations.  Optional.
+     * @param   pvUser      User argument to pass to the callbacks.
+     * @param   pszDesc     Pointer to description string. This must not be freed.
+     * @param   phIoPorts   Where to return the I/O port range handle.
+     *
+     * @remarks Caller enters the device critical section prior to invoking the
+     *          registered callback methods.
+     *
+     * @sa      PDMDevHlpIoPortSetUpContext, PDMDevHlpIoPortMap,
+     *          PDMDevHlpIoPortUnmap.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnIoPortCreateEx,(PPDMDEVINS pDevIns, RTIOPORT cPorts,
+                                                 uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
+                                                 PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
+                                                 PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr,
+                                                 RTR3PTR pvUser, const char *pszDesc, PIOMIOPORTHANDLE phIoPorts));
+
+    /**
+     * Maps an I/O port range.
+     *
+     * @returns VBox status.
+     * @param   pDevIns     The device instance to register the ports with.
+     * @param   hIoPorts    The I/O port range handle.
+     * @param   Port        Where to map the range.
+     * @sa      PDMDevHlpIoPortUnmap, PDMDevHlpIoPortSetUpContext,
+     *          PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnIoPortMap,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT Port));
+
+    /**
+     * Unmaps an I/O port range.
+     *
+     * @returns VBox status.
+     * @param   pDevIns     The device instance to register the ports with.
+     * @param   hIoPorts    The I/O port range handle.
+     * @sa      PDMDevHlpIoPortMap, PDMDevHlpIoPortSetUpContext,
+     *          PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnIoPortUnmap,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts));
 
     /**
@@ -1919,4 +2246,5 @@
      * @remarks Caller enters the device critical section prior to invoking the
      *          registered callback methods.
+     * @deprecated
      */
     DECLR3CALLBACKMEMBER(int, pfnIOPortRegister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTHCPTR pvUser,
@@ -1945,4 +2273,5 @@
      * @remarks Caller enters the device critical section prior to invoking the
      *          registered callback methods.
+     * @deprecated
      */
     DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterRC,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTRCPTR pvUser,
@@ -1968,4 +2297,5 @@
      * @remarks Caller enters the device critical section prior to invoking the
      *          registered callback methods.
+     * @deprecated
      */
     DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterR0,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTR0PTR pvUser,
@@ -1984,4 +2314,80 @@
      */
     DECLR3CALLBACKMEMBER(int, pfnIOPortDeregister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts));
+
+    /**
+     * Creates a memory mapped I/O (MMIO) region for a device.
+     *
+     * The MMIO region must be mapped in a separately call.  Any ring-0 and
+     * raw-mode context callback handlers needs to be set up in the respective
+     * contexts.
+     *
+     * @returns VBox status.
+     * @param   pDevIns     The device instance to register the ports with.
+     * @param   cbRegion    The size of the region in bytes.
+     * @param   fFlag       Reserved, MBZ.
+     * @param   pPciDev     The PCI device the range is associated with, if
+     *                      applicable.
+     * @param   iPciRegion  The PCI device region in the high 16-bit word and
+     *                      sub-region in the low 16-bit word.  UINT32_MAX if NA.
+     * @param   pfnWrite    Pointer to function which is gonna handle Write
+     *                      operations.
+     * @param   pfnRead     Pointer to function which is gonna handle Read
+     *                      operations.
+     * @param   pfnFill     Pointer to function which is gonna handle Fill/memset
+     *                      operations. (optional)
+     * @param   pvUser      User argument to pass to the callbacks.
+     * @param   pszDesc     Pointer to description string. This must not be freed.
+     * @param   phRegion    Where to return the MMIO region handle.
+     *
+     * @remarks Caller enters the device critical section prior to invoking the
+     *          registered callback methods.
+     *
+     * @sa      PDMDevHlpMmioSetUpContext, PDMDevHlpMmioMap, PDMDevHlpMmioUnmap.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnMmioCreateEx,(PPDMDEVINS pDevIns, RTGCPHYS cbRegion,
+                                               uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
+                                               PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
+                                               void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion));
+
+    /**
+     * Maps a memory mapped I/O (MMIO) region.
+     *
+     * @returns VBox status.
+     * @param   pDevIns     The device instance the region is associated with.
+     * @param   hRegion     The MMIO region handle.
+     * @param   GCPhys       Where to map the region.
+     * @sa      PDMDevHlpMmioUnmap, PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx,
+     *          PDMDevHlpMmioSetUpContext
+     */
+    DECLR3CALLBACKMEMBER(int, pfnMmioMap,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys));
+
+    /**
+     * Maps a memory mapped I/O (MMIO) region.
+     *
+     * @returns VBox status.
+     * @param   pDevIns     The device instance the region is associated with.
+     * @param   hRegion     The MMIO region handle.
+     * @sa      PDMDevHlpMmioMap, PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx,
+     *          PDMDevHlpMmioSetUpContext
+     */
+    DECLR3CALLBACKMEMBER(int, pfnMmioUnmap,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion));
+
+    /**
+     * Reduces the length of a MMIO range.
+     *
+     * This is for implementations of PDMPCIDEV::pfnRegionLoadChangeHookR3 and will
+     * only work during saved state restore.  It will not call the PCI bus code, as
+     * that is expected to restore the saved resource configuration.
+     *
+     * It just adjusts the mapping length of the region so that when pfnMmioMap is
+     * called it will only map @a cbRegion bytes and not the value set during
+     * registration.
+     *
+     * @return VBox status code.
+     * @param   pDevIns     The device owning the range.
+     * @param   hRegion     The MMIO region handle.
+     * @param   cbRegion    The new size, must be smaller.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnMmioReduce,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS cbRegion));
 
     /**
@@ -2004,4 +2410,5 @@
      * @remarks Caller enters the device critical section prior to invoking the
      *          registered callback methods.
+     * @deprecated
      */
     DECLR3CALLBACKMEMBER(int, pfnMMIORegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTHCPTR pvUser,
@@ -2026,4 +2433,5 @@
      * @remarks Caller enters the device critical section prior to invoking the
      *          registered callback methods.
+     * @deprecated
      */
     DECLR3CALLBACKMEMBER(int, pfnMMIORegisterRC,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTRCPTR pvUser,
@@ -2047,4 +2455,5 @@
      * @remarks Caller enters the device critical section prior to invoking the
      *          registered callback methods.
+     * @deprecated
      */
     DECLR3CALLBACKMEMBER(int, pfnMMIORegisterR0,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTR0PTR pvUser,
@@ -2060,4 +2469,5 @@
      * @param   GCPhysStart         First physical address in the range.
      * @param   cbRange             The size of the range (in bytes).
+     * @deprecated
      */
     DECLR3CALLBACKMEMBER(int, pfnMMIODeregister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange));
@@ -2066,7 +2476,7 @@
      * Allocate and register a MMIO2 region.
      *
-     * As mentioned elsewhere, MMIO2 is just RAM spelled differently. It's
-     * RAM associated with a device. It is also non-shared memory with a
-     * permanent ring-3 mapping and page backing (presently).
+     * As mentioned elsewhere, MMIO2 is just RAM spelled differently.  It's RAM
+     * associated with a device.  It is also non-shared memory with a permanent
+     * ring-3 mapping and page backing (presently).
      *
      * @returns VBox status.
@@ -2133,4 +2543,5 @@
      * @sa      PDMDevHlpMMIOExMap, PDMDevHlpMMIOExUnmap, PDMDevHlpMMIOExDeregister,
      *          PDMDevHlpMMIORegisterEx
+     * @deprecated
      */
     DECLR3CALLBACKMEMBER(int, pfnMMIOExPreRegister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS cbRegion,
@@ -2152,4 +2563,5 @@
      * @param   iRegion             The region number used during registration.
      * @thread  EMT.
+     * @deprecated for MMIO
      */
     DECLR3CALLBACKMEMBER(int, pfnMMIOExDeregister,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion));
@@ -2171,4 +2583,5 @@
      * @param   GCPhys              The physical address to map it at.
      * @thread  EMT.
+     * @deprecated for MMIO
      */
     DECLR3CALLBACKMEMBER(int, pfnMMIOExMap,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys));
@@ -2184,4 +2597,5 @@
      * @param   GCPhys              The physical address it's currently mapped at.
      * @thread  EMT.
+     * @deprecated for MMIO
      */
     DECLR3CALLBACKMEMBER(int, pfnMMIOExUnmap,(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, uint32_t iRegion, RTGCPHYS GCPhys));
@@ -2317,4 +2731,76 @@
                                               PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone));
 
+    /** @name Exported SSM Functions
+     * @{ */
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutStruct,(PSSMHANDLE pSSM, const void *pvStruct, PCSSMFIELD paFields));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutStructEx,(PSSMHANDLE pSSM, const void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutBool,(PSSMHANDLE pSSM, bool fBool));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutU8,(PSSMHANDLE pSSM, uint8_t u8));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutS8,(PSSMHANDLE pSSM, int8_t i8));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutU16,(PSSMHANDLE pSSM, uint16_t u16));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutS16,(PSSMHANDLE pSSM, int16_t i16));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutU32,(PSSMHANDLE pSSM, uint32_t u32));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutS32,(PSSMHANDLE pSSM, int32_t i32));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutU64,(PSSMHANDLE pSSM, uint64_t u64));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutS64,(PSSMHANDLE pSSM, int64_t i64));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutU128,(PSSMHANDLE pSSM, uint128_t u128));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutS128,(PSSMHANDLE pSSM, int128_t i128));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutUInt,(PSSMHANDLE pSSM, RTUINT u));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutSInt,(PSSMHANDLE pSSM, RTINT i));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutGCUInt,(PSSMHANDLE pSSM, RTGCUINT u));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutGCUIntReg,(PSSMHANDLE pSSM, RTGCUINTREG u));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutGCPhys32,(PSSMHANDLE pSSM, RTGCPHYS32 GCPhys));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutGCPhys64,(PSSMHANDLE pSSM, RTGCPHYS64 GCPhys));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutGCPhys,(PSSMHANDLE pSSM, RTGCPHYS GCPhys));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutGCPtr,(PSSMHANDLE pSSM, RTGCPTR GCPtr));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutGCUIntPtr,(PSSMHANDLE pSSM, RTGCUINTPTR GCPtr));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutRCPtr,(PSSMHANDLE pSSM, RTRCPTR RCPtr));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutIOPort,(PSSMHANDLE pSSM, RTIOPORT IOPort));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutSel,(PSSMHANDLE pSSM, RTSEL Sel));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutMem,(PSSMHANDLE pSSM, const void *pv, size_t cb));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMPutStrZ,(PSSMHANDLE pSSM, const char *psz));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetStruct,(PSSMHANDLE pSSM, void *pvStruct, PCSSMFIELD paFields));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetStructEx,(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetBool,(PSSMHANDLE pSSM, bool *pfBool));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetU8,(PSSMHANDLE pSSM, uint8_t *pu8));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetS8,(PSSMHANDLE pSSM, int8_t *pi8));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetU16,(PSSMHANDLE pSSM, uint16_t *pu16));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetS16,(PSSMHANDLE pSSM, int16_t *pi16));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetU32,(PSSMHANDLE pSSM, uint32_t *pu32));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetS32,(PSSMHANDLE pSSM, int32_t *pi32));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetU64,(PSSMHANDLE pSSM, uint64_t *pu64));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetS64,(PSSMHANDLE pSSM, int64_t *pi64));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetU128,(PSSMHANDLE pSSM, uint128_t *pu128));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetS128,(PSSMHANDLE pSSM, int128_t *pi128));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetUInt,(PSSMHANDLE pSSM, PRTUINT pu));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetSInt,(PSSMHANDLE pSSM, PRTINT pi));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetGCUInt,(PSSMHANDLE pSSM, PRTGCUINT pu));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetGCUIntReg,(PSSMHANDLE pSSM, PRTGCUINTREG pu));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetGCPhys32,(PSSMHANDLE pSSM, PRTGCPHYS32 pGCPhys));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetGCPhys64,(PSSMHANDLE pSSM, PRTGCPHYS64 pGCPhys));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetGCPhys,(PSSMHANDLE pSSM, PRTGCPHYS pGCPhys));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetGCPtr,(PSSMHANDLE pSSM, PRTGCPTR pGCPtr));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetGCUIntPtr,(PSSMHANDLE pSSM, PRTGCUINTPTR pGCPtr));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetRCPtr,(PSSMHANDLE pSSM, PRTRCPTR pRCPtr));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetIOPort,(PSSMHANDLE pSSM, PRTIOPORT pIOPort));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetSel,(PSSMHANDLE pSSM, PRTSEL pSel));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetMem,(PSSMHANDLE pSSM, void *pv, size_t cb));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetStrZ,(PSSMHANDLE pSSM, char *psz, size_t cbMax));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMGetStrZEx,(PSSMHANDLE pSSM, char *psz, size_t cbMax, size_t *pcbStr));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMSkip,(PSSMHANDLE pSSM, size_t cb));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMSkipToEndOfUnit,(PSSMHANDLE pSSM));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMSetLoadError,(PSSMHANDLE pSSM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(6, 7));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMSetLoadErrorV,(PSSMHANDLE pSSM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMSetCfgError,(PSSMHANDLE pSSM, RT_SRC_POS_DECL, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(5, 6));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMSetCfgErrorV,(PSSMHANDLE pSSM, RT_SRC_POS_DECL, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(5, 0));
+    DECLR3CALLBACKMEMBER(int,      pfnSSMHandleGetStatus,(PSSMHANDLE pSSM));
+    DECLR3CALLBACKMEMBER(SSMAFTER, pfnSSMHandleGetAfter,(PSSMHANDLE pSSM));
+    DECLR3CALLBACKMEMBER(bool,     pfnSSMHandleIsLiveSave,(PSSMHANDLE pSSM));
+    DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleMaxDowntime,(PSSMHANDLE pSSM));
+    DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleHostBits,(PSSMHANDLE pSSM));
+    DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleRevision,(PSSMHANDLE pSSM));
+    DECLR3CALLBACKMEMBER(uint32_t, pfnSSMHandleVersion,(PSSMHANDLE pSSM));
+    /** @} */              
+
     /**
      * Creates a timer.
@@ -2336,4 +2822,54 @@
 
     /**
+     * Creates a timer w/ a cross context handle.
+     *
+     * @returns VBox status.
+     * @param   pDevIns             The device instance.
+     * @param   enmClock            The clock to use on this timer.
+     * @param   pfnCallback         Callback function.
+     * @param   pvUser              User argument for the callback.
+     * @param   fFlags              Flags, see TMTIMER_FLAGS_*.
+     * @param   pszDesc             Pointer to description string which must stay around
+     *                              until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
+     * @param   phTimer             Where to store the timer handle on success.
+     * @remarks Caller enters the device critical section prior to invoking the
+     *          callback.
+     */
+    DECLR3CALLBACKMEMBER(int, pfnTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
+                                              void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer));
+
+    /**
+     * Translates a timer handle to a pointer.
+     *
+     * @returns The time address.
+     * @param   pDevIns             The device instance.
+     * @param   hTimer              The timer handle.
+     */
+    DECLR3CALLBACKMEMBER(PTMTIMERR3, pfnTimerToPtr,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+
+    /** @name Timer handle method wrappers
+     * @{ */
+    DECLR3CALLBACKMEMBER(uint64_t, pfnTimerFromMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs));
+    DECLR3CALLBACKMEMBER(uint64_t, pfnTimerFromMilli,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs));
+    DECLR3CALLBACKMEMBER(uint64_t, pfnTimerFromNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs));
+    DECLR3CALLBACKMEMBER(uint64_t, pfnTimerGet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR3CALLBACKMEMBER(uint64_t, pfnTimerGetFreq,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR3CALLBACKMEMBER(uint64_t, pfnTimerGetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR3CALLBACKMEMBER(bool,     pfnTimerIsActive,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR3CALLBACKMEMBER(bool,     pfnTimerIsLockOwner,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR3CALLBACKMEMBER(int,      pfnTimerLock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy));
+    DECLR3CALLBACKMEMBER(int,      pfnTimerSet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire));
+    DECLR3CALLBACKMEMBER(int,      pfnTimerSetFrequencyHint,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz));
+    DECLR3CALLBACKMEMBER(int,      pfnTimerSetMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext));
+    DECLR3CALLBACKMEMBER(int,      pfnTimerSetMillies,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext));
+    DECLR3CALLBACKMEMBER(int,      pfnTimerSetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext));
+    DECLR3CALLBACKMEMBER(int,      pfnTimerSetRelative,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now));
+    DECLR3CALLBACKMEMBER(int,      pfnTimerStop,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR3CALLBACKMEMBER(void,     pfnTimerUnlock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR3CALLBACKMEMBER(int,      pfnTimerSave,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM));
+    DECLR3CALLBACKMEMBER(int,      pfnTimerLoad,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM));
+    /** @} */
+
+    /**
      * Get the real world UTC time adjusted for VM lag, user offset and warpdrive.
      *
@@ -2343,4 +2879,68 @@
      */
     DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnTMUtcNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime));
+
+    /** @name Exported CFGM Functions.
+     * @{ */
+    DECLR3CALLBACKMEMBER(bool,      pfnCFGMExists,(           PCFGMNODE pNode, const char *pszName));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryType,(        PCFGMNODE pNode, const char *pszName, PCFGMVALUETYPE penmType));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQuerySize,(        PCFGMNODE pNode, const char *pszName, size_t *pcb));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryInteger,(     PCFGMNODE pNode, const char *pszName, uint64_t *pu64));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryIntegerDef,(  PCFGMNODE pNode, const char *pszName, uint64_t *pu64, uint64_t u64Def));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryString,(      PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryStringDef,(   PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString, const char *pszDef));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryBytes,(       PCFGMNODE pNode, const char *pszName, void *pvData, size_t cbData));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryU64,(         PCFGMNODE pNode, const char *pszName, uint64_t *pu64));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryU64Def,(      PCFGMNODE pNode, const char *pszName, uint64_t *pu64, uint64_t u64Def));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryS64,(         PCFGMNODE pNode, const char *pszName, int64_t *pi64));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryS64Def,(      PCFGMNODE pNode, const char *pszName, int64_t *pi64, int64_t i64Def));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryU32,(         PCFGMNODE pNode, const char *pszName, uint32_t *pu32));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryU32Def,(      PCFGMNODE pNode, const char *pszName, uint32_t *pu32, uint32_t u32Def));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryS32,(         PCFGMNODE pNode, const char *pszName, int32_t *pi32));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryS32Def,(      PCFGMNODE pNode, const char *pszName, int32_t *pi32, int32_t i32Def));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryU16,(         PCFGMNODE pNode, const char *pszName, uint16_t *pu16));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryU16Def,(      PCFGMNODE pNode, const char *pszName, uint16_t *pu16, uint16_t u16Def));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryS16,(         PCFGMNODE pNode, const char *pszName, int16_t *pi16));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryS16Def,(      PCFGMNODE pNode, const char *pszName, int16_t *pi16, int16_t i16Def));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryU8,(          PCFGMNODE pNode, const char *pszName, uint8_t *pu8));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryU8Def,(       PCFGMNODE pNode, const char *pszName, uint8_t *pu8, uint8_t u8Def));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryS8,(          PCFGMNODE pNode, const char *pszName, int8_t *pi8));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryS8Def,(       PCFGMNODE pNode, const char *pszName, int8_t *pi8, int8_t i8Def));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryBool,(        PCFGMNODE pNode, const char *pszName, bool *pf));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryBoolDef,(     PCFGMNODE pNode, const char *pszName, bool *pf, bool fDef));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryPort,(        PCFGMNODE pNode, const char *pszName, PRTIOPORT pPort));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryPortDef,(     PCFGMNODE pNode, const char *pszName, PRTIOPORT pPort, RTIOPORT PortDef));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryUInt,(        PCFGMNODE pNode, const char *pszName, unsigned int *pu));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryUIntDef,(     PCFGMNODE pNode, const char *pszName, unsigned int *pu, unsigned int uDef));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQuerySInt,(        PCFGMNODE pNode, const char *pszName, signed int *pi));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQuerySIntDef,(     PCFGMNODE pNode, const char *pszName, signed int *pi, signed int iDef));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryPtr,(         PCFGMNODE pNode, const char *pszName, void **ppv));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryPtrDef,(      PCFGMNODE pNode, const char *pszName, void **ppv, void *pvDef));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryGCPtr,(       PCFGMNODE pNode, const char *pszName, PRTGCPTR pGCPtr));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryGCPtrDef,(    PCFGMNODE pNode, const char *pszName, PRTGCPTR pGCPtr, RTGCPTR GCPtrDef));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryGCPtrU,(      PCFGMNODE pNode, const char *pszName, PRTGCUINTPTR pGCPtr));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryGCPtrUDef,(   PCFGMNODE pNode, const char *pszName, PRTGCUINTPTR pGCPtr, RTGCUINTPTR GCPtrDef));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryGCPtrS,(      PCFGMNODE pNode, const char *pszName, PRTGCINTPTR pGCPtr));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryGCPtrSDef,(   PCFGMNODE pNode, const char *pszName, PRTGCINTPTR pGCPtr, RTGCINTPTR GCPtrDef));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryStringAlloc,( PCFGMNODE pNode, const char *pszName, char **ppszString));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMQueryStringAllocDef,(PCFGMNODE pNode, const char *pszName, char **ppszString, const char *pszDef));
+    DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetParent,(PCFGMNODE pNode));
+    DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetChild,(PCFGMNODE pNode, const char *pszPath));
+    DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetChildF,(PCFGMNODE pNode, const char *pszPathFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3));
+    DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetChildFV,(PCFGMNODE pNode, const char *pszPathFormat, va_list Args) RT_IPRT_FORMAT_ATTR(3, 0));
+    DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetFirstChild,(PCFGMNODE pNode));
+    DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMGetNextChild,(PCFGMNODE pCur));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMGetName,(PCFGMNODE pCur, char *pszName, size_t cchName));
+    DECLR3CALLBACKMEMBER(size_t,    pfnCFGMGetNameLen,(PCFGMNODE pCur));
+    DECLR3CALLBACKMEMBER(bool,      pfnCFGMAreChildrenValid,(PCFGMNODE pNode, const char *pszzValid));
+    DECLR3CALLBACKMEMBER(PCFGMLEAF, pfnCFGMGetFirstValue,(PCFGMNODE pCur));
+    DECLR3CALLBACKMEMBER(PCFGMLEAF, pfnCFGMGetNextValue,(PCFGMLEAF pCur));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMGetValueName,(PCFGMLEAF pCur, char *pszName, size_t cchName));
+    DECLR3CALLBACKMEMBER(size_t,    pfnCFGMGetValueNameLen,(PCFGMLEAF pCur));
+    DECLR3CALLBACKMEMBER(CFGMVALUETYPE, pfnCFGMGetValueType,(PCFGMLEAF pCur));
+    DECLR3CALLBACKMEMBER(bool,      pfnCFGMAreValuesValid,(PCFGMNODE pNode, const char *pszzValid));
+    DECLR3CALLBACKMEMBER(int,       pfnCFGMValidateConfig,(PCFGMNODE pNode, const char *pszNode,
+                                                           const char *pszValidValues, const char *pszValidNodes,
+                                                           const char *pszWho, uint32_t uInstance));
+    /** @} */
 
     /**
@@ -2949,4 +3549,5 @@
      * @returns The ring-0 address of the NOP critical section.
      * @param   pDevIns             The device instance.
+     * @deprecated
      */
     DECLR3CALLBACKMEMBER(R0PTRTYPE(PPDMCRITSECT), pfnCritSectGetNopR0,(PPDMDEVINS pDevIns));
@@ -2957,4 +3558,5 @@
      * @returns The raw-mode context address of the NOP critical section.
      * @param   pDevIns             The device instance.
+     * @deprecated
      */
     DECLR3CALLBACKMEMBER(RCPTRTYPE(PPDMCRITSECT), pfnCritSectGetNopRC,(PPDMDEVINS pDevIns));
@@ -2963,4 +3565,7 @@
      * Changes the device level critical section from the automatically created
      * default to one desired by the device constructor.
+     *
+     * For ring-0 and raw-mode capable devices, the call must be repeated in each of
+     * the additional contexts.
      *
      * @returns VBox status code.
@@ -2971,4 +3576,18 @@
      */
     DECLR3CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
+
+    /** @name Exported PDM Critical Section Functions
+     * @{ */
+    DECLR3CALLBACKMEMBER(bool,     pfnCritSectYield,(PPDMCRITSECT pCritSect));
+    DECLR3CALLBACKMEMBER(int,      pfnCritSectEnter,(PPDMCRITSECT pCritSect, int rcBusy));
+    DECLR3CALLBACKMEMBER(int,      pfnCritSectEnterDebug,(PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
+    DECLR3CALLBACKMEMBER(int,      pfnCritSectTryEnter,(PPDMCRITSECT pCritSect));
+    DECLR3CALLBACKMEMBER(int,      pfnCritSectTryEnterDebug,(PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
+    DECLR3CALLBACKMEMBER(int,      pfnCritSectLeave,(PPDMCRITSECT pCritSect));
+    DECLR3CALLBACKMEMBER(bool,     pfnCritSectIsOwner,(PCPDMCRITSECT pCritSect));
+    DECLR3CALLBACKMEMBER(bool,     pfnCritSectIsInitialized,(PCPDMCRITSECT pCritSect));
+    DECLR3CALLBACKMEMBER(bool,     pfnCritSectHasWaiters,(PCPDMCRITSECT pCritSect));
+    DECLR3CALLBACKMEMBER(uint32_t, pfnCritSectGetRecursion,(PCPDMCRITSECT pCritSect));
+    /** @} */
 
     /**
@@ -3643,4 +4262,60 @@
 
     /**
+     * Sets up raw-mode context callback handlers for an I/O port range.
+     *
+     * The range must have been registered in ring-3 first using
+     * PDMDevHlpIoPortCreate() or PDMDevHlpIoPortCreateEx().
+     *
+     * @returns VBox status.
+     * @param   pDevIns     The device instance to register the ports with.
+     * @param   hIoPorts    The I/O port range handle.
+     * @param   pfnOut      Pointer to function which is gonna handle OUT
+     *                      operations. Optional.
+     * @param   pfnIn       Pointer to function which is gonna handle IN operations.
+     *                      Optional.
+     * @param   pfnOutStr   Pointer to function which is gonna handle string OUT
+     *                      operations.  Optional.
+     * @param   pfnInStr    Pointer to function which is gonna handle string IN
+     *                      operations.  Optional.
+     * @param   pvUser      User argument to pass to the callbacks.
+     *
+     * @remarks Caller enters the device critical section prior to invoking the
+     *          registered callback methods.
+     *
+     * @sa      PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx, PDMDevHlpIoPortMap,
+     *          PDMDevHlpIoPortUnmap.
+     */
+    DECLRCCALLBACKMEMBER(int, pfnIoPortSetUpContextEx,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
+                                                       PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
+                                                       PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr,
+                                                       void *pvUser));
+
+    /**
+     * Sets up raw-mode context callback handlers for an MMIO region.
+     *
+     * The region must have been registered in ring-3 first using
+     * PDMDevHlpMmioCreate() or PDMDevHlpMmioCreateEx().
+     *
+     * @returns VBox status.
+     * @param   pDevIns     The device instance to register the ports with.
+     * @param   hRegion     The MMIO region handle.
+     * @param   pfnWrite    Pointer to function which is gonna handle Write
+     *                      operations.
+     * @param   pfnRead     Pointer to function which is gonna handle Read
+     *                      operations.
+     * @param   pfnFill     Pointer to function which is gonna handle Fill/memset
+     *                      operations. (optional)
+     * @param   pvUser      User argument to pass to the callbacks.
+     *
+     * @remarks Caller enters the device critical section prior to invoking the
+     *          registered callback methods.
+     *
+     * @sa      PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx, PDMDevHlpMmioMap,
+     *          PDMDevHlpMmioUnmap.
+     */
+    DECLRCCALLBACKMEMBER(int, pfnMmioSetUpContextEx,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIOWRITE pfnWrite,
+                                                     PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill, void *pvUser));
+
+    /**
      * Bus master physical memory read from the given PCI device.
      *
@@ -3800,14 +4475,4 @@
 
     /**
-     * Set parameters for pending MMIO patch operation
-     *
-     * @returns VBox status code.
-     * @param   pDevIns         Device instance.
-     * @param   GCPhys          MMIO physical address
-     * @param   pCachedData     GC pointer to cached data
-     */
-    DECLRCCALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
-
-    /**
      * Gets the VM handle. Restricted API.
      *
@@ -3857,4 +4522,39 @@
      */
     DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
+
+    /**
+     * Gets the NOP critical section.
+     *
+     * @returns The ring-3 address of the NOP critical section.
+     * @param   pDevIns             The device instance.
+     */
+    DECLRCCALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
+
+    /**
+     * Changes the device level critical section from the automatically created
+     * default to one desired by the device constructor.
+     *
+     * Must first be done in ring-3.
+     *
+     * @returns VBox status code.
+     * @param   pDevIns             The device instance.
+     * @param   pCritSect           The critical section to use.  NULL is not
+     *                              valid, instead use the NOP critical
+     *                              section.
+     */
+    DECLRCCALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
+
+    /** @name Exported PDM Critical Section Functions
+     * @{ */
+    DECLRCCALLBACKMEMBER(int,      pfnCritSectEnter,(PPDMCRITSECT pCritSect, int rcBusy));
+    DECLRCCALLBACKMEMBER(int,      pfnCritSectEnterDebug,(PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
+    DECLRCCALLBACKMEMBER(int,      pfnCritSectTryEnter,(PPDMCRITSECT pCritSect));
+    DECLRCCALLBACKMEMBER(int,      pfnCritSectTryEnterDebug,(PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
+    DECLRCCALLBACKMEMBER(int,      pfnCritSectLeave,(PPDMCRITSECT pCritSect));
+    DECLRCCALLBACKMEMBER(bool,     pfnCritSectIsOwner,(PCPDMCRITSECT pCritSect));
+    DECLRCCALLBACKMEMBER(bool,     pfnCritSectIsInitialized,(PCPDMCRITSECT pCritSect));
+    DECLRCCALLBACKMEMBER(bool,     pfnCritSectHasWaiters,(PCPDMCRITSECT pCritSect));
+    DECLRCCALLBACKMEMBER(uint32_t, pfnCritSectGetRecursion,(PCPDMCRITSECT pCritSect));
+    /** @} */
 
     /**
@@ -3887,10 +4587,10 @@
 } PDMDEVHLPRC;
 /** Pointer PDM Device RC API. */
-typedef RCPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC;
+typedef RGPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC;
 /** Pointer PDM Device RC API. */
-typedef RCPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC;
+typedef RGPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC;
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 7, 0)
+#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 8, 0)
 
 
@@ -3902,4 +4602,60 @@
     /** Structure version. PDM_DEVHLPR0_VERSION defines the current version. */
     uint32_t                    u32Version;
+
+    /**
+     * Sets up ring-0 callback handlers for an I/O port range.
+     *
+     * The range must have been registered in ring-3 first using
+     * PDMDevHlpIoPortCreate() or PDMDevHlpIoPortCreateEx().
+     *
+     * @returns VBox status.
+     * @param   pDevIns     The device instance to register the ports with.
+     * @param   hIoPorts    The I/O port range handle.
+     * @param   pfnOut      Pointer to function which is gonna handle OUT
+     *                      operations. Optional.
+     * @param   pfnIn       Pointer to function which is gonna handle IN operations.
+     *                      Optional.
+     * @param   pfnOutStr   Pointer to function which is gonna handle string OUT
+     *                      operations.  Optional.
+     * @param   pfnInStr    Pointer to function which is gonna handle string IN
+     *                      operations.  Optional.
+     * @param   pvUser      User argument to pass to the callbacks.
+     *
+     * @remarks Caller enters the device critical section prior to invoking the
+     *          registered callback methods.
+     *
+     * @sa      PDMDevHlpIoPortCreate, PDMDevHlpIoPortCreateEx, PDMDevHlpIoPortMap,
+     *          PDMDevHlpIoPortUnmap.
+     */
+    DECLR0CALLBACKMEMBER(int, pfnIoPortSetUpContextEx,(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
+                                                       PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
+                                                       PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr,
+                                                       void *pvUser));
+
+    /**
+     * Sets up ring-0 callback handlers for an MMIO region.
+     *
+     * The region must have been registered in ring-3 first using
+     * PDMDevHlpMmioCreate() or PDMDevHlpMmioCreateEx().
+     *
+     * @returns VBox status.
+     * @param   pDevIns     The device instance to register the ports with.
+     * @param   hRegion     The MMIO region handle.
+     * @param   pfnWrite    Pointer to function which is gonna handle Write
+     *                      operations.
+     * @param   pfnRead     Pointer to function which is gonna handle Read
+     *                      operations.
+     * @param   pfnFill     Pointer to function which is gonna handle Fill/memset
+     *                      operations. (optional)
+     * @param   pvUser      User argument to pass to the callbacks.
+     *
+     * @remarks Caller enters the device critical section prior to invoking the
+     *          registered callback methods.
+     *
+     * @sa      PDMDevHlpMmioCreate, PDMDevHlpMmioCreateEx, PDMDevHlpMmioMap,
+     *          PDMDevHlpMmioUnmap.
+     */
+    DECLR0CALLBACKMEMBER(int, pfnMmioSetUpContextEx,(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIOWRITE pfnWrite,
+                                                     PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill, void *pvUser));
 
     /**
@@ -4061,14 +4817,4 @@
 
     /**
-     * Set parameters for pending MMIO patch operation
-     *
-     * @returns rc.
-     * @param   pDevIns         Device instance.
-     * @param   GCPhys          MMIO physical address
-     * @param   pCachedData     GC pointer to cached data
-     */
-    DECLR0CALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
-
-    /**
      * Gets the VM handle. Restricted API.
      *
@@ -4095,4 +4841,34 @@
 
     /**
+     * Translates a timer handle to a pointer.
+     *
+     * @returns The time address.
+     * @param   pDevIns             The device instance.
+     * @param   hTimer              The timer handle.
+     */
+    DECLR0CALLBACKMEMBER(PTMTIMERR0, pfnTimerToPtr,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+
+    /** @name Timer handle method wrappers
+     * @{ */
+    DECLR0CALLBACKMEMBER(uint64_t, pfnTimerFromMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs));
+    DECLR0CALLBACKMEMBER(uint64_t, pfnTimerFromMilli,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs));
+    DECLR0CALLBACKMEMBER(uint64_t, pfnTimerFromNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs));
+    DECLR0CALLBACKMEMBER(uint64_t, pfnTimerGet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR0CALLBACKMEMBER(uint64_t, pfnTimerGetFreq,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR0CALLBACKMEMBER(uint64_t, pfnTimerGetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR0CALLBACKMEMBER(bool,     pfnTimerIsActive,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR0CALLBACKMEMBER(bool,     pfnTimerIsLockOwner,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR0CALLBACKMEMBER(int,      pfnTimerLock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy));
+    DECLR0CALLBACKMEMBER(int,      pfnTimerSet,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire));
+    DECLR0CALLBACKMEMBER(int,      pfnTimerSetFrequencyHint,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz));
+    DECLR0CALLBACKMEMBER(int,      pfnTimerSetMicro,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext));
+    DECLR0CALLBACKMEMBER(int,      pfnTimerSetMillies,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext));
+    DECLR0CALLBACKMEMBER(int,      pfnTimerSetNano,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext));
+    DECLR0CALLBACKMEMBER(int,      pfnTimerSetRelative,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now));
+    DECLR0CALLBACKMEMBER(int,      pfnTimerStop,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    DECLR0CALLBACKMEMBER(void,     pfnTimerUnlock,(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer));
+    /** @} */
+
+    /**
      * Get the current virtual clock time in a VM. The clock frequency must be
      * queried separately.
@@ -4118,4 +4894,39 @@
      */
     DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
+
+    /**
+     * Gets the NOP critical section.
+     *
+     * @returns The ring-3 address of the NOP critical section.
+     * @param   pDevIns             The device instance.
+     */
+    DECLR0CALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
+
+    /**
+     * Changes the device level critical section from the automatically created
+     * default to one desired by the device constructor.
+     *
+     * Must first be done in ring-3.
+     *
+     * @returns VBox status code.
+     * @param   pDevIns             The device instance.
+     * @param   pCritSect           The critical section to use.  NULL is not
+     *                              valid, instead use the NOP critical
+     *                              section.
+     */
+    DECLR0CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
+
+    /** @name Exported PDM Critical Section Functions
+     * @{ */
+    DECLR0CALLBACKMEMBER(int,      pfnCritSectEnter,(PPDMCRITSECT pCritSect, int rcBusy));
+    DECLR0CALLBACKMEMBER(int,      pfnCritSectEnterDebug,(PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
+    DECLR0CALLBACKMEMBER(int,      pfnCritSectTryEnter,(PPDMCRITSECT pCritSect));
+    DECLR0CALLBACKMEMBER(int,      pfnCritSectTryEnterDebug,(PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
+    DECLR0CALLBACKMEMBER(int,      pfnCritSectLeave,(PPDMCRITSECT pCritSect));
+    DECLR0CALLBACKMEMBER(bool,     pfnCritSectIsOwner,(PCPDMCRITSECT pCritSect));
+    DECLR0CALLBACKMEMBER(bool,     pfnCritSectIsInitialized,(PCPDMCRITSECT pCritSect));
+    DECLR0CALLBACKMEMBER(bool,     pfnCritSectHasWaiters,(PCPDMCRITSECT pCritSect));
+    DECLR0CALLBACKMEMBER(uint32_t, pfnCritSectGetRecursion,(PCPDMCRITSECT pCritSect));
+    /** @} */
 
     /**
@@ -4153,6 +4964,5 @@
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 8, 0)
-
+#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 9, 0)
 
 
@@ -4160,31 +4970,24 @@
  * PDM Device Instance.
  */
-typedef struct PDMDEVINS
+typedef struct PDMDEVINSR3
 {
     /** Structure version. PDM_DEVINS_VERSION defines the current version. */
-    uint32_t                    u32Version;
+    uint32_t                        u32Version;
     /** Device instance number. */
-    uint32_t                    iInstance;
-
-    /** Pointer the GC PDM Device API. */
-    PCPDMDEVHLPRC               pHlpRC;
-    /** Pointer to device instance data. */
-    RTRCPTR                     pvInstanceDataRC;
-    /** The critical section for the device, see pCritSectXR3. */
-    RCPTRTYPE(PPDMCRITSECT)     pCritSectRoRC;
-    /** Alignment padding.  */
-    RTRCPTR                     pAlignmentRC;
-
-    /** Pointer the R0 PDM Device API. */
-    PCPDMDEVHLPR0               pHlpR0;
-    /** Pointer to device instance data (R0). */
-    RTR0PTR                     pvInstanceDataR0;
-    /** The critical section for the device, see pCritSectXR3. */
-    R0PTRTYPE(PPDMCRITSECT)     pCritSectRoR0;
-
+    uint32_t                        iInstance;
+    /** Size of the ring-3, raw-mode and shared bits. */
+    uint32_t                        cbRing3;
+    /** Set if ring-0 context is enabled. */
+    bool                            fR0Enabled;
+    /** Set if raw-mode context is enabled. */
+    bool                            fRCEnabled;
+    /** Alignment padding. */
+    bool                            afReserved[2];
     /** Pointer the HC PDM Device API. */
-    PCPDMDEVHLPR3               pHlpR3;
-    /** Pointer to device instance data. */
-    RTR3PTR                     pvInstanceDataR3;
+    PCPDMDEVHLPR3                   pHlpR3;
+    /** Pointer to the shared device instance data. */
+    RTR3PTR                         pvInstanceDataR3;
+    /** Pointer to the device instance data for ring-3. */
+    RTR3PTR                         pvInstanceDataForR3;
     /** The critical section for the device.
      *
@@ -4198,11 +5001,9 @@
      * very early on.
      */
-    R3PTRTYPE(PPDMCRITSECT)     pCritSectRoR3;
-
+    R3PTRTYPE(PPDMCRITSECT)         pCritSectRoR3;
     /** Pointer to device registration structure.  */
-    R3PTRTYPE(PCPDMDEVREG)      pReg;
+    R3PTRTYPE(PCPDMDEVREG)          pReg;
     /** Configuration handle. */
-    R3PTRTYPE(PCFGMNODE)        pCfg;
-
+    R3PTRTYPE(PCFGMNODE)            pCfg;
     /** The base interface of the device.
      *
@@ -4210,14 +5011,26 @@
      * device level interfaces to export. To obtain this interface
      * call PDMR3QueryDevice(). */
-    PDMIBASE                    IBase;
+    PDMIBASE                        IBase;
 
     /** Tracing indicator. */
-    uint32_t                    fTracing;
+    uint32_t                        fTracing;
     /** The tracing ID of this device.  */
-    uint32_t                    idTracing;
-#if HC_ARCH_BITS == 32
+    uint32_t                        idTracing;
+
+    /** Ring-3 pointer to the raw-mode device instance. */
+    R3PTRTYPE(struct PDMDEVINSRC *) pDevInsForRCR3;
+    /** Raw-mode address of the raw-mode device instance. */
+    RTRGPTR                         pDevInsForRC;
+    /** Ring-3 pointer to the raw-mode instance data. */
+    RTR3PTR                         pvInstanceDataForRCR3;
+
+    /** Temporarily. */
+    R0PTRTYPE(struct PDMDEVINSR0 *) pDevInsR0RemoveMe;
+    /** Temporarily. */
+    RTR0PTR                         pvInstanceDataR0;
+    /** Temporarily. */
+    RTRCPTR                         pvInstanceDataRC;
     /** Align the internal data more naturally. */
-    uint32_t                    au32Padding[HC_ARCH_BITS == 32 ? 13 : 0];
-#endif
+    uint32_t                        au32Padding[HC_ARCH_BITS == 32 ? 4 : 1];
 
     /** Internal data. */
@@ -4225,19 +5038,152 @@
     {
 #ifdef PDMDEVINSINT_DECLARED
-        PDMDEVINSINT            s;
+        PDMDEVINSINTR3              s;
 #endif
-        uint8_t                 padding[HC_ARCH_BITS == 32 ? 72 : 112 + 0x28];
+        uint8_t                     padding[HC_ARCH_BITS == 32 ? 0x60 : 0x80];
     } Internal;
 
-    /** Device instance data. The size of this area is defined
-     * in the PDMDEVREG::cbInstanceData field. */
-    char                        achInstanceData[8];
-} PDMDEVINS;
-
-/** Current PDMDEVINS version number. */
-#define PDM_DEVINS_VERSION                      PDM_VERSION_MAKE(0xffe4, 3, 0)
-
-/** Converts a pointer to the PDMDEVINS::IBase to a pointer to PDMDEVINS. */
+    /** Device instance data for ring-3.  The size of this area is defined
+     * in the PDMDEVREG::cbInstanceR3 field. */
+    char                            achInstanceData[8];
+} PDMDEVINSR3;
+
+/** Current PDMDEVINSR3 version number. */
+#define PDM_DEVINSR3_VERSION        PDM_VERSION_MAKE(0xff82, 1, 0)
+
+/** Converts a pointer to the PDMDEVINSR3::IBase to a pointer to PDMDEVINS. */
 #define PDMIBASE_2_PDMDEV(pInterface) ( (PPDMDEVINS)((char *)(pInterface) - RT_UOFFSETOF(PDMDEVINS, IBase)) )
+
+
+/**
+ * PDM ring-0 device instance.
+ */
+typedef struct PDMDEVINSR0
+{
+    /** Structure version. PDM_DEVINSR0_VERSION defines the current version. */
+    uint32_t                        u32Version;
+    /** Device instance number. */
+    uint32_t                        iInstance;
+
+    /** Pointer the HC PDM Device API. */
+    PCPDMDEVHLPR0                   pHlpR0;
+    /** Pointer to the shared device instance data. */
+    RTR0PTR                         pvInstanceDataR0;
+    /** Pointer to the device instance data for ring-0. */
+    RTR0PTR                         pvInstanceDataForR0;
+    /** The critical section for the device.
+     *
+     * TM and IOM will enter this critical section before calling into the device
+     * code.  PDM will when doing power on, power off, reset, suspend and resume
+     * notifications.  SSM will currently not, but this will be changed later on.
+     *
+     * The device gets a critical section automatically assigned to it before
+     * the constructor is called.  If the constructor wishes to use a different
+     * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
+     * very early on.
+     */
+    R0PTRTYPE(PPDMCRITSECT)         pCritSectRoR0;
+    /** Pointer to the ring-0 device registration structure.  */
+    R0PTRTYPE(PCPDMDEVREGR0)        pReg;
+    /** Ring-3 address of the ring-3 device instance. */
+    R3PTRTYPE(struct PDMDEVINSR3 *) pDevInsForR3;
+    /** Ring-0 pointer to the ring-3 device instance. */
+    R0PTRTYPE(struct PDMDEVINSR3 *) pDevInsForR3R0;
+    /** Ring-0 pointer to the ring-3 instance data. */
+    RTR0PTR                         pvInstanceDataForR3R0;
+    /** Raw-mode address of the raw-mode device instance. */
+    RGPTRTYPE(struct PDMDEVINSRC *) pDevInsForRC;
+    /** Ring-0 pointer to the raw-mode device instance. */
+    R0PTRTYPE(struct PDMDEVINSRC *) pDevInsForRCR0;
+    /** Ring-0 pointer to the raw-mode instance data. */
+    RTR0PTR                         pvInstanceDataForRCR0;
+#if HC_ARCH_BITS == 32
+    /** Align the internal data more naturally. */
+    uint32_t                        au32Padding[HC_ARCH_BITS == 32 ? 3 : 0];
+#endif
+
+    /** Internal data. */
+    union
+    {
+#ifdef PDMDEVINSINT_DECLARED
+        PDMDEVINSINTR0              s;
+#endif
+        uint8_t                     padding[HC_ARCH_BITS == 32 ? 0x80 : 0x60];
+    } Internal;
+
+    /** Device instance data for ring-0. The size of this area is defined
+     * in the PDMDEVREG::cbInstanceR0 field. */
+    char                            achInstanceData[8];
+} PDMDEVINSR0;
+
+/** Current PDMDEVINSR0 version number. */
+#define PDM_DEVINSR0_VERSION        PDM_VERSION_MAKE(0xff83, 1, 0)
+
+
+/**
+ * PDM raw-mode device instance.
+ */
+typedef struct PDMDEVINSRC
+{
+    /** Structure version. PDM_DEVINSRC_VERSION defines the current version. */
+    uint32_t                        u32Version;
+    /** Device instance number. */
+    uint32_t                        iInstance;
+
+    /** Pointer the HC PDM Device API. */
+    PCPDMDEVHLPRC                   pHlpRC;
+    /** Pointer to the shared device instance data. */
+    RTRGPTR                         pvInstanceDataRC;
+    /** Pointer to the device instance data for raw-mode. */
+    RTRGPTR                         pvInstanceDataForRC;
+    /** The critical section for the device.
+     *
+     * TM and IOM will enter this critical section before calling into the device
+     * code.  PDM will when doing power on, power off, reset, suspend and resume
+     * notifications.  SSM will currently not, but this will be changed later on.
+     *
+     * The device gets a critical section automatically assigned to it before
+     * the constructor is called.  If the constructor wishes to use a different
+     * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
+     * very early on.
+     */
+    RGPTRTYPE(PPDMCRITSECT)         pCritSectRoRC;
+    /** Pointer to the ring-0 device registration structure.  */
+    RGPTRTYPE(PCPDMDEVREGR0)        pReg;
+
+    /** Internal data. */
+    union
+    {
+#ifdef PDMDEVINSINT_DECLARED
+        PDMDEVINSINTRC              s;
+#endif
+        uint8_t                     padding[0x10];
+    } Internal;
+
+    /** Device instance data for ring-0. The size of this area is defined
+     * in the PDMDEVREG::cbInstanceR0 field. */
+    char                            achInstanceData[8];
+} PDMDEVINSRC;
+
+/** Current PDMDEVINSR0 version number. */
+#define PDM_DEVINSRC_VERSION        PDM_VERSION_MAKE(0xff84, 1, 0)
+
+
+/** @def PDM_DEVINS_VERSION
+ * Current PDMDEVINS version number. */
+/** @typedef PDMDEVINS
+ * The device instance structure for the current context. */
+#ifdef IN_RING3
+# define PDM_DEVINS_VERSION         PDM_DEVINSR3_VERSION
+typedef PDMDEVINSR3                 PDMDEVINS;
+#elif defined(IN_RING0)
+# define PDM_DEVINS_VERSION         PDM_DEVINSR0_VERSION
+typedef PDMDEVINSR0                 PDMDEVINS;
+#elif defined(IN_RC)
+# define PDM_DEVINS_VERSION         PDM_DEVINSRC_VERSION
+typedef PDMDEVINSRC                 PDMDEVINS;
+#else
+# error "Missing context defines: IN_RING0, IN_RING3, IN_RC"
+#endif
+
 
 /**
@@ -4297,6 +5243,6 @@
     do \
     { \
-        int rcValCfg = CFGMR3ValidateConfig((pDevIns)->pCfg, "/", pszValidValues, pszValidNodes, \
-                                            (pDevIns)->pReg->szName, (pDevIns)->iInstance); \
+        int rcValCfg = pDevIns->pHlpR3->pfnCFGMValidateConfig((pDevIns)->pCfg, "/", pszValidValues, pszValidNodes, \
+                                                              (pDevIns)->pReg->szName, (pDevIns)->iInstance); \
         if (RT_SUCCESS(rcValCfg)) \
         { /* likely */ } else return rcValCfg; \
@@ -4345,15 +5291,37 @@
  * Converts a PDM Device instance pointer a RC PDM Device instance pointer.
  */
-#define PDMDEVINS_2_RCPTR(pDevIns)  ( (RCPTRTYPE(PPDMDEVINS))((RTRCUINTPTR)(pDevIns)->pvInstanceDataRC - (RTRCUINTPTR)RT_UOFFSETOF(PDMDEVINS, achInstanceData)) )
+#ifdef IN_RC
+# define PDMDEVINS_2_RCPTR(pDevIns)  (pDevIns)
+#else
+# define PDMDEVINS_2_RCPTR(pDevIns)  ( (pDevIns)->pDevInsForRC )
+#endif
 
 /** @def PDMDEVINS_2_R3PTR
  * Converts a PDM Device instance pointer a R3 PDM Device instance pointer.
  */
-#define PDMDEVINS_2_R3PTR(pDevIns)  ( (R3PTRTYPE(PPDMDEVINS))((RTHCUINTPTR)(pDevIns)->pvInstanceDataR3 - RT_UOFFSETOF(PDMDEVINS, achInstanceData)) )
+#ifdef IN_RING3
+# define PDMDEVINS_2_R3PTR(pDevIns)  (pDevIns)
+#else
+# define PDMDEVINS_2_R3PTR(pDevIns)  ( (pDevIns)->pDevInsForR3 )
+#endif
 
 /** @def PDMDEVINS_2_R0PTR
  * Converts a PDM Device instance pointer a R0 PDM Device instance pointer.
  */
-#define PDMDEVINS_2_R0PTR(pDevIns)  ( (R0PTRTYPE(PPDMDEVINS))((RTR0UINTPTR)(pDevIns)->pvInstanceDataR0 - RT_UOFFSETOF(PDMDEVINS, achInstanceData)) )
+#ifdef IN_RING0
+# define PDMDEVINS_2_R0PTR(pDevIns)  (pDevIns)
+#else
+# define PDMDEVINS_2_R0PTR(pDevIns)  ( (pDevIns)->pDevInsR0RemoveMe )
+#endif
+
+/** @def PDMDEVINS_DATA_2_R0_REMOVE_ME
+ * Converts a PDM device instance data pointer to a ring-0 one.
+ * @deprecated
+ */
+#ifdef IN_RING0
+# define PDMDEVINS_DATA_2_R0_REMOVE_ME(pDevIns, pvCC)  (pvCC)
+#else
+# define PDMDEVINS_DATA_2_R0_REMOVE_ME(pDevIns, pvCC)  ( (pDevIns)->pvInstanceDataR0 + (uintptr_t)(pvCC) - (uintptr_t)(pDevIns)->CTX_SUFF(pvInstanceData) )
+#endif
 
 
@@ -4397,4 +5365,153 @@
     return pDevIns->pHlpR3->pfnIOPortDeregister(pDevIns, Port, cPorts);
 }
+
+/**
+ * Combines PDMDevHlpIoPortCreate() & PDMDevHlpIoPortMap().
+ */
+DECLINLINE(int) PDMDevHlpIoPortCreateAndMap(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, PFNIOMIOPORTOUT pfnOut,
+                                            PFNIOMIOPORTIN pfnIn, void *pvUser, const char *pszDesc, PIOMIOPORTHANDLE phIoPorts)
+{
+    int rc = pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, 0, NULL, UINT32_MAX,
+                                                pfnOut, pfnIn, NULL, NULL, pvUser, pszDesc, phIoPorts);
+    if (RT_SUCCESS(rc))
+        rc = pDevIns->pHlpR3->pfnIoPortMap(pDevIns, *phIoPorts, Port);
+    return rc;
+}
+
+/**
+ * @sa PDMDevHlpIoPortCreateEx
+ */
+DECLINLINE(int) PDMDevHlpIoPortCreate(PPDMDEVINS pDevIns, RTIOPORT cPorts, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
+                                      PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, void *pvUser, const char *pszDesc,
+                                      PIOMIOPORTHANDLE phIoPorts)
+{
+    return pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, 0, pPciDev, iPciRegion,
+                                              pfnOut, pfnIn, NULL, NULL, pvUser, pszDesc, phIoPorts);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnIoPortCreateEx
+ */
+DECLINLINE(int) PDMDevHlpIoPortCreateEx(PPDMDEVINS pDevIns, RTIOPORT cPorts, uint32_t fFlags, PPDMPCIDEV pPciDev,
+                                        uint32_t iPciRegion, PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
+                                        PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr,
+                                        void *pvUser, const char *pszDesc, PIOMIOPORTHANDLE phIoPorts)
+{
+    return pDevIns->pHlpR3->pfnIoPortCreateEx(pDevIns, cPorts, fFlags, pPciDev, iPciRegion,
+                                              pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser, pszDesc, phIoPorts);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnIoPortMap
+ */
+DECLINLINE(int) PDMDevHlpIoPortMap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT Port)
+{
+    return pDevIns->pHlpR3->pfnIoPortMap(pDevIns, hIoPorts, Port);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnIoPortUnmap
+ */
+DECLINLINE(int) PDMDevHlpIoPortUnmap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)
+{
+    return pDevIns->pHlpR3->pfnIoPortUnmap(pDevIns, hIoPorts);
+}
+
+#endif /* IN_RING3 */
+#ifndef IN_RING3
+
+/**
+ * @sa PDMDevHlpIoPortSetUpContextEx
+ */
+DECLINLINE(int) PDMDevHlpIoPortSetUpContext(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
+                                            PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn, void *pvUser)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnIoPortSetUpContextEx(pDevIns, hIoPorts, pfnOut, pfnIn, NULL, NULL, pvUser);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnIoPortCreateEx
+ */
+DECLINLINE(int) PDMDevHlpIoPortSetUpContextEx(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
+                                              PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
+                                              PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, void *pvUser)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnIoPortSetUpContextEx(pDevIns, hIoPorts, pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser);
+}
+
+#endif /* !IN_RING3 */
+#ifdef IN_RING3
+
+
+/**
+ * @sa PDMDevHlpMmioCreateEx
+ */
+DECLINLINE(int) PDMDevHlpMmioCreate(PPDMDEVINS pDevIns, RTGCPHYS cbRegion, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
+                                    PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, void *pvUser,
+                                    const char *pszDesc, PIOMMMIOHANDLE phRegion)
+{
+    return pDevIns->pHlpR3->pfnMmioCreateEx(pDevIns, cbRegion, 0, pPciDev, iPciRegion,
+                                            pfnWrite, pfnRead, NULL, pvUser, pszDesc, phRegion);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMmioCreateEx
+ */
+DECLINLINE(int) PDMDevHlpMmioCreateEx(PPDMDEVINS pDevIns, RTGCPHYS cbRegion,
+                                      uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
+                                      PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
+                                      void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion)
+{
+    return pDevIns->pHlpR3->pfnMmioCreateEx(pDevIns, cbRegion, fFlags, pPciDev, iPciRegion,
+                                            pfnWrite, pfnRead, pfnFill, pvUser, pszDesc, phRegion);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMmioMap
+ */
+DECLINLINE(int) PDMDevHlpMmioMap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys)
+{
+    return pDevIns->pHlpR3->pfnMmioMap(pDevIns, hRegion, GCPhys);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMmioUnmap
+ */
+DECLINLINE(int) PDMDevHlpMmioUnmap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
+{
+    return pDevIns->pHlpR3->pfnMmioUnmap(pDevIns, hRegion);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMmioReduce
+ */
+DECLINLINE(int) PDMDevHlpMmioReduce(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS cbRegion)
+{
+    return pDevIns->pHlpR3->pfnMmioReduce(pDevIns, hRegion, cbRegion);
+}
+
+#endif /* IN_RING3 */
+#ifndef IN_RING3
+
+/**
+ * @sa PDMDevHlpMmioSetUpContextEx
+ */
+DECLINLINE(int) PDMDevHlpMmioSetUpContext(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion,
+                                          PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, void *pvUser)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnMmioSetUpContextEx(pDevIns, hRegion, pfnWrite, pfnRead, NULL, pvUser);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMmioCreateEx
+ */
+DECLINLINE(int) PDMDevHlpMmioSetUpContextEx(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIOWRITE pfnWrite,
+                                            PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill, void *pvUser)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnMmioSetUpContextEx(pDevIns, hRegion, pfnWrite, pfnRead, pfnFill, pvUser);
+}
+
+#endif /* !IN_RING3 */
+#ifdef IN_RING3
 
 /**
@@ -4667,4 +5784,177 @@
 
 /**
+ * @copydoc PDMDEVHLPR3::pfnTimerCreate
+ */
+DECLINLINE(int) PDMDevHlpTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser,
+                                     uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
+{
+    return pDevIns->pHlpR3->pfnTimerCreate(pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, phTimer);
+}
+
+#endif /* IN_RING3 */
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerToPtr
+ */
+DECLINLINE(PTMTIMER) PDMDevHlpTimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerToPtr(pDevIns, hTimer);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerFromMicro
+ */
+DECLINLINE(uint64_t) PDMDevHlpTimerFromMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerFromMicro(pDevIns, hTimer, cMicroSecs);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerFromMilli
+ */
+DECLINLINE(uint64_t) PDMDevHlpTimerFromMilli(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerFromMilli(pDevIns, hTimer, cMilliSecs);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerFromNano
+ */
+DECLINLINE(uint64_t) PDMDevHlpTimerFromNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerFromNano(pDevIns, hTimer, cNanoSecs);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerGet
+ */
+DECLINLINE(uint64_t) PDMDevHlpTimerGet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerGet(pDevIns, hTimer);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerGetFreq
+ */
+DECLINLINE(uint64_t) PDMDevHlpTimerGetFreq(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerGetFreq(pDevIns, hTimer);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerGetNano
+ */
+DECLINLINE(uint64_t) PDMDevHlpTimerGetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerGetNano(pDevIns, hTimer);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerIsActive
+ */
+DECLINLINE(bool)     PDMDevHlpTimerIsActive(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerIsActive(pDevIns, hTimer);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerIsLockOwner
+ */
+DECLINLINE(bool)     PDMDevHlpTimerIsLockOwner(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerIsLockOwner(pDevIns, hTimer);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerLock
+ */
+DECLINLINE(int)      PDMDevHlpTimerLock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerLock(pDevIns, hTimer, rcBusy);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerSet
+ */
+DECLINLINE(int)      PDMDevHlpTimerSet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerSet(pDevIns, hTimer, uExpire);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerSetFrequencyHint
+ */
+DECLINLINE(int)      PDMDevHlpTimerSetFrequencyHint(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetFrequencyHint(pDevIns, hTimer, uHz);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerSetMicro
+ */
+DECLINLINE(int)      PDMDevHlpTimerSetMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetMicro(pDevIns, hTimer, cMicrosToNext);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerSetMillies
+ */
+DECLINLINE(int)      PDMDevHlpTimerSetMillies(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetMillies(pDevIns, hTimer, cMilliesToNext);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerSetNano
+ */
+DECLINLINE(int)      PDMDevHlpTimerSetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetNano(pDevIns, hTimer, cNanosToNext);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerSetRelative
+ */
+DECLINLINE(int)      PDMDevHlpTimerSetRelative(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerSetRelative(pDevIns, hTimer, cTicksToNext, pu64Now);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerStop
+ */
+DECLINLINE(int)      PDMDevHlpTimerStop(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnTimerStop(pDevIns, hTimer);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerUnlock
+ */
+DECLINLINE(void)     PDMDevHlpTimerUnlock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    pDevIns->CTX_SUFF(pHlp)->pfnTimerUnlock(pDevIns, hTimer);
+}
+
+#ifdef IN_RING3
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerSave
+ */
+DECLINLINE(int) PDMDevHlpTimerSave(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
+{
+    return pDevIns->pHlpR3->pfnTimerSave(pDevIns, hTimer, pSSM);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTimerLoad
+ */
+DECLINLINE(int) PDMDevHlpTimerLoad(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
+{
+    return pDevIns->pHlpR3->pfnTimerLoad(pDevIns, hTimer, pSSM);
+}
+
+/**
  * @copydoc PDMDEVHLPR3::pfnTMUtcNow
  */
@@ -4674,5 +5964,5 @@
 }
 
-#endif /* IN_RING3 */
+#endif
 
 /**
@@ -5175,4 +6465,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * @copydoc PDMDEVHLPR3::pfnCritSectGetNop
@@ -5180,6 +6472,8 @@
 DECLINLINE(PPDMCRITSECT) PDMDevHlpCritSectGetNop(PPDMDEVINS pDevIns)
 {
-    return pDevIns->pHlpR3->pfnCritSectGetNop(pDevIns);
-}
+    return pDevIns->CTX_SUFF(pHlp)->pfnCritSectGetNop(pDevIns);
+}
+
+#ifdef IN_RING3
 
 /**
@@ -5199,4 +6493,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * @copydoc PDMDEVHLPR3::pfnSetDeviceCritSect
@@ -5204,6 +6500,105 @@
 DECLINLINE(int) PDMDevHlpSetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
 {
-    return pDevIns->pHlpR3->pfnSetDeviceCritSect(pDevIns, pCritSect);
-}
+    return pDevIns->CTX_SUFF(pHlp)->pfnSetDeviceCritSect(pDevIns, pCritSect);
+}
+
+/**
+ * @copydoc PDMCritSectEnter
+ * @param   pDevIns  The device instance.
+ */
+DECLINLINE(int) PDMDevHlpCritSectEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnCritSectEnter(pCritSect, rcBusy);
+}
+
+/**
+ * @copydoc PDMCritSectEnterDebug
+ * @param   pDevIns  The device instance.
+ */
+DECLINLINE(int) PDMDevHlpCritSectEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnCritSectEnterDebug(pCritSect, rcBusy, uId, RT_SRC_POS_ARGS);
+}
+
+/**
+ * @copydoc PDMCritSectTryEnter
+ * @param   pDevIns  The device instance.
+ */
+DECLINLINE(int)      PDMDevHlpCritSectTryEnter(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnCritSectTryEnter(pCritSect);
+}
+
+/**
+ * @copydoc PDMCritSectTryEnterDebug
+ * @param   pDevIns  The device instance.
+ */
+DECLINLINE(int)      PDMDevHlpCritSectTryEnterDebug(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnCritSectTryEnterDebug(pCritSect, uId, RT_SRC_POS_ARGS);
+}
+
+/**
+ * @copydoc PDMCritSectLeave
+ * @param   pDevIns  The device instance.
+ */
+DECLINLINE(int)      PDMDevHlpCritSectLeave(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnCritSectLeave(pCritSect);
+}
+
+/**
+ * @copydoc PDMCritSectIsOwner
+ * @param   pDevIns  The device instance.
+ */
+DECLINLINE(bool)     PDMDevHlpCritSectIsOwner(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnCritSectIsOwner(pCritSect);
+}
+
+/**
+ * @copydoc PDMCritSectIsInitialized
+ * @param   pDevIns  The device instance.
+ */
+DECLINLINE(bool)     PDMDevHlpCritSectIsInitialized(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnCritSectIsInitialized(pCritSect);
+}
+
+/**
+ * @copydoc PDMCritSectHasWaiters
+ * @param   pDevIns  The device instance.
+ */
+DECLINLINE(bool)     PDMDevHlpCritSectHasWaiters(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnCritSectHasWaiters(pCritSect);
+}
+
+/**
+ * @copydoc PDMCritSectGetRecursion
+ * @param   pDevIns  The device instance.
+ */
+DECLINLINE(uint32_t) PDMDevHlpCritSectGetRecursion(PPDMDEVINS pDevIns, PCPDMCRITSECT pCritSect)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnCritSectGetRecursion(pCritSect);
+}
+
+/**
+ * @copydoc PDMCritSect
+ * @param   pDevIns  The device instance.
+ */
+
+/* Strict build: Remap the two enter calls to the debug versions. */
+#ifdef VBOX_STRICT
+# ifdef IPRT_INCLUDED_asm_h
+#  define PDMDevHlpCritSectEnter(pDevIns, pCritSect, rcBusy) PDMDevHlpCritSectEnterDebug((pDevIns), (pCritSect), (rcBusy), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+#  define PDMDevHlpCritSectTryEnter(pDevIns, pCritSect)      PDMDevHlpCritSectTryEnterDebug((pDevIns), (pCritSect), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# else
+#  define PDMDevHlpCritSectEnter(pDevIns, pCritSect, rcBusy) PDMDevHlpCritSectEnterDebug((pDevIns), (pCritSect), (rcBusy), 0, RT_SRC_POS)
+#  define PDMDevHlpCritSectTryEnter(pDevIns, pCritSect)      PDMDevHlpCritSectTryEnterDebug((pDevIns), (pCritSect), 0, RT_SRC_POS)
+# endif
+#endif
+
+#ifdef IN_RING3
 
 /**
Index: /trunk/include/VBox/vmm/pdmins.h
===================================================================
--- /trunk/include/VBox/vmm/pdmins.h	(revision 80530)
+++ /trunk/include/VBox/vmm/pdmins.h	(revision 80531)
@@ -50,10 +50,22 @@
 
 /** @def PDMINS_2_DATA
- * Converts a PDM Device, USB Device, or Driver instance pointer to a pointer to the instance data.
+ * Gets the shared instance data for a PDM device, USB device, or driver instance.
  */
-#define PDMINS_2_DATA(pIns, type)   ( (type)(void *)&(pIns)->achInstanceData[0] )
+#define PDMINS_2_DATA(pIns, type)       ( (type)(pIns)->CTX_SUFF(pvInstanceData) )
+
+/** @def PDMINS_2_DATA_CC
+ * Gets the current context instance data for a PDM device, USB device, or driver instance.
+ */
+#define PDMINS_2_DATA_CC(pIns, type)    ( (type)(void *)&(pIns)->achInstanceData[0] )
+
+/* @def PDMINS_2_DATA_RC
+ * Gets the raw-mode context instance data for a PDM device instance.
+ */
+#define PDMINS_2_DATA_RC(pIns, type)    ( (type)(pIns)->CTX_SUFF(pvInstanceDataForRC) )
+
 
 /** @def PDMINS_2_DATA_RCPTR
  * Converts a PDM Device, USB Device, or Driver instance pointer to a RC pointer to the instance data.
+ * @deprecated
  */
 #define PDMINS_2_DATA_RCPTR(pIns)   ( (pIns)->pvInstanceDataRC )
@@ -61,4 +73,5 @@
 /** @def PDMINS_2_DATA_R3PTR
  * Converts a PDM Device, USB Device, or Driver instance pointer to a HC pointer to the instance data.
+ * @deprecated
  */
 #define PDMINS_2_DATA_R3PTR(pIns)   ( (pIns)->pvInstanceDataR3 )
@@ -66,4 +79,5 @@
 /** @def PDMINS_2_DATA_R0PTR
  * Converts a PDM Device, USB Device, or Driver instance pointer to a R0 pointer to the instance data.
+ * @deprecated
  */
 #define PDMINS_2_DATA_R0PTR(pIns)   ( (pIns)->pvInstanceDataR0 )
Index: /trunk/include/VBox/vmm/ssm.h
===================================================================
--- /trunk/include/VBox/vmm/ssm.h	(revision 80530)
+++ /trunk/include/VBox/vmm/ssm.h	(revision 80531)
@@ -1291,4 +1291,5 @@
 VMMR3DECL(int) SSMR3SetLoadErrorV(PSSMHANDLE pSSM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(6, 0);
 VMMR3DECL(int) SSMR3SetCfgError(PSSMHANDLE pSSM, RT_SRC_POS_DECL, const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(5, 6);
+VMMR3DECL(int) SSMR3SetCfgErrorV(PSSMHANDLE pSSM, RT_SRC_POS_DECL, const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(5, 0);
 
 /** @} */
Index: /trunk/include/VBox/vmm/vmm.h
===================================================================
--- /trunk/include/VBox/vmm/vmm.h	(revision 80530)
+++ /trunk/include/VBox/vmm/vmm.h	(revision 80531)
@@ -353,4 +353,12 @@
     /** Call PDMR0DeviceCallReqHandler. */
     VMMR0_DO_PDM_DEVICE_CALL_REQ_HANDLER,
+    /** Call PDMR0DeviceCreateReqHandler. */
+    VMMR0_DO_PDM_DEVICE_CREATE,
+    /** Call PDMR0DeviceGenCallReqHandler. */
+    VMMR0_DO_PDM_DEVICE_GEN_CALL,
+    /** Old style device compat: Set ring-0 critical section. */
+    VMMR0_DO_PDM_DEVICE_COMPAT_SET_CRITSECT,
+    /** Old style device compat: Register PCI device. */
+    VMMR0_DO_PDM_DEVICE_COMPAT_REG_PCIDEV,
 
     /** Set a GVMM or GMM configuration value. */
Index: /trunk/include/iprt/cdefs.h
===================================================================
--- /trunk/include/iprt/cdefs.h	(revision 80530)
+++ /trunk/include/iprt/cdefs.h	(revision 80531)
@@ -750,4 +750,11 @@
 #define RCPTRTYPE(RCType)       CTXTYPE(RCType, RTRCPTR, RTRCPTR)
 
+/** @def GCPTRTYPE
+ * This will become RCPTRTYPE once we've convered all uses of RCPTRTYPE to this.
+ *
+ * @param   RCType  The RC type.
+ */
+#define RGPTRTYPE(RCType)       CTXTYPE(RCType, RTGCPTR, RTGCPTR)
+
 /** @def R3R0PTRTYPE
  * Declare a pointer which is used in HC, is explicitly valid in ring 3 and 0,
@@ -1430,4 +1437,9 @@
 #else
 # define DECLRCCALLBACKMEMBER(type, name, args)  RTRCPTR name
+#endif
+#ifdef IN_RC
+# define DECLRGCALLBACKMEMBER(type, name, args)  DECLCALLBACKMEMBER(type, name)  args
+#else
+# define DECLRGCALLBACKMEMBER(type, name, args)  RTRGPTR name
 #endif
 
Index: /trunk/include/iprt/err.h
===================================================================
--- /trunk/include/iprt/err.h	(revision 80530)
+++ /trunk/include/iprt/err.h	(revision 80531)
@@ -103,4 +103,6 @@
 /** The request function is not implemented. */
 #define VERR_NOT_IMPLEMENTED                (-12)
+/** The request function is not implemented. */
+#define VINF_NOT_IMPLEMENTED                12
 /** Invalid flags was given. */
 #define VERR_INVALID_FLAGS                  (-13)
@@ -372,4 +374,10 @@
 /** Incompatible configuration requested. */
 #define VERR_INCOMPATIBLE_CONFIG            (-22420)
+/** String is not terminated within the buffer bounds. */
+#define VERR_NO_STRING_TERMINATOR           (-22421)
+/** Empty string. */
+#define VERR_EMPTY_STRING                   (-22422)
+/** Too many references to an object. */
+#define VERR_TOO_MANY_REFERENCES            (-22423)
 /** @} */
 
Index: /trunk/include/iprt/list.h
===================================================================
--- /trunk/include/iprt/list.h	(revision 80530)
+++ /trunk/include/iprt/list.h	(revision 80531)
@@ -74,6 +74,6 @@
 
 /** Version of RTLISTNODE for holding a ring-3 only list in data which gets
- * shared between multiple contexts */
-#if defined(IN_RING3)
+ * shared between multiple contexts. */
+#ifdef IN_RING3
 typedef RTLISTNODE RTLISTNODER3;
 #else
@@ -81,6 +81,17 @@
 #endif
 /** Version of RTLISTANCHOR for holding a ring-3 only list in data which gets
- * shared between multiple contexts */
+ * shared between multiple contexts. */
 typedef RTLISTNODER3 RTLISTANCHORR3;
+
+/** Version of RTLISTNODE for holding a ring-0 only list in data which gets
+ * shared between multiple contexts. */
+#ifdef IN_RING0
+typedef RTLISTNODE RTLISTNODER0;
+#else
+typedef struct { RTR0PTR aOffLimits[2]; } RTLISTNODER0;
+#endif
+/** Version of RTLISTANCHOR for holding a ring-0 only list in data which gets
+ * shared between multiple contexts. */
+typedef RTLISTNODER0 RTLISTANCHORR0;
 
 
Index: /trunk/include/iprt/types.h
===================================================================
--- /trunk/include/iprt/types.h	(revision 80530)
+++ /trunk/include/iprt/types.h	(revision 80531)
@@ -1879,4 +1879,18 @@
 #define RTRCINTPTR_MAX          ((RTRCINTPTR)INT32_MAX)
 
+/* The following are only temporarily while we clean up RTRCPTR usage: */
+#ifdef IN_RC
+typedef void            RT_FAR *RTRGPTR;
+#else
+typedef uint64_t                RTRGPTR;
+#endif
+typedef RTRGPTR         RT_FAR *PRTRGPTR;
+typedef const RTRGPTR   RT_FAR *PCRTRGPTR;
+#ifdef IN_RC
+# define NIL_RTRGPTR            (NULL)
+#else
+# define NIL_RTRGPTR            ((RTRGPTR)0)
+#endif
+
 /** @} */
 
Index: /trunk/src/VBox/Devices/Audio/DevHDA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevHDA.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Audio/DevHDA.cpp	(revision 80531)
@@ -5355,4 +5355,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * The device registration structure.
@@ -5360,55 +5362,71 @@
 const PDMDEVREG g_DeviceHDA =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "hda",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Intel HD Audio Controller",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_AUDIO,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(HDASTATE),
-    /* pfnConstruct */
-    hdaR3Construct,
-    /* pfnDestruct */
-    hdaR3Destruct,
-    /* pfnRelocate */
-    hdaR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    hdaR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    hdaR3Attach,
-    /* pfnDetach */
-    hdaR3Detach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    hdaR3PowerOff,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "hda",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_AUDIO,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(HDASTATE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Intel HD Audio Controller",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           hdaR3Construct,
+    /* .pfnDestruct = */            hdaR3Destruct,
+    /* .pfnRelocate = */            hdaR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               hdaR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              hdaR3Attach,
+    /* .pfnDetach = */              hdaR3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            hdaR3PowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Audio/DevIchAc97.cpp	(revision 80531)
@@ -4543,4 +4543,6 @@
 }
 
+#endif /* !IN_RING3 */
+
 /**
  * The device registration structure.
@@ -4548,55 +4550,71 @@
 const PDMDEVREG g_DeviceICHAC97 =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "ichac97",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "ICH AC'97 Audio Controller",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_AUDIO,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(AC97STATE),
-    /* pfnConstruct */
-    ichac97R3Construct,
-    /* pfnDestruct */
-    ichac97R3Destruct,
-    /* pfnRelocate */
-    ichac97R3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    ichac97R3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    ichac97R3Attach,
-    /* pfnDetach */
-    ichac97R3Detach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    ichac97R3PowerOff,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "ichac97",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_AUDIO,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(AC97STATE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "ICH AC'97 Audio Controller",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           ichac97R3Construct,
+    /* .pfnDestruct = */            ichac97R3Destruct,
+    /* .pfnRelocate = */            ichac97R3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               ichac97R3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              ichac97R3Attach,
+    /* .pfnDetach = */              ichac97R3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            ichac97R3PowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* !IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/Audio/DevSB16.cpp
===================================================================
--- /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Audio/DevSB16.cpp	(revision 80531)
@@ -2597,52 +2597,69 @@
 const PDMDEVREG g_DeviceSB16 =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "sb16",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "Sound Blaster 16 Controller",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS,
-    /* fClass */
-    PDM_DEVREG_CLASS_AUDIO,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(SB16STATE),
-    /* pfnConstruct */
-    sb16Construct,
-    /* pfnDestruct */
-    sb16Destruct,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    sb16DevReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    sb16Attach,
-    /* pfnDetach */
-    sb16Detach,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    sb16PowerOff,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "sb16",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fClass = */                 PDM_DEVREG_CLASS_AUDIO,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(SB16STATE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Sound Blaster 16 Controller",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "",
+    /* .pszR0Mod = */               "",
+    /* .pfnConstruct = */           sb16Construct,
+    /* .pfnDestruct = */            sb16Destruct,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               sb16DevReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              sb16Attach,
+    /* .pfnDetach = */              sb16Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            sb16PowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
Index: /trunk/src/VBox/Devices/Bus/DevPCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Bus/DevPCI.cpp	(revision 80531)
@@ -1394,4 +1394,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -1400,55 +1401,71 @@
 const PDMDEVREG g_DevicePCI =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "pci",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "i440FX PCI bridge and PIIX3 ISA bridge.",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_BUS_PCI | PDM_DEVREG_CLASS_BUS_ISA,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(DEVPCIROOT),
-    /* pfnConstruct */
-    pciR3Construct,
-    /* pfnDestruct */
-    pciR3Destruct,
-    /* pfnRelocate */
-    devpciR3RootRelocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    pciR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "pci",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_BUS_PCI | PDM_DEVREG_CLASS_BUS_ISA,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVPCIROOT),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "i440FX PCI bridge and PIIX3 ISA bridge.",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           pciR3Construct,
+    /* .pfnDestruct = */            pciR3Destruct,
+    /* .pfnRelocate = */            devpciR3RootRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               pciR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 
 };
-#endif /* IN_RING3 */
 
 
@@ -1719,4 +1736,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -1726,54 +1744,69 @@
 const PDMDEVREG g_DevicePCIBridge =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "pcibridge",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "82801 Mobile PCI to PCI bridge",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_BUS_PCI,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(DEVPCIBUS),
-    /* pfnConstruct */
-    pcibridgeR3Construct,
-    /* pfnDestruct */
-    pcibridgeR3Destruct,
-    /* pfnRelocate */
-    devpciR3BusRelocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    pcibridgeR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "pcibridge",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_BUS_PCI,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVPCIBUS),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "82801 Mobile PCI to PCI bridge",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           pcibridgeR3Construct,
+    /* .pfnDestruct = */            pcibridgeR3Destruct,
+    /* .pfnRelocate = */            devpciR3BusRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               pcibridgeR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
-
Index: /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 80531)
@@ -3588,5 +3588,5 @@
 }
 
-
+#endif /* IN_RING3 */
 
 /**
@@ -3595,52 +3595,69 @@
 const PDMDEVREG g_DevicePciIch9 =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "ich9pci",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "ICH9 PCI bridge",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_BUS_PCI | PDM_DEVREG_CLASS_BUS_ISA,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(DEVPCIROOT),
-    /* pfnConstruct */
-    ich9pciConstruct,
-    /* pfnDestruct */
-    ich9pciDestruct,
-    /* pfnRelocate */
-    devpciR3RootRelocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    ich9pciReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "ich9pci",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_BUS_PCI | PDM_DEVREG_CLASS_BUS_ISA,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVPCIROOT),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "ICH9 PCI bridge",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           ich9pciConstruct,
+    /* .pfnDestruct = */            ich9pciDestruct,
+    /* .pfnRelocate = */            devpciR3RootRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               ich9pciReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
@@ -3651,54 +3668,69 @@
 const PDMDEVREG g_DevicePciIch9Bridge =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "ich9pcibridge",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "ICH9 PCI to PCI bridge",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_BUS_PCI,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(DEVPCIBUS),
-    /* pfnConstruct */
-    ich9pcibridgeConstruct,
-    /* pfnDestruct */
-    ich9pcibridgeDestruct,
-    /* pfnRelocate */
-    devpciR3BusRelocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL, /* Must be NULL, to make sure only bus driver handles reset */
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "ich9pcibridge",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_BUS_PCI,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVPCIBUS),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "ICH9 PCI to PCI bridge",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           ich9pcibridgeConstruct,
+    /* .pfnDestruct = */            ich9pcibridgeDestruct,
+    /* .pfnRelocate = */            devpciR3BusRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               NULL, /* Must be NULL, to make sure only bus driver handles reset */
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
-
Index: /trunk/src/VBox/Devices/Bus/DevPciMerge1.cpp.h
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPciMerge1.cpp.h	(revision 80530)
+++ /trunk/src/VBox/Devices/Bus/DevPciMerge1.cpp.h	(revision 80531)
@@ -51,4 +51,5 @@
  *
  * @returns VBox status code.
+ * @param   pDevIns         The PCI bus device instance.
  * @param   pBus            The bus to register with.
  * @param   pPciDev         The PCI device structure.
@@ -64,5 +65,5 @@
  * @remarks Caller enters the PDM critical section.
  */
-static int pciR3MergedRegisterDeviceOnBus(PDEVPCIBUS pBus, PPDMPCIDEV pPciDev, uint32_t fFlags,
+static int pciR3MergedRegisterDeviceOnBus(PPDMDEVINS pDevIns, PDEVPCIBUS pBus, PPDMPCIDEV pPciDev, uint32_t fFlags,
                                           uint8_t uPciDevNo, uint8_t uPciFunNo, const char *pszName,
                                           PFNPCICONFIGREAD pfnConfigRead, PFNPCICONFIGWRITE pfnConfigWrite)
@@ -193,6 +194,7 @@
     pPciDev->uDevFn                 = VBOX_PCI_DEVFN_MAKE(uPciDevNo, uPciFunNo);
     pPciDev->Int.s.pBusR3           = pBus;
-    pPciDev->Int.s.pBusR0           = MMHyperR3ToR0(PDMDevHlpGetVM(pBus->CTX_SUFF(pDevIns)), pBus);
-    pPciDev->Int.s.pBusRC           = MMHyperR3ToRC(PDMDevHlpGetVM(pBus->CTX_SUFF(pDevIns)), pBus);
+    Assert(pBus == PDMINS_2_DATA(pDevIns, PDEVPCIBUS));
+    pPciDev->Int.s.pBusR0           = PDMINS_2_DATA_R0PTR(pDevIns);
+    pPciDev->Int.s.pBusRC           = PDMINS_2_DATA_RCPTR(pDevIns);
     pPciDev->Int.s.pfnConfigRead    = pfnConfigRead;
     pPciDev->Int.s.pfnConfigWrite   = pfnConfigWrite;
@@ -223,5 +225,5 @@
     PDEVPCIBUS pBus = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
     AssertCompileMemberOffset(DEVPCIROOT, PciBus, 0);
-    return pciR3MergedRegisterDeviceOnBus(pBus, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName,
+    return pciR3MergedRegisterDeviceOnBus(pDevIns, pBus, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName,
                                           devpciR3CommonDefaultConfigRead, devpciR3CommonDefaultConfigWrite);
 }
@@ -235,5 +237,5 @@
 {
     PDEVPCIBUS pBus = PDMINS_2_DATA(pDevIns, PDEVPCIBUS);
-    return pciR3MergedRegisterDeviceOnBus(pBus, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName,
+    return pciR3MergedRegisterDeviceOnBus(pDevIns, pBus, pPciDev, fFlags, uPciDevNo, uPciFunNo, pszName,
                                           devpciR3CommonDefaultConfigRead, devpciR3CommonDefaultConfigWrite);
 }
Index: /trunk/src/VBox/Devices/EFI/DevEFI.cpp
===================================================================
--- /trunk/src/VBox/Devices/EFI/DevEFI.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/EFI/DevEFI.cpp	(revision 80531)
@@ -2453,4 +2453,5 @@
 }
 
+
 /**
  * The device registration structure.
@@ -2458,52 +2459,70 @@
 const PDMDEVREG g_DeviceEFI =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "efi",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "Extensible Firmware Interface Device. "
-    "LUN#0 - NVRAM port",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64,
-    /* fClass */
-    PDM_DEVREG_CLASS_ARCH_BIOS,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(DEVEFI),
-    /* pfnConstruct */
-    efiConstruct,
-    /* pfnDestruct */
-    efiDestruct,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    efiMemSetup,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    efiReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete. */
-    efiInitComplete,
-    /* pfnPowerOff */
-    efiPowerOff,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "efi",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fClass = */                 PDM_DEVREG_CLASS_ARCH_BIOS,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVEFI),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Extensible Firmware Interface Device.\n"
+                                    "LUN#0 - NVRAM port",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "",
+    /* .pszR0Mod = */               "",
+    /* .pfnConstruct = */           efiConstruct,
+    /* .pfnDestruct = */            efiDestruct,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            efiMemSetup,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               efiReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        efiInitComplete,
+    /* .pfnPowerOff = */            efiPowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
+
Index: /trunk/src/VBox/Devices/EFI/DevFlash.cpp
===================================================================
--- /trunk/src/VBox/Devices/EFI/DevFlash.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/EFI/DevFlash.cpp	(revision 80531)
@@ -71,6 +71,4 @@
 *   Structures and Typedefs                                                                                                      *
 *********************************************************************************************************************************/
-
-
 /**
  * The flash device
@@ -111,13 +109,4 @@
 
 
-/*********************************************************************************************************************************
-*   Internal Functions                                                                                                           *
-*********************************************************************************************************************************/
-
-
-/*********************************************************************************************************************************
-*   Global Variables                                                                                                             *
-*********************************************************************************************************************************/
-
 #ifdef IN_RING3 /* for now */
 
@@ -526,4 +515,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -532,54 +522,70 @@
 const PDMDEVREG g_DeviceFlash =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "flash",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Flash Memory Device",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
-    /* fClass */
-    PDM_DEVREG_CLASS_ARCH,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(DEVFLASH),
-    /* pfnConstruct */
-    flashConstruct,
-    /* pfnDestruct */
-    flashDestruct,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    flashReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete. */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "flash",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
+    /* .fClass = */                 PDM_DEVREG_CLASS_ARCH,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVFLASH),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Flash Memory Device",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           flashConstruct,
+    /* .pfnDestruct = */            flashDestruct,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               flashReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/EFI/DevSmc.cpp
===================================================================
--- /trunk/src/VBox/Devices/EFI/DevSmc.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/EFI/DevSmc.cpp	(revision 80531)
@@ -1489,4 +1489,6 @@
 }
 
+#endif /* IN_RING3 */
+
 
 /**
@@ -1495,54 +1497,70 @@
 const PDMDEVREG g_DeviceSmc =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "smc",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Apple System Management Controller",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
-    /* fClass */
-    PDM_DEVREG_CLASS_ARCH,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(DEVSMC),
-    /* pfnConstruct */
-    smcConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete. */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "smc",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
+    /* .fClass = */                 PDM_DEVREG_CLASS_ARCH,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVSMC),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Apple System Management Controller",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           smcConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               NULL,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/GIMDev/GIMDev.cpp
===================================================================
--- /trunk/src/VBox/Devices/GIMDev/GIMDev.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/GIMDev/GIMDev.cpp	(revision 80531)
@@ -405,4 +405,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -411,54 +412,70 @@
 const PDMDEVREG g_DeviceGIMDev =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "GIMDev",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "VirtualBox GIM Device",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
-    /* fClass */
-    PDM_DEVREG_CLASS_MISC,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(GIMDEV),
-    /* pfnConstruct */
-    gimdevR3Construct,
-    /* pfnDestruct */
-    gimdevR3Destruct,
-    /* pfnRelocate */
-    gimdevR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    gimdevR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "GIMDev",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
+    /* .fClass = */                 PDM_DEVREG_CLASS_MISC,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(GIMDEV),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "VirtualBox GIM Device",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           gimdevR3Construct,
+    /* .pfnDestruct = */            gimdevR3Destruct,
+    /* .pfnRelocate = */            gimdevR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               gimdevR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
-#endif /* IN_RING3 */
 
 #endif  /* VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 80531)
@@ -6521,6 +6521,6 @@
     rc = PGMR3HandlerPhysicalTypeRegister(pVM, PGMPHYSHANDLERKIND_WRITE,
                                           vgaLFBAccessHandler,
-                                          g_DeviceVga.szR0Mod, "vgaLFBAccessHandler", "vgaLbfAccessPfHandler",
-                                          g_DeviceVga.szRCMod, "vgaLFBAccessHandler", "vgaLbfAccessPfHandler",
+                                          g_DeviceVga.pszR0Mod, "vgaLFBAccessHandler", "vgaLbfAccessPfHandler",
+                                          g_DeviceVga.pszRCMod, "vgaLFBAccessHandler", "vgaLbfAccessPfHandler",
                                           "VGA LFB", &pThis->hLfbAccessHandlerType);
     AssertRCReturn(rc, rc);
@@ -7263,4 +7263,6 @@
 }
 
+#endif /* !IN_RING3 */
+
 /**
  * The device registration structure.
@@ -7268,55 +7270,71 @@
 const PDMDEVREG g_DeviceVga =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "vga",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "VGA Adaptor with VESA extensions.",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_GRAPHICS,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(VGASTATE),
-    /* pfnConstruct */
-    vgaR3Construct,
-    /* pfnDestruct */
-    vgaR3Destruct,
-    /* pfnRelocate */
-    vgaR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    vgaR3PowerOn,
-    /* pfnReset */
-    vgaR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    vgaR3Resume,
-    /* pfnAttach */
-    vgaAttach,
-    /* pfnDetach */
-    vgaDetach,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "vga",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_GRAPHICS,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(VGASTATE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "VGA Adaptor with VESA extensions.",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           vgaR3Construct,
+    /* .pfnDestruct = */            vgaR3Destruct,
+    /* .pfnRelocate = */            vgaR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             vgaR3PowerOn,
+    /* .pfnReset = */               vgaR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              vgaR3Resume,
+    /* .pfnAttach = */              vgaAttach,
+    /* .pfnDetach = */              vgaDetach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* !IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/Input/DevPS2.cpp
===================================================================
--- /trunk/src/VBox/Devices/Input/DevPS2.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Input/DevPS2.cpp	(revision 80531)
@@ -1041,4 +1041,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -1047,57 +1048,73 @@
 const PDMDEVREG g_DevicePS2KeyboardMouse =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "pckbd",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "PS/2 Keyboard and Mouse device. Emulates both the keyboard, mouse and the keyboard controller. "
-    "LUN #0 is the keyboard connector. "
-    "LUN #1 is the aux/mouse connector.",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_INPUT,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(KBDState),
-    /* pfnConstruct */
-    kbdConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    kbdRelocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    kbdReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    kbdAttach,
-    /* pfnDetach */
-    kbdDetach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "pckbd",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_INPUT,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(KBDState),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "PS/2 Keyboard and Mouse device. Emulates both the keyboard, mouse and the keyboard controller.\n"
+                                    "LUN #0 is the keyboard connector.\n"
+                                    "LUN #1 is the aux/mouse connector.",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           kbdConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            kbdRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               kbdReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              kbdAttach,
+    /* .pfnDetach = */              kbdDetach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Devices/Makefile.kmk	(revision 80530)
+++ /trunk/src/VBox/Devices/Makefile.kmk	(revision 80531)
@@ -132,5 +132,4 @@
  	$(VBOX_GRAPHICS_INCS)
  VBoxDD_DEFS             = \
- 	VBOX_ACPI \
  	VBOX_HGCM_HOST_CODE \
  	$(if $(VBOX_WITH_HGCM),VBOX_WITH_HGCM,) \
@@ -1097,4 +1096,5 @@
   	Serial/UartCore.cpp \
  	Parallel/DevParallel.cpp \
+	GIMDev/GIMDev.cpp \
   	VMMDev/VMMDev.cpp \
  	VMMDev/VMMDevTesting.cpp \
Index: /trunk/src/VBox/Devices/Misc/VirtualKD.cpp
===================================================================
--- /trunk/src/VBox/Devices/Misc/VirtualKD.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Misc/VirtualKD.cpp	(revision 80531)
@@ -35,5 +35,4 @@
 *   Defined Constants And Macros                                                                                                 *
 *********************************************************************************************************************************/
-
 #define IKDClient_InterfaceVersion 3
 
@@ -228,52 +227,69 @@
 const PDMDEVREG g_DeviceVirtualKD =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "VirtualKD",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "Provides fast debugging interface when debugging Windows kernel",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS,
-    /* fClass */
-    PDM_DEVREG_CLASS_MISC,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(VIRTUALKD),
-    /* pfnConstruct */
-    vkdConstruct,
-    /* pfnDestruct */
-    vkdDestruct,
-    /* pfnRelocate */
-    NULL,
-    /* pfnIOCtl */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "VirtualKD",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fClass = */                 PDM_DEVREG_CLASS_MISC,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(VIRTUALKD),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Provides fast debugging interface when debugging Windows kernel",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "",
+    /* .pszR0Mod = */               "",
+    /* .pfnConstruct = */           vkdConstruct,
+    /* .pfnDestruct = */            vkdDestruct,
+    /* .pfnRelocate = */            NULL,
+    /* pfnIOCtl */    NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               NULL,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
Index: /trunk/src/VBox/Devices/Network/DevE1000.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevE1000.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Network/DevE1000.cpp	(revision 80531)
@@ -8093,4 +8093,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * The device registration structure.
@@ -8098,60 +8100,70 @@
 const PDMDEVREG g_DeviceE1000 =
 {
-    /* Structure version. PDM_DEVREG_VERSION defines the current version. */
-    PDM_DEVREG_VERSION,
-    /* Device name. */
-    "e1000",
-    /* Name of guest context module (no path).
-     * Only evalutated if PDM_DEVREG_FLAGS_RC is set. */
-    "VBoxDDRC.rc",
-    /* Name of ring-0 module (no path).
-     * Only evalutated if PDM_DEVREG_FLAGS_RC is set. */
-    "VBoxDDR0.r0",
-    /* The description of the device. The UTF-8 string pointed to shall, like this structure,
-     * remain unchanged from registration till VM destruction. */
-    "Intel PRO/1000 MT Desktop Ethernet.\n",
-
-    /* Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
-    PDM_DEVREG_CLASS_NETWORK,
-    /* Maximum number of instances (per VM). */
-    ~0U,
-    /* Size of the instance data. */
-    sizeof(E1KSTATE),
-
-    /* pfnConstruct */
-    e1kR3Construct,
-    /* pfnDestruct */
-    e1kR3Destruct,
-    /* pfnRelocate */
-    e1kR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    e1kR3Reset,
-    /* pfnSuspend */
-    e1kR3Suspend,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    e1kR3Attach,
-    /* pfnDeatch */
-    e1kR3Detach,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    e1kR3PowerOff,
-    /* pfnSoftReset */
-    NULL,
-
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "e1000",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_NETWORK,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(E1KSTATE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Intel PRO/1000 MT Desktop Ethernet.",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           e1kR3Construct,
+    /* .pfnDestruct = */            e1kR3Destruct,
+    /* .pfnRelocate = */            e1kR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               e1kR3Reset,
+    /* .pfnSuspend = */             e1kR3Suspend,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              e1kR3Attach,
+    /* pfnDeatch */    e1kR3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            e1kR3PowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/Network/DevINIP.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevINIP.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Network/DevINIP.cpp	(revision 80531)
@@ -59,5 +59,4 @@
 *   Macros and Defines                                                                                                           *
 *********************************************************************************************************************************/
-
 /** Maximum frame size this device can handle. */
 #define DEVINIP_MAX_FRAME 1514
@@ -730,50 +729,69 @@
 const PDMDEVREG g_DeviceINIP =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "IntNetIP",
-    /* szRCMod/szR0Mod */
-    "",
-    "",
-    /* pszDescription */
-    "Internal Network IP stack device",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS,
-    /* fClass. As this is used by the storage devices, it must come earlier. */
-    PDM_DEVREG_CLASS_VMM_DEV,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(DEVINTNETIP),
-    /* pfnConstruct */
-    devINIPConstruct,
-    /* pfnDestruct */
-    devINIPDestruct,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "IntNetIP",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fClass = */                 PDM_DEVREG_CLASS_VMM_DEV, /* As this is used by the storage devices, it must come earlier. */
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVINTNETIP),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Internal Network IP stack device",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "",
+    /* .pszR0Mod = */               "",
+    /* .pfnConstruct = */           devINIPConstruct,
+    /* .pfnDestruct = */            devINIPDestruct,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               NULL,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
+
Index: /trunk/src/VBox/Devices/Network/DevPCNet.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 80531)
@@ -5532,4 +5532,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -5538,63 +5539,75 @@
 const PDMDEVREG g_DevicePCNet =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "pcnet",
-    /* szRCMod */
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "pcnet",
 #ifdef PCNET_GC_ENABLED
-    "VBoxDDRC.rc",
-    "VBoxDDR0.r0",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
 #else
-    "",
-    "",
-#endif
-    /* pszDescription */
-    "AMD PCnet Ethernet controller.\n",
-    /* fFlags */
-#ifdef PCNET_GC_ENABLED
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
+#endif
+    /* .fClass = */                 PDM_DEVREG_CLASS_NETWORK,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(PCNETSTATE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "AMD PCnet Ethernet controller.\n",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           pcnetConstruct,
+    /* .pfnDestruct = */            pcnetDestruct,
+    /* .pfnRelocate = */            pcnetRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               pcnetReset,
+    /* .pfnSuspend = */             pcnetSuspend,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              pcnetAttach,
+    /* .pfnDetach = */              pcnetDetach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            pcnetPowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
 #else
-    PDM_DEVREG_FLAGS_DEFAULT_BITS,
-#endif
-    /* fClass */
-    PDM_DEVREG_CLASS_NETWORK,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(PCNETSTATE),
-    /* pfnConstruct */
-    pcnetConstruct,
-    /* pfnDestruct */
-    pcnetDestruct,
-    /* pfnRelocate */
-    pcnetRelocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    pcnetReset,
-    /* pfnSuspend */
-    pcnetSuspend,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    pcnetAttach,
-    /* pfnDetach */
-    pcnetDetach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete. */
-    NULL,
-    /* pfnPowerOff. */
-    pcnetPowerOff,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp
===================================================================
--- /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Network/DevVirtioNet.cpp	(revision 80531)
@@ -2343,4 +2343,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * The device registration structure.
@@ -2348,64 +2350,74 @@
 const PDMDEVREG g_DeviceVirtioNet =
 {
-    /* Structure version. PDM_DEVREG_VERSION defines the current version. */
-    PDM_DEVREG_VERSION,
-    /* Device name. */
-    "virtio-net",
-    /* Name of guest context module (no path).
-     * Only evalutated if PDM_DEVREG_FLAGS_RC is set. */
-    "VBoxDDRC.rc",
-    /* Name of ring-0 module (no path).
-     * Only evalutated if PDM_DEVREG_FLAGS_RC is set. */
-    "VBoxDDR0.r0",
-    /* The description of the device. The UTF-8 string pointed to shall, like this structure,
-     * remain unchanged from registration till VM destruction. */
-    "Virtio Ethernet.\n",
-
-    /* Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
+    /* .u32version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "virtio-net",
 #ifdef VNET_GC_SUPPORT
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
 #else
-    PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
 #endif
-    /* Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
-    PDM_DEVREG_CLASS_NETWORK,
-    /* Maximum number of instances (per VM). */
-    ~0U,
-    /* Size of the instance data. */
-    sizeof(VNETSTATE),
-
-    /* pfnConstruct */
-    vnetConstruct,
-    /* pfnDestruct */
-    vnetDestruct,
-    /* pfnRelocate */
-    vnetRelocate,
-    /* pfnMemSetup. */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    vnetSuspend,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    vnetAttach,
-    /* pfnDetach */
-    vnetDetach,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    vnetPowerOff,
-    /* pfnSoftReset */
-    NULL,
-
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .fClass = */                 PDM_DEVREG_CLASS_NETWORK,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(VNETSTATE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Virtio Ethernet.\n",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           vnetConstruct,
+    /* .pfnDestruct = */            vnetDestruct,
+    /* .pfnRelocate = */            vnetRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               NULL,
+    /* .pfnSuspend = */             vnetSuspend,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              vnetAttach,
+    /* .pfnDetach = */              vnetDetach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            vnetPowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/PC/DevACPI.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 80531)
@@ -4178,4 +4178,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * The device registration structure.
@@ -4183,54 +4185,70 @@
 const PDMDEVREG g_DeviceACPI =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "acpi",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Advanced Configuration and Power Interface",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_ACPI,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(ACPIState),
-    /* pfnConstruct */
-    acpiR3Construct,
-    /* pfnDestruct */
-    acpiR3Destruct,
-    /* pfnRelocate */
-    acpiR3Relocate,
-    /* pfnMemSetup */
-    acpiR3MemSetup,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    acpiR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    acpiR3Resume,
-    /* pfnAttach */
-    acpiR3Attach,
-    /* pfnDetach */
-    acpiR3Detach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "acpi",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_ACPI,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(ACPIState),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Advanced Configuration and Power Interface",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           acpiR3Construct,
+    /* .pfnDestruct = */            acpiR3Destruct,
+    /* .pfnRelocate = */            acpiR3Relocate,
+    /* .pfnMemSetup = */            acpiR3MemSetup,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               acpiR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              acpiR3Resume,
+    /* .pfnAttach = */              acpiR3Attach,
+    /* .pfnDetach = */              acpiR3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/PC/DevDMA.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevDMA.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/PC/DevDMA.cpp	(revision 80531)
@@ -1120,4 +1120,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * The device registration structure.
@@ -1125,54 +1127,71 @@
 const PDMDEVREG g_DeviceDMA =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "8237A",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "DMA Controller Device",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
-    /* fClass */
-    PDM_DEVREG_CLASS_DMA,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(DMAState),
-    /* pfnConstruct */
-    dmaConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    dmaReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "8237A",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
+    /* .fClass = */                 PDM_DEVREG_CLASS_DMA,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DMAState),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "DMA Controller Device",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           dmaConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               dmaReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
-#endif /* IN_RING3 */
+
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/PC/DevHPET.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevHPET.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/PC/DevHPET.cpp	(revision 80531)
@@ -1472,4 +1472,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -1478,56 +1479,71 @@
 const PDMDEVREG g_DeviceHPET =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "hpet",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    " High Precision Event Timer (HPET) Device",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36
-    | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_PIT,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(HPET),
-    /* pfnConstruct */
-    hpetR3Construct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    hpetR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    hpetR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "hpet",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_PIT,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(HPET),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "High Precision Event Timer (HPET) Device",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           hpetR3Construct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            hpetR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               hpetR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/PC/DevIoApic.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevIoApic.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/PC/DevIoApic.cpp	(revision 80531)
@@ -1367,4 +1367,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -1373,56 +1374,71 @@
 const PDMDEVREG g_DeviceIOAPIC =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "ioapic",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "I/O Advanced Programmable Interrupt Controller (IO-APIC) Device",
-    /* fFlags */
-      PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36
-    | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_PIC,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(IOAPIC),
-    /* pfnConstruct */
-    ioapicR3Construct,
-    /* pfnDestruct */
-    ioapicR3Destruct,
-    /* pfnRelocate */
-    ioapicR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    ioapicR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "ioapic",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_PIC,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(IOAPIC),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "I/O Advanced Programmable Interrupt Controller (IO-APIC) Device",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           ioapicR3Construct,
+    /* .pfnDestruct = */            ioapicR3Destruct,
+    /* .pfnRelocate = */            ioapicR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               ioapicR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/PC/DevLpc-new.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevLpc-new.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/PC/DevLpc-new.cpp	(revision 80531)
@@ -382,4 +382,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -388,55 +389,71 @@
 const PDMDEVREG g_DeviceLPC =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "lpc",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "Low Pin Count (LPC) Bus",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36,
-    /* fClass */
-    PDM_DEVREG_CLASS_MISC,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(LPCSTATE),
-    /* pfnConstruct */
-    lpcConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "lpc",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fClass = */                 PDM_DEVREG_CLASS_MISC,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(LPCSTATE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Low Pin Count (LPC) Bus",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "",
+    /* .pszR0Mod = */               "",
+    /* .pfnConstruct = */           lpcConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               NULL,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/PC/DevPIC.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevPIC.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/PC/DevPIC.cpp	(revision 80531)
@@ -1037,4 +1037,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -1043,55 +1044,71 @@
 const PDMDEVREG g_DeviceI8259 =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "i8259",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Intel 8259 Programmable Interrupt Controller (PIC) Device.",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_PIC,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(DEVPIC),
-    /* pfnConstruct */
-    picConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    picRelocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    picReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "i8259",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_PIC,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVPIC),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Intel 8259 Programmable Interrupt Controller (PIC) Device.",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           picConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            picRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               picReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/PC/DevPcArch.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevPcArch.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/PC/DevPcArch.cpp	(revision 80531)
@@ -288,52 +288,69 @@
 const PDMDEVREG g_DevicePcArch =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "pcarch",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "PC Architecture Device",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
-    /* fClass */
-    PDM_DEVREG_CLASS_ARCH,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(DEVPCARCH),
-    /* pfnConstruct */
-    pcarchConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete. */
-    pcarchInitComplete,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "pcarch",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
+    /* .fClass = */                 PDM_DEVREG_CLASS_ARCH,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVPCARCH),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "PC Architecture Device",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "",
+    /* .pszR0Mod = */               "",
+    /* .pfnConstruct = */           pcarchConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               NULL,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        pcarchInitComplete,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
Index: /trunk/src/VBox/Devices/PC/DevPcBios.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevPcBios.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/PC/DevPcBios.cpp	(revision 80531)
@@ -1800,52 +1800,69 @@
 const PDMDEVREG g_DevicePcBios =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "pcbios",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "PC BIOS Device",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64,
-    /* fClass */
-    PDM_DEVREG_CLASS_ARCH_BIOS,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(DEVPCBIOS),
-    /* pfnConstruct */
-    pcbiosConstruct,
-    /* pfnDestruct */
-    pcbiosDestruct,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    pcbiosMemSetup,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    pcbiosReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete. */
-    pcbiosInitComplete,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "pcbios",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fClass = */                 PDM_DEVREG_CLASS_ARCH_BIOS,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVPCBIOS),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "PC BIOS Device",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "",
+    /* .pszR0Mod = */               "",
+    /* .pfnConstruct = */           pcbiosConstruct,
+    /* .pfnDestruct = */            pcbiosDestruct,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            pcbiosMemSetup,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               pcbiosReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        pcbiosInitComplete,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
Index: /trunk/src/VBox/Devices/PC/DevPit-i8254.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevPit-i8254.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/PC/DevPit-i8254.cpp	(revision 80531)
@@ -1522,4 +1522,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -1528,54 +1529,70 @@
 const PDMDEVREG g_DeviceI8254 =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "i8254",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Intel 8254 Programmable Interval Timer (PIT) And Dummy Speaker Device",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_PIT,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(PITSTATE),
-    /* pfnConstruct */
-    pitConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    pitRelocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    pitReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "i8254",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_PIT,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(PITSTATE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Intel 8254 Programmable Interval Timer (PIT) And Dummy Speaker Device",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           pitConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            pitRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               pitReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/PC/DevRTC.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevRTC.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/PC/DevRTC.cpp	(revision 80531)
@@ -129,4 +129,5 @@
 };
 
+#if 0 /* new / old style device selector */
 
 typedef struct RTCSTATE
@@ -137,11 +138,11 @@
     struct my_tm current_tm;
     /** The configured IRQ. */
-    int32_t irq;
+    int32_t                 irq;
     /** The configured I/O port base. */
-    RTIOPORT IOPortBase;
+    RTIOPORT                IOPortBase;
     /** Use UTC or local time initially. */
-    bool fUTC;
+    bool                    fUTC;
     /** Disabled by HPET legacy mode. */
-    bool fDisabledByHpet;
+    bool                    fDisabledByHpet;
     /* periodic timer */
     int64_t next_periodic_time;
@@ -149,46 +150,21 @@
     int64_t next_second_time;
 
-    /** Pointer to the device instance - R3 Ptr. */
-    PPDMDEVINSR3 pDevInsR3;
-    /** The periodic timer (rtcTimerPeriodic) - R3 Ptr. */
-    PTMTIMERR3 pPeriodicTimerR3;
-    /** The second timer (rtcTimerSecond) - R3 Ptr. */
-    PTMTIMERR3 pSecondTimerR3;
-    /** The second second timer (rtcTimerSecond2) - R3 Ptr. */
-    PTMTIMERR3 pSecondTimer2R3;
-
-    /** Pointer to the device instance - R0 Ptr. */
-    PPDMDEVINSR0 pDevInsR0;
-    /** The periodic timer (rtcTimerPeriodic) - R0 Ptr. */
-    PTMTIMERR0 pPeriodicTimerR0;
-    /** The second timer (rtcTimerSecond) - R0 Ptr. */
-    PTMTIMERR0 pSecondTimerR0;
-    /** The second second timer (rtcTimerSecond2) - R0 Ptr. */
-    PTMTIMERR0 pSecondTimer2R0;
-
-    /** Pointer to the device instance - RC Ptr. */
-    PPDMDEVINSRC pDevInsRC;
-    /** The periodic timer (rtcTimerPeriodic) - RC Ptr. */
-    PTMTIMERRC pPeriodicTimerRC;
-    /** The second timer (rtcTimerSecond) - RC Ptr. */
-    PTMTIMERRC pSecondTimerRC;
-    /** The second second timer (rtcTimerSecond2) - RC Ptr. */
-    PTMTIMERRC pSecondTimer2RC;
-
-    /** The RTC registration structure. */
-    PDMRTCREG RtcReg;
-    /** The RTC device helpers. */
-    R3PTRTYPE(PCPDMRTCHLP) pRtcHlpR3;
+    /** The periodic timer (rtcTimerPeriodic). */
+    TMTIMERHANDLE           hPeriodicTimer;
+    /** The second timer (rtcTimerSecond). */
+    TMTIMERHANDLE           hSecondTimer;
+    /** The second second timer (rtcTimerSecond2). */
+    TMTIMERHANDLE           hSecondTimer2;
+    /** The I/O port range handle. */
+    IOMIOPORTHANDLE         hIoPorts;
+
     /** Number of release log entries. Used to prevent flooding. */
-    uint32_t cRelLogEntries;
+    uint32_t                cRelLogEntries;
     /** The current/previous logged timer period. */
-    int32_t CurLogPeriod;
+    int32_t                 CurLogPeriod;
     /** The current/previous hinted timer period. */
-    int32_t CurHintPeriod;
+    int32_t                 CurHintPeriod;
     /** How many consecutive times the UIP has been seen. */
-    int32_t cUipSeen;
-
-    /** HPET legacy mode notification interface. */
-    PDMIHPETLEGACYNOTIFY  IHpetLegacyNotify;
+    int32_t                 cUipSeen;
 
     /** Number of IRQs that's been raised. */
@@ -200,7 +176,71 @@
 typedef RTCSTATE *PRTCSTATE;
 
+
+/**
+ * RTC ring-3 instance data.
+ */
+typedef struct RTCSTATER3
+{
+    /** Pointer to the device instance. */
+    PPDMDEVINSR3            pDevInsR3;
+
+    /** The RTC registration structure. */
+    PDMRTCREG               RtcReg;
+    /** The RTC device helpers. */
+    R3PTRTYPE(PCPDMRTCHLP)  pRtcHlpR3;
+
+    /** Pointer to the shared state (for the IHpetLegacyNotify callback). */
+    PRTCSTATE               pShared;
+    /** HPET legacy mode notification interface. */
+    PDMIHPETLEGACYNOTIFY    IHpetLegacyNotify;
+} RTCSTATER3;
+/** Pointer to the ring-3 RTC device instance data. */
+typedef RTCSTATER3 *PRTCSTATER3;
+
+
+/**
+ * RTC ring-0 instance data.
+ * @note Not needed, but serves as example for testing the new model.
+ */
+typedef struct RTCSTATER0
+{
+    /** Pointer to the device instance. */
+    PPDMDEVINSR0            pDevInsR0;
+} RTCSTATER0;
+/** Pointer to the ring-0 RTC device instance data. */
+typedef RTCSTATER0 *PRTCSTATER0;
+
+
+/**
+ * RTC raw-mode instance data.
+ * @note Not needed, but serves as example for testing the new model.
+ */
+typedef struct RTCSTATERC
+{
+    /** Pointer to the device instance. */
+    PPDMDEVINSRC            pDevInsRC;
+} RTCSTATERC;
+/** Pointer to the raw-mode RTC device instance data. */
+typedef RTCSTATERC *PRTCSTATERC;
+
+
+/** @def PRTCSTATECC
+ * Pointer to the instance data for the current context. */
+#ifdef IN_RING3
+typedef  RTCSTATER3  RTCSTATECC;
+typedef PRTCSTATER3 PRTCSTATECC;
+#elif defined(IN_RING0)
+typedef  RTCSTATER0  RTCSTATECC;
+typedef PRTCSTATER0 PRTCSTATECC;
+#elif defined(IN_RING0)
+typedef  RTCSTATERC  RTCSTATECC;
+typedef PRTCSTATERC PRTCSTATECC;
+# error "Not IN_RING3, IN_RING0 or IN_RC"
+#endif
+
+
 #ifndef VBOX_DEVICE_STRUCT_TESTCASE
 
-static void rtc_timer_update(PRTCSTATE pThis, int64_t current_time)
+static void rtc_timer_update(PPDMDEVINS pDevIns, PRTCSTATE pThis, int64_t current_time)
 {
     int period_code, period;
@@ -208,6 +248,6 @@
     uint32_t freq;
 
-    Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
-    Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
+    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
+    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
 
     period_code = pThis->cmos_data[RTC_REG_A] & 0x0f;
@@ -220,10 +260,10 @@
         period = 1 << (period_code - 1);
         /* compute 32 kHz clock */
-        freq = TMTimerGetFreq(pThis->CTX_SUFF(pPeriodicTimer));
+        freq = PDMDevHlpTimerGetFreq(pDevIns, pThis->hPeriodicTimer);
 
         cur_clock = ASMMultU64ByU32DivByU32(current_time, 32768, freq);
         next_irq_clock = (cur_clock & ~(uint64_t)(period - 1)) + period;
         pThis->next_periodic_time = ASMMultU64ByU32DivByU32(next_irq_clock, freq, 32768) + 1;
-        TMTimerSet(pThis->CTX_SUFF(pPeriodicTimer), pThis->next_periodic_time);
+        PDMDevHlpTimerSet(pDevIns, pThis->hPeriodicTimer, pThis->next_periodic_time);
 
 #ifdef IN_RING3
@@ -239,5 +279,5 @@
 #endif
             pThis->CurHintPeriod = period;
-            TMTimerSetFrequencyHint(pThis->CTX_SUFF(pPeriodicTimer), _32K / period);
+            PDMDevHlpTimerSetFrequencyHint(pDevIns, pThis->hPeriodicTimer, _32K / period);
         }
     }
@@ -245,17 +285,18 @@
     {
 #ifdef IN_RING3
-        if (TMTimerIsActive(pThis->CTX_SUFF(pPeriodicTimer)) && pThis->cRelLogEntries++ < 64)
+        if (PDMDevHlpTimerIsActive(pDevIns, pThis->hPeriodicTimer) && pThis->cRelLogEntries++ < 64)
             LogRel(("RTC: Stopped the periodic timer\n"));
 #endif
-        TMTimerStop(pThis->CTX_SUFF(pPeriodicTimer));
-    }
-}
-
-
-static void rtc_raise_irq(PRTCSTATE pThis, uint32_t iLevel)
+        PDMDevHlpTimerStop(pDevIns, pThis->hPeriodicTimer);
+    }
+    RT_NOREF(pDevIns);
+}
+
+
+static void rtc_raise_irq(PPDMDEVINS pDevIns, PRTCSTATE pThis, uint32_t iLevel)
 {
     if (!pThis->fDisabledByHpet)
     {
-        PDMDevHlpISASetIrq(pThis->CTX_SUFF(pDevIns), pThis->irq, iLevel);
+        PDMDevHlpISASetIrq(pDevIns, pThis->irq, iLevel);
         if (iLevel)
             STAM_COUNTER_INC(&pThis->StatRTCIrq);
@@ -347,5 +388,5 @@
             case RTC_REG_C:
                 *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
-                rtc_raise_irq(pThis, 0);
+                rtc_raise_irq(pDevIns, pThis, 0);
                 pThis->cmos_data[RTC_REG_C] = 0x00;
                 break;
@@ -382,5 +423,5 @@
            a timely fashion. */
         if (u32 == RTC_REG_A)
-            TMTimerGet(pThis->CTX_SUFF(pSecondTimer));
+            PDMDevHlpTimerGet(pDevIns, pThis->hSecondTimer);
     }
     else
@@ -418,9 +459,9 @@
                    we're letting IOM do the locking, we must not return without
                    holding the device lock.*/
-                PDMCritSectLeave(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo));
-                int rc1 = TMTimerLock(pThis->CTX_SUFF(pPeriodicTimer), VINF_SUCCESS /* must get it */);
-                int rc2 = PDMCritSectEnter(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS /* must get it */);
+                PDMDevHlpCritSectLeave(pDevIns, pDevIns->CTX_SUFF(pCritSectRo));
+                int rc1 = PDMDevHlpTimerLock(pDevIns, pThis->hPeriodicTimer, VINF_SUCCESS /* must get it */);
+                int rc2 = PDMDevHlpCritSectEnter(pDevIns, pDevIns->CTX_SUFF(pCritSectRo), VINF_SUCCESS /* must get it */);
                 AssertRCReturn(rc1, rc1);
-                AssertRCReturnStmt(rc2, TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer)), rc2);
+                AssertRCReturnStmt(rc2, PDMDevHlpTimerUnlock(pDevIns, pThis->hPeriodicTimer), rc2);
 
                 if (idx == RTC_REG_A)
@@ -449,7 +490,7 @@
                 }
 
-                rtc_timer_update(pThis, TMTimerGet(pThis->CTX_SUFF(pPeriodicTimer)));
-
-                TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer));
+                rtc_timer_update(pDevIns, pThis, PDMDevHlpTimerGet(pDevIns, pThis->hPeriodicTimer));
+
+                PDMDevHlpTimerUnlock(pDevIns, pThis->hPeriodicTimer);
                 /* the caller leaves the other lock. */
                 break;
@@ -558,12 +599,13 @@
     RT_NOREF2(pTimer, pvUser);
     PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
-    Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
-    Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
-
-    rtc_timer_update(pThis, pThis->next_periodic_time);
+    Assert(pTimer == PDMDevHlpTimerToPtr(pDevIns, pThis->hPeriodicTimer));
+    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
+    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
+
+    rtc_timer_update(pDevIns, pThis, pThis->next_periodic_time);
     STAM_COUNTER_INC(&pThis->StatRTCTimerCB);
     pThis->cmos_data[RTC_REG_C] |= 0xc0;
 
-    rtc_raise_irq(pThis, 1);
+    rtc_raise_irq(pDevIns, pThis, 1);
 }
 
@@ -638,4 +680,1162 @@
 static DECLCALLBACK(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
 {
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+
+    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
+    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
+    Assert(pTimer == PDMDevHlpTimerToPtr(pDevIns, pThis->hSecondTimer));
+    RT_NOREF(pvUser);
+
+    /* if the oscillator is not in normal operation, we do not update */
+    if ((pThis->cmos_data[RTC_REG_A] & 0x70) != 0x20)
+    {
+        pThis->next_second_time += PDMDevHlpTimerGetFreq(pDevIns, pThis->hSecondTimer);
+        PDMDevHlpTimerSet(pDevIns, pThis->hSecondTimer, pThis->next_second_time);
+    }
+    else
+    {
+        rtc_next_second(&pThis->current_tm);
+
+        if (!(pThis->cmos_data[RTC_REG_B] & REG_B_SET))
+        {
+            /* update in progress bit */
+            Log2(("RTC: UIP %x -> 1\n", !!(pThis->cmos_data[RTC_REG_A] & REG_A_UIP)));
+            pThis->cmos_data[RTC_REG_A] |= REG_A_UIP;
+        }
+
+        /* 244140 ns = 8 / 32768 seconds */
+        uint64_t delay = PDMDevHlpTimerFromNano(pDevIns, pThis->hSecondTimer2, 244140);
+        PDMDevHlpTimerSet(pDevIns, pThis->hSecondTimer2, pThis->next_second_time + delay);
+    }
+}
+
+
+/* Used by rtc_set_date and rtcTimerSecond2. */
+static void rtc_copy_date(PRTCSTATE pThis)
+{
+    const struct my_tm *tm = &pThis->current_tm;
+
+    pThis->cmos_data[RTC_SECONDS] = to_bcd(pThis, tm->tm_sec);
+    pThis->cmos_data[RTC_MINUTES] = to_bcd(pThis, tm->tm_min);
+    if (pThis->cmos_data[RTC_REG_B] & 0x02)
+    {
+        /* 24 hour format */
+        pThis->cmos_data[RTC_HOURS] = to_bcd(pThis, tm->tm_hour);
+    }
+    else
+    {
+        /* 12 hour format */
+        int h = tm->tm_hour % 12;
+        pThis->cmos_data[RTC_HOURS] = to_bcd(pThis, h ? h : 12);
+        if (tm->tm_hour >= 12)
+            pThis->cmos_data[RTC_HOURS] |= 0x80;
+    }
+    pThis->cmos_data[RTC_DAY_OF_WEEK] = to_bcd(pThis, tm->tm_wday);
+    pThis->cmos_data[RTC_DAY_OF_MONTH] = to_bcd(pThis, tm->tm_mday);
+    pThis->cmos_data[RTC_MONTH] = to_bcd(pThis, tm->tm_mon + 1);
+    pThis->cmos_data[RTC_YEAR] = to_bcd(pThis, tm->tm_year % 100);
+}
+
+
+/**
+ * @callback_method_impl{FNTMTIMERDEV, Second2 timer.}
+ */
+static DECLCALLBACK(void) rtcTimerSecond2(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
+{
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+
+    Assert(PDMDevHlpTimerIsLockOwner(pDevIns, pThis->hPeriodicTimer));
+    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
+    Assert(pTimer == PDMDevHlpTimerToPtr(pDevIns, pThis->hSecondTimer2));
+    RT_NOREF2(pTimer, pvUser);
+
+    if (!(pThis->cmos_data[RTC_REG_B] & REG_B_SET))
+        rtc_copy_date(pThis);
+
+    /* check alarm */
+    if (pThis->cmos_data[RTC_REG_B] & REG_B_AIE)
+    {
+        if (   (   (pThis->cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0
+                || from_bcd(pThis, pThis->cmos_data[RTC_SECONDS_ALARM]) == pThis->current_tm.tm_sec)
+            && (   (pThis->cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0
+                || from_bcd(pThis, pThis->cmos_data[RTC_MINUTES_ALARM]) == pThis->current_tm.tm_min)
+            && (   (pThis->cmos_data[RTC_HOURS_ALARM  ] & 0xc0) == 0xc0
+                || from_bcd(pThis, pThis->cmos_data[RTC_HOURS_ALARM  ]) == pThis->current_tm.tm_hour)
+            )
+        {
+            pThis->cmos_data[RTC_REG_C] |= 0xa0;
+            rtc_raise_irq(pDevIns, pThis, 1);
+        }
+    }
+
+    /* update ended interrupt */
+    if (pThis->cmos_data[RTC_REG_B] & REG_B_UIE)
+    {
+        pThis->cmos_data[RTC_REG_C] |= 0x90;
+        rtc_raise_irq(pDevIns, pThis, 1);
+    }
+
+    /* clear update in progress bit */
+    Log2(("RTC: UIP %x -> 0\n", !!(pThis->cmos_data[RTC_REG_A] & REG_A_UIP)));
+    pThis->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
+
+    pThis->next_second_time += PDMDevHlpTimerGetFreq(pDevIns, pThis->hSecondTimer);
+    PDMDevHlpTimerSet(pDevIns, pThis->hSecondTimer, pThis->next_second_time);
+}
+
+
+/* -=-=-=-=-=- Saved State -=-=-=-=-=- */
+
+
+/**
+ * @callback_method_impl{FNSSMDEVLIVEEXEC}
+ */
+static DECLCALLBACK(int) rtcLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
+{
+    RT_NOREF1(uPass);
+    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
+    PRTCSTATE     pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+
+    pHlp->pfnSSMPutU8(    pSSM, pThis->irq);
+    pHlp->pfnSSMPutIOPort(pSSM, pThis->IOPortBase);
+    pHlp->pfnSSMPutBool(  pSSM, pThis->fUTC);
+
+    return VINF_SSM_DONT_CALL_AGAIN;
+}
+
+
+/**
+ * @callback_method_impl{FNSSMDEVSAVEEXEC}
+ */
+static DECLCALLBACK(int) rtcSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
+{
+    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
+    PRTCSTATE     pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+
+    /* The config. */
+    rtcLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
+
+    /* The state. */
+    pHlp->pfnSSMPutMem(pSSM, pThis->cmos_data, CMOS_BANK_SIZE);
+    pHlp->pfnSSMPutU8(pSSM, pThis->cmos_index[0]);
+
+    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_sec);
+    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_min);
+    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_hour);
+    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_wday);
+    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_mday);
+    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_mon);
+    pHlp->pfnSSMPutS32(pSSM, pThis->current_tm.tm_year);
+
+    PDMDevHlpTimerSave(pDevIns, pThis->hPeriodicTimer, pSSM);
+
+    pHlp->pfnSSMPutS64(pSSM, pThis->next_periodic_time);
+
+    pHlp->pfnSSMPutS64(pSSM, pThis->next_second_time);
+    PDMDevHlpTimerSave(pDevIns, pThis->hSecondTimer, pSSM);
+    PDMDevHlpTimerSave(pDevIns, pThis->hSecondTimer2, pSSM);
+
+    pHlp->pfnSSMPutBool(pSSM, pThis->fDisabledByHpet);
+
+    pHlp->pfnSSMPutMem(pSSM, &pThis->cmos_data[CMOS_BANK_SIZE], CMOS_BANK_SIZE);
+    return pHlp->pfnSSMPutU8(pSSM, pThis->cmos_index[1]);
+}
+
+
+/**
+ * @callback_method_impl{FNSSMDEVLOADEXEC}
+ */
+static DECLCALLBACK(int) rtcLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
+{
+    PCPDMDEVHLPR3 pHlp  = pDevIns->pHlpR3;
+    PRTCSTATE     pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+    int           rc;
+
+    if (    uVersion != RTC_SAVED_STATE_VERSION
+        &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_32PRE
+        &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_31
+        &&  uVersion != RTC_SAVED_STATE_VERSION_VBOX_30)
+        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
+
+    /* The config. */
+    if (uVersion > RTC_SAVED_STATE_VERSION_VBOX_30)
+    {
+        uint8_t u8Irq;
+        rc = pHlp->pfnSSMGetU8(pSSM, &u8Irq);
+        AssertRCReturn(rc, rc);
+        if (u8Irq != pThis->irq)
+            return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - u8Irq: saved=%#x config=%#x"), u8Irq, pThis->irq);
+
+        RTIOPORT IOPortBase;
+        rc = pHlp->pfnSSMGetIOPort(pSSM, &IOPortBase);
+        AssertRCReturn(rc, rc);
+        if (IOPortBase != pThis->IOPortBase)
+            return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS, N_("Config mismatch - IOPortBase: saved=%RTiop config=%RTiop"), IOPortBase, pThis->IOPortBase);
+
+        bool fUTC;
+        rc = pHlp->pfnSSMGetBool(pSSM, &fUTC);
+        AssertRCReturn(rc, rc);
+        if (fUTC != pThis->fUTC)
+            LogRel(("RTC: Config mismatch - fUTC: saved=%RTbool config=%RTbool\n", fUTC, pThis->fUTC));
+    }
+
+    if (uPass != SSM_PASS_FINAL)
+        return VINF_SUCCESS;
+
+    /* The state. */
+    pHlp->pfnSSMGetMem(pSSM, pThis->cmos_data, CMOS_BANK_SIZE);
+    pHlp->pfnSSMGetU8(pSSM, &pThis->cmos_index[0]);
+
+    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_sec);
+    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_min);
+    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_hour);
+    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_wday);
+    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_mday);
+    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_mon);
+    pHlp->pfnSSMGetS32(pSSM, &pThis->current_tm.tm_year);
+
+    PDMDevHlpTimerLoad(pDevIns, pThis->hPeriodicTimer, pSSM);
+
+    pHlp->pfnSSMGetS64(pSSM, &pThis->next_periodic_time);
+
+    pHlp->pfnSSMGetS64(pSSM, &pThis->next_second_time);
+    PDMDevHlpTimerLoad(pDevIns, pThis->hSecondTimer, pSSM);
+    PDMDevHlpTimerLoad(pDevIns, pThis->hSecondTimer2, pSSM);
+
+    if (uVersion > RTC_SAVED_STATE_VERSION_VBOX_31)
+         pHlp->pfnSSMGetBool(pSSM, &pThis->fDisabledByHpet);
+
+    if (uVersion > RTC_SAVED_STATE_VERSION_VBOX_32PRE)
+    {
+        /* Second CMOS bank. */
+        pHlp->pfnSSMGetMem(pSSM, &pThis->cmos_data[CMOS_BANK_SIZE], CMOS_BANK_SIZE);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->cmos_index[1]);
+    }
+
+    int period_code = pThis->cmos_data[RTC_REG_A] & 0x0f;
+    if (    period_code != 0
+        &&  (pThis->cmos_data[RTC_REG_B] & REG_B_PIE))
+    {
+        if (period_code <= 2)
+            period_code += 7;
+        int period = 1 << (period_code - 1);
+        LogRel(("RTC: period=%#x (%d) %u Hz (restore)\n", period, period, _32K / period));
+        PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VINF_SUCCESS);
+        PDMDevHlpTimerSetFrequencyHint(pDevIns, pThis->hPeriodicTimer, _32K / period);
+        PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
+        pThis->CurLogPeriod  = period;
+        pThis->CurHintPeriod = period;
+    }
+    else
+    {
+        LogRel(("RTC: Stopped the periodic timer (restore)\n"));
+        pThis->CurLogPeriod  = 0;
+        pThis->CurHintPeriod = 0;
+    }
+    pThis->cRelLogEntries = 0;
+
+    return VINF_SUCCESS;
+}
+
+
+/* -=-=-=-=-=- PDM Interface provided by the RTC device  -=-=-=-=-=- */
+
+/**
+ * Calculate and update the standard CMOS checksum.
+ *
+ * @param   pThis       Pointer to the RTC state data.
+ */
+static void rtcCalcCRC(PRTCSTATE pThis)
+{
+    uint16_t u16 = 0;
+    for (unsigned i = RTC_CRC_START; i <= RTC_CRC_LAST; i++)
+        u16 += pThis->cmos_data[i];
+
+    pThis->cmos_data[RTC_CRC_LOW]  = u16 & 0xff;
+    pThis->cmos_data[RTC_CRC_HIGH] = (u16 >> 8) & 0xff;
+}
+
+
+/**
+ * @interface_method_impl{PDMRTCREG,pfnWrite}
+ */
+static DECLCALLBACK(int) rtcCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
+{
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->pCritSectRoR3));
+    if (iReg < RT_ELEMENTS(pThis->cmos_data))
+    {
+        pThis->cmos_data[iReg] = u8Value;
+
+        /* does it require checksum update? */
+        if (    iReg >= RTC_CRC_START
+            &&  iReg <= RTC_CRC_LAST)
+            rtcCalcCRC(pThis);
+
+        return VINF_SUCCESS;
+    }
+
+    AssertMsgFailed(("iReg=%d\n", iReg));
+    return VERR_INVALID_PARAMETER;
+}
+
+
+/**
+ * @interface_method_impl{PDMRTCREG,pfnRead}
+ */
+static DECLCALLBACK(int) rtcCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
+{
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+    Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->pCritSectRoR3));
+
+    if (iReg < RT_ELEMENTS(pThis->cmos_data))
+    {
+        *pu8Value = pThis->cmos_data[iReg];
+        return VINF_SUCCESS;
+    }
+    AssertMsgFailed(("iReg=%d\n", iReg));
+    return VERR_INVALID_PARAMETER;
+}
+
+
+/**
+ * @interface_method_impl{PDMIHPETLEGACYNOTIFY,pfnModeChanged}
+ */
+static DECLCALLBACK(void) rtcHpetLegacyNotify_ModeChanged(PPDMIHPETLEGACYNOTIFY pInterface, bool fActivated)
+{
+    PRTCSTATECC pThisCC = RT_FROM_MEMBER(pInterface, RTCSTATER3, IHpetLegacyNotify);
+    PPDMDEVINS pDevIns = pThisCC->pDevInsR3;
+    PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED);
+
+    pThisCC->pShared->fDisabledByHpet = fActivated;
+
+    PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
+}
+
+
+
+/* -=-=-=-=-=- IBase -=-=-=-=-=- */
+
+/**
+ * @interface_method_impl{PDMIBASE,pfnQueryInterface}
+ */
+static DECLCALLBACK(void *) rtcQueryInterface(PPDMIBASE pInterface, const char *pszIID)
+{
+    PPDMDEVINS  pDevIns = RT_FROM_MEMBER(pInterface, PDMDEVINS, IBase);
+    PRTCSTATECC pThisCC = PDMINS_2_DATA_CC(pDevIns, PRTCSTATECC);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE,             &pDevIns->IBase);
+    PDMIBASE_RETURN_INTERFACE(pszIID, PDMIHPETLEGACYNOTIFY, &pThisCC->IHpetLegacyNotify);
+    return NULL;
+}
+
+
+/* -=-=-=-=-=- PDMDEVREG -=-=-=-=-=- */
+
+static void rtc_set_memory(PRTCSTATE pThis, int addr, int val)
+{
+    if (addr >= 0 && addr <= 127)
+        pThis->cmos_data[addr] = val;
+}
+
+
+static void rtc_set_date(PRTCSTATE pThis, const struct my_tm *tm)
+{
+    pThis->current_tm = *tm;
+    rtc_copy_date(pThis);
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnInitComplete}
+ *
+ * Used to set the clock.
+ */
+static DECLCALLBACK(int)  rtcInitComplete(PPDMDEVINS pDevIns)
+{
+    /** @todo this should be (re)done at power on if we didn't load a state... */
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+
+    /*
+     * Set the CMOS date/time.
+     */
+    RTTIMESPEC  Now;
+    PDMDevHlpTMUtcNow(pDevIns, &Now);
+    RTTIME Time;
+    if (pThis->fUTC)
+        RTTimeExplode(&Time, &Now);
+    else
+        RTTimeLocalExplode(&Time, &Now);
+
+    struct my_tm Tm;
+    memset(&Tm, 0, sizeof(Tm));
+    Tm.tm_year = Time.i32Year - 1900;
+    Tm.tm_mon  = Time.u8Month - 1;
+    Tm.tm_mday = Time.u8MonthDay;
+    Tm.tm_wday = (Time.u8WeekDay + 1 + 7) % 7; /* 0 = Monday -> Sunday */
+    Tm.tm_yday = Time.u16YearDay - 1;
+    Tm.tm_hour = Time.u8Hour;
+    Tm.tm_min  = Time.u8Minute;
+    Tm.tm_sec  = Time.u8Second;
+
+    rtc_set_date(pThis, &Tm);
+
+    int iYear = to_bcd(pThis, (Tm.tm_year / 100) + 19); /* tm_year is 1900 based */
+    rtc_set_memory(pThis, 0x32, iYear);                 /* 32h - Century Byte (BCD value for the century */
+    rtc_set_memory(pThis, 0x37, iYear);                 /* 37h - (IBM PS/2) Date Century Byte */
+
+    /*
+     * Recalculate the checksum just in case.
+     */
+    rtcCalcCRC(pThis);
+
+    Log(("CMOS bank 0: \n%16.128Rhxd\n", &pThis->cmos_data[0]));
+    Log(("CMOS bank 1: \n%16.128Rhxd\n", &pThis->cmos_data[CMOS_BANK_SIZE]));
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnRelocate}
+ */
+static DECLCALLBACK(void) rtcRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
+{
+    RT_NOREF1(offDelta);
+    PRTCSTATERC pThisRC = PDMINS_2_DATA_RC(pDevIns, PRTCSTATERC);
+    pThisRC->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnReset}
+ */
+static DECLCALLBACK(void) rtcReset(PPDMDEVINS pDevIns)
+{
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+
+    /* Reset index values (important for second bank). */
+    pThis->cmos_index[0] = 0;
+    pThis->cmos_index[1] = CMOS_BANK_SIZE;   /* Point to start of second bank. */
+}
+
+
+/**
+ * @interface_method_impl{PDMDEVREG,pfnConstruct}
+ */
+static DECLCALLBACK(int)  rtcConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
+{
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
+    PCPDMDEVHLPR3 pHlp    = pDevIns->pHlpR3;
+    PRTCSTATE     pThis   = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+    PRTCSTATECC   pThisCC = PDMINS_2_DATA_CC(pDevIns, PRTCSTATECC);
+    int           rc;
+    Assert(iInstance == 0); RT_NOREF(iInstance);
+
+    /*
+     * Validate configuration.
+     */
+    PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "Irq|Base|UseUTC", "");
+
+    /*
+     * Init the data.
+     */
+    uint8_t u8Irq;
+    rc = pHlp->pfnCFGMQueryU8Def(pCfg, "Irq", &u8Irq, 8);
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("Configuration error: Querying \"Irq\" as a uint8_t failed"));
+    pThis->irq = u8Irq;
+
+    rc = pHlp->pfnCFGMQueryPortDef(pCfg, "Base", &pThis->IOPortBase, 0x70);
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("Configuration error: Querying \"Base\" as a RTIOPORT failed"));
+
+    rc = pHlp->pfnCFGMQueryBoolDef(pCfg, "UseUTC", &pThis->fUTC, false);
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("Configuration error: Querying \"UseUTC\" as a bool failed"));
+
+    Log(("RTC: Irq=%#x Base=%#x fR0Enabled=%RTbool fRCEnabled=%RTbool\n",
+         u8Irq, pThis->IOPortBase, pDevIns->fR0Enabled, pDevIns->fRCEnabled));
+
+
+    pThis->cmos_data[RTC_REG_A] = 0x26;
+    pThis->cmos_data[RTC_REG_B] = 0x02;
+    pThis->cmos_data[RTC_REG_C] = 0x00;
+    pThis->cmos_data[RTC_REG_D] = 0x80;
+    pThis->fDisabledByHpet      = false;
+    pThis->cmos_index[1]        = CMOS_BANK_SIZE;   /* Point to start of second bank. */
+
+    pThisCC->pDevInsR3                          = pDevIns;
+    pThisCC->RtcReg.u32Version                  = PDM_RTCREG_VERSION;
+    pThisCC->RtcReg.pfnRead                     = rtcCMOSRead;
+    pThisCC->RtcReg.pfnWrite                    = rtcCMOSWrite;
+    pThisCC->IHpetLegacyNotify.pfnModeChanged   = rtcHpetLegacyNotify_ModeChanged;
+
+    /* IBase */
+    pDevIns->IBase.pfnQueryInterface            = rtcQueryInterface;
+
+    /*
+     * Create timers.
+     */
+    /* Periodic timer. */
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerPeriodic, pThis,
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Periodic", &pThis->hPeriodicTimer);
+    AssertRCReturn(rc, rc);
+
+    /* Seconds timer. */
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond, pThis,
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Second", &pThis->hSecondTimer);
+    AssertRCReturn(rc, rc);
+
+    /* The second2 timer, this is always active. */
+    rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, rtcTimerSecond2, pThis,
+                              TMTIMER_FLAGS_DEFAULT_CRIT_SECT, "MC146818 RTC/CMOS - Second2", &pThis->hSecondTimer2);
+    AssertRCReturn(rc, rc);
+
+    pThis->next_second_time = PDMDevHlpTimerGet(pDevIns, pThis->hSecondTimer2)
+                            + (PDMDevHlpTimerGetFreq(pDevIns, pThis->hSecondTimer2) * 99) / 100;
+    rc = PDMDevHlpTimerLock(pDevIns, pThis->hSecondTimer2, VERR_IGNORED);
+    AssertRCReturn(rc, rc);
+    rc = PDMDevHlpTimerSet(pDevIns, pThis->hSecondTimer2, pThis->next_second_time);
+    PDMDevHlpTimerUnlock(pDevIns, pThis->hSecondTimer2);
+    AssertRCReturn(rc, rc);
+
+    /*
+     * Register I/O ports.
+     */
+    rc = PDMDevHlpIoPortCreateAndMap(pDevIns, pThis->IOPortBase, 4, rtcIOPortWrite, rtcIOPortRead, NULL /*pvUser*/,
+                                     "MC146818 RTC/CMOS", &pThis->hIoPorts);
+    AssertRCReturn(rc, rc);
+
+    /*
+     * Register the saved state.
+     */
+    rc = PDMDevHlpSSMRegister3(pDevIns, RTC_SAVED_STATE_VERSION, sizeof(*pThis), rtcLiveExec, rtcSaveExec, rtcLoadExec);
+    AssertRCReturn(rc, rc);
+
+    /*
+     * Register ourselves as the RTC/CMOS with PDM.
+     */
+    rc = PDMDevHlpRTCRegister(pDevIns, &pThisCC->RtcReg, &pThisCC->pRtcHlpR3);
+    AssertRCReturn(rc, rc);
+
+    /*
+     * Register debugger info callback.
+     */
+    PDMDevHlpDBGFInfoRegister(pDevIns, "cmos1", "Display CMOS Bank 1 Info (0x0e-0x7f). No arguments. See also rtc.", rtcCmosBankInfo);
+    PDMDevHlpDBGFInfoRegister(pDevIns, "cmos2", "Display CMOS Bank 2 Info (0x0e-0x7f). No arguments.", rtcCmosBank2Info);
+    PDMDevHlpDBGFInfoRegister(pDevIns, "rtc",   "Display CMOS RTC (0x00-0x0d). No arguments. See also cmos1 & cmos2", rtcCmosClockInfo);
+
+    /*
+     * Register statistics.
+     */
+    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRTCIrq,      STAMTYPE_COUNTER, "/TM/RTC/Irq",      STAMUNIT_OCCURENCES,  "The number of times a RTC interrupt was triggered.");
+    PDMDevHlpSTAMRegister(pDevIns, &pThis->StatRTCTimerCB,  STAMTYPE_COUNTER, "/TM/RTC/TimerCB",  STAMUNIT_OCCURENCES,  "The number of times the RTC timer callback ran.");
+
+    return VINF_SUCCESS;
+}
+
+#else /* !IN_RING3 */
+
+static DECLCALLBACK(int)  rtcRZConstruct(PPDMDEVINS pDevIns)
+{
+    PRTCSTATE   pThis   = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+    PRTCSTATER0 pThisCC = PDMINS_2_DATA_CC(pDevIns, PRTCSTATECC);
+    pThisCC->CTX_SUFF(pDevIns) = pDevIns;
+
+    int rc = PDMDevHlpIoPortSetUpContext(pDevIns, pThis->hIoPorts, rtcIOPortWrite, rtcIOPortRead, NULL /*pvUser*/);
+    AssertRCReturn(rc, rc);
+
+    return VINF_SUCCESS;
+}
+
+#endif /* !IN_RING3 */
+
+/**
+ * The device registration structure.
+ */
+const PDMDEVREG g_DeviceMC146818 =
+{
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "mc146818",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_NEW_STYLE
+                                    | PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
+    /* .fClass = */                 PDM_DEVREG_CLASS_RTC,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         1,
+    /* .cbInstanceShared = */       sizeof(RTCSTATE),
+    /* .cbInstanceCC = */           sizeof(RTCSTATECC),
+    /* .cbInstanceRC = */           sizeof(RTCSTATERC),
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Motorola MC146818 RTC/CMOS Device.",
+#ifdef IN_RING3
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           rtcConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            rtcRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               rtcReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        rtcInitComplete,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           rtcRZConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           rtcRZConstruct,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not IN_RING3, IN_RING0 nor IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
+};
+
+#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
+
+#else /* OLD STYLE DEVICE: */
+
+typedef struct RTCSTATE
+{
+    uint8_t cmos_data[256];
+    uint8_t cmos_index[2];
+    uint8_t Alignment0[6];
+    struct my_tm current_tm;
+    /** The configured IRQ. */
+    int32_t irq;
+    /** The configured I/O port base. */
+    RTIOPORT IOPortBase;
+    /** Use UTC or local time initially. */
+    bool fUTC;
+    /** Disabled by HPET legacy mode. */
+    bool fDisabledByHpet;
+    /* periodic timer */
+    int64_t next_periodic_time;
+    /* second update */
+    int64_t next_second_time;
+
+    /** Pointer to the device instance - R3 Ptr. */
+    PPDMDEVINSR3 pDevInsR3;
+    /** The periodic timer (rtcTimerPeriodic) - R3 Ptr. */
+    PTMTIMERR3 pPeriodicTimerR3;
+    /** The second timer (rtcTimerSecond) - R3 Ptr. */
+    PTMTIMERR3 pSecondTimerR3;
+    /** The second second timer (rtcTimerSecond2) - R3 Ptr. */
+    PTMTIMERR3 pSecondTimer2R3;
+
+    /** Pointer to the device instance - R0 Ptr. */
+    PPDMDEVINSR0 pDevInsR0;
+    /** The periodic timer (rtcTimerPeriodic) - R0 Ptr. */
+    PTMTIMERR0 pPeriodicTimerR0;
+    /** The second timer (rtcTimerSecond) - R0 Ptr. */
+    PTMTIMERR0 pSecondTimerR0;
+    /** The second second timer (rtcTimerSecond2) - R0 Ptr. */
+    PTMTIMERR0 pSecondTimer2R0;
+
+    /** Pointer to the device instance - RC Ptr. */
+    PPDMDEVINSRC pDevInsRC;
+    /** The periodic timer (rtcTimerPeriodic) - RC Ptr. */
+    PTMTIMERRC pPeriodicTimerRC;
+    /** The second timer (rtcTimerSecond) - RC Ptr. */
+    PTMTIMERRC pSecondTimerRC;
+    /** The second second timer (rtcTimerSecond2) - RC Ptr. */
+    PTMTIMERRC pSecondTimer2RC;
+
+    /** The RTC registration structure. */
+    PDMRTCREG RtcReg;
+    /** The RTC device helpers. */
+    R3PTRTYPE(PCPDMRTCHLP) pRtcHlpR3;
+    /** Number of release log entries. Used to prevent flooding. */
+    uint32_t cRelLogEntries;
+    /** The current/previous logged timer period. */
+    int32_t CurLogPeriod;
+    /** The current/previous hinted timer period. */
+    int32_t CurHintPeriod;
+    /** How many consecutive times the UIP has been seen. */
+    int32_t cUipSeen;
+
+    /** HPET legacy mode notification interface. */
+    PDMIHPETLEGACYNOTIFY  IHpetLegacyNotify;
+
+    /** Number of IRQs that's been raised. */
+    STAMCOUNTER             StatRTCIrq;
+    /** Number of times the timer callback handler ran. */
+    STAMCOUNTER             StatRTCTimerCB;
+} RTCSTATE;
+/** Pointer to the RTC device state. */
+typedef RTCSTATE *PRTCSTATE;
+
+#ifndef VBOX_DEVICE_STRUCT_TESTCASE
+
+static void rtc_timer_update(PRTCSTATE pThis, int64_t current_time)
+{
+    int period_code, period;
+    uint64_t cur_clock, next_irq_clock;
+    uint32_t freq;
+
+    Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
+    Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
+
+    period_code = pThis->cmos_data[RTC_REG_A] & 0x0f;
+    if (   period_code != 0
+        && (pThis->cmos_data[RTC_REG_B] & REG_B_PIE))
+    {
+        if (period_code <= 2)
+            period_code += 7;
+        /* period in 32 kHz cycles */
+        period = 1 << (period_code - 1);
+        /* compute 32 kHz clock */
+        freq = TMTimerGetFreq(pThis->CTX_SUFF(pPeriodicTimer));
+
+        cur_clock = ASMMultU64ByU32DivByU32(current_time, 32768, freq);
+        next_irq_clock = (cur_clock & ~(uint64_t)(period - 1)) + period;
+        pThis->next_periodic_time = ASMMultU64ByU32DivByU32(next_irq_clock, freq, 32768) + 1;
+        TMTimerSet(pThis->CTX_SUFF(pPeriodicTimer), pThis->next_periodic_time);
+
+#ifdef IN_RING3
+        if (RT_UNLIKELY(period != pThis->CurLogPeriod))
+#else
+        if (RT_UNLIKELY(period != pThis->CurHintPeriod))
+#endif
+        {
+#ifdef IN_RING3
+            if (pThis->cRelLogEntries++ < 64)
+                LogRel(("RTC: period=%#x (%d) %u Hz\n", period, period, _32K / period));
+            pThis->CurLogPeriod  = period;
+#endif
+            pThis->CurHintPeriod = period;
+            TMTimerSetFrequencyHint(pThis->CTX_SUFF(pPeriodicTimer), _32K / period);
+        }
+    }
+    else
+    {
+#ifdef IN_RING3
+        if (TMTimerIsActive(pThis->CTX_SUFF(pPeriodicTimer)) && pThis->cRelLogEntries++ < 64)
+            LogRel(("RTC: Stopped the periodic timer\n"));
+#endif
+        TMTimerStop(pThis->CTX_SUFF(pPeriodicTimer));
+    }
+}
+
+
+static void rtc_raise_irq(PRTCSTATE pThis, uint32_t iLevel)
+{
+    if (!pThis->fDisabledByHpet)
+    {
+        PDMDevHlpISASetIrq(pThis->CTX_SUFF(pDevIns), pThis->irq, iLevel);
+        if (iLevel)
+            STAM_COUNTER_INC(&pThis->StatRTCIrq);
+    }
+}
+
+
+#ifdef IN_RING3
+DECLINLINE(int) to_bcd(PRTCSTATE pThis, int a)
+{
+    if (pThis->cmos_data[RTC_REG_B] & 0x04)
+        return a;
+    return ((a / 10) << 4) | (a % 10);
+}
+#endif
+
+
+DECLINLINE(int) from_bcd(PRTCSTATE pThis, int a)
+{
+    if (pThis->cmos_data[RTC_REG_B] & 0x04)
+        return a;
+    return ((a >> 4) * 10) + (a & 0x0f);
+}
+
+
+static void rtc_set_time(PRTCSTATE pThis)
+{
+    struct my_tm *tm = &pThis->current_tm;
+
+    tm->tm_sec  = from_bcd(pThis, pThis->cmos_data[RTC_SECONDS]);
+    tm->tm_min  = from_bcd(pThis, pThis->cmos_data[RTC_MINUTES]);
+    tm->tm_hour = from_bcd(pThis, pThis->cmos_data[RTC_HOURS] & 0x7f);
+    if (!(pThis->cmos_data[RTC_REG_B] & 0x02))
+    {
+        tm->tm_hour %= 12;
+        if (pThis->cmos_data[RTC_HOURS] & 0x80)
+            tm->tm_hour += 12;
+    }
+    tm->tm_wday = from_bcd(pThis, pThis->cmos_data[RTC_DAY_OF_WEEK]);
+    tm->tm_mday = from_bcd(pThis, pThis->cmos_data[RTC_DAY_OF_MONTH]);
+    tm->tm_mon  = from_bcd(pThis, pThis->cmos_data[RTC_MONTH]) - 1;
+    tm->tm_year = from_bcd(pThis, pThis->cmos_data[RTC_YEAR]) + 100;
+}
+
+
+/* -=-=-=-=-=- I/O Port Handlers -=-=-=-=-=- */
+
+
+/**
+ * @callback_method_impl{FNIOMIOPORTIN}
+ */
+PDMBOTHCBDECL(int) rtcIOPortRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t *pu32, unsigned cb)
+{
+    NOREF(pvUser);
+    if (cb != 1)
+        return VERR_IOM_IOPORT_UNUSED;
+
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+    if ((uPort & 1) == 0)
+        *pu32 = 0xff;
+    else
+    {
+        unsigned bank = (uPort >> 1) & 1;
+        switch (pThis->cmos_index[bank])
+        {
+            case RTC_SECONDS:
+            case RTC_MINUTES:
+            case RTC_HOURS:
+            case RTC_DAY_OF_WEEK:
+            case RTC_DAY_OF_MONTH:
+            case RTC_MONTH:
+            case RTC_YEAR:
+                *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
+                break;
+
+            case RTC_REG_A:
+                if (pThis->cmos_data[RTC_REG_A] & REG_A_UIP)
+                    ++pThis->cUipSeen;
+                else
+                    pThis->cUipSeen = 0;
+                if (pThis->cUipSeen >= 250)
+                {
+                    pThis->cmos_data[pThis->cmos_index[0]] &= ~REG_A_UIP;
+                    pThis->cUipSeen = 0;
+                }
+                *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
+                break;
+
+            case RTC_REG_C:
+                *pu32 = pThis->cmos_data[pThis->cmos_index[0]];
+                rtc_raise_irq(pThis, 0);
+                pThis->cmos_data[RTC_REG_C] = 0x00;
+                break;
+
+            default:
+                *pu32 = pThis->cmos_data[pThis->cmos_index[bank]];
+                break;
+        }
+
+        Log(("CMOS: Read bank %d idx %#04x: %#04x\n", bank, pThis->cmos_index[bank], *pu32));
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * @callback_method_impl{FNIOMIOPORTOUT}
+ */
+PDMBOTHCBDECL(int) rtcIOPortWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT uPort, uint32_t u32, unsigned cb)
+{
+    NOREF(pvUser);
+    if (cb != 1)
+        return VINF_SUCCESS;
+
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+    uint32_t bank = (uPort >> 1) & 1;
+    if ((uPort & 1) == 0)
+    {
+        pThis->cmos_index[bank] = (u32 & 0x7f) + (bank * CMOS_BANK_SIZE);
+
+        /* HACK ALERT! Attempt to trigger VM_FF_TIMER and/or VM_FF_TM_VIRTUAL_SYNC
+           for forcing the pSecondTimer2 timer to run be run and clear UIP in
+           a timely fashion. */
+        if (u32 == RTC_REG_A)
+            TMTimerGet(pThis->CTX_SUFF(pSecondTimer));
+    }
+    else
+    {
+        Log(("CMOS: Write bank %d idx %#04x: %#04x (old %#04x)\n", bank,
+             pThis->cmos_index[bank], u32, pThis->cmos_data[pThis->cmos_index[bank]]));
+
+        int const idx = pThis->cmos_index[bank];
+        switch (idx)
+        {
+            case RTC_SECONDS_ALARM:
+            case RTC_MINUTES_ALARM:
+            case RTC_HOURS_ALARM:
+                pThis->cmos_data[pThis->cmos_index[0]] = u32;
+                break;
+
+            case RTC_SECONDS:
+            case RTC_MINUTES:
+            case RTC_HOURS:
+            case RTC_DAY_OF_WEEK:
+            case RTC_DAY_OF_MONTH:
+            case RTC_MONTH:
+            case RTC_YEAR:
+                pThis->cmos_data[pThis->cmos_index[0]] = u32;
+                /* if in set mode, do not update the time */
+                if (!(pThis->cmos_data[RTC_REG_B] & REG_B_SET))
+                    rtc_set_time(pThis);
+                break;
+
+            case RTC_REG_A:
+            case RTC_REG_B:
+            {
+                /* We need to acquire the clock lock, because of lock ordering
+                   issues this means having to release the device lock.  Since
+                   we're letting IOM do the locking, we must not return without
+                   holding the device lock.*/
+                PDMCritSectLeave(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo));
+                int rc1 = TMTimerLock(pThis->CTX_SUFF(pPeriodicTimer), VINF_SUCCESS /* must get it */);
+                int rc2 = PDMCritSectEnter(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo), VINF_SUCCESS /* must get it */);
+                AssertRCReturn(rc1, rc1);
+                AssertRCReturnStmt(rc2, TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer)), rc2);
+
+                if (idx == RTC_REG_A)
+                {
+                    /* UIP bit is read only */
+                    pThis->cmos_data[RTC_REG_A] = (u32                        & ~REG_A_UIP)
+                                                | (pThis->cmos_data[RTC_REG_A] & REG_A_UIP);
+                }
+                else
+                {
+                    if (u32 & REG_B_SET)
+                    {
+                        /* set mode: reset UIP mode */
+                        pThis->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
+#if 0 /* This is probably wrong as it breaks changing the time/date in OS/2. */
+                        u32 &= ~REG_B_UIE;
+#endif
+                    }
+                    else
+                    {
+                        /* if disabling set mode, update the time */
+                        if (pThis->cmos_data[RTC_REG_B] & REG_B_SET)
+                            rtc_set_time(pThis);
+                    }
+                    pThis->cmos_data[RTC_REG_B] = u32;
+                }
+
+                rtc_timer_update(pThis, TMTimerGet(pThis->CTX_SUFF(pPeriodicTimer)));
+
+                TMTimerUnlock(pThis->CTX_SUFF(pPeriodicTimer));
+                /* the caller leaves the other lock. */
+                break;
+            }
+
+            case RTC_REG_C:
+            case RTC_REG_D:
+                /* cannot write to them */
+                break;
+
+            default:
+                pThis->cmos_data[pThis->cmos_index[bank]] = u32;
+                break;
+        }
+    }
+
+    return VINF_SUCCESS;
+}
+
+#ifdef IN_RING3
+
+/* -=-=-=-=-=- Debug Info Handlers  -=-=-=-=-=- */
+
+/**
+ * @callback_method_impl{FNDBGFHANDLERDEV,
+ *      Dumps the cmos Bank Info.}
+ */
+static DECLCALLBACK(void) rtcCmosBankInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    RT_NOREF1(pszArgs);
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+
+    pHlp->pfnPrintf(pHlp,
+                    "First CMOS bank, offsets 0x0E - 0x7F\n"
+                    "Offset %02x : --- use 'info rtc' to show CMOS clock ---", 0);
+    for (unsigned iCmos = CMOS_BANK_LOWER_LIMIT; iCmos <= CMOS_BANK_UPPER_LIMIT; iCmos++)
+    {
+        if ((iCmos & 15) == 0)
+            pHlp->pfnPrintf(pHlp, "Offset %02x : %02x", iCmos, pThis->cmos_data[iCmos]);
+        else if ((iCmos & 15) == 8)
+            pHlp->pfnPrintf(pHlp, "-%02x", pThis->cmos_data[iCmos]);
+        else if ((iCmos & 15) == 15)
+            pHlp->pfnPrintf(pHlp, " %02x\n", pThis->cmos_data[iCmos]);
+        else
+            pHlp->pfnPrintf(pHlp, " %02x", pThis->cmos_data[iCmos]);
+    }
+}
+
+/**
+ * @callback_method_impl{FNDBGFHANDLERDEV,
+ *      Dumps the cmos Bank2 Info.}
+ */
+static DECLCALLBACK(void) rtcCmosBank2Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    RT_NOREF1(pszArgs);
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+
+    pHlp->pfnPrintf(pHlp, "Second CMOS bank, offsets 0x80 - 0xFF\n");
+    for (uint16_t iCmos = CMOS_BANK2_LOWER_LIMIT; iCmos <= CMOS_BANK2_UPPER_LIMIT; iCmos++)
+    {
+        if ((iCmos & 15) == 0)
+            pHlp->pfnPrintf(pHlp, "Offset %02x : %02x", iCmos, pThis->cmos_data[iCmos]);
+        else if ((iCmos & 15) == 8)
+            pHlp->pfnPrintf(pHlp, "-%02x", pThis->cmos_data[iCmos]);
+        else if ((iCmos & 15) == 15)
+            pHlp->pfnPrintf(pHlp, " %02x\n", pThis->cmos_data[iCmos]);
+        else
+            pHlp->pfnPrintf(pHlp, " %02x", pThis->cmos_data[iCmos]);
+    }
+}
+
+/**
+ * @callback_method_impl{FNDBGFHANDLERDEV,
+ *      Dumps the cmos RTC Info.}
+ */
+static DECLCALLBACK(void) rtcCmosClockInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    RT_NOREF1(pszArgs);
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+    uint8_t u8Sec   = from_bcd(pThis, pThis->cmos_data[RTC_SECONDS]);
+    uint8_t u8Min   = from_bcd(pThis, pThis->cmos_data[RTC_MINUTES]);
+    uint8_t u8Hr    = from_bcd(pThis, pThis->cmos_data[RTC_HOURS] & 0x7f);
+    if (   !(pThis->cmos_data[RTC_REG_B] & 0x02)
+        && (pThis->cmos_data[RTC_HOURS] & 0x80))
+        u8Hr += 12;
+    uint8_t u8Day   = from_bcd(pThis, pThis->cmos_data[RTC_DAY_OF_MONTH]);
+    uint8_t u8Month = from_bcd(pThis, pThis->cmos_data[RTC_MONTH]) ;
+    uint8_t u8Year  = from_bcd(pThis, pThis->cmos_data[RTC_YEAR]);
+    pHlp->pfnPrintf(pHlp, "Time: %02u:%02u:%02u  Date: %02u-%02u-%02u\n",
+                    u8Hr, u8Min, u8Sec, u8Year, u8Month, u8Day);
+    pHlp->pfnPrintf(pHlp, "REG A=%02x B=%02x C=%02x D=%02x\n",
+                    pThis->cmos_data[RTC_REG_A], pThis->cmos_data[RTC_REG_B],
+                    pThis->cmos_data[RTC_REG_C], pThis->cmos_data[RTC_REG_D]);
+}
+
+
+
+/* -=-=-=-=-=- Timers and their support code  -=-=-=-=-=- */
+
+
+/**
+ * @callback_method_impl{FNTMTIMERDEV, periodic}
+ */
+static DECLCALLBACK(void) rtcTimerPeriodic(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
+{
+    RT_NOREF2(pTimer, pvUser);
+    PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
+    Assert(TMTimerIsLockOwner(pThis->CTX_SUFF(pPeriodicTimer)));
+    Assert(PDMCritSectIsOwner(pThis->CTX_SUFF(pDevIns)->CTX_SUFF(pCritSectRo)));
+
+    rtc_timer_update(pThis, pThis->next_periodic_time);
+    STAM_COUNTER_INC(&pThis->StatRTCTimerCB);
+    pThis->cmos_data[RTC_REG_C] |= 0xc0;
+
+    rtc_raise_irq(pThis, 1);
+}
+
+
+/* month is between 0 and 11. */
+static int get_days_in_month(int month, int year)
+{
+    static const int days_tab[12] =
+    {
+        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+    };
+    int d;
+
+    if ((unsigned )month >= 12)
+        return 31;
+
+    d = days_tab[month];
+    if (month == 1)
+    {
+        if ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0))
+            d++;
+    }
+    return d;
+}
+
+
+/* update 'tm' to the next second */
+static void rtc_next_second(struct my_tm *tm)
+{
+    int days_in_month;
+
+    tm->tm_sec++;
+    if ((unsigned)tm->tm_sec >= 60)
+    {
+        tm->tm_sec = 0;
+        tm->tm_min++;
+        if ((unsigned)tm->tm_min >= 60)
+        {
+            tm->tm_min = 0;
+            tm->tm_hour++;
+            if ((unsigned)tm->tm_hour >= 24)
+            {
+                tm->tm_hour = 0;
+                /* next day */
+                tm->tm_wday++;
+                if ((unsigned)tm->tm_wday >= 7)
+                    tm->tm_wday = 0;
+                days_in_month = get_days_in_month(tm->tm_mon,
+                                                  tm->tm_year + 1900);
+                tm->tm_mday++;
+                if (tm->tm_mday < 1)
+                    tm->tm_mday = 1;
+                else if (tm->tm_mday > days_in_month)
+                {
+                    tm->tm_mday = 1;
+                    tm->tm_mon++;
+                    if (tm->tm_mon >= 12)
+                    {
+                        tm->tm_mon = 0;
+                        tm->tm_year++;
+                    }
+                }
+            }
+        }
+    }
+}
+
+
+/**
+ * @callback_method_impl{FNTMTIMERDEV, Second timer.}
+ */
+static DECLCALLBACK(void) rtcTimerSecond(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
+{
     RT_NOREF2(pTimer, pvUser);
     PRTCSTATE pThis = PDMINS_2_DATA(pDevIns, PRTCSTATE);
@@ -1239,4 +2439,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -1245,55 +2446,73 @@
 const PDMDEVREG g_DeviceMC146818 =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "mc146818",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Motorola MC146818 RTC/CMOS Device.",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36 | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_RTC,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(RTCSTATE),
-    /* pfnConstruct */
-    rtcConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    rtcRelocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    rtcReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    rtcInitComplete,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "mc146818",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
+    /* .fClass = */                 PDM_DEVREG_CLASS_RTC,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         1,
+    /* .cbInstanceShared = */       sizeof(RTCSTATE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Motorola MC146818 RTC/CMOS Device.",
+#ifdef IN_RING3
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           rtcConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            rtcRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               rtcReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        rtcInitComplete,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not IN_RING3, IN_RING0 nor IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
+
+#endif /* OLD STYLE DEVICE */
Index: /trunk/src/VBox/Devices/Parallel/DevParallel.cpp
===================================================================
--- /trunk/src/VBox/Devices/Parallel/DevParallel.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Parallel/DevParallel.cpp	(revision 80531)
@@ -807,4 +807,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * The device registration structure.
@@ -812,54 +814,71 @@
 const PDMDEVREG g_DeviceParallelPort =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "parallel",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Parallel Communication Port",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_PARALLEL,
-    /* cMaxInstances */
-    2,
-    /* cbInstance */
-    sizeof(PARALLELPORT),
-    /* pfnConstruct */
-    parallelR3Construct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    parallelR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "parallel",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_PARALLEL,
+    /* .cMaxInstances = */          2,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(PARALLELPORT),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Parallel Communication Port",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           parallelR3Construct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            parallelR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               NULL,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
-#endif /* IN_RING3 */
+
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/Samples/DevPlayground.cpp
===================================================================
--- /trunk/src/VBox/Devices/Samples/DevPlayground.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Samples/DevPlayground.cpp	(revision 80531)
@@ -341,52 +341,69 @@
 static const PDMDEVREG g_DevicePlayground =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "playground",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "VBox Playground Device.",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS,
-    /* fClass */
-    PDM_DEVREG_CLASS_MISC,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(VBOXPLAYGROUNDDEVICE),
-    /* pfnConstruct */
-    devPlaygroundConstruct,
-    /* pfnDestruct */
-    devPlaygroundDestruct,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "playground",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fClass = */                 PDM_DEVREG_CLASS_MISC,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(VBOXPLAYGROUNDDEVICE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "VBox Playground Device.",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "",
+    /* .pszR0Mod = */               "",
+    /* .pfnConstruct = */           devPlaygroundConstruct,
+    /* .pfnDestruct = */            devPlaygroundDestruct,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               NULL,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
Index: /trunk/src/VBox/Devices/Samples/VBoxSampleDevice.cpp
===================================================================
--- /trunk/src/VBox/Devices/Samples/VBoxSampleDevice.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Samples/VBoxSampleDevice.cpp	(revision 80531)
@@ -89,52 +89,69 @@
 static const PDMDEVREG g_DeviceSample =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "sample",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "VBox Sample Device.",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS,
-    /* fClass */
-    PDM_DEVREG_CLASS_MISC,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(VBOXSAMPLEDEVICE),
-    /* pfnConstruct */
-    devSampleConstruct,
-    /* pfnDestruct */
-    devSampleDestruct,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    NULL,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "sample",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fClass = */                 PDM_DEVREG_CLASS_MISC,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(VBOXSAMPLEDEVICE),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "VBox Sample Device.",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "",
+    /* .pszR0Mod = */               "",
+    /* .pfnConstruct = */           devSampleConstruct,
+    /* .pfnDestruct = */            devSampleDestruct,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               NULL,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
Index: /trunk/src/VBox/Devices/Serial/DevOxPcie958.cpp
===================================================================
--- /trunk/src/VBox/Devices/Serial/DevOxPcie958.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Serial/DevOxPcie958.cpp	(revision 80531)
@@ -598,5 +598,5 @@
         && VM_IS_RAW_MODE_ENABLED(pVM))
     {
-        rc = PDMR3LdrGetSymbolRC(pVM, pDevIns->pReg->szRCMod, "ox958IrqReq", &pfnSerialIrqReqRC);
+        rc = PDMR3LdrGetSymbolRC(pVM, pDevIns->pReg->pszRCMod, "ox958IrqReq", &pfnSerialIrqReqRC);
         if (RT_FAILURE(rc))
             return rc;
@@ -606,5 +606,5 @@
     if (fR0Enabled)
     {
-        rc = PDMR3LdrGetSymbolR0(pVM, pDevIns->pReg->szR0Mod, "ox958IrqReq", &pfnSerialIrqReqR0);
+        rc = PDMR3LdrGetSymbolR0(pVM, pDevIns->pReg->pszR0Mod, "ox958IrqReq", &pfnSerialIrqReqR0);
         if (RT_FAILURE(rc))
             return rc;
@@ -624,58 +624,76 @@
 }
 
+#endif /* IN_RING3 */
+
 
 const PDMDEVREG g_DeviceOxPcie958 =
 {
-    /* u32version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "oxpcie958uart",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "OXPCIe958 based UART controller.\n",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_SERIAL,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(DEVOX958),
-    /* pfnConstruct */
-    ox958R3Construct,
-    /* pfnDestruct */
-    ox958R3Destruct,
-    /* pfnRelocate */
-    ox958R3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    ox958R3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    ox958R3Attach,
-    /* pfnDetach */
-    ox958R3Detach,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "oxpcie958uart",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_SERIAL,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVOX958),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "OXPCIe958 based UART controller.\n",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           ox958R3Construct,
+    /* .pfnDestruct = */            ox958R3Destruct,
+    /* .pfnRelocate = */            ox958R3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               ox958R3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              ox958R3Attach,
+    /* .pfnDetach = */              ox958R3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/Devices/Serial/DevSerial.cpp
===================================================================
--- /trunk/src/VBox/Devices/Serial/DevSerial.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Serial/DevSerial.cpp	(revision 80531)
@@ -426,5 +426,5 @@
         if (   RT_SUCCESS(rc)
             && VM_IS_RAW_MODE_ENABLED(pVM)) /** @todo this dynamic symbol resolving will be reworked later! */
-            rc = PDMR3LdrGetSymbolRC(pVM, pDevIns->pReg->szRCMod, "serialIrqReq", &pfnSerialIrqReqRC);
+            rc = PDMR3LdrGetSymbolRC(pVM, pDevIns->pReg->pszRCMod, "serialIrqReq", &pfnSerialIrqReqRC);
         if (RT_FAILURE(rc))
             return rc;
@@ -436,5 +436,5 @@
         rc = PDMDevHlpIOPortRegisterR0(pDevIns, uIoBase, 8, 0, "serialIoPortWrite", "serialIoPortRead", NULL, NULL, "SERIAL");
         if (RT_SUCCESS(rc)) /** @todo this dynamic symbol resolving will be reworked later! */
-            rc = PDMR3LdrGetSymbolR0(pVM, pDevIns->pReg->szR0Mod, "serialIrqReq", &pfnSerialIrqReqR0);
+            rc = PDMR3LdrGetSymbolR0(pVM, pDevIns->pReg->pszR0Mod, "serialIrqReq", &pfnSerialIrqReqR0);
         if (RT_FAILURE(rc))
             return rc;
@@ -461,4 +461,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -467,54 +468,71 @@
 const PDMDEVREG g_DeviceSerialPort =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "serial",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Serial Communication Port",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_SERIAL,
-    /* cMaxInstances */
-    UINT32_MAX,
-    /* cbInstance */
-    sizeof(DEVSERIAL),
-    /* pfnConstruct */
-    serialR3Construct,
-    /* pfnDestruct */
-    serialR3Destruct,
-    /* pfnRelocate */
-    serialR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    serialR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    serialR3Attach,
-    /* pfnDetach */
-    serialR3Detach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "serial",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_SERIAL,
+    /* .cMaxInstances = */          UINT32_MAX,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(DEVSERIAL),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Serial Communication Port",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           serialR3Construct,
+    /* .pfnDestruct = */            serialR3Destruct,
+    /* .pfnRelocate = */            serialR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               serialR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              serialR3Attach,
+    /* .pfnDetach = */              serialR3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
-#endif /* IN_RING3 */
 
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
+
Index: /trunk/src/VBox/Devices/Storage/DevAHCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevAHCI.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Storage/DevAHCI.cpp	(revision 80531)
@@ -6224,4 +6224,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * The device registration structure.
@@ -6229,56 +6231,72 @@
 const PDMDEVREG g_DeviceAHCI =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "ahci",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Intel AHCI controller.\n",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
-    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION |
-    PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION,
-    /* fClass */
-    PDM_DEVREG_CLASS_STORAGE,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(AHCI),
-    /* pfnConstruct */
-    ahciR3Construct,
-    /* pfnDestruct */
-    ahciR3Destruct,
-    /* pfnRelocate */
-    ahciR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    ahciR3Reset,
-    /* pfnSuspend */
-    ahciR3Suspend,
-    /* pfnResume */
-    ahciR3Resume,
-    /* pfnAttach */
-    ahciR3Attach,
-    /* pfnDetach */
-    ahciR3Detach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    ahciR3PowerOff,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "ahci",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
+                                    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION |
+                                    PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION,
+    /* .fClass = */                 PDM_DEVREG_CLASS_STORAGE,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(AHCI),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Intel AHCI controller.\n",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           ahciR3Construct,
+    /* .pfnDestruct = */            ahciR3Destruct,
+    /* .pfnRelocate = */            ahciR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               ahciR3Reset,
+    /* .pfnSuspend = */             ahciR3Suspend,
+    /* .pfnResume = */              ahciR3Resume,
+    /* .pfnAttach = */              ahciR3Attach,
+    /* .pfnDetach = */              ahciR3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            ahciR3PowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/Storage/DevATA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Storage/DevATA.cpp	(revision 80531)
@@ -7647,6 +7647,6 @@
             pIf->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
             pIf->pControllerR3 = &pThis->aCts[i];
-            pIf->pControllerR0 = MMHyperR3ToR0(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
-            pIf->pControllerRC = MMHyperR3ToRC(PDMDevHlpGetVM(pDevIns), &pThis->aCts[i]);
+            pIf->pControllerR0 = PDMDEVINS_DATA_2_R0_REMOVE_ME(pDevIns, &pThis->aCts[i]);
+            pIf->pControllerRC = PDMDEVINS_DATA_2_R0_REMOVE_ME(pDevIns, &pThis->aCts[i]);
             pIf->IBase.pfnQueryInterface       = ataR3QueryInterface;
             pIf->IMountNotify.pfnMountNotify   = ataR3MountNotify;
@@ -8050,4 +8050,5 @@
 }
 
+#endif /* IN_RING3 */
 
 /**
@@ -8056,60 +8057,76 @@
 const PDMDEVREG g_DevicePIIX3IDE =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "piix3ide",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Intel PIIX3 ATA controller.\n"
-    "  LUN #0 is primary master.\n"
-    "  LUN #1 is primary slave.\n"
-    "  LUN #2 is secondary master.\n"
-    "  LUN #3 is secondary slave.\n"
-    "  LUN #999 is the LED/Status connector.",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
-    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION |
-    PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION,
-    /* fClass */
-    PDM_DEVREG_CLASS_STORAGE,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(PCIATAState),
-    /* pfnConstruct */
-    ataR3Construct,
-    /* pfnDestruct */
-    ataR3Destruct,
-    /* pfnRelocate */
-    ataR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    ataR3Reset,
-    /* pfnSuspend */
-    ataR3Suspend,
-    /* pfnResume */
-    ataR3Resume,
-    /* pfnAttach */
-    ataR3Attach,
-    /* pfnDetach */
-    ataR3Detach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    ataR3PowerOff,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "piix3ide",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
+                                    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION |
+                                    PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION,
+    /* .fClass = */                 PDM_DEVREG_CLASS_STORAGE,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(PCIATAState),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Intel PIIX3 ATA controller.\n"
+                                    "  LUN #0 is primary master.\n"
+                                    "  LUN #1 is primary slave.\n"
+                                    "  LUN #2 is secondary master.\n"
+                                    "  LUN #3 is secondary slave.\n"
+                                    "  LUN #999 is the LED/Status connector.",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           ataR3Construct,
+    /* .pfnDestruct = */            ataR3Destruct,
+    /* .pfnRelocate = */            ataR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               ataR3Reset,
+    /* .pfnSuspend = */             ataR3Suspend,
+    /* .pfnResume = */              ataR3Resume,
+    /* .pfnAttach = */              ataR3Attach,
+    /* .pfnDetach = */              ataR3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            ataR3PowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Storage/DevBusLogic.cpp	(revision 80531)
@@ -4485,4 +4485,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * The device registration structure.
@@ -4490,56 +4492,72 @@
 const PDMDEVREG g_DeviceBusLogic =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "buslogic",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "BusLogic BT-958 SCSI host adapter.\n",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
-    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION |
-    PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION,
-    /* fClass */
-    PDM_DEVREG_CLASS_STORAGE,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(BUSLOGIC),
-    /* pfnConstruct */
-    buslogicR3Construct,
-    /* pfnDestruct */
-    buslogicR3Destruct,
-    /* pfnRelocate */
-    buslogicR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    buslogicR3Reset,
-    /* pfnSuspend */
-    buslogicR3Suspend,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    buslogicR3Attach,
-    /* pfnDetach */
-    buslogicR3Detach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    buslogicR3PowerOff,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "buslogic",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
+                                    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION |
+                                    PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION,
+    /* .fClass = */                 PDM_DEVREG_CLASS_STORAGE,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(BUSLOGIC),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "BusLogic BT-958 SCSI host adapter.\n",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           buslogicR3Construct,
+    /* .pfnDestruct = */            buslogicR3Destruct,
+    /* .pfnRelocate = */            buslogicR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               buslogicR3Reset,
+    /* .pfnSuspend = */             buslogicR3Suspend,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              buslogicR3Attach,
+    /* .pfnDetach = */              buslogicR3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            buslogicR3PowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/Storage/DevFdc.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevFdc.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Storage/DevFdc.cpp	(revision 80531)
@@ -2838,52 +2838,69 @@
 const PDMDEVREG g_DeviceFloppyController =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "i82078",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "",
-    /* pszDescription */
-    "Floppy drive controller (Intel 82078)",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS,
-    /* fClass */
-    PDM_DEVREG_CLASS_STORAGE,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(fdctrl_t),
-    /* pfnConstruct */
-    fdcConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    NULL,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    fdcReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    fdcAttach,
-    /* pfnDetach */
-    fdcDetach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "i82078",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fClass = */                 PDM_DEVREG_CLASS_STORAGE,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(fdctrl_t),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Floppy drive controller (Intel 82078)",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "",
+    /* .pszR0Mod = */               "",
+    /* .pfnConstruct = */           fdcConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            NULL,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               fdcReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              fdcAttach,
+    /* .pfnDetach = */              fdcDetach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
Index: /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp	(revision 80531)
@@ -5733,4 +5733,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * The device registration structure - SPI SCSI controller.
@@ -5738,53 +5740,70 @@
 const PDMDEVREG g_DeviceLsiLogicSCSI =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "lsilogicscsi",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "LSI Logic 53c1030 SCSI controller.\n",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
-    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION,
-    /* fClass */
-    PDM_DEVREG_CLASS_STORAGE,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(LSILOGICSCSI),
-    /* pfnConstruct */
-    lsilogicR3Construct,
-    /* pfnDestruct */
-    lsilogicR3Destruct,
-    /* pfnRelocate */
-    lsilogicR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    lsilogicR3Reset,
-    /* pfnSuspend */
-    lsilogicR3Suspend,
-    /* pfnResume */
-    lsilogicR3Resume,
-    /* pfnAttach */
-    lsilogicR3Attach,
-    /* pfnDetach */
-    lsilogicR3Detach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    lsilogicR3PowerOff,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "lsilogicscsi",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
+                                    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION,
+    /* .fClass = */                 PDM_DEVREG_CLASS_STORAGE,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(LSILOGICSCSI),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "LSI Logic 53c1030 SCSI controller.\n",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           lsilogicR3Construct,
+    /* .pfnDestruct = */            lsilogicR3Destruct,
+    /* .pfnRelocate = */            lsilogicR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               lsilogicR3Reset,
+    /* .pfnSuspend = */             lsilogicR3Suspend,
+    /* .pfnResume = */              lsilogicR3Resume,
+    /* .pfnAttach = */              lsilogicR3Attach,
+    /* .pfnDetach = */              lsilogicR3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            lsilogicR3PowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
@@ -5794,56 +5813,72 @@
 const PDMDEVREG g_DeviceLsiLogicSAS =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "lsilogicsas",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "LSI Logic SAS1068 controller.\n",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
-    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION |
-    PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION,
-    /* fClass */
-    PDM_DEVREG_CLASS_STORAGE,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(LSILOGICSCSI),
-    /* pfnConstruct */
-    lsilogicR3Construct,
-    /* pfnDestruct */
-    lsilogicR3Destruct,
-    /* pfnRelocate */
-    lsilogicR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    lsilogicR3Reset,
-    /* pfnSuspend */
-    lsilogicR3Suspend,
-    /* pfnResume */
-    lsilogicR3Resume,
-    /* pfnAttach */
-    lsilogicR3Attach,
-    /* pfnDetach */
-    lsilogicR3Detach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    lsilogicR3PowerOff,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "lsilogicsas",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0 |
+                                    PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION | PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION |
+                                    PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION,
+    /* .fClass = */                 PDM_DEVREG_CLASS_STORAGE,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(LSILOGICSCSI),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "LSI Logic SAS1068 controller.\n",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           lsilogicR3Construct,
+    /* .pfnDestruct = */            lsilogicR3Destruct,
+    /* .pfnRelocate = */            lsilogicR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               lsilogicR3Reset,
+    /* .pfnSuspend = */             lsilogicR3Suspend,
+    /* .pfnResume = */              lsilogicR3Resume,
+    /* .pfnAttach = */              lsilogicR3Attach,
+    /* .pfnDetach = */              lsilogicR3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            lsilogicR3PowerOff,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/Storage/DevVirtioSCSI.cpp	(revision 80531)
@@ -2319,55 +2319,73 @@
 const PDMDEVREG g_DeviceVirtioSCSI =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "virtio-scsi",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Virtio Host SCSI.\n",
-    /* fFlags */
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "virtio-scsi",
 #ifdef VIRTIOSCSI_GC_SUPPORT
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
 #else
-    PDM_DEVREG_FLAGS_DEFAULT_BITS,
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS,
 #endif
-    /* fClass */
-    PDM_DEVREG_CLASS_MISC,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(VIRTIOSCSI),
-    /* pfnConstruct */
-    virtioScsiConstruct,
-    /* pfnDestruct */
-    virtioScsiDestruct,
-    /* pfnRelocate */
-    virtioScsiR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    virtioScsiR3PDMReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    virtioScsiR3Attach,
-    /* pfnDetach */
-    virtioScsiR3Detach,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .fClass = */                 PDM_DEVREG_CLASS_MISC,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(VIRTIOSCSI),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Virtio Host SCSI.\n",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           virtioScsiConstruct,
+    /* .pfnDestruct = */            virtioScsiDestruct,
+    /* .pfnRelocate = */            virtioScsiR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               virtioScsiR3PDMReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              virtioScsiR3Attach,
+    /* .pfnDetach = */              virtioScsiR3Detach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
+
Index: /trunk/src/VBox/Devices/USB/DevOHCI.cpp
===================================================================
--- /trunk/src/VBox/Devices/USB/DevOHCI.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/USB/DevOHCI.cpp	(revision 80531)
@@ -6145,57 +6145,74 @@
 }
 
+#endif /* IN_RING3 */
 
 const PDMDEVREG g_DeviceOHCI =
 {
-    /* u32version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "usb-ohci",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "OHCI USB controller.\n",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_BUS_USB,
-    /* cMaxInstances */
-    ~0U,
-    /* cbInstance */
-    sizeof(OHCI),
-    /* pfnConstruct */
-    ohciR3Construct,
-    /* pfnDestruct */
-    ohciR3Destruct,
-    /* pfnRelocate */
-    ohciR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    ohciR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    ohciR3Resume,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "usb-ohci",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_BUS_USB,
+    /* .cMaxInstances = */          ~0U,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(OHCI),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "OHCI USB controller.\n",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           ohciR3Construct,
+    /* .pfnDestruct = */            ohciR3Destruct,
+    /* .pfnRelocate = */            ohciR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               ohciR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              ohciR3Resume,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#endif /* IN_RING3 */
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp
===================================================================
--- /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/VMMDev/VMMDev.cpp	(revision 80531)
@@ -4735,4 +4735,6 @@
 }
 
+#endif /* IN_RING3 */
+
 /**
  * The device registration structure.
@@ -4740,57 +4742,74 @@
 extern "C" const PDMDEVREG g_DeviceVMMDev =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "VMMDev",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "VirtualBox VMM Device\n",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_VMM_DEV,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(VMMDevState),
-    /* pfnConstruct */
-    vmmdevConstruct,
-    /* pfnDestruct */
-    vmmdevDestruct,
-    /* pfnRelocate */
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "VMMDev",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_VMM_DEV,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(VMMDevState),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "VirtualBox VMM Device\n",
+#if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           vmmdevConstruct,
+    /* .pfnDestruct = */            vmmdevDestruct,
 # ifdef VBOX_WITH_RAW_MODE_KEEP
-    vmmdevRelocate,
+    /* .pfnRelocate = */            vmmdevRelocate,
 # else
-    NULL,
+    /* .pfnRelocate = */            NULL,
 # endif
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    vmmdevReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               vmmdevReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
-#endif /* IN_RING3 */
+
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
Index: /trunk/src/VBox/Devices/build/VBoxDD.cpp
===================================================================
--- /trunk/src/VBox/Devices/build/VBoxDD.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/build/VBoxDD.cpp	(revision 80531)
@@ -146,9 +146,7 @@
         return rc;
 #endif
-#ifdef VBOX_ACPI
     rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceACPI);
     if (RT_FAILURE(rc))
         return rc;
-#endif
     rc = pCallbacks->pfnRegister(pCallbacks, &g_DeviceDMA);
     if (RT_FAILURE(rc))
Index: /trunk/src/VBox/Devices/build/VBoxDD2.h
===================================================================
--- /trunk/src/VBox/Devices/build/VBoxDD2.h	(revision 80530)
+++ /trunk/src/VBox/Devices/build/VBoxDD2.h	(revision 80531)
@@ -71,3 +71,2 @@
 
 #endif /* !VBOX_INCLUDED_SRC_build_VBoxDD2_h */
-
Index: /trunk/src/VBox/Devices/build/VBoxDDR0.cpp
===================================================================
--- /trunk/src/VBox/Devices/build/VBoxDDR0.cpp	(revision 80530)
+++ /trunk/src/VBox/Devices/build/VBoxDDR0.cpp	(revision 80531)
@@ -20,5 +20,10 @@
 *   Header Files                                                                                                                 *
 *********************************************************************************************************************************/
-#include <iprt/types.h>
+#define LOG_GROUP LOG_GROUP_DEV
+#include <VBox/log.h>
+#include <VBox/sup.h>
+#include <VBox/vmm/pdmdev.h>
+
+#include "VBoxDD.h"
 
 
@@ -31,2 +36,97 @@
 #endif
 
+/**
+ * Pointer to the ring-0 device registrations for VBoxDDR0.
+ */
+static PCPDMDEVREGR0 g_apVBoxDDR0DevRegs[] =
+{
+    &g_DevicePCI,
+    &g_DevicePciIch9,
+    &g_DeviceIOAPIC,
+    &g_DevicePS2KeyboardMouse,
+    &g_DevicePIIX3IDE,
+    &g_DeviceI8254,
+    &g_DeviceI8259,
+    &g_DeviceHPET,
+    &g_DeviceSmc,
+    /// @todo &g_DeviceFlash,
+    &g_DeviceMC146818,
+    &g_DeviceVga,
+    &g_DeviceVMMDev,
+    &g_DevicePCNet,
+#ifdef VBOX_WITH_E1000
+    &g_DeviceE1000,
+#endif
+#ifdef VBOX_WITH_VIRTIO
+    &g_DeviceVirtioNet,
+#endif
+    &g_DeviceICHAC97,
+    &g_DeviceHDA,
+#ifdef VBOX_WITH_VUSB
+    &g_DeviceOHCI,
+#endif
+#ifdef VBOX_WITH_EHCI_IMPL
+    &g_DeviceEHCI,
+#endif
+#ifdef VBOX_WITH_XHCI_IMPL
+    &g_DeviceXHCI,
+#endif
+    &g_DeviceACPI,
+    &g_DeviceDMA,
+    &g_DeviceSerialPort,
+    &g_DeviceOxPcie958,
+    &g_DeviceParallelPort,
+#ifdef VBOX_WITH_AHCI
+    &g_DeviceAHCI,
+#endif
+#ifdef VBOX_WITH_BUSLOGIC
+    &g_DeviceBusLogic,
+#endif
+    &g_DevicePCIBridge,
+    &g_DevicePciIch9Bridge,
+#ifdef VBOX_WITH_LSILOGIC
+    &g_DeviceLsiLogicSCSI,
+    &g_DeviceLsiLogicSAS,
+#endif
+#ifdef VBOX_WITH_NVME_IMPL
+    &g_DeviceNVMe,
+#endif
+#ifdef VBOX_WITH_VIRTIO_SCSI
+    &g_DeviceVirtioSCSI,
+#endif
+#ifdef VBOX_WITH_PCI_PASSTHROUGH_IMPL
+    &g_DevicePciRaw,
+#endif
+    &g_DeviceGIMDev,
+#ifdef VBOX_WITH_NEW_LPC_DEVICE
+    &g_DeviceLPC,
+#endif
+};
+
+/**
+ * Module device registration record for VBoxDDR0.
+ */
+static PDMDEVMODREGR0 g_VBoxDDR0ModDevReg =
+{
+    /* .u32Version = */ PDM_DEVMODREGR0_VERSION,
+    /* .cDevRegs = */   RT_ELEMENTS(g_apVBoxDDR0DevRegs),
+    /* .papDevRegs = */ &g_apVBoxDDR0DevRegs[0],
+    /* .hMod = */       NULL,
+    /* .ListEntry = */  { NULL, NULL },
+};
+
+
+DECLEXPORT(int)  ModuleInit(void *hMod)
+{
+    LogFlow(("VBoxDDR0/ModuleInit: %p\n", hMod));
+    return PDMR0DeviceRegisterModule(hMod, &g_VBoxDDR0ModDevReg);
+}
+
+
+DECLEXPORT(void) ModuleTerm(void *hMod)
+{
+    LogFlow(("VBoxDDR0/ModuleTerm: %p\n", hMod));
+    PDMR0DeviceDeregisterModule(hMod, &g_VBoxDDR0ModDevReg);
+}
+
+
Index: /trunk/src/VBox/ExtPacks/BusMouseSample/BusMouse.cpp
===================================================================
--- /trunk/src/VBox/ExtPacks/BusMouseSample/BusMouse.cpp	(revision 80530)
+++ /trunk/src/VBox/ExtPacks/BusMouseSample/BusMouse.cpp	(revision 80531)
@@ -826,4 +826,6 @@
 }
 
+# endif /* IN_RING3 */
+
 
 /**
@@ -832,57 +834,72 @@
 const PDMDEVREG g_DeviceBusMouse =
 {
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "busmouse",
-    /* szRCMod */
-    "VBoxDDRC.rc",
-    /* szR0Mod */
-    "VBoxDDR0.r0",
-    /* pszDescription */
-    "Microsoft Bus Mouse controller. "
-    "LUN #0 is the mouse connector.",
-    /* fFlags */
-    PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36
-    | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_INPUT,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(MouState),
-    /* pfnConstruct */
-    mouConstruct,
-    /* pfnDestruct */
-    NULL,
-    /* pfnRelocate */
-    mouRelocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    mouReset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    mouAttach,
-    /* pfnDetach */
-    mouDetach,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    NULL,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "busmouse",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_INPUT,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(MouState),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Microsoft Bus Mouse controller. LUN #0 is the mouse connector.",
+# if defined(IN_RING3)
+    /* .pszRCMod = */               "VBoxDDRC.rc",
+    /* .pszR0Mod = */               "VBoxDDR0.r0",
+    /* .pfnConstruct = */           mouConstruct,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnRelocate = */            mouRelocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               mouReset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              mouAttach,
+    /* .pfnDetach = */              mouDetach,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        NULL,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+# elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+# elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+# else
+#  error "Not in IN_RING3, IN_RING0 or IN_RC!"
+# endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
 };
 
-#ifdef VBOX_IN_EXTPACK_R3
+#if defined(VBOX_IN_EXTPACK_R3) && defined(IN_RING3)
 /**
  * @callback_method_impl{FNPDMVBOXDEVICESREGISTER}
@@ -899,7 +916,6 @@
     return pCallbacks->pfnRegister(pCallbacks, &g_DeviceBusMouse);
 }
-#endif /* VBOX_IN_EXTPACK_R3 */
-
-# endif /* IN_RING3 */
+#endif
+
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp	(revision 80530)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp	(revision 80531)
@@ -142,5 +142,5 @@
 static int                  supdrvLdrSetVMMR0EPs(PSUPDRVDEVEXT pDevExt, void *pvVMMR0, void *pvVMMR0EntryFast, void *pvVMMR0EntryEx);
 static void                 supdrvLdrUnsetVMMR0EPs(PSUPDRVDEVEXT pDevExt);
-static int                  supdrvLdrAddUsage(PSUPDRVSESSION pSession, PSUPDRVLDRIMAGE pImage);
+static int                  supdrvLdrAddUsage(PSUPDRVSESSION pSession, PSUPDRVLDRIMAGE pImage, bool fRing3Usage);
 static void                 supdrvLdrFree(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage);
 DECLINLINE(int)             supdrvLdrLock(PSUPDRVDEVEXT pDevExt);
@@ -207,4 +207,10 @@
     { "SUPR0GetVmxUsability",                   (void *)(uintptr_t)SUPR0GetVmxUsability },
     { "SUPR0GetRawModeUsability",               (void *)(uintptr_t)SUPR0GetRawModeUsability },
+    { "SUPR0LdrIsLockOwnerByMod",               (void *)(uintptr_t)SUPR0LdrIsLockOwnerByMod },
+    { "SUPR0LdrLock",                           (void *)(uintptr_t)SUPR0LdrLock },
+    { "SUPR0LdrUnlock",                         (void *)(uintptr_t)SUPR0LdrUnlock },
+    { "SUPR0LdrModByName",                      (void *)(uintptr_t)SUPR0LdrModByName },
+    { "SUPR0LdrModRelease",                     (void *)(uintptr_t)SUPR0LdrModRelease },
+    { "SUPR0LdrModRetain",                      (void *)(uintptr_t)SUPR0LdrModRetain },
     { "SUPR0LockMem",                           (void *)(uintptr_t)SUPR0LockMem },
     { "SUPR0LowAlloc",                          (void *)(uintptr_t)SUPR0LowAlloc },
@@ -593,4 +599,5 @@
                         pDevExt->pLdrInitImage  = NULL;
                         pDevExt->hLdrInitThread = NIL_RTNATIVETHREAD;
+                        pDevExt->hLdrTermThread = NIL_RTNATIVETHREAD;
                         pDevExt->u32Cookie      = BIRD;  /** @todo make this random? */
                         pDevExt->cbSession      = (uint32_t)cbSession;
@@ -1073,6 +1080,7 @@
             void           *pvFree = pUsage;
             PSUPDRVLDRIMAGE pImage = pUsage->pImage;
-            if (pImage->cUsage > pUsage->cUsage)
-                pImage->cUsage -= pUsage->cUsage;
+            uint32_t        cUsage = pUsage->cRing0Usage + pUsage->cRing3Usage;
+            if (pImage->cUsage > cUsage)
+                pImage->cUsage -= cUsage;
             else
                 supdrvLdrFree(pDevExt, pImage);
@@ -5062,5 +5070,5 @@
                 pReq->u.Out.fNeedsLoading = pImage->uState == SUP_IOCTL_LDR_OPEN;
                 pReq->u.Out.fNativeLoader = pImage->fNative;
-                supdrvLdrAddUsage(pSession, pImage);
+                supdrvLdrAddUsage(pSession, pImage, true /*fRing3Usage*/);
                 supdrvLdrUnlock(pDevExt);
                 SUPDRV_CHECK_SMAP_CHECK(pDevExt, RT_NOTHING);
@@ -5068,6 +5076,6 @@
             }
             supdrvLdrUnlock(pDevExt);
-            Log(("supdrvIOCtl_LdrOpen: To many existing references to '%s'!\n", pReq->u.In.szName));
-            return VERR_INTERNAL_ERROR_3; /** @todo add VERR_TOO_MANY_REFERENCES */
+            Log(("supdrvIOCtl_LdrOpen: Too many existing references to '%s'!\n", pReq->u.In.szName));
+            return VERR_TOO_MANY_REFERENCES;
         }
     }
@@ -5113,4 +5121,5 @@
     pImage->cUsage          = 1;
     pImage->pDevExt         = pDevExt;
+    pImage->uMagic          = SUPDRVLDRIMAGE_MAGIC;
     memcpy(pImage->szName, pReq->u.In.szName, cchName + 1);
 
@@ -5132,4 +5141,5 @@
     {
         supdrvLdrUnlock(pDevExt);
+        pImage->uMagic = SUPDRVLDRIMAGE_MAGIC_DEAD;
         RTMemFree(pImage);
         Log(("supdrvIOCtl_LdrOpen(%s): failed - %Rrc\n", pReq->u.In.szName, rc));
@@ -5144,5 +5154,5 @@
     pDevExt->pLdrImages     = pImage;
 
-    supdrvLdrAddUsage(pSession, pImage);
+    supdrvLdrAddUsage(pSession, pImage, true /*fRing3Usage*/);
 
     pReq->u.Out.pvImageBase   = pImage->pvImage;
@@ -5484,4 +5494,10 @@
         return VERR_INVALID_HANDLE;
     }
+    if (pUsage->cRing3Usage == 0)
+    {
+        supdrvLdrUnlock(pDevExt);
+        Log(("SUP_IOCTL_LDR_FREE: No ring-3 reference to the image!\n"));
+        return VERR_CALLER_NO_REFERENCE;
+    }
 
     /*
@@ -5490,5 +5506,5 @@
     rc = VINF_SUCCESS;
     pImage = pUsage->pImage;
-    if (pImage->cUsage <= 1 || pUsage->cUsage <= 1)
+    if (pImage->cUsage <= 1 || pUsage->cRing3Usage + pUsage->cRing0Usage <= 1)
     {
         /*
@@ -5541,8 +5557,5 @@
         }
         else
-        {
             Log(("supdrvIOCtl_LdrFree: Dangling objects in %p/%s!\n", pImage->pvImage, pImage->szName));
-            rc = VINF_SUCCESS; /** @todo BRANCH-2.1: remove this after branching. */
-        }
     }
     else
@@ -5552,5 +5565,5 @@
          */
         pImage->cUsage--;
-        pUsage->cUsage--;
+        pUsage->cRing3Usage--;
     }
 
@@ -5722,5 +5735,5 @@
                 rc = supdrvOSLdrQuerySymbol(pDevExt, pImage, pszSymbol, cbSymbol - 1, (void **)&pReq->u.Out.pfnSymbol);
                 if (RT_SUCCESS(rc))
-                    rc = supdrvLdrAddUsage(pSession, pImage);
+                    rc = supdrvLdrAddUsage(pSession, pImage, true /*fRing3Usage*/);
             }
             else
@@ -5738,5 +5751,5 @@
                          */
                         pReq->u.Out.pfnSymbol = (PFNRT)((uintptr_t)pImage->pvImage + (int32_t)paSyms[i].offSymbol);
-                        rc = supdrvLdrAddUsage(pSession, pImage);
+                        rc = supdrvLdrAddUsage(pSession, pImage, true /*fRing3Usage*/);
                         break;
                     }
@@ -5844,9 +5857,10 @@
  * @param   pSession    Session in question.
  * @param   pImage      Image which the session is using.
- */
-static int supdrvLdrAddUsage(PSUPDRVSESSION pSession, PSUPDRVLDRIMAGE pImage)
+ * @param   fRing3Usage Set if it's ring-3 usage, clear if ring-0.
+ */
+static int supdrvLdrAddUsage(PSUPDRVSESSION pSession, PSUPDRVLDRIMAGE pImage, bool fRing3Usage)
 {
     PSUPDRVLDRUSAGE pUsage;
-    LogFlow(("supdrvLdrAddUsage: pImage=%p\n", pImage));
+    LogFlow(("supdrvLdrAddUsage: pImage=%p %d\n", pImage, fRing3Usage));
 
     /*
@@ -5858,5 +5872,8 @@
         if (pUsage->pImage == pImage)
         {
-            pUsage->cUsage++;
+            if (fRing3Usage)
+                pUsage->cRing3Usage++;
+            else
+                pUsage->cRing0Usage++;
             return VINF_SUCCESS;
         }
@@ -5869,7 +5886,8 @@
     pUsage = (PSUPDRVLDRUSAGE)RTMemAlloc(sizeof(*pUsage));
     AssertReturn(pUsage, /*VERR_NO_MEMORY*/ VERR_INTERNAL_ERROR_5);
-    pUsage->cUsage = 1;
-    pUsage->pImage = pImage;
-    pUsage->pNext  = pSession->pLdrUsage;
+    pUsage->cRing3Usage = fRing3Usage ? 1 : 0;
+    pUsage->cRing0Usage = fRing3Usage ? 0 : 1;
+    pUsage->pImage      = pImage;
+    pUsage->pNext       = pSession->pLdrUsage;
     pSession->pLdrUsage = pUsage;
     return VINF_SUCCESS;
@@ -5940,5 +5958,7 @@
     {
         LogFlow(("supdrvIOCtl_LdrLoad: calling pfnModuleTerm=%p\n", pImage->pfnModuleTerm));
+        pDevExt->hLdrTermThread = RTThreadNativeSelf();
         pImage->pfnModuleTerm(pImage);
+        pDevExt->hLdrTermThread = NIL_RTNATIVETHREAD;
     }
 
@@ -5953,4 +5973,5 @@
 
     /* free the image */
+    pImage->uMagic  = SUPDRVLDRIMAGE_MAGIC_DEAD;
     pImage->cUsage  = 0;
     pImage->pDevExt = NULL;
@@ -5972,4 +5993,5 @@
  * @returns IPRT status code.
  * @param   pDevExt         The device extension.
+ * @note    Not recursive on all platforms yet.
  */
 DECLINLINE(int) supdrvLdrLock(PSUPDRVDEVEXT pDevExt)
@@ -5998,4 +6020,290 @@
     return RTSemFastMutexRelease(pDevExt->mtxLdr);
 #endif
+}
+
+
+/**
+ * Acquires the global loader lock.
+ *
+ * This can be useful when accessing structures being modified by the ModuleInit
+ * and ModuleTerm.  Use SUPR0LdrUnlock() to unlock.
+ *
+ * @returns VBox status code.
+ * @param   pSession        The session doing the locking.
+ *
+ * @note    Cannot be used during ModuleInit or ModuleTerm callbacks.
+ */
+SUPR0DECL(int) SUPR0LdrLock(PSUPDRVSESSION pSession)
+{
+    AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
+    return supdrvLdrLock(pSession->pDevExt);
+}
+
+
+/**
+ * Releases the global loader lock.
+ *
+ * Must correspond to a SUPR0LdrLock call!
+ *
+ * @returns VBox status code.
+ * @param   pSession        The session doing the locking.
+ *
+ * @note    Cannot be used during ModuleInit or ModuleTerm callbacks.
+ */
+SUPR0DECL(int) SUPR0LdrUnlock(PSUPDRVSESSION pSession)
+{
+    AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
+    return supdrvLdrUnlock(pSession->pDevExt);
+}
+
+
+/**
+ * For checking lock ownership in Assert() statements during ModuleInit and
+ * ModuleTerm.
+ *
+ * @returns Whether we own the loader lock or not.
+ * @param   hMod            The module in question.
+ * @param   fWantToHear     For hosts where it is difficult to know who owns the
+ *                          lock, this will be returned instead.
+ */
+SUPR0DECL(bool) SUPR0LdrIsLockOwnerByMod(void *hMod, bool fWantToHear)
+{
+    PSUPDRVDEVEXT   pDevExt;
+    RTNATIVETHREAD  hOwner;
+
+    PSUPDRVLDRIMAGE pImage = (PSUPDRVLDRIMAGE)hMod;
+    AssertPtrReturn(pImage, fWantToHear);
+    AssertReturn(pImage->uMagic == SUPDRVLDRIMAGE_MAGIC, fWantToHear);
+
+    pDevExt = pImage->pDevExt;
+    AssertPtrReturn(pDevExt, fWantToHear);
+
+    /*
+     * Expecting this to be called at init/term time only, so this will be sufficient.
+     */
+    hOwner = pDevExt->hLdrInitThread;
+    if (hOwner == NIL_RTNATIVETHREAD)
+        hOwner = pDevExt->hLdrTermThread;
+    if (hOwner != NIL_RTNATIVETHREAD)
+        return hOwner == RTThreadNativeSelf();
+
+    /*
+     * Neither of the two semaphore variants currently offers very good
+     * introspection, so we wing it for now.  This API is VBOX_STRICT only.
+     */
+#ifdef SUPDRV_USE_MUTEX_FOR_LDR
+    return RTSemMutexIsOwned(pDevExt->mtxLdr) && fWantToHear;
+#else
+    return fWantToHear;
+#endif
+}
+
+
+/**
+ * Locates and retains the given module for ring-0 usage.
+ *
+ * @returns VBox status code.
+ * @param   pSession        The session to associate the module reference with.
+ * @param   pszName         The module name (no path).
+ * @param   phMod           Where to return the module handle.  The module is
+ *                          referenced and a call to SUPR0LdrModRelease() is
+ *                          necessary when done with it.
+ */
+SUPR0DECL(int) SUPR0LdrModByName(PSUPDRVSESSION pSession, const char *pszName, void **phMod)
+{
+    int             rc;
+    size_t          cchName;
+    PSUPDRVDEVEXT   pDevExt;
+
+    /*
+     * Validate input.
+     */
+    AssertPtrReturn(phMod, VERR_INVALID_POINTER);
+    *phMod = NULL;
+    AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pszName, VERR_INVALID_POINTER);
+    cchName = strlen(pszName);
+    AssertReturn(cchName > 0, VERR_EMPTY_STRING);
+    AssertReturn(cchName < RT_SIZEOFMEMB(SUPDRVLDRIMAGE, szName), VERR_MODULE_NOT_FOUND);
+
+    /*
+     * Do the lookup.
+     */
+    pDevExt = pSession->pDevExt;
+    rc = supdrvLdrLock(pDevExt);
+    if (RT_SUCCESS(rc))
+    {
+        PSUPDRVLDRIMAGE pImage;
+        for (pImage = pDevExt->pLdrImages; pImage; pImage = pImage->pNext)
+        {
+            if (   pImage->szName[cchName] == '\0'
+                && !memcmp(pImage->szName, pszName, cchName))
+            {
+                /*
+                 * Check the state and make sure we don't overflow the reference counter before return it.
+                 */
+                uint32_t uState = pImage->uState;
+                if (uState == SUP_IOCTL_LDR_LOAD)
+                {
+                    if (RT_LIKELY(pImage->cUsage < UINT32_MAX / 2U))
+                    {
+                        pImage->cUsage++;
+                        supdrvLdrAddUsage(pSession, pImage, false /*fRing3Usage*/);
+                        *phMod = pImage;
+                        supdrvLdrUnlock(pDevExt);
+                        return VINF_SUCCESS;
+                    }
+                    supdrvLdrUnlock(pDevExt);
+                    Log(("SUPR0LdrModByName: Too many existing references to '%s'!\n", pszName));
+                    return VERR_TOO_MANY_REFERENCES;
+                }
+                supdrvLdrUnlock(pDevExt);
+                Log(("SUPR0LdrModByName: Module '%s' is not in the loaded state (%d)!\n", pszName, uState));
+                return VERR_INVALID_STATE;
+            }
+        }
+        supdrvLdrUnlock(pDevExt);
+        Log(("SUPR0LdrModByName: Module '%s' not found!\n", pszName));
+        rc = VERR_MODULE_NOT_FOUND;
+    }
+    return rc;
+}
+
+
+/**
+ * Retains a ring-0 module reference.
+ *
+ * Release reference when done by calling SUPR0LdrModRelease().
+ *
+ * @returns VBox status code.
+ * @param   pSession        The session to reference the module in.  A usage
+ *                          record is added if needed.
+ * @param   hMod            The handle to the module to retain.
+ */
+SUPR0DECL(int) SUPR0LdrModRetain(PSUPDRVSESSION pSession, void *hMod)
+{
+    PSUPDRVDEVEXT   pDevExt;
+    PSUPDRVLDRIMAGE pImage;
+    int             rc;
+
+    /* Validate input a little. */
+    AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
+    AssertPtrReturn(hMod, VERR_INVALID_HANDLE);
+    pImage = (PSUPDRVLDRIMAGE)hMod;
+    AssertReturn(pImage->uMagic == SUPDRVLDRIMAGE_MAGIC, VERR_INVALID_HANDLE);
+
+    /* Reference the module: */
+    pDevExt = pSession->pDevExt;
+    rc = supdrvLdrLock(pDevExt);
+    if (RT_SUCCESS(rc))
+    {
+        if (pImage->uMagic == SUPDRVLDRIMAGE_MAGIC)
+        {
+            if (RT_LIKELY(pImage->cUsage < UINT32_MAX / 2U))
+            {
+                rc = supdrvLdrAddUsage(pSession, pImage, false /*fRing3Usage*/);
+                if (RT_SUCCESS(rc))
+                {
+                    pImage->cUsage++;
+                    rc = VINF_SUCCESS;
+                }
+            }
+            else
+                AssertFailedStmt(rc = VERR_TOO_MANY_REFERENCES);
+        }
+        else
+            AssertFailedStmt(rc = VERR_INVALID_HANDLE);
+        supdrvLdrUnlock(pDevExt);
+    }
+    return rc;
+}
+
+
+/**
+ * Releases a ring-0 module reference retained by SUPR0LdrModByName() or
+ * SUPR0LdrModRetain().
+ *
+ * @returns VBox status code.
+ * @param   pSession            The session that the module was retained in.
+ * @param   hMod                The module handle.  NULL is silently ignored.
+ */
+SUPR0DECL(int) SUPR0LdrModRelease(PSUPDRVSESSION pSession, void *hMod)
+{
+    PSUPDRVDEVEXT   pDevExt;
+    PSUPDRVLDRIMAGE pImage;
+    int             rc;
+
+    /*
+     * Validate input.
+     */
+    AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
+    if (!hMod)
+        return VINF_SUCCESS;
+    AssertPtrReturn(hMod, VERR_INVALID_HANDLE);
+    pImage = (PSUPDRVLDRIMAGE)hMod;
+    AssertReturn(pImage->uMagic == SUPDRVLDRIMAGE_MAGIC, VERR_INVALID_HANDLE);
+
+    /*
+     * Take the loader lock and revalidate the module:
+     */
+    pDevExt = pSession->pDevExt;
+    rc = supdrvLdrLock(pDevExt);
+    if (RT_SUCCESS(rc))
+    {
+        if (pImage->uMagic == SUPDRVLDRIMAGE_MAGIC)
+        {
+            /*
+             * Find the usage record for the module:
+             */
+            PSUPDRVLDRUSAGE pPrevUsage = NULL;
+            PSUPDRVLDRUSAGE pUsage;
+
+            rc = VERR_MODULE_NOT_FOUND;
+            for (pUsage = pSession->pLdrUsage; pUsage; pUsage = pUsage->pNext)
+            {
+                if (pUsage->pImage == pImage)
+                {
+                    /*
+                     * Drop a ring-0 reference:
+                     */
+                    Assert(pImage->cUsage >= pUsage->cRing0Usage + pUsage->cRing3Usage);
+                    if (pUsage->cRing0Usage > 0)
+                    {
+                        if (pImage->cUsage > 1)
+                        {
+                            pImage->cUsage      -= 1;
+                            pUsage->cRing0Usage -= 1;
+                            rc = VINF_SUCCESS;
+                        }
+                        else
+                        {
+                            supdrvLdrFree(pDevExt, pImage);
+
+                            if (pPrevUsage)
+                                pPrevUsage->pNext = pUsage->pNext;
+                            else
+                                pSession->pLdrUsage = pUsage->pNext;
+                            pUsage->pNext       = NULL;
+                            pUsage->pImage      = NULL;
+                            pUsage->cRing0Usage = 0;
+                            pUsage->cRing3Usage = 0;
+                            RTMemFree(pUsage);
+
+                            rc = VINF_OBJECT_DESTROYED;
+                        }
+                    }
+                    else
+                        AssertFailedStmt(rc = VERR_CALLER_NO_REFERENCE);
+                    break;
+                }
+                pPrevUsage = pUsage;
+            }
+        }
+        else
+            AssertFailedStmt(rc = VERR_INVALID_HANDLE);
+        supdrvLdrUnlock(pDevExt);
+    }
+    return rc;
+
 }
 
Index: /trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h	(revision 80530)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h	(revision 80531)
@@ -331,4 +331,6 @@
      * member is NULL then). */
     void                           *pvImageAlloc;
+    /** Magic value (SUPDRVLDRIMAGE_MAGIC). */
+    uint32_t                        uMagic;
     /** Size of the image including the tables. This is mainly for verification
      * of the load request. */
@@ -384,4 +386,9 @@
 } SUPDRVLDRIMAGE, *PSUPDRVLDRIMAGE;
 
+/** Magic value for SUPDRVLDRIMAGE::uMagic (Charlotte Bronte). */
+#define SUPDRVLDRIMAGE_MAGIC        UINT32_C(0x18160421)
+/** Magic value for SUPDRVLDRIMAGE::uMagic when freed. */
+#define SUPDRVLDRIMAGE_MAGIC_DEAD   UINT32_C(0x18550331)
+
 
 /** Image usage record. */
@@ -392,6 +399,8 @@
     /** The image. */
     PSUPDRVLDRIMAGE                 pImage;
-    /** Load count. */
-    uint32_t volatile               cUsage;
+    /** Load count (ring-3). */
+    uint32_t volatile               cRing3Usage;
+    /** Ring-0 usage counter. */
+    uint32_t volatile               cRing0Usage;
 } SUPDRVLDRUSAGE, *PSUPDRVLDRUSAGE;
 
@@ -647,4 +656,6 @@
     /** The thread currently executing a ModuleInit function. */
     RTNATIVETHREAD volatile         hLdrInitThread;
+    /** The thread currently executing a ModuleTerm function. */
+    RTNATIVETHREAD volatile         hLdrTermThread;
     /** @} */
 
Index: /trunk/src/VBox/VMM/VMMAll/APICAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 80531)
@@ -3508,2 +3508,75 @@
 }
 
+
+/**
+ * APIC device registration structure.
+ */
+const PDMDEVREG g_DeviceAPIC =
+{
+    /* .u32Version = */             PDM_DEVREG_VERSION,
+    /* .uReserved0 = */             0,
+    /* .szName = */                 "apic",
+    /* .fFlags = */                 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_R0,
+    /* .fClass = */                 PDM_DEVREG_CLASS_PIC,
+    /* .cMaxInstances = */          1,
+    /* .uSharedVersion = */         42,
+    /* .cbInstanceShared = */       sizeof(APICDEV),
+    /* .cbInstanceCC = */           0,
+    /* .cbInstanceRC = */           0,
+    /* .uReserved1 = */             0,
+    /* .pszDescription = */         "Advanced Programmable Interrupt Controller",
+#if defined(IN_RING3)
+    /* .szRCMod = */                "VMMRC.rc",
+    /* .szR0Mod = */                "VMMR0.r0",
+    /* .pfnConstruct = */           apicR3Construct,
+    /* .pfnDestruct = */            apicR3Destruct,
+    /* .pfnRelocate = */            apicR3Relocate,
+    /* .pfnMemSetup = */            NULL,
+    /* .pfnPowerOn = */             NULL,
+    /* .pfnReset = */               apicR3Reset,
+    /* .pfnSuspend = */             NULL,
+    /* .pfnResume = */              NULL,
+    /* .pfnAttach = */              NULL,
+    /* .pfnDetach = */              NULL,
+    /* .pfnQueryInterface = */      NULL,
+    /* .pfnInitComplete = */        apicR3InitComplete,
+    /* .pfnPowerOff = */            NULL,
+    /* .pfnSoftReset = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RING0)
+    /* .pfnEarlyConstruct = */      NULL,
+    /* .pfnConstruct = */           NULL,
+    /* .pfnDestruct = */            NULL,
+    /* .pfnFinalDestruct = */       NULL,
+    /* .pfnRequest = */             NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#elif defined(IN_RC)
+    /* .pfnConstruct = */           NULL,
+    /* .pfnReserved0 = */           NULL,
+    /* .pfnReserved1 = */           NULL,
+    /* .pfnReserved2 = */           NULL,
+    /* .pfnReserved3 = */           NULL,
+    /* .pfnReserved4 = */           NULL,
+    /* .pfnReserved5 = */           NULL,
+    /* .pfnReserved6 = */           NULL,
+    /* .pfnReserved7 = */           NULL,
+#else
+# error "Not in IN_RING3, IN_RING0 or IN_RC!"
+#endif
+    /* .u32VersionEnd = */          PDM_DEVREG_VERSION
+};
+
Index: /trunk/src/VBox/VMM/VMMAll/AllPdbTypeHack.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/AllPdbTypeHack.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMAll/AllPdbTypeHack.cpp	(revision 80531)
@@ -94,5 +94,5 @@
          | pCs2->s.Core.fFlags
          | (pCs2 == g_PdbTypeHack4)
-         | g_PdbTypeHack5->Internal.s.fIntFlags
+         | g_PdbTypeHack5->Internal.s.idxR0Device
          | (g_PdbTypeHack5 != NULL)
          | (uint32_t)g_PdbTypeHack6->Internal.s.fDetaching
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp	(revision 80531)
@@ -160,8 +160,10 @@
                     ("Not RC pointer! pvUserRC=%RRv\n", pvUserRC),
                     VERR_INVALID_PARAMETER);
+#if 0 /* No longer valid. */
     AssertMsgReturn(    (RTR0UINTPTR)pvUserR0 < 0x10000
                     ||  MMHyperR3ToR0(pVM, MMHyperR0ToR3(pVM, pvUserR0)) == pvUserR0,
                     ("Not R0 pointer! pvUserR0=%RHv\n", pvUserR0),
                     VERR_INVALID_PARAMETER);
+#endif
 
     /*
Index: /trunk/src/VBox/VMM/VMMAll/TMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMAll/TMAll.cpp	(revision 80531)
@@ -32,4 +32,5 @@
 # endif
 #endif
+#include <VBox/vmm/pdmdev.h> /* (for TMTIMER_GET_CRITSECT implementation) */
 #include "TMInternal.h"
 #include <VBox/vmm/vmcc.h>
@@ -53,4 +54,20 @@
 *   Defined Constants And Macros                                                                                                 *
 *********************************************************************************************************************************/
+#ifdef VBOX_STRICT
+/** @def TMTIMER_GET_CRITSECT
+ * Helper for safely resolving the critical section for a timer belonging to a
+ * device instance.
+ * @todo needs reworking later as it uses PDMDEVINSR0::pDevInsR0RemoveMe.  */
+# ifdef IN_RING3
+#  define TMTIMER_GET_CRITSECT(pTimer) ((pTimer)->pCritSect)
+# else
+#  define TMTIMER_GET_CRITSECT(pTimer) \
+    (     (pTimer)->enmType == TMTIMERTYPE_DEV \
+       && (pTimer)->pCritSect == ((struct PDMDEVINSR3 *)(pTimer)->u.Dev.pDevIns)->pCritSectRoR3 \
+     ? ((struct PDMDEVINSR3 *)(pTimer)->u.Dev.pDevIns)->pDevInsR0RemoveMe->pCritSectRoR0 \
+     : (PPDMCRITSECT)MMHyperR3ToCC((pTimer)->CTX_SUFF(pVM), (pTimer)->pCritSect) )
+# endif
+#endif
+
 /** @def TMTIMER_ASSERT_CRITSECT
  * Checks that the caller owns the critical section if one is associated with
@@ -62,5 +79,5 @@
         { \
             VMSTATE      enmState; \
-            PPDMCRITSECT pCritSect = (PPDMCRITSECT)MMHyperR3ToCC((pTimer)->CTX_SUFF(pVM), (pTimer)->pCritSect); \
+            PPDMCRITSECT pCritSect = TMTIMER_GET_CRITSECT(pTimer); \
             AssertMsg(   pCritSect \
                       && (   PDMCritSectIsOwner(pCritSect) \
@@ -95,5 +112,5 @@
         { \
             VMSTATE      enmState; \
-            PPDMCRITSECT pCritSect = (PPDMCRITSECT)MMHyperR3ToCC(pVM, (pTimer)->pCritSect); \
+            PPDMCRITSECT pCritSect = TMTIMER_GET_CRITSECT(pTimer); \
             AssertMsg(   pCritSect \
                       && (   !PDMCritSectIsOwner(pCritSect) \
Index: /trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp	(revision 80531)
@@ -54,4 +54,5 @@
 #include <VBox/vmm/gmm.h>
 #include "GVMMR0Internal.h"
+#include <VBox/vmm/pdm.h>
 #include <VBox/vmm/vmcc.h>
 #include <VBox/vmm/vmcpuset.h>
@@ -901,4 +902,5 @@
                         gvmmR0InitPerVMData(pGVM, iHandle, cCpus, pSession);
                         GMMR0InitPerVMData(pGVM);
+                        PDMR0InitPerVMData(pGVM);
                         pGVM->gvmm.s.VMMemObj  = hVMMemObj;
 
@@ -1291,4 +1293,5 @@
     NEMR0CleanupVM(pGVM);
 #endif
+    PDMR0CleanupVM(pGVM);
 
     AssertCompile(NIL_RTTHREADCTXHOOK == (RTTHREADCTXHOOK)0); /* Depends on zero initialized memory working for NIL at the moment. */
Index: /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 80531)
@@ -24,17 +24,22 @@
 #include "PDMInternal.h"
 #include <VBox/vmm/pdm.h>
+#include <VBox/vmm/apic.h>
+#include <VBox/vmm/mm.h>
 #include <VBox/vmm/pgm.h>
-#include <VBox/vmm/mm.h>
-#include <VBox/vmm/vmcc.h>
 #include <VBox/vmm/gvm.h>
 #include <VBox/vmm/vmm.h>
 #include <VBox/vmm/hm.h>
-#include <VBox/vmm/apic.h>
+#include <VBox/vmm/vmcc.h>
 
 #include <VBox/log.h>
 #include <VBox/err.h>
 #include <VBox/vmm/gvmm.h>
+#include <VBox/sup.h>
 #include <iprt/asm.h>
 #include <iprt/assert.h>
+#include <iprt/ctype.h>
+#include <iprt/mem.h>
+#include <iprt/memobj.h>
+#include <iprt/process.h>
 #include <iprt/string.h>
 
@@ -56,4 +61,28 @@
 RT_C_DECLS_END
 
+/** List of PDMDEVMODREGR0 structures protected by the loader lock. */
+static RTLISTANCHOR g_PDMDevModList;
+
+
+/**
+ * Pointer to the ring-0 device registrations for VMMR0.
+ */
+static const PDMDEVREGR0 *g_apVMM0DevRegs[] =
+{
+    &g_DeviceAPIC,
+};
+
+/**
+ * Module device registration record for VMMR0.
+ */
+static PDMDEVMODREGR0 g_VBoxDDR0ModDevReg =
+{
+    /* .u32Version = */ PDM_DEVMODREGR0_VERSION,
+    /* .cDevRegs = */   RT_ELEMENTS(g_apVMM0DevRegs),
+    /* .papDevRegs = */ &g_apVMM0DevRegs[0],
+    /* .hMod = */       NULL,
+    /* .ListEntry = */  { NULL, NULL },
+};
+
 
 /*********************************************************************************************************************************
@@ -63,8 +92,120 @@
 
 
+/**
+ * Initializes the global ring-0 PDM data.
+ */
+VMMR0_INT_DECL(void) PDMR0Init(void *hMod)
+{
+    RTListInit(&g_PDMDevModList);
+    g_VBoxDDR0ModDevReg.hMod = hMod;
+    RTListAppend(&g_PDMDevModList, &g_VBoxDDR0ModDevReg.ListEntry);
+}
+
+
+/**
+ * Used by PDMR0CleanupVM to destroy a device instance.
+ *
+ * This is done during VM cleanup so that we're sure there are no active threads
+ * inside the device code.
+ *
+ * @param   pGVM        The global (ring-0) VM structure.
+ * @param   pDevIns     The device instance.
+ * @param   idxR0Device The device instance handle.
+ */
+static int pdmR0DeviceDestroy(PGVM pGVM, PPDMDEVINSR0 pDevIns, uint32_t idxR0Device)
+{
+    /*
+     * Assert sanity.
+     */
+    Assert(idxR0Device < pGVM->pdmr0.s.cDevInstances);
+    AssertPtrReturn(pDevIns, VERR_INVALID_HANDLE);
+    Assert(pDevIns->u32Version == PDM_DEVINSR0_VERSION);
+    Assert(pDevIns->Internal.s.idxR0Device == idxR0Device);
+
+    /*
+     * Call the final destructor if there is one.
+     */
+    if (pDevIns->pReg->pfnFinalDestruct)
+        pDevIns->pReg->pfnFinalDestruct(pDevIns);
+    pDevIns->u32Version = ~PDM_DEVINSR0_VERSION;
+
+    /*
+     * Remove the device from the instance table.
+     */
+    Assert(pGVM->pdmr0.s.apDevInstances[idxR0Device] == pDevIns);
+    pGVM->pdmr0.s.apDevInstances[idxR0Device] = NULL;
+    if (idxR0Device + 1 == pGVM->pdmr0.s.cDevInstances)
+        pGVM->pdmr0.s.cDevInstances = idxR0Device;
+
+    /*
+     * Free the ring-3 mapping and instance memory.
+     */
+    RTR0MEMOBJ hMemObj = pDevIns->Internal.s.hMapObj;
+    pDevIns->Internal.s.hMapObj = NIL_RTR0MEMOBJ;
+    RTR0MemObjFree(hMemObj, true);
+
+    hMemObj = pDevIns->Internal.s.hMemObj;
+    pDevIns->Internal.s.hMemObj = NIL_RTR0MEMOBJ;
+    RTR0MemObjFree(hMemObj, true);
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Initializes the per-VM data for the PDM.
+ *
+ * This is called from under the GVMM lock, so it only need to initialize the
+ * data so PDMR0CleanupVM and others will work smoothly.
+ *
+ * @param   pGVM    Pointer to the global VM structure.
+ */
+VMMR0_INT_DECL(void) PDMR0InitPerVMData(PGVM pGVM)
+{
+    AssertCompile(sizeof(pGVM->pdm.s) <= sizeof(pGVM->pdm.padding));
+    AssertCompile(sizeof(pGVM->pdmr0.s) <= sizeof(pGVM->pdmr0.padding));
+
+    pGVM->pdmr0.s.cDevInstances = 0;
+}
+
+
+/**
+ * Cleans up any loose ends before the GVM structure is destroyed.
+ */
+VMMR0_INT_DECL(void) PDMR0CleanupVM(PGVM pGVM)
+{
+    uint32_t i = pGVM->pdmr0.s.cDevInstances;
+    while (i-- > 0)
+    {
+        PPDMDEVINSR0 pDevIns = pGVM->pdmr0.s.apDevInstances[i];
+        if (pDevIns)
+            pdmR0DeviceDestroy(pGVM, pDevIns, i);
+    }
+}
+
 
 /** @name Ring-0 Device Helpers
  * @{
  */
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnIoPortSetUpContextEx} */
+static DECLCALLBACK(int) pdmR0DevHlp_IoPortSetUpContextEx(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
+                                                          PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
+                                                          PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr,
+                                                          void *pvUser)
+{
+    RT_NOREF(pDevIns, hIoPorts, pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser);
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnMmioSetUpContextEx} */
+static DECLCALLBACK(int) pdmR0DevHlp_MmioSetUpContextEx(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIOWRITE pfnWrite,
+                                                        PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill, void *pvUser)
+{
+    RT_NOREF(pDevIns, hRegion, pfnWrite, pfnRead, pfnFill, pvUser);
+    return VERR_NOT_IMPLEMENTED;
+}
+
 
 /** @interface_method_impl{PDMDEVHLPR0,pfnPCIPhysRead} */
@@ -132,5 +273,5 @@
     LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: pPciDev=%p:{%#x} iIrq=%d iLevel=%d\n",
              pDevIns, pDevIns->iInstance, pPciDev, pPciDev->uDevFn, iIrq, iLevel));
-    PGVM         pGVM    = pDevIns->Internal.s.pVMR0;
+    PGVM         pGVM    = pDevIns->Internal.s.pGVM;
     PPDMPCIBUS   pPciBus = pPciDev->Int.s.pPdmBusR0;
 
@@ -139,5 +280,5 @@
     if (iLevel & PDM_IRQ_LEVEL_HIGH)
     {
-        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->idTracing);
+        pDevIns->Internal.s.pIntR3R0->uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->Internal.s.pInsR3R0->idTracing);
         if (iLevel == PDM_IRQ_LEVEL_HIGH)
             VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
@@ -146,5 +287,5 @@
     }
     else
-        uTagSrc = pDevIns->Internal.s.uLastIrqTag;
+        uTagSrc = pDevIns->Internal.s.pIntR3R0->uLastIrqTag;
 
     if (    pPciBus
@@ -185,5 +326,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
-    PGVM pGVM = pDevIns->Internal.s.pVMR0;
+    PGVM pGVM = pDevIns->Internal.s.pGVM;
 
     pdmLock(pGVM);
@@ -191,5 +332,5 @@
     if (iLevel & PDM_IRQ_LEVEL_HIGH)
     {
-        pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->idTracing);
+        pDevIns->Internal.s.pIntR3R0->uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->Internal.s.pInsR3R0->idTracing);
         if (iLevel == PDM_IRQ_LEVEL_HIGH)
             VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
@@ -198,5 +339,5 @@
     }
     else
-        uTagSrc = pDevIns->Internal.s.uLastIrqTag;
+        uTagSrc = pDevIns->Internal.s.pIntR3R0->uLastIrqTag;
 
     bool fRc = pdmR0IsaSetIrq(pGVM, iIrq, iLevel, uTagSrc);
@@ -214,8 +355,8 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR0DevHlp_IoApicSendMsi: caller=%p/%d: GCPhys=%RGp uValue=%#x\n", pDevIns, pDevIns->iInstance, GCPhys, uValue));
-    PGVM pGVM = pDevIns->Internal.s.pVMR0;
+    PGVM pGVM = pDevIns->Internal.s.pGVM;
 
     uint32_t uTagSrc;
-    pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->idTracing);
+    pDevIns->Internal.s.pIntR3R0->uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->Internal.s.pInsR3R0->idTracing);
     VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
 
@@ -236,5 +377,5 @@
              pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
 
-    VBOXSTRICTRC rcStrict = PGMPhysRead(pDevIns->Internal.s.pVMR0, GCPhys, pvBuf, cbRead, PGMACCESSORIGIN_DEVICE);
+    VBOXSTRICTRC rcStrict = PGMPhysRead(pDevIns->Internal.s.pGVM, GCPhys, pvBuf, cbRead, PGMACCESSORIGIN_DEVICE);
     AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
 
@@ -251,5 +392,5 @@
              pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
 
-    VBOXSTRICTRC rcStrict = PGMPhysWrite(pDevIns->Internal.s.pVMR0, GCPhys, pvBuf, cbWrite, PGMACCESSORIGIN_DEVICE);
+    VBOXSTRICTRC rcStrict = PGMPhysWrite(pDevIns->Internal.s.pGVM, GCPhys, pvBuf, cbWrite, PGMACCESSORIGIN_DEVICE);
     AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
 
@@ -265,5 +406,5 @@
     LogFlow(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
 
-    bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu(pDevIns->Internal.s.pVMR0));
+    bool fEnabled = PGMPhysIsA20Enabled(VMMGetCpu(pDevIns->Internal.s.pGVM));
 
     Log(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
@@ -277,5 +418,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
 
-    VMSTATE enmVMState = pDevIns->Internal.s.pVMR0->enmVMState;
+    VMSTATE enmVMState = pDevIns->Internal.s.pGVM->enmVMState;
 
     LogFlow(("pdmR0DevHlp_VMState: caller=%p/%d: returns %d\n", pDevIns, pDevIns->iInstance, enmVMState));
@@ -290,5 +431,5 @@
     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);
+    int rc2 = VMSetErrorV(pDevIns->Internal.s.pGVM, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
     va_end(args);
     return rc;
@@ -300,5 +441,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMR0, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
+    int rc2 = VMSetErrorV(pDevIns->Internal.s.pGVM, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
     return rc;
 }
@@ -311,5 +452,5 @@
     va_list va;
     va_start(va, pszFormat);
-    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
+    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pGVM, fFlags, pszErrorId, pszFormat, va);
     va_end(va);
     return rc;
@@ -321,21 +462,8 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMR0, fFlags, pszErrorId, pszFormat, va);
+    int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pGVM, fFlags, pszErrorId, pszFormat, va);
     return rc;
 }
 
-
-/** @interface_method_impl{PDMDEVHLPR0,pfnPATMSetMMIOPatchInfo} */
-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();
-    NOREF(GCPhys); NOREF(pCachedData); NOREF(pDevIns);
-
-/*    return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMR0, GCPhys, pCachedData); */
-    return VINF_SUCCESS;
-}
 
 
@@ -345,5 +473,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return pDevIns->Internal.s.pVMR0;
+    return pDevIns->Internal.s.pGVM;
 }
 
@@ -354,5 +482,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR0DevHlp_GetVMCPU: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return VMMGetCpu(pDevIns->Internal.s.pVMR0);
+    return VMMGetCpu(pDevIns->Internal.s.pGVM);
 }
 
@@ -362,5 +490,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    VMCPUID idCpu = VMMGetCpuId(pDevIns->Internal.s.pVMR0);
+    VMCPUID idCpu = VMMGetCpuId(pDevIns->Internal.s.pGVM);
     LogFlow(("pdmR0DevHlp_GetCurrentCpuId: caller='%p'/%d for CPU %u\n", pDevIns, pDevIns->iInstance, idCpu));
     return idCpu;
@@ -368,4 +496,131 @@
 
 
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerToPtr} */
+static DECLCALLBACK(PTMTIMERR0) pdmR0DevHlp_TimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    RT_NOREF(pDevIns);
+    return (PTMTIMERR0)MMHyperR3ToCC(pDevIns->Internal.s.pGVM, hTimer);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerFromMicro} */
+static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerFromMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
+{
+    return TMTimerFromMicro(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMicroSecs);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerFromMilli} */
+static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerFromMilli(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs)
+{
+    return TMTimerFromMilli(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMilliSecs);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerFromNano} */
+static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerFromNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
+{
+    return TMTimerFromNano(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cNanoSecs);
+}
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerGet} */
+static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerGet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerGet(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerGetFreq} */
+static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerGetFreq(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerGetFreq(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerGetNano} */
+static DECLCALLBACK(uint64_t) pdmR0DevHlp_TimerGetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerGetNano(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerIsActive} */
+static DECLCALLBACK(bool) pdmR0DevHlp_TimerIsActive(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerIsActive(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerIsLockOwner} */
+static DECLCALLBACK(bool) pdmR0DevHlp_TimerIsLockOwner(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerIsLockOwner(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerLock} */
+static DECLCALLBACK(int) pdmR0DevHlp_TimerLock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy)
+{
+    return TMTimerLock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), rcBusy);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerSet} */
+static DECLCALLBACK(int) pdmR0DevHlp_TimerSet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire)
+{
+    return TMTimerSet(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), uExpire);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerSetFrequencyHint} */
+static DECLCALLBACK(int) pdmR0DevHlp_TimerSetFrequencyHint(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz)
+{
+    return TMTimerSetFrequencyHint(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), uHz);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerSetMicro} */
+static DECLCALLBACK(int) pdmR0DevHlp_TimerSetMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
+{
+    return TMTimerSetMicro(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMicrosToNext);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerSetMillies} */
+static DECLCALLBACK(int) pdmR0DevHlp_TimerSetMillies(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext)
+{
+    return TMTimerSetMillies(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cMilliesToNext);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerSetNano} */
+static DECLCALLBACK(int) pdmR0DevHlp_TimerSetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
+{
+    return TMTimerSetNano(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cNanosToNext);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerSetRelative} */
+static DECLCALLBACK(int) pdmR0DevHlp_TimerSetRelative(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
+{
+    return TMTimerSetRelative(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer), cTicksToNext, pu64Now);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerStop} */
+static DECLCALLBACK(int) pdmR0DevHlp_TimerStop(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerStop(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnTimerUnlock} */
+static DECLCALLBACK(void) pdmR0DevHlp_TimerUnlock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    TMTimerUnlock(pdmR0DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
 /** @interface_method_impl{PDMDEVHLPR0,pfnTMTimeVirtGet} */
 static DECLCALLBACK(uint64_t) pdmR0DevHlp_TMTimeVirtGet(PPDMDEVINS pDevIns)
@@ -373,5 +628,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR0DevHlp_TMTimeVirtGet: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return TMVirtualGet(pDevIns->Internal.s.pVMR0);
+    return TMVirtualGet(pDevIns->Internal.s.pGVM);
 }
 
@@ -382,5 +637,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR0DevHlp_TMTimeVirtGetFreq: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return TMVirtualGetFreq(pDevIns->Internal.s.pVMR0);
+    return TMVirtualGetFreq(pDevIns->Internal.s.pGVM);
 }
 
@@ -391,7 +646,47 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     LogFlow(("pdmR0DevHlp_TMTimeVirtGetNano: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));
-    return TMVirtualToNano(pDevIns->Internal.s.pVMR0, TMVirtualGet(pDevIns->Internal.s.pVMR0));
-}
-
+    return TMVirtualToNano(pDevIns->Internal.s.pGVM, TMVirtualGet(pDevIns->Internal.s.pGVM));
+}
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnCritSectGetNop} */
+static DECLCALLBACK(PPDMCRITSECT) pdmR0DevHlp_CritSectGetNop(PPDMDEVINS pDevIns)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PGVM pGVM = pDevIns->Internal.s.pGVM;
+
+    PPDMCRITSECT pCritSect = &pGVM->pdm.s.NopCritSect;
+    LogFlow(("pdmR0DevHlp_CritSectGetNop: caller='%s'/%d: return %p\n", pDevIns->pReg->szName, pDevIns->iInstance, pCritSect));
+    return pCritSect;
+}
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnSetDeviceCritSect} */
+static DECLCALLBACK(int) pdmR0DevHlp_SetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
+{
+    /*
+     * Validate input.
+     *
+     * Note! We only allow the automatically created default critical section
+     *       to be replaced by this API.
+     */
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    AssertPtrReturn(pCritSect, VERR_INVALID_POINTER);
+    LogFlow(("pdmR0DevHlp_SetDeviceCritSect: caller='%s'/%d: pCritSect=%p (%s)\n",
+             pDevIns->pReg->szName, pDevIns->iInstance, pCritSect, pCritSect->s.pszName));
+    AssertReturn(PDMCritSectIsInitialized(pCritSect), VERR_INVALID_PARAMETER);
+    PGVM pGVM = pDevIns->Internal.s.pGVM;
+    AssertReturn(pCritSect->s.pVMR0 == pGVM, VERR_INVALID_PARAMETER);
+
+    VM_ASSERT_EMT(pGVM);
+    VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
+
+    /*
+     * Check that ring-3 has already done this, then effect the change.
+     */
+    AssertReturn(pDevIns->pDevInsForR3R0->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_CHANGED_CRITSECT, VERR_WRONG_ORDER);
+    pDevIns->pCritSectRoR0 = pCritSect;
+
+    LogFlow(("pdmR0DevHlp_SetDeviceCritSect: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
+    return VINF_SUCCESS;
+}
 
 /** @interface_method_impl{PDMDEVHLPR0,pfnDBGFTraceBuf} */
@@ -399,5 +694,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    RTTRACEBUF hTraceBuf = pDevIns->Internal.s.pVMR0->hTraceBufR0;
+    RTTRACEBUF hTraceBuf = pDevIns->Internal.s.pGVM->hTraceBufR0;
     LogFlow(("pdmR3DevHlp_DBGFTraceBuf: caller='%p'/%d: returns %p\n", pDevIns, pDevIns->iInstance, hTraceBuf));
     return hTraceBuf;
@@ -411,4 +706,6 @@
 {
     PDM_DEVHLPR0_VERSION,
+    pdmR0DevHlp_IoPortSetUpContextEx,
+    pdmR0DevHlp_MmioSetUpContextEx,
     pdmR0DevHlp_PCIPhysRead,
     pdmR0DevHlp_PCIPhysWrite,
@@ -424,22 +721,50 @@
     pdmR0DevHlp_VMSetRuntimeError,
     pdmR0DevHlp_VMSetRuntimeErrorV,
-    pdmR0DevHlp_PATMSetMMIOPatchInfo,
     pdmR0DevHlp_GetVM,
     pdmR0DevHlp_GetVMCPU,
     pdmR0DevHlp_GetCurrentCpuId,
+    pdmR0DevHlp_TimerToPtr,
+    pdmR0DevHlp_TimerFromMicro,
+    pdmR0DevHlp_TimerFromMilli,
+    pdmR0DevHlp_TimerFromNano,
+    pdmR0DevHlp_TimerGet,
+    pdmR0DevHlp_TimerGetFreq,
+    pdmR0DevHlp_TimerGetNano,
+    pdmR0DevHlp_TimerIsActive,
+    pdmR0DevHlp_TimerIsLockOwner,
+    pdmR0DevHlp_TimerLock,
+    pdmR0DevHlp_TimerSet,
+    pdmR0DevHlp_TimerSetFrequencyHint,
+    pdmR0DevHlp_TimerSetMicro,
+    pdmR0DevHlp_TimerSetMillies,
+    pdmR0DevHlp_TimerSetNano,
+    pdmR0DevHlp_TimerSetRelative,
+    pdmR0DevHlp_TimerStop,
+    pdmR0DevHlp_TimerUnlock,
     pdmR0DevHlp_TMTimeVirtGet,
     pdmR0DevHlp_TMTimeVirtGetFreq,
     pdmR0DevHlp_TMTimeVirtGetNano,
+    pdmR0DevHlp_CritSectGetNop,
+    pdmR0DevHlp_SetDeviceCritSect,
+    PDMCritSectEnter,
+    PDMCritSectEnterDebug,
+    PDMCritSectTryEnter,
+    PDMCritSectTryEnterDebug,
+    PDMCritSectLeave,
+    PDMCritSectIsOwner,
+    PDMCritSectIsInitialized,
+    PDMCritSectHasWaiters,
+    PDMCritSectGetRecursion,
     pdmR0DevHlp_DBGFTraceBuf,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
+    NULL /*pfnReserved1*/,
+    NULL /*pfnReserved2*/,
+    NULL /*pfnReserved3*/,
+    NULL /*pfnReserved4*/,
+    NULL /*pfnReserved5*/,
+    NULL /*pfnReserved6*/,
+    NULL /*pfnReserved7*/,
+    NULL /*pfnReserved8*/,
+    NULL /*pfnReserved9*/,
+    NULL /*pfnReserved10*/,
     PDM_DEVHLPR0_VERSION
 };
@@ -458,5 +783,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    PGVM     pGVM  = (PGVM)pDevIns->Internal.s.pVMR0;
+    PGVM     pGVM  = (PGVM)pDevIns->Internal.s.pGVM;
     PVMCPUCC pVCpu = &pGVM->aCpus[0];     /* for PIC we always deliver to CPU 0, MP use APIC */
     /** @todo r=ramshankar: Propagating rcRZ and make all callers handle it? */
@@ -469,5 +794,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    PGVM     pGVM  = (PGVM)pDevIns->Internal.s.pVMR0;
+    PGVM     pGVM  = (PGVM)pDevIns->Internal.s.pGVM;
     PVMCPUCC pVCpu = &pGVM->aCpus[0];     /* for PIC we always deliver to CPU 0, MP use APIC */
     /** @todo r=ramshankar: Propagating rcRZ and make all callers handle it? */
@@ -480,5 +805,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
+    return pdmLockEx(pDevIns->Internal.s.pGVM, rc);
 }
 
@@ -488,5 +813,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMR0);
+    pdmUnlock(pDevIns->Internal.s.pGVM);
 }
 
@@ -518,5 +843,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    PGVM pGVM = pDevIns->Internal.s.pVMR0;
+    PGVM pGVM = pDevIns->Internal.s.pGVM;
     LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 uVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
              pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc));
@@ -529,5 +854,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
+    return pdmLockEx(pDevIns->Internal.s.pGVM, rc);
 }
 
@@ -537,5 +862,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMR0);
+    pdmUnlock(pDevIns->Internal.s.pGVM);
 }
 
@@ -567,5 +892,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
-    PGVM pGVM = pDevIns->Internal.s.pVMR0;
+    PGVM pGVM = pDevIns->Internal.s.pGVM;
 
     pdmLock(pGVM);
@@ -580,5 +905,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     Log4(("pdmR0PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
-    PGVM pGVM = pDevIns->Internal.s.pVMR0;
+    PGVM pGVM = pDevIns->Internal.s.pGVM;
 
     if (pGVM->pdm.s.IoApic.pDevInsR0)
@@ -609,5 +934,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     Log4(("pdmR0PciHlp_IoApicSendMsi: GCPhys=%p uValue=%d uTagSrc=%#x\n", GCPhys, uValue, uTagSrc));
-    PGVM pGVM = pDevIns->Internal.s.pVMR0;
+    PGVM pGVM = pDevIns->Internal.s.pGVM;
     if (pGVM->pdm.s.IoApic.pDevInsR0)
         pGVM->pdm.s.IoApic.pfnSendMsiR0(pGVM->pdm.s.IoApic.pDevInsR0, GCPhys, uValue, uTagSrc);
@@ -621,5 +946,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    return pdmLockEx(pDevIns->Internal.s.pVMR0, rc);
+    return pdmLockEx(pDevIns->Internal.s.pGVM, rc);
 }
 
@@ -629,5 +954,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    pdmUnlock(pDevIns->Internal.s.pVMR0);
+    pdmUnlock(pDevIns->Internal.s.pGVM);
 }
 
@@ -840,5 +1165,5 @@
         PPDMDEVINS pDevIns = pReq->pDevInsR0;
         AssertPtrReturn(pDevIns, VERR_INVALID_POINTER);
-        AssertReturn(pDevIns->Internal.s.pVMR0 == pGVM, VERR_INVALID_PARAMETER);
+        AssertReturn(pDevIns->Internal.s.pGVM == pGVM, VERR_INVALID_PARAMETER);
 
         PFNPDMDEVREQHANDLERR0 pfnReqHandlerR0 = pReq->pfnReqHandlerR0;
@@ -850,2 +1175,614 @@
 }
 
+
+/**
+ * Worker for PDMR0DeviceCreate that does the actual instantiation.
+ *
+ * Allocates a memory object and devides it up as follows:
+ * @verbatim
+ *   ----------------------
+ *   ring-0 devins
+ *   ----------------------
+ *   ring-0 instance data
+ *   ----------------------
+ *   page alignment padding
+ *   ----------------------
+ *   ring-3 devins
+ *   ----------------------
+ *   ring-3 instance data
+ *   ----------------------
+ *  [page alignment padding] -
+ *  [----------------------]  \
+ *  [raw-mode devins       ]   - Optional, only when raw-mode is enabled.
+ *  [----------------------]  /
+ *  [raw-mode instance data] -
+ *   ----------------------
+ *   shared instance data
+ *   ----------------------
+ *   default crit section
+ *   ----------------------
+ * @endverbatim
+ *
+ * @returns VBox status code.
+ * @param   pGVM            The global (ring-0) VM structure.
+ * @param   pDevReg         The device registration structure.
+ * @param   iInstance       The device instance number.
+ * @param   cbInstanceR3    The size of the ring-3 instance data.
+ * @param   cbInstanceRC    The size of the raw-mode instance data.
+ * @param   hMod            The module implementing the device.  On success, the
+ * @param   RCPtrMapping    The raw-mode context mapping address, NIL_RTGCPTR if
+ *                          not to include raw-mode.
+ * @param   ppDevInsR3      Where to return the ring-3 device instance address.
+ * @thread  EMT(0)
+ */
+static int pdmR0DeviceCreateWorker(PGVM pGVM, PCPDMDEVREGR0 pDevReg, uint32_t iInstance, uint32_t cbInstanceR3,
+                                   uint32_t cbInstanceRC, RTRGPTR RCPtrMapping, void *hMod, PPDMDEVINSR3 *ppDevInsR3)
+{
+    /*
+     * Check that the instance number isn't a duplicate.
+     */
+    for (size_t i = 0; i < pGVM->pdmr0.s.cDevInstances; i++)
+    {
+        PPDMDEVINS pCur = pGVM->pdmr0.s.apDevInstances[i];
+        AssertLogRelReturn(!pCur || pCur->pReg != pDevReg || pCur->iInstance != iInstance, VERR_DUPLICATE);
+    }
+
+    /*
+     * Figure out how much memory we need and allocate it.
+     */
+    uint32_t const cbRing0  = RT_ALIGN_32(RT_UOFFSETOF(PDMDEVINSR0, achInstanceData) + pDevReg->cbInstanceCC, PAGE_SIZE);
+    uint32_t const cbRing3  = RT_ALIGN_32(RT_UOFFSETOF(PDMDEVINSR3, achInstanceData) + cbInstanceR3,
+                                          RCPtrMapping != NIL_RTRGPTR ? PAGE_SIZE : 64);
+    uint32_t const cbRC     = RCPtrMapping != NIL_RTRGPTR ? 0
+                            : RT_ALIGN_32(RT_UOFFSETOF(PDMDEVINSRC, achInstanceData) + cbInstanceRC, 64);
+    uint32_t const cbShared = RT_ALIGN_32(pDevReg->cbInstanceShared, 64);
+    uint32_t const cbTotal  = RT_ALIGN_32(cbRing0 + cbRing3 + cbRC + cbShared + sizeof(PDMCRITSECT), PAGE_SIZE);
+
+    RTR0MEMOBJ hMemObj;
+    int rc = RTR0MemObjAllocPage(&hMemObj, cbTotal, false /*fExecutable*/);
+    if (RT_FAILURE(rc))
+        return rc;
+    RT_BZERO(RTR0MemObjAddress(hMemObj), cbTotal);
+
+    /* Map it. */
+    RTR0MEMOBJ hMapObj;
+    rc = RTR0MemObjMapUserEx(&hMapObj, hMemObj, (RTR3PTR)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, RTR0ProcHandleSelf(),
+                             cbRing0, cbTotal - cbRing0);
+    if (RT_SUCCESS(rc))
+    {
+        PPDMDEVINSR0        pDevIns   = (PPDMDEVINSR0)RTR0MemObjAddress(hMemObj);
+        struct PDMDEVINSR3 *pDevInsR3 = (struct PDMDEVINSR3 *)((uint8_t *)pDevIns + cbRing0);
+
+        /*
+         * Initialize the ring-0 instance.
+         */
+        pDevIns->u32Version             = PDM_DEVINSR0_VERSION;
+        pDevIns->iInstance              = iInstance;
+        pDevIns->pHlpR0                 = &g_pdmR0DevHlp;
+        pDevIns->pvInstanceDataR0       = (uint8_t *)pDevIns + cbRing0 + cbRing3 + cbRC;
+        pDevIns->pvInstanceDataForR0    = &pDevIns->achInstanceData[0];
+        pDevIns->pCritSectRoR0          = (PPDMCRITSECT)(  (uint8_t *)pDevIns->pvInstanceDataR0
+                                                         + RT_ALIGN_32(pDevReg->cbInstanceShared, 64));
+        pDevIns->pReg                   = pDevReg;
+        pDevIns->pDevInsForR3           = RTR0MemObjAddressR3(hMapObj);
+        pDevIns->pDevInsForR3R0         = pDevInsR3;
+        pDevIns->pvInstanceDataForR3R0  = &pDevInsR3->achInstanceData[0];
+        pDevIns->Internal.s.pGVM        = pGVM;
+        pDevIns->Internal.s.pRegR0      = pDevReg;
+        pDevIns->Internal.s.hMod        = hMod;
+        pDevIns->Internal.s.hMemObj     = hMemObj;
+        pDevIns->Internal.s.hMapObj     = hMapObj;
+        pDevIns->Internal.s.pInsR3R0    = pDevInsR3;
+        pDevIns->Internal.s.pIntR3R0    = &pDevInsR3->Internal.s;
+
+        /*
+         * Initialize the ring-3 instance data as much as we can.
+         */
+        pDevInsR3->u32Version           = PDM_DEVINSR3_VERSION;
+        pDevInsR3->iInstance            = iInstance;
+        pDevInsR3->cbRing3              = cbTotal - cbRing0;
+        pDevInsR3->fR0Enabled           = true;
+        pDevInsR3->fRCEnabled           = RCPtrMapping != NIL_RTRGPTR;
+        pDevInsR3->pvInstanceDataR3     = pDevIns->pDevInsForR3 + cbRing3 + cbRC;
+        pDevInsR3->pvInstanceDataForR3  = pDevIns->pDevInsForR3 + RT_UOFFSETOF(PDMDEVINSR3, achInstanceData);
+        pDevInsR3->pCritSectRoR3        = pDevIns->pDevInsForR3 + cbRing3 + cbRC + cbShared;
+        pDevInsR3->pDevInsR0RemoveMe    = pDevIns;
+        pDevInsR3->pvInstanceDataR0     = pDevIns->pvInstanceDataR0;
+        pDevInsR3->pvInstanceDataRC     = RCPtrMapping == NIL_RTRGPTR
+                                        ? NIL_RTRGPTR : pDevIns->pDevInsForRC + RT_UOFFSETOF(PDMDEVINSRC, achInstanceData);
+        pDevInsR3->pDevInsForRC         = pDevIns->pDevInsForRC;
+        pDevInsR3->pDevInsForRCR3       = pDevIns->pDevInsForR3 + cbRing3;
+        pDevInsR3->pDevInsForRCR3       = pDevInsR3->pDevInsForRCR3 + RT_UOFFSETOF(PDMDEVINSRC, achInstanceData);
+
+        pDevInsR3->Internal.s.pVMR3     = pGVM->pVMR3;
+        pDevInsR3->Internal.s.fIntFlags = RCPtrMapping == NIL_RTRGPTR ? PDMDEVINSINT_FLAGS_R0_ENABLED
+                                        : PDMDEVINSINT_FLAGS_R0_ENABLED | PDMDEVINSINT_FLAGS_RC_ENABLED;
+
+        /*
+         * Initialize the raw-mode instance data as much as possible.
+         */
+        if (RCPtrMapping != NIL_RTRGPTR)
+        {
+            struct PDMDEVINSRC *pDevInsRC = RCPtrMapping == NIL_RTRGPTR ? NULL
+                                          : (struct PDMDEVINSRC *)((uint8_t *)pDevIns + cbRing0 + cbRing3);
+
+            pDevIns->pDevInsForRC           = RCPtrMapping;
+            pDevIns->pDevInsForRCR0         = pDevInsRC;
+            pDevIns->pvInstanceDataForRCR0  = &pDevInsRC->achInstanceData[0];
+
+            pDevInsRC->u32Version           = PDM_DEVINSRC_VERSION;
+            pDevInsRC->iInstance            = iInstance;
+            pDevInsRC->pvInstanceDataRC     = pDevIns->pDevInsForRC + cbRC;
+            pDevInsRC->pvInstanceDataForRC  = pDevIns->pDevInsForRC + RT_UOFFSETOF(PDMDEVINSRC, achInstanceData);
+            pDevInsRC->pCritSectRoRC        = pDevIns->pDevInsForRC + cbRC + cbShared;
+            pDevInsRC->Internal.s.pVMRC     = pGVM->pVMRC;
+        }
+
+        /*
+         * Add to the device instance array and set its handle value.
+         */
+        AssertCompile(sizeof(pGVM->pdmr0.padding) == sizeof(pGVM->pdmr0));
+        uint32_t idxR0Device = pGVM->pdmr0.s.cDevInstances;
+        if (idxR0Device < RT_ELEMENTS(pGVM->pdmr0.s.apDevInstances))
+        {
+            pGVM->pdmr0.s.apDevInstances[idxR0Device] = pDevIns;
+            pGVM->pdmr0.s.cDevInstances = idxR0Device + 1;
+            pDevIns->Internal.s.idxR0Device   = idxR0Device;
+            pDevInsR3->Internal.s.idxR0Device = idxR0Device;
+
+            /*
+             * Call the early constructor if present.
+             */
+            if (pDevReg->pfnEarlyConstruct)
+                rc = pDevReg->pfnEarlyConstruct(pDevIns);
+            if (RT_SUCCESS(rc))
+            {
+                /*
+                 * We're done.
+                 */
+                *ppDevInsR3 = RTR0MemObjAddressR3(hMapObj);
+                return rc;
+            }
+
+            /*
+             * Bail out.
+             */
+            if (pDevIns->pReg->pfnFinalDestruct)
+                pDevIns->pReg->pfnFinalDestruct(pDevIns);
+
+            pGVM->pdmr0.s.apDevInstances[idxR0Device] = NULL;
+            Assert(pGVM->pdmr0.s.cDevInstances == idxR0Device + 1);
+            pGVM->pdmr0.s.cDevInstances = idxR0Device;
+        }
+
+        RTR0MemObjFree(hMapObj, true);
+    }
+    RTR0MemObjFree(hMemObj, true);
+    return rc;
+}
+
+
+/**
+ * Used by ring-3 PDM to create a device instance that operates both in ring-3
+ * and ring-0.
+ *
+ * Creates an instance of a device (for both ring-3 and ring-0, and optionally
+ * raw-mode context).
+ *
+ * @returns VBox status code.
+ * @param   pGVM    The global (ring-0) VM structure.
+ * @param   pReq    Pointer to the request buffer.
+ * @thread  EMT(0)
+ */
+VMMR0_INT_DECL(int) PDMR0DeviceCreateReqHandler(PGVM pGVM, PPDMDEVICECREATEREQ pReq)
+{
+    LogFlow(("PDMR0DeviceCreateReqHandler: %s in %s\n", pReq->szDevName, pReq->szModName));
+
+    /*
+     * Validate the request.
+     */
+    AssertReturn(pReq->Hdr.cbReq == sizeof(*pReq), VERR_INVALID_PARAMETER);
+    pReq->pDevInsR3 = NIL_RTR3PTR;
+
+    int rc = GVMMR0ValidateGVMandEMT(pGVM, 0);
+    AssertRCReturn(rc, rc);
+
+    AssertReturn(pReq->fFlags           != 0, VERR_INVALID_FLAGS);
+    AssertReturn(pReq->fClass           != 0, VERR_WRONG_TYPE);
+    AssertReturn(pReq->uSharedVersion   != 0, VERR_INVALID_PARAMETER);
+    AssertReturn(pReq->cbInstanceShared != 0, VERR_INVALID_PARAMETER);
+    size_t const cchDevName = RTStrNLen(pReq->szDevName, sizeof(pReq->szDevName));
+    AssertReturn(cchDevName < sizeof(pReq->szDevName), VERR_NO_STRING_TERMINATOR);
+    AssertReturn(cchDevName > 0, VERR_EMPTY_STRING);
+    AssertReturn(cchDevName < RT_SIZEOFMEMB(PDMDEVREG, szName), VERR_NOT_FOUND);
+
+    size_t const cchModName = RTStrNLen(pReq->szModName, sizeof(pReq->szModName));
+    AssertReturn(cchModName < sizeof(pReq->szModName), VERR_NO_STRING_TERMINATOR);
+    AssertReturn(cchModName > 0, VERR_EMPTY_STRING);
+    AssertReturn(pReq->cbInstanceR3 <= _2M, VERR_OUT_OF_RANGE);
+    AssertReturn(pReq->cbInstanceRC <= _512K, VERR_OUT_OF_RANGE);
+    AssertReturn(pReq->iInstance < 1024, VERR_OUT_OF_RANGE);
+
+    /*
+     * Reference the module.
+     */
+    void *hMod = NULL;
+    rc = SUPR0LdrModByName(pGVM->pSession, pReq->szModName, &hMod);
+    if (RT_FAILURE(rc))
+    {
+        LogRel(("PDMR0DeviceCreateReqHandler: SUPR0LdrModByName(,%s,) failed: %Rrc\n", pReq->szModName, rc));
+        return rc;
+    }
+
+    /*
+     * Look for the the module and the device registration structure.
+     */
+    int rcLock = SUPR0LdrLock(pGVM->pSession);
+    AssertRC(rc);
+
+    rc = VERR_NOT_FOUND;
+    PPDMDEVMODREGR0 pMod;
+    RTListForEach(&g_PDMDevModList, pMod, PDMDEVMODREGR0, ListEntry)
+    {
+        if (pMod->hMod == hMod)
+        {
+            /*
+             * Found the module. We can drop the loader lock now before we
+             * search the devices it registers.
+             */
+            if (RT_SUCCESS(rcLock))
+            {
+                rcLock = SUPR0LdrUnlock(pGVM->pSession);
+                AssertRC(rcLock);
+            }
+            rcLock = VERR_ALREADY_RESET;
+
+            PCPDMDEVREGR0 *papDevRegs = pMod->papDevRegs;
+            size_t         i          = pMod->cDevRegs;
+            while (i-- > 0)
+            {
+                PCPDMDEVREGR0 pDevReg = papDevRegs[i];
+                LogFlow(("PDMR0DeviceCreateReqHandler: candidate #%u: %s %#x\n", i, pReq->szDevName, pDevReg->u32Version));
+                if (   PDM_VERSION_ARE_COMPATIBLE(pDevReg->u32Version, PDM_DEVREGR0_VERSION)
+                    && pDevReg->szName[cchDevName] == '\0'
+                    && memcmp(pDevReg->szName, pReq->szDevName, cchDevName) == 0)
+                {
+
+                    /*
+                     * Found the device, now check whether it matches the ring-3 registration.
+                     */
+                    if (   pReq->uSharedVersion   == pDevReg->uSharedVersion
+                        && pReq->cbInstanceShared == pDevReg->cbInstanceShared
+                        && pReq->cbInstanceRC     == pDevReg->cbInstanceRC
+                        && pReq->fFlags           == pDevReg->fFlags
+                        && pReq->fClass           == pDevReg->fClass
+                        && pReq->cMaxInstances    == pDevReg->cMaxInstances)
+                    {
+                        rc = pdmR0DeviceCreateWorker(pGVM, pDevReg, pReq->iInstance, pReq->fRCEnabled,
+                                                     pReq->cbInstanceR3, pReq->cbInstanceRC, hMod,
+                                                     &pReq->pDevInsR3);
+                        if (RT_SUCCESS(rc))
+                            hMod = NULL; /* keep the module reference */
+                    }
+                    else
+                    {
+                        LogRel(("PDMR0DeviceCreate: Ring-3 does not match ring-0 device registration (%s):\n"
+                                "    uSharedVersion: %#x vs %#x\n"
+                                "  cbInstanceShared: %#x vs %#x\n"
+                                "      cbInstanceRC: %#x vs %#x\n"
+                                "            fFlags: %#x vs %#x\n"
+                                "            fClass: %#x vs %#x\n"
+                                "     cMaxInstances: %#x vs %#x\n",
+                                pReq->szDevName,
+                                pReq->uSharedVersion,   pDevReg->uSharedVersion,
+                                pReq->cbInstanceShared, pDevReg->cbInstanceShared,
+                                pReq->cbInstanceRC,     pDevReg->cbInstanceRC,
+                                pReq->fFlags,           pDevReg->fFlags,
+                                pReq->fClass,           pDevReg->fClass,
+                                pReq->cMaxInstances,    pDevReg->cMaxInstances));
+                        rc = VERR_INCOMPATIBLE_CONFIG;
+                    }
+                }
+            }
+            break;
+        }
+    }
+
+    if (RT_SUCCESS_NP(rcLock))
+    {
+        rcLock = SUPR0LdrUnlock(pGVM->pSession);
+        AssertRC(rcLock);
+    }
+    SUPR0LdrModRelease(pGVM->pSession, hMod);
+    return rc;
+}
+
+
+/**
+ * Used by ring-3 PDM to call standard ring-0 device methods.
+ *
+ * @returns VBox status code.
+ * @param   pGVM    The global (ring-0) VM structure.
+ * @param   pReq    Pointer to the request buffer.
+ * @thread  EMT(0)
+ */
+VMMR0_INT_DECL(int) PDMR0DeviceGenCallReqHandler(PGVM pGVM, PPDMDEVICEGENCALLREQ pReq)
+{
+    /*
+     * Validate the request.
+     */
+    AssertReturn(pReq->Hdr.cbReq == sizeof(*pReq), VERR_INVALID_PARAMETER);
+
+    int rc = GVMMR0ValidateGVMandEMT(pGVM, 0);
+    AssertRCReturn(rc, rc);
+
+    AssertReturn(pReq->idxR0Device < pGVM->pdmr0.s.cDevInstances, VERR_INVALID_HANDLE);
+    PPDMDEVINSR0 pDevIns = pGVM->pdmr0.s.apDevInstances[pReq->idxR0Device];
+    AssertPtrReturn(pDevIns, VERR_INVALID_HANDLE);
+    AssertReturn(pDevIns->pDevInsForR3 == pReq->pDevInsR3, VERR_INVALID_HANDLE);
+
+    /*
+     * Make the call.
+     */
+    rc = VINF_SUCCESS /*VINF_NOT_IMPLEMENTED*/;
+    switch (pReq->enmCall)
+    {
+        case PDMDEVICEGENCALL_CONSTRUCT:
+            AssertMsgBreakStmt(pGVM->enmVMState < VMSTATE_CREATED, ("enmVMState=%d\n", pGVM->enmVMState), rc = VERR_INVALID_STATE);
+            if (pDevIns->pReg->pfnConstruct)
+                rc = pDevIns->pReg->pfnConstruct(pDevIns);
+            break;
+
+        case PDMDEVICEGENCALL_DESTRUCT:
+            AssertMsgBreakStmt(pGVM->enmVMState < VMSTATE_CREATED || pGVM->enmVMState >= VMSTATE_DESTROYING,
+                               ("enmVMState=%d\n", pGVM->enmVMState), rc = VERR_INVALID_STATE);
+            if (pDevIns->pReg->pfnDestruct)
+            {
+                pDevIns->pReg->pfnDestruct(pDevIns);
+                rc = VINF_SUCCESS;
+            }
+            break;
+
+        default:
+            AssertMsgFailed(("enmCall=%d\n", pReq->enmCall));
+            rc = VERR_INVALID_FUNCTION;
+            break;
+    }
+
+    return rc;
+}
+
+
+/**
+ * Legacy device mode compatiblity.
+ *
+ * @returns VBox status code.
+ * @param   pGVM    The global (ring-0) VM structure.
+ * @param   pReq    Pointer to the request buffer.
+ * @thread  EMT(0)
+ */
+VMMR0_INT_DECL(int) PDMR0DeviceCompatSetCritSectReqHandler(PGVM pGVM, PPDMDEVICECOMPATSETCRITSECTREQ pReq)
+{
+    /*
+     * Validate the request.
+     */
+    AssertReturn(pReq->Hdr.cbReq == sizeof(*pReq), VERR_INVALID_PARAMETER);
+
+    int rc = GVMMR0ValidateGVMandEMT(pGVM, 0);
+    AssertRCReturn(rc, rc);
+
+    AssertReturn(pReq->idxR0Device < pGVM->pdmr0.s.cDevInstances, VERR_INVALID_HANDLE);
+    PPDMDEVINSR0 pDevIns = pGVM->pdmr0.s.apDevInstances[pReq->idxR0Device];
+    AssertPtrReturn(pDevIns, VERR_INVALID_HANDLE);
+    AssertReturn(pDevIns->pDevInsForR3 == pReq->pDevInsR3, VERR_INVALID_HANDLE);
+
+    AssertReturn(pGVM->enmVMState == VMSTATE_CREATING, VERR_INVALID_STATE);
+
+    /*
+     * The critical section address can be in a few different places:
+     *      1. shared data.
+     *      2. nop section.
+     *      3. pdm critsect.
+     */
+    PPDMCRITSECT pCritSect;
+    if (pReq->pCritSectR3 == pGVM->pVMR3 + RT_UOFFSETOF(VM, pdm.s.NopCritSect))
+    {
+        pCritSect = &pGVM->pdm.s.NopCritSect;
+        Log(("PDMR0DeviceCompatSetCritSectReqHandler: Nop - %p %#x\n", pCritSect, pCritSect->s.Core.u32Magic));
+    }
+    else if (pReq->pCritSectR3 == pGVM->pVMR3 + RT_UOFFSETOF(VM, pdm.s.CritSect))
+    {
+        pCritSect = &pGVM->pdm.s.CritSect;
+        Log(("PDMR0DeviceCompatSetCritSectReqHandler: PDM - %p %#x\n", pCritSect, pCritSect->s.Core.u32Magic));
+    }
+    else
+    {
+        size_t offCritSect = pReq->pCritSectR3 - pDevIns->pDevInsForR3R0->pvInstanceDataR3;
+        AssertLogRelMsgReturn(   offCritSect                     <  pDevIns->pReg->cbInstanceShared
+                              && offCritSect + sizeof(PDMPCIDEV) <= pDevIns->pReg->cbInstanceShared,
+                              ("offCritSect=%p pCritSectR3=%p cbInstanceShared=%#x (%s)\n",
+                               offCritSect, pReq->pCritSectR3, pDevIns->pReg->cbInstanceShared, pDevIns->pReg->szName),
+                              VERR_INVALID_POINTER);
+        pCritSect = (PPDMCRITSECT)((uint8_t *)pDevIns->pvInstanceDataR0 + offCritSect);
+        Log(("PDMR0DeviceCompatSetCritSectReqHandler: custom - %#x/%p %#x\n", offCritSect, pCritSect, pCritSect->s.Core.u32Magic));
+    }
+    AssertLogRelMsgReturn(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC,
+                          ("cs=%p magic=%#x dev=%s\n", pCritSect, pCritSect->s.Core.u32Magic, pDevIns->pReg->szName),
+                          VERR_INVALID_MAGIC);
+
+    /*
+     * Make the update.
+     */
+    pDevIns->pCritSectRoR0 = pCritSect;
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Legacy device mode compatiblity.
+ *
+ * @returns VBox status code.
+ * @param   pGVM    The global (ring-0) VM structure.
+ * @param   pReq    Pointer to the request buffer.
+ * @thread  EMT(0)
+ */
+VMMR0_INT_DECL(int) PDMR0DeviceCompatRegPciDevReqHandler(PGVM pGVM, PPDMDEVICECOMPATREGPCIDEVREQ pReq)
+{
+    /*
+     * Validate the request.
+     */
+    AssertReturn(pReq->Hdr.cbReq == sizeof(*pReq), VERR_INVALID_PARAMETER);
+
+    int rc = GVMMR0ValidateGVMandEMT(pGVM, 0);
+    AssertRCReturn(rc, rc);
+
+    AssertReturn(pReq->idxR0Device < pGVM->pdmr0.s.cDevInstances, VERR_INVALID_HANDLE);
+    PPDMDEVINSR0 pDevIns = pGVM->pdmr0.s.apDevInstances[pReq->idxR0Device];
+    AssertPtrReturn(pDevIns, VERR_INVALID_HANDLE);
+    AssertReturn(pDevIns->pDevInsForR3 == pReq->pDevInsR3, VERR_INVALID_HANDLE);
+
+    AssertReturn(pGVM->enmVMState == VMSTATE_CREATING, VERR_INVALID_STATE);
+
+    /*
+     * The address must be within the shared instance data.
+     */
+    size_t offPciDev = pReq->pPciDevR3 - pDevIns->pDevInsForR3R0->pvInstanceDataR3;
+    AssertLogRelMsgReturn(   offPciDev                     <  pDevIns->pReg->cbInstanceShared
+                          && offPciDev + sizeof(PDMPCIDEV) <= pDevIns->pReg->cbInstanceShared,
+                          ("offPciDev=%p pPciDevR3=%p cbInstanceShared=%#x (%s)\n",
+                           offPciDev, pReq->pPciDevR3, pDevIns->pReg->cbInstanceShared, pDevIns->pReg->szName),
+                          VERR_INVALID_POINTER);
+    PPDMPCIDEV pPciDev = (PPDMPCIDEV)((uint8_t *)pDevIns->pvInstanceDataR0 + offPciDev);
+    AssertReturn(pPciDev->Int.s.pDevInsR3 == pReq->pDevInsR3, VERR_MISMATCH);
+
+    /*
+     * Append the pci device to the list.
+     */
+    PPDMPCIDEV pPciDevPrev = pDevIns->Internal.s.pHeadPciDevR0;
+    if (!pPciDevPrev)
+        pDevIns->Internal.s.pHeadPciDevR0 = pPciDev;
+    else
+    {
+        while (pPciDevPrev->Int.s.pNextR0)
+            pPciDevPrev = pPciDevPrev->Int.s.pNextR0;
+        pPciDevPrev->Int.s.pNextR0 = pPciDev;
+    }
+    pPciDev->Int.s.pNextR0 = NULL;
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Registers the device implementations living in a module.
+ *
+ * This should normally only be called during ModuleInit().  The should be a
+ * call to PDMR0DeviceDeregisterModule from the ModuleTerm() function to undo
+ * the effects of this call.
+ *
+ * @returns VBox status code.
+ * @param   hMod            The module handle of the module being registered.
+ * @param   pModReg         The module registration structure.  This will be
+ *                          used directly so it must live as long as the module
+ *                          and be writable.
+ *
+ * @note    Caller must own the loader lock!
+ */
+VMMR0DECL(int) PDMR0DeviceRegisterModule(void *hMod, PPDMDEVMODREGR0 pModReg)
+{
+    /*
+     * Validate the input.
+     */
+    AssertPtrReturn(hMod, VERR_INVALID_HANDLE);
+    Assert(SUPR0LdrIsLockOwnerByMod(hMod, true));
+
+    AssertPtrReturn(pModReg, VERR_INVALID_POINTER);
+    AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE(pModReg->u32Version, PDM_DEVMODREGR0_VERSION),
+                          ("pModReg->u32Version=%#x vs %#x\n", pModReg->u32Version, PDM_DEVMODREGR0_VERSION),
+                          VERR_VERSION_MISMATCH);
+    AssertLogRelMsgReturn(pModReg->cDevRegs <= 256 && pModReg->cDevRegs > 0, ("cDevRegs=%u\n", pModReg->cDevRegs),
+                          VERR_OUT_OF_RANGE);
+    AssertLogRelMsgReturn(pModReg->hMod == NULL, ("hMod=%p\n", pModReg->hMod), VERR_INVALID_PARAMETER);
+    AssertLogRelMsgReturn(pModReg->ListEntry.pNext == NULL, ("pNext=%p\n", pModReg->ListEntry.pNext), VERR_INVALID_PARAMETER);
+    AssertLogRelMsgReturn(pModReg->ListEntry.pPrev == NULL, ("pPrev=%p\n", pModReg->ListEntry.pPrev), VERR_INVALID_PARAMETER);
+
+    for (size_t i = 0; i < pModReg->cDevRegs; i++)
+    {
+        PCPDMDEVREGR0 pDevReg = pModReg->papDevRegs[i];
+        AssertLogRelMsgReturn(RT_VALID_PTR(pDevReg), ("[%u]: %p\n", i, pDevReg), VERR_INVALID_POINTER);
+        AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE(pDevReg->u32Version, PDM_DEVREGR0_VERSION),
+                              ("pDevReg->u32Version=%#x vs %#x\n", pModReg->u32Version, PDM_DEVREGR0_VERSION), VERR_VERSION_MISMATCH);
+        AssertLogRelMsgReturn(RT_VALID_PTR(pDevReg->pszDescription), ("[%u]: %p\n", i, pDevReg->pszDescription), VERR_INVALID_POINTER);
+        AssertLogRelMsgReturn(pDevReg->uReserved0   == 0, ("[%u]: %#x\n", i, pDevReg->uReserved0),    VERR_INVALID_PARAMETER);
+        AssertLogRelMsgReturn(pDevReg->uReserved1   == 0, ("[%u]: %#x\n", i, pDevReg->uReserved1),    VERR_INVALID_PARAMETER);
+        AssertLogRelMsgReturn(pDevReg->fClass       != 0, ("[%u]: %#x\n", i, pDevReg->fClass),        VERR_INVALID_PARAMETER);
+        AssertLogRelMsgReturn(pDevReg->fFlags       != 0, ("[%u]: %#x\n", i, pDevReg->fFlags),        VERR_INVALID_PARAMETER);
+        AssertLogRelMsgReturn(pDevReg->cMaxInstances > 0, ("[%u]: %#x\n", i, pDevReg->cMaxInstances), VERR_INVALID_PARAMETER);
+
+        /* The name must be printable ascii and correctly terminated. */
+        for (size_t off = 0; off < RT_ELEMENTS(pDevReg->szName); off++)
+        {
+            char ch = pDevReg->szName[off];
+            AssertLogRelMsgReturn(RT_C_IS_PRINT(ch) || (ch == '\0' && off > 0),
+                                  ("[%u]: off=%u  szName: %.*Rhxs\n", i, off, sizeof(pDevReg->szName), &pDevReg->szName[0]),
+                                  VERR_INVALID_NAME);
+            if (ch == '\0')
+                break;
+        }
+    }
+
+    /*
+     * Add it, assuming we're being called at ModuleInit/ModuleTerm time only, or
+     * that the caller has already taken the loader lock.
+     */
+    pModReg->hMod = hMod;
+    RTListAppend(&g_PDMDevModList, &pModReg->ListEntry);
+
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Deregisters the device implementations living in a module.
+ *
+ * This should normally only be called during ModuleTerm().
+ *
+ * @returns VBox status code.
+ * @param   hMod            The module handle of the module being registered.
+ * @param   pModReg         The module registration structure.  This will be
+ *                          used directly so it must live as long as the module
+ *                          and be writable.
+ *
+ * @note    Caller must own the loader lock!
+ */
+VMMR0DECL(int) PDMR0DeviceDeregisterModule(void *hMod, PPDMDEVMODREGR0 pModReg)
+{
+    /*
+     * Validate the input.
+     */
+    AssertPtrReturn(hMod, VERR_INVALID_HANDLE);
+    Assert(SUPR0LdrIsLockOwnerByMod(hMod, true));
+
+    AssertPtrReturn(pModReg, VERR_INVALID_POINTER);
+    AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE(pModReg->u32Version, PDM_DEVMODREGR0_VERSION),
+                          ("pModReg->u32Version=%#x vs %#x\n", pModReg->u32Version, PDM_DEVMODREGR0_VERSION),
+                          VERR_VERSION_MISMATCH);
+    AssertLogRelMsgReturn(pModReg->hMod == hMod || pModReg->hMod == NULL, ("pModReg->hMod=%p vs %p\n", pModReg->hMod, hMod),
+                          VERR_INVALID_PARAMETER);
+
+    /*
+     * Unlink the registration record and return it to virgin conditions.  Ignore
+     * the call if not registered.
+     */
+    if (pModReg->hMod)
+    {
+        pModReg->hMod = NULL;
+        RTListNodeRemove(&pModReg->ListEntry);
+        pModReg->ListEntry.pNext = NULL;
+        pModReg->ListEntry.pPrev = NULL;
+        return VINF_SUCCESS;
+    }
+    return VWRN_NOT_FOUND;
+}
+
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 80531)
@@ -220,4 +220,8 @@
                 {
                     VMM_CHECK_SMAP_CHECK(RT_NOTHING);
+
+                    PDMR0Init(hMod);
+                    VMM_CHECK_SMAP_CHECK(RT_NOTHING);
+
                     rc = PGMRegisterStringFormatTypes();
                     if (RT_SUCCESS(rc))
@@ -1994,4 +1998,42 @@
         }
 
+        case VMMR0_DO_PDM_DEVICE_CREATE:
+        {
+            if (!pReqHdr || u64Arg || idCpu != 0)
+                return VERR_INVALID_PARAMETER;
+            rc = PDMR0DeviceCreateReqHandler(pGVM, (PPDMDEVICECREATEREQ)pReqHdr);
+            VMM_CHECK_SMAP_CHECK2(pGVM, RT_NOTHING);
+            break;
+        }
+
+        case VMMR0_DO_PDM_DEVICE_GEN_CALL:
+        {
+            if (!pReqHdr || u64Arg || idCpu != 0)
+                return VERR_INVALID_PARAMETER;
+            rc = PDMR0DeviceGenCallReqHandler(pGVM, (PPDMDEVICEGENCALLREQ)pReqHdr);
+            VMM_CHECK_SMAP_CHECK2(pGVM, RT_NOTHING);
+            break;
+        }
+
+        /** @todo Remove the once all devices has been converted to new style! @bugref{9218} */
+        case VMMR0_DO_PDM_DEVICE_COMPAT_SET_CRITSECT:
+        {
+            if (!pReqHdr || u64Arg || idCpu != 0)
+                return VERR_INVALID_PARAMETER;
+            rc = PDMR0DeviceCompatSetCritSectReqHandler(pGVM, (PPDMDEVICECOMPATSETCRITSECTREQ)pReqHdr);
+            VMM_CHECK_SMAP_CHECK2(pGVM, RT_NOTHING);
+            break;
+        }
+
+        /** @todo Remove the once all devices has been converted to new style! @bugref{9218} */
+        case VMMR0_DO_PDM_DEVICE_COMPAT_REG_PCIDEV:
+        {
+            if (!pReqHdr || u64Arg || idCpu != 0)
+                return VERR_INVALID_PARAMETER;
+            rc = PDMR0DeviceCompatRegPciDevReqHandler(pGVM, (PPDMDEVICECOMPATREGPCIDEVREQ)pReqHdr);
+            VMM_CHECK_SMAP_CHECK2(pGVM, RT_NOTHING);
+            break;
+        }
+
         /*
          * Requests to the internal networking service.
@@ -2252,12 +2294,13 @@
             case VMMR0_DO_VMMR0_INIT:
             case VMMR0_DO_VMMR0_TERM:
+
+            case VMMR0_DO_PDM_DEVICE_CREATE:
             {
-                PGVMCPU   pGVCpu = &pGVM->aCpus[idCpu];
-                PVMCPUCC  pVCpu  = pGVCpu;
+                PGVMCPU        pGVCpu        = &pGVM->aCpus[idCpu];
                 RTNATIVETHREAD hNativeThread = RTThreadNativeSelf();
-                if (RT_LIKELY(   pGVCpu->hEMT           == hNativeThread
-                              && pVCpu->hNativeThreadR0 == hNativeThread))
+                if (RT_LIKELY(   pGVCpu->hEMT            == hNativeThread
+                              && pGVCpu->hNativeThreadR0 == hNativeThread))
                 {
-                    if (!pVCpu->vmm.s.CallRing3JmpBufR0.pvSavedStack)
+                    if (!pGVCpu->vmm.s.CallRing3JmpBufR0.pvSavedStack)
                         break;
 
@@ -2270,5 +2313,5 @@
                     Args.u64Arg = u64Arg;
                     Args.pSession = pSession;
-                    return vmmR0CallRing3SetJmpEx(&pVCpu->vmm.s.CallRing3JmpBufR0, vmmR0EntryExWrapper, &Args);
+                    return vmmR0CallRing3SetJmpEx(&pGVCpu->vmm.s.CallRing3JmpBufR0, vmmR0EntryExWrapper, &Args);
                 }
                 return VERR_VM_THREAD_NOT_EMT;
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.def
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.def	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.def	(revision 80531)
@@ -37,4 +37,6 @@
     PGMPhysWriteGCPtr
     PGMPhysSimpleDirtyWriteGCPtr
+    PDMR0DeviceRegisterModule
+    PDMR0DeviceDeregisterModule
     IOMMMIOResetRegion
     IOMMMIOMapMMIO2Page
Index: /trunk/src/VBox/VMM/VMMR3/APIC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 80531)
@@ -1161,5 +1161,5 @@
  * @interface_method_impl{PDMDEVREG,pfnReset}
  */
-static DECLCALLBACK(void) apicR3Reset(PPDMDEVINS pDevIns)
+DECLCALLBACK(void) apicR3Reset(PPDMDEVINS pDevIns)
 {
     PVM pVM = PDMDevHlpGetVM(pDevIns);
@@ -1188,5 +1188,5 @@
  * @interface_method_impl{PDMDEVREG,pfnRelocate}
  */
-static DECLCALLBACK(void) apicR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
+DECLCALLBACK(void) apicR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
 {
     RT_NOREF(pDevIns, offDelta);
@@ -1348,5 +1348,5 @@
  * @interface_method_impl{PDMDEVREG,pfnDestruct}
  */
-static DECLCALLBACK(int) apicR3Destruct(PPDMDEVINS pDevIns)
+DECLCALLBACK(int) apicR3Destruct(PPDMDEVINS pDevIns)
 {
     PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
@@ -1362,5 +1362,5 @@
  * @interface_method_impl{PDMDEVREG,pfnInitComplete}
  */
-static DECLCALLBACK(int) apicR3InitComplete(PPDMDEVINS pDevIns)
+DECLCALLBACK(int) apicR3InitComplete(PPDMDEVINS pDevIns)
 {
     PVM   pVM   = PDMDevHlpGetVM(pDevIns);
@@ -1388,5 +1388,5 @@
  * @interface_method_impl{PDMDEVREG,pfnConstruct}
  */
-static DECLCALLBACK(int) apicR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
+DECLCALLBACK(int) apicR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
 {
     /*
@@ -1407,6 +1407,6 @@
     pApicDev->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
 
+    pApic->pApicDevR3   = pApicDev;
     pApic->pApicDevR0   = PDMINS_2_DATA_R0PTR(pDevIns);
-    pApic->pApicDevR3   = (PAPICDEV)PDMINS_2_DATA_R3PTR(pDevIns);
 
     /*
@@ -1595,70 +1595,4 @@
 }
 
-
-/**
- * APIC device registration structure.
- */
-static const PDMDEVREG g_DeviceAPIC =
-{
-    /* u32Version */
-    PDM_DEVREG_VERSION,
-    /* szName */
-    "apic",
-    /* szRCMod */
-    "",
-    /* szR0Mod */
-    "VMMR0.r0",
-    /* pszDescription */
-    "Advanced Programmable Interrupt Controller",
-    /* fFlags */
-      PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_32_64 | PDM_DEVREG_FLAGS_PAE36
-    | PDM_DEVREG_FLAGS_R0,
-    /* fClass */
-    PDM_DEVREG_CLASS_PIC,
-    /* cMaxInstances */
-    1,
-    /* cbInstance */
-    sizeof(APICDEV),
-    /* pfnConstruct */
-    apicR3Construct,
-    /* pfnDestruct */
-    apicR3Destruct,
-    /* pfnRelocate */
-    apicR3Relocate,
-    /* pfnMemSetup */
-    NULL,
-    /* pfnPowerOn */
-    NULL,
-    /* pfnReset */
-    apicR3Reset,
-    /* pfnSuspend */
-    NULL,
-    /* pfnResume */
-    NULL,
-    /* pfnAttach */
-    NULL,
-    /* pfnDetach */
-    NULL,
-    /* pfnQueryInterface. */
-    NULL,
-    /* pfnInitComplete */
-    apicR3InitComplete,
-    /* pfnPowerOff */
-    NULL,
-    /* pfnSoftReset */
-    NULL,
-    /* u32VersionEnd */
-    PDM_DEVREG_VERSION
-};
-
-
-/**
- * Called by PDM to register the APIC device.
- */
-VMMR3_INT_DECL(int) APICR3RegisterDevice(PPDMDEVREGCB pCallbacks)
-{
-    return pCallbacks->pfnRegister(pCallbacks, &g_DeviceAPIC);
-}
-
 #endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
 
Index: /trunk/src/VBox/VMM/VMMR3/IOM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/IOM.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR3/IOM.cpp	(revision 80531)
@@ -717,5 +717,5 @@
         pRange->pfnOutStrCallback = pfnOutStrCallback;
         pRange->pfnInStrCallback = pfnInStrCallback;
-        pRange->pDevIns         = MMHyperCCToRC(pVM, pDevIns);
+        pRange->pDevIns         = pDevIns->pDevInsForRC;
         pRange->pszDesc         = pszDesc;
 
@@ -829,5 +829,5 @@
         pRange->pfnOutStrCallback = pfnOutStrCallback;
         pRange->pfnInStrCallback = pfnInStrCallback;
-        pRange->pDevIns         = MMHyperR3ToR0(pVM, pDevIns);
+        pRange->pDevIns         = PDMDEVINS_2_R0PTR(pDevIns);
         pRange->pszDesc         = pszDesc;
 
@@ -1492,5 +1492,5 @@
     pRange->pfnWriteCallbackRC= pfnWriteCallback;
     pRange->pfnFillCallbackRC = pfnFillCallback;
-    pRange->pDevInsRC         = MMHyperCCToRC(pVM, pDevIns);
+    pRange->pDevInsRC         = pDevIns->pDevInsForRC;
     IOM_UNLOCK_EXCL(pVM);
 
@@ -1552,5 +1552,5 @@
     pRange->pfnWriteCallbackR0= pfnWriteCallback;
     pRange->pfnFillCallbackR0 = pfnFillCallback;
-    pRange->pDevInsR0         = MMHyperCCToR0(pVM, pDevIns);
+    pRange->pDevInsR0         = pDevIns->pDevInsR0RemoveMe;
     IOM_UNLOCK_EXCL(pVM);
 
@@ -1743,5 +1743,5 @@
         {
             pRange->pvUserR0            = pvUserR0;
-            pRange->pDevInsR0           = MMHyperCCToR0(pVM, pDevIns);
+            pRange->pDevInsR0           = pDevIns->pDevInsR0RemoveMe;
             pRange->pfnReadCallbackR0   = pfnReadCallbackR0;
             pRange->pfnWriteCallbackR0  = pfnWriteCallbackR0;
@@ -1753,5 +1753,5 @@
         {
             pRange->pvUserRC            = pvUserRC;
-            pRange->pDevInsRC           = MMHyperCCToRC(pVM, pDevIns);
+            pRange->pDevInsRC           = pDevIns->pDevInsForRC;
             pRange->pfnReadCallbackRC   = pfnReadCallbackRC;
             pRange->pfnWriteCallbackRC  = pfnWriteCallbackRC;
Index: /trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp	(revision 80531)
@@ -1461,5 +1461,5 @@
                 DWORD const    dwErrLast = RTNtLastErrorValue();
                 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS,
-                                  "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", hrc, rcNtLast, dwErrLast);
+                                  "Call to VidMessageSlotMap failed: Last=%#x/%u", rcNtLast, dwErrLast);
             }
         }
Index: /trunk/src/VBox/VMM/VMMR3/PDM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDM.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR3/PDM.cpp	(revision 80531)
@@ -556,4 +556,5 @@
      * Devices & Drivers.
      */
+#ifdef VBOX_WITH_RAW_MODE_KEEP /* needs fixing */
     int rc;
     PCPDMDEVHLPRC pDevHlpRC = NIL_RTRCPTR;
@@ -624,4 +625,5 @@
 
     }
+#endif
 }
 
@@ -747,7 +749,19 @@
         if (pDevIns->pReg->pfnDestruct)
         {
-            LogFlow(("pdmR3DevTerm: Destroying - device '%s'/%d\n",
-                     pDevIns->pReg->szName, pDevIns->iInstance));
+            LogFlow(("pdmR3DevTerm: Destroying - device '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
             pDevIns->pReg->pfnDestruct(pDevIns);
+        }
+
+        if (pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_CONTRUCT)
+        {
+            LogFlow(("pdmR3DevTerm: Destroying (ring-0) - device '%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
+            PDMDEVICEGENCALLREQ Req;
+            Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+            Req.Hdr.cbReq    = sizeof(Req);
+            Req.enmCall      = PDMDEVICEGENCALL_DESTRUCT;
+            Req.idxR0Device  = pDevIns->Internal.s.idxR0Device;
+            Req.pDevInsR3    = pDevIns;
+            int rc2 = VMMR3CallR0(pVM, VMMR0_DO_PDM_DEVICE_GEN_CALL, 0, &Req.Hdr);
+            AssertRC(rc2);
         }
 
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 80531)
@@ -32,4 +32,5 @@
 #endif
 #include <VBox/vmm/dbgf.h>
+#include <VBox/vmm/ssm.h>
 #include <VBox/vmm/vmapi.h>
 #include <VBox/vmm/vmm.h>
@@ -73,5 +74,5 @@
     }
     return PDMR3LdrGetSymbolRCLazy(pVM,
-                                   pDevIns->Internal.s.pDevR3->pReg->szRCMod,
+                                   pDevIns->Internal.s.pDevR3->pReg->pszRCMod,
                                    pDevIns->Internal.s.pDevR3->pszRCSearchPath,
                                    pszSymbol, ppvValue);
@@ -85,5 +86,5 @@
 {
     return PDMR3LdrGetSymbolR0Lazy(pDevIns->Internal.s.pVMR3,
-                                   pDevIns->Internal.s.pDevR3->pReg->szR0Mod,
+                                   pDevIns->Internal.s.pDevR3->pReg->pszR0Mod,
                                    pDevIns->Internal.s.pDevR3->pszR0SearchPath,
                                    pszSymbol, ppvValue);
@@ -95,4 +96,31 @@
  */
 
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortCreateEx} */
+static DECLCALLBACK(int) pdmR3DevHlp_IoPortCreateEx(PPDMDEVINS pDevIns, RTIOPORT cPorts,
+                                                    uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
+                                                    PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
+                                                    PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr,
+                                                    RTR3PTR pvUser, const char *pszDesc, PIOMIOPORTHANDLE phIoPorts)
+{
+    RT_NOREF(pDevIns, cPorts, fFlags, pPciDev, iPciRegion, pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser, pszDesc, phIoPorts);
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortMap} */
+static DECLCALLBACK(int) pdmR3DevHlp_IoPortMap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT Port)
+{
+    RT_NOREF(pDevIns, hIoPorts, Port);
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortUnmap} */
+static DECLCALLBACK(int) pdmR3DevHlp_IoPortUnmap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)
+{
+    RT_NOREF(pDevIns, hIoPorts);
+    return VERR_NOT_IMPLEMENTED;
+}
 
 /** @interface_method_impl{PDMDEVHLPR3,pfnIOPortRegister} */
@@ -128,5 +156,5 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    Assert(pDevIns->pReg->szRCMod[0]);
+    Assert(pDevIns->pReg->pszRCMod[0]);
     Assert(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC);
     LogFlow(("pdmR3DevHlp_IOPortRegisterRC: caller='%s'/%d: Port=%#x cPorts=%#x pvUser=%p pszOut=%p:{%s} pszIn=%p:{%s} pszOutStr=%p:{%s} pszInStr=%p:{%s} pszDesc=%p:{%s}\n", pDevIns->pReg->szName, pDevIns->iInstance,
@@ -140,5 +168,5 @@
     VM_ASSERT_EMT(pVM);
     int rc = VINF_SUCCESS;
-    if (   pDevIns->pReg->szRCMod[0]
+    if (   pDevIns->pReg->pszRCMod[0]
         && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
         && VM_IS_RAW_MODE_ENABLED(pVM))
@@ -148,5 +176,5 @@
         {
             rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszIn, &RCPtrIn);
-            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pReg->szRCMod, pszIn));
+            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pReg->pszRCMod, pszIn));
         }
         RTRCPTR RCPtrOut = NIL_RTRCPTR;
@@ -154,5 +182,5 @@
         {
             rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszOut, &RCPtrOut);
-            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pReg->szRCMod, pszOut));
+            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pReg->pszRCMod, pszOut));
         }
         RTRCPTR RCPtrInStr = NIL_RTRCPTR;
@@ -160,5 +188,5 @@
         {
             rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszInStr, &RCPtrInStr);
-            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pReg->szRCMod, pszInStr));
+            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pReg->pszRCMod, pszInStr));
         }
         RTRCPTR RCPtrOutStr = NIL_RTRCPTR;
@@ -166,5 +194,5 @@
         {
             rc = pdmR3DevGetSymbolRCLazy(pDevIns, pszOutStr, &RCPtrOutStr);
-            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pReg->szRCMod, pszOutStr));
+            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pReg->pszRCMod, pszOutStr));
         }
 
@@ -212,5 +240,5 @@
      */
     int rc = VINF_SUCCESS;
-    if (    pDevIns->pReg->szR0Mod[0]
+    if (    pDevIns->pReg->pszR0Mod[0]
         &&  (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0))
     {
@@ -219,5 +247,5 @@
         {
             rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszIn, &pfnR0PtrIn);
-            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pReg->szR0Mod, pszIn));
+            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszIn)\n", pDevIns->pReg->pszR0Mod, pszIn));
         }
         R0PTRTYPE(PFNIOMIOPORTOUT) pfnR0PtrOut = 0;
@@ -225,5 +253,5 @@
         {
             rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszOut, &pfnR0PtrOut);
-            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pReg->szR0Mod, pszOut));
+            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOut)\n", pDevIns->pReg->pszR0Mod, pszOut));
         }
         R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnR0PtrInStr = 0;
@@ -231,5 +259,5 @@
         {
             rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszInStr, &pfnR0PtrInStr);
-            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pReg->szR0Mod, pszInStr));
+            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszInStr)\n", pDevIns->pReg->pszR0Mod, pszInStr));
         }
         R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnR0PtrOutStr = 0;
@@ -237,5 +265,5 @@
         {
             rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pszOutStr, &pfnR0PtrOutStr);
-            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pReg->szR0Mod, pszOutStr));
+            AssertMsgRC(rc, ("Failed to resolve %s.%s (pszOutStr)\n", pDevIns->pReg->pszR0Mod, pszOutStr));
         }
 
@@ -280,4 +308,39 @@
 
 
+/** @interface_method_impl{PDMDEVHLPR3,pfnMmioCreateEx} */
+static DECLCALLBACK(int) pdmR3DevHlp_MmioCreateEx(PPDMDEVINS pDevIns, RTGCPHYS cbRegion,
+                                                  uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
+                                                  PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
+                                                  void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion)
+{
+    RT_NOREF(pDevIns, cbRegion, fFlags, pPciDev, iPciRegion, pfnWrite, pfnRead, pfnFill, pvUser, pszDesc, phRegion);
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnMmioMap} */
+static DECLCALLBACK(int) pdmR3DevHlp_MmioMap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys)
+{
+    RT_NOREF(pDevIns, hRegion, GCPhys);
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnMmioUnmap} */
+static DECLCALLBACK(int) pdmR3DevHlp_MmioUnmap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
+{
+    RT_NOREF(pDevIns, hRegion);
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnMmioReduce} */
+static DECLCALLBACK(int) pdmR3DevHlp_MmioReduce(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS cbRegion)
+{
+    RT_NOREF(pDevIns, hRegion, cbRegion);
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
 /** @interface_method_impl{PDMDEVHLPR3,pfnMMIORegister} */
 static DECLCALLBACK(int) pdmR3DevHlp_MMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, RTGCPHYS cbRange, RTHCPTR pvUser,
@@ -312,5 +375,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
-    Assert(pDevIns->pReg->szR0Mod[0]);
+    Assert(pDevIns->pReg->pszR0Mod[0]);
     Assert(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0);
     LogFlow(("pdmR3DevHlp_MMIORegisterRC: caller='%s'/%d: GCPhysStart=%RGp cbRange=%RGp pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n",
@@ -323,5 +386,5 @@
      */
     int rc = VINF_SUCCESS;
-    if (   pDevIns->pReg->szRCMod[0]
+    if (   pDevIns->pReg->pszRCMod[0]
         && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
         && VM_IS_RAW_MODE_ENABLED(pDevIns->Internal.s.pVMR3))
@@ -345,7 +408,7 @@
         else
         {
-            AssertMsgRC(rc,  ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pReg->szRCMod, pszWrite));
-            AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n",  pDevIns->pReg->szRCMod, pszRead));
-            AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n",  pDevIns->pReg->szRCMod, pszFill));
+            AssertMsgRC(rc,  ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pReg->pszRCMod, pszWrite));
+            AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n",  pDevIns->pReg->pszRCMod, pszRead));
+            AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n",  pDevIns->pReg->pszRCMod, pszFill));
             if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
                 rc = rc2;
@@ -374,5 +437,5 @@
     PDMDEV_ASSERT_DEVINS(pDevIns);
     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
-    Assert(pDevIns->pReg->szR0Mod[0]);
+    Assert(pDevIns->pReg->pszR0Mod[0]);
     Assert(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0);
     LogFlow(("pdmR3DevHlp_MMIORegisterHC: caller='%s'/%d: GCPhysStart=%RGp cbRange=%RGp pvUser=%p pszWrite=%p:{%s} pszRead=%p:{%s} pszFill=%p:{%s}\n",
@@ -384,5 +447,5 @@
      */
     int rc = VINF_SUCCESS;
-    if (   pDevIns->pReg->szR0Mod[0]
+    if (   pDevIns->pReg->pszR0Mod[0]
         && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0))
     {
@@ -403,7 +466,7 @@
         else
         {
-            AssertMsgRC(rc,  ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pReg->szR0Mod, pszWrite));
-            AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n",  pDevIns->pReg->szR0Mod, pszRead));
-            AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n",  pDevIns->pReg->szR0Mod, pszFill));
+            AssertMsgRC(rc,  ("Failed to resolve %s.%s (pszWrite)\n", pDevIns->pReg->pszR0Mod, pszWrite));
+            AssertMsgRC(rc2, ("Failed to resolve %s.%s (pszRead)\n",  pDevIns->pReg->pszR0Mod, pszRead));
+            AssertMsgRC(rc3, ("Failed to resolve %s.%s (pszFill)\n",  pDevIns->pReg->pszR0Mod, pszFill));
             if (RT_FAILURE(rc2) && RT_SUCCESS(rc))
                 rc = rc2;
@@ -489,8 +552,8 @@
      */
     AssertLogRelReturn(   (!pszWriteR0 && !pszReadR0 && !pszFillR0)
-                       || (pDevIns->pReg->szR0Mod[0] && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)),
+                       || (pDevIns->pReg->pszR0Mod[0] && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)),
                        VERR_INVALID_PARAMETER);
     AssertLogRelReturn(   (!pszWriteRC && !pszReadRC && !pszFillRC)
-                       || (pDevIns->pReg->szRCMod[0] && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)),
+                       || (pDevIns->pReg->pszRCMod[0] && (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)),
                        VERR_INVALID_PARAMETER);
 
@@ -790,4 +853,172 @@
     LogFlow(("pdmR3DevHlp_TMTimerCreate: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
     return rc;
+}
+
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerCreate} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback,
+                                                 void *pvUser, uint32_t fFlags, const char *pszDesc, PTMTIMERHANDLE phTimer)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMR3;
+    VM_ASSERT_EMT(pVM);
+    LogFlow(("pdmR3DevHlp_TimerCreate: caller='%s'/%d: enmClock=%d pfnCallback=%p pvUser=%p fFlags=%#x pszDesc=%p:{%s} phTimer=%p\n",
+             pDevIns->pReg->szName, pDevIns->iInstance, enmClock, pfnCallback, pvUser, fFlags, pszDesc, pszDesc, phTimer));
+
+    if (pDevIns->iInstance > 0) /** @todo use a string cache here later. */
+    {
+         char *pszDesc2 = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_DESC, "%s [%u]", pszDesc, pDevIns->iInstance);
+         if (pszDesc2)
+             pszDesc = pszDesc2;
+    }
+
+    PTMTIMER pTimer = NULL;
+    int rc = TMR3TimerCreateDevice(pVM, pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, &pTimer);
+    *phTimer = (uintptr_t)pTimer;
+
+    LogFlow(("pdmR3DevHlp_TimerCreate: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
+    return rc;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerToPtr} */
+static DECLCALLBACK(PTMTIMERR3) pdmR3DevHlp_TimerToPtr(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    RT_NOREF(pDevIns);
+    return (PTMTIMERR3)hTimer;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerFromMicro} */
+static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerFromMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicroSecs)
+{
+    return TMTimerFromMicro(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cMicroSecs);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerFromMilli} */
+static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerFromMilli(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliSecs)
+{
+    return TMTimerFromMilli(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cMilliSecs);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerFromNano} */
+static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerFromNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanoSecs)
+{
+    return TMTimerFromNano(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cNanoSecs);
+}
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerGet} */
+static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerGet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerGet(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerGetFreq} */
+static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerGetFreq(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerGetFreq(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerGetNano} */
+static DECLCALLBACK(uint64_t) pdmR3DevHlp_TimerGetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerGetNano(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerIsActive} */
+static DECLCALLBACK(bool) pdmR3DevHlp_TimerIsActive(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerIsActive(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerIsLockOwner} */
+static DECLCALLBACK(bool) pdmR3DevHlp_TimerIsLockOwner(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerIsLockOwner(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerLock} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerLock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, int rcBusy)
+{
+    return TMTimerLock(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), rcBusy);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSet} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerSet(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t uExpire)
+{
+    return TMTimerSet(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), uExpire);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetFrequencyHint} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerSetFrequencyHint(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint32_t uHz)
+{
+    return TMTimerSetFrequencyHint(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), uHz);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetMicro} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerSetMicro(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMicrosToNext)
+{
+    return TMTimerSetMicro(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cMicrosToNext);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetMillies} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerSetMillies(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cMilliesToNext)
+{
+    return TMTimerSetMillies(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cMilliesToNext);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetNano} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerSetNano(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cNanosToNext)
+{
+    return TMTimerSetNano(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cNanosToNext);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSetRelative} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerSetRelative(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, uint64_t cTicksToNext, uint64_t *pu64Now)
+{
+    return TMTimerSetRelative(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), cTicksToNext, pu64Now);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerStop} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerStop(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    return TMTimerStop(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerUnlock} */
+static DECLCALLBACK(void) pdmR3DevHlp_TimerUnlock(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer)
+{
+    TMTimerUnlock(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer));
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerSave} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerSave(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
+{
+    return TMR3TimerSave(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), pSSM);
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR3,pfnTimerLoad} */
+static DECLCALLBACK(int) pdmR3DevHlp_TimerLoad(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, PSSMHANDLE pSSM)
+{
+    return TMR3TimerLoad(pdmR3DevHlp_TimerToPtr(pDevIns, hTimer), pSSM);
 }
 
@@ -1579,5 +1810,5 @@
         if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
         {
-            pPciDev->Int.s.pDevInsR0 = MMHyperR3ToR0(pVM, pDevIns);
+            pPciDev->Int.s.pDevInsR0 = pDevIns->pDevInsR0RemoveMe;
             pPciDev->Int.s.pPdmBusR0 = MMHyperR3ToR0(pVM, pBus);
         }
@@ -1588,10 +1819,10 @@
         }
 
-        if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
-        {
-            pPciDev->Int.s.pDevInsRC = MMHyperR3ToRC(pVM, pDevIns);
-            pPciDev->Int.s.pPdmBusRC = MMHyperR3ToRC(pVM, pBus);
-        }
-        else
+        //if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
+        //{
+        //    pPciDev->Int.s.pDevInsRC = MMHyperR3ToRC(pVM, pDevIns);
+        //    pPciDev->Int.s.pPdmBusRC = MMHyperR3ToRC(pVM, pBus);
+        //}
+        //else
         {
             pPciDev->Int.s.pDevInsRC = NIL_RTRCPTR;
@@ -1618,12 +1849,6 @@
                 Assert(!pPrevPciDev->Int.s.pNextR3);
                 pPrevPciDev->Int.s.pNextR3 = pPciDev;
-                if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
-                    pPrevPciDev->Int.s.pNextR0 = MMHyperR3ToR0(pVM, pPciDev);
-                else
-                    pPrevPciDev->Int.s.pNextR0 = NIL_RTR0PTR;
-                if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
-                    pPrevPciDev->Int.s.pNextRC = MMHyperR3ToRC(pVM, pPciDev);
-                else
-                    pPrevPciDev->Int.s.pNextRC = NIL_RTRCPTR;
+                pPrevPciDev->Int.s.pNextR0 = NIL_RTRCPTR;
+                pPrevPciDev->Int.s.pNextRC = NIL_RTRCPTR;
             }
             else
@@ -1631,12 +1856,18 @@
                 Assert(!pDevIns->Internal.s.pHeadPciDevR3);
                 pDevIns->Internal.s.pHeadPciDevR3 = pPciDev;
-                if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
-                    pDevIns->Internal.s.pHeadPciDevR0 = MMHyperR3ToR0(pVM, pPciDev);
-                else
-                    pDevIns->Internal.s.pHeadPciDevR0 = NIL_RTR0PTR;
-                if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
-                    pDevIns->Internal.s.pHeadPciDevRC = MMHyperR3ToRC(pVM, pPciDev);
-                else
-                    pDevIns->Internal.s.pHeadPciDevRC = NIL_RTRCPTR;
+            }
+
+            Assert(RT_BOOL(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED) == pDevIns->fR0Enabled);
+            if (   (pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED)
+                && !(pDevIns->Internal.s.pDevR3->pReg->fFlags & PDM_DEVREG_FLAGS_NEW_STYLE))
+            {
+                PDMDEVICECOMPATREGPCIDEVREQ Req;
+                Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+                Req.Hdr.cbReq    = sizeof(Req);
+                Req.idxR0Device  = pDevIns->Internal.s.idxR0Device;
+                Req.pDevInsR3    = pDevIns;
+                Req.pPciDevR3    = pPciDev;
+                rc = VMMR3CallR0(pVM, VMMR0_DO_PDM_DEVICE_COMPAT_REG_PCIDEV, 0, &Req.Hdr);
+                AssertLogRelRCReturn(rc, rc);
             }
 
@@ -2210,19 +2441,22 @@
     PPDMCRITSECT pOldCritSect = pDevIns->pCritSectRoR3;
     pDevIns->pCritSectRoR3 = pCritSect;
-    if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0)
-        pDevIns->pCritSectRoR0 = MMHyperCCToR0(pVM, pDevIns->pCritSectRoR3);
-    else
-        Assert(pDevIns->pCritSectRoR0 == NIL_RTRCPTR);
-
-    if (pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC)
-        pDevIns->pCritSectRoRC = MMHyperCCToRC(pVM, pDevIns->pCritSectRoR3);
-    else
-        Assert(pDevIns->pCritSectRoRC == NIL_RTRCPTR);
+    pDevIns->Internal.s.fIntFlags |= PDMDEVINSINT_FLAGS_CHANGED_CRITSECT;
+
+    Assert(RT_BOOL(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED) == pDevIns->fR0Enabled);
+    if (   (pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED)
+        && !(pDevIns->Internal.s.pDevR3->pReg->fFlags & PDM_DEVREG_FLAGS_NEW_STYLE))
+    {
+        PDMDEVICECOMPATSETCRITSECTREQ Req;
+        Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+        Req.Hdr.cbReq    = sizeof(Req);
+        Req.idxR0Device  = pDevIns->Internal.s.idxR0Device;
+        Req.pDevInsR3    = pDevIns;
+        Req.pCritSectR3  = pCritSect;
+        int rc = VMMR3CallR0(pVM, VMMR0_DO_PDM_DEVICE_COMPAT_SET_CRITSECT, 0, &Req.Hdr);
+        AssertLogRelRCReturn(rc, rc);
+    }
 
     PDMR3CritSectDelete(pOldCritSect);
-    if (pDevIns->pReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0))
-        MMHyperFree(pVM, pOldCritSect);
-    else
-        MMR3HeapFree(pOldCritSect);
+    Assert((uintptr_t)pOldCritSect - (uintptr_t)pDevIns < pDevIns->cbRing3);
 
     LogFlow(("pdmR3DevHlp_SetDeviceCritSect: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
@@ -2613,5 +2847,5 @@
             rc = PDMR3LdrGetInterfaceSymbols(pDevIns->Internal.s.pVMR3,
                                              pvInterface, cbInterface,
-                                             pDevIns->pReg->szRCMod, pDevIns->Internal.s.pDevR3->pszRCSearchPath,
+                                             pDevIns->pReg->pszRCMod, pDevIns->Internal.s.pDevR3->pszRCSearchPath,
                                              pszSymPrefix, pszSymList,
                                              false /*fRing0OrRC*/);
@@ -2651,5 +2885,5 @@
             rc = PDMR3LdrGetInterfaceSymbols(pDevIns->Internal.s.pVMR3,
                                              pvInterface, cbInterface,
-                                             pDevIns->pReg->szR0Mod, pDevIns->Internal.s.pDevR3->pszR0SearchPath,
+                                             pDevIns->pReg->pszR0Mod, pDevIns->Internal.s.pDevR3->pszR0SearchPath,
                                              pszSymPrefix, pszSymList,
                                              true /*fRing0OrRC*/);
@@ -2863,5 +3097,5 @@
     {
         int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pPciBusReg->pszSetIrqRC, &pPciBus->pfnSetIrqRC);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pPciBusReg->pszSetIrqRC, rc));
+        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszRCMod, pPciBusReg->pszSetIrqRC, rc));
         if (RT_FAILURE(rc))
         {
@@ -2883,5 +3117,5 @@
     {
         int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pPciBusReg->pszSetIrqR0, &pPciBus->pfnSetIrqR0);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pPciBusReg->pszSetIrqR0, rc));
+        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszR0Mod, pPciBusReg->pszSetIrqR0, rc));
         if (RT_FAILURE(rc))
         {
@@ -2996,9 +3230,9 @@
     {
         int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pPicReg->pszSetIrqRC, &pVM->pdm.s.Pic.pfnSetIrqRC);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pPicReg->pszSetIrqRC, rc));
+        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszRCMod, pPicReg->pszSetIrqRC, rc));
         if (RT_SUCCESS(rc))
         {
             rc = pdmR3DevGetSymbolRCLazy(pDevIns, pPicReg->pszGetInterruptRC, &pVM->pdm.s.Pic.pfnGetInterruptRC);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pPicReg->pszGetInterruptRC, rc));
+            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszRCMod, pPicReg->pszGetInterruptRC, rc));
         }
         if (RT_FAILURE(rc))
@@ -3022,9 +3256,9 @@
     {
         int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pPicReg->pszSetIrqR0, &pVM->pdm.s.Pic.pfnSetIrqR0);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pPicReg->pszSetIrqR0, rc));
+        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszR0Mod, pPicReg->pszSetIrqR0, rc));
         if (RT_SUCCESS(rc))
         {
             rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pPicReg->pszGetInterruptR0, &pVM->pdm.s.Pic.pfnGetInterruptR0);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pPicReg->pszGetInterruptR0, rc));
+            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszR0Mod, pPicReg->pszGetInterruptR0, rc));
         }
         if (RT_FAILURE(rc))
@@ -3080,5 +3314,5 @@
      */
     pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
-    Assert(pVM->pdm.s.Apic.pDevInsRC);
+    Assert(pVM->pdm.s.Apic.pDevInsRC || !VM_IS_RAW_MODE_ENABLED(pVM));
 
     pVM->pdm.s.Apic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
@@ -3175,4 +3409,5 @@
         return VERR_INVALID_PARAMETER;
     }
+#if 0
     if (    pIoApicReg->pszSetIrqRC
         &&  !pVM->pdm.s.Apic.pDevInsRC)
@@ -3182,4 +3417,5 @@
         return VERR_INVALID_PARAMETER;
     }
+#endif
 
     /*
@@ -3199,5 +3435,5 @@
     {
         int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pIoApicReg->pszSetIrqRC, &pVM->pdm.s.IoApic.pfnSetIrqRC);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pIoApicReg->pszSetIrqRC, rc));
+        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszRCMod, pIoApicReg->pszSetIrqRC, rc));
         if (RT_FAILURE(rc))
         {
@@ -3216,5 +3452,5 @@
     {
         int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pIoApicReg->pszSendMsiRC, &pVM->pdm.s.IoApic.pfnSendMsiRC);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pIoApicReg->pszSendMsiRC, rc));
+        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszRCMod, pIoApicReg->pszSendMsiRC, rc));
         if (RT_FAILURE(rc))
         {
@@ -3231,5 +3467,5 @@
     {
         int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pIoApicReg->pszSetEoiRC, &pVM->pdm.s.IoApic.pfnSetEoiRC);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pIoApicReg->pszSetEoiRC, rc));
+        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszRCMod, pIoApicReg->pszSetEoiRC, rc));
         if (RT_FAILURE(rc))
         {
@@ -3249,5 +3485,5 @@
     {
         int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pIoApicReg->pszSetIrqR0, &pVM->pdm.s.IoApic.pfnSetIrqR0);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pIoApicReg->pszSetIrqR0, rc));
+        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszR0Mod, pIoApicReg->pszSetIrqR0, rc));
         if (RT_FAILURE(rc))
         {
@@ -3267,5 +3503,5 @@
     {
         int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pIoApicReg->pszSendMsiR0, &pVM->pdm.s.IoApic.pfnSendMsiR0);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pIoApicReg->pszSendMsiR0, rc));
+        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszR0Mod, pIoApicReg->pszSendMsiR0, rc));
         if (RT_FAILURE(rc))
         {
@@ -3282,5 +3518,5 @@
     {
         int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pIoApicReg->pszSetEoiR0, &pVM->pdm.s.IoApic.pfnSetEoiR0);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pIoApicReg->pszSetEoiR0, rc));
+        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->pszR0Mod, pIoApicReg->pszSetEoiR0, rc));
         if (RT_FAILURE(rc))
         {
@@ -3767,8 +4003,15 @@
 {
     PDM_DEVHLPR3_VERSION,
+    pdmR3DevHlp_IoPortCreateEx,
+    pdmR3DevHlp_IoPortMap,
+    pdmR3DevHlp_IoPortUnmap,
     pdmR3DevHlp_IOPortRegister,
     pdmR3DevHlp_IOPortRegisterRC,
     pdmR3DevHlp_IOPortRegisterR0,
     pdmR3DevHlp_IOPortDeregister,
+    pdmR3DevHlp_MmioCreateEx,
+    pdmR3DevHlp_MmioMap,
+    pdmR3DevHlp_MmioUnmap,
+    pdmR3DevHlp_MmioReduce,
     pdmR3DevHlp_MMIORegister,
     pdmR3DevHlp_MMIORegisterRC,
@@ -3786,6 +4029,153 @@
     pdmR3DevHlp_ROMProtectShadow,
     pdmR3DevHlp_SSMRegister,
+    SSMR3PutStruct,
+    SSMR3PutStructEx,
+    SSMR3PutBool,
+    SSMR3PutU8,
+    SSMR3PutS8,
+    SSMR3PutU16,
+    SSMR3PutS16,
+    SSMR3PutU32,
+    SSMR3PutS32,
+    SSMR3PutU64,
+    SSMR3PutS64,
+    SSMR3PutU128,
+    SSMR3PutS128,
+    SSMR3PutUInt,
+    SSMR3PutSInt,
+    SSMR3PutGCUInt,
+    SSMR3PutGCUIntReg,
+    SSMR3PutGCPhys32,
+    SSMR3PutGCPhys64,
+    SSMR3PutGCPhys,
+    SSMR3PutGCPtr,
+    SSMR3PutGCUIntPtr,
+    SSMR3PutRCPtr,
+    SSMR3PutIOPort,
+    SSMR3PutSel,
+    SSMR3PutMem,
+    SSMR3PutStrZ,
+    SSMR3GetStruct,
+    SSMR3GetStructEx,
+    SSMR3GetBool,
+    SSMR3GetU8,
+    SSMR3GetS8,
+    SSMR3GetU16,
+    SSMR3GetS16,
+    SSMR3GetU32,
+    SSMR3GetS32,
+    SSMR3GetU64,
+    SSMR3GetS64,
+    SSMR3GetU128,
+    SSMR3GetS128,
+    SSMR3GetUInt,
+    SSMR3GetSInt,
+    SSMR3GetGCUInt,
+    SSMR3GetGCUIntReg,
+    SSMR3GetGCPhys32,
+    SSMR3GetGCPhys64,
+    SSMR3GetGCPhys,
+    SSMR3GetGCPtr,
+    SSMR3GetGCUIntPtr,
+    SSMR3GetRCPtr,
+    SSMR3GetIOPort,
+    SSMR3GetSel,
+    SSMR3GetMem,
+    SSMR3GetStrZ,
+    SSMR3GetStrZEx,
+    SSMR3Skip,
+    SSMR3SkipToEndOfUnit,
+    SSMR3SetLoadError,
+    SSMR3SetLoadErrorV,
+    SSMR3SetCfgError,
+    SSMR3SetCfgErrorV,
+    SSMR3HandleGetStatus,
+    SSMR3HandleGetAfter,
+    SSMR3HandleIsLiveSave,
+    SSMR3HandleMaxDowntime,
+    SSMR3HandleHostBits,
+    SSMR3HandleRevision,
+    SSMR3HandleVersion,
     pdmR3DevHlp_TMTimerCreate,
+    pdmR3DevHlp_TimerCreate,
+    pdmR3DevHlp_TimerToPtr,
+    pdmR3DevHlp_TimerFromMicro,
+    pdmR3DevHlp_TimerFromMilli,
+    pdmR3DevHlp_TimerFromNano,
+    pdmR3DevHlp_TimerGet,
+    pdmR3DevHlp_TimerGetFreq,
+    pdmR3DevHlp_TimerGetNano,
+    pdmR3DevHlp_TimerIsActive,
+    pdmR3DevHlp_TimerIsLockOwner,
+    pdmR3DevHlp_TimerLock,
+    pdmR3DevHlp_TimerSet,
+    pdmR3DevHlp_TimerSetFrequencyHint,
+    pdmR3DevHlp_TimerSetMicro,
+    pdmR3DevHlp_TimerSetMillies,
+    pdmR3DevHlp_TimerSetNano,
+    pdmR3DevHlp_TimerSetRelative,
+    pdmR3DevHlp_TimerStop,
+    pdmR3DevHlp_TimerUnlock,
+    pdmR3DevHlp_TimerSave,
+    pdmR3DevHlp_TimerLoad,
     pdmR3DevHlp_TMUtcNow,
+    CFGMR3Exists,
+    CFGMR3QueryType,
+    CFGMR3QuerySize,
+    CFGMR3QueryInteger,
+    CFGMR3QueryIntegerDef,
+    CFGMR3QueryString,
+    CFGMR3QueryStringDef,
+    CFGMR3QueryBytes,
+    CFGMR3QueryU64,
+    CFGMR3QueryU64Def,
+    CFGMR3QueryS64,
+    CFGMR3QueryS64Def,
+    CFGMR3QueryU32,
+    CFGMR3QueryU32Def,
+    CFGMR3QueryS32,
+    CFGMR3QueryS32Def,
+    CFGMR3QueryU16,
+    CFGMR3QueryU16Def,
+    CFGMR3QueryS16,
+    CFGMR3QueryS16Def,
+    CFGMR3QueryU8,
+    CFGMR3QueryU8Def,
+    CFGMR3QueryS8,
+    CFGMR3QueryS8Def,
+    CFGMR3QueryBool,
+    CFGMR3QueryBoolDef,
+    CFGMR3QueryPort,
+    CFGMR3QueryPortDef,
+    CFGMR3QueryUInt,
+    CFGMR3QueryUIntDef,
+    CFGMR3QuerySInt,
+    CFGMR3QuerySIntDef,
+    CFGMR3QueryPtr,
+    CFGMR3QueryPtrDef,
+    CFGMR3QueryGCPtr,
+    CFGMR3QueryGCPtrDef,
+    CFGMR3QueryGCPtrU,
+    CFGMR3QueryGCPtrUDef,
+    CFGMR3QueryGCPtrS,
+    CFGMR3QueryGCPtrSDef,
+    CFGMR3QueryStringAlloc,
+    CFGMR3QueryStringAllocDef,
+    CFGMR3GetParent,
+    CFGMR3GetChild,
+    CFGMR3GetChildF,
+    CFGMR3GetChildFV,
+    CFGMR3GetFirstChild,
+    CFGMR3GetNextChild,
+    CFGMR3GetName,
+    CFGMR3GetNameLen,
+    CFGMR3AreChildrenValid,
+    CFGMR3GetFirstValue,
+    CFGMR3GetNextValue,
+    CFGMR3GetValueName,
+    CFGMR3GetValueNameLen,
+    CFGMR3GetValueType,
+    CFGMR3AreValuesValid,
+    CFGMR3ValidateConfig,
     pdmR3DevHlp_PhysRead,
     pdmR3DevHlp_PhysWrite,
@@ -3832,4 +4222,14 @@
     pdmR3DevHlp_CritSectGetNopRC,
     pdmR3DevHlp_SetDeviceCritSect,
+    PDMR3CritSectYield,
+    PDMCritSectEnter,
+    PDMCritSectEnterDebug,
+    PDMCritSectTryEnter,
+    PDMCritSectTryEnterDebug,
+    PDMCritSectLeave,
+    PDMCritSectIsOwner,
+    PDMCritSectIsInitialized,
+    PDMCritSectHasWaiters,
+    PDMCritSectGetRecursion,
     pdmR3DevHlp_ThreadCreate,
     pdmR3DevHlp_SetAsyncNotification,
@@ -4042,8 +4442,15 @@
 {
     PDM_DEVHLPR3_VERSION,
+    pdmR3DevHlp_IoPortCreateEx,
+    pdmR3DevHlp_IoPortMap,
+    pdmR3DevHlp_IoPortUnmap,
     pdmR3DevHlp_IOPortRegister,
     pdmR3DevHlp_IOPortRegisterRC,
     pdmR3DevHlp_IOPortRegisterR0,
     pdmR3DevHlp_IOPortDeregister,
+    pdmR3DevHlp_MmioCreateEx,
+    pdmR3DevHlp_MmioMap,
+    pdmR3DevHlp_MmioUnmap,
+    pdmR3DevHlp_MmioReduce,
     pdmR3DevHlp_MMIORegister,
     pdmR3DevHlp_MMIORegisterRC,
@@ -4061,6 +4468,153 @@
     pdmR3DevHlp_ROMProtectShadow,
     pdmR3DevHlp_SSMRegister,
+    SSMR3PutStruct,
+    SSMR3PutStructEx,
+    SSMR3PutBool,
+    SSMR3PutU8,
+    SSMR3PutS8,
+    SSMR3PutU16,
+    SSMR3PutS16,
+    SSMR3PutU32,
+    SSMR3PutS32,
+    SSMR3PutU64,
+    SSMR3PutS64,
+    SSMR3PutU128,
+    SSMR3PutS128,
+    SSMR3PutUInt,
+    SSMR3PutSInt,
+    SSMR3PutGCUInt,
+    SSMR3PutGCUIntReg,
+    SSMR3PutGCPhys32,
+    SSMR3PutGCPhys64,
+    SSMR3PutGCPhys,
+    SSMR3PutGCPtr,
+    SSMR3PutGCUIntPtr,
+    SSMR3PutRCPtr,
+    SSMR3PutIOPort,
+    SSMR3PutSel,
+    SSMR3PutMem,
+    SSMR3PutStrZ,
+    SSMR3GetStruct,
+    SSMR3GetStructEx,
+    SSMR3GetBool,
+    SSMR3GetU8,
+    SSMR3GetS8,
+    SSMR3GetU16,
+    SSMR3GetS16,
+    SSMR3GetU32,
+    SSMR3GetS32,
+    SSMR3GetU64,
+    SSMR3GetS64,
+    SSMR3GetU128,
+    SSMR3GetS128,
+    SSMR3GetUInt,
+    SSMR3GetSInt,
+    SSMR3GetGCUInt,
+    SSMR3GetGCUIntReg,
+    SSMR3GetGCPhys32,
+    SSMR3GetGCPhys64,
+    SSMR3GetGCPhys,
+    SSMR3GetGCPtr,
+    SSMR3GetGCUIntPtr,
+    SSMR3GetRCPtr,
+    SSMR3GetIOPort,
+    SSMR3GetSel,
+    SSMR3GetMem,
+    SSMR3GetStrZ,
+    SSMR3GetStrZEx,
+    SSMR3Skip,
+    SSMR3SkipToEndOfUnit,
+    SSMR3SetLoadError,
+    SSMR3SetLoadErrorV,
+    SSMR3SetCfgError,
+    SSMR3SetCfgErrorV,
+    SSMR3HandleGetStatus,
+    SSMR3HandleGetAfter,
+    SSMR3HandleIsLiveSave,
+    SSMR3HandleMaxDowntime,
+    SSMR3HandleHostBits,
+    SSMR3HandleRevision,
+    SSMR3HandleVersion,
     pdmR3DevHlp_TMTimerCreate,
+    pdmR3DevHlp_TimerCreate,
+    pdmR3DevHlp_TimerToPtr,
+    pdmR3DevHlp_TimerFromMicro,
+    pdmR3DevHlp_TimerFromMilli,
+    pdmR3DevHlp_TimerFromNano,
+    pdmR3DevHlp_TimerGet,
+    pdmR3DevHlp_TimerGetFreq,
+    pdmR3DevHlp_TimerGetNano,
+    pdmR3DevHlp_TimerIsActive,
+    pdmR3DevHlp_TimerIsLockOwner,
+    pdmR3DevHlp_TimerLock,
+    pdmR3DevHlp_TimerSet,
+    pdmR3DevHlp_TimerSetFrequencyHint,
+    pdmR3DevHlp_TimerSetMicro,
+    pdmR3DevHlp_TimerSetMillies,
+    pdmR3DevHlp_TimerSetNano,
+    pdmR3DevHlp_TimerSetRelative,
+    pdmR3DevHlp_TimerStop,
+    pdmR3DevHlp_TimerUnlock,
+    pdmR3DevHlp_TimerSave,
+    pdmR3DevHlp_TimerLoad,
     pdmR3DevHlp_TMUtcNow,
+    CFGMR3Exists,
+    CFGMR3QueryType,
+    CFGMR3QuerySize,
+    CFGMR3QueryInteger,
+    CFGMR3QueryIntegerDef,
+    CFGMR3QueryString,
+    CFGMR3QueryStringDef,
+    CFGMR3QueryBytes,
+    CFGMR3QueryU64,
+    CFGMR3QueryU64Def,
+    CFGMR3QueryS64,
+    CFGMR3QueryS64Def,
+    CFGMR3QueryU32,
+    CFGMR3QueryU32Def,
+    CFGMR3QueryS32,
+    CFGMR3QueryS32Def,
+    CFGMR3QueryU16,
+    CFGMR3QueryU16Def,
+    CFGMR3QueryS16,
+    CFGMR3QueryS16Def,
+    CFGMR3QueryU8,
+    CFGMR3QueryU8Def,
+    CFGMR3QueryS8,
+    CFGMR3QueryS8Def,
+    CFGMR3QueryBool,
+    CFGMR3QueryBoolDef,
+    CFGMR3QueryPort,
+    CFGMR3QueryPortDef,
+    CFGMR3QueryUInt,
+    CFGMR3QueryUIntDef,
+    CFGMR3QuerySInt,
+    CFGMR3QuerySIntDef,
+    CFGMR3QueryPtr,
+    CFGMR3QueryPtrDef,
+    CFGMR3QueryGCPtr,
+    CFGMR3QueryGCPtrDef,
+    CFGMR3QueryGCPtrU,
+    CFGMR3QueryGCPtrUDef,
+    CFGMR3QueryGCPtrS,
+    CFGMR3QueryGCPtrSDef,
+    CFGMR3QueryStringAlloc,
+    CFGMR3QueryStringAllocDef,
+    CFGMR3GetParent,
+    CFGMR3GetChild,
+    CFGMR3GetChildF,
+    CFGMR3GetChildFV,
+    CFGMR3GetFirstChild,
+    CFGMR3GetNextChild,
+    CFGMR3GetName,
+    CFGMR3GetNameLen,
+    CFGMR3AreChildrenValid,
+    CFGMR3GetFirstValue,
+    CFGMR3GetNextValue,
+    CFGMR3GetValueName,
+    CFGMR3GetValueNameLen,
+    CFGMR3GetValueType,
+    CFGMR3AreValuesValid,
+    CFGMR3ValidateConfig,
     pdmR3DevHlp_PhysRead,
     pdmR3DevHlp_PhysWrite,
@@ -4107,4 +4661,14 @@
     pdmR3DevHlp_CritSectGetNopRC,
     pdmR3DevHlp_SetDeviceCritSect,
+    PDMR3CritSectYield,
+    PDMCritSectEnter,
+    PDMCritSectEnterDebug,
+    PDMCritSectTryEnter,
+    PDMCritSectTryEnterDebug,
+    PDMCritSectLeave,
+    PDMCritSectIsOwner,
+    PDMCritSectIsInitialized,
+    PDMCritSectHasWaiters,
+    PDMCritSectGetRecursion,
     pdmR3DevHlp_ThreadCreate,
     pdmR3DevHlp_SetAsyncNotification,
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevice.cpp	(revision 80531)
@@ -23,14 +23,14 @@
 #include "PDMInternal.h"
 #include <VBox/vmm/pdm.h>
+#include <VBox/vmm/apic.h>
+#include <VBox/vmm/cfgm.h>
+#include <VBox/vmm/dbgf.h>
+#include <VBox/vmm/hm.h>
 #include <VBox/vmm/mm.h>
+#include <VBox/vmm/iom.h>
 #include <VBox/vmm/pgm.h>
-#include <VBox/vmm/iom.h>
-#include <VBox/vmm/hm.h>
-#include <VBox/vmm/cfgm.h>
-#include <VBox/vmm/apic.h>
 #ifdef VBOX_WITH_REM
 # include <VBox/vmm/rem.h>
 #endif
-#include <VBox/vmm/dbgf.h>
 #include <VBox/vmm/vm.h>
 #include <VBox/vmm/uvm.h>
@@ -132,15 +132,4 @@
      * Get the RC & R0 devhlps and create the devhlp R3 task queue.
      */
-    PCPDMDEVHLPRC pHlpRC = NIL_RTRCPTR;
-    if (VM_IS_RAW_MODE_ENABLED(pVM))
-    {
-        rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCDevHlp", &pHlpRC);
-        AssertReleaseRCReturn(rc, rc);
-    }
-
-    PCPDMDEVHLPR0 pHlpR0;
-    rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0DevHlp", &pHlpR0);
-    AssertReleaseRCReturn(rc, rc);
-
     rc = PDMR3QueueCreateInternal(pVM, sizeof(PDMDEVHLPTASK), 8, 0, pdmR3DevHlpQueueConsumer, true, "DevHlp",
                                   &pVM->pdm.s.pDevHlpQueueR3);
@@ -273,4 +262,6 @@
     for (i = 0; i < cDevs; i++)
     {
+        PDMDEVREGR3 const * const pReg = paDevs[i].pDev->pReg;
+
         /*
          * Gather a bit of config.
@@ -286,4 +277,36 @@
             return rc;
         }
+
+        /* RZEnabled, R0Enabled, RCEnabled*/
+        bool fR0Enabled = false;
+        bool fRCEnabled = false;
+        if (pReg->fFlags & (PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC))
+        {
+            if (pReg->fFlags & PDM_DEVREG_FLAGS_R0)
+            {
+                if (pReg->fFlags & PDM_DEVREG_FLAGS_REQUIRE_R0)
+                    fR0Enabled = true;
+                else
+                {
+                    rc = CFGMR3QueryBoolDef(paDevs[i].pNode, "R0Enabled", &fR0Enabled,
+                                            !(pReg->fFlags & PDM_DEVREG_FLAGS_OPT_IN_R0));
+                    AssertLogRelRCReturn(rc, rc);
+                }
+            }
+
+            if (pReg->fFlags & PDM_DEVREG_FLAGS_RC)
+            {
+                if (pReg->fFlags & PDM_DEVREG_FLAGS_REQUIRE_RC)
+                    fRCEnabled = true;
+                else
+                {
+                    rc = CFGMR3QueryBoolDef(paDevs[i].pNode, "RCEnabled", &fRCEnabled,
+                                            !(pReg->fFlags & PDM_DEVREG_FLAGS_OPT_IN_RC));
+                    AssertLogRelRCReturn(rc, rc);
+                }
+                fRCEnabled = false;
+            }
+        }
+
         /* config node */
         PCFGMNODE pConfigNode = CFGMR3GetChild(paDevs[i].pNode, "Config");
@@ -302,60 +325,82 @@
          * Allocate the device instance and critical section.
          */
-        AssertReturn(paDevs[i].pDev->cInstances < paDevs[i].pDev->pReg->cMaxInstances, VERR_PDM_TOO_MANY_DEVICE_INSTANCES);
-        size_t cb = RT_UOFFSETOF_DYN(PDMDEVINS, achInstanceData[paDevs[i].pDev->pReg->cbInstance]);
-        cb = RT_ALIGN_Z(cb, 16);
-        PPDMDEVINS pDevIns;
-        if (paDevs[i].pDev->pReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0))
-            rc = MMR3HyperAllocOnceNoRel(pVM, cb, 0, MM_TAG_PDM_DEVICE, (void **)&pDevIns);
+        AssertLogRelReturn(paDevs[i].pDev->cInstances < pReg->cMaxInstances,
+                           VERR_PDM_TOO_MANY_DEVICE_INSTANCES);
+        PPDMDEVINS   pDevIns;
+        PPDMCRITSECT pCritSect;
+        if (fR0Enabled || fRCEnabled)
+        {
+            AssertLogRel(fR0Enabled /* not possible to just enabled raw-mode atm. */);
+
+            rc = PDMR3LdrLoadR0(pVM->pUVM, pReg->pszR0Mod);
+            if (RT_FAILURE(rc))
+                return VMR3SetError(pVM->pUVM, rc, RT_SRC_POS, "Failed to load ring-0 module '%s' for device '%s'",
+                                    pReg->pszR0Mod, pReg->szName);
+
+            PDMDEVICECREATEREQ Req;
+            Req.Hdr.u32Magic     = SUPVMMR0REQHDR_MAGIC;
+            Req.Hdr.cbReq        = sizeof(Req);
+            Req.pDevInsR3        = NULL;
+            Req.fFlags           = pReg->fFlags;
+            Req.fClass           = pReg->fClass;
+            Req.cMaxInstances    = pReg->cMaxInstances;
+            Req.uSharedVersion   = pReg->uSharedVersion;
+            Req.cbInstanceShared = pReg->cbInstanceShared;
+            Req.cbInstanceR3     = pReg->cbInstanceCC;
+            Req.cbInstanceRC     = pReg->cbInstanceRC;
+            Req.iInstance        = paDevs[i].iInstance;
+            Req.fRCEnabled       = fRCEnabled;
+            Req.afReserved[0]    = false;
+            Req.afReserved[1]    = false;
+            Req.afReserved[2]    = false;
+            rc = RTStrCopy(Req.szDevName, sizeof(Req.szDevName), pReg->szName);
+            AssertLogRelRCReturn(rc, rc);
+            rc = RTStrCopy(Req.szModName, sizeof(Req.szModName), pReg->pszR0Mod);
+            AssertLogRelRCReturn(rc, rc);
+            rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_PDM_DEVICE_CREATE, 0, &Req.Hdr);
+            AssertLogRelMsgRCReturn(rc, ("VMMR0_DO_PDM_DEVICE_CREATE for %s failed: %Rrc\n", pReg->szName, rc), rc);
+            pDevIns = Req.pDevInsR3;
+            pCritSect = pDevIns->pCritSectRoR3;
+            Assert(pDevIns->Internal.s.fIntFlags & PDMDEVINSINT_FLAGS_R0_ENABLED);
+        }
         else
+        {
+            uint32_t cb = RT_UOFFSETOF_DYN(PDMDEVINS, achInstanceData[pReg->cbInstanceCC]);
+            uint32_t const offShared = cb;
+            cb  = RT_ALIGN_32(cb, 64);
+            cb += RT_ALIGN_32(pReg->cbInstanceShared, 64);
+            cb += RT_ALIGN_32(sizeof(*pCritSect), 64);
             rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_DEVICE, cb, (void **)&pDevIns);
-        AssertLogRelMsgRCReturn(rc,
-                                ("Failed to allocate %d bytes of instance data for device '%s'. rc=%Rrc\n",
-                                cb, paDevs[i].pDev->pReg->szName, rc),
-                                rc);
-        PPDMCRITSECT pCritSect;
-        if (paDevs[i].pDev->pReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0))
-            rc = MMHyperAlloc(pVM, sizeof(*pCritSect), 0, MM_TAG_PDM_DEVICE, (void **)&pCritSect);
-        else
-            rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_DEVICE, sizeof(*pCritSect), (void **)&pCritSect);
-        AssertLogRelMsgRCReturn(rc, ("Failed to allocate a critical section for the device (%Rrc)\n",  rc), rc);
-
-        /*
-         * Initialize it.
-         */
-        pDevIns->u32Version                     = PDM_DEVINS_VERSION;
-        pDevIns->iInstance                      = paDevs[i].iInstance;
-        //pDevIns->Internal.s.pNextR3             = NULL;
-        //pDevIns->Internal.s.pPerDeviceNextR3    = NULL;
-        pDevIns->Internal.s.pDevR3              = paDevs[i].pDev;
-        pDevIns->Internal.s.pVMR3               = pVM;
-        pDevIns->Internal.s.pVMR0               = pVM->pVMR0ForCall;
-        pDevIns->Internal.s.pVMRC               = pVM->pVMRC;
-        //pDevIns->Internal.s.pLunsR3             = NULL;
-        pDevIns->Internal.s.pCfgHandle          = paDevs[i].pNode;
-        //pDevIns->Internal.s.pHeadPciDevR3       = NULL;
-        //pDevIns->Internal.s.pHeadPciDevR0       = 0;
-        //pDevIns->Internal.s.pHeadPciDevRC       = 0;
-        pDevIns->Internal.s.fIntFlags           = PDMDEVINSINT_FLAGS_SUSPENDED;
-        //pDevIns->Internal.s.uLastIrqTag         = 0;
+            AssertLogRelMsgRCReturn(rc, ("Failed to allocate %zu bytes of instance data for device '%s'. rc=%Rrc\n",
+                                         cb, pReg->szName, rc), rc);
+            /* Initialize it: */
+            pDevIns->u32Version                     = PDM_DEVINSR3_VERSION;
+            pDevIns->iInstance                      = paDevs[i].iInstance;
+            pDevIns->cbRing3                        = cb;
+            //pDevIns->fR0Enabled                     = false;
+            //pDevIns->fRCEnabled                     = false;
+            pDevIns->pvInstanceDataR3               = (uint8_t *)pDevIns + offShared;
+            pDevIns->pvInstanceDataForR3            = &pDevIns->achInstanceData[0];
+            pCritSect = (PPDMCRITSECT)((uint8_t *)pDevIns + cb - RT_ALIGN_32(sizeof(*pCritSect), 64));
+            pDevIns->pCritSectRoR3                  = pCritSect;
+        }
+
         pDevIns->pHlpR3                         = fTrusted ? &g_pdmR3DevHlpTrusted : &g_pdmR3DevHlpUnTrusted;
-        pDevIns->pHlpRC                         = pHlpRC;
-        pDevIns->pHlpR0                         = pHlpR0;
-        pDevIns->pReg                           = paDevs[i].pDev->pReg;
+        pDevIns->pReg                           = pReg;
         pDevIns->pCfg                           = pConfigNode;
         //pDevIns->IBase.pfnQueryInterface        = NULL;
         //pDevIns->fTracing                       = 0;
         pDevIns->idTracing                      = ++pVM->pdm.s.idTracingDev;
-        pDevIns->pvInstanceDataR3               = &pDevIns->achInstanceData[0];
-        pDevIns->pvInstanceDataRC               = pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC
-                                                ? MMHyperR3ToRC(pVM, pDevIns->pvInstanceDataR3) : NIL_RTRCPTR;
-        pDevIns->pvInstanceDataR0               = pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0
-                                                ? MMHyperR3ToR0(pVM, pDevIns->pvInstanceDataR3) : NIL_RTR0PTR;
-
-        pDevIns->pCritSectRoR3                  = pCritSect;
-        pDevIns->pCritSectRoRC                  = pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC
-                                                ? MMHyperR3ToRC(pVM, pCritSect) : NIL_RTRCPTR;
-        pDevIns->pCritSectRoR0                  = pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0
-                                                ? MMHyperR3ToR0(pVM, pCritSect) : NIL_RTR0PTR;
+
+        //pDevIns->Internal.s.pNextR3             = NULL;
+        //pDevIns->Internal.s.pPerDeviceNextR3    = NULL;
+        pDevIns->Internal.s.pDevR3              = paDevs[i].pDev;
+        //pDevIns->Internal.s.pLunsR3             = NULL;
+        //pDevIns->Internal.s.pfnAsyncNotify      = NULL;
+        pDevIns->Internal.s.pCfgHandle          = paDevs[i].pNode;
+        pDevIns->Internal.s.pVMR3               = pVM;
+        //pDevIns->Internal.s.pHeadPciDevR3       = NULL;
+        pDevIns->Internal.s.fIntFlags          |= PDMDEVINSINT_FLAGS_SUSPENDED;
+        //pDevIns->Internal.s.uLastIrqTag         = 0;
 
         rc = pdmR3CritSectInitDeviceAuto(pVM, pDevIns, pCritSect, RT_SRC_POS,
@@ -402,4 +447,26 @@
             return rc == VERR_VERSION_MISMATCH ? VERR_PDM_DEVICE_VERSION_MISMATCH : rc;
         }
+
+        /*
+         * Call the ring-0 constructor if applicable.
+         */
+        if (fR0Enabled)
+        {
+            PDMDEVICEGENCALLREQ Req;
+            Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
+            Req.Hdr.cbReq    = sizeof(Req);
+            Req.enmCall      = PDMDEVICEGENCALL_CONSTRUCT;
+            Req.idxR0Device  = pDevIns->Internal.s.idxR0Device;
+            Req.pDevInsR3    = pDevIns;
+            rc = VMMR3CallR0Emt(pVM, pVM->apCpusR3[0], VMMR0_DO_PDM_DEVICE_GEN_CALL, 0, &Req.Hdr);
+            pDevIns->Internal.s.fIntFlags |= PDMDEVINSINT_FLAGS_R0_CONTRUCT;
+            if (RT_FAILURE(rc))
+            {
+                LogRel(("PDM: Failed to construct (ring-0) '%s'/%d! %Rra\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
+                paDevs[i].pDev->cInstances--;
+                return rc == VERR_VERSION_MISMATCH ? VERR_PDM_DEVICE_VERSION_MISMATCH : rc;
+            }
+        }
+
     } /* for device instances */
 
@@ -493,7 +560,7 @@
 
     /*
-     * Load the internal VMM APIC device.
-     */
-    int rc = APICR3RegisterDevice(&RegCB.Core);
+     * Register the internal VMM APIC device.
+     */
+    int rc = pdmR3DevReg_Register(&RegCB.Core, &g_DeviceAPIC);
     AssertRCReturn(rc, rc);
 
@@ -658,12 +725,12 @@
                     VERR_PDM_INVALID_DEVICE_REGISTRATION);
     AssertMsgReturn(   !(pReg->fFlags & PDM_DEVREG_FLAGS_RC)
-                    || (   pReg->szRCMod[0]
-                        && strlen(pReg->szRCMod) < sizeof(pReg->szRCMod)),
-                    ("Invalid GC module name '%s' - (Device %s)\n", pReg->szRCMod, pReg->szName),
+                    || (   pReg->pszRCMod[0]
+                        && strlen(pReg->pszRCMod) < RT_SIZEOFMEMB(PDMDEVICECREATEREQ, szModName)),
+                    ("Invalid GC module name '%s' - (Device %s)\n", pReg->pszRCMod, pReg->szName),
                     VERR_PDM_INVALID_DEVICE_REGISTRATION);
     AssertMsgReturn(   !(pReg->fFlags & PDM_DEVREG_FLAGS_R0)
-                    || (   pReg->szR0Mod[0]
-                        && strlen(pReg->szR0Mod) < sizeof(pReg->szR0Mod)),
-                    ("Invalid R0 module name '%s' - (Device %s)\n", pReg->szR0Mod, pReg->szName),
+                    || (   pReg->pszR0Mod[0]
+                        && strlen(pReg->pszR0Mod) < RT_SIZEOFMEMB(PDMDEVICECREATEREQ, szModName)),
+                    ("Invalid R0 module name '%s' - (Device %s)\n", pReg->pszR0Mod, pReg->szName),
                     VERR_PDM_INVALID_DEVICE_REGISTRATION);
     AssertMsgReturn((pReg->fFlags & PDM_DEVREG_FLAGS_HOST_BITS_MASK) == PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT,
@@ -679,6 +746,8 @@
                     ("Max instances %u! (Device %s)\n", pReg->cMaxInstances, pReg->szName),
                     VERR_PDM_INVALID_DEVICE_REGISTRATION);
-    AssertMsgReturn(pReg->cbInstance <= (uint32_t)(pReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0)  ? 96 * _1K : _1M),
-                    ("Instance size %d bytes! (Device %s)\n", pReg->cbInstance, pReg->szName),
+    AssertMsgReturn(pReg->cbInstanceShared <= (uint32_t)(pReg->fFlags & (PDM_DEVREG_FLAGS_RC | PDM_DEVREG_FLAGS_R0)  ? 96 * _1K : _1M),
+                    ("Instance size %d bytes! (Device %s)\n", pReg->cbInstanceShared, pReg->szName),
+                    VERR_PDM_INVALID_DEVICE_REGISTRATION);
+    AssertMsgReturn(pReg->cbInstanceCC <= _2M, ("Instance size %d bytes! (Device %s)\n", pReg->cbInstanceCC, pReg->szName),
                     VERR_PDM_INVALID_DEVICE_REGISTRATION);
     AssertMsgReturn(pReg->pfnConstruct,
Index: /trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR3/PDMLdr.cpp	(revision 80531)
@@ -737,4 +737,33 @@
 }
 
+
+/**
+ * Makes sure a ring-0 module is loaded.
+ *
+ * @returns VBox status code.
+ * @param   pUVM            Pointer to the user mode VM structure.
+ */
+VMMR3_INT_DECL(int) PDMR3LdrLoadR0(PUVM pUVM, const char *pszModule)
+{
+    /*
+     * Find the module.
+     */
+    RTCritSectEnter(&pUVM->pdm.s.ListCritSect);
+    for (PPDMMOD pModule = pUVM->pdm.s.pModules; pModule; pModule = pModule->pNext)
+    {
+        if (   pModule->eType == PDMMOD_TYPE_R0
+            && !strcmp(pModule->szName, pszModule))
+        {
+            RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
+            return VINF_SUCCESS;
+        }
+    }
+    RTCritSectLeave(&pUVM->pdm.s.ListCritSect);
+
+    /*
+     * Okay, load it.
+     */
+    return pdmR3LoadR0U(pUVM, NULL, pszModule, NULL);
+}
 
 
Index: /trunk/src/VBox/VMM/VMMR3/SSM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/SSM.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/VMMR3/SSM.cpp	(revision 80531)
@@ -9081,4 +9081,19 @@
 }
 
+
+/**
+ * SSMR3SetLoadError wrapper that returns VERR_SSM_LOAD_CONFIG_MISMATCH.
+ *
+ * @returns VERR_SSM_LOAD_CONFIG_MISMATCH.
+ * @param   pSSM                The saved state handle.
+ * @param   SRC_POS             The error location, use RT_SRC_POS.
+ * @param   pszFormat           The message format string.
+ * @param   va                  Variable argument list.
+ */
+VMMR3DECL(int) SSMR3SetCfgErrorV(PSSMHANDLE pSSM, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
+{
+    return SSMR3SetLoadErrorV(pSSM, VERR_SSM_LOAD_CONFIG_MISMATCH, RT_SRC_POS_ARGS, pszFormat, va);
+}
+
 #endif /* !SSM_STANDALONE */
 
Index: /trunk/src/VBox/VMM/include/APICInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/APICInternal.h	(revision 80530)
+++ /trunk/src/VBox/VMM/include/APICInternal.h	(revision 80531)
@@ -23,7 +23,6 @@
 
 #include <VBox/sup.h>
-#include <VBox/types.h>
+#include <VBox/vmm/pdmdev.h> /* before apic.h! */
 #include <VBox/vmm/apic.h>
-#include <VBox/vmm/pdmdev.h>
 
 /** @defgroup grp_apic_int       Internal
@@ -1434,4 +1433,10 @@
 void                          apicResetCpu(PVMCPUCC pVCpu, bool fResetApicBaseMsr);
 
+DECLCALLBACK(int)             apicR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg);
+DECLCALLBACK(int)             apicR3Destruct(PPDMDEVINS pDevIns);
+DECLCALLBACK(void)            apicR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
+DECLCALLBACK(void)            apicR3Reset(PPDMDEVINS pDevIns);
+DECLCALLBACK(int)             apicR3InitComplete(PPDMDEVINS pDevIns);
+
 RT_C_DECLS_END
 
Index: /trunk/src/VBox/VMM/include/PDMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/PDMInternal.h	(revision 80530)
+++ /trunk/src/VBox/VMM/include/PDMInternal.h	(revision 80531)
@@ -120,4 +120,75 @@
     PDMASYNCCOMPLETIONEPCLASSTYPE_32BIT_HACK = 0x7fffffff
 } PDMASYNCCOMPLETIONEPCLASSTYPE;
+
+/**
+ * Private device instance data, ring-3.
+ */
+typedef struct PDMDEVINSINTR3
+{
+    /** Pointer to the next instance.
+     * (Head is pointed to by PDM::pDevInstances.) */
+    R3PTRTYPE(PPDMDEVINS)           pNextR3;
+    /** Pointer to the next per device instance.
+     * (Head is pointed to by PDMDEV::pInstances.) */
+    R3PTRTYPE(PPDMDEVINS)           pPerDeviceNextR3;
+    /** Pointer to device structure. */
+    R3PTRTYPE(PPDMDEV)              pDevR3;
+    /** Pointer to the list of logical units associated with the device. (FIFO) */
+    R3PTRTYPE(PPDMLUN)              pLunsR3;
+    /** Pointer to the asynchronous notification callback set while in
+     * FNPDMDEVSUSPEND or FNPDMDEVPOWEROFF. */
+    R3PTRTYPE(PFNPDMDEVASYNCNOTIFY) pfnAsyncNotify;
+    /** Configuration handle to the instance node. */
+    R3PTRTYPE(PCFGMNODE)            pCfgHandle;
+
+    /** R3 pointer to the VM this instance was created for. */
+    PVMR3                           pVMR3;
+    /** Associated PCI device list head (first is default). */
+    R3PTRTYPE(PPDMPCIDEV)           pHeadPciDevR3;
+
+    /** Flags, see PDMDEVINSINT_FLAGS_XXX. */
+    uint32_t                        fIntFlags;
+    /** The last IRQ tag (for tracing it thru clearing). */
+    uint32_t                        uLastIrqTag;
+    /** The ring-0 device index (for making ring-0 calls). */
+    uint32_t                        idxR0Device;
+} PDMDEVINSINTR3;
+
+
+/**
+ * Private device instance data, ring-0.
+ */
+typedef struct PDMDEVINSINTR0
+{
+    /** Pointer to the VM this instance was created for. */
+    R0PTRTYPE(PGVM)                 pGVM;
+    /** Associated PCI device list head (first is default). */
+    R0PTRTYPE(PPDMPCIDEV)           pHeadPciDevR0;
+    /** Pointer to device structure. */
+    R0PTRTYPE(struct PDMDEVREGR0 const *) pRegR0;
+    /** The ring-0 module reference. */
+    RTR0PTR                         hMod;
+    /** Pointer to the ring-0 mapping of the ring-3 internal data (for uLastIrqTag). */
+    R0PTRTYPE(PDMDEVINSINTR3 *)     pIntR3R0;
+    /** Pointer to the ring-0 mapping of the ring-3 instance (for idTracing). */
+    R0PTRTYPE(struct PDMDEVINSR3 *) pInsR3R0;
+    /** The device instance memory. */
+    RTR0MEMOBJ                      hMemObj;
+    /** The ring-3 mapping object. */
+    RTR0MEMOBJ                      hMapObj;
+    /** Index into PDMR0PERVM::apDevInstances. */
+    uint32_t                        idxR0Device;
+} PDMDEVINSINTR0;
+
+
+/**
+ * Private device instance data, raw-mode
+ */
+typedef struct PDMDEVINSINTRC
+{
+    /** Pointer to the VM this instance was created for. */
+    RGPTRTYPE(PVM)                  pVMRC;
+} PDMDEVINSINTRC;
+
 
 /**
@@ -166,5 +237,5 @@
  * @{ */
 /** Used by pdmR3Load to mark device instances it found in the saved state. */
-#define PDMDEVINSINT_FLAGS_FOUND         RT_BIT_32(0)
+#define PDMDEVINSINT_FLAGS_FOUND            RT_BIT_32(0)
 /** Indicates that the device hasn't been powered on or resumed.
  * This is used by PDMR3PowerOn, PDMR3Resume, PDMR3Suspend and PDMR3PowerOff
@@ -176,7 +247,13 @@
  * PDMR3Suspend.
  */
-#define PDMDEVINSINT_FLAGS_SUSPENDED     RT_BIT_32(1)
+#define PDMDEVINSINT_FLAGS_SUSPENDED        RT_BIT_32(1)
 /** Indicates that the device has been reset already.  Used by PDMR3Reset. */
-#define PDMDEVINSINT_FLAGS_RESET         RT_BIT_32(2)
+#define PDMDEVINSINT_FLAGS_RESET            RT_BIT_32(2)
+#define PDMDEVINSINT_FLAGS_R0_ENABLED       RT_BIT_32(3)
+#define PDMDEVINSINT_FLAGS_RC_ENABLED       RT_BIT_32(4)
+/** Set if we've called the ring-0 constructor. */
+#define PDMDEVINSINT_FLAGS_R0_CONTRUCT      RT_BIT_32(5)
+/** Set if using non-default critical section.  */
+#define PDMDEVINSINT_FLAGS_CHANGED_CRITSECT RT_BIT_32(6)
 /** @} */
 
@@ -438,5 +515,5 @@
  * device, like for instance the PS/2 keyboard port on the
  * keyboard controller device. The LUNs are chained on the
- * device the belong to (PDMDEVINSINT::pLunsR3).
+ * device they belong to (PDMDEVINSINT::pLunsR3).
  */
 typedef struct PDMLUN
@@ -463,5 +540,5 @@
 
 /**
- * PDM Device.
+ * PDM Device, ring-3.
  */
 typedef struct PDMDEV
@@ -470,7 +547,7 @@
     R3PTRTYPE(PPDMDEV)              pNext;
     /** Device name length. (search optimization) */
-    RTUINT                          cchName;
+    uint32_t                        cchName;
     /** Registration structure. */
-    R3PTRTYPE(const struct PDMDEVREG *) pReg;
+    R3PTRTYPE(const struct PDMDEVREGR3 *) pReg;
     /** Number of instances. */
     uint32_t                        cInstances;
@@ -482,4 +559,24 @@
     char                           *pszR0SearchPath;
 } PDMDEV;
+
+
+#if 0
+/**
+ * PDM Device, ring-0.
+ */
+typedef struct PDMDEVR0
+{
+    /** Pointer to the next device. */
+    R0PTRTYPE(PPDMDEVR0)            pNext;
+    /** Device name length. (search optimization) */
+    uint32_t                        cchName;
+    /** Registration structure. */
+    R3PTRTYPE(const struct PDMDEVREGR0 *) pReg;
+    /** Number of instances. */
+    uint32_t                        cInstances;
+    /** Pointer to chain of instances. */
+    PPDMDEVINSR0                    pInstances;
+} PDMDEVR0;
+#endif
 
 
@@ -1122,4 +1219,15 @@
 
 
+/**
+ * PDM data kept in the ring-0 GVM.
+ */
+typedef struct PDMR0PERVM
+{
+    /** Number of valid ring-0 device instances (apDevInstances). */
+    uint32_t                        cDevInstances;
+    /** Pointer to ring-0 device instances. */
+    R0PTRTYPE(struct PDMDEVINSR0 *) apDevInstances[190];
+} PDMR0PERVM;
+
 
 /**
@@ -1200,5 +1308,5 @@
         AssertPtr(pDevIns); \
         Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \
-        Assert(pDevIns->CTX_SUFF(pvInstanceData) == (void *)&pDevIns->achInstanceData[0]); \
+        Assert(pDevIns->CTX_SUFF(pvInstanceDataFor) == (void *)&pDevIns->achInstanceData[0]); \
     } while (0)
 #else
Index: /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 80530)
+++ /trunk/src/VBox/VMM/testcase/tstVMStructSize.cpp	(revision 80531)
@@ -314,8 +314,18 @@
 
     /* pdm */
-    PRINT_OFFSET(PDMDEVINS, Internal);
-    PRINT_OFFSET(PDMDEVINS, achInstanceData);
-    CHECK_MEMBER_ALIGNMENT(PDMDEVINS, achInstanceData, 64);
-    CHECK_PADDING(PDMDEVINS, Internal, 1);
+    PRINT_OFFSET(PDMDEVINSR3, Internal);
+    PRINT_OFFSET(PDMDEVINSR3, achInstanceData);
+    CHECK_MEMBER_ALIGNMENT(PDMDEVINSR3, achInstanceData, 64);
+    CHECK_PADDING(PDMDEVINSR3, Internal, 1);
+
+    PRINT_OFFSET(PDMDEVINSR0, Internal);
+    PRINT_OFFSET(PDMDEVINSR0, achInstanceData);
+    CHECK_MEMBER_ALIGNMENT(PDMDEVINSR0, achInstanceData, 64);
+    CHECK_PADDING(PDMDEVINSR0, Internal, 1);
+
+    PRINT_OFFSET(PDMDEVINSRC, Internal);
+    PRINT_OFFSET(PDMDEVINSRC, achInstanceData);
+    CHECK_MEMBER_ALIGNMENT(PDMDEVINSRC, achInstanceData, 64);
+    CHECK_PADDING(PDMDEVINSRC, Internal, 1);
 
     PRINT_OFFSET(PDMUSBINS, Internal);
