summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mips/arc/cmdline.c4
-rw-r--r--arch/mips/arc/memory.c133
-rw-r--r--arch/mips/baget/prom/init.c8
-rw-r--r--arch/mips/ddb5074/prom.c31
-rw-r--r--arch/mips/ddb5074/setup.c5
-rw-r--r--arch/mips/dec/prom/cmdline.c4
-rw-r--r--arch/mips/dec/prom/memory.c56
-rw-r--r--arch/mips/jazz/Makefile5
-rw-r--r--arch/mips/jazz/setup.c8
-rw-r--r--arch/mips/kernel/Makefile4
-rw-r--r--arch/mips/kernel/setup.c228
-rw-r--r--arch/mips/mm/init.c26
-rw-r--r--arch/mips/sgi/kernel/setup.c9
-rw-r--r--arch/mips/sni/setup.c5
-rw-r--r--include/asm-mips/bootinfo.h29
-rw-r--r--include/asm-mips/sgialib.h19
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)