Patchwork [01/15] ioport: separate registration from mapping

login
register
mail settings
Submitter Blue Swirl
Date July 12, 2010, 6:39 p.m.
Message ID <AANLkTimucbXgS7EGXc309Ikhi_JDrtP2iNWiDfEsx3ea@mail.gmail.com>
Download mbox | patch
Permalink /patch/58642/
State New
Headers show

Comments

Blue Swirl - July 12, 2010, 6:39 p.m.
Add I/O port registration functions which separate registration
from the mapping stage.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 ioport.c |  117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 ioport.h |    6 +++
 2 files changed, 111 insertions(+), 12 deletions(-)

Patch

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);