From patchwork Thu Apr 22 23:47:31 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 50771 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 080A9B7D1A for ; Fri, 23 Apr 2010 10:14:35 +1000 (EST) Received: from localhost ([127.0.0.1]:46111 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O56Aa-0005r4-FH for incoming@patchwork.ozlabs.org; Thu, 22 Apr 2010 19:50:56 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1O569M-0005ql-Jr for qemu-devel@nongnu.org; Thu, 22 Apr 2010 19:49:40 -0400 Received: from [140.186.70.92] (port=46994 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1O569K-0005qE-Vz for qemu-devel@nongnu.org; Thu, 22 Apr 2010 19:49:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1O569J-0002zX-31 for qemu-devel@nongnu.org; Thu, 22 Apr 2010 19:49:38 -0400 Received: from are.twiddle.net ([75.149.56.221]:39983) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1O569I-0002zK-Mc for qemu-devel@nongnu.org; Thu, 22 Apr 2010 19:49:37 -0400 Received: by are.twiddle.net (Postfix, from userid 5000) id D3ACB101C; Thu, 22 Apr 2010 16:49:34 -0700 (PDT) In-Reply-To: <4BD0A994.2090608@twiddle.net> References: <4BD0A994.2090608@twiddle.net> From: Richard Henderson Date: Thu, 22 Apr 2010 16:47:31 -0700 To: qemu-devel@nongnu.org Message-Id: <20100422234934.D3ACB101C@are.twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: blauwirbel@gmail.com Subject: [Qemu-devel] [PATCH] Remove IO_MEM_SUBWIDTH. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Greatly simplify the subpage implementation by not supporting multiple devices at the same address at different widths. We don't need full copies of mem_read/mem_write/opaque for each address, only a single index back into the main io_mem_* arrays. Signed-off-by: Richard Henderson --- cpu-common.h | 1 - exec.c | 113 ++++++++++++++++++--------------------------------------- 2 files changed, 36 insertions(+), 78 deletions(-) diff --git a/cpu-common.h b/cpu-common.h index b730ca0..b24cecc 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -125,7 +125,6 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr, /* Acts like a ROM when read and like a device when written. */ #define IO_MEM_ROMD (1) #define IO_MEM_SUBPAGE (2) -#define IO_MEM_SUBWIDTH (4) #endif diff --git a/exec.c b/exec.c index 43366ac..14d1fd7 100644 --- a/exec.c +++ b/exec.c @@ -2549,16 +2549,15 @@ static inline void tlb_set_dirty(CPUState *env, #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK) typedef struct subpage_t { target_phys_addr_t base; - CPUReadMemoryFunc * const *mem_read[TARGET_PAGE_SIZE][4]; - CPUWriteMemoryFunc * const *mem_write[TARGET_PAGE_SIZE][4]; - void *opaque[TARGET_PAGE_SIZE][2][4]; - ram_addr_t region_offset[TARGET_PAGE_SIZE][2][4]; + ram_addr_t sub_io_index[TARGET_PAGE_SIZE]; + ram_addr_t region_offset[TARGET_PAGE_SIZE]; } subpage_t; static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, ram_addr_t memory, ram_addr_t region_offset); -static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, - ram_addr_t orig_memory, ram_addr_t region_offset); +static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys, + ram_addr_t orig_memory, + ram_addr_t region_offset); #define CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, \ need_subpage) \ do { \ @@ -2596,7 +2595,7 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, PhysPageDesc *p; CPUState *env; ram_addr_t orig_size = size; - void *subpage; + subpage_t *subpage; cpu_notify_set_memory(start_addr, size, phys_offset); @@ -2615,7 +2614,7 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, need_subpage); - if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) { + if (need_subpage) { if (!(orig_memory & IO_MEM_SUBPAGE)) { subpage = subpage_init((addr & TARGET_PAGE_MASK), &p->phys_offset, orig_memory, @@ -2647,7 +2646,7 @@ void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, CHECK_SUBPAGE(addr, start_addr, start_addr2, end_addr, end_addr2, need_subpage); - if (need_subpage || phys_offset & IO_MEM_SUBWIDTH) { + if (need_subpage) { subpage = subpage_init((addr & TARGET_PAGE_MASK), &p->phys_offset, IO_MEM_UNASSIGNED, addr & TARGET_PAGE_MASK); @@ -3145,89 +3144,65 @@ static CPUWriteMemoryFunc * const watch_mem_write[3] = { watch_mem_writel, }; -static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr, - unsigned int len) +static inline uint32_t subpage_readlen (subpage_t *mmio, + target_phys_addr_t addr, + unsigned int len) { - uint32_t ret; - unsigned int idx; - - idx = SUBPAGE_IDX(addr); + unsigned int idx = SUBPAGE_IDX(addr); #if defined(DEBUG_SUBPAGE) printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__, mmio, len, addr, idx); #endif - ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len], - addr + mmio->region_offset[idx][0][len]); - return ret; + addr += mmio->region_offset[idx]; + idx = mmio->sub_io_index[idx]; + return io_mem_read[idx][len](io_mem_opaque[idx], addr); } static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr, - uint32_t value, unsigned int len) + uint32_t value, unsigned int len) { - unsigned int idx; - - idx = SUBPAGE_IDX(addr); + unsigned int idx = SUBPAGE_IDX(addr); #if defined(DEBUG_SUBPAGE) - printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__, - mmio, len, addr, idx, value); + printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", + __func__, mmio, len, addr, idx, value); #endif - (**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len], - addr + mmio->region_offset[idx][1][len], - value); + + addr += mmio->region_offset[idx]; + idx = mmio->sub_io_index[idx]; + io_mem_write[idx][len](io_mem_opaque[idx], addr, value); } static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr) { -#if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr); -#endif - return subpage_readlen(opaque, addr, 0); } static void subpage_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) { -#if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value); -#endif subpage_writelen(opaque, addr, value, 0); } static uint32_t subpage_readw (void *opaque, target_phys_addr_t addr) { -#if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr); -#endif - return subpage_readlen(opaque, addr, 1); } static void subpage_writew (void *opaque, target_phys_addr_t addr, uint32_t value) { -#if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value); -#endif subpage_writelen(opaque, addr, value, 1); } static uint32_t subpage_readl (void *opaque, target_phys_addr_t addr) { -#if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr); -#endif - return subpage_readlen(opaque, addr, 2); } -static void subpage_writel (void *opaque, - target_phys_addr_t addr, uint32_t value) +static void subpage_writel (void *opaque, target_phys_addr_t addr, + uint32_t value) { -#if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value); -#endif subpage_writelen(opaque, addr, value, 2); } @@ -3247,7 +3222,6 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, ram_addr_t memory, ram_addr_t region_offset) { int idx, eidx; - unsigned int i; if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE) return -1; @@ -3257,27 +3231,18 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__, mmio, start, end, idx, eidx, memory); #endif - memory >>= IO_MEM_SHIFT; + memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); for (; idx <= eidx; idx++) { - for (i = 0; i < 4; i++) { - if (io_mem_read[memory][i]) { - mmio->mem_read[idx][i] = &io_mem_read[memory][i]; - mmio->opaque[idx][0][i] = io_mem_opaque[memory]; - mmio->region_offset[idx][0][i] = region_offset; - } - if (io_mem_write[memory][i]) { - mmio->mem_write[idx][i] = &io_mem_write[memory][i]; - mmio->opaque[idx][1][i] = io_mem_opaque[memory]; - mmio->region_offset[idx][1][i] = region_offset; - } - } + mmio->sub_io_index[idx] = memory; + mmio->region_offset[idx] = region_offset; } return 0; } -static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, - ram_addr_t orig_memory, ram_addr_t region_offset) +static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys, + ram_addr_t orig_memory, + ram_addr_t region_offset) { subpage_t *mmio; int subpage_memory; @@ -3291,8 +3256,7 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, mmio, base, TARGET_PAGE_SIZE, subpage_memory); #endif *phys = subpage_memory | IO_MEM_SUBPAGE; - subpage_register(mmio, 0, TARGET_PAGE_SIZE - 1, orig_memory, - region_offset); + subpage_register(mmio, 0, TARGET_PAGE_SIZE-1, orig_memory, region_offset); return mmio; } @@ -3322,8 +3286,6 @@ static int cpu_register_io_memory_fixed(int io_index, CPUWriteMemoryFunc * const *mem_write, void *opaque) { - int i, subwidth = 0; - if (io_index <= 0) { io_index = get_free_io_mem_idx(); if (io_index == -1) @@ -3334,14 +3296,11 @@ static int cpu_register_io_memory_fixed(int io_index, return -1; } - for(i = 0;i < 3; i++) { - if (!mem_read[i] || !mem_write[i]) - subwidth = IO_MEM_SUBWIDTH; - io_mem_read[io_index][i] = mem_read[i]; - io_mem_write[io_index][i] = mem_write[i]; - } + memcpy(io_mem_read[io_index], mem_read, 3 * sizeof(CPUReadMemoryFunc*)); + memcpy(io_mem_write[io_index], mem_write, 3 * sizeof(CPUWriteMemoryFunc*)); io_mem_opaque[io_index] = opaque; - return (io_index << IO_MEM_SHIFT) | subwidth; + + return (io_index << IO_MEM_SHIFT); } int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,