summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-27 23:21:57 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-27 23:21:57 +0000
commit511bcd7c5924ce9e98ad1cb851988f7448dfef0f (patch)
tree6194d472814ef315450ee5fe190c3cbbdc762c49 /arch/mips
parent0a20dc624ae03f1acb9e72b704907f3b5c79cff9 (diff)
Bootmem fixes for IP22.
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/arc/memory.c108
-rw-r--r--arch/mips/mm/init.c19
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,