Index: /trunk/include/VBox/pci.h
===================================================================
--- /trunk/include/VBox/pci.h	(revision 34230)
+++ /trunk/include/VBox/pci.h	(revision 34231)
@@ -492,7 +492,9 @@
 
 /** Fixed I/O region number for ROM. */
-#define PCI_ROM_SLOT 6
+#define PCI_ROM_SLOT    6
+#define VBOX_PCI_ROM_SLOT    6
 /** Max number of I/O regions. */
 #define PCI_NUM_REGIONS 7
+#define VBOX_PCI_NUM_REGIONS 7
 
 /*
@@ -649,4 +651,15 @@
 {
     return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_INTX_DISABLE) != 0;
+}
+
+/**
+ * Gets the status config register.
+ *
+ * @returns status config register.
+ * @param   pPciDev         The PCI device.
+ */
+DECLINLINE(uint16_t) PCIDevGetStatus(PPCIDEVICE pPciDev)
+{
+    return PCIDevGetWord(pPciDev, VBOX_PCI_STATUS);
 }
 
Index: /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp
===================================================================
--- /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 34230)
+++ /trunk/src/VBox/Devices/Bus/DevPciIch9.cpp	(revision 34231)
@@ -699,5 +699,5 @@
 DECLINLINE(uint32_t) ich9pciGetRegionReg(int iRegion)
 {
-    return (iRegion == PCI_ROM_SLOT) ?
+    return (iRegion == VBOX_PCI_ROM_SLOT) ?
             VBOX_PCI_ROM_ADDRESS : (VBOX_PCI_BASE_ADDRESS_0 + iRegion * 4);
 }
@@ -1731,5 +1731,29 @@
 }
 
-
+DECLINLINE(void) ich9pciWriteBarByte(PCIDevice *aDev, int iRegion, int iOffset, uint8_t u8Val)
+{
+    PCIIORegion * pRegion = &aDev->Int.s.aIORegions[iRegion];
+
+    int iRegionSize = pRegion->size;
+
+    /* Region doesn't exist */
+    if (iRegionSize == 0)
+        return;
+
+    uint32_t uAddr = ich9pciGetRegionReg(iRegion) + iOffset;
+    /* Region size must be power of two */
+    Assert((iRegionSize & (iRegionSize - 1)) == 0);
+    uint8_t uMask = ((iRegionSize - 1) >> (iOffset*8)) & 0xff;
+
+    if (iOffset == 0)
+    {
+        uMask |= (pRegion->type & PCI_ADDRESS_SPACE_IO) ?
+                (1 << 2) - 1 /* 2 lowest bits for IO region */ :
+                (1 << 4) - 1 /* 4 lowest bits for memory region, also ROM enable bit for ROM region */;
+    }
+
+    u8Val = (PCIDevGetByte(aDev, uAddr) & uMask) | (u8Val & ~uMask);
+    PCIDevSetByte(aDev, uAddr, u8Val);
+}
 /**
  * See paragraph 7.5 of PCI Express specification (p. 349) for definition of
@@ -1770,35 +1794,4 @@
     }
 
-
-    /* Fast case - update one of BARs or ROM address, 'while' only for 'break' */
-    while (   len == 4
-           && (   (   u32Address >= VBOX_PCI_BASE_ADDRESS_0
-                   && u32Address <  VBOX_PCI_BASE_ADDRESS_0 + 6 * 4)
-               || (   u32Address >= VBOX_PCI_ROM_ADDRESS
-                   && u32Address <  VBOX_PCI_ROM_ADDRESS+4)
-              )
-           )
-    {
-        PCIIORegion *pRegion;
-        int reg, regionSize;
-
-        reg = (u32Address >= VBOX_PCI_ROM_ADDRESS) ? PCI_ROM_SLOT : (u32Address - VBOX_PCI_BASE_ADDRESS_0) >> 2;
-        pRegion = &aDev->Int.s.aIORegions[reg];
-        regionSize = pRegion->size;
-        if (regionSize == 0)
-            break;
-        /* compute the stored value */
-        if (reg == PCI_ROM_SLOT) {
-            /* keep ROM enable bit */
-            val &= (~(regionSize - 1)) | 1;
-        } else {
-            val &= ~(regionSize - 1);
-            val |= pRegion->type;
-        }
-        PCIDevSetDWord(aDev, u32Address, val);
-        ich9pciUpdateMappings(aDev);
-        return;
-    }
-
     uint32_t addr = u32Address;
     bool fUpdateMappings = false;
@@ -1806,4 +1799,5 @@
     {
         bool fWritable = false;
+        bool fRom = false;
         switch (PCIDevGetHeaderType(aDev))
         {
@@ -1820,10 +1814,4 @@
                     case VBOX_PCI_CLASS_BASE:
                     case VBOX_PCI_HEADER_TYPE:
-                    case VBOX_PCI_BASE_ADDRESS_0: case VBOX_PCI_BASE_ADDRESS_0+1: case VBOX_PCI_BASE_ADDRESS_0+2: case VBOX_PCI_BASE_ADDRESS_0+3:
-                    case VBOX_PCI_BASE_ADDRESS_1: case VBOX_PCI_BASE_ADDRESS_1+1: case VBOX_PCI_BASE_ADDRESS_1+2: case VBOX_PCI_BASE_ADDRESS_1+3:
-                    case VBOX_PCI_BASE_ADDRESS_2: case VBOX_PCI_BASE_ADDRESS_2+1: case VBOX_PCI_BASE_ADDRESS_2+2: case VBOX_PCI_BASE_ADDRESS_2+3:
-                    case VBOX_PCI_BASE_ADDRESS_3: case VBOX_PCI_BASE_ADDRESS_3+1: case VBOX_PCI_BASE_ADDRESS_3+2: case VBOX_PCI_BASE_ADDRESS_3+3:
-                    case VBOX_PCI_BASE_ADDRESS_4: case VBOX_PCI_BASE_ADDRESS_4+1: case VBOX_PCI_BASE_ADDRESS_4+2: case VBOX_PCI_BASE_ADDRESS_4+3:
-                    case VBOX_PCI_BASE_ADDRESS_5: case VBOX_PCI_BASE_ADDRESS_5+1: case VBOX_PCI_BASE_ADDRESS_5+2: case VBOX_PCI_BASE_ADDRESS_5+3:
                     case VBOX_PCI_SUBSYSTEM_VENDOR_ID: case VBOX_PCI_SUBSYSTEM_VENDOR_ID+1:
                     case VBOX_PCI_SUBSYSTEM_ID: case VBOX_PCI_SUBSYSTEM_ID+1:
@@ -1863,5 +1851,4 @@
 
         uint8_t u8Val = (uint8_t)val;
-
         switch (addr)
         {
@@ -1888,4 +1875,19 @@
                 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:
+                fRom = true;
+            case VBOX_PCI_BASE_ADDRESS_0: case VBOX_PCI_BASE_ADDRESS_0+1: case VBOX_PCI_BASE_ADDRESS_0+2: case VBOX_PCI_BASE_ADDRESS_0+3:
+            case VBOX_PCI_BASE_ADDRESS_1: case VBOX_PCI_BASE_ADDRESS_1+1: case VBOX_PCI_BASE_ADDRESS_1+2: case VBOX_PCI_BASE_ADDRESS_1+3:
+            case VBOX_PCI_BASE_ADDRESS_2: case VBOX_PCI_BASE_ADDRESS_2+1: case VBOX_PCI_BASE_ADDRESS_2+2: case VBOX_PCI_BASE_ADDRESS_2+3:
+            case VBOX_PCI_BASE_ADDRESS_3: case VBOX_PCI_BASE_ADDRESS_3+1: case VBOX_PCI_BASE_ADDRESS_3+2: case VBOX_PCI_BASE_ADDRESS_3+3:
+            case VBOX_PCI_BASE_ADDRESS_4: case VBOX_PCI_BASE_ADDRESS_4+1: case VBOX_PCI_BASE_ADDRESS_4+2: case VBOX_PCI_BASE_ADDRESS_4+3:
+            case VBOX_PCI_BASE_ADDRESS_5: case VBOX_PCI_BASE_ADDRESS_5+1: case VBOX_PCI_BASE_ADDRESS_5+2: case VBOX_PCI_BASE_ADDRESS_5+3:
+            {
+                int iRegion = fRom ? VBOX_PCI_ROM_SLOT : (addr - VBOX_PCI_BASE_ADDRESS_0) >> 2;
+                int iOffset = addr & 0x3;
+                ich9pciWriteBarByte(aDev, iRegion, iOffset, u8Val);
+                fUpdateMappings = true;
+                break;
+            }
             default:
                 if (fWritable)
@@ -1897,5 +1899,5 @@
 
     if (fUpdateMappings)
-        /* if the command register is modified, we must modify the mappings */
+        /* if the command/base address register is modified, we must modify the mappings */
         ich9pciUpdateMappings(aDev);
 }
