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[] = {