* north bridge address to pci address.
*/
-#include <assert.h>
-
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
#include "hw/i386/pc.h"
//#define DEBUG_BONITO
#ifdef DEBUG_BONITO
-#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__)
+#define DPRINTF(fmt, ...) fprintf(stderr, "%s: " fmt, __func__, ##__VA_ARGS__)
#else
#define DPRINTF(fmt, ...)
#endif
#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
} 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)
{
uint32_t saddr;
int reset = 0;
- saddr = (addr - BONITO_REGBASE) >> 2;
+ saddr = addr >> 2;
DPRINTF("bonito_writel "TARGET_FMT_plx" val %x saddr %x\n", addr, val, saddr);
switch (saddr) {
}
s->regs[saddr] = val;
if (reset) {
- qemu_system_reset_request();
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
}
break;
case BONITO_INTENSET:
PCIBonitoState *s = opaque;
uint32_t saddr;
- saddr = (addr - BONITO_REGBASE) >> 2;
+ saddr = addr >> 2;
DPRINTF("bonito_readl "TARGET_FMT_plx"\n", addr);
switch (saddr) {
uint32_t val;
PCIBonitoState *s = opaque;
+ if (addr >= sizeof(s->bonldma)) {
+ return 0;
+ }
+
val = ((uint32_t *)(&s->bonldma))[addr/sizeof(uint32_t)];
return val;
{
PCIBonitoState *s = opaque;
+ if (addr >= sizeof(s->bonldma)) {
+ return;
+ }
+
((uint32_t *)(&s->bonldma))[addr/sizeof(uint32_t)] = val & 0xffffffff;
}
uint32_t val;
PCIBonitoState *s = opaque;
+ if (addr >= sizeof(s->boncop)) {
+ return 0;
+ }
+
val = ((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)];
return val;
{
PCIBonitoState *s = opaque;
+ if (addr >= sizeof(s->boncop)) {
+ return;
+ }
+
((uint32_t *)(&s->boncop))[addr/sizeof(uint32_t)] = val & 0xffffffff;
}
cfgaddr |= (s->regs[BONITO_PCIMAP_CFG] & 0xffff) << 16;
idsel = (cfgaddr & BONITO_PCICONF_IDSEL_MASK) >> BONITO_PCICONF_IDSEL_OFFSET;
- devno = ffs(idsel) - 1;
+ devno = ctz32(idsel);
funno = (cfgaddr & BONITO_PCICONF_FUN_MASK) >> BONITO_PCICONF_FUN_OFFSET;
regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET;
if (idsel == 0) {
- fprintf(stderr, "error in bonito pci config address " TARGET_FMT_plx
- ",pcimap_cfg=%x\n", addr, s->regs[BONITO_PCIMAP_CFG]);
+ error_report("error in bonito pci config address " TARGET_FMT_plx
+ ",pcimap_cfg=%x", addr, s->regs[BONITO_PCIMAP_CFG]);
exit(1);
}
pciaddr = PCI_ADDR(pci_bus_num(phb->bus), devno, funno, regno);
return pciaddr;
}
-static void bonito_spciconf_writeb(void *opaque, hwaddr addr,
- uint32_t val)
-{
- PCIBonitoState *s = opaque;
- PCIDevice *d = PCI_DEVICE(s);
- PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
- uint32_t pciaddr;
- uint16_t status;
-
- DPRINTF("bonito_spciconf_writeb "TARGET_FMT_plx" val %x\n", addr, val);
- pciaddr = bonito_sbridge_pciaddr(s, addr);
-
- if (pciaddr == 0xffffffff) {
- return;
- }
-
- /* set the pci address in s->config_reg */
- 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(d->config + PCI_STATUS);
- status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
- pci_set_word(d->config + PCI_STATUS, status);
-}
-
-static void bonito_spciconf_writew(void *opaque, hwaddr addr,
- uint32_t val)
-{
- PCIBonitoState *s = opaque;
- PCIDevice *d = PCI_DEVICE(s);
- PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
- uint32_t pciaddr;
- uint16_t status;
-
- DPRINTF("bonito_spciconf_writew "TARGET_FMT_plx" val %x\n", addr, val);
- assert((addr & 0x1) == 0);
-
- pciaddr = bonito_sbridge_pciaddr(s, addr);
-
- if (pciaddr == 0xffffffff) {
- return;
- }
-
- /* set the pci address in s->config_reg */
- 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(d->config + PCI_STATUS);
- status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
- pci_set_word(d->config + PCI_STATUS, status);
-}
-
-static void bonito_spciconf_writel(void *opaque, hwaddr addr,
- uint32_t val)
+static void bonito_spciconf_write(void *opaque, hwaddr addr, uint64_t val,
+ unsigned size)
{
PCIBonitoState *s = opaque;
PCIDevice *d = PCI_DEVICE(s);
uint32_t pciaddr;
uint16_t status;
- DPRINTF("bonito_spciconf_writel "TARGET_FMT_plx" val %x\n", addr, val);
- assert((addr & 0x3) == 0);
+ DPRINTF("bonito_spciconf_write "TARGET_FMT_plx" size %d val %x\n",
+ addr, size, val);
pciaddr = bonito_sbridge_pciaddr(s, addr);
/* set the pci address in s->config_reg */
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(d->config + PCI_STATUS);
- status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
- pci_set_word(d->config + PCI_STATUS, status);
-}
-
-static uint32_t bonito_spciconf_readb(void *opaque, hwaddr addr)
-{
- PCIBonitoState *s = opaque;
- PCIDevice *d = PCI_DEVICE(s);
- PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
- uint32_t pciaddr;
- uint16_t status;
-
- DPRINTF("bonito_spciconf_readb "TARGET_FMT_plx"\n", addr);
- pciaddr = bonito_sbridge_pciaddr(s, addr);
-
- if (pciaddr == 0xffffffff) {
- return 0xff;
- }
-
- /* set the pci address in s->config_reg */
- phb->config_reg = (pciaddr) | (1u << 31);
+ pci_data_write(phb->bus, phb->config_reg, val, size);
/* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
status = pci_get_word(d->config + PCI_STATUS);
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
pci_set_word(d->config + PCI_STATUS, status);
-
- return pci_data_read(phb->bus, phb->config_reg, 1);
-}
-
-static uint32_t bonito_spciconf_readw(void *opaque, hwaddr addr)
-{
- PCIBonitoState *s = opaque;
- PCIDevice *d = PCI_DEVICE(s);
- PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);
- uint32_t pciaddr;
- uint16_t status;
-
- DPRINTF("bonito_spciconf_readw "TARGET_FMT_plx"\n", addr);
- assert((addr & 0x1) == 0);
-
- pciaddr = bonito_sbridge_pciaddr(s, addr);
-
- if (pciaddr == 0xffffffff) {
- return 0xffff;
- }
-
- /* set the pci address in s->config_reg */
- phb->config_reg = (pciaddr) | (1u << 31);
-
- /* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */
- status = pci_get_word(d->config + PCI_STATUS);
- status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
- pci_set_word(d->config + PCI_STATUS, status);
-
- return pci_data_read(phb->bus, phb->config_reg, 2);
}
-static uint32_t bonito_spciconf_readl(void *opaque, hwaddr addr)
+static uint64_t bonito_spciconf_read(void *opaque, hwaddr addr, unsigned size)
{
PCIBonitoState *s = opaque;
PCIDevice *d = PCI_DEVICE(s);
uint32_t pciaddr;
uint16_t status;
- DPRINTF("bonito_spciconf_readl "TARGET_FMT_plx"\n", addr);
- assert((addr & 0x3) == 0);
+ DPRINTF("bonito_spciconf_read "TARGET_FMT_plx" size %d\n", addr, size);
pciaddr = bonito_sbridge_pciaddr(s, addr);
if (pciaddr == 0xffffffff) {
- return 0xffffffff;
+ return MAKE_64BIT_MASK(0, size * 8);
}
/* set the pci address in s->config_reg */
status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);
pci_set_word(d->config + PCI_STATUS, status);
- return pci_data_read(phb->bus, phb->config_reg, 4);
+ return pci_data_read(phb->bus, phb->config_reg, size);
}
/* south bridge PCI configure space. 0x1fe8 0000 - 0x1fef ffff */
static const MemoryRegionOps bonito_spciconf_ops = {
- .old_mmio = {
- .read = {
- bonito_spciconf_readb,
- bonito_spciconf_readw,
- bonito_spciconf_readl,
- },
- .write = {
- bonito_spciconf_writeb,
- bonito_spciconf_writew,
- bonito_spciconf_writel,
- },
- },
+ .read = bonito_spciconf_read,
+ .write = bonito_spciconf_write,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
+ .impl.min_access_size = 1,
+ .impl.max_access_size = 4,
.endianness = DEVICE_NATIVE_ENDIAN,
};
.name = "Bonito",
.version_id = 1,
.minimum_version_id = 1,
- .minimum_version_id_old = 1,
- .fields = (VMStateField []) {
+ .fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, PCIBonitoState),
VMSTATE_END_OF_LIST()
}
};
-static int bonito_pcihost_initfn(SysBusDevice *dev)
+static void bonito_pcihost_realize(DeviceState *dev, Error **errp)
{
PCIHostState *phb = PCI_HOST_BRIDGE(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, TYPE_PCI_BUS);
-
- return 0;
+ phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
+ pci_bonito_set_irq, pci_bonito_map_irq,
+ dev, get_system_memory(), get_system_io(),
+ 0x28, 32, TYPE_PCI_BUS);
}
-static int bonito_initfn(PCIDevice *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);
pci_set_byte(dev->config + PCI_MAX_LAT, 0x00);
qemu_register_reset(bonito_reset, s);
-
- return 0;
}
PCIBus *bonito_init(qemu_irq *pic)
pcihost->pic = 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));
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
- k->init = bonito_initfn;
+ k->realize = bonito_realize;
k->vendor_id = 0xdf53;
k->device_id = 0x00d5;
k->revision = 0x01;
* PCI-facing part of the host bridge, not usable without the
* host-facing part, which can't be device_add'ed, yet.
*/
- dc->cannot_instantiate_with_device_add_yet = true;
+ dc->user_creatable = false;
}
static const TypeInfo bonito_info = {
- .name = "Bonito",
+ .name = TYPE_PCI_BONITO,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIBonitoState),
.class_init = bonito_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+ { },
+ },
};
static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
{
- SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
- k->init = bonito_pcihost_initfn;
+ dc->realize = bonito_pcihost_realize;
}
static const TypeInfo bonito_pcihost_info = {