[OpenBIOS] r517 - trunk/openbios-devel/arch/sparc64

svn at openbios.org svn at openbios.org
Fri Jul 31 13:16:24 CEST 2009


Author: blueswirl
Date: 2009-07-31 13:16:24 +0200 (Fri, 31 Jul 2009)
New Revision: 517

Modified:
   trunk/openbios-devel/arch/sparc64/lib.c
   trunk/openbios-devel/arch/sparc64/openbios.c
   trunk/openbios-devel/arch/sparc64/tree.fs
   trunk/openbios-devel/arch/sparc64/vectors.S
Log:
Switch sparc64 to ofmem (Igor Kovalenko)

Initialize ofmem at startup.
Switch malloc/realloc/free to use ofmem.
Implement runtime migration of startup mappings to ofmem.
Implement mmu miss handlers to install tlb entries based on ofmem
translations list.


Modified: trunk/openbios-devel/arch/sparc64/lib.c
===================================================================
--- trunk/openbios-devel/arch/sparc64/lib.c	2009-07-31 11:15:30 UTC (rev 516)
+++ trunk/openbios-devel/arch/sparc64/lib.c	2009-07-31 11:16:24 UTC (rev 517)
@@ -34,32 +34,19 @@
 	return i;
 }
 
-#define MEMSIZE ((128 + 256 + 512) * 1024)
-static char memory[MEMSIZE];
-static void *memptr=memory;
-static int memsize=MEMSIZE;
-
-
 void *malloc(int size)
 {
-	void *ret=(void *)0;
+	return ofmem_malloc(size);
+}
 
-	if( !size )
-		return NULL;
-
-        size = (size + 7) & ~7;
-
-	if(memsize>=size) {
-		memsize-=size;
-		ret=memptr;
-		memptr = (void *)((unsigned long)memptr + size);
-	}
-	return ret;
+void* realloc( void *ptr, size_t size )
+{
+	return ofmem_realloc(ptr, size);
 }
 
 void free(void *ptr)
 {
-	/* Nothing yet */
+	ofmem_free(ptr);
 }
 
 #define PAGE_SIZE_4M   (4 * 1024 * 1024)
@@ -84,50 +71,44 @@
 
 void ofmem_walk_boot_map(translation_entry_cb cb)
 {
-}
-
-static int
-spitfire_translate(unsigned long virt, unsigned long *p_phys,
-                   unsigned long *p_data, unsigned long *p_size)
-{
-    unsigned long phys, tag, data, mask, size;
+    unsigned long phys, virt, size, mode, data, mask;
     unsigned int i;
 
     for (i = 0; i < 64; i++) {
         data = spitfire_get_dtlb_data(i);
-        if (data & 0x8000000000000000ULL) { // Valid entry?
+        if (data & SPITFIRE_TTE_VALID) {
             switch ((data >> 61) & 3) {
             default:
-            case 0x0: // 8k
+            case 0x0: /* 8k */
                 mask = 0xffffffffffffe000ULL;
                 size = PAGE_SIZE_8K;
                 break;
-            case 0x1: // 64k
+            case 0x1: /* 64k */
                 mask = 0xffffffffffff0000ULL;
                 size = PAGE_SIZE_64K;
                 break;
-            case 0x2: // 512k
+            case 0x2: /* 512k */
                 mask = 0xfffffffffff80000ULL;
                 size = PAGE_SIZE_512K;
                 break;
-            case 0x3: // 4M
+            case 0x3: /* 4M */
                 mask = 0xffffffffffc00000ULL;
                 size = PAGE_SIZE_4M;
                 break;
             }
-            tag = spitfire_get_dtlb_tag(i);
-            if ((virt & mask) == (tag & mask)) {
-                phys = data & mask & 0x000001fffffff000ULL;
-                phys |= virt & ~mask;
-                *p_phys = phys;
-                *p_data = data & 0xfff;
-                *p_size = size;
-                return -1;
-            }
+
+            virt = spitfire_get_dtlb_tag(i);
+            virt &= mask;
+
+            /* extract 41bit physical address */
+            phys = data & 0x000001fffffff000ULL;
+			phys &= mask;
+
+			mode = data & 0xfff;
+
+			cb(phys, virt, size, mode);
         }
     }
-
-    return 0;
 }
 
 /*
@@ -137,18 +118,21 @@
 static void
 mmu_translate(void)
 {
-    unsigned long virt, phys, data, size;
+    ucell virt, phys, mode;
 
     virt = POP();
 
-    if (spitfire_translate(virt, &phys, &data, &size)) {
-        PUSH(phys & 0xffffffff);
-        PUSH(phys >> 32);
-        PUSH(data);
-        PUSH(-1);
-        return;
+    phys = ofmem_translate(virt, &mode);
+
+    if (phys != -1UL) {
+		PUSH(phys & 0xffffffff);
+		PUSH(phys >> 32);
+		PUSH(mode);
+		PUSH(-1);
     }
-    PUSH(0);
+    else {
+    	PUSH(0);
+    }
 }
 
 static void
@@ -218,13 +202,15 @@
 }
 
 static void
-map_pages(unsigned long virt, unsigned long size, unsigned long phys,
-		unsigned long mode)
+map_pages(unsigned long phys, unsigned long virt,
+		  unsigned long size, unsigned long mode)
 {
-    unsigned long tte_data, currsize;
+	unsigned long tte_data, currsize;
 
-    size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K;
-    while (size >= PAGE_SIZE_8K) {
+	/* aligned to 8k page */
+	size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K;
+
+	while (size > 0) {
         currsize = size;
         if (currsize >= PAGE_SIZE_4M &&
             (virt & PAGE_MASK_4M) == 0 &&
@@ -248,8 +234,9 @@
 
         tte_data |= phys | mode | SPITFIRE_TTE_VALID;
 
-        dtlb_load2(virt, tte_data);
         itlb_load2(virt, tte_data);
+        dtlb_load2(virt, tte_data);
+
         size -= currsize;
         phys += currsize;
         virt += currsize;
@@ -268,7 +255,7 @@
 static void
 mmu_map(void)
 {
-    unsigned long virt, size, mode, phys;
+    ucell virt, size, mode, phys;
 
     mode = POP();
     size = POP();
@@ -276,7 +263,8 @@
     phys = POP();
     phys <<= 32;
     phys |= POP();
-    map_pages(virt, size, phys, mode);
+
+    ofmem_map(phys, virt, size, mode);
 }
 
 static void
@@ -294,22 +282,19 @@
 }
 
 static void
-unmap_pages(unsigned long virt, unsigned long size)
+unmap_pages(ucell virt, ucell size)
 {
-    unsigned long phys, data;
+	ucell va;
 
-    unsigned long currsize;
+    /* align address to 8k */
+    virt &= ~PAGE_MASK_8K;
 
-    // align size
+    /* align size to 8k */
     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;
+    for (va = virt; va < virt + size; va += PAGE_SIZE_8K) {
+        itlb_demap(va);
+        dtlb_demap(va);
     }
 }
 
@@ -325,11 +310,11 @@
 static void
 mmu_unmap(void)
 {
-    unsigned long virt, size;
+    ucell virt, size;
 
     size = POP();
     virt = POP();
-    unmap_pages(virt, size);
+    ofmem_unmap(virt, size);
 }
 
 /*
@@ -339,13 +324,23 @@
 static void
 mmu_claim(void)
 {
-    unsigned long virt, size, align;
+    ucell virt=-1UL, size, align;
 
     align = POP();
     size = POP();
-    virt = POP();
-    printk("claim virt = %lx size = %lx align = %lx\n", virt, size, align);
-    PUSH(virt); // XXX
+    if (!align) {
+    	virt = POP();
+    }
+
+    printk("claim virt=" FMT_ucellx " size=" FMT_ucellx " align=" FMT_ucellx
+    		"\n",
+    		virt, size, align);
+
+    virt = ofmem_claim_virt(virt, size, align);
+
+    printk("claimed virt=" FMT_ucellx "\n", virt);
+
+    PUSH(virt);
 }
 
 /*
@@ -355,14 +350,63 @@
 static void
 mmu_release(void)
 {
-    unsigned long virt, size;
+    ucell virt, size;
 
     size = POP();
     virt = POP();
-    printk("release virt = %lx size = %lx\n", virt, size);
-    // XXX
+    printk("release virt=" FMT_ucellx " size=" FMT_ucellx "\n", virt, size);
+
+    ofmem_release(virt, size);
 }
 
+/* ( phys size align --- base ) */
+static void
+mem_claim( void )
+{
+    ucell phys=-1UL, size, align;
+
+    align = POP();
+    size = POP();
+    if (!align) {
+        phys = POP();
+        phys <<= 32;
+        phys |= POP();
+    }
+
+    printk("mem_claim phys=" FMT_ucellx " size=" FMT_ucellx
+    		" align=" FMT_ucellx "\n",
+    		phys, size, align);
+
+    phys = ofmem_claim_phys(phys, size, align);
+
+    printk("ofmem_claim_phys result phys=" FMT_ucellx "\n", phys);
+
+    ofmem_map(phys, phys, size, -1);
+
+    PUSH(phys >> 32);
+    PUSH(phys & 0xffffffffUL);
+}
+
+/* ( phys size --- ) */
+static void
+mem_release( void )
+{
+    ucell phys, size;
+
+    size = POP();
+    phys = POP();
+    printk("release virt=" FMT_ucellx " size=" FMT_ucellx "\n", phys, size);
+
+    ofmem_release(phys, size);
+}
+
+DECLARE_NODE(memory, INSTALL_OPEN, 0, "/memory");
+
+NODE_METHODS( memory ) = {
+    { "claim",              mem_claim       },
+    { "release",            mem_release     },
+};
+
 DECLARE_UNNAMED_NODE(mmu, INSTALL_OPEN, 0);
 
 NODE_METHODS(mmu) = {
@@ -381,7 +425,10 @@
 {
     char nodebuff[256];
 
-    // MMU node
+    /* memory node */
+    REGISTER_NODE_METHODS(memory, "/memory");
+
+    /* MMU node */
     snprintf(nodebuff, sizeof(nodebuff), "/%s", cpuname);
     push_str(nodebuff);
     fword("find-device");
@@ -397,6 +444,8 @@
 
     REGISTER_NODE_METHODS(mmu, nodebuff);
 
+    ofmem_register(find_dev("/memory"), find_dev("/virtual-memory"));
+
     push_str("/chosen");
     fword("find-device");
 
@@ -409,7 +458,7 @@
     push_str("/memory");
     fword("find-device");
 
-    // All memory: 0 to RAM_size
+    /* All memory: 0 to RAM_size */
     PUSH(0);
     fword("encode-int");
     PUSH(0);
@@ -424,108 +473,6 @@
     push_str("reg");
     fword("property");
 
-    // Available memory: 0 to va2pa(_start)
-    PUSH(0);
-    fword("encode-int");
-    PUSH(0);
-    fword("encode-int");
-    fword("encode+");
-    PUSH((va2pa((unsigned long)&_data) - 8192) >> 32);
-    fword("encode-int");
-    fword("encode+");
-    PUSH((va2pa((unsigned long)&_data) - 8192) & 0xffffffff);
-    fword("encode-int");
-    fword("encode+");
-    push_str("available");
-    fword("property");
-
-    // XXX
-    // Translations
-    push_str("/virtual-memory");
-    fword("find-device");
-
-    // 0 to 16M: 1:1
-    PUSH(0);
-    fword("encode-int");
-    PUSH(0);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(16 * 1024 * 1024);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0x80000000);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0x00000036);
-    fword("encode-int");
-    fword("encode+");
-
-    // _start to _data: ROM used
-    PUSH(0);
-    fword("encode-int");
-    fword("encode+");
-    PUSH((unsigned long)&_start);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0);
-    fword("encode-int");
-    fword("encode+");
-    PUSH((unsigned long)&_data - (unsigned long)&_start);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0x800001ff);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0xf0000074);
-    fword("encode-int");
-    fword("encode+");
-
-    // _data to _end: end of RAM
-    PUSH(0);
-    fword("encode-int");
-    fword("encode+");
-    PUSH((unsigned long)&_data);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0);
-    fword("encode-int");
-    fword("encode+");
-    PUSH((unsigned long)&_data - (unsigned long)&_start);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(((va2pa((unsigned long)&_data) - 8192) >> 32) | 0x80000000);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(((va2pa((unsigned long)&_data) - 8192) & 0xffffffff) | 0x36);
-    fword("encode-int");
-    fword("encode+");
-
-    // VGA buffer (128k): 1:1
-    PUSH(0x1ff);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0x004a0000);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(128 * 1024);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0x800001ff);
-    fword("encode-int");
-    fword("encode+");
-    PUSH(0x004a0076);
-    fword("encode-int");
-    fword("encode+");
-
-    push_str("translations");
-    fword("property");
-
     push_str("/openprom/client-services");
     fword("find-device");
     bind_func("claim", mmu_claim);

Modified: trunk/openbios-devel/arch/sparc64/openbios.c
===================================================================
--- trunk/openbios-devel/arch/sparc64/openbios.c	2009-07-31 11:15:30 UTC (rev 516)
+++ trunk/openbios-devel/arch/sparc64/openbios.c	2009-07-31 11:16:24 UTC (rev 517)
@@ -20,6 +20,7 @@
 #define NO_QEMU_PROTOS
 #include "openbios/fw_cfg.h"
 #include "video_subr.h"
+#include "ofmem.h"
 
 #define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
 
@@ -495,6 +496,8 @@
         printk("OpenBIOS for Sparc64\n");
 #endif
 
+        ofmem_init();
+
         collect_sys_info(&sys_info);
 
         dict = malloc(DICTIONARY_SIZE);

Modified: trunk/openbios-devel/arch/sparc64/tree.fs
===================================================================
--- trunk/openbios-devel/arch/sparc64/tree.fs	2009-07-31 11:15:30 UTC (rev 516)
+++ trunk/openbios-devel/arch/sparc64/tree.fs	2009-07-31 11:16:24 UTC (rev 517)
@@ -27,11 +27,12 @@
 
 new-device
   " memory" device-name
+  " memory" device-type
   external
   : open true ;
   : close ;
   \ claim ( phys size align -- base )
-  : claim 2drop ;
+\  : claim 2drop ;
   \ release ( phys size -- )
 finish-device
 
@@ -41,7 +42,7 @@
   : open true ;
   : close ;
   \ claim ( phys size align -- base )
-  : claim 2drop ;
+\  : claim 2drop ;
   \ release ( phys size -- )
 finish-device
 

Modified: trunk/openbios-devel/arch/sparc64/vectors.S
===================================================================
--- trunk/openbios-devel/arch/sparc64/vectors.S	2009-07-31 11:15:30 UTC (rev 516)
+++ trunk/openbios-devel/arch/sparc64/vectors.S	2009-07-31 11:16:24 UTC (rev 517)
@@ -101,6 +101,8 @@
                  ba bug; mov lvl, %g1; nop; nop; nop; nop; nop; nop;
 #define BTRAPTL1(lvl) BTRAP(lvl)
 #define BTRAPS(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3) BTRAP(x+4) BTRAP(x+5) BTRAP(x+6) BTRAP(x+7)
+#define BTRAPS4(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3)
+#define TRAP_HANDLER(routine) ba routine; nop; nop; nop; nop; nop; nop; nop;
 
 #define STACK_BIAS		2047
 	.globl	sparc64_ttable_tl0, sparc64_ttable_tl1
@@ -131,7 +133,16 @@
 		BTRAPS(0x40) BTRAPS(0x48)
 #endif
 		BTRAPS(0x50) BTRAPS(0x58)
-		BTRAPS(0x60) BTRAPS(0x68)
+		BTRAPS4(0x60)
+		TRAP_HANDLER(reload_IMMU_tlb)    ! 0x64 : instruction_access_MMU_miss
+		TRAP_HANDLER(reload_IMMU_tlb)    ! 0x65 : instruction_access_MMU_miss
+		TRAP_HANDLER(reload_IMMU_tlb)    ! 0x66 : instruction_access_MMU_miss
+		TRAP_HANDLER(reload_IMMU_tlb)    ! 0x67 : instruction_access_MMU_miss
+		TRAP_HANDLER(reload_DMMU_tlb)    ! 0x68 : data_access_MMU_miss
+		TRAP_HANDLER(reload_DMMU_tlb)    ! 0x69 : data_access_MMU_miss
+		TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6A : data_access_MMU_miss
+		TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6B : data_access_MMU_miss
+		BTRAPS4(0x6C)    ! data_access_protection
 		BTRAPS(0x70) BTRAPS(0x78)
 tl0_s0n:        SPILL_WINDOW
 tl0_s1n:        SPILL_WINDOW
@@ -206,7 +217,16 @@
 		BTRAPS(0x40) BTRAPS(0x48)
 #endif
 		BTRAPS(0x50) BTRAPS(0x58)
-		BTRAPS(0x60) BTRAPS(0x68)
+		BTRAPS4(0x60)
+		TRAP_HANDLER(reload_IMMU_tlb)    ! 0x64 : instruction_access_MMU_miss
+		TRAP_HANDLER(reload_IMMU_tlb)    ! 0x65 : instruction_access_MMU_miss
+		TRAP_HANDLER(reload_IMMU_tlb)    ! 0x66 : instruction_access_MMU_miss
+		TRAP_HANDLER(reload_IMMU_tlb)    ! 0x67 : instruction_access_MMU_miss
+		TRAP_HANDLER(reload_DMMU_tlb)    ! 0x68 : data_access_MMU_miss
+		TRAP_HANDLER(reload_DMMU_tlb)    ! 0x69 : data_access_MMU_miss
+		TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6A : data_access_MMU_miss
+		TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6B : data_access_MMU_miss
+		BTRAPS4(0x6C)    ! data_access_protection
 		BTRAPS(0x70) BTRAPS(0x78)
 tl1_s0n:        SPILL_WINDOW
 tl1_s1n:        SPILL_WINDOW
@@ -300,6 +320,86 @@
         restored
         retry
 
+        .globl reload_DMMU_tlb, reload_IMMU_tlb
+
+reload_DMMU_tlb:
+        mov     6 << 3, %g2           ! va = fault virtual address
+        ldxa    [%g2] ASI_DMMU, %g1   ! from tag access register
+
+        srlx    %g1, 13, %g1          ! %g1 = va rounded to 8k page
+        sllx    %g1, 13, %g1          !
+
+        setx    g_ofmem_translations, %g7, %g3
+        ldx     [%g3], %g3            ! translation_t* t = *g_ofmem_translations
+dmmu_next_trans:
+        ldx     [%g3], %g3
+        brz      %g3, bug             ! NULL pointer
+         nop
+        ldx     [%g3+0x08], %g4       ! t->virt
+        sub     %g1, %g4, %g7         ! %g7 offset = va - t->virt
+        brlz    %g7, dmmu_next_trans  ! va < t->virt ?
+         nop
+        ldx     [%g3+0x10], %g4       ! t->size
+        sub     %g7, %g4, %g4         ! va >= t->virt - t->size ?
+        brgez   %g4, dmmu_next_trans
+         nop
+
+        ! install 8k tlb entry
+
+        ldx     [%g3+0x18], %g4       ! t->phys
+        add     %g4, %g7, %g4         ! %g4 page physical address = t->phys + offset
+        ldx     [%g3+0x20], %g5       ! t->mode
+
+        set     0x80000000, %g2       ! valid tte, 8k size
+        sllx    %g2, 32, %g2
+        or      %g2, %g5, %g2         ! mix in translation mode
+        or      %g2, %g4, %g3         ! mix in phys addr mode
+
+        mov     6 << 3, %g2           ! page virtual address
+        stxa    %g1, [%g2] ASI_DMMU   !
+        stxa    %g3, [%g0] ASI_DTLB_DATA_IN
+
+        retry
+
+reload_IMMU_tlb:
+        mov     6 << 3, %g2           ! va = fault virtual address
+        ldxa    [%g2] ASI_IMMU, %g1   ! from tag access register
+
+        srlx    %g1, 13, %g1          ! %g1 = va rounded to 8k page
+        sllx    %g1, 13, %g1          !
+
+        setx    g_ofmem_translations, %g7, %g3
+        ldx     [%g3], %g3            ! translation_t* t = *g_ofmem_translations
+immu_next_trans:
+        ldx     [%g3], %g3
+        brz      %g3, bug             ! NULL pointer
+         nop
+        ldx     [%g3+0x08], %g4       ! t->virt
+        sub     %g1, %g4, %g7         ! %g7 offset = va - t->virt
+        brlz    %g7, immu_next_trans  ! va < t->virt ?
+         nop
+        ldx     [%g3+0x10], %g4       ! t->size
+        sub     %g7, %g4, %g4         ! va >= t->virt - t->size ?
+        brgez   %g4, immu_next_trans
+         nop
+
+        ! install 8k tlb entry
+
+        ldx     [%g3+0x18], %g4       ! t->phys
+        add     %g4, %g7, %g4         ! %g4 page physical address = t->phys + offset
+        ldx     [%g3+0x20], %g5       ! t->mode
+
+        set     0x80000000, %g2       ! valid tte, 8k size
+        sllx    %g2, 32, %g2
+        or      %g2, %g5, %g2         ! mix in translation mode
+        or      %g2, %g4, %g3         ! mix in phys addr mode
+
+        mov     6 << 3, %g2           ! page virtual address
+        stxa    %g1, [%g2] ASI_IMMU   !
+        stxa    %g3, [%g0] ASI_ITLB_DATA_IN
+
+        retry
+
 __divide_error:
 bug:
         /* Dump the exception and its context */




More information about the OpenBIOS mailing list