aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/ac97.c88
-rw-r--r--hw/apb_pci.c1
-rw-r--r--hw/axis_dev88.c21
-rw-r--r--hw/bonito.c1
-rw-r--r--hw/cirrus_vga.c459
-rw-r--r--hw/cris_pic_cpu.c1
-rw-r--r--hw/cuda.c6
-rw-r--r--hw/e1000.c113
-rw-r--r--hw/eepro100.c181
-rw-r--r--hw/es1370.c43
-rw-r--r--hw/escc.c42
-rw-r--r--hw/escc.h2
-rw-r--r--hw/etraxfs.c159
-rw-r--r--hw/etraxfs.h19
-rw-r--r--hw/etraxfs_eth.c84
-rw-r--r--hw/etraxfs_ser.c10
-rw-r--r--hw/grackle_pci.c8
-rw-r--r--hw/gt64xxx.c4
-rw-r--r--hw/heathrow_pic.c29
-rw-r--r--hw/hid.c76
-rw-r--r--hw/hid.h1
-rw-r--r--hw/hw.h20
-rw-r--r--hw/ide.h2
-rw-r--r--hw/ide/ahci.c31
-rw-r--r--hw/ide/ahci.h2
-rw-r--r--hw/ide/cmd646.c204
-rw-r--r--hw/ide/ich.c3
-rw-r--r--hw/ide/macio.c36
-rw-r--r--hw/ide/pci.c25
-rw-r--r--hw/ide/pci.h19
-rw-r--r--hw/ide/piix.c63
-rw-r--r--hw/ide/via.c64
-rw-r--r--hw/intel-hda.c35
-rw-r--r--hw/isa.h2
-rw-r--r--hw/isa_mmio.c29
-rw-r--r--hw/ivshmem.c158
-rw-r--r--hw/kvmclock.c7
-rw-r--r--hw/lance.c31
-rw-r--r--hw/lsi53c895a.c257
-rw-r--r--hw/mac_dbdma.c32
-rw-r--r--hw/mac_dbdma.h4
-rw-r--r--hw/mac_nvram.c39
-rw-r--r--hw/macio.c73
-rw-r--r--hw/milkymist-softusb.c122
-rw-r--r--hw/msix.c64
-rw-r--r--hw/msix.h6
-rw-r--r--hw/ne2000-isa.c13
-rw-r--r--hw/ne2000.c77
-rw-r--r--hw/ne2000.h8
-rw-r--r--hw/openpic.c81
-rw-r--r--hw/openpic.h2
-rw-r--r--hw/pc.h4
-rw-r--r--hw/pc_piix.c6
-rw-r--r--hw/pci.c133
-rw-r--r--hw/pci.h26
-rw-r--r--hw/pci_internals.h3
-rw-r--r--hw/pcnet-pci.c74
-rw-r--r--hw/pcnet.h4
-rw-r--r--hw/piix_pci.c14
-rw-r--r--hw/ppc4xx_pci.c1
-rw-r--r--hw/ppc_mac.h27
-rw-r--r--hw/ppc_newworld.c34
-rw-r--r--hw/ppc_oldworld.c27
-rw-r--r--hw/ppc_prep.c2
-rw-r--r--hw/ppce500_pci.c7
-rw-r--r--hw/prep_pci.c8
-rw-r--r--hw/prep_pci.h4
-rw-r--r--hw/qxl-render.c2
-rw-r--r--hw/qxl.c142
-rw-r--r--hw/qxl.h6
-rw-r--r--hw/rtl8139.c70
-rw-r--r--hw/sh_pci.c4
-rw-r--r--hw/sun4u.c49
-rw-r--r--hw/unin_pci.c16
-rw-r--r--hw/usb-ehci.c36
-rw-r--r--hw/usb-hid.c58
-rw-r--r--hw/usb-ohci.c2
-rw-r--r--hw/usb-uhci.c41
-rw-r--r--hw/usb.h3
-rw-r--r--hw/versatile_pci.c2
-rw-r--r--hw/vga-isa-mm.c46
-rw-r--r--hw/vga-isa.c10
-rw-r--r--hw/vga-pci.c27
-rw-r--r--hw/vga.c178
-rw-r--r--hw/vga_int.h18
-rw-r--r--hw/virtio-pci.c85
-rw-r--r--hw/virtio-pci.h3
-rw-r--r--hw/vmware_vga.c153
-rw-r--r--hw/wdt_i6300esb.c43
-rw-r--r--hw/xen_platform.c82
90 files changed, 1863 insertions, 2444 deletions
diff --git a/hw/ac97.c b/hw/ac97.c
index 0b59896fbb..541d9a4b97 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -160,8 +160,9 @@ typedef struct AC97LinkState {
SWVoiceIn *voice_mc;
int invalid_freq[3];
uint8_t silence[128];
- uint32_t base[2];
int bup_flag;
+ MemoryRegion io_nam;
+ MemoryRegion io_nabm;
} AC97LinkState;
enum {
@@ -583,7 +584,7 @@ static uint32_t nam_readw (void *opaque, uint32_t addr)
{
AC97LinkState *s = opaque;
uint32_t val = ~0U;
- uint32_t index = addr - s->base[0];
+ uint32_t index = addr;
s->cas = 0;
val = mixer_load (s, index);
return val;
@@ -611,7 +612,7 @@ static void nam_writeb (void *opaque, uint32_t addr, uint32_t val)
static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
{
AC97LinkState *s = opaque;
- uint32_t index = addr - s->base[0];
+ uint32_t index = addr;
s->cas = 0;
switch (index) {
case AC97_Reset:
@@ -714,7 +715,7 @@ static uint32_t nabm_readb (void *opaque, uint32_t addr)
{
AC97LinkState *s = opaque;
AC97BusMasterRegs *r = NULL;
- uint32_t index = addr - s->base[1];
+ uint32_t index = addr;
uint32_t val = ~0U;
switch (index) {
@@ -769,7 +770,7 @@ static uint32_t nabm_readw (void *opaque, uint32_t addr)
{
AC97LinkState *s = opaque;
AC97BusMasterRegs *r = NULL;
- uint32_t index = addr - s->base[1];
+ uint32_t index = addr;
uint32_t val = ~0U;
switch (index) {
@@ -798,7 +799,7 @@ static uint32_t nabm_readl (void *opaque, uint32_t addr)
{
AC97LinkState *s = opaque;
AC97BusMasterRegs *r = NULL;
- uint32_t index = addr - s->base[1];
+ uint32_t index = addr;
uint32_t val = ~0U;
switch (index) {
@@ -848,7 +849,7 @@ static void nabm_writeb (void *opaque, uint32_t addr, uint32_t val)
{
AC97LinkState *s = opaque;
AC97BusMasterRegs *r = NULL;
- uint32_t index = addr - s->base[1];
+ uint32_t index = addr;
switch (index) {
case PI_LVI:
case PO_LVI:
@@ -904,7 +905,7 @@ static void nabm_writew (void *opaque, uint32_t addr, uint32_t val)
{
AC97LinkState *s = opaque;
AC97BusMasterRegs *r = NULL;
- uint32_t index = addr - s->base[1];
+ uint32_t index = addr;
switch (index) {
case PI_SR:
case PO_SR:
@@ -924,7 +925,7 @@ static void nabm_writel (void *opaque, uint32_t addr, uint32_t val)
{
AC97LinkState *s = opaque;
AC97BusMasterRegs *r = NULL;
- uint32_t index = addr - s->base[1];
+ uint32_t index = addr;
switch (index) {
case PI_BDBAR:
case PO_BDBAR:
@@ -1230,31 +1231,33 @@ static const VMStateDescription vmstate_ac97 = {
}
};
-static void ac97_map (PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, pci_dev);
- PCIDevice *d = &s->dev;
-
- if (!region_num) {
- s->base[0] = addr;
- register_ioport_read (addr, 256 * 1, 1, nam_readb, d);
- register_ioport_read (addr, 256 * 2, 2, nam_readw, d);
- register_ioport_read (addr, 256 * 4, 4, nam_readl, d);
- register_ioport_write (addr, 256 * 1, 1, nam_writeb, d);
- register_ioport_write (addr, 256 * 2, 2, nam_writew, d);
- register_ioport_write (addr, 256 * 4, 4, nam_writel, d);
- }
- else {
- s->base[1] = addr;
- register_ioport_read (addr, 64 * 1, 1, nabm_readb, d);
- register_ioport_read (addr, 64 * 2, 2, nabm_readw, d);
- register_ioport_read (addr, 64 * 4, 4, nabm_readl, d);
- register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d);
- register_ioport_write (addr, 64 * 2, 2, nabm_writew, d);
- register_ioport_write (addr, 64 * 4, 4, nabm_writel, d);
- }
-}
+static const MemoryRegionPortio nam_portio[] = {
+ { 0, 256 * 1, 1, .read = nam_readb, },
+ { 0, 256 * 2, 2, .read = nam_readw, },
+ { 0, 256 * 4, 4, .read = nam_readl, },
+ { 0, 256 * 1, 1, .write = nam_writeb, },
+ { 0, 256 * 2, 2, .write = nam_writew, },
+ { 0, 256 * 4, 4, .write = nam_writel, },
+ PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionOps ac97_io_nam_ops = {
+ .old_portio = nam_portio,
+};
+
+static const MemoryRegionPortio nabm_portio[] = {
+ { 0, 64 * 1, 1, .read = nabm_readb, },
+ { 0, 64 * 2, 2, .read = nabm_readw, },
+ { 0, 64 * 4, 4, .read = nabm_readl, },
+ { 0, 64 * 1, 1, .write = nabm_writeb, },
+ { 0, 64 * 2, 2, .write = nabm_writew, },
+ { 0, 64 * 4, 4, .write = nabm_writel, },
+ PORTIO_END_OF_LIST()
+};
+
+static const MemoryRegionOps ac97_io_nabm_ops = {
+ .old_portio = nabm_portio,
+};
static void ac97_on_reset (void *opaque)
{
@@ -1311,15 +1314,25 @@ static int ac97_initfn (PCIDevice *dev)
/* TODO: RST# value should be 0. */
c[PCI_INTERRUPT_PIN] = 0x01; /* intr_pn interrupt pin ro */
- pci_register_bar (&s->dev, 0, 256 * 4, PCI_BASE_ADDRESS_SPACE_IO,
- ac97_map);
- pci_register_bar (&s->dev, 1, 64 * 4, PCI_BASE_ADDRESS_SPACE_IO, ac97_map);
+ memory_region_init_io (&s->io_nam, &ac97_io_nam_ops, s, "ac97-nam", 1024);
+ memory_region_init_io (&s->io_nabm, &ac97_io_nabm_ops, s, "ac97-nabm", 256);
+ pci_register_bar (&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
+ pci_register_bar (&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
qemu_register_reset (ac97_on_reset, s);
AUD_register_card ("ac97", &s->card);
ac97_on_reset (s);
return 0;
}
+static int ac97_exitfn (PCIDevice *dev)
+{
+ AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev);
+
+ memory_region_destroy (&s->io_nam);
+ memory_region_destroy (&s->io_nabm);
+ return 0;
+}
+
int ac97_init (PCIBus *bus)
{
pci_create_simple (bus, -1, "AC97");
@@ -1332,6 +1345,7 @@ static PCIDeviceInfo ac97_info = {
.qdev.size = sizeof (AC97LinkState),
.qdev.vmsd = &vmstate_ac97,
.init = ac97_initfn,
+ .exit = ac97_exitfn,
.vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82801AA_5,
.revision = 0x01,
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 8b9939c06a..163822617b 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -348,6 +348,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
d->bus = pci_register_bus(&d->busdev.qdev, "pci",
pci_apb_set_irq, pci_pbm_map_irq, d,
get_system_memory(),
+ get_system_io(),
0, 32);
pci_bus_set_mem_base(d->bus, mem_base);
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index e0a8c14c12..d9002a5e2c 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -255,7 +255,7 @@ void axisdev88_init (ram_addr_t ram_size,
DriveInfo *nand;
qemu_irq irq[30], nmi[2], *cpu_irq;
void *etraxfs_dmac;
- struct etraxfs_dma_client *eth[2] = {NULL, NULL};
+ struct etraxfs_dma_client *dma_eth;
int i;
int nand_regs;
int gpio_regs;
@@ -315,16 +315,18 @@ void axisdev88_init (ram_addr_t ram_size,
}
/* Add the two ethernet blocks. */
- eth[0] = etraxfs_eth_init(&nd_table[0], 0x30034000, 1);
- if (nb_nics > 1)
- eth[1] = etraxfs_eth_init(&nd_table[1], 0x30036000, 2);
+ dma_eth = qemu_mallocz(sizeof dma_eth[0] * 4); /* Allocate 4 channels. */
+ etraxfs_eth_init(&nd_table[0], 0x30034000, 1, &dma_eth[0], &dma_eth[1]);
+ if (nb_nics > 1) {
+ etraxfs_eth_init(&nd_table[1], 0x30036000, 2, &dma_eth[2], &dma_eth[3]);
+ }
/* The DMA Connector block is missing, hardwire things for now. */
- etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]);
- etraxfs_dmac_connect_client(etraxfs_dmac, 1, eth[0] + 1);
- if (eth[1]) {
- etraxfs_dmac_connect_client(etraxfs_dmac, 6, eth[1]);
- etraxfs_dmac_connect_client(etraxfs_dmac, 7, eth[1] + 1);
+ etraxfs_dmac_connect_client(etraxfs_dmac, 0, &dma_eth[0]);
+ etraxfs_dmac_connect_client(etraxfs_dmac, 1, &dma_eth[1]);
+ if (nb_nics > 1) {
+ etraxfs_dmac_connect_client(etraxfs_dmac, 6, &dma_eth[2]);
+ etraxfs_dmac_connect_client(etraxfs_dmac, 7, &dma_eth[3]);
}
/* 2 timers. */
@@ -350,6 +352,7 @@ static QEMUMachine axisdev88_machine = {
.name = "axis-dev88",
.desc = "AXIS devboard 88",
.init = axisdev88_init,
+ .is_default = 1,
};
static void axisdev88_machine_init(void)
diff --git a/hw/bonito.c b/hw/bonito.c
index 5f62dda6e2..8708e95688 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -775,6 +775,7 @@ PCIBus *bonito_init(qemu_irq *pic)
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;
qdev_init_nofail(dev);
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index f39d1f82ff..b48930994a 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -32,6 +32,7 @@
#include "console.h"
#include "vga_int.h"
#include "loader.h"
+#include "exec-memory.h"
/*
* TODO:
@@ -200,9 +201,14 @@ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
typedef struct CirrusVGAState {
VGACommonState vga;
- int cirrus_linear_io_addr;
- int cirrus_linear_bitblt_io_addr;
- int cirrus_mmio_io_addr;
+ MemoryRegion cirrus_linear_io;
+ MemoryRegion cirrus_linear_bitblt_io;
+ MemoryRegion cirrus_mmio_io;
+ MemoryRegion pci_bar;
+ bool linear_vram; /* vga.vram mapped over cirrus_linear_io */
+ MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */
+ MemoryRegion low_mem; /* always mapped, overridden by: */
+ MemoryRegion *cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */
uint32_t cirrus_addr_mask;
uint32_t linear_mmio_mask;
uint8_t cirrus_shadow_gr0;
@@ -612,7 +618,7 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
off_cur &= TARGET_PAGE_MASK;
while (off_cur < off_cur_end) {
- cpu_physical_memory_set_dirty(s->vga.vram_offset + off_cur);
+ memory_region_set_dirty(&s->vga.vram, off_cur);
off_cur += TARGET_PAGE_SIZE;
}
off_begin += off_pitch;
@@ -1177,12 +1183,6 @@ static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index)
}
if (limit > 0) {
- /* Thinking about changing bank base? First, drop the dirty bitmap information
- * on the current location, otherwise we lose this pointer forever */
- if (s->vga.lfb_vram_mapped) {
- target_phys_addr_t base_addr = isa_mem_base + 0xa0000 + bank_index * 0x8000;
- cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000);
- }
s->cirrus_bank_base[bank_index] = offset;
s->cirrus_bank_limit[bank_index] = limit;
} else {
@@ -1921,8 +1921,8 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s,
val <<= 1;
dst++;
}
- cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
- cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 7);
+ memory_region_set_dirty(&s->vga.vram, offset);
+ memory_region_set_dirty(&s->vga.vram, offset + 7);
}
static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
@@ -1946,8 +1946,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
val <<= 1;
dst += 2;
}
- cpu_physical_memory_set_dirty(s->vga.vram_offset + offset);
- cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 15);
+ memory_region_set_dirty(&s->vga.vram, offset);
+ memory_region_set_dirty(&s->vga.vram, offset + 15);
}
/***************************************
@@ -1956,7 +1956,9 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s,
*
***************************************/
-static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_vga_mem_read(void *opaque,
+ target_phys_addr_t addr,
+ uint32_t size)
{
CirrusVGAState *s = opaque;
unsigned bank_index;
@@ -1964,11 +1966,9 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
uint32_t val;
if ((s->vga.sr[0x07] & 0x01) == 0) {
- return vga_mem_readb(s, addr);
+ return vga_mem_readb(&s->vga, addr);
}
- addr &= 0x1ffff;
-
if (addr < 0x10000) {
/* XXX handle bitblt */
/* video memory */
@@ -2000,28 +2000,10 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr)
return val;
}
-static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-
- v = cirrus_vga_mem_readb(opaque, addr);
- v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
- return v;
-}
-
-static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-
- v = cirrus_vga_mem_readb(opaque, addr);
- v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8;
- v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16;
- v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24;
- return v;
-}
-
-static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t mem_value)
+static void cirrus_vga_mem_write(void *opaque,
+ target_phys_addr_t addr,
+ uint64_t mem_value,
+ uint32_t size)
{
CirrusVGAState *s = opaque;
unsigned bank_index;
@@ -2029,12 +2011,10 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
unsigned mode;
if ((s->vga.sr[0x07] & 0x01) == 0) {
- vga_mem_writeb(s, addr, mem_value);
+ vga_mem_writeb(&s->vga, addr, mem_value);
return;
}
- addr &= 0x1ffff;
-
if (addr < 0x10000) {
if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
/* bitblt */
@@ -2057,8 +2037,7 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
mode = s->vga.gr[0x05] & 0x7;
if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
*(s->vga.vram_ptr + bank_offset) = mem_value;
- cpu_physical_memory_set_dirty(s->vga.vram_offset +
- bank_offset);
+ memory_region_set_dirty(&s->vga.vram, bank_offset);
} else {
if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
cirrus_mem_writeb_mode4and5_8bpp(s, mode,
@@ -2085,30 +2064,14 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr,
}
}
-static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- cirrus_vga_mem_writeb(opaque, addr, val & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = {
- cirrus_vga_mem_readb,
- cirrus_vga_mem_readw,
- cirrus_vga_mem_readl,
-};
-
-static CPUWriteMemoryFunc * const cirrus_vga_mem_write[3] = {
- cirrus_vga_mem_writeb,
- cirrus_vga_mem_writew,
- cirrus_vga_mem_writel,
+static const MemoryRegionOps cirrus_vga_mem_ops = {
+ .read = cirrus_vga_mem_read,
+ .write = cirrus_vga_mem_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
};
/***************************************
@@ -2287,7 +2250,8 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y)
*
***************************************/
-static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_linear_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
CirrusVGAState *s = opaque;
uint32_t ret;
@@ -2315,28 +2279,8 @@ static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr)
return ret;
}
-static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-
- v = cirrus_linear_readb(opaque, addr);
- v |= cirrus_linear_readb(opaque, addr + 1) << 8;
- return v;
-}
-
-static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-
- v = cirrus_linear_readb(opaque, addr);
- v |= cirrus_linear_readb(opaque, addr + 1) << 8;
- v |= cirrus_linear_readb(opaque, addr + 2) << 16;
- v |= cirrus_linear_readb(opaque, addr + 3) << 24;
- return v;
-}
-
-static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void cirrus_linear_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
CirrusVGAState *s = opaque;
unsigned mode;
@@ -2365,7 +2309,7 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
mode = s->vga.gr[0x05] & 0x7;
if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) {
*(s->vga.vram_ptr + addr) = (uint8_t) val;
- cpu_physical_memory_set_dirty(s->vga.vram_offset + addr);
+ memory_region_set_dirty(&s->vga.vram, addr);
} else {
if ((s->vga.gr[0x0B] & 0x14) != 0x14) {
cirrus_mem_writeb_mode4and5_8bpp(s, mode, addr, val);
@@ -2376,35 +2320,6 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr,
}
}
-static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- cirrus_linear_writeb(opaque, addr, val & 0xff);
- cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- cirrus_linear_writeb(opaque, addr, val & 0xff);
- cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-
-static CPUReadMemoryFunc * const cirrus_linear_read[3] = {
- cirrus_linear_readb,
- cirrus_linear_readw,
- cirrus_linear_readl,
-};
-
-static CPUWriteMemoryFunc * const cirrus_linear_write[3] = {
- cirrus_linear_writeb,
- cirrus_linear_writew,
- cirrus_linear_writel,
-};
-
/***************************************
*
* system to screen memory access
@@ -2412,37 +2327,23 @@ static CPUWriteMemoryFunc * const cirrus_linear_write[3] = {
***************************************/
-static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_linear_bitblt_read(void *opaque,
+ target_phys_addr_t addr,
+ unsigned size)
{
+ CirrusVGAState *s = opaque;
uint32_t ret;
/* XXX handle bitblt */
+ (void)s;
ret = 0xff;
return ret;
}
-static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-
- v = cirrus_linear_bitblt_readb(opaque, addr);
- v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
- return v;
-}
-
-static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-
- v = cirrus_linear_bitblt_readb(opaque, addr);
- v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16;
- v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24;
- return v;
-}
-
-static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void cirrus_linear_bitblt_write(void *opaque,
+ target_phys_addr_t addr,
+ uint64_t val,
+ unsigned size)
{
CirrusVGAState *s = opaque;
@@ -2455,83 +2356,70 @@ static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr,
}
}
-static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-
-static CPUReadMemoryFunc * const cirrus_linear_bitblt_read[3] = {
- cirrus_linear_bitblt_readb,
- cirrus_linear_bitblt_readw,
- cirrus_linear_bitblt_readl,
-};
-
-static CPUWriteMemoryFunc * const cirrus_linear_bitblt_write[3] = {
- cirrus_linear_bitblt_writeb,
- cirrus_linear_bitblt_writew,
- cirrus_linear_bitblt_writel,
+static const MemoryRegionOps cirrus_linear_bitblt_io_ops = {
+ .read = cirrus_linear_bitblt_read,
+ .write = cirrus_linear_bitblt_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
};
-static void map_linear_vram(CirrusVGAState *s)
+static void unmap_bank(CirrusVGAState *s, unsigned bank)
{
- if (!s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
- s->vga.map_addr = s->vga.lfb_addr;
- s->vga.map_end = s->vga.lfb_end;
- cpu_register_physical_memory_log(s->vga.map_addr,
- s->vga.map_end - s->vga.map_addr,
- s->vga.vram_offset, 0, true);
+ if (s->cirrus_bank[bank]) {
+ memory_region_del_subregion(&s->low_mem_container,
+ s->cirrus_bank[bank]);
+ memory_region_destroy(s->cirrus_bank[bank]);
+ qemu_free(s->cirrus_bank[bank]);
+ s->cirrus_bank[bank] = NULL;
}
+}
- if (!s->vga.map_addr)
- return;
-
- s->vga.lfb_vram_mapped = 0;
+static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
+{
+ MemoryRegion *mr;
+ static const char *names[] = { "vga.bank0", "vga.bank1" };
if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
&& !((s->vga.sr[0x07] & 0x01) == 0)
&& !((s->vga.gr[0x0B] & 0x14) == 0x14)
&& !(s->vga.gr[0x0B] & 0x02)) {
- cpu_register_physical_memory_log(isa_mem_base + 0xa0000, 0x8000,
- (s->vga.vram_offset +
- s->cirrus_bank_base[0]) |
- IO_MEM_RAM, 0, true);
- cpu_register_physical_memory_log(isa_mem_base + 0xa8000, 0x8000,
- (s->vga.vram_offset +
- s->cirrus_bank_base[1]) |
- IO_MEM_RAM, 0, true);
-
- s->vga.lfb_vram_mapped = 1;
- }
- else {
- cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
- s->vga.vga_io_memory);
+ mr = qemu_malloc(sizeof(*mr));
+ memory_region_init_alias(mr, names[bank], &s->vga.vram,
+ s->cirrus_bank_base[bank], 0x8000);
+ memory_region_add_subregion_overlap(
+ &s->low_mem_container,
+ 0x8000 * bank,
+ mr,
+ 1);
+ unmap_bank(s, bank);
+ s->cirrus_bank[bank] = mr;
+ } else {
+ unmap_bank(s, bank);
}
+}
- vga_dirty_log_start(&s->vga);
+static void map_linear_vram(CirrusVGAState *s)
+{
+ if (!s->linear_vram) {
+ s->linear_vram = true;
+ memory_region_add_subregion_overlap(&s->pci_bar, 0, &s->vga.vram, 1);
+ }
+ map_linear_vram_bank(s, 0);
+ map_linear_vram_bank(s, 1);
}
static void unmap_linear_vram(CirrusVGAState *s)
{
- if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) {
- s->vga.map_addr = s->vga.map_end = 0;
- cpu_register_physical_memory(s->vga.lfb_addr, s->vga.vram_size,
- s->cirrus_linear_io_addr);
+ if (s->linear_vram) {
+ s->linear_vram = false;
+ memory_region_del_subregion(&s->pci_bar, &s->vga.vram);
}
- cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,
- s->vga.vga_io_memory);
+ unmap_bank(s, 0);
+ unmap_bank(s, 1);
}
/* Compute the memory access functions */
@@ -2765,12 +2653,11 @@ static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
*
***************************************/
-static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t cirrus_mmio_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
CirrusVGAState *s = opaque;
- addr &= CIRRUS_PNPMMIO_SIZE - 1;
-
if (addr >= 0x100) {
return cirrus_mmio_blt_read(s, addr - 0x100);
} else {
@@ -2778,33 +2665,11 @@ static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr)
}
}
-static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-
- v = cirrus_mmio_readb(opaque, addr);
- v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
- return v;
-}
-
-static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
-
- v = cirrus_mmio_readb(opaque, addr);
- v |= cirrus_mmio_readb(opaque, addr + 1) << 8;
- v |= cirrus_mmio_readb(opaque, addr + 2) << 16;
- v |= cirrus_mmio_readb(opaque, addr + 3) << 24;
- return v;
-}
-
-static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void cirrus_mmio_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
CirrusVGAState *s = opaque;
- addr &= CIRRUS_PNPMMIO_SIZE - 1;
-
if (addr >= 0x100) {
cirrus_mmio_blt_write(s, addr - 0x100, val);
} else {
@@ -2812,33 +2677,14 @@ static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr,
}
}
-static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- cirrus_mmio_writeb(opaque, addr, val & 0xff);
- cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- cirrus_mmio_writeb(opaque, addr, val & 0xff);
- cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
-
-static CPUReadMemoryFunc * const cirrus_mmio_read[3] = {
- cirrus_mmio_readb,
- cirrus_mmio_readw,
- cirrus_mmio_readl,
-};
-
-static CPUWriteMemoryFunc * const cirrus_mmio_write[3] = {
- cirrus_mmio_writeb,
- cirrus_mmio_writew,
- cirrus_mmio_writel,
+static const MemoryRegionOps cirrus_mmio_io_ops = {
+ .read = cirrus_mmio_read,
+ .write = cirrus_mmio_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
};
/* load/save state */
@@ -2947,6 +2793,16 @@ static void cirrus_reset(void *opaque)
s->cirrus_hidden_dac_data = 0;
}
+static const MemoryRegionOps cirrus_linear_io_ops = {
+ .read = cirrus_linear_read,
+ .write = cirrus_linear_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
+};
+
static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
{
int i;
@@ -2993,28 +2849,33 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
register_ioport_read(0x3ba, 1, 1, cirrus_vga_ioport_read, s);
register_ioport_read(0x3da, 1, 1, cirrus_vga_ioport_read, s);
- s->vga.vga_io_memory = cpu_register_io_memory(cirrus_vga_mem_read,
- cirrus_vga_mem_write, s,
- DEVICE_LITTLE_ENDIAN);
- cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
- s->vga.vga_io_memory);
- qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+ memory_region_init(&s->low_mem_container,
+ "cirrus-lowmem-container",
+ 0x20000);
+
+ memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s,
+ "cirrus-low-memory", 0x20000);
+ memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
+ memory_region_add_subregion_overlap(get_system_memory(),
+ isa_mem_base + 0x000a0000,
+ &s->low_mem_container,
+ 1);
+ memory_region_set_coalescing(&s->low_mem);
/* I/O handler for LFB */
- s->cirrus_linear_io_addr =
- cpu_register_io_memory(cirrus_linear_read, cirrus_linear_write, s,
- DEVICE_LITTLE_ENDIAN);
+ memory_region_init_io(&s->cirrus_linear_io, &cirrus_linear_io_ops, s,
+ "cirrus-linear-io", VGA_RAM_SIZE);
/* I/O handler for LFB */
- s->cirrus_linear_bitblt_io_addr =
- cpu_register_io_memory(cirrus_linear_bitblt_read,
- cirrus_linear_bitblt_write, s,
- DEVICE_LITTLE_ENDIAN);
+ memory_region_init_io(&s->cirrus_linear_bitblt_io,
+ &cirrus_linear_bitblt_io_ops,
+ s,
+ "cirrus-bitblt-mmio",
+ 0x400000);
/* I/O handler for memory-mapped I/O */
- s->cirrus_mmio_io_addr =
- cpu_register_io_memory(cirrus_mmio_read, cirrus_mmio_write, s,
- DEVICE_LITTLE_ENDIAN);
+ memory_region_init_io(&s->cirrus_mmio_io, &cirrus_mmio_io_ops, s,
+ "cirrus-mmio", CIRRUS_PNPMMIO_SIZE);
s->real_vram_size =
(s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024;
@@ -3060,42 +2921,6 @@ void isa_cirrus_vga_init(void)
*
***************************************/
-static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- CirrusVGAState *s = &DO_UPCAST(PCICirrusVGAState, dev, d)->cirrus_vga;
-
- /* XXX: add byte swapping apertures */
- cpu_register_physical_memory(addr, s->vga.vram_size,
- s->cirrus_linear_io_addr);
- cpu_register_physical_memory(addr + 0x1000000, 0x400000,
- s->cirrus_linear_bitblt_io_addr);
-
- s->vga.map_addr = s->vga.map_end = 0;
- s->vga.lfb_addr = addr & TARGET_PAGE_MASK;
- s->vga.lfb_end = ((addr + VGA_RAM_SIZE) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
- /* account for overflow */
- if (s->vga.lfb_end < addr + VGA_RAM_SIZE)
- s->vga.lfb_end = addr + VGA_RAM_SIZE;
-
- vga_dirty_log_start(&s->vga);
-}
-
-static void pci_cirrus_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- PCICirrusVGAState *pvs = DO_UPCAST(PCICirrusVGAState, dev, d);
- CirrusVGAState *s = &pvs->cirrus_vga;
-
- pci_default_write_config(d, address, val, len);
- if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED) {
- s->vga.map_addr = 0;
- s->vga.lfb_addr = 0;
- s->vga.lfb_end = 0;
- }
- cirrus_update_memory_access(s);
-}
-
static int pci_cirrus_vga_initfn(PCIDevice *dev)
{
PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
@@ -3112,15 +2937,20 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
/* setup PCI */
+ memory_region_init(&s->pci_bar, "cirrus-pci-bar0", 0x2000000);
+
+ /* XXX: add byte swapping apertures */
+ memory_region_add_subregion(&s->pci_bar, 0, &s->cirrus_linear_io);
+ memory_region_add_subregion(&s->pci_bar, 0x1000000,
+ &s->cirrus_linear_bitblt_io);
+
/* setup memory space */
/* memory #0 LFB */
/* memory #1 memory-mapped I/O */
/* XXX: s->vga.vram_size must be a power of two */
- pci_register_bar(&d->dev, 0, 0x2000000,
- PCI_BASE_ADDRESS_MEM_PREFETCH, cirrus_pci_lfb_map);
+ pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->pci_bar);
if (device_id == CIRRUS_ID_CLGD5446) {
- pci_register_bar_simple(&d->dev, 1, CIRRUS_PNPMMIO_SIZE, 0,
- s->cirrus_mmio_io_addr);
+ pci_register_bar(&d->dev, 1, 0, &s->cirrus_mmio_io);
}
return 0;
}
@@ -3138,7 +2968,6 @@ static PCIDeviceInfo cirrus_vga_info = {
.no_hotplug = 1,
.init = pci_cirrus_vga_initfn,
.romfile = VGABIOS_CIRRUS_FILENAME,
- .config_write = pci_cirrus_write_config,
.vendor_id = PCI_VENDOR_ID_CIRRUS,
.device_id = CIRRUS_ID_CLGD5446,
.class_id = PCI_CLASS_DISPLAY_VGA,
diff --git a/hw/cris_pic_cpu.c b/hw/cris_pic_cpu.c
index a92d445f29..7f1e4ab855 100644
--- a/hw/cris_pic_cpu.c
+++ b/hw/cris_pic_cpu.c
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
+#include "sysbus.h"
#include "hw.h"
#include "pc.h"
#include "etraxfs.h"
diff --git a/hw/cuda.c b/hw/cuda.c
index 065c362aef..5c92d81b4b 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -117,6 +117,7 @@ typedef struct CUDATimer {
} CUDATimer;
typedef struct CUDAState {
+ MemoryRegion mem;
/* cuda registers */
uint8_t b; /* B-side data */
uint8_t a; /* A-side data */
@@ -722,7 +723,7 @@ static void cuda_reset(void *opaque)
set_counter(s, &s->timers[1], 0xffff);
}
-void cuda_init (int *cuda_mem_index, qemu_irq irq)
+void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq)
{
struct tm tm;
CUDAState *s = &cuda_state;
@@ -738,8 +739,9 @@ void cuda_init (int *cuda_mem_index, qemu_irq irq)
s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
- *cuda_mem_index = cpu_register_io_memory(cuda_read, cuda_write, s,
+ cpu_register_io_memory(cuda_read, cuda_write, s,
DEVICE_NATIVE_ENDIAN);
+ *cuda_mem = &s->mem;
vmstate_register(NULL, -1, &vmstate_cuda, s);
qemu_register_reset(cuda_reset, s);
}
diff --git a/hw/e1000.c b/hw/e1000.c
index 96d84f91ae..29b453f7b1 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -82,7 +82,8 @@ typedef struct E1000State_st {
PCIDevice dev;
NICState *nic;
NICConf conf;
- int mmio_index;
+ MemoryRegion mmio;
+ MemoryRegion io;
uint32_t mac_reg[0x8000];
uint16_t phy_reg[0x20];
@@ -151,14 +152,6 @@ static const char phy_regcap[0x20] = {
};
static void
-ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr,
- pcibus_t size, int type)
-{
- DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS
- " size=0x%08"FMT_PCIBUS"\n", addr, size);
-}
-
-static void
set_interrupt_cause(E1000State *s, int index, uint32_t val)
{
if (val)
@@ -905,7 +898,8 @@ static void (*macreg_writeops[])(E1000State *, int, uint32_t) = {
enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) };
static void
-e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+e1000_mmio_write(void *opaque, target_phys_addr_t addr, uint64_t val,
+ unsigned size)
{
E1000State *s = opaque;
unsigned int index = (addr & 0x1ffff) >> 2;
@@ -913,31 +907,15 @@ e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
if (index < NWRITEOPS && macreg_writeops[index]) {
macreg_writeops[index](s, index, val);
} else if (index < NREADOPS && macreg_readops[index]) {
- DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04x\n", index<<2, val);
+ DBGOUT(MMIO, "e1000_mmio_writel RO %x: 0x%04"PRIx64"\n", index<<2, val);
} else {
- DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08x\n",
+ DBGOUT(UNKNOWN, "MMIO unknown write addr=0x%08x,val=0x%08"PRIx64"\n",
index<<2, val);
}
}
-static void
-e1000_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- // emulate hw without byte enables: no RMW
- e1000_mmio_writel(opaque, addr & ~3,
- (val & 0xffff) << (8*(addr & 3)));
-}
-
-static void
-e1000_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- // emulate hw without byte enables: no RMW
- e1000_mmio_writel(opaque, addr & ~3,
- (val & 0xff) << (8*(addr & 3)));
-}
-
-static uint32_t
-e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t
+e1000_mmio_read(void *opaque, target_phys_addr_t addr, unsigned size)
{
E1000State *s = opaque;
unsigned int index = (addr & 0x1ffff) >> 2;
@@ -950,20 +928,39 @@ e1000_mmio_readl(void *opaque, target_phys_addr_t addr)
return 0;
}
-static uint32_t
-e1000_mmio_readb(void *opaque, target_phys_addr_t addr)
+static const MemoryRegionOps e1000_mmio_ops = {
+ .read = e1000_mmio_read,
+ .write = e1000_mmio_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
+
+static uint64_t e1000_io_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
- return ((e1000_mmio_readl(opaque, addr & ~3)) >>
- (8 * (addr & 3))) & 0xff;
+ E1000State *s = opaque;
+
+ (void)s;
+ return 0;
}
-static uint32_t
-e1000_mmio_readw(void *opaque, target_phys_addr_t addr)
+static void e1000_io_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
- return ((e1000_mmio_readl(opaque, addr & ~3)) >>
- (8 * (addr & 3))) & 0xffff;
+ E1000State *s = opaque;
+
+ (void)s;
}
+static const MemoryRegionOps e1000_io_ops = {
+ .read = e1000_io_read,
+ .write = e1000_io_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
static bool is_version_1(void *opaque, int version_id)
{
return version_id == 1;
@@ -1083,36 +1080,22 @@ static const uint32_t mac_reg_init[] = {
/* PCI interface */
-static CPUWriteMemoryFunc * const e1000_mmio_write[] = {
- e1000_mmio_writeb, e1000_mmio_writew, e1000_mmio_writel
-};
-
-static CPUReadMemoryFunc * const e1000_mmio_read[] = {
- e1000_mmio_readb, e1000_mmio_readw, e1000_mmio_readl
-};
-
static void
-e1000_mmio_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+e1000_mmio_setup(E1000State *d)
{
- E1000State *d = DO_UPCAST(E1000State, dev, pci_dev);
int i;
const uint32_t excluded_regs[] = {
E1000_MDIC, E1000_ICR, E1000_ICS, E1000_IMS,
E1000_IMC, E1000_TCTL, E1000_TDT, PNPMMIO_SIZE
};
-
- DBGOUT(MMIO, "e1000_mmio_map addr=0x%08"FMT_PCIBUS" 0x%08"FMT_PCIBUS"\n",
- addr, size);
-
- cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index);
- qemu_register_coalesced_mmio(addr, excluded_regs[0]);
-
+ memory_region_init_io(&d->mmio, &e1000_mmio_ops, d, "e1000-mmio",
+ PNPMMIO_SIZE);
+ memory_region_add_coalescing(&d->mmio, 0, excluded_regs[0]);
for (i = 0; excluded_regs[i] != PNPMMIO_SIZE; i++)
- qemu_register_coalesced_mmio(addr + excluded_regs[i] + 4,
- excluded_regs[i + 1] -
- excluded_regs[i] - 4);
+ memory_region_add_coalescing(&d->mmio, excluded_regs[i] + 4,
+ excluded_regs[i+1] - excluded_regs[i] - 4);
+ memory_region_init_io(&d->io, &e1000_io_ops, d, "e1000-io", IOPORT_SIZE);
}
static void
@@ -1128,7 +1111,8 @@ pci_e1000_uninit(PCIDevice *dev)
{
E1000State *d = DO_UPCAST(E1000State, dev, dev);
- cpu_unregister_io_memory(d->mmio_index);
+ memory_region_destroy(&d->mmio);
+ memory_region_destroy(&d->io);
qemu_del_vlan_client(&d->nic->nc);
return 0;
}
@@ -1172,14 +1156,11 @@ static int pci_e1000_init(PCIDevice *pci_dev)
/* TODO: RST# value should be 0 if programmable, PCI spec 6.2.4 */
pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
- d->mmio_index = cpu_register_io_memory(e1000_mmio_read,
- e1000_mmio_write, d, DEVICE_LITTLE_ENDIAN);
+ e1000_mmio_setup(d);
- pci_register_bar(&d->dev, 0, PNPMMIO_SIZE,
- PCI_BASE_ADDRESS_SPACE_MEMORY, e1000_mmio_map);
+ pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
- pci_register_bar(&d->dev, 1, IOPORT_SIZE,
- PCI_BASE_ADDRESS_SPACE_IO, ioport_map);
+ pci_register_bar(&d->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->io);
memmove(d->eeprom_data, e1000_eeprom_template,
sizeof e1000_eeprom_template);
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 9b6f4a5cd8..a636d309be 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -228,13 +228,14 @@ typedef struct {
PCIDevice dev;
/* Hash register (multicast mask array, multiple individual addresses). */
uint8_t mult[8];
- int mmio_index;
+ MemoryRegion mmio_bar;
+ MemoryRegion io_bar;
+ MemoryRegion flash_bar;
NICState *nic;
NICConf conf;
uint8_t scb_stat; /* SCB stat/ack byte */
uint8_t int_stat; /* PCI interrupt status */
/* region must not be saved by nic_save. */
- uint32_t region1; /* PCI region 1 address */
uint16_t mdimem[32];
eeprom_t *eeprom;
uint32_t device; /* device variant */
@@ -1584,147 +1585,36 @@ static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
}
}
-/*****************************************************************************
- *
- * Port mapped I/O.
- *
- ****************************************************************************/
-
-static uint32_t ioport_read1(void *opaque, uint32_t addr)
-{
- EEPRO100State *s = opaque;
-#if 0
- logout("addr=%s\n", regname(addr));
-#endif
- return eepro100_read1(s, addr - s->region1);
-}
-
-static uint32_t ioport_read2(void *opaque, uint32_t addr)
-{
- EEPRO100State *s = opaque;
- return eepro100_read2(s, addr - s->region1);
-}
-
-static uint32_t ioport_read4(void *opaque, uint32_t addr)
-{
- EEPRO100State *s = opaque;
- return eepro100_read4(s, addr - s->region1);
-}
-
-static void ioport_write1(void *opaque, uint32_t addr, uint32_t val)
-{
- EEPRO100State *s = opaque;
-#if 0
- logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
- eepro100_write1(s, addr - s->region1, val);
-}
-
-static void ioport_write2(void *opaque, uint32_t addr, uint32_t val)
-{
- EEPRO100State *s = opaque;
- eepro100_write2(s, addr - s->region1, val);
-}
-
-static void ioport_write4(void *opaque, uint32_t addr, uint32_t val)
-{
- EEPRO100State *s = opaque;
- eepro100_write4(s, addr - s->region1, val);
-}
-
-/***********************************************************/
-/* PCI EEPRO100 definitions */
-
-static void pci_map(PCIDevice * pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
-
- TRACE(OTHER, logout("region %d, addr=0x%08"FMT_PCIBUS", "
- "size=0x%08"FMT_PCIBUS", type=%d\n",
- region_num, addr, size, type));
-
- assert(region_num == 1);
- register_ioport_write(addr, size, 1, ioport_write1, s);
- register_ioport_read(addr, size, 1, ioport_read1, s);
- register_ioport_write(addr, size, 2, ioport_write2, s);
- register_ioport_read(addr, size, 2, ioport_read2, s);
- register_ioport_write(addr, size, 4, ioport_write4, s);
- register_ioport_read(addr, size, 4, ioport_read4, s);
-
- s->region1 = addr;
-}
-
-/*****************************************************************************
- *
- * Memory mapped I/O.
- *
- ****************************************************************************/
-
-static void pci_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- EEPRO100State *s = opaque;
-#if 0
- logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
- eepro100_write1(s, addr, val);
-}
-
-static void pci_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
+static uint64_t eepro100_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
EEPRO100State *s = opaque;
-#if 0
- logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
- eepro100_write2(s, addr, val);
-}
-static void pci_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- EEPRO100State *s = opaque;
-#if 0
- logout("addr=%s val=0x%02x\n", regname(addr), val);
-#endif
- eepro100_write4(s, addr, val);
-}
-
-static uint32_t pci_mmio_readb(void *opaque, target_phys_addr_t addr)
-{
- EEPRO100State *s = opaque;
-#if 0
- logout("addr=%s\n", regname(addr));
-#endif
- return eepro100_read1(s, addr);
+ switch (size) {
+ case 1: return eepro100_read1(s, addr);
+ case 2: return eepro100_read2(s, addr);
+ case 4: return eepro100_read4(s, addr);
+ default: abort();
+ }
}
-static uint32_t pci_mmio_readw(void *opaque, target_phys_addr_t addr)
+static void eepro100_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
{
EEPRO100State *s = opaque;
-#if 0
- logout("addr=%s\n", regname(addr));
-#endif
- return eepro100_read2(s, addr);
-}
-static uint32_t pci_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- EEPRO100State *s = opaque;
-#if 0
- logout("addr=%s\n", regname(addr));
-#endif
- return eepro100_read4(s, addr);
+ switch (size) {
+ case 1: return eepro100_write1(s, addr, data);
+ case 2: return eepro100_write2(s, addr, data);
+ case 4: return eepro100_write4(s, addr, data);
+ default: abort();
+ }
}
-static CPUWriteMemoryFunc * const pci_mmio_write[] = {
- pci_mmio_writeb,
- pci_mmio_writew,
- pci_mmio_writel
-};
-
-static CPUReadMemoryFunc * const pci_mmio_read[] = {
- pci_mmio_readb,
- pci_mmio_readw,
- pci_mmio_readl
+static const MemoryRegionOps eepro100_ops = {
+ .read = eepro100_read,
+ .write = eepro100_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
static int nic_can_receive(VLANClientState *nc)
@@ -1953,7 +1843,9 @@ static int pci_nic_uninit(PCIDevice *pci_dev)
{
EEPRO100State *s = DO_UPCAST(EEPRO100State, dev, pci_dev);
- cpu_unregister_io_memory(s->mmio_index);
+ memory_region_destroy(&s->mmio_bar);
+ memory_region_destroy(&s->io_bar);
+ memory_region_destroy(&s->flash_bar);
vmstate_unregister(&pci_dev->qdev, s->vmstate, s);
eeprom93xx_free(&pci_dev->qdev, s->eeprom);
qemu_del_vlan_client(&s->nic->nc);
@@ -1985,20 +1877,19 @@ static int e100_nic_init(PCIDevice *pci_dev)
s->eeprom = eeprom93xx_new(&pci_dev->qdev, EEPROM_SIZE);
/* Handler for memory-mapped I/O */
- s->mmio_index =
- cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s,
- DEVICE_LITTLE_ENDIAN);
-
- pci_register_bar_simple(&s->dev, 0, PCI_MEM_SIZE,
- PCI_BASE_ADDRESS_MEM_PREFETCH, s->mmio_index);
-
- pci_register_bar(&s->dev, 1, PCI_IO_SIZE, PCI_BASE_ADDRESS_SPACE_IO,
- pci_map);
- pci_register_bar_simple(&s->dev, 2, PCI_FLASH_SIZE, 0, s->mmio_index);
+ memory_region_init_io(&s->mmio_bar, &eepro100_ops, s, "eepro100-mmio",
+ PCI_MEM_SIZE);
+ pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->mmio_bar);
+ memory_region_init_io(&s->io_bar, &eepro100_ops, s, "eepro100-io",
+ PCI_IO_SIZE);
+ pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
+ /* FIXME: flash aliases to mmio?! */
+ memory_region_init_io(&s->flash_bar, &eepro100_ops, s, "eepro100-flash",
+ PCI_FLASH_SIZE);
+ pci_register_bar(&s->dev, 2, 0, &s->flash_bar);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
logout("macaddr: %s\n", nic_dump(&s->conf.macaddr.a[0], 6));
- assert(s->region1 == 0);
nic_reset(s);
diff --git a/hw/es1370.c b/hw/es1370.c
index 1ed62b7da3..a9387d15cc 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -268,6 +268,7 @@ struct chan {
typedef struct ES1370State {
PCIDevice dev;
QEMUSoundCard card;
+ MemoryRegion io;
struct chan chan[NB_CHANNELS];
SWVoiceOut *dac_voice[2];
SWVoiceIn *adc_voice;
@@ -775,7 +776,6 @@ IO_READ_PROTO (es1370_readl)
return val;
}
-
static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
int max, int *irq)
{
@@ -906,23 +906,20 @@ static void es1370_adc_callback (void *opaque, int avail)
es1370_run_channel (s, ADC_CHANNEL, avail);
}
-static void es1370_map (PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- ES1370State *s = DO_UPCAST (ES1370State, dev, pci_dev);
-
- (void) region_num;
- (void) size;
- (void) type;
-
- register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s);
- register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s);
- register_ioport_write (addr, 0x40, 4, es1370_writel, s);
+static const MemoryRegionPortio es1370_portio[] = {
+ { 0, 0x40 * 4, 1, .write = es1370_writeb, },
+ { 0, 0x40 * 2, 2, .write = es1370_writew, },
+ { 0, 0x40, 4, .write = es1370_writel, },
+ { 0, 0x40 * 4, 1, .read = es1370_readb, },
+ { 0, 0x40 * 2, 2, .read = es1370_readw, },
+ { 0, 0x40, 4, .read = es1370_readl, },
+ PORTIO_END_OF_LIST()
+};
- register_ioport_read (addr, 0x40 * 4, 1, es1370_readb, s);
- register_ioport_read (addr, 0x40 * 2, 2, es1370_readw, s);
- register_ioport_read (addr, 0x40, 4, es1370_readl, s);
-}
+static const MemoryRegionOps es1370_io_ops = {
+ .old_portio = es1370_portio,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
static const VMStateDescription vmstate_es1370_channel = {
.name = "es1370_channel",
@@ -1011,7 +1008,8 @@ static int es1370_initfn (PCIDevice *dev)
c[PCI_MIN_GNT] = 0x0c;
c[PCI_MAX_LAT] = 0x80;
- pci_register_bar (&s->dev, 0, 256, PCI_BASE_ADDRESS_SPACE_IO, es1370_map);
+ memory_region_init_io (&s->io, &es1370_io_ops, s, "es1370", 256);
+ pci_register_bar (&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
qemu_register_reset (es1370_on_reset, s);
AUD_register_card ("es1370", &s->card);
@@ -1019,6 +1017,14 @@ static int es1370_initfn (PCIDevice *dev)
return 0;
}
+static int es1370_exitfn(PCIDevice *dev)
+{
+ ES1370State *s = DO_UPCAST (ES1370State, dev, dev);
+
+ memory_region_destroy (&s->io);
+ return 0;
+}
+
int es1370_init (PCIBus *bus)
{
pci_create_simple (bus, -1, "ES1370");
@@ -1031,6 +1037,7 @@ static PCIDeviceInfo es1370_info = {
.qdev.size = sizeof (ES1370State),
.qdev.vmsd = &vmstate_es1370,
.init = es1370_initfn,
+ .exit = es1370_exitfn,
.vendor_id = PCI_VENDOR_ID_ENSONIQ,
.device_id = PCI_DEVICE_ID_ENSONIQ_ES1370,
.class_id = PCI_CLASS_MULTIMEDIA_AUDIO,
diff --git a/hw/escc.c b/hw/escc.c
index f6fd9192ea..bea5873a02 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -126,7 +126,7 @@ struct SerialState {
SysBusDevice busdev;
struct ChannelState chn[2];
uint32_t it_shift;
- int mmio_index;
+ MemoryRegion mmio;
uint32_t disabled;
uint32_t frequency;
};
@@ -490,7 +490,8 @@ static void escc_update_parameters(ChannelState *s)
qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
}
-static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void escc_mem_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
SerialState *serial = opaque;
ChannelState *s;
@@ -592,7 +593,8 @@ static void escc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
}
}
-static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
SerialState *serial = opaque;
ChannelState *s;
@@ -627,6 +629,16 @@ static uint32_t escc_mem_readb(void *opaque, target_phys_addr_t addr)
return 0;
}
+static const MemoryRegionOps escc_mem_ops = {
+ .read = escc_mem_read,
+ .write = escc_mem_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
+};
+
static int serial_can_receive(void *opaque)
{
ChannelState *s = opaque;
@@ -668,18 +680,6 @@ static void serial_event(void *opaque, int event)
serial_receive_break(s);
}
-static CPUReadMemoryFunc * const escc_mem_read[3] = {
- escc_mem_readb,
- NULL,
- NULL,
-};
-
-static CPUWriteMemoryFunc * const escc_mem_write[3] = {
- escc_mem_writeb,
- NULL,
- NULL,
-};
-
static const VMStateDescription vmstate_escc_chn = {
.name ="escc_chn",
.version_id = 2,
@@ -712,7 +712,7 @@ static const VMStateDescription vmstate_escc = {
}
};
-int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
+MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
CharDriverState *chrA, CharDriverState *chrB,
int clock, int it_shift)
{
@@ -737,7 +737,7 @@ int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
}
d = FROM_SYSBUS(SerialState, s);
- return d->mmio_index;
+ return &d->mmio;
}
static const uint8_t keycodes[128] = {
@@ -901,7 +901,6 @@ void slavio_serial_ms_kbd_init(target_phys_addr_t base, qemu_irq irq,
static int escc_init1(SysBusDevice *dev)
{
SerialState *s = FROM_SYSBUS(SerialState, dev);
- int io;
unsigned int i;
s->chn[0].disabled = s->disabled;
@@ -918,10 +917,9 @@ static int escc_init1(SysBusDevice *dev)
s->chn[0].otherchn = &s->chn[1];
s->chn[1].otherchn = &s->chn[0];
- io = cpu_register_io_memory(escc_mem_read, escc_mem_write, s,
- DEVICE_NATIVE_ENDIAN);
- sysbus_init_mmio(dev, ESCC_SIZE << s->it_shift, io);
- s->mmio_index = io;
+ memory_region_init_io(&s->mmio, &escc_mem_ops, s, "escc",
+ ESCC_SIZE << s->it_shift);
+ sysbus_init_mmio_region(dev, &s->mmio);
if (s->chn[0].type == mouse) {
qemu_add_mouse_event_handler(sunmouse_event, &s->chn[0], 0,
diff --git a/hw/escc.h b/hw/escc.h
index 015b9d0089..d1da46fd06 100644
--- a/hw/escc.h
+++ b/hw/escc.h
@@ -1,6 +1,6 @@
/* escc.c */
#define ESCC_SIZE 4
-int escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
+MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,
CharDriverState *chrA, CharDriverState *chrB,
int clock, int it_shift);
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
deleted file mode 100644
index b84d74a11e..0000000000
--- a/hw/etraxfs.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * QEMU ETRAX System Emulator
- *
- * Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "sysbus.h"
-#include "boards.h"
-#include "net.h"
-#include "flash.h"
-#include "etraxfs.h"
-#include "loader.h"
-#include "elf.h"
-#include "cris-boot.h"
-#include "blockdev.h"
-
-#define FLASH_SIZE 0x2000000
-#define INTMEM_SIZE (128 * 1024)
-
-static struct cris_load_info li;
-
-static void flash_cpu_reset(void *opaque)
-{
- CPUState *env = opaque;
- cpu_reset(env);
-}
-
-static
-void bareetraxfs_init (ram_addr_t ram_size,
- const char *boot_device,
- const char *kernel_filename, const char *kernel_cmdline,
- const char *initrd_filename, const char *cpu_model)
-{
- DeviceState *dev;
- SysBusDevice *s;
- CPUState *env;
- qemu_irq irq[30], nmi[2], *cpu_irq;
- void *etraxfs_dmac;
- struct etraxfs_dma_client *eth[2] = {NULL, NULL};
- DriveInfo *dinfo;
- int i;
- ram_addr_t phys_ram;
- ram_addr_t phys_flash;
- ram_addr_t phys_intmem;
-
- /* init CPUs */
- if (cpu_model == NULL) {
- cpu_model = "crisv32";
- }
- env = cpu_init(cpu_model);
-
- /* allocate RAM */
- phys_ram = qemu_ram_alloc(NULL, "etraxfs.ram", ram_size);
- cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM);
-
- /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the
- internal memory. */
- phys_intmem = qemu_ram_alloc(NULL, "etraxfs.chipram", INTMEM_SIZE);
- cpu_register_physical_memory(0x38000000, INTMEM_SIZE,
- phys_intmem | IO_MEM_RAM);
-
-
- phys_flash = qemu_ram_alloc(NULL, "etraxfs.flash", FLASH_SIZE);
- dinfo = drive_get(IF_PFLASH, 0, 0);
- pflash_cfi02_register(0x0, phys_flash,
- dinfo ? dinfo->bdrv : NULL, (64 * 1024),
- FLASH_SIZE >> 16,
- 1, 2, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x555, 0x2aa, 0);
- cpu_irq = cris_pic_init_cpu(env);
- dev = qdev_create(NULL, "etraxfs,pic");
- /* FIXME: Is there a proper way to signal vectors to the CPU core? */
- qdev_prop_set_ptr(dev, "interrupt_vector", &env->interrupt_vector);
- qdev_init_nofail(dev);
- s = sysbus_from_qdev(dev);
- sysbus_mmio_map(s, 0, 0x3001c000);
- sysbus_connect_irq(s, 0, cpu_irq[0]);
- sysbus_connect_irq(s, 1, cpu_irq[1]);
- for (i = 0; i < 30; i++) {
- irq[i] = qdev_get_gpio_in(dev, i);
- }
- nmi[0] = qdev_get_gpio_in(dev, 30);
- nmi[1] = qdev_get_gpio_in(dev, 31);
-
- etraxfs_dmac = etraxfs_dmac_init(0x30000000, 10);
- for (i = 0; i < 10; i++) {
- /* On ETRAX, odd numbered channels are inputs. */
- etraxfs_dmac_connect(etraxfs_dmac, i, irq + 7 + i, i & 1);
- }
-
- /* Add the two ethernet blocks. */
- eth[0] = etraxfs_eth_init(&nd_table[0], 0x30034000, 1);
- if (nb_nics > 1)
- eth[1] = etraxfs_eth_init(&nd_table[1], 0x30036000, 2);
-
- /* The DMA Connector block is missing, hardwire things for now. */
- etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]);
- etraxfs_dmac_connect_client(etraxfs_dmac, 1, eth[0] + 1);
- if (eth[1]) {
- etraxfs_dmac_connect_client(etraxfs_dmac, 6, eth[1]);
- etraxfs_dmac_connect_client(etraxfs_dmac, 7, eth[1] + 1);
- }
-
- /* 2 timers. */
- sysbus_create_varargs("etraxfs,timer", 0x3001e000, irq[0x1b], nmi[1], NULL);
- sysbus_create_varargs("etraxfs,timer", 0x3005e000, irq[0x1b], nmi[1], NULL);
-
- for (i = 0; i < 4; i++) {
- sysbus_create_simple("etraxfs,serial", 0x30026000 + i * 0x2000,
- irq[0x14 + i]);
- }
-
- if (kernel_filename) {
- li.image_filename = kernel_filename;
- li.cmdline = kernel_cmdline;
- cris_load_image(env, &li);
- } else {
- if (!dinfo) {
- fprintf(stderr,
- "Provide a kernel image or a flash image to boot from.\n");
- exit(1);
- }
-
- /* Nothing more to do for flash images, those boot from addr 0. */
- qemu_register_reset(flash_cpu_reset, env);
- }
-}
-
-static QEMUMachine bareetraxfs_machine = {
- .name = "bareetraxfs",
- .desc = "Bare ETRAX FS board",
- .init = bareetraxfs_init,
- .is_default = 1,
-};
-
-static void bareetraxfs_machine_init(void)
-{
- qemu_register_machine(&bareetraxfs_machine);
-}
-
-machine_init(bareetraxfs_machine_init);
diff --git a/hw/etraxfs.h b/hw/etraxfs.h
index 01fb9d3e82..1554b0b8e8 100644
--- a/hw/etraxfs.h
+++ b/hw/etraxfs.h
@@ -25,4 +25,21 @@
#include "etraxfs_dma.h"
qemu_irq *cris_pic_init_cpu(CPUState *env);
-void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr);
+
+/* Instantiate an ETRAXFS Ethernet MAC. */
+static inline DeviceState *
+etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr,
+ void *dma_out, void *dma_in)
+{
+ DeviceState *dev;
+ qemu_check_nic_model(nd, "fseth");
+
+ dev = qdev_create(NULL, "etraxfs-eth");
+ qdev_set_nic_properties(dev, nd);
+ qdev_prop_set_uint32(dev, "phyaddr", phyaddr);
+ qdev_prop_set_ptr(dev, "dma_out", dma_out);
+ qdev_prop_set_ptr(dev, "dma_in", dma_in);
+ qdev_init_nofail(dev);
+ sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+ return dev;
+}
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index dff5f55f33..92d4ecac8f 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -23,7 +23,7 @@
*/
#include <stdio.h>
-#include "hw.h"
+#include "sysbus.h"
#include "net.h"
#include "etraxfs.h"
@@ -319,6 +319,7 @@ static void mdio_cycle(struct qemu_mdio *bus)
struct fs_eth
{
+ SysBusDevice busdev;
NICState *nic;
NICConf conf;
int ethregs;
@@ -327,8 +328,14 @@ struct fs_eth
uint8_t macaddr[2][6];
uint32_t regs[FS_ETH_MAX_REGS];
- struct etraxfs_dma_client *dma_out;
- struct etraxfs_dma_client *dma_in;
+ union {
+ void *vdma_out;
+ struct etraxfs_dma_client *dma_out;
+ };
+ union {
+ void *vdma_in;
+ struct etraxfs_dma_client *dma_in;
+ };
/* MDIO bus. */
struct qemu_mdio mdio_bus;
@@ -562,7 +569,11 @@ static void eth_cleanup(VLANClientState *nc)
cpu_unregister_io_memory(eth->ethregs);
- qemu_free(eth->dma_out);
+ /* Disconnect the client. */
+ eth->dma_out->client.push = NULL;
+ eth->dma_out->client.opaque = NULL;
+ eth->dma_in->client.opaque = NULL;
+ eth->dma_in->client.pull = NULL;
qemu_free(eth);
}
@@ -575,39 +586,50 @@ static NetClientInfo net_etraxfs_info = {
.link_status_changed = eth_set_link,
};
-void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr)
+static int fs_eth_init(SysBusDevice *dev)
{
- struct etraxfs_dma_client *dma = NULL;
- struct fs_eth *eth = NULL;
+ struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev);
+ int eth_regs;
- qemu_check_nic_model(nd, "fseth");
-
- dma = qemu_mallocz(sizeof *dma * 2);
- eth = qemu_mallocz(sizeof *eth);
-
- dma[0].client.push = eth_tx_push;
- dma[0].client.opaque = eth;
- dma[1].client.opaque = eth;
- dma[1].client.pull = NULL;
+ if (!s->dma_out || !s->dma_in) {
+ hw_error("Unconnected ETRAX-FS Ethernet MAC.\n");
+ }
- eth->dma_out = dma;
- eth->dma_in = dma + 1;
+ s->dma_out->client.push = eth_tx_push;
+ s->dma_out->client.opaque = s;
+ s->dma_in->client.opaque = s;
+ s->dma_in->client.pull = NULL;
- /* Connect the phy. */
- eth->phyaddr = phyaddr & 0x1f;
- tdk_init(&eth->phy);
- mdio_attach(&eth->mdio_bus, &eth->phy, eth->phyaddr);
+ eth_regs = cpu_register_io_memory(eth_read, eth_write, s,
+ DEVICE_LITTLE_ENDIAN);
+ sysbus_init_mmio(dev, 0x5c, eth_regs);
- eth->ethregs = cpu_register_io_memory(eth_read, eth_write, eth,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory (base, 0x5c, eth->ethregs);
+ qemu_macaddr_default_if_unset(&s->conf.macaddr);
+ s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf,
+ dev->qdev.info->name, dev->qdev.id, s);
+ qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
- eth->conf.macaddr = nd->macaddr;
- eth->conf.vlan = nd->vlan;
- eth->conf.peer = nd->netdev;
+ tdk_init(&s->phy);
+ mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr);
+ return 0;
+}
- eth->nic = qemu_new_nic(&net_etraxfs_info, &eth->conf,
- nd->model, nd->name, eth);
+static SysBusDeviceInfo etraxfs_eth_info = {
+ .init = fs_eth_init,
+ .qdev.name = "etraxfs-eth",
+ .qdev.size = sizeof(struct fs_eth),
+ .qdev.props = (Property[]) {
+ DEFINE_PROP_UINT32("phyaddr", struct fs_eth, phyaddr, 1),
+ DEFINE_PROP_PTR("dma_out", struct fs_eth, vdma_out),
+ DEFINE_PROP_PTR("dma_in", struct fs_eth, vdma_in),
+ DEFINE_NIC_PROPERTIES(struct fs_eth, conf),
+ DEFINE_PROP_END_OF_LIST(),
+ }
+};
- return dma;
+static void etraxfs_eth_register(void)
+{
+ sysbus_register_withprop(&etraxfs_eth_info);
}
+
+device_init(etraxfs_eth_register)
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index b917d4db11..28b86ea2d4 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -24,6 +24,7 @@
#include "sysbus.h"
#include "qemu-char.h"
+#include "qemu-log.h"
#define D(x)
@@ -100,7 +101,7 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
break;
default:
r = s->regs[addr];
- D(printf ("%s " TARGET_FMT_plx "=%x\n", __func__, addr, r));
+ D(qemu_log("%s " TARGET_FMT_plx "=%x\n", __func__, addr, r));
break;
}
return r;
@@ -113,7 +114,7 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
unsigned char ch = value;
D(CPUState *env = s->env);
- D(printf ("%s " TARGET_FMT_plx "=%x\n", __func__, addr, value));
+ D(qemu_log("%s " TARGET_FMT_plx "=%x\n", __func__, addr, value));
addr >>= 2;
switch (addr)
{
@@ -127,7 +128,8 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
if (s->pending_tx) {
value &= ~1;
s->pending_tx = 0;
- D(printf("fixedup value=%x r_intr=%x\n", value, s->regs[R_INTR]));
+ D(qemu_log("fixedup value=%x r_intr=%x\n",
+ value, s->regs[R_INTR]));
}
s->regs[addr] = value;
s->regs[R_INTR] &= ~value;
@@ -157,7 +159,7 @@ static void serial_receive(void *opaque, const uint8_t *buf, int size)
/* Got a byte. */
if (s->rx_fifo_len >= 16) {
- printf("WARNING: UART dropped char.\n");
+ qemu_log("WARNING: UART dropped char.\n");
return;
}
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index da67cf9b38..9a823e1c06 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -62,7 +62,8 @@ static void pci_grackle_reset(void *opaque)
}
PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
- MemoryRegion *address_space)
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io)
{
DeviceState *dev;
SysBusDevice *s;
@@ -75,7 +76,10 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
pci_grackle_set_irq,
pci_grackle_map_irq,
- pic, address_space, 0, 4);
+ pic,
+ address_space_mem,
+ address_space_io,
+ 0, 4);
pci_create_simple(d->host_state.bus, 0, "grackle");
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 65e63ddab8..d5415580e4 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1093,7 +1093,9 @@ PCIBus *gt64120_register(qemu_irq *pic)
d = FROM_SYSBUS(GT64120State, s);
d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci",
gt64120_pci_set_irq, gt64120_pci_map_irq,
- pic, get_system_memory(),
+ pic,
+ get_system_memory(),
+ get_system_io(),
PCI_DEVFN(18, 0), 4);
d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d,
DEVICE_NATIVE_ENDIAN);
diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c
index 5fd71a0f71..3ba0b0e0fb 100644
--- a/hw/heathrow_pic.c
+++ b/hw/heathrow_pic.c
@@ -43,6 +43,7 @@ typedef struct HeathrowPIC {
} HeathrowPIC;
typedef struct HeathrowPICS {
+ MemoryRegion mem;
HeathrowPIC pics[2];
qemu_irq *irqs;
} HeathrowPICS;
@@ -62,7 +63,8 @@ static void heathrow_pic_update(HeathrowPICS *s)
}
}
-static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+static void pic_write(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
{
HeathrowPICS *s = opaque;
HeathrowPIC *pic;
@@ -89,7 +91,8 @@ static void pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
}
}
-static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t pic_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
HeathrowPICS *s = opaque;
HeathrowPIC *pic;
@@ -120,19 +123,12 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
return value;
}
-static CPUWriteMemoryFunc * const pic_write[] = {
- &pic_writel,
- &pic_writel,
- &pic_writel,
+static const MemoryRegionOps heathrow_pic_ops = {
+ .read = pic_read,
+ .write = pic_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
-static CPUReadMemoryFunc * const pic_read[] = {
- &pic_readl,
- &pic_readl,
- &pic_readl,
-};
-
-
static void heathrow_pic_set_irq(void *opaque, int num, int level)
{
HeathrowPICS *s = opaque;
@@ -201,7 +197,7 @@ static void heathrow_pic_reset(void *opaque)
s->pics[1].level_triggered = 0x1ff00000;
}
-qemu_irq *heathrow_pic_init(int *pmem_index,
+qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
int nb_cpus, qemu_irq **irqs)
{
HeathrowPICS *s;
@@ -209,8 +205,9 @@ qemu_irq *heathrow_pic_init(int *pmem_index,
s = qemu_mallocz(sizeof(HeathrowPICS));
/* only 1 CPU */
s->irqs = irqs[0];
- *pmem_index = cpu_register_io_memory(pic_read, pic_write, s,
- DEVICE_LITTLE_ENDIAN);
+ memory_region_init_io(&s->mem, &heathrow_pic_ops, s,
+ "heathrow-pic", 0x1000);
+ *pmem = &s->mem;
vmstate_register(NULL, -1, &vmstate_heathrow_pic, s);
qemu_register_reset(heathrow_pic_reset, s);
diff --git a/hw/hid.c b/hw/hid.c
index 7b5ef5fc92..ec066cf2d3 100644
--- a/hw/hid.c
+++ b/hw/hid.c
@@ -218,16 +218,21 @@ static inline int int_clamp(int val, int vmin, int vmax)
}
}
+void hid_pointer_activate(HIDState *hs)
+{
+ if (!hs->ptr.mouse_grabbed) {
+ qemu_activate_mouse_event_handler(hs->ptr.eh_entry);
+ hs->ptr.mouse_grabbed = 1;
+ }
+}
+
int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
{
int dx, dy, dz, b, l;
int index;
HIDPointerEvent *e;
- if (!hs->ptr.mouse_grabbed) {
- qemu_activate_mouse_event_handler(hs->ptr.eh_entry);
- hs->ptr.mouse_grabbed = 1;
- }
+ hid_pointer_activate(hs);
/* When the buffer is empty, return the last event. Relative
movements will all be zero. */
@@ -359,7 +364,6 @@ void hid_reset(HIDState *hs)
{
switch (hs->kind) {
case HID_KEYBOARD:
- qemu_add_kbd_event_handler(hid_keyboard_event, hs);
memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
hs->kbd.keys = 0;
@@ -393,7 +397,9 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event)
hs->kind = kind;
hs->event = event;
- if (hs->kind == HID_MOUSE) {
+ if (hs->kind == HID_KEYBOARD) {
+ qemu_add_kbd_event_handler(hid_keyboard_event, hs);
+ } else if (hs->kind == HID_MOUSE) {
hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
0, "QEMU HID Mouse");
} else if (hs->kind == HID_TABLET) {
@@ -401,3 +407,61 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event)
1, "QEMU HID Tablet");
}
}
+
+static int hid_post_load(void *opaque, int version_id)
+{
+ HIDState *s = opaque;
+
+ if (s->idle) {
+ hid_set_next_idle(s, qemu_get_clock_ns(vm_clock));
+ }
+ return 0;
+}
+
+static const VMStateDescription vmstate_hid_ptr_queue = {
+ .name = "HIDPointerEventQueue",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (VMStateField[]) {
+ VMSTATE_INT32(xdx, HIDPointerEvent),
+ VMSTATE_INT32(ydy, HIDPointerEvent),
+ VMSTATE_INT32(dz, HIDPointerEvent),
+ VMSTATE_INT32(buttons_state, HIDPointerEvent),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+const VMStateDescription vmstate_hid_ptr_device = {
+ .name = "HIDPointerDevice",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = hid_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_STRUCT_ARRAY(ptr.queue, HIDState, QUEUE_LENGTH, 0,
+ vmstate_hid_ptr_queue, HIDPointerEvent),
+ VMSTATE_UINT32(head, HIDState),
+ VMSTATE_UINT32(n, HIDState),
+ VMSTATE_INT32(protocol, HIDState),
+ VMSTATE_UINT8(idle, HIDState),
+ VMSTATE_END_OF_LIST(),
+ }
+};
+
+const VMStateDescription vmstate_hid_keyboard_device = {
+ .name = "HIDKeyboardDevice",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .post_load = hid_post_load,
+ .fields = (VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(kbd.keycodes, HIDState, QUEUE_LENGTH),
+ VMSTATE_UINT32(head, HIDState),
+ VMSTATE_UINT32(n, HIDState),
+ VMSTATE_UINT16(kbd.modifiers, HIDState),
+ VMSTATE_UINT8(kbd.leds, HIDState),
+ VMSTATE_UINT8_ARRAY(kbd.key, HIDState, 16),
+ VMSTATE_INT32(kbd.keys, HIDState),
+ VMSTATE_INT32(protocol, HIDState),
+ VMSTATE_UINT8(idle, HIDState),
+ VMSTATE_END_OF_LIST(),
+ }
+};
diff --git a/hw/hid.h b/hw/hid.h
index 4a8fa5b63f..9ce03b118c 100644
--- a/hw/hid.h
+++ b/hw/hid.h
@@ -51,6 +51,7 @@ void hid_free(HIDState *hs);
bool hid_has_events(HIDState *hs);
void hid_set_next_idle(HIDState *hs, int64_t curtime);
+void hid_pointer_activate(HIDState *hs);
int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len);
int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len);
int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len);
diff --git a/hw/hw.h b/hw/hw.h
index df6ca65058..a124da9c26 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -701,6 +701,26 @@ extern const VMStateDescription vmstate_ptimer;
.offset = vmstate_offset_pointer(_state, _field, ptimer_state), \
}
+extern const VMStateDescription vmstate_hid_keyboard_device;
+
+#define VMSTATE_HID_KEYBOARD_DEVICE(_field, _state) { \
+ .name = (stringify(_field)), \
+ .size = sizeof(HIDState), \
+ .vmsd = &vmstate_hid_keyboard_device, \
+ .flags = VMS_STRUCT, \
+ .offset = vmstate_offset_value(_state, _field, HIDState), \
+}
+
+extern const VMStateDescription vmstate_hid_ptr_device;
+
+#define VMSTATE_HID_POINTER_DEVICE(_field, _state) { \
+ .name = (stringify(_field)), \
+ .size = sizeof(HIDState), \
+ .vmsd = &vmstate_hid_ptr_device, \
+ .flags = VMS_STRUCT, \
+ .offset = vmstate_offset_value(_state, _field, HIDState), \
+}
+
/* _f : field name
_f_n : num of elements field_name
_n : num of elements
diff --git a/hw/ide.h b/hw/ide.h
index a490cbb6c5..9059aae289 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -19,7 +19,7 @@ PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
/* ide-macio.c */
-int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
+MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
void *dbdma, int channel, qemu_irq dma_irq);
/* ide-mmio.c */
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 1f008a3dda..e207ca0894 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -276,12 +276,12 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
}
}
-static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr)
+static uint64_t ahci_mem_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
- AHCIState *s = ptr;
+ AHCIState *s = opaque;
uint32_t val = 0;
- addr = addr & 0xfff;
if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
switch (addr) {
case HOST_CAP:
@@ -314,10 +314,10 @@ static uint32_t ahci_mem_readl(void *ptr, target_phys_addr_t addr)
-static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
+static void ahci_mem_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
- AHCIState *s = ptr;
- addr = addr & 0xfff;
+ AHCIState *s = opaque;
/* Only aligned reads are allowed on AHCI */
if (addr & 3) {
@@ -364,16 +364,10 @@ static void ahci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
}
-static CPUReadMemoryFunc * const ahci_readfn[3]={
- ahci_mem_readl,
- ahci_mem_readl,
- ahci_mem_readl
-};
-
-static CPUWriteMemoryFunc * const ahci_writefn[3]={
- ahci_mem_writel,
- ahci_mem_writel,
- ahci_mem_writel
+static MemoryRegionOps ahci_mem_ops = {
+ .read = ahci_mem_read,
+ .write = ahci_mem_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
static void ahci_reg_init(AHCIState *s)
@@ -1131,8 +1125,8 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
s->ports = ports;
s->dev = qemu_mallocz(sizeof(AHCIDevice) * ports);
ahci_reg_init(s);
- s->mem = cpu_register_io_memory(ahci_readfn, ahci_writefn, s,
- DEVICE_LITTLE_ENDIAN);
+ /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
+ memory_region_init_io(&s->mem, &ahci_mem_ops, s, "ahci", 0x1000);
irqs = qemu_allocate_irqs(ahci_irq_set, s, s->ports);
for (i = 0; i < s->ports; i++) {
@@ -1151,6 +1145,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
void ahci_uninit(AHCIState *s)
{
+ memory_region_destroy(&s->mem);
qemu_free(s->dev);
}
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index dc86951ebf..e456193b2b 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -289,7 +289,7 @@ struct AHCIDevice {
typedef struct AHCIState {
AHCIDevice *dev;
AHCIControlRegs control_regs;
- int mem;
+ MemoryRegion mem;
int ports;
qemu_irq irq;
} AHCIState;
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 56302b5060..4d91e2c642 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -44,35 +44,95 @@
static void cmd646_update_irq(PCIIDEState *d);
-static void ide_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static uint64_t cmd646_cmd_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
- PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
- IDEBus *bus;
-
- if (region_num <= 3) {
- bus = &d->bus[(region_num >> 1)];
- if (region_num & 1) {
- register_ioport_read(addr + 2, 1, 1, ide_status_read, bus);
- register_ioport_write(addr + 2, 1, 1, ide_cmd_write, bus);
+ CMD646BAR *cmd646bar = opaque;
+
+ if (addr != 2 || size != 1) {
+ return ((uint64_t)1 << (size * 8)) - 1;
+ }
+ return ide_status_read(cmd646bar->bus, addr + 2);
+}
+
+static void cmd646_cmd_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
+{
+ CMD646BAR *cmd646bar = opaque;
+
+ if (addr != 2 || size != 1) {
+ return;
+ }
+ ide_cmd_write(cmd646bar->bus, addr + 2, data);
+}
+
+static MemoryRegionOps cmd646_cmd_ops = {
+ .read = cmd646_cmd_read,
+ .write = cmd646_cmd_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static uint64_t cmd646_data_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ CMD646BAR *cmd646bar = opaque;
+
+ if (size == 1) {
+ return ide_ioport_read(cmd646bar->bus, addr);
+ } else if (addr == 0) {
+ if (size == 2) {
+ return ide_data_readw(cmd646bar->bus, addr);
} else {
- register_ioport_write(addr, 8, 1, ide_ioport_write, bus);
- register_ioport_read(addr, 8, 1, ide_ioport_read, bus);
-
- /* data ports */
- register_ioport_write(addr, 2, 2, ide_data_writew, bus);
- register_ioport_read(addr, 2, 2, ide_data_readw, bus);
- register_ioport_write(addr, 4, 4, ide_data_writel, bus);
- register_ioport_read(addr, 4, 4, ide_data_readl, bus);
+ return ide_data_readl(cmd646bar->bus, addr);
}
}
+ return ((uint64_t)1 << (size * 8)) - 1;
}
-static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm,
- uint32_t addr)
+static void cmd646_data_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
{
+ CMD646BAR *cmd646bar = opaque;
+
+ if (size == 1) {
+ return ide_ioport_write(cmd646bar->bus, addr, data);
+ } else if (addr == 0) {
+ if (size == 2) {
+ return ide_data_writew(cmd646bar->bus, addr, data);
+ } else {
+ return ide_data_writel(cmd646bar->bus, addr, data);
+ }
+ }
+}
+
+static MemoryRegionOps cmd646_data_ops = {
+ .read = cmd646_data_read,
+ .write = cmd646_data_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void setup_cmd646_bar(PCIIDEState *d, int bus_num)
+{
+ IDEBus *bus = &d->bus[bus_num];
+ CMD646BAR *bar = &d->cmd646_bar[bus_num];
+
+ bar->bus = bus;
+ bar->pci_dev = d;
+ memory_region_init_io(&bar->cmd, &cmd646_cmd_ops, bar, "cmd646-cmd", 4);
+ memory_region_init_io(&bar->data, &cmd646_data_ops, bar, "cmd646-data", 8);
+}
+
+static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ BMDMAState *bm = opaque;
+ PCIIDEState *pci_dev = bm->pci_dev;
uint32_t val;
+ if (size != 1) {
+ return ((uint64_t)1 << (size * 8)) - 1;
+ }
+
switch(addr & 3) {
case 0:
val = bm->cmd;
@@ -100,31 +160,22 @@ static uint32_t bmdma_readb_common(PCIIDEState *pci_dev, BMDMAState *bm,
return val;
}
-static uint32_t bmdma_readb_0(void *opaque, uint32_t addr)
+static void bmdma_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
- PCIIDEState *pci_dev = opaque;
- BMDMAState *bm = &pci_dev->bmdma[0];
-
- return bmdma_readb_common(pci_dev, bm, addr);
-}
+ BMDMAState *bm = opaque;
+ PCIIDEState *pci_dev = bm->pci_dev;
-static uint32_t bmdma_readb_1(void *opaque, uint32_t addr)
-{
- PCIIDEState *pci_dev = opaque;
- BMDMAState *bm = &pci_dev->bmdma[1];
-
- return bmdma_readb_common(pci_dev, bm, addr);
-}
+ if (size != 1) {
+ return;
+ }
-static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm,
- uint32_t addr, uint32_t val)
-{
#ifdef DEBUG_IDE
printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
#endif
switch(addr & 3) {
case 0:
- bmdma_cmd_writeb(bm, addr, val);
+ bmdma_cmd_writeb(bm, val);
break;
case 1:
pci_dev->dev.config[MRDMODE] =
@@ -143,42 +194,25 @@ static void bmdma_writeb_common(PCIIDEState *pci_dev, BMDMAState *bm,
}
}
-static void bmdma_writeb_0(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIIDEState *pci_dev = opaque;
- BMDMAState *bm = &pci_dev->bmdma[0];
-
- bmdma_writeb_common(pci_dev, bm, addr, val);
-}
-
-static void bmdma_writeb_1(void *opaque, uint32_t addr, uint32_t val)
-{
- PCIIDEState *pci_dev = opaque;
- BMDMAState *bm = &pci_dev->bmdma[1];
-
- bmdma_writeb_common(pci_dev, bm, addr, val);
-}
+static MemoryRegionOps cmd646_bmdma_ops = {
+ .read = bmdma_read,
+ .write = bmdma_write,
+};
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static void bmdma_setup_bar(PCIIDEState *d)
{
- PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
+ BMDMAState *bm;
int i;
+ memory_region_init(&d->bmdma_bar, "cmd646-bmdma", 16);
for(i = 0;i < 2; i++) {
- BMDMAState *bm = &d->bmdma[i];
-
- if (i == 0) {
- register_ioport_write(addr, 4, 1, bmdma_writeb_0, d);
- register_ioport_read(addr, 4, 1, bmdma_readb_0, d);
- } else {
- register_ioport_write(addr, 4, 1, bmdma_writeb_1, d);
- register_ioport_read(addr, 4, 1, bmdma_readb_1, d);
- }
-
- iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4);
- ioport_register(&bm->addr_ioport);
- addr += 8;
+ bm = &d->bmdma[i];
+ memory_region_init_io(&bm->extra_io, &cmd646_bmdma_ops, bm,
+ "cmd646-bmdma-bus", 4);
+ memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+ memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm,
+ "cmd646-bmdma-ioport", 4);
+ memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
}
}
@@ -234,11 +268,14 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
pci_conf[0x51] |= 0x08; /* enable IDE1 */
}
- pci_register_bar(dev, 0, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
- pci_register_bar(dev, 1, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
- pci_register_bar(dev, 2, 0x8, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
- pci_register_bar(dev, 3, 0x4, PCI_BASE_ADDRESS_SPACE_IO, ide_map);
- pci_register_bar(dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map);
+ setup_cmd646_bar(d, 0);
+ setup_cmd646_bar(d, 1);
+ pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].data);
+ pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[0].cmd);
+ pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].data);
+ pci_register_bar(dev, 3, PCI_BASE_ADDRESS_SPACE_IO, &d->cmd646_bar[1].cmd);
+ bmdma_setup_bar(d);
+ pci_register_bar(dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
/* TODO: RST# value should be 0 */
pci_conf[PCI_INTERRUPT_PIN] = 0x01; // interrupt on pin 1
@@ -248,7 +285,7 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
ide_bus_new(&d->bus[i], &d->dev.qdev, i);
ide_init2(&d->bus[i], irq[i]);
- bmdma_init(&d->bus[i], &d->bmdma[i]);
+ bmdma_init(&d->bus[i], &d->bmdma[i], d);
d->bmdma[i].bus = &d->bus[i];
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&d->bmdma[i].dma);
@@ -259,6 +296,24 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
return 0;
}
+static int pci_cmd646_ide_exitfn(PCIDevice *dev)
+{
+ PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
+ unsigned i;
+
+ for (i = 0; i < 2; ++i) {
+ memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
+ memory_region_destroy(&d->bmdma[i].extra_io);
+ memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+ memory_region_destroy(&d->bmdma[i].addr_ioport);
+ memory_region_destroy(&d->cmd646_bar[i].cmd);
+ memory_region_destroy(&d->cmd646_bar[i].data);
+ }
+ memory_region_destroy(&d->bmdma_bar);
+
+ return 0;
+}
+
void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
int secondary_ide_enabled)
{
@@ -276,6 +331,7 @@ static PCIDeviceInfo cmd646_ide_info[] = {
.qdev.name = "cmd646-ide",
.qdev.size = sizeof(PCIIDEState),
.init = pci_cmd646_ide_initfn,
+ .exit = pci_cmd646_ide_exitfn,
.vendor_id = PCI_VENDOR_ID_CMD,
.device_id = PCI_DEVICE_ID_CMD_646,
.revision = 0x07, // IDE controller revision
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index d241ea8005..5278bc4d6c 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -98,8 +98,7 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
msi_init(dev, 0x50, 1, true, false);
d->ahci.irq = d->card.irq[0];
- /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
- pci_register_bar_simple(&d->card, 5, 0x1000, 0, d->ahci.mem);
+ pci_register_bar(&d->card, 5, 0, &d->ahci.mem);
return 0;
}
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 7daeb31ec3..7ee35e9bd9 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -35,6 +35,7 @@
/* MacIO based PowerPC IDE */
typedef struct MACIOIDEState {
+ MemoryRegion mem;
IDEBus bus;
BlockDriverAIOCB *aiocb;
} MACIOIDEState;
@@ -281,16 +282,20 @@ static uint32_t pmac_ide_readl (void *opaque,target_phys_addr_t addr)
return retval;
}
-static CPUWriteMemoryFunc * const pmac_ide_write[] = {
- pmac_ide_writeb,
- pmac_ide_writew,
- pmac_ide_writel,
-};
-
-static CPUReadMemoryFunc * const pmac_ide_read[] = {
- pmac_ide_readb,
- pmac_ide_readw,
- pmac_ide_readl,
+static MemoryRegionOps pmac_ide_ops = {
+ .old_mmio = {
+ .write = {
+ pmac_ide_writeb,
+ pmac_ide_writew,
+ pmac_ide_writel,
+ },
+ .read = {
+ pmac_ide_readb,
+ pmac_ide_readw,
+ pmac_ide_readl,
+ },
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static const VMStateDescription vmstate_pmac = {
@@ -315,11 +320,10 @@ static void pmac_ide_reset(void *opaque)
/* hd_table must contain 4 block drivers */
/* PowerMac uses memory mapped registers, not I/O. Return the memory
I/O index to access the ide. */
-int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
- void *dbdma, int channel, qemu_irq dma_irq)
+MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
+ void *dbdma, int channel, qemu_irq dma_irq)
{
MACIOIDEState *d;
- int pmac_ide_memory;
d = qemu_mallocz(sizeof(MACIOIDEState));
ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq);
@@ -327,11 +331,9 @@ int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
if (dbdma)
DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d);
- pmac_ide_memory = cpu_register_io_memory(pmac_ide_read,
- pmac_ide_write, d,
- DEVICE_NATIVE_ENDIAN);
+ memory_region_init_io(&d->mem, &pmac_ide_ops, d, "pmac-ide", 0x1000);
vmstate_register(NULL, 0, &vmstate_pmac, d);
qemu_register_reset(pmac_ide_reset, d);
- return pmac_ide_memory;
+ return &d->mem;
}
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 9f3050a15e..d1a14d7cc1 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -287,9 +287,8 @@ static void bmdma_irq(void *opaque, int n, int level)
qemu_set_irq(bm->irq, level);
}
-void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
+void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
{
- BMDMAState *bm = opaque;
#ifdef DEBUG_IDE
printf("%s: 0x%08x\n", __func__, val);
#endif
@@ -328,22 +327,24 @@ void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)
bm->cmd = val & 0x09;
}
-static void bmdma_addr_read(IORange *ioport, uint64_t addr,
- unsigned width, uint64_t *data)
+static uint64_t bmdma_addr_read(void *opaque, target_phys_addr_t addr,
+ unsigned width)
{
- BMDMAState *bm = container_of(ioport, BMDMAState, addr_ioport);
+ BMDMAState *bm = opaque;
uint32_t mask = (1ULL << (width * 8)) - 1;
+ uint64_t data;
- *data = (bm->addr >> (addr * 8)) & mask;
+ data = (bm->addr >> (addr * 8)) & mask;
#ifdef DEBUG_IDE
printf("%s: 0x%08x\n", __func__, (unsigned)*data);
#endif
+ return data;
}
-static void bmdma_addr_write(IORange *ioport, uint64_t addr,
- unsigned width, uint64_t data)
+static void bmdma_addr_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned width)
{
- BMDMAState *bm = container_of(ioport, BMDMAState, addr_ioport);
+ BMDMAState *bm = opaque;
int shift = addr * 8;
uint32_t mask = (1ULL << (width * 8)) - 1;
@@ -354,9 +355,10 @@ static void bmdma_addr_write(IORange *ioport, uint64_t addr,
bm->addr |= ((data & mask) << shift) & ~3;
}
-const IORangeOps bmdma_addr_ioport_ops = {
+MemoryRegionOps bmdma_addr_ioport_ops = {
.read = bmdma_addr_read,
.write = bmdma_addr_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
static bool ide_bmdma_current_needed(void *opaque)
@@ -514,7 +516,7 @@ static const struct IDEDMAOps bmdma_ops = {
.reset = bmdma_reset,
};
-void bmdma_init(IDEBus *bus, BMDMAState *bm)
+void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d)
{
qemu_irq *irq;
@@ -527,4 +529,5 @@ void bmdma_init(IDEBus *bus, BMDMAState *bm)
bm->irq = bus->irq;
irq = qemu_allocate_irqs(bmdma_irq, bm, 1);
bus->irq = *irq;
+ bm->pci_dev = d;
}
diff --git a/hw/ide/pci.h b/hw/ide/pci.h
index b4f3691a5c..a694e546d7 100644
--- a/hw/ide/pci.h
+++ b/hw/ide/pci.h
@@ -19,20 +19,31 @@ typedef struct BMDMAState {
BlockDriverCompletionFunc *dma_cb;
int64_t sector_num;
uint32_t nsector;
- IORange addr_ioport;
+ MemoryRegion addr_ioport;
+ MemoryRegion extra_io;
QEMUBH *bh;
qemu_irq irq;
/* Bit 0-2 and 7: BM status register
* Bit 3-6: bus->error_status */
uint8_t migration_compat_status;
+ struct PCIIDEState *pci_dev;
} BMDMAState;
+typedef struct CMD646BAR {
+ MemoryRegion cmd;
+ MemoryRegion data;
+ IDEBus *bus;
+ struct PCIIDEState *pci_dev;
+} CMD646BAR;
+
typedef struct PCIIDEState {
PCIDevice dev;
IDEBus bus[2];
BMDMAState bmdma[2];
uint32_t secondary; /* used only for cmd646 */
+ MemoryRegion bmdma_bar;
+ CMD646BAR cmd646_bar[2]; /* used only for cmd646 */
} PCIIDEState;
@@ -43,9 +54,9 @@ static inline IDEState *bmdma_active_if(BMDMAState *bmdma)
}
-void bmdma_init(IDEBus *bus, BMDMAState *bm);
-void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val);
-extern const IORangeOps bmdma_addr_ioport_ops;
+void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
+void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
+extern MemoryRegionOps bmdma_addr_ioport_ops;
void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table);
extern const VMStateDescription vmstate_ide_pci;
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index f527dbd57e..8525336075 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -33,11 +33,15 @@
#include <hw/ide/pci.h>
-static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, unsigned size)
{
BMDMAState *bm = opaque;
uint32_t val;
+ if (size != 1) {
+ return ((uint64_t)1 << (size * 8)) - 1;
+ }
+
switch(addr & 3) {
case 0:
val = bm->cmd;
@@ -55,36 +59,46 @@ static uint32_t bmdma_readb(void *opaque, uint32_t addr)
return val;
}
-static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void bmdma_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
BMDMAState *bm = opaque;
+
+ if (size != 1) {
+ return;
+ }
+
#ifdef DEBUG_IDE
printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
#endif
switch(addr & 3) {
+ case 0:
+ return bmdma_cmd_writeb(bm, val);
case 2:
bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
break;
}
}
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static MemoryRegionOps piix_bmdma_ops = {
+ .read = bmdma_read,
+ .write = bmdma_write,
+};
+
+static void bmdma_setup_bar(PCIIDEState *d)
{
- PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
int i;
+ memory_region_init(&d->bmdma_bar, "piix-bmdma-container", 16);
for(i = 0;i < 2; i++) {
BMDMAState *bm = &d->bmdma[i];
- register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
-
- register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
- register_ioport_read(addr, 4, 1, bmdma_readb, bm);
-
- iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4);
- ioport_register(&bm->addr_ioport);
- addr += 8;
+ memory_region_init_io(&bm->extra_io, &piix_bmdma_ops, bm,
+ "piix-bmdma", 4);
+ memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+ memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm,
+ "bmdma", 4);
+ memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
}
}
@@ -124,7 +138,7 @@ static void pci_piix_init_ports(PCIIDEState *d) {
ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq));
- bmdma_init(&d->bus[i], &d->bmdma[i]);
+ bmdma_init(&d->bus[i], &d->bmdma[i], d);
d->bmdma[i].bus = &d->bus[i];
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&d->bmdma[i].dma);
@@ -140,7 +154,8 @@ static int pci_piix_ide_initfn(PCIDevice *dev)
qemu_register_reset(piix3_reset, d);
- pci_register_bar(&d->dev, 4, 0x10, PCI_BASE_ADDRESS_SPACE_IO, bmdma_map);
+ bmdma_setup_bar(d);
+ pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
vmstate_register(&d->dev.qdev, 0, &vmstate_ide_pci, d);
@@ -185,6 +200,22 @@ PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
return dev;
}
+static int pci_piix_ide_exitfn(PCIDevice *dev)
+{
+ PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
+ unsigned i;
+
+ for (i = 0; i < 2; ++i) {
+ memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
+ memory_region_destroy(&d->bmdma[i].extra_io);
+ memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+ memory_region_destroy(&d->bmdma[i].addr_ioport);
+ }
+ memory_region_destroy(&d->bmdma_bar);
+
+ return 0;
+}
+
/* hd_table must contain 4 block drivers */
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
@@ -214,6 +245,7 @@ static PCIDeviceInfo piix_ide_info[] = {
.qdev.no_user = 1,
.no_hotplug = 1,
.init = pci_piix_ide_initfn,
+ .exit = pci_piix_ide_exitfn,
.vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82371SB_1,
.class_id = PCI_CLASS_STORAGE_IDE,
@@ -231,6 +263,7 @@ static PCIDeviceInfo piix_ide_info[] = {
.qdev.no_user = 1,
.no_hotplug = 1,
.init = pci_piix_ide_initfn,
+ .exit = pci_piix_ide_exitfn,
.vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82371AB,
.class_id = PCI_CLASS_STORAGE_IDE,
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 3474c37ff7..c0b9d43827 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -34,11 +34,16 @@
#include <hw/ide/pci.h>
-static uint32_t bmdma_readb(void *opaque, uint32_t addr)
+static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
BMDMAState *bm = opaque;
uint32_t val;
+ if (size != 1) {
+ return ((uint64_t)1 << (size * 8)) - 1;
+ }
+
switch (addr & 3) {
case 0:
val = bm->cmd;
@@ -56,13 +61,21 @@ static uint32_t bmdma_readb(void *opaque, uint32_t addr)
return val;
}
-static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void bmdma_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
BMDMAState *bm = opaque;
+
+ if (size != 1) {
+ return;
+ }
+
#ifdef DEBUG_IDE
printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
#endif
switch (addr & 3) {
+ case 0:
+ return bmdma_cmd_writeb(bm, val);
case 2:
bm->status = (val & 0x60) | (bm->status & 1) | (bm->status & ~val & 0x06);
break;
@@ -70,23 +83,25 @@ static void bmdma_writeb(void *opaque, uint32_t addr, uint32_t val)
}
}
-static void bmdma_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static MemoryRegionOps via_bmdma_ops = {
+ .read = bmdma_read,
+ .write = bmdma_write,
+};
+
+static void bmdma_setup_bar(PCIIDEState *d)
{
- PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, pci_dev);
int i;
+ memory_region_init(&d->bmdma_bar, "via-bmdma-container", 16);
for(i = 0;i < 2; i++) {
BMDMAState *bm = &d->bmdma[i];
- register_ioport_write(addr, 1, 1, bmdma_cmd_writeb, bm);
-
- register_ioport_write(addr + 1, 3, 1, bmdma_writeb, bm);
- register_ioport_read(addr, 4, 1, bmdma_readb, bm);
-
- iorange_init(&bm->addr_ioport, &bmdma_addr_ioport_ops, addr + 4, 4);
- ioport_register(&bm->addr_ioport);
- addr += 8;
+ memory_region_init_io(&bm->extra_io, &via_bmdma_ops, bm,
+ "via-bmdma", 4);
+ memory_region_add_subregion(&d->bmdma_bar, i * 8, &bm->extra_io);
+ memory_region_init_io(&bm->addr_ioport, &bmdma_addr_ioport_ops, bm,
+ "bmdma", 4);
+ memory_region_add_subregion(&d->bmdma_bar, i * 8 + 4, &bm->addr_ioport);
}
}
@@ -147,7 +162,7 @@ static void vt82c686b_init_ports(PCIIDEState *d) {
ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
ide_init2(&d->bus[i], isa_get_irq(port_info[i].isairq));
- bmdma_init(&d->bus[i], &d->bmdma[i]);
+ bmdma_init(&d->bus[i], &d->bmdma[i], d);
d->bmdma[i].bus = &d->bus[i];
qemu_add_vm_change_state_handler(d->bus[i].dma->ops->restart_cb,
&d->bmdma[i].dma);
@@ -164,8 +179,8 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
qemu_register_reset(via_reset, d);
- pci_register_bar(&d->dev, 4, 0x10,
- PCI_BASE_ADDRESS_SPACE_IO, bmdma_map);
+ bmdma_setup_bar(d);
+ pci_register_bar(&d->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &d->bmdma_bar);
vmstate_register(&dev->qdev, 0, &vmstate_ide_pci, d);
@@ -174,6 +189,22 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
return 0;
}
+static int vt82c686b_ide_exitfn(PCIDevice *dev)
+{
+ PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
+ unsigned i;
+
+ for (i = 0; i < 2; ++i) {
+ memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].extra_io);
+ memory_region_destroy(&d->bmdma[i].extra_io);
+ memory_region_del_subregion(&d->bmdma_bar, &d->bmdma[i].addr_ioport);
+ memory_region_destroy(&d->bmdma[i].addr_ioport);
+ }
+ memory_region_destroy(&d->bmdma_bar);
+
+ return 0;
+}
+
void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
{
PCIDevice *dev;
@@ -187,6 +218,7 @@ static PCIDeviceInfo via_ide_info = {
.qdev.size = sizeof(PCIIDEState),
.qdev.no_user = 1,
.init = vt82c686b_ide_initfn,
+ .exit = vt82c686b_ide_exitfn,
.vendor_id = PCI_VENDOR_ID_VIA,
.device_id = PCI_DEVICE_ID_VIA_IDE,
.revision = 0x06,
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 5a2bc3aaa9..fa56a92215 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -177,7 +177,7 @@ struct IntelHDAState {
IntelHDAStream st[8];
/* state */
- int mmio_addr;
+ MemoryRegion mmio;
uint32_t rirb_count;
int64_t wall_base_ns;
@@ -1084,16 +1084,20 @@ static uint32_t intel_hda_mmio_readl(void *opaque, target_phys_addr_t addr)
return intel_hda_reg_read(d, reg, 0xffffffff);
}
-static CPUReadMemoryFunc * const intel_hda_mmio_read[3] = {
- intel_hda_mmio_readb,
- intel_hda_mmio_readw,
- intel_hda_mmio_readl,
-};
-
-static CPUWriteMemoryFunc * const intel_hda_mmio_write[3] = {
- intel_hda_mmio_writeb,
- intel_hda_mmio_writew,
- intel_hda_mmio_writel,
+static const MemoryRegionOps intel_hda_mmio_ops = {
+ .old_mmio = {
+ .read = {
+ intel_hda_mmio_readb,
+ intel_hda_mmio_readw,
+ intel_hda_mmio_readl,
+ },
+ .write = {
+ intel_hda_mmio_writeb,
+ intel_hda_mmio_writew,
+ intel_hda_mmio_writel,
+ },
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
/* --------------------------------------------------------------------- */
@@ -1130,10 +1134,9 @@ static int intel_hda_init(PCIDevice *pci)
/* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */
conf[0x40] = 0x01;
- d->mmio_addr = cpu_register_io_memory(intel_hda_mmio_read,
- intel_hda_mmio_write, d,
- DEVICE_NATIVE_ENDIAN);
- pci_register_bar_simple(&d->pci, 0, 0x4000, 0, d->mmio_addr);
+ memory_region_init_io(&d->mmio, &intel_hda_mmio_ops, d,
+ "intel-hda", 0x4000);
+ pci_register_bar(&d->pci, 0, 0, &d->mmio);
if (d->msi) {
msi_init(&d->pci, 0x50, 1, true, false);
}
@@ -1149,7 +1152,7 @@ static int intel_hda_exit(PCIDevice *pci)
IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci);
msi_uninit(&d->pci);
- cpu_unregister_io_memory(d->mmio_addr);
+ memory_region_destroy(&d->mmio);
return 0;
}
diff --git a/hw/isa.h b/hw/isa.h
index d2b6126602..f1f21812d6 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -4,6 +4,7 @@
/* ISA bus */
#include "ioport.h"
+#include "memory.h"
#include "qdev.h"
typedef struct ISABus ISABus;
@@ -37,6 +38,7 @@ ISADevice *isa_create_simple(const char *name);
extern target_phys_addr_t isa_mem_base;
+void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size);
void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size);
/* dma.c */
diff --git a/hw/isa_mmio.c b/hw/isa_mmio.c
index ca957fb010..3d2af1a63c 100644
--- a/hw/isa_mmio.c
+++ b/hw/isa_mmio.c
@@ -24,6 +24,7 @@
#include "hw.h"
#include "isa.h"
+#include "exec-memory.h"
static void isa_mmio_writeb (void *opaque, target_phys_addr_t addr,
uint32_t val)
@@ -58,25 +59,23 @@ static uint32_t isa_mmio_readl(void *opaque, target_phys_addr_t addr)
return cpu_inl(addr & IOPORTS_MASK);
}
-static CPUWriteMemoryFunc * const isa_mmio_write[] = {
- &isa_mmio_writeb,
- &isa_mmio_writew,
- &isa_mmio_writel,
+static const MemoryRegionOps isa_mmio_ops = {
+ .old_mmio = {
+ .write = { isa_mmio_writeb, isa_mmio_writew, isa_mmio_writel },
+ .read = { isa_mmio_readb, isa_mmio_readw, isa_mmio_readl, },
+ },
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
-static CPUReadMemoryFunc * const isa_mmio_read[] = {
- &isa_mmio_readb,
- &isa_mmio_readw,
- &isa_mmio_readl,
-};
+void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size)
+{
+ memory_region_init_io(mr, &isa_mmio_ops, NULL, "isa-mmio", size);
+}
void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size)
{
- int isa_mmio_iomemtype;
+ MemoryRegion *mr = qemu_malloc(sizeof(*mr));
- isa_mmio_iomemtype = cpu_register_io_memory(isa_mmio_read,
- isa_mmio_write,
- NULL,
- DEVICE_LITTLE_ENDIAN);
- cpu_register_physical_memory(base, size, isa_mmio_iomemtype);
+ isa_mmio_setup(mr, size);
+ memory_region_add_subregion(get_system_memory(), base, mr);
}
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 3055dd2a50..42a5877032 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -56,11 +56,16 @@ typedef struct IVShmemState {
CharDriverState **eventfd_chr;
CharDriverState *server_chr;
- int ivshmem_mmio_io_addr;
+ MemoryRegion ivshmem_mmio;
pcibus_t mmio_addr;
- pcibus_t shm_pci_addr;
- uint64_t ivshmem_offset;
+ /* We might need to register the BAR before we actually have the memory.
+ * So prepare a container MemoryRegion for the BAR immediately and
+ * add a subregion when we have the memory.
+ */
+ MemoryRegion bar;
+ MemoryRegion ivshmem;
+ MemoryRegion msix_bar;
uint64_t ivshmem_size; /* size of shared memory region */
int shm_fd; /* shared memory file descriptor */
@@ -96,23 +101,6 @@ static inline bool is_power_of_two(uint64_t x) {
return (x & (x - 1)) == 0;
}
-static void ivshmem_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev);
-
- s->shm_pci_addr = addr;
-
- if (s->ivshmem_offset > 0) {
- cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size,
- s->ivshmem_offset);
- }
-
- IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %"
- PRIu64 ", size = %" FMT_PCIBUS "\n", addr, s->ivshmem_offset, size);
-
-}
-
/* accessing registers - based on rtl8139 */
static void ivshmem_update_irq(IVShmemState *s, int val)
{
@@ -168,15 +156,8 @@ static uint32_t ivshmem_IntrStatus_read(IVShmemState *s)
return ret;
}
-static void ivshmem_io_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
-
- IVSHMEM_DPRINTF("We shouldn't be writing words\n");
-}
-
-static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void ivshmem_io_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
IVShmemState *s = opaque;
@@ -219,20 +200,8 @@ static void ivshmem_io_writel(void *opaque, target_phys_addr_t addr,
}
}
-static void ivshmem_io_writeb(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- IVSHMEM_DPRINTF("We shouldn't be writing bytes\n");
-}
-
-static uint32_t ivshmem_io_readw(void *opaque, target_phys_addr_t addr)
-{
-
- IVSHMEM_DPRINTF("We shouldn't be reading words\n");
- return 0;
-}
-
-static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t ivshmem_io_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
IVShmemState *s = opaque;
@@ -265,23 +234,14 @@ static uint32_t ivshmem_io_readl(void *opaque, target_phys_addr_t addr)
return ret;
}
-static uint32_t ivshmem_io_readb(void *opaque, target_phys_addr_t addr)
-{
- IVSHMEM_DPRINTF("We shouldn't be reading bytes\n");
-
- return 0;
-}
-
-static CPUReadMemoryFunc * const ivshmem_mmio_read[3] = {
- ivshmem_io_readb,
- ivshmem_io_readw,
- ivshmem_io_readl,
-};
-
-static CPUWriteMemoryFunc * const ivshmem_mmio_write[3] = {
- ivshmem_io_writeb,
- ivshmem_io_writew,
- ivshmem_io_writel,
+static const MemoryRegionOps ivshmem_mmio_ops = {
+ .read = ivshmem_io_read,
+ .write = ivshmem_io_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .impl = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
};
static void ivshmem_receive(void *opaque, const uint8_t *buf, int size)
@@ -371,12 +331,12 @@ static void create_shared_memory_BAR(IVShmemState *s, int fd) {
ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev, "ivshmem.bar2",
- s->ivshmem_size, ptr);
+ memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev, "ivshmem.bar2",
+ s->ivshmem_size, ptr);
+ memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
/* region for shared memory */
- pci_register_bar(&s->dev, 2, s->ivshmem_size,
- PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map);
+ pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
}
static void close_guest_eventfds(IVShmemState *s, int posn)
@@ -401,8 +361,12 @@ static void setup_ioeventfds(IVShmemState *s) {
for (i = 0; i <= s->max_peer; i++) {
for (j = 0; j < s->peers[i].nb_eventfds; j++) {
- kvm_set_ioeventfd_mmio_long(s->peers[i].eventfds[j],
- s->mmio_addr + DOORBELL, (i << 16) | j, 1);
+ memory_region_add_eventfd(&s->ivshmem_mmio,
+ DOORBELL,
+ 4,
+ true,
+ (i << 16) | j,
+ s->peers[i].eventfds[j]);
}
}
}
@@ -483,18 +447,13 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
/* mmap the region and map into the BAR2 */
map_ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED,
incoming_fd, 0);
- s->ivshmem_offset = qemu_ram_alloc_from_ptr(&s->dev.qdev,
- "ivshmem.bar2", s->ivshmem_size, map_ptr);
+ memory_region_init_ram_ptr(&s->ivshmem, &s->dev.qdev,
+ "ivshmem.bar2", s->ivshmem_size, map_ptr);
- IVSHMEM_DPRINTF("guest pci addr = %" FMT_PCIBUS ", guest h/w addr = %"
- PRIu64 ", size = %" PRIu64 "\n", s->shm_pci_addr,
+ IVSHMEM_DPRINTF("guest h/w addr = %" PRIu64 ", size = %" PRIu64 "\n",
s->ivshmem_offset, s->ivshmem_size);
- if (s->shm_pci_addr > 0) {
- /* map memory into BAR2 */
- cpu_register_physical_memory(s->shm_pci_addr, s->ivshmem_size,
- s->ivshmem_offset);
- }
+ memory_region_add_subregion(&s->bar, 0, &s->ivshmem);
/* only store the fd if it is successfully mapped */
s->shm_fd = incoming_fd;
@@ -549,20 +508,6 @@ static void ivshmem_reset(DeviceState *d)
return;
}
-static void ivshmem_mmio_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- IVShmemState *s = DO_UPCAST(IVShmemState, dev, pci_dev);
-
- s->mmio_addr = addr;
- cpu_register_physical_memory(addr + 0, IVSHMEM_REG_BAR_SIZE,
- s->ivshmem_mmio_io_addr);
-
- if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
- setup_ioeventfds(s);
- }
-}
-
static uint64_t ivshmem_get_size(IVShmemState * s) {
uint64_t value;
@@ -596,11 +541,10 @@ static void ivshmem_setup_msi(IVShmemState * s) {
/* allocate the MSI-X vectors */
- if (!msix_init(&s->dev, s->vectors, 1, 0)) {
- pci_register_bar(&s->dev, 1,
- msix_bar_size(&s->dev),
- PCI_BASE_ADDRESS_SPACE_MEMORY,
- msix_mmio_map);
+ memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
+ if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
+ pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+ &s->msix_bar);
IVSHMEM_DPRINTF("msix initialized (%d vectors)\n", s->vectors);
} else {
IVSHMEM_DPRINTF("msix initialization failed\n");
@@ -710,15 +654,20 @@ static int pci_ivshmem_init(PCIDevice *dev)
pci_config_set_interrupt_pin(pci_conf, 1);
- s->shm_pci_addr = 0;
- s->ivshmem_offset = 0;
s->shm_fd = 0;
- s->ivshmem_mmio_io_addr = cpu_register_io_memory(ivshmem_mmio_read,
- ivshmem_mmio_write, s, DEVICE_NATIVE_ENDIAN);
+ memory_region_init_io(&s->ivshmem_mmio, &ivshmem_mmio_ops, s,
+ "ivshmem-mmio", IVSHMEM_REG_BAR_SIZE);
+
+ if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
+ setup_ioeventfds(s);
+ }
+
/* region for registers*/
- pci_register_bar(&s->dev, 0, IVSHMEM_REG_BAR_SIZE,
- PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_mmio_map);
+ pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,
+ &s->ivshmem_mmio);
+
+ memory_region_init(&s->bar, "ivshmem-bar2-container", s->ivshmem_size);
if ((s->server_chr != NULL) &&
(strncmp(s->server_chr->filename, "unix:", 5) == 0)) {
@@ -744,8 +693,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
/* allocate/initialize space for interrupt handling */
s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer));
- pci_register_bar(&s->dev, 2, s->ivshmem_size,
- PCI_BASE_ADDRESS_SPACE_MEMORY, ivshmem_map);
+ pci_register_bar(&s->dev, 2,
+ PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem);
s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *));
@@ -792,7 +741,10 @@ static int pci_ivshmem_uninit(PCIDevice *dev)
{
IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
- cpu_unregister_io_memory(s->ivshmem_mmio_io_addr);
+ memory_region_destroy(&s->ivshmem_mmio);
+ memory_region_del_subregion(&s->bar, &s->ivshmem);
+ memory_region_destroy(&s->ivshmem);
+ memory_region_destroy(&s->bar);
unregister_savevm(&dev->qdev, "ivshmem", s);
return 0;
diff --git a/hw/kvmclock.c b/hw/kvmclock.c
index 692ad182f0..b73aec409c 100644
--- a/hw/kvmclock.c
+++ b/hw/kvmclock.c
@@ -101,11 +101,8 @@ static SysBusDeviceInfo kvmclock_info = {
void kvmclock_create(void)
{
if (kvm_enabled() &&
- first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE)
-#ifdef KVM_FEATURE_CLOCKSOURCE2
- || (1ULL << KVM_FEATURE_CLOCKSOURCE2)
-#endif
- )) {
+ first_cpu->cpuid_kvm_features & ((1ULL << KVM_FEATURE_CLOCKSOURCE) |
+ (1ULL << KVM_FEATURE_CLOCKSOURCE2))) {
sysbus_create_simple("kvmclock", -1, NULL);
}
}
diff --git a/hw/lance.c b/hw/lance.c
index ddb1cbb7a4..d83e7f57a9 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -55,8 +55,8 @@ static void parent_lance_reset(void *opaque, int irq, int level)
pcnet_h_reset(&d->state);
}
-static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void lance_mem_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
SysBusPCNetState *d = opaque;
@@ -64,7 +64,8 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
pcnet_ioport_writew(&d->state, addr, val & 0xffff);
}
-static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
+static uint64_t lance_mem_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
SysBusPCNetState *d = opaque;
uint32_t val;
@@ -74,16 +75,14 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
return val & 0xffff;
}
-static CPUReadMemoryFunc * const lance_mem_read[3] = {
- NULL,
- lance_mem_readw,
- NULL,
-};
-
-static CPUWriteMemoryFunc * const lance_mem_write[3] = {
- NULL,
- lance_mem_writew,
- NULL,
+static const MemoryRegionOps lance_mem_ops = {
+ .read = lance_mem_read,
+ .write = lance_mem_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 2,
+ .max_access_size = 2,
+ },
};
static void lance_cleanup(VLANClientState *nc)
@@ -117,13 +116,11 @@ static int lance_init(SysBusDevice *dev)
SysBusPCNetState *d = FROM_SYSBUS(SysBusPCNetState, dev);
PCNetState *s = &d->state;
- s->mmio_index =
- cpu_register_io_memory(lance_mem_read, lance_mem_write, d,
- DEVICE_NATIVE_ENDIAN);
+ memory_region_init_io(&s->mmio, &lance_mem_ops, d, "lance-mmio", 4);
qdev_init_gpio_in(&dev->qdev, parent_lance_reset, 1);
- sysbus_init_mmio(dev, 4, s->mmio_index);
+ sysbus_init_mmio_region(dev, &s->mmio);
sysbus_init_irq(dev, &s->irq);
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index e9904c49d9..d067a0227e 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -185,9 +185,9 @@ typedef struct lsi_request {
typedef struct {
PCIDevice dev;
- int mmio_io_addr;
- int ram_io_addr;
- uint32_t script_ram_base;
+ MemoryRegion mmio_io;
+ MemoryRegion ram_io;
+ MemoryRegion io_io;
int carry; /* ??? Should this be an a visible register somewhere? */
int status;
@@ -391,10 +391,9 @@ static inline uint32_t read_dword(LSIState *s, uint32_t addr)
{
uint32_t buf;
- /* Optimize reading from SCRIPTS RAM. */
- if ((addr & 0xffffe000) == s->script_ram_base) {
- return s->script_ram[(addr & 0x1fff) >> 2];
- }
+ /* XXX: an optimization here used to fast-path the read from scripts
+ * memory. But that bypasses any iommu.
+ */
cpu_physical_memory_read(addr, (uint8_t *)&buf, 4);
return cpu_to_le32(buf);
}
@@ -1899,232 +1898,90 @@ static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)
#undef CASE_SET_REG32
}
-static void lsi_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void lsi_mmio_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
LSIState *s = opaque;
lsi_reg_writeb(s, addr & 0xff, val);
}
-static void lsi_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LSIState *s = opaque;
-
- addr &= 0xff;
- lsi_reg_writeb(s, addr, val & 0xff);
- lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-}
-
-static void lsi_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LSIState *s = opaque;
-
- addr &= 0xff;
- lsi_reg_writeb(s, addr, val & 0xff);
- lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
- lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
- lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);
-}
-
-static uint32_t lsi_mmio_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t lsi_mmio_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
LSIState *s = opaque;
return lsi_reg_readb(s, addr & 0xff);
}
-static uint32_t lsi_mmio_readw(void *opaque, target_phys_addr_t addr)
-{
- LSIState *s = opaque;
- uint32_t val;
-
- addr &= 0xff;
- val = lsi_reg_readb(s, addr);
- val |= lsi_reg_readb(s, addr + 1) << 8;
- return val;
-}
-
-static uint32_t lsi_mmio_readl(void *opaque, target_phys_addr_t addr)
-{
- LSIState *s = opaque;
- uint32_t val;
- addr &= 0xff;
- val = lsi_reg_readb(s, addr);
- val |= lsi_reg_readb(s, addr + 1) << 8;
- val |= lsi_reg_readb(s, addr + 2) << 16;
- val |= lsi_reg_readb(s, addr + 3) << 24;
- return val;
-}
-
-static CPUReadMemoryFunc * const lsi_mmio_readfn[3] = {
- lsi_mmio_readb,
- lsi_mmio_readw,
- lsi_mmio_readl,
-};
-
-static CPUWriteMemoryFunc * const lsi_mmio_writefn[3] = {
- lsi_mmio_writeb,
- lsi_mmio_writew,
- lsi_mmio_writel,
+static const MemoryRegionOps lsi_mmio_ops = {
+ .read = lsi_mmio_read,
+ .write = lsi_mmio_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
};
-static void lsi_ram_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void lsi_ram_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
LSIState *s = opaque;
uint32_t newval;
+ uint32_t mask;
int shift;
- addr &= 0x1fff;
newval = s->script_ram[addr >> 2];
shift = (addr & 3) * 8;
- newval &= ~(0xff << shift);
+ mask = ((uint64_t)1 << (size * 8)) - 1;
+ newval &= ~(mask << shift);
newval |= val << shift;
s->script_ram[addr >> 2] = newval;
}
-static void lsi_ram_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LSIState *s = opaque;
- uint32_t newval;
-
- addr &= 0x1fff;
- newval = s->script_ram[addr >> 2];
- if (addr & 2) {
- newval = (newval & 0xffff) | (val << 16);
- } else {
- newval = (newval & 0xffff0000) | val;
- }
- s->script_ram[addr >> 2] = newval;
-}
-
-
-static void lsi_ram_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- LSIState *s = opaque;
-
- addr &= 0x1fff;
- s->script_ram[addr >> 2] = val;
-}
-
-static uint32_t lsi_ram_readb(void *opaque, target_phys_addr_t addr)
+static uint64_t lsi_ram_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
LSIState *s = opaque;
uint32_t val;
+ uint32_t mask;
- addr &= 0x1fff;
val = s->script_ram[addr >> 2];
+ mask = ((uint64_t)1 << (size * 8)) - 1;
val >>= (addr & 3) * 8;
- return val & 0xff;
-}
-
-static uint32_t lsi_ram_readw(void *opaque, target_phys_addr_t addr)
-{
- LSIState *s = opaque;
- uint32_t val;
-
- addr &= 0x1fff;
- val = s->script_ram[addr >> 2];
- if (addr & 2)
- val >>= 16;
- return val;
-}
-
-static uint32_t lsi_ram_readl(void *opaque, target_phys_addr_t addr)
-{
- LSIState *s = opaque;
-
- addr &= 0x1fff;
- return s->script_ram[addr >> 2];
+ return val & mask;
}
-static CPUReadMemoryFunc * const lsi_ram_readfn[3] = {
- lsi_ram_readb,
- lsi_ram_readw,
- lsi_ram_readl,
+static const MemoryRegionOps lsi_ram_ops = {
+ .read = lsi_ram_read,
+ .write = lsi_ram_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
-static CPUWriteMemoryFunc * const lsi_ram_writefn[3] = {
- lsi_ram_writeb,
- lsi_ram_writew,
- lsi_ram_writel,
-};
-
-static uint32_t lsi_io_readb(void *opaque, uint32_t addr)
+static uint64_t lsi_io_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
LSIState *s = opaque;
return lsi_reg_readb(s, addr & 0xff);
}
-static uint32_t lsi_io_readw(void *opaque, uint32_t addr)
-{
- LSIState *s = opaque;
- uint32_t val;
- addr &= 0xff;
- val = lsi_reg_readb(s, addr);
- val |= lsi_reg_readb(s, addr + 1) << 8;
- return val;
-}
-
-static uint32_t lsi_io_readl(void *opaque, uint32_t addr)
-{
- LSIState *s = opaque;
- uint32_t val;
- addr &= 0xff;
- val = lsi_reg_readb(s, addr);
- val |= lsi_reg_readb(s, addr + 1) << 8;
- val |= lsi_reg_readb(s, addr + 2) << 16;
- val |= lsi_reg_readb(s, addr + 3) << 24;
- return val;
-}
-
-static void lsi_io_writeb(void *opaque, uint32_t addr, uint32_t val)
+static void lsi_io_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
LSIState *s = opaque;
lsi_reg_writeb(s, addr & 0xff, val);
}
-static void lsi_io_writew(void *opaque, uint32_t addr, uint32_t val)
-{
- LSIState *s = opaque;
- addr &= 0xff;
- lsi_reg_writeb(s, addr, val & 0xff);
- lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
-}
-
-static void lsi_io_writel(void *opaque, uint32_t addr, uint32_t val)
-{
- LSIState *s = opaque;
- addr &= 0xff;
- lsi_reg_writeb(s, addr, val & 0xff);
- lsi_reg_writeb(s, addr + 1, (val >> 8) & 0xff);
- lsi_reg_writeb(s, addr + 2, (val >> 16) & 0xff);
- lsi_reg_writeb(s, addr + 3, (val >> 24) & 0xff);
-}
-
-static void lsi_io_mapfunc(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- LSIState *s = DO_UPCAST(LSIState, dev, pci_dev);
-
- DPRINTF("Mapping IO at %08"FMT_PCIBUS"\n", addr);
-
- register_ioport_write(addr, 256, 1, lsi_io_writeb, s);
- register_ioport_read(addr, 256, 1, lsi_io_readb, s);
- register_ioport_write(addr, 256, 2, lsi_io_writew, s);
- register_ioport_read(addr, 256, 2, lsi_io_readw, s);
- register_ioport_write(addr, 256, 4, lsi_io_writel, s);
- register_ioport_read(addr, 256, 4, lsi_io_readl, s);
-}
-
-static void lsi_ram_mapfunc(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- LSIState *s = DO_UPCAST(LSIState, dev, pci_dev);
-
- DPRINTF("Mapping ram at %08"FMT_PCIBUS"\n", addr);
- s->script_ram_base = addr;
- cpu_register_physical_memory(addr + 0, 0x2000, s->ram_io_addr);
-}
+static const MemoryRegionOps lsi_io_ops = {
+ .read = lsi_io_read,
+ .write = lsi_io_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
+};
static void lsi_scsi_reset(DeviceState *dev)
{
@@ -2231,8 +2088,9 @@ static int lsi_scsi_uninit(PCIDevice *d)
{
LSIState *s = DO_UPCAST(LSIState, dev, d);
- cpu_unregister_io_memory(s->mmio_io_addr);
- cpu_unregister_io_memory(s->ram_io_addr);
+ memory_region_destroy(&s->mmio_io);
+ memory_region_destroy(&s->ram_io);
+ memory_region_destroy(&s->io_io);
return 0;
}
@@ -2256,18 +2114,13 @@ static int lsi_scsi_init(PCIDevice *dev)
/* Interrupt pin 1 */
pci_conf[PCI_INTERRUPT_PIN] = 0x01;
- s->mmio_io_addr = cpu_register_io_memory(lsi_mmio_readfn,
- lsi_mmio_writefn, s,
- DEVICE_NATIVE_ENDIAN);
- s->ram_io_addr = cpu_register_io_memory(lsi_ram_readfn,
- lsi_ram_writefn, s,
- DEVICE_NATIVE_ENDIAN);
-
- pci_register_bar(&s->dev, 0, 256,
- PCI_BASE_ADDRESS_SPACE_IO, lsi_io_mapfunc);
- pci_register_bar_simple(&s->dev, 1, 0x400, 0, s->mmio_io_addr);
- pci_register_bar(&s->dev, 2, 0x2000,
- PCI_BASE_ADDRESS_SPACE_MEMORY, lsi_ram_mapfunc);
+ memory_region_init_io(&s->mmio_io, &lsi_mmio_ops, s, "lsi-mmio", 0x400);
+ memory_region_init_io(&s->ram_io, &lsi_ram_ops, s, "lsi-ram", 0x2000);
+ memory_region_init_io(&s->io_io, &lsi_io_ops, s, "lsi-io", 256);
+
+ pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_io);
+ pci_register_bar(&s->dev, 1, 0, &s->mmio_io);
+ pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io);
QTAILQ_INIT(&s->queue);
scsi_bus_new(&s->bus, &dev->qdev, 1, LSI_MAX_DEVS, &lsi_scsi_ops);
diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c
index ed4458e3bb..350d901edc 100644
--- a/hw/mac_dbdma.c
+++ b/hw/mac_dbdma.c
@@ -166,6 +166,7 @@ typedef struct DBDMA_channel {
} DBDMA_channel;
typedef struct {
+ MemoryRegion mem;
DBDMA_channel channels[DBDMA_CHANNELS];
} DBDMAState;
@@ -703,8 +704,8 @@ dbdma_control_write(DBDMA_channel *ch)
ch->flush(&ch->io);
}
-static void dbdma_writel (void *opaque,
- target_phys_addr_t addr, uint32_t value)
+static void dbdma_write(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
{
int channel = addr >> DBDMA_CHANNEL_SHIFT;
DBDMAState *s = opaque;
@@ -753,7 +754,8 @@ static void dbdma_writel (void *opaque,
}
}
-static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t dbdma_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
uint32_t value;
int channel = addr >> DBDMA_CHANNEL_SHIFT;
@@ -798,16 +800,14 @@ static uint32_t dbdma_readl (void *opaque, target_phys_addr_t addr)
return value;
}
-static CPUWriteMemoryFunc * const dbdma_write[] = {
- NULL,
- NULL,
- dbdma_writel,
-};
-
-static CPUReadMemoryFunc * const dbdma_read[] = {
- NULL,
- NULL,
- dbdma_readl,
+static const MemoryRegionOps dbdma_ops = {
+ .read = dbdma_read,
+ .write = dbdma_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
};
static const VMStateDescription vmstate_dbdma_channel = {
@@ -842,14 +842,14 @@ static void dbdma_reset(void *opaque)
memset(s->channels[i].regs, 0, DBDMA_SIZE);
}
-void* DBDMA_init (int *dbdma_mem_index)
+void* DBDMA_init (MemoryRegion **dbdma_mem)
{
DBDMAState *s;
s = qemu_mallocz(sizeof(DBDMAState));
- *dbdma_mem_index = cpu_register_io_memory(dbdma_read, dbdma_write, s,
- DEVICE_LITTLE_ENDIAN);
+ memory_region_init_io(&s->mem, &dbdma_ops, s, "dbdma", 0x1000);
+ *dbdma_mem = &s->mem;
vmstate_register(NULL, -1, &vmstate_dbdma, s);
qemu_register_reset(dbdma_reset, s);
diff --git a/hw/mac_dbdma.h b/hw/mac_dbdma.h
index d236c5b3f2..933e17c5b9 100644
--- a/hw/mac_dbdma.h
+++ b/hw/mac_dbdma.h
@@ -20,6 +20,8 @@
* THE SOFTWARE.
*/
+#include "memory.h"
+
typedef struct DBDMA_io DBDMA_io;
typedef void (*DBDMA_flush)(DBDMA_io *io);
@@ -40,4 +42,4 @@ void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
DBDMA_rw rw, DBDMA_flush flush,
void *opaque);
void DBDMA_schedule(void);
-void* DBDMA_init (int *dbdma_mem_index);
+void* DBDMA_init (MemoryRegion **dbdma_mem);
diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index 61e53d28b4..ced1e585da 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -39,7 +39,7 @@
struct MacIONVRAMState {
uint32_t size;
- int mem_index;
+ MemoryRegion mem;
unsigned int it_shift;
uint8_t *data;
};
@@ -71,8 +71,8 @@ void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val)
}
/* macio style NVRAM device */
-static void macio_nvram_writeb (void *opaque,
- target_phys_addr_t addr, uint32_t value)
+static void macio_nvram_writeb(void *opaque, target_phys_addr_t addr,
+ uint64_t value, unsigned size)
{
MacIONVRAMState *s = opaque;
@@ -81,7 +81,8 @@ static void macio_nvram_writeb (void *opaque,
NVR_DPRINTF("writeb addr %04x val %x\n", (int)addr, value);
}
-static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
+static uint64_t macio_nvram_readb(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
MacIONVRAMState *s = opaque;
uint32_t value;
@@ -93,16 +94,10 @@ static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr)
return value;
}
-static CPUWriteMemoryFunc * const nvram_write[] = {
- &macio_nvram_writeb,
- &macio_nvram_writeb,
- &macio_nvram_writeb,
-};
-
-static CPUReadMemoryFunc * const nvram_read[] = {
- &macio_nvram_readb,
- &macio_nvram_readb,
- &macio_nvram_readb,
+static const MemoryRegionOps macio_nvram_ops = {
+ .read = macio_nvram_readb,
+ .write = macio_nvram_writeb,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static const VMStateDescription vmstate_macio_nvram = {
@@ -121,7 +116,7 @@ static void macio_nvram_reset(void *opaque)
{
}
-MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
+MacIONVRAMState *macio_nvram_init (target_phys_addr_t size,
unsigned int it_shift)
{
MacIONVRAMState *s;
@@ -131,22 +126,18 @@ MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
s->size = size;
s->it_shift = it_shift;
- s->mem_index = cpu_register_io_memory(nvram_read, nvram_write, s,
- DEVICE_NATIVE_ENDIAN);
- *mem_index = s->mem_index;
+ memory_region_init_io(&s->mem, &macio_nvram_ops, s, "macio-nvram",
+ size << it_shift);
vmstate_register(NULL, -1, &vmstate_macio_nvram, s);
qemu_register_reset(macio_nvram_reset, s);
return s;
}
-void macio_nvram_map (void *opaque, target_phys_addr_t mem_base)
+void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
+ target_phys_addr_t mem_base)
{
- MacIONVRAMState *s;
-
- s = opaque;
- cpu_register_physical_memory(mem_base, s->size << s->it_shift,
- s->mem_index);
+ memory_region_add_subregion(bar, mem_base, &s->mem);
}
/* Set up a system OpenBIOS NVRAM partition */
diff --git a/hw/macio.c b/hw/macio.c
index 789ca5529d..cc6ae40050 100644
--- a/hw/macio.c
+++ b/hw/macio.c
@@ -30,58 +30,55 @@
typedef struct macio_state_t macio_state_t;
struct macio_state_t {
int is_oldworld;
- int pic_mem_index;
- int dbdma_mem_index;
- int cuda_mem_index;
- int escc_mem_index;
+ MemoryRegion bar;
+ MemoryRegion *pic_mem;
+ MemoryRegion *dbdma_mem;
+ MemoryRegion *cuda_mem;
+ MemoryRegion *escc_mem;
void *nvram;
int nb_ide;
- int ide_mem_index[4];
+ MemoryRegion *ide_mem[4];
};
-static void macio_map (PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static void macio_bar_setup(macio_state_t *macio_state)
{
- macio_state_t *macio_state;
int i;
+ MemoryRegion *bar = &macio_state->bar;
- macio_state = (macio_state_t *)(pci_dev + 1);
- if (macio_state->pic_mem_index >= 0) {
+ memory_region_init(bar, "macio", 0x80000);
+ if (macio_state->pic_mem) {
if (macio_state->is_oldworld) {
/* Heathrow PIC */
- cpu_register_physical_memory(addr + 0x00000, 0x1000,
- macio_state->pic_mem_index);
+ memory_region_add_subregion(bar, 0x00000, macio_state->pic_mem);
} else {
/* OpenPIC */
- cpu_register_physical_memory(addr + 0x40000, 0x40000,
- macio_state->pic_mem_index);
+ memory_region_add_subregion(bar, 0x40000, macio_state->pic_mem);
}
}
- if (macio_state->dbdma_mem_index >= 0) {
- cpu_register_physical_memory(addr + 0x08000, 0x1000,
- macio_state->dbdma_mem_index);
+ if (macio_state->dbdma_mem) {
+ memory_region_add_subregion(bar, 0x08000, macio_state->dbdma_mem);
}
- if (macio_state->escc_mem_index >= 0) {
- cpu_register_physical_memory(addr + 0x13000, ESCC_SIZE << 4,
- macio_state->escc_mem_index);
+ if (macio_state->escc_mem) {
+ memory_region_add_subregion(bar, 0x13000, macio_state->escc_mem);
}
- if (macio_state->cuda_mem_index >= 0) {
- cpu_register_physical_memory(addr + 0x16000, 0x2000,
- macio_state->cuda_mem_index);
+ if (macio_state->cuda_mem) {
+ memory_region_add_subregion(bar, 0x16000, macio_state->cuda_mem);
}
for (i = 0; i < macio_state->nb_ide; i++) {
- if (macio_state->ide_mem_index[i] >= 0) {
- cpu_register_physical_memory(addr + 0x1f000 + (i * 0x1000), 0x1000,
- macio_state->ide_mem_index[i]);
+ if (macio_state->ide_mem[i]) {
+ memory_region_add_subregion(bar, 0x1f000 + (i * 0x1000),
+ macio_state->ide_mem[i]);
}
}
if (macio_state->nvram != NULL)
- macio_nvram_map(macio_state->nvram, addr + 0x60000);
+ macio_nvram_setup_bar(macio_state->nvram, bar, 0x60000);
}
-void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
- int dbdma_mem_index, int cuda_mem_index, void *nvram,
- int nb_ide, int *ide_mem_index, int escc_mem_index)
+void macio_init (PCIBus *bus, int device_id, int is_oldworld,
+ MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+ MemoryRegion *cuda_mem, void *nvram,
+ int nb_ide, MemoryRegion **ide_mem,
+ MemoryRegion *escc_mem)
{
PCIDevice *d;
macio_state_t *macio_state;
@@ -92,18 +89,18 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
-1, NULL, NULL);
macio_state = (macio_state_t *)(d + 1);
macio_state->is_oldworld = is_oldworld;
- macio_state->pic_mem_index = pic_mem_index;
- macio_state->dbdma_mem_index = dbdma_mem_index;
- macio_state->cuda_mem_index = cuda_mem_index;
- macio_state->escc_mem_index = escc_mem_index;
+ macio_state->pic_mem = pic_mem;
+ macio_state->dbdma_mem = dbdma_mem;
+ macio_state->cuda_mem = cuda_mem;
+ macio_state->escc_mem = escc_mem;
macio_state->nvram = nvram;
if (nb_ide > 4)
nb_ide = 4;
macio_state->nb_ide = nb_ide;
for (i = 0; i < nb_ide; i++)
- macio_state->ide_mem_index[i] = ide_mem_index[i];
+ macio_state->ide_mem[i] = ide_mem[i];
for (; i < 4; i++)
- macio_state->ide_mem_index[i] = -1;
+ macio_state->ide_mem[i] = NULL;
/* Note: this code is strongly inspirated from the corresponding code
in PearPC */
@@ -113,6 +110,6 @@ void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
d->config[0x3d] = 0x01; // interrupt on pin 1
- pci_register_bar(d, 0, 0x80000,
- PCI_BASE_ADDRESS_SPACE_MEMORY, macio_map);
+ macio_bar_setup(macio_state);
+ pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &macio_state->bar);
}
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index 75c85aeb6f..fe4eedb2cb 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -25,7 +25,7 @@
#include "sysbus.h"
#include "trace.h"
#include "console.h"
-#include "usb.h"
+#include "hid.h"
#include "qemu-error.h"
enum {
@@ -46,9 +46,8 @@ enum {
struct MilkymistSoftUsbState {
SysBusDevice busdev;
- USBBus usbbus;
- USBPort usbport[2];
- USBDevice *usbdev;
+ HIDState hid_kbd;
+ HIDState hid_mouse;
qemu_irq irq;
@@ -62,13 +61,10 @@ struct MilkymistSoftUsbState {
uint32_t regs[R_MAX];
/* mouse state */
- int mouse_dx;
- int mouse_dy;
- int mouse_dz;
- uint8_t mouse_buttons_state;
+ uint8_t mouse_hid_buffer[4];
/* keyboard state */
- uint8_t kbd_usb_buffer[8];
+ uint8_t kbd_hid_buffer[8];
};
typedef struct MilkymistSoftUsbState MilkymistSoftUsbState;
@@ -177,16 +173,10 @@ static inline void softusb_write_pmem(MilkymistSoftUsbState *s,
static void softusb_mouse_changed(MilkymistSoftUsbState *s)
{
uint8_t m;
- uint8_t buf[4];
-
- buf[0] = s->mouse_buttons_state;
- buf[1] = s->mouse_dx;
- buf[2] = s->mouse_dy;
- buf[3] = s->mouse_dz;
softusb_read_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
trace_milkymist_softusb_mevt(m);
- softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, buf, 4);
+ softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, s->mouse_hid_buffer, 4);
m = (m + 1) & 0xf;
softusb_write_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
@@ -200,7 +190,7 @@ static void softusb_kbd_changed(MilkymistSoftUsbState *s)
softusb_read_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
trace_milkymist_softusb_kevt(m);
- softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_usb_buffer, 8);
+ softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_hid_buffer, 8);
m = (m + 1) & 0x7;
softusb_write_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
@@ -208,62 +198,42 @@ static void softusb_kbd_changed(MilkymistSoftUsbState *s)
qemu_irq_pulse(s->irq);
}
-static void softusb_mouse_event(void *opaque,
- int dx, int dy, int dz, int buttons_state)
+static void softusb_kbd_hid_datain(HIDState *hs)
{
- MilkymistSoftUsbState *s = opaque;
+ MilkymistSoftUsbState *s = container_of(hs, MilkymistSoftUsbState, hid_kbd);
+ int len;
/* if device is in reset, do nothing */
if (s->regs[R_CTRL] & CTRL_RESET) {
return;
}
- trace_milkymist_softusb_mouse_event(dx, dy, dz, buttons_state);
+ len = hid_keyboard_poll(hs, s->kbd_hid_buffer, sizeof(s->kbd_hid_buffer));
- s->mouse_dx = dx;
- s->mouse_dy = dy;
- s->mouse_dz = dz;
- s->mouse_buttons_state = buttons_state;
-
- softusb_mouse_changed(s);
+ if (len == 8) {
+ softusb_kbd_changed(s);
+ }
}
-static void softusb_usbdev_datain(void *opaque)
+static void softusb_mouse_hid_datain(HIDState *hs)
{
- MilkymistSoftUsbState *s = opaque;
-
- USBPacket p;
-
- usb_packet_init(&p);
- usb_packet_setup(&p, USB_TOKEN_IN, 0, 1);
- usb_packet_addbuf(&p, s->kbd_usb_buffer, sizeof(s->kbd_usb_buffer));
- s->usbdev->info->handle_data(s->usbdev, &p);
- usb_packet_cleanup(&p);
-
- softusb_kbd_changed(s);
-}
+ MilkymistSoftUsbState *s =
+ container_of(hs, MilkymistSoftUsbState, hid_mouse);
+ int len;
-static void softusb_attach(USBPort *port)
-{
-}
+ /* if device is in reset, do nothing */
+ if (s->regs[R_CTRL] & CTRL_RESET) {
+ return;
+ }
-static void softusb_detach(USBPort *port)
-{
-}
+ len = hid_pointer_poll(hs, s->mouse_hid_buffer,
+ sizeof(s->mouse_hid_buffer));
-static void softusb_child_detach(USBPort *port, USBDevice *child)
-{
+ if (len == 4) {
+ softusb_mouse_changed(s);
+ }
}
-static USBPortOps softusb_ops = {
- .attach = softusb_attach,
- .detach = softusb_detach,
- .child_detach = softusb_child_detach,
-};
-
-static USBBusOps softusb_bus_ops = {
-};
-
static void milkymist_softusb_reset(DeviceState *d)
{
MilkymistSoftUsbState *s =
@@ -273,11 +243,11 @@ static void milkymist_softusb_reset(DeviceState *d)
for (i = 0; i < R_MAX; i++) {
s->regs[i] = 0;
}
- s->mouse_dx = 0;
- s->mouse_dy = 0;
- s->mouse_dz = 0;
- s->mouse_buttons_state = 0;
- memset(s->kbd_usb_buffer, 0, sizeof(s->kbd_usb_buffer));
+ memset(s->kbd_hid_buffer, 0, sizeof(s->kbd_hid_buffer));
+ memset(s->mouse_hid_buffer, 0, sizeof(s->mouse_hid_buffer));
+
+ hid_reset(&s->hid_kbd);
+ hid_reset(&s->hid_mouse);
/* defaults */
s->regs[R_CTRL] = CTRL_RESET;
@@ -304,23 +274,8 @@ static int milkymist_softusb_init(SysBusDevice *dev)
cpu_register_physical_memory(s->dmem_base, s->dmem_size,
dmem_ram | IO_MEM_RAM);
- qemu_add_mouse_event_handler(softusb_mouse_event, s, 0, "Milkymist Mouse");
-
- /* create our usb bus */
- usb_bus_new(&s->usbbus, &softusb_bus_ops, NULL);
-
- /* our two ports */
- /* FIXME: claim to support full speed devices. qemu mouse and keyboard
- * report themselves as full speed devices. */
- usb_register_port(&s->usbbus, &s->usbport[0], NULL, 0, &softusb_ops,
- USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
- usb_register_port(&s->usbbus, &s->usbport[1], NULL, 1, &softusb_ops,
- USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
-
- /* and finally create an usb keyboard */
- s->usbdev = usb_create_simple(&s->usbbus, "usb-kbd");
- usb_hid_datain_cb(s->usbdev, s, softusb_usbdev_datain);
- s->usbdev->info->handle_reset(s->usbdev);
+ hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
+ hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
return 0;
}
@@ -332,11 +287,10 @@ static const VMStateDescription vmstate_milkymist_softusb = {
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, MilkymistSoftUsbState, R_MAX),
- VMSTATE_INT32(mouse_dx, MilkymistSoftUsbState),
- VMSTATE_INT32(mouse_dy, MilkymistSoftUsbState),
- VMSTATE_INT32(mouse_dz, MilkymistSoftUsbState),
- VMSTATE_UINT8(mouse_buttons_state, MilkymistSoftUsbState),
- VMSTATE_BUFFER(kbd_usb_buffer, MilkymistSoftUsbState),
+ VMSTATE_HID_KEYBOARD_DEVICE(hid_kbd, MilkymistSoftUsbState),
+ VMSTATE_HID_POINTER_DEVICE(hid_mouse, MilkymistSoftUsbState),
+ VMSTATE_BUFFER(kbd_hid_buffer, MilkymistSoftUsbState),
+ VMSTATE_BUFFER(mouse_hid_buffer, MilkymistSoftUsbState),
VMSTATE_END_OF_LIST()
}
};
diff --git a/hw/msix.c b/hw/msix.c
index e67e700a33..8536c3fc80 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -82,7 +82,8 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
return 0;
}
-static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t msix_mmio_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
PCIDevice *dev = opaque;
unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
@@ -91,12 +92,6 @@ static uint32_t msix_mmio_readl(void *opaque, target_phys_addr_t addr)
return pci_get_long(page + offset);
}
-static uint32_t msix_mmio_read_unallowed(void *opaque, target_phys_addr_t addr)
-{
- fprintf(stderr, "MSI-X: only dword read is allowed!\n");
- return 0;
-}
-
static uint8_t msix_pending_mask(int vector)
{
return 1 << (vector % 8);
@@ -169,8 +164,8 @@ void msix_write_config(PCIDevice *dev, uint32_t addr,
}
}
-static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
- uint32_t val)
+static void msix_mmio_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
PCIDevice *dev = opaque;
unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
@@ -179,37 +174,25 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
msix_handle_mask_update(dev, vector);
}
-static void msix_mmio_write_unallowed(void *opaque, target_phys_addr_t addr,
- uint32_t val)
-{
- fprintf(stderr, "MSI-X: only dword write is allowed!\n");
-}
-
-static CPUWriteMemoryFunc * const msix_mmio_write[] = {
- msix_mmio_write_unallowed, msix_mmio_write_unallowed, msix_mmio_writel
-};
-
-static CPUReadMemoryFunc * const msix_mmio_read[] = {
- msix_mmio_read_unallowed, msix_mmio_read_unallowed, msix_mmio_readl
+static const MemoryRegionOps msix_mmio_ops = {
+ .read = msix_mmio_read,
+ .write = msix_mmio_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
};
-/* Should be called from device's map method. */
-void msix_mmio_map(PCIDevice *d, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static void msix_mmio_setup(PCIDevice *d, MemoryRegion *bar)
{
uint8_t *config = d->config + d->msix_cap;
uint32_t table = pci_get_long(config + PCI_MSIX_TABLE);
uint32_t offset = table & ~(MSIX_PAGE_SIZE - 1);
/* TODO: for assigned devices, we'll want to make it possible to map
* pending bits separately in case they are in a separate bar. */
- int table_bir = table & PCI_MSIX_FLAGS_BIRMASK;
- if (table_bir != region_num)
- return;
- if (size <= offset)
- return;
- cpu_register_physical_memory(addr + offset, size - offset,
- d->msix_mmio_index);
+ memory_region_add_subregion(bar, offset, &d->msix_mmio);
}
static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
@@ -225,6 +208,7 @@ static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
/* Initialize the MSI-X structures. Note: if MSI-X is supported, BAR size is
* modified, it should be retrieved with msix_bar_size. */
int msix_init(struct PCIDevice *dev, unsigned short nentries,
+ MemoryRegion *bar,
unsigned bar_nr, unsigned bar_size)
{
int ret;
@@ -241,13 +225,8 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
dev->msix_table_page = qemu_mallocz(MSIX_PAGE_SIZE);
msix_mask_all(dev, nentries);
- dev->msix_mmio_index = cpu_register_io_memory(msix_mmio_read,
- msix_mmio_write, dev,
- DEVICE_NATIVE_ENDIAN);
- if (dev->msix_mmio_index == -1) {
- ret = -EBUSY;
- goto err_index;
- }
+ memory_region_init_io(&dev->msix_mmio, &msix_mmio_ops, dev,
+ "msix", MSIX_PAGE_SIZE);
dev->msix_entries_nr = nentries;
ret = msix_add_config(dev, nentries, bar_nr, bar_size);
@@ -255,12 +234,12 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
goto err_config;
dev->cap_present |= QEMU_PCI_CAP_MSIX;
+ msix_mmio_setup(dev, bar);
return 0;
err_config:
dev->msix_entries_nr = 0;
- cpu_unregister_io_memory(dev->msix_mmio_index);
-err_index:
+ memory_region_destroy(&dev->msix_mmio);
qemu_free(dev->msix_table_page);
dev->msix_table_page = NULL;
qemu_free(dev->msix_entry_used);
@@ -279,7 +258,7 @@ static void msix_free_irq_entries(PCIDevice *dev)
}
/* Clean up resources for the device. */
-int msix_uninit(PCIDevice *dev)
+int msix_uninit(PCIDevice *dev, MemoryRegion *bar)
{
if (!(dev->cap_present & QEMU_PCI_CAP_MSIX))
return 0;
@@ -287,7 +266,8 @@ int msix_uninit(PCIDevice *dev)
dev->msix_cap = 0;
msix_free_irq_entries(dev);
dev->msix_entries_nr = 0;
- cpu_unregister_io_memory(dev->msix_mmio_index);
+ memory_region_del_subregion(bar, &dev->msix_mmio);
+ memory_region_destroy(&dev->msix_mmio);
qemu_free(dev->msix_table_page);
dev->msix_table_page = NULL;
qemu_free(dev->msix_entry_used);
diff --git a/hw/msix.h b/hw/msix.h
index a9f7993c39..7e04336618 100644
--- a/hw/msix.h
+++ b/hw/msix.h
@@ -5,15 +5,13 @@
#include "pci.h"
int msix_init(PCIDevice *pdev, unsigned short nentries,
+ MemoryRegion *bar,
unsigned bar_nr, unsigned bar_size);
void msix_write_config(PCIDevice *pci_dev, uint32_t address,
uint32_t val, int len);
-void msix_mmio_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type);
-
-int msix_uninit(PCIDevice *d);
+int msix_uninit(PCIDevice *d, MemoryRegion *bar);
void msix_save(PCIDevice *dev, QEMUFile *f);
void msix_load(PCIDevice *dev, QEMUFile *f);
diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index e41dbbaa79..756ed5ca46 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -27,6 +27,7 @@
#include "qdev.h"
#include "net.h"
#include "ne2000.h"
+#include "exec-memory.h"
typedef struct ISANE2000State {
ISADevice dev;
@@ -66,19 +67,11 @@ static int isa_ne2000_initfn(ISADevice *dev)
ISANE2000State *isa = DO_UPCAST(ISANE2000State, dev, dev);
NE2000State *s = &isa->ne2000;
- register_ioport_write(isa->iobase, 16, 1, ne2000_ioport_write, s);
- register_ioport_read(isa->iobase, 16, 1, ne2000_ioport_read, s);
+ ne2000_setup_io(s, 0x20);
isa_init_ioport_range(dev, isa->iobase, 16);
-
- register_ioport_write(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_write, s);
- register_ioport_read(isa->iobase + 0x10, 1, 1, ne2000_asic_ioport_read, s);
- register_ioport_write(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_write, s);
- register_ioport_read(isa->iobase + 0x10, 2, 2, ne2000_asic_ioport_read, s);
isa_init_ioport_range(dev, isa->iobase + 0x10, 2);
-
- register_ioport_write(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
- register_ioport_read(isa->iobase + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
isa_init_ioport(dev, isa->iobase + 0x1f);
+ memory_region_add_subregion(get_system_io(), isa->iobase, &s->io);
isa_init_irq(dev, &s->irq, isa->isairq);
diff --git a/hw/ne2000.c b/hw/ne2000.c
index f8acaaeeb6..a035a85244 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -297,7 +297,7 @@ ssize_t ne2000_receive(VLANClientState *nc, const uint8_t *buf, size_t size_)
return size_;
}
-void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
NE2000State *s = opaque;
int offset, page, index;
@@ -394,7 +394,7 @@ void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
}
}
-uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr)
{
NE2000State *s = opaque;
int offset, page, ret;
@@ -544,7 +544,7 @@ static inline void ne2000_dma_update(NE2000State *s, int len)
}
}
-void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
NE2000State *s = opaque;
@@ -564,7 +564,7 @@ void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
}
}
-uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr)
{
NE2000State *s = opaque;
int ret;
@@ -612,12 +612,12 @@ static uint32_t ne2000_asic_ioport_readl(void *opaque, uint32_t addr)
return ret;
}
-void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
/* nothing to do (end of reset pulse) */
}
-uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
+static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
{
NE2000State *s = opaque;
ne2000_reset(s);
@@ -676,27 +676,55 @@ static const VMStateDescription vmstate_pci_ne2000 = {
}
};
-/***********************************************************/
-/* PCI NE2000 definitions */
+static uint64_t ne2000_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ NE2000State *s = opaque;
-static void ne2000_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+ if (addr < 0x10 && size == 1) {
+ return ne2000_ioport_read(s, addr);
+ } else if (addr == 0x10) {
+ if (size <= 2) {
+ return ne2000_asic_ioport_read(s, addr);
+ } else {
+ return ne2000_asic_ioport_readl(s, addr);
+ }
+ } else if (addr == 0x1f && size == 1) {
+ return ne2000_reset_ioport_read(s, addr);
+ }
+ return ((uint64_t)1 << (size * 8)) - 1;
+}
+
+static void ne2000_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
{
- PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
- NE2000State *s = &d->ne2000;
+ NE2000State *s = opaque;
+
+ if (addr < 0x10 && size == 1) {
+ return ne2000_ioport_write(s, addr, data);
+ } else if (addr == 0x10) {
+ if (size <= 2) {
+ return ne2000_asic_ioport_write(s, addr, data);
+ } else {
+ return ne2000_asic_ioport_writel(s, addr, data);
+ }
+ } else if (addr == 0x1f && size == 1) {
+ return ne2000_reset_ioport_write(s, addr, data);
+ }
+}
- register_ioport_write(addr, 16, 1, ne2000_ioport_write, s);
- register_ioport_read(addr, 16, 1, ne2000_ioport_read, s);
+static const MemoryRegionOps ne2000_ops = {
+ .read = ne2000_read,
+ .write = ne2000_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
- register_ioport_write(addr + 0x10, 1, 1, ne2000_asic_ioport_write, s);
- register_ioport_read(addr + 0x10, 1, 1, ne2000_asic_ioport_read, s);
- register_ioport_write(addr + 0x10, 2, 2, ne2000_asic_ioport_write, s);
- register_ioport_read(addr + 0x10, 2, 2, ne2000_asic_ioport_read, s);
- register_ioport_write(addr + 0x10, 4, 4, ne2000_asic_ioport_writel, s);
- register_ioport_read(addr + 0x10, 4, 4, ne2000_asic_ioport_readl, s);
+/***********************************************************/
+/* PCI NE2000 definitions */
- register_ioport_write(addr + 0x1f, 1, 1, ne2000_reset_ioport_write, s);
- register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
+void ne2000_setup_io(NE2000State *s, unsigned size)
+{
+ memory_region_init_io(&s->io, &ne2000_ops, s, "ne2000", size);
}
static void ne2000_cleanup(VLANClientState *nc)
@@ -724,9 +752,9 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
/* TODO: RST# value should be 0. PCI spec 6.2.4 */
pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
- pci_register_bar(&d->dev, 0, 0x100,
- PCI_BASE_ADDRESS_SPACE_IO, ne2000_map);
s = &d->ne2000;
+ ne2000_setup_io(s, 0x100);
+ pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
s->irq = d->dev.irq[0];
qemu_macaddr_default_if_unset(&s->c.macaddr);
@@ -754,6 +782,7 @@ static int pci_ne2000_exit(PCIDevice *pci_dev)
PCINE2000State *d = DO_UPCAST(PCINE2000State, dev, pci_dev);
NE2000State *s = &d->ne2000;
+ memory_region_destroy(&s->io);
qemu_del_vlan_client(&s->nic->nc);
return 0;
}
diff --git a/hw/ne2000.h b/hw/ne2000.h
index 54fdfca133..5fee052194 100644
--- a/hw/ne2000.h
+++ b/hw/ne2000.h
@@ -4,6 +4,7 @@
#define NE2000_MEM_SIZE NE2000_PMEM_END
typedef struct NE2000State {
+ MemoryRegion io;
uint8_t cmd;
uint32_t start;
uint32_t stop;
@@ -27,12 +28,7 @@ typedef struct NE2000State {
uint8_t mem[NE2000_MEM_SIZE];
} NE2000State;
-void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t ne2000_ioport_read(void *opaque, uint32_t addr);
-void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr);
-void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr);
+void ne2000_setup_io(NE2000State *s, unsigned size);
extern const VMStateDescription vmstate_ne2000;
void ne2000_reset(NE2000State *s);
int ne2000_can_receive(VLANClientState *vc);
diff --git a/hw/openpic.c b/hw/openpic.c
index 6d2cf994ba..ccd4a14f81 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -205,7 +205,7 @@ typedef struct IRQ_dst_t {
typedef struct openpic_t {
PCIDevice pci_dev;
- int mem_index;
+ MemoryRegion mem;
/* Global registers */
uint32_t frep; /* Feature reporting register */
uint32_t glbc; /* Global configuration register */
@@ -984,47 +984,34 @@ static uint32_t openpic_readl (void *opaque,target_phys_addr_t addr)
return retval;
}
-static CPUWriteMemoryFunc * const openpic_write[] = {
- &openpic_buggy_write,
- &openpic_buggy_write,
- &openpic_writel,
-};
+static uint64_t openpic_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ openpic_t *opp = opaque;
-static CPUReadMemoryFunc * const openpic_read[] = {
- &openpic_buggy_read,
- &openpic_buggy_read,
- &openpic_readl,
-};
+ switch (size) {
+ case 4: return openpic_readl(opp, addr);
+ default: return openpic_buggy_read(opp, addr);
+ }
+}
-static void openpic_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static void openpic_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
{
- openpic_t *opp;
+ openpic_t *opp = opaque;
- DPRINTF("Map OpenPIC\n");
- opp = (openpic_t *)pci_dev;
- /* Global registers */
- DPRINTF("Register OPENPIC gbl %08x => %08x\n",
- addr + 0x1000, addr + 0x1000 + 0x100);
- /* Timer registers */
- DPRINTF("Register OPENPIC timer %08x => %08x\n",
- addr + 0x1100, addr + 0x1100 + 0x40 * MAX_TMR);
- /* Interrupt source registers */
- DPRINTF("Register OPENPIC src %08x => %08x\n",
- addr + 0x10000, addr + 0x10000 + 0x20 * (OPENPIC_EXT_IRQ + 2));
- /* Per CPU registers */
- DPRINTF("Register OPENPIC dst %08x => %08x\n",
- addr + 0x20000, addr + 0x20000 + 0x1000 * MAX_CPU);
- cpu_register_physical_memory(addr, 0x40000, opp->mem_index);
-#if 0 // Don't implement ISU for now
- opp_io_memory = cpu_register_io_memory(openpic_src_read,
- openpic_src_write, NULL
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
- opp_io_memory);
-#endif
+ switch (size) {
+ case 4: return openpic_writel(opp, addr, data);
+ default: return openpic_buggy_write(opp, addr, data);
+ }
}
+static const MemoryRegionOps openpic_ops = {
+ .read = openpic_read,
+ .write = openpic_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q)
{
unsigned int i;
@@ -1161,7 +1148,7 @@ static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src)
qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]);
}
-qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
+qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
qemu_irq **irqs, qemu_irq irq_out)
{
openpic_t *opp;
@@ -1180,14 +1167,22 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER); // FIXME?
pci_conf[0x3d] = 0x00; // no interrupt pin
+ memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
+#if 0 // Don't implement ISU for now
+ opp_io_memory = cpu_register_io_memory(openpic_src_read,
+ openpic_src_write, NULL
+ DEVICE_NATIVE_ENDIAN);
+ cpu_register_physical_memory(isu_base, 0x20 * (EXT_IRQ + 2),
+ opp_io_memory);
+#endif
+
/* Register I/O spaces */
- pci_register_bar(&opp->pci_dev, 0, 0x40000,
- PCI_BASE_ADDRESS_SPACE_MEMORY, &openpic_map);
+ pci_register_bar(&opp->pci_dev, 0,
+ PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem);
} else {
opp = qemu_mallocz(sizeof(openpic_t));
+ memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
}
- opp->mem_index = cpu_register_io_memory(openpic_read, openpic_write, opp,
- DEVICE_LITTLE_ENDIAN);
// isu_base &= 0xFFFC0000;
opp->nb_cpus = nb_cpus;
@@ -1223,8 +1218,8 @@ qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
opp->irq_raise = openpic_irq_raise;
opp->reset = openpic_reset;
- if (pmem_index)
- *pmem_index = opp->mem_index;
+ if (pmem)
+ *pmem = &opp->mem;
return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq);
}
diff --git a/hw/openpic.h b/hw/openpic.h
index 0957c1ff00..75de3616ad 100644
--- a/hw/openpic.h
+++ b/hw/openpic.h
@@ -11,7 +11,7 @@ enum {
OPENPIC_OUTPUT_NB,
};
-qemu_irq *openpic_init (PCIBus *bus, int *pmem_index, int nb_cpus,
+qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
qemu_irq **irqs, qemu_irq irq_out);
qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
qemu_irq **irqs, qemu_irq irq_out);
diff --git a/hw/pc.h b/hw/pc.h
index a2de0fecfa..ec34db7385 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -179,7 +179,9 @@ struct PCII440FXState;
typedef struct PCII440FXState PCII440FXState;
PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
- qemu_irq *pic, MemoryRegion *address_space,
+ qemu_irq *pic,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
ram_addr_t ram_size);
void i440fx_init_memory_mappings(PCII440FXState *d);
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index c0a2abe4bc..7dd5008dce 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -69,6 +69,7 @@ static void ioapic_init(IsaIrqState *isa_irq_state)
/* PC hardware initialisation */
static void pc_init1(MemoryRegion *system_memory,
+ MemoryRegion *system_io,
ram_addr_t ram_size,
const char *boot_device,
const char *kernel_filename,
@@ -129,7 +130,7 @@ static void pc_init1(MemoryRegion *system_memory,
if (pci_enabled) {
pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq,
- system_memory, ram_size);
+ system_memory, system_io, ram_size);
} else {
pci_bus = NULL;
i440fx_state = NULL;
@@ -218,6 +219,7 @@ static void pc_init_pci(ram_addr_t ram_size,
const char *cpu_model)
{
pc_init1(get_system_memory(),
+ get_system_io(),
ram_size, boot_device,
kernel_filename, kernel_cmdline,
initrd_filename, cpu_model, 1, 1);
@@ -231,6 +233,7 @@ static void pc_init_pci_no_kvmclock(ram_addr_t ram_size,
const char *cpu_model)
{
pc_init1(get_system_memory(),
+ get_system_io(),
ram_size, boot_device,
kernel_filename, kernel_cmdline,
initrd_filename, cpu_model, 1, 0);
@@ -246,6 +249,7 @@ static void pc_init_isa(ram_addr_t ram_size,
if (cpu_model == NULL)
cpu_model = "486";
pc_init1(get_system_memory(),
+ get_system_io(),
ram_size, boot_device,
kernel_filename, kernel_cmdline,
initrd_filename, cpu_model, 0, 1);
diff --git a/hw/pci.c b/hw/pci.c
index 8621d3d2b1..dc7271a19f 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -264,13 +264,15 @@ int pci_find_domain(const PCIBus *bus)
void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
const char *name,
- MemoryRegion *address_space,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
uint8_t devfn_min)
{
qbus_create_inplace(&bus->qbus, &pci_bus_info, parent, name);
assert(PCI_FUNC(devfn_min) == 0);
bus->devfn_min = devfn_min;
- bus->address_space = address_space;
+ bus->address_space_mem = address_space_mem;
+ bus->address_space_io = address_space_io;
/* host bridge */
QLIST_INIT(&bus->child);
@@ -280,13 +282,16 @@ void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
}
PCIBus *pci_bus_new(DeviceState *parent, const char *name,
- MemoryRegion *address_space, uint8_t devfn_min)
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min)
{
PCIBus *bus;
bus = qemu_mallocz(sizeof(*bus));
bus->qbus.qdev_allocated = 1;
- pci_bus_new_inplace(bus, parent, name, address_space, devfn_min);
+ pci_bus_new_inplace(bus, parent, name, address_space_mem,
+ address_space_io, devfn_min);
return bus;
}
@@ -315,12 +320,14 @@ void pci_bus_set_mem_base(PCIBus *bus, target_phys_addr_t base)
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
void *irq_opaque,
- MemoryRegion *address_space,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
uint8_t devfn_min, int nirq)
{
PCIBus *bus;
- bus = pci_bus_new(parent, name, address_space, devfn_min);
+ bus = pci_bus_new(parent, name, address_space_mem,
+ address_space_io, devfn_min);
pci_bus_irqs(bus, set_irq, map_irq, irq_opaque, nirq);
return bus;
}
@@ -841,19 +848,7 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev)
r = &pci_dev->io_regions[i];
if (!r->size || r->addr == PCI_BAR_UNMAPPED)
continue;
- if (r->type == PCI_BASE_ADDRESS_SPACE_IO) {
- isa_unassign_ioport(r->addr, r->filtered_size);
- } else {
- if (r->memory) {
- memory_region_del_subregion(pci_dev->bus->address_space,
- r->memory);
- } else {
- cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus,
- r->addr),
- r->filtered_size,
- IO_MEM_UNASSIGNED);
- }
- }
+ memory_region_del_subregion(r->address_space, r->memory);
}
}
@@ -876,12 +871,12 @@ static int pci_unregister_device(DeviceState *dev)
}
void pci_register_bar(PCIDevice *pci_dev, int region_num,
- pcibus_t size, uint8_t type,
- PCIMapIORegionFunc *map_func)
+ uint8_t type, MemoryRegion *memory)
{
PCIIORegion *r;
uint32_t addr;
uint64_t wmask;
+ pcibus_t size = memory_region_size(memory);
assert(region_num >= 0);
assert(region_num < PCI_NUM_REGIONS);
@@ -896,8 +891,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
r->size = size;
r->filtered_size = size;
r->type = type;
- r->map_func = map_func;
- r->ram_addr = IO_MEM_UNASSIGNED;
r->memory = NULL;
wmask = ~(size - 1);
@@ -915,41 +908,16 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num,
pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff);
pci_set_long(pci_dev->cmask + addr, 0xffffffff);
}
+ pci_dev->io_regions[region_num].memory = memory;
+ pci_dev->io_regions[region_num].address_space
+ = type & PCI_BASE_ADDRESS_SPACE_IO
+ ? pci_dev->bus->address_space_io
+ : pci_dev->bus->address_space_mem;
}
-static void pci_simple_bar_mapfunc(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- cpu_register_physical_memory(addr, size,
- pci_dev->io_regions[region_num].ram_addr);
-}
-
-static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size,
- int type)
-{
- memory_region_add_subregion_overlap(pci_dev->bus->address_space,
- addr,
- pci_dev->io_regions[region_num].memory,
- 1);
-}
-
-void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
- pcibus_t size, uint8_t attr, ram_addr_t ram_addr)
-{
- pci_register_bar(pci_dev, region_num, size,
- PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
- pci_simple_bar_mapfunc);
- pci_dev->io_regions[region_num].ram_addr = ram_addr;
-}
-
-void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
- uint8_t attr, MemoryRegion *memory)
+pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num)
{
- pci_register_bar(pci_dev, region_num, memory_region_size(memory),
- PCI_BASE_ADDRESS_SPACE_MEMORY | attr,
- pci_simple_bar_mapfunc_region);
- pci_dev->io_regions[region_num].memory = memory;
+ return pci_dev->io_regions[region_num].addr;
}
static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size,
@@ -1079,28 +1047,7 @@ static void pci_update_mappings(PCIDevice *d)
/* now do the real mapping */
if (r->addr != PCI_BAR_UNMAPPED) {
- if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
- int class;
- /* NOTE: specific hack for IDE in PC case:
- only one byte must be mapped. */
- class = pci_get_word(d->config + PCI_CLASS_DEVICE);
- if (class == 0x0101 && r->size == 4) {
- isa_unassign_ioport(r->addr + 2, 1);
- } else {
- isa_unassign_ioport(r->addr, r->filtered_size);
- }
- } else {
- if (r->memory) {
- memory_region_del_subregion(d->bus->address_space,
- r->memory);
- } else {
- cpu_register_physical_memory(pci_to_cpu_addr(d->bus,
- r->addr),
- r->filtered_size,
- IO_MEM_UNASSIGNED);
- qemu_unregister_coalesced_mmio(r->addr, r->filtered_size);
- }
- }
+ memory_region_del_subregion(r->address_space, r->memory);
}
r->addr = new_addr;
r->filtered_size = filtered_size;
@@ -1113,10 +1060,16 @@ static void pci_update_mappings(PCIDevice *d)
* addr & (size - 1) != 0.
*/
if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
- r->map_func(d, i, r->addr, r->filtered_size, r->type);
+ memory_region_add_subregion_overlap(r->address_space,
+ r->addr,
+ r->memory,
+ 1);
} else {
- r->map_func(d, i, pci_to_cpu_addr(d->bus, r->addr),
- r->filtered_size, r->type);
+ memory_region_add_subregion_overlap(r->address_space,
+ pci_to_cpu_addr(d->bus,
+ r->addr),
+ r->memory,
+ 1);
}
}
}
@@ -1858,11 +1811,6 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
return next;
}
-static void pci_map_option_rom(PCIDevice *pdev, int region_num, pcibus_t addr, pcibus_t size, int type)
-{
- cpu_register_physical_memory(addr, size, pdev->rom_offset);
-}
-
/* Patch the PCI vendor and device ids in a PCI rom image if necessary.
This is needed for an option rom which is used for more than one device. */
static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size)
@@ -1966,9 +1914,9 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->vmsd->name);
else
snprintf(name, sizeof(name), "%s.rom", pdev->qdev.info->name);
- pdev->rom_offset = qemu_ram_alloc(&pdev->qdev, name, size);
-
- ptr = qemu_get_ram_ptr(pdev->rom_offset);
+ pdev->has_rom = true;
+ memory_region_init_ram(&pdev->rom, &pdev->qdev, name, size);
+ ptr = memory_region_get_ram_ptr(&pdev->rom);
load_image(path, ptr);
qemu_free(path);
@@ -1979,19 +1927,18 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
qemu_put_ram_ptr(ptr);
- pci_register_bar(pdev, PCI_ROM_SLOT, size,
- 0, pci_map_option_rom);
+ pci_register_bar(pdev, PCI_ROM_SLOT, 0, &pdev->rom);
return 0;
}
static void pci_del_option_rom(PCIDevice *pdev)
{
- if (!pdev->rom_offset)
+ if (!pdev->has_rom)
return;
- qemu_ram_free(pdev->rom_offset);
- pdev->rom_offset = 0;
+ memory_region_destroy(&pdev->rom);
+ pdev->has_rom = false;
}
/*
diff --git a/hw/pci.h b/hw/pci.h
index c51156d21c..d7ad7fb95f 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -92,9 +92,8 @@ typedef struct PCIIORegion {
pcibus_t size;
pcibus_t filtered_size;
uint8_t type;
- PCIMapIORegionFunc *map_func;
- ram_addr_t ram_addr;
MemoryRegion *memory;
+ MemoryRegion *address_space;
} PCIIORegion;
#define PCI_ROM_SLOT 6
@@ -175,7 +174,7 @@ struct PCIDevice {
/* Space to store MSIX table */
uint8_t *msix_table_page;
/* MMIO index used to map MSIX table and pending bit entries. */
- int msix_mmio_index;
+ MemoryRegion msix_mmio;
/* Reference-count for entries actually in use by driver. */
unsigned *msix_entry_used;
/* Region including the MSI-X table */
@@ -191,7 +190,8 @@ struct PCIDevice {
/* Location of option rom */
char *romfile;
- ram_addr_t rom_offset;
+ bool has_rom;
+ MemoryRegion rom;
uint32_t rom_bar;
};
@@ -201,12 +201,8 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
PCIConfigWriteFunc *config_write);
void pci_register_bar(PCIDevice *pci_dev, int region_num,
- pcibus_t size, uint8_t type,
- PCIMapIORegionFunc *map_func);
-void pci_register_bar_simple(PCIDevice *pci_dev, int region_num,
- pcibus_t size, uint8_t attr, ram_addr_t ram_addr);
-void pci_register_bar_region(PCIDevice *pci_dev, int region_num,
- uint8_t attr, MemoryRegion *memory);
+ uint8_t attr, MemoryRegion *memory);
+pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size);
@@ -238,10 +234,13 @@ typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev,
PCIHotplugState state);
void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
const char *name,
- MemoryRegion *address_space,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
uint8_t devfn_min);
PCIBus *pci_bus_new(DeviceState *parent, const char *name,
- MemoryRegion *address_space, uint8_t devfn_min);
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
+ uint8_t devfn_min);
void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
void *irq_opaque, int nirq);
int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
@@ -249,7 +248,8 @@ void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev);
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
void *irq_opaque,
- MemoryRegion *address_space,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
uint8_t devfn_min, int nirq);
void pci_device_reset(PCIDevice *dev);
void pci_bus_reset(PCIBus *bus);
diff --git a/hw/pci_internals.h b/hw/pci_internals.h
index c3a463a703..c7fd23dc54 100644
--- a/hw/pci_internals.h
+++ b/hw/pci_internals.h
@@ -25,7 +25,8 @@ struct PCIBus {
PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX];
PCIDevice *parent_dev;
target_phys_addr_t mem_base;
- MemoryRegion *address_space;
+ MemoryRegion *address_space_mem;
+ MemoryRegion *address_space_io;
QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */
QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */
diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 216cf81492..13d9380b00 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -46,6 +46,7 @@
typedef struct {
PCIDevice pci_dev;
PCNetState state;
+ MemoryRegion io_bar;
} PCIPCNetState;
static void pcnet_aprom_writeb(void *opaque, uint32_t addr, uint32_t val)
@@ -69,25 +70,41 @@ static uint32_t pcnet_aprom_readb(void *opaque, uint32_t addr)
return val;
}
-static void pcnet_ioport_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static uint64_t pcnet_ioport_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
- PCNetState *d = &DO_UPCAST(PCIPCNetState, pci_dev, pci_dev)->state;
+ PCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
- printf("pcnet_ioport_map addr=0x%04"FMT_PCIBUS" size=0x%04"FMT_PCIBUS"\n",
- addr, size);
-#endif
+ if (addr < 16 && size == 1) {
+ return pcnet_aprom_readb(d, addr);
+ } else if (addr >= 0x10 && addr < 0x20 && size == 2) {
+ return pcnet_ioport_readw(d, addr);
+ } else if (addr >= 0x10 && addr < 0x20 && size == 4) {
+ return pcnet_ioport_readl(d, addr);
+ }
+ return ((uint64_t)1 << (size * 8)) - 1;
+}
- register_ioport_write(addr, 16, 1, pcnet_aprom_writeb, d);
- register_ioport_read(addr, 16, 1, pcnet_aprom_readb, d);
+static void pcnet_ioport_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
+{
+ PCNetState *d = opaque;
- register_ioport_write(addr + 0x10, 0x10, 2, pcnet_ioport_writew, d);
- register_ioport_read(addr + 0x10, 0x10, 2, pcnet_ioport_readw, d);
- register_ioport_write(addr + 0x10, 0x10, 4, pcnet_ioport_writel, d);
- register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
+ if (addr < 16 && size == 1) {
+ return pcnet_aprom_writeb(d, addr, data);
+ } else if (addr >= 0x10 && addr < 0x20 && size == 2) {
+ return pcnet_ioport_writew(d, addr, data);
+ } else if (addr >= 0x10 && addr < 0x20 && size == 4) {
+ return pcnet_ioport_writel(d, addr, data);
+ }
}
+static const MemoryRegionOps pcnet_io_ops = {
+ .read = pcnet_ioport_read,
+ .write = pcnet_ioport_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
{
PCNetState *d = opaque;
@@ -202,16 +219,12 @@ static const VMStateDescription vmstate_pci_pcnet = {
/* PCI interface */
-static CPUWriteMemoryFunc * const pcnet_mmio_write[] = {
- &pcnet_mmio_writeb,
- &pcnet_mmio_writew,
- &pcnet_mmio_writel
-};
-
-static CPUReadMemoryFunc * const pcnet_mmio_read[] = {
- &pcnet_mmio_readb,
- &pcnet_mmio_readw,
- &pcnet_mmio_readl
+static const MemoryRegionOps pcnet_mmio_ops = {
+ .old_mmio = {
+ .read = { pcnet_mmio_readb, pcnet_mmio_readw, pcnet_mmio_readl },
+ .write = { pcnet_mmio_writeb, pcnet_mmio_writew, pcnet_mmio_writel },
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
@@ -237,7 +250,8 @@ static int pci_pcnet_uninit(PCIDevice *dev)
{
PCIPCNetState *d = DO_UPCAST(PCIPCNetState, pci_dev, dev);
- cpu_unregister_io_memory(d->state.mmio_index);
+ memory_region_destroy(&d->state.mmio);
+ memory_region_destroy(&d->io_bar);
qemu_del_timer(d->state.poll_timer);
qemu_free_timer(d->state.poll_timer);
qemu_del_vlan_client(&d->state.nic->nc);
@@ -276,14 +290,14 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
pci_conf[PCI_MAX_LAT] = 0xff;
/* Handler for memory-mapped I/O */
- s->mmio_index =
- cpu_register_io_memory(pcnet_mmio_read, pcnet_mmio_write, &d->state,
- DEVICE_NATIVE_ENDIAN);
+ memory_region_init_io(&d->state.mmio, &pcnet_mmio_ops, d, "pcnet-mmio",
+ PCNET_PNPMMIO_SIZE);
- pci_register_bar(pci_dev, 0, PCNET_IOPORT_SIZE,
- PCI_BASE_ADDRESS_SPACE_IO, pcnet_ioport_map);
+ memory_region_init_io(&d->io_bar, &pcnet_io_ops, d, "pcnet-io",
+ PCNET_IOPORT_SIZE);
+ pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar);
- pci_register_bar_simple(pci_dev, 1, PCNET_PNPMMIO_SIZE, 0, s->mmio_index);
+ pci_register_bar(pci_dev, 1, 0, &s->mmio);
s->irq = pci_dev->irq[0];
s->phys_mem_read = pci_physical_memory_read;
diff --git a/hw/pcnet.h b/hw/pcnet.h
index 534bdf9c2b..7e1c6853dd 100644
--- a/hw/pcnet.h
+++ b/hw/pcnet.h
@@ -4,6 +4,7 @@
#define PCNET_LOOPTEST_CRC 1
#define PCNET_LOOPTEST_NOCRC 2
+#include "memory.h"
typedef struct PCNetState_st PCNetState;
@@ -17,7 +18,8 @@ struct PCNetState_st {
uint16_t csr[128];
uint16_t bcr[32];
uint64_t timer;
- int mmio_index, xmit_pos;
+ MemoryRegion mmio;
+ int xmit_pos;
uint8_t buffer[4096];
int tx_busy;
qemu_irq irq;
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 80d6665350..28a3ee2e9c 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -242,7 +242,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
PCII440FXState **pi440fx_state,
int *piix3_devfn,
qemu_irq *pic,
- MemoryRegion *address_space,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
ram_addr_t ram_size)
{
DeviceState *dev;
@@ -253,8 +254,9 @@ static PCIBus *i440fx_common_init(const char *device_name,
dev = qdev_create(NULL, "i440FX-pcihost");
s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
- s->address_space = address_space;
- b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space, 0);
+ s->address_space = address_space_mem;
+ b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space,
+ address_space_io, 0);
s->bus = b;
qdev_init_nofail(dev);
@@ -291,13 +293,15 @@ static PCIBus *i440fx_common_init(const char *device_name,
}
PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
- qemu_irq *pic, MemoryRegion *address_space,
+ qemu_irq *pic,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io,
ram_addr_t ram_size)
{
PCIBus *b;
b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic,
- address_space, ram_size);
+ address_space_mem, address_space_io, ram_size);
return b;
}
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 15c24f6e7a..c7696b07d5 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -348,6 +348,7 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
ppc4xx_pci_map_irq,
pci_irqs,
get_system_memory(),
+ get_system_io(),
0, 4);
controller->pci_dev = pci_register_device(controller->pci_state.bus,
diff --git a/hw/ppc_mac.h b/hw/ppc_mac.h
index 6fad20a745..7351bb6d37 100644
--- a/hw/ppc_mac.h
+++ b/hw/ppc_mac.h
@@ -42,31 +42,38 @@
#define ESCC_CLOCK 3686400
/* Cuda */
-void cuda_init (int *cuda_mem_index, qemu_irq irq);
+void cuda_init (MemoryRegion **cuda_mem, qemu_irq irq);
/* MacIO */
-void macio_init (PCIBus *bus, int device_id, int is_oldworld, int pic_mem_index,
- int dbdma_mem_index, int cuda_mem_index, void *nvram,
- int nb_ide, int *ide_mem_index, int escc_mem_index);
+void macio_init (PCIBus *bus, int device_id, int is_oldworld,
+ MemoryRegion *pic_mem, MemoryRegion *dbdma_mem,
+ MemoryRegion *cuda_mem, void *nvram,
+ int nb_ide, MemoryRegion **ide_mem, MemoryRegion *escc_mem);
/* Heathrow PIC */
-qemu_irq *heathrow_pic_init(int *pmem_index,
+qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
int nb_cpus, qemu_irq **irqs);
/* Grackle PCI */
PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
- MemoryRegion *address_space);
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io);
/* UniNorth PCI */
-PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space);
-PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space);
+PCIBus *pci_pmac_init(qemu_irq *pic,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io);
+PCIBus *pci_pmac_u3_init(qemu_irq *pic,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io);
/* Mac NVRAM */
typedef struct MacIONVRAMState MacIONVRAMState;
-MacIONVRAMState *macio_nvram_init (int *mem_index, target_phys_addr_t size,
+MacIONVRAMState *macio_nvram_init (target_phys_addr_t size,
unsigned int it_shift);
-void macio_nvram_map (void *opaque, target_phys_addr_t mem_base);
+void macio_nvram_setup_bar(MacIONVRAMState *s, MemoryRegion *bar,
+ target_phys_addr_t mem_base);
void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len);
uint32_t macio_nvram_read (void *opaque, uint32_t addr);
void macio_nvram_write (void *opaque, uint32_t addr, uint32_t val);
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 2c0fae8ef3..303902290b 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -144,10 +144,9 @@ static void ppc_core99_init (ram_addr_t ram_size,
long kernel_size, initrd_size;
PCIBus *pci_bus;
MacIONVRAMState *nvr;
- int nvram_mem_index;
int bios_size;
- int pic_mem_index, dbdma_mem_index, cuda_mem_index, escc_mem_index;
- int ide_mem_index[3];
+ MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
+ MemoryRegion *ide_mem[3];
int ppc_boot_device;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
void *fw_cfg;
@@ -315,44 +314,43 @@ static void ppc_core99_init (ram_addr_t ram_size,
exit(1);
}
}
- pic = openpic_init(NULL, &pic_mem_index, smp_cpus, openpic_irqs, NULL);
+ pic = openpic_init(NULL, &pic_mem, smp_cpus, openpic_irqs, NULL);
if (PPC_INPUT(env) == PPC_FLAGS_INPUT_970) {
/* 970 gets a U3 bus */
- pci_bus = pci_pmac_u3_init(pic, get_system_memory());
+ pci_bus = pci_pmac_u3_init(pic, get_system_memory(), get_system_io());
machine_arch = ARCH_MAC99_U3;
} else {
- pci_bus = pci_pmac_init(pic, get_system_memory());
+ pci_bus = pci_pmac_init(pic, get_system_memory(), get_system_io());
machine_arch = ARCH_MAC99;
}
/* init basic PC hardware */
pci_vga_init(pci_bus);
- escc_mem_index = escc_init(0x80013000, pic[0x25], pic[0x24],
- serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
+ escc_mem = escc_init(0x80013000, pic[0x25], pic[0x24],
+ serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
for(i = 0; i < nb_nics; i++)
pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
ide_drive_get(hd, MAX_IDE_BUS);
- dbdma = DBDMA_init(&dbdma_mem_index);
+ dbdma = DBDMA_init(&dbdma_mem);
/* We only emulate 2 out of 3 IDE controllers for now */
- ide_mem_index[0] = -1;
- ide_mem_index[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
- ide_mem_index[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
+ ide_mem[0] = NULL;
+ ide_mem[1] = pmac_ide_init(hd, pic[0x0d], dbdma, 0x16, pic[0x02]);
+ ide_mem[2] = pmac_ide_init(&hd[MAX_IDE_DEVS], pic[0x0e], dbdma, 0x1a, pic[0x02]);
/* cuda also initialize ADB */
if (machine_arch == ARCH_MAC99_U3) {
usb_enabled = 1;
}
- cuda_init(&cuda_mem_index, pic[0x19]);
+ cuda_init(&cuda_mem, pic[0x19]);
adb_kbd_init(&adb_bus);
adb_mouse_init(&adb_bus);
- macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem_index,
- dbdma_mem_index, cuda_mem_index, NULL, 3, ide_mem_index,
- escc_mem_index);
+ macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
+ dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_mem);
if (usb_enabled) {
usb_ohci_init_pci(pci_bus, -1);
@@ -369,9 +367,9 @@ static void ppc_core99_init (ram_addr_t ram_size,
graphic_depth = 15;
/* The NewWorld NVRAM is not located in the MacIO device */
- nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 1);
+ nvr = macio_nvram_init(0x2000, 1);
pmac_format_nvram_partition(nvr, 0x2000);
- macio_nvram_map(nvr, 0xFFF04000);
+ macio_nvram_setup_bar(nvr, get_system_memory(), 0xFFF04000);
/* No PCI init: the BIOS will do it */
fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 585afd6c4b..41703a7e2c 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -82,8 +82,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
PCIBus *pci_bus;
MacIONVRAMState *nvr;
int bios_size;
- int pic_mem_index, nvram_mem_index, dbdma_mem_index, cuda_mem_index;
- int escc_mem_index, ide_mem_index[2];
+ MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
+ MemoryRegion *escc_mem, *ide_mem[2];
uint16_t ppc_boot_device;
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
void *fw_cfg;
@@ -233,11 +233,13 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
hw_error("Only 6xx bus is supported on heathrow machine\n");
}
- pic = heathrow_pic_init(&pic_mem_index, 1, heathrow_irqs);
- pci_bus = pci_grackle_init(0xfec00000, pic, get_system_memory());
+ pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs);
+ pci_bus = pci_grackle_init(0xfec00000, pic,
+ get_system_memory(),
+ get_system_io());
pci_vga_init(pci_bus);
- escc_mem_index = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
+ escc_mem = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
serial_hds[1], ESCC_CLOCK, 4);
for(i = 0; i < nb_nics; i++)
@@ -247,9 +249,9 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
ide_drive_get(hd, MAX_IDE_BUS);
/* First IDE channel is a MAC IDE on the MacIO bus */
- dbdma = DBDMA_init(&dbdma_mem_index);
- ide_mem_index[0] = -1;
- ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
+ dbdma = DBDMA_init(&dbdma_mem);
+ ide_mem[0] = NULL;
+ ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
/* Second IDE channel is a CMD646 on the PCI bus */
hd[0] = hd[MAX_IDE_DEVS];
@@ -258,17 +260,16 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
pci_cmd646_ide_init(pci_bus, hd, 0);
/* cuda also initialize ADB */
- cuda_init(&cuda_mem_index, pic[0x12]);
+ cuda_init(&cuda_mem, pic[0x12]);
adb_kbd_init(&adb_bus);
adb_mouse_init(&adb_bus);
- nvr = macio_nvram_init(&nvram_mem_index, 0x2000, 4);
+ nvr = macio_nvram_init(0x2000, 4);
pmac_format_nvram_partition(nvr, 0x2000);
- macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem_index,
- dbdma_mem_index, cuda_mem_index, nvr, 2, ide_mem_index,
- escc_mem_index);
+ macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem,
+ dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_mem);
if (usb_enabled) {
usb_ohci_init_pci(pci_bus, -1);
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 91ebe07dcd..38d8573d14 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -649,7 +649,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
hw_error("Only 6xx bus is supported on PREP machine\n");
}
i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
- pci_bus = pci_prep_init(i8259, get_system_memory());
+ pci_bus = pci_prep_init(i8259, get_system_memory(), get_system_io());
/* Hmm, prep has no pci-isa bridge ??? */
isa_bus_new(NULL);
isa_bus_irqs(i8259);
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 134453965b..6a9f97975d 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -282,7 +282,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
PPCE500PCIState *s;
PCIBus *b;
int i;
- MemoryRegion *address_space = get_system_memory();
+ MemoryRegion *address_space_mem = get_system_memory();
+ MemoryRegion *address_space_io = get_system_io();
h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
s = DO_UPCAST(PPCE500PCIState, pci_state, h);
@@ -292,8 +293,8 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
}
b = pci_register_bus(&s->pci_state.busdev.qdev, NULL, mpc85xx_pci_set_irq,
- mpc85xx_pci_map_irq, s->irq, address_space,
- PCI_DEVFN(0x11, 0), 4);
+ mpc85xx_pci_map_irq, s->irq, address_space_mem,
+ address_space_io, PCI_DEVFN(0x11, 0), 4);
s->pci_state.bus = b;
pci_create_simple(b, 0, "e500-host-bridge");
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index da02f0ea8e..58619ddf74 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -110,7 +110,9 @@ static void prep_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(pic[(irq_num & 1) ? 11 : 9] , level);
}
-PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space)
+PCIBus *pci_prep_init(qemu_irq *pic,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io)
{
PREPPCIState *s;
PCIDevice *d;
@@ -119,7 +121,9 @@ PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space)
s = qemu_mallocz(sizeof(PREPPCIState));
s->bus = pci_register_bus(NULL, "pci",
prep_set_irq, prep_map_irq, pic,
- address_space, 0, 4);
+ address_space_mem,
+ address_space_io,
+ 0, 4);
pci_host_conf_register_ioport(0xcf8, s);
diff --git a/hw/prep_pci.h b/hw/prep_pci.h
index a27368b99b..b6b481a517 100644
--- a/hw/prep_pci.h
+++ b/hw/prep_pci.h
@@ -4,6 +4,8 @@
#include "qemu-common.h"
#include "memory.h"
-PCIBus *pci_prep_init(qemu_irq *pic, MemoryRegion *address_space);
+PCIBus *pci_prep_init(qemu_irq *pic,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io);
#endif
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 643ff2d841..1b775770ce 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -86,7 +86,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
}
qemu_free_displaysurface(vga->ds);
- qxl->guest_primary.data = qemu_get_ram_ptr(qxl->vga.vram_offset);
+ qxl->guest_primary.data = memory_region_get_ram_ptr(&qxl->vga.vram);
if (qxl->guest_primary.stride < 0) {
/* spice surface is upside down -> need extra buffer to flip */
qxl->guest_primary.stride = -qxl->guest_primary.stride;
diff --git a/hw/qxl.c b/hw/qxl.c
index b684608f87..b34bccf62e 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -263,7 +263,7 @@ static ram_addr_t qxl_rom_size(void)
static void init_qxl_rom(PCIQXLDevice *d)
{
- QXLRom *rom = qemu_get_ram_ptr(d->rom_offset);
+ QXLRom *rom = memory_region_get_ram_ptr(&d->rom_bar);
QXLModes *modes = (QXLModes *)(rom + 1);
uint32_t ram_header_size;
uint32_t surface0_area_size;
@@ -339,39 +339,37 @@ static void init_qxl_ram(PCIQXLDevice *d)
}
/* can be called from spice server thread context */
-static void qxl_set_dirty(ram_addr_t addr, ram_addr_t end)
+static void qxl_set_dirty(MemoryRegion *mr, ram_addr_t addr, ram_addr_t end)
{
while (addr < end) {
- cpu_physical_memory_set_dirty(addr);
+ memory_region_set_dirty(mr, addr);
addr += TARGET_PAGE_SIZE;
}
}
static void qxl_rom_set_dirty(PCIQXLDevice *qxl)
{
- ram_addr_t addr = qxl->rom_offset;
- qxl_set_dirty(addr, addr + qxl->rom_size);
+ qxl_set_dirty(&qxl->rom_bar, 0, qxl->rom_size);
}
/* called from spice server thread context only */
static void qxl_ram_set_dirty(PCIQXLDevice *qxl, void *ptr)
{
- ram_addr_t addr = qxl->vga.vram_offset;
void *base = qxl->vga.vram_ptr;
intptr_t offset;
offset = ptr - base;
offset &= ~(TARGET_PAGE_SIZE-1);
assert(offset < qxl->vga.vram_size);
- qxl_set_dirty(addr + offset, addr + offset + TARGET_PAGE_SIZE);
+ qxl_set_dirty(&qxl->vga.vram, offset, offset + TARGET_PAGE_SIZE);
}
/* can be called from spice server thread context */
static void qxl_ring_set_dirty(PCIQXLDevice *qxl)
{
- ram_addr_t addr = qxl->vga.vram_offset + qxl->shadow_rom.ram_header_offset;
- ram_addr_t end = qxl->vga.vram_offset + qxl->vga.vram_size;
- qxl_set_dirty(addr, end);
+ ram_addr_t addr = qxl->shadow_rom.ram_header_offset;
+ ram_addr_t end = qxl->vga.vram_size;
+ qxl_set_dirty(&qxl->vga.vram, addr, end);
}
/*
@@ -819,35 +817,19 @@ static void qxl_set_irq(PCIQXLDevice *d)
qxl_ring_set_dirty(d);
}
-static void qxl_write_config(PCIDevice *d, uint32_t address,
- uint32_t val, int len)
-{
- PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, d);
- VGACommonState *vga = &qxl->vga;
-
- vga_dirty_log_stop(vga);
- pci_default_write_config(d, address, val, len);
- if (vga->map_addr && qxl->pci.io_regions[0].addr == -1) {
- vga->map_addr = 0;
- }
- vga_dirty_log_start(vga);
-}
-
static void qxl_check_state(PCIQXLDevice *d)
{
QXLRam *ram = d->ram;
- assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring));
- assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring));
+ assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cmd_ring));
+ assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cursor_ring));
}
static void qxl_reset_state(PCIQXLDevice *d)
{
- QXLRam *ram = d->ram;
QXLRom *rom = d->rom;
- assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cmd_ring));
- assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cursor_ring));
+ qxl_check_state(d);
d->shadow_rom.update_id = cpu_to_le32(0);
*rom = d->shadow_rom;
qxl_rom_set_dirty(d);
@@ -959,10 +941,10 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
switch (pci_region) {
case QXL_RAM_RANGE_INDEX:
- virt_start = (intptr_t)qemu_get_ram_ptr(d->vga.vram_offset);
+ virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vga.vram);
break;
case QXL_VRAM_RANGE_INDEX:
- virt_start = (intptr_t)qemu_get_ram_ptr(d->vram_offset);
+ virt_start = (intptr_t)memory_region_get_ram_ptr(&d->vram_bar);
break;
default:
/* should not happen */
@@ -1132,10 +1114,11 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
qxl_rom_set_dirty(d);
}
-static void ioport_write(void *opaque, uint32_t addr, uint32_t val)
+static void ioport_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
PCIQXLDevice *d = opaque;
- uint32_t io_port = addr - d->io_base;
+ uint32_t io_port = addr;
qxl_async_io async = QXL_SYNC;
#if SPICE_INTERFACE_QXL_MINOR >= 1
uint32_t orig_io_port = io_port;
@@ -1204,7 +1187,7 @@ async_common:
}
d->current_async = orig_io_port;
qemu_mutex_unlock(&d->async_lock);
- dprint(d, 2, "start async %d (%d)\n", io_port, val);
+ dprint(d, 2, "start async %d (%"PRId64")\n", io_port, val);
break;
default:
break;
@@ -1241,7 +1224,7 @@ async_common:
d->oom_running = 0;
break;
case QXL_IO_SET_MODE:
- dprint(d, 1, "QXL_SET_MODE %d\n", val);
+ dprint(d, 1, "QXL_SET_MODE %d\n", (int)val);
qxl_set_mode(d, val, 0);
break;
case QXL_IO_LOG:
@@ -1320,7 +1303,8 @@ async_common:
break;
}
case QXL_IO_FLUSH_SURFACES_ASYNC:
- dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC (%d) (%s, s#=%d, res#=%d)\n",
+ dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC"
+ " (%"PRId64") (%s, s#=%d, res#=%d)\n",
val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
d->num_free_res);
qxl_spice_flush_surfaces_async(d);
@@ -1348,7 +1332,8 @@ cancel_async:
#endif
}
-static uint32_t ioport_read(void *opaque, uint32_t addr)
+static uint64_t ioport_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
PCIQXLDevice *d = opaque;
@@ -1356,42 +1341,14 @@ static uint32_t ioport_read(void *opaque, uint32_t addr)
return 0xff;
}
-static void qxl_map(PCIDevice *pci, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- static const char *names[] = {
- [ QXL_IO_RANGE_INDEX ] = "ioports",
- [ QXL_RAM_RANGE_INDEX ] = "devram",
- [ QXL_ROM_RANGE_INDEX ] = "rom",
- [ QXL_VRAM_RANGE_INDEX ] = "vram",
- };
- PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, pci);
-
- dprint(qxl, 1, "%s: bar %d [%s] addr 0x%lx size 0x%lx\n", __FUNCTION__,
- region_num, names[region_num], addr, size);
-
- switch (region_num) {
- case QXL_IO_RANGE_INDEX:
- register_ioport_write(addr, size, 1, ioport_write, pci);
- register_ioport_read(addr, size, 1, ioport_read, pci);
- qxl->io_base = addr;
- break;
- case QXL_RAM_RANGE_INDEX:
- cpu_register_physical_memory(addr, size, qxl->vga.vram_offset | IO_MEM_RAM);
- qxl->vga.map_addr = addr;
- qxl->vga.map_end = addr + size;
- if (qxl->id == 0) {
- vga_dirty_log_start(&qxl->vga);
- }
- break;
- case QXL_ROM_RANGE_INDEX:
- cpu_register_physical_memory(addr, size, qxl->rom_offset | IO_MEM_ROM);
- break;
- case QXL_VRAM_RANGE_INDEX:
- cpu_register_physical_memory(addr, size, qxl->vram_offset | IO_MEM_RAM);
- break;
- }
-}
+static const MemoryRegionOps qxl_io_ops = {
+ .read = ioport_read,
+ .write = ioport_write,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
+};
static void pipe_read(void *opaque)
{
@@ -1511,10 +1468,9 @@ static void qxl_vm_change_state_handler(void *opaque, int running, int reason)
* to make sure they are saved */
/* FIXME #1: should go out during "live" stage */
/* FIXME #2: we only need to save the areas which are actually used */
- ram_addr_t vram_addr = qxl->vram_offset;
- ram_addr_t surface0_addr = qxl->vga.vram_offset + qxl->shadow_rom.draw_area_offset;
- qxl_set_dirty(vram_addr, vram_addr + qxl->vram_size);
- qxl_set_dirty(surface0_addr, surface0_addr + qxl->shadow_rom.surface0_area_size);
+ qxl_set_dirty(&qxl->vram_bar, 0, qxl->vram_size);
+ qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
+ qxl->shadow_rom.surface0_area_size);
}
}
@@ -1580,7 +1536,8 @@ static int qxl_init_common(PCIQXLDevice *qxl)
pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
qxl->rom_size = qxl_rom_size();
- qxl->rom_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vrom", qxl->rom_size);
+ memory_region_init_ram(&qxl->rom_bar, &qxl->pci.qdev, "qxl.vrom",
+ qxl->rom_size);
init_qxl_rom(qxl);
init_qxl_ram(qxl);
@@ -1591,26 +1548,32 @@ static int qxl_init_common(PCIQXLDevice *qxl)
qxl->vram_size = 4096;
}
qxl->vram_size = msb_mask(qxl->vram_size * 2 - 1);
- qxl->vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vram", qxl->vram_size);
+ memory_region_init_ram(&qxl->vram_bar, &qxl->pci.qdev, "qxl.vram",
+ qxl->vram_size);
io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
if (qxl->revision == 1) {
io_size = 8;
}
+ memory_region_init_io(&qxl->io_bar, &qxl_io_ops, qxl,
+ "qxl-ioports", io_size);
+ if (qxl->id == 0) {
+ vga_dirty_log_start(&qxl->vga);
+ }
+
+
pci_register_bar(&qxl->pci, QXL_IO_RANGE_INDEX,
- io_size, PCI_BASE_ADDRESS_SPACE_IO, qxl_map);
+ PCI_BASE_ADDRESS_SPACE_IO, &qxl->io_bar);
pci_register_bar(&qxl->pci, QXL_ROM_RANGE_INDEX,
- qxl->rom_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
- qxl_map);
+ PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->rom_bar);
pci_register_bar(&qxl->pci, QXL_RAM_RANGE_INDEX,
- qxl->vga.vram_size, PCI_BASE_ADDRESS_SPACE_MEMORY,
- qxl_map);
+ PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vga.vram);
- pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX, qxl->vram_size,
- PCI_BASE_ADDRESS_SPACE_MEMORY, qxl_map);
+ pci_register_bar(&qxl->pci, QXL_VRAM_RANGE_INDEX,
+ PCI_BASE_ADDRESS_SPACE_MEMORY, &qxl->vram_bar);
qxl->ssd.qxl.base.sif = &qxl_interface.base;
qxl->ssd.qxl.id = qxl->id;
@@ -1664,9 +1627,9 @@ static int qxl_init_secondary(PCIDevice *dev)
ram_size = 16 * 1024 * 1024;
}
qxl->vga.vram_size = ram_size;
- qxl->vga.vram_offset = qemu_ram_alloc(&qxl->pci.qdev, "qxl.vgavram",
- qxl->vga.vram_size);
- qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset);
+ memory_region_init_ram(&qxl->vga.vram, &qxl->pci.qdev, "qxl.vgavram",
+ qxl->vga.vram_size);
+ qxl->vga.vram_ptr = memory_region_get_ram_ptr(&qxl->vga.vram);
return qxl_init_common(qxl);
}
@@ -1829,7 +1792,6 @@ static PCIDeviceInfo qxl_info_primary = {
.qdev.vmsd = &qxl_vmstate,
.no_hotplug = 1,
.init = qxl_init_primary,
- .config_write = qxl_write_config,
.romfile = "vgabios-qxl.bin",
.vendor_id = REDHAT_PCI_VENDOR_ID,
.device_id = QXL_DEVICE_ID_STABLE,
diff --git a/hw/qxl.h b/hw/qxl.h
index 4bcf7e1429..868db813f9 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -79,14 +79,14 @@ typedef struct PCIQXLDevice {
QXLRom *rom;
QXLModes *modes;
uint32_t rom_size;
- uint64_t rom_offset;
+ MemoryRegion rom_bar;
/* vram pci bar */
uint32_t vram_size;
- uint64_t vram_offset;
+ MemoryRegion vram_bar;
/* io bar */
- uint32_t io_base;
+ MemoryRegion io_bar;
} PCIQXLDevice;
#define PANIC_ON(x) if ((x)) { \
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 5214b8cb7c..c6cafc2513 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -474,7 +474,6 @@ typedef struct RTL8139State {
NICState *nic;
NICConf conf;
- int rtl8139_mmio_io_addr;
/* C ring mode */
uint32_t currTxDesc;
@@ -506,6 +505,9 @@ typedef struct RTL8139State {
QEMUTimer *timer;
int64_t TimerExpire;
+ MemoryRegion bar_io;
+ MemoryRegion bar_mem;
+
/* Support migration to/from old versions */
int rtl8139_mmio_io_addr_dummy;
} RTL8139State;
@@ -3283,7 +3285,7 @@ static void rtl8139_pre_save(void *opaque)
rtl8139_set_next_tctr_time(s, current_time);
s->TCTR = muldiv64(current_time - s->TCTR_base, PCI_FREQUENCY,
get_ticks_per_sec());
- s->rtl8139_mmio_io_addr_dummy = s->rtl8139_mmio_io_addr;
+ s->rtl8139_mmio_io_addr_dummy = 0;
}
static const VMStateDescription vmstate_rtl8139 = {
@@ -3379,31 +3381,35 @@ static const VMStateDescription vmstate_rtl8139 = {
/***********************************************************/
/* PCI RTL8139 definitions */
-static void rtl8139_ioport_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- RTL8139State *s = DO_UPCAST(RTL8139State, dev, pci_dev);
-
- register_ioport_write(addr, 0x100, 1, rtl8139_ioport_writeb, s);
- register_ioport_read( addr, 0x100, 1, rtl8139_ioport_readb, s);
-
- register_ioport_write(addr, 0x100, 2, rtl8139_ioport_writew, s);
- register_ioport_read( addr, 0x100, 2, rtl8139_ioport_readw, s);
-
- register_ioport_write(addr, 0x100, 4, rtl8139_ioport_writel, s);
- register_ioport_read( addr, 0x100, 4, rtl8139_ioport_readl, s);
-}
+static const MemoryRegionPortio rtl8139_portio[] = {
+ { 0, 0x100, 1, .read = rtl8139_ioport_readb, },
+ { 0, 0x100, 1, .write = rtl8139_ioport_writeb, },
+ { 0, 0x100, 2, .read = rtl8139_ioport_readw, },
+ { 0, 0x100, 2, .write = rtl8139_ioport_writew, },
+ { 0, 0x100, 4, .read = rtl8139_ioport_readl, },
+ { 0, 0x100, 4, .write = rtl8139_ioport_writel, },
+ PORTIO_END_OF_LIST()
+};
-static CPUReadMemoryFunc * const rtl8139_mmio_read[3] = {
- rtl8139_mmio_readb,
- rtl8139_mmio_readw,
- rtl8139_mmio_readl,
+static const MemoryRegionOps rtl8139_io_ops = {
+ .old_portio = rtl8139_portio,
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
-static CPUWriteMemoryFunc * const rtl8139_mmio_write[3] = {
- rtl8139_mmio_writeb,
- rtl8139_mmio_writew,
- rtl8139_mmio_writel,
+static const MemoryRegionOps rtl8139_mmio_ops = {
+ .old_mmio = {
+ .read = {
+ rtl8139_mmio_readb,
+ rtl8139_mmio_readw,
+ rtl8139_mmio_readl,
+ },
+ .write = {
+ rtl8139_mmio_writeb,
+ rtl8139_mmio_writew,
+ rtl8139_mmio_writel,
+ },
+ },
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
static void rtl8139_timer(void *opaque)
@@ -3432,7 +3438,8 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
{
RTL8139State *s = DO_UPCAST(RTL8139State, dev, dev);
- cpu_unregister_io_memory(s->rtl8139_mmio_io_addr);
+ memory_region_destroy(&s->bar_io);
+ memory_region_destroy(&s->bar_mem);
if (s->cplus_txbuffer) {
qemu_free(s->cplus_txbuffer);
s->cplus_txbuffer = NULL;
@@ -3462,15 +3469,10 @@ static int pci_rtl8139_init(PCIDevice *dev)
* list bit in status register, and offset 0xdc seems unused. */
pci_conf[PCI_CAPABILITY_LIST] = 0xdc;
- /* I/O handler for memory-mapped I/O */
- s->rtl8139_mmio_io_addr =
- cpu_register_io_memory(rtl8139_mmio_read, rtl8139_mmio_write, s,
- DEVICE_LITTLE_ENDIAN);
-
- pci_register_bar(&s->dev, 0, 0x100,
- PCI_BASE_ADDRESS_SPACE_IO, rtl8139_ioport_map);
-
- pci_register_bar_simple(&s->dev, 1, 0x100, 0, s->rtl8139_mmio_io_addr);
+ memory_region_init_io(&s->bar_io, &rtl8139_io_ops, s, "rtl8139", 0x100);
+ memory_region_init_io(&s->bar_mem, &rtl8139_mmio_ops, s, "rtl8139", 0x100);
+ pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->bar_io);
+ pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar_mem);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index 0ef93a062e..cd8650143c 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -128,7 +128,9 @@ static int sh_pci_init_device(SysBusDevice *dev)
}
s->bus = pci_register_bus(&s->busdev.qdev, "pci",
sh_pci_set_irq, sh_pci_map_irq,
- s->irq, get_system_memory(),
+ s->irq,
+ get_system_memory(),
+ get_system_io(),
PCI_DEVFN(0, 0), 4);
s->memconfig = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w,
s, DEVICE_NATIVE_ENDIAN);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index d7dcaf007d..7b2d0b17e4 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -91,6 +91,12 @@ struct hwdef {
uint64_t console_serial_base;
};
+typedef struct EbusState {
+ PCIDevice pci_dev;
+ MemoryRegion bar0;
+ MemoryRegion bar1;
+} EbusState;
+
int DMA_get_channel_mode (int nchan)
{
return 0;
@@ -518,21 +524,6 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
}
}
-static void ebus_mmio_mapfunc(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- EBUS_DPRINTF("Mapping region %d registers at %" FMT_PCIBUS "\n",
- region_num, addr);
- switch (region_num) {
- case 0:
- isa_mmio_init(addr, 0x1000000);
- break;
- case 1:
- isa_mmio_init(addr, 0x800000);
- break;
- }
-}
-
static void dummy_isa_irq_handler(void *opaque, int n, int level)
{
}
@@ -549,27 +540,29 @@ pci_ebus_init(PCIBus *bus, int devfn)
}
static int
-pci_ebus_init1(PCIDevice *s)
+pci_ebus_init1(PCIDevice *pci_dev)
{
- isa_bus_new(&s->qdev);
+ EbusState *s = DO_UPCAST(EbusState, pci_dev, pci_dev);
+
+ isa_bus_new(&pci_dev->qdev);
- s->config[0x04] = 0x06; // command = bus master, pci mem
- s->config[0x05] = 0x00;
- s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
- s->config[0x07] = 0x03; // status = medium devsel
- s->config[0x09] = 0x00; // programming i/f
- s->config[0x0D] = 0x0a; // latency_timer
+ pci_dev->config[0x04] = 0x06; // command = bus master, pci mem
+ pci_dev->config[0x05] = 0x00;
+ pci_dev->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
+ pci_dev->config[0x07] = 0x03; // status = medium devsel
+ pci_dev->config[0x09] = 0x00; // programming i/f
+ pci_dev->config[0x0D] = 0x0a; // latency_timer
- pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY,
- ebus_mmio_mapfunc);
- pci_register_bar(s, 1, 0x800000, PCI_BASE_ADDRESS_SPACE_MEMORY,
- ebus_mmio_mapfunc);
+ isa_mmio_setup(&s->bar0, 0x1000000);
+ pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0);
+ isa_mmio_setup(&s->bar1, 0x800000);
+ pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1);
return 0;
}
static PCIDeviceInfo ebus_info = {
.qdev.name = "ebus",
- .qdev.size = sizeof(PCIDevice),
+ .qdev.size = sizeof(EbusState),
.init = pci_ebus_init1,
.vendor_id = PCI_VENDOR_ID_SUN,
.device_id = PCI_DEVICE_ID_SUN_EBUS,
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index b499523c93..f896f8c76b 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -201,7 +201,9 @@ static int pci_unin_internal_init_device(SysBusDevice *dev)
return 0;
}
-PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
+PCIBus *pci_pmac_init(qemu_irq *pic,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io)
{
DeviceState *dev;
SysBusDevice *s;
@@ -215,7 +217,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
d = FROM_SYSBUS(UNINState, s);
d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
pci_unin_set_irq, pci_unin_map_irq,
- pic, address_space,
+ pic,
+ address_space_mem,
+ address_space_io,
PCI_DEVFN(11, 0), 4);
#if 0
@@ -253,7 +257,9 @@ PCIBus *pci_pmac_init(qemu_irq *pic, MemoryRegion *address_space)
return d->host_state.bus;
}
-PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space)
+PCIBus *pci_pmac_u3_init(qemu_irq *pic,
+ MemoryRegion *address_space_mem,
+ MemoryRegion *address_space_io)
{
DeviceState *dev;
SysBusDevice *s;
@@ -268,7 +274,9 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic, MemoryRegion *address_space)
d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",
pci_unin_set_irq, pci_unin_map_irq,
- pic, address_space,
+ pic,
+ address_space_mem,
+ address_space_io,
PCI_DEVFN(11, 0), 4);
sysbus_mmio_map(s, 0, 0xf0800000);
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index 2b43895315..c9d0a692ed 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -370,8 +370,7 @@ struct EHCIState {
PCIDevice dev;
USBBus bus;
qemu_irq irq;
- target_phys_addr_t mem_base;
- int mem;
+ MemoryRegion mem;
int companion_count;
/* properties */
@@ -2179,29 +2178,15 @@ static void ehci_frame_timer(void *opaque)
qemu_mod_timer(ehci->frame_timer, expire_time);
}
-static CPUReadMemoryFunc *ehci_readfn[3]={
- ehci_mem_readb,
- ehci_mem_readw,
- ehci_mem_readl
-};
-static CPUWriteMemoryFunc *ehci_writefn[3]={
- ehci_mem_writeb,
- ehci_mem_writew,
- ehci_mem_writel
+static const MemoryRegionOps ehci_mem_ops = {
+ .old_mmio = {
+ .read = { ehci_mem_readb, ehci_mem_readw, ehci_mem_readl },
+ .write = { ehci_mem_writeb, ehci_mem_writew, ehci_mem_writel },
+ },
+ .endianness = DEVICE_LITTLE_ENDIAN,
};
-static void ehci_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- EHCIState *s =(EHCIState *)pci_dev;
-
- DPRINTF("ehci_map: region %d, addr %08" PRIx64 ", size %" PRId64 ", s->mem %08X\n",
- region_num, addr, size, s->mem);
- s->mem_base = addr;
- cpu_register_physical_memory(addr, size, s->mem);
-}
-
static int usb_ehci_initfn(PCIDevice *dev);
static USBPortOps ehci_port_ops = {
@@ -2316,11 +2301,8 @@ static int usb_ehci_initfn(PCIDevice *dev)
qemu_register_reset(ehci_reset, s);
- s->mem = cpu_register_io_memory(ehci_readfn, ehci_writefn, s,
- DEVICE_LITTLE_ENDIAN);
-
- pci_register_bar(&s->dev, 0, MMIO_SIZE, PCI_BASE_ADDRESS_SPACE_MEMORY,
- ehci_map);
+ memory_region_init_io(&s->mem, &ehci_mem_ops, s, "ehci", MMIO_SIZE);
+ pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
fprintf(stderr, "*** EHCI support is under development ***\n");
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index e5d57de888..ba79466401 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -45,8 +45,6 @@
typedef struct USBHIDState {
USBDevice dev;
HIDState hid;
- void *datain_opaque;
- void (*datain)(void *);
} USBHIDState;
enum {
@@ -362,10 +360,6 @@ static void usb_hid_changed(HIDState *hs)
{
USBHIDState *us = container_of(hs, USBHIDState, hid);
- if (us->datain) {
- us->datain(us->datain_opaque);
- }
-
usb_wakeup(&us->dev);
}
@@ -454,6 +448,9 @@ static int usb_hid_handle_control(USBDevice *dev, USBPacket *p,
case SET_IDLE:
hs->idle = (uint8_t) (value >> 8);
hid_set_next_idle(hs, qemu_get_clock_ns(vm_clock));
+ if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
+ hid_pointer_activate(hs);
+ }
ret = 0;
break;
default:
@@ -530,49 +527,13 @@ static int usb_keyboard_initfn(USBDevice *dev)
return usb_hid_initfn(dev, HID_KEYBOARD);
}
-void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
-{
- USBHIDState *s = (USBHIDState *)dev;
-
- s->datain_opaque = opaque;
- s->datain = datain;
-}
-
-static int usb_hid_post_load(void *opaque, int version_id)
-{
- USBHIDState *s = opaque;
-
- if (s->hid.idle) {
- hid_set_next_idle(&s->hid, qemu_get_clock_ns(vm_clock));
- }
- return 0;
-}
-
-static const VMStateDescription vmstate_usb_ptr_queue = {
- .name = "usb-ptr-queue",
- .version_id = 1,
- .minimum_version_id = 1,
- .fields = (VMStateField []) {
- VMSTATE_INT32(xdx, HIDPointerEvent),
- VMSTATE_INT32(ydy, HIDPointerEvent),
- VMSTATE_INT32(dz, HIDPointerEvent),
- VMSTATE_INT32(buttons_state, HIDPointerEvent),
- VMSTATE_END_OF_LIST()
- }
-};
static const VMStateDescription vmstate_usb_ptr = {
.name = "usb-ptr",
.version_id = 1,
.minimum_version_id = 1,
- .post_load = usb_hid_post_load,
.fields = (VMStateField []) {
VMSTATE_USB_DEVICE(dev, USBHIDState),
- VMSTATE_STRUCT_ARRAY(hid.ptr.queue, USBHIDState, QUEUE_LENGTH, 0,
- vmstate_usb_ptr_queue, HIDPointerEvent),
- VMSTATE_UINT32(hid.head, USBHIDState),
- VMSTATE_UINT32(hid.n, USBHIDState),
- VMSTATE_INT32(hid.protocol, USBHIDState),
- VMSTATE_UINT8(hid.idle, USBHIDState),
+ VMSTATE_HID_POINTER_DEVICE(hid, USBHIDState),
VMSTATE_END_OF_LIST()
}
};
@@ -581,18 +542,9 @@ static const VMStateDescription vmstate_usb_kbd = {
.name = "usb-kbd",
.version_id = 1,
.minimum_version_id = 1,
- .post_load = usb_hid_post_load,
.fields = (VMStateField []) {
VMSTATE_USB_DEVICE(dev, USBHIDState),
- VMSTATE_UINT32_ARRAY(hid.kbd.keycodes, USBHIDState, QUEUE_LENGTH),
- VMSTATE_UINT32(hid.head, USBHIDState),
- VMSTATE_UINT32(hid.n, USBHIDState),
- VMSTATE_UINT16(hid.kbd.modifiers, USBHIDState),
- VMSTATE_UINT8(hid.kbd.leds, USBHIDState),
- VMSTATE_UINT8_ARRAY(hid.kbd.key, USBHIDState, 16),
- VMSTATE_INT32(hid.kbd.keys, USBHIDState),
- VMSTATE_INT32(hid.protocol, USBHIDState),
- VMSTATE_UINT8(hid.idle, USBHIDState),
+ VMSTATE_HID_KEYBOARD_DEVICE(hid, USBHIDState),
VMSTATE_END_OF_LIST()
}
};
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index d39bcb0c0d..d30db3f92f 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1790,7 +1790,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
ohci->state.irq = ohci->pci_dev.irq[0];
/* TODO: avoid cast below by using dev */
- pci_register_bar_region(&ohci->pci_dev, 0, 0, &ohci->state.mem);
+ pci_register_bar(&ohci->pci_dev, 0, 0, &ohci->state.mem);
return 0;
}
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 824e3a5e8b..16088d7dca 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -129,6 +129,7 @@ typedef struct UHCIPort {
struct UHCIState {
PCIDevice dev;
+ MemoryRegion io_bar;
USBBus bus; /* Note unused when we're a companion controller */
uint16_t cmd; /* cmd register */
uint16_t status;
@@ -1096,18 +1097,19 @@ static void uhci_frame_timer(void *opaque)
qemu_mod_timer(s->frame_timer, s->expire_time);
}
-static void uhci_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- UHCIState *s = (UHCIState *)pci_dev;
-
- register_ioport_write(addr, 32, 2, uhci_ioport_writew, s);
- register_ioport_read(addr, 32, 2, uhci_ioport_readw, s);
- register_ioport_write(addr, 32, 4, uhci_ioport_writel, s);
- register_ioport_read(addr, 32, 4, uhci_ioport_readl, s);
- register_ioport_write(addr, 32, 1, uhci_ioport_writeb, s);
- register_ioport_read(addr, 32, 1, uhci_ioport_readb, s);
-}
+static const MemoryRegionPortio uhci_portio[] = {
+ { 0, 32, 2, .write = uhci_ioport_writew, },
+ { 0, 32, 2, .read = uhci_ioport_readw, },
+ { 0, 32, 4, .write = uhci_ioport_writel, },
+ { 0, 32, 4, .read = uhci_ioport_readl, },
+ { 0, 32, 1, .write = uhci_ioport_writeb, },
+ { 0, 32, 1, .read = uhci_ioport_readb, },
+ PORTIO_END_OF_LIST()
+};
+
+static const MemoryRegionOps uhci_ioport_ops = {
+ .old_portio = uhci_portio,
+};
static USBPortOps uhci_port_ops = {
.attach = uhci_attach,
@@ -1154,10 +1156,10 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
qemu_register_reset(uhci_reset, s);
+ memory_region_init_io(&s->io_bar, &uhci_ioport_ops, s, "uhci", 0x20);
/* Use region 4 for consistency with real hardware. BSD guests seem
to rely on this. */
- pci_register_bar(&s->dev, 4, 0x20,
- PCI_BASE_ADDRESS_SPACE_IO, uhci_map);
+ pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
return 0;
}
@@ -1177,6 +1179,14 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
return usb_uhci_common_initfn(dev);
}
+static int usb_uhci_exit(PCIDevice *dev)
+{
+ UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+
+ memory_region_destroy(&s->io_bar);
+ return 0;
+}
+
static Property uhci_properties[] = {
DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
@@ -1189,6 +1199,7 @@ static PCIDeviceInfo uhci_info[] = {
.qdev.size = sizeof(UHCIState),
.qdev.vmsd = &vmstate_uhci,
.init = usb_uhci_common_initfn,
+ .exit = usb_uhci_exit,
.vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82371SB_2,
.revision = 0x01,
@@ -1199,6 +1210,7 @@ static PCIDeviceInfo uhci_info[] = {
.qdev.size = sizeof(UHCIState),
.qdev.vmsd = &vmstate_uhci,
.init = usb_uhci_common_initfn,
+ .exit = usb_uhci_exit,
.vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_82371AB_2,
.revision = 0x01,
@@ -1209,6 +1221,7 @@ static PCIDeviceInfo uhci_info[] = {
.qdev.size = sizeof(UHCIState),
.qdev.vmsd = &vmstate_uhci,
.init = usb_uhci_vt82c686b_initfn,
+ .exit = usb_uhci_exit,
.vendor_id = PCI_VENDOR_ID_VIA,
.device_id = PCI_DEVICE_ID_VIA_UHCI,
.revision = 0x01,
diff --git a/hw/usb.h b/hw/usb.h
index 84d04df2e1..d784448290 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -316,9 +316,6 @@ USBDevice *usb_host_device_open(const char *devname);
int usb_host_device_close(const char *devname);
void usb_host_info(Monitor *mon);
-/* usb-hid.c */
-void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *));
-
/* usb-bt.c */
USBDevice *usb_bt_init(HCIInfo *hci);
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index cffe387187..e1d5c0bf5a 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -112,7 +112,7 @@ static int pci_vpb_init(SysBusDevice *dev)
}
bus = pci_register_bus(&dev->qdev, "pci",
pci_vpb_set_irq, pci_vpb_map_irq, s->irq,
- get_system_memory(),
+ get_system_memory(), get_system_io(),
PCI_DEVFN(11, 0), 4);
/* ??? Register memory space. */
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 4954bb18be..96e6e7dd21 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -27,6 +27,7 @@
#include "vga_int.h"
#include "pixel_ops.h"
#include "qemu-timer.h"
+#include "exec-memory.h"
typedef struct ISAVGAMMState {
VGACommonState vga;
@@ -79,35 +80,44 @@ static void vga_mm_writel (void *opaque,
vga_ioport_write(&s->vga, addr >> s->it_shift, value);
}
-static CPUReadMemoryFunc * const vga_mm_read_ctrl[] = {
- &vga_mm_readb,
- &vga_mm_readw,
- &vga_mm_readl,
-};
-
-static CPUWriteMemoryFunc * const vga_mm_write_ctrl[] = {
- &vga_mm_writeb,
- &vga_mm_writew,
- &vga_mm_writel,
+static const MemoryRegionOps vga_mm_ctrl_ops = {
+ .old_mmio = {
+ .read = {
+ vga_mm_readb,
+ vga_mm_readw,
+ vga_mm_readl,
+ },
+ .write = {
+ vga_mm_writeb,
+ vga_mm_writew,
+ vga_mm_writel,
+ },
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base,
target_phys_addr_t ctrl_base, int it_shift)
{
- int s_ioport_ctrl, vga_io_memory;
+ MemoryRegion *s_ioport_ctrl, *vga_io_memory;
s->it_shift = it_shift;
- s_ioport_ctrl = cpu_register_io_memory(vga_mm_read_ctrl, vga_mm_write_ctrl, s,
- DEVICE_NATIVE_ENDIAN);
- vga_io_memory = cpu_register_io_memory(vga_mem_read, vga_mem_write, s,
- DEVICE_NATIVE_ENDIAN);
+ s_ioport_ctrl = qemu_malloc(sizeof(*s_ioport_ctrl));
+ memory_region_init_io(s_ioport_ctrl, &vga_mm_ctrl_ops, s,
+ "vga-mm-ctrl", 0x100000);
+
+ vga_io_memory = qemu_malloc(sizeof(*vga_io_memory));
+ /* XXX: endianness? */
+ memory_region_init_io(vga_io_memory, &vga_mem_ops, &s->vga,
+ "vga-mem", 0x20000);
vmstate_register(NULL, 0, &vmstate_vga_common, s);
- cpu_register_physical_memory(ctrl_base, 0x100000, s_ioport_ctrl);
+ memory_region_add_subregion(get_system_memory(), ctrl_base, s_ioport_ctrl);
s->vga.bank_offset = 0;
- cpu_register_physical_memory(vram_base + 0x000a0000, 0x20000, vga_io_memory);
- qemu_register_coalesced_mmio(vram_base + 0x000a0000, 0x20000);
+ memory_region_add_subregion(get_system_memory(),
+ vram_base + 0x000a0000, vga_io_memory);
+ memory_region_set_coalescing(vga_io_memory);
}
int isa_vga_mm_init(target_phys_addr_t vram_base,
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 245841f18b..fef7f58f28 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -28,6 +28,7 @@
#include "pixel_ops.h"
#include "qemu-timer.h"
#include "loader.h"
+#include "exec-memory.h"
typedef struct ISAVGAState {
ISADevice dev;
@@ -46,13 +47,14 @@ static int vga_initfn(ISADevice *dev)
{
ISAVGAState *d = DO_UPCAST(ISAVGAState, dev, dev);
VGACommonState *s = &d->state;
- int vga_io_memory;
+ MemoryRegion *vga_io_memory;
vga_common_init(s, VGA_RAM_SIZE);
vga_io_memory = vga_init_io(s);
- cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
- vga_io_memory);
- qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+ memory_region_add_subregion_overlap(get_system_memory(),
+ isa_mem_base + 0x000a0000,
+ vga_io_memory, 1);
+ memory_region_set_coalescing(vga_io_memory);
isa_init_ioport(dev, 0x3c0);
isa_init_ioport(dev, 0x3b4);
isa_init_ioport(dev, 0x3ba);
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 481f448e3f..c67be0abeb 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -47,29 +47,6 @@ static const VMStateDescription vmstate_vga_pci = {
}
};
-static void vga_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- PCIVGAState *d = (PCIVGAState *)pci_dev;
- VGACommonState *s = &d->vga;
-
- cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
- s->map_addr = addr;
- s->map_end = addr + s->vram_size;
- vga_dirty_log_start(s);
-}
-
-static void pci_vga_write_config(PCIDevice *d,
- uint32_t address, uint32_t val, int len)
-{
- PCIVGAState *pvs = container_of(d, PCIVGAState, dev);
- VGACommonState *s = &pvs->vga;
-
- pci_default_write_config(d, address, val, len);
- if (s->map_addr && pvs->dev.io_regions[0].addr == -1)
- s->map_addr = 0;
-}
-
static int pci_vga_initfn(PCIDevice *dev)
{
PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
@@ -83,8 +60,7 @@ static int pci_vga_initfn(PCIDevice *dev)
s->screen_dump, s->text_update, s);
/* XXX: VGA_RAM_SIZE must be a power of two */
- pci_register_bar(&d->dev, 0, VGA_RAM_SIZE,
- PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
+ pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
if (!dev->rom_bar) {
/* compatibility with pc-0.13 and older */
@@ -106,7 +82,6 @@ static PCIDeviceInfo vga_info = {
.qdev.vmsd = &vmstate_vga_pci,
.no_hotplug = 1,
.init = pci_vga_initfn,
- .config_write = pci_vga_write_config,
.romfile = "vgabios-stdvga.bin",
/* dummy VGA (same as Bochs ID) */
diff --git a/hw/vga.c b/hw/vga.c
index 0f54734624..33dc478a7d 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -28,6 +28,7 @@
#include "vga_int.h"
#include "pixel_ops.h"
#include "qemu-timer.h"
+#include "exec-memory.h"
//#define DEBUG_VGA
//#define DEBUG_VGA_MEM
@@ -707,9 +708,8 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
#endif
/* called for accesses between 0xa0000 and 0xc0000 */
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
+uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr)
{
- VGACommonState *s = opaque;
int memory_map_mode, plane;
uint32_t ret;
@@ -763,28 +763,9 @@ uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
return ret;
}
-static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
- v = vga_mem_readb(opaque, addr);
- v |= vga_mem_readb(opaque, addr + 1) << 8;
- return v;
-}
-
-static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr)
-{
- uint32_t v;
- v = vga_mem_readb(opaque, addr);
- v |= vga_mem_readb(opaque, addr + 1) << 8;
- v |= vga_mem_readb(opaque, addr + 2) << 16;
- v |= vga_mem_readb(opaque, addr + 3) << 24;
- return v;
-}
-
/* called for accesses between 0xa0000 and 0xc0000 */
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val)
{
- VGACommonState *s = opaque;
int memory_map_mode, plane, write_mode, b, func_select, mask;
uint32_t write_mask, bit_mask, set_mask;
@@ -825,7 +806,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr);
#endif
s->plane_updated |= mask; /* only used to detect font change */
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
+ memory_region_set_dirty(&s->vram, addr);
}
} else if (s->gr[5] & 0x10) {
/* odd/even mode (aka text mode mapping) */
@@ -838,7 +819,7 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr);
#endif
s->plane_updated |= mask; /* only used to detect font change */
- cpu_physical_memory_set_dirty(s->vram_offset + addr);
+ memory_region_set_dirty(&s->vram, addr);
}
} else {
/* standard VGA latched access */
@@ -912,24 +893,10 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
printf("vga: latch: [0x" TARGET_FMT_plx "] mask=0x%08x val=0x%08x\n",
addr * 4, write_mask, val);
#endif
- cpu_physical_memory_set_dirty(s->vram_offset + (addr << 2));
+ memory_region_set_dirty(&s->vram, addr << 2);
}
}
-static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- vga_mem_writeb(opaque, addr, val & 0xff);
- vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
-}
-
-static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
- vga_mem_writeb(opaque, addr, val & 0xff);
- vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
- vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
- vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
-}
-
typedef void vga_draw_glyph8_func(uint8_t *d, int linesize,
const uint8_t *font_ptr, int h,
uint32_t fgcol, uint32_t bgcol);
@@ -1553,57 +1520,17 @@ void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2)
static void vga_sync_dirty_bitmap(VGACommonState *s)
{
- if (s->map_addr)
- cpu_physical_sync_dirty_bitmap(s->map_addr, s->map_end);
-
- if (s->lfb_vram_mapped) {
- cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa0000, 0xa8000);
- cpu_physical_sync_dirty_bitmap(isa_mem_base + 0xa8000, 0xb0000);
- }
-
-#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_mapped) {
- cpu_physical_sync_dirty_bitmap(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
- VBE_DISPI_LFB_PHYSICAL_ADDRESS + s->vram_size);
- }
-#endif
-
+ memory_region_sync_dirty_bitmap(&s->vram);
}
void vga_dirty_log_start(VGACommonState *s)
{
- if (s->map_addr) {
- cpu_physical_log_start(s->map_addr, s->map_end - s->map_addr);
- }
-
- if (s->lfb_vram_mapped) {
- cpu_physical_log_start(isa_mem_base + 0xa0000, 0x8000);
- cpu_physical_log_start(isa_mem_base + 0xa8000, 0x8000);
- }
-
-#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_mapped) {
- cpu_physical_log_start(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
- }
-#endif
+ memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
}
void vga_dirty_log_stop(VGACommonState *s)
{
- if (s->map_addr) {
- cpu_physical_log_stop(s->map_addr, s->map_end - s->map_addr);
- }
-
- if (s->lfb_vram_mapped) {
- cpu_physical_log_stop(isa_mem_base + 0xa0000, 0x8000);
- cpu_physical_log_stop(isa_mem_base + 0xa8000, 0x8000);
- }
-
-#ifdef CONFIG_BOCHS_VBE
- if (s->vbe_mapped) {
- cpu_physical_log_stop(VBE_DISPI_LFB_PHYSICAL_ADDRESS, s->vram_size);
- }
-#endif
+ memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
}
void vga_dirty_log_restart(VGACommonState *s)
@@ -1773,15 +1700,16 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
if (!(s->cr[0x17] & 2)) {
addr = (addr & ~0x8000) | ((y1 & 2) << 14);
}
- page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);
- page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);
+ page0 = addr & TARGET_PAGE_MASK;
+ page1 = (addr + bwidth - 1) & TARGET_PAGE_MASK;
update = full_update |
- cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |
- cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);
+ memory_region_get_dirty(&s->vram, page0, DIRTY_MEMORY_VGA) |
+ memory_region_get_dirty(&s->vram, page1, DIRTY_MEMORY_VGA);
if ((page1 - page0) > TARGET_PAGE_SIZE) {
/* if wide line, can use another page */
- update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,
- VGA_DIRTY_FLAG);
+ update |= memory_region_get_dirty(&s->vram,
+ page0 + TARGET_PAGE_SIZE,
+ DIRTY_MEMORY_VGA);
}
/* explicit invalidation for the hardware cursor */
update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;
@@ -1826,8 +1754,10 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
}
/* reset modified pages */
if (page_max >= page_min) {
- cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,
- VGA_DIRTY_FLAG);
+ memory_region_reset_dirty(&s->vram,
+ page_min,
+ page_max + TARGET_PAGE_SIZE - page_min,
+ DIRTY_MEMORY_VGA);
}
memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);
}
@@ -1906,11 +1836,6 @@ static void vga_invalidate_display(void *opaque)
void vga_common_reset(VGACommonState *s)
{
- s->lfb_addr = 0;
- s->lfb_end = 0;
- s->map_addr = 0;
- s->map_end = 0;
- s->lfb_vram_mapped = 0;
s->sr_index = 0;
memset(s->sr, '\0', sizeof(s->sr));
s->gr_index = 0;
@@ -2141,16 +2066,30 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
dpy_update(s->ds, 0, 0, s->last_width, height);
}
-CPUReadMemoryFunc * const vga_mem_read[3] = {
- vga_mem_readb,
- vga_mem_readw,
- vga_mem_readl,
-};
+static uint64_t vga_mem_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
+{
+ VGACommonState *s = opaque;
+
+ return vga_mem_readb(s, addr);
+}
+
+static void vga_mem_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
+{
+ VGACommonState *s = opaque;
+
+ return vga_mem_writeb(s, addr, data);
+}
-CPUWriteMemoryFunc * const vga_mem_write[3] = {
- vga_mem_writeb,
- vga_mem_writew,
- vga_mem_writel,
+const MemoryRegionOps vga_mem_ops = {
+ .read = vga_mem_read,
+ .write = vga_mem_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .impl = {
+ .min_access_size = 1,
+ .max_access_size = 1,
+ },
};
static int vga_common_post_load(void *opaque, int version_id)
@@ -2236,8 +2175,8 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
#else
s->is_vbe_vmstate = 0;
#endif
- s->vram_offset = qemu_ram_alloc(NULL, "vga.vram", vga_ram_size);
- s->vram_ptr = qemu_get_ram_ptr(s->vram_offset);
+ memory_region_init_ram(&s->vram, NULL, "vga.vram", vga_ram_size);
+ s->vram_ptr = memory_region_get_ram_ptr(&s->vram);
s->vram_size = vga_ram_size;
s->get_bpp = vga_get_bpp;
s->get_offsets = vga_get_offsets;
@@ -2257,11 +2196,14 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
s->update_retrace_info = vga_precise_update_retrace_info;
break;
}
+ vga_dirty_log_start(s);
}
/* used by both ISA and PCI */
-int vga_init_io(VGACommonState *s)
+MemoryRegion *vga_init_io(VGACommonState *s)
{
+ MemoryRegion *vga_mem;
+
register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s);
register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s);
@@ -2292,30 +2234,36 @@ int vga_init_io(VGACommonState *s)
#endif
#endif /* CONFIG_BOCHS_VBE */
- return cpu_register_io_memory(vga_mem_read, vga_mem_write, s,
- DEVICE_LITTLE_ENDIAN);
+ vga_mem = qemu_malloc(sizeof(*vga_mem));
+ memory_region_init_io(vga_mem, &vga_mem_ops, s,
+ "vga-lowmem", 0x20000);
+
+ return vga_mem;
}
void vga_init(VGACommonState *s)
{
- int vga_io_memory;
+ MemoryRegion *vga_io_memory;
qemu_register_reset(vga_reset, s);
s->bank_offset = 0;
vga_io_memory = vga_init_io(s);
- cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000,
- vga_io_memory);
- qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000);
+ memory_region_add_subregion_overlap(get_system_memory(),
+ isa_mem_base + 0x000a0000,
+ vga_io_memory,
+ 1);
+ memory_region_set_coalescing(vga_io_memory);
}
void vga_init_vbe(VGACommonState *s)
{
#ifdef CONFIG_BOCHS_VBE
/* XXX: use optimized standard vga accesses */
- cpu_register_physical_memory(VBE_DISPI_LFB_PHYSICAL_ADDRESS,
- VGA_RAM_SIZE, s->vram_offset);
+ memory_region_add_subregion(get_system_memory(),
+ VBE_DISPI_LFB_PHYSICAL_ADDRESS,
+ &s->vram);
s->vbe_mapped = 1;
#endif
}
diff --git a/hw/vga_int.h b/hw/vga_int.h
index eee91a84f3..100d98c8bf 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -23,6 +23,7 @@
*/
#include <hw/hw.h>
+#include "memory.h"
#define MSR_COLOR_EMULATION 0x01
#define MSR_PAGE_SELECT 0x20
@@ -105,11 +106,7 @@ typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s);
typedef struct VGACommonState {
uint8_t *vram_ptr;
- ram_addr_t vram_offset;
- target_phys_addr_t lfb_addr;
- target_phys_addr_t lfb_end;
- target_phys_addr_t map_addr;
- target_phys_addr_t map_end;
+ MemoryRegion vram;
uint32_t vram_size;
uint32_t latch;
uint32_t lfb_vram_mapped; /* whether 0xa0000 is mapped as ram */
@@ -134,7 +131,7 @@ typedef struct VGACommonState {
int dac_8bit;
uint8_t palette[768];
int32_t bank_offset;
- int vga_io_memory;
+ MemoryRegion *vga_io_memory;
int (*get_bpp)(struct VGACommonState *s);
void (*get_offsets)(struct VGACommonState *s,
uint32_t *pline_offset,
@@ -191,7 +188,7 @@ static inline int c6_to_8(int v)
void vga_common_init(VGACommonState *s, int vga_ram_size);
void vga_init(VGACommonState *s);
-int vga_init_io(VGACommonState *s);
+MemoryRegion *vga_init_io(VGACommonState *s);
void vga_common_reset(VGACommonState *s);
void vga_dirty_log_start(VGACommonState *s);
@@ -201,8 +198,8 @@ void vga_dirty_log_restart(VGACommonState *s);
extern const VMStateDescription vmstate_vga_common;
uint32_t vga_ioport_read(void *opaque, uint32_t addr);
void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val);
-uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr);
-void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val);
+uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr);
+void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val);
void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
int ppm_save(const char *filename, struct DisplaySurface *ds);
@@ -229,5 +226,4 @@ extern const uint8_t gr_mask[16];
#define VGABIOS_FILENAME "vgabios.bin"
#define VGABIOS_CIRRUS_FILENAME "vgabios-cirrus.bin"
-extern CPUReadMemoryFunc * const vga_mem_read[3];
-extern CPUWriteMemoryFunc * const vga_mem_write[3];
+extern const MemoryRegionOps vga_mem_ops;
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index f3b3293db0..df27c198b0 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -162,7 +162,8 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
{
VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
- int r;
+ int r = 0;
+
if (assign) {
r = event_notifier_init(notifier, 1);
if (r < 0) {
@@ -170,24 +171,11 @@ static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
__func__, r);
return r;
}
- r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
- proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
- n, assign);
- if (r < 0) {
- error_report("%s: unable to map ioeventfd: %d",
- __func__, r);
- event_notifier_cleanup(notifier);
- }
+ memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
+ true, n, event_notifier_get_fd(notifier));
} else {
- r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
- proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
- n, assign);
- if (r < 0) {
- error_report("%s: unable to unmap ioeventfd: %d",
- __func__, r);
- return r;
- }
-
+ memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
+ true, n, event_notifier_get_fd(notifier));
/* Handle the race condition where the guest kicked and we deassigned
* before we got around to handling the kick.
*/
@@ -424,7 +412,6 @@ static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
{
VirtIOPCIProxy *proxy = opaque;
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
- addr -= proxy->addr;
if (addr < config)
return virtio_ioport_read(proxy, addr);
addr -= config;
@@ -435,7 +422,6 @@ static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
{
VirtIOPCIProxy *proxy = opaque;
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
- addr -= proxy->addr;
if (addr < config)
return virtio_ioport_read(proxy, addr);
addr -= config;
@@ -446,7 +432,6 @@ static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
{
VirtIOPCIProxy *proxy = opaque;
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
- addr -= proxy->addr;
if (addr < config)
return virtio_ioport_read(proxy, addr);
addr -= config;
@@ -457,7 +442,6 @@ static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
{
VirtIOPCIProxy *proxy = opaque;
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
- addr -= proxy->addr;
if (addr < config) {
virtio_ioport_write(proxy, addr, val);
return;
@@ -470,7 +454,6 @@ static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
{
VirtIOPCIProxy *proxy = opaque;
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
- addr -= proxy->addr;
if (addr < config) {
virtio_ioport_write(proxy, addr, val);
return;
@@ -483,7 +466,6 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
{
VirtIOPCIProxy *proxy = opaque;
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
- addr -= proxy->addr;
if (addr < config) {
virtio_ioport_write(proxy, addr, val);
return;
@@ -492,25 +474,20 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
virtio_config_writel(proxy->vdev, addr, val);
}
-static void virtio_map(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev);
- VirtIODevice *vdev = proxy->vdev;
- unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len;
-
- proxy->addr = addr;
-
- register_ioport_write(addr, config_len, 1, virtio_pci_config_writeb, proxy);
- register_ioport_write(addr, config_len, 2, virtio_pci_config_writew, proxy);
- register_ioport_write(addr, config_len, 4, virtio_pci_config_writel, proxy);
- register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy);
- register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy);
- register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy);
+const MemoryRegionPortio virtio_portio[] = {
+ { 0, 0x10000, 1, .write = virtio_pci_config_writeb, },
+ { 0, 0x10000, 2, .write = virtio_pci_config_writew, },
+ { 0, 0x10000, 4, .write = virtio_pci_config_writel, },
+ { 0, 0x10000, 1, .read = virtio_pci_config_readb, },
+ { 0, 0x10000, 2, .read = virtio_pci_config_readw, },
+ { 0, 0x10000, 4, .read = virtio_pci_config_readl, },
+ PORTIO_END_OF_LIST()
+};
- if (vdev->config_len)
- vdev->get_config(vdev, vdev->config);
-}
+static const MemoryRegionOps virtio_pci_config_ops = {
+ .old_portio = virtio_portio,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
uint32_t val, int len)
@@ -664,11 +641,11 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
pci_set_word(config + 0x2e, vdev->device_id);
config[0x3d] = 1;
- if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) {
- pci_register_bar(&proxy->pci_dev, 1,
- msix_bar_size(&proxy->pci_dev),
- PCI_BASE_ADDRESS_SPACE_MEMORY,
- msix_mmio_map);
+ memory_region_init(&proxy->msix_bar, "virtio-msix", 4096);
+ if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors,
+ &proxy->msix_bar, 1, 0)) {
+ pci_register_bar(&proxy->pci_dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
+ &proxy->msix_bar);
} else
vdev->nvectors = 0;
@@ -678,8 +655,10 @@ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
if (size & (size-1))
size = 1 << qemu_fls(size);
- pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO,
- virtio_map);
+ memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
+ "virtio-pci", size);
+ pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
+ &proxy->bar);
if (!kvm_has_many_ioeventfds()) {
proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
@@ -714,7 +693,13 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
static int virtio_exit_pci(PCIDevice *pci_dev)
{
- return msix_uninit(pci_dev);
+ VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+ int r;
+
+ memory_region_destroy(&proxy->bar);
+ r = msix_uninit(pci_dev, &proxy->msix_bar);
+ memory_region_destroy(&proxy->msix_bar);
+ return r;
}
static int virtio_blk_exit_pci(PCIDevice *pci_dev)
diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
index 1f0de5684d..14c10f7d67 100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@ -21,8 +21,9 @@
typedef struct {
PCIDevice pci_dev;
VirtIODevice *vdev;
+ MemoryRegion bar;
+ MemoryRegion msix_bar;
uint32_t flags;
- uint32_t addr;
uint32_t class_code;
uint32_t nvectors;
BlockConf block;
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 354c221720..d5cfa70cba 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -52,8 +52,6 @@ struct vmsvga_state_s {
int on;
} cursor;
- target_phys_addr_t vram_base;
-
int index;
int scratch_size;
uint32_t *scratch;
@@ -67,10 +65,9 @@ struct vmsvga_state_s {
int syncing;
int fb_size;
- ram_addr_t fifo_offset;
+ MemoryRegion fifo_ram;
uint8_t *fifo_ptr;
unsigned int fifo_size;
- target_phys_addr_t fifo_base;
union {
uint32_t *fifo;
@@ -94,6 +91,7 @@ struct vmsvga_state_s {
struct pci_vmsvga_state_s {
PCIDevice card;
struct vmsvga_state_s chip;
+ MemoryRegion io_bar;
};
#define SVGA_MAGIC 0x900000UL
@@ -761,8 +759,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
case SVGA_REG_BYTES_PER_LINE:
return ((s->depth + 7) >> 3) * s->new_width;
- case SVGA_REG_FB_START:
- return s->vram_base;
+ case SVGA_REG_FB_START: {
+ struct pci_vmsvga_state_s *pci_vmsvga
+ = container_of(s, struct pci_vmsvga_state_s, chip);
+ return pci_get_bar_addr(&pci_vmsvga->card, 1);
+ }
case SVGA_REG_FB_OFFSET:
return 0x0;
@@ -788,8 +789,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
#endif
return caps;
- case SVGA_REG_MEM_START:
- return s->fifo_base;
+ case SVGA_REG_MEM_START: {
+ struct pci_vmsvga_state_s *pci_vmsvga
+ = container_of(s, struct pci_vmsvga_state_s, chip);
+ return pci_get_bar_addr(&pci_vmsvga->card, 2);
+ }
case SVGA_REG_MEM_SIZE:
return s->fifo_size;
@@ -1134,17 +1138,22 @@ static void vmsvga_vram_writel(void *opaque, target_phys_addr_t addr,
*(uint32_t *) (s->vram_ptr + addr) = value;
}
-static CPUReadMemoryFunc * const vmsvga_vram_read[] = {
- vmsvga_vram_readb,
- vmsvga_vram_readw,
- vmsvga_vram_readl,
-};
+static const MemoryRegionOps vmsvga_vram_io_ops = {
+ .old_mmio = {
+ .read = {
+ vmsvga_vram_readb,
+ vmsvga_vram_readw,
+ vmsvga_vram_readl,
+ },
+ .write = {
+ vmsvga_vram_writeb,
+ vmsvga_vram_writew,
+ vmsvga_vram_writel,
+ },
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
+}
-static CPUWriteMemoryFunc * const vmsvga_vram_write[] = {
- vmsvga_vram_writeb,
- vmsvga_vram_writew,
- vmsvga_vram_writel,
-};
#endif
static int vmsvga_post_load(void *opaque, int version_id)
@@ -1210,8 +1219,8 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
s->fifo_size = SVGA_FIFO_SIZE;
- s->fifo_offset = qemu_ram_alloc(NULL, "vmsvga.fifo", s->fifo_size);
- s->fifo_ptr = qemu_get_ram_ptr(s->fifo_offset);
+ memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size);
+ s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
vga_common_init(&s->vga, vga_ram_size);
vga_init(&s->vga);
@@ -1220,80 +1229,76 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
vmsvga_reset(s);
}
-static void pci_vmsvga_map_ioport(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static uint64_t vmsvga_io_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
- struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
- struct vmsvga_state_s *s = &d->chip;
-
- register_ioport_read(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
- 1, 4, vmsvga_index_read, s);
- register_ioport_write(addr + SVGA_IO_MUL * SVGA_INDEX_PORT,
- 1, 4, vmsvga_index_write, s);
- register_ioport_read(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
- 1, 4, vmsvga_value_read, s);
- register_ioport_write(addr + SVGA_IO_MUL * SVGA_VALUE_PORT,
- 1, 4, vmsvga_value_write, s);
- register_ioport_read(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
- 1, 4, vmsvga_bios_read, s);
- register_ioport_write(addr + SVGA_IO_MUL * SVGA_BIOS_PORT,
- 1, 4, vmsvga_bios_write, s);
+ struct vmsvga_state_s *s = opaque;
+
+ switch (addr) {
+ case SVGA_IO_MUL * SVGA_INDEX_PORT: return vmsvga_index_read(s, addr);
+ case SVGA_IO_MUL * SVGA_VALUE_PORT: return vmsvga_value_read(s, addr);
+ case SVGA_IO_MUL * SVGA_BIOS_PORT: return vmsvga_bios_read(s, addr);
+ default: return -1u;
+ }
}
-static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static void vmsvga_io_write(void *opaque, target_phys_addr_t addr,
+ uint64_t data, unsigned size)
{
- struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
- struct vmsvga_state_s *s = &d->chip;
- ram_addr_t iomemtype;
-
- s->vram_base = addr;
-#ifdef DIRECT_VRAM
- iomemtype = cpu_register_io_memory(vmsvga_vram_read,
- vmsvga_vram_write, s, DEVICE_NATIVE_ENDIAN);
-#else
- iomemtype = s->vga.vram_offset | IO_MEM_RAM;
-#endif
- cpu_register_physical_memory(s->vram_base, s->vga.vram_size,
- iomemtype);
+ struct vmsvga_state_s *s = opaque;
- s->vga.map_addr = addr;
- s->vga.map_end = addr + s->vga.vram_size;
- vga_dirty_log_restart(&s->vga);
+ switch (addr) {
+ case SVGA_IO_MUL * SVGA_INDEX_PORT:
+ return vmsvga_index_write(s, addr, data);
+ case SVGA_IO_MUL * SVGA_VALUE_PORT:
+ return vmsvga_value_write(s, addr, data);
+ case SVGA_IO_MUL * SVGA_BIOS_PORT:
+ return vmsvga_bios_write(s, addr, data);
+ }
}
-static void pci_vmsvga_map_fifo(PCIDevice *pci_dev, int region_num,
- pcibus_t addr, pcibus_t size, int type)
-{
- struct pci_vmsvga_state_s *d = (struct pci_vmsvga_state_s *) pci_dev;
- struct vmsvga_state_s *s = &d->chip;
- ram_addr_t iomemtype;
-
- s->fifo_base = addr;
- iomemtype = s->fifo_offset | IO_MEM_RAM;
- cpu_register_physical_memory(s->fifo_base, s->fifo_size,
- iomemtype);
-}
+static const MemoryRegionOps vmsvga_io_ops = {
+ .read = vmsvga_io_read,
+ .write = vmsvga_io_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ },
+};
static int pci_vmsvga_initfn(PCIDevice *dev)
{
struct pci_vmsvga_state_s *s =
DO_UPCAST(struct pci_vmsvga_state_s, card, dev);
+ MemoryRegion *iomem;
+
+#ifdef DIRECT_VRAM
+ DirectMem *directmem = qemu_malloc(sizeof(*directmem));
+
+ iomem = &directmem->mr;
+ memory_region_init_io(iomem, &vmsvga_vram_io_ops, &s->chip, "vmsvga",
+ memory_region_size(&s->chip.vga.vram));
+#else
+ iomem = &s->chip.vga.vram;
+#endif
+
+ vga_dirty_log_restart(&s->chip.vga);
s->card.config[PCI_CACHE_LINE_SIZE] = 0x08; /* Cache line size */
s->card.config[PCI_LATENCY_TIMER] = 0x40; /* Latency timer */
s->card.config[PCI_INTERRUPT_LINE] = 0xff; /* End */
- pci_register_bar(&s->card, 0, 0x10,
- PCI_BASE_ADDRESS_SPACE_IO, pci_vmsvga_map_ioport);
- pci_register_bar(&s->card, 1, VGA_RAM_SIZE,
- PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_mem);
-
- pci_register_bar(&s->card, 2, SVGA_FIFO_SIZE,
- PCI_BASE_ADDRESS_MEM_PREFETCH, pci_vmsvga_map_fifo);
+ memory_region_init_io(&s->io_bar, &vmsvga_io_ops, &s->chip,
+ "vmsvga-io", 0x10);
+ pci_register_bar(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
vmsvga_init(&s->chip, VGA_RAM_SIZE);
+ pci_register_bar(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
+ pci_register_bar(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
+ &s->chip.fifo_ram);
+
if (!dev->rom_bar) {
/* compatibility with pc-0.13 and older */
vga_init_vbe(&s->chip.vga);
diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 53786ce8fa..20d8673186 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -66,6 +66,7 @@
/* Device state. */
struct I6300State {
PCIDevice dev;
+ MemoryRegion io_mem;
int reboot_enabled; /* "Reboot" on timer expiry. The real action
* performed depends on the -watchdog-action
@@ -355,6 +356,22 @@ static void i6300esb_mem_writel(void *vp, target_phys_addr_t addr, uint32_t val)
}
}
+static const MemoryRegionOps i6300esb_ops = {
+ .old_mmio = {
+ .read = {
+ i6300esb_mem_readb,
+ i6300esb_mem_readw,
+ i6300esb_mem_readl,
+ },
+ .write = {
+ i6300esb_mem_writeb,
+ i6300esb_mem_writew,
+ i6300esb_mem_writel,
+ },
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
static const VMStateDescription vmstate_i6300esb = {
.name = "i6300esb_wdt",
.version_id = sizeof(I6300State),
@@ -381,31 +398,28 @@ static const VMStateDescription vmstate_i6300esb = {
static int i6300esb_init(PCIDevice *dev)
{
I6300State *d = DO_UPCAST(I6300State, dev, dev);
- int io_mem;
- static CPUReadMemoryFunc * const mem_read[3] = {
- i6300esb_mem_readb,
- i6300esb_mem_readw,
- i6300esb_mem_readl,
- };
- static CPUWriteMemoryFunc * const mem_write[3] = {
- i6300esb_mem_writeb,
- i6300esb_mem_writew,
- i6300esb_mem_writel,
- };
i6300esb_debug("I6300State = %p\n", d);
d->timer = qemu_new_timer_ns(vm_clock, i6300esb_timer_expired, d);
d->previous_reboot_flag = 0;
- io_mem = cpu_register_io_memory(mem_read, mem_write, d,
- DEVICE_NATIVE_ENDIAN);
- pci_register_bar_simple(&d->dev, 0, 0x10, 0, io_mem);
+ memory_region_init_io(&d->io_mem, &i6300esb_ops, d, "i6300esb", 0x10);
+ pci_register_bar(&d->dev, 0, 0, &d->io_mem);
/* qemu_register_coalesced_mmio (addr, 0x10); ? */
return 0;
}
+static int i6300esb_exit(PCIDevice *dev)
+{
+ I6300State *d = DO_UPCAST(I6300State, dev, dev);
+
+ memory_region_destroy(&d->io_mem);
+
+ return 0;
+}
+
static WatchdogTimerModel model = {
.wdt_name = "i6300esb",
.wdt_description = "Intel 6300ESB",
@@ -419,6 +433,7 @@ static PCIDeviceInfo i6300esb_info = {
.config_read = i6300esb_config_read,
.config_write = i6300esb_config_write,
.init = i6300esb_init,
+ .exit = i6300esb_exit,
.vendor_id = PCI_VENDOR_ID_INTEL,
.device_id = PCI_DEVICE_ID_INTEL_ESB_9,
.class_id = PCI_CLASS_SYSTEM_OTHER,
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index fb6be6a464..6e3ba8b507 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -32,8 +32,8 @@
#include "xen_common.h"
#include "net.h"
#include "xen_backend.h"
-#include "rwhandler.h"
#include "trace.h"
+#include "exec-memory.h"
#include <xenguest.h>
@@ -51,6 +51,9 @@
typedef struct PCIXenPlatformState {
PCIDevice pci_dev;
+ MemoryRegion fixed_io;
+ MemoryRegion bar;
+ MemoryRegion mmio_bar;
uint8_t flags; /* used only for version_id == 2 */
int drivers_blacklisted;
uint16_t driver_product_version;
@@ -221,21 +224,32 @@ static void platform_fixed_ioport_reset(void *opaque)
platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, 0);
}
+const MemoryRegionPortio xen_platform_ioport[] = {
+ { 0, 16, 4, .write = platform_fixed_ioport_writel, },
+ { 0, 16, 2, .write = platform_fixed_ioport_writew, },
+ { 0, 16, 1, .write = platform_fixed_ioport_writeb, },
+ { 0, 16, 2, .read = platform_fixed_ioport_readw, },
+ { 0, 16, 1, .read = platform_fixed_ioport_readb, },
+ PORTIO_END_OF_LIST()
+};
+
+static const MemoryRegionOps platform_fixed_io_ops = {
+ .old_portio = xen_platform_ioport,
+ .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
static void platform_fixed_ioport_init(PCIXenPlatformState* s)
{
- register_ioport_write(XEN_PLATFORM_IOPORT, 16, 4, platform_fixed_ioport_writel, s);
- register_ioport_write(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_writew, s);
- register_ioport_write(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_writeb, s);
- register_ioport_read(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_readw, s);
- register_ioport_read(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_readb, s);
+ memory_region_init_io(&s->fixed_io, &platform_fixed_io_ops, s,
+ "xen-fixed", 16);
+ memory_region_add_subregion(get_system_io(), XEN_PLATFORM_IOPORT,
+ &s->fixed_io);
}
/* Xen Platform PCI Device */
static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
{
- addr &= 0xff;
-
if (addr == 0) {
return platform_fixed_ioport_readb(opaque, XEN_PLATFORM_IOPORT);
} else {
@@ -247,9 +261,6 @@ static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val
{
PCIXenPlatformState *s = opaque;
- addr &= 0xff;
- val &= 0xff;
-
switch (addr) {
case 0: /* Platform flags */
platform_fixed_ioport_writeb(opaque, XEN_PLATFORM_IOPORT, val);
@@ -262,15 +273,23 @@ static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val
}
}
-static void platform_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type)
-{
- PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, pci_dev);
+static MemoryRegionPortio xen_pci_portio[] = {
+ { 0, 0x100, 1, .read = xen_platform_ioport_readb, },
+ { 0, 0x100, 1, .write = xen_platform_ioport_writeb, },
+ PORTIO_END_OF_LIST()
+};
+
+static const MemoryRegionOps xen_pci_io_ops = {
+ .old_portio = xen_pci_portio,
+};
- register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
- register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
+static void platform_ioport_bar_setup(PCIXenPlatformState *d)
+{
+ memory_region_init_io(&d->bar, &xen_pci_io_ops, d, "xen-pci", 0x100);
}
-static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int len)
+static uint64_t platform_mmio_read(void *opaque, target_phys_addr_t addr,
+ unsigned size)
{
DPRINTF("Warning: attempted read from physical address "
"0x" TARGET_FMT_plx " in xen platform mmio space\n", addr);
@@ -278,28 +297,24 @@ static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int
return 0;
}
-static void platform_mmio_write(ReadWriteHandler *handler, pcibus_t addr,
- uint32_t val, int len)
+static void platform_mmio_write(void *opaque, target_phys_addr_t addr,
+ uint64_t val, unsigned size)
{
- DPRINTF("Warning: attempted write of 0x%x to physical "
+ DPRINTF("Warning: attempted write of 0x%"PRIx64" to physical "
"address 0x" TARGET_FMT_plx " in xen platform mmio space\n",
val, addr);
}
-static ReadWriteHandler platform_mmio_handler = {
+static const MemoryRegionOps platform_mmio_handler = {
.read = &platform_mmio_read,
.write = &platform_mmio_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
-static void platform_mmio_map(PCIDevice *d, int region_num,
- pcibus_t addr, pcibus_t size, int type)
+static void platform_mmio_setup(PCIXenPlatformState *d)
{
- int mmio_io_addr;
-
- mmio_io_addr = cpu_register_io_memory_simple(&platform_mmio_handler,
- DEVICE_NATIVE_ENDIAN);
-
- cpu_register_physical_memory(addr, size, mmio_io_addr);
+ memory_region_init_io(&d->mmio_bar, &platform_mmio_handler, d,
+ "xen-mmio", 0x1000000);
}
static int xen_platform_post_load(void *opaque, int version_id)
@@ -337,12 +352,13 @@ static int xen_platform_initfn(PCIDevice *dev)
pci_conf[PCI_INTERRUPT_PIN] = 1;
- pci_register_bar(&d->pci_dev, 0, 0x100,
- PCI_BASE_ADDRESS_SPACE_IO, platform_ioport_map);
+ platform_ioport_bar_setup(d);
+ pci_register_bar(&d->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->bar);
/* reserve 16MB mmio address for share memory*/
- pci_register_bar(&d->pci_dev, 1, 0x1000000,
- PCI_BASE_ADDRESS_MEM_PREFETCH, platform_mmio_map);
+ platform_mmio_setup(d);
+ pci_register_bar(&d->pci_dev, 1, PCI_BASE_ADDRESS_MEM_PREFETCH,
+ &d->mmio_bar);
platform_fixed_ioport_init(d);