Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp	(revision 22443)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp	(revision 22444)
@@ -1206,27 +1206,58 @@
          VBoxBiosString,
          sizeof(VBoxBiosString));
-#if defined(VBOX_WITH_HGSMI) && defined(VBOX_WITH_VIDEOHWACCEL)
-      VIDEO_ACCESS_RANGE tmpRanges[1];
-      ULONG slot;
-
-      /* need to call VideoPortGetAccessRanges to ensure interrupt info in ConfigInfo gets set up */
-      VP_STATUS status = VideoPortGetAccessRanges(HwDeviceExtension,
-                                        0,
-                                        NULL,
-                                        1,
-                                        tmpRanges,
-                                        NULL,
-                                        NULL,
-                                        (PULONG) &slot);
-      Assert(status == NO_ERROR );
-//      Assert(AccessRanges[0].RangeStart.QuadPart == tmpRanges[0].RangeStart.QuadPart);
-//      Assert(AccessRanges[0].RangeLength == tmpRanges[0].RangeLength);
-//      Assert(AccessRanges[0].RangeInIoSpace == tmpRanges[0].RangeInIoSpace);
-//      Assert(AccessRanges[0].RangeVisible == tmpRanges[0].RangeVisible);
-//      Assert(AccessRanges[0].RangeShareable == tmpRanges[0].RangeShareable);
-//      Assert(AccessRanges[0].RangePassive == tmpRanges[0].RangePassive);
-
-      /* no matter what we get with VideoPortGetAccessRanges, we assert the default ranges */
-#endif
+#ifdef VBOX_WITH_HGSMI
+      if (VBoxHGSMIIsSupported ((PDEVICE_EXTENSION)HwDeviceExtension))
+      {
+          dprintf(("VBoxVideo::VBoxVideoFindAdapter: calling VideoPortGetAccessRanges\n"));
+
+          /* Ports not yet found. */
+          ((PDEVICE_EXTENSION)HwDeviceExtension)->u.primary.IOPortHost = 0;
+          ((PDEVICE_EXTENSION)HwDeviceExtension)->u.primary.IOPortGuest = 0;
+
+          VIDEO_ACCESS_RANGE tmpRanges[2];
+          ULONG slot;
+
+          /* need to call VideoPortGetAccessRanges to ensure interrupt info in ConfigInfo gets set up */
+          VP_STATUS status = VideoPortGetAccessRanges(HwDeviceExtension,
+                                            0,
+                                            NULL,
+                                            sizeof (tmpRanges)/sizeof (tmpRanges[0]),
+                                            tmpRanges,
+                                            NULL,
+                                            NULL,
+                                            (PULONG) &slot);
+          if (status == NO_ERROR)
+          {
+              ULONG iRange = 0;
+              for (; iRange < sizeof (tmpRanges)/sizeof (tmpRanges[0]); iRange++)
+              {
+                  dprintf(("VBoxVideo::VBoxVideoFindAdapter: range[%i]:\n"
+                           "    RangeStart = 0x%llx\n"
+                           "    RangeLength = %d\n"
+                           "    RangeInIoSpace = %d\n"
+                           "    RangeVisible = %d\n"
+                           "    RangeShareable = %d\n"
+                           "    RangePassive = %d\n",
+                           iRange,
+                           tmpRanges[iRange].RangeStart.QuadPart,
+                           tmpRanges[iRange].RangeLength,
+                           tmpRanges[iRange].RangeInIoSpace,
+                           tmpRanges[iRange].RangeVisible,
+                           tmpRanges[iRange].RangeShareable,
+                           tmpRanges[iRange].RangePassive));
+                   if (tmpRanges[iRange].RangeInIoSpace)
+                   {
+                       PVOID ioBase = VideoPortGetDeviceBase(HwDeviceExtension, tmpRanges[iRange].RangeStart, 8, VIDEO_MEMORY_SPACE_IO);
+                       dprintf (("ioBase %p\n", ioBase));
+
+                       ((PDEVICE_EXTENSION)HwDeviceExtension)->u.primary.IOPortHost = (RTIOPORT)ioBase + VGA_PORT_OFF_HGSMI_HOST;
+                       ((PDEVICE_EXTENSION)HwDeviceExtension)->u.primary.IOPortGuest = (RTIOPORT)ioBase + VGA_PORT_OFF_HGSMI_GUEST;
+                   }
+              }
+          }
+
+          /* no matter what we get with VideoPortGetAccessRanges, we assert the default ranges */
+      }
+#endif /* VBOX_WITH_HGSMI */
       rc = VideoPortVerifyAccessRanges(HwDeviceExtension, 1, AccessRanges);
       dprintf(("VBoxVideo::VBoxVideoFindAdapter: VideoPortVerifyAccessRanges returned 0x%x\n", rc));
@@ -1777,5 +1808,5 @@
                 VideoPortWritePortUlong((PULONG)VBE_DISPI_IOPORT_DATA, VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE + pDevExt->iDevice);
 #else
-                VBoxVideoHostWriteUlong(((PDEVICE_EXTENSION)HwDeviceExtension)->pPrimary, VBE_DISPI_INDEX_VBOX_VIDEO, VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE + pDevExt->iDevice);
+                VBoxVideoVBEWriteUlong(((PDEVICE_EXTENSION)HwDeviceExtension)->pPrimary, VBE_DISPI_INDEX_VBOX_VIDEO, VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE + pDevExt->iDevice);
 #endif
             }
@@ -2044,5 +2075,5 @@
     VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_DATA, VBE_DISPI_DISABLED);
 #else
-    VBoxVideoHostWriteUshort(((PDEVICE_EXTENSION)HwDeviceExtension)->pPrimary, VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
+    VBoxVideoVBEWriteUshort(((PDEVICE_EXTENSION)HwDeviceExtension)->pPrimary, VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);
 #endif
 
@@ -2159,8 +2190,8 @@
     /** @todo read from the port to see if the mode switch was successful */
 #else
-    VBoxVideoHostWriteUshort(DeviceExtension->pPrimary, VBE_DISPI_INDEX_XRES, (USHORT)ModeInfo->VisScreenWidth);
-    VBoxVideoHostWriteUshort(DeviceExtension->pPrimary, VBE_DISPI_INDEX_YRES, (USHORT)ModeInfo->VisScreenHeight);
-    VBoxVideoHostWriteUshort(DeviceExtension->pPrimary, VBE_DISPI_INDEX_BPP, (USHORT)ModeInfo->BitsPerPlane);
-    VBoxVideoHostWriteUshort(DeviceExtension->pPrimary, VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
+    VBoxVideoVBEWriteUshort(DeviceExtension->pPrimary, VBE_DISPI_INDEX_XRES, (USHORT)ModeInfo->VisScreenWidth);
+    VBoxVideoVBEWriteUshort(DeviceExtension->pPrimary, VBE_DISPI_INDEX_YRES, (USHORT)ModeInfo->VisScreenHeight);
+    VBoxVideoVBEWriteUshort(DeviceExtension->pPrimary, VBE_DISPI_INDEX_BPP, (USHORT)ModeInfo->BitsPerPlane);
+    VBoxVideoVBEWriteUshort(DeviceExtension->pPrimary, VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
 #endif
 
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h	(revision 22443)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h	(revision 22444)
@@ -51,8 +51,4 @@
 #define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
 #define VBE_DISPI_INDEX_VBOX_VIDEO      0xa
-#ifdef VBOX_WITH_HGSMI
-#define VBE_DISPI_INDEX_VBVA_HOST       0xb
-#define VBE_DISPI_INDEX_VBVA_GUEST      0xc
-#endif /* VBOX_WITH_HGSMI */
 
 #define VBE_DISPI_ID2                   0xB0C2
@@ -70,4 +66,9 @@
 #define VBE_DISPI_TOTAL_VIDEO_MEMORY_BYTES      (VBE_DISPI_TOTAL_VIDEO_MEMORY_KB * 1024)
 
+#ifdef VBOX_WITH_HGSMI
+#define VGA_PORT_OFF_HGSMI_HOST  0
+#define VGA_PORT_OFF_HGSMI_GUEST 4
+#endif /* VBOX_WITH_HGSMI */
+
 typedef struct _DEVICE_EXTENSION
 {
@@ -142,4 +143,10 @@
 
            PSPIN_LOCK pGHRWLock; /* lock for making guest->host read/writes atomic */
+
+           /* The IO Port Number for host commands. */
+           RTIOPORT IOPortHost;
+
+           /* The IO Port Number for guest commands. */
+           RTIOPORT IOPortGuest;
 #endif /* VBOX_WITH_HGSMI */
        } primary;
@@ -256,5 +263,5 @@
 #ifdef VBOX_WITH_HGSMI
 
-DECLINLINE(void) VBoxVideoHostWriteUlongLocked(USHORT dataType, ULONG data)
+DECLINLINE(void) VBoxVideoVBEWriteUlongLocked(USHORT dataType, ULONG data)
 {
     VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, dataType);
@@ -262,5 +269,5 @@
 }
 
-DECLINLINE(void) VBoxVideoHostWriteUshortLocked(USHORT dataType, USHORT data)
+DECLINLINE(void) VBoxVideoVBEWriteUshortLocked(USHORT dataType, USHORT data)
 {
     VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, dataType);
@@ -268,5 +275,5 @@
 }
 
-DECLINLINE(ULONG) VBoxVideoHostReadUlongLocked (USHORT dataType)
+DECLINLINE(ULONG) VBoxVideoVBEReadUlongLocked (USHORT dataType)
 {
     VideoPortWritePortUshort((PUSHORT)VBE_DISPI_IOPORT_INDEX, dataType);
@@ -274,5 +281,5 @@
 }
 
-DECLINLINE(void) VBoxVideoHostWriteUlong(PDEVICE_EXTENSION PrimaryExtension, USHORT dataType, ULONG data)
+DECLINLINE(void) VBoxVideoVBEWriteUlong(PDEVICE_EXTENSION PrimaryExtension, USHORT dataType, ULONG data)
 {
     UCHAR oldIrql;
@@ -280,5 +287,5 @@
     		PrimaryExtension->u.primary.pGHRWLock,
             &oldIrql);
-    VBoxVideoHostWriteUlongLocked(dataType, data);
+    VBoxVideoVBEWriteUlongLocked(dataType, data);
     VideoPortReleaseSpinLock(PrimaryExtension,
     		PrimaryExtension->u.primary.pGHRWLock,
@@ -286,5 +293,5 @@
 }
 
-DECLINLINE(void) VBoxVideoHostWriteUshort(PDEVICE_EXTENSION PrimaryExtension, USHORT dataType, USHORT data)
+DECLINLINE(void) VBoxVideoVBEWriteUshort(PDEVICE_EXTENSION PrimaryExtension, USHORT dataType, USHORT data)
 {
     UCHAR oldIrql;
@@ -292,5 +299,5 @@
     		PrimaryExtension->u.primary.pGHRWLock,
             &oldIrql);
-    VBoxVideoHostWriteUshortLocked(dataType, data);
+    VBoxVideoVBEWriteUshortLocked(dataType, data);
     VideoPortReleaseSpinLock(PrimaryExtension,
     		PrimaryExtension->u.primary.pGHRWLock,
@@ -298,16 +305,39 @@
 }
 
-DECLINLINE(ULONG) VBoxVideoHostReadUlong(PDEVICE_EXTENSION PrimaryExtension, USHORT dataType)
-{
-	ULONG data;
+DECLINLINE(ULONG) VBoxVideoVBEReadUlong(PDEVICE_EXTENSION PrimaryExtension, USHORT dataType)
+{
+    ULONG data;
     UCHAR oldIrql;
     VideoPortAcquireSpinLock(PrimaryExtension,
     		PrimaryExtension->u.primary.pGHRWLock,
             &oldIrql);
-	data = VBoxVideoHostReadUlongLocked(dataType);
+    data = VBoxVideoVBEReadUlongLocked(dataType);
     VideoPortReleaseSpinLock(PrimaryExtension,
     		PrimaryExtension->u.primary.pGHRWLock,
             oldIrql);
     return data;
+}
+
+/*
+ * Host and Guest port IO helpers.
+ */
+DECLINLINE(void) VBoxHGSMIHostWrite(PDEVICE_EXTENSION PrimaryExtension, ULONG data)
+{
+    VideoPortWritePortUlong((PULONG)PrimaryExtension->pPrimary->u.primary.IOPortHost, data);
+}
+
+DECLINLINE(ULONG) VBoxHGSMIHostRead(PDEVICE_EXTENSION PrimaryExtension)
+{
+    return VideoPortReadPortUlong((PULONG)PrimaryExtension->pPrimary->u.primary.IOPortHost);
+}
+
+DECLINLINE(void) VBoxHGSMIGuestWrite(PDEVICE_EXTENSION PrimaryExtension, ULONG data)
+{
+    VideoPortWritePortUlong((PULONG)PrimaryExtension->pPrimary->u.primary.IOPortGuest, data);
+}
+
+DECLINLINE(ULONG) VBoxHGSMIGuestRead(PDEVICE_EXTENSION PrimaryExtension)
+{
+    return VideoPortReadPortUlong((PULONG)PrimaryExtension->pPrimary->u.primary.IOPortGuest);
 }
 
Index: trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 22443)
+++ trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 22444)
@@ -71,4 +71,7 @@
 #define VGA_MAPPING_SIZE    _512K
 
+#ifdef VBOX_WITH_HGSMI
+#define PCIDEV_2_VGASTATE(pPciDev)    ((VGAState *)((uintptr_t)pPciDev - RT_OFFSETOF(VGAState, Dev)))
+#endif /* VBOX_WITH_HGSMI */
 /** Converts a vga adaptor state pointer to a device instance pointer. */
 #define VGASTATE2DEVINS(pVgaState)    ((pVgaState)->CTX_SUFF(pDevIns))
@@ -3414,4 +3417,123 @@
 }
 
+#ifdef VBOX_WITH_HGSMI
+#ifdef IN_RING3
+/**
+ * Port I/O Handler for PCI Ports OUT operations.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDevIns     The device instance.
+ * @param   pvUser      User argument - ignored.
+ * @param   Port        Port number used for the operation.
+ * @param   u32         The value to output.
+ * @param   cb          The value size in bytes.
+ */
+static DECLCALLBACK(int) vgaR3IOPortPCIWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
+{
+    LogFlowFunc(("Port 0x%x, u32 0x%x, cb %d\n", Port, u32, cb));
+    VGAState *s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+
+    int rc = PDMCritSectEnter(&s->lock, VERR_SEM_BUSY);
+    if (rc != VINF_SUCCESS)
+        return rc;
+
+    NOREF(pvUser);
+
+    if (cb == 4)
+    {
+        RTIOPORT portOffset = Port - s->IOPortBase;
+
+        switch (portOffset)
+        {
+            case VGA_PORT_OFF_HGSMI_HOST:
+            {
+#if defined(VBOX_WITH_VIDEOHWACCEL)
+                if(u32 == HGSMIOFFSET_VOID)
+                {
+                    PDMDevHlpPCISetIrq(pDevIns, 0, PDM_IRQ_LEVEL_LOW);
+                    HGSMIClearHostGuestFlags(s->pHGSMI, HGSMIHOSTFLAGS_IRQ);
+                }
+                else
+#endif
+                {
+                    HGSMIHostWrite(s->pHGSMI, u32);
+                }
+            } break;
+
+            case VGA_PORT_OFF_HGSMI_GUEST:
+            {
+                HGSMIGuestWrite(s->pHGSMI, u32);
+            } break;
+
+            default:
+            {
+                AssertMsgFailed(("vgaR3IOPortPCIWrite: Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
+            } break;
+        }
+    }
+    else
+    {
+        AssertMsgFailed(("vgaR3IOPortPCIWrite: Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
+    }
+
+    PDMCritSectLeave(&s->lock);
+    return VINF_SUCCESS;
+}
+
+/**
+ * Port I/O Handler for PCI Port IN operations.
+ *
+ * @returns VBox status code.
+ *
+ * @param   pDevIns     The device instance.
+ * @param   pvUser      User argument - ignored.
+ * @param   Port        Port number used for the operation.
+ * @param   pu32        Where to store the result.
+ * @param   cb          Number of bytes to read.
+ */
+static DECLCALLBACK(int) vgaR3IOPortPCIRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb)
+{
+    LogFlowFunc(("Port 0x%x, cb %d\n", Port, cb));
+    VGAState *s = PDMINS_2_DATA(pDevIns, PVGASTATE);
+
+    int rc = PDMCritSectEnter(&s->lock, VERR_SEM_BUSY);
+    if (rc != VINF_SUCCESS)
+        return rc;
+
+    NOREF(pvUser);
+
+    if (cb == 4)
+    {
+        RTIOPORT portOffset = Port - s->IOPortBase;
+
+        switch (portOffset)
+        {
+            case VGA_PORT_OFF_HGSMI_HOST:
+            {
+                *pu32 = HGSMIHostRead(s->pHGSMI);
+            } break;
+            case VGA_PORT_OFF_HGSMI_GUEST:
+            {
+                *pu32 = HGSMIGuestRead(s->pHGSMI);
+            } break;
+            default:
+            {
+                AssertMsgFailed(("vgaR3IOPortPCIRead: Port=%#x cb=%d\n", Port, cb));
+                rc = VERR_IOM_IOPORT_UNUSED;
+            } break;
+        }
+    }
+    else
+    {
+        AssertMsgFailed(("vgaR3IOPortPCIRead: Port=%#x cb=%d\n", Port, cb));
+        rc = VERR_IOM_IOPORT_UNUSED;
+    }
+
+    PDMCritSectLeave(&s->lock);
+    return rc;
+}
+#endif /* IN_RING3 */
+#endif /* VBOX_WITH_HGSMI */
 
 
@@ -5640,5 +5762,43 @@
 }
 
-
+#ifdef VBOX_WITH_HGSMI
+#ifdef IN_RING3
+/**
+ * Callback function for mapping a PCI I/O region.
+ *
+ * @return VBox status code.
+ * @param   pPciDev         Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
+ * @param   iRegion         The region number.
+ * @param   GCPhysAddress   Physical address of the region. If iType is PCI_ADDRESS_SPACE_IO, this is an
+ *                          I/O port, else it's a physical address.
+ *                          This address is *NOT* relative to pci_mem_base like earlier!
+ * @param   enmType         One of the PCI_ADDRESS_SPACE_* values.
+ */
+static DECLCALLBACK(int) vgaR3IOPortRegionMap(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType)
+{
+    VGAState *pThis = PCIDEV_2_VGASTATE(pPciDev);
+    int rc = VINF_SUCCESS;
+
+    Assert(enmType == PCI_ADDRESS_SPACE_IO);
+    Assert(iRegion == 1);
+    AssertMsg(RT_ALIGN(GCPhysAddress, 8) == GCPhysAddress, ("Expected 8 byte alignment. GCPhysAddress=%#x\n", GCPhysAddress));
+
+    /*
+     * Save the base port address to simplify Port offset calculations.
+     */
+    pThis->IOPortBase = (RTIOPORT)GCPhysAddress;
+
+    /*
+     * Register port IO handlers.
+     */
+    rc = PDMDevHlpIOPortRegister(pPciDev->pDevIns,
+                                 (RTIOPORT)GCPhysAddress, cb,
+                                 (void*)pThis, vgaR3IOPortPCIWrite, vgaR3IOPortPCIRead,
+                                 NULL, NULL, "VGA PCI IO Ports");
+    AssertRC(rc);
+    return rc;
+}
+#endif /* IN_RING3 */
+#endif /* VBOX_WITH_HGSMI */
 
 /**
@@ -5980,4 +6140,9 @@
     if (RT_FAILURE(rc))
         return rc;
+#ifdef VBOX_WITH_HGSMI
+    rc = PDMDevHlpPCIIORegionRegister(pDevIns, 1, 0x10, PCI_ADDRESS_SPACE_IO, vgaR3IOPortRegionMap);
+    if (RT_FAILURE(rc))
+        return rc;
+#endif /* VBOX_WITH_HGSMI */
 
     /* Initialize the PDM lock. */
Index: trunk/src/VBox/Devices/Graphics/DevVGA.h
===================================================================
--- trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 22443)
+++ trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 22444)
@@ -47,4 +47,7 @@
 #ifdef VBOX_WITH_HGSMI
 #include "HGSMI/HGSMIHost.h"
+
+#define VGA_PORT_OFF_HGSMI_HOST  0
+#define VGA_PORT_OFF_HGSMI_GUEST 4
 #endif /* VBOX_WITH_HGSMI */
 
@@ -398,4 +401,9 @@
     uint32_t                    au32LogoPalette[256];
 #endif /* VBOX */
+#ifdef VBOX_WITH_HGSMI
+    /** Base port in the assigned PCI I/O space. */
+    RTIOPORT                    IOPortBase;
+    uint8_t                     Padding11[6];    /**< Alignment padding. */
+#endif /* VBOX_WITH_HGSMI */
 } VGAState;
 #ifdef VBOX
