summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.objs2
-rw-r--r--Makefile.target2
-rw-r--r--hw/arm11mpcore.c13
-rw-r--r--hw/fdc.c34
-rw-r--r--hw/gus.c38
-rw-r--r--hw/ide/core.c30
-rw-r--r--hw/ide/internal.h3
-rw-r--r--hw/ide/isa.c4
-rw-r--r--hw/ide/piix.c7
-rw-r--r--hw/ide/via.c7
-rw-r--r--hw/isa-bus.c45
-rw-r--r--hw/isa.h38
-rw-r--r--hw/lan9118.c29
-rw-r--r--hw/m48t59.c15
-rw-r--r--hw/mc146818rtc.c15
-rw-r--r--hw/ne2000-isa.c5
-rw-r--r--hw/palm.c53
-rw-r--r--hw/parallel.c47
-rw-r--r--hw/pc.c16
-rw-r--r--hw/petalogix_ml605_mmu.c15
-rw-r--r--hw/petalogix_s3adsp1800_mmu.c18
-rw-r--r--hw/ppc405_boards.c85
-rw-r--r--hw/ppc_newworld.c39
-rw-r--r--hw/qxl.c2
-rw-r--r--hw/realview.c12
-rw-r--r--hw/sb16.c32
-rw-r--r--hw/versatile_pci.c42
-rw-r--r--hw/versatilepb.c12
-rw-r--r--hw/vga-isa.c17
-rw-r--r--hw/vga-pci.c2
-rw-r--r--hw/vga.c73
-rw-r--r--hw/vga_int.h7
-rw-r--r--hw/vmport.c16
-rw-r--r--hw/vmware_vga.c7
-rw-r--r--ioport.c108
-rw-r--r--ioport.h21
-rw-r--r--memory.c18
37 files changed, 535 insertions, 394 deletions
diff --git a/Makefile.objs b/Makefile.objs
index 7b0739c524..6424efde41 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -82,7 +82,7 @@ common-obj-$(CONFIG_WIN32) += os-win32.o
common-obj-$(CONFIG_POSIX) += os-posix.o
common-obj-y += tcg-runtime.o host-utils.o
-common-obj-y += irq.o ioport.o input.o
+common-obj-y += irq.o input.o
common-obj-$(CONFIG_PTIMER) += ptimer.o
common-obj-$(CONFIG_MAX7310) += max7310.o
common-obj-$(CONFIG_WM8750) += wm8750.o
diff --git a/Makefile.target b/Makefile.target
index 42adfecc35..c22b3cb8e3 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -183,7 +183,7 @@ endif #CONFIG_BSD_USER
# System emulator target
ifdef CONFIG_SOFTMMU
-obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o
+obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o
# virtio has to be here due to weird dependency between PCI and virtio-net.
# need to fix this properly
obj-$(CONFIG_NO_PCI) += pci-stub.o
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index 7d60ef6ba8..974a0d8262 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -48,17 +48,6 @@ static void mpcore_rirq_set_irq(void *opaque, int irq, int level)
}
}
-static void mpcore_rirq_map(SysBusDevice *dev, target_phys_addr_t base)
-{
- mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev);
- sysbus_mmio_map(s->priv, 0, base);
-}
-
-static void mpcore_rirq_unmap(SysBusDevice *dev, target_phys_addr_t base)
-{
- /* nothing to do */
-}
-
static int realview_mpcore_init(SysBusDevice *dev)
{
mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev);
@@ -84,7 +73,7 @@ static int realview_mpcore_init(SysBusDevice *dev)
}
}
qdev_init_gpio_in(&dev->qdev, mpcore_rirq_set_irq, 64);
- sysbus_init_mmio_cb2(dev, mpcore_rirq_map, mpcore_rirq_unmap);
+ sysbus_init_mmio_region(dev, sysbus_mmio_get_region(s->priv, 0));
return 0;
}
diff --git a/hw/fdc.c b/hw/fdc.c
index 0f1cee9439..4b06e049e8 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -424,7 +424,6 @@ typedef struct FDCtrlSysBus {
typedef struct FDCtrlISABus {
ISADevice busdev;
- MemoryRegion io_0, io_7;
struct FDCtrl state;
int32_t bootindexA;
int32_t bootindexB;
@@ -1880,32 +1879,10 @@ static int fdctrl_init_common(FDCtrl *fdctrl)
return fdctrl_connect_drives(fdctrl);
}
-static uint32_t fdctrl_read_port_7(void *opaque, uint32_t reg)
-{
- return fdctrl_read(opaque, reg + 7);
-}
-
-static void fdctrl_write_port_7(void *opaque, uint32_t reg, uint32_t value)
-{
- fdctrl_write(opaque, reg + 7, value);
-}
-
-static const MemoryRegionPortio fdc_portio_0[] = {
+static const MemoryRegionPortio fdc_portio_list[] = {
{ 1, 5, 1, .read = fdctrl_read, .write = fdctrl_write },
- PORTIO_END_OF_LIST()
-};
-
-static const MemoryRegionPortio fdc_portio_7[] = {
- { 0, 1, 1, .read = fdctrl_read_port_7, .write = fdctrl_write_port_7 },
- PORTIO_END_OF_LIST()
-};
-
-static const MemoryRegionOps fdc_ioport_0_ops = {
- .old_portio = fdc_portio_0
-};
-
-static const MemoryRegionOps fdc_ioport_7_ops = {
- .old_portio = fdc_portio_7
+ { 7, 1, 1, .read = fdctrl_read, .write = fdctrl_write },
+ PORTIO_END_OF_LIST(),
};
static int isabus_fdc_init1(ISADevice *dev)
@@ -1917,10 +1894,7 @@ static int isabus_fdc_init1(ISADevice *dev)
int dma_chann = 2;
int ret;
- memory_region_init_io(&isa->io_0, &fdc_ioport_0_ops, fdctrl, "fdc", 6);
- memory_region_init_io(&isa->io_7, &fdc_ioport_7_ops, fdctrl, "fdc", 1);
- isa_register_ioport(dev, &isa->io_0, iobase);
- isa_register_ioport(dev, &isa->io_7, iobase + 7);
+ isa_register_portio_list(dev, iobase, fdc_portio_list, fdctrl, "fdc");
isa_init_irq(&isa->busdev, &fdctrl->irq, isairq);
fdctrl->dma_chann = dma_chann;
diff --git a/hw/gus.c b/hw/gus.c
index a65192d4a2..b5eb548795 100644
--- a/hw/gus.c
+++ b/hw/gus.c
@@ -232,6 +232,22 @@ static const VMStateDescription vmstate_gus = {
}
};
+static const MemoryRegionPortio gus_portio_list1[] = {
+ {0x000, 1, 1, .write = gus_writeb },
+ {0x000, 1, 2, .write = gus_writew },
+ {0x006, 10, 1, .read = gus_readb, .write = gus_writeb },
+ {0x006, 10, 2, .read = gus_readw, .write = gus_writew },
+ {0x100, 8, 1, .read = gus_readb, .write = gus_writeb },
+ {0x100, 8, 2, .read = gus_readw, .write = gus_writew },
+ PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionPortio gus_portio_list2[] = {
+ {0, 1, 1, .read = gus_readb },
+ {0, 1, 2, .read = gus_readw },
+ PORTIO_END_OF_LIST(),
+};
+
static int gus_initfn (ISADevice *dev)
{
GUSState *s = DO_UPCAST (GUSState, dev, dev);
@@ -262,25 +278,9 @@ static int gus_initfn (ISADevice *dev)
s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift;
s->mixbuf = g_malloc0 (s->samples << s->shift);
- register_ioport_write (s->port, 1, 1, gus_writeb, s);
- register_ioport_write (s->port, 1, 2, gus_writew, s);
- isa_init_ioport_range (dev, s->port, 2);
-
- register_ioport_read ((s->port + 0x100) & 0xf00, 1, 1, gus_readb, s);
- register_ioport_read ((s->port + 0x100) & 0xf00, 1, 2, gus_readw, s);
- isa_init_ioport_range (dev, (s->port + 0x100) & 0xf00, 2);
-
- register_ioport_write (s->port + 6, 10, 1, gus_writeb, s);
- register_ioport_write (s->port + 6, 10, 2, gus_writew, s);
- register_ioport_read (s->port + 6, 10, 1, gus_readb, s);
- register_ioport_read (s->port + 6, 10, 2, gus_readw, s);
- isa_init_ioport_range (dev, s->port + 6, 10);
-
- register_ioport_write (s->port + 0x100, 8, 1, gus_writeb, s);
- register_ioport_write (s->port + 0x100, 8, 2, gus_writew, s);
- register_ioport_read (s->port + 0x100, 8, 1, gus_readb, s);
- register_ioport_read (s->port + 0x100, 8, 2, gus_readw, s);
- isa_init_ioport_range (dev, s->port + 0x100, 8);
+ isa_register_portio_list (dev, s->port, gus_portio_list1, s, "gus");
+ isa_register_portio_list (dev, (s->port + 0x100) & 0xf00,
+ gus_portio_list2, s, "gus");
DMA_register_channel (s->emu.gusdma, GUS_read_DMA, s);
s->emu.himemaddr = s->himem;
diff --git a/hw/ide/core.c b/hw/ide/core.c
index b71a356f39..534b186f6f 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -25,6 +25,7 @@
#include <hw/hw.h>
#include <hw/pc.h>
#include <hw/pci.h>
+#include <hw/isa.h>
#include "qemu-error.h"
#include "qemu-timer.h"
#include "sysemu.h"
@@ -1969,20 +1970,27 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
bus->dma = &ide_dma_nop;
}
-void ide_init_ioport(IDEBus *bus, int iobase, int iobase2)
+static const MemoryRegionPortio ide_portio_list[] = {
+ { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
+ { 0, 2, 2, .read = ide_data_readw, .write = ide_data_writew },
+ { 0, 4, 4, .read = ide_data_readl, .write = ide_data_writel },
+ PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionPortio ide_portio2_list[] = {
+ { 0, 1, 1, .read = ide_status_read, .write = ide_cmd_write },
+ PORTIO_END_OF_LIST(),
+};
+
+void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2)
{
- register_ioport_write(iobase, 8, 1, ide_ioport_write, bus);
- register_ioport_read(iobase, 8, 1, ide_ioport_read, bus);
+ /* ??? Assume only ISA and PCI configurations, and that the PCI-ISA
+ bridge has been setup properly to always register with ISA. */
+ isa_register_portio_list(dev, iobase, ide_portio_list, bus, "ide");
+
if (iobase2) {
- register_ioport_read(iobase2, 1, 1, ide_status_read, bus);
- register_ioport_write(iobase2, 1, 1, ide_cmd_write, bus);
+ isa_register_portio_list(dev, iobase2, ide_portio2_list, bus, "ide");
}
-
- /* data ports */
- register_ioport_write(iobase, 2, 2, ide_data_writew, bus);
- register_ioport_read(iobase, 2, 2, ide_data_readw, bus);
- register_ioport_write(iobase, 4, 4, ide_data_writel, bus);
- register_ioport_read(iobase, 4, 4, ide_data_readl, bus);
}
static bool is_identify_set(void *opaque, int version_id)
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 9046e96013..c39dc058f4 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -7,6 +7,7 @@
* non-internal declarations are in hw/ide.h
*/
#include <hw/ide.h>
+#include <hw/isa.h>
#include "iorange.h"
#include "dma.h"
#include "sysemu.h"
@@ -600,7 +601,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
void ide_init2(IDEBus *bus, qemu_irq irq);
void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
DriveInfo *hd1, qemu_irq irq);
-void ide_init_ioport(IDEBus *bus, int iobase, int iobase2);
+void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2);
void ide_exec_cmd(IDEBus *bus, uint32_t val);
void ide_dma_cb(void *opaque, int ret);
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 28b69d2cc3..01a9e59cb9 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -66,10 +66,8 @@ static int isa_ide_initfn(ISADevice *dev)
ISAIDEState *s = DO_UPCAST(ISAIDEState, dev, dev);
ide_bus_new(&s->bus, &s->dev.qdev, 0);
- ide_init_ioport(&s->bus, s->iobase, s->iobase2);
+ ide_init_ioport(&s->bus, dev, s->iobase, s->iobase2);
isa_init_irq(dev, &s->irq, s->isairq);
- isa_init_ioport_range(dev, s->iobase, 8);
- isa_init_ioport(dev, s->iobase2);
ide_init2(&s->bus, s->irq);
vmstate_register(&dev->qdev, 0, &vmstate_ide_isa, s);
return 0;
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 88d318127c..08cbbe2032 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -122,8 +122,7 @@ static void piix3_reset(void *opaque)
}
static void pci_piix_init_ports(PCIIDEState *d) {
- int i;
- struct {
+ static const struct {
int iobase;
int iobase2;
int isairq;
@@ -131,10 +130,12 @@ static void pci_piix_init_ports(PCIIDEState *d) {
{0x1f0, 0x3f6, 14},
{0x170, 0x376, 15},
};
+ int i;
for (i = 0; i < 2; i++) {
ide_bus_new(&d->bus[i], &d->dev.qdev, i);
- ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
+ ide_init_ioport(&d->bus[i], NULL, 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], d);
diff --git a/hw/ide/via.c b/hw/ide/via.c
index dab8a39f57..098f150bb2 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -146,8 +146,7 @@ static void via_reset(void *opaque)
}
static void vt82c686b_init_ports(PCIIDEState *d) {
- int i;
- struct {
+ static const struct {
int iobase;
int iobase2;
int isairq;
@@ -155,10 +154,12 @@ static void vt82c686b_init_ports(PCIIDEState *d) {
{0x1f0, 0x3f6, 14},
{0x170, 0x376, 15},
};
+ int i;
for (i = 0; i < 2; i++) {
ide_bus_new(&d->bus[i], &d->dev.qdev, i);
- ide_init_ioport(&d->bus[i], port_info[i].iobase, port_info[i].iobase2);
+ ide_init_ioport(&d->bus[i], NULL, 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], d);
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 6c15a31fe8..7c2c2619d0 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -83,39 +83,32 @@ void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq)
dev->nirqs++;
}
-static void isa_init_ioport_one(ISADevice *dev, uint16_t ioport)
+static inline void isa_init_ioport(ISADevice *dev, uint16_t ioport)
{
- assert(dev->nioports < ARRAY_SIZE(dev->ioports));
- dev->ioports[dev->nioports++] = ioport;
+ if (dev && (dev->ioport_id == 0 || ioport < dev->ioport_id)) {
+ dev->ioport_id = ioport;
+ }
}
-static int isa_cmp_ports(const void *p1, const void *p2)
+void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
{
- return *(uint16_t*)p1 - *(uint16_t*)p2;
+ memory_region_add_subregion(isabus->address_space_io, start, io);
+ isa_init_ioport(dev, start);
}
-void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length)
+void isa_register_portio_list(ISADevice *dev, uint16_t start,
+ const MemoryRegionPortio *pio_start,
+ void *opaque, const char *name)
{
- int i;
- for (i = start; i < start + length; i++) {
- isa_init_ioport_one(dev, i);
- }
- qsort(dev->ioports, dev->nioports, sizeof(dev->ioports[0]), isa_cmp_ports);
-}
+ PortioList *piolist = g_new(PortioList, 1);
-void isa_init_ioport(ISADevice *dev, uint16_t ioport)
-{
- isa_init_ioport_range(dev, ioport, 1);
-}
+ /* START is how we should treat DEV, regardless of the actual
+ contents of the portio array. This is how the old code
+ actually handled e.g. the FDC device. */
+ isa_init_ioport(dev, start);
-void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
-{
- memory_region_add_subregion(isabus->address_space_io, start, io);
- if (dev != NULL) {
- assert(dev->nio < ARRAY_SIZE(dev->io));
- dev->io[dev->nio++] = io;
- isa_init_ioport_range(dev, start, memory_region_size(io));
- }
+ portio_list_init(piolist, pio_start, opaque, name);
+ portio_list_add(piolist, isabus->address_space_io, start);
}
static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
@@ -208,8 +201,8 @@ static char *isabus_get_fw_dev_path(DeviceState *dev)
int off;
off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev));
- if (d->nioports) {
- snprintf(path + off, sizeof(path) - off, "@%04x", d->ioports[0]);
+ if (d->ioport_id) {
+ snprintf(path + off, sizeof(path) - off, "@%04x", d->ioport_id);
}
return strdup(path);
diff --git a/hw/isa.h b/hw/isa.h
index 432d17ab26..d3cae350a0 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -13,12 +13,9 @@ typedef struct ISADeviceInfo ISADeviceInfo;
struct ISADevice {
DeviceState qdev;
- MemoryRegion *io[32];
uint32_t isairq[2];
- uint16_t ioports[32];
int nirqs;
- int nioports;
- int nio;
+ int ioport_id;
};
typedef int (*isa_qdev_initfn)(ISADevice *dev);
@@ -31,15 +28,42 @@ ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io);
void isa_bus_irqs(qemu_irq *irqs);
qemu_irq isa_get_irq(int isairq);
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
-void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start);
-void isa_init_ioport(ISADevice *dev, uint16_t ioport);
-void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length);
void isa_qdev_register(ISADeviceInfo *info);
MemoryRegion *isa_address_space(ISADevice *dev);
ISADevice *isa_create(const char *name);
ISADevice *isa_try_create(const char *name);
ISADevice *isa_create_simple(const char *name);
+/**
+ * isa_register_ioport: Install an I/O port region on the ISA bus.
+ *
+ * Register an I/O port region via memory_region_add_subregion
+ * inside the ISA I/O address space.
+ *
+ * @dev: the ISADevice against which these are registered; may be NULL.
+ * @io: the #MemoryRegion being registered.
+ * @start: the base I/O port.
+ */
+void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start);
+
+/**
+ * isa_register_portio_list: Initialize a set of ISA io ports
+ *
+ * Several ISA devices have many dis-joint I/O ports. Worse, these I/O
+ * ports can be interleaved with I/O ports from other devices. This
+ * function makes it easy to create multiple MemoryRegions for a single
+ * device and use the legacy portio routines.
+ *
+ * @dev: the ISADevice against which these are registered; may be NULL.
+ * @start: the base I/O port against which the portio->offset is applied.
+ * @portio: the ports, sorted by offset.
+ * @opaque: passed into the old_portio callbacks.
+ * @name: passed into memory_region_init_io.
+ */
+void isa_register_portio_list(ISADevice *dev, uint16_t start,
+ const MemoryRegionPortio *portio,
+ void *opaque, const char *name);
+
extern target_phys_addr_t isa_mem_base;
void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size);
diff --git a/hw/lan9118.c b/hw/lan9118.c
index 73a8661ca3..634b88ee14 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -152,7 +152,7 @@ typedef struct {
NICState *nic;
NICConf conf;
qemu_irq irq;
- int mmio_index;
+ MemoryRegion mmio;
ptimer_state *timer;
uint32_t irq_cfg;
@@ -895,7 +895,7 @@ static void lan9118_tick(void *opaque)
}
static void lan9118_writel(void *opaque, target_phys_addr_t offset,
- uint32_t val)
+ uint64_t val, unsigned size)
{
lan9118_state *s = (lan9118_state *)opaque;
offset &= 0xff;
@@ -1022,13 +1022,14 @@ static void lan9118_writel(void *opaque, target_phys_addr_t offset,
break;
default:
- hw_error("lan9118_write: Bad reg 0x%x = %x\n", (int)offset, val);
+ hw_error("lan9118_write: Bad reg 0x%x = %x\n", (int)offset, (int)val);
break;
}
lan9118_update(s);
}
-static uint32_t lan9118_readl(void *opaque, target_phys_addr_t offset)
+static uint64_t lan9118_readl(void *opaque, target_phys_addr_t offset,
+ unsigned size)
{
lan9118_state *s = (lan9118_state *)opaque;
@@ -1101,16 +1102,10 @@ static uint32_t lan9118_readl(void *opaque, target_phys_addr_t offset)
return 0;
}
-static CPUReadMemoryFunc * const lan9118_readfn[] = {
- lan9118_readl,
- lan9118_readl,
- lan9118_readl
-};
-
-static CPUWriteMemoryFunc * const lan9118_writefn[] = {
- lan9118_writel,
- lan9118_writel,
- lan9118_writel
+static const MemoryRegionOps lan9118_mem_ops = {
+ .read = lan9118_readl,
+ .write = lan9118_writel,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void lan9118_cleanup(VLANClientState *nc)
@@ -1135,10 +1130,8 @@ static int lan9118_init1(SysBusDevice *dev)
QEMUBH *bh;
int i;
- s->mmio_index = cpu_register_io_memory(lan9118_readfn,
- lan9118_writefn, s,
- DEVICE_NATIVE_ENDIAN);
- sysbus_init_mmio(dev, 0x100, s->mmio_index);
+ memory_region_init_io(&s->mmio, &lan9118_mem_ops, s, "lan9118-mmio", 0x100);
+ sysbus_init_mmio_region(dev, &s->mmio);
sysbus_init_irq(dev, &s->irq);
qemu_macaddr_default_if_unset(&s->conf.macaddr);
diff --git a/hw/m48t59.c b/hw/m48t59.c
index 0cc361eedc..f318e67919 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -73,6 +73,7 @@ struct M48t59State {
typedef struct M48t59ISAState {
ISADevice busdev;
M48t59State state;
+ MemoryRegion io;
} M48t59ISAState;
typedef struct M48t59SysBusState {
@@ -626,6 +627,15 @@ static void m48t59_reset_sysbus(DeviceState *d)
m48t59_reset_common(NVRAM);
}
+static const MemoryRegionPortio m48t59_portio[] = {
+ {0, 4, 1, .read = NVRAM_readb, .write = NVRAM_writeb },
+ PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionOps m48t59_io_ops = {
+ .old_portio = m48t59_portio,
+};
+
/* Initialisation routine */
M48t59State *m48t59_init(qemu_irq IRQ, target_phys_addr_t mem_base,
uint32_t io_base, uint16_t size, int type)
@@ -669,10 +679,9 @@ M48t59State *m48t59_init_isa(uint32_t io_base, uint16_t size, int type)
d = DO_UPCAST(M48t59ISAState, busdev, dev);
s = &d->state;
+ memory_region_init_io(&d->io, &m48t59_io_ops, s, "m48t59", 4);
if (io_base != 0) {
- register_ioport_read(io_base, 0x04, 1, NVRAM_readb, s);
- register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s);
- isa_init_ioport_range(dev, io_base, 4);
+ isa_register_ioport(dev, &d->io, io_base);
}
return s;
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index feb3b25acd..2aaca2ff41 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -81,6 +81,7 @@
typedef struct RTCState {
ISADevice dev;
+ MemoryRegion io;
uint8_t cmos_data[128];
uint8_t cmos_index;
struct tm current_tm;
@@ -604,6 +605,15 @@ static void rtc_reset(void *opaque)
#endif
}
+static const MemoryRegionPortio cmos_portio[] = {
+ {0, 2, 1, .read = cmos_ioport_read, .write = cmos_ioport_write },
+ PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionOps cmos_ops = {
+ .old_portio = cmos_portio
+};
+
static int rtc_initfn(ISADevice *dev)
{
RTCState *s = DO_UPCAST(RTCState, dev, dev);
@@ -632,9 +642,8 @@ static int rtc_initfn(ISADevice *dev)
qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100;
qemu_mod_timer(s->second_timer2, s->next_second_time);
- register_ioport_write(base, 2, 1, cmos_ioport_write, s);
- register_ioport_read(base, 2, 1, cmos_ioport_read, s);
- isa_init_ioport_range(dev, base, 2);
+ memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2);
+ isa_register_ioport(dev, &s->io, base);
qdev_set_legacy_instance_id(&dev->qdev, base, 2);
qemu_register_reset(rtc_reset, s);
diff --git a/hw/ne2000-isa.c b/hw/ne2000-isa.c
index 756ed5ca46..11ffee7d7c 100644
--- a/hw/ne2000-isa.c
+++ b/hw/ne2000-isa.c
@@ -68,10 +68,7 @@ static int isa_ne2000_initfn(ISADevice *dev)
NE2000State *s = &isa->ne2000;
ne2000_setup_io(s, 0x20);
- isa_init_ioport_range(dev, isa->iobase, 16);
- isa_init_ioport_range(dev, isa->iobase + 0x10, 2);
- isa_init_ioport(dev, isa->iobase + 0x1f);
- memory_region_add_subregion(get_system_io(), isa->iobase, &s->io);
+ isa_register_ioport(dev, &s->io, isa->iobase);
isa_init_irq(dev, &s->irq, isa->isairq);
diff --git a/hw/palm.c b/hw/palm.c
index d8f50e3413..094bfde369 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -54,16 +54,12 @@ static void static_write(void *opaque, target_phys_addr_t offset,
#endif
}
-static CPUReadMemoryFunc * const static_readfn[] = {
- static_readb,
- static_readh,
- static_readw,
-};
-
-static CPUWriteMemoryFunc * const static_writefn[] = {
- static_write,
- static_write,
- static_write,
+static const MemoryRegionOps static_ops = {
+ .old_mmio = {
+ .read = { static_readb, static_readh, static_readw, },
+ .write = { static_write, static_write, static_write, },
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
/* Palm Tunsgten|E support */
@@ -203,34 +199,35 @@ static void palmte_init(ram_addr_t ram_size,
struct omap_mpu_state_s *cpu;
int flash_size = 0x00800000;
int sdram_size = palmte_binfo.ram_size;
- int io;
static uint32_t cs0val = 0xffffffff;
static uint32_t cs1val = 0x0000e1a0;
static uint32_t cs2val = 0x0000e1a0;
static uint32_t cs3val = 0xe1a0e1a0;
int rom_size, rom_loaded = 0;
DisplayState *ds = get_displaystate();
+ MemoryRegion *flash = g_new(MemoryRegion, 1);
+ MemoryRegion *cs = g_new(MemoryRegion, 4);
cpu = omap310_mpu_init(address_space_mem, sdram_size, cpu_model);
/* External Flash (EMIFS) */
- cpu_register_physical_memory(OMAP_CS0_BASE, flash_size,
- qemu_ram_alloc(NULL, "palmte.flash",
- flash_size) | IO_MEM_ROM);
-
- io = cpu_register_io_memory(static_readfn, static_writefn, &cs0val,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(OMAP_CS0_BASE + flash_size,
- OMAP_CS0_SIZE - flash_size, io);
- io = cpu_register_io_memory(static_readfn, static_writefn, &cs1val,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(OMAP_CS1_BASE, OMAP_CS1_SIZE, io);
- io = cpu_register_io_memory(static_readfn, static_writefn, &cs2val,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(OMAP_CS2_BASE, OMAP_CS2_SIZE, io);
- io = cpu_register_io_memory(static_readfn, static_writefn, &cs3val,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(OMAP_CS3_BASE, OMAP_CS3_SIZE, io);
+ memory_region_init_ram(flash, NULL, "palmte.flash", flash_size);
+ memory_region_set_readonly(flash, true);
+ memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash);
+
+ memory_region_init_io(&cs[0], &static_ops, &cs0val, "palmte-cs0",
+ OMAP_CS0_SIZE - flash_size);
+ memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE + flash_size,
+ &cs[0]);
+ memory_region_init_io(&cs[1], &static_ops, &cs1val, "palmte-cs1",
+ OMAP_CS1_SIZE);
+ memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1]);
+ memory_region_init_io(&cs[2], &static_ops, &cs2val, "palmte-cs2",
+ OMAP_CS2_SIZE);
+ memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2]);
+ memory_region_init_io(&cs[3], &static_ops, &cs3val, "palmte-cs3",
+ OMAP_CS3_SIZE);
+ memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3]);
palmte_microwire_setup(cpu);
diff --git a/hw/parallel.c b/hw/parallel.c
index ecbc8c3b77..8494d94f69 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -448,6 +448,29 @@ static void parallel_reset(void *opaque)
static const int isa_parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
+static const MemoryRegionPortio isa_parallel_portio_hw_list[] = {
+ { 0, 8, 1,
+ .read = parallel_ioport_read_hw,
+ .write = parallel_ioport_write_hw },
+ { 4, 1, 2,
+ .read = parallel_ioport_eppdata_read_hw2,
+ .write = parallel_ioport_eppdata_write_hw2 },
+ { 4, 1, 4,
+ .read = parallel_ioport_eppdata_read_hw4,
+ .write = parallel_ioport_eppdata_write_hw4 },
+ { 0x400, 8, 1,
+ .read = parallel_ioport_ecp_read,
+ .write = parallel_ioport_ecp_write },
+ PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionPortio isa_parallel_portio_sw_list[] = {
+ { 0, 8, 1,
+ .read = parallel_ioport_read_sw,
+ .write = parallel_ioport_write_sw },
+ PORTIO_END_OF_LIST(),
+};
+
static int parallel_isa_initfn(ISADevice *dev)
{
static int index;
@@ -478,25 +501,11 @@ static int parallel_isa_initfn(ISADevice *dev)
s->status = dummy;
}
- if (s->hw_driver) {
- register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s);
- register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s);
- isa_init_ioport_range(dev, base, 8);
-
- register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
- register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
- register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
- register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
- isa_init_ioport(dev, base+4);
- register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s);
- register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s);
- isa_init_ioport_range(dev, base+0x400, 8);
- }
- else {
- register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s);
- register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s);
- isa_init_ioport_range(dev, base, 8);
- }
+ isa_register_portio_list(dev, base,
+ (s->hw_driver
+ ? &isa_parallel_portio_hw_list[0]
+ : &isa_parallel_portio_sw_list[0]),
+ s, "parallel");
return 0;
}
diff --git a/hw/pc.c b/hw/pc.c
index 203627d46e..ded475805f 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -428,6 +428,7 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
/* port 92 stuff: could be split off */
typedef struct Port92State {
ISADevice dev;
+ MemoryRegion io;
uint8_t outport;
qemu_irq *a20_out;
} Port92State;
@@ -479,13 +480,22 @@ static void port92_reset(DeviceState *d)
s->outport &= ~1;
}
+static const MemoryRegionPortio port92_portio[] = {
+ { 0, 1, 1, .read = port92_read, .write = port92_write },
+ PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionOps port92_ops = {
+ .old_portio = port92_portio
+};
+
static int port92_initfn(ISADevice *dev)
{
Port92State *s = DO_UPCAST(Port92State, dev, dev);
- register_ioport_read(0x92, 1, 1, port92_read, s);
- register_ioport_write(0x92, 1, 1, port92_write, s);
- isa_init_ioport(dev, 0x92);
+ memory_region_init_io(&s->io, &port92_ops, s, "port92", 1);
+ isa_register_ioport(dev, &s->io, 0x92);
+
s->outport = 0;
return 0;
}
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index 2a0f7fd031..fb4ba29bf8 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -149,8 +149,8 @@ petalogix_ml605_init(ram_addr_t ram_size,
DriveInfo *dinfo;
int i;
target_phys_addr_t ddr_base = MEMORY_BASEADDR;
- ram_addr_t phys_lmb_bram;
- ram_addr_t phys_ram;
+ MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1);
+ MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
qemu_irq irq[32], *cpu_irq;
/* init CPUs */
@@ -162,13 +162,12 @@ petalogix_ml605_init(ram_addr_t ram_size,
qemu_register_reset(main_cpu_reset, env);
/* Attach emulated BRAM through the LMB. */
- phys_lmb_bram = qemu_ram_alloc(NULL, "petalogix_ml605.lmb_bram",
- LMB_BRAM_SIZE);
- cpu_register_physical_memory(0x00000000, LMB_BRAM_SIZE,
- phys_lmb_bram | IO_MEM_RAM);
+ memory_region_init_ram(phys_lmb_bram, NULL, "petalogix_ml605.lmb_bram",
+ LMB_BRAM_SIZE);
+ memory_region_add_subregion(address_space_mem, 0x00000000, phys_lmb_bram);
- phys_ram = qemu_ram_alloc(NULL, "petalogix_ml605.ram", ram_size);
- cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
+ memory_region_init_ram(phys_ram, NULL, "petalogix_ml605.ram", ram_size);
+ memory_region_add_subregion(address_space_mem, ddr_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
/* 5th parameter 2 means bank-width
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 66fb96d8eb..17da2fd87c 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -35,6 +35,7 @@
#include "loader.h"
#include "elf.h"
#include "blockdev.h"
+#include "exec-memory.h"
#include "microblaze_pic_cpu.h"
@@ -125,9 +126,10 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
DriveInfo *dinfo;
int i;
target_phys_addr_t ddr_base = 0x90000000;
- ram_addr_t phys_lmb_bram;
- ram_addr_t phys_ram;
+ MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1);
+ MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
qemu_irq irq[32], *cpu_irq;
+ MemoryRegion *sysmem = get_system_memory();
/* init CPUs */
if (cpu_model == NULL) {
@@ -139,13 +141,13 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
qemu_register_reset(main_cpu_reset, env);
/* Attach emulated BRAM through the LMB. */
- phys_lmb_bram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.lmb_bram",
- LMB_BRAM_SIZE);
- cpu_register_physical_memory(0x00000000, LMB_BRAM_SIZE,
- phys_lmb_bram | IO_MEM_RAM);
+ memory_region_init_ram(phys_lmb_bram, NULL,
+ "petalogix_s3adsp1800.lmb_bram", LMB_BRAM_SIZE);
+ memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram);
- phys_ram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.ram", ram_size);
- cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
+ memory_region_init_ram(phys_ram, NULL, "petalogix_s3adsp1800.ram",
+ ram_size);
+ memory_region_add_subregion(sysmem, ddr_base, phys_ram);
dinfo = drive_get(IF_PFLASH, 0, 0);
pflash_cfi01_register(0xa0000000,
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index 9136288d08..672e9347ac 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -137,16 +137,16 @@ static void ref405ep_fpga_writel (void *opaque,
ref405ep_fpga_writeb(opaque, addr + 3, value & 0xFF);
}
-static CPUReadMemoryFunc * const ref405ep_fpga_read[] = {
- &ref405ep_fpga_readb,
- &ref405ep_fpga_readw,
- &ref405ep_fpga_readl,
-};
-
-static CPUWriteMemoryFunc * const ref405ep_fpga_write[] = {
- &ref405ep_fpga_writeb,
- &ref405ep_fpga_writew,
- &ref405ep_fpga_writel,
+static const MemoryRegionOps ref405ep_fpga_ops = {
+ .old_mmio = {
+ .read = {
+ ref405ep_fpga_readb, ref405ep_fpga_readw, ref405ep_fpga_readl,
+ },
+ .write = {
+ ref405ep_fpga_writeb, ref405ep_fpga_writew, ref405ep_fpga_writel,
+ },
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void ref405ep_fpga_reset (void *opaque)
@@ -158,16 +158,15 @@ static void ref405ep_fpga_reset (void *opaque)
fpga->reg1 = 0x0F;
}
-static void ref405ep_fpga_init (uint32_t base)
+static void ref405ep_fpga_init (MemoryRegion *sysmem, uint32_t base)
{
ref405ep_fpga_t *fpga;
- int fpga_memory;
+ MemoryRegion *fpga_memory = g_new(MemoryRegion, 1);
fpga = g_malloc0(sizeof(ref405ep_fpga_t));
- fpga_memory = cpu_register_io_memory(ref405ep_fpga_read,
- ref405ep_fpga_write, fpga,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x00000100, fpga_memory);
+ memory_region_init_io(fpga_memory, &ref405ep_fpga_ops, fpga,
+ "fpga", 0x00000100);
+ memory_region_add_subregion(sysmem, base, fpga_memory);
qemu_register_reset(&ref405ep_fpga_reset, fpga);
}
@@ -183,7 +182,8 @@ static void ref405ep_init (ram_addr_t ram_size,
CPUPPCState *env;
qemu_irq *pic;
MemoryRegion *bios;
- ram_addr_t sram_offset, bdloc;
+ MemoryRegion *sram = g_new(MemoryRegion, 1);
+ ram_addr_t bdloc;
MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
target_phys_addr_t ram_bases[2], ram_sizes[2];
target_ulong sram_size;
@@ -195,6 +195,7 @@ static void ref405ep_init (ram_addr_t ram_size,
int linux_boot;
int fl_idx, fl_sectors, len;
DriveInfo *dinfo;
+ MemoryRegion *sysmem = get_system_memory();
/* XXX: fix this */
memory_region_init_ram(&ram_memories[0], NULL, "ef405ep.ram", 0x08000000);
@@ -207,17 +208,12 @@ static void ref405ep_init (ram_addr_t ram_size,
#ifdef DEBUG_BOARD_INIT
printf("%s: register cpu\n", __func__);
#endif
- env = ppc405ep_init(get_system_memory(), ram_memories, ram_bases, ram_sizes,
+ env = ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
33333333, &pic, kernel_filename == NULL ? 0 : 1);
/* allocate SRAM */
sram_size = 512 * 1024;
- sram_offset = qemu_ram_alloc(NULL, "ef405ep.sram", sram_size);
-#ifdef DEBUG_BOARD_INIT
- printf("%s: register SRAM at offset " RAM_ADDR_FMT "\n",
- __func__, sram_offset);
-#endif
- cpu_register_physical_memory(0xFFF00000, sram_size,
- sram_offset | IO_MEM_RAM);
+ memory_region_init_ram(sram, NULL, "ef405ep.sram", sram_size);
+ memory_region_add_subregion(sysmem, 0xFFF00000, sram);
/* allocate and load BIOS */
#ifdef DEBUG_BOARD_INIT
printf("%s: register BIOS\n", __func__);
@@ -264,14 +260,13 @@ static void ref405ep_init (ram_addr_t ram_size,
}
bios_size = (bios_size + 0xfff) & ~0xfff;
memory_region_set_readonly(bios, true);
- memory_region_add_subregion(get_system_memory(),
- (uint32_t)(-bios_size), bios);
+ memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
}
/* Register FPGA */
#ifdef DEBUG_BOARD_INIT
printf("%s: register FPGA\n", __func__);
#endif
- ref405ep_fpga_init(0xF0300000);
+ ref405ep_fpga_init(sysmem, 0xF0300000);
/* Register NVRAM */
#ifdef DEBUG_BOARD_INIT
printf("%s: register NVRAM\n", __func__);
@@ -469,16 +464,12 @@ static void taihu_cpld_writel (void *opaque,
taihu_cpld_writeb(opaque, addr + 3, value & 0xFF);
}
-static CPUReadMemoryFunc * const taihu_cpld_read[] = {
- &taihu_cpld_readb,
- &taihu_cpld_readw,
- &taihu_cpld_readl,
-};
-
-static CPUWriteMemoryFunc * const taihu_cpld_write[] = {
- &taihu_cpld_writeb,
- &taihu_cpld_writew,
- &taihu_cpld_writel,
+static const MemoryRegionOps taihu_cpld_ops = {
+ .old_mmio = {
+ .read = { taihu_cpld_readb, taihu_cpld_readw, taihu_cpld_readl, },
+ .write = { taihu_cpld_writeb, taihu_cpld_writew, taihu_cpld_writel, },
+ },
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static void taihu_cpld_reset (void *opaque)
@@ -490,16 +481,14 @@ static void taihu_cpld_reset (void *opaque)
cpld->reg1 = 0x80;
}
-static void taihu_cpld_init (uint32_t base)
+static void taihu_cpld_init (MemoryRegion *sysmem, uint32_t base)
{
taihu_cpld_t *cpld;
- int cpld_memory;
+ MemoryRegion *cpld_memory = g_new(MemoryRegion, 1);
cpld = g_malloc0(sizeof(taihu_cpld_t));
- cpld_memory = cpu_register_io_memory(taihu_cpld_read,
- taihu_cpld_write, cpld,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(base, 0x00000100, cpld_memory);
+ memory_region_init_io(cpld_memory, &taihu_cpld_ops, cpld, "cpld", 0x100);
+ memory_region_add_subregion(sysmem, base, cpld_memory);
qemu_register_reset(&taihu_cpld_reset, cpld);
}
@@ -512,6 +501,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
{
char *filename;
qemu_irq *pic;
+ MemoryRegion *sysmem = get_system_memory();
MemoryRegion *bios;
MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
target_phys_addr_t ram_bases[2], ram_sizes[2];
@@ -535,7 +525,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
#ifdef DEBUG_BOARD_INIT
printf("%s: register cpu\n", __func__);
#endif
- ppc405ep_init(get_system_memory(), ram_memories, ram_bases, ram_sizes,
+ ppc405ep_init(sysmem, ram_memories, ram_bases, ram_sizes,
33333333, &pic, kernel_filename == NULL ? 0 : 1);
/* allocate and load BIOS */
#ifdef DEBUG_BOARD_INIT
@@ -585,8 +575,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
}
bios_size = (bios_size + 0xfff) & ~0xfff;
memory_region_set_readonly(bios, true);
- memory_region_add_subregion(get_system_memory(), (uint32_t)(-bios_size),
- bios);
+ memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
}
/* Register Linux flash */
dinfo = drive_get(IF_PFLASH, 0, fl_idx);
@@ -611,7 +600,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
#ifdef DEBUG_BOARD_INIT
printf("%s: register CPLD\n", __func__);
#endif
- taihu_cpld_init(0x50100000);
+ taihu_cpld_init(sysmem, 0x50100000);
/* Load kernel */
linux_boot = (kernel_filename != NULL);
if (linux_boot) {
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index b9a50db3fa..8c84f9e9a5 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -84,12 +84,13 @@
#endif
/* UniN device */
-static void unin_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+static void unin_write(void *opaque, target_phys_addr_t addr, uint64_t value,
+ unsigned size)
{
- UNIN_DPRINTF("writel addr " TARGET_FMT_plx " val %x\n", addr, value);
+ UNIN_DPRINTF("write addr " TARGET_FMT_plx " val %"PRIx64"\n", addr, value);
}
-static uint32_t unin_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t unin_read(void *opaque, target_phys_addr_t addr, unsigned size)
{
uint32_t value;
@@ -99,16 +100,10 @@ static uint32_t unin_readl (void *opaque, target_phys_addr_t addr)
return value;
}
-static CPUWriteMemoryFunc * const unin_write[] = {
- &unin_writel,
- &unin_writel,
- &unin_writel,
-};
-
-static CPUReadMemoryFunc * const unin_read[] = {
- &unin_readl,
- &unin_readl,
- &unin_readl,
+static const MemoryRegionOps unin_ops = {
+ .read = unin_read,
+ .write = unin_write,
+ .endianness = DEVICE_NATIVE_ENDIAN,
};
static int fw_cfg_boot_set(void *opaque, const char *boot_device)
@@ -138,9 +133,9 @@ static void ppc_core99_init (ram_addr_t ram_size,
CPUState *env = NULL;
char *filename;
qemu_irq *pic, **openpic_irqs;
- int unin_memory;
+ MemoryRegion *unin_memory = g_new(MemoryRegion, 1);
int linux_boot, i;
- ram_addr_t ram_offset, bios_offset;
+ MemoryRegion *ram = g_new(MemoryRegion, 1), *bios = g_new(MemoryRegion, 1);
target_phys_addr_t kernel_base, initrd_base, cmdline_base = 0;
long kernel_size, initrd_size;
PCIBus *pci_bus;
@@ -176,15 +171,16 @@ static void ppc_core99_init (ram_addr_t ram_size,
}
/* allocate RAM */
- ram_offset = qemu_ram_alloc(NULL, "ppc_core99.ram", ram_size);
- cpu_register_physical_memory(0, ram_size, ram_offset);
+ memory_region_init_ram(ram, NULL, "ppc_core99.ram", ram_size);
+ memory_region_add_subregion(get_system_memory(), 0, ram);
/* allocate and load BIOS */
- bios_offset = qemu_ram_alloc(NULL, "ppc_core99.bios", BIOS_SIZE);
+ memory_region_init_ram(bios, NULL, "ppc_core99.bios", BIOS_SIZE);
if (bios_name == NULL)
bios_name = PROM_FILENAME;
filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
- cpu_register_physical_memory(PROM_ADDR, BIOS_SIZE, bios_offset | IO_MEM_ROM);
+ memory_region_set_readonly(bios, true);
+ memory_region_add_subregion(get_system_memory(), PROM_ADDR, bios);
/* Load OpenBIOS (ELF) */
if (filename) {
@@ -267,9 +263,8 @@ static void ppc_core99_init (ram_addr_t ram_size,
isa_mmio_init(0xf2000000, 0x00800000);
/* UniN init */
- unin_memory = cpu_register_io_memory(unin_read, unin_write, NULL,
- DEVICE_NATIVE_ENDIAN);
- cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
+ memory_region_init_io(unin_memory, &unin_ops, NULL, "unin", 0x1000);
+ memory_region_add_subregion(get_system_memory(), 0xf8000000, unin_memory);
openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
openpic_irqs[0] =
diff --git a/hw/qxl.c b/hw/qxl.c
index 6db2f1a466..03848edb75 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1601,7 +1601,7 @@ static int qxl_init_primary(PCIDevice *dev)
ram_size = 32 * 1024 * 1024;
}
vga_common_init(vga, ram_size);
- vga_init(vga, pci_address_space(dev));
+ vga_init(vga, pci_address_space(dev), pci_address_space_io(dev), false);
register_ioport_write(0x3c0, 16, 1, qxl_vga_ioport_write, vga);
register_ioport_write(0x3b4, 2, 1, qxl_vga_ioport_write, vga);
register_ioport_write(0x3d4, 2, 1, qxl_vga_ioport_write, vga);
diff --git a/hw/realview.c b/hw/realview.c
index 549bb150c6..11ffb8a824 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -272,8 +272,16 @@ static void realview_init(ram_addr_t ram_size,
sysbus_create_simple("pl031", 0x10017000, pic[10]);
if (!is_pb) {
- dev = sysbus_create_varargs("realview_pci", 0x60000000,
- pic[48], pic[49], pic[50], pic[51], NULL);
+ dev = qdev_create(NULL, "realview_pci");
+ busdev = sysbus_from_qdev(dev);
+ qdev_init_nofail(dev);
+ sysbus_mmio_map(busdev, 0, 0x61000000); /* PCI self-config */
+ sysbus_mmio_map(busdev, 1, 0x62000000); /* PCI config */
+ sysbus_mmio_map(busdev, 2, 0x63000000); /* PCI I/O */
+ sysbus_connect_irq(busdev, 0, pic[48]);
+ sysbus_connect_irq(busdev, 1, pic[49]);
+ sysbus_connect_irq(busdev, 2, pic[50]);
+ sysbus_connect_irq(busdev, 3, pic[51]);
pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
if (usb_enabled) {
usb_ohci_init_pci(pci_bus, -1);
diff --git a/hw/sb16.c b/hw/sb16.c
index aca52e09ab..f0658ac596 100644
--- a/hw/sb16.c
+++ b/hw/sb16.c
@@ -1341,12 +1341,21 @@ static const VMStateDescription vmstate_sb16 = {
}
};
+static const MemoryRegionPortio sb16_ioport_list[] = {
+ { 4, 1, 1, .write = mixer_write_indexb },
+ { 4, 1, 2, .write = mixer_write_indexw },
+ { 5, 1, 1, .read = mixer_read, .write = mixer_write_datab },
+ { 6, 1, 1, .read = dsp_read, .write = dsp_write },
+ { 10, 1, 1, .read = dsp_read },
+ { 12, 1, 1, .write = dsp_write },
+ { 12, 4, 1, .read = dsp_read },
+ PORTIO_END_OF_LIST(),
+};
+
+
static int sb16_initfn (ISADevice *dev)
{
- static const uint8_t dsp_write_ports[] = {0x6, 0xc};
- static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
SB16State *s;
- int i;
s = DO_UPCAST (SB16State, dev, dev);
@@ -1366,22 +1375,7 @@ static int sb16_initfn (ISADevice *dev)
dolog ("warning: Could not create auxiliary timer\n");
}
- for (i = 0; i < ARRAY_SIZE (dsp_write_ports); i++) {
- register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
- isa_init_ioport (dev, s->port + dsp_write_ports[i]);
- }
-
- for (i = 0; i < ARRAY_SIZE (dsp_read_ports); i++) {
- register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
- isa_init_ioport (dev, s->port + dsp_read_ports[i]);
- }
-
- register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
- register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
- isa_init_ioport (dev, s->port + 0x4);
- register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
- register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
- isa_init_ioport (dev, s->port + 0x5);
+ isa_register_portio_list (dev, s->port, sb16_ioport_list, s, "sb16");
DMA_register_channel (s->hdma, SB_read_DMA, s);
DMA_register_channel (s->dma, SB_read_DMA, s);
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 98e56f1610..8a88696f2c 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -58,38 +58,6 @@ static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(pic[irq_num], level);
}
-
-static void pci_vpb_map(SysBusDevice *dev, target_phys_addr_t base)
-{
- PCIVPBState *s = (PCIVPBState *)dev;
- /* Selfconfig area. */
- memory_region_add_subregion(get_system_memory(), base + 0x01000000,
- &s->mem_config);
- /* Normal config area. */
- memory_region_add_subregion(get_system_memory(), base + 0x02000000,
- &s->mem_config2);
-
- if (s->realview) {
- /* IO memory area. */
- memory_region_add_subregion(get_system_memory(), base + 0x03000000,
- &s->isa);
- }
-}
-
-static void pci_vpb_unmap(SysBusDevice *dev, target_phys_addr_t base)
-{
- PCIVPBState *s = (PCIVPBState *)dev;
- /* Selfconfig area. */
- memory_region_del_subregion(get_system_memory(), &s->mem_config);
- /* Normal config area. */
- memory_region_del_subregion(get_system_memory(), &s->mem_config2);
-
- if (s->realview) {
- /* IO memory area. */
- memory_region_del_subregion(get_system_memory(), &s->isa);
- }
-}
-
static int pci_vpb_init(SysBusDevice *dev)
{
PCIVPBState *s = FROM_SYSBUS(PCIVPBState, dev);
@@ -106,16 +74,22 @@ static int pci_vpb_init(SysBusDevice *dev)
/* ??? Register memory space. */
+ /* Our memory regions are:
+ * 0 : PCI self config window
+ * 1 : PCI config window
+ * 2 : PCI IO window (realview_pci only)
+ */
memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus,
"pci-vpb-selfconfig", 0x1000000);
+ sysbus_init_mmio_region(dev, &s->mem_config);
memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus,
"pci-vpb-config", 0x1000000);
+ sysbus_init_mmio_region(dev, &s->mem_config2);
if (s->realview) {
isa_mmio_setup(&s->isa, 0x0100000);
+ sysbus_init_mmio_region(dev, &s->isa);
}
- sysbus_init_mmio_cb2(dev, pci_vpb_map, pci_vpb_unmap);
-
pci_create_simple(bus, -1, "versatile_pci_host");
return 0;
}
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 49f8f5fc56..68402cc479 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -181,6 +181,7 @@ static void versatile_init(ram_addr_t ram_size,
qemu_irq pic[32];
qemu_irq sic[32];
DeviceState *dev, *sysctl;
+ SysBusDevice *busdev;
PCIBus *pci_bus;
NICInfo *nd;
int n;
@@ -219,8 +220,15 @@ static void versatile_init(ram_addr_t ram_size,
sysbus_create_simple("pl050_keyboard", 0x10006000, sic[3]);
sysbus_create_simple("pl050_mouse", 0x10007000, sic[4]);
- dev = sysbus_create_varargs("versatile_pci", 0x40000000,
- sic[27], sic[28], sic[29], sic[30], NULL);
+ dev = qdev_create(NULL, "versatile_pci");
+ busdev = sysbus_from_qdev(dev);
+ qdev_init_nofail(dev);
+ sysbus_mmio_map(busdev, 0, 0x41000000); /* PCI self-config */
+ sysbus_mmio_map(busdev, 1, 0x42000000); /* PCI config */
+ sysbus_connect_irq(busdev, 0, sic[27]);
+ sysbus_connect_irq(busdev, 1, sic[28]);
+ sysbus_connect_irq(busdev, 2, sic[29]);
+ sysbus_connect_irq(busdev, 3, sic[30]);
pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
/* The Versatile PCI bridge does not provide access to PCI IO space,
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 6b5c8ed970..4825313f67 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -47,24 +47,19 @@ static int vga_initfn(ISADevice *dev)
ISAVGAState *d = DO_UPCAST(ISAVGAState, dev, dev);
VGACommonState *s = &d->state;
MemoryRegion *vga_io_memory;
+ const MemoryRegionPortio *vga_ports, *vbe_ports;
vga_common_init(s, VGA_RAM_SIZE);
s->legacy_address_space = isa_address_space(dev);
- vga_io_memory = vga_init_io(s);
+ vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
+ isa_register_portio_list(dev, 0x3b0, vga_ports, s, "vga");
+ if (vbe_ports) {
+ isa_register_portio_list(dev, 0x1ce, vbe_ports, s, "vbe");
+ }
memory_region_add_subregion_overlap(isa_address_space(dev),
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);
- isa_init_ioport(dev, 0x3da);
- isa_init_ioport(dev, 0x3c0);
-#ifdef CONFIG_BOCHS_VBE
- isa_init_ioport(dev, 0x1ce);
- isa_init_ioport(dev, 0x1cf);
- isa_init_ioport(dev, 0x1d0);
-#endif /* CONFIG_BOCHS_VBE */
s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update, s);
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 3c8bcb00b7..14bfadbfcf 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -54,7 +54,7 @@ static int pci_vga_initfn(PCIDevice *dev)
// vga + console init
vga_common_init(s, VGA_RAM_SIZE);
- vga_init(s, pci_address_space(dev));
+ vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
s->ds = graphic_console_init(s->update, s->invalidate,
s->screen_dump, s->text_update, s);
diff --git a/hw/vga.c b/hw/vga.c
index f9a6014f4e..5beaa9992a 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2241,40 +2241,39 @@ void vga_common_init(VGACommonState *s, int vga_ram_size)
vga_dirty_log_start(s);
}
-/* used by both ISA and PCI */
-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);
- register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s);
- register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s);
- register_ioport_write(0x3da, 1, 1, vga_ioport_write, s);
-
- register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s);
-
- register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s);
- register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s);
- register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s);
- register_ioport_read(0x3da, 1, 1, vga_ioport_read, s);
+static const MemoryRegionPortio vga_portio_list[] = {
+ { 0x04, 2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3b4 */
+ { 0x0a, 1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3ba */
+ { 0x10, 16, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3c0 */
+ { 0x24, 2, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3d4 */
+ { 0x2a, 1, 1, .read = vga_ioport_read, .write = vga_ioport_write }, /* 3da */
+ PORTIO_END_OF_LIST(),
+};
#ifdef CONFIG_BOCHS_VBE
-#if defined (TARGET_I386)
- register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
- register_ioport_read(0x1cf, 1, 2, vbe_ioport_read_data, s);
+static const MemoryRegionPortio vbe_portio_list[] = {
+ { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
+# ifdef TARGET_I386
+ { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
+# else
+ { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
+# endif
+ PORTIO_END_OF_LIST(),
+};
+#endif /* CONFIG_BOCHS_VBE */
- register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
- register_ioport_write(0x1cf, 1, 2, vbe_ioport_write_data, s);
-#else
- register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
- register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s);
+/* Used by both ISA and PCI */
+MemoryRegion *vga_init_io(VGACommonState *s,
+ const MemoryRegionPortio **vga_ports,
+ const MemoryRegionPortio **vbe_ports)
+{
+ MemoryRegion *vga_mem;
- register_ioport_write(0x1ce, 1, 2, vbe_ioport_write_index, s);
- register_ioport_write(0x1d0, 1, 2, vbe_ioport_write_data, s);
+ *vga_ports = vga_portio_list;
+ *vbe_ports = NULL;
+#ifdef CONFIG_BOCHS_VBE
+ *vbe_ports = vbe_portio_list;
#endif
-#endif /* CONFIG_BOCHS_VBE */
vga_mem = g_malloc(sizeof(*vga_mem));
memory_region_init_io(vga_mem, &vga_mem_ops, s,
@@ -2283,9 +2282,13 @@ MemoryRegion *vga_init_io(VGACommonState *s)
return vga_mem;
}
-void vga_init(VGACommonState *s, MemoryRegion *address_space)
+void vga_init(VGACommonState *s, MemoryRegion *address_space,
+ MemoryRegion *address_space_io, bool init_vga_ports)
{
MemoryRegion *vga_io_memory;
+ const MemoryRegionPortio *vga_ports, *vbe_ports;
+ PortioList *vga_port_list = g_new(PortioList, 1);
+ PortioList *vbe_port_list = g_new(PortioList, 1);
qemu_register_reset(vga_reset, s);
@@ -2293,12 +2296,20 @@ void vga_init(VGACommonState *s, MemoryRegion *address_space)
s->legacy_address_space = address_space;
- vga_io_memory = vga_init_io(s);
+ vga_io_memory = vga_init_io(s, &vga_ports, &vbe_ports);
memory_region_add_subregion_overlap(address_space,
isa_mem_base + 0x000a0000,
vga_io_memory,
1);
memory_region_set_coalescing(vga_io_memory);
+ if (init_vga_ports) {
+ portio_list_init(vga_port_list, vga_ports, s, "vga");
+ portio_list_add(vga_port_list, address_space_io, 0x3b0);
+ }
+ if (vbe_ports) {
+ portio_list_init(vbe_port_list, vbe_ports, s, "vbe");
+ portio_list_add(vbe_port_list, address_space_io, 0x1ce);
+ }
}
void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 99287dde9b..c1e700fa0b 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -187,8 +187,11 @@ static inline int c6_to_8(int v)
}
void vga_common_init(VGACommonState *s, int vga_ram_size);
-void vga_init(VGACommonState *s, MemoryRegion *address_space);
-MemoryRegion *vga_init_io(VGACommonState *s);
+void vga_init(VGACommonState *s, MemoryRegion *address_space,
+ MemoryRegion *address_space_io, bool init_vga_ports);
+MemoryRegion *vga_init_io(VGACommonState *s,
+ const MemoryRegionPortio **vga_ports,
+ const MemoryRegionPortio **vbe_ports);
void vga_common_reset(VGACommonState *s);
void vga_dirty_log_start(VGACommonState *s);
diff --git a/hw/vmport.c b/hw/vmport.c
index c8aefaabb8..b5c6fa19cd 100644
--- a/hw/vmport.c
+++ b/hw/vmport.c
@@ -38,6 +38,7 @@
typedef struct _VMPortState
{
ISADevice dev;
+ MemoryRegion io;
IOPortReadFunc *func[VMPORT_ENTRIES];
void *opaque[VMPORT_ENTRIES];
} VMPortState;
@@ -120,13 +121,22 @@ void vmmouse_set_data(const uint32_t *data)
env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5];
}
+static const MemoryRegionPortio vmport_portio[] = {
+ {0, 1, 4, .read = vmport_ioport_read, .write = vmport_ioport_write },
+ PORTIO_END_OF_LIST(),
+};
+
+static const MemoryRegionOps vmport_ops = {
+ .old_portio = vmport_portio
+};
+
static int vmport_initfn(ISADevice *dev)
{
VMPortState *s = DO_UPCAST(VMPortState, dev, dev);
- register_ioport_read(0x5658, 1, 4, vmport_ioport_read, s);
- register_ioport_write(0x5658, 1, 4, vmport_ioport_write, s);
- isa_init_ioport(dev, 0x5658);
+ memory_region_init_io(&s->io, &vmport_ops, s, "vmport", 1);
+ isa_register_ioport(dev, &s->io, 0x5658);
+
port_state = s;
/* Register some generic port commands */
vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, NULL);
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index aa682376ad..af70bdee09 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1079,7 +1079,7 @@ static const VMStateDescription vmstate_vmware_vga = {
};
static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size,
- MemoryRegion *address_space)
+ MemoryRegion *address_space, MemoryRegion *io)
{
s->scratch_size = SVGA_SCRATCH_SIZE;
s->scratch = g_malloc(s->scratch_size * 4);
@@ -1095,7 +1095,7 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size,
s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
vga_common_init(&s->vga, vga_ram_size);
- vga_init(&s->vga, address_space);
+ vga_init(&s->vga, address_space, io, true);
vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
s->depth = ds_get_bits_per_pixel(s->vga.ds);
@@ -1183,7 +1183,8 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
"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_address_space(dev));
+ vmsvga_init(&s->chip, VGA_RAM_SIZE, pci_address_space(dev),
+ pci_address_space_io(dev));
pci_register_bar(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
pci_register_bar(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
diff --git a/ioport.c b/ioport.c
index a32483ba84..36fa3a477e 100644
--- a/ioport.c
+++ b/ioport.c
@@ -27,6 +27,7 @@
#include "ioport.h"
#include "trace.h"
+#include "memory.h"
/***********************************************************/
/* IO Port */
@@ -313,3 +314,110 @@ uint32_t cpu_inl(pio_addr_t addr)
LOG_IOPORT("inl : %04"FMT_pioaddr" %08"PRIx32"\n", addr, val);
return val;
}
+
+void portio_list_init(PortioList *piolist,
+ const MemoryRegionPortio *callbacks,
+ void *opaque, const char *name)
+{
+ unsigned n = 0;
+
+ while (callbacks[n].size) {
+ ++n;
+ }
+
+ piolist->ports = callbacks;
+ piolist->nr = 0;
+ piolist->regions = g_new0(MemoryRegion *, n);
+ piolist->address_space = NULL;
+ piolist->opaque = opaque;
+ piolist->name = name;
+}
+
+void portio_list_destroy(PortioList *piolist)
+{
+ g_free(piolist->regions);
+}
+
+static void portio_list_add_1(PortioList *piolist,
+ const MemoryRegionPortio *pio_init,
+ unsigned count, unsigned start,
+ unsigned off_low, unsigned off_high)
+{
+ MemoryRegionPortio *pio;
+ MemoryRegionOps *ops;
+ MemoryRegion *region;
+ unsigned i;
+
+ /* Copy the sub-list and null-terminate it. */
+ pio = g_new(MemoryRegionPortio, count + 1);
+ memcpy(pio, pio_init, sizeof(MemoryRegionPortio) * count);
+ memset(pio + count, 0, sizeof(MemoryRegionPortio));
+
+ /* Adjust the offsets to all be zero-based for the region. */
+ for (i = 0; i < count; ++i) {
+ pio[i].offset -= off_low;
+ }
+
+ ops = g_new0(MemoryRegionOps, 1);
+ ops->old_portio = pio;
+
+ region = g_new(MemoryRegion, 1);
+ memory_region_init_io(region, ops, piolist->opaque, piolist->name,
+ off_high - off_low);
+ memory_region_set_offset(region, start + off_low);
+ memory_region_add_subregion(piolist->address_space,
+ start + off_low, region);
+ piolist->regions[piolist->nr++] = region;
+}
+
+void portio_list_add(PortioList *piolist,
+ MemoryRegion *address_space,
+ uint32_t start)
+{
+ const MemoryRegionPortio *pio, *pio_start = piolist->ports;
+ unsigned int off_low, off_high, off_last, count;
+
+ piolist->address_space = address_space;
+
+ /* Handle the first entry specially. */
+ off_last = off_low = pio_start->offset;
+ off_high = off_low + pio_start->len;
+ count = 1;
+
+ for (pio = pio_start + 1; pio->size != 0; pio++, count++) {
+ /* All entries must be sorted by offset. */
+ assert(pio->offset >= off_last);
+ off_last = pio->offset;
+
+ /* If we see a hole, break the region. */
+ if (off_last > off_high) {
+ portio_list_add_1(piolist, pio_start, count, start, off_low,
+ off_high);
+ /* ... and start collecting anew. */
+ pio_start = pio;
+ off_low = off_last;
+ off_high = off_low + pio->len;
+ count = 0;
+ } else if (off_last + pio->len > off_high) {
+ off_high = off_last + pio->len;
+ }
+ }
+
+ /* There will always be an open sub-list. */
+ portio_list_add_1(piolist, pio_start, count, start, off_low, off_high);
+}
+
+void portio_list_del(PortioList *piolist)
+{
+ MemoryRegion *mr;
+ unsigned i;
+
+ for (i = 0; i < piolist->nr; ++i) {
+ mr = piolist->regions[i];
+ memory_region_del_subregion(piolist->address_space, mr);
+ memory_region_destroy(mr);
+ g_free((MemoryRegionOps *)mr->ops);
+ g_free(mr);
+ piolist->regions[i] = NULL;
+ }
+}
diff --git a/ioport.h b/ioport.h
index 82ffd9d81a..ae3e9da0b5 100644
--- a/ioport.h
+++ b/ioport.h
@@ -52,4 +52,25 @@ uint8_t cpu_inb(pio_addr_t addr);
uint16_t cpu_inw(pio_addr_t addr);
uint32_t cpu_inl(pio_addr_t addr);
+struct MemoryRegion;
+struct MemoryRegionPortio;
+
+typedef struct PortioList {
+ const struct MemoryRegionPortio *ports;
+ struct MemoryRegion *address_space;
+ unsigned nr;
+ struct MemoryRegion **regions;
+ void *opaque;
+ const char *name;
+} PortioList;
+
+void portio_list_init(PortioList *piolist,
+ const struct MemoryRegionPortio *callbacks,
+ void *opaque, const char *name);
+void portio_list_destroy(PortioList *piolist);
+void portio_list_add(PortioList *piolist,
+ struct MemoryRegion *address_space,
+ uint32_t addr);
+void portio_list_del(PortioList *piolist);
+
#endif /* IOPORT_H */
diff --git a/memory.c b/memory.c
index f46e6268c2..dc5e35d667 100644
--- a/memory.c
+++ b/memory.c
@@ -403,12 +403,17 @@ static void memory_region_iorange_read(IORange *iorange,
*data = ((uint64_t)1 << (width * 8)) - 1;
if (mrp) {
- *data = mrp->read(mr->opaque, offset);
+ *data = mrp->read(mr->opaque, offset + mr->offset);
+ } else if (width == 2) {
+ mrp = find_portio(mr, offset, 1, false);
+ assert(mrp);
+ *data = mrp->read(mr->opaque, offset + mr->offset) |
+ (mrp->read(mr->opaque, offset + mr->offset + 1) << 8);
}
return;
}
*data = 0;
- access_with_adjusted_size(offset, data, width,
+ access_with_adjusted_size(offset + mr->offset, data, width,
mr->ops->impl.min_access_size,
mr->ops->impl.max_access_size,
memory_region_read_accessor, mr);
@@ -425,11 +430,16 @@ static void memory_region_iorange_write(IORange *iorange,
const MemoryRegionPortio *mrp = find_portio(mr, offset, width, true);
if (mrp) {
- mrp->write(mr->opaque, offset, data);
+ mrp->write(mr->opaque, offset + mr->offset, data);
+ } else if (width == 2) {
+ mrp = find_portio(mr, offset, 1, false);
+ assert(mrp);
+ mrp->write(mr->opaque, offset + mr->offset, data & 0xff);
+ mrp->write(mr->opaque, offset + mr->offset + 1, data >> 8);
}
return;
}
- access_with_adjusted_size(offset, &data, width,
+ access_with_adjusted_size(offset + mr->offset, &data, width,
mr->ops->impl.min_access_size,
mr->ops->impl.max_access_size,
memory_region_write_accessor, mr);