Patchwork [v3,03/14] bonito: QOM'ify Bonito PCI host bridge

login
register
mail settings
Submitter Andreas Färber
Date July 4, 2012, 5:19 p.m.
Message ID <1341422373-13614-4-git-send-email-afaerber@suse.de>
Download mbox | patch
Permalink /patch/169025/
State New
Headers show

Comments

Andreas Färber - July 4, 2012, 5:19 p.m.
Introduce type constant. Avoid accessing DeviceState or SysBusDevice
indirectly through PCIHostState field.

Drop global state by passing BonitoState as opaque and adding the IRQs
and a pointer to PCIBonitoState to its state.

Signed-off-by: Andreas Färber <afaerber@suse.de>
---
 hw/bonito.c |  146 ++++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 90 insertions(+), 56 deletions(-)

Patch

diff --git a/hw/bonito.c b/hw/bonito.c
index b990875..062c701 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -180,11 +180,14 @@ 
 #define PCI_ADDR(busno,devno,funno,regno)  \
     ((((busno)<<16)&0xff0000) + (((devno)<<11)&0xf800) + (((funno)<<8)&0x700) + (regno))
 
-typedef PCIHostState BonitoState;
+#define TYPE_BONITO_PCI_HOST_BRIDGE "Bonito-pcihost"
+
+typedef struct BonitoState BonitoState;
 
 typedef struct PCIBonitoState
 {
     PCIDevice dev;
+
     BonitoState *pcihost;
     uint32_t regs[BONITO_REGS];
 
@@ -218,7 +221,16 @@  typedef struct PCIBonitoState
 
 } PCIBonitoState;
 
-PCIBonitoState * bonito_state;
+#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;
+};
 
 static void bonito_writel(void *opaque, target_phys_addr_t addr,
                           uint64_t val, unsigned size)
@@ -314,9 +326,10 @@  static void bonito_pciconf_writel(void *opaque, target_phys_addr_t addr,
                                   uint64_t val, unsigned size)
 {
     PCIBonitoState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(s);
 
     DPRINTF("bonito_pciconf_writel "TARGET_FMT_plx" val %x\n", addr, val);
-    s->dev.config_write(&s->dev, addr, val, 4);
+    d->config_write(d, addr, val, 4);
 }
 
 static uint64_t bonito_pciconf_readl(void *opaque, target_phys_addr_t addr,
@@ -324,9 +337,10 @@  static uint64_t bonito_pciconf_readl(void *opaque, target_phys_addr_t addr,
 {
 
     PCIBonitoState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(s);
 
     DPRINTF("bonito_pciconf_readl "TARGET_FMT_plx"\n", addr);
-    return s->dev.config_read(&s->dev, addr, 4);
+    return d->config_read(d, addr, 4);
 }
 
 /* north bridge PCI configure space. 0x1fe0 0000 - 0x1fe0 00ff */
@@ -402,6 +416,7 @@  static const MemoryRegionOps bonito_cop_ops = {
 static uint32_t bonito_sbridge_pciaddr(void *opaque, target_phys_addr_t addr)
 {
     PCIBonitoState *s = opaque;
+    PCIHostState *phb = FROM_SYSBUS(PCIHostState, SYS_BUS_DEVICE(s->pcihost));
     uint32_t cfgaddr;
     uint32_t idsel;
     uint32_t devno;
@@ -423,13 +438,13 @@  static uint32_t bonito_sbridge_pciaddr(void *opaque, target_phys_addr_t addr)
     regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET;
 
     if (idsel == 0) {
-        fprintf(stderr, "error in bonito pci config address" TARGET_FMT_plx
+        fprintf(stderr, "error in bonito pci config address " TARGET_FMT_plx
             ",pcimap_cfg=%x\n", addr, s->regs[BONITO_PCIMAP_CFG]);
         exit(1);
     }
-    pciaddr = PCI_ADDR(pci_bus_num(s->pcihost->bus), devno, funno, regno);
+    pciaddr = PCI_ADDR(pci_bus_num(phb->bus), devno, funno, regno);
     DPRINTF("cfgaddr %x pciaddr %x busno %x devno %d funno %d regno %d\n",
-        cfgaddr, pciaddr, pci_bus_num(s->pcihost->bus), devno, funno, regno);
+        cfgaddr, pciaddr, pci_bus_num(phb->bus), devno, funno, regno);
 
     return pciaddr;
 }
@@ -438,6 +453,8 @@  static void bonito_spciconf_writeb(void *opaque, target_phys_addr_t addr,
                                    uint32_t val)
 {
     PCIBonitoState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(s);
+    PCIHostState *phb = FROM_SYSBUS(PCIHostState, SYS_BUS_DEVICE(s->pcihost));
     uint32_t pciaddr;
     uint16_t status;
 
@@ -449,24 +466,26 @@  static void bonito_spciconf_writeb(void *opaque, target_phys_addr_t addr,
     }
 
     /* set the pci address in s->config_reg */
-    s->pcihost->config_reg = (pciaddr) | (1u << 31);
-    pci_data_write(s->pcihost->bus, s->pcihost->config_reg, val & 0xff, 1);
+    phb->config_reg = (pciaddr) | (1u << 31);
+    pci_data_write(phb->bus, phb->config_reg, val & 0xff, 1);
 
     /* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
-    status = pci_get_word(s->dev.config + PCI_STATUS);
+    status = pci_get_word(d->config + PCI_STATUS);
     status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
-    pci_set_word(s->dev.config + PCI_STATUS, status);
+    pci_set_word(d->config + PCI_STATUS, status);
 }
 
 static void bonito_spciconf_writew(void *opaque, target_phys_addr_t addr,
                                    uint32_t val)
 {
     PCIBonitoState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(s);
+    PCIHostState *phb = FROM_SYSBUS(PCIHostState, SYS_BUS_DEVICE(s->pcihost));
     uint32_t pciaddr;
     uint16_t status;
 
     DPRINTF("bonito_spciconf_writew "TARGET_FMT_plx" val %x\n", addr, val);
-    assert((addr&0x1)==0);
+    assert((addr & 0x1) == 0);
 
     pciaddr = bonito_sbridge_pciaddr(s, addr);
 
@@ -475,24 +494,26 @@  static void bonito_spciconf_writew(void *opaque, target_phys_addr_t addr,
     }
 
     /* set the pci address in s->config_reg */
-    s->pcihost->config_reg = (pciaddr) | (1u << 31);
-    pci_data_write(s->pcihost->bus, s->pcihost->config_reg, val, 2);
+    phb->config_reg = (pciaddr) | (1u << 31);
+    pci_data_write(phb->bus, phb->config_reg, val, 2);
 
     /* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
-    status = pci_get_word(s->dev.config + PCI_STATUS);
+    status = pci_get_word(d->config + PCI_STATUS);
     status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
-    pci_set_word(s->dev.config + PCI_STATUS, status);
+    pci_set_word(d->config + PCI_STATUS, status);
 }
 
 static void bonito_spciconf_writel(void *opaque, target_phys_addr_t addr,
                                    uint32_t val)
 {
     PCIBonitoState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(s);
+    PCIHostState *phb = FROM_SYSBUS(PCIHostState, SYS_BUS_DEVICE(s->pcihost));
     uint32_t pciaddr;
     uint16_t status;
 
     DPRINTF("bonito_spciconf_writel "TARGET_FMT_plx" val %x\n", addr, val);
-    assert((addr&0x3)==0);
+    assert((addr & 0x3) == 0);
 
     pciaddr = bonito_sbridge_pciaddr(s, addr);
 
@@ -501,18 +522,20 @@  static void bonito_spciconf_writel(void *opaque, target_phys_addr_t addr,
     }
 
     /* set the pci address in s->config_reg */
-    s->pcihost->config_reg = (pciaddr) | (1u << 31);
-    pci_data_write(s->pcihost->bus, s->pcihost->config_reg, val, 4);
+    phb->config_reg = (pciaddr) | (1u << 31);
+    pci_data_write(phb->bus, phb->config_reg, val, 4);
 
     /* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
-    status = pci_get_word(s->dev.config + PCI_STATUS);
+    status = pci_get_word(d->config + PCI_STATUS);
     status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
-    pci_set_word(s->dev.config + PCI_STATUS, status);
+    pci_set_word(d->config + PCI_STATUS, status);
 }
 
 static uint32_t bonito_spciconf_readb(void *opaque, target_phys_addr_t addr)
 {
     PCIBonitoState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(s);
+    PCIHostState *phb = FROM_SYSBUS(PCIHostState, SYS_BUS_DEVICE(s->pcihost));
     uint32_t pciaddr;
     uint16_t status;
 
@@ -524,24 +547,26 @@  static uint32_t bonito_spciconf_readb(void *opaque, target_phys_addr_t addr)
     }
 
     /* set the pci address in s->config_reg */
-    s->pcihost->config_reg = (pciaddr) | (1u << 31);
+    phb->config_reg = (pciaddr) | (1u << 31);
 
     /* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
-    status = pci_get_word(s->dev.config + PCI_STATUS);
+    status = pci_get_word(d->config + PCI_STATUS);
     status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
-    pci_set_word(s->dev.config + PCI_STATUS, status);
+    pci_set_word(d->config + PCI_STATUS, status);
 
-    return pci_data_read(s->pcihost->bus, s->pcihost->config_reg, 1);
+    return pci_data_read(phb->bus, phb->config_reg, 1);
 }
 
 static uint32_t bonito_spciconf_readw(void *opaque, target_phys_addr_t addr)
 {
     PCIBonitoState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(s);
+    PCIHostState *phb = FROM_SYSBUS(PCIHostState, SYS_BUS_DEVICE(s->pcihost));
     uint32_t pciaddr;
     uint16_t status;
 
     DPRINTF("bonito_spciconf_readw "TARGET_FMT_plx"\n", addr);
-    assert((addr&0x1)==0);
+    assert((addr & 0x1) == 0);
 
     pciaddr = bonito_sbridge_pciaddr(s, addr);
 
@@ -550,24 +575,26 @@  static uint32_t bonito_spciconf_readw(void *opaque, target_phys_addr_t addr)
     }
 
     /* set the pci address in s->config_reg */
-    s->pcihost->config_reg = (pciaddr) | (1u << 31);
+    phb->config_reg = (pciaddr) | (1u << 31);
 
     /* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
-    status = pci_get_word(s->dev.config + PCI_STATUS);
+    status = pci_get_word(d->config + PCI_STATUS);
     status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
-    pci_set_word(s->dev.config + PCI_STATUS, status);
+    pci_set_word(d->config + PCI_STATUS, status);
 
-    return pci_data_read(s->pcihost->bus, s->pcihost->config_reg, 2);
+    return pci_data_read(phb->bus, phb->config_reg, 2);
 }
 
 static uint32_t bonito_spciconf_readl(void *opaque, target_phys_addr_t addr)
 {
     PCIBonitoState *s = opaque;
+    PCIDevice *d = PCI_DEVICE(s);
+    PCIHostState *phb = FROM_SYSBUS(PCIHostState, SYS_BUS_DEVICE(s->pcihost));
     uint32_t pciaddr;
     uint16_t status;
 
     DPRINTF("bonito_spciconf_readl "TARGET_FMT_plx"\n", addr);
-    assert((addr&0x3) == 0);
+    assert((addr & 0x3) == 0);
 
     pciaddr = bonito_sbridge_pciaddr(s, addr);
 
@@ -576,14 +603,14 @@  static uint32_t bonito_spciconf_readl(void *opaque, target_phys_addr_t addr)
     }
 
     /* set the pci address in s->config_reg */
-    s->pcihost->config_reg = (pciaddr) | (1u << 31);
+    phb->config_reg = (pciaddr) | (1u << 31);
 
     /* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
-    status = pci_get_word(s->dev.config + PCI_STATUS);
+    status = pci_get_word(d->config + PCI_STATUS);
     status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
-    pci_set_word(s->dev.config + PCI_STATUS, status);
+    pci_set_word(d->config + PCI_STATUS, status);
 
-    return pci_data_read(s->pcihost->bus, s->pcihost->config_reg, 4);
+    return pci_data_read(phb->bus, phb->config_reg, 4);
 }
 
 /* south bridge PCI configure space. 0x1fe8 0000 - 0x1fef ffff */
@@ -607,13 +634,15 @@  static const MemoryRegionOps bonito_spciconf_ops = {
 
 static void pci_bonito_set_irq(void *opaque, int irq_num, int level)
 {
-    qemu_irq *pic = opaque;
+    BonitoState *s = opaque;
+    qemu_irq *pic = s->pic;
+    PCIBonitoState *bonito_state = s->pci_dev;
     int internal_irq = irq_num - BONITO_IRQ_BASE;
 
-    if (bonito_state->regs[BONITO_INTEDGE] & (1<<internal_irq)) {
+    if (bonito_state->regs[BONITO_INTEDGE] & (1 << internal_irq)) {
         qemu_irq_pulse(*pic);
     } else {   /* level triggered */
-        if (bonito_state->regs[BONITO_INTPOL] & (1<<internal_irq)) {
+        if (bonito_state->regs[BONITO_INTPOL] & (1 << internal_irq)) {
             qemu_irq_raise(*pic);
         } else {
             qemu_irq_lower(*pic);
@@ -673,13 +702,21 @@  static const VMStateDescription vmstate_bonito = {
 
 static int bonito_pcihost_initfn(SysBusDevice *dev)
 {
+    PCIHostState *phb = FROM_SYSBUS(PCIHostState, dev);
+
+    phb->bus = pci_register_bus(DEVICE(dev), "pci",
+                                pci_bonito_set_irq, pci_bonito_map_irq, dev,
+                                get_system_memory(), get_system_io(),
+                                0x28, 32);
+
     return 0;
 }
 
 static int bonito_initfn(PCIDevice *dev)
 {
     PCIBonitoState *s = DO_UPCAST(PCIBonitoState, dev, dev);
-    SysBusDevice *sysbus = &s->pcihost->busdev;
+    SysBusDevice *sysbus = SYS_BUS_DEVICE(s->pcihost);
+    PCIHostState *phb = FROM_SYSBUS(PCIHostState, sysbus);
 
     /* Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */
     pci_config_set_prog_interface(dev->config, 0x00);
@@ -691,15 +728,15 @@  static int bonito_initfn(PCIDevice *dev)
     sysbus_mmio_map(sysbus, 0, BONITO_INTERNAL_REG_BASE);
 
     /* set the north bridge pci configure  mapping */
-    memory_region_init_io(&s->pcihost->conf_mem, &bonito_pciconf_ops, s,
+    memory_region_init_io(&phb->conf_mem, &bonito_pciconf_ops, s,
                           "north-bridge-pci-config", BONITO_PCICONFIG_SIZE);
-    sysbus_init_mmio(sysbus, &s->pcihost->conf_mem);
+    sysbus_init_mmio(sysbus, &phb->conf_mem);
     sysbus_mmio_map(sysbus, 1, BONITO_PCICONFIG_BASE);
 
     /* set the south bridge pci configure  mapping */
-    memory_region_init_io(&s->pcihost->data_mem, &bonito_spciconf_ops, s,
+    memory_region_init_io(&phb->data_mem, &bonito_spciconf_ops, s,
                           "south-bridge-pci-config", BONITO_SPCICONFIG_SIZE);
-    sysbus_init_mmio(sysbus, &s->pcihost->data_mem);
+    sysbus_init_mmio(sysbus, &phb->data_mem);
     sysbus_mmio_map(sysbus, 2, BONITO_SPCICONFIG_BASE);
 
     memory_region_init_io(&s->iomem_ldma, &bonito_ldma_ops, s,
@@ -742,28 +779,25 @@  static int bonito_initfn(PCIDevice *dev)
 PCIBus *bonito_init(qemu_irq *pic)
 {
     DeviceState *dev;
-    PCIBus *b;
     BonitoState *pcihost;
+    PCIHostState *phb;
     PCIBonitoState *s;
     PCIDevice *d;
 
-    dev = qdev_create(NULL, "Bonito-pcihost");
-    pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev));
-    b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq,
-                         pci_bonito_map_irq, pic, get_system_memory(),
-                         get_system_io(),
-                         0x28, 32);
-    pcihost->bus = b;
+    dev = qdev_create(NULL, TYPE_BONITO_PCI_HOST_BRIDGE);
+    phb = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
+    pcihost = BONITO_PCI_HOST_BRIDGE(dev);
+    pcihost->pic = pic;
     qdev_init_nofail(dev);
 
     /* set the pcihost pointer before bonito_initfn is called */
-    d = pci_create(b, PCI_DEVFN(0, 0), "Bonito");
+    d = pci_create(phb->bus, PCI_DEVFN(0, 0), "Bonito");
     s = DO_UPCAST(PCIBonitoState, dev, d);
     s->pcihost = pcihost;
-    bonito_state = s;
-    qdev_init_nofail(&d->qdev);
+    pcihost->pci_dev = s;
+    qdev_init_nofail(DEVICE(d));
 
-    return b;
+    return phb->bus;
 }
 
 static void bonito_class_init(ObjectClass *klass, void *data)
@@ -798,7 +832,7 @@  static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
 }
 
 static const TypeInfo bonito_pcihost_info = {
-    .name          = "Bonito-pcihost",
+    .name          = TYPE_BONITO_PCI_HOST_BRIDGE,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(BonitoState),
     .class_init    = bonito_pcihost_class_init,