From patchwork Mon Jul 12 18:39:46 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Blue Swirl X-Patchwork-Id: 58642 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 D7F88B6F17 for ; Tue, 13 Jul 2010 04:41:14 +1000 (EST) Received: from localhost ([127.0.0.1]:53955 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OYNwE-00004u-T7 for incoming@patchwork.ozlabs.org; Mon, 12 Jul 2010 14:41:10 -0400 Received: from [140.186.70.92] (port=47252 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OYNvF-0008Vo-44 for qemu-devel@nongnu.org; Mon, 12 Jul 2010 14:40:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OYNvD-00063C-U8 for qemu-devel@nongnu.org; Mon, 12 Jul 2010 14:40:08 -0400 Received: from mail-pv0-f173.google.com ([74.125.83.173]:59014) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OYNvD-000634-J7 for qemu-devel@nongnu.org; Mon, 12 Jul 2010 14:40:07 -0400 Received: by pvg7 with SMTP id 7so1957702pvg.4 for ; Mon, 12 Jul 2010 11:40:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:mime-version:received:from:date :message-id:subject:to:content-type; bh=9UJeY3MKqyFW1NKBKJXiXFXYewmizST+IeFs5Hkqshc=; b=kjVYIa+xYkQbhz6jYwvMTuG7/91F9Pi8F6bZYaQ+qvIveF+3OsL1X0qA05p9zfg4Xh d+GdW53PP+Ho253UeHfkP5J65OwwWg+3kU6UDhuKHSwbLtrKSrCawlvUoxDEWc8WMRFD mKxJD404vGMGevEROCJzXq1auDk3bDb4fluoI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:from:date:message-id:subject:to:content-type; b=NwyQ8rugzVrb/1l4wgIAbzN+qPKNfIo2U7trGwKSpf7+teLzGmpaaZDqadMoy7s8xp AGLj/sE18Ic3s1of+D0fCcomBNwHaeyg02Tu9IILpaQQ35uL9aRkJqiasdblKbcZl2eD JuAQ78UBuszHJw6XFiapj+jO95MfDA+Qn2aS4= Received: by 10.142.48.18 with SMTP id v18mr2046959wfv.337.1278960006074; Mon, 12 Jul 2010 11:40:06 -0700 (PDT) MIME-Version: 1.0 Received: by 10.142.212.14 with HTTP; Mon, 12 Jul 2010 11:39:46 -0700 (PDT) From: Blue Swirl Date: Mon, 12 Jul 2010 18:39:46 +0000 Message-ID: To: qemu-devel , Anthony Liguori , "Michael S. Tsirkin" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: Subject: [Qemu-devel] [PATCH 01/15] ioport: separate registration from mapping 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 Add I/O port registration functions which separate registration from the mapping stage. Signed-off-by: Blue Swirl --- ioport.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ ioport.h | 6 +++ 2 files changed, 111 insertions(+), 12 deletions(-) diff --git a/ioport.c b/ioport.c index 53dd87a..54fff7e 100644 --- a/ioport.c +++ b/ioport.c @@ -54,29 +54,39 @@ static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl; static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel; +#define IO_NB_ENTRIES 256 + +static IOPortWriteFunc *io_writes[IO_NB_ENTRIES][3]; +static IOPortReadFunc *io_reads[IO_NB_ENTRIES][3]; +static void *io_opaques[IO_NB_ENTRIES]; +static int io_sizes[IO_NB_ENTRIES]; +static char io_used[IO_NB_ENTRIES]; + +static IOPortReadFunc * const default_read_func[3] = { + default_ioport_readb, + default_ioport_readw, + default_ioport_readl +}; + static uint32_t ioport_read(int index, uint32_t address) { - static IOPortReadFunc * const default_func[3] = { - default_ioport_readb, - default_ioport_readw, - default_ioport_readl - }; IOPortReadFunc *func = ioport_read_table[index][address]; if (!func) - func = default_func[index]; + func = default_read_func[index]; return func(ioport_opaque[address], address); } +static IOPortWriteFunc * const default_write_func[3] = { + default_ioport_writeb, + default_ioport_writew, + default_ioport_writel +}; + static void ioport_write(int index, uint32_t address, uint32_t data) { - static IOPortWriteFunc * const default_func[3] = { - default_ioport_writeb, - default_ioport_writew, - default_ioport_writel - }; IOPortWriteFunc *func = ioport_write_table[index][address]; if (!func) - func = default_func[index]; + func = default_write_func[index]; func(ioport_opaque[address], address, data); } @@ -173,6 +183,84 @@ int register_ioport_write(pio_addr_t start, int length, int size, return 0; } +static int get_free_io_mem_idx(void) +{ + int i; + + for (i = 0; i < IO_NB_ENTRIES; i++) { + if (!io_used[i]) { + io_used[i] = 1; + return i; + } + } + fprintf(stderr, "RAN out out io_mem_idx, max %d !\n", IO_NB_ENTRIES); + return -1; +} + +/* io_read and io_write are arrays of functions containing the + function to access byte (index 0), word (index 1) and dword (index + 2). Functions can be omitted with a NULL function pointer. (-1) is + returned if error. */ +int cpu_register_io(IOPortReadFunc * const *io_read, + IOPortWriteFunc * const *io_write, + int size, void *opaque) +{ + unsigned int i; + int io_index; + + io_index = get_free_io_mem_idx(); + if (io_index == -1) { + return io_index; + } + + if (io_read) { + for (i = 0; i < 3; i++) { + io_reads[io_index][i] = io_read[i]; + } + } + if (io_write) { + for (i = 0; i < 3; i++) { + io_writes[io_index][i] = io_write[i]; + } + } + io_opaques[io_index] = opaque; + io_sizes[io_index] = size; + + return io_index; +} + +void cpu_unregister_io(int io_index) +{ + unsigned int i; + + for (i = 0; i < 3; i++) { + io_reads[io_index][i] = NULL; + io_writes[io_index][i] = NULL; + } + io_opaques[io_index] = NULL; + io_sizes[io_index] = 0; + io_used[io_index] = 0; +} + +void cpu_map_io(pio_addr_t start, int io_index) +{ + unsigned int i; + + assert(io_index >= 0); + for (i = 0; i < 3; i++) { + if (io_reads[io_index][i]) { + register_ioport_read(start, io_sizes[io_index], 1 << i, + io_reads[io_index][i], + io_opaques[io_index]); + } + if (io_writes[io_index][i]) { + register_ioport_write(start, io_sizes[io_index], 1 << i, + io_writes[io_index][i], + io_opaques[io_index]); + } + } +} + void isa_unassign_ioport(pio_addr_t start, int length) { int i; @@ -190,6 +278,11 @@ void isa_unassign_ioport(pio_addr_t start, int length) } } +void cpu_unmap_io(pio_addr_t start, int io_index) +{ + isa_unassign_ioport(start, io_sizes[io_index]); +} + /***********************************************************/ void cpu_outb(pio_addr_t addr, uint8_t val) diff --git a/ioport.h b/ioport.h index 3d3c8a3..4ba78ed 100644 --- a/ioport.h +++ b/ioport.h @@ -40,6 +40,12 @@ int register_ioport_read(pio_addr_t start, int length, int size, IOPortReadFunc *func, void *opaque); int register_ioport_write(pio_addr_t start, int length, int size, IOPortWriteFunc *func, void *opaque); +int cpu_register_io(IOPortReadFunc * const *io_read, + IOPortWriteFunc * const *io_write, + int size, void *opaque); +void cpu_unregister_io(int io_index); +void cpu_map_io(pio_addr_t start, int io_index); +void cpu_unmap_io(pio_addr_t start, int io_index); void isa_unassign_ioport(pio_addr_t start, int length);