Author: blueswirl Date: 2008-07-18 22:14:09 +0200 (Fri, 18 Jul 2008) New Revision: 211
Modified: openbios-devel/arch/sparc64/openbios.c Log: Fix available and total memory Implement a static list of mmu translations Map more pages Add a fake unmap method
Modified: openbios-devel/arch/sparc64/openbios.c =================================================================== --- openbios-devel/arch/sparc64/openbios.c 2008-07-18 10:34:17 UTC (rev 210) +++ openbios-devel/arch/sparc64/openbios.c 2008-07-18 20:14:09 UTC (rev 211) @@ -59,6 +59,15 @@ const char *name; };
+#define PAGE_SIZE_4M (4 * 1024 * 1024) +#define PAGE_SIZE_512K (512 * 1024) +#define PAGE_SIZE_64K (64 * 1024) +#define PAGE_SIZE_8K (8 * 1024) +#define PAGE_MASK_4M (4 * 1024 * 1024 - 1) +#define PAGE_MASK_512K (512 * 1024 - 1) +#define PAGE_MASK_64K (64 * 1024 - 1) +#define PAGE_MASK_8K (8 * 1024 - 1) + static void mmu_open(void) { @@ -95,6 +104,15 @@ } }
+static void +dtlb_load2(unsigned long vaddr, unsigned long tte_data) +{ + 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 -- ? ) */ @@ -106,11 +124,16 @@ vaddr = POP(); tte_data = POP(); idx = POP(); + dtlb_load2(vaddr, tte_data); +}
+static void +itlb_load2(unsigned long vaddr, unsigned long tte_data) +{ 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)); + : : "r" (vaddr), "r" (48), "i" (ASI_IMMU), + "r" (tte_data), "i" (ASI_ITLB_DATA_IN)); }
/* @@ -124,11 +147,43 @@ vaddr = POP(); tte_data = POP(); idx = POP(); + itlb_load2(vaddr, tte_data); +}
- 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)); +static void +map_pages(unsigned long virt, unsigned long size, unsigned long phys) +{ + unsigned long tte_data, currsize; + + size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K; + while (size >= PAGE_SIZE_8K) { + currsize = size; + if (currsize >= PAGE_SIZE_4M && + (virt & PAGE_MASK_4M) == 0 && + (phys & PAGE_MASK_4M) == 0) { + currsize = PAGE_SIZE_4M; + tte_data = 6ULL << 60; + } else if (currsize >= PAGE_SIZE_512K && + (virt & PAGE_MASK_512K) == 0 && + (phys & PAGE_MASK_512K) == 0) { + currsize = PAGE_SIZE_8K; + tte_data = 4ULL << 60; + } else if (currsize >= PAGE_SIZE_64K && + (virt & PAGE_MASK_64K) == 0 && + (phys & PAGE_MASK_64K) == 0) { + currsize = PAGE_SIZE_64K; + tte_data = 2ULL << 60; + } else { + currsize = PAGE_SIZE_8K; + tte_data = 0; + } + tte_data |= phys | 0x8000000000000036ULL; + dtlb_load2(virt, tte_data); + itlb_load2(virt, tte_data); + size -= currsize; + phys += currsize; + virt += currsize; + } }
/* @@ -138,7 +193,7 @@ static void mmu_map(void) { - unsigned long virt, size, mode, phys, tte_data; + unsigned long virt, size, mode, phys;
mode = POP(); size = POP(); @@ -146,29 +201,21 @@ phys = POP(); phys <<= 32; phys |= POP(); + map_pages(virt, size, phys); +}
- tte_data = phys | 0x8000000000000036ULL; - 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_IMMU), - "r" (tte_data), "i" (ASI_ITLB_DATA_IN)); +/* + 3.6.5 unmap + ( virt size -- ) +*/ +static void +mmu_unmap(void) +{ + unsigned long virt, size; + + size = POP(); + virt = POP(); + //unmap_pages(virt, size); }
DECLARE_UNNAMED_NODE(mmu, INSTALL_OPEN, 0); @@ -180,6 +227,7 @@ { "SUNW,dtlb-load", dtlb_load }, { "SUNW,itlb-load", itlb_load }, { "map", mmu_map }, + { "unmap", mmu_unmap }, };
/* @@ -421,8 +469,12 @@ push_str("/memory"); fword("find-device");
+ // All memory: 0 to RAM_size PUSH(0); fword("encode-int"); + PUSH(0); + fword("encode-int"); + fword("encode+"); PUSH((int)(nv_info.RAM0_size >> 32)); fword("encode-int"); fword("encode+"); @@ -432,47 +484,105 @@ push_str("reg"); fword("property");
+ // Available memory: 0 to va2pa(_start) PUSH(0); fword("encode-int"); PUSH(0); fword("encode-int"); fword("encode+"); - PUSH((unsigned long)&_start - 4096); + PUSH((va2pa((unsigned long)&_data) - 8192) >> 32); fword("encode-int"); fword("encode+"); - PUSH(0); + PUSH((va2pa((unsigned long)&_data) - 8192) & 0xffffffff); fword("encode-int"); fword("encode+"); - PUSH(va2pa((unsigned long)&_iomem)); - fword("encode-int"); - fword("encode+"); - PUSH(-va2pa((unsigned long)&_iomem)); - fword("encode-int"); - fword("encode+"); push_str("available"); fword("property");
// XXX + // Translations push_str("/virtual-memory"); fword("find-device");
+ // 0 to va2pa(_start): 1:1 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(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)&_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(((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");