From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: avi@redhat.com
Subject: [Qemu-devel] [PATCH 04/16] isa: Add isa_register_portio_list().
Date: Tue, 23 Aug 2011 17:13:43 -0700 [thread overview]
Message-ID: <1314144835-29098-5-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1314144835-29098-1-git-send-email-rth@twiddle.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
hw/isa-bus.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hw/isa.h | 31 ++++++++++++++++++++++-
memory.c | 8 +++---
3 files changed, 113 insertions(+), 5 deletions(-)
diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index e9c1712..648b421 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -103,6 +103,85 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start)
}
}
+static void isa_register_portio_1(ISADevice *dev,
+ const MemoryRegionPortio *pio_init,
+ unsigned count, unsigned start,
+ unsigned off_low, unsigned off_high,
+ void *opaque, const char *name)
+{
+ MemoryRegionPortio *pio;
+ MemoryRegionOps *ops;
+ MemoryRegion *region;
+ unsigned i;
+
+ if (off_low == 0 && pio_init[count].size == 0) {
+ /* Special case simple adjustments. */
+ pio = (MemoryRegionPortio *) pio_init;
+ } else {
+ /* 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, opaque, name, off_high - off_low);
+ memory_region_set_offset(region, start + off_low);
+ memory_region_add_subregion(isabus->address_space_io,
+ start + off_low, region);
+}
+
+void isa_register_portio_list(ISADevice *dev, uint16_t start,
+ const MemoryRegionPortio *pio_start,
+ void *opaque, const char *name)
+{
+ const MemoryRegionPortio *pio;
+ unsigned int off_low, off_high, off_last, count;
+
+ /* 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. */
+ if (dev) {
+ isa_init_ioport(dev, start);
+ }
+
+ /* 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) {
+ isa_register_portio_1(dev, pio_start, count, start, off_low,
+ off_high, opaque, name);
+ /* ... 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. */
+ isa_register_portio_1(dev, pio_start, count, start, off_low,
+ off_high, opaque, name);
+}
+
static int isa_qdev_init(DeviceState *qdev, DeviceInfo *base)
{
ISADevice *dev = DO_UPCAST(ISADevice, qdev, qdev);
diff --git a/hw/isa.h b/hw/isa.h
index c5c2618..177ef95 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -28,7 +28,6 @@ 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);
@@ -37,6 +36,36 @@ 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/memory.c b/memory.c
index 8e9ac46..6fc53b8 100644
--- a/memory.c
+++ b/memory.c
@@ -396,12 +396,12 @@ 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);
}
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);
@@ -418,11 +418,11 @@ 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);
}
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);
--
1.7.4.4
next prev parent reply other threads:[~2011-08-24 0:14 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-24 0:13 [Qemu-devel] [PATCH 00/16] isa_register_portio_list, v2 Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 01/16] fixup: merge with last sm501 patch Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 02/16] fixup: merge with last arm_sysctl patch Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 03/16] isa: Tidy support code for isabus_get_fw_dev_path Richard Henderson
2011-08-24 0:13 ` Richard Henderson [this message]
2011-08-24 0:13 ` [Qemu-devel] [PATCH 05/16] fdc: Convert to isa_register_portio_list Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 06/16] gus: " Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 07/16] m48t59: Convert to isa_register_ioport Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 08/16] rtc: " Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 09/16] ne2000: " Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 10/16] parallel: Convert to isa_register_portio_list Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 11/16] sb16: " Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 12/16] vga: " Richard Henderson
2011-09-18 13:45 ` Avi Kivity
2011-09-18 14:16 ` Richard Henderson
2011-09-18 14:27 ` Avi Kivity
2011-09-18 14:56 ` Avi Kivity
2011-09-18 15:15 ` Richard Henderson
2011-09-18 15:19 ` Avi Kivity
2011-08-24 0:13 ` [Qemu-devel] [PATCH 13/16] pc: Convert port92 to isa_register_ioport Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 14/16] vmport: Convert " Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 15/16] ide: Convert to isa_register_portio_list Richard Henderson
2011-08-24 0:13 ` [Qemu-devel] [PATCH 16/16] isa: Remove isa_init_ioport_range and isa_init_ioport Richard Henderson
2011-08-24 9:18 ` [Qemu-devel] [PATCH 00/16] isa_register_portio_list, v2 Avi Kivity
2011-08-24 9:35 ` malc
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1314144835-29098-5-git-send-email-rth@twiddle.net \
--to=rth@twiddle.net \
--cc=avi@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).