diff options
author | Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 1998-10-18 13:32:08 +0000 |
---|---|---|
committer | Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 1998-10-18 13:32:08 +0000 |
commit | 25a83c8ea51aa41db55dc9995479851c9802a9d9 (patch) | |
tree | 771e989f138b1824adedf1d9f146fc26267cbe3c /arch/mips/arc/memory.c | |
parent | c71fb12ee22941aa89fea27670b7d88992b253aa (diff) |
moved sgi/prom and made it a little bit more generic for ARC like firmwares
Diffstat (limited to 'arch/mips/arc/memory.c')
-rw-r--r-- | arch/mips/arc/memory.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/arch/mips/arc/memory.c b/arch/mips/arc/memory.c new file mode 100644 index 000000000..655446a01 --- /dev/null +++ b/arch/mips/arc/memory.c @@ -0,0 +1,144 @@ +/* + * memory.c: PROM library functions for acquiring/using memory descriptors + * given to us from the ARCS firmware. + * + * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) + * + * $Id: memory.c,v 1.2 1998/04/05 11:24:02 ralf Exp $ + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/mm.h> +#include <linux/swap.h> +#include <linux/config.h> + +#include <asm/sgialib.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/bootinfo.h> + +/* #define DEBUG */ + +__initfunc(struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr)) +{ + return romvec->get_mdesc(curr); +} + +#ifdef DEBUG /* convenient for debugging */ +#ifdef CONFIG_SGI +static char *mtypes[8] = { + "Exception Block", + "ARCS Romvec Page", + "Free/Contig RAM", + "Generic Free RAM", + "Bad Memory", + "Standlong Program Pages", + "ARCS Temp Storage Area", + "ARCS Permanent Storage Area" +}; +#else +static char *mtypes[8] = { + "Exception Block", + "SystemParameterBlock", + "FreeMemory", + "Bad Memory", + "LoadedProgram", + "FirmwareTemporary", + "FirmwarePermanent", + "FreeContigiuous" +#endif +#endif + +static struct prom_pmemblock prom_pblocks[PROM_MAX_PMEMBLOCKS]; + +__initfunc(struct prom_pmemblock *prom_getpblock_array(void)) +{ + return &prom_pblocks[0]; +} + +__initfunc(static void prom_setup_memupper(void)) +{ + struct prom_pmemblock *p, *highest; + + for(p = prom_getpblock_array(), highest = 0; p->size != 0; p++) { + if(p->base == 0xdeadbeef) + prom_printf("WHEEE, bogus pmemblock\n"); + if(!highest || p->base > highest->base) + highest = p; + } + mips_memory_upper = highest->base + highest->size; +#ifdef DEBUG + prom_printf("prom_setup_memupper: mips_memory_upper = %08lx\n", + mips_memory_upper); +#endif +} + +__initfunc(void prom_meminit(void)) +{ + struct linux_mdesc *p; + int totram; + int i = 0; + + p = prom_getmdesc(PROM_NULL_MDESC); +#ifdef DEBUG + prom_printf("ARCS MEMORY DESCRIPTOR dump:\n"); + 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); + i++; + } +#endif + p = prom_getmdesc(PROM_NULL_MDESC); + totram = 0; + i = 0; + while(p) { + if(p->type == free || p->type == fcontig) { + prom_pblocks[i].base = + ((p->base<<PAGE_SHIFT) + 0x80000000); + prom_pblocks[i].size = p->pages << PAGE_SHIFT; + totram += prom_pblocks[i].size; +#ifdef DEBUG + prom_printf("free_chunk[%d]: base=%08lx size=%d\n", + i, prom_pblocks[i].base, + prom_pblocks[i].size); +#endif + i++; + } + p = prom_getmdesc(p); + } + prom_pblocks[i].base = 0xdeadbeef; + prom_pblocks[i].size = 0; /* indicates last elem. of array */ + printk("PROMLIB: Total free ram %d bytes (%dK,%dMB)\n", + totram, (totram/1024), (totram/1024/1024)); + + /* Setup upper physical memory bound. */ + prom_setup_memupper(); +} + +/* Called from mem_init() to fixup the mem_map page settings. */ +__initfunc(void prom_fixup_mem_map(unsigned long start, unsigned long end)) +{ + struct prom_pmemblock *p; + int i, nents; + + /* Determine number of pblockarray entries. */ + p = prom_getpblock_array(); + for(i = 0; p[i].size; i++) + ; + nents = i; + while(start < end) { + for(i = 0; i < nents; i++) { + if((start >= (p[i].base)) && + (start < (p[i].base + p[i].size))) { + start = p[i].base + p[i].size; + start &= PAGE_MASK; + continue; + } + } + set_bit(PG_reserved, &mem_map[MAP_NR(start)].flags); + start += PAGE_SIZE; + } +} |