- A general remark : instead of using SPARC_IOMMU_TRANSLATE, you should use new memory helpers to read or write bytes such as pcnet_physical_memory_read() and pcnet_physical_memory_write(). The rationale is that ultimately pci memory accesses will also use PCI specific I/Os to handle the case where the PCI memory is not mapped directly in the CPU address space. For the sparc iommu you should define global helpers such as sparc_iommu_memory_read() and sparc_iommu_memory_write().

Something like this?

_________________________________________________________________
FREE pop-up blocking with the new MSN Toolbar - get it now! http://toolbar.msn.click-url.com/go/onm00200415ave/direct/01/
Index: qemu/hw/iommu.c
===================================================================
--- qemu.orig/hw/iommu.c        2006-08-24 18:53:19.000000000 +0000
+++ qemu/hw/iommu.c     2006-08-24 19:23:59.000000000 +0000
@@ -186,21 +186,56 @@
    iommu_mem_writew,
};

-uint32_t iommu_translate_local(void *opaque, uint32_t addr)
+static uint32_t iommu_page_get_flags(void *opaque, uint32_t addr)
{
    IOMMUState *s = opaque;
-    uint32_t iopte, pa, tmppte;
+    uint32_t iopte;

    iopte = s->regs[1] << 4;
    addr &= ~s->iostart;
    iopte += (addr >> (PAGE_SHIFT - 2)) & ~3;
-    pa = ldl_phys(iopte);
+    return ldl_phys(iopte);
+}
+
+uint32_t iommu_translate_local(void *opaque, uint32_t addr)
+{
+    uint32_t pa, tmppte;
+
+    pa = iommu_page_get_flags(opaque, addr);
    tmppte = pa;
    pa = ((pa & IOPTE_PAGE) << 4) + (addr & PAGE_MASK);
DPRINTF("xlate dva %x => pa %x (iopte[%x] = %x)\n", addr, pa, iopte, tmppte);
    return pa;
}

+void sparc_iommu_memory_rw_local(void *opaque, target_phys_addr_t addr,
+                                 uint8_t *buf, int len, int is_write)
+{
+    int l, flags;
+    target_ulong page;
+    void * p;
+
+    while (len > 0) {
+        page = addr & TARGET_PAGE_MASK;
+        l = (page + TARGET_PAGE_SIZE) - addr;
+        if (l > len)
+            l = len;
+        flags = iommu_page_get_flags(opaque, page);
+        if (!(flags & IOPTE_VALID))
+            return;
+        if (is_write) {
+            if (!(flags & IOPTE_WRITE))
+                return;
+            cpu_physical_memory_write(addr, buf, len);
+        } else {
+            cpu_physical_memory_read(buf, addr, len);
+        }
+        len -= l;
+        buf += l;
+        addr += l;
+    }
+}
+
static void iommu_save(QEMUFile *f, void *opaque)
{
    IOMMUState *s = opaque;
Index: qemu/hw/sun4m.c
===================================================================
--- qemu.orig/hw/sun4m.c        2006-08-24 19:17:45.000000000 +0000
+++ qemu/hw/sun4m.c     2006-08-24 19:18:51.000000000 +0000
@@ -199,12 +199,17 @@
    return iommu_translate_local(iommu, addr);
}

-void sparc_iommu_memory_rw(target_phys_addr_t addr,
-                           uint8_t *buf, int len, int is_write)
+void sparc_iommu_memory_read(target_phys_addr_t addr,
+                           uint8_t *buf, int len)
{
-    return sparc_iommu_memory_rwl(iommu, addr, buf, len, is_write);
+    return sparc_iommu_memory_rw_local(iommu, addr, buf, len, 0);
}

+void sparc_iommu_memory_write(target_phys_addr_t addr,
+                           uint8_t *buf, int len)
+{
+    return sparc_iommu_memory_rw_local(iommu, addr, buf, len, 1);
+}

static void *slavio_misc;

Index: qemu/vl.h
===================================================================
--- qemu.orig/vl.h      2006-08-24 19:17:55.000000000 +0000
+++ qemu/vl.h   2006-08-24 19:19:59.000000000 +0000
@@ -1027,10 +1027,16 @@
extern QEMUMachine sun4m_machine;
uint32_t iommu_translate(uint32_t addr);
void pic_set_irq_cpu(int irq, int level, unsigned int cpu);
+void sparc_iommu_memory_read(target_phys_addr_t addr,
+                             uint8_t *buf, int len);
+void sparc_iommu_memory_write(target_phys_addr_t addr,
+                              uint8_t *buf, int len);

/* iommu.c */
void *iommu_init(uint32_t addr);
uint32_t iommu_translate_local(void *opaque, uint32_t addr);
+void sparc_iommu_memory_rw_local(void *opaque, target_phys_addr_t addr,
+                                 uint8_t *buf, int len, int is_write);

/* lance.c */
void lance_init(NICInfo *nd, int irq, uint32_t leaddr, uint32_t ledaddr);

_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel

Reply via email to