[OpenBIOS] r238 - openbios-devel/arch/sparc64

svn at openbios.org svn at openbios.org
Sat Sep 27 21:45:19 CEST 2008


Author: blueswirl
Date: 2008-09-27 21:45:19 +0200 (Sat, 27 Sep 2008)
New Revision: 238

Modified:
   openbios-devel/arch/sparc64/openbios.c
Log:
Add mmu translate and unmap methods (Igor Kovalenko)

Modified: openbios-devel/arch/sparc64/openbios.c
===================================================================
--- openbios-devel/arch/sparc64/openbios.c	2008-09-18 18:41:26 UTC (rev 237)
+++ openbios-devel/arch/sparc64/openbios.c	2008-09-27 19:45:19 UTC (rev 238)
@@ -85,18 +85,13 @@
 {
 }
 
-/*
-  3.6.5 translate
-  ( virt -- false | phys.lo ... phys.hi mode true )
-*/
-static void
-mmu_translate(void)
+static int
+spitfire_translate(unsigned long virt, unsigned long *p_phys,
+                   unsigned long *p_data, unsigned long *p_size)
 {
-    unsigned long virt, phys, tag, data, mask;
+    unsigned long phys, tag, data, mask, size;
     unsigned int i;
 
-    virt = POP();
-
     for (i = 0; i < 64; i++) {
         data = spitfire_get_dtlb_data(i);
         if (data & 0x8000000000000000) { // Valid entry?
@@ -104,29 +99,54 @@
             default:
             case 0x0: // 8k
                 mask = 0xffffffffffffe000ULL;
+                size = PAGE_SIZE_8K;
                 break;
             case 0x1: // 64k
                 mask = 0xffffffffffff0000ULL;
+                size = PAGE_SIZE_64K;
                 break;
             case 0x2: // 512k
                 mask = 0xfffffffffff80000ULL;
+                size = PAGE_SIZE_512K;
                 break;
             case 0x3: // 4M
                 mask = 0xffffffffffc00000ULL;
+                size = PAGE_SIZE_4M;
                 break;
             }
             tag = spitfire_get_dtlb_tag(i);
             if ((virt & mask) == (tag & mask)) {
                 phys = data & mask & 0x000001fffffff000;
                 phys |= virt & ~mask;
-                PUSH(phys & 0xffffffff);
-                PUSH(phys >> 32);
-                PUSH(data & 0xfff);
-                PUSH(-1);
-                return;
+                *p_phys = phys;
+                *p_data = data & 0xfff;
+                *p_size = size;
+                return -1;
             }
         }
     }
+
+    return 0;
+}
+
+/*
+  3.6.5 translate
+  ( virt -- false | phys.lo ... phys.hi mode true )
+*/
+static void
+mmu_translate(void)
+{
+    unsigned long virt, phys, data, size;
+
+    virt = POP();
+
+    if (spitfire_translate(virt, &phys, &data, &size)) {
+        PUSH(phys & 0xffffffff);
+        PUSH(phys >> 32);
+        PUSH(data);
+        PUSH(-1);
+        return;
+    }
     PUSH(0);
 }
 
@@ -250,6 +270,40 @@
     map_pages(virt, size, phys);
 }
 
+static void
+itlb_demap(unsigned long vaddr)
+{
+    asm("stxa %0, [%0] %1\n"
+        : : "r" (vaddr), "i" (ASI_IMMU_DEMAP));
+}
+
+static void
+dtlb_demap(unsigned long vaddr)
+{
+    asm("stxa %0, [%0] %1\n"
+        : : "r" (vaddr), "i" (ASI_DMMU_DEMAP));
+}
+
+static void
+unmap_pages(unsigned long virt, unsigned long size)
+{
+    unsigned long phys, data;
+
+    unsigned long tte_data, currsize;
+
+    // align size
+    size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K;
+
+    while (spitfire_translate(virt, &phys, &data, &currsize)) {
+
+        itlb_demap(virt & ~0x1fffULL);
+        dtlb_demap(virt & ~0x1fffULL);
+
+        size -= currsize;
+        virt += currsize;
+    }
+}
+
 /*
   3.6.5 unmap
   ( virt size -- )
@@ -261,7 +315,7 @@
 
     size = POP();
     virt = POP();
-    //unmap_pages(virt, size);
+    unmap_pages(virt, size);
 }
 
 /*




More information about the OpenBIOS mailing list