Il 06/05/2013 16:26, Jan Kiszka ha scritto: > This will be needed for some corner cases with para-virtual the I/O > ports. > > Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> > --- > exec.c | 33 ++++++++++++++++++--------------- > 1 files changed, 18 insertions(+), 15 deletions(-) > > diff --git a/exec.c b/exec.c > index 3ee1f3f..9c582b1 100644 > --- a/exec.c > +++ b/exec.c > @@ -1833,38 +1833,41 @@ void address_space_rw(AddressSpace *as, hwaddr addr, > uint8_t *buf, > uint8_t *ptr; > uint32_t val; > MemoryRegionSection *section; > + MemoryRegion *mr; > > while (len > 0) { > l = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr; > if (l > len) > l = len; > section = address_space_lookup_region(as, addr); > + mr = section->mr; > > if (is_write) { > - if (!memory_region_is_ram(section->mr)) { > + if (!memory_region_is_ram(mr)) { > hwaddr addr1; > addr1 = memory_region_section_addr(section, addr); > /* XXX: could force cpu_single_env to NULL to avoid > potential bugs */ > - if (l >= 4 && ((addr1 & 3) == 0)) { > + if (l >= 4 && ((addr1 & 3) == 0 || mr->ops->impl.unaligned)) > {
Does the length matter at all if unaligned accesses are allowed? I think it shouldn't... Paolo > /* 32 bit write access */ > val = ldl_p(buf); > - io_mem_write(section->mr, addr1, val, 4); > + io_mem_write(mr, addr1, val, 4); > l = 4; > - } else if (l >= 2 && ((addr1 & 1) == 0)) { > + } else if (l >= 2 && > + ((addr1 & 1) == 0 || mr->ops->impl.unaligned)) { > /* 16 bit write access */ > val = lduw_p(buf); > - io_mem_write(section->mr, addr1, val, 2); > + io_mem_write(mr, addr1, val, 2); > l = 2; > } else { > /* 8 bit write access */ > val = ldub_p(buf); > - io_mem_write(section->mr, addr1, val, 1); > + io_mem_write(mr, addr1, val, 1); > l = 1; > } > } else if (!section->readonly) { > ram_addr_t addr1; > - addr1 = memory_region_get_ram_addr(section->mr) > + addr1 = memory_region_get_ram_addr(mr) > + memory_region_section_addr(section, addr); > /* RAM case */ > ptr = qemu_get_ram_ptr(addr1); > @@ -1873,30 +1876,30 @@ void address_space_rw(AddressSpace *as, hwaddr addr, > uint8_t *buf, > qemu_put_ram_ptr(ptr); > } > } else { > - if (!(memory_region_is_ram(section->mr) || > - memory_region_is_romd(section->mr))) { > + if (!(memory_region_is_ram(mr) || memory_region_is_romd(mr))) { > hwaddr addr1; > /* I/O case */ > addr1 = memory_region_section_addr(section, addr); > - if (l >= 4 && ((addr1 & 3) == 0)) { > + if (l >= 4 && ((addr1 & 3) == 0 || mr->ops->impl.unaligned)) > { > /* 32 bit read access */ > - val = io_mem_read(section->mr, addr1, 4); > + val = io_mem_read(mr, addr1, 4); > stl_p(buf, val); > l = 4; > - } else if (l >= 2 && ((addr1 & 1) == 0)) { > + } else if (l >= 2 && > + ((addr1 & 1) == 0 || mr->ops->impl.unaligned)) { > /* 16 bit read access */ > - val = io_mem_read(section->mr, addr1, 2); > + val = io_mem_read(mr, addr1, 2); > stw_p(buf, val); > l = 2; > } else { > /* 8 bit read access */ > - val = io_mem_read(section->mr, addr1, 1); > + val = io_mem_read(mr, addr1, 1); > stb_p(buf, val); > l = 1; > } > } else { > /* RAM case */ > - ptr = qemu_get_ram_ptr(section->mr->ram_addr > + ptr = qemu_get_ram_ptr(mr->ram_addr > + memory_region_section_addr(section, > addr)); > memcpy(buf, ptr, l); >