Index: /trunk/include/VBox/gic-its.h
===================================================================
--- /trunk/include/VBox/gic-its.h	(revision 108940)
+++ /trunk/include/VBox/gic-its.h	(revision 108941)
@@ -320,5 +320,6 @@
 /** GITS_BASER: Mask of valid read-write bits. */
 #define GITS_CTRL_REG_BASER_RW_MASK                             (UINT64_MAX & ~(  GITS_BF_CTRL_REG_BASER_ENTRY_SIZE_MASK \
-                                                                                | GITS_BF_CTRL_REG_BASER_TYPE_MASK))
+                                                                                | GITS_BF_CTRL_REG_BASER_TYPE_MASK \
+                                                                                | GITS_BF_CTRL_REG_BASER_INDIRECT_MASK))
 
 /** GITS_BASER: Table type - Unimplemented (not a table). */
Index: /trunk/src/VBox/VMM/VMMAll/GICAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/GICAll.cpp	(revision 108940)
+++ /trunk/src/VBox/VMM/VMMAll/GICAll.cpp	(revision 108941)
@@ -3102,13 +3102,13 @@
     pGicDev->fAffRoutingEnabled = true; /* GICv2 backwards compatibility is not implemented, so this is RA1/WI. */
 
-    /* LPIs. */
-    RT_ZERO(pGicDev->bmLpiPending);
-    RT_ZERO(pGicDev->abLpiConfig);
-    pGicDev->uLpiConfigBaseReg.u = 0;
-    pGicDev->fEnableLpis = false;
-
     /* GITS. */
     PGITSDEV pGitsDev = &pGicDev->Gits;
     gitsInit(pGitsDev);
+
+    /* LPIs. */
+    RT_ZERO(pGicDev->abLpiConfig);
+    RT_ZERO(pGicDev->bmLpiPending);
+    pGicDev->uLpiConfigBaseReg.u = 0;
+    pGicDev->fEnableLpis = false;
 }
 
Index: /trunk/src/VBox/VMM/VMMAll/GITSAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/GITSAll.cpp	(revision 108940)
+++ /trunk/src/VBox/VMM/VMMAll/GITSAll.cpp	(revision 108941)
@@ -69,5 +69,61 @@
  * during compile time. */
 #define GITSDIAG_DESC(a_Name)                       RT_CONCAT(kGitsDiag_, a_Name) < kGitsDiag_End ? RT_STR(a_Name) : "Ignored"
-/** @} */
+
+/** @def GITS_SET_REG_U64_FULL
+ * Sets a 64-bit GITS register.
+ * @param   a_uReg      The 64-bit register to set.
+ * @param   a_uValue    The 64-bit value being written.
+ * @param   a_fRwMask   The 64-bit mask of valid read-write bits.
+ */
+#define GITS_SET_REG_U64_FULL(a_uReg, a_uValue, a_fRwMask) \
+    do \
+    { \
+        AssertCompile(sizeof(a_uReg) == sizeof(uint64_t)); \
+        AssertCompile(sizeof(a_fRwMask) == sizeof(uint64_t)); \
+        (a_uReg) = ((a_uReg) & ~(a_fRwMask)) | ((a_uValue) & (a_fRwMask)); \
+    } while (0)
+
+/** @def GITS_SET_REG_U64_LO
+ * Sets the lower half of a 64-bit GITS register.
+ * @param   a_uReg      The lower half of a 64-bit register to set.
+ * @param   a_uValue    The value being written (only lower 32-bits are used).
+ * @param   a_fRwMask   The 64-bit mask of valid read-write bits.
+ */
+#define GITS_SET_REG_U64_LO(a_uReg, a_uValue, a_fRwMask) \
+    do \
+    { \
+        AssertCompile(sizeof(a_uReg) == sizeof(uint32_t)); \
+        AssertCompile(sizeof(a_fRwMask) == sizeof(uint64_t)); \
+        (a_uReg) = ((a_uReg) & ~(RT_LO_U32(a_fRwMask))) | ((uint32_t)(a_uValue) & (RT_LO_U32(a_fRwMask))); \
+    } while (0)
+
+/** @def GITS_SET_REG_U64_HI
+ * Sets the upper half of a 64-bit GITS register.
+ * @param   a_uReg      The upper half of the 64-bit register to set.
+ * @param   a_uValue    The value being written (only lower 32-bits are used).
+ * @param   a_fRwMask   The 64-bit mask of valid read-write bits.
+ */
+#define GITS_SET_REG_U64_HI(a_uReg, a_uValue, a_fRwMask) \
+    do \
+    { \
+        AssertCompile(sizeof(a_uReg) == sizeof(uint32_t)); \
+        AssertCompile(sizeof(a_fRwMask) == sizeof(uint64_t)); \
+        (a_uReg) = ((a_uReg) & ~(RT_HI_U32(a_fRwMask))) | ((uint32_t)(a_uValue) & (RT_HI_U32(a_fRwMask))); \
+    } while (0)
+
+/** @def GITS_SET_REG_U32_FULL
+ * Sets a 32-bit GITS register.
+ * @param   a_uReg      The 32-bit register to set.
+ * @param   a_uValue    The 32-bit value being written (only lower 32-bits are
+ *                      used).
+ * @param   a_fRwMask   The mask of valid read-write bits (only lower 32-bits are
+ *                      used).
+ */
+#define GITS_SET_REG_U32(a_uReg, a_uValue, a_fRwMask) \
+    do \
+    { \
+        AssertCompile(sizeof(a_uReg) == sizeof(uint32_t)); \
+        (a_uReg) = ((a_uReg) & ~(a_fRwMask)) | ((uint32_t)(a_uValue) & (uint32_t)(a_fRwMask)); \
+    } while (0)
 
 
@@ -311,17 +367,18 @@
     if (GITS_IS_REG_IN_RANGE(offReg, GITS_CTRL_REG_BASER_OFF_FIRST, GITS_CTRL_REG_BASER_RANGE_SIZE))
     {
-        uint16_t const cbReg  = sizeof(uint64_t);
-        uint16_t const idxReg = (offReg - GITS_CTRL_REG_BASER_OFF_FIRST) / cbReg;
+        uint16_t const cbReg   = sizeof(uint64_t);
+        uint16_t const idxReg  = (offReg - GITS_CTRL_REG_BASER_OFF_FIRST) / cbReg;
+        uint64_t const fRwMask = GITS_CTRL_REG_BASER_RW_MASK;
         if (!(offReg & 7))
         {
             if (cb == 8)
-                pGitsDev->aItsTableRegs[idxReg].u = uValue & GITS_CTRL_REG_BASER_RW_MASK;
+                GITS_SET_REG_U64_FULL(pGitsDev->aItsTableRegs[idxReg].u, uValue, fRwMask);
             else
-                pGitsDev->aItsTableRegs[idxReg].s.Lo = uValue & RT_LO_U32(GITS_CTRL_REG_BASER_RW_MASK);
+                GITS_SET_REG_U64_LO(pGitsDev->aItsTableRegs[idxReg].s.Lo, uValue, fRwMask);
         }
         else
         {
             Assert(cb == 4);
-            pGitsDev->aItsTableRegs[idxReg].s.Hi = uValue & RT_HI_U32(GITS_CTRL_REG_BASER_RW_MASK);
+            GITS_SET_REG_U64_HI(pGitsDev->aItsTableRegs[idxReg].s.Hi, uValue, fRwMask);
         }
         return;
@@ -333,5 +390,5 @@
             Assert(cb == 4);
             Assert(!(pGitsDev->uTypeReg.u & GITS_BF_CTRL_REG_TYPER_UMSI_IRQ_MASK));
-            pGitsDev->uCtrlReg = uValue & GITS_BF_CTRL_REG_CTLR_RW_MASK;
+            GITS_SET_REG_U32(pGitsDev->uCtrlReg, uValue, GITS_BF_CTRL_REG_CTLR_RW_MASK);
             if (RT_BF_GET(uValue, GITS_BF_CTRL_REG_CTLR_ENABLED))
                 pGitsDev->uCtrlReg &= GITS_BF_CTRL_REG_CTLR_QUIESCENT_MASK;
@@ -340,9 +397,8 @@
 
         case GITS_CTRL_REG_CBASER_OFF:
-            uValue &= GITS_CTRL_REG_CBASER_RW_MASK;
             if (cb == 8)
-                pGitsDev->uCmdBaseReg.u = uValue;
+                GITS_SET_REG_U64_FULL(pGitsDev->uCmdBaseReg.u, uValue, GITS_CTRL_REG_CBASER_RW_MASK);
             else
-                pGitsDev->uCmdBaseReg.s.Lo = (uint32_t)uValue;
+                GITS_SET_REG_U64_LO(pGitsDev->uCmdBaseReg.s.Lo, uValue, GITS_CTRL_REG_CBASER_RW_MASK);
             gitsCmdQueueThreadWakeUpIfNeeded(pDevIns, pGitsDev);
             break;
@@ -350,10 +406,10 @@
         case GITS_CTRL_REG_CBASER_OFF + 4:
             Assert(cb == 4);
-            pGitsDev->uCmdBaseReg.s.Hi = uValue & RT_HI_U32(GITS_CTRL_REG_CBASER_RW_MASK);
+            GITS_SET_REG_U64_HI(pGitsDev->uCmdBaseReg.s.Hi, uValue, GITS_CTRL_REG_CBASER_RW_MASK);
             gitsCmdQueueThreadWakeUpIfNeeded(pDevIns, pGitsDev);
             break;
 
         case GITS_CTRL_REG_CWRITER_OFF:
-            pGitsDev->uCmdWriteReg = uValue & RT_LO_U32(GITS_CTRL_REG_CWRITER_RW_MASK);
+            GITS_SET_REG_U32(pGitsDev->uCmdWriteReg, uValue, GITS_CTRL_REG_CWRITER_RW_MASK);
             gitsCmdQueueThreadWakeUpIfNeeded(pDevIns, pGitsDev);
             break;
@@ -387,5 +443,8 @@
     Log4Func(("\n"));
 
-    pGitsDev->uCtrlReg   = RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_QUIESCENT,  1);
+    /* GITS_CTLR.*/
+    pGitsDev->uCtrlReg = RT_BF_MAKE(GITS_BF_CTRL_REG_CTLR_QUIESCENT,  1);
+
+    /* GITS_TYPER. */
     pGitsDev->uTypeReg.u = RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_PHYSICAL,  1)     /* Physical LPIs supported. */
                        /*| RT_BF_MAKE(GITS_BF_CTRL_REG_TYPER_VIRTUAL,   0) */  /* Virtual LPIs not supported. */
@@ -410,15 +469,20 @@
                                                                                   GITS_CTLR.Enabled and GITS_BASER<n>.Valid. */
     Assert(RT_ELEMENTS(pGitsDev->auCtes) >= RT_BF_GET(pGitsDev->uTypeReg.u, GITS_BF_CTRL_REG_TYPER_HCC));
+
+    /* GITS_BASER<n>. */
     RT_ZERO(pGitsDev->aItsTableRegs);
-
     pGitsDev->aItsTableRegs[0].u = RT_BF_MAKE(GITS_BF_CTRL_REG_BASER_ENTRY_SIZE, GITS_ITE_SIZE - 1)
                                  | RT_BF_MAKE(GITS_BF_CTRL_REG_BASER_TYPE,       GITS_BASER_TYPE_DEVICES)
                                  | RT_BF_MAKE(GITS_BF_CTRL_REG_BASER_VALID,      1);
 
-    pGitsDev->uCmdBaseReg.u   = 0;
-    pGitsDev->uCmdReadReg     = 0;
-    pGitsDev->uCmdWriteReg    = 0;
+    /* GITS_CBASER, GITS_CREADR, GITS_CWRITER. */
+    pGitsDev->uCmdBaseReg.u = 0;
+    pGitsDev->uCmdReadReg   = 0;
+    pGitsDev->uCmdWriteReg  = 0;
+
+    /* Collection Table. */
     RT_ZERO(pGitsDev->auCtes);
 
+    /* Misc. stuff. */
     pGitsDev->cCmdQueueErrors = 0;
 }
@@ -426,8 +490,6 @@
 
 #ifdef IN_RING3
-DECL_HIDDEN_CALLBACK(void) gitsR3DbgInfo(PCGITSDEV pGitsDev, PCDBGFINFOHLP pHlp, const char *pszArgs)
-{
-    RT_NOREF(pszArgs);
-
+DECL_HIDDEN_CALLBACK(void) gitsR3DbgInfo(PCGITSDEV pGitsDev, PCDBGFINFOHLP pHlp)
+{
     pHlp->pfnPrintf(pHlp, "GIC ITS:\n");
 
Index: /trunk/src/VBox/VMM/VMMR3/GICR3.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GICR3.cpp	(revision 108940)
+++ /trunk/src/VBox/VMM/VMMR3/GICR3.cpp	(revision 108941)
@@ -287,11 +287,59 @@
 static DECLCALLBACK(void) gicR3DbgInfoIts(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
 {
-    PGIC pGic = VM_TO_GIC(pVM);
+    NOREF(pszArgs);
+    PGIC       pGic    = VM_TO_GIC(pVM);
+    PPDMDEVINS pDevIns = pGic->CTX_SUFF(pDevIns);
+    PCGICDEV   pGicDev = PDMDEVINS_2_DATA(pDevIns, PCGICDEV);
+    if (pGicDev->hMmioGits != NIL_IOMMMIOHANDLE)
+        gitsR3DbgInfo(&pGicDev->Gits, pHlp);
+    else
+        pHlp->pfnPrintf(pHlp, "GIC ITS is not mapped/configured for the VM\n");
+}
+
+
+/**
+ * Dumps the GIC LPI information.
+ *
+ * @param   pVM         The cross context VM structure.
+ * @param   pHlp        The info helpers.
+ * @param   pszArgs     Arguments, ignored.
+ */
+static DECLCALLBACK(void) gicR3DbgInfoLpi(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
+{
+    NOREF(pszArgs);
+    PGIC       pGic     = VM_TO_GIC(pVM);
     PPDMDEVINS pDevIns  = pGic->CTX_SUFF(pDevIns);
     PCGICDEV   pGicDev  = PDMDEVINS_2_DATA(pDevIns, PCGICDEV);
-    if (pGicDev->hMmioGits != NIL_IOMMMIOHANDLE)
-        gitsR3DbgInfo(&pGicDev->Gits, pHlp, pszArgs);
-    else
-        pHlp->pfnPrintf(pHlp, "GIC ITS is not mapped/configured for the VM\n");
+    if (!pGicDev->fLpi)
+    {
+        pHlp->pfnPrintf(pHlp, "GIC LPI support is not enabled for the VM\n");
+        return;
+    }
+    pHlp->pfnPrintf(pHlp, "GIC LPIs:\n");
+    pHlp->pfnPrintf(pHlp, "  Enabled            = %RTbool\n", pGicDev->fEnableLpis);
+
+    /* GICR_PENDBASER. */
+    {
+        uint64_t const uReg = pGicDev->uLpiPendingBaseReg.u;
+        pHlp->pfnPrintf(pHlp, "  uLpiPendingBaseReg = %#RX64\n", uReg);
+        pHlp->pfnPrintf(pHlp, "    Inner cache        = %#x\n",     RT_BF_GET(uReg, GIC_BF_REDIST_REG_PENDBASER_INNER_CACHE));
+        pHlp->pfnPrintf(pHlp, "    Shareability       = %#x\n",     RT_BF_GET(uReg, GIC_BF_REDIST_REG_PENDBASER_SHAREABILITY));
+        pHlp->pfnPrintf(pHlp, "    Phys addr          = %#RX64\n",  uReg & GIC_BF_REDIST_REG_PENDBASER_PHYS_ADDR_MASK);
+        pHlp->pfnPrintf(pHlp, "    Outer cache        = %#x\n",     RT_BF_GET(uReg, GIC_BF_REDIST_REG_PENDBASER_OUTER_CACHE));
+        pHlp->pfnPrintf(pHlp, "    Pending Table Zero = %RTbool\n", RT_BF_GET(uReg, GIC_BF_REDIST_REG_PENDBASER_PTZ));
+    }
+
+    /* GICR_PROPBASER. */
+    {
+        uint64_t const uReg   = pGicDev->uLpiConfigBaseReg.u;
+        uint8_t const cIdBits = RT_BF_GET(uReg, GIC_BF_REDIST_REG_PROPBASER_ID_BITS);
+        pHlp->pfnPrintf(pHlp, "  uLpiConfigBaseReg  = %#RX64\n", uReg);
+        pHlp->pfnPrintf(pHlp, "    ID bits            = %#x (%u bits)\n", cIdBits, cIdBits);
+        pHlp->pfnPrintf(pHlp, "    Inner cache        = %#x\n",    RT_BF_GET(uReg, GIC_BF_REDIST_REG_PROPBASER_INNER_CACHE));
+        pHlp->pfnPrintf(pHlp, "    Shareability       = %#x\n",    RT_BF_GET(uReg, GIC_BF_REDIST_REG_PROPBASER_SHAREABILITY));
+        pHlp->pfnPrintf(pHlp, "    Phys addr          = %#RX64\n", uReg & GIC_BF_REDIST_REG_PROPBASER_PHYS_ADDR_MASK);
+        pHlp->pfnPrintf(pHlp, "    Outer cache        = %#x\n",    RT_BF_GET(uReg, GIC_BF_REDIST_REG_PROPBASER_OUTER_CACHE));
+    }
+    /** @todo Dump LPI config and LPI pending registers. */
 }
 
@@ -957,4 +1005,5 @@
     DBGFR3InfoRegisterInternalEx(pVM, "gicredist", "Dumps GIC redistributor information.", gicR3DbgInfoReDist, DBGFINFO_FLAGS_ALL_EMTS);
     DBGFR3InfoRegisterInternalEx(pVM, "gicits",    "Dumps GIC ITS information.",           gicR3DbgInfoIts,    DBGFINFO_FLAGS_ALL_EMTS);
+    DBGFR3InfoRegisterInternalEx(pVM, "giclpi",    "Dumps GIC LPI information.",           gicR3DbgInfoLpi,    DBGFINFO_FLAGS_ALL_EMTS);
 
     /*
Index: /trunk/src/VBox/VMM/include/GITSInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/GITSInternal.h	(revision 108940)
+++ /trunk/src/VBox/VMM/include/GITSInternal.h	(revision 108941)
@@ -202,5 +202,5 @@
 
 #ifdef IN_RING3
-DECL_HIDDEN_CALLBACK(void)         gitsR3DbgInfo(PCGITSDEV pGitsDev, PCDBGFINFOHLP pHlp, const char *pszArgs);
+DECL_HIDDEN_CALLBACK(void)         gitsR3DbgInfo(PCGITSDEV pGitsDev, PCDBGFINFOHLP pHlp);
 DECL_HIDDEN_CALLBACK(int)          gitsR3CmdQueueProcess(PPDMDEVINS pDevIns, PGITSDEV pGitsDev, void *pvBuf, uint32_t cbBuf);
 #endif
