bonito: QOM'ify Bonito PCI host bridge

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>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Andreas Färber 2012-08-20 19:07:58 +02:00 committed by Anthony Liguori
parent 94dd91d651
commit c5589ee974

View File

@ -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,