From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JMlDE-00082i-3m for qemu-devel@nongnu.org; Wed, 06 Feb 2008 09:25:20 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JMlDC-00081r-Vk for qemu-devel@nongnu.org; Wed, 06 Feb 2008 09:25:19 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JMlDC-00081o-Og for qemu-devel@nongnu.org; Wed, 06 Feb 2008 09:25:18 -0500 Received: from smtp02.citrix.com ([66.165.176.63]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1JMlDC-0006FA-Ct for qemu-devel@nongnu.org; Wed, 06 Feb 2008 09:25:18 -0500 Received: from implementation.famille.thibault.fr (dhcp-16-192.uk.xensource.com [172.31.16.192]) by smtp01.ad.xensource.com (8.13.1/8.13.1) with ESMTP id m16EORSL006213 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Wed, 6 Feb 2008 06:24:29 -0800 Received: from samy by implementation.famille.thibault.fr with local (Exim 4.68) (envelope-from ) id 1JMlCM-00057U-Lf for qemu-devel@nongnu.org; Wed, 06 Feb 2008 15:24:26 +0100 Date: Wed, 6 Feb 2008 14:24:26 +0000 From: Samuel Thibault Message-ID: <20080206142426.GH4338@implementation.uk.xensource.com> References: <20071119152016.GE6331@implementation.uk.xensource.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="mP3DRpeJDSE+ciuQ" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20071119152016.GE6331@implementation.uk.xensource.com> Subject: [Qemu-devel] [PATCH] memory usage and ioports Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --mP3DRpeJDSE+ciuQ Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit Samuel Thibault, le Mon 19 Nov 2007 15:20:16 +0000, a écrit : > Qemu currently uses 6 65k tables of pointers for handling ioports, which > makes 3MB on 64bit machines. There's a comment that says "XXX: use a two > level table to limit memory usage". But wouldn't it be more simple and > effective to just allocate them through mmap() and when a NULL pointer > is read, call the default handlers? Here is a patch that does this and indeed saves 3MB on 64bit machines. Samuel --mP3DRpeJDSE+ciuQ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=patch-qemu-ioport ? ChangeLog Index: vl.c =================================================================== RCS file: /sources/qemu/qemu/vl.c,v retrieving revision 1.403 diff -u -p -r1.403 vl.c --- vl.c 3 Feb 2008 03:45:47 -0000 1.403 +++ vl.c 6 Feb 2008 14:22:18 -0000 @@ -267,17 +267,29 @@ static void default_ioport_writeb(void * static uint32_t default_ioport_readw(void *opaque, uint32_t address) { uint32_t data; - data = ioport_read_table[0][address](ioport_opaque[address], address); + IOPortReadFunc *func = ioport_read_table[0][address]; + if (!func) + func = default_ioport_readb; + data = func(ioport_opaque[address], address); address = (address + 1) & (MAX_IOPORTS - 1); - data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8; + func = ioport_read_table[0][address]; + if (!func) + func = default_ioport_readb; + data |= func(ioport_opaque[address], address) << 8; return data; } static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data) { - ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff); + IOPortWriteFunc *func = ioport_write_table[0][address]; + if (!func) + func = default_ioport_writeb; + func(ioport_opaque[address], address, data & 0xff); address = (address + 1) & (MAX_IOPORTS - 1); - ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff); + func = ioport_write_table[0][address]; + if (!func) + func = default_ioport_writeb; + func(ioport_opaque[address], address, (data >> 8) & 0xff); } static uint32_t default_ioport_readl(void *opaque, uint32_t address) @@ -297,16 +309,6 @@ static void default_ioport_writel(void * static void init_ioports(void) { - int i; - - for(i = 0; i < MAX_IOPORTS; i++) { - ioport_read_table[0][i] = default_ioport_readb; - ioport_write_table[0][i] = default_ioport_writeb; - ioport_read_table[1][i] = default_ioport_readw; - ioport_write_table[1][i] = default_ioport_writew; - ioport_read_table[2][i] = default_ioport_readl; - ioport_write_table[2][i] = default_ioport_writel; - } } /* size is the word size in byte */ @@ -378,11 +380,14 @@ void isa_unassign_ioport(int start, int void cpu_outb(CPUState *env, int addr, int val) { + IOPortWriteFunc *func = ioport_write_table[0][addr]; + if (!func) + func = default_ioport_writeb; #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "outb: %04x %02x\n", addr, val); #endif - ioport_write_table[0][addr](ioport_opaque[addr], addr, val); + func(ioport_opaque[addr], addr, val); #ifdef USE_KQEMU if (env) env->last_io_time = cpu_get_time_fast(); @@ -391,11 +396,14 @@ void cpu_outb(CPUState *env, int addr, i void cpu_outw(CPUState *env, int addr, int val) { + IOPortWriteFunc *func = ioport_write_table[1][addr]; + if (!func) + func = default_ioport_writew; #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "outw: %04x %04x\n", addr, val); #endif - ioport_write_table[1][addr](ioport_opaque[addr], addr, val); + func(ioport_opaque[addr], addr, val); #ifdef USE_KQEMU if (env) env->last_io_time = cpu_get_time_fast(); @@ -404,11 +412,14 @@ void cpu_outw(CPUState *env, int addr, i void cpu_outl(CPUState *env, int addr, int val) { + IOPortWriteFunc *func = ioport_write_table[2][addr]; + if (!func) + func = default_ioport_writel; #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "outl: %04x %08x\n", addr, val); #endif - ioport_write_table[2][addr](ioport_opaque[addr], addr, val); + func(ioport_opaque[addr], addr, val); #ifdef USE_KQEMU if (env) env->last_io_time = cpu_get_time_fast(); @@ -418,7 +429,10 @@ void cpu_outl(CPUState *env, int addr, i int cpu_inb(CPUState *env, int addr) { int val; - val = ioport_read_table[0][addr](ioport_opaque[addr], addr); + IOPortReadFunc *func = ioport_read_table[0][addr]; + if (!func) + func = default_ioport_readb; + val = func(ioport_opaque[addr], addr); #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "inb : %04x %02x\n", addr, val); @@ -433,7 +447,10 @@ int cpu_inb(CPUState *env, int addr) int cpu_inw(CPUState *env, int addr) { int val; - val = ioport_read_table[1][addr](ioport_opaque[addr], addr); + IOPortReadFunc *func = ioport_read_table[1][addr]; + if (!func) + func = default_ioport_readw; + val = func(ioport_opaque[addr], addr); #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "inw : %04x %04x\n", addr, val); @@ -448,7 +465,10 @@ int cpu_inw(CPUState *env, int addr) int cpu_inl(CPUState *env, int addr) { int val; - val = ioport_read_table[2][addr](ioport_opaque[addr], addr); + IOPortReadFunc *func = ioport_read_table[2][addr]; + if (!func) + func = default_ioport_readl; + val = func(ioport_opaque[addr], addr); #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "inl : %04x %08x\n", addr, val); --mP3DRpeJDSE+ciuQ--