This patch fixes up the following issues for enabling PCI passthrough
with stub domain.
- Reading and writing a data to/from device register with
pci_{read/write}_block, byte swap occurs.
- Can't get a BAR in pt_libpci_fixup.
- Don't get PCI Vendor ID, Device ID and Device Class for PCI passthrough
device.
Thanks,
--
Shohei Fujiwara
Signed-off-by: Shohei Fujiwara <fujiwara-sxa@xxxxxxxxxxxxxxx>
diff --git a/hw/pass-through.c b/hw/pass-through.c
index 4a86309..6373227 100644
--- a/hw/pass-through.c
+++ b/hw/pass-through.c
@@ -1104,6 +1104,58 @@ out:
return index;
}
+static int pt_pci_write_block(struct pci_dev *d, int pos, uint32_t *val,
+ int len)
+{
+ int ret = 0;
+
+ switch (len)
+ {
+ case 1:
+ ret = pci_write_byte(d, pos, *(uint8_t *)val);
+ break;
+ case 2:
+ ret = pci_write_word(d, pos, *(uint16_t *)val);
+ break;
+ case 4:
+ ret = pci_write_long(d, pos, *val);
+ break;
+ }
+ return ret;
+}
+
+static int pt_pci_read_block(struct pci_dev *d, int pos, uint32_t *val,
+ int len)
+{
+ uint32_t valid_mask = 0xffffffff;
+ int ret = 1;
+
+ switch (len)
+ {
+ case 1:
+ *val = (uint32_t)pci_read_byte(d, pos);
+ break;
+ case 2:
+ *val = (uint32_t)pci_read_word(d, pos);
+ break;
+ case 4:
+ *val = pci_read_long(d, pos);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+
+ if (ret)
+ {
+ valid_mask = (0xffffffff >> ((4 - len) << 3));
+ if ((*val & valid_mask) == valid_mask)
+ ret = 0;
+ }
+
+ return ret;
+}
+
static void pt_pci_write_config(PCIDevice *d, uint32_t address, uint32_t val,
int len)
{
@@ -1195,7 +1247,7 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t
address, uint32_t val,
}
/* read I/O device register value */
- ret = pci_read_block(pci_dev, address, (uint8_t *)&read_val, len);
+ ret = pt_pci_read_block(pci_dev, address, &read_val, len);
if (!ret)
{
@@ -1281,7 +1333,7 @@ static void pt_pci_write_config(PCIDevice *d, uint32_t
address, uint32_t val,
val >>= ((address & 3) << 3);
out:
- ret = pci_write_block(pci_dev, address, (uint8_t *)&val, len);
+ ret = pt_pci_write_block(pci_dev, address, &val, len);
if (!ret)
PT_LOG("Error: pci_write_block failed. return value[%d].\n", ret);
@@ -1364,7 +1416,7 @@ static uint32_t pt_pci_read_config(PCIDevice *d, uint32_t
address, int len)
}
/* read I/O device register value */
- ret = pci_read_block(pci_dev, address, (uint8_t *)&val, len);
+ ret = pt_pci_read_block(pci_dev, address, &val, len);
if (!ret)
{
@@ -1461,6 +1513,7 @@ exit:
static void pt_libpci_fixup(struct pci_dev *dev)
{
#if !defined(PCI_LIB_VERSION) || PCI_LIB_VERSION < 0x030100
+#ifndef CONFIG_STUBDOM
int i;
FILE *fp;
char path[PATH_MAX], buf[256];
@@ -1492,6 +1545,30 @@ static void pt_libpci_fixup(struct pci_dev *dev)
}
fclose(fp);
+#else
+ uint32_t value = 0;
+ int i;
+
+ for ( i = 0; i < PCI_NUM_REGIONS; i++ )
+ {
+ value = pci_read_long(dev, PCI_BASE_ADDRESS_0 + i*4);
+ if ( i < PCI_ROM_SLOT )
+ {
+ dev->base_addr[i] |= (value & 0x0f);
+ }
+ else
+ {
+ dev->rom_base_addr |= (value & 0x0f);
+ }
+
+ if ((value & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
+ == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64) )
+ {
+ i++;
+ }
+ }
+
+#endif /* !CONFIG_STUBDOM */
#endif /* PCI_LIB_VERSION < 0x030100 */
}
@@ -3582,7 +3659,12 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
PT_LOG("Error: couldn't locate device in libpci structures\n");
return NULL;
}
+#ifndef CONFIG_STUBDOM
pci_fill_info(pci_dev, PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE |
PCI_FILL_SIZES);
+#else
+ pci_fill_info(pci_dev, PCI_FILL_IRQ | PCI_FILL_BASES | PCI_FILL_ROM_BASE
+ | PCI_FILL_SIZES | PCI_FILL_IDENT | PCI_FILL_CLASS);
+#endif
pt_libpci_fixup(pci_dev);
if ( e_devfn == PT_VIRT_DEVFN_AUTO ) {
@@ -3711,9 +3793,16 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
}
out:
+#ifndef CONFIG_STUBDOM
PT_LOG("Real physical device %02x:%02x.%x registered successfuly!\n"
"IRQ type = %s\n", r_bus, r_dev, r_func,
assigned_device->msi_trans_en? "MSI-INTx":"INTx");
+#else
+ PT_LOG("Real physical device %02x:%02x.%x registered successfuly!\n",
+ r_bus, r_dev, r_func);
+ PT_LOG("IRQ type = %s\n",
+ assigned_device->msi_trans_en? "MSI-INTx":"INTx");
+#endif
return assigned_device;
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|