From patchwork Mon Jan 2 16:33:32 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Avi Kivity X-Patchwork-Id: 133878 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 2A89C1007D2 for ; Tue, 3 Jan 2012 04:23:13 +1100 (EST) Received: from localhost ([::1]:34723 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rhkqu-0008Ff-LF for incoming@patchwork.ozlabs.org; Mon, 02 Jan 2012 11:35:12 -0500 Received: from eggs.gnu.org ([140.186.70.92]:35731) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rhkpq-0006C8-Ec for qemu-devel@nongnu.org; Mon, 02 Jan 2012 11:34:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Rhkpd-0007Iz-RC for qemu-devel@nongnu.org; Mon, 02 Jan 2012 11:34:02 -0500 Received: from mx1.redhat.com ([209.132.183.28]:13064) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rhkpc-0007Hx-Li for qemu-devel@nongnu.org; Mon, 02 Jan 2012 11:33:53 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q02GXptK013242 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 2 Jan 2012 11:33:52 -0500 Received: from cleopatra.tlv.redhat.com (cleopatra.tlv.redhat.com [10.35.255.11]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q02GXmSB028666 for ; Mon, 2 Jan 2012 11:33:51 -0500 Received: from s01.tlv.redhat.com (s01.tlv.redhat.com [10.35.255.8]) by cleopatra.tlv.redhat.com (Postfix) with ESMTP id 51C68250BAB; Mon, 2 Jan 2012 18:33:43 +0200 (IST) From: Avi Kivity To: qemu-devel@nongnu.org Date: Mon, 2 Jan 2012 18:33:32 +0200 Message-Id: <1325522015-503-14-git-send-email-avi@redhat.com> In-Reply-To: <1325522015-503-1-git-send-email-avi@redhat.com> References: <1325522015-503-1-git-send-email-avi@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 13/16] Direct dispatch through MemoryRegion X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Now that all mmio goes through MemoryRegions, we can convert io_mem_opaque to be a MemoryRegion pointer, and remove the thunks that convert from old-style CPU{Read,Write}MemoryFunc to MemoryRegionOps. Signed-off-by: Avi Kivity --- exec-all.h | 4 +- exec-obsolete.h | 5 +- exec.c | 40 +++++------------- memory.c | 122 ++++++++++++++++++------------------------------------- 4 files changed, 53 insertions(+), 118 deletions(-) diff --git a/exec-all.h b/exec-all.h index 3d72952..51d01f2 100644 --- a/exec-all.h +++ b/exec-all.h @@ -302,9 +302,7 @@ extern void *tci_tb_ptr; uint64_t io_mem_read(int index, target_phys_addr_t addr, unsigned size); void io_mem_write(int index, target_phys_addr_t addr, uint64_t value, unsigned size); -extern CPUWriteMemoryFunc *_io_mem_write[IO_MEM_NB_ENTRIES][4]; -extern CPUReadMemoryFunc *_io_mem_read[IO_MEM_NB_ENTRIES][4]; -extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; +extern struct MemoryRegion *io_mem_region[IO_MEM_NB_ENTRIES]; void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, void *retaddr); diff --git a/exec-obsolete.h b/exec-obsolete.h index e08e750..f8af27e 100644 --- a/exec-obsolete.h +++ b/exec-obsolete.h @@ -31,9 +31,8 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size, MemoryRegion *mr); void qemu_ram_free(ram_addr_t addr); void qemu_ram_free_from_ptr(ram_addr_t addr); -int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read, - CPUWriteMemoryFunc * const *mem_write, - void *opaque); +struct MemoryRegion; +int cpu_register_io_memory(MemoryRegion *mr); void cpu_unregister_io_memory(int table_address); struct MemoryRegionSection; diff --git a/exec.c b/exec.c index fc1dcb7..b443dbb 100644 --- a/exec.c +++ b/exec.c @@ -208,9 +208,7 @@ static void memory_map_init(void); /* io memory support */ -CPUWriteMemoryFunc *_io_mem_write[IO_MEM_NB_ENTRIES][4]; -CPUReadMemoryFunc *_io_mem_read[IO_MEM_NB_ENTRIES][4]; -void *io_mem_opaque[IO_MEM_NB_ENTRIES]; +MemoryRegion *io_mem_region[IO_MEM_NB_ENTRIES]; static char io_mem_used[IO_MEM_NB_ENTRIES]; static MemoryRegion io_mem_watch; #endif @@ -2563,8 +2561,10 @@ void cpu_register_physical_memory_log(MemoryRegionSection *section, &p->phys_offset, orig_memory, p->region_offset); } else { - subpage = io_mem_opaque[(orig_memory & ~TARGET_PAGE_MASK) - >> IO_MEM_SHIFT]; + MemoryRegion *mr + = io_mem_region[(orig_memory & ~TARGET_PAGE_MASK) + >> IO_MEM_SHIFT]; + subpage = container_of(mr, subpage_t, iomem); } subpage_register(subpage, start_addr2, end_addr2, phys_offset, region_offset); @@ -3427,13 +3427,8 @@ static int get_free_io_mem_idx(void) modified. If it is zero, a new io zone is allocated. The return value can be used with cpu_register_physical_memory(). (-1) is returned if error. */ -static int cpu_register_io_memory_fixed(int io_index, - CPUReadMemoryFunc * const *mem_read, - CPUWriteMemoryFunc * const *mem_write, - void *opaque) +static int cpu_register_io_memory_fixed(int io_index, MemoryRegion *mr) { - int i; - if (io_index <= 0) { io_index = get_free_io_mem_idx(); if (io_index == -1) @@ -3444,36 +3439,21 @@ static int cpu_register_io_memory_fixed(int io_index, return -1; } - for (i = 0; i < 3; ++i) { - assert(mem_read[i]); - _io_mem_read[io_index][i] = mem_read[i]; - } - for (i = 0; i < 3; ++i) { - assert(mem_write[i]); - _io_mem_write[io_index][i] = mem_write[i]; - } - io_mem_opaque[io_index] = opaque; + io_mem_region[io_index] = mr; return (io_index << IO_MEM_SHIFT); } -int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read, - CPUWriteMemoryFunc * const *mem_write, - void *opaque) +int cpu_register_io_memory(MemoryRegion *mr) { - return cpu_register_io_memory_fixed(0, mem_read, mem_write, opaque); + return cpu_register_io_memory_fixed(0, mr); } void cpu_unregister_io_memory(int io_table_address) { - int i; int io_index = io_table_address >> IO_MEM_SHIFT; - for (i=0;i < 3; i++) { - _io_mem_read[io_index][i] = NULL; - _io_mem_write[io_index][i] = NULL; - } - io_mem_opaque[io_index] = NULL; + io_mem_region[io_index] = NULL; io_mem_used[io_index] = 0; } diff --git a/memory.c b/memory.c index e34bc65..25b36ff 100644 --- a/memory.c +++ b/memory.c @@ -906,11 +906,10 @@ static bool memory_region_access_valid(MemoryRegion *mr, return true; } -static uint32_t memory_region_read_thunk_n(void *_mr, - target_phys_addr_t addr, - unsigned size) +static uint64_t memory_region_dispatch_read1(MemoryRegion *mr, + target_phys_addr_t addr, + unsigned size) { - MemoryRegion *mr = _mr; uint64_t data = 0; if (!memory_region_access_valid(mr, addr, size, false)) { @@ -930,17 +929,45 @@ static uint32_t memory_region_read_thunk_n(void *_mr, return data; } -static void memory_region_write_thunk_n(void *_mr, - target_phys_addr_t addr, - unsigned size, - uint64_t data) +static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size) { - MemoryRegion *mr = _mr; + if (memory_region_wrong_endianness(mr)) { + switch (size) { + case 1: + break; + case 2: + *data = bswap16(*data); + break; + case 4: + *data = bswap32(*data); + default: + abort(); + } + } +} + +static uint64_t memory_region_dispatch_read(MemoryRegion *mr, + target_phys_addr_t addr, + unsigned size) +{ + uint64_t ret; + + ret = memory_region_dispatch_read1(mr, addr, size); + adjust_endianness(mr, &ret, size); + return ret; +} +static void memory_region_dispatch_write(MemoryRegion *mr, + target_phys_addr_t addr, + uint64_t data, + unsigned size) +{ if (!memory_region_access_valid(mr, addr, size, true)) { return; /* FIXME: better signalling */ } + adjust_endianness(mr, &data, size); + if (!mr->ops->write) { mr->ops->old_mmio.write[bitops_ffsl(size)](mr->opaque, addr, data); return; @@ -953,69 +980,6 @@ static void memory_region_write_thunk_n(void *_mr, memory_region_write_accessor, mr); } -static uint32_t memory_region_read_thunk_b(void *mr, target_phys_addr_t addr) -{ - return memory_region_read_thunk_n(mr, addr, 1); -} - -static uint32_t memory_region_read_thunk_w(void *mr, target_phys_addr_t addr) -{ - uint32_t data; - - data = memory_region_read_thunk_n(mr, addr, 2); - if (memory_region_wrong_endianness(mr)) { - data = bswap16(data); - } - return data; -} - -static uint32_t memory_region_read_thunk_l(void *mr, target_phys_addr_t addr) -{ - uint32_t data; - - data = memory_region_read_thunk_n(mr, addr, 4); - if (memory_region_wrong_endianness(mr)) { - data = bswap32(data); - } - return data; -} - -static void memory_region_write_thunk_b(void *mr, target_phys_addr_t addr, - uint32_t data) -{ - memory_region_write_thunk_n(mr, addr, 1, data); -} - -static void memory_region_write_thunk_w(void *mr, target_phys_addr_t addr, - uint32_t data) -{ - if (memory_region_wrong_endianness(mr)) { - data = bswap16(data); - } - memory_region_write_thunk_n(mr, addr, 2, data); -} - -static void memory_region_write_thunk_l(void *mr, target_phys_addr_t addr, - uint32_t data) -{ - if (memory_region_wrong_endianness(mr)) { - data = bswap32(data); - } - memory_region_write_thunk_n(mr, addr, 4, data); -} - -static CPUReadMemoryFunc * const memory_region_read_thunk[] = { - memory_region_read_thunk_b, - memory_region_read_thunk_w, - memory_region_read_thunk_l, -}; - -static CPUWriteMemoryFunc * const memory_region_write_thunk[] = { - memory_region_write_thunk_b, - memory_region_write_thunk_w, - memory_region_write_thunk_l, -}; - void memory_region_init_io(MemoryRegion *mr, const MemoryRegionOps *ops, void *opaque, @@ -1027,9 +991,7 @@ void memory_region_init_io(MemoryRegion *mr, mr->opaque = opaque; mr->terminates = true; mr->destructor = memory_region_destructor_iomem; - mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk, - memory_region_write_thunk, - mr); + mr->ram_addr = cpu_register_io_memory(mr); } void memory_region_init_ram(MemoryRegion *mr, @@ -1078,9 +1040,7 @@ void memory_region_init_rom_device(MemoryRegion *mr, mr->terminates = true; mr->destructor = memory_region_destructor_rom_device; mr->ram_addr = qemu_ram_alloc(size, mr); - mr->ram_addr |= cpu_register_io_memory(memory_region_read_thunk, - memory_region_write_thunk, - mr); + mr->ram_addr |= cpu_register_io_memory(mr); mr->ram_addr |= IO_MEM_ROMD; } @@ -1552,15 +1512,13 @@ void set_system_io_map(MemoryRegion *mr) uint64_t io_mem_read(int io_index, target_phys_addr_t addr, unsigned size) { - return _io_mem_read[io_index][bitops_ffsl(size)](io_mem_opaque[io_index], - addr); + return memory_region_dispatch_read(io_mem_region[io_index], addr, size); } void io_mem_write(int io_index, target_phys_addr_t addr, uint64_t val, unsigned size) { - _io_mem_write[io_index][bitops_ffsl(size)](io_mem_opaque[io_index], - addr, val); + memory_region_dispatch_write(io_mem_region[io_index], addr, val, size); } typedef struct MemoryRegionList MemoryRegionList;