- 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