aboutsummaryrefslogtreecommitdiff
path: root/hw/iommu.c
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2006-08-29 04:52:16 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2006-08-29 04:52:16 +0000
commita917d384ac0d09cd68266a6f2ca5c94212c8f81e (patch)
treef54b8fb2880361c0bf09087c3e382fc562193516 /hw/iommu.c
parent508d92d0573319d7dbd827f6216aec44c1421832 (diff)
downloadqemu-a917d384ac0d09cd68266a6f2ca5c94212c8f81e.zip
qemu-a917d384ac0d09cd68266a6f2ca5c94212c8f81e.tar.gz
qemu-a917d384ac0d09cd68266a6f2ca5c94212c8f81e.tar.bz2
SCSI TCQ support.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2139 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/iommu.c')
-rw-r--r--hw/iommu.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/hw/iommu.c b/hw/iommu.c
index e7d96c8..83001bd 100644
--- a/hw/iommu.c
+++ b/hw/iommu.c
@@ -186,21 +186,62 @@ static CPUWriteMemoryFunc *iommu_mem_write[3] = {
iommu_mem_writew,
};
-uint32_t iommu_translate_local(void *opaque, uint32_t addr)
+static uint32_t iommu_page_get_flags(IOMMUState *s, 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);
+}
+
+static uint32_t iommu_translate_pa(IOMMUState *s, uint32_t addr, uint32_t pa)
+{
+ uint32_t tmppte;
+
tmppte = pa;
pa = ((pa & IOPTE_PAGE) << 4) + (addr & PAGE_MASK);
- DPRINTF("xlate dva %x => pa %x (iopte[%x] = %x)\n", addr, pa, iopte, tmppte);
+ DPRINTF("xlate dva %x => pa %x (iopte = %x)\n", addr, pa, tmppte);
return pa;
}
+uint32_t iommu_translate_local(void *opaque, uint32_t addr)
+{
+ uint32_t flags;
+ flags = iommu_page_get_flags(opaque, addr);
+ return iommu_translate_pa(opaque, addr, flags);
+}
+
+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, phys_addr;
+ 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;
+ phys_addr = iommu_translate_pa(opaque, addr, flags);
+ if (is_write) {
+ if (!(flags & IOPTE_WRITE))
+ return;
+ cpu_physical_memory_write(phys_addr, buf, len);
+ } else {
+ cpu_physical_memory_read(phys_addr, buf, len);
+ }
+ len -= l;
+ buf += l;
+ addr += l;
+ }
+}
+
static void iommu_save(QEMUFile *f, void *opaque)
{
IOMMUState *s = opaque;