From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LsI1z-00030i-Gg for qemu-devel@nongnu.org; Fri, 10 Apr 2009 10:48:35 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LsI1v-000309-Ue for qemu-devel@nongnu.org; Fri, 10 Apr 2009 10:48:35 -0400 Received: from [199.232.76.173] (port=35788 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LsI1v-000306-OA for qemu-devel@nongnu.org; Fri, 10 Apr 2009 10:48:31 -0400 Received: from belushi.uits.indiana.edu ([129.79.1.188]:38488) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LsI1v-00021d-8n for qemu-devel@nongnu.org; Fri, 10 Apr 2009 10:48:31 -0400 Received: from mail-relay.iu.edu (candy.uits.indiana.edu [129.79.1.201]) by belushi.uits.indiana.edu (8.14.2/8.13.8/IU Messaging Team) with ESMTP id n3AEmRTI022739 for ; Fri, 10 Apr 2009 10:48:27 -0400 Received: from [129.79.35.119] (nibbler.dlib.indiana.edu [129.79.35.119]) (authenticated bits=0) by mail-relay.iu.edu (8.14.2/8.13.8/IU Messaging Team Submission) with ESMTP id n3AEmQIs023312 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 10 Apr 2009 10:48:26 -0400 From: Brian Wheeler Content-Type: text/plain Date: Fri, 10 Apr 2009 10:48:25 -0400 Message-Id: <1239374905.28083.21.camel@nibbler.dlib.indiana.edu> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH] two level table for IO port lookup 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 The alpha architecture uses 24 bits for the io port address so this patch adds a two level table and puts the IO port data into a struct...because sizeof(void *) * 7 * 16777216 is nearly a 1G on my workstation. I've set the alpha target to use a 12/12 split and everything else to use 8/8. Signed-off-by: Brian Wheeler --- vl.c.orig 2009-04-10 10:01:52.000000000 -0400 +++ vl.c 2009-04-10 10:13:33.000000000 -0400 @@ -168,7 +168,7 @@ //#define DEBUG_IOPORT //#define DEBUG_NET //#define DEBUG_SLIRP - +//#define DEBUG_IOPORT_FIND #ifdef DEBUG_IOPORT # define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__) @@ -184,14 +184,30 @@ /* Max number of bluetooth switches on the commandline. */ #define MAX_BT_CMDLINE 10 -/* XXX: use a two level table to limit memory usage */ -#define MAX_IOPORTS 65536 - const char *bios_dir = CONFIG_QEMU_SHAREDIR; const char *bios_name = NULL; -static void *ioport_opaque[MAX_IOPORTS]; -static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; -static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; + +struct ioport { + void *opaque; + IOPortReadFunc *read[3]; + IOPortWriteFunc *write[3]; +}; +typedef struct ioport ioport_t; + +#ifdef TARGET_ALPHA +#define IOPORT_MAXBITS 24 +#define IOPORT_PAGESIZE 12 +#else +#define IOPORT_MAXBITS 16 +#define IOPORT_PAGESIZE 8 +#endif + +#define IOPORT_ENTRYMASK ((1<> IOPORT_PAGESIZE; + uint32_t entry = address & IOPORT_ENTRYMASK; + if(address >= (1<opaque); + printf(" read: %p, %p, %p\n", p->read[0], p->read[1], p->read[2]); + printf(" write: %p, %p, %p\n", p->write[0], p->write[1], p->write[2]); +#endif + return p; +} + static uint32_t ioport_read(int index, uint32_t address) { static IOPortReadFunc *default_func[3] = { @@ -295,10 +338,11 @@ default_ioport_readw, default_ioport_readl }; - IOPortReadFunc *func = ioport_read_table[index][address]; + ioport_t *p = ioport_find(address); + IOPortReadFunc *func = p->read[index]; if (!func) func = default_func[index]; - return func(ioport_opaque[address], address); + return func(p->opaque, address); } static void ioport_write(int index, uint32_t address, uint32_t data) @@ -308,10 +352,11 @@ default_ioport_writew, default_ioport_writel }; - IOPortWriteFunc *func = ioport_write_table[index][address]; + ioport_t *p = ioport_find(address); + IOPortWriteFunc *func = p->write[index]; if (!func) func = default_func[index]; - func(ioport_opaque[address], address, data); + func(p->opaque, address, data); } static uint32_t default_ioport_readb(void *opaque, uint32_t address) @@ -378,10 +423,11 @@ return -1; } for(i = start; i < start + length; i += size) { - ioport_read_table[bsize][i] = func; - if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque) + ioport_t *p = ioport_find(i); + p->read[bsize] = func; + if (p->opaque != NULL && p->opaque != opaque) hw_error("register_ioport_read: invalid opaque"); - ioport_opaque[i] = opaque; + p->opaque = opaque; } return 0; } @@ -403,10 +449,11 @@ return -1; } for(i = start; i < start + length; i += size) { - ioport_write_table[bsize][i] = func; - if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque) + ioport_t *p = ioport_find(i); + p->write[bsize] = func; + if (p->opaque != NULL && p->opaque != opaque) hw_error("register_ioport_write: invalid opaque"); - ioport_opaque[i] = opaque; + p->opaque = opaque; } return 0; } @@ -416,15 +463,16 @@ int i; for(i = start; i < start + length; i++) { - ioport_read_table[0][i] = default_ioport_readb; - ioport_read_table[1][i] = default_ioport_readw; - ioport_read_table[2][i] = default_ioport_readl; - - ioport_write_table[0][i] = default_ioport_writeb; - ioport_write_table[1][i] = default_ioport_writew; - ioport_write_table[2][i] = default_ioport_writel; + ioport_t *p = ioport_find(i); + p->read[0] = default_ioport_readb; + p->read[1] = default_ioport_readw; + p->read[2] = default_ioport_readl; + + p->write[0] = default_ioport_writeb; + p->write[1] = default_ioport_writew; + p->write[2] = default_ioport_writel; - ioport_opaque[i] = NULL; + p->opaque = NULL; } }