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@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