From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:52037) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZMpf-0002zp-Sb for qemu-devel@nongnu.org; Mon, 06 May 2013 10:56:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UZMpa-0006yK-Tb for qemu-devel@nongnu.org; Mon, 06 May 2013 10:56:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:62151) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZMpa-0006yA-AL for qemu-devel@nongnu.org; Mon, 06 May 2013 10:55:58 -0400 Message-ID: <5187C473.5070101@redhat.com> Date: Mon, 06 May 2013 16:55:47 +0200 From: Paolo Bonzini MIME-Version: 1.0 References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [RFC][PATCH 11/15] memory: Allow unaligned address_space_rw List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Jan Kiszka Cc: Liu Ping Fan , qemu-devel , =?ISO-8859-15?Q?Andreas_F=E4rbe?= =?ISO-8859-15?Q?r?= 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 > --- > 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); >