[OpenBIOS] [PATCH 03/15] SPARC32: allocate contiguous physical memory for DVMA

Mark Cave-Ayland mark.cave-ayland at ilande.co.uk
Mon May 21 23:33:10 CEST 2018


Currently we dynamically allocate physical memory for DVMA as required, however
that makes mapping between IOVA and physical addresses almost impossible since the
resulting regions are not contiguous.

Resolve this by allocating a contiguous physical memory block that we can use to
easily map between IOVA and physical addresses.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
 drivers/iommu.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu.c b/drivers/iommu.c
index be486c0..0bf742f 100644
--- a/drivers/iommu.c
+++ b/drivers/iommu.c
@@ -25,6 +25,7 @@ struct iommu {
     struct iommu_regs *regs;
     unsigned int *page_table;
     unsigned long plow;     /* Base bus address */
+    unsigned long pphys;    /* Base phys address */
 };
 
 static struct iommu ciommu;
@@ -51,18 +52,14 @@ dvma_alloc(int size, unsigned int *pphys)
     unsigned int i;
     unsigned int *iopte;
     struct iommu *t = &ciommu;
-    int ret;
 
     npages = (size + (PAGE_SIZE-1)) / PAGE_SIZE;
-    ret = ofmem_posix_memalign(&va, npages * PAGE_SIZE, PAGE_SIZE);
-    if (ret != 0)
-        return NULL;
-
     iova = (unsigned int)mem_alloc(&cdvmem, npages * PAGE_SIZE, PAGE_SIZE);
     if (iova == 0)
         return NULL;
 
-    pa = (unsigned int)va2pa((unsigned long)va);
+    pa = t->pphys + (iova - t->plow);
+    va = (void *)pa2va((unsigned long)pa);
 
     /*
      * Change page attributes in MMU to uncached.
@@ -86,6 +83,8 @@ dvma_alloc(int size, unsigned int *pphys)
     return va;
 }
 
+#define DVMA_SIZE 0x4000
+
 /*
  * Initialize IOMMU
  * This looks like initialization of CPU MMU but
@@ -94,7 +93,7 @@ dvma_alloc(int size, unsigned int *pphys)
 static struct iommu_regs *
 iommu_init(struct iommu *t, uint64_t base)
 {
-    unsigned int *ptab;
+    unsigned int *ptab, pva;
     int ptsize;
 #ifdef CONFIG_DEBUG_IOMMU
     unsigned int impl, vers;
@@ -145,7 +144,13 @@ iommu_init(struct iommu *t, uint64_t base)
     DPRINTF("IOMMU: impl %d vers %d page table at 0x%p (pa 0x%x) of size %d bytes\n",
             impl, vers, t->page_table, tmp, ptsize);
 
-    mem_init(&cdvmem, (char*)t->plow, (char *)0xfffff000);
+    mem_init(&cdvmem, (char*)t->plow, (char *)(t->plow + DVMA_SIZE));
+    ret = ofmem_posix_memalign((void *)&pva, DVMA_SIZE, PAGE_SIZE);
+    if (ret != 0) {
+        DPRINTF("Cannot allocate IOMMU phys size [0x%x]\n", DVMA_SIZE);
+        for (;;) { }
+    }
+    t->pphys = va2pa(pva);
     return regs;
 }
 
-- 
2.11.0




More information about the OpenBIOS mailing list