diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 23:21:57 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-27 23:21:57 +0000 |
commit | 511bcd7c5924ce9e98ad1cb851988f7448dfef0f (patch) | |
tree | 6194d472814ef315450ee5fe190c3cbbdc762c49 /arch/mips | |
parent | 0a20dc624ae03f1acb9e72b704907f3b5c79cff9 (diff) |
Bootmem fixes for IP22.
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/arc/memory.c | 108 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 19 |
2 files changed, 76 insertions, 51 deletions
diff --git a/arch/mips/arc/memory.c b/arch/mips/arc/memory.c index a3b02dc67..4582297c2 100644 --- a/arch/mips/arc/memory.c +++ b/arch/mips/arc/memory.c @@ -4,7 +4,7 @@ * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * - * $Id: memory.c,v 1.8 2000/01/17 23:32:46 ralf Exp $ + * $Id: memory.c,v 1.9 2000/01/27 01:05:23 ralf Exp $ */ #include <linux/init.h> #include <linux/kernel.h> @@ -24,9 +24,10 @@ extern char _end; -struct linux_mdesc * __init prom_getmdesc(struct linux_mdesc *curr) +struct linux_mdesc * __init +ArcGetMemoryDescriptor(struct linux_mdesc *Current) { - return romvec->get_mdesc(curr); + return romvec->get_mdesc(Current); } #ifdef DEBUG /* convenient for debugging */ @@ -54,7 +55,7 @@ static char *arc_mtypes[8] = { #define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc] #endif -static struct prom_pmemblock prom_pblocks[PROM_MAX_PMEMBLOCKS]; +static struct prom_pmemblock pblocks[PROM_MAX_PMEMBLOCKS]; #define MEMTYPE_DONTUSE 0 #define MEMTYPE_PROM 1 @@ -103,102 +104,125 @@ static inline int memtype_classify_arc (union linux_memtypes type) static int __init prom_memtype_classify (union linux_memtypes type) { if (prom_flags & PROM_FLAG_ARCS) /* SGI is ``different'' ... */ - return memtype_classify_arc(type); + return memtype_classify_arcs(type); return memtype_classify_arc(type); } -static unsigned long __init find_max_low_pfn(void) +static inline unsigned long find_max_low_pfn(void) { struct prom_pmemblock *p, *highest; + unsigned long pfn; - for (p = prom_pblocks, highest = 0; p->size != 0; p++) { + p = pblocks; + highest = 0; + while (p->size != 0) { if (!highest || p->base > highest->base) highest = p; + p++; } + + pfn = (highest->base + highest->size) >> PAGE_SHIFT; #ifdef DEBUG - prom_printf("find_max_low_pfn: mips_memory_upper = %08lx\n", highest); + prom_printf("find_max_low_pfn: 0x%lx pfns.\n", pfn); #endif - return (highest->base + highest->size) >> PAGE_SHIFT; + return pfn; } -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) -#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) +static inline struct prom_pmemblock *find_largest_memblock(void) +{ + struct prom_pmemblock *p, *largest; + + p = pblocks; + largest = 0; + while (p->size != 0) { + if (!largest || p->size > largest->size) + largest = p; + p++; + } + + return largest; +} void __init prom_meminit(void) { - unsigned long start_pfn; + struct prom_pmemblock *largest; + unsigned long bootmap_size; struct linux_mdesc *p; int totram; int i = 0; #ifdef DEBUG prom_printf("ARCS MEMORY DESCRIPTOR dump:\n"); - p = prom_getmdesc(PROM_NULL_MDESC); + p = ArcGetMemoryDescriptor(PROM_NULL_MDESC); while(p) { prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>\n", i, p, p->base, p->pages, mtypes(p->type)); - p = prom_getmdesc(p); + p = ArcGetMemoryDescriptor(p); i++; } #endif totram = 0; - p = prom_getmdesc(PROM_NULL_MDESC); i = 0; - while (p) { - prom_pblocks[i].type = prom_memtype_classify(p->type); - prom_pblocks[i].base = p->base << PAGE_SHIFT; - prom_pblocks[i].size = p->pages << PAGE_SHIFT; + p = PROM_NULL_MDESC; + while ((p = ArcGetMemoryDescriptor(p))) { + pblocks[i].type = prom_memtype_classify(p->type); + pblocks[i].base = p->base << PAGE_SHIFT; + pblocks[i].size = p->pages << PAGE_SHIFT; - switch (prom_pblocks[i].type) { + switch (pblocks[i].type) { case MEMTYPE_FREE: - totram += prom_pblocks[i].size; + totram += pblocks[i].size; #ifdef DEBUG - prom_printf("free_chunk[%d]: base=%08lx size=%d\n", - i, prom_pblocks[i].base, - prom_pblocks[i].size); + prom_printf("free_chunk[%d]: base=%08lx size=%x\n", + i, pblocks[i].base, + pblocks[i].size); #endif i++; break; case MEMTYPE_PROM: #ifdef DEBUG - prom_printf("prom_chunk[%d]: base=%08lx size=%d\n", - i, prom_pblocks[i].base, - prom_pblocks[i].size); + prom_printf("prom_chunk[%d]: base=%08lx size=%x\n", + i, pblocks[i].base, + pblocks[i].size); #endif i++; break; default: break; } - p = prom_getmdesc(p); } - prom_pblocks[i].size = 0; + pblocks[i].size = 0; - /* Setup upper physical memory bound. */ max_low_pfn = find_max_low_pfn(); + largest = find_largest_memblock(); + bootmap_size = init_bootmem(largest->base >> PAGE_SHIFT, max_low_pfn); - start_pfn = PFN_UP((unsigned long)&_end - PAGE_OFFSET); - init_bootmem(start_pfn, max_low_pfn); + for (i = 0; pblocks[i].size; i++) + if (pblocks[i].type == MEMTYPE_FREE) + free_bootmem(pblocks[i].base, pblocks[i].size); - for (i = 0; prom_pblocks[i].size; i++) - if (prom_pblocks[i].type == MEMTYPE_FREE) - free_bootmem(prom_pblocks[i].base, prom_pblocks[i].size); + /* This test is simpleminded. It will fail if the bootmem bitmap + falls into multiple adjacent ARC memory areas. */ + if (bootmap_size > largest->size) { + prom_printf("CRITIAL: overwriting PROM data.\n"); + BUG(); + } + reserve_bootmem(largest->base, bootmap_size); - printk("PROMLIB: Total free ram %d bytes (%dK,%dMB)\n", - totram, (totram/1024), (totram/1024/1024)); + printk("PROMLIB: Total free ram %dK / %dMB.\n", + totram >> 10, totram >> 20); } -void __init prom_free_prom_memory (void) +void __init +prom_free_prom_memory (void) { struct prom_pmemblock *p; unsigned long freed = 0; unsigned long addr; - for (p = prom_pblocks; p->size != 0; p++) { + for (p = pblocks; p->size != 0; p++) { if (p->type != MEMTYPE_PROM) continue; @@ -211,5 +235,5 @@ void __init prom_free_prom_memory (void) freed += PAGE_SIZE; } } - printk("Freeing prom memory: %ldk freed\n", freed >> 10); + printk("Freeing prom memory: %ldkb freed\n", freed >> 10); } diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index cf74a6dd5..20ff288ce 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.20 2000/01/26 00:07:44 ralf Exp $ +/* $Id: init.c,v 1.21 2000/01/27 01:05:23 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -259,7 +259,7 @@ extern int page_is_ram(unsigned long pagenr); void __init mem_init(void) { unsigned long codesize, reservedpages, datasize, initsize; - unsigned long tmp; + unsigned long tmp, nonram; max_mapnr = num_physpages = max_low_pfn; high_memory = (void *) __va(max_mapnr << PAGE_SHIFT); @@ -267,21 +267,22 @@ void __init mem_init(void) totalram_pages += free_all_bootmem(); totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */ - reservedpages = 0; + reservedpages = nonram = 0; for (tmp = 0; tmp < max_low_pfn; tmp++) - /* - * Only count resrved RAM pages - */ - if (page_is_ram(tmp) && PageReserved(mem_map+tmp)) - reservedpages++; + if (page_is_ram(tmp)) { + nonram++; + if (PageReserved(mem_map+tmp)) + reservedpages++; + } codesize = (unsigned long) &_etext - (unsigned long) &_ftext; datasize = (unsigned long) &_edata - (unsigned long) &_fdata; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; + printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, " "%ldk data, %ldk init)\n", (unsigned long) nr_free_pages << (PAGE_SHIFT-10), - max_mapnr << (PAGE_SHIFT-10), + (max_mapnr - nonram) << (PAGE_SHIFT-10), codesize >> 10, reservedpages << (PAGE_SHIFT-10), datasize >> 10, |