From: Tom Rini <trini@kernel.crashing.org>

Re-add support to the bootwrapper for talking with OF on PReP machines. 
This fixes memory detection of some machines.



---

 arch/ppc/boot/prep/Makefile |    3 +-
 arch/ppc/boot/prep/head.S   |   26 +++++++++++++++++++---
 arch/ppc/boot/prep/misc.c   |   52 ++++++++++++++++++++++++++++++++++++++------
 3 files changed, 70 insertions(+), 11 deletions(-)

diff -puN arch/ppc/boot/prep/head.S~ppc32-of-bootwrapper-support arch/ppc/boot/prep/head.S
--- 25/arch/ppc/boot/prep/head.S~ppc32-of-bootwrapper-support	2004-01-08 10:47:25.000000000 -0800
+++ 25-akpm/arch/ppc/boot/prep/head.S	2004-01-08 10:47:25.000000000 -0800
@@ -35,9 +35,28 @@ start_:
 
 	mr	r11,r3		/* Save pointer to residual/board data */
 
-	/* Establish default MSR value */
-	li	r3,MSR_IP|MSR_FP
-	mtmsr	r3
+/*
+ * Save the OF pointer to r25, but only if the entry point is in a sane
+ * location; if not we store 0.  If there is no entry point, or it is
+ * invalid, we establish the default MSR value immediately.  Otherwise,
+ * we defer doing that, to allow OF functions to be called, until we
+ * begin uncompressing the kernel.
+ */
+	lis	r3,0x0fff		/* r3 = 0x0fffffff */
+	ori	r3,r3,0xffff
+
+	subc	r3,r3,r5		/* r3 = (r5 <= r3) ? ~0 : 0 */
+	subfe	r3,r3,r3
+	nand	r3,r3,r3
+
+	and.	r5,r5,r3		/* r5 will be cleared if (r5 > r3) */
+	bne+	haveOF
+
+	li	r3,MSR_IP|MSR_FP	/* Not OF: set MSR immediately */
+  	mtmsr	r3
+	isync
+haveOF:
+	mr	r25,r5
 
 	/* compute the size of the whole image in words. */
 	lis	r4,start@h
@@ -111,6 +130,7 @@ start_ldr:
 	mr	r4,r7			/* Program length */
 	mr	r5,r6			/* Checksum */
 	mr	r6,r11			/* Residual data */
+	mr      r7,r25                  /* Validated OFW interface */
 	bl	decompress_kernel
 
 	/*
diff -puN arch/ppc/boot/prep/Makefile~ppc32-of-bootwrapper-support arch/ppc/boot/prep/Makefile
--- 25/arch/ppc/boot/prep/Makefile~ppc32-of-bootwrapper-support	2004-01-08 10:47:25.000000000 -0800
+++ 25-akpm/arch/ppc/boot/prep/Makefile	2004-01-08 10:47:25.000000000 -0800
@@ -27,9 +27,10 @@ utils	:= $(boot)/utils
 bootlib	:= $(boot)/lib
 images	:= $(boot)/images
 simple	:= $(boot)/simple
+of1275	:= $(boot)/of1275
 
 OBJCOPYFLAGS	:= -O elf32-powerpc
-LIBS 		:= $(common)/lib.a $(bootlib)/lib.a
+LIBS 		:= $(common)/lib.a $(bootlib)/lib.a $(of1275)/lib.a
 
 targets		:= $(boot-y) dummy.o ../simple/legacy.o
 OBJS		:= $(addprefix $(obj)/,$(boot-y)) $(simple)/legacy.o
diff -puN arch/ppc/boot/prep/misc.c~ppc32-of-bootwrapper-support arch/ppc/boot/prep/misc.c
--- 25/arch/ppc/boot/prep/misc.c~ppc32-of-bootwrapper-support	2004-01-08 10:47:25.000000000 -0800
+++ 25-akpm/arch/ppc/boot/prep/misc.c	2004-01-08 10:47:25.000000000 -0800
@@ -19,7 +19,7 @@
 #include <asm/bootinfo.h>
 #include <asm/mmu.h>
 #include <asm/byteorder.h>
-
+#include "of1275.h"
 #include "nonstdio.h"
 #include "zlib.h"
 
@@ -114,17 +114,19 @@ scroll(void)
 
 unsigned long
 decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
-		  RESIDUAL *residual)
+		  RESIDUAL *residual, void *OFW_interface)
 {
 	int timer = 0;
 	extern unsigned long start;
 	char *cp, ch;
 	unsigned long TotalMemory;
-	unsigned char board_type;
-	unsigned char base_mod;
 	int start_multi = 0;
 	unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base;
 
+	/* If we have Open Firmware, initialise it immediately */
+	if (OFW_interface)
+		ofinit(OFW_interface);
+
 	serial_fixups();
 #if defined(CONFIG_SERIAL_8250_CONSOLE)
 	com_port = serial_init(0, NULL);
@@ -163,7 +165,8 @@ decompress_kernel(unsigned long load_add
 		/* Is this Motorola PPCBug? */
 		if ((1 & residual->VitalProductData.FirmwareSupports) &&
 		    (1 == residual->VitalProductData.FirmwareSupplier)) {
-			board_type = inb(0x800) & 0xF0;
+			unsigned char base_mod;
+			unsigned char board_type = inb(0x800) & 0xF0;
 
 			/*
 			 * Reset the onboard 21x4x Ethernet
@@ -229,8 +232,31 @@ decompress_kernel(unsigned long load_add
 	/* If it's not, see if we have anything in the residual data. */
 	else if (residual && residual->TotalMemory)
 		TotalMemory = residual->TotalMemory;
-	/* Fall back to hard-coding 32MB. */
-	else
+	else if (OFW_interface) {
+		/*
+		 * This is a 'best guess' check.  We want to make sure
+		 * we don't try this on a PReP box without OF
+		 *     -- Cort
+		 */
+		while (OFW_interface)
+		{
+			phandle dev_handle;
+			int mem_info[2];
+
+			/* get handle to memory description */
+			if (!(dev_handle = finddevice("/memory@0")))
+				break;
+
+			/* get the info */
+			if (getprop(dev_handle, "reg", mem_info,
+						sizeof(mem_info)) != 8)
+				break;
+
+			TotalMemory = mem_info[1];
+			break;
+		}
+	} else
+		/* Fall back to hard-coding 32MB. */
 		TotalMemory = 32*1024*1024;
 
 
@@ -304,6 +330,18 @@ decompress_kernel(unsigned long load_add
 	*cp = 0;
 	puts("\nUncompressing Linux...");
 
+	/*
+	 * If we have OF, then we have deferred setting the MSR.
+	 * We must set it now because we are about to overwrite
+	 * the exception table.  The new MSR value will disable
+	 * machine check exceptions and point the exception table
+	 * to the ROM.
+	 */
+	if (OFW_interface) {
+		mtmsr(MSR_IP | MSR_FP);
+		asm volatile("isync");
+	}
+
 	gunzip(0, 0x400000, zimage_start, &zimage_size);
 	puts("done.\n");
 

_