pci_host: convert conf index and data ports to memory API

Reviewed-by: Richard Henderson  <rth@twiddle.net>
Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
Avi Kivity 2011-07-24 17:47:18 +03:00
parent be35694da9
commit d2c33733c8
9 changed files with 130 additions and 132 deletions

View file

@ -80,16 +80,15 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
static int pci_dec_21154_init_device(SysBusDevice *dev) static int pci_dec_21154_init_device(SysBusDevice *dev)
{ {
DECState *s; DECState *s;
int pci_mem_config, pci_mem_data;
s = FROM_SYSBUS(DECState, dev); s = FROM_SYSBUS(DECState, dev);
pci_mem_config = pci_host_conf_register_mmio(&s->host_state, memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
DEVICE_LITTLE_ENDIAN); &s->host_state, "pci-conf-idx", 0x1000);
pci_mem_data = pci_host_data_register_mmio(&s->host_state, memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
DEVICE_LITTLE_ENDIAN); &s->host_state, "pci-data-idx", 0x1000);
sysbus_init_mmio(dev, 0x1000, pci_mem_config); sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
sysbus_init_mmio(dev, 0x1000, pci_mem_data); sysbus_init_mmio_region(dev, &s->host_state.data_mem);
return 0; return 0;
} }

View file

@ -92,16 +92,15 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
static int pci_grackle_init_device(SysBusDevice *dev) static int pci_grackle_init_device(SysBusDevice *dev)
{ {
GrackleState *s; GrackleState *s;
int pci_mem_config, pci_mem_data;
s = FROM_SYSBUS(GrackleState, dev); s = FROM_SYSBUS(GrackleState, dev);
pci_mem_config = pci_host_conf_register_mmio(&s->host_state, memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
DEVICE_LITTLE_ENDIAN); &s->host_state, "pci-conf-idx", 0x1000);
pci_mem_data = pci_host_data_register_mmio(&s->host_state, memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
DEVICE_LITTLE_ENDIAN); &s->host_state, "pci-data-idx", 0x1000);
sysbus_init_mmio(dev, 0x1000, pci_mem_config); sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
sysbus_init_mmio(dev, 0x1000, pci_mem_data); sysbus_init_mmio_region(dev, &s->host_state.data_mem);
qemu_register_reset(pci_grackle_reset, &s->host_state); qemu_register_reset(pci_grackle_reset, &s->host_state);
return 0; return 0;

View file

@ -94,82 +94,72 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
return val; return val;
} }
static void pci_host_config_write(ReadWriteHandler *handler, static void pci_host_config_write(void *opaque, target_phys_addr_t addr,
pcibus_t addr, uint32_t val, int len) uint64_t val, unsigned len)
{ {
PCIHostState *s = container_of(handler, PCIHostState, conf_handler); PCIHostState *s = opaque;
PCI_DPRINTF("%s addr %" FMT_PCIBUS " %d val %"PRIx32"\n", PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx64"\n",
__func__, addr, len, val); __func__, addr, len, val);
s->config_reg = val; s->config_reg = val;
} }
static uint32_t pci_host_config_read(ReadWriteHandler *handler, static uint64_t pci_host_config_read(void *opaque, target_phys_addr_t addr,
pcibus_t addr, int len) unsigned len)
{ {
PCIHostState *s = container_of(handler, PCIHostState, conf_handler); PCIHostState *s = opaque;
uint32_t val = s->config_reg; uint32_t val = s->config_reg;
PCI_DPRINTF("%s addr %" FMT_PCIBUS " len %d val %"PRIx32"\n", PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx32"\n",
__func__, addr, len, val); __func__, addr, len, val);
return val; return val;
} }
static void pci_host_data_write(ReadWriteHandler *handler, static void pci_host_data_write(void *opaque, target_phys_addr_t addr,
pcibus_t addr, uint32_t val, int len) uint64_t val, unsigned len)
{ {
PCIHostState *s = container_of(handler, PCIHostState, data_handler); PCIHostState *s = opaque;
PCI_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n", PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n",
addr, len, val); addr, len, (unsigned)val);
if (s->config_reg & (1u << 31)) if (s->config_reg & (1u << 31))
pci_data_write(s->bus, s->config_reg | (addr & 3), val, len); pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
} }
static uint32_t pci_host_data_read(ReadWriteHandler *handler, static uint64_t pci_host_data_read(void *opaque,
pcibus_t addr, int len) target_phys_addr_t addr, unsigned len)
{ {
PCIHostState *s = container_of(handler, PCIHostState, data_handler); PCIHostState *s = opaque;
uint32_t val; uint32_t val;
if (!(s->config_reg & (1 << 31))) if (!(s->config_reg & (1 << 31)))
return 0xffffffff; return 0xffffffff;
val = pci_data_read(s->bus, s->config_reg | (addr & 3), len); val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
PCI_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n", PCI_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n",
addr, len, val); addr, len, val);
return val; return val;
} }
static void pci_host_init(PCIHostState *s) const MemoryRegionOps pci_host_conf_le_ops = {
{ .read = pci_host_config_read,
s->conf_handler.write = pci_host_config_write; .write = pci_host_config_write,
s->conf_handler.read = pci_host_config_read; .endianness = DEVICE_LITTLE_ENDIAN,
s->data_handler.write = pci_host_data_write; };
s->data_handler.read = pci_host_data_read;
}
int pci_host_conf_register_mmio(PCIHostState *s, int endian) const MemoryRegionOps pci_host_conf_be_ops = {
{ .read = pci_host_config_read,
pci_host_init(s); .write = pci_host_config_write,
return cpu_register_io_memory_simple(&s->conf_handler, endian); .endianness = DEVICE_BIG_ENDIAN,
} };
void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s) const MemoryRegionOps pci_host_data_le_ops = {
{ .read = pci_host_data_read,
pci_host_init(s); .write = pci_host_data_write,
register_ioport_simple(&s->conf_handler, ioport, 4, 4); .endianness = DEVICE_LITTLE_ENDIAN,
sysbus_init_ioports(&s->busdev, ioport, 4); };
}
const MemoryRegionOps pci_host_data_be_ops = {
.read = pci_host_data_read,
.write = pci_host_data_write,
.endianness = DEVICE_BIG_ENDIAN,
};
int pci_host_data_register_mmio(PCIHostState *s, int endian)
{
pci_host_init(s);
return cpu_register_io_memory_simple(&s->data_handler, endian);
}
void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s)
{
pci_host_init(s);
register_ioport_simple(&s->data_handler, ioport, 4, 1);
register_ioport_simple(&s->data_handler, ioport, 4, 2);
register_ioport_simple(&s->data_handler, ioport, 4, 4);
sysbus_init_ioports(&s->busdev, ioport, 4);
}

View file

@ -29,12 +29,11 @@
#define PCI_HOST_H #define PCI_HOST_H
#include "sysbus.h" #include "sysbus.h"
#include "rwhandler.h"
struct PCIHostState { struct PCIHostState {
SysBusDevice busdev; SysBusDevice busdev;
ReadWriteHandler conf_handler; MemoryRegion conf_mem;
ReadWriteHandler data_handler; MemoryRegion data_mem;
MemoryRegion *address_space; MemoryRegion *address_space;
uint32_t config_reg; uint32_t config_reg;
PCIBus *bus; PCIBus *bus;
@ -49,12 +48,9 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len); void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len); uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
/* for mmio */ extern const MemoryRegionOps pci_host_conf_le_ops;
int pci_host_conf_register_mmio(PCIHostState *s, int endian); extern const MemoryRegionOps pci_host_conf_be_ops;
int pci_host_data_register_mmio(PCIHostState *s, int endian); extern const MemoryRegionOps pci_host_data_le_ops;
extern const MemoryRegionOps pci_host_data_be_ops;
/* for ioio */
void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s);
void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s);
#endif /* PCI_HOST_H */ #endif /* PCI_HOST_H */

View file

@ -235,9 +235,16 @@ static int i440fx_pcihost_initfn(SysBusDevice *dev)
{ {
I440FXState *s = FROM_SYSBUS(I440FXState, dev); I440FXState *s = FROM_SYSBUS(I440FXState, dev);
pci_host_conf_register_ioport(0xcf8, s); memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s,
"pci-conf-idx", 4);
sysbus_add_io(dev, 0xcf8, &s->conf_mem);
sysbus_init_ioports(&s->busdev, 0xcf8, 4);
memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s,
"pci-conf-data", 4);
sysbus_add_io(dev, 0xcfc, &s->data_mem);
sysbus_init_ioports(&s->busdev, 0xcfc, 4);
pci_host_data_register_ioport(0xcfc, s);
return 0; return 0;
} }

View file

@ -368,10 +368,12 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
cpu_register_physical_memory(config_space + PCIC0_CFGADDR, 4, index); cpu_register_physical_memory(config_space + PCIC0_CFGADDR, 4, index);
/* CFGDATA */ /* CFGDATA */
index = pci_host_data_register_mmio(&controller->pci_state, 1); memory_region_init_io(&controller->pci_state.data_mem,
if (index < 0) &pci_host_data_be_ops,
goto free; &controller->pci_state, "pci-conf-data", 4);
cpu_register_physical_memory(config_space + PCIC0_CFGDATA, 4, index); memory_region_add_subregion(get_system_memory(),
config_space + PCIC0_CFGDATA,
&controller->pci_state.data_mem);
/* Internal registers */ /* Internal registers */
index = cpu_register_io_memory(pci_reg_read, pci_reg_write, controller, index = cpu_register_io_memory(pci_reg_read, pci_reg_write, controller,

View file

@ -79,8 +79,6 @@ struct PPCE500PCIState {
uint32_t gasket_time; uint32_t gasket_time;
qemu_irq irq[4]; qemu_irq irq[4];
/* mmio maps */ /* mmio maps */
int cfgaddr;
int cfgdata;
int reg; int reg;
}; };
@ -268,18 +266,18 @@ static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base)
PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev)); PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
PPCE500PCIState *s = DO_UPCAST(PPCE500PCIState, pci_state, h); PPCE500PCIState *s = DO_UPCAST(PPCE500PCIState, pci_state, h);
cpu_register_physical_memory(base + PCIE500_CFGADDR, 4, s->cfgaddr); sysbus_add_memory(dev, base + PCIE500_CFGADDR, &h->conf_mem);
cpu_register_physical_memory(base + PCIE500_CFGDATA, 4, s->cfgdata); sysbus_add_memory(dev, base + PCIE500_CFGDATA, &h->data_mem);
cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE, cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
s->reg); s->reg);
} }
static void e500_pci_unmap(SysBusDevice *dev, target_phys_addr_t base) static void e500_pci_unmap(SysBusDevice *dev, target_phys_addr_t base)
{ {
cpu_register_physical_memory(base + PCIE500_CFGADDR, 4, PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
IO_MEM_UNASSIGNED);
cpu_register_physical_memory(base + PCIE500_CFGDATA, 4, sysbus_del_memory(dev, &h->conf_mem);
IO_MEM_UNASSIGNED); sysbus_del_memory(dev, &h->data_mem);
cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE, cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
IO_MEM_UNASSIGNED); IO_MEM_UNASSIGNED);
} }
@ -309,9 +307,10 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
pci_create_simple(b, 0, "e500-host-bridge"); pci_create_simple(b, 0, "e500-host-bridge");
s->cfgaddr = pci_host_conf_register_mmio(&s->pci_state, DEVICE_BIG_ENDIAN); memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, h,
s->cfgdata = pci_host_data_register_mmio(&s->pci_state, "pci-conf-idx", 4);
DEVICE_LITTLE_ENDIAN); memory_region_init_io(&h->data_mem, &pci_host_data_le_ops, h,
"pci-conf-data", 4);
s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s, s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s,
DEVICE_BIG_ENDIAN); DEVICE_BIG_ENDIAN);
sysbus_init_mmio_cb2(dev, e500_pci_map, e500_pci_unmap); sysbus_init_mmio_cb2(dev, e500_pci_map, e500_pci_unmap);

View file

@ -125,9 +125,15 @@ PCIBus *pci_prep_init(qemu_irq *pic,
address_space_io, address_space_io,
0, 4); 0, 4);
pci_host_conf_register_ioport(0xcf8, s); memory_region_init_io(&s->conf_mem, &pci_host_conf_be_ops, s,
"pci-conf-idx", 1);
memory_region_add_subregion(address_space_io, 0xcf8, &s->conf_mem);
sysbus_init_ioports(&s->busdev, 0xcf8, 1);
pci_host_data_register_ioport(0xcfc, s); memory_region_init_io(&s->conf_mem, &pci_host_data_be_ops, s,
"pci-conf-data", 1);
memory_region_add_subregion(address_space_io, 0xcfc, &s->data_mem);
sysbus_init_ioports(&s->busdev, 0xcfc, 1);
PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read, PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read,
PPC_PCIIO_write, s, PPC_PCIIO_write, s,

View file

@ -41,7 +41,6 @@ static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e };
typedef struct UNINState { typedef struct UNINState {
SysBusDevice busdev; SysBusDevice busdev;
PCIHostState host_state; PCIHostState host_state;
ReadWriteHandler data_handler;
} UNINState; } UNINState;
static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num) static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
@ -100,67 +99,70 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr)
return retval; return retval;
} }
static void unin_data_write(ReadWriteHandler *handler, static void unin_data_write(void *opaque, target_phys_addr_t addr,
pcibus_t addr, uint32_t val, int len) uint64_t val, unsigned len)
{ {
UNINState *s = container_of(handler, UNINState, data_handler); UNINState *s = opaque;
UNIN_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val); UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n",
addr, len, val);
pci_data_write(s->host_state.bus, pci_data_write(s->host_state.bus,
unin_get_config_reg(s->host_state.config_reg, addr), unin_get_config_reg(s->host_state.config_reg, addr),
val, len); val, len);
} }
static uint32_t unin_data_read(ReadWriteHandler *handler, static uint64_t unin_data_read(void *opaque, target_phys_addr_t addr,
pcibus_t addr, int len) unsigned len)
{ {
UNINState *s = container_of(handler, UNINState, data_handler); UNINState *s = opaque;
uint32_t val; uint32_t val;
val = pci_data_read(s->host_state.bus, val = pci_data_read(s->host_state.bus,
unin_get_config_reg(s->host_state.config_reg, addr), unin_get_config_reg(s->host_state.config_reg, addr),
len); len);
UNIN_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val); UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n",
addr, len, val);
return val; return val;
} }
static const MemoryRegionOps unin_data_ops = {
.read = unin_data_read,
.write = unin_data_write,
.endianness = DEVICE_LITTLE_ENDIAN,
};
static int pci_unin_main_init_device(SysBusDevice *dev) static int pci_unin_main_init_device(SysBusDevice *dev)
{ {
UNINState *s; UNINState *s;
int pci_mem_config, pci_mem_data;
/* Use values found on a real PowerMac */ /* Use values found on a real PowerMac */
/* Uninorth main bus */ /* Uninorth main bus */
s = FROM_SYSBUS(UNINState, dev); s = FROM_SYSBUS(UNINState, dev);
pci_mem_config = pci_host_conf_register_mmio(&s->host_state, memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
DEVICE_LITTLE_ENDIAN); &s->host_state, "pci-conf-idx", 0x1000);
s->data_handler.read = unin_data_read; memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
s->data_handler.write = unin_data_write; "pci-conf-data", 0x1000);
pci_mem_data = cpu_register_io_memory_simple(&s->data_handler, sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
DEVICE_LITTLE_ENDIAN); sysbus_init_mmio_region(dev, &s->host_state.data_mem);
sysbus_init_mmio(dev, 0x1000, pci_mem_config);
sysbus_init_mmio(dev, 0x1000, pci_mem_data);
qemu_register_reset(pci_unin_reset, &s->host_state); qemu_register_reset(pci_unin_reset, &s->host_state);
return 0; return 0;
} }
static int pci_u3_agp_init_device(SysBusDevice *dev) static int pci_u3_agp_init_device(SysBusDevice *dev)
{ {
UNINState *s; UNINState *s;
int pci_mem_config, pci_mem_data;
/* Uninorth U3 AGP bus */ /* Uninorth U3 AGP bus */
s = FROM_SYSBUS(UNINState, dev); s = FROM_SYSBUS(UNINState, dev);
pci_mem_config = pci_host_conf_register_mmio(&s->host_state, memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
DEVICE_LITTLE_ENDIAN); &s->host_state, "pci-conf-idx", 0x1000);
s->data_handler.read = unin_data_read; memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
s->data_handler.write = unin_data_write; "pci-conf-data", 0x1000);
pci_mem_data = cpu_register_io_memory_simple(&s->data_handler, sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
DEVICE_LITTLE_ENDIAN); sysbus_init_mmio_region(dev, &s->host_state.data_mem);
sysbus_init_mmio(dev, 0x1000, pci_mem_config);
sysbus_init_mmio(dev, 0x1000, pci_mem_data);
qemu_register_reset(pci_unin_reset, &s->host_state); qemu_register_reset(pci_unin_reset, &s->host_state);
@ -170,34 +172,32 @@ static int pci_u3_agp_init_device(SysBusDevice *dev)
static int pci_unin_agp_init_device(SysBusDevice *dev) static int pci_unin_agp_init_device(SysBusDevice *dev)
{ {
UNINState *s; UNINState *s;
int pci_mem_config, pci_mem_data;
/* Uninorth AGP bus */ /* Uninorth AGP bus */
s = FROM_SYSBUS(UNINState, dev); s = FROM_SYSBUS(UNINState, dev);
pci_mem_config = pci_host_conf_register_mmio(&s->host_state, memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
DEVICE_LITTLE_ENDIAN); &s->host_state, "pci-conf-idx", 0x1000);
pci_mem_data = pci_host_data_register_mmio(&s->host_state, memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
DEVICE_LITTLE_ENDIAN); &s->host_state, "pci-conf-data", 0x1000);
sysbus_init_mmio(dev, 0x1000, pci_mem_config); sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
sysbus_init_mmio(dev, 0x1000, pci_mem_data); sysbus_init_mmio_region(dev, &s->host_state.data_mem);
return 0; return 0;
} }
static int pci_unin_internal_init_device(SysBusDevice *dev) static int pci_unin_internal_init_device(SysBusDevice *dev)
{ {
UNINState *s; UNINState *s;
int pci_mem_config, pci_mem_data;
/* Uninorth internal bus */ /* Uninorth internal bus */
s = FROM_SYSBUS(UNINState, dev); s = FROM_SYSBUS(UNINState, dev);
pci_mem_config = pci_host_conf_register_mmio(&s->host_state, memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
DEVICE_LITTLE_ENDIAN); &s->host_state, "pci-conf-idx", 0x1000);
pci_mem_data = pci_host_data_register_mmio(&s->host_state, memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
DEVICE_LITTLE_ENDIAN); &s->host_state, "pci-conf-data", 0x1000);
sysbus_init_mmio(dev, 0x1000, pci_mem_config); sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
sysbus_init_mmio(dev, 0x1000, pci_mem_data); sysbus_init_mmio_region(dev, &s->host_state.data_mem);
return 0; return 0;
} }