Path: blob/master/arch/mips/mti-malta/malta-memory.c
10817 views
/*1* Carsten Langgaard, [email protected]2* Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.3*4* This program is free software; you can distribute it and/or modify it5* under the terms of the GNU General Public License (Version 2) as6* published by the Free Software Foundation.7*8* This program is distributed in the hope it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* for more details.12*13* You should have received a copy of the GNU General Public License along14* with this program; if not, write to the Free Software Foundation, Inc.,15* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.16*17* PROM library functions for acquiring/using memory descriptors given to18* us from the YAMON.19*/20#include <linux/init.h>21#include <linux/mm.h>22#include <linux/bootmem.h>23#include <linux/pfn.h>24#include <linux/string.h>2526#include <asm/bootinfo.h>27#include <asm/page.h>28#include <asm/sections.h>2930#include <asm/mips-boards/prom.h>3132/*#define DEBUG*/3334enum yamon_memtypes {35yamon_dontuse,36yamon_prom,37yamon_free,38};39static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];4041#ifdef DEBUG42static char *mtypes[3] = {43"Dont use memory",44"YAMON PROM memory",45"Free memory",46};47#endif4849/* determined physical memory size, not overridden by command line args */50unsigned long physical_memsize = 0L;5152static struct prom_pmemblock * __init prom_getmdesc(void)53{54char *memsize_str;55unsigned int memsize;56char *ptr;57static char cmdline[COMMAND_LINE_SIZE] __initdata;5859/* otherwise look in the environment */60memsize_str = prom_getenv("memsize");61if (!memsize_str) {62printk(KERN_WARNING63"memsize not set in boot prom, set to default (32Mb)\n");64physical_memsize = 0x02000000;65} else {66#ifdef DEBUG67pr_debug("prom_memsize = %s\n", memsize_str);68#endif69physical_memsize = simple_strtol(memsize_str, NULL, 0);70}7172#ifdef CONFIG_CPU_BIG_ENDIAN73/* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last74word of physical memory */75physical_memsize -= PAGE_SIZE;76#endif7778/* Check the command line for a memsize directive that overrides79the physical/default amount */80strcpy(cmdline, arcs_cmdline);81ptr = strstr(cmdline, "memsize=");82if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))83ptr = strstr(ptr, " memsize=");8485if (ptr)86memsize = memparse(ptr + 8, &ptr);87else88memsize = physical_memsize;8990memset(mdesc, 0, sizeof(mdesc));9192mdesc[0].type = yamon_dontuse;93mdesc[0].base = 0x00000000;94mdesc[0].size = 0x00001000;9596mdesc[1].type = yamon_prom;97mdesc[1].base = 0x00001000;98mdesc[1].size = 0x000ef000;99100/*101* The area 0x000f0000-0x000fffff is allocated for BIOS memory by the102* south bridge and PCI access always forwarded to the ISA Bus and103* BIOSCS# is always generated.104* This mean that this area can't be used as DMA memory for PCI105* devices.106*/107mdesc[2].type = yamon_dontuse;108mdesc[2].base = 0x000f0000;109mdesc[2].size = 0x00010000;110111mdesc[3].type = yamon_dontuse;112mdesc[3].base = 0x00100000;113mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base;114115mdesc[4].type = yamon_free;116mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));117mdesc[4].size = memsize - mdesc[4].base;118119return &mdesc[0];120}121122static int __init prom_memtype_classify(unsigned int type)123{124switch (type) {125case yamon_free:126return BOOT_MEM_RAM;127case yamon_prom:128return BOOT_MEM_ROM_DATA;129default:130return BOOT_MEM_RESERVED;131}132}133134void __init prom_meminit(void)135{136struct prom_pmemblock *p;137138#ifdef DEBUG139pr_debug("YAMON MEMORY DESCRIPTOR dump:\n");140p = prom_getmdesc();141while (p->size) {142int i = 0;143pr_debug("[%d,%p]: base<%08lx> size<%08lx> type<%s>\n",144i, p, p->base, p->size, mtypes[p->type]);145p++;146i++;147}148#endif149p = prom_getmdesc();150151while (p->size) {152long type;153unsigned long base, size;154155type = prom_memtype_classify(p->type);156base = p->base;157size = p->size;158159add_memory_region(base, size, type);160p++;161}162}163164void __init prom_free_prom_memory(void)165{166unsigned long addr;167int i;168169for (i = 0; i < boot_mem_map.nr_map; i++) {170if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)171continue;172173addr = boot_mem_map.map[i].addr;174free_init_pages("prom memory",175addr, addr + boot_mem_map.map[i].size);176}177}178179180