[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC] [PATCH 2/2] ioemu: fix up some issues for PCI passthrough with stub domain
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |