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

svn at openbios.org svn at openbios.org
Wed Jul 16 13:47:23 CEST 2008


Author: blueswirl
Date: 2008-07-16 13:47:23 +0200 (Wed, 16 Jul 2008)
New Revision: 202

Modified:
   openbios-devel/arch/sparc64/init.fs
   openbios-devel/arch/sparc64/openbios.c
Log:
Add MMU node and ops

Modified: openbios-devel/arch/sparc64/init.fs
===================================================================
--- openbios-devel/arch/sparc64/init.fs	2008-07-15 15:04:02 UTC (rev 201)
+++ openbios-devel/arch/sparc64/init.fs	2008-07-16 11:47:23 UTC (rev 202)
@@ -32,7 +32,6 @@
 \ preopen device nodes (and store the ihandles under /chosen)
 :noname
   " memory" " /memory" preopen
-  " mmu" " /cpus/@0" preopen
 
 ; SYSTEM-initializer
 

Modified: openbios-devel/arch/sparc64/openbios.c
===================================================================
--- openbios-devel/arch/sparc64/openbios.c	2008-07-15 15:04:02 UTC (rev 201)
+++ openbios-devel/arch/sparc64/openbios.c	2008-07-16 11:47:23 UTC (rev 202)
@@ -21,7 +21,22 @@
 #include "openbios/firmware_abi.h"
 #include "boot.h"
 #include "../../drivers/timer.h" // XXX
+#include "asi.h"
+#include "libc/vsprintf.h"
 
+#define REGISTER_NAMED_NODE( name, path )   do {                        \
+        bind_new_node( name##_flags_, name##_size_,                     \
+                       path, name##_m, sizeof(name##_m)/sizeof(method_t)); \
+    } while(0)
+
+#define REGISTER_NODE_METHODS( name, path )   do {                      \
+        const char *paths[1];                                           \
+                                                                        \
+        paths[0] = path;                                                \
+        bind_node( name##_flags_, name##_size_,                         \
+                   paths, 1, name##_m, sizeof(name##_m)/sizeof(method_t)); \
+    } while(0)
+
 static unsigned char intdict[256 * 1024];
 
 // XXX
@@ -42,9 +57,132 @@
     const char *name;
 };
 
+static void
+mmu_open(void)
+{
+    RET(-1);
+}
+
+static void
+mmu_close(void)
+{
+}
+
+/*
+  3.6.5 translate
+  ( virt -- false | phys.lo ... phys.hi mode true )
+*/
+static void
+mmu_translate(void)
+{
+    unsigned long virt, phys;
+
+    virt = POP();
+
+    asm("ldxa [%1] %2, %0\n"
+        : "=r"(phys) : "r" (virt), "i" (ASI_DTLB_TAG_READ));
+
+    if (phys & 0x8000000000000000) { // Valid entry?
+        PUSH(phys >> 32);
+        PUSH(phys & 0xffffffff);
+        PUSH(0); // XXX
+        PUSH(-1);
+    } else {
+        PUSH(0);
+    }
+}
+
+/*
+  ( index tte_data vaddr -- ? )
+*/
+static void
+dtlb_load(void)
+{
+    unsigned long vaddr, tte_data, idx;
+
+    vaddr = POP();
+    tte_data = POP();
+    idx = POP();
+
+    asm("stxa %0, [%1] %2\n"
+        "stxa %3, [%%g0] %4\n"
+        : : "r" (vaddr), "r" (48), "i" (ASI_DMMU),
+          "r" (tte_data), "i" (ASI_DTLB_DATA_IN));
+}
+
+/*
+  ( index tte_data vaddr -- ? )
+*/
+static void
+itlb_load(void)
+{
+    unsigned long vaddr, tte_data, idx;
+
+    vaddr = POP();
+    tte_data = POP();
+    idx = POP();
+
+    asm("stxa %0, [%1] %2\n"
+        "stxa %3, [%%g0] %4\n"
+        : : "r" (vaddr), "r" (48), "i" (ASI_IMMU),
+          "r" (tte_data), "i" (ASI_ITLB_DATA_IN));
+}
+
+/*
+  3.6.5 map
+  ( phys.lo ... phys.hi virt size mode -- )
+*/
+static void
+mmu_map(void)
+{
+    unsigned long virt, size, mode, phys, tte_data;
+
+    mode = POP();
+    size = POP();
+    virt = POP();
+    phys = POP();
+    phys <<= 32;
+    phys |= POP();
+
+    tte_data = phys | 0x36;
+    switch (size) {
+    case 8192:
+        break;
+    case 65536:
+        tte_data |= 2ULL << 60;
+        break;
+    case 512 * 1024:
+        tte_data |= 4ULL << 60;
+        break;
+    case 4 * 1024 * 1024:
+        tte_data |= 6ULL << 60;
+        break;
+    }
+    asm("stxa %0, [%1] %2\n"
+        "stxa %3, [%%g0] %4\n"
+        : : "r" (virt), "r" (48), "i" (ASI_DMMU),
+          "r" (tte_data), "i" (ASI_DTLB_DATA_IN));
+    asm("stxa %0, [%1] %2\n"
+        "stxa %3, [%%g0] %4\n"
+        : : "r" (virt), "r" (48), "i" (ASI_DMMU),
+          "r" (tte_data), "i" (ASI_DTLB_DATA_IN));
+}
+
+DECLARE_UNNAMED_NODE(mmu, INSTALL_OPEN, 0);
+
+NODE_METHODS(mmu) = {
+    { "open",               mmu_open              },
+    { "close",              mmu_close             },
+    { "translate",          mmu_translate         },
+    { "SUNW,dtlb-load",     dtlb_load             },
+    { "SUNW,itlb-load",     itlb_load             },
+    { "map",                mmu_map               },
+};
+
 static void cpu_generic_init(const struct cpudef *cpu)
 {
     unsigned long iu_version;
+    char nodebuff[256];
 
     push_str("/");
     fword("find-device");
@@ -81,6 +219,31 @@
     fword("property");
 
     fword("finish-device");
+
+    // MMU node
+    sprintf(nodebuff, "/%s", cpu->name);
+    push_str(nodebuff);
+    fword("find-device");
+
+    fword("new-device");
+
+    push_str("mmu");
+    fword("device-name");
+
+    fword("finish-device");
+
+    sprintf(nodebuff, "/%s/mmu", cpu->name);
+
+    REGISTER_NODE_METHODS(mmu, nodebuff);
+
+    push_str("/chosen");
+    fword("find-device");
+
+    push_str(nodebuff);
+    fword("open-dev");
+    fword("encode-int");
+    push_str("mmu");
+    fword("property");
 }
 
 static const struct cpudef sparc_defs[] = {




More information about the OpenBIOS mailing list