Index: trunk/src/VBox/Devices/Network/DevPCNet.cpp
===================================================================
--- trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 11197)
+++ trunk/src/VBox/Devices/Network/DevPCNet.cpp	(revision 11199)
@@ -1,5 +1,11 @@
 /* $Id$ */
 /** @file
- * AMD PCnet-PCI II / PCnet-FAST III (Am79C970A / Am79C973) Ethernet Controller Emulation.
+ * DevPCNet - AMD PCnet-PCI II / PCnet-FAST III (Am79C970A / Am79C973) Ethernet Controller Emulation.
+ *
+ * This software was written to be compatible with the specifications:
+ *      AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
+ *      AMD Publication# 19436  Rev:E  Amendment/0  Issue Date: June 2000
+ * and
+ *      todo
  */
 
@@ -43,9 +49,4 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
- */
-
-/* This software was written to be compatible with the specification:
- * AMD Am79C970A PCnet-PCI II Ethernet Controller Data-Sheet
- * AMD Publication# 19436  Rev:E  Amendment/0  Issue Date: June 2000
  */
 
@@ -68,5 +69,5 @@
 #endif
 
-#include "Builtins.h"
+#include "../Builtins.h"
 
 /* Enable this to catch writes to the ring descriptors instead of using excessive polling */
@@ -111,8 +112,10 @@
     PCIDEVICE                           PciDev;
 #ifndef PCNET_NO_POLLING
-    /** Poll timer (address for host context) */
-    R3R0PTRTYPE(PTMTIMER)               pTimerPollHC;
-    /** Poll timer (address for guest context) */
-    RCPTRTYPE(PTMTIMER)                 pTimerPollGC;
+    /** Poll timer - R3. */
+    PTMTIMERR3                          pTimerPollR3;
+    /** Poll timer - R0. */
+    PTMTIMERR0                          pTimerPollR0;
+    /** Poll timer - RC. */
+    PTMTIMERRC                          pTimerPollRC;
 #endif
 
@@ -121,8 +124,10 @@
 #endif
 
-    /** Software Interrupt timer (address for host context) */
-    R3R0PTRTYPE(PTMTIMER)               pTimerSoftIntHC;
-    /** Software Interrupt timer (address for guest context) */
-    RCPTRTYPE(PTMTIMER)                 pTimerSoftIntGC;
+    /** Software Interrupt timer - R3. */
+    PTMTIMERR3                          pTimerSoftIntR3;
+    /** Software Interrupt timer - R0. */
+    PTMTIMERR0                          pTimerSoftIntR0;
+    /** Software Interrupt timer - RC. */
+    PTMTIMERRC                          pTimerSoftIntRC;
 
     /** Register Address Pointer */
@@ -165,15 +170,23 @@
     RTGCPHYS32                          GCUpperPhys;
 
-    /** Transmit signaller */
-    RCPTRTYPE(PPDMQUEUE)                pXmitQueueGC;
-    R3R0PTRTYPE(PPDMQUEUE)              pXmitQueueHC;
-
-    /** Receive signaller */
-    R3R0PTRTYPE(PPDMQUEUE)              pCanRxQueueHC;
-    RCPTRTYPE(PPDMQUEUE)                pCanRxQueueGC;
-    /** Pointer to the device instance. */
-    RCPTRTYPE(PPDMDEVINS)               pDevInsGC;
-    /** Pointer to the device instance. */
-    R3R0PTRTYPE(PPDMDEVINS)             pDevInsHC;
+    /** Transmit signaller - RC. */
+    RCPTRTYPE(PPDMQUEUE)                pXmitQueueRC;
+    /** Transmit signaller - R3. */
+    R3PTRTYPE(PPDMQUEUE)                pXmitQueueR3;
+    /** Transmit signaller - R0. */
+    R0PTRTYPE(PPDMQUEUE)                pXmitQueueR0;
+
+    /** Receive signaller - R3. */
+    R3PTRTYPE(PPDMQUEUE)                pCanRxQueueR3;
+    /** Receive signaller - R0. */
+    R0PTRTYPE(PPDMQUEUE)                pCanRxQueueR0;
+    /** Receive signaller - RC. */
+    RCPTRTYPE(PPDMQUEUE)                pCanRxQueueRC;
+    /** Pointer to the device instance - RC. */
+    PPDMDEVINSRC                        pDevInsRC;
+    /** Pointer to the device instance - R3. */
+    PPDMDEVINSR3                        pDevInsR3;
+    /** Pointer to the device instance - R0. */
+    PPDMDEVINSR0                        pDevInsR0;
     /** Restore timer.
      *  This is used to disconnect and reconnect the link after a restore. */
@@ -234,12 +247,14 @@
     uint32_t                            cbRDRAOld;
 
-    DECLGCCALLBACKMEMBER(int, pfnEMInterpretInstructionGC, (PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize));
+    DECLRCCALLBACKMEMBER(int, pfnEMInterpretInstructionRC, (PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize));
     DECLR0CALLBACKMEMBER(int, pfnEMInterpretInstructionR0, (PVM pVM, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize));
 #endif
 
-    /** The host context of the shared memory used for the private interface. */
-    R3R0PTRTYPE(PPCNETGUESTSHAREDMEMORY) pSharedMMIOHC;
-    /** The hypervisor/guest context of the shared memory used for the private interface. */
-    RCPTRTYPE(PPCNETGUESTSHAREDMEMORY)  pSharedMMIOGC;
+    /** The shared memory used for the private interface - R3. */
+    R3PTRTYPE(PPCNETGUESTSHAREDMEMORY)  pSharedMMIOR3;
+    /** The shared memory used for the private interface - R0. */
+    R0PTRTYPE(PPCNETGUESTSHAREDMEMORY)  pSharedMMIOR0;
+    /** The shared memory used for the private interface - RC. */
+    RCPTRTYPE(PPCNETGUESTSHAREDMEMORY)  pSharedMMIORC;
 
 #if HC_ARCH_BITS == 64
@@ -255,10 +270,10 @@
 
 #ifdef PCNET_QUEUE_SEND_PACKETS
-    #define PCNET_MAX_XMIT_SLOTS         128
-    #define PCNET_MAX_XMIT_SLOTS_MASK    (PCNET_MAX_XMIT_SLOTS-1)
+# define PCNET_MAX_XMIT_SLOTS           128
+# define PCNET_MAX_XMIT_SLOTS_MASK      (PCNET_MAX_XMIT_SLOTS - 1)
 
     uint32_t                            iXmitRingBufProd;
     uint32_t                            iXmitRingBufCons;
-    /* XXX currently atomic operations on this variable are overkill */
+    /** @todo XXX currently atomic operations on this variable are overkill */
     volatile int32_t                    cXmitRingBufPending;
     uint16_t                            cbXmitRingBuffer[PCNET_MAX_XMIT_SLOTS];
@@ -315,5 +330,5 @@
 };
 
-#define PCNETSTATE_2_DEVINS(pPCNet)            ((pPCNet)->CTXSUFF(pDevIns))
+#define PCNETSTATE_2_DEVINS(pPCNet)            ((pPCNet)->CTX_SUFF(pDevIns))
 #define PCIDEV_2_PCNETSTATE(pPciDev)           ((PCNetState *)(pPciDev))
 #define PCNET_INST_NR                          (PCNETSTATE_2_DEVINS(pData)->iInstance)
@@ -619,7 +634,7 @@
     {
         /* RX/TX descriptors shared between host and guest => direct copy */
-        uint8_t *pv = (uint8_t*)pData->CTXSUFF(pSharedMMIO)
+        uint8_t *pv = (uint8_t*)pData->CTX_SUFF(pSharedMMIO)
                     + (addr - pData->GCTDRA)
-                    + pData->CTXSUFF(pSharedMMIO)->V.V1.offTxDescriptors;
+                    + pData->CTX_SUFF(pSharedMMIO)->V.V1.offTxDescriptors;
         if (!(pv[7] & 0x80) && fRetIfNotOwn)
             return false;
@@ -681,7 +696,7 @@
     {
         /* RX/TX descriptors shared between host and guest => direct copy */
-        uint8_t *pv = (uint8_t*)pData->CTXSUFF(pSharedMMIO)
+        uint8_t *pv = (uint8_t*)pData->CTX_SUFF(pSharedMMIO)
                     + (addr - pData->GCTDRA)
-                    + pData->CTXSUFF(pSharedMMIO)->V.V1.offTxDescriptors;
+                    + pData->CTX_SUFF(pSharedMMIO)->V.V1.offTxDescriptors;
         memcpy(pv, tmd, 16);
         pv[7] &= ~0x80;
@@ -738,7 +753,7 @@
     {
         /* RX/TX descriptors shared between host and guest => direct copy */
-        uint8_t *pb = (uint8_t*)pData->CTXSUFF(pSharedMMIO)
+        uint8_t *pb = (uint8_t*)pData->CTX_SUFF(pSharedMMIO)
                     + (addr - pData->GCRDRA)
-                    + pData->CTXSUFF(pSharedMMIO)->V.V1.offRxDescriptors;
+                    + pData->CTX_SUFF(pSharedMMIO)->V.V1.offRxDescriptors;
         if (!(pb[7] & 0x80) && fRetIfNotOwn)
             return false;
@@ -798,7 +813,7 @@
     {
         /* RX/TX descriptors shared between host and guest => direct copy */
-        uint8_t *pv = (uint8_t*)pData->CTXSUFF(pSharedMMIO)
+        uint8_t *pv = (uint8_t*)pData->CTX_SUFF(pSharedMMIO)
                     + (addr - pData->GCRDRA)
-                    + pData->CTXSUFF(pSharedMMIO)->V.V1.offRxDescriptors;
+                    + pData->CTX_SUFF(pSharedMMIO)->V.V1.offRxDescriptors;
         memcpy(pv, rmd, 16);
         pv[7] &= ~0x80;
@@ -853,5 +868,5 @@
 #define ETH_ALEN 6
 #pragma pack(1)
-struct ether_header
+struct ether_header /** @todo Use RTNETETHERHDR */
 {
     uint8_t  ether_dhost[ETH_ALEN]; /**< destination ethernet address */
@@ -885,7 +900,7 @@
 {
     /* Clear the entire block for pcnetReset usage. */
-    memset(pData->pSharedMMIOHC, 0, PCNET_GUEST_SHARED_MEMORY_SIZE);
-
-    pData->pSharedMMIOHC->u32Version = PCNET_GUEST_INTERFACE_VERSION;
+    memset(pData->pSharedMMIOR3, 0, PCNET_GUEST_SHARED_MEMORY_SIZE);
+
+    pData->pSharedMMIOR3->u32Version = PCNET_GUEST_INTERFACE_VERSION;
     uint32_t off = 2048; /* Leave some space for more fields within the header */
 
@@ -893,8 +908,8 @@
      * The Descriptor arrays.
      */
-    pData->pSharedMMIOHC->V.V1.offTxDescriptors = off;
+    pData->pSharedMMIOR3->V.V1.offTxDescriptors = off;
     off = RT_ALIGN(off + PCNET_GUEST_TX_DESCRIPTOR_SIZE * PCNET_GUEST_MAX_TX_DESCRIPTORS, 32);
 
-    pData->pSharedMMIOHC->V.V1.offRxDescriptors = off;
+    pData->pSharedMMIOR3->V.V1.offRxDescriptors = off;
     off = RT_ALIGN(off + PCNET_GUEST_RX_DESCRIPTOR_SIZE * PCNET_GUEST_MAX_RX_DESCRIPTORS, 32);
 
@@ -908,15 +923,15 @@
 #if 0
     /* Don't allocate TX buffers since Windows guests cannot use it */
-    pData->pSharedMMIOHC->V.V1.offTxBuffers = off;
+    pData->pSharedMMIOR3->V.V1.offTxBuffers = off;
     off = RT_ALIGN(off + PCNET_GUEST_NIC_BUFFER_SIZE * PCNET_GUEST_MAX_TX_DESCRIPTORS, 32);
 #endif
 
-    pData->pSharedMMIOHC->V.V1.offRxBuffers = off;
-    pData->pSharedMMIOHC->fFlags = PCNET_GUEST_FLAGS_ADMIT_HOST;
+    pData->pSharedMMIOR3->V.V1.offRxBuffers = off;
+    pData->pSharedMMIOR3->fFlags = PCNET_GUEST_FLAGS_ADMIT_HOST;
     off = RT_ALIGN(off + PCNET_GUEST_NIC_BUFFER_SIZE * PCNET_GUEST_MAX_RX_DESCRIPTORS, 32);
     AssertRelease(off <= PCNET_GUEST_SHARED_MEMORY_SIZE);
 
     /* Update the header with the final size. */
-    pData->pSharedMMIOHC->cbUsed = off;
+    pData->pSharedMMIOR3->cbUsed = off;
 }
 
@@ -1380,6 +1395,6 @@
 static void pcnetEnablePrivateIf(PCNetState *pData)
 {
-    bool fPrivIfEnabled =       pData->pSharedMMIOHC
-                          && !!(pData->CTXSUFF(pSharedMMIO)->fFlags & PCNET_GUEST_FLAGS_ADMIT_GUEST);
+    bool fPrivIfEnabled =       pData->pSharedMMIOR3
+                          && !!(pData->CTX_SUFF(pSharedMMIO)->fFlags & PCNET_GUEST_FLAGS_ADMIT_GUEST);
     if (fPrivIfEnabled != pData->fPrivIfEnabled)
     {
@@ -1662,7 +1677,7 @@
                     pcnetWakeupReceive(PCNETSTATE_2_DEVINS(pData));
 #else
-                    PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(CTXSUFF(pData->pCanRxQueue));
+                    PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(pData->CTX_SUFF(pCanRxQueue));
                     if (pItem)
-                        PDMQueueInsert(CTXSUFF(pData->pCanRxQueue), pItem);
+                        PDMQueueInsert(pData->CTX_SUFF(pCanRxQueue), pItem);
 #endif
                 }
@@ -1857,6 +1872,6 @@
             if (pData->fPrivIfEnabled)
             {
-                uint8_t *pb = (uint8_t*)pData->CTXSUFF(pSharedMMIO)
-                            + rbadr - pData->GCRDRA + pData->CTXSUFF(pSharedMMIO)->V.V1.offRxDescriptors;
+                uint8_t *pb = (uint8_t*)pData->CTX_SUFF(pSharedMMIO)
+                            + rbadr - pData->GCRDRA + pData->CTX_SUFF(pSharedMMIO)->V.V1.offRxDescriptors;
                 memcpy(pb, src, count);
             }
@@ -1896,6 +1911,6 @@
                 if (pData->fPrivIfEnabled)
                 {
-                    uint8_t *pb = (uint8_t*)pData->CTXSUFF(pSharedMMIO)
-                                + rbadr - pData->GCRDRA + pData->CTXSUFF(pSharedMMIO)->V.V1.offRxDescriptors;
+                    uint8_t *pb = (uint8_t*)pData->CTX_SUFF(pSharedMMIO)
+                                + rbadr - pData->GCRDRA + pData->CTX_SUFF(pSharedMMIO)->V.V1.offRxDescriptors;
                     memcpy(pb, src, count);
                 }
@@ -2021,5 +2036,5 @@
     pData->pvSendFrame = pData->abSendBuf;
 #endif
-    PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, pData->pvSendFrame, cbFrame);
+    PDMDevHlpPhysRead(pData->CTX_SUFF(pDevIns), GCPhysFrame, pData->pvSendFrame, cbFrame);
     pData->cbSendFrame = cbFrame;
 }
@@ -2032,5 +2047,5 @@
 {
     Assert(pData->cbSendFrame + cbFrame <= MAX_FRAME);
-    PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, pData->pvSendFrame + pData->cbSendFrame, cbFrame);
+    PDMDevHlpPhysRead(pData->CTX_SUFF(pDevIns), GCPhysFrame, pData->pvSendFrame + pData->cbSendFrame, cbFrame);
     pData->cbSendFrame += cbFrame;
 }
@@ -2123,5 +2138,5 @@
 DECLINLINE(void) pcnetXmitFlushFrames(PCNetState *pData)
 {
-    pcnetXmitQueueConsumer(CTXSUFF(pData->pDevIns), NULL);
+    pcnetXmitQueueConsumer(pData->CTX_SUFF(pDevIns), NULL);
 }
 
@@ -2160,16 +2175,16 @@
 #else
 # if 1
-    PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(CTXSUFF(pData->pXmitQueue));
+    PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(pData->CTX_SUFF(pXmitQueue));
     if (RT_UNLIKELY(pItem))
-        PDMQueueInsert(CTXSUFF(pData->pXmitQueue), pItem);
+        PDMQueueInsert(pData->CTX_SUFF(pXmitQueue), pItem);
 # else
     if (ASMAtomicIncU32(&pData->cPendingSends) < 16)
     {
-        PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(CTXSUFF(pData->pXmitQueue));
+        PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(pData->CTX_SUFF(pXmitQueue));
         if (RT_UNLIKELY(pItem))
-            PDMQueueInsert(CTXSUFF(pData->pXmitQueue), pItem);
+            PDMQueueInsert(pData->CTX_SUFF(pXmitQueue), pItem);
     }
     else
-        PDMQueueFlush(CTXSUFF(pData->pXmitQueue));
+        PDMQueueFlush(pData->CTX_SUFF(pXmitQueue));
 # endif
 #endif
@@ -2540,5 +2555,5 @@
 static void pcnetPollTimerStart(PCNetState *pData)
 {
-    TMTimerSetMillies(pData->CTXSUFF(pTimerPoll), 2);
+    TMTimerSetMillies(pData->CTX_SUFF(pTimerPoll), 2);
 }
 
@@ -2595,5 +2610,5 @@
         pcnetPollRxTx(pData);
 #else
-        uint64_t u64Now = TMTimerGet(pData->CTXSUFF(pTimerPoll));
+        uint64_t u64Now = TMTimerGet(pData->CTX_SUFF(pTimerPoll));
         if (RT_UNLIKELY(u64Now - pData->u64LastPoll > 200000))
         {
@@ -2601,5 +2616,5 @@
             pcnetPollRxTx(pData);
         }
-        if (!TMTimerIsActive(pData->CTXSUFF(pTimerPoll)))
+        if (!TMTimerIsActive(pData->CTX_SUFF(pTimerPoll)))
             pcnetPollTimerStart(pData);
 #endif
@@ -2910,5 +2925,5 @@
             pData->aBCR[BCR_STVAL] = val;
             if (pData->fAm79C973)
-                TMTimerSetNano(pData->CTXSUFF(pTimerSoftInt), 12800U * val);
+                TMTimerSetNano(pData->CTX_SUFF(pTimerSoftInt), 12800U * val);
             break;
 
@@ -3703,5 +3718,5 @@
     pData->aCSR[7] |= 0x0800; /* STINT */
     pcnetUpdateIrq(pData);
-    TMTimerSetNano(pData->CTXSUFF(pTimerSoftInt), 12800U * (pData->aBCR[BCR_STVAL] & 0xffff));
+    TMTimerSetNano(pData->CTX_SUFF(pTimerSoftInt), 12800U * (pData->aBCR[BCR_STVAL] & 0xffff));
 }
 
@@ -4139,10 +4154,10 @@
     return VINF_SUCCESS;
 #else
-    rc = TMR3TimerSave(pData->CTXSUFF(pTimerPoll), pSSMHandle);
+    rc = TMR3TimerSave(pData->CTX_SUFF(pTimerPoll), pSSMHandle);
     if (VBOX_FAILURE(rc))
         return rc;
 #endif
     if (pData->fAm79C973)
-        rc = TMR3TimerSave(pData->CTXSUFF(pTimerSoftInt), pSSMHandle);
+        rc = TMR3TimerSave(pData->CTX_SUFF(pTimerSoftInt), pSSMHandle);
     return rc;
 }
@@ -4215,5 +4230,5 @@
     SSMR3GetU32(pSSMHandle, &pData->u32LinkSpeed);
 #ifndef PCNET_NO_POLLING
-    TMR3TimerLoad(pData->CTXSUFF(pTimerPoll), pSSMHandle);
+    TMR3TimerLoad(pData->CTX_SUFF(pTimerPoll), pSSMHandle);
 #endif
     if (pData->fAm79C973)
@@ -4221,5 +4236,5 @@
         if (   SSM_VERSION_MAJOR(u32Version) >  0
             || SSM_VERSION_MINOR(u32Version) >= 8)
-            TMR3TimerLoad(pData->CTXSUFF(pTimerSoftInt), pSSMHandle);
+            TMR3TimerLoad(pData->CTX_SUFF(pTimerSoftInt), pSSMHandle);
     }
 
@@ -4334,5 +4349,5 @@
     ASMAtomicXchgBool(&pData->fMaybeOutOfSpace, true);
     STAM_PROFILE_START(&pData->StatRxOverflow, a);
-    while (RT_LIKELY(PDMDevHlpVMState(pData->CTXSUFF(pDevIns)) == VMSTATE_RUNNING))
+    while (RT_LIKELY(PDMDevHlpVMState(pData->CTX_SUFF(pDevIns)) == VMSTATE_RUNNING))
     {
         int rc2 = pcnetCanReceive(pData);
@@ -4524,5 +4539,5 @@
         pcnetTimerRestore(pDevIns, pData->pTimerRestore);
     }
-    if (pData->pSharedMMIOHC)
+    if (pData->pSharedMMIOR3)
         pcnetInitSharedMemory(pData);
 
@@ -4538,16 +4553,16 @@
 {
     PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *);
-    pData->pDevInsGC     = PDMDEVINS_2_GCPTR(pDevIns);
-    pData->pXmitQueueGC  = PDMQueueGCPtr(pData->pXmitQueueHC);
-    pData->pCanRxQueueGC = PDMQueueGCPtr(pData->pCanRxQueueHC);
-    if (pData->pSharedMMIOHC)
-        pData->pSharedMMIOGC += offDelta;
+    pData->pDevInsRC     = PDMDEVINS_2_RCPTR(pDevIns);
+    pData->pXmitQueueRC  = PDMQueueRCPtr(pData->pXmitQueueR3);
+    pData->pCanRxQueueRC = PDMQueueRCPtr(pData->pCanRxQueueR3);
+    if (pData->pSharedMMIOR3)
+        pData->pSharedMMIORC += offDelta;
 #ifdef PCNET_NO_POLLING
-    *(RTHCUINTPTR *)&pData->pfnEMInterpretInstructionGC += offDelta;
+    pData->pfnEMInterpretInstructionRC += offDelta;
 #else
-    pData->pTimerPollGC  = TMTimerGCPtr(pData->pTimerPollHC);
+    pData->pTimerPollRC  = TMTimerRCPtr(pData->pTimerPollR3);
 #endif
     if (pData->fAm79C973)
-        pData->pTimerSoftIntGC = TMTimerGCPtr(pData->pTimerSoftIntHC);
+        pData->pTimerSoftIntRC = TMTimerRCPtr(pData->pTimerSoftIntR3);
 }
 
@@ -4616,7 +4631,13 @@
 
     /*
+     * Init what's required to make the destructor safe.
+     */
+    pData->hEventOutOfRxSpace = NIL_RTSEMEVENT;
+    pData->hSendEventSem = NIL_RTSEMEVENT;
+
+    /*
      * Validate configuration.
      */
-    if (!CFGMR3AreValuesValid(pCfgHandle, "MAC\0CableConnected\0Am79C973\0LineSpeed\0GCEnabled\0R0Enabled\0PrivIfEnabled\0"))
+    if (!CFGMR3AreValuesValid(pCfgHandle, "MAC\0" "CableConnected\0" "Am79C973\0" "LineSpeed\0" "GCEnabled\0" "R0Enabled\0" "PrivIfEnabled\0"))
         return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
                                 N_("Invalid configuraton for pcnet device"));
@@ -4629,37 +4650,27 @@
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"MAC\" value"));
-    rc = CFGMR3QueryBool(pCfgHandle, "CableConnected", &pData->fLinkUp);
-    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
-        pData->fLinkUp = true;
-    else if (VBOX_FAILURE(rc))
+    rc = CFGMR3QueryBoolDef(pCfgHandle, "CableConnected", &pData->fLinkUp, true);
+    if (VBOX_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"CableConnected\" value"));
 
-    rc = CFGMR3QueryBool(pCfgHandle, "Am79C973", &pData->fAm79C973);
-    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
-        pData->fAm79C973 = false;
-    else if (VBOX_FAILURE(rc))
+    rc = CFGMR3QueryBoolDef(pCfgHandle, "Am79C973", &pData->fAm79C973, false);
+    if (VBOX_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"Am79C973\" value"));
 
-    rc = CFGMR3QueryU32(pCfgHandle, "LineSpeed", &pData->u32LinkSpeed);
-    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
-        pData->u32LinkSpeed = 1000000;    /* 1GBit/s (in kbps units)*/
-    else if (VBOX_FAILURE(rc))
+    rc = CFGMR3QueryU32Def(pCfgHandle, "LineSpeed", &pData->u32LinkSpeed, 1000000); /* 1GBit/s (in kbps units)*/
+    if (VBOX_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"LineSpeed\" value"));
 
 #ifdef PCNET_GC_ENABLED
-    rc = CFGMR3QueryBool(pCfgHandle, "GCEnabled", &pData->fGCEnabled);
-    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
-        pData->fGCEnabled = true;
-    else if (VBOX_FAILURE(rc))
+    rc = CFGMR3QueryBoolDef(pCfgHandle, "GCEnabled", &pData->fGCEnabled, true);
+    if (VBOX_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"GCEnabled\" value"));
 
-    rc = CFGMR3QueryBool(pCfgHandle, "R0Enabled", &pData->fR0Enabled);
-    if (rc == VERR_CFGM_VALUE_NOT_FOUND)
-        pData->fR0Enabled = true;
-    else if (VBOX_FAILURE(rc))
+    rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &pData->fR0Enabled, true);
+    if (VBOX_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to get the \"R0Enabled\" value"));
@@ -4674,6 +4685,7 @@
      * Initialize data (most of it anyway).
      */
-    pData->pDevInsHC                        = pDevIns;
-    pData->pDevInsGC                        = PDMDEVINS_2_GCPTR(pDevIns);
+    pData->pDevInsR3                        = pDevIns;
+    pData->pDevInsR0                        = PDMDEVINS_2_R0PTR(pDevIns);
+    pData->pDevInsRC                        = PDMDEVINS_2_RCPTR(pDevIns);
     pData->Led.u32Magic                     = PDMLED_MAGIC;
     /* IBase */
@@ -4745,19 +4757,18 @@
     if (fPrivIfEnabled)
     {
-        RTRCPTR pRCMapping;
-
         /*
          * Initialize shared memory between host and guest for descriptors and RX buffers. Most guests
          * should not care if there is an additional PCI ressource but just in case we made this configurable.
          */
-        rc = PDMDevHlpMMIO2Register(pDevIns, 2, PCNET_GUEST_SHARED_MEMORY_SIZE, 0, (void **)&pData->pSharedMMIOHC, "PCNetShMem");
+        rc = PDMDevHlpMMIO2Register(pDevIns, 2, PCNET_GUEST_SHARED_MEMORY_SIZE, 0, (void **)&pData->pSharedMMIOR3, "PCNetShMem");
         if (VBOX_FAILURE(rc))
             return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
                                        N_("Failed to allocate %u bytes of memory for the PCNet device"), PCNET_GUEST_SHARED_MEMORY_SIZE);
-        rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, 2, 0, 8192, "PCNetShMem", &pRCMapping);
+        rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, 2, 0, 8192, "PCNetShMem", &pData->pSharedMMIORC);
         if (VBOX_FAILURE(rc))
             return PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS,
                                        N_("Failed to map 8192 bytes of memory for the PCNet device into the hyper memory"));
-        pData->pSharedMMIOGC = pRCMapping;
+        pData->pSharedMMIOR0 = (uintptr_t)pData->pSharedMMIOR3; /** @todo #1865: Map MMIO2 into ring-0. */
+
         pcnetInitSharedMemory(pData);
         rc = PDMDevHlpPCIIORegionRegister(pDevIns, 2, PCNET_GUEST_SHARED_MEMORY_SIZE,
@@ -4768,26 +4779,18 @@
 
 #ifdef PCNET_NO_POLLING
+    /*
+     * Resolve the R0 and RC handlers.
+     */
     rc = PDMR3GetSymbolR0Lazy(PDMDevHlpGetVM(pDevIns), NULL, "EMInterpretInstruction", &pData->pfnEMInterpretInstructionR0);
     if (VBOX_SUCCESS(rc))
-    {
-        /*
-         * Resolve the GC handler.
-         */
-        RTGCPTR pfnHandlerGC;
-        rc = PDMR3GetSymbolGCLazy(PDMDevHlpGetVM(pDevIns), NULL, "EMInterpretInstruction", (RTGCPTR *)&pData->pfnEMInterpretInstructionGC);
-    }
-    if (VBOX_FAILURE(rc))
-    {
-        AssertMsgFailed(("PDMR3GetSymbolGCLazy -> %Vrc\n", rc));
-        return rc;
-    }
+        rc = PDMR3GetSymbolGCLazy(PDMDevHlpGetVM(pDevIns), NULL, "EMInterpretInstruction", (RTGCPTR *)&pData->pfnEMInterpretInstructionRC);
+    AssertLogRelMsgRCReturn(rc, ("PDMR3GetSymbolGCLazy(EMInterpretInstruction) -> %Vrc\n", rc), rc);
 #else
     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimer,
-                                "PCNet Poll Timer", &pData->pTimerPollHC);
+                                "PCNet Poll Timer", &pData->pTimerPollR3);
     if (VBOX_FAILURE(rc))
-    {
-        AssertMsgFailed(("pfnTMTimerCreate pcnetTimer -> %Vrc\n", rc));
         return rc;
-    }
+    pData->pTimerPollR0 = TMTimerR0Ptr(pData->pTimerPollR3);
+    pData->pTimerPollRC = TMTimerRCPtr(pData->pTimerPollR3);
 #endif
     if (pData->fAm79C973)
@@ -4795,18 +4798,15 @@
         /* Software Interrupt timer */
         rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimerSoftInt,
-                                    "PCNet SoftInt Timer", &pData->pTimerSoftIntHC);
-        if (VBOX_FAILURE(rc))
-        {
-            AssertMsgFailed(("pfnTMTimerCreate pcnetTimerSoftInt -> %Vrc\n", rc));
+                                    "PCNet SoftInt Timer", &pData->pTimerSoftIntR3);
+        if (RT_FAILURE(rc))
             return rc;
-        }
+        pData->pTimerSoftIntR0 = TMTimerR0Ptr(pData->pTimerSoftIntR3);
+        pData->pTimerSoftIntRC = TMTimerRCPtr(pData->pTimerSoftIntR3);
     }
     rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL, pcnetTimerRestore,
                                 "PCNet Restore Timer", &pData->pTimerRestore);
-    if (VBOX_FAILURE(rc))
-    {
-        AssertMsgFailed(("pfnTMTimerCreate pcnetTimerRestore -> %Vrc\n", rc));
+    if (RT_FAILURE(rc))
         return rc;
-    }
+
     rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance,
                               PCNET_SAVEDSTATE_VERSION, sizeof(*pData),
@@ -4818,5 +4818,5 @@
     /*
      * Initialize critical section.
-     * This must of course be done before attaching drivers or anything else which can call us back..
+     * This must of course be done before attaching drivers or anything else which can call us back.
      */
     char szName[24];
@@ -4833,8 +4833,9 @@
      */
     rc = PDMDevHlpPDMQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 1, 0,
-                                 pcnetXmitQueueConsumer, true, &pData->pXmitQueueHC);
+                                 pcnetXmitQueueConsumer, true, &pData->pXmitQueueR3);
     if (VBOX_FAILURE(rc))
         return rc;
-    pData->pXmitQueueGC = PDMQueueGCPtr(pData->pXmitQueueHC);
+    pData->pXmitQueueR0 = PDMQueueR0Ptr(pData->pXmitQueueR3);
+    pData->pXmitQueueRC = PDMQueueRCPtr(pData->pXmitQueueR3);
 
     /*
@@ -4842,8 +4843,9 @@
      */
     rc = PDMDevHlpPDMQueueCreate(pDevIns, sizeof(PDMQUEUEITEMCORE), 1, 0,
-                                 pcnetCanRxQueueConsumer, true, &pData->pCanRxQueueHC);
+                                 pcnetCanRxQueueConsumer, true, &pData->pCanRxQueueR3);
     if (VBOX_FAILURE(rc))
         return rc;
-    pData->pCanRxQueueGC = PDMQueueGCPtr(pData->pCanRxQueueHC);
+    pData->pCanRxQueueR0 = PDMQueueR0Ptr(pData->pCanRxQueueR3);
+    pData->pCanRxQueueRC = PDMQueueRCPtr(pData->pCanRxQueueR3);
 
     /*
@@ -4908,10 +4910,7 @@
     AssertRCReturn(rc, rc);
 
-    unsigned i;
-    NOREF(i);
-
 #ifdef PCNET_QUEUE_SEND_PACKETS
     pData->apXmitRingBuffer[0] = (uint8_t *)RTMemAlloc(PCNET_MAX_XMIT_SLOTS * MAX_FRAME);
-    for (i = 1; i < PCNET_MAX_XMIT_SLOTS; i++)
+    for (unsigned i = 1; i < PCNET_MAX_XMIT_SLOTS; i++)
         pData->apXmitRingBuffer[i] = pData->apXmitRingBuffer[0] + i*MAX_FRAME;
 #endif
@@ -4948,9 +4947,10 @@
     PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatTmdStoreHC,         STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling PCNet TmdStore in HC",     "/Devices/PCNet%d/TmdStoreHC", iInstance);
 
-    for (i = 0; i < ELEMENTS(pData->aStatXmitFlush) - 1; i++)
+    unsigned i;
+    for (i = 0; i < RT_ELEMENTS(pData->aStatXmitFlush) - 1; i++)
         PDMDevHlpSTAMRegisterF(pDevIns, &pData->aStatXmitFlush[i],  STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,       "",                                   "/Devices/PCNet%d/XmitFlushIrq/%d", iInstance, i + 1);
     PDMDevHlpSTAMRegisterF(pDevIns, &pData->aStatXmitFlush[i],      STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,       "",                                   "/Devices/PCNet%d/XmitFlushIrq/%d+", iInstance, i + 1);
 
-    for (i = 0; i < ELEMENTS(pData->aStatXmitChainCounts) - 1; i++)
+    for (i = 0; i < RT_ELEMENTS(pData->aStatXmitChainCounts) - 1; i++)
         PDMDevHlpSTAMRegisterF(pDevIns, &pData->aStatXmitChainCounts[i], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,  "",                                   "/Devices/PCNet%d/XmitChainCounts/%d", iInstance, i + 1);
     PDMDevHlpSTAMRegisterF(pDevIns, &pData->aStatXmitChainCounts[i], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,      "",                                   "/Devices/PCNet%d/XmitChainCounts/%d+", iInstance, i + 1);
Index: trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp
===================================================================
--- trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp	(revision 11197)
+++ trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp	(revision 11199)
@@ -321,9 +321,11 @@
     GEN_CHECK_OFF(PCNetState, PciDev);
 #ifndef PCNET_NO_POLLING
-    GEN_CHECK_OFF(PCNetState, pTimerPollHC);
-    GEN_CHECK_OFF(PCNetState, pTimerPollGC);
-#endif
-    GEN_CHECK_OFF(PCNetState, pTimerSoftIntHC);
-    GEN_CHECK_OFF(PCNetState, pTimerSoftIntGC);
+    GEN_CHECK_OFF(PCNetState, pTimerPollR3);
+    GEN_CHECK_OFF(PCNetState, pTimerPollR0);
+    GEN_CHECK_OFF(PCNetState, pTimerPollRC);
+#endif
+    GEN_CHECK_OFF(PCNetState, pTimerSoftIntR3);
+    GEN_CHECK_OFF(PCNetState, pTimerSoftIntR0);
+    GEN_CHECK_OFF(PCNetState, pTimerSoftIntRC);
     GEN_CHECK_OFF(PCNetState, u32RAP);
     GEN_CHECK_OFF(PCNetState, iISR);
@@ -348,11 +350,14 @@
     GEN_CHECK_OFF(PCNetState, iLog2DescSize);
     GEN_CHECK_OFF(PCNetState, GCUpperPhys);
-    GEN_CHECK_OFF(PCNetState, pXmitQueueHC);
-    GEN_CHECK_OFF(PCNetState, pXmitQueueGC);
-    GEN_CHECK_OFF(PCNetState, pCanRxQueueHC);
-    GEN_CHECK_OFF(PCNetState, pCanRxQueueGC);
+    GEN_CHECK_OFF(PCNetState, pXmitQueueR3);
+    GEN_CHECK_OFF(PCNetState, pXmitQueueR0);
+    GEN_CHECK_OFF(PCNetState, pXmitQueueRC);
+    GEN_CHECK_OFF(PCNetState, pCanRxQueueR3);
+    GEN_CHECK_OFF(PCNetState, pCanRxQueueR0);
+    GEN_CHECK_OFF(PCNetState, pCanRxQueueRC);
     GEN_CHECK_OFF(PCNetState, pTimerRestore);
-    GEN_CHECK_OFF(PCNetState, pDevInsHC);
-    GEN_CHECK_OFF(PCNetState, pDevInsGC);
+    GEN_CHECK_OFF(PCNetState, pDevInsR3);
+    GEN_CHECK_OFF(PCNetState, pDevInsR0);
+    GEN_CHECK_OFF(PCNetState, pDevInsRC);
     GEN_CHECK_OFF(PCNetState, pDrv);
     GEN_CHECK_OFF(PCNetState, pDrvBase);
@@ -381,6 +386,7 @@
     GEN_CHECK_OFF(PCNetState, pfnEMInterpretInstructionR0
 #endif
-    GEN_CHECK_OFF(PCNetState, pSharedMMIOHC);
-    GEN_CHECK_OFF(PCNetState, pSharedMMIOGC);
+    GEN_CHECK_OFF(PCNetState, pSharedMMIOR3);
+    GEN_CHECK_OFF(PCNetState, pSharedMMIOR0);
+    GEN_CHECK_OFF(PCNetState, pSharedMMIORC);
     GEN_CHECK_OFF(PCNetState, fPrivIfEnabled);
     GEN_CHECK_OFF(PCNetState, fGCEnabled);
