patch-2.4.21 linux-2.4.21/arch/ppc/boot/common/misc-simple.c

Next file: linux-2.4.21/arch/ppc/boot/common/mpc10x_memory.c
Previous file: linux-2.4.21/arch/ppc/boot/common/misc-common.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.20/arch/ppc/boot/common/misc-simple.c linux-2.4.21/arch/ppc/boot/common/misc-simple.c
@@ -10,12 +10,10 @@
  * Author: Matt Porter <mporter@mvista.com>
  * Derived from arch/ppc/boot/prep/misc.c
  *
- * Copyright 2001 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
+ * 2001 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
  */
 
 #include <linux/types.h>
@@ -27,6 +25,7 @@
 #include <asm/mmu.h>
 #include <asm/bootinfo.h>
 
+#include "mpc10x.h"
 #include "nonstdio.h"
 #include "zlib.h"
 
@@ -44,6 +43,12 @@
 #define HAS_KEYB 0
 #endif
 
+/* Will / Can the user give input? */
+#if (defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_VGA_CONSOLE)) \
+	&& !defined(CONFIG_GEMINI)
+#define INTERACTIVE_CONSOLE	1
+#endif
+
 char *avail_ram;
 char *end_avail;
 char *zimage_start;
@@ -64,21 +69,42 @@
 extern unsigned long start;
 
 extern int CRT_tstc(void);
+extern unsigned long mpc10x_get_mem_size(int map);
 extern unsigned long serial_init(int chan, void *ignored);
 extern void serial_close(unsigned long com_port);
 extern void gunzip(void *, int, unsigned char *, int *);
 extern void serial_fixups(void);
 
+/* Allow decompress_kernel to be hooked into.  This is the default. */
+void * __attribute__ ((weak))
+load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
+		void *bp)
+{
+	return decompress_kernel(load_addr, num_words, cksum, bp);
+}
+
 struct bi_record *
 decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
 {
+#ifdef INTERACTIVE_CONSOLE
 	int timer = 0;
-	char *cp, ch;
-	struct bi_record *rec, *birecs;
+	char ch;
+#endif
+	char *cp;
+	struct bi_record *rec;
+	unsigned long rec_loc, initrd_loc, TotalMemory = 0;
 
 	serial_fixups();
 	com_port = serial_init(0, NULL);
 
+#ifdef CONFIG_LOPEC
+	/*
+	 * This should work on any board with an MPC10X which is properly
+	 * initalized.
+	 */
+	TotalMemory = mpc10x_get_mem_size(MPC10X_MEM_MAP_B);
+#endif
+
 	/* assume the chunk below 8M is free */
 	end_avail = (char *)0x00800000;
 
@@ -148,8 +174,7 @@
 	memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
 	while ( *cp ) putc(*cp++);
 
-#if (defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_VGA_CONSOLE)) \
-	&& !defined(CONFIG_GEMINI)
+#ifdef INTERACTIVE_CONSOLE
 	/*
 	 * If they have a console, allow them to edit the command line.
 	 * Otherwise, don't bother wasting the five seconds.
@@ -189,14 +214,40 @@
 	/*
 	 * Create bi_recs for cmd_line and initrds
 	 */
-	rec = (struct bi_record *)_ALIGN((unsigned long)(zimage_size) +
+	rec_loc = _ALIGN((unsigned long)(zimage_size) +
 			(1 << 20) - 1, (1 << 20));
-	birecs = rec;
+	rec = (struct bi_record *)rec_loc;
 
+	/* We need to make sure that the initrd and bi_recs do not
+	 * overlap. */
+	if ( initrd_size ) {
+		initrd_loc = (unsigned long)(&__ramdisk_begin);
+		/* If the bi_recs are in the middle of the current
+		 * initrd, move the initrd to the next MB
+		 * boundary. */
+		if ((rec_loc > initrd_loc) &&
+				((initrd_loc + initrd_size) > rec_loc)) {
+			initrd_loc = _ALIGN((unsigned long)(zimage_size)
+					+ (2 << 20) - 1, (2 << 20));
+		 	memmove((void *)initrd_loc, &__ramdisk_begin,
+				 initrd_size);
+	         	puts("initrd moved:  "); puthex(initrd_loc);
+		 	puts(" "); puthex(initrd_loc + initrd_size);
+		 	puts("\n");
+		}
+	}
+ 
 	rec->tag = BI_FIRST;
 	rec->size = sizeof(struct bi_record);
 	rec = (struct bi_record *)((unsigned long)rec + rec->size);
 
+	if ( TotalMemory ) {
+		rec->tag = BI_MEMSIZE;
+		rec->data[0] = TotalMemory;
+		rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	}
+
 	rec->tag = BI_CMD_LINE;
 	memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
 	rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
@@ -204,7 +255,7 @@
 
 	if ( initrd_size ) {
 		rec->tag = BI_INITRD;
-		rec->data[0] = (unsigned long)(&__ramdisk_begin);
+		rec->data[0] = initrd_loc;
 		rec->data[1] = initrd_size;
 		rec->size = sizeof(struct bi_record) + 2 *
 			sizeof(unsigned long);
@@ -218,5 +269,5 @@
 	puts("Now booting the kernel\n");
 	serial_close(com_port);
 
-	return birecs;
+	return (struct bi_record *)rec_loc;
 }

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)