From b40acf99bef69fa8ab0f9092ff162fde945eec12 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 24 Jun 2013 10:45:09 +0200 Subject: ioport: Switch dispatching to memory core layer The current ioport dispatcher is a complex beast, mostly due to the need to deal with old portio interface users. But we can overcome it without converting all portio users by embedding the required base address of a MemoryRegionPortio access into that data structure. That removes the need to have the additional MemoryRegionIORange structure in the loop on every access. To handle old portio memory ops, we simply install dispatching handlers for portio memory regions when registering them with the memory core. This removes the need for the old_portio field. We can drop the additional aliasing of ioport regions and also the special address space listener. cpu_in and cpu_out now simply call address_space_read/write. And we can concentrate portio handling in a single source file. Signed-off-by: Jan Kiszka Signed-off-by: Paolo Bonzini --- memory.c | 88 ---------------------------------------------------------------- 1 file changed, 88 deletions(-) (limited to 'memory.c') diff --git a/memory.c b/memory.c index 757e9a5592..1431356d50 100644 --- a/memory.c +++ b/memory.c @@ -401,94 +401,6 @@ static void access_with_adjusted_size(hwaddr addr, } } -static const MemoryRegionPortio *find_portio(MemoryRegion *mr, uint64_t offset, - unsigned width, bool write) -{ - const MemoryRegionPortio *mrp; - - for (mrp = mr->ops->old_portio; mrp->size; ++mrp) { - if (offset >= mrp->offset && offset < mrp->offset + mrp->len - && width == mrp->size - && (write ? (bool)mrp->write : (bool)mrp->read)) { - return mrp; - } - } - return NULL; -} - -static void memory_region_iorange_read(IORange *iorange, - uint64_t offset, - unsigned width, - uint64_t *data) -{ - MemoryRegionIORange *mrio - = container_of(iorange, MemoryRegionIORange, iorange); - MemoryRegion *mr = mrio->mr; - - offset += mrio->offset; - if (mr->ops->old_portio) { - const MemoryRegionPortio *mrp = find_portio(mr, offset - mrio->offset, - width, false); - - *data = ((uint64_t)1 << (width * 8)) - 1; - if (mrp) { - *data = mrp->read(mr->opaque, offset); - } else if (width == 2) { - mrp = find_portio(mr, offset - mrio->offset, 1, false); - assert(mrp); - *data = mrp->read(mr->opaque, offset) | - (mrp->read(mr->opaque, offset + 1) << 8); - } - return; - } - *data = 0; - access_with_adjusted_size(offset, data, width, - mr->ops->impl.min_access_size, - mr->ops->impl.max_access_size, - memory_region_read_accessor, mr); -} - -static void memory_region_iorange_write(IORange *iorange, - uint64_t offset, - unsigned width, - uint64_t data) -{ - MemoryRegionIORange *mrio - = container_of(iorange, MemoryRegionIORange, iorange); - MemoryRegion *mr = mrio->mr; - - offset += mrio->offset; - if (mr->ops->old_portio) { - const MemoryRegionPortio *mrp = find_portio(mr, offset - mrio->offset, - width, true); - - if (mrp) { - mrp->write(mr->opaque, offset, data); - } else if (width == 2) { - mrp = find_portio(mr, offset - mrio->offset, 1, true); - assert(mrp); - mrp->write(mr->opaque, offset, data & 0xff); - mrp->write(mr->opaque, offset + 1, data >> 8); - } - return; - } - access_with_adjusted_size(offset, &data, width, - mr->ops->impl.min_access_size, - mr->ops->impl.max_access_size, - memory_region_write_accessor, mr); -} - -static void memory_region_iorange_destructor(IORange *iorange) -{ - g_free(container_of(iorange, MemoryRegionIORange, iorange)); -} - -const IORangeOps memory_region_iorange_ops = { - .read = memory_region_iorange_read, - .write = memory_region_iorange_write, - .destructor = memory_region_iorange_destructor, -}; - static AddressSpace *memory_region_to_address_space(MemoryRegion *mr) { AddressSpace *as; -- cgit v1.2.1