diff options
Diffstat (limited to 'qemu/hw/pci-host')
-rw-r--r-- | qemu/hw/pci-host/apb.c | 8 | ||||
-rw-r--r-- | qemu/hw/pci-host/bonito.c | 41 | ||||
-rw-r--r-- | qemu/hw/pci-host/gpex.c | 1 | ||||
-rw-r--r-- | qemu/hw/pci-host/grackle.c | 3 | ||||
-rw-r--r-- | qemu/hw/pci-host/pam.c | 1 | ||||
-rw-r--r-- | qemu/hw/pci-host/piix.c | 137 | ||||
-rw-r--r-- | qemu/hw/pci-host/ppce500.c | 5 | ||||
-rw-r--r-- | qemu/hw/pci-host/prep.c | 16 | ||||
-rw-r--r-- | qemu/hw/pci-host/q35.c | 52 | ||||
-rw-r--r-- | qemu/hw/pci-host/uninorth.c | 22 | ||||
-rw-r--r-- | qemu/hw/pci-host/versatile.c | 12 |
11 files changed, 217 insertions, 81 deletions
diff --git a/qemu/hw/pci-host/apb.c b/qemu/hw/pci-host/apb.c index 599768e2d..aaef7bb3a 100644 --- a/qemu/hw/pci-host/apb.c +++ b/qemu/hw/pci-host/apb.c @@ -27,6 +27,7 @@ Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is the secondary PCI bridge. */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/pci/pci.h" #include "hw/pci/pci_host.h" @@ -634,12 +635,7 @@ static void pci_apb_set_irq(void *opaque, int irq_num, int level) static int apb_pci_bridge_initfn(PCIDevice *dev) { - int rc; - - rc = pci_bridge_initfn(dev, TYPE_PCI_BUS); - if (rc < 0) { - return rc; - } + pci_bridge_initfn(dev, TYPE_PCI_BUS); /* * command register: diff --git a/qemu/hw/pci-host/bonito.c b/qemu/hw/pci-host/bonito.c index 3a731fe18..1999ece59 100644 --- a/qemu/hw/pci-host/bonito.c +++ b/qemu/hw/pci-host/bonito.c @@ -37,7 +37,7 @@ * north bridge address to pci address. */ -#include <assert.h> +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/pci/pci.h" @@ -180,8 +180,6 @@ #define PCI_ADDR(busno,devno,funno,regno) \ ((((busno)<<16)&0xff0000) + (((devno)<<11)&0xf800) + (((funno)<<8)&0x700) + (regno)) -#define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost" - typedef struct BonitoState BonitoState; typedef struct PCIBonitoState @@ -215,17 +213,20 @@ typedef struct PCIBonitoState } PCIBonitoState; -#define BONITO_PCI_HOST_BRIDGE(obj) \ - OBJECT_CHECK(BonitoState, (obj), TYPE_BONITO_PCI_HOST_BRIDGE) - struct BonitoState { PCIHostState parent_obj; - qemu_irq *pic; - PCIBonitoState *pci_dev; }; +#define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost" +#define BONITO_PCI_HOST_BRIDGE(obj) \ + OBJECT_CHECK(BonitoState, (obj), TYPE_BONITO_PCI_HOST_BRIDGE) + +#define TYPE_PCI_BONITO "Bonito" +#define PCI_BONITO(obj) \ + OBJECT_CHECK(PCIBonitoState, (obj), TYPE_PCI_BONITO) + static void bonito_writel(void *opaque, hwaddr addr, uint64_t val, unsigned size) { @@ -355,6 +356,10 @@ static uint64_t bonito_ldma_readl(void *opaque, hwaddr addr, uint32_t val; PCIBonitoState *s = opaque; + if (addr >= sizeof(s->bonldma)) { + return 0; + } + val = ((uint32_t *)(&s->bonldma))[addr/sizeof(uint32_t)]; return val; @@ -365,6 +370,10 @@ static void bonito_ldma_writel(void *opaque, hwaddr addr, { PCIBonitoState *s = opaque; + if (addr >= sizeof(s->bonldma)) { + return; + } + ((uint32_t *)(&s->bonldma))[addr/sizeof(uint32_t)] = val & 0xffffffff; } @@ -384,6 +393,10 @@ static uint64_t bonito_cop_readl(void *opaque, hwaddr addr, uint32_t val; PCIBonitoState *s = opaque; + if (addr >= sizeof(s->boncop)) { + return 0; + } + val = ((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)]; return val; @@ -394,6 +407,10 @@ static void bonito_cop_writel(void *opaque, hwaddr addr, { PCIBonitoState *s = opaque; + if (addr >= sizeof(s->boncop)) { + return; + } + ((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)] = val & 0xffffffff; } @@ -707,7 +724,7 @@ static int bonito_pcihost_initfn(SysBusDevice *dev) static void bonito_realize(PCIDevice *dev, Error **errp) { - PCIBonitoState *s = DO_UPCAST(PCIBonitoState, dev, dev); + PCIBonitoState *s = PCI_BONITO(dev); SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost); PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost); @@ -783,8 +800,8 @@ PCIBus *bonito_init(qemu_irq *pic) qdev_init_nofail(dev); /* set the pcihost pointer before bonito_initfn is called */ - d = pci_create(phb->bus, PCI_DEVFN(0, 0), "Bonito"); - s = DO_UPCAST(PCIBonitoState, dev, d); + d = pci_create(phb->bus, PCI_DEVFN(0, 0), TYPE_PCI_BONITO); + s = PCI_BONITO(d); s->pcihost = pcihost; pcihost->pci_dev = s; qdev_init_nofail(DEVICE(d)); @@ -812,7 +829,7 @@ static void bonito_class_init(ObjectClass *klass, void *data) } static const TypeInfo bonito_info = { - .name = "Bonito", + .name = TYPE_PCI_BONITO, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIBonitoState), .class_init = bonito_class_init, diff --git a/qemu/hw/pci-host/gpex.c b/qemu/hw/pci-host/gpex.c index 9d8fb5a49..66055ee5c 100644 --- a/qemu/hw/pci-host/gpex.c +++ b/qemu/hw/pci-host/gpex.c @@ -28,6 +28,7 @@ * http://www.kernel.org/doc/Documentation/devicetree/bindings/pci/host-generic-pci.txt * http://www.firmware.org/1275/practice/imap/imap0_9d.pdf */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/pci-host/gpex.h" diff --git a/qemu/hw/pci-host/grackle.c b/qemu/hw/pci-host/grackle.c index bfe707a1a..8f9121615 100644 --- a/qemu/hw/pci-host/grackle.c +++ b/qemu/hw/pci-host/grackle.c @@ -23,6 +23,7 @@ * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "hw/pci/pci_host.h" #include "hw/ppc/mac.h" #include "hw/pci/pci.h" @@ -146,8 +147,10 @@ static const TypeInfo grackle_pci_info = { static void pci_grackle_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); k->init = pci_grackle_init_device; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } static const TypeInfo grackle_pci_host_info = { diff --git a/qemu/hw/pci-host/pam.c b/qemu/hw/pci-host/pam.c index 17d826cba..e361ecb7e 100644 --- a/qemu/hw/pci-host/pam.c +++ b/qemu/hw/pci-host/pam.c @@ -27,6 +27,7 @@ * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "qom/object.h" #include "sysemu/sysemu.h" #include "hw/pci-host/pam.h" diff --git a/qemu/hw/pci-host/piix.c b/qemu/hw/pci-host/piix.c index ad55f9966..df2b0e26f 100644 --- a/qemu/hw/pci-host/piix.c +++ b/qemu/hw/pci-host/piix.c @@ -22,25 +22,27 @@ * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/i386/pc.h" #include "hw/pci/pci.h" #include "hw/pci/pci_host.h" #include "hw/isa/isa.h" #include "hw/sysbus.h" +#include "qapi/error.h" #include "qemu/range.h" #include "hw/xen/xen.h" #include "hw/pci-host/pam.h" #include "sysemu/sysemu.h" #include "hw/i386/ioapic.h" #include "qapi/visitor.h" +#include "qemu/error-report.h" /* * I440FX chipset data sheet. * http://download.intel.com/design/chipsets/datashts/29054901.pdf */ -#define TYPE_I440FX_PCI_HOST_BRIDGE "i440FX-pcihost" #define I440FX_PCI_HOST_BRIDGE(obj) \ OBJECT_CHECK(I440FXState, (obj), TYPE_I440FX_PCI_HOST_BRIDGE) @@ -95,7 +97,6 @@ typedef struct PIIX3State { #define PIIX3_PCI_DEVICE(obj) \ OBJECT_CHECK(PIIX3State, (obj), TYPE_PIIX3_PCI_DEVICE) -#define TYPE_I440FX_PCI_DEVICE "i440FX" #define I440FX_PCI_DEVICE(obj) \ OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE) @@ -117,6 +118,11 @@ struct PCII440FXState { #define I440FX_PAM_SIZE 7 #define I440FX_SMRAM 0x72 +/* Older coreboot versions (4.0 and older) read a config register that doesn't + * exist in real hardware, to get the RAM size from QEMU. + */ +#define I440FX_COREBOOT_RAM_SIZE 0x57 + static void piix3_set_irq(void *opaque, int pirq, int level); static PCIINTxRoute piix3_route_intx_pin_to_irq(void *opaque, int pci_intx); static void piix3_write_config_xen(PCIDevice *dev, @@ -211,39 +217,39 @@ static const VMStateDescription vmstate_i440fx = { }; static void i440fx_pcihost_get_pci_hole_start(Object *obj, Visitor *v, - void *opaque, const char *name, + const char *name, void *opaque, Error **errp) { I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj); uint32_t value = s->pci_info.w32.begin; - visit_type_uint32(v, &value, name, errp); + visit_type_uint32(v, name, &value, errp); } static void i440fx_pcihost_get_pci_hole_end(Object *obj, Visitor *v, - void *opaque, const char *name, + const char *name, void *opaque, Error **errp) { I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj); uint32_t value = s->pci_info.w32.end; - visit_type_uint32(v, &value, name, errp); + visit_type_uint32(v, name, &value, errp); } static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v, - void *opaque, const char *name, - Error **errp) + const char *name, + void *opaque, Error **errp) { PCIHostState *h = PCI_HOST_BRIDGE(obj); Range w64; pci_bus_get_w64_range(h->bus, &w64); - visit_type_uint64(v, &w64.begin, name, errp); + visit_type_uint64(v, name, &w64.begin, errp); } static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v, - void *opaque, const char *name, + const char *name, void *opaque, Error **errp) { PCIHostState *h = PCI_HOST_BRIDGE(obj); @@ -251,7 +257,7 @@ static void i440fx_pcihost_get_pci_hole64_end(Object *obj, Visitor *v, pci_bus_get_w64_range(h->bus, &w64); - visit_type_uint64(v, &w64.end, name, errp); + visit_type_uint64(v, name, &w64.end, errp); } static void i440fx_pcihost_initfn(Object *obj) @@ -298,9 +304,14 @@ static void i440fx_pcihost_realize(DeviceState *dev, Error **errp) static void i440fx_realize(PCIDevice *dev, Error **errp) { dev->config[I440FX_SMRAM] = 0x02; + + if (object_property_get_bool(qdev_get_machine(), "iommu", NULL)) { + error_report("warning: i440fx doesn't support emulated iommu"); + } } -PCIBus *i440fx_init(PCII440FXState **pi440fx_state, +PCIBus *i440fx_init(const char *host_type, const char *pci_type, + PCII440FXState **pi440fx_state, int *piix3_devfn, ISABus **isa_bus, qemu_irq *pic, MemoryRegion *address_space_mem, @@ -320,7 +331,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, unsigned i; I440FXState *i440fx; - dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE); + dev = qdev_create(NULL, host_type); s = PCI_HOST_BRIDGE(dev); b = pci_bus_new(dev, NULL, pci_address_space, address_space_io, 0, TYPE_PCI_BUS); @@ -328,7 +339,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL); qdev_init_nofail(dev); - d = pci_create_simple(b, 0, TYPE_I440FX_PCI_DEVICE); + d = pci_create_simple(b, 0, pci_type); *pi440fx_state = I440FX_PCI_DEVICE(d); f = *pi440fx_state; f->system_memory = address_space_mem; @@ -394,7 +405,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, if (ram_size > 255) { ram_size = 255; } - d->config[0x57] = ram_size; + d->config[I440FX_COREBOOT_RAM_SIZE] = ram_size; i440fx_update_memory_mappings(f); @@ -642,8 +653,10 @@ static void piix3_realize(PCIDevice *dev, Error **errp) { PIIX3State *d = PIIX3_PCI_DEVICE(dev); - isa_bus_new(DEVICE(d), get_system_memory(), - pci_address_space_io(dev)); + if (!isa_bus_new(DEVICE(d), get_system_memory(), + pci_address_space_io(dev), errp)) { + return; + } memory_region_init_io(&d->rcr_mem, OBJECT(dev), &rcr_ops, d, "piix3-reset-control", 1); @@ -735,6 +748,95 @@ static const TypeInfo i440fx_info = { .class_init = i440fx_class_init, }; +/* IGD Passthrough Host Bridge. */ +typedef struct { + uint8_t offset; + uint8_t len; +} IGDHostInfo; + +/* Here we just expose minimal host bridge offset subset. */ +static const IGDHostInfo igd_host_bridge_infos[] = { + {0x08, 2}, /* revision id */ + {0x2c, 2}, /* sybsystem vendor id */ + {0x2e, 2}, /* sybsystem id */ + {0x50, 2}, /* SNB: processor graphics control register */ + {0x52, 2}, /* processor graphics control register */ + {0xa4, 4}, /* SNB: graphics base of stolen memory */ + {0xa8, 4}, /* SNB: base of GTT stolen memory */ +}; + +static int host_pci_config_read(int pos, int len, uint32_t *val) +{ + char path[PATH_MAX]; + int config_fd; + ssize_t size = sizeof(path); + /* Access real host bridge. */ + int rc = snprintf(path, size, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/%s", + 0, 0, 0, 0, "config"); + int ret = 0; + + if (rc >= size || rc < 0) { + return -ENODEV; + } + + config_fd = open(path, O_RDWR); + if (config_fd < 0) { + return -ENODEV; + } + + if (lseek(config_fd, pos, SEEK_SET) != pos) { + ret = -errno; + goto out; + } + + do { + rc = read(config_fd, (uint8_t *)val, len); + } while (rc < 0 && (errno == EINTR || errno == EAGAIN)); + if (rc != len) { + ret = -errno; + } + +out: + close(config_fd); + return ret; +} + +static int igd_pt_i440fx_initfn(struct PCIDevice *pci_dev) +{ + uint32_t val = 0; + int rc, i, num; + int pos, len; + + num = ARRAY_SIZE(igd_host_bridge_infos); + for (i = 0; i < num; i++) { + pos = igd_host_bridge_infos[i].offset; + len = igd_host_bridge_infos[i].len; + rc = host_pci_config_read(pos, len, &val); + if (rc) { + return -ENODEV; + } + pci_default_write_config(pci_dev, pos, val, len); + } + + return 0; +} + +static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->init = igd_pt_i440fx_initfn; + dc->desc = "IGD Passthrough Host bridge"; +} + +static const TypeInfo igd_passthrough_i440fx_info = { + .name = TYPE_IGD_PASSTHROUGH_I440FX_PCI_DEVICE, + .parent = TYPE_I440FX_PCI_DEVICE, + .instance_size = sizeof(PCII440FXState), + .class_init = igd_passthrough_i440fx_class_init, +}; + static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge, PCIBus *rootbus) { @@ -776,6 +878,7 @@ static const TypeInfo i440fx_pcihost_info = { static void i440fx_register_types(void) { type_register_static(&i440fx_info); + type_register_static(&igd_passthrough_i440fx_info); type_register_static(&piix3_pci_type_info); type_register_static(&piix3_info); type_register_static(&piix3_xen_info); diff --git a/qemu/hw/pci-host/ppce500.c b/qemu/hw/pci-host/ppce500.c index 613ba73c6..e502bc050 100644 --- a/qemu/hw/pci-host/ppce500.c +++ b/qemu/hw/pci-host/ppce500.c @@ -14,6 +14,7 @@ * (at your option) any later version. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/ppc/e500-ccsr.h" #include "hw/pci/pci.h" @@ -140,7 +141,7 @@ static uint64_t pci_reg_read4(void *opaque, hwaddr addr, case PPCE500_PCI_OW3: case PPCE500_PCI_OW4: idx = (addr >> 5) & 0x7; - switch (addr & 0xC) { + switch (addr & 0x1F) { case PCI_POTAR: value = pci->pob[idx].potar; break; @@ -162,7 +163,7 @@ static uint64_t pci_reg_read4(void *opaque, hwaddr addr, case PPCE500_PCI_IW2: case PPCE500_PCI_IW1: idx = ((addr >> 5) & 0x3) - 1; - switch (addr & 0xC) { + switch (addr & 0x1F) { case PCI_PITAR: value = pci->pib[idx].pitar; break; diff --git a/qemu/hw/pci-host/prep.c b/qemu/hw/pci-host/prep.c index c63f45d21..487e32ecb 100644 --- a/qemu/hw/pci-host/prep.c +++ b/qemu/hw/pci-host/prep.c @@ -23,6 +23,8 @@ * THE SOFTWARE. */ +#include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/hw.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" @@ -302,7 +304,7 @@ static void raven_realize(PCIDevice *d, Error **errp) d->config[0x34] = 0x00; // capabilities_pointer memory_region_init_ram(&s->bios, OBJECT(s), "bios", BIOS_SIZE, - &error_abort); + &error_fatal); memory_region_set_readonly(&s->bios, true); memory_region_add_subregion(get_system_memory(), (uint32_t)(-BIOS_SIZE), &s->bios); @@ -312,7 +314,7 @@ static void raven_realize(PCIDevice *d, Error **errp) if (filename) { if (s->elf_machine != EM_NONE) { bios_size = load_elf(filename, NULL, NULL, NULL, - NULL, NULL, 1, s->elf_machine, 0); + NULL, NULL, 1, s->elf_machine, 0, 0); } if (bios_size < 0) { bios_size = get_image_size(filename); @@ -326,11 +328,10 @@ static void raven_realize(PCIDevice *d, Error **errp) } } if (bios_size < 0 || bios_size > BIOS_SIZE) { + /* FIXME should error_setg() */ hw_error("qemu: could not load bios image '%s'\n", s->bios_name); } - if (filename) { - g_free(filename); - } + g_free(filename); } } @@ -357,8 +358,9 @@ static void raven_class_init(ObjectClass *klass, void *data) dc->desc = "PReP Host Bridge - Motorola Raven"; dc->vmsd = &vmstate_raven; /* - * PCI-facing part of the host bridge, not usable without the - * host-facing part, which can't be device_add'ed, yet. + * Reason: PCI-facing part of the host bridge, not usable without + * the host-facing part, which can't be device_add'ed, yet. + * Reason: realize() method uses hw_error(). */ dc->cannot_instantiate_with_device_add_yet = true; } diff --git a/qemu/hw/pci-host/q35.c b/qemu/hw/pci-host/q35.c index bd7409456..70f897e3a 100644 --- a/qemu/hw/pci-host/q35.c +++ b/qemu/hw/pci-host/q35.c @@ -27,8 +27,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/pci-host/q35.h" +#include "qapi/error.h" #include "qapi/visitor.h" /**************************************************************************** @@ -67,27 +69,27 @@ static const char *q35_host_root_bus_path(PCIHostState *host_bridge, } static void q35_host_get_pci_hole_start(Object *obj, Visitor *v, - void *opaque, const char *name, + const char *name, void *opaque, Error **errp) { Q35PCIHost *s = Q35_HOST_DEVICE(obj); uint32_t value = s->mch.pci_info.w32.begin; - visit_type_uint32(v, &value, name, errp); + visit_type_uint32(v, name, &value, errp); } static void q35_host_get_pci_hole_end(Object *obj, Visitor *v, - void *opaque, const char *name, + const char *name, void *opaque, Error **errp) { Q35PCIHost *s = Q35_HOST_DEVICE(obj); uint32_t value = s->mch.pci_info.w32.end; - visit_type_uint32(v, &value, name, errp); + visit_type_uint32(v, name, &value, errp); } static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v, - void *opaque, const char *name, + const char *name, void *opaque, Error **errp) { PCIHostState *h = PCI_HOST_BRIDGE(obj); @@ -95,11 +97,11 @@ static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v, pci_bus_get_w64_range(h->bus, &w64); - visit_type_uint64(v, &w64.begin, name, errp); + visit_type_uint64(v, name, &w64.begin, errp); } static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v, - void *opaque, const char *name, + const char *name, void *opaque, Error **errp) { PCIHostState *h = PCI_HOST_BRIDGE(obj); @@ -107,17 +109,16 @@ static void q35_host_get_pci_hole64_end(Object *obj, Visitor *v, pci_bus_get_w64_range(h->bus, &w64); - visit_type_uint64(v, &w64.end, name, errp); + visit_type_uint64(v, name, &w64.end, errp); } -static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, - void *opaque, const char *name, - Error **errp) +static void q35_host_get_mmcfg_size(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) { PCIExpressHost *e = PCIE_HOST_BRIDGE(obj); uint32_t value = e->size; - visit_type_uint32(v, &value, name, errp); + visit_type_uint32(v, name, &value, errp); } static Property mch_props[] = { @@ -426,31 +427,12 @@ static void mch_reset(DeviceState *qdev) static AddressSpace *q35_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) { IntelIOMMUState *s = opaque; - VTDAddressSpace **pvtd_as; - int bus_num = pci_bus_num(bus); + VTDAddressSpace *vtd_as; - assert(0 <= bus_num && bus_num <= VTD_PCI_BUS_MAX); assert(0 <= devfn && devfn <= VTD_PCI_DEVFN_MAX); - pvtd_as = s->address_spaces[bus_num]; - if (!pvtd_as) { - /* No corresponding free() */ - pvtd_as = g_malloc0(sizeof(VTDAddressSpace *) * VTD_PCI_DEVFN_MAX); - s->address_spaces[bus_num] = pvtd_as; - } - if (!pvtd_as[devfn]) { - pvtd_as[devfn] = g_malloc0(sizeof(VTDAddressSpace)); - - pvtd_as[devfn]->bus_num = (uint8_t)bus_num; - pvtd_as[devfn]->devfn = (uint8_t)devfn; - pvtd_as[devfn]->iommu_state = s; - pvtd_as[devfn]->context_cache_entry.context_cache_gen = 0; - memory_region_init_iommu(&pvtd_as[devfn]->iommu, OBJECT(s), - &s->iommu_ops, "intel_iommu", UINT64_MAX); - address_space_init(&pvtd_as[devfn]->as, - &pvtd_as[devfn]->iommu, "intel_iommu"); - } - return &pvtd_as[devfn]->as; + vtd_as = vtd_find_add_as(s, bus, devfn); + return &vtd_as->as; } static void mch_init_dmar(MCHPCIState *mch) @@ -525,7 +507,7 @@ static void mch_realize(PCIDevice *d, Error **errp) PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); } /* Intel IOMMU (VT-d) */ - if (machine_iommu(current_machine)) { + if (object_property_get_bool(qdev_get_machine(), "iommu", NULL)) { mch_init_dmar(mch); } } diff --git a/qemu/hw/pci-host/uninorth.c b/qemu/hw/pci-host/uninorth.c index f0144eb7b..15b105423 100644 --- a/qemu/hw/pci-host/uninorth.c +++ b/qemu/hw/pci-host/uninorth.c @@ -21,6 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "hw/hw.h" #include "hw/ppc/mac.h" #include "hw/pci/pci.h" @@ -119,7 +120,7 @@ static void unin_data_write(void *opaque, hwaddr addr, { UNINState *s = opaque; PCIHostState *phb = PCI_HOST_BRIDGE(s); - UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n", + UNIN_DPRINTF("write addr " TARGET_FMT_plx " len %d val %"PRIx64"\n", addr, len, val); pci_data_write(phb->bus, unin_get_config_reg(phb->config_reg, addr), @@ -136,7 +137,7 @@ static uint64_t unin_data_read(void *opaque, hwaddr addr, val = pci_data_read(phb->bus, unin_get_config_reg(phb->config_reg, addr), len); - UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n", + UNIN_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n", addr, len, val); return val; } @@ -330,6 +331,15 @@ static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp) d->config[0x0C] = 0x08; // cache_line_size d->config[0x0D] = 0x10; // latency_timer // d->config[0x34] = 0x80; // capabilities_pointer + /* + * Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI + * memory space with base 0x80000000, size 0x10000000 for Apple's + * AppleMacRiscPCI driver + */ + d->config[0x48] = 0x0; + d->config[0x49] = 0x0; + d->config[0x4a] = 0x0; + d->config[0x4b] = 0x1; } static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp) @@ -446,8 +456,10 @@ static const TypeInfo unin_internal_pci_host_info = { static void pci_unin_main_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); sbc->init = pci_unin_main_init_device; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } static const TypeInfo pci_unin_main_info = { @@ -460,8 +472,10 @@ static const TypeInfo pci_unin_main_info = { static void pci_u3_agp_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); sbc->init = pci_u3_agp_init_device; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } static const TypeInfo pci_u3_agp_info = { @@ -474,8 +488,10 @@ static const TypeInfo pci_u3_agp_info = { static void pci_unin_agp_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); sbc->init = pci_unin_agp_init_device; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } static const TypeInfo pci_unin_agp_info = { @@ -488,8 +504,10 @@ static const TypeInfo pci_unin_agp_info = { static void pci_unin_internal_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); sbc->init = pci_unin_internal_init_device; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); } static const TypeInfo pci_unin_internal_info = { diff --git a/qemu/hw/pci-host/versatile.c b/qemu/hw/pci-host/versatile.c index 6d2355309..339ec2c50 100644 --- a/qemu/hw/pci-host/versatile.c +++ b/qemu/hw/pci-host/versatile.c @@ -7,6 +7,7 @@ * This code is licensed under the LGPL. */ +#include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" @@ -500,6 +501,8 @@ static void pci_vpb_class_init(ObjectClass *klass, void *data) dc->reset = pci_vpb_reset; dc->vmsd = &pci_vpb_vmstate; dc->props = pci_vpb_properties; + /* Reason: object_unref() hangs */ + dc->cannot_destroy_with_object_finalize_yet = true; } static const TypeInfo pci_vpb_info = { @@ -521,10 +524,19 @@ static void pci_realview_init(Object *obj) s->mem_win_size[2] = 0x08000000; } +static void pci_realview_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(class); + + /* Reason: object_unref() hangs */ + dc->cannot_destroy_with_object_finalize_yet = true; +} + static const TypeInfo pci_realview_info = { .name = "realview_pci", .parent = TYPE_VERSATILE_PCI, .instance_init = pci_realview_init, + .class_init = pci_realview_class_init, }; static void versatile_pci_register_types(void) |