From 323abebf9997f30fb357602e169ea6333ac20bc3 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 27 Feb 2012 17:18:11 +0000 Subject: pseries: Remove unused constant from PCI code The 'bars' constant array was used in experimental device allocation code which is no longer necessary now that we always run the SLOF firmware. This patch removes the now redundant variable. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- hw/spapr_pci.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'hw/spapr_pci.c') diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 374dcf8..3d5e50a 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -32,13 +32,6 @@ #include "hw/pci_internals.h" -static const uint32_t bars[] = { - PCI_BASE_ADDRESS_0, PCI_BASE_ADDRESS_1, - PCI_BASE_ADDRESS_2, PCI_BASE_ADDRESS_3, - PCI_BASE_ADDRESS_4, PCI_BASE_ADDRESS_5 - /*, PCI_ROM_ADDRESS*/ -}; - static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid, uint32_t config_addr) { -- cgit v1.1 From 76ab9583cea5c742f32743cc65abc326719bd646 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Mon, 27 Feb 2012 17:18:12 +0000 Subject: pseries: Remove PCI device from PCI host bridge code The sPAPR PCI code defines a PCI device "spapr-pci-host-bridge-pci" which is never used. This came over from the earlier bridge driver we used as a template. Some other bridges appear on their own PCI bus as a device, but that is not true of pSeries bridges, which are pure host to PCI with no visible presence on the PCI side. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- hw/spapr_pci.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'hw/spapr_pci.c') diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 3d5e50a..c06afac 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -202,25 +202,6 @@ static int spapr_phb_init(SysBusDevice *s) return 0; } -static int spapr_main_pci_host_init(PCIDevice *d) -{ - return 0; -} - -static void spapr_main_pci_host_class_init(ObjectClass *klass, void *data) -{ - PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - - k->init = spapr_main_pci_host_init; -} - -static TypeInfo spapr_main_pci_host_info = { - .name = "spapr-pci-host-bridge-pci", - .parent = TYPE_PCI_DEVICE, - .instance_size = sizeof(PCIDevice), - .class_init = spapr_main_pci_host_class_init, -}; - static void spapr_phb_class_init(ObjectClass *klass, void *data) { SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); @@ -238,7 +219,6 @@ static TypeInfo spapr_phb_info = { static void spapr_register_types(void) { type_register_static(&spapr_phb_info); - type_register_static(&spapr_main_pci_host_info); } type_init(spapr_register_types) -- cgit v1.1 From d07fee7e8ad9d3611404fa145270d3b885b2772a Mon Sep 17 00:00:00 2001 From: David Gibson Date: Wed, 7 Mar 2012 15:12:21 +0000 Subject: pseries: Add support for level interrupts to XICS The pseries "xics" interrupt controller, like most interrupt controllers can support both message (i.e. edge sensitive) interrupts and level sensitive interrupts, but it needs to know which are which. When I implemented the xics emulation for qemu, the only devices we supported were the PAPR virtual IO devices. These devices only use message interrupts, so they were the only ones I implemented in xics. Since then, however, we have added support for PCI devices, which use level sensitive interrupts. It turns out the message interrupt logic still actually works most of the time for these, but there are circumstances where we can lost interrupts due to the incorrect interrupt logic. This patch, therefore, implements the correct xics level-sensitive interrupt logic. The type of the interrupt is set when a device allocates a new xics interrupt. Signed-off-by: David Gibson Signed-off-by: Alexander Graf --- hw/spapr_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'hw/spapr_pci.c') diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index c06afac..233250f 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -190,7 +190,7 @@ static int spapr_phb_init(SysBusDevice *s) qemu_irq qirq; uint32_t num; - qirq = spapr_allocate_irq(0, &num); + qirq = spapr_allocate_lsi(0, &num); if (!qirq) { return -1; } -- cgit v1.1 From 298a971024534e9ab6c7b57845bbbd8188867d7a Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 12 Mar 2012 17:50:24 +0000 Subject: pseries: Configure PCI bridge using properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, the function spapr_create_phb() uses its parameters to initialize the correct memory windows for the new PCI Host Bridge (PHB). This is not the way things are supposed to be done with qdevs, and means you can't create extra PHBs easily using -device. Since pSeries machines can and do have many PHBs with various configurations, this is a real limitation, not just a theoretical. This patch, therefore, alters the PHB initialization code to use qdev properties to set these parameters of the new bridge, moving most of the code from spapr_create_phb() to spapr_phb_init(). While we're at it, we change the naming of each PCI bus and its associated memory regions to be less arbitrary and make it easier to relate the guest and qemu views of memory to each other. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson Reviewed-by: Andreas Färber Signed-off-by: Alexander Graf --- hw/spapr_pci.c | 166 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 91 insertions(+), 75 deletions(-) (limited to 'hw/spapr_pci.c') diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index 233250f..e7ef551 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -180,49 +180,6 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(phb->lsi_table[irq_num].qirq, level); } -static int spapr_phb_init(SysBusDevice *s) -{ - sPAPRPHBState *phb = FROM_SYSBUS(sPAPRPHBState, s); - int i; - - /* Initialize the LSI table */ - for (i = 0; i < SPAPR_PCI_NUM_LSI; i++) { - qemu_irq qirq; - uint32_t num; - - qirq = spapr_allocate_lsi(0, &num); - if (!qirq) { - return -1; - } - - phb->lsi_table[i].dt_irq = num; - phb->lsi_table[i].qirq = qirq; - } - - return 0; -} - -static void spapr_phb_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); - - sdc->init = spapr_phb_init; -} - -static TypeInfo spapr_phb_info = { - .name = "spapr-pci-host-bridge", - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(sPAPRPHBState), - .class_init = spapr_phb_class_init, -}; - -static void spapr_register_types(void) -{ - type_register_static(&spapr_phb_info); -} - -type_init(spapr_register_types) - static uint64_t spapr_io_read(void *opaque, target_phys_addr_t addr, unsigned size) { @@ -260,35 +217,29 @@ static const MemoryRegionOps spapr_io_ops = { .write = spapr_io_write }; -void spapr_create_phb(sPAPREnvironment *spapr, - const char *busname, uint64_t buid, - uint64_t mem_win_addr, uint64_t mem_win_size, - uint64_t io_win_addr) +/* + * PHB PCI device + */ +static int spapr_phb_init(SysBusDevice *s) { - DeviceState *dev; - SysBusDevice *s; - sPAPRPHBState *phb; + sPAPRPHBState *phb = FROM_SYSBUS(sPAPRPHBState, s); + char *namebuf; + int i; PCIBus *bus; - char namebuf[strlen(busname)+11]; - dev = qdev_create(NULL, "spapr-pci-host-bridge"); - qdev_init_nofail(dev); - s = sysbus_from_qdev(dev); - phb = FROM_SYSBUS(sPAPRPHBState, s); + phb->dtbusname = g_strdup_printf("pci@%" PRIx64, phb->buid); + namebuf = alloca(strlen(phb->dtbusname) + 32); - phb->mem_win_addr = mem_win_addr; - - sprintf(namebuf, "%s-mem", busname); + /* Initialize memory regions */ + sprintf(namebuf, "%s.mmio", phb->dtbusname); memory_region_init(&phb->memspace, namebuf, INT64_MAX); - sprintf(namebuf, "%s-memwindow", busname); + sprintf(namebuf, "%s.mmio-alias", phb->dtbusname); memory_region_init_alias(&phb->memwindow, namebuf, &phb->memspace, - SPAPR_PCI_MEM_WIN_BUS_OFFSET, mem_win_size); - memory_region_add_subregion(get_system_memory(), mem_win_addr, + SPAPR_PCI_MEM_WIN_BUS_OFFSET, phb->mem_win_size); + memory_region_add_subregion(get_system_memory(), phb->mem_win_addr, &phb->memwindow); - phb->io_win_addr = io_win_addr; - /* On ppc, we only have MMIO no specific IO space from the CPU * perspective. In theory we ought to be able to embed the PCI IO * memory region direction in the system memory space. However, @@ -297,33 +248,92 @@ void spapr_create_phb(sPAPREnvironment *spapr, * system io address space. This hack to bounce things via * system_io works around the problem until all the users of * old_portion are updated */ - sprintf(namebuf, "%s-io", busname); + sprintf(namebuf, "%s.io", phb->dtbusname); memory_region_init(&phb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE); /* FIXME: fix to support multiple PHBs */ memory_region_add_subregion(get_system_io(), 0, &phb->iospace); - sprintf(namebuf, "%s-iowindow", busname); + sprintf(namebuf, "%s.io-alias", phb->dtbusname); memory_region_init_io(&phb->iowindow, &spapr_io_ops, phb, namebuf, SPAPR_PCI_IO_WIN_SIZE); - memory_region_add_subregion(get_system_memory(), io_win_addr, + memory_region_add_subregion(get_system_memory(), phb->io_win_addr, &phb->iowindow); - phb->host_state.bus = bus = pci_register_bus(&phb->busdev.qdev, busname, - pci_spapr_set_irq, - pci_spapr_map_irq, - phb, - &phb->memspace, &phb->iospace, - PCI_DEVFN(0, 0), - SPAPR_PCI_NUM_LSI); + bus = pci_register_bus(&phb->busdev.qdev, + phb->busname ? phb->busname : phb->dtbusname, + pci_spapr_set_irq, pci_spapr_map_irq, phb, + &phb->memspace, &phb->iospace, + PCI_DEVFN(0, 0), SPAPR_PCI_NUM_LSI); + phb->host_state.bus = bus; + + QLIST_INSERT_HEAD(&spapr->phbs, phb, list); + + /* Initialize the LSI table */ + for (i = 0; i < SPAPR_PCI_NUM_LSI; i++) { + qemu_irq qirq; + uint32_t num; + + qirq = spapr_allocate_lsi(0, &num); + if (!qirq) { + return -1; + } + + phb->lsi_table[i].dt_irq = num; + phb->lsi_table[i].qirq = qirq; + } + + return 0; +} + +static Property spapr_phb_properties[] = { + DEFINE_PROP_HEX64("buid", sPAPRPHBState, buid, 0), + DEFINE_PROP_STRING("busname", sPAPRPHBState, busname), + DEFINE_PROP_HEX64("mem_win_addr", sPAPRPHBState, mem_win_addr, 0), + DEFINE_PROP_HEX64("mem_win_size", sPAPRPHBState, mem_win_size, 0x20000000), + DEFINE_PROP_HEX64("io_win_addr", sPAPRPHBState, io_win_addr, 0), + DEFINE_PROP_HEX64("io_win_size", sPAPRPHBState, io_win_size, 0x10000), + DEFINE_PROP_END_OF_LIST(), +}; + +static void spapr_phb_class_init(ObjectClass *klass, void *data) +{ + SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); + + sdc->init = spapr_phb_init; + dc->props = spapr_phb_properties; spapr_rtas_register("read-pci-config", rtas_read_pci_config); spapr_rtas_register("write-pci-config", rtas_write_pci_config); spapr_rtas_register("ibm,read-pci-config", rtas_ibm_read_pci_config); spapr_rtas_register("ibm,write-pci-config", rtas_ibm_write_pci_config); +} - QLIST_INSERT_HEAD(&spapr->phbs, phb, list); +static TypeInfo spapr_phb_info = { + .name = "spapr-pci-host-bridge", + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(sPAPRPHBState), + .class_init = spapr_phb_class_init, +}; + +void spapr_create_phb(sPAPREnvironment *spapr, + const char *busname, uint64_t buid, + uint64_t mem_win_addr, uint64_t mem_win_size, + uint64_t io_win_addr) +{ + DeviceState *dev; + + dev = qdev_create(NULL, spapr_phb_info.name); - /* pci_bus_set_mem_base(bus, mem_va_start - SPAPR_PCI_MEM_BAR_START); */ + if (busname) { + qdev_prop_set_string(dev, "busname", g_strdup(busname)); + } + qdev_prop_set_uint64(dev, "buid", buid); + qdev_prop_set_uint64(dev, "mem_win_addr", mem_win_addr); + qdev_prop_set_uint64(dev, "mem_win_size", mem_win_size); + qdev_prop_set_uint64(dev, "io_win_addr", io_win_addr); + + qdev_init_nofail(dev); } /* Macros to operate with address in OF binding to PCI */ @@ -415,3 +425,9 @@ int spapr_populate_pci_devices(sPAPRPHBState *phb, return 0; } + +static void register_types(void) +{ + type_register_static(&spapr_phb_info); +} +type_init(register_types) -- cgit v1.1