From patchwork Thu Jul 22 21:54:30 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Blue Swirl X-Patchwork-Id: 59694 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 E1D9F1007F0 for ; Fri, 23 Jul 2010 09:12:36 +1000 (EST) Received: from localhost ([127.0.0.1]:41026 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Oc4wK-0006ib-Ed for incoming@patchwork.ozlabs.org; Thu, 22 Jul 2010 19:12:32 -0400 Received: from [140.186.70.92] (port=43087 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Oc3xW-0003b3-6k for qemu-devel@nongnu.org; Thu, 22 Jul 2010 18:09:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1Oc3j9-0002HK-93 for qemu-devel@nongnu.org; Thu, 22 Jul 2010 17:54:52 -0400 Received: from mail-vw0-f45.google.com ([209.85.212.45]:56272) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1Oc3j9-0002HC-27 for qemu-devel@nongnu.org; Thu, 22 Jul 2010 17:54:51 -0400 Received: by vws19 with SMTP id 19so691483vws.4 for ; Thu, 22 Jul 2010 14:54:50 -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=mjVEslW9DUmHYEeirMY5pJq0flOoPUKIdNYysXdgpLg=; b=OXsy0/3DEwdAY/+wowqzncyA0laZo4IG1LAgDoSoEuFGDS9BSU37ebYccn1ny5LAJq n2Hv9q8v+W2Khf2nOK3VFYAL7Dm6joHQuHdthEkVS0YPeGTZxwFOCpeCtLXVZ2ActlP7 5QwhGz+k+6ZG2WoZQwBDmGGbSiUxPvnxu044c= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:from:date:message-id:subject:to:content-type; b=WTiRi8gGHAXP/DYH5k7Iear3WTaRlqXHoNlatnfz9NRZO+oDlAXIq2h2gOkOY4w68q DyasMeubkBEJKljd+uuX/V0pyFHL16Fx9Y0AGDkoYySjcthS10CzRLLIuQqOLZQjkmq4 +eXbrHPD+b9iseVD0yubVC4eRLKl9dMpka8h4= Received: by 10.224.60.20 with SMTP id n20mr1698231qah.279.1279835690182; Thu, 22 Jul 2010 14:54:50 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.185.146 with HTTP; Thu, 22 Jul 2010 14:54:30 -0700 (PDT) From: Blue Swirl Date: Thu, 22 Jul 2010 21:54:30 +0000 Message-ID: To: qemu-devel X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [Qemu-devel] [PATCH 01/34] 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);