Index: /trunk/include/VBox/vmm/pdmdev.h
===================================================================
--- /trunk/include/VBox/vmm/pdmdev.h	(revision 81908)
+++ /trunk/include/VBox/vmm/pdmdev.h	(revision 81909)
@@ -1254,5 +1254,5 @@
 
 /**
- * Programmable Interrupt Controller registration structure.
+ * Programmable Interrupt Controller registration structure (all contexts).
  */
 typedef struct PDMPICREG
@@ -1270,5 +1270,5 @@
      * @remarks Caller enters the PDM critical section.
      */
-    DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
+    DECLCALLBACKMEMBER(void, pfnSetIrq)(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc);
 
     /**
@@ -1280,15 +1280,8 @@
      * @remarks Caller enters the PDM critical section.
      */
-    DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
-
-    /** The name of the RC SetIrq entry point. */
-    const char         *pszSetIrqRC;
-    /** The name of the RC GetInterrupt entry point. */
-    const char         *pszGetInterruptRC;
-
-    /** The name of the R0 SetIrq entry point. */
-    const char         *pszSetIrqR0;
-    /** The name of the R0 GetInterrupt entry point. */
-    const char         *pszGetInterruptR0;
+    DECLCALLBACKMEMBER(int, pfnGetInterrupt)(PPDMDEVINS pDevIns, uint32_t *puTagSrc);
+
+    /** Just a safety precaution. */
+    uint32_t                    u32TheEnd;
 } PDMPICREG;
 /** Pointer to a PIC registration structure. */
@@ -1296,12 +1289,12 @@
 
 /** Current PDMPICREG version number. */
-#define PDM_PICREG_VERSION                      PDM_VERSION_MAKE(0xfffa, 2, 0)
-
-/**
- * PIC RC helpers.
- */
-typedef struct PDMPICHLPRC
-{
-    /** Structure version. PDM_PICHLPRC_VERSION defines the current version. */
+#define PDM_PICREG_VERSION                      PDM_VERSION_MAKE(0xfffa, 3, 0)
+
+/**
+ * PIC helpers, same in all contexts.
+ */
+typedef struct PDMPICHLP
+{
+    /** Structure version. PDM_PICHLP_VERSION defines the current version. */
     uint32_t                u32Version;
 
@@ -1311,5 +1304,5 @@
      * @param   pDevIns         Device instance of the PIC.
      */
-    DECLRCCALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
+    DECLCALLBACKMEMBER(void, pfnSetInterruptFF)(PPDMDEVINS pDevIns);
 
     /**
@@ -1318,5 +1311,5 @@
      * @param   pDevIns         Device instance of the PIC.
      */
-    DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
+    DECLCALLBACKMEMBER(void, pfnClearInterruptFF)(PPDMDEVINS pDevIns);
 
     /**
@@ -1328,5 +1321,5 @@
      * @param   rc              What to return if we fail to acquire the lock.
      */
-    DECLRCCALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
+    DECLCALLBACKMEMBER(int,   pfnLock)(PPDMDEVINS pDevIns, int rc);
 
     /**
@@ -1335,143 +1328,16 @@
      * @param   pDevIns         The PIC device instance.
      */
-    DECLRCCALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
+    DECLCALLBACKMEMBER(void,  pfnUnlock)(PPDMDEVINS pDevIns);
 
     /** Just a safety precaution. */
     uint32_t                u32TheEnd;
-} PDMPICHLPRC;
-
-/** Pointer to PIC RC helpers. */
-typedef RCPTRTYPE(PDMPICHLPRC *) PPDMPICHLPRC;
-/** Pointer to const PIC RC helpers. */
-typedef RCPTRTYPE(const PDMPICHLPRC *) PCPDMPICHLPRC;
-
-/** Current PDMPICHLPRC version number. */
-#define PDM_PICHLPRC_VERSION                    PDM_VERSION_MAKE(0xfff9, 2, 0)
-
-
-/**
- * PIC R0 helpers.
- */
-typedef struct PDMPICHLPR0
-{
-    /** Structure version. PDM_PICHLPR0_VERSION defines the current version. */
-    uint32_t                u32Version;
-
-    /**
-     * Set the interrupt force action flag.
-     *
-     * @param   pDevIns         Device instance of the PIC.
-     */
-    DECLR0CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
-
-    /**
-     * Clear the interrupt force action flag.
-     *
-     * @param   pDevIns         Device instance of the PIC.
-     */
-    DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
-
-    /**
-     * Acquires the PDM lock.
-     *
-     * @returns VINF_SUCCESS on success.
-     * @returns rc if we failed to acquire the lock.
-     * @param   pDevIns         The PIC device instance.
-     * @param   rc              What to return if we fail to acquire the lock.
-     */
-    DECLR0CALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
-
-    /**
-     * Releases the PDM lock.
-     *
-     * @param   pDevIns         The PCI device instance.
-     */
-    DECLR0CALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
-
-    /** Just a safety precaution. */
-    uint32_t                u32TheEnd;
-} PDMPICHLPR0;
-
-/** Pointer to PIC R0 helpers. */
-typedef R0PTRTYPE(PDMPICHLPR0 *) PPDMPICHLPR0;
-/** Pointer to const PIC R0 helpers. */
-typedef R0PTRTYPE(const PDMPICHLPR0 *) PCPDMPICHLPR0;
-
-/** Current PDMPICHLPR0 version number. */
-#define PDM_PICHLPR0_VERSION                    PDM_VERSION_MAKE(0xfff8, 1, 0)
-
-/**
- * PIC R3 helpers.
- */
-typedef struct PDMPICHLPR3
-{
-    /** Structure version. PDM_PICHLP_VERSION defines the current version. */
-    uint32_t                u32Version;
-
-    /**
-     * Set the interrupt force action flag.
-     *
-     * @param   pDevIns         Device instance of the PIC.
-     */
-    DECLR3CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
-
-    /**
-     * Clear the interrupt force action flag.
-     *
-     * @param   pDevIns         Device instance of the PIC.
-     */
-    DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
-
-    /**
-     * Acquires the PDM lock.
-     *
-     * @returns VINF_SUCCESS on success.
-     * @returns Fatal error on failure.
-     * @param   pDevIns         The PIC device instance.
-     * @param   rc              Dummy for making the interface identical to the RC and R0 versions.
-     */
-    DECLR3CALLBACKMEMBER(int,   pfnLock,(PPDMDEVINS pDevIns, int rc));
-
-    /**
-     * Releases the PDM lock.
-     *
-     * @param   pDevIns         The PIC device instance.
-     */
-    DECLR3CALLBACKMEMBER(void,  pfnUnlock,(PPDMDEVINS pDevIns));
-
-    /**
-     * Gets the address of the RC PIC helpers.
-     *
-     * This should be called at both construction and relocation time
-     * to obtain the correct address of the RC helpers.
-     *
-     * @returns RC pointer to the PIC helpers.
-     * @param   pDevIns         Device instance of the PIC.
-     */
-    DECLR3CALLBACKMEMBER(PCPDMPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
-
-    /**
-     * Gets the address of the R0 PIC helpers.
-     *
-     * This should be called at both construction and relocation time
-     * to obtain the correct address of the R0 helpers.
-     *
-     * @returns R0 pointer to the PIC helpers.
-     * @param   pDevIns         Device instance of the PIC.
-     */
-    DECLR3CALLBACKMEMBER(PCPDMPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
-
-    /** Just a safety precaution. */
-    uint32_t                u32TheEnd;
-} PDMPICHLPR3;
-
-/** Pointer to PIC R3 helpers. */
-typedef R3PTRTYPE(PDMPICHLPR3 *) PPDMPICHLPR3;
-/** Pointer to const PIC R3 helpers. */
-typedef R3PTRTYPE(const PDMPICHLPR3 *) PCPDMPICHLPR3;
-
-/** Current PDMPICHLPR3 version number. */
-#define PDM_PICHLPR3_VERSION                    PDM_VERSION_MAKE(0xfff7, 1, 0)
-
+} PDMPICHLP;
+/** Pointer to PIC helpers. */
+typedef PDMPICHLP *PPDMPICHLP;
+/** Pointer to const PIC helpers. */
+typedef const PDMPICHLP *PCPDMPICHLP;
+
+/** Current PDMPICHLP version number. */
+#define PDM_PICHLP_VERSION                      PDM_VERSION_MAKE(0xfff9, 3, 0)
 
 
@@ -4033,8 +3899,9 @@
      * @param   pDevIns             The device instance.
      * @param   pPicReg             Pointer to a PIC registration structure.
-     * @param   ppPicHlpR3          Where to store the pointer to the PIC HC
+     * @param   ppPicHlp            Where to store the pointer to the ring-3 PIC
      *                              helpers.
-     */
-    DECLR3CALLBACKMEMBER(int, pfnPICRegister,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3));
+     * @sa      PDMDevHlpPICSetUpContext
+     */
+    DECLR3CALLBACKMEMBER(int, pfnPICRegister,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp));
 
     /**
@@ -4955,4 +4822,18 @@
     DECLRCCALLBACKMEMBER(int, pfnPCIBusSetUpContext,(PPDMDEVINS pDevIns, PPDMPCIBUSREGRC pPciBusReg, PCPDMPCIHLPRC *ppPciHlp));
 
+    /**
+     * Sets up the PIC for the raw-mode context.
+     *
+     * This must be called after ring-3 has registered the PIC using
+     * PDMDevHlpPICRegister().
+     *
+     * @returns VBox status code.
+     * @param   pDevIns     The device instance.
+     * @param   pPicReg     The PIC registration information for ring-0,
+     *                      considered volatile and copied.
+     * @param   ppPciHlp    Where to return the raw-mode PIC helpers.
+     */
+    DECLRCCALLBACKMEMBER(int, pfnPCISetUpContext,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp));
+
     /** Space reserved for future members.
      * @{ */
@@ -4978,5 +4859,5 @@
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 10, 0)
+#define PDM_DEVHLPRC_VERSION                    PDM_VERSION_MAKE(0xffe6, 11, 0)
 
 
@@ -5415,8 +5296,22 @@
      * @param   pDevIns     The device instance.
      * @param   pPciBusReg  The PCI bus registration information for ring-0,
-     *                      considered volatile.
+     *                      considered volatile and copied.
      * @param   ppPciHlp    Where to return the ring-0 PCI bus helpers.
      */
     DECLR0CALLBACKMEMBER(int, pfnPCIBusSetUpContext,(PPDMDEVINS pDevIns, PPDMPCIBUSREGR0 pPciBusReg, PCPDMPCIHLPR0 *ppPciHlp));
+
+    /**
+     * Sets up the PIC for the ring-0 context.
+     *
+     * This must be called after ring-3 has registered the PIC using
+     * PDMDevHlpPICRegister().
+     *
+     * @returns VBox status code.
+     * @param   pDevIns     The device instance.
+     * @param   pPicReg     The PIC registration information for ring-0,
+     *                      considered volatile and copied.
+     * @param   ppPciHlp    Where to return the ring-0 PIC helpers.
+     */
+    DECLR0CALLBACKMEMBER(int, pfnPICSetUpContext,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp));
 
     /** Space reserved for future members.
@@ -5443,5 +5338,5 @@
 
 /** Current PDMDEVHLP version number. */
-#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 11, 0)
+#define PDM_DEVHLPR0_VERSION                    PDM_VERSION_MAKE(0xffe5, 12, 0)
 
 
@@ -7759,5 +7654,5 @@
 #endif
 
-#ifdef IN_RING3
+#if defined(IN_RING3) || defined(DOXYGEN_RUNNING)
 
 /**
@@ -7876,7 +7771,7 @@
  * @copydoc PDMDEVHLPR3::pfnPICRegister
  */
-DECLINLINE(int) PDMDevHlpPICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
-{
-    return pDevIns->pHlpR3->pfnPICRegister(pDevIns, pPicReg, ppPicHlpR3);
+DECLINLINE(int) PDMDevHlpPICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp)
+{
+    return pDevIns->pHlpR3->pfnPICRegister(pDevIns, pPicReg, ppPicHlp);
 }
 
@@ -8017,12 +7912,22 @@
 }
 
-#else  /* !IN_RING3 */
-
-/**
- * @copydoc PDMDEVHLPR0::pfnPCIBusSetUp
+#endif /* IN_RING3 || DOXYGEN_RUNNING */
+
+#if !defined(IN_RING3) || defined(DOXYGEN_RUNNING)
+
+/**
+ * @copydoc PDMDEVHLPR0::pfnPCIBusSetUpContext
  */
 DECLINLINE(int) PDMDevHlpPCIBusSetUpContext(PPDMDEVINS pDevIns, CTX_SUFF(PPDMPCIBUSREG) pPciBusReg, CTX_SUFF(PCPDMPCIHLP) *ppPciHlp)
 {
     return pDevIns->CTX_SUFF(pHlp)->pfnPCIBusSetUpContext(pDevIns, pPciBusReg, ppPciHlp);
+}
+
+/**
+ * @copydoc PDMDEVHLPR0::pfnPICSetUpContext
+ */
+DECLINLINE(int) PDMDevHlpPICSetUpContext(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp)
+{
+    return pDevIns->CTX_SUFF(pHlp)->pfnPICSetUpContext(pDevIns, pPicReg, ppPicHlp);
 }
 
Index: /trunk/src/VBox/Devices/PC/DevPIC.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevPIC.cpp	(revision 81908)
+++ /trunk/src/VBox/Devices/PC/DevPIC.cpp	(revision 81909)
@@ -124,13 +124,13 @@
     PPDMDEVINSR3            pDevInsR3;
     /** Pointer to the PIC R3 helpers. */
-    PCPDMPICHLPR3           pPicHlpR3;
+    R3PTRTYPE(PCPDMPICHLP)  pPicHlpR3;
     /** Pointer to the device instance - R0 Ptr. */
     PPDMDEVINSR0            pDevInsR0;
     /** Pointer to the PIC R0 helpers. */
-    PCPDMPICHLPR0           pPicHlpR0;
+    R0PTRTYPE(PCPDMPICHLP)  pPicHlpR0;
     /** Pointer to the device instance - RC Ptr. */
     PPDMDEVINSRC            pDevInsRC;
     /** Pointer to the PIC RC helpers. */
-    PCPDMPICHLPRC           pPicHlpRC;
+    RCPTRTYPE(PCPDMPICHLP)  pPicHlpRC;
     /** Number of release log entries. Used to prevent flooding. */
     uint32_t                cRelLogEntries;
@@ -725,5 +725,5 @@
  * @callback_method_impl{FNDBGFHANDLERDEV}
  */
-static DECLCALLBACK(void) picInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+static DECLCALLBACK(void) picIR3nfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
 {
     PDEVPIC pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC);
@@ -757,24 +757,26 @@
  * @callback_method_impl{FNSSMDEVSAVEEXEC}
  */
-static DECLCALLBACK(int) picSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
-{
-    PDEVPIC     pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC);
+static DECLCALLBACK(int) picR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
+{
+    PDEVPIC         pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC);
+    PCPDMDEVHLPR3   pHlp  = pDevIns->pHlpR3;
+
     for (unsigned i = 0; i < RT_ELEMENTS(pThis->aPics); i++)
     {
-        SSMR3PutU8(pSSM, pThis->aPics[i].last_irr);
-        SSMR3PutU8(pSSM, pThis->aPics[i].irr);
-        SSMR3PutU8(pSSM, pThis->aPics[i].imr);
-        SSMR3PutU8(pSSM, pThis->aPics[i].isr);
-        SSMR3PutU8(pSSM, pThis->aPics[i].priority_add);
-        SSMR3PutU8(pSSM, pThis->aPics[i].irq_base);
-        SSMR3PutU8(pSSM, pThis->aPics[i].read_reg_select);
-        SSMR3PutU8(pSSM, pThis->aPics[i].poll);
-        SSMR3PutU8(pSSM, pThis->aPics[i].special_mask);
-        SSMR3PutU8(pSSM, pThis->aPics[i].init_state);
-        SSMR3PutU8(pSSM, pThis->aPics[i].auto_eoi);
-        SSMR3PutU8(pSSM, pThis->aPics[i].rotate_on_auto_eoi);
-        SSMR3PutU8(pSSM, pThis->aPics[i].special_fully_nested_mode);
-        SSMR3PutU8(pSSM, pThis->aPics[i].init4);
-        SSMR3PutU8(pSSM, pThis->aPics[i].elcr);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].last_irr);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].irr);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].imr);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].isr);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].priority_add);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].irq_base);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].read_reg_select);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].poll);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].special_mask);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].init_state);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].auto_eoi);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].rotate_on_auto_eoi);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].special_fully_nested_mode);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].init4);
+        pHlp->pfnSSMPutU8(pSSM, pThis->aPics[i].elcr);
     }
     return VINF_SUCCESS;
@@ -785,7 +787,8 @@
  * @callback_method_impl{FNSSMDEVLOADEXEC}
  */
-static DECLCALLBACK(int) picLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
-{
-    PDEVPIC pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC);
+static DECLCALLBACK(int) picR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
+{
+    PDEVPIC         pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC);
+    PCPDMDEVHLPR3   pHlp  = pDevIns->pHlpR3;
 
     if (uVersion != 1)
@@ -795,19 +798,19 @@
     for (unsigned i = 0; i < RT_ELEMENTS(pThis->aPics); i++)
     {
-        SSMR3GetU8(pSSM, &pThis->aPics[i].last_irr);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].irr);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].imr);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].isr);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].priority_add);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].irq_base);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].read_reg_select);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].poll);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].special_mask);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].init_state);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].auto_eoi);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].rotate_on_auto_eoi);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].special_fully_nested_mode);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].init4);
-        SSMR3GetU8(pSSM, &pThis->aPics[i].elcr);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].last_irr);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].irr);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].imr);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].isr);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].priority_add);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].irq_base);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].read_reg_select);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].poll);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].special_mask);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].init_state);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].auto_eoi);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].rotate_on_auto_eoi);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].special_fully_nested_mode);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].init4);
+        pHlp->pfnSSMGetU8(pSSM, &pThis->aPics[i].elcr);
     }
 
@@ -822,9 +825,9 @@
  * @interface_method_impl{PDMDEVREG,pfnReset}
  */
-static DECLCALLBACK(void)  picReset(PPDMDEVINS pDevIns)
+static DECLCALLBACK(void)  picR3Reset(PPDMDEVINS pDevIns)
 {
     PDEVPIC     pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC);
     unsigned    i;
-    LogFlow(("picReset:\n"));
+    LogFlow(("picR3Reset:\n"));
     pThis->pPicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR);
 
@@ -839,5 +842,5 @@
  * @interface_method_impl{PDMDEVREG,pfnRelocate}
  */
-static DECLCALLBACK(void) picRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
+static DECLCALLBACK(void) picR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
 {
     RT_NOREF1(offDelta);
@@ -846,5 +849,5 @@
 
     pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
-    pThis->pPicHlpRC = pThis->pPicHlpR3->pfnGetRCHelpers(pDevIns);
+    pThis->pPicHlpRC += offDelta;
     for (i = 0; i < RT_ELEMENTS(pThis->aPics); i++)
         pThis->aPics[i].pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
@@ -855,12 +858,11 @@
  * @interface_method_impl{PDMDEVREG,pfnConstruct}
  */
-static DECLCALLBACK(int)  picConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
+static DECLCALLBACK(int)  picR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
 {
     PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
-    RT_NOREF1(iInstance);
     PDEVPIC         pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC);
     int             rc;
-    bool            fGCEnabled;
-    bool            fR0Enabled;
+    RT_NOREF(iInstance, pCfg);
+
     Assert(iInstance == 0);
 
@@ -868,18 +870,6 @@
      * Validate and read configuration.
      */
-    if (!CFGMR3AreValuesValid(pCfg, "GCEnabled\0" "R0Enabled\0"))
-        return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
-
-    rc = CFGMR3QueryBoolDef(pCfg, "GCEnabled", &fGCEnabled, true);
-    if (RT_FAILURE(rc))
-        return PDMDEV_SET_ERROR(pDevIns, rc,
-                                N_("Configuration error: failed to read GCEnabled as boolean"));
-
-    rc = CFGMR3QueryBoolDef(pCfg, "R0Enabled", &fR0Enabled, true);
-    if (RT_FAILURE(rc))
-        return PDMDEV_SET_ERROR(pDevIns, rc,
-                                N_("Configuration error: failed to read R0Enabled as boolean"));
-
-    Log(("DevPIC: fGCEnabled=%RTbool fR0Enabled=%RTbool\n", fGCEnabled, fR0Enabled));
+    PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "", "");
+    Log(("DevPIC: fRCEnabled=%RTbool fR0Enabled=%RTbool\n", pDevIns->fRCEnabled, pDevIns->fR0Enabled));
 
     /*
@@ -907,35 +897,9 @@
     PDMPICREG PicReg;
     PicReg.u32Version           = PDM_PICREG_VERSION;
-    PicReg.pfnSetIrqR3          = picSetIrq;
-    PicReg.pfnGetInterruptR3    = picGetInterrupt;
-
-    if (fGCEnabled)
-    {
-        PicReg.pszSetIrqRC          = "picSetIrq";
-        PicReg.pszGetInterruptRC    = "picGetInterrupt";
-    }
-    else
-    {
-        PicReg.pszSetIrqRC          = NULL;
-        PicReg.pszGetInterruptRC    = NULL;
-    }
-
-    if (fR0Enabled)
-    {
-        PicReg.pszSetIrqR0          = "picSetIrq";
-        PicReg.pszGetInterruptR0    = "picGetInterrupt";
-    }
-    else
-    {
-        PicReg.pszSetIrqR0          = NULL;
-        PicReg.pszGetInterruptR0    = NULL;
-    }
-
+    PicReg.pfnSetIrq            = picSetIrq;
+    PicReg.pfnGetInterrupt      = picGetInterrupt;
+    PicReg.u32TheEnd            = PDM_PICREG_VERSION;
     rc = PDMDevHlpPICRegister(pDevIns, &PicReg, &pThis->pPicHlpR3);
-    AssertLogRelMsgRCReturn(rc, ("PICRegister -> %Rrc\n", rc), rc);
-    if (fGCEnabled)
-        pThis->pPicHlpRC = pThis->pPicHlpR3->pfnGetRCHelpers(pDevIns);
-    if (fR0Enabled)
-        pThis->pPicHlpR0 = pThis->pPicHlpR3->pfnGetR0Helpers(pDevIns);
+    AssertLogRelMsgRCReturn(rc, ("PDMDevHlpPICRegister -> %Rrc\n", rc), rc);
 
     /*
@@ -955,5 +919,5 @@
     if (RT_FAILURE(rc))
         return rc;
-    if (fGCEnabled)
+    if (pDevIns->fRCEnabled)
     {
         rc = PDMDevHlpIOPortRegisterRC(pDevIns,  0x20, 2, 0, "picIOPortWrite", "picIOPortRead", NULL, NULL, "i8259 PIC #0");
@@ -964,5 +928,5 @@
             return rc;
     }
-    if (fR0Enabled)
+    if (pDevIns->fR0Enabled)
     {
         rc = PDMDevHlpIOPortRegisterR0(pDevIns,  0x20, 2, 0, "picIOPortWrite", "picIOPortRead", NULL, NULL, "i8259 PIC #0");
@@ -982,5 +946,5 @@
     if (RT_FAILURE(rc))
         return rc;
-    if (fGCEnabled)
+    if (pDevIns->fRCEnabled)
     {
         RTRCPTR pDataRC = PDMINS_2_DATA_RCPTR(pDevIns);
@@ -994,5 +958,5 @@
             return rc;
     }
-    if (fR0Enabled)
+    if (pDevIns->fR0Enabled)
     {
         RTR0PTR pDataR0 = PDMINS_2_DATA_R0PTR(pDevIns);
@@ -1007,5 +971,5 @@
     }
 
-    rc = PDMDevHlpSSMRegister(pDevIns, 1 /* uVersion */, sizeof(*pThis), picSaveExec, picLoadExec);
+    rc = PDMDevHlpSSMRegister(pDevIns, 1 /* uVersion */, sizeof(*pThis), picR3SaveExec, picR3LoadExec);
     if (RT_FAILURE(rc))
         return rc;
@@ -1015,10 +979,10 @@
      * Register the info item.
      */
-    PDMDevHlpDBGFInfoRegister(pDevIns, "pic", "PIC info.", picInfo);
+    PDMDevHlpDBGFInfoRegister(pDevIns, "pic", "PIC info.", picIR3nfo);
 
     /*
      * Initialize the device state.
      */
-    picReset(pDevIns);
+    picR3Reset(pDevIns);
 
 #ifdef VBOX_WITH_STATISTICS
@@ -1037,5 +1001,29 @@
 }
 
-#endif /* IN_RING3 */
+#else  /* !IN_RING3 */
+
+/**
+ * @callback_method_impl{PDMDEVREGR0,pfnConstruct}
+ */
+static DECLCALLBACK(int) picRZConstruct(PPDMDEVINS pDevIns)
+{
+    PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
+    PDEVPIC pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPIC);
+
+    int rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
+    AssertRCReturn(rc, rc);
+
+    PDMPICREG PicReg;
+    PicReg.u32Version           = PDM_PICREG_VERSION;
+    PicReg.pfnSetIrq            = picSetIrq;
+    PicReg.pfnGetInterrupt      = picGetInterrupt;
+    PicReg.u32TheEnd            = PDM_PICREG_VERSION;
+    rc = PDMDevHlpPICSetUpContext(pDevIns, &PicReg, &pThis->CTX_SUFF(pPicHlp));
+    AssertLogRelMsgRCReturn(rc, ("PDMDevHlpPICSetUpContext -> %Rrc\n", rc), rc);
+
+    return VINF_SUCCESS;
+}
+
+#endif /* !IN_RING3 */
 
 /**
@@ -1060,10 +1048,10 @@
     /* .pszRCMod = */               "VBoxDDRC.rc",
     /* .pszR0Mod = */               "VBoxDDR0.r0",
-    /* .pfnConstruct = */           picConstruct,
+    /* .pfnConstruct = */           picR3Construct,
     /* .pfnDestruct = */            NULL,
-    /* .pfnRelocate = */            picRelocate,
+    /* .pfnRelocate = */            picR3Relocate,
     /* .pfnMemSetup = */            NULL,
     /* .pfnPowerOn = */             NULL,
-    /* .pfnReset = */               picReset,
+    /* .pfnReset = */               picR3Reset,
     /* .pfnSuspend = */             NULL,
     /* .pfnResume = */              NULL,
@@ -1084,5 +1072,5 @@
 #elif defined(IN_RING0)
     /* .pfnEarlyConstruct = */      NULL,
-    /* .pfnConstruct = */           NULL,
+    /* .pfnConstruct = */           picRZConstruct,
     /* .pfnDestruct = */            NULL,
     /* .pfnFinalDestruct = */       NULL,
@@ -1097,5 +1085,5 @@
     /* .pfnReserved7 = */           NULL,
 #elif defined(IN_RC)
-    /* .pfnConstruct = */           NULL,
+    /* .pfnConstruct = */           picRZConstruct,
     /* .pfnReserved0 = */           NULL,
     /* .pfnReserved1 = */           NULL,
Index: /trunk/src/VBox/VMM/VMMAll/APICAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 81908)
+++ /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 81909)
@@ -2683,4 +2683,6 @@
  * @param   rcRZ        The return code if the operation cannot be performed in
  *                      the current context.
+ *
+ * @note    All callers totally ignores the status code!
  */
 VMM_INT_DECL(VBOXSTRICTRC) APICLocalInterrupt(PVMCPUCC pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ)
@@ -2808,7 +2810,7 @@
                 default:
                 {
-                    rcStrict = VERR_INTERNAL_ERROR_3;
                     AssertMsgFailed(("APIC%u: LocalInterrupt: Invalid delivery mode %#x (%s) on LINT%d\n", pVCpu->idCpu,
                                      enmDeliveryMode, apicGetDeliveryModeName(enmDeliveryMode), u8Pin));
+                    rcStrict = VERR_INTERNAL_ERROR_3;
                     break;
                 }
Index: /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 81908)
+++ /trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 81909)
@@ -54,5 +54,5 @@
 RT_C_DECLS_BEGIN
 extern DECLEXPORT(const PDMDEVHLPR0)    g_pdmR0DevHlp;
-extern DECLEXPORT(const PDMPICHLPR0)    g_pdmR0PicHlp;
+extern DECLEXPORT(const PDMPICHLP)      g_pdmR0PicHlp;
 extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp;
 extern DECLEXPORT(const PDMPCIHLPR0)    g_pdmR0PciHlp;
@@ -1093,4 +1093,51 @@
 
     LogFlow(("pdmR0DevHlp_PCIBusSetUpContext: caller='%p'/%d: returns VINF_SUCCESS\n", pDevIns, pDevIns->iInstance));
+    return VINF_SUCCESS;
+}
+
+
+/** @interface_method_impl{PDMDEVHLPR0,pfnPICSetUpContext} */
+static DECLCALLBACK(int) pdmR0DevHlp_PICSetUpContext(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    LogFlow(("pdmR0DevHlp_PICSetUpContext: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pfnGetInterruptR3=%p, .pszGetIrqRC=%p:{%s}, .pszGetInterruptRC=%p:{%s}, .pszGetIrqR0=%p:{%s}, .pszGetInterruptR0=%p:{%s} } ppPicHlp=%p\n",
+             pDevIns->pReg->szName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrq, pPicReg->pfnGetInterrupt, ppPicHlp));
+    PGVM pGVM = pDevIns->Internal.s.pGVM;
+
+    /*
+     * Validate input.
+     */
+    AssertMsgReturn(pPicReg->u32Version == PDM_PICREG_VERSION,
+                    ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32Version, PDM_PICREG_VERSION),
+                    VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pPicReg->pfnSetIrq, VERR_INVALID_POINTER);
+    AssertPtrReturn(pPicReg->pfnGetInterrupt, VERR_INVALID_POINTER);
+    AssertMsgReturn(pPicReg->u32TheEnd == PDM_PICREG_VERSION,
+                    ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32TheEnd, PDM_PICREG_VERSION),
+                    VERR_INVALID_PARAMETER);
+    AssertPtrReturn(ppPicHlp, VERR_INVALID_POINTER);
+
+    VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
+    VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
+
+    /* Check that it's the same device as made the ring-3 registrations: */
+    AssertLogRelMsgReturn(pGVM->pdm.s.Pic.pDevInsR3 == pDevIns->pDevInsForR3,
+                          ("%p vs %p\n", pGVM->pdm.s.Pic.pDevInsR3, pDevIns->pDevInsForR3), VERR_NOT_OWNER);
+
+    /* Check that it isn't already registered in ring-0: */
+    AssertLogRelMsgReturn(pGVM->pdm.s.Pic.pDevInsR0 == NULL, ("%p (caller pDevIns=%p)\n", pGVM->pdm.s.Pic.pDevInsR0, pDevIns),
+                          VERR_ALREADY_EXISTS);
+
+    /*
+     * Take down the callbacks and instance.
+     */
+    pGVM->pdm.s.Pic.pDevInsR0 = pDevIns;
+    pGVM->pdm.s.Pic.pfnSetIrqR0 = pPicReg->pfnSetIrq;
+    pGVM->pdm.s.Pic.pfnGetInterruptR0 = pPicReg->pfnGetInterrupt;
+    Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
+
+    /* set the helper pointer and return. */
+    *ppPicHlp = &g_pdmR0PicHlp;
+    LogFlow(("pdmR0DevHlp_PICSetUpContext: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
     return VINF_SUCCESS;
 }
@@ -1174,4 +1221,5 @@
     pdmR0DevHlp_DBGFTraceBuf,
     pdmR0DevHlp_PCIBusSetUpContext,
+    pdmR0DevHlp_PICSetUpContext,
     NULL /*pfnReserved1*/,
     NULL /*pfnReserved2*/,
@@ -1196,5 +1244,5 @@
  */
 
-/** @interface_method_impl{PDMPICHLPR0,pfnSetInterruptFF} */
+/** @interface_method_impl{PDMPICHLP,pfnSetInterruptFF} */
 static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
 {
@@ -1207,5 +1255,5 @@
 
 
-/** @interface_method_impl{PDMPICHLPR0,pfnClearInterruptFF} */
+/** @interface_method_impl{PDMPICHLP,pfnClearInterruptFF} */
 static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
 {
@@ -1218,5 +1266,5 @@
 
 
-/** @interface_method_impl{PDMPICHLPR0,pfnLock} */
+/** @interface_method_impl{PDMPICHLP,pfnLock} */
 static DECLCALLBACK(int) pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
 {
@@ -1226,5 +1274,5 @@
 
 
-/** @interface_method_impl{PDMPICHLPR0,pfnUnlock} */
+/** @interface_method_impl{PDMPICHLP,pfnUnlock} */
 static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns)
 {
@@ -1237,12 +1285,12 @@
  * The Ring-0 PIC Helper Callbacks.
  */
-extern DECLEXPORT(const PDMPICHLPR0) g_pdmR0PicHlp =
-{
-    PDM_PICHLPR0_VERSION,
+extern DECLEXPORT(const PDMPICHLP) g_pdmR0PicHlp =
+{
+    PDM_PICHLP_VERSION,
     pdmR0PicHlp_SetInterruptFF,
     pdmR0PicHlp_ClearInterruptFF,
     pdmR0PicHlp_Lock,
     pdmR0PicHlp_Unlock,
-    PDM_PICHLPR0_VERSION
+    PDM_PICHLP_VERSION
 };
 
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 81908)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 81909)
@@ -3678,137 +3678,44 @@
 
 /** @interface_method_impl{PDMDEVHLPR3,pfnPICRegister} */
-static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
+static DECLCALLBACK(int) pdmR3DevHlp_PICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLP *ppPicHlp)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
-    LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pfnGetInterruptR3=%p, .pszGetIrqRC=%p:{%s}, .pszGetInterruptRC=%p:{%s}, .pszGetIrqR0=%p:{%s}, .pszGetInterruptR0=%p:{%s} } ppPicHlpR3=%p\n",
-             pDevIns->pReg->szName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrqR3, pPicReg->pfnGetInterruptR3,
-             pPicReg->pszSetIrqRC, pPicReg->pszSetIrqRC, pPicReg->pszGetInterruptRC, pPicReg->pszGetInterruptRC,
-             pPicReg->pszSetIrqR0, pPicReg->pszSetIrqR0, pPicReg->pszGetInterruptR0, pPicReg->pszGetInterruptR0,
-             ppPicHlpR3));
+    LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: pPicReg=%p:{.u32Version=%#x, .pfnSetIrqR3=%p, .pfnGetInterruptR3=%p, .pszGetIrqRC=%p:{%s}, .pszGetInterruptRC=%p:{%s}, .pszGetIrqR0=%p:{%s}, .pszGetInterruptR0=%p:{%s} } ppPicHlp=%p\n",
+             pDevIns->pReg->szName, pDevIns->iInstance, pPicReg, pPicReg->u32Version, pPicReg->pfnSetIrq, pPicReg->pfnGetInterrupt, ppPicHlp));
+    PVM pVM = pDevIns->Internal.s.pVMR3;
 
     /*
      * Validate input.
      */
-    if (pPicReg->u32Version != PDM_PICREG_VERSION)
-    {
-        AssertMsgFailed(("u32Version=%#x expected %#x\n", pPicReg->u32Version, PDM_PICREG_VERSION));
-        LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
-    if (    !pPicReg->pfnSetIrqR3
-        ||  !pPicReg->pfnGetInterruptR3)
-    {
-        Assert(pPicReg->pfnSetIrqR3);
-        Assert(pPicReg->pfnGetInterruptR3);
-        LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (R3 callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
-    if (    (   pPicReg->pszSetIrqRC
-             || pPicReg->pszGetInterruptRC)
-        &&  (   !VALID_PTR(pPicReg->pszSetIrqRC)
-             || !VALID_PTR(pPicReg->pszGetInterruptRC))
-       )
-    {
-        Assert(VALID_PTR(pPicReg->pszSetIrqRC));
-        Assert(VALID_PTR(pPicReg->pszGetInterruptRC));
-        LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (RC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
-    if (    pPicReg->pszSetIrqRC
-        &&  !(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC))
-    {
-        Assert(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_RC);
-        LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (RC flag)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
-    if (    pPicReg->pszSetIrqR0
-        &&  !(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0))
-    {
-        Assert(pDevIns->pReg->fFlags & PDM_DEVREG_FLAGS_R0);
-        LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (R0 flag)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
-    if (!ppPicHlpR3)
-    {
-        Assert(ppPicHlpR3);
-        LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc (ppPicHlpR3)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
+    AssertMsgReturn(pPicReg->u32Version == PDM_PICREG_VERSION,
+                    ("%s/%d: u32Version=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32Version, PDM_PICREG_VERSION),
+                    VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pPicReg->pfnSetIrq, VERR_INVALID_POINTER);
+    AssertPtrReturn(pPicReg->pfnGetInterrupt, VERR_INVALID_POINTER);
+    AssertMsgReturn(pPicReg->u32TheEnd == PDM_PICREG_VERSION,
+                    ("%s/%d: u32TheEnd=%#x expected %#x\n", pDevIns->pReg->szName, pDevIns->iInstance, pPicReg->u32TheEnd, PDM_PICREG_VERSION),
+                    VERR_INVALID_PARAMETER);
+    AssertPtrReturn(ppPicHlp, VERR_INVALID_POINTER);
+
+    VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_WRONG_ORDER);
+    VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
 
     /*
      * Only one PIC device.
      */
-    PVM pVM = pDevIns->Internal.s.pVMR3;
-    if (pVM->pdm.s.Pic.pDevInsR3)
-    {
-        AssertMsgFailed(("Only one pic device is supported!\n"));
-        LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
-
-    /*
-     * RC stuff.
-     */
-    if (pPicReg->pszSetIrqRC)
-    {
-        int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pPicReg->pszSetIrqRC, &pVM->pdm.s.Pic.pfnSetIrqRC);
-        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->pszRCMod, pPicReg->pszGetInterruptRC, rc));
-        }
-        if (RT_FAILURE(rc))
-        {
-            LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
-            return rc;
-        }
-        pVM->pdm.s.Pic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
-    }
-    else
-    {
-        pVM->pdm.s.Pic.pDevInsRC = 0;
-        pVM->pdm.s.Pic.pfnSetIrqRC = 0;
-        pVM->pdm.s.Pic.pfnGetInterruptRC = 0;
-    }
-
-    /*
-     * R0 stuff.
-     */
-    if (pPicReg->pszSetIrqR0)
-    {
-        int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pPicReg->pszSetIrqR0, &pVM->pdm.s.Pic.pfnSetIrqR0);
-        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->pszR0Mod, pPicReg->pszGetInterruptR0, rc));
-        }
-        if (RT_FAILURE(rc))
-        {
-            LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
-            return rc;
-        }
-        pVM->pdm.s.Pic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
-        Assert(pVM->pdm.s.Pic.pDevInsR0);
-    }
-    else
-    {
-        pVM->pdm.s.Pic.pfnSetIrqR0 = 0;
-        pVM->pdm.s.Pic.pfnGetInterruptR0 = 0;
-        pVM->pdm.s.Pic.pDevInsR0 = 0;
-    }
-
-    /*
-     * R3 stuff.
+    AssertMsgReturn(pVM->pdm.s.Pic.pDevInsR3 == NULL, ("%s/%d: Only one PIC!\n", pDevIns->pReg->szName, pDevIns->iInstance),
+                    VERR_ALREADY_EXISTS);
+
+    /*
+     * Take down the callbacks and instance.
      */
     pVM->pdm.s.Pic.pDevInsR3 = pDevIns;
-    pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrqR3;
-    pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterruptR3;
+    pVM->pdm.s.Pic.pfnSetIrqR3 = pPicReg->pfnSetIrq;
+    pVM->pdm.s.Pic.pfnGetInterruptR3 = pPicReg->pfnGetInterrupt;
     Log(("PDM: Registered PIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
 
     /* set the helper pointer and return. */
-    *ppPicHlpR3 = &g_pdmR3DevPicHlp;
+    *ppPicHlp = &g_pdmR3DevPicHlp;
     LogFlow(("pdmR3DevHlp_PICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
     return VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp	(revision 81908)
+++ /trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp	(revision 81909)
@@ -45,10 +45,10 @@
  */
 
-/** @interface_method_impl{PDMPICHLPR3,pfnSetInterruptFF} */
+/** @interface_method_impl{PDMPICHLP,pfnSetInterruptFF} */
 static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM    pVM = pDevIns->Internal.s.pVMR3;
-    PVMCPU pVCpu = pVM->apCpusR3[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+    PVMCPU pVCpu = pVM->apCpusR3[0];  /* for PIC we always deliver to CPU 0, SMP uses APIC */
 
     /* IRQ state should be loaded as-is by "LoadExec". Changes can be made from LoadDone. */
@@ -59,10 +59,10 @@
 
 
-/** @interface_method_impl{PDMPICHLPR3,pfnClearInterruptFF} */
+/** @interface_method_impl{PDMPICHLP,pfnClearInterruptFF} */
 static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM pVM = pDevIns->Internal.s.pVMR3;
-    PVMCPU pVCpu = pVM->apCpusR3[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
+    PVMCPU pVCpu = pVM->apCpusR3[0];  /* for PIC we always deliver to CPU 0, SMP uses APIC */
 
     /* IRQ state should be loaded as-is by "LoadExec". Changes can be made from LoadDone. */
@@ -73,5 +73,5 @@
 
 
-/** @interface_method_impl{PDMPICHLPR3,pfnLock} */
+/** @interface_method_impl{PDMPICHLP,pfnLock} */
 static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
 {
@@ -81,5 +81,5 @@
 
 
-/** @interface_method_impl{PDMPICHLPR3,pfnUnlock} */
+/** @interface_method_impl{PDMPICHLP,pfnUnlock} */
 static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns)
 {
@@ -89,54 +89,15 @@
 
 
-/** @interface_method_impl{PDMPICHLPR3,pfnGetRCHelpers} */
-static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMR3;
-    VM_ASSERT_EMT(pVM);
-
-    RTRCPTR pRCHelpers = NIL_RTRCPTR;
-    if (VM_IS_RAW_MODE_ENABLED(pVM))
-    {
-        int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPicHlp", &pRCHelpers);
-        AssertReleaseRC(rc);
-        AssertRelease(pRCHelpers);
-    }
-
-    LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
-             pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
-    return pRCHelpers;
-}
-
-
-/** @interface_method_impl{PDMPICHLPR3,pfnGetR0Helpers} */
-static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMR3;
-    VM_ASSERT_EMT(pVM);
-    PCPDMPICHLPR0 pR0Helpers = 0;
-    int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PicHlp", &pR0Helpers);
-    AssertReleaseRC(rc);
-    AssertRelease(pR0Helpers);
-    LogFlow(("pdmR3PicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
-             pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
-    return pR0Helpers;
-}
-
-
 /**
  * PIC Device Helpers.
  */
-const PDMPICHLPR3 g_pdmR3DevPicHlp =
-{
-    PDM_PICHLPR3_VERSION,
+const PDMPICHLP g_pdmR3DevPicHlp =
+{
+    PDM_PICHLP_VERSION,
     pdmR3PicHlp_SetInterruptFF,
     pdmR3PicHlp_ClearInterruptFF,
     pdmR3PicHlp_Lock,
     pdmR3PicHlp_Unlock,
-    pdmR3PicHlp_GetRCHelpers,
-    pdmR3PicHlp_GetR0Helpers,
-    PDM_PICHLPR3_VERSION /* the end */
+    PDM_PICHLP_VERSION /* the end */
 };
 
Index: /trunk/src/VBox/VMM/include/PDMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/PDMInternal.h	(revision 81908)
+++ /trunk/src/VBox/VMM/include/PDMInternal.h	(revision 81909)
@@ -1388,5 +1388,5 @@
 extern const PDMDEVHLPR3    g_pdmR3DevHlpTrusted;
 extern const PDMDEVHLPR3    g_pdmR3DevHlpUnTrusted;
-extern const PDMPICHLPR3    g_pdmR3DevPicHlp;
+extern const PDMPICHLP      g_pdmR3DevPicHlp;
 extern const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp;
 extern const PDMFWHLPR3     g_pdmR3DevFirmwareHlp;
