diff options
-rw-r--r-- | Makefile.objs | 2 | ||||
-rw-r--r-- | Makefile.target | 2 | ||||
-rw-r--r-- | hw/arm11mpcore.c | 13 | ||||
-rw-r--r-- | hw/fdc.c | 34 | ||||
-rw-r--r-- | hw/gus.c | 38 | ||||
-rw-r--r-- | hw/ide/core.c | 30 | ||||
-rw-r--r-- | hw/ide/internal.h | 3 | ||||
-rw-r--r-- | hw/ide/isa.c | 4 | ||||
-rw-r--r-- | hw/ide/piix.c | 7 | ||||
-rw-r--r-- | hw/ide/via.c | 7 | ||||
-rw-r--r-- | hw/isa-bus.c | 45 | ||||
-rw-r--r-- | hw/isa.h | 38 | ||||
-rw-r--r-- | hw/lan9118.c | 29 | ||||
-rw-r--r-- | hw/m48t59.c | 15 | ||||
-rw-r--r-- | hw/mc146818rtc.c | 15 | ||||
-rw-r--r-- | hw/ne2000-isa.c | 5 | ||||
-rw-r--r-- | hw/palm.c | 53 | ||||
-rw-r--r-- | hw/parallel.c | 47 | ||||
-rw-r--r-- | hw/pc.c | 16 | ||||
-rw-r--r-- | hw/petalogix_ml605_mmu.c | 15 | ||||
-rw-r--r-- | hw/petalogix_s3adsp1800_mmu.c | 18 | ||||
-rw-r--r-- | hw/ppc405_boards.c | 85 | ||||
-rw-r--r-- | hw/ppc_newworld.c | 39 | ||||
-rw-r--r-- | hw/qxl.c | 2 | ||||
-rw-r--r-- | hw/realview.c | 12 | ||||
-rw-r--r-- | hw/sb16.c | 32 | ||||
-rw-r--r-- | hw/versatile_pci.c | 42 | ||||
-rw-r--r-- | hw/versatilepb.c | 12 | ||||
-rw-r--r-- | hw/vga-isa.c | 17 | ||||
-rw-r--r-- | hw/vga-pci.c | 2 | ||||
-rw-r--r-- | hw/vga.c | 73 | ||||
-rw-r--r-- | hw/vga_int.h | 7 | ||||
-rw-r--r-- | hw/vmport.c | 16 | ||||
-rw-r--r-- | hw/vmware_vga.c | 7 | ||||
-rw-r--r-- | ioport.c | 108 | ||||
-rw-r--r-- | ioport.h | 21 | ||||
-rw-r--r-- | memory.c | 18 |
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; } @@ -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; @@ -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); @@ -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); @@ -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; } @@ -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] = @@ -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); @@ -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); @@ -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, @@ -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; + } +} @@ -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 */ @@ -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); |