support for opaque data on memory I/Os


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@874 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/exec-all.h b/exec-all.h
index 20c7d3b..8167d1a 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -377,6 +377,7 @@
 
 extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
 extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
+extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
 
 #ifdef __powerpc__
 static inline int testandset (int *p)
diff --git a/exec.c b/exec.c
index 9a6d81a..617dea1 100644
--- a/exec.c
+++ b/exec.c
@@ -117,6 +117,7 @@
 /* io memory support */
 CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
 CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
+void *io_mem_opaque[IO_MEM_NB_ENTRIES];
 static int io_mem_nb;
 
 /* log support */
@@ -711,10 +712,13 @@
     PageDesc *p;
     int offset, b;
 #if 0
-    if (cpu_single_env->cr[0] & CR0_PE_MASK) {
-        printf("modifying code at 0x%x size=%d EIP=%x\n", 
-               (vaddr & TARGET_PAGE_MASK) | (start & ~TARGET_PAGE_MASK), len, 
-               cpu_single_env->eip);
+    if (1) {
+        if (loglevel) {
+            fprintf(logfile, "modifying code at 0x%x size=%d EIP=%x PC=%08x\n", 
+                   cpu_single_env->mem_write_vaddr, len, 
+                   cpu_single_env->eip, 
+                   cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);
+        }
     }
 #endif
     p = page_find(start >> TARGET_PAGE_BITS);
@@ -1799,12 +1803,12 @@
     }
 }
 
-static uint32_t unassigned_mem_readb(target_phys_addr_t addr)
+static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
 {
     return 0;
 }
 
-static void unassigned_mem_writeb(target_phys_addr_t addr, uint32_t val)
+static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
 }
 
@@ -1823,7 +1827,7 @@
 /* self modifying code support in soft mmu mode : writing to a page
    containing code comes to these functions */
 
-static void code_mem_writeb(target_phys_addr_t addr, uint32_t val)
+static void code_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     unsigned long phys_addr;
 
@@ -1835,7 +1839,7 @@
     phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
 }
 
-static void code_mem_writew(target_phys_addr_t addr, uint32_t val)
+static void code_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     unsigned long phys_addr;
 
@@ -1847,7 +1851,7 @@
     phys_ram_dirty[phys_addr >> TARGET_PAGE_BITS] = 1;
 }
 
-static void code_mem_writel(target_phys_addr_t addr, uint32_t val)
+static void code_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     unsigned long phys_addr;
 
@@ -1871,19 +1875,19 @@
     code_mem_writel,
 };
 
-static void notdirty_mem_writeb(target_phys_addr_t addr, uint32_t val)
+static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     stb_raw((uint8_t *)addr, val);
     tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
 }
 
-static void notdirty_mem_writew(target_phys_addr_t addr, uint32_t val)
+static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     stw_raw((uint8_t *)addr, val);
     tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
 }
 
-static void notdirty_mem_writel(target_phys_addr_t addr, uint32_t val)
+static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     stl_raw((uint8_t *)addr, val);
     tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
@@ -1897,10 +1901,10 @@
 
 static void io_mem_init(void)
 {
-    cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, code_mem_read, unassigned_mem_write);
-    cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write);
-    cpu_register_io_memory(IO_MEM_CODE >> IO_MEM_SHIFT, code_mem_read, code_mem_write);
-    cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, code_mem_read, notdirty_mem_write);
+    cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, code_mem_read, unassigned_mem_write, NULL);
+    cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, unassigned_mem_read, unassigned_mem_write, NULL);
+    cpu_register_io_memory(IO_MEM_CODE >> IO_MEM_SHIFT, code_mem_read, code_mem_write, NULL);
+    cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, code_mem_read, notdirty_mem_write, NULL);
     io_mem_nb = 5;
 
     /* alloc dirty bits array */
@@ -1915,7 +1919,8 @@
    cpu_register_physical_memory(). (-1) is returned if error. */
 int cpu_register_io_memory(int io_index,
                            CPUReadMemoryFunc **mem_read,
-                           CPUWriteMemoryFunc **mem_write)
+                           CPUWriteMemoryFunc **mem_write,
+                           void *opaque)
 {
     int i;
 
@@ -1932,6 +1937,7 @@
         io_mem_read[io_index][i] = mem_read[i];
         io_mem_write[io_index][i] = mem_write[i];
     }
+    io_mem_opaque[io_index] = opaque;
     return io_index << IO_MEM_SHIFT;
 }
 
@@ -1994,17 +2000,17 @@
                 if (l >= 4 && ((addr & 3) == 0)) {
                     /* 32 bit read access */
                     val = ldl_raw(buf);
-                    io_mem_write[io_index][2](addr, val);
+                    io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
                     l = 4;
                 } else if (l >= 2 && ((addr & 1) == 0)) {
                     /* 16 bit read access */
                     val = lduw_raw(buf);
-                    io_mem_write[io_index][1](addr, val);
+                    io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val);
                     l = 2;
                 } else {
                     /* 8 bit access */
                     val = ldub_raw(buf);
-                    io_mem_write[io_index][0](addr, val);
+                    io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val);
                     l = 1;
                 }
             } else {
@@ -2025,17 +2031,17 @@
                 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
                 if (l >= 4 && ((addr & 3) == 0)) {
                     /* 32 bit read access */
-                    val = io_mem_read[io_index][2](addr);
+                    val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
                     stl_raw(buf, val);
                     l = 4;
                 } else if (l >= 2 && ((addr & 1) == 0)) {
                     /* 16 bit read access */
-                    val = io_mem_read[io_index][1](addr);
+                    val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr);
                     stw_raw(buf, val);
                     l = 2;
                 } else {
                     /* 8 bit access */
-                    val = io_mem_read[io_index][0](addr);
+                    val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr);
                     stb_raw(buf, val);
                     l = 1;
                 }
diff --git a/hw/ppc.c b/hw/ppc.c
index 7793cbd..2c39121 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -197,18 +197,18 @@
 }
 #endif
 
-static void PPC_io_writeb (target_phys_addr_t addr, uint32_t value)
+static void PPC_io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
     cpu_outb(NULL, addr & 0xffff, value);
 }
 
-static uint32_t PPC_io_readb (target_phys_addr_t addr)
+static uint32_t PPC_io_readb (void *opaque, target_phys_addr_t addr)
 {
     uint32_t ret = cpu_inb(NULL, addr & 0xffff);
     return ret;
 }
 
-static void PPC_io_writew (target_phys_addr_t addr, uint32_t value)
+static void PPC_io_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
     value = bswap16(value);
@@ -216,7 +216,7 @@
     cpu_outw(NULL, addr & 0xffff, value);
 }
 
-static uint32_t PPC_io_readw (target_phys_addr_t addr)
+static uint32_t PPC_io_readw (void *opaque, target_phys_addr_t addr)
 {
     uint32_t ret = cpu_inw(NULL, addr & 0xffff);
 #ifdef TARGET_WORDS_BIGENDIAN
@@ -225,7 +225,7 @@
     return ret;
 }
 
-static void PPC_io_writel (target_phys_addr_t addr, uint32_t value)
+static void PPC_io_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
     value = bswap32(value);
@@ -233,7 +233,7 @@
     cpu_outl(NULL, addr & 0xffff, value);
 }
 
-static uint32_t PPC_io_readl (target_phys_addr_t addr)
+static uint32_t PPC_io_readl (void *opaque, target_phys_addr_t addr)
 {
     uint32_t ret = cpu_inl(NULL, addr & 0xffff);
 
diff --git a/hw/ppc_chrp.c b/hw/ppc_chrp.c
index 380fb6e..d2ab170 100644
--- a/hw/ppc_chrp.c
+++ b/hw/ppc_chrp.c
@@ -64,7 +64,7 @@
     pci_pmac_init();
 
     /* Register 64 KB of ISA IO space */
-    PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write);
+    PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL);
     cpu_register_physical_memory(0x80000000, 0x10000, PPC_io_memory);
     //    cpu_register_physical_memory(0xfe000000, 0xfe010000, PPC_io_memory);
 
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 4a866ef..45b5853 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -98,7 +98,7 @@
 
 /* PCI intack register */
 /* Read-only register (?) */
-static void _PPC_intack_write (target_phys_addr_t addr, uint32_t value)
+static void _PPC_intack_write (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
     //    printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
 }
@@ -114,12 +114,12 @@
     return retval;
 }
 
-static uint32_t PPC_intack_readb (target_phys_addr_t addr)
+static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr)
 {
     return _PPC_intack_read(addr);
 }
 
-static uint32_t PPC_intack_readw (target_phys_addr_t addr)
+static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
     return bswap16(_PPC_intack_read(addr));
@@ -128,7 +128,7 @@
 #endif
 }
 
-static uint32_t PPC_intack_readl (target_phys_addr_t addr)
+static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
     return bswap32(_PPC_intack_read(addr));
@@ -177,12 +177,12 @@
 } XCSR;
 #endif
 
-static void PPC_XCSR_writeb (target_phys_addr_t addr, uint32_t value)
+static void PPC_XCSR_writeb (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
     printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
 }
 
-static void PPC_XCSR_writew (target_phys_addr_t addr, uint32_t value)
+static void PPC_XCSR_writew (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
     value = bswap16(value);
@@ -190,7 +190,7 @@
     printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
 }
 
-static void PPC_XCSR_writel (target_phys_addr_t addr, uint32_t value)
+static void PPC_XCSR_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
     value = bswap32(value);
@@ -198,7 +198,7 @@
     printf("%s: 0x%08lx => 0x%08x\n", __func__, (long)addr, value);
 }
 
-static uint32_t PPC_XCSR_readb (target_phys_addr_t addr)
+static uint32_t PPC_XCSR_readb (void *opaque, target_phys_addr_t addr)
 {
     uint32_t retval = 0;
 
@@ -207,7 +207,7 @@
     return retval;
 }
 
-static uint32_t PPC_XCSR_readw (target_phys_addr_t addr)
+static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
 {
     uint32_t retval = 0;
 
@@ -219,7 +219,7 @@
     return retval;
 }
 
-static uint32_t PPC_XCSR_readl (target_phys_addr_t addr)
+static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr)
 {
     uint32_t retval = 0;
 
@@ -480,7 +480,7 @@
     isa_mem_base = 0xc0000000;
     pci_prep_init();
     /* Register 64 KB of ISA IO space */
-    PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write);
+    PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write, NULL);
     cpu_register_physical_memory(0x80000000, 0x00010000, PPC_io_memory);
 
     /* init basic PC hardware */
@@ -525,10 +525,10 @@
     register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);
     /* PCI intack location */
     PPC_io_memory = cpu_register_io_memory(0, PPC_intack_read,
-                                           PPC_intack_write);
+                                           PPC_intack_write, NULL);
     cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
     /* PowerPC control and status register group */
-    PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write);
+    PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write, NULL);
     cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
 
     nvram = m48t59_init(8, 0x0074, NVRAM_SIZE);
diff --git a/hw/vga.c b/hw/vga.c
index 30dead0..8d8ad9b 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -656,9 +656,9 @@
 #endif
 
 /* called for accesses between 0xa0000 and 0xc0000 */
-static uint32_t vga_mem_readb(target_phys_addr_t addr)
+static uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
 {
-    VGAState *s = &vga_state;
+    VGAState *s = opaque;
     int memory_map_mode, plane;
     uint32_t ret;
     
@@ -712,40 +712,40 @@
     return ret;
 }
 
-static uint32_t vga_mem_readw(target_phys_addr_t addr)
+static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr)
 {
     uint32_t v;
 #ifdef TARGET_WORDS_BIGENDIAN
-    v = vga_mem_readb(addr) << 8;
-    v |= vga_mem_readb(addr + 1);
+    v = vga_mem_readb(opaque, addr) << 8;
+    v |= vga_mem_readb(opaque, addr + 1);
 #else
-    v = vga_mem_readb(addr);
-    v |= vga_mem_readb(addr + 1) << 8;
+    v = vga_mem_readb(opaque, addr);
+    v |= vga_mem_readb(opaque, addr + 1) << 8;
 #endif
     return v;
 }
 
-static uint32_t vga_mem_readl(target_phys_addr_t addr)
+static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr)
 {
     uint32_t v;
 #ifdef TARGET_WORDS_BIGENDIAN
-    v = vga_mem_readb(addr) << 24;
-    v |= vga_mem_readb(addr + 1) << 16;
-    v |= vga_mem_readb(addr + 2) << 8;
-    v |= vga_mem_readb(addr + 3);
+    v = vga_mem_readb(opaque, addr) << 24;
+    v |= vga_mem_readb(opaque, addr + 1) << 16;
+    v |= vga_mem_readb(opaque, addr + 2) << 8;
+    v |= vga_mem_readb(opaque, addr + 3);
 #else
-    v = vga_mem_readb(addr);
-    v |= vga_mem_readb(addr + 1) << 8;
-    v |= vga_mem_readb(addr + 2) << 16;
-    v |= vga_mem_readb(addr + 3) << 24;
+    v = vga_mem_readb(opaque, addr);
+    v |= vga_mem_readb(opaque, addr + 1) << 8;
+    v |= vga_mem_readb(opaque, addr + 2) << 16;
+    v |= vga_mem_readb(opaque, addr + 3) << 24;
 #endif
     return v;
 }
 
 /* called for accesses between 0xa0000 and 0xc0000 */
-static void vga_mem_writeb(target_phys_addr_t addr, uint32_t val)
+static void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
-    VGAState *s = &vga_state;
+    VGAState *s = opaque;
     int memory_map_mode, plane, write_mode, b, func_select;
     uint32_t write_mask, bit_mask, set_mask;
 
@@ -871,29 +871,29 @@
     }
 }
 
-static void vga_mem_writew(target_phys_addr_t addr, uint32_t val)
+static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
-    vga_mem_writeb(addr, (val >> 8) & 0xff);
-    vga_mem_writeb(addr + 1, val & 0xff);
+    vga_mem_writeb(opaque, addr, (val >> 8) & 0xff);
+    vga_mem_writeb(opaque, addr + 1, val & 0xff);
 #else
-    vga_mem_writeb(addr, val & 0xff);
-    vga_mem_writeb(addr + 1, (val >> 8) & 0xff);
+    vga_mem_writeb(opaque, addr, val & 0xff);
+    vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
 #endif
 }
 
-static void vga_mem_writel(target_phys_addr_t addr, uint32_t val)
+static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
-    vga_mem_writeb(addr, (val >> 24) & 0xff);
-    vga_mem_writeb(addr + 1, (val >> 16) & 0xff);
-    vga_mem_writeb(addr + 2, (val >> 8) & 0xff);
-    vga_mem_writeb(addr + 3, val & 0xff);
+    vga_mem_writeb(opaque, addr, (val >> 24) & 0xff);
+    vga_mem_writeb(opaque, addr + 1, (val >> 16) & 0xff);
+    vga_mem_writeb(opaque, addr + 2, (val >> 8) & 0xff);
+    vga_mem_writeb(opaque, addr + 3, val & 0xff);
 #else
-    vga_mem_writeb(addr, val & 0xff);
-    vga_mem_writeb(addr + 1, (val >> 8) & 0xff);
-    vga_mem_writeb(addr + 2, (val >> 16) & 0xff);
-    vga_mem_writeb(addr + 3, (val >> 24) & 0xff);
+    vga_mem_writeb(opaque, addr, val & 0xff);
+    vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff);
+    vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff);
+    vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff);
 #endif
 }
 
@@ -1826,7 +1826,7 @@
 #endif
 #endif /* CONFIG_BOCHS_VBE */
 
-    vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write);
+    vga_io_memory = cpu_register_io_memory(0, vga_mem_read, vga_mem_write, s);
     cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, 
                                  vga_io_memory);
 
diff --git a/softmmu_template.h b/softmmu_template.h
index 413c599..73fdbec 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -55,14 +55,14 @@
 
     index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
 #if SHIFT <= 2
-    res = io_mem_read[index][SHIFT](physaddr);
+    res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr);
 #else
 #ifdef TARGET_WORDS_BIGENDIAN
-    res = (uint64_t)io_mem_read[index][2](physaddr) << 32;
-    res |= io_mem_read[index][2](physaddr + 4);
+    res = (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr) << 32;
+    res |= io_mem_read[index][2](io_mem_opaque[index], physaddr + 4);
 #else
-    res = io_mem_read[index][2](physaddr);
-    res |= (uint64_t)io_mem_read[index][2](physaddr + 4) << 32;
+    res = io_mem_read[index][2](io_mem_opaque[index], physaddr);
+    res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
 #endif
 #endif /* SHIFT > 2 */
     return res;
@@ -79,14 +79,14 @@
     env->mem_write_vaddr = tlb_addr;
     env->mem_write_pc = (unsigned long)retaddr;
 #if SHIFT <= 2
-    io_mem_write[index][SHIFT](physaddr, val);
+    io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val);
 #else
 #ifdef TARGET_WORDS_BIGENDIAN
-    io_mem_write[index][2](physaddr, val >> 32);
-    io_mem_write[index][2](physaddr + 4, val);
+    io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32);
+    io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val);
 #else
-    io_mem_write[index][2](physaddr, val);
-    io_mem_write[index][2](physaddr + 4, val >> 32);
+    io_mem_write[index][2](io_mem_opaque[index], physaddr, val);
+    io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
 #endif
 #endif /* SHIFT > 2 */
 }