From: Tom Rini 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 #include #include - +#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"); _