[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