diff options
-rw-r--r-- | arch/mips/arc/cmdline.c | 4 | ||||
-rw-r--r-- | arch/mips/arc/memory.c | 133 | ||||
-rw-r--r-- | arch/mips/baget/prom/init.c | 8 | ||||
-rw-r--r-- | arch/mips/ddb5074/prom.c | 31 | ||||
-rw-r--r-- | arch/mips/ddb5074/setup.c | 5 | ||||
-rw-r--r-- | arch/mips/dec/prom/cmdline.c | 4 | ||||
-rw-r--r-- | arch/mips/dec/prom/memory.c | 56 | ||||
-rw-r--r-- | arch/mips/jazz/Makefile | 5 | ||||
-rw-r--r-- | arch/mips/jazz/setup.c | 8 | ||||
-rw-r--r-- | arch/mips/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/mips/kernel/setup.c | 228 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 26 | ||||
-rw-r--r-- | arch/mips/sgi/kernel/setup.c | 9 | ||||
-rw-r--r-- | arch/mips/sni/setup.c | 5 | ||||
-rw-r--r-- | include/asm-mips/bootinfo.h | 29 | ||||
-rw-r--r-- | include/asm-mips/sgialib.h | 19 |
16 files changed, 327 insertions, 247 deletions
diff --git a/arch/mips/arc/cmdline.c b/arch/mips/arc/cmdline.c index ba356e65d..e6f348384 100644 --- a/arch/mips/arc/cmdline.c +++ b/arch/mips/arc/cmdline.c @@ -2,8 +2,6 @@ * cmdline.c: Kernel command line creation using ARCS argc/argv. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: cmdline.c,v 1.1 1998/10/18 13:32:08 tsbogend Exp $ */ #include <linux/init.h> #include <linux/kernel.h> @@ -14,7 +12,7 @@ #undef DEBUG_CMDLINE -char arcs_cmdline[CL_SIZE]; +char arcs_cmdline[COMMAND_LINE_SIZE]; char * __init prom_getcmdline(void) { diff --git a/arch/mips/arc/memory.c b/arch/mips/arc/memory.c index 7988cfc39..73b692e1d 100644 --- a/arch/mips/arc/memory.c +++ b/arch/mips/arc/memory.c @@ -3,8 +3,6 @@ * given to us from the ARCS firmware. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) - * - * $Id: memory.c,v 1.10 2000/01/27 23:21:57 ralf Exp $ */ #include <linux/init.h> #include <linux/kernel.h> @@ -47,31 +45,25 @@ static char *arc_mtypes[8] = { "LoadedProgram", "FirmwareTemporary", "FirmwarePermanent", - "FreeContigiuous" + "FreeContiguous" }; #define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] : arc_mtypes[a.arc] #endif -static struct prom_pmemblock pblocks[PROM_MAX_PMEMBLOCKS]; - -#define MEMTYPE_DONTUSE 0 -#define MEMTYPE_PROM 1 -#define MEMTYPE_FREE 2 - static inline int memtype_classify_arcs (union linux_memtypes type) { switch (type.arcs) { case arcs_fcontig: case arcs_free: - return MEMTYPE_FREE; + return BOOT_MEM_RAM; case arcs_atmp: - return MEMTYPE_PROM; + return BOOT_MEM_ROM_DATA; case arcs_eblock: case arcs_rvpage: case arcs_bmem: case arcs_prog: case arcs_aperm: - return MEMTYPE_DONTUSE; + return BOOT_MEM_RESERVED; default: BUG(); } @@ -83,15 +75,15 @@ static inline int memtype_classify_arc (union linux_memtypes type) switch (type.arc) { case arc_free: case arc_fcontig: - return MEMTYPE_FREE; + return BOOT_MEM_RAM; case arc_atmp: - return MEMTYPE_PROM; + return BOOT_MEM_ROM_DATA; case arc_eblock: case arc_rvpage: case arc_bmem: case arc_prog: case arc_aperm: - return MEMTYPE_DONTUSE; + return BOOT_MEM_RESERVED; default: BUG(); } @@ -106,50 +98,13 @@ static int __init prom_memtype_classify (union linux_memtypes type) return memtype_classify_arc(type); } -static inline unsigned long find_max_low_pfn(void) -{ - struct prom_pmemblock *p, *highest; - unsigned long pfn; - - 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: 0x%lx pfns.\n", pfn); -#endif - return pfn; -} - -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) { - struct prom_pmemblock *largest; - unsigned long bootmap_size; struct linux_mdesc *p; - int totram; - int i = 0; #ifdef DEBUG + int i = 0; + prom_printf("ARCS MEMORY DESCRIPTOR dump:\n"); p = ArcGetMemoryDescriptor(PROM_NULL_MDESC); while(p) { @@ -160,77 +115,37 @@ void __init prom_meminit(void) } #endif - totram = 0; - i = 0; 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; + unsigned long base, size; + long type; - switch (pblocks[i].type) { - case MEMTYPE_FREE: - totram += pblocks[i].size; -#ifdef DEBUG - 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=%x\n", - i, pblocks[i].base, - pblocks[i].size); -#endif - i++; - break; - default: - break; - } - } - pblocks[i].size = 0; - - max_low_pfn = find_max_low_pfn(); - - largest = find_largest_memblock(); - bootmap_size = init_bootmem(largest->base >> PAGE_SHIFT, max_low_pfn); - - for (i = 0; pblocks[i].size; i++) - if (pblocks[i].type == MEMTYPE_FREE) - free_bootmem(pblocks[i].base, pblocks[i].size); + base = __pa(p->base << PAGE_SHIFT); /* Fix up from KSEG0 */ + size = p->pages << PAGE_SHIFT; + type = prom_memtype_classify(p->type); - /* 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(); + add_memory_region(base, pages, type); } - - /* Reserve the memory bootmap itself */ - reserve_bootmem(largest->base, bootmap_size); - - printk("PROMLIB: Total free ram %dK / %dMB.\n", - totram >> 10, totram >> 20); } void __init prom_free_prom_memory (void) { + int i; struct prom_pmemblock *p; unsigned long freed = 0; unsigned long addr; - for (p = pblocks; p->size != 0; p++) { - if (p->type != MEMTYPE_PROM) + for (i = 0; i < boot_mem_map.nr_map; i++) { + if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA) continue; - addr = PAGE_OFFSET + p->base; - while (addr < p->base + p->size) { - ClearPageReserved(virt_to_page(addr)); - set_page_count(virt_to_page(addr), 1); - free_page(addr); + addr = boot_mem_map.map[i].addr; + while (addr < boot_mem_map.map[i].addr + + boot_mem_map.map[i].size) { + ClearPageReserved(virt_to_page(__va(addr))); + set_page_count(virt_to_page(__va(addr)), 1); + free_page(__va(addr)); addr += PAGE_SIZE; freed += PAGE_SIZE; } diff --git a/arch/mips/baget/prom/init.c b/arch/mips/baget/prom/init.c index a87c004ec..02fcc5b92 100644 --- a/arch/mips/baget/prom/init.c +++ b/arch/mips/baget/prom/init.c @@ -2,13 +2,11 @@ * init.c: PROM library initialisation code. * * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov - * - * $Id: init.c,v 1.3 1999/10/09 00:00:57 ralf Exp $ */ #include <linux/init.h> #include <asm/bootinfo.h> -char arcs_cmdline[CL_SIZE]; +char arcs_cmdline[COMMAND_LINE_SIZE]; int __init prom_init(unsigned int mem_upper) { @@ -19,10 +17,6 @@ int __init prom_init(unsigned int mem_upper) return 0; } -void __init prom_fixup_mem_map(unsigned long start, unsigned long end) -{ -} - void prom_free_prom_memory (void) { } diff --git a/arch/mips/ddb5074/prom.c b/arch/mips/ddb5074/prom.c index 0c580d48b..832f8a675 100644 --- a/arch/mips/ddb5074/prom.c +++ b/arch/mips/ddb5074/prom.c @@ -13,19 +13,11 @@ #include <asm/bootinfo.h> -char arcs_cmdline[CL_SIZE]; - -extern char _end; - -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) - +char arcs_cmdline[COMMAND_LINE_SIZE]; void __init prom_init(const char *s) { int i = 0; - unsigned long mem_size, free_start, free_end, start_pfn, - bootmap_size; // _serinit(); @@ -36,26 +28,9 @@ void __init prom_init(const char *s) mips_machgroup = MACH_GROUP_NEC_DDB; mips_machtype = MACH_NEC_DDB5074; - /* 64 MB non-upgradable */ - mem_size = 64 << 20; - - free_start = PHYSADDR(PFN_ALIGN(&_end)); - free_end = mem_size; - start_pfn = PFN_UP((unsigned long) &_end); - /* - * Register all the contiguous memory with the bootmem allocator - * and free it. Be careful about the bootmem freemap. - */ - bootmap_size = init_bootmem(start_pfn, mem_size >> PAGE_SHIFT); - - /* Free the entire available memory after the _end symbol. */ - free_start += bootmap_size; - free_bootmem(free_start, free_end - free_start); -} - -void __init prom_fixup_mem_map(unsigned long start, unsigned long end) -{ + /* 64 MB non-upgradable */ + add_memory_region(0, 64 << 20, BOOT_MEM_RAM); } void __init prom_free_prom_memory(void) diff --git a/arch/mips/ddb5074/setup.c b/arch/mips/ddb5074/setup.c index 3b75d6b04..d8cc518de 100644 --- a/arch/mips/ddb5074/setup.c +++ b/arch/mips/ddb5074/setup.c @@ -118,11 +118,6 @@ void __init ddb_setup(void) panic_timeout = 180; } -int __init page_is_ram(unsigned long pagenr) -{ - return 1; -} - #define USE_NILE4_SERIAL 0 diff --git a/arch/mips/dec/prom/cmdline.c b/arch/mips/dec/prom/cmdline.c index 27b31818a..d6d3db18f 100644 --- a/arch/mips/dec/prom/cmdline.c +++ b/arch/mips/dec/prom/cmdline.c @@ -2,8 +2,6 @@ * cmdline.c: read the command line passed to us by the PROM. * * Copyright (C) 1998 Harald Koerfgen - * - * $Id: cmdline.c,v 1.2 1999/10/09 00:00:57 ralf Exp $ */ #include <linux/init.h> #include <linux/kernel.h> @@ -19,7 +17,7 @@ extern int (*prom_printf)(char *, ...); #endif -char arcs_cmdline[CL_SIZE]; +char arcs_cmdline[COMMAND_LINE_SIZE]; void __init prom_init_cmdline(int argc, char **argv, unsigned long magic) { diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c index e54e78a25..6c6b97d10 100644 --- a/arch/mips/dec/prom/memory.c +++ b/arch/mips/dec/prom/memory.c @@ -2,6 +2,7 @@ * memory.c: memory initialisation code. * * Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine + * Copyright (C) 2000 Maciej W. Rozycki * * $Id: memory.c,v 1.3 1999/10/09 00:00:58 ralf Exp $ */ @@ -14,6 +15,8 @@ #include <asm/addrspace.h> #include <asm/page.h> +#include <asm/bootinfo.h> + #include <asm/dec/machtype.h> #include "prom.h" @@ -33,11 +36,6 @@ extern int (*prom_printf)(char *, ...); volatile unsigned long mem_err = 0; /* So we know an error occured */ -extern char _end; - -#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) - /* * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen * off the end of real memory. Only suitable for the 2100/3100's (PMAX). @@ -45,7 +43,7 @@ extern char _end; #define CHUNK_SIZE 0x400000 -unsigned long __init pmax_get_memory_size(void) +static void __init pmax_setup_memory_region(void) { volatile unsigned char *memory_page, dummy; char old_handler[0x80]; @@ -66,17 +64,19 @@ unsigned long __init pmax_get_memory_size(void) dummy = *memory_page; } memcpy((void *)(KSEG0 + 0x80), &old_handler, 0x80); - return (unsigned long)memory_page - KSEG1 - CHUNK_SIZE; + + add_memory_region(0, (unsigned long)memory_page - KSEG1 - CHUNK_SIZE, + BOOT_MEM_RAM); } /* * Use the REX prom calls to get hold of the memory bitmap, and thence * determine memory size. */ -unsigned long __init rex_get_memory_size(void) +static void __init rex_setup_memory_region(void) { int i, bitmap_size; - unsigned long mem_size = 0; + unsigned long mem_start = 0, mem_size = 0; memmap *bm; /* some free 64k */ @@ -88,40 +88,24 @@ unsigned long __init rex_get_memory_size(void) /* FIXME: very simplistically only add full sets of pages */ if (bm->bitmap[i] == 0xff) mem_size += (8 * bm->pagesize); + else if (!mem_size) + mem_start += (8 * bm->pagesize); + else { + add_memory_region(mem_start, mem_size, BOOT_MEM_RAM); + mem_start += mem_size + (8 * bm->pagesize); + mem_size = 0; + } } - - return (mem_size); + if (mem_size) + add_memory_region(mem_start, mem_size, BOOT_MEM_RAM); } void __init prom_meminit(unsigned int magic) { - unsigned long free_start, free_end, start_pfn, bootmap_size; - unsigned long mem_size = 0; - if (magic != REX_PROM_MAGIC) - mem_size = pmax_get_memory_size(); + pmax_setup_memory_region(); else - mem_size = rex_get_memory_size(); - - free_start = PHYSADDR(PFN_ALIGN(&_end)); - free_end = mem_size; - start_pfn = PFN_UP((unsigned long)&_end); - -#ifdef PROM_DEBUG - prom_printf("free_start: 0x%08x\n", free_start); - prom_printf("free_end: 0x%08x\n", free_end); - prom_printf("start_pfn: 0x%08x\n", start_pfn); -#endif - - /* Register all the contiguous memory with the bootmem allocator - and free it. Be careful about the bootmem freemap. */ - bootmap_size = init_bootmem(start_pfn, mem_size >> PAGE_SHIFT); - free_bootmem(free_start + bootmap_size, free_end - free_start - bootmap_size); -} - -int __init page_is_ram(unsigned long pagenr) -{ - return 1; + rex_setup_memory_region(); } void prom_free_prom_memory (void) diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile index 3b3e83e96..03f6259f4 100644 --- a/arch/mips/jazz/Makefile +++ b/arch/mips/jazz/Makefile @@ -1,4 +1,3 @@ -# $Id: Makefile,v 1.5 1999/01/03 17:50:47 ralf Exp $ # # Makefile for the Jazz family specific parts of the kernel # @@ -8,9 +7,9 @@ # .S.s: - $(CPP) $(CFLAGS) $< -o $*.s + $(CPP) $(CFLAGS) $< -o $@ .S.o: - $(CC) $(CFLAGS) -c $< -o $*.o + $(CC) $(CFLAGS) -c $< -o $@ all: jazz.o O_TARGET := jazz.o diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index a16ce7b69..91d2f176b 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c @@ -1,5 +1,4 @@ -/* $Id: setup.c,v 1.24 1999/10/09 00:00:58 ralf Exp $ - * +/* * Setup pointers to hardware-dependent routines. * * This file is subject to the terms and conditions of the GNU General Public @@ -80,11 +79,6 @@ static void __init jazz_irq_setup(void) i8259_setup_irq(2, &irq2); } -int __init page_is_ram(unsigned long pagenr) -{ - return 1; -} - void __init jazz_setup(void) { add_wired_entry (0x02000017, 0x03c00017, 0xe0000000, PM_64K); diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 88e233919..bdb8bc727 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -6,8 +6,10 @@ # unless it's something special (ie not a .c file). # +.S.s: + $(CPP) $(AFLAGS) $< -o $@ .S.o: - $(CC) $(CFLAGS) -c $< -o $*.o + $(CC) $(AFLAGS) -c $< -o $@ all: kernel.o head.o init_task.o EXTRA_ASFLAGS = -mips3 -mcpu=r4000 diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 1a679e64a..08ceb6758 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -6,6 +6,7 @@ * Copyright (C) 1995 Linus Torvalds * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 Ralf Baechle * Copyright (C) 1996 Stoned Elipot + * Copyright (C) 2000 Maciej W. Rozycki */ #include <linux/config.h> #include <linux/errno.h> @@ -99,12 +100,14 @@ unsigned long mips_memory_upper = KSEG0; /* this is set by kernel_entry() */ unsigned long mips_machtype = MACH_UNKNOWN; unsigned long mips_machgroup = MACH_GROUP_UNKNOWN; +struct boot_mem_map boot_mem_map; + unsigned char aux_device_present; -extern int _end; +extern char _ftext, _etext, _fdata, _edata, _end; -static char command_line[CL_SIZE] = { 0, }; - char saved_command_line[CL_SIZE]; -extern char arcs_cmdline[CL_SIZE]; +static char command_line[COMMAND_LINE_SIZE]; + char saved_command_line[COMMAND_LINE_SIZE]; +extern char arcs_cmdline[COMMAND_LINE_SIZE]; /* * The board specific setup routine sets irq_setup to point to a board @@ -130,6 +133,9 @@ extern void loadmmu(void); extern asmlinkage void start_kernel(void); extern int prom_init(int, char **, char **, int *); +static struct resource code_resource = { "Kernel code" }; +static struct resource data_resource = { "Kernel data" }; + /* * Probe whether cpu has config register by trying to play with * alternate cache bit and see whether it matters. @@ -341,6 +347,97 @@ static void __init default_irq_setup(void) panic("Unknown machtype in init_IRQ"); } +void __init add_memory_region(unsigned long start, unsigned long size, + long type) +{ + int x = boot_mem_map.nr_map; + + if (x == BOOT_MEM_MAP_MAX) { + printk("Ooops! Too many entries in the memory map!\n"); + return; + } + + boot_mem_map.map[x].addr = start; + boot_mem_map.map[x].size = size; + boot_mem_map.map[x].type = type; + boot_mem_map.nr_map++; +} + +static void __init print_memory_map(void) +{ + int i; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + printk(" memory: %08lx @ %08lx ", + boot_mem_map.map[i].size, boot_mem_map.map[i].addr); + switch (boot_mem_map.map[i].type) { + case BOOT_MEM_RAM: + printk("(usable)\n"); + break; + case BOOT_MEM_ROM_DATA: + printk("(ROM data)\n"); + break; + case BOOT_MEM_RESERVED: + printk("(reserved)\n"); + break; + default: + printk("type %lu\n", boot_mem_map.map[i].type); + break; + } + } +} + +static inline void parse_mem_cmdline(void) +{ + char c = ' ', *to = command_line, *from = saved_command_line; + unsigned long start_at, mem_size; + int len = 0; + int usermem = 0; + + printk("Determined physical RAM map:\n"); + print_memory_map(); + + for (;;) { + /* + * "mem=XXX[kKmM]" defines a memory region from + * 0 to <XXX>, overriding the determined size. + * "mem=XXX[KkmM]@YYY[KkmM]" defines a memory region from + * <YYY> to <YYY>+<XXX>, overriding the determined size. + */ + if (c == ' ' && !memcmp(from, "mem=", 4)) { + if (to != command_line) + to--; + /* + * If a user specifies memory size, we + * blow away any automatically generated + * size. + */ + if (usermem == 0) { + boot_mem_map.nr_map = 0; + usermem = 1; + } + mem_size = memparse(from + 4, &from); + if (*from == '@') + start_at = memparse(from + 1, &from); + else + start_at = 0; + add_memory_region(start_at, mem_size, BOOT_MEM_RAM); + } + c = *(from++); + if (!c) + break; + if (COMMAND_LINE_SIZE <= ++len) + break; + *(to++) = c; + } + *to = '\0'; + + if (usermem) { + printk("User-defined physical RAM map:\n"); + print_memory_map(); + } +} + void __init setup_arch(char **cmdline_p) { void baget_setup(void); @@ -355,6 +452,10 @@ void __init setup_arch(char **cmdline_p) void atlas_setup(void); void malta_setup(void); + unsigned long bootmap_size; + unsigned long start_pfn, max_pfn; + int i; + /* Save defaults for configuration-dependent routines. */ irq_setup = default_irq_setup; @@ -434,12 +535,88 @@ void __init setup_arch(char **cmdline_p) panic("Unsupported architecture"); } - strncpy (command_line, arcs_cmdline, CL_SIZE); - memcpy(saved_command_line, command_line, CL_SIZE); - saved_command_line[CL_SIZE-1] = '\0'; - + strncpy(command_line, arcs_cmdline, sizeof command_line); + command_line[sizeof command_line - 1] = 0; + strcpy(saved_command_line, command_line); *cmdline_p = command_line; + parse_mem_cmdline(); + +#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) + + /* + * Partially used pages are not usable - thus + * we are rounding upwards. + */ + start_pfn = PFN_UP(__pa(&_end)); + + /* Find the highest page frame number we have available. */ + max_pfn = 0; + for (i = 0; i < boot_mem_map.nr_map; i++) { + unsigned long start, end; + + if (boot_mem_map.map[i].type != BOOT_MEM_RAM) + continue; + + start = PFN_UP(boot_mem_map.map[i].addr); + end = PFN_DOWN(boot_mem_map.map[i].addr + + boot_mem_map.map[i].size); + + if (start >= end) + continue; + if (end > max_pfn) + max_pfn = end; + } + + /* Initialize the boot-time allocator. */ + bootmap_size = init_bootmem(start_pfn, max_pfn); + + /* + * Register fully available low RAM pages with the bootmem allocator. + */ + for (i = 0; i < boot_mem_map.nr_map; i++) { + unsigned long curr_pfn, last_pfn, size; + + /* + * Reserve usable memory. + */ + if (boot_mem_map.map[i].type != BOOT_MEM_RAM) + continue; + + /* + * We are rounding up the start address of usable memory: + */ + curr_pfn = PFN_UP(boot_mem_map.map[i].addr); + if (curr_pfn >= max_pfn) + continue; + if (curr_pfn < start_pfn) + curr_pfn = start_pfn; + + /* + * ... and at the end of the usable range downwards: + */ + last_pfn = PFN_DOWN(boot_mem_map.map[i].addr + + boot_mem_map.map[i].size); + + if (last_pfn > max_pfn) + last_pfn = max_pfn; + + /* + * ... finally, did all the rounding and playing + * around just make the area go away? + */ + if (last_pfn <= curr_pfn) + continue; + + size = last_pfn - curr_pfn; + free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); + } + + /* Reserve the bootmap memory. */ + reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size); + #if 0 #ifdef CONFIG_BLK_DEV_INITRD #error "Fixme, I'm broken." @@ -463,6 +640,41 @@ void __init setup_arch(char **cmdline_p) #endif /* 0 */ paging_init(); + + code_resource.start = virt_to_bus(&_ftext); + code_resource.end = virt_to_bus(&_etext) - 1; + data_resource.start = virt_to_bus(&_fdata); + data_resource.end = virt_to_bus(&_edata) - 1; + + /* + * Request address space for all standard RAM. + */ + for (i = 0; i < boot_mem_map.nr_map; i++) { + struct resource *res; + + res = alloc_bootmem(sizeof(struct resource)); + switch (boot_mem_map.map[i].type) { + case BOOT_MEM_RAM: + case BOOT_MEM_ROM_DATA: + res->name = "System RAM"; + break; + case BOOT_MEM_RESERVED: + default: + res->name = "reserved"; + } + res->start = boot_mem_map.map[i].addr; + res->end = res->start + boot_mem_map.map[i].size - 1; + res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; + request_resource(&iomem_resource, res); + + /* + * We dont't know which RAM region contains kernel data, + * so we try it repeatedly and let the resource manager + * test it. + */ + request_resource(res, &code_resource); + request_resource(res, &data_resource); + } } void r3081_wait(void) diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index c632eee00..7035b1574 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -41,7 +41,6 @@ static unsigned long totalram_pages; -extern void prom_fixup_mem_map(unsigned long start, unsigned long end); extern void prom_free_prom_memory(void); @@ -271,7 +270,30 @@ void __init paging_init(void) free_area_init(zones_size); } -extern int page_is_ram(unsigned long pagenr); +#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) + +static inline int page_is_ram(unsigned long pagenr) +{ + int i; + + for (i = 0; i < boot_mem_map.nr_map; i++) { + unsigned long addr, end; + + if (boot_mem_map.map[i].type != BOOT_MEM_RAM) + /* not usable memory */ + continue; + + addr = PFN_UP(boot_mem_map.map[i].addr); + end = PFN_DOWN(boot_mem_map.map[i].addr + + boot_mem_map.map[i].size); + + if (pagenr >= addr && pagenr < end) + return 1; + } + + return 0; +} void __init mem_init(void) { diff --git a/arch/mips/sgi/kernel/setup.c b/arch/mips/sgi/kernel/setup.c index 4c533b131..13ed88c45 100644 --- a/arch/mips/sgi/kernel/setup.c +++ b/arch/mips/sgi/kernel/setup.c @@ -128,15 +128,6 @@ static void __init sgi_irq_setup(void) #endif } -int __init page_is_ram(unsigned long pagenr) -{ - if ((pagenr<<PAGE_SHIFT) < 0x2000UL) - return 1; - if ((pagenr<<PAGE_SHIFT) > 0x08002000) - return 1; - return 0; -} - void (*board_time_init)(struct irqaction *irq); static unsigned long dosample(volatile unsigned char *tcwp, diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index db053720c..e4f38ae7b 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c @@ -75,11 +75,6 @@ static inline void sni_pcimt_detect(void) printk("%s.\n", boardtype); } -int __init page_is_ram(unsigned long pagenr) -{ - return 1; -} - void __init sni_rm200_pci_setup(void) { sni_pcimt_detect(); diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index a966c37d9..2e60500b4 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -170,9 +170,14 @@ "R5000A", "R4640", "Nevada", "RM7000", "R5432", "MIPS 4Kc", \ "MIPS 5Kc", "R4310" } -#define CL_SIZE (255) +#define COMMAND_LINE_SIZE 256 -#ifndef _LANGUAGE_ASSEMBLY +#define BOOT_MEM_MAP_MAX 32 +#define BOOT_MEM_RAM 1 +#define BOOT_MEM_ROM_DATA 2 +#define BOOT_MEM_RESERVED 3 + +#ifndef __ASSEMBLY__ /* * Some machine parameters passed by the bootloaders. @@ -206,6 +211,24 @@ extern unsigned long mips_machtype; extern unsigned long mips_machgroup; extern unsigned long mips_tlb_entries; -#endif /* _LANGUAGE_ASSEMBLY */ +/* + * A memory map that's built upon what was determined + * or specified on the command line. + */ +struct boot_mem_map { + int nr_map; + struct { + unsigned long addr; /* start of memory segment */ + unsigned long size; /* size of memory segment */ + long type; /* type of memory segment */ + } map[BOOT_MEM_MAP_MAX]; +}; + +extern struct boot_mem_map boot_mem_map; + +extern void add_memory_region(unsigned long start, unsigned long size, + long type); + +#endif /* !__ASSEMBLY__ */ #endif /* _ASM_BOOTINFO_H */ diff --git a/include/asm-mips/sgialib.h b/include/asm-mips/sgialib.h index 8a9e2f49e..3c59e224b 100644 --- a/include/asm-mips/sgialib.h +++ b/include/asm-mips/sgialib.h @@ -1,9 +1,8 @@ -/* $Id: sgialib.h,v 1.5 2000/03/19 01:28:58 ralf Exp $ +/* * sgialib.h: SGI ARCS firmware interface library for the Linux kernel. * * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) */ - #ifndef _ASM_SGIALIB_H #define _ASM_SGIALIB_H @@ -30,28 +29,12 @@ extern char prom_getchar(void); /* Generic printf() using ARCS console I/O. */ extern void prom_printf(char *fmt, ...); -/* Memory descriptor management. */ -#define PROM_MAX_PMEMBLOCKS 32 -struct prom_pmemblock { - unsigned long base; /* Within KSEG0. */ - unsigned int size; /* In bytes. */ - unsigned int type; /* free or prom memory */ -}; - -/* Get next memory descriptor after CURR, returns first descriptor - * in chain is CURR is NULL. - */ -extern struct linux_mdesc *prom_getmdesc(struct linux_mdesc *curr); #define PROM_NULL_MDESC ((struct linux_mdesc *) 0) /* Called by prom_init to setup the physical memory pmemblock * array. */ extern void prom_meminit(void); -extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem); - -/* Returns pointer to PROM physical memory block array. */ -extern struct prom_pmemblock *prom_getpblock_array(void); /* PROM device tree library routines. */ #define PROM_NULL_COMPONENT ((pcomponent *) 0) |