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