Index: trunk/src/VBox/Devices/PC/DevHPET.cpp
===================================================================
--- trunk/src/VBox/Devices/PC/DevHPET.cpp	(revision 44626)
+++ trunk/src/VBox/Devices/PC/DevHPET.cpp	(revision 44629)
@@ -1,9 +1,9 @@
 /* $Id$ */
 /** @file
- * HPET virtual device - High Precision Event Timer emulation
+ * HPET virtual device - High Precision Event Timer emulation.
  */
 
 /*
- * Copyright (C) 2009-2012 Oracle Corporation
+ * Copyright (C) 2009-2013 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -45,6 +45,6 @@
  */
 
-/** Base address for MMIO. */
-/* On ICH9, it is 0xFED0x000 where 'x' is 0-3, default 0. We do not support
+/** Base address for MMIO.
+ * On ICH9, it is 0xFED0x000 where 'x' is 0-3, default 0. We do not support
  * relocation as the platform firmware is responsible for configuring the
  * HPET base address and the OS isn't expected to move it.
@@ -52,5 +52,5 @@
 #define HPET_BASE                   0xfed00000
 
-/* HPET reserves a 1K range. */
+/** HPET reserves a 1K range. */
 #define HPET_BAR_SIZE               0x1000
 
@@ -70,36 +70,42 @@
 #define HPET_CLK_PERIOD_ICH9        UINT32_C(69841279)
 
-/*
+/**
  * Femtosecods in a nanosecond
  */
 #define FS_PER_NS                   1000000
 
-/*
- * Interrupt type
- */
+/** @name Interrupt type
+ * @{ */
 #define HPET_TIMER_TYPE_LEVEL       1
 #define HPET_TIMER_TYPE_EDGE        0
-
-/* Delivery mode */
-#define HPET_TIMER_DELIVERY_APIC    0   /* Delivery through APIC. */
-#define HPET_TIMER_DELIVERY_FSB     1   /* Delivery through FSB. */
+/** @} */
+
+/** @name Delivery mode
+ * @{ */
+#define HPET_TIMER_DELIVERY_APIC    0   /**< Delivery through APIC. */
+#define HPET_TIMER_DELIVERY_FSB     1   /**< Delivery through FSB. */
+/** @} */
 
 #define HPET_TIMER_CAP_FSB_INT_DEL (1 << 15)
 #define HPET_TIMER_CAP_PER_INT     (1 << 4)
 
-#define HPET_CFG_ENABLE          0x001 /* ENABLE_CNF */
-#define HPET_CFG_LEGACY          0x002 /* LEG_RT_CNF */
-
-/* Register offsets in HPET space. */
-#define HPET_ID                  0x000  /* Device ID. */
-#define HPET_PERIOD              0x004  /* Clock period in femtoseconds. */
-#define HPET_CFG                 0x010  /* Configuration register. */
-#define HPET_STATUS              0x020  /* Status register. */
-#define HPET_COUNTER             0x0f0  /* Main HPET counter. */
-
-/* Timer N offsets (within each timer's space). */
-#define HPET_TN_CFG              0x000  /* Timer N configuration. */
-#define HPET_TN_CMP              0x008  /* Timer N comparator. */
-#define HPET_TN_ROUTE            0x010  /* Timer N interrupt route. */
+#define HPET_CFG_ENABLE          0x001  /**< ENABLE_CNF */
+#define HPET_CFG_LEGACY          0x002  /**< LEG_RT_CNF */
+
+/** @name Register offsets in HPET space.
+ * @{ */
+#define HPET_ID                  0x000  /**< Device ID. */
+#define HPET_PERIOD              0x004  /**< Clock period in femtoseconds. */
+#define HPET_CFG                 0x010  /**< Configuration register. */
+#define HPET_STATUS              0x020  /**< Status register. */
+#define HPET_COUNTER             0x0f0  /**< Main HPET counter. */
+/** @} */
+
+/** @name Timer N offsets (within each timer's space).
+ * @{ */
+#define HPET_TN_CFG              0x000  /**< Timer N configuration. */
+#define HPET_TN_CMP              0x008  /**< Timer N comparator. */
+#define HPET_TN_ROUTE            0x010  /**< Timer N interrupt route. */
+/** @} */
 
 #define HPET_CFG_WRITE_MASK      0x3
@@ -133,5 +139,5 @@
 #define DEVHPET_LOCK_RETURN(a_pThis, a_rcBusy)  \
     do { \
-        int rcLock = PDMCritSectEnter(&(a_pThis)->csLock, (a_rcBusy)); \
+        int rcLock = PDMCritSectEnter(&(a_pThis)->CritSect, (a_rcBusy)); \
         if (rcLock != VINF_SUCCESS) \
             return rcLock; \
@@ -142,5 +148,5 @@
  */
 #define DEVHPET_UNLOCK(a_pThis) \
-    do { PDMCritSectLeave(&(a_pThis)->csLock); } while (0)
+    do { PDMCritSectLeave(&(a_pThis)->CritSect); } while (0)
 
 
@@ -153,5 +159,5 @@
         if (rcLock != VINF_SUCCESS) \
             return rcLock; \
-        rcLock = PDMCritSectEnter(&(a_pThis)->csLock, (a_rcBusy)); \
+        rcLock = PDMCritSectEnter(&(a_pThis)->CritSect, (a_rcBusy)); \
         if (rcLock != VINF_SUCCESS) \
         { \
@@ -167,5 +173,5 @@
 #define DEVHPET_UNLOCK_BOTH(a_pThis) \
     do { \
-        PDMCritSectLeave(&(a_pThis)->csLock); \
+        PDMCritSectLeave(&(a_pThis)->CritSect); \
         TMTimerUnlock((a_pThis)->aTimers[0].CTX_SUFF(pTimer)); \
     } while (0)
@@ -175,37 +181,39 @@
 *   Structures and Typedefs                                                    *
 *******************************************************************************/
-struct HpetState;
-typedef struct HpetTimer
+/**
+ * A HPET timer.
+ */
+typedef struct HPETTIMER
 {
     /** The HPET timer - R3 Ptr. */
-    PTMTIMERR3                       pTimerR3;
+    PTMTIMERR3                  pTimerR3;
     /** Pointer to the instance data - R3 Ptr. */
-    R3PTRTYPE(struct HpetState *)    pHpetR3;
+    R3PTRTYPE(struct HPET *)    pHpetR3;
 
     /** The HPET timer - R0 Ptr. */
-    PTMTIMERR0                       pTimerR0;
+    PTMTIMERR0                  pTimerR0;
     /** Pointer to the instance data - R0 Ptr. */
-    R0PTRTYPE(struct HpetState *)    pHpetR0;
+    R0PTRTYPE(struct HPET *)    pHpetR0;
 
     /** The HPET timer - RC Ptr. */
-    PTMTIMERRC                       pTimerRC;
+    PTMTIMERRC                  pTimerRC;
     /** Pointer to the instance data - RC Ptr. */
-    RCPTRTYPE(struct HpetState *)    pHpetRC;
+    RCPTRTYPE(struct HPET *)    pHpetRC;
 
     /** Timer index. */
-    uint8_t                          idxTimer;
+    uint8_t                     idxTimer;
     /** Wrap. */
-    uint8_t                          u8Wrap;
+    uint8_t                     u8Wrap;
     /** Alignment. */
-    uint32_t                         alignment0;
+    uint32_t                    alignment0;
 
     /** @name Memory-mapped, software visible timer registers.
      * @{ */
     /** Configuration/capabilities. */
-    uint64_t                         u64Config;
+    uint64_t                    u64Config;
     /** Comparator. */
-    uint64_t                         u64Cmp;
+    uint64_t                    u64Cmp;
     /** FSB route, not supported now. */
-    uint64_t                         u64Fsb;
+    uint64_t                    u64Fsb;
     /** @} */
 
@@ -213,53 +221,57 @@
      * @{ */
     /** Last value written to comparator. */
-    uint64_t                         u64Period;
+    uint64_t                    u64Period;
     /** @} */
-} HpetTimer;
-AssertCompileMemberAlignment(HpetTimer, u64Config, sizeof(uint64_t));
-
-typedef struct HpetState
+} HPETTIMER;
+AssertCompileMemberAlignment(HPETTIMER, u64Config, sizeof(uint64_t));
+
+/**
+ * The HPET state.
+ */
+typedef struct HPET
 {
     /** Pointer to the device instance. - R3 ptr. */
-    PPDMDEVINSR3         pDevInsR3;
+    PPDMDEVINSR3                pDevInsR3;
     /** The HPET helpers - R3 Ptr. */
-    PCPDMHPETHLPR3       pHpetHlpR3;
+    PCPDMHPETHLPR3              pHpetHlpR3;
 
     /** Pointer to the device instance. - R0 ptr. */
-    PPDMDEVINSR0         pDevInsR0;
+    PPDMDEVINSR0                pDevInsR0;
     /** The HPET helpers - R0 Ptr. */
-    PCPDMHPETHLPR0       pHpetHlpR0;
+    PCPDMHPETHLPR0              pHpetHlpR0;
 
     /** Pointer to the device instance. - RC ptr. */
-    PPDMDEVINSRC         pDevInsRC;
+    PPDMDEVINSRC                pDevInsRC;
     /** The HPET helpers - RC Ptr. */
-    PCPDMHPETHLPRC       pHpetHlpRC;
+    PCPDMHPETHLPRC              pHpetHlpRC;
 
     /** Timer structures. */
-    HpetTimer            aTimers[RT_MAX(HPET_NUM_TIMERS_PIIX, HPET_NUM_TIMERS_ICH9)];
+    HPETTIMER                   aTimers[RT_MAX(HPET_NUM_TIMERS_PIIX, HPET_NUM_TIMERS_ICH9)];
 
     /** Offset realtive to the virtual sync clock. */
-    uint64_t             u64HpetOffset;
+    uint64_t                    u64HpetOffset;
 
     /** @name Memory-mapped, software visible registers
      * @{ */
     /** Capabilities. */
-    uint32_t             u32Capabilities;
+    uint32_t                    u32Capabilities;
     /** HPET_PERIOD - . */
-    uint32_t             u32Period;
+    uint32_t                    u32Period;
     /** Configuration. */
-    uint64_t             u64HpetConfig;
+    uint64_t                    u64HpetConfig;
     /** Interrupt status register. */
-    uint64_t             u64Isr;
+    uint64_t                    u64Isr;
     /** Main counter. */
-    uint64_t             u64HpetCounter;
+    uint64_t                    u64HpetCounter;
     /** @}  */
 
     /** Global device lock. */
-    PDMCRITSECT          csLock;
+    PDMCRITSECT                 CritSect;
 
     /** Whether we emulate ICH9 HPET (different frequency & timer count). */
-    bool                 fIch9;
-    uint8_t              padding0[7];
-} HpetState;
+    bool                        fIch9;
+    /** Size alignment padding. */
+    uint8_t                     abPadding0[7];
+} HPET;
 
 
@@ -267,5 +279,5 @@
 
 
-DECLINLINE(bool) hpet32bitTimer(HpetTimer *pHpetTimer)
+DECLINLINE(bool) hpet32bitTimer(HPETTIMER *pHpetTimer)
 {
     uint64_t u64Cfg = pHpetTimer->u64Config;
@@ -274,20 +286,20 @@
 }
 
-DECLINLINE(uint64_t) hpetInvalidValue(HpetTimer *pHpetTimer)
+DECLINLINE(uint64_t) hpetInvalidValue(HPETTIMER *pHpetTimer)
 {
     return hpet32bitTimer(pHpetTimer) ? UINT32_MAX : UINT64_MAX;
 }
 
-DECLINLINE(uint64_t) hpetTicksToNs(HpetState *pThis, uint64_t value)
+DECLINLINE(uint64_t) hpetTicksToNs(HPET *pThis, uint64_t value)
 {
     return ASMMultU64ByU32DivByU32(value,  pThis->u32Period, FS_PER_NS);
 }
 
-DECLINLINE(uint64_t) nsToHpetTicks(HpetState const *pThis, uint64_t u64Value)
+DECLINLINE(uint64_t) nsToHpetTicks(HPET const *pThis, uint64_t u64Value)
 {
     return ASMMultU64ByU32DivByU32(u64Value, FS_PER_NS, pThis->u32Period);
 }
 
-DECLINLINE(uint64_t) hpetGetTicks(HpetState const *pThis)
+DECLINLINE(uint64_t) hpetGetTicks(HPET const *pThis)
 {
     /*
@@ -300,7 +312,5 @@
 }
 
-DECLINLINE(uint64_t) hpetUpdateMasked(uint64_t u64NewValue,
-                                      uint64_t u64OldValue,
-                                      uint64_t u64Mask)
+DECLINLINE(uint64_t) hpetUpdateMasked(uint64_t u64NewValue, uint64_t u64OldValue, uint64_t u64Mask)
 {
     u64NewValue &= u64Mask;
@@ -309,7 +319,5 @@
 }
 
-DECLINLINE(bool) hpetBitJustSet(uint64_t u64OldValue,
-                                uint64_t u64NewValue,
-                                uint64_t u64Mask)
+DECLINLINE(bool) hpetBitJustSet(uint64_t u64OldValue, uint64_t u64NewValue, uint64_t u64Mask)
 {
     return !(u64OldValue & u64Mask)
@@ -317,7 +325,5 @@
 }
 
-DECLINLINE(bool) hpetBitJustCleared(uint64_t u64OldValue,
-                                    uint64_t u64NewValue,
-                                    uint64_t u64Mask)
+DECLINLINE(bool) hpetBitJustCleared(uint64_t u64OldValue, uint64_t u64NewValue, uint64_t u64Mask)
 {
     return !!(u64OldValue & u64Mask)
@@ -325,6 +331,5 @@
 }
 
-DECLINLINE(uint64_t) hpetComputeDiff(HpetTimer *pHpetTimer,
-                                     uint64_t   u64Now)
+DECLINLINE(uint64_t) hpetComputeDiff(HPETTIMER *pHpetTimer, uint64_t u64Now)
 {
 
@@ -348,5 +353,5 @@
 
 
-static void hpetAdjustComparator(HpetTimer *pHpetTimer, uint64_t u64Now)
+static void hpetAdjustComparator(HPETTIMER *pHpetTimer, uint64_t u64Now)
 {
     uint64_t    u64Period = pHpetTimer->u64Period;
@@ -367,5 +372,5 @@
  * @param   pHpetTimer  The timer.
  */
-DECLINLINE(void) hpetTimerSetFrequencyHint(HpetState *pThis, HpetTimer *pHpetTimer)
+DECLINLINE(void) hpetTimerSetFrequencyHint(HPET *pThis, HPETTIMER *pHpetTimer)
 {
     if (pHpetTimer->u64Config & HPET_TN_PERIODIC)
@@ -379,5 +384,5 @@
 
 
-static void hpetProgramTimer(HpetTimer *pHpetTimer)
+static void hpetProgramTimer(HPETTIMER *pHpetTimer)
 {
     /* no wrapping on new timers */
@@ -434,7 +439,7 @@
  * @remarks ASSUMES the caller holds the HPET lock.
  */
-static int hpetTimerRegRead32(HpetState const *pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t *pu32Value)
-{
-    Assert(PDMCritSectIsOwner(&pThis->csLock));
+static int hpetTimerRegRead32(HPET const *pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t *pu32Value)
+{
+    Assert(PDMCritSectIsOwner(&pThis->CritSect));
 
     if (   iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities)  /* The second check is only to satisfy Parfait; */
@@ -448,5 +453,5 @@
     }
 
-    HpetTimer const *pHpetTimer = &pThis->aTimers[iTimerNo];
+    HPETTIMER const *pHpetTimer = &pThis->aTimers[iTimerNo];
     uint32_t u32Value;
     switch (iTimerReg)
@@ -503,7 +508,7 @@
  *          the TM lock.
  */
-static int hpetTimerRegWrite32(HpetState *pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t u32NewValue)
-{
-    Assert(!PDMCritSectIsOwner(&pThis->csLock) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));
+static int hpetTimerRegWrite32(HPET *pThis, uint32_t iTimerNo, uint32_t iTimerReg, uint32_t u32NewValue)
+{
+    Assert(!PDMCritSectIsOwner(&pThis->CritSect) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));
 
     if (   iTimerNo >= HPET_CAP_GET_TIMERS(pThis->u32Capabilities)
@@ -515,5 +520,5 @@
         return VINF_SUCCESS;
     }
-    HpetTimer *pHpetTimer = &pThis->aTimers[iTimerNo];
+    HPETTIMER *pHpetTimer = &pThis->aTimers[iTimerNo];
 
     switch (iTimerReg)
@@ -635,7 +640,7 @@
  * @remarks The caller must not own the device lock if HPET_COUNTER is read.
  */
-static int hpetConfigRegRead32(HpetState *pThis, uint32_t idxReg, uint32_t *pu32Value)
-{
-    Assert(!PDMCritSectIsOwner(&pThis->csLock) || (idxReg != HPET_COUNTER && idxReg != HPET_COUNTER + 4));
+static int hpetConfigRegRead32(HPET *pThis, uint32_t idxReg, uint32_t *pu32Value)
+{
+    Assert(!PDMCritSectIsOwner(&pThis->CritSect) || (idxReg != HPET_COUNTER && idxReg != HPET_COUNTER + 4));
 
     uint32_t u32Value;
@@ -720,7 +725,7 @@
  *          the TM lock.
  */
-static int hpetConfigRegWrite32(HpetState *pThis, uint32_t idxReg, uint32_t u32NewValue)
-{
-    Assert(!PDMCritSectIsOwner(&pThis->csLock) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));
+static int hpetConfigRegWrite32(HPET *pThis, uint32_t idxReg, uint32_t u32NewValue)
+{
+    Assert(!PDMCritSectIsOwner(&pThis->CritSect) || TMTimerIsLockOwner(pThis->aTimers[0].CTX_SUFF(pTimer)));
 
     int rc = VINF_SUCCESS;
@@ -856,84 +861,69 @@
 PDMBOTHCBDECL(int)  hpetMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
 {
-    HpetState      *pThis  = PDMINS_2_DATA(pDevIns, HpetState*);
+    HPET      *pThis  = PDMINS_2_DATA(pDevIns, HPET*);
     uint32_t const  idxReg = (uint32_t)(GCPhysAddr - HPET_BASE);
     NOREF(pvUser);
+    Assert(cb == 4 || cb == 8);
 
     LogFlow(("hpetMMIORead (%d): %llx (%x)\n", cb, (uint64_t)GCPhysAddr, idxReg));
 
-    int rc = VINF_SUCCESS;
-    switch (cb)
-    {
-        case 4:
+    int rc;
+    if (cb == 4)
+    {
+        /*
+         * 4-byte access.
+         */
+        if (idxReg >= 0x100 && idxReg < 0x400)
+        {
+            DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_READ);
+            rc = hpetTimerRegRead32(pThis,
+                                    (idxReg - 0x100) / 0x20,
+                                    (idxReg - 0x100) % 0x20,
+                                    (uint32_t *)pv);
+            DEVHPET_UNLOCK(pThis);
+        }
+        else
+            rc = hpetConfigRegRead32(pThis, idxReg, (uint32_t *)pv);
+    }
+    else
+    {
+        /*
+         * 8-byte access - Split the access except for timing sensitive registers.
+         * The others assume the protection of the lock.
+         */
+        PRTUINT64U pValue = (PRTUINT64U)pv;
+        if (idxReg == HPET_COUNTER)
+        {
+            /* When reading HPET counter we must read it in a single read,
+               to avoid unexpected time jumps on 32-bit overflow. */
+            DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_READ);
+            if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
+                pValue->u = hpetGetTicks(pThis);
+            else
+                pValue->u = pThis->u64HpetCounter;
+            DEVHPET_UNLOCK_BOTH(pThis);
+            rc = VINF_SUCCESS;
+        }
+        else
+        {
+            DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_READ);
             if (idxReg >= 0x100 && idxReg < 0x400)
             {
-                DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_READ);
-                rc = hpetTimerRegRead32(pThis,
-                                        (idxReg - 0x100) / 0x20,
-                                        (idxReg - 0x100) % 0x20,
-                                        (uint32_t *)pv);
-                DEVHPET_UNLOCK(pThis);
-            }
-            else
-                rc = hpetConfigRegRead32(pThis, idxReg, (uint32_t *)pv);
-            break;
-
-        case 8:
-        {
-            /* Unaligned accesses not allowed */
-            if (RT_UNLIKELY(idxReg % 8 != 0))
-            {
-                rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "idxReg=%#x cb=8\n", idxReg);
-                break;
-            }
-
-            /* Split the access except for timing sensitive registers.  The
-               others assume the protection of the lock. */
-            PRTUINT64U pValue = (PRTUINT64U)pv;
-            if (idxReg == HPET_COUNTER)
-            {
-                /* When reading HPET counter we must read it in a single read,
-                   to avoid unexpected time jumps on 32-bit overflow. */
-                DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_READ);
-                if (pThis->u64HpetConfig & HPET_CFG_ENABLE)
-                    pValue->u = hpetGetTicks(pThis);
-                else
-                    pValue->u = pThis->u64HpetCounter;
-                DEVHPET_UNLOCK_BOTH(pThis);
+                uint32_t iTimer    = (idxReg - 0x100) / 0x20;
+                uint32_t iTimerReg = (idxReg - 0x100) % 0x20;
+                rc = hpetTimerRegRead32(pThis, iTimer, iTimerReg, &pValue->s.Lo);
+                if (rc == VINF_SUCCESS)
+                    rc = hpetTimerRegRead32(pThis, iTimer, iTimerReg + 4, &pValue->s.Hi);
             }
             else
             {
-                DEVHPET_LOCK_RETURN(pThis, VINF_IOM_R3_MMIO_READ);
-                if (idxReg >= 0x100 && idxReg < 0x400)
-                {
-                    uint32_t iTimer    = (idxReg - 0x100) / 0x20;
-                    uint32_t iTimerReg = (idxReg - 0x100) % 0x20;
-                    rc = hpetTimerRegRead32(pThis, iTimer, iTimerReg, &pValue->s.Lo);
-                    if (rc == VINF_SUCCESS)
-                        rc = hpetTimerRegRead32(pThis, iTimer, iTimerReg + 4, &pValue->s.Hi);
-                }
-                else
-                {
-                    /* for most 8-byte accesses we just split them, happens under lock anyway. */
-                    rc = hpetConfigRegRead32(pThis, idxReg, &pValue->s.Lo);
-                    if (rc == VINF_SUCCESS)
-                        rc = hpetConfigRegRead32(pThis, idxReg + 4, &pValue->s.Hi);
-                }
-                DEVHPET_UNLOCK(pThis);
+                /* for most 8-byte accesses we just split them, happens under lock anyway. */
+                rc = hpetConfigRegRead32(pThis, idxReg, &pValue->s.Lo);
+                if (rc == VINF_SUCCESS)
+                    rc = hpetConfigRegRead32(pThis, idxReg + 4, &pValue->s.Hi);
             }
-            break;
-        }
-
-        case 1:
-        case 2:
-            Log(("Narrow read: %d\n", cb));
-            rc = VINF_SUCCESS;
-            break;
-
-        default:
-            AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
-            rc = VINF_SUCCESS;
-    }
-
+            DEVHPET_UNLOCK(pThis);
+        }
+    }
     return rc;
 }
@@ -945,65 +935,47 @@
 PDMBOTHCBDECL(int) hpetMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb)
 {
-    HpetState  *pThis  = PDMINS_2_DATA(pDevIns, HpetState*);
+    HPET  *pThis  = PDMINS_2_DATA(pDevIns, HPET*);
     uint32_t    idxReg = (uint32_t)(GCPhysAddr - HPET_BASE);
     LogFlow(("hpetMMIOWrite: cb=%u reg=%03x (%RGp) val=%llx\n",
              cb, idxReg, GCPhysAddr, cb == 4 ? *(uint32_t *)pv : cb == 8 ? *(uint64_t *)pv : 0xdeadbeef));
     NOREF(pvUser);
+    Assert(cb == 4 || cb == 8);
 
     int rc;
-    switch (cb)
-    {
-        case 4:
-            if (idxReg >= 0x100 && idxReg < 0x400)
-                rc = hpetTimerRegWrite32(pThis,
-                                         (idxReg - 0x100) / 0x20,
-                                         (idxReg - 0x100) % 0x20,
-                                         *(uint32_t const *)pv);
-            else
-                rc = hpetConfigRegWrite32(pThis, idxReg, *(uint32_t const *)pv);
-            break;
-
-        case 8:
-        {
-            /* Unaligned accesses are not allowed. */
-            if (RT_UNLIKELY(idxReg % 8 != 0))
-            {
-                rc = PDMDevHlpDBGFStop(pDevIns, RT_SRC_POS, "idxReg=%#x cb=8\n", idxReg);
-                break;
-            }
-
-            /* Split the access and rely on the locking to prevent trouble. */
-            DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE);
-            RTUINT64U uValue;
-            uValue.u = *(uint64_t const *)pv;
-            if (idxReg >= 0x100 && idxReg < 0x400)
-            {
-                uint32_t iTimer    = (idxReg - 0x100) / 0x20;
-                uint32_t iTimerReg = (idxReg - 0x100) % 0x20;
-/** @todo Consider handling iTimerReg == HPET_TN_CMP specially here */
-                rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg, uValue.s.Lo);
-                if (RT_LIKELY(rc == VINF_SUCCESS))
-                    rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg + 4, uValue.s.Hi);
-            }
-            else
-            {
-                rc = hpetConfigRegWrite32(pThis, idxReg, uValue.s.Lo);
-                if (RT_LIKELY(rc == VINF_SUCCESS))
-                    rc = hpetConfigRegWrite32(pThis, idxReg + 4, uValue.s.Hi);
-            }
-            DEVHPET_UNLOCK_BOTH(pThis);
-            break;
-        }
-
-        case 1:
-        case 2:
-            Log(("Narrow write: %d\n", cb));
-            rc = VINF_SUCCESS;
-            break;
-
-        default:
-            AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
-            rc = VERR_INTERNAL_ERROR;
-            break;
+    if (cb == 4)
+    {
+        if (idxReg >= 0x100 && idxReg < 0x400)
+            rc = hpetTimerRegWrite32(pThis,
+                                     (idxReg - 0x100) / 0x20,
+                                     (idxReg - 0x100) % 0x20,
+                                     *(uint32_t const *)pv);
+        else
+            rc = hpetConfigRegWrite32(pThis, idxReg, *(uint32_t const *)pv);
+    }
+    else
+    {
+        /*
+         * 8-byte access.
+         */
+        /* Split the access and rely on the locking to prevent trouble. */
+        DEVHPET_LOCK_BOTH_RETURN(pThis, VINF_IOM_R3_MMIO_WRITE);
+        RTUINT64U uValue;
+        uValue.u = *(uint64_t const *)pv;
+        if (idxReg >= 0x100 && idxReg < 0x400)
+        {
+            uint32_t iTimer    = (idxReg - 0x100) / 0x20;
+            uint32_t iTimerReg = (idxReg - 0x100) % 0x20;
+    /** @todo Consider handling iTimerReg == HPET_TN_CMP specially here */
+            rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg, uValue.s.Lo);
+            if (RT_LIKELY(rc == VINF_SUCCESS))
+                rc = hpetTimerRegWrite32(pThis, iTimer, iTimerReg + 4, uValue.s.Hi);
+        }
+        else
+        {
+            rc = hpetConfigRegWrite32(pThis, idxReg, uValue.s.Lo);
+            if (RT_LIKELY(rc == VINF_SUCCESS))
+                rc = hpetConfigRegWrite32(pThis, idxReg + 4, uValue.s.Hi);
+        }
+        DEVHPET_UNLOCK_BOTH(pThis);
     }
 
@@ -1021,5 +993,5 @@
  * @param   pHpetTimer          The HPET timer.
  */
-static uint32_t hpetTimerCbGetIrq(struct HpetTimer const *pHpetTimer)
+static uint32_t hpetR3TimerGetIrq(struct HPETTIMER const *pHpetTimer)
 {
     /*
@@ -1040,10 +1012,10 @@
 
 /**
- * Used by hpetTimerCb to update the IRQ status.
+ * Used by hpetR3Timer to update the IRQ status.
  *
  * @param   pThis               The HPET device state.
  * @param   pHpetTimer          The HPET timer.
  */
-static void hpetTimerCbUpdateIrq(HpetState *pThis, struct HpetTimer *pHpetTimer)
+static void hpetR3TimerUpdateIrq(HPET *pThis, struct HPETTIMER *pHpetTimer)
 {
     /** @todo: is it correct? */
@@ -1051,5 +1023,5 @@
         && !!(pThis->u64HpetConfig & HPET_CFG_ENABLE))
     {
-        uint32_t irq = hpetTimerCbGetIrq(pHpetTimer);
+        uint32_t irq = hpetR3TimerGetIrq(pHpetTimer);
         Log4(("HPET: raising IRQ %d\n", irq));
 
@@ -1075,8 +1047,8 @@
  * @param   pvUser          Pointer to the HPET timer state.
  */
-static DECLCALLBACK(void) hpetTimerCb(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
-{
-    HpetState *pThis      = PDMINS_2_DATA(pDevIns, HpetState *);
-    HpetTimer *pHpetTimer = (HpetTimer *)pvUser;
+static DECLCALLBACK(void) hpetR3Timer(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
+{
+    HPET *pThis      = PDMINS_2_DATA(pDevIns, HPET *);
+    HPETTIMER *pHpetTimer = (HPETTIMER *)pvUser;
     uint64_t   u64Period  = pHpetTimer->u64Period;
     uint64_t   u64CurTick = hpetGetTicks(pThis);
@@ -1106,5 +1078,5 @@
 
     /* Should it really be under lock, does it really matter? */
-    hpetTimerCbUpdateIrq(pThis, pHpetTimer);
+    hpetR3TimerUpdateIrq(pThis, pHpetTimer);
 }
 
@@ -1116,7 +1088,7 @@
  * @callback_method_impl{FNDBGFHANDLERDEV}
  */
-static DECLCALLBACK(void) hpetInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
-{
-    HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
+static DECLCALLBACK(void) hpetR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    HPET *pThis = PDMINS_2_DATA(pDevIns, HPET *);
     NOREF(pszArgs);
 
@@ -1149,7 +1121,7 @@
  * @callback_method_impl{FNSSMDEVLIVEEXEC}
  */
-static DECLCALLBACK(int) hpetLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
-{
-    HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
+static DECLCALLBACK(int) hpetR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
+{
+    HPET *pThis = PDMINS_2_DATA(pDevIns, HPET *);
     NOREF(uPass);
 
@@ -1163,12 +1135,12 @@
  * @callback_method_impl{FNSSMDEVSAVEEXEC}
  */
-static DECLCALLBACK(int) hpetSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
-{
-    HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
+static DECLCALLBACK(int) hpetR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
+{
+    HPET *pThis = PDMINS_2_DATA(pDevIns, HPET *);
 
     /*
      * The config.
      */
-    hpetLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
+    hpetR3LiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
 
     /*
@@ -1178,5 +1150,5 @@
     for (uint32_t iTimer = 0; iTimer < cTimers; iTimer++)
     {
-        HpetTimer *pHpetTimer = &pThis->aTimers[iTimer];
+        HPETTIMER *pHpetTimer = &pThis->aTimers[iTimer];
         TMR3TimerSave(pHpetTimer->pTimerR3, pSSM);
         SSMR3PutU8(pSSM,  pHpetTimer->u8Wrap);
@@ -1199,7 +1171,7 @@
  * @callback_method_impl{FNSSMDEVLOADEXEC}
  */
-static DECLCALLBACK(int) hpetLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
-{
-    HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
+static DECLCALLBACK(int) hpetR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
+{
+    HPET *pThis = PDMINS_2_DATA(pDevIns, HPET *);
 
     /*
@@ -1229,5 +1201,5 @@
     for (uint32_t iTimer = 0; iTimer < cTimers; iTimer++)
     {
-        HpetTimer *pHpetTimer = &pThis->aTimers[iTimer];
+        HPETTIMER *pHpetTimer = &pThis->aTimers[iTimer];
         TMR3TimerLoad(pHpetTimer->pTimerR3, pSSM);
         SSMR3GetU8(pSSM,  &pHpetTimer->u8Wrap);
@@ -1255,12 +1227,12 @@
      * Set the timer frequency hints.
      */
-    PDMCritSectEnter(&pThis->csLock, VERR_IGNORED);
+    PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED);
     for (uint32_t iTimer = 0; iTimer < cTimers; iTimer++)
     {
-        HpetTimer *pHpetTimer = &pThis->aTimers[iTimer];
+        HPETTIMER *pHpetTimer = &pThis->aTimers[iTimer];
         if (TMTimerIsActive(pHpetTimer->CTX_SUFF(pTimer)))
             hpetTimerSetFrequencyHint(pThis, pHpetTimer);
     }
-    PDMCritSectLeave(&pThis->csLock);
+    PDMCritSectLeave(&pThis->CritSect);
     return VINF_SUCCESS;
 }
@@ -1273,8 +1245,8 @@
  * @interface_method_impl{PDMDEVREG,pfnRelocate}
  */
-static DECLCALLBACK(void) hpetRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
-{
-    HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
-    LogFlow(("hpetRelocate:\n"));
+static DECLCALLBACK(void) hpetR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
+{
+    HPET *pThis = PDMINS_2_DATA(pDevIns, HPET *);
+    LogFlow(("hpetR3Relocate:\n"));
     NOREF(offDelta);
 
@@ -1284,5 +1256,5 @@
     for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
     {
-        HpetTimer *pTm = &pThis->aTimers[i];
+        HPETTIMER *pTm = &pThis->aTimers[i];
         if (pTm->pTimerR3)
             pTm->pTimerRC = TMTimerRCPtr(pTm->pTimerR3);
@@ -1295,8 +1267,8 @@
  * @interface_method_impl{PDMDEVREG,pfnReset}
  */
-static DECLCALLBACK(void) hpetReset(PPDMDEVINS pDevIns)
-{
-    HpetState *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
-    LogFlow(("hpetReset:\n"));
+static DECLCALLBACK(void) hpetR3Reset(PPDMDEVINS pDevIns)
+{
+    HPET *pThis = PDMINS_2_DATA(pDevIns, HPET *);
+    LogFlow(("hpetR3Reset:\n"));
 
     /*
@@ -1306,5 +1278,5 @@
     for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
     {
-        HpetTimer *pHpetTimer = &pThis->aTimers[i];
+        HPETTIMER *pHpetTimer = &pThis->aTimers[i];
         Assert(pHpetTimer->idxTimer == i);
         TMTimerStop(pHpetTimer->pTimerR3);
@@ -1359,11 +1331,29 @@
  * @interface_method_impl{PDMDEVREG,pfnConstruct}
  */
-static DECLCALLBACK(int) hpetConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
+static DECLCALLBACK(int) hpetR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
 {
     PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
-    HpetState   *pThis = PDMINS_2_DATA(pDevIns, HpetState *);
+    HPET   *pThis = PDMINS_2_DATA(pDevIns, HPET *);
 
     /* Only one HPET device now, as we use fixed MMIO region. */
     Assert(iInstance == 0);
+
+    /*
+     * Initialize the device state.
+     */
+    pThis->pDevInsR3 = pDevIns;
+    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
+    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+
+    /* Init the HPET timers (init all regardless of how many we expose). */
+    for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
+    {
+        HPETTIMER *pHpetTimer = &pThis->aTimers[i];
+
+        pHpetTimer->idxTimer = i;
+        pHpetTimer->pHpetR3  = pThis;
+        pHpetTimer->pHpetR0  = PDMINS_2_DATA_R0PTR(pDevIns);
+        pHpetTimer->pHpetRC  = PDMINS_2_DATA_RCPTR(pDevIns);
+    }
 
     /*
@@ -1389,15 +1379,12 @@
                                 N_("Configuration error: failed to read ICH9 as boolean"));
 
-    /*
-     * Initialize the device state.
-     */
-    pThis->pDevInsR3 = pDevIns;
-    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
-    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
-
-    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->csLock, RT_SRC_POS, "HPET#%u", pDevIns->iInstance);
+
+    /*
+     * Create critsect and timers.
+     * Note! We don't use the default critical section of the device, but our own.
+     */
+    rc = PDMDevHlpCritSectInit(pDevIns, &pThis->CritSect, RT_SRC_POS, "HPET");
     AssertRCReturn(rc, rc);
 
-    /* No automatic locking. */
     rc = PDMDevHlpSetDeviceCritSect(pDevIns, PDMDevHlpCritSectGetNop(pDevIns));
     AssertRCReturn(rc, rc);
@@ -1406,12 +1393,7 @@
     for (unsigned i = 0; i < RT_ELEMENTS(pThis->aTimers); i++)
     {
-        HpetTimer *pHpetTimer = &pThis->aTimers[i];
-
-        pHpetTimer->idxTimer = i;
-        pHpetTimer->pHpetR3  = pThis;
-        pHpetTimer->pHpetR0  = PDMINS_2_DATA_R0PTR(pDevIns);
-        pHpetTimer->pHpetRC  = PDMINS_2_DATA_RCPTR(pDevIns);
-
-        rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hpetTimerCb, pHpetTimer,
+        HPETTIMER *pHpetTimer = &pThis->aTimers[i];
+
+        rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, hpetR3Timer, pHpetTimer,
                                     TMTIMER_FLAGS_NO_CRIT_SECT, "HPET Timer",
                                     &pThis->aTimers[i].pTimerR3);
@@ -1419,10 +1401,12 @@
         pThis->aTimers[i].pTimerRC = TMTimerRCPtr(pThis->aTimers[i].pTimerR3);
         pThis->aTimers[i].pTimerR0 = TMTimerR0Ptr(pThis->aTimers[i].pTimerR3);
-        rc = TMR3TimerSetCritSect(pThis->aTimers[i].pTimerR3, &pThis->csLock);
+        rc = TMR3TimerSetCritSect(pThis->aTimers[i].pTimerR3, &pThis->CritSect);
         AssertRCReturn(rc, rc);
     }
 
-    /* This must be done prior to registering the HPET, right? */
-    hpetReset(pDevIns);
+    /*
+     * This must be done prior to registering the HPET, right?
+     */
+    hpetR3Reset(pDevIns);
 
     /*
@@ -1439,5 +1423,5 @@
      */
     rc = PDMDevHlpMMIORegister(pDevIns, HPET_BASE, HPET_BAR_SIZE, pThis,
-                               IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
+                               IOMMMIO_FLAGS_READ_DWORD_QWORD | IOMMMIO_FLAGS_WRITE_ONLY_DWORD_QWORD,
                                hpetMMIOWrite, hpetMMIORead, "HPET Memory");
     AssertRCReturn(rc, rc);
@@ -1463,9 +1447,9 @@
 
     /* Register SSM callbacks */
-    rc = PDMDevHlpSSMRegister3(pDevIns, HPET_SAVED_STATE_VERSION, sizeof(*pThis), hpetLiveExec, hpetSaveExec, hpetLoadExec);
+    rc = PDMDevHlpSSMRegister3(pDevIns, HPET_SAVED_STATE_VERSION, sizeof(*pThis), hpetR3LiveExec, hpetR3SaveExec, hpetR3LoadExec);
     AssertRCReturn(rc, rc);
 
     /* Register an info callback. */
-    PDMDevHlpDBGFInfoRegister(pDevIns, "hpet", "Display HPET status. (no arguments)", hpetInfo);
+    PDMDevHlpDBGFInfoRegister(pDevIns, "hpet", "Display HPET status. (no arguments)", hpetR3Info);
 
     return VINF_SUCCESS;
@@ -1489,5 +1473,6 @@
     " 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,
+    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,
@@ -1495,11 +1480,11 @@
     1,
     /* cbInstance */
-    sizeof(HpetState),
+    sizeof(HPET),
     /* pfnConstruct */
-    hpetConstruct,
+    hpetR3Construct,
     /* pfnDestruct */
     NULL,
     /* pfnRelocate */
-    hpetRelocate,
+    hpetR3Relocate,
     /* pfnIOCtl */
     NULL,
@@ -1507,5 +1492,5 @@
     NULL,
     /* pfnReset */
-    hpetReset,
+    hpetR3Reset,
     /* pfnSuspend */
     NULL,
