diff options
-rw-r--r-- | exec.c | 8 | ||||
-rw-r--r-- | memory.c | 26 | ||||
-rw-r--r-- | memory.h | 9 |
3 files changed, 34 insertions, 9 deletions
@@ -3668,9 +3668,13 @@ static void io_commit(MemoryListener *listener) static void io_region_add(MemoryListener *listener, MemoryRegionSection *section) { - iorange_init(§ion->mr->iorange, &memory_region_iorange_ops, + MemoryRegionIORange *mrio = g_new(MemoryRegionIORange, 1); + + mrio->mr = section->mr; + mrio->offset = section->offset_within_region; + iorange_init(&mrio->iorange, &memory_region_iorange_ops, section->offset_within_address_space, section->size); - ioport_register(§ion->mr->iorange); + ioport_register(&mrio->iorange); } static void io_region_del(MemoryListener *listener, @@ -382,16 +382,20 @@ static void memory_region_iorange_read(IORange *iorange, unsigned width, uint64_t *data) { - MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange); + 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, width, false); + 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, 1, false); + mrp = find_portio(mr, offset - mrio->offset, 1, false); assert(mrp); *data = mrp->read(mr->opaque, offset) | (mrp->read(mr->opaque, offset + 1) << 8); @@ -410,15 +414,19 @@ static void memory_region_iorange_write(IORange *iorange, unsigned width, uint64_t data) { - MemoryRegion *mr = container_of(iorange, MemoryRegion, iorange); + 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, width, true); + 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, 1, false); + mrp = find_portio(mr, offset - mrio->offset, 1, false); assert(mrp); mrp->write(mr->opaque, offset, data & 0xff); mrp->write(mr->opaque, offset + 1, data >> 8); @@ -431,9 +439,15 @@ static void memory_region_iorange_write(IORange *iorange, 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 address_space_io; @@ -43,6 +43,14 @@ struct MemoryRegionMmio { CPUWriteMemoryFunc *write[3]; }; +/* Internal use; thunks between old-style IORange and MemoryRegions. */ +typedef struct MemoryRegionIORange MemoryRegionIORange; +struct MemoryRegionIORange { + IORange iorange; + MemoryRegion *mr; + target_phys_addr_t offset; +}; + /* * Memory region callbacks */ @@ -117,7 +125,6 @@ struct MemoryRegion { target_phys_addr_t addr; void (*destructor)(MemoryRegion *mr); ram_addr_t ram_addr; - IORange iorange; bool subpage; bool terminates; bool readable; |