diff mbox

[2/5] pci-assign: Fix dword read at PCI_COMMAND

Message ID 5c4909dd1796ece440be44c6c07a70dbed3887bd.1292282738.git.jan.kiszka@web.de (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Kiszka Dec. 13, 2010, 11:25 p.m. UTC
None
diff mbox

Patch

diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index bc3a57b..6ff1456 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -494,14 +494,11 @@  static uint32_t assigned_dev_pci_read_config(PCIDevice *d, uint32_t address,
     /*
      * Catch access to
      *  - vendor & device ID
-     *  - command register (if emulation needed)
      *  - base address registers
      *  - ROM base address & capability pointer
      *  - interrupt line & pin
      */
     if (ranges_overlap(address, len, PCI_VENDOR_ID, 4) ||
-        (pci_dev->need_emulate_cmd &&
-         ranges_overlap(address, len, PCI_COMMAND, 2)) ||
         ranges_overlap(address, len, PCI_BASE_ADDRESS_0, 24) ||
         ranges_overlap(address, len, PCI_ROM_ADDRESS, 8) ||
         ranges_overlap(address, len, PCI_INTERRUPT_LINE, 2)) {
@@ -533,6 +530,17 @@  do_log:
     DEBUG("(%x.%x): address=%04x val=0x%08x len=%d\n",
           (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, val, len);
 
+    if (pci_dev->need_emulate_cmd &&
+        ranges_overlap(address, len, PCI_COMMAND, 2)) {
+        if (address == PCI_COMMAND) {
+            val &= 0xffff0000;
+            val |= pci_default_read_config(d, PCI_COMMAND, 2);
+        } else {
+            /* high-byte access */
+            val = pci_default_read_config(d, PCI_COMMAND+1, 1);
+        }
+    }
+
     if (!pci_dev->cap.available) {
         /* kill the special capabilities */
         if (address == PCI_COMMAND && len == 4) {