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:
parent
94dd91d651
commit
c5589ee974
146
hw/bonito.c
146
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,
|
||||
|
Loading…
Reference in New Issue
Block a user