This patchset aims to tidy up various parts of OFMEM, with the ultimate aim of reducing the image sizes. The first 4 patches perform the reorganisation, while the remainder of the patches ensure that video memory and the Forth machine memory are no longer contained within the image.
Note: the resulting SPARC64 image is now approximately half of its original size - BUT because we require 512K alignment for various parts of the image because of the 512K MMU page size, our ability to claim this space back directly is limited. Any further ideas on this would be welcomed.
Mark Cave-Ayland (8): Rename ofmem_arch_early_map_pages() to ofmem_arch_map_pages(). SPARC32: Move ofmem_arch_map_pages() into ofmem_sparc32.c with all the other architecture-specific code. SPARC64: Refactor tte-data code in preparation for moving architecture-specific code to ofmem_sparc64.c. SPARC64: Move ofmem_arch_map_pages()/ofmem_arch_unmap_pages() into ofmem_sparc64.c with all the other architecture-specific code. Remove architecture-specific routines from ofmem.h. SPARC64: Remove video initialisation hack. SPARC64: Swap Forth machine memory allocation over to OFMEM memory pool. SPARC32: Swap Forth machine memory allocation over to OFMEM memory pool.
openbios-devel/arch/ppc/ofmem.c | 2 +- openbios-devel/arch/ppc/qemu/ofmem.c | 6 +- openbios-devel/arch/sparc32/lib.c | 95 +--------- openbios-devel/arch/sparc32/ofmem_sparc32.c | 82 ++++++++- openbios-devel/arch/sparc32/openbios.c | 27 ++- openbios-devel/arch/sparc64/ldscript | 6 - openbios-devel/arch/sparc64/lib.c | 210 ++------------------ openbios-devel/arch/sparc64/ofmem_sparc64.c | 176 ++++++++++++++++- openbios-devel/arch/sparc64/ofmem_sparc64.h | 32 --- openbios-devel/arch/sparc64/openbios.c | 30 ++- openbios-devel/drivers/iommu.c | 4 +- openbios-devel/drivers/vga_vbe.c | 9 +- .../include/arch/sparc32/ofmem_sparc32.h | 28 +++ openbios-devel/include/arch/sparc64/io.h | 2 +- .../include/arch/sparc64/ofmem_sparc64.h | 50 +++++ openbios-devel/include/libopenbios/ofmem.h | 22 +-- openbios-devel/libopenbios/ofmem_common.c | 6 +- openbios-devel/packages/video.c | 4 +- 18 files changed, 405 insertions(+), 386 deletions(-) delete mode 100644 openbios-devel/arch/sparc64/ofmem_sparc64.h create mode 100644 openbios-devel/include/arch/sparc32/ofmem_sparc32.h create mode 100644 openbios-devel/include/arch/sparc64/ofmem_sparc64.h
This OFMEM call does actually map the page for the architectures that require it, so let's change its name so that we now have a symmetrical ofmem_arch_map_pages() and ofmem_arch_unmap_pages() API.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/ppc/ofmem.c | 2 +- openbios-devel/arch/ppc/qemu/ofmem.c | 2 +- openbios-devel/arch/sparc32/lib.c | 2 +- openbios-devel/arch/sparc64/lib.c | 2 +- openbios-devel/drivers/iommu.c | 2 +- openbios-devel/include/libopenbios/ofmem.h | 6 +++--- openbios-devel/libopenbios/ofmem_common.c | 6 +++--- 7 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/openbios-devel/arch/ppc/ofmem.c b/openbios-devel/arch/ppc/ofmem.c index 436cfe3..c9b066e 100644 --- a/openbios-devel/arch/ppc/ofmem.c +++ b/openbios-devel/arch/ppc/ofmem.c @@ -121,7 +121,7 @@ void ofmem_arch_unmap_pages(ucell virt, ucell size) /* kill page mappings in provided range */ }
-void ofmem_arch_early_map_pages(ucell phys, ucell virt, ucell size, ucell mode) +void ofmem_arch_map_pages(ucell phys, ucell virt, ucell size, ucell mode) { /* none yet */ } diff --git a/openbios-devel/arch/ppc/qemu/ofmem.c b/openbios-devel/arch/ppc/qemu/ofmem.c index 1319389..fbade1e 100644 --- a/openbios-devel/arch/ppc/qemu/ofmem.c +++ b/openbios-devel/arch/ppc/qemu/ofmem.c @@ -129,7 +129,7 @@ void ofmem_arch_unmap_pages(ucell virt, ucell size) /* kill page mappings in provided range */ }
-void ofmem_arch_early_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode) +void ofmem_arch_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode) { /* none yet */ } diff --git a/openbios-devel/arch/sparc32/lib.c b/openbios-devel/arch/sparc32/lib.c index 020f781..dde5a0f 100644 --- a/openbios-devel/arch/sparc32/lib.c +++ b/openbios-devel/arch/sparc32/lib.c @@ -342,7 +342,7 @@ void ofmem_arch_unmap_pages(ucell virt, ucell size) /* Currently do nothing */ }
-void ofmem_arch_early_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode) +void ofmem_arch_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode) { map_pages(phys, virt, size, mode); } diff --git a/openbios-devel/arch/sparc64/lib.c b/openbios-devel/arch/sparc64/lib.c index 58286ba..893fde1 100644 --- a/openbios-devel/arch/sparc64/lib.c +++ b/openbios-devel/arch/sparc64/lib.c @@ -476,7 +476,7 @@ void ofmem_arch_unmap_pages(ucell virt, ucell size) unmap_pages(virt, size); }
-void ofmem_arch_early_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode) +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 diff --git a/openbios-devel/drivers/iommu.c b/openbios-devel/drivers/iommu.c index 5eb8a60..47c6130 100644 --- a/openbios-devel/drivers/iommu.c +++ b/openbios-devel/drivers/iommu.c @@ -68,7 +68,7 @@ dvma_alloc(int size, unsigned int *pphys) */ mva = (unsigned int) va; mpa = (unsigned int) pa; - ofmem_arch_early_map_pages(mpa, mva, npages * PAGE_SIZE, ofmem_arch_io_translation_mode(mpa)); + ofmem_arch_map_pages(mpa, mva, npages * PAGE_SIZE, ofmem_arch_io_translation_mode(mpa));
/* * Map into IOMMU page table. diff --git a/openbios-devel/include/libopenbios/ofmem.h b/openbios-devel/include/libopenbios/ofmem.h index 30f20d8..f5c442e 100644 --- a/openbios-devel/include/libopenbios/ofmem.h +++ b/openbios-devel/include/libopenbios/ofmem.h @@ -67,15 +67,15 @@ extern phys_addr_t ofmem_arch_get_phys_top(void); extern ucell ofmem_arch_get_iomem_base(void); extern ucell ofmem_arch_get_iomem_top(void); extern retain_t* ofmem_arch_get_retained(void); -extern int ofmem_arch_get_physaddr_cellsize(void); -extern int ofmem_arch_encode_physaddr(ucell *p, phys_addr_t value); +extern int ofmem_arch_get_physaddr_cellsize(void); +extern int ofmem_arch_encode_physaddr(ucell *p, phys_addr_t value); extern int ofmem_arch_get_available_entry_size(phandle_t ph); extern void ofmem_arch_create_available_entry(phandle_t ph, ucell *availentry, phys_addr_t start, ucell size); extern int ofmem_arch_get_translation_entry_size(void); extern void ofmem_arch_create_translation_entry(ucell *transentry, translation_t *t); extern ucell ofmem_arch_default_translation_mode( phys_addr_t phys ); extern ucell ofmem_arch_io_translation_mode( phys_addr_t phys ); -extern void ofmem_arch_early_map_pages(phys_addr_t phys, ucell virt, ucell size, +extern void ofmem_arch_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode); extern void ofmem_arch_unmap_pages(ucell virt, ucell size); /* sparc64 uses this method */ diff --git a/openbios-devel/libopenbios/ofmem_common.c b/openbios-devel/libopenbios/ofmem_common.c index ac36fca..bae0732 100644 --- a/openbios-devel/libopenbios/ofmem_common.c +++ b/openbios-devel/libopenbios/ofmem_common.c @@ -794,8 +794,8 @@ int ofmem_map( phys_addr_t phys, ucell virt, ucell size, ucell mode ) /* install translations */ ofmem_map_page_range(phys, virt, size, mode);
- /* allow arch to install mappings early, e.g. for locked mappings */ - ofmem_arch_early_map_pages(phys, virt, size, mode); + /* allow arch to map the pages */ + ofmem_arch_map_pages(phys, virt, size, mode);
return 0; } @@ -836,7 +836,7 @@ ucell ofmem_map_io( phys_addr_t phys, ucell size ) mode = ofmem_arch_io_translation_mode(off);
ofmem_map_page_range(phys, virt, npages * PAGE_SIZE, mode); - ofmem_arch_early_map_pages(phys, virt, npages * PAGE_SIZE, mode); + ofmem_arch_map_pages(phys, virt, npages * PAGE_SIZE, mode);
return (virt + off); }
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/lib.c | 93 ++------------------------- openbios-devel/arch/sparc32/ofmem_sparc32.c | 78 ++++++++++++++++++++++- openbios-devel/include/libopenbios/ofmem.h | 3 + 3 files changed, 85 insertions(+), 89 deletions(-)
diff --git a/openbios-devel/arch/sparc32/lib.c b/openbios-devel/arch/sparc32/lib.c index dde5a0f..799399c 100644 --- a/openbios-devel/arch/sparc32/lib.c +++ b/openbios-devel/arch/sparc32/lib.c @@ -56,8 +56,8 @@ struct mem { struct mem cdvmem; /* Current device virtual memory space */
unsigned int va_shift; +unsigned long *l1; static unsigned long *context_table; -static unsigned long *l1;
static ucell *mem_reg = 0; static ucell *mem_avail = 0; @@ -141,78 +141,6 @@ mem_alloc(struct mem *t, int size, int align) return p; }
-static unsigned long -find_pte(unsigned long va, int alloc) -{ - uint32_t pte; - void *p; - unsigned long pa; - int ret; - - pte = l1[(va >> SRMMU_PGDIR_SHIFT) & (SRMMU_PTRS_PER_PGD - 1)]; - if ((pte & SRMMU_ET_MASK) == SRMMU_ET_INVALID) { - if (alloc) { - ret = ofmem_posix_memalign(&p, SRMMU_PTRS_PER_PMD * sizeof(int), - SRMMU_PTRS_PER_PMD * sizeof(int)); - if (ret != 0) - return ret; - pte = SRMMU_ET_PTD | ((va2pa((unsigned long)p)) >> 4); - l1[(va >> SRMMU_PGDIR_SHIFT) & (SRMMU_PTRS_PER_PGD - 1)] = pte; - /* barrier() */ - } else { - return -1; - } - } - - pa = (pte & 0xFFFFFFF0) << 4; - pa += ((va >> SRMMU_PMD_SHIFT) & (SRMMU_PTRS_PER_PMD - 1)) << 2; - pte = *(uint32_t *)pa2va(pa); - if ((pte & SRMMU_ET_MASK) == SRMMU_ET_INVALID) { - if (alloc) { - ret = ofmem_posix_memalign(&p, SRMMU_PTRS_PER_PTE * sizeof(void *), - SRMMU_PTRS_PER_PTE * sizeof(void *)); - if (ret != 0) - return ret; - pte = SRMMU_ET_PTD | ((va2pa((unsigned int)p)) >> 4); - *(uint32_t *)pa2va(pa) = pte; - } else { - return -2; - } - } - - pa = (pte & 0xFFFFFFF0) << 4; - pa += ((va >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1)) << 2; - - return pa2va(pa); -} - -static void -map_pages(phys_addr_t phys, unsigned long virt, - unsigned long size, unsigned long mode) -{ - unsigned long npages, off; - uint32_t pte; - unsigned long pa; - - DPRINTF("map_pages: va 0x%lx, pa 0x%llx, size 0x%lx\n", virt, phys, size); - - off = phys & (PAGE_SIZE - 1); - npages = (off + (size - 1) + (PAGE_SIZE - 1)) / PAGE_SIZE; - phys &= ~(uint64_t)(PAGE_SIZE - 1); - - while (npages-- != 0) { - pa = find_pte(virt, 1); - - pte = SRMMU_ET_PTE | ((phys & PAGE_MASK) >> 4); - pte |= mode; - - *(uint32_t *)pa = pte; - - virt += PAGE_SIZE; - phys += PAGE_SIZE; - } -} - /* * D5.3 pgmap@ ( va -- pte ) */ @@ -269,8 +197,7 @@ ob_map_pages(void) pa <<= 32; pa |= POP() & 0xffffffff;
- map_pages(pa, va, size, ofmem_arch_default_translation_mode(pa)); - DPRINTF("map-page: va 0x%lx pa 0x%llx size 0x%x\n", va, pa, size); + ofmem_arch_map_pages(pa, va, size, ofmem_arch_default_translation_mode(pa)); }
static void @@ -327,7 +254,7 @@ char *obp_dumb_mmap(char *va, int which_io, unsigned int pa, { uint64_t mpa = ((uint64_t)which_io << 32) | (uint64_t)pa;
- map_pages(mpa, (unsigned long)va, size, ofmem_arch_default_translation_mode(mpa)); + ofmem_arch_map_pages(mpa, (unsigned long)va, size, ofmem_arch_default_translation_mode(mpa)); return va; }
@@ -337,16 +264,6 @@ void obp_dumb_munmap(__attribute__((unused)) char *va, DPRINTF("obp_dumb_munmap: virta 0x%x, sz %d\n", (unsigned int)va, size); }
-void ofmem_arch_unmap_pages(ucell virt, ucell size) -{ - /* Currently do nothing */ -} - -void ofmem_arch_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode) -{ - map_pages(phys, virt, size, mode); -} - char *obp_memalloc(char *va, unsigned int size, unsigned int align) { phys_addr_t phys; @@ -483,10 +400,10 @@ init_mmu_swift(void) va = (unsigned long)&_start; size = (unsigned long)&_end - (unsigned long)&_start; pa = va2pa(va); - map_pages(pa, va, size, ofmem_arch_default_translation_mode(pa)); + ofmem_arch_map_pages(pa, va, size, ofmem_arch_default_translation_mode(pa));
// 1:1 mapping for RAM - map_pages(0, 0, LOWMEMSZ, ofmem_arch_default_translation_mode(0)); + ofmem_arch_map_pages(0, 0, LOWMEMSZ, ofmem_arch_default_translation_mode(0));
/* * Flush cache diff --git a/openbios-devel/arch/sparc32/ofmem_sparc32.c b/openbios-devel/arch/sparc32/ofmem_sparc32.c index bd52538..19d0d8e 100644 --- a/openbios-devel/arch/sparc32/ofmem_sparc32.c +++ b/openbios-devel/arch/sparc32/ofmem_sparc32.c @@ -133,12 +133,88 @@ int ofmem_arch_get_available_entry_size(phandle_t ph) /* Generate memory available property entry for Sparc32 */ void ofmem_arch_create_available_entry(phandle_t ph, ucell *availentry, phys_addr_t start, ucell size) { - int i = 0; + int i = 0;
i += ofmem_arch_encode_physaddr(availentry, start); availentry[i] = size; }
+/* Unmap a set of pages */ +void ofmem_arch_unmap_pages(ucell virt, ucell size) +{ + /* Currently do nothing */ +} + +/* Map a set of pages */ +void ofmem_arch_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode) +{ + unsigned long npages, off; + uint32_t pte; + unsigned long pa; + + off = phys & (PAGE_SIZE - 1); + npages = (off + (size - 1) + (PAGE_SIZE - 1)) / PAGE_SIZE; + phys &= ~(uint64_t)(PAGE_SIZE - 1); + + while (npages-- != 0) { + pa = find_pte(virt, 1); + + pte = SRMMU_ET_PTE | ((phys & PAGE_MASK) >> 4); + pte |= mode; + + *(uint32_t *)pa = pte; + + virt += PAGE_SIZE; + phys += PAGE_SIZE; + } +} + +/* Architecture-specific OFMEM helpers */ +unsigned long +find_pte(unsigned long va, int alloc) +{ + uint32_t pte; + void *p; + unsigned long pa; + int ret; + + pte = l1[(va >> SRMMU_PGDIR_SHIFT) & (SRMMU_PTRS_PER_PGD - 1)]; + if ((pte & SRMMU_ET_MASK) == SRMMU_ET_INVALID) { + if (alloc) { + ret = ofmem_posix_memalign(&p, SRMMU_PTRS_PER_PMD * sizeof(int), + SRMMU_PTRS_PER_PMD * sizeof(int)); + if (ret != 0) + return ret; + pte = SRMMU_ET_PTD | ((va2pa((unsigned long)p)) >> 4); + l1[(va >> SRMMU_PGDIR_SHIFT) & (SRMMU_PTRS_PER_PGD - 1)] = pte; + /* barrier() */ + } else { + return -1; + } + } + + pa = (pte & 0xFFFFFFF0) << 4; + pa += ((va >> SRMMU_PMD_SHIFT) & (SRMMU_PTRS_PER_PMD - 1)) << 2; + pte = *(uint32_t *)pa2va(pa); + if ((pte & SRMMU_ET_MASK) == SRMMU_ET_INVALID) { + if (alloc) { + ret = ofmem_posix_memalign(&p, SRMMU_PTRS_PER_PTE * sizeof(void *), + SRMMU_PTRS_PER_PTE * sizeof(void *)); + if (ret != 0) + return ret; + pte = SRMMU_ET_PTD | ((va2pa((unsigned int)p)) >> 4); + *(uint32_t *)pa2va(pa) = pte; + } else { + return -2; + } + } + + pa = (pte & 0xFFFFFFF0) << 4; + pa += ((va >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1)) << 2; + + return pa2va(pa); +} + /************************************************************************/ /* misc */ /************************************************************************/ diff --git a/openbios-devel/include/libopenbios/ofmem.h b/openbios-devel/include/libopenbios/ofmem.h index f5c442e..68a84c8 100644 --- a/openbios-devel/include/libopenbios/ofmem.h +++ b/openbios-devel/include/libopenbios/ofmem.h @@ -139,6 +139,9 @@ unsigned long get_ram_bottom( void ); struct mem; extern struct mem cdvmem;
+extern unsigned long *l1; +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); #endif
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
Note that we also take some of the ITLB/DTLB helpers with us.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc64/lib.c | 155 --------------------------- openbios-devel/arch/sparc64/ofmem_sparc64.c | 142 ++++++++++++++++++++++++- openbios-devel/arch/sparc64/ofmem_sparc64.h | 3 +- openbios-devel/include/libopenbios/ofmem.h | 18 +++ 4 files changed, 160 insertions(+), 158 deletions(-)
diff --git a/openbios-devel/arch/sparc64/lib.c b/openbios-devel/arch/sparc64/lib.c index 122665e..abcac9f 100644 --- a/openbios-devel/arch/sparc64/lib.c +++ b/openbios-devel/arch/sparc64/lib.c @@ -70,15 +70,6 @@ void free(void *ptr) ofmem_free(ptr); }
-#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) { @@ -180,37 +171,6 @@ error: PUSH(0); }
-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)); -} - -static void -dtlb_load3(unsigned long vaddr, unsigned long tte_data, - unsigned long tte_index) -{ - asm("stxa %0, [%1] %2\n" - "stxa %3, [%4] %5\n" - : : "r" (vaddr), "r" (48), "i" (ASI_DMMU), - "r" (tte_data), "r" (tte_index << 3), "i" (ASI_DTLB_DATA_ACCESS)); -} - -static unsigned long -dtlb_faultva(void) -{ - unsigned long faultva; - - asm("ldxa [%1] %2, %0\n" - : "=r" (faultva) - : "r" (48), "i" (ASI_DMMU)); - - return faultva; -} - /* ( index tte_data vaddr -- ? ) */ @@ -267,25 +227,6 @@ dtlb_miss_handler(void)
}
-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_IMMU), - "r" (tte_data), "i" (ASI_ITLB_DATA_IN)); -} - -static void -itlb_load3(unsigned long vaddr, unsigned long tte_data, - unsigned long tte_index) -{ - asm("stxa %0, [%1] %2\n" - "stxa %3, [%4] %5\n" - : : "r" (vaddr), "r" (48), "i" (ASI_IMMU), - "r" (tte_data), "r" (tte_index << 3), "i" (ASI_ITLB_DATA_ACCESS)); -} - /* ( index tte_data vaddr -- ? ) */ @@ -300,18 +241,6 @@ itlb_load(void) itlb_load3(vaddr, tte_data, idx); }
-static unsigned long -itlb_faultva(void) -{ - unsigned long faultva; - - asm("ldxa [%1] %2, %0\n" - : "=r" (faultva) - : "r" (48), "i" (ASI_IMMU)); - - return faultva; -} - /* MMU I-TLB miss handler */ void itlb_miss_handler(void) @@ -353,49 +282,6 @@ itlb_miss_handler(void) } }
-void ofmem_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode) -{ - unsigned long tte_data, currsize; - - /* 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 && - (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_512K; - 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 | mode | SPITFIRE_TTE_VALID; - - 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; - } -} - /* 3.6.5 map ( phys.lo ... phys.hi virt size mode -- ) @@ -416,47 +302,6 @@ mmu_map(void) ofmem_map(phys, virt, size, mode); }
-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(ucell virt, ucell size) -{ - ucell va; - - /* align address to 8k */ - virt &= ~PAGE_MASK_8K; - - /* align size to 8k */ - size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K; - - for (va = virt; va < virt + size; va += PAGE_SIZE_8K) { - itlb_demap(va); - dtlb_demap(va); - } -} - -void ofmem_arch_unmap_pages(ucell virt, ucell size) -{ - unmap_pages(virt, size); -} - -void ofmem_arch_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode) -{ - ofmem_map_pages(phys, virt, size, mode); -} - /* 3.6.5 unmap ( virt size -- ) diff --git a/openbios-devel/arch/sparc64/ofmem_sparc64.c b/openbios-devel/arch/sparc64/ofmem_sparc64.c index f451a3c..5445d60 100644 --- a/openbios-devel/arch/sparc64/ofmem_sparc64.c +++ b/openbios-devel/arch/sparc64/ofmem_sparc64.c @@ -135,6 +135,68 @@ void ofmem_arch_create_available_entry(phandle_t ph, ucell *availentry, phys_add availentry[i] = size; }
+/* Unmap a set of pages */ +void ofmem_arch_unmap_pages(ucell virt, ucell size) +{ + ucell va; + + /* align address to 8k */ + virt &= ~PAGE_MASK_8K; + + /* align size to 8k */ + size = (size + PAGE_MASK_8K) & ~PAGE_MASK_8K; + + for (va = virt; va < virt + size; va += PAGE_SIZE_8K) { + itlb_demap(va); + dtlb_demap(va); + } +} + +/* Map a set of pages */ +void ofmem_arch_map_pages(phys_addr_t phys, ucell virt, ucell size, ucell mode) +{ + unsigned long tte_data, currsize; + + /* Install locked tlb entries now */ + if (mode & SPITFIRE_TTE_LOCKED) { + + /* 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 && + (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_512K; + 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 | mode | SPITFIRE_TTE_VALID; + + itlb_load2(virt, tte_data); + dtlb_load2(virt, tte_data); + + size -= currsize; + phys += currsize; + virt += currsize; + } + } +} + /************************************************************************/ /* misc */ /************************************************************************/ @@ -163,7 +225,7 @@ ucell ofmem_arch_io_translation_mode( phys_addr_t phys ) return SPITFIRE_TTE_CV | SPITFIRE_TTE_WRITABLE; }
-/* Architecture-specific helpers */ +/* Architecture-specific OFMEM helpers */ unsigned long find_tte(unsigned long va) { @@ -194,6 +256,84 @@ find_tte(unsigned long va) return -1; }
+/* ITLB handlers */ +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_IMMU), + "r" (tte_data), "i" (ASI_ITLB_DATA_IN)); +} + +void +itlb_load3(unsigned long vaddr, unsigned long tte_data, + unsigned long tte_index) +{ + asm("stxa %0, [%1] %2\n" + "stxa %3, [%4] %5\n" + : : "r" (vaddr), "r" (48), "i" (ASI_IMMU), + "r" (tte_data), "r" (tte_index << 3), "i" (ASI_ITLB_DATA_ACCESS)); +} + +unsigned long +itlb_faultva(void) +{ + unsigned long faultva; + + asm("ldxa [%1] %2, %0\n" + : "=r" (faultva) + : "r" (48), "i" (ASI_IMMU)); + + return faultva; +} + +void +itlb_demap(unsigned long vaddr) +{ + asm("stxa %0, [%0] %1\n" + : : "r" (vaddr), "i" (ASI_IMMU_DEMAP)); +} + +/* DTLB handlers */ +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)); +} + +void +dtlb_load3(unsigned long vaddr, unsigned long tte_data, + unsigned long tte_index) +{ + asm("stxa %0, [%1] %2\n" + "stxa %3, [%4] %5\n" + : : "r" (vaddr), "r" (48), "i" (ASI_DMMU), + "r" (tte_data), "r" (tte_index << 3), "i" (ASI_DTLB_DATA_ACCESS)); +} + +unsigned long +dtlb_faultva(void) +{ + unsigned long faultva; + + asm("ldxa [%1] %2, %0\n" + : "=r" (faultva) + : "r" (48), "i" (ASI_DMMU)); + + return faultva; +} + +void +dtlb_demap(unsigned long vaddr) +{ + asm("stxa %0, [%0] %1\n" + : : "r" (vaddr), "i" (ASI_DMMU_DEMAP)); +} + /************************************************************************/ /* init / cleanup */ /************************************************************************/ diff --git a/openbios-devel/arch/sparc64/ofmem_sparc64.h b/openbios-devel/arch/sparc64/ofmem_sparc64.h index 58802b4..ad67f71 100644 --- a/openbios-devel/arch/sparc64/ofmem_sparc64.h +++ b/openbios-devel/arch/sparc64/ofmem_sparc64.h @@ -18,8 +18,7 @@
extern void ofmem_map_pages(ucell phys, ucell virt, ucell size, ucell mode);
-typedef int (*translation_entry_cb)(ucell phys, ucell virt, - ucell size, ucell mode); +typedef int (*translation_entry_cb)(ucell phys, ucell virt, ucell size, ucell mode);
extern void ofmem_walk_boot_map(translation_entry_cb cb);
diff --git a/openbios-devel/include/libopenbios/ofmem.h b/openbios-devel/include/libopenbios/ofmem.h index 957f165..85c6912 100644 --- a/openbios-devel/include/libopenbios/ofmem.h +++ b/openbios-devel/include/libopenbios/ofmem.h @@ -147,9 +147,27 @@ void *mem_alloc(struct mem *t, int size, int align);
#elif defined(CONFIG_SPARC64)
+#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) + extern ucell *va2ttedata; extern unsigned long find_tte(unsigned long va);
+void itlb_load2(unsigned long vaddr, unsigned long tte_data); +void itlb_load3(unsigned long vaddr, unsigned long tte_data, unsigned long tte_index); +unsigned long itlb_faultva(void); +void itlb_demap(unsigned long vaddr); +void dtlb_load2(unsigned long vaddr, unsigned long tte_data); +void dtlb_load3(unsigned long vaddr, unsigned long tte_data, unsigned long tte_index); +unsigned long dtlb_faultva(void); +void dtlb_demap(unsigned long vaddr); + #endif
#ifdef PAGE_SHIFT
This cleans up the OFMEM interface by allowing us to keep all of the architecture-specific code in separate header files; in particular ofmem_sparc32.h and ofmem_sparc64.h. PPC doesn't reference the variables from ofmem.h outside of ofmem.c, so simply redefine them as static variables.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/ppc/qemu/ofmem.c | 4 +- openbios-devel/arch/sparc32/lib.c | 2 +- openbios-devel/arch/sparc32/ofmem_sparc32.c | 2 +- openbios-devel/arch/sparc64/lib.c | 2 +- openbios-devel/arch/sparc64/ofmem_sparc64.c | 2 +- openbios-devel/arch/sparc64/ofmem_sparc64.h | 31 ------------ openbios-devel/drivers/iommu.c | 2 +- .../include/arch/sparc32/ofmem_sparc32.h | 28 +++++++++++ .../include/arch/sparc64/ofmem_sparc64.h | 50 ++++++++++++++++++++ openbios-devel/include/libopenbios/ofmem.h | 43 ----------------- 10 files changed, 85 insertions(+), 81 deletions(-) delete mode 100644 openbios-devel/arch/sparc64/ofmem_sparc64.h create mode 100644 openbios-devel/include/arch/sparc32/ofmem_sparc32.h create mode 100644 openbios-devel/include/arch/sparc64/ofmem_sparc64.h
diff --git a/openbios-devel/arch/ppc/qemu/ofmem.c b/openbios-devel/arch/ppc/qemu/ofmem.c index fbade1e..25555a0 100644 --- a/openbios-devel/arch/ppc/qemu/ofmem.c +++ b/openbios-devel/arch/ppc/qemu/ofmem.c @@ -75,13 +75,13 @@ get_rom_base(void) return ofmem->ramsize - OF_CODE_SIZE; }
-unsigned long +static unsigned long get_ram_top(void) { return get_hash_base() - (32 + 64 + 64) * 1024 - OFMEM_SIZE; }
-unsigned long +static unsigned long get_ram_bottom(void) { return FREE_BASE; diff --git a/openbios-devel/arch/sparc32/lib.c b/openbios-devel/arch/sparc32/lib.c index 799399c..483069c 100644 --- a/openbios-devel/arch/sparc32/lib.c +++ b/openbios-devel/arch/sparc32/lib.c @@ -9,7 +9,7 @@
#include "libc/vsprintf.h" #include "libopenbios/bindings.h" -#include "libopenbios/ofmem.h" +#include "arch/sparc32/ofmem_sparc32.h" #include "asm/asi.h" #include "pgtsrmmu.h" #include "openprom.h" diff --git a/openbios-devel/arch/sparc32/ofmem_sparc32.c b/openbios-devel/arch/sparc32/ofmem_sparc32.c index 19d0d8e..20eab20 100644 --- a/openbios-devel/arch/sparc32/ofmem_sparc32.c +++ b/openbios-devel/arch/sparc32/ofmem_sparc32.c @@ -15,7 +15,7 @@ #include "config.h" #include "libopenbios/bindings.h" #include "libc/string.h" -#include "libopenbios/ofmem.h" +#include "arch/sparc32/ofmem_sparc32.h" #include "asm/asi.h" #include "pgtsrmmu.h"
diff --git a/openbios-devel/arch/sparc64/lib.c b/openbios-devel/arch/sparc64/lib.c index abcac9f..e9101af 100644 --- a/openbios-devel/arch/sparc64/lib.c +++ b/openbios-devel/arch/sparc64/lib.c @@ -14,7 +14,7 @@ #include "libopenbios/sys_info.h" #include "boot.h"
-#include "ofmem_sparc64.h" +#include "arch/sparc64/ofmem_sparc64.h"
/* Format a string and print it on the screen, just like the libc * function printf. diff --git a/openbios-devel/arch/sparc64/ofmem_sparc64.c b/openbios-devel/arch/sparc64/ofmem_sparc64.c index 5445d60..984eae4 100644 --- a/openbios-devel/arch/sparc64/ofmem_sparc64.c +++ b/openbios-devel/arch/sparc64/ofmem_sparc64.c @@ -15,7 +15,7 @@ #include "config.h" #include "libopenbios/bindings.h" #include "libc/string.h" -#include "ofmem_sparc64.h" +#include "arch/sparc64/ofmem_sparc64.h" #include "spitfire.h"
#define OF_MALLOC_BASE ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8)) diff --git a/openbios-devel/arch/sparc64/ofmem_sparc64.h b/openbios-devel/arch/sparc64/ofmem_sparc64.h deleted file mode 100644 index ad67f71..0000000 --- a/openbios-devel/arch/sparc64/ofmem_sparc64.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * <ofmem_sparc64.h> - * - * OF Memory manager - * - * Copyright (C) 1999, 2002 Samuel Rydh (samuel@ibrium.se) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation - * - */ - -#ifndef _H_OFMEM_SPARC64 -#define _H_OFMEM_SPARC64 - -#include "libopenbios/ofmem.h" - -extern void ofmem_map_pages(ucell phys, ucell virt, ucell size, ucell mode); - -typedef int (*translation_entry_cb)(ucell phys, ucell virt, ucell size, ucell mode); - -extern void ofmem_walk_boot_map(translation_entry_cb cb); - -extern translation_t **g_ofmem_translations; - -extern void dtlb_miss_handler(void); -extern void itlb_miss_handler(void); -extern void bug(void); - -#endif /* _H_OFMEM_SPARC64 */ diff --git a/openbios-devel/drivers/iommu.c b/openbios-devel/drivers/iommu.c index 47c6130..45005c1 100644 --- a/openbios-devel/drivers/iommu.c +++ b/openbios-devel/drivers/iommu.c @@ -8,7 +8,7 @@ #include "libopenbios/bindings.h" #include "drivers/drivers.h" #include "iommu.h" -#include "libopenbios/ofmem.h" +#include "arch/sparc32/ofmem_sparc32.h"
#ifdef CONFIG_DEBUG_IOMMU #define DPRINTF(fmt, args...) \ diff --git a/openbios-devel/include/arch/sparc32/ofmem_sparc32.h b/openbios-devel/include/arch/sparc32/ofmem_sparc32.h new file mode 100644 index 0000000..7a35b44 --- /dev/null +++ b/openbios-devel/include/arch/sparc32/ofmem_sparc32.h @@ -0,0 +1,28 @@ +/* + * <ofmem_sparc32.h> + * + * OF Memory manager + * + * Copyright (C) 1999, 2002 Samuel Rydh (samuel@ibrium.se) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation + * + */ + +#ifndef _H_OFMEM_SPARC32 +#define _H_OFMEM_SPARC32 + +#include "libopenbios/ofmem.h" + +struct mem; +extern struct mem cdvmem; + +extern unsigned long *l1; +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); + +#endif /* _H_OFMEM_SPARC32 */ \ No newline at end of file diff --git a/openbios-devel/include/arch/sparc64/ofmem_sparc64.h b/openbios-devel/include/arch/sparc64/ofmem_sparc64.h new file mode 100644 index 0000000..7ff24ae --- /dev/null +++ b/openbios-devel/include/arch/sparc64/ofmem_sparc64.h @@ -0,0 +1,50 @@ +/* + * <ofmem_sparc64.h> + * + * OF Memory manager + * + * Copyright (C) 1999, 2002 Samuel Rydh (samuel@ibrium.se) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation + * + */ + +#ifndef _H_OFMEM_SPARC64 +#define _H_OFMEM_SPARC64 + +#include "libopenbios/ofmem.h" + +#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) + +extern ucell *va2ttedata; +extern unsigned long find_tte(unsigned long va); + +void itlb_load2(unsigned long vaddr, unsigned long tte_data); +void itlb_load3(unsigned long vaddr, unsigned long tte_data, unsigned long tte_index); +unsigned long itlb_faultva(void); +void itlb_demap(unsigned long vaddr); +void dtlb_load2(unsigned long vaddr, unsigned long tte_data); +void dtlb_load3(unsigned long vaddr, unsigned long tte_data, unsigned long tte_index); +unsigned long dtlb_faultva(void); +void dtlb_demap(unsigned long vaddr); + +typedef int (*translation_entry_cb)(ucell phys, ucell virt, ucell size, ucell mode); + +extern void ofmem_walk_boot_map(translation_entry_cb cb); + +extern translation_t **g_ofmem_translations; + +extern void dtlb_miss_handler(void); +extern void itlb_miss_handler(void); +extern void bug(void); + +#endif /* _H_OFMEM_SPARC64 */ diff --git a/openbios-devel/include/libopenbios/ofmem.h b/openbios-devel/include/libopenbios/ofmem.h index 85c6912..ec21c2e 100644 --- a/openbios-devel/include/libopenbios/ofmem.h +++ b/openbios-devel/include/libopenbios/ofmem.h @@ -129,52 +129,9 @@ extern phandle_t s_phandle_mmu; /* Currently the same for all architectures */ #define PAGE_SHIFT 12
-#ifdef CONFIG_PPC -unsigned long get_ram_top( void ); -unsigned long get_ram_bottom( void ); - -#elif defined(CONFIG_SPARC32) - -/* arch/sparc32/lib.c */ -struct mem; -extern struct mem cdvmem; - -extern unsigned long *l1; -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) - -#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) - -extern ucell *va2ttedata; -extern unsigned long find_tte(unsigned long va); - -void itlb_load2(unsigned long vaddr, unsigned long tte_data); -void itlb_load3(unsigned long vaddr, unsigned long tte_data, unsigned long tte_index); -unsigned long itlb_faultva(void); -void itlb_demap(unsigned long vaddr); -void dtlb_load2(unsigned long vaddr, unsigned long tte_data); -void dtlb_load3(unsigned long vaddr, unsigned long tte_data, unsigned long tte_index); -unsigned long dtlb_faultva(void); -void dtlb_demap(unsigned long vaddr); - -#endif - -#ifdef PAGE_SHIFT #define PAGE_SIZE (1 << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE - 1)) #define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK) -#endif
#if defined(CONFIG_DEBUG_OFMEM) # define OFMEM_TRACE(fmt, ...) do { printk("OFMEM: " fmt, ## __VA_ARGS__); } while (0)
Now that we have OFMEM, as long as we have a PCI bus then we can configure the address of the framebuffer automatically without having an architecture-specific hack.
Similarly we can remove all reference to the video memory variables _vmem and _evmem since the memory is allocated outside of the OpenBIOS image.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc64/ldscript | 6 ------ openbios-devel/drivers/vga_vbe.c | 9 +-------- openbios-devel/include/arch/sparc64/io.h | 2 +- openbios-devel/packages/video.c | 4 ++-- 4 files changed, 4 insertions(+), 17 deletions(-)
diff --git a/openbios-devel/arch/sparc64/ldscript b/openbios-devel/arch/sparc64/ldscript index 11167c0..ace00e5 100644 --- a/openbios-devel/arch/sparc64/ldscript +++ b/openbios-devel/arch/sparc64/ldscript @@ -12,7 +12,6 @@ BASE_ADDR = 0x00000000ffd00000;
/* 16KB stack */ STACK_SIZE = 16384; -VMEM_SIZE = 128 * 1024; IOMEM_SIZE = 256 * 1024 + 768 * 1024;
SECTIONS @@ -51,11 +50,6 @@ SECTIONS *(.bss.*) *(COMMON)
- . = ALIGN(4096); - _vmem = .; - . += VMEM_SIZE; - _evmem = .; - _stack = .; . += STACK_SIZE; . = ALIGN(16); diff --git a/openbios-devel/drivers/vga_vbe.c b/openbios-devel/drivers/vga_vbe.c index 2c229b4..569e70d 100644 --- a/openbios-devel/drivers/vga_vbe.c +++ b/openbios-devel/drivers/vga_vbe.c @@ -133,7 +133,7 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, int depth = VGA_DEFAULT_DEPTH; int linebytes = VGA_DEFAULT_LINEBYTES;
-#if defined(CONFIG_QEMU) && (defined(CONFIG_PPC) || defined(CONFIG_SPARC64)) +#if defined(CONFIG_QEMU) && (defined(CONFIG_PPC) || defined(CONFIG_SPARC32) || defined(CONFIG_SPARC64)) int w, h, d; w = fw_cfg_read_i16(FW_CFG_ARCH_WIDTH); h = fw_cfg_read_i16(FW_CFG_ARCH_HEIGHT); @@ -144,13 +144,6 @@ void vga_vbe_init(const char *path, unsigned long fb, uint32_t fb_size, depth = d; linebytes = (width * ((depth + 7) / 8)); } -#ifdef CONFIG_SPARC64 -#define VGA_VADDR 0xfe000000 - ofmem_claim_phys(fb, fb_size, 0); - ofmem_claim_virt(VGA_VADDR, fb_size, 0); - ofmem_map(fb, VGA_VADDR, fb_size, 0x76); - fb = VGA_VADDR; -#endif #endif
vga_vbe_set_mode(width, height, depth); diff --git a/openbios-devel/include/arch/sparc64/io.h b/openbios-devel/include/arch/sparc64/io.h index 68d6121..2e4dfa3 100644 --- a/openbios-devel/include/arch/sparc64/io.h +++ b/openbios-devel/include/arch/sparc64/io.h @@ -9,7 +9,7 @@
extern unsigned long va_shift; // Set in entry.S // Defined in ldscript -extern char _start, _data, _stack, _estack, _end, _vmem, _evmem, _iomem; +extern char _start, _data, _stack, _estack, _end, _iomem;
// XXX check use and merge #define phys_to_virt(phys) ((void *) ((unsigned long) (phys))) diff --git a/openbios-devel/packages/video.c b/openbios-devel/packages/video.c index 9eddd0f..98b9d2a 100644 --- a/openbios-devel/packages/video.c +++ b/openbios-devel/packages/video.c @@ -312,7 +312,7 @@ void init_video( unsigned long fb, int width, int height, int depth, int rb ) { int i; -#ifdef CONFIG_PPC +#if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI) int s, size; #endif phandle_t ph=0; @@ -332,7 +332,7 @@ init_video( unsigned long fb, int width, int height, int depth, int rb ) video.has_video = 1; video.pal = malloc( 256 * sizeof(unsigned long) );
-#ifdef CONFIG_PPC +#if defined(CONFIG_OFMEM) && defined(CONFIG_DRIVER_PCI) s = (video.fb.mphys & 0xfff); size = ((video.fb.h * video.fb.rb + s) + 0xfff) & ~0xfff;
Instead of using our internal memory pool to run the Forth machine, allocate the memory using OFMEM. This enables us to dramatically increase the memory available to Forth clients whilst substantially reducing the memory requirement for the resulting image.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc64/ofmem_sparc64.c | 2 +- openbios-devel/arch/sparc64/openbios.c | 30 ++++++++++++++++++--------- 2 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/openbios-devel/arch/sparc64/ofmem_sparc64.c b/openbios-devel/arch/sparc64/ofmem_sparc64.c index 984eae4..50224e6 100644 --- a/openbios-devel/arch/sparc64/ofmem_sparc64.c +++ b/openbios-devel/arch/sparc64/ofmem_sparc64.c @@ -20,7 +20,7 @@
#define OF_MALLOC_BASE ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
-#define MEMSIZE ((256 + 512) * 1024) +#define MEMSIZE (128 * 1024) static union { char memory[MEMSIZE]; ofmem_t ofmem; diff --git a/openbios-devel/arch/sparc64/openbios.c b/openbios-devel/arch/sparc64/openbios.c index ab32a8f..607cba4 100644 --- a/openbios-devel/arch/sparc64/openbios.c +++ b/openbios-devel/arch/sparc64/openbios.c @@ -21,7 +21,8 @@ #include "../../drivers/timer.h" // XXX #define NO_QEMU_PROTOS #include "arch/common/fw_cfg.h" -#include "libopenbios/ofmem.h" +#include "arch/sparc64/ofmem_sparc64.h" +#include "spitfire.h"
#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
@@ -32,9 +33,7 @@ #define APB_SPECIAL_BASE 0x1fe00000000ULL #define APB_MEM_BASE 0x1ff00000000ULL
-#define MEMORY_SIZE (512*1024) /* 512K ram for hosted system */ - -static ucell *memory; +#define MEMORY_SIZE (1024*1024) /* 1M ram for hosted system */
// XXX #define NVRAM_SIZE 0x2000 @@ -553,17 +552,28 @@ void udelay(unsigned int usecs)
static void init_memory(void) { - memory = malloc(MEMORY_SIZE); - if (!memory) - printk("panic: not enough memory on host system.\n"); + phys_addr_t phys; + ucell virt; + + /* Claim the memory from OFMEM */ + phys = ofmem_claim_phys(-1, MEMORY_SIZE, PAGE_SIZE); + if (!phys) + printk("panic: not enough physical memory on host system.\n"); + + virt = ofmem_claim_virt(-1, MEMORY_SIZE, PAGE_SIZE); + if (!virt) + printk("panic: not enough virtual memory on host system.\n"); + + /* Generate the mapping (and lock translation into the TLBs) */ + ofmem_map(phys, virt, MEMORY_SIZE, ofmem_arch_default_translation_mode(phys) | SPITFIRE_TTE_LOCKED);
/* we push start and end of memory to the stack * so that it can be used by the forth word QUIT * to initialize the memory allocator */ - - PUSH((ucell)memory); - PUSH((ucell)memory + (ucell)MEMORY_SIZE); + + PUSH(virt); + PUSH(virt + MEMORY_SIZE); }
static void
Instead of using our internal memory pool to run the Forth machine, allocate the memory using OFMEM. This enables us to dramatically increase the memory available to Forth clients whilst reducing the memory requirement for the resulting image.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc32/ofmem_sparc32.c | 2 +- openbios-devel/arch/sparc32/openbios.c | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/openbios-devel/arch/sparc32/ofmem_sparc32.c b/openbios-devel/arch/sparc32/ofmem_sparc32.c index 20eab20..e2f4159 100644 --- a/openbios-devel/arch/sparc32/ofmem_sparc32.c +++ b/openbios-devel/arch/sparc32/ofmem_sparc32.c @@ -21,7 +21,7 @@
#define OF_MALLOC_BASE ((char*)OFMEM + ALIGN_SIZE(sizeof(ofmem_t), 8))
-#define MEMSIZE (384 * 1024) +#define MEMSIZE (256 * 1024) static union { char memory[MEMSIZE]; ofmem_t ofmem; diff --git a/openbios-devel/arch/sparc32/openbios.c b/openbios-devel/arch/sparc32/openbios.c index d5d453d..74a0da2 100644 --- a/openbios-devel/arch/sparc32/openbios.c +++ b/openbios-devel/arch/sparc32/openbios.c @@ -27,12 +27,10 @@ #include "arch/common/fw_cfg.h" #include "libopenbios/ofmem.h"
-#define MEMORY_SIZE (128*1024) /* 128K ram for hosted system */ +#define MEMORY_SIZE (1024*1024) /* 1M ram for hosted system */ #define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" #define FW_CFG_SUN4M_DEPTH (FW_CFG_ARCH_LOCAL + 0x00)
-static ucell *memory; - int qemu_machine_type;
struct hwdef { @@ -807,17 +805,28 @@ static void setup_stdio(void)
static void init_memory(void) { - memory = malloc(MEMORY_SIZE); - if (!memory) - printk("panic: not enough memory on host system.\n"); + phys_addr_t phys; + ucell virt; + + /* Claim the memory from OFMEM */ + phys = ofmem_claim_phys(-1, MEMORY_SIZE, PAGE_SIZE); + if (!phys) + printk("panic: not enough physical memory on host system.\n"); + + virt = ofmem_claim_virt(-1, MEMORY_SIZE, PAGE_SIZE); + if (!virt) + printk("panic: not enough virtual memory on host system.\n"); + + /* Generate the mapping (and lock translation into the TLBs) */ + ofmem_map(phys, virt, MEMORY_SIZE, ofmem_arch_default_translation_mode(phys));
/* we push start and end of memory to the stack * so that it can be used by the forth word QUIT * to initialize the memory allocator */ - - PUSH((ucell)memory); - PUSH((ucell)memory + MEMORY_SIZE); + + PUSH(virt); + PUSH(virt + MEMORY_SIZE); }
static void
On Fri, Apr 6, 2012 at 19:48, Mark Cave-Ayland mark.cave-ayland@ilande.co.uk wrote:
This patchset aims to tidy up various parts of OFMEM, with the ultimate aim of reducing the image sizes. The first 4 patches perform the reorganisation, while the remainder of the patches ensure that video memory and the Forth machine memory are no longer contained within the image.
Patches look OK. Coding style could be adjusted while moving the code and 'extern' is not useful in C for function prototypes.
Note: the resulting SPARC64 image is now approximately half of its original size - BUT because we require 512K alignment for various parts of the image because of the 512K MMU page size, our ability to claim this space back directly is limited. Any further ideas on this would be welcomed.
At least FSYS_BUF in grubfs could be dynamically allocated and/or shrunk, maybe some others also from this list: $ nm --size --size-sort obj-sparc64/openbios-builtin.elf.nostrip | egrep -v ' [tTrR] ' | tail 0000000000000100 b dp2.1303 0000000000000100 b file_descriptors 0000000000000100 b obio_cmdline 0000000000000118 d main_ctx 0000000000001000 B dstack 0000000000001000 B rstack 0000000000004000 b image_stack 0000000000008000 B FSYS_BUF 0000000000080000 d forth_dictionary 00000000000c0000 b s_ofmem_data
It wouldn't help here, but sections .text and .rodata could be merged, GCC already assumes that .text is readable. This would save one TLB entry since combined size is still < 512k.
Mark Cave-Ayland (8): Rename ofmem_arch_early_map_pages() to ofmem_arch_map_pages(). SPARC32: Move ofmem_arch_map_pages() into ofmem_sparc32.c with all the other architecture-specific code. SPARC64: Refactor tte-data code in preparation for moving architecture-specific code to ofmem_sparc64.c. SPARC64: Move ofmem_arch_map_pages()/ofmem_arch_unmap_pages() into ofmem_sparc64.c with all the other architecture-specific code. Remove architecture-specific routines from ofmem.h. SPARC64: Remove video initialisation hack. SPARC64: Swap Forth machine memory allocation over to OFMEM memory pool. SPARC32: Swap Forth machine memory allocation over to OFMEM memory pool.
openbios-devel/arch/ppc/ofmem.c | 2 +- openbios-devel/arch/ppc/qemu/ofmem.c | 6 +- openbios-devel/arch/sparc32/lib.c | 95 +--------- openbios-devel/arch/sparc32/ofmem_sparc32.c | 82 ++++++++- openbios-devel/arch/sparc32/openbios.c | 27 ++- openbios-devel/arch/sparc64/ldscript | 6 - openbios-devel/arch/sparc64/lib.c | 210 ++------------------ openbios-devel/arch/sparc64/ofmem_sparc64.c | 176 ++++++++++++++++- openbios-devel/arch/sparc64/ofmem_sparc64.h | 32 --- openbios-devel/arch/sparc64/openbios.c | 30 ++- openbios-devel/drivers/iommu.c | 4 +- openbios-devel/drivers/vga_vbe.c | 9 +- .../include/arch/sparc32/ofmem_sparc32.h | 28 +++ openbios-devel/include/arch/sparc64/io.h | 2 +- .../include/arch/sparc64/ofmem_sparc64.h | 50 +++++ openbios-devel/include/libopenbios/ofmem.h | 22 +-- openbios-devel/libopenbios/ofmem_common.c | 6 +- openbios-devel/packages/video.c | 4 +- 18 files changed, 405 insertions(+), 386 deletions(-) delete mode 100644 openbios-devel/arch/sparc64/ofmem_sparc64.h create mode 100644 openbios-devel/include/arch/sparc32/ofmem_sparc32.h create mode 100644 openbios-devel/include/arch/sparc64/ofmem_sparc64.h
-- 1.7.2.5
-- OpenBIOS http://openbios.org/ Mailinglist: http://lists.openbios.org/mailman/listinfo Free your System - May the Forth be with you
Hi Mark,
Am 06.04.2012 21:48, schrieb Mark Cave-Ayland:
This OFMEM call does actually map the page for the architectures that require it, so let's change its name so that we now have a symmetrical ofmem_arch_map_pages() and ofmem_arch_unmap_pages() API.
I don't really mind either way, assuming you've compile-tested it.
I would've assumed though and "early" indicates at which times in the code this function may be used?
Andreas
On 10/04/12 13:20, Andreas Färber wrote:
Hi Mark,
Am 06.04.2012 21:48, schrieb Mark Cave-Ayland:
This OFMEM call does actually map the page for the architectures that require it, so let's change its name so that we now have a symmetrical ofmem_arch_map_pages() and ofmem_arch_unmap_pages() API.
I don't really mind either way, assuming you've compile-tested it.
Sure, I've tested PPC with my patches applied and it seems to work - I notice though that PPC looks as if it already allocates it's Forth machine memory outside of the image - please correct me if I'm wrong? I'm not too familiar with the way the PPC MMU works with hash tables.
I would've assumed though and "early" indicates at which times in the code this function may be used?
Well, it's more interesting than that. For SPARC, when you map the memory it is first added to the translation_t linked list. The TLB miss handlers simply iterate over this list in order to find the mapping before continuing. Therefore when creating a mapping, since the translation_t list already contains the entry created by ofmem_map_page_range(), all the ofmem_arch_map_pages() function has to do is update any existing TLB entries.
Now I'm quite tempted to rename ofmem_map_page_range() to map_page_range() or similar and remove it from the public OFMEM API (only SPARC64 seems to use it) to make things a little clearer as to the difference between the two functions and also create the symmetry with unmap_page_range() in ofmem_common.c - what do you think?
ATB,
Mark.
On Tue, Apr 10, 2012 at 7:11 PM, Mark Cave-Ayland mark.cave-ayland@ilande.co.uk wrote:
On 10/04/12 13:20, Andreas Färber wrote:
Hi Mark,
Am 06.04.2012 21:48, schrieb Mark Cave-Ayland:
This OFMEM call does actually map the page for the architectures that require it, so let's change its name so that we now have a symmetrical ofmem_arch_map_pages() and ofmem_arch_unmap_pages() API.
I don't really mind either way, assuming you've compile-tested it.
Sure, I've tested PPC with my patches applied and it seems to work - I notice though that PPC looks as if it already allocates it's Forth machine memory outside of the image - please correct me if I'm wrong? I'm not too familiar with the way the PPC MMU works with hash tables.
I would've assumed though and "early" indicates at which times in the code this function may be used?
Well, it's more interesting than that. For SPARC, when you map the memory it is first added to the translation_t linked list. The TLB miss handlers simply iterate over this list in order to find the mapping before continuing. Therefore when creating a mapping, since the translation_t list already contains the entry created by ofmem_map_page_range(), all the ofmem_arch_map_pages() function has to do is update any existing TLB entries.
The "early" variant was intended to perform one-time injection of mapped pages that were acquired before c source code is entered so it was not safe to call common mapping routine yet. I was afraid to implement mapping code in assembly.