[OpenBIOS] [PATCH 3/8] SPARC64: Refactor tte-data code in preparation for moving architecture-specific code to ofmem_sparc64.c.
Mark Cave-Ayland
mark.cave-ayland at ilande.co.uk
Sun Apr 22 22:29:04 CEST 2012
Note we also change pgmap@ so it explicitly searches for a TTE entry using
architecture-specific code, plus add the code to detect whether a page is
marked as locked or not into the main page mapping function.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
---
openbios-devel/arch/sparc64/lib.c | 79 +++++++++------------------
openbios-devel/arch/sparc64/ofmem_sparc64.c | 32 +++++++++++
openbios-devel/include/libopenbios/ofmem.h | 6 ++
3 files changed, 64 insertions(+), 53 deletions(-)
diff --git a/openbios-devel/arch/sparc64/lib.c b/openbios-devel/arch/sparc64/lib.c
index 893fde1..122665e 100644
--- a/openbios-devel/arch/sparc64/lib.c
+++ b/openbios-devel/arch/sparc64/lib.c
@@ -16,8 +16,6 @@
#include "ofmem_sparc64.h"
-static ucell *va2ttedata = 0;
-
/* Format a string and print it on the screen, just like the libc
* function printf.
*/
@@ -165,35 +163,21 @@ mmu_translate(void)
static void
pgmap_fetch(void)
{
- translation_t *t = *g_ofmem_translations;
- unsigned long va, tte_data;
-
- va = POP();
-
- /* Search the ofmem linked list for this virtual address */
- while (t != NULL) {
- /* Find the correct range */
- if (va >= t->virt && va < (t->virt + t->size)) {
+ unsigned long va, tte_data;
- /* valid tte, 8k size */
- tte_data = SPITFIRE_TTE_VALID;
+ va = POP();
- /* mix in phys address mode */
- tte_data |= t->mode;
+ tte_data = find_tte(va);
+ if (tte_data == -1)
+ goto error;
- /* mix in page physical address = t->phys + offset */
- tte_data |= t->phys + (va - t->virt);
-
- /* return tte_data */
- PUSH(tte_data);
-
- return;
- }
- t = t->next;
- }
+ /* return tte_data */
+ PUSH(tte_data);
+ return;
- /* If we get here, there was no entry */
- PUSH(0);
+error:
+ /* If we get here, there was no entry */
+ PUSH(0);
}
static void
@@ -270,9 +254,7 @@ dtlb_miss_handler(void)
}
} else {
/* Search the ofmem linked list for this virtual address */
- PUSH(faultva);
- pgmap_fetch();
- tte_data = POP();
+ tte_data = find_tte(faultva);
}
if (tte_data) {
@@ -359,9 +341,7 @@ itlb_miss_handler(void)
}
} else {
/* Search the ofmem linked list for this virtual address */
- PUSH(faultva);
- pgmap_fetch();
- tte_data = POP();
+ tte_data = find_tte(faultva);
}
if (tte_data) {
@@ -373,16 +353,14 @@ itlb_miss_handler(void)
}
}
-static void
-map_pages(phys_addr_t phys, unsigned long virt,
- unsigned long size, unsigned long mode)
+void ofmem_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode)
{
- unsigned long tte_data, currsize;
+ unsigned long tte_data, currsize;
- /* aligned to 8k page */
- size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K;
+ /* aligned to 8k page */
+ size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K;
- while (size > 0) {
+ while (size > 0) {
currsize = size;
if (currsize >= PAGE_SIZE_4M &&
(virt & PAGE_MASK_4M) == 0 &&
@@ -406,20 +384,18 @@ map_pages(phys_addr_t phys, unsigned long virt,
tte_data |= phys | mode | SPITFIRE_TTE_VALID;
- itlb_load2(virt, tte_data);
- dtlb_load2(virt, tte_data);
-
+ if (mode & SPITFIRE_TTE_LOCKED) {
+ // install locked tlb entries now
+ itlb_load2(virt, tte_data);
+ dtlb_load2(virt, tte_data);
+ }
+
size -= currsize;
phys += currsize;
virt += currsize;
}
}
-void ofmem_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode)
-{
- return map_pages(phys, virt, size, mode);
-}
-
/*
3.6.5 map
( phys.lo ... phys.hi virt size mode -- )
@@ -457,7 +433,7 @@ dtlb_demap(unsigned long vaddr)
static void
unmap_pages(ucell virt, ucell size)
{
- ucell va;
+ ucell va;
/* align address to 8k */
virt &= ~PAGE_MASK_8K;
@@ -478,10 +454,7 @@ void ofmem_arch_unmap_pages(ucell virt, ucell size)
void ofmem_arch_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode)
{
- if (mode & SPITFIRE_TTE_LOCKED) {
- // install locked tlb entries now
- ofmem_map_pages(phys, virt, size, mode);
- }
+ ofmem_map_pages(phys, virt, size, mode);
}
/*
diff --git a/openbios-devel/arch/sparc64/ofmem_sparc64.c b/openbios-devel/arch/sparc64/ofmem_sparc64.c
index 889a5a5..f451a3c 100644
--- a/openbios-devel/arch/sparc64/ofmem_sparc64.c
+++ b/openbios-devel/arch/sparc64/ofmem_sparc64.c
@@ -31,6 +31,7 @@ static union {
translation_t **g_ofmem_translations = &s_ofmem_data.ofmem.trans;
+ucell *va2ttedata = 0;
extern uint64_t qemu_mem_size;
static inline size_t ALIGN_SIZE(size_t x, size_t a)
@@ -162,6 +163,37 @@ ucell ofmem_arch_io_translation_mode( phys_addr_t phys )
return SPITFIRE_TTE_CV | SPITFIRE_TTE_WRITABLE;
}
+/* Architecture-specific helpers */
+unsigned long
+find_tte(unsigned long va)
+{
+ translation_t *t = *g_ofmem_translations;
+ unsigned long tte_data;
+
+ /* Search the ofmem linked list for this virtual address */
+ while (t != NULL) {
+ /* Find the correct range */
+ if (va >= t->virt && va < (t->virt + t->size)) {
+
+ /* valid tte, 8k size */
+ tte_data = SPITFIRE_TTE_VALID;
+
+ /* mix in phys address mode */
+ tte_data |= t->mode;
+
+ /* mix in page physical address = t->phys + offset */
+ tte_data |= t->phys + (va - t->virt);
+
+ /* return tte_data */
+ return tte_data;
+ }
+ t = t->next;
+ }
+
+ /* Couldn't find tte */
+ return -1;
+}
+
/************************************************************************/
/* init / cleanup */
/************************************************************************/
diff --git a/openbios-devel/include/libopenbios/ofmem.h b/openbios-devel/include/libopenbios/ofmem.h
index 68a84c8..957f165 100644
--- a/openbios-devel/include/libopenbios/ofmem.h
+++ b/openbios-devel/include/libopenbios/ofmem.h
@@ -144,6 +144,12 @@ extern unsigned long find_pte(unsigned long va, int alloc);
void mem_init(struct mem *t, char *begin, char *limit);
void *mem_alloc(struct mem *t, int size, int align);
+
+#elif defined(CONFIG_SPARC64)
+
+extern ucell *va2ttedata;
+extern unsigned long find_tte(unsigned long va);
+
#endif
#ifdef PAGE_SHIFT
--
1.7.2.5
More information about the OpenBIOS
mailing list