Index: /trunk/include/VBox/rawpci.h
===================================================================
--- /trunk/include/VBox/rawpci.h	(revision 36152)
+++ /trunk/include/VBox/rawpci.h	(revision 36153)
@@ -74,4 +74,5 @@
     RTGCPHYS             StartAddress;
     uint64_t             iRegionSize;
+    int32_t              iRegion;
     uint32_t             fFlags;
     /* out */
@@ -88,4 +89,5 @@
     RTR3PTR              pvAddressR3;
     RTR0PTR              pvAddressR0;
+    int32_t              iRegion;
 } PCIRAWREQUNMAPREGION;
 
@@ -296,4 +298,5 @@
                                              RTHCPHYS       RegionStart,
                                              uint64_t       u64RegionSize,
+                                             int32_t        fFlags,
                                              RTR0PTR        *pRegionBaseR0));
 
@@ -304,4 +307,5 @@
      */
     DECLR0CALLBACKMEMBER(int,  pfnUnmapRegion,(PRAWPCIDEVPORT pPort,
+                                               int32_t        iRegion,
                                                RTHCPHYS       RegionStart,
                                                uint64_t       u64RegionSize,
Index: /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 36152)
+++ /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 36153)
@@ -248,5 +248,5 @@
 PDMBOTHCBDECL(int)  ich9pciIOPortAddressWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
 {
-    Log(("ich9pciIOPortAddressWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
+    LogFlow(("ich9pciIOPortAddressWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
     NOREF(pvUser);
     if (cb == 4)
@@ -282,5 +282,5 @@
         *pu32 = pThis->uConfigReg;
         PCI_UNLOCK(pDevIns);
-        Log(("pciIOPortAddressRead: Port=%#x cb=%d -> %#x\n", Port, cb, *pu32));
+        LogFlow(("pciIOPortAddressRead: Port=%#x cb=%d -> %#x\n", Port, cb, *pu32));
         return VINF_SUCCESS;
     }
@@ -329,5 +329,4 @@
 #ifdef IN_RING3
             R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pAddr->iDeviceFunc];
-            Log(("ich9pciConfigWrite: %s: addr=%02x val=%08x len=%d\n", aDev->name, pAddr->iRegister, val, cb));
             aDev->Int.s.pfnConfigWrite(aDev, pAddr->iRegister, val, cb);
 #else
@@ -383,5 +382,5 @@
 PDMBOTHCBDECL(int)  ich9pciIOPortDataWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb)
 {
-    Log(("pciIOPortDataWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
+    LogFlow(("pciIOPortDataWrite: Port=%#x u32=%#x cb=%d\n", Port, u32, cb));
     NOREF(pvUser);
     int rc = VINF_SUCCESS;
@@ -437,5 +436,4 @@
             R3PTRTYPE(PCIDevice *) aDev = pGlobals->aPciBus.apDevices[pPciAddr->iDeviceFunc];
             *pu32 = aDev->Int.s.pfnConfigRead(aDev, pPciAddr->iRegister, cb);
-            Log(("ich9pciDataReadAddr: %s: addr=%02x val=%08x len=%d\n", aDev->name, pPciAddr->iRegister, *pu32, cb));
 #else
             rc = rcReschedule;
@@ -448,5 +446,5 @@
 
   out:
-    Log2(("ich9pciDataReadAddr: %02x:%02x:%02x reg %x(%d) gave %x %Rrc\n",
+    Log3(("ich9pciDataReadAddr: %02x:%02x:%02x reg %x(%d) gave %x %Rrc\n",
           pPciAddr->iBus, pPciAddr->iDeviceFunc >> 3, pPciAddr->iDeviceFunc & 0x7, pPciAddr->iRegister,
           cb, *pu32, rc));
@@ -494,5 +492,5 @@
         int rc = ich9pciDataRead(PDMINS_2_DATA(pDevIns, PPCIGLOBALS), Port, cb, pu32);
         PCI_UNLOCK(pDevIns);
-        Log(("pciIOPortDataRead: Port=%#x cb=%#x -> %#x (%Rrc)\n", Port, cb, *pu32, rc));
+        LogFlow(("pciIOPortDataRead: Port=%#x cb=%#x -> %#x (%Rrc)\n", Port, cb, *pu32, rc));
         return rc;
     }
@@ -701,5 +699,5 @@
         uint32_t uSecondary   = PCIDevGetByte(pBridge, VBOX_PCI_SECONDARY_BUS);
         uint32_t uSubordinate = PCIDevGetByte(pBridge, VBOX_PCI_SUBORDINATE_BUS);
-        Log2(("ich9pciFindBridge on bus %p, bridge %d: %d in %d..%d\n", pBus, iBridge, iBus, uSecondary, uSubordinate));
+        Log3(("ich9pciFindBridge on bus %p, bridge %d: %d in %d..%d\n", pBus, iBridge, iBus, uSecondary, uSubordinate));
         if (iBus >= uSecondary && iBus <= uSubordinate)
             return pBridge;
@@ -708,4 +706,24 @@
     /* Nothing found. */
     return NULL;
+}
+
+static uint32_t ich9pciGetCfg(PCIDevice* aDev, int32_t iRegister, int cb)
+{
+    return aDev->Int.s.pfnConfigRead(aDev, iRegister, cb);
+}
+
+static uint8_t ich9pciGetByte(PCIDevice* aDev, int32_t iRegister)
+{
+    return (uint8_t)ich9pciGetCfg(aDev, iRegister, 1);
+}
+
+static uint16_t ich9pciGetWord(PCIDevice* aDev, int32_t iRegister)
+{
+    return (uint16_t)ich9pciGetCfg(aDev, iRegister, 2);
+}
+
+static uint32_t ich9pciGetDWord(PCIDevice* aDev, int32_t iRegister)
+{
+    return (uint32_t)ich9pciGetCfg(aDev, iRegister, 4);
 }
 
@@ -757,12 +775,12 @@
 {
     PPCIBUS pBus = pDev->Int.s.CTX_SUFF(pBus);
-    uint32_t uLast, uNew;
-
-    int iCmd = PCIDevGetCommand(pDev);
+    uint64_t uLast, uNew;
+
+    int iCmd = ich9pciGetWord(pDev, VBOX_PCI_COMMAND);
     for (int iRegion = 0; iRegion < PCI_NUM_REGIONS; iRegion++)
     {
         PCIIORegion* pRegion = &pDev->Int.s.aIORegions[iRegion];
-        uint32_t uConfigReg = ich9pciGetRegionReg(iRegion);
-        int32_t  iRegionSize =  pRegion->size;
+        uint32_t uConfigReg  = ich9pciGetRegionReg(iRegion);
+        int64_t  iRegionSize =  pRegion->size;
         int rc;
 
@@ -770,5 +788,5 @@
             continue;
 
-        AssertMsg((pRegion->type & PCI_ADDRESS_SPACE_BAR64) == 0, ("64-bit BARs not yet implemented\n"));
+        bool f64Bit = (pRegion->type & PCI_ADDRESS_SPACE_BAR64) != 0;
 
         if (pRegion->type & PCI_ADDRESS_SPACE_IO)
@@ -778,5 +796,5 @@
             {
                 /* IO access allowed */
-                uNew = ich9pciConfigReadDev(pDev, uConfigReg, 4);
+                uNew = ich9pciGetDWord(pDev, uConfigReg);
                 uNew &= ~(iRegionSize - 1);
                 uLast = uNew + iRegionSize - 1;
@@ -792,5 +810,17 @@
             if (iCmd & PCI_COMMAND_MEMACCESS)
             {
-                uNew = ich9pciConfigReadDev(pDev, uConfigReg, 4);
+                uNew = ich9pciGetDWord(pDev, uConfigReg);
+
+                if (f64Bit)
+                {
+                    uNew |= ((uint64_t)ich9pciGetDWord(pDev, uConfigReg+4)) << 32;
+                    if (uNew > UINT64_C(0x0000010000000000))
+                    {
+                        /* Workaround for REM being unhapping with mapping very lange 64-bit addresses */
+                        Log(("Ignoring too 64-bit BAR: %llx\n", uNew));
+                        uNew = INVALID_PCI_ADDRESS;
+                    }
+                }
+
                 /* the ROM slot has a specific enable bit */
                 if (iRegion == PCI_ROM_SLOT && !(uNew & 1))
@@ -819,4 +849,5 @@
             if (pRegion->addr != INVALID_PCI_ADDRESS)
             {
+
                 /* finally, map the region */
                 rc = pRegion->map_func(pDev, iRegion,
@@ -1512,5 +1543,5 @@
 }
 
-static void ich9pciSetRegionAddress(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, int iRegion, uint32_t addr)
+static void ich9pciSetRegionAddress(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn, int iRegion, uint64_t addr)
 {
     uint32_t uReg = ich9pciGetRegionReg(iRegion);
@@ -1520,4 +1551,7 @@
     /* Read command register. */
     uint16_t uCmd = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_COMMAND, 2);
+
+    Log(("Set region address: %02x:%02x.%d region %d address=%lld\n",
+         uBus, uDevFn>>3, uDevFn&7, addr));
 
     if ( iRegion == PCI_ROM_SLOT )
@@ -1528,6 +1562,10 @@
         uCmd |= PCI_COMMAND_MEMACCESS; /* Enable MMIO access. */
 
+    bool f64Bit = (uResourceType & PCI_ADDRESS_SPACE_BAR64) != 0;
+
     /* Write address of the device. */
-    ich9pciConfigWrite(pGlobals, uBus, uDevFn, uReg, addr, 4);
+    ich9pciConfigWrite(pGlobals, uBus, uDevFn, uReg, (uint32_t)addr, 4);
+    if (f64Bit)
+        ich9pciConfigWrite(pGlobals, uBus, uDevFn, uReg + 4, (uint32_t)(addr >> 32), 4);
 
     /* enable memory mappings */
@@ -1604,8 +1642,7 @@
 static void ich9pciBiosInitDevice(PPCIGLOBALS pGlobals, uint8_t uBus, uint8_t uDevFn)
 {
-    uint32_t *paddr;
     uint16_t uDevClass, uVendor, uDevice;
     uint8_t uCmd;
-    
+
     uDevClass  = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_CLASS_DEVICE, 2);
     uVendor    = ich9pciConfigRead(pGlobals, uBus, uDevFn, VBOX_PCI_VENDOR_ID, 2);
@@ -1662,32 +1699,59 @@
                    are cleared. . */
                 uint8_t u8ResourceType = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 1);
-                ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
-                uint32_t u32Size = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 4);
-                /* Clear resource information depending on resource type. */
-                if ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS) /* I/O */
-                    u32Size &= ~(0x01);
-                else                        /* MMIO */
-                    u32Size &= ~(0x0f);
-
+
+                bool f64bit = (u8ResourceType & PCI_ADDRESS_SPACE_BAR64) != 0;
                 bool fIsPio = ((u8ResourceType & PCI_COMMAND_IOACCESS) == PCI_COMMAND_IOACCESS);
-                /*
-                 * Invert all bits and add 1 to get size of the region.
-                 * (From PCI implementation note)
-                 */
-                if (fIsPio && (u32Size & UINT32_C(0xffff0000)) == 0)
-                    u32Size = (~(u32Size | UINT32_C(0xffff0000))) + 1;
+                uint64_t cbRegSize64 = 0;
+
+                if (f64bit)
+                {
+                    ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address,   UINT32_C(0xffffffff), 4);
+                    ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address+4, UINT32_C(0xffffffff), 4);
+                    cbRegSize64  =            ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address,   4);
+                    cbRegSize64 |= ((uint64_t)ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address+4, 4) << 32);
+                    cbRegSize64 &= ~UINT64_C(0x0f);
+                    cbRegSize64 = (~cbRegSize64) + 1;
+
+                    /* No 64-bit PIO regions possible. */
+                    Assert((u8ResourceType & PCI_COMMAND_IOACCESS) == 0);
+                }
                 else
-                    u32Size = (~u32Size) + 1;
-
-                Log(("%s: Size of region %u for device %d on bus %d is %u\n", __FUNCTION__, iRegion, uDevFn, uBus, u32Size));
-
-                if (u32Size)
                 {
-                    paddr = fIsPio ? &pGlobals->uPciBiosIo : &pGlobals->uPciBiosMmio;
-                    *paddr = (*paddr + u32Size - 1) & ~(u32Size - 1);
+                    uint32_t cbRegSize32;
+                    ich9pciConfigWrite(pGlobals, uBus, uDevFn, u32Address, UINT32_C(0xffffffff), 4);
+                    cbRegSize32 = ich9pciConfigRead(pGlobals, uBus, uDevFn, u32Address, 4);
+
+                    /* Clear resource information depending on resource type. */
+                    if (fIsPio) /* PIO */
+                        cbRegSize32 &= ~UINT32_C(0x01);
+                    else        /* MMIO */
+                        cbRegSize32 &= ~UINT32_C(0x0f);
+
+                    /*
+                     * Invert all bits and add 1 to get size of the region.
+                     * (From PCI implementation note)
+                     */
+                    if (fIsPio && (cbRegSize32 & UINT32_C(0xffff0000)) == 0)
+                        cbRegSize32 = (~(cbRegSize32 | UINT32_C(0xffff0000))) + 1;
+                    else
+                        cbRegSize32 = (~cbRegSize32) + 1;
+
+                    cbRegSize64 = cbRegSize32;
+                }
+                Assert(cbRegSize64 == (uint32_t)cbRegSize64);
+                Log2(("%s: Size of region %u for device %d on bus %d is %lld\n", __FUNCTION__, iRegion, uDevFn, uBus, cbRegSize64));
+
+                if (cbRegSize64)
+                {
+                    uint32_t  cbRegSize32 = (uint32_t)cbRegSize64;
+                    uint32_t* paddr = fIsPio ? &pGlobals->uPciBiosIo : &pGlobals->uPciBiosMmio;
+                    *paddr = (*paddr + cbRegSize32 - 1) & ~(cbRegSize32 - 1);
                     Log(("%s: Start address of %s region %u is %#x\n", __FUNCTION__, (fIsPio ? "I/O" : "MMIO"), iRegion, *paddr));
                     ich9pciSetRegionAddress(pGlobals, uBus, uDevFn, iRegion, *paddr);
-                    *paddr += u32Size;
-                    Log(("%s: New address is %#x\n", __FUNCTION__, *paddr));
+                    *paddr += cbRegSize32;
+                    Log2(("%s: New address is %#x\n", __FUNCTION__, *paddr));
+
+                    if (f64bit)
+                        iRegion++; /* skip next region */
                 }
             }
@@ -1916,11 +1980,14 @@
 
     uint32_t addr = u32Address;
-    bool fUpdateMappings = false;
-    bool fP2PBridge = false;
+    bool     fUpdateMappings = false;
+    bool     fP2PBridge = false;
+    bool     fPassthrough = pciDevIsPassthrough(aDev);
+    uint8_t  u8HeaderType = ich9pciGetByte(aDev, VBOX_PCI_HEADER_TYPE);
+
     for (uint32_t i = 0; i < len; i++)
     {
         bool fWritable = false;
         bool fRom = false;
-        switch (PCIDevGetHeaderType(aDev))
+        switch (u8HeaderType)
         {
             case 0x00: /* normal device */
@@ -1981,17 +2048,16 @@
             case VBOX_PCI_COMMAND: /* Command register, bits 0-7. */
                 fUpdateMappings = true;
-                PCIDevSetByte(aDev, addr, u8Val);
-                break;
+                goto default_case;
             case VBOX_PCI_COMMAND+1: /* Command register, bits 8-15. */
                 /* don't change reserved bits (11-15) */
                 u8Val &= UINT32_C(~0xf8);
                 fUpdateMappings = true;
-                PCIDevSetByte(aDev, addr, u8Val);
-                break;
+                goto default_case;
             case VBOX_PCI_STATUS:  /* Status register, bits 0-7. */
                 /* don't change read-only bits => actually all lower bits are read-only */
                 u8Val &= UINT32_C(~0xff);
                 /* status register, low part: clear bits by writing a '1' to the corresponding bit */
-                aDev->config[addr] &= ~u8Val;
+                if (!fPassthrough)
+                    aDev->config[addr] &= ~u8Val;
                 break;
             case VBOX_PCI_STATUS+1:  /* Status register, bits 8-15. */
@@ -1999,5 +2065,6 @@
                 u8Val &= UINT32_C(~0x06);
                 /* status register, high part: clear bits by writing a '1' to the corresponding bit */
-                aDev->config[addr] &= ~u8Val;
+                if (!fPassthrough)
+                    aDev->config[addr] &= ~u8Val;
                 break;
             case VBOX_PCI_ROM_ADDRESS:    case VBOX_PCI_ROM_ADDRESS   +1: case VBOX_PCI_ROM_ADDRESS   +2: case VBOX_PCI_ROM_ADDRESS   +3:
@@ -2017,5 +2084,6 @@
                     int iRegion = fRom ? VBOX_PCI_ROM_SLOT : (addr - VBOX_PCI_BASE_ADDRESS_0) >> 2;
                     int iOffset = addr & 0x3;
-                    ich9pciWriteBarByte(aDev, iRegion, iOffset, u8Val);
+                    if (!fPassthrough)
+                        ich9pciWriteBarByte(aDev, iRegion, iOffset, u8Val);
                     fUpdateMappings = true;
                 }
@@ -2024,5 +2092,5 @@
             default:
             default_case:
-                if (fWritable)
+                if (fWritable && !fPassthrough)
                     PCIDevSetByte(aDev, addr, u8Val);
         }
@@ -2199,23 +2267,4 @@
         pHlp->pfnPrintf(pHlp, "    ");
     }
-}
-static uint32_t ich9pciGetCfg(PCIDevice* aDev, int32_t iRegister, int cb)
-{
-    return aDev->Int.s.pfnConfigRead(aDev, iRegister, cb);
-}
-
-static uint8_t ich9pciGetByte(PCIDevice* aDev, int32_t iRegister)
-{
-    return (uint8_t)ich9pciGetCfg(aDev, iRegister, 1);
-}
-
-static uint16_t ich9pciGetWord(PCIDevice* aDev, int32_t iRegister)
-{
-    return (uint16_t)ich9pciGetCfg(aDev, iRegister, 2);
-}
-
-static uint32_t ich9pciGetDWord(PCIDevice* aDev, int32_t iRegister)
-{
-    return (uint32_t)ich9pciGetCfg(aDev, iRegister, 4);
 }
 
@@ -2258,14 +2307,19 @@
 
                     uint32_t u32Addr = ich9pciGetDWord(pPciDev, ich9pciGetRegionReg(iRegion));
-                    const char * szDesc;
-
+                    const char * pszDesc;
+                    char szDescBuf[128];
+
+                    bool f64Bit = (pRegion->type & PCI_ADDRESS_SPACE_BAR64);
                     if (pRegion->type & PCI_ADDRESS_SPACE_IO)
                     {
-                        szDesc = "IO";
+                        pszDesc = "IO";
                         u32Addr &= ~0x3;
                     }
                     else
                     {
-                        szDesc = "MMIO";
+                        RTStrPrintf(szDescBuf, sizeof(szDescBuf), "MMIO%s%s",
+                                    f64Bit ? "64" : "32",
+                                    (pRegion->type & PCI_ADDRESS_SPACE_MEM_PREFETCH) ? " PREFETCH" : "");
+                        pszDesc = szDescBuf;
                         u32Addr &= ~0xf;
                     }
@@ -2273,5 +2327,7 @@
                     printIndent(pHlp, iIndent + 2);
                     pHlp->pfnPrintf(pHlp, "  %s region #%d: %x..%x\n",
-                                    szDesc, iRegion, u32Addr, u32Addr+iRegionSize);
+                                    pszDesc, iRegion, u32Addr, u32Addr+iRegionSize);
+                    if (f64Bit)
+                        iRegion++;
                 }
             }
Index: /trunk/src/VBox/HostDrivers/VBoxPci/VBoxPci.c
===================================================================
--- /trunk/src/VBox/HostDrivers/VBoxPci/VBoxPci.c	(revision 36152)
+++ /trunk/src/VBox/HostDrivers/VBoxPci/VBoxPci.c	(revision 36153)
@@ -139,9 +139,10 @@
                                     RTHCPHYS       RegionStart,
                                     uint64_t       u64RegionSize,
+                                    int32_t        fFlags,
                                     RTR0PTR        *pRegionBase)
 {
     PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
 
-    int rc = vboxPciOsDevMapRegion(pThis, iRegion, RegionStart, u64RegionSize, pRegionBase);
+    int rc = vboxPciOsDevMapRegion(pThis, iRegion, RegionStart, u64RegionSize, fFlags, pRegionBase);
 
     return rc;
@@ -152,4 +153,5 @@
  */
 DECLHIDDEN(int) vboxPciDevUnmapRegion(PRAWPCIDEVPORT pPort,
+                                      int32_t        iRegion,
                                       RTHCPHYS       RegionStart,
                                       uint64_t       u64RegionSize,
@@ -158,5 +160,5 @@
     PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
 
-    int rc = vboxPciOsDevUnmapRegion(pThis, RegionStart, u64RegionSize, RegionBase);
+    int rc = vboxPciOsDevUnmapRegion(pThis, iRegion, RegionStart, u64RegionSize, RegionBase);
 
     return rc;
@@ -170,5 +172,7 @@
     PVBOXRAWPCIINS pThis = DEVPORT_2_VBOXRAWPCIINS(pPort);
 
-    int rc = vboxPciOsDevPciCfgRead(pThis, Register, pValue);
+    int rc;
+
+    rc = vboxPciOsDevPciCfgRead(pThis, Register, pValue);
 
     return rc;
Index: /trunk/src/VBox/HostDrivers/VBoxPci/VBoxPciInternal.h
===================================================================
--- /trunk/src/VBox/HostDrivers/VBoxPci/VBoxPciInternal.h	(revision 36152)
+++ /trunk/src/VBox/HostDrivers/VBoxPci/VBoxPciInternal.h	(revision 36153)
@@ -113,6 +113,8 @@
                                        RTHCPHYS       pRegionStart,
                                        uint64_t       u64RegionSize,
+                                       uint32_t       fFlags,
                                        RTR0PTR        *pRegionBase);
 DECLHIDDEN(int)  vboxPciOsDevUnmapRegion(PVBOXRAWPCIINS pIns,
+                                         int32_t        iRegion,
                                          RTHCPHYS       RegionStart,
                                          uint64_t       u64RegionSize,
