Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
new file mode 100644
index 0000000..995f89b
--- /dev/null
+++ b/arch/ppc/boot/Makefile
@@ -0,0 +1,34 @@
+#
+# arch/ppc/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994 by Linus Torvalds
+# Adapted for PowerPC by Gary Thomas
+# modified by Cort (cort@cs.nmt.edu)
+#
+
+CFLAGS	 	+= -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include
+HOSTCFLAGS	+= -Iarch/$(ARCH)/boot/include
+
+BOOT_TARGETS	= zImage zImage.initrd znetboot znetboot.initrd
+
+bootdir-y			:= simple
+bootdir-$(CONFIG_PPC_OF)	+= openfirmware
+subdir-y			:= lib common images
+subdir-$(CONFIG_PPC_OF)		+= of1275
+
+# for cleaning
+subdir-				+= simple openfirmware
+
+hostprogs-y := $(addprefix utils/, addnote mknote hack-coff mkprep mkbugboot mktree)
+
+.PHONY: $(BOOT_TARGETS) $(bootdir-y)
+
+$(BOOT_TARGETS): $(bootdir-y)
+
+$(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \
+		$(addprefix $(obj)/,$(hostprogs-y))
+	$(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS)
diff --git a/arch/ppc/boot/common/Makefile b/arch/ppc/boot/common/Makefile
new file mode 100644
index 0000000..f88d647
--- /dev/null
+++ b/arch/ppc/boot/common/Makefile
@@ -0,0 +1,13 @@
+#
+# arch/ppc/boot/common/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Tom Rini	January 2001
+#
+
+lib-y					:= string.o util.o misc-common.o \
+						serial_stub.o bootinfo.o
+lib-$(CONFIG_SERIAL_8250_CONSOLE)	+= ns16550.o
diff --git a/arch/ppc/boot/common/bootinfo.c b/arch/ppc/boot/common/bootinfo.c
new file mode 100644
index 0000000..9c6e528
--- /dev/null
+++ b/arch/ppc/boot/common/bootinfo.c
@@ -0,0 +1,70 @@
+/*
+ * arch/ppc/common/bootinfo.c
+ *
+ * General bootinfo record utilities
+ * Author: Randy Vinson <rvinson@mvista.com>
+ *
+ * 2002 (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>
+#include <linux/string.h>
+#include <asm/bootinfo.h>
+
+#include "nonstdio.h"
+
+static struct bi_record * birec = NULL;
+
+static struct bi_record *
+__bootinfo_build(struct bi_record *rec, unsigned long tag, unsigned long size,
+		 void *data)
+{
+	/* set the tag */
+	rec->tag = tag;
+
+	/* if the caller has any data, copy it */
+	if (size)
+		memcpy(rec->data, (char *)data, size);
+
+	/* set the record size */
+	rec->size = sizeof(struct bi_record) + size;
+
+	/* advance to the next available space */
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	return rec;
+}
+
+void
+bootinfo_init(struct bi_record *rec)
+{
+
+	/* save start of birec area */
+	birec = rec;
+
+	/* create an empty list */
+	rec = __bootinfo_build(rec, BI_FIRST, 0, NULL);
+	(void) __bootinfo_build(rec, BI_LAST, 0, NULL);
+
+}
+
+void
+bootinfo_append(unsigned long tag, unsigned long size, void * data)
+{
+
+	struct bi_record *rec = birec;
+
+	/* paranoia */
+	if ((rec == NULL) || (rec->tag != BI_FIRST))
+		return;
+
+	/* find the last entry in the list */
+	while (rec->tag != BI_LAST)
+		rec = (struct bi_record *)((ulong)rec + rec->size);
+
+	/* overlay BI_LAST record with new one and tag on a new BI_LAST */
+	rec = __bootinfo_build(rec, tag, size, data);
+	(void) __bootinfo_build(rec, BI_LAST, 0, NULL);
+}
diff --git a/arch/ppc/boot/common/crt0.S b/arch/ppc/boot/common/crt0.S
new file mode 100644
index 0000000..4d31b82
--- /dev/null
+++ b/arch/ppc/boot/common/crt0.S
@@ -0,0 +1,81 @@
+/*    Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
+ *      Initial Power Macintosh COFF version.
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *      Modifications for IBM PowerPC 400-class processor evaluation
+ *      boards.
+ *
+ *    Module name: crt0.S
+ *
+ *    Description:
+ *      Boot loader execution entry point. Clears out .bss section as per
+ *      ANSI C requirements. Invalidates and flushes the caches over the
+ *      range covered by the boot loader's .text section. Sets up a stack
+ *      below the .text section entry point.
+ *
+ *    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.
+ */
+
+#include <linux/config.h>
+#include <asm/ppc_asm.h>
+
+	.text
+
+	.globl	_start
+_start:
+#ifdef XCOFF
+	.long	__start,0,0
+
+	.globl	__start
+__start:
+#endif
+
+	## Flush and invalidate the caches for the range in memory covering
+	## the .text section of the boot loader
+
+	lis	r9,_start@h		# r9 = &_start
+	lis	r8,_etext@ha		#
+	addi	r8,r8,_etext@l		# r8 = &_etext
+3:	dcbf	r0,r9			# Flush the data cache
+	icbi	r0,r9			# Invalidate the instruction cache
+	addi	r9,r9,0x10		# Increment by one cache line
+	cmplw	cr0,r9,r8		# Are we at the end yet?
+	blt	3b			# No, keep flushing and invalidating
+	sync				# sync ; isync after flushing the icache
+	isync
+
+	## Clear out the BSS as per ANSI C requirements
+
+	lis	r7,_end@ha
+	addi	r7,r7,_end@l		# r7 = &_end
+	lis	r8,__bss_start@ha	#
+	addi	r8,r8,__bss_start@l	# r8 = &_bss_start
+
+	## Determine how large an area, in number of words, to clear
+
+	subf	r7,r8,r7		# r7 = &_end - &_bss_start + 1
+	addi	r7,r7,3			# r7 += 3
+	srwi.	r7,r7,2			# r7 = size in words.
+	beq	2f			# If the size is zero, do not bother
+	addi	r8,r8,-4		# r8 -= 4
+	mtctr	r7			# SPRN_CTR = number of words to clear
+	li	r0,0			# r0 = 0
+1:	stwu	r0,4(r8)		# Clear out a word
+	bdnz	1b			# If we are not done yet, keep clearing
+2:
+
+#ifdef CONFIG_40x
+	## Set up the stack
+
+	lis	r9,_start@h		# r9 = &_start (text section entry)
+	ori	r9,r9,_start@l
+	subi	r1,r9,64		# Start the stack 64 bytes below _start
+	clrrwi	r1,r1,4			# Make sure it is aligned on 16 bytes.
+	li	r0,0
+	stwu	r0,-16(r1)
+	mtlr	r9
+#endif
+
+	b	start			# All done, start the real work.
diff --git a/arch/ppc/boot/common/misc-common.c b/arch/ppc/boot/common/misc-common.c
new file mode 100644
index 0000000..e79e6b3
--- /dev/null
+++ b/arch/ppc/boot/common/misc-common.c
@@ -0,0 +1,553 @@
+/*
+ * arch/ppc/boot/common/misc-common.c
+ *
+ * Misc. bootloader code (almost) all platforms can use
+ *
+ * Author: Johnnie Peters <jpeters@mvista.com>
+ * Editor: Tom Rini <trini@mvista.com>
+ *
+ * Derived from arch/ppc/boot/prep/misc.c
+ *
+ * 2000-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 <stdarg.h>	/* for va_ bits */
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/zlib.h>
+#include "nonstdio.h"
+
+/* If we're on a PReP, assume we have a keyboard controller
+ * Also note, if we're not PReP, we assume you are a serial
+ * console - Tom */
+#if defined(CONFIG_PPC_PREP) && defined(CONFIG_VGA_CONSOLE)
+extern void cursor(int x, int y);
+extern void scroll(void);
+extern char *vidmem;
+extern int lines, cols;
+extern int orig_x, orig_y;
+extern int keyb_present;
+extern int CRT_tstc(void);
+extern int CRT_getc(void);
+#else
+int cursor(int x, int y) {return 0;}
+void scroll(void) {}
+char vidmem[1];
+#define lines 0
+#define cols 0
+int orig_x = 0;
+int orig_y = 0;
+#define keyb_present 0
+int CRT_tstc(void) {return 0;}
+int CRT_getc(void) {return 0;}
+#endif
+
+extern char *avail_ram;
+extern char *end_avail;
+extern char _end[];
+
+void puts(const char *);
+void putc(const char c);
+void puthex(unsigned long val);
+void gunzip(void *, int, unsigned char *, int *);
+static int _cvt(unsigned long val, char *buf, long radix, char *digits);
+
+void _vprintk(void(*putc)(const char), const char *fmt0, va_list ap);
+unsigned char *ISA_io = NULL;
+
+#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)
+extern unsigned long com_port;
+
+extern int serial_tstc(unsigned long com_port);
+extern unsigned char serial_getc(unsigned long com_port);
+extern void serial_putc(unsigned long com_port, unsigned char c);
+#endif
+
+void pause(void)
+{
+	puts("pause\n");
+}
+
+void exit(void)
+{
+	puts("exit\n");
+	while(1);
+}
+
+int tstc(void)
+{
+#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)
+	if(keyb_present)
+		return (CRT_tstc() || serial_tstc(com_port));
+	else
+		return (serial_tstc(com_port));
+#else
+	return CRT_tstc();
+#endif
+}
+
+int getc(void)
+{
+	while (1) {
+#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)
+		if (serial_tstc(com_port))
+			return (serial_getc(com_port));
+#endif /* serial console */
+		if (keyb_present)
+			if(CRT_tstc())
+				return (CRT_getc());
+	}
+}
+
+void
+putc(const char c)
+{
+	int x,y;
+
+#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)
+	serial_putc(com_port, c);
+	if ( c == '\n' )
+		serial_putc(com_port, '\r');
+#endif /* serial console */
+
+	x = orig_x;
+	y = orig_y;
+
+	if ( c == '\n' ) {
+		x = 0;
+		if ( ++y >= lines ) {
+			scroll();
+			y--;
+		}
+	} else if (c == '\r') {
+		x = 0;
+	} else if (c == '\b') {
+		if (x > 0) {
+			x--;
+		}
+	} else {
+		vidmem [ ( x + cols * y ) * 2 ] = c;
+		if ( ++x >= cols ) {
+			x = 0;
+			if ( ++y >= lines ) {
+				scroll();
+				y--;
+			}
+		}
+	}
+
+	cursor(x, y);
+
+	orig_x = x;
+	orig_y = y;
+}
+
+void puts(const char *s)
+{
+	int x,y;
+	char c;
+
+	x = orig_x;
+	y = orig_y;
+
+	while ( ( c = *s++ ) != '\0' ) {
+#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)
+	        serial_putc(com_port, c);
+	        if ( c == '\n' ) serial_putc(com_port, '\r');
+#endif /* serial console */
+
+		if ( c == '\n' ) {
+			x = 0;
+			if ( ++y >= lines ) {
+				scroll();
+				y--;
+			}
+		} else if (c == '\b') {
+		  if (x > 0) {
+		    x--;
+		  }
+		} else {
+			vidmem [ ( x + cols * y ) * 2 ] = c;
+			if ( ++x >= cols ) {
+				x = 0;
+				if ( ++y >= lines ) {
+					scroll();
+					y--;
+				}
+			}
+		}
+	}
+
+	cursor(x, y);
+
+	orig_x = x;
+	orig_y = y;
+}
+
+void error(char *x)
+{
+	puts("\n\n");
+	puts(x);
+	puts("\n\n -- System halted");
+
+	while(1);	/* Halt */
+}
+
+static void *zalloc(unsigned size)
+{
+	void *p = avail_ram;
+
+	size = (size + 7) & -8;
+	avail_ram += size;
+	if (avail_ram > end_avail) {
+		puts("oops... out of memory\n");
+		pause();
+	}
+	return p;
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+	z_stream s;
+	int r, i, flags;
+
+	/* skip header */
+	i = 10;
+	flags = src[3];
+	if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
+		puts("bad gzipped data\n");
+		exit();
+	}
+	if ((flags & EXTRA_FIELD) != 0)
+		i = 12 + src[10] + (src[11] << 8);
+	if ((flags & ORIG_NAME) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & COMMENT) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & HEAD_CRC) != 0)
+		i += 2;
+	if (i >= *lenp) {
+		puts("gunzip: ran out of data in header\n");
+		exit();
+	}
+
+	/* Initialize ourself. */
+	s.workspace = zalloc(zlib_inflate_workspacesize());
+	r = zlib_inflateInit2(&s, -MAX_WBITS);
+	if (r != Z_OK) {
+		puts("zlib_inflateInit2 returned "); puthex(r); puts("\n");
+		exit();
+	}
+	s.next_in = src + i;
+	s.avail_in = *lenp - i;
+	s.next_out = dst;
+	s.avail_out = dstlen;
+	r = zlib_inflate(&s, Z_FINISH);
+	if (r != Z_OK && r != Z_STREAM_END) {
+		puts("inflate returned "); puthex(r); puts("\n");
+		exit();
+	}
+	*lenp = s.next_out - (unsigned char *) dst;
+	zlib_inflateEnd(&s);
+}
+
+void
+puthex(unsigned long val)
+{
+
+	unsigned char buf[10];
+	int i;
+	for (i = 7;  i >= 0;  i--)
+	{
+		buf[i] = "0123456789ABCDEF"[val & 0x0F];
+		val >>= 4;
+	}
+	buf[8] = '\0';
+	puts(buf);
+}
+
+#define FALSE 0
+#define TRUE  1
+
+void
+_printk(char const *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	_vprintk(putc, fmt, ap);
+	va_end(ap);
+	return;
+}
+
+#define is_digit(c) ((c >= '0') && (c <= '9'))
+
+void
+_vprintk(void(*putc)(const char), const char *fmt0, va_list ap)
+{
+	char c, sign, *cp = 0;
+	int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right;
+	char buf[32];
+	long val;
+	while ((c = *fmt0++))
+	{
+		if (c == '%')
+		{
+			c = *fmt0++;
+			left_prec = right_prec = pad_on_right = 0;
+			if (c == '-')
+			{
+				c = *fmt0++;
+				pad_on_right++;
+			}
+			if (c == '0')
+			{
+				zero_fill = TRUE;
+				c = *fmt0++;
+			} else
+			{
+				zero_fill = FALSE;
+			}
+			while (is_digit(c))
+			{
+				left_prec = (left_prec * 10) + (c - '0');
+				c = *fmt0++;
+			}
+			if (c == '.')
+			{
+				c = *fmt0++;
+				zero_fill++;
+				while (is_digit(c))
+				{
+					right_prec = (right_prec * 10) + (c - '0');
+					c = *fmt0++;
+				}
+			} else
+			{
+				right_prec = left_prec;
+			}
+			sign = '\0';
+			switch (c)
+			{
+			case 'd':
+			case 'x':
+			case 'X':
+				val = va_arg(ap, long);
+				switch (c)
+				{
+				case 'd':
+					if (val < 0)
+					{
+						sign = '-';
+						val = -val;
+					}
+					length = _cvt(val, buf, 10, "0123456789");
+					break;
+				case 'x':
+					length = _cvt(val, buf, 16, "0123456789abcdef");
+					break;
+				case 'X':
+					length = _cvt(val, buf, 16, "0123456789ABCDEF");
+					break;
+				}
+				cp = buf;
+				break;
+			case 's':
+				cp = va_arg(ap, char *);
+				length = strlen(cp);
+				break;
+			case 'c':
+				c = va_arg(ap, long /*char*/);
+				(*putc)(c);
+				continue;
+			default:
+				(*putc)('?');
+			}
+			pad = left_prec - length;
+			if (sign != '\0')
+			{
+				pad--;
+			}
+			if (zero_fill)
+			{
+				c = '0';
+				if (sign != '\0')
+				{
+					(*putc)(sign);
+					sign = '\0';
+				}
+			} else
+			{
+				c = ' ';
+			}
+			if (!pad_on_right)
+			{
+				while (pad-- > 0)
+				{
+					(*putc)(c);
+				}
+			}
+			if (sign != '\0')
+			{
+				(*putc)(sign);
+			}
+			while (length-- > 0)
+			{
+				(*putc)(c = *cp++);
+				if (c == '\n')
+				{
+					(*putc)('\r');
+				}
+			}
+			if (pad_on_right)
+			{
+				while (pad-- > 0)
+				{
+					(*putc)(c);
+				}
+			}
+		} else
+		{
+			(*putc)(c);
+			if (c == '\n')
+			{
+				(*putc)('\r');
+			}
+		}
+	}
+}
+
+int
+_cvt(unsigned long val, char *buf, long radix, char *digits)
+{
+	char temp[80];
+	char *cp = temp;
+	int length = 0;
+	if (val == 0)
+	{ /* Special case */
+		*cp++ = '0';
+	} else
+		while (val)
+		{
+			*cp++ = digits[val % radix];
+			val /= radix;
+		}
+	while (cp != temp)
+	{
+		*buf++ = *--cp;
+		length++;
+	}
+	*buf = '\0';
+	return (length);
+}
+
+void
+_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
+{
+	int i, c;
+	if ((unsigned int)s > (unsigned int)p)
+	{
+		s = (unsigned int)s - (unsigned int)p;
+	}
+	while (s > 0)
+	{
+		if (base)
+		{
+			_printk("%06X: ", (int)p - (int)base);
+		} else
+		{
+			_printk("%06X: ", p);
+		}
+		for (i = 0;  i < 16;  i++)
+		{
+			if (i < s)
+			{
+				_printk("%02X", p[i] & 0xFF);
+			} else
+			{
+				_printk("  ");
+			}
+			if ((i % 2) == 1) _printk(" ");
+			if ((i % 8) == 7) _printk(" ");
+		}
+		_printk(" |");
+		for (i = 0;  i < 16;  i++)
+		{
+			if (i < s)
+			{
+				c = p[i] & 0xFF;
+				if ((c < 0x20) || (c >= 0x7F)) c = '.';
+			} else
+			{
+				c = ' ';
+			}
+			_printk("%c", c);
+		}
+		_printk("|\n");
+		s -= 16;
+		p += 16;
+	}
+}
+
+void
+_dump_buf(unsigned char *p, int s)
+{
+	_printk("\n");
+	_dump_buf_with_offset(p, s, 0);
+}
+
+/* Very simple inb/outb routines.  We declare ISA_io to be 0 above, and
+ * then modify it on platforms which need to.  We do it like this
+ * because on some platforms we give inb/outb an exact location, and
+ * on others it's an offset from a given location. -- Tom
+ */
+
+void ISA_init(unsigned long base)
+{
+	ISA_io = (unsigned char *)base;
+}
+
+void
+outb(int port, unsigned char val)
+{
+	/* Ensure I/O operations complete */
+	__asm__ volatile("eieio");
+	ISA_io[port] = val;
+}
+
+unsigned char
+inb(int port)
+{
+	/* Ensure I/O operations complete */
+	__asm__ volatile("eieio");
+	return (ISA_io[port]);
+}
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff --git a/arch/ppc/boot/common/ns16550.c b/arch/ppc/boot/common/ns16550.c
new file mode 100644
index 0000000..9017c54
--- /dev/null
+++ b/arch/ppc/boot/common/ns16550.c
@@ -0,0 +1,99 @@
+/*
+ * COM1 NS16550 support
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+
+#include "nonstdio.h"
+#include "serial.h"
+
+#define SERIAL_BAUD	9600
+
+extern unsigned long ISA_io;
+
+static struct serial_state rs_table[RS_TABLE_SIZE] = {
+	SERIAL_PORT_DFNS	/* Defined in <asm/serial.h> */
+};
+
+static int shift;
+
+unsigned long serial_init(int chan, void *ignored)
+{
+	unsigned long com_port;
+	unsigned char lcr, dlm;
+
+	/* We need to find out which type io we're expecting.  If it's
+	 * 'SERIAL_IO_PORT', we get an offset from the isa_io_base.
+	 * If it's 'SERIAL_IO_MEM', we can the exact location.  -- Tom */
+	switch (rs_table[chan].io_type) {
+		case SERIAL_IO_PORT:
+			com_port = rs_table[chan].port;
+			break;
+		case SERIAL_IO_MEM:
+			com_port = (unsigned long)rs_table[chan].iomem_base;
+			break;
+		default:
+			/* We can't deal with it. */
+			return -1;
+	}
+
+	/* How far apart the registers are. */
+	shift = rs_table[chan].iomem_reg_shift;
+	
+	/* save the LCR */
+	lcr = inb(com_port + (UART_LCR << shift));
+	/* Access baud rate */
+	outb(com_port + (UART_LCR << shift), 0x80);
+	dlm = inb(com_port + (UART_DLM << shift));
+	/*
+	 * Test if serial port is unconfigured.
+	 * We assume that no-one uses less than 110 baud or
+	 * less than 7 bits per character these days.
+	 *  -- paulus.
+	 */
+
+	if ((dlm <= 4) && (lcr & 2))
+		/* port is configured, put the old LCR back */
+		outb(com_port + (UART_LCR << shift), lcr);
+	else {
+		/* Input clock. */
+		outb(com_port + (UART_DLL << shift),
+		     (BASE_BAUD / SERIAL_BAUD) & 0xFF);
+		outb(com_port + (UART_DLM << shift),
+		     (BASE_BAUD / SERIAL_BAUD) >> 8);
+		/* 8 data, 1 stop, no parity */
+		outb(com_port + (UART_LCR << shift), 0x03);
+		/* RTS/DTR */
+		outb(com_port + (UART_MCR << shift), 0x03);
+	}
+	/* Clear & enable FIFOs */
+	outb(com_port + (UART_FCR << shift), 0x07);
+
+	return (com_port);
+}
+
+void
+serial_putc(unsigned long com_port, unsigned char c)
+{
+	while ((inb(com_port + (UART_LSR << shift)) & UART_LSR_THRE) == 0)
+		;
+	outb(com_port, c);
+}
+
+unsigned char
+serial_getc(unsigned long com_port)
+{
+	while ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) == 0)
+		;
+	return inb(com_port);
+}
+
+int
+serial_tstc(unsigned long com_port)
+{
+	return ((inb(com_port + (UART_LSR << shift)) & UART_LSR_DR) != 0);
+}
diff --git a/arch/ppc/boot/common/serial_stub.c b/arch/ppc/boot/common/serial_stub.c
new file mode 100644
index 0000000..03dfaa0
--- /dev/null
+++ b/arch/ppc/boot/common/serial_stub.c
@@ -0,0 +1,23 @@
+/*
+ * arch/ppc/boot/common/serial_stub.c
+ *
+ * This is a few stub routines to make the boot code cleaner looking when
+ * there is no serial port support doesn't need to be closed, for example.
+ *
+ * Author: Tom Rini <trini@mvista.com>
+ *
+ * 2003 (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.
+ */
+
+unsigned long __attribute__ ((weak))
+serial_init(int chan, void *ignored)
+{
+	return 0;
+}
+
+void __attribute__ ((weak))
+serial_close(unsigned long com_port)
+{
+}
diff --git a/arch/ppc/boot/common/string.S b/arch/ppc/boot/common/string.S
new file mode 100644
index 0000000..8016e43
--- /dev/null
+++ b/arch/ppc/boot/common/string.S
@@ -0,0 +1,150 @@
+/*
+ * String handling functions for PowerPC.
+ *
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * 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.
+ */
+#define r0	0
+#define r3	3
+#define r4	4
+#define r5	5
+#define r6	6
+#define r7	7
+#define r8	8
+
+	.globl	strlen
+strlen:
+	addi	r4,r3,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	bne	1b
+	subf	r3,r3,r4
+	blr
+
+	.globl	memset
+memset:
+	rlwimi	r4,r4,8,16,23
+	rlwimi	r4,r4,16,0,15
+	addi	r6,r3,-4
+	cmplwi	0,r5,4
+	blt	7f
+	stwu	r4,4(r6)
+	beqlr
+	andi.	r0,r6,3
+	add	r5,r0,r5
+	subf	r6,r0,r6
+	rlwinm	r0,r5,32-2,2,31
+	mtctr	r0
+	bdz	6f
+1:	stwu	r4,4(r6)
+	bdnz	1b
+6:	andi.	r5,r5,3
+7:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r6,r6,3
+8:	stbu	r4,1(r6)
+	bdnz	8b
+	blr
+
+	.globl	memmove
+memmove:
+	cmplw	0,r3,r4
+	bgt	backwards_memcpy
+	/* fall through */
+
+	.globl	memcpy
+memcpy:
+	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+	addi	r6,r3,-4
+	addi	r4,r4,-4
+	beq	2f			/* if less than 8 bytes to do */
+	andi.	r0,r6,3			/* get dest word aligned */
+	mtctr	r7
+	bne	5f
+1:	lwz	r7,4(r4)
+	lwzu	r8,8(r4)
+	stw	r7,4(r6)
+	stwu	r8,8(r6)
+	bdnz	1b
+	andi.	r5,r5,7
+2:	cmplwi	0,r5,4
+	blt	3f
+	lwzu	r0,4(r4)
+	addi	r5,r5,-4
+	stwu	r0,4(r6)
+3:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r4,r4,3
+	addi	r6,r6,3
+4:	lbzu	r0,1(r4)
+	stbu	r0,1(r6)
+	bdnz	4b
+	blr
+5:	subfic	r0,r0,4
+	mtctr	r0
+6:	lbz	r7,4(r4)
+	addi	r4,r4,1
+	stb	r7,4(r6)
+	addi	r6,r6,1
+	bdnz	6b
+	subf	r5,r0,r5
+	rlwinm.	r7,r5,32-3,3,31
+	beq	2b
+	mtctr	r7
+	b	1b
+
+	.globl	backwards_memcpy
+backwards_memcpy:
+	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+	add	r6,r3,r5
+	add	r4,r4,r5
+	beq	2f
+	andi.	r0,r6,3
+	mtctr	r7
+	bne	5f
+1:	lwz	r7,-4(r4)
+	lwzu	r8,-8(r4)
+	stw	r7,-4(r6)
+	stwu	r8,-8(r6)
+	bdnz	1b
+	andi.	r5,r5,7
+2:	cmplwi	0,r5,4
+	blt	3f
+	lwzu	r0,-4(r4)
+	subi	r5,r5,4
+	stwu	r0,-4(r6)
+3:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+4:	lbzu	r0,-1(r4)
+	stbu	r0,-1(r6)
+	bdnz	4b
+	blr
+5:	mtctr	r0
+6:	lbzu	r7,-1(r4)
+	stbu	r7,-1(r6)
+	bdnz	6b
+	subf	r5,r0,r5
+	rlwinm.	r7,r5,32-3,3,31
+	beq	2b
+	mtctr	r7
+	b	1b
+
+	.globl	memcmp
+memcmp:
+	cmpwi	0,r5,0
+	blelr
+	mtctr	r5
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r3,1(r6)
+	lbzu	r0,1(r4)
+	subf.	r3,r0,r3
+	bdnzt	2,1b
+	blr
diff --git a/arch/ppc/boot/common/util.S b/arch/ppc/boot/common/util.S
new file mode 100644
index 0000000..47e6414
--- /dev/null
+++ b/arch/ppc/boot/common/util.S
@@ -0,0 +1,293 @@
+/*
+ * arch/ppc/boot/common/util.S
+ *
+ * Useful bootup functions, which are more easily done in asm than C.
+ *
+ * NOTE:  Be very very careful about the registers you use here.
+ *	We don't follow any ABI calling convention among the
+ *	assembler functions that call each other, especially early
+ *	in the initialization.  Please preserve at least r3 and r4
+ *	for these early functions, as they often contain information
+ *	passed from boot roms into the C decompress function.
+ *
+ * Author: Tom Rini
+ *	   trini@mvista.com
+ * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
+ *
+ * 2001-2004 (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 <asm/processor.h>
+#include <asm/cache.h>
+#include <asm/ppc_asm.h>
+
+
+	.text
+
+#ifdef CONFIG_6xx
+	.globl	disable_6xx_mmu
+disable_6xx_mmu:
+	/* Establish default MSR value, exception prefix 0xFFF.
+	 * If necessary, this function must fix up the LR if we
+	 * return to a different address space once the MMU is
+	 * disabled.
+	 */
+	li	r8,MSR_IP|MSR_FP
+	mtmsr	r8
+	isync
+
+	/* Test for a 601 */
+	mfpvr	r10
+	srwi	r10,r10,16
+	cmpwi	0,r10,1		/* 601 ? */
+	beq	.clearbats_601
+
+	/* Clear BATs */
+	li	r8,0
+	mtspr	SPRN_DBAT0U,r8
+	mtspr	SPRN_DBAT0L,r8
+	mtspr	SPRN_DBAT1U,r8
+	mtspr	SPRN_DBAT1L,r8
+	mtspr	SPRN_DBAT2U,r8
+	mtspr	SPRN_DBAT2L,r8
+	mtspr	SPRN_DBAT3U,r8
+	mtspr	SPRN_DBAT3L,r8
+.clearbats_601:
+	mtspr	SPRN_IBAT0U,r8
+	mtspr	SPRN_IBAT0L,r8
+	mtspr	SPRN_IBAT1U,r8
+	mtspr	SPRN_IBAT1L,r8
+	mtspr	SPRN_IBAT2U,r8
+	mtspr	SPRN_IBAT2L,r8
+	mtspr	SPRN_IBAT3U,r8
+	mtspr	SPRN_IBAT3L,r8
+	isync
+	sync
+	sync
+
+	/* Set segment registers */
+	li	r8,16		/* load up segment register values */
+	mtctr	r8		/* for context 0 */
+	lis	r8,0x2000	/* Ku = 1, VSID = 0 */
+	li	r10,0
+3:	mtsrin	r8,r10
+	addi	r8,r8,0x111	/* increment VSID */
+	addis	r10,r10,0x1000	/* address of next segment */
+	bdnz	3b
+	blr
+
+	.globl	disable_6xx_l1cache
+disable_6xx_l1cache:
+	/* Enable, invalidate and then disable the L1 icache/dcache. */
+	li	r8,0
+	ori	r8,r8,(HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI)
+	mfspr	r11,SPRN_HID0
+	or	r11,r11,r8
+	andc	r10,r11,r8
+	isync
+	mtspr	SPRN_HID0,r8
+	sync
+	isync
+	mtspr	SPRN_HID0,r10
+	sync
+	isync
+	blr
+#endif
+
+	.globl	_setup_L2CR
+_setup_L2CR:
+/*
+ * We should be skipping this section on CPUs where this results in an
+ * illegal instruction.  If not, please send trini@kernel.crashing.org
+ * the PVR of your CPU.
+ */
+	/* Invalidate/disable L2 cache */
+	sync
+	isync
+	mfspr	r8,SPRN_L2CR
+	rlwinm	r8,r8,0,1,31
+	oris	r8,r8,L2CR_L2I@h
+	sync
+	isync
+	mtspr	SPRN_L2CR,r8
+	sync
+	isync
+
+	/* Wait for the invalidation to complete */
+	mfspr   r8,SPRN_PVR
+	srwi    r8,r8,16
+	cmplwi	cr0,r8,0x8000			/* 7450 */
+	cmplwi	cr1,r8,0x8001			/* 7455 */
+	cmplwi	cr2,r8,0x8002			/* 7457 */
+	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq	/* Now test if any are true. */
+	cror	4*cr0+eq,4*cr0+eq,4*cr2+eq
+	bne     2f
+
+1:	mfspr	r8,SPRN_L2CR	/* On 745x, poll L2I bit (bit 10) */
+	rlwinm.	r9,r8,0,10,10
+	bne	1b
+	b	3f
+
+2:      mfspr   r8,SPRN_L2CR	/* On 75x & 74[01]0, poll L2IP bit (bit 31) */
+	rlwinm. r9,r8,0,31,31
+	bne     2b
+
+3:	rlwinm	r8,r8,0,11,9	/* Turn off L2I bit */
+	sync
+	isync
+	mtspr	SPRN_L2CR,r8
+	sync
+	isync
+	blr
+
+	.globl	_setup_L3CR
+_setup_L3CR:
+	/* Invalidate/disable L3 cache */
+	sync
+	isync
+	mfspr	r8,SPRN_L3CR
+	rlwinm	r8,r8,0,1,31
+	ori	r8,r8,L3CR_L3I@l
+	sync
+	isync
+	mtspr	SPRN_L3CR,r8
+	sync
+	isync
+
+	/* Wait for the invalidation to complete */
+1:	mfspr	r8,SPRN_L3CR
+	rlwinm.	r9,r8,0,21,21
+	bne	1b
+
+	rlwinm	r8,r8,0,22,20		/* Turn off L3I bit */
+	sync
+	isync
+	mtspr	SPRN_L3CR,r8
+	sync
+	isync
+	blr
+
+
+/* udelay (on non-601 processors) needs to know the period of the
+ * timebase in nanoseconds.  This used to be hardcoded to be 60ns
+ * (period of 66MHz/4).  Now a variable is used that is initialized to
+ * 60 for backward compatibility, but it can be overridden as necessary
+ * with code something like this:
+ *    extern unsigned long timebase_period_ns;
+ *    timebase_period_ns = 1000000000 / bd->bi_tbfreq;
+ */
+	.data
+	.globl timebase_period_ns
+timebase_period_ns:
+	.long	60
+
+	.text
+/*
+ * Delay for a number of microseconds
+ */
+	.globl	udelay
+udelay:
+	mfspr	r4,SPRN_PVR
+	srwi	r4,r4,16
+	cmpwi	0,r4,1		/* 601 ? */
+	bne	.udelay_not_601
+00:	li	r0,86	/* Instructions / microsecond? */
+	mtctr	r0
+10:	addi	r0,r0,0 /* NOP */
+	bdnz	10b
+	subic.	r3,r3,1
+	bne	00b
+	blr
+
+.udelay_not_601:
+	mulli	r4,r3,1000	/* nanoseconds */
+	/*  Change r4 to be the number of ticks using:	
+	 *	(nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns
+	 *  timebase_period_ns defaults to 60 (16.6MHz) */
+	lis	r5,timebase_period_ns@ha
+	lwz	r5,timebase_period_ns@l(r5)
+	add	r4,r4,r5
+	addi	r4,r4,-1
+	divw	r4,r4,r5	/* BUS ticks */
+1:	mftbu	r5
+	mftb	r6
+	mftbu	r7
+	cmpw	0,r5,r7
+	bne	1b		/* Get [synced] base time */
+	addc	r9,r6,r4	/* Compute end time */
+	addze	r8,r5
+2:	mftbu	r5
+	cmpw	0,r5,r8
+	blt	2b
+	bgt	3f
+	mftb	r6
+	cmpw	0,r6,r9
+	blt	2b
+3:	blr
+
+	.section ".relocate_code","xa"
+/*
+ * Flush and enable instruction cache
+ * First, flush the data cache in case it was enabled and may be
+ * holding instructions for copy back.
+ */
+_GLOBAL(flush_instruction_cache)
+	mflr	r6
+	bl	flush_data_cache
+
+#ifdef CONFIG_8xx
+	lis	r3, IDC_INVALL@h
+	mtspr	SPRN_IC_CST, r3
+	lis	r3, IDC_ENABLE@h
+	mtspr	SPRN_IC_CST, r3
+	lis	r3, IDC_DISABLE@h
+	mtspr	SPRN_DC_CST, r3
+#elif CONFIG_4xx
+	lis	r3,start@h		# r9 = &_start
+	lis	r4,_etext@ha
+	addi	r4,r4,_etext@l		# r8 = &_etext
+1:	dcbf	r0,r3			# Flush the data cache
+	icbi	r0,r3			# Invalidate the instruction cache
+	addi	r3,r3,0x10		# Increment by one cache line
+	cmplwi	cr0,r3,r4		# Are we at the end yet?
+	blt	1b			# No, keep flushing and invalidating
+#else
+	/* Enable, invalidate and then disable the L1 icache/dcache. */
+	li	r3,0
+	ori	r3,r3,(HID0_ICE|HID0_DCE|HID0_ICFI|HID0_DCI)
+	mfspr	r4,SPRN_HID0
+	or	r5,r4,r3
+	isync
+	mtspr	SPRN_HID0,r5
+	sync
+	isync
+	ori	r5,r4,HID0_ICE	/* Enable cache */
+	mtspr	SPRN_HID0,r5
+	sync
+	isync
+#endif
+	mtlr	r6
+	blr
+
+#define NUM_CACHE_LINES 128*8
+#define cache_flush_buffer 0x1000
+
+/*
+ * Flush data cache
+ * Do this by just reading lots of stuff into the cache.
+ */
+_GLOBAL(flush_data_cache)
+	lis	r3,cache_flush_buffer@h
+	ori	r3,r3,cache_flush_buffer@l
+	li	r4,NUM_CACHE_LINES
+	mtctr	r4
+00:	lwz	r4,0(r3)
+	addi	r3,r3,L1_CACHE_BYTES	/* Next line, please */
+	bdnz	00b
+10:	blr
+
+	.previous
+
diff --git a/arch/ppc/boot/images/Makefile b/arch/ppc/boot/images/Makefile
new file mode 100644
index 0000000..774de8e
--- /dev/null
+++ b/arch/ppc/boot/images/Makefile
@@ -0,0 +1,27 @@
+#
+# This dir holds all of the images for PPC machines.
+# Tom Rini	January 2001
+
+MKIMAGE		:= $(srctree)/scripts/mkuboot.sh
+
+extra-y		:= vmlinux.bin vmlinux.gz
+
+OBJCOPYFLAGS_vmlinux.bin := -O binary
+$(obj)/vmlinux.bin: vmlinux FORCE
+	$(call if_changed,objcopy)
+
+$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
+	$(call if_changed,gzip)
+
+quiet_cmd_uimage = UIMAGE  $@
+      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \
+               -C gzip -a 00000000 -e 00000000 -n 'Linux-$(KERNELRELEASE)' \
+               -d $< $@
+
+targets += uImage
+$(obj)/uImage: $(obj)/vmlinux.gz
+	$(call if_changed,uimage)
+	@echo '  Image $@ is ready'
+
+# Files generated that shall be removed upon make clean
+clean-files	:= sImage vmapus vmlinux* miboot* zImage* uImage
diff --git a/arch/ppc/boot/include/cpc700.h b/arch/ppc/boot/include/cpc700.h
new file mode 100644
index 0000000..28cfcde
--- /dev/null
+++ b/arch/ppc/boot/include/cpc700.h
@@ -0,0 +1,26 @@
+
+#ifndef __PPC_BOOT_CPC700_H
+#define __PPC_BOOT_CPC700_H
+
+#define CPC700_MEM_CFGADDR    0xff500008
+#define CPC700_MEM_CFGDATA    0xff50000c
+
+#define CPC700_MB0SA            0x38
+#define CPC700_MB0EA            0x58
+#define CPC700_MB1SA            0x3c
+#define CPC700_MB1EA            0x5c
+#define CPC700_MB2SA            0x40
+#define CPC700_MB2EA            0x60
+#define CPC700_MB3SA            0x44
+#define CPC700_MB3EA            0x64
+#define CPC700_MB4SA            0x48
+#define CPC700_MB4EA            0x68
+
+static inline long
+cpc700_read_memreg(int reg)
+{
+	out_be32((volatile unsigned int *) CPC700_MEM_CFGADDR, reg);
+	return in_be32((volatile unsigned int *) CPC700_MEM_CFGDATA);
+}
+
+#endif
diff --git a/arch/ppc/boot/include/iso_font.h b/arch/ppc/boot/include/iso_font.h
new file mode 100644
index 0000000..bff050e
--- /dev/null
+++ b/arch/ppc/boot/include/iso_font.h
@@ -0,0 +1,257 @@
+static const unsigned char font[] = {
+/* 0x00 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x01 */ 0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xBD,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,
+/* 0x02 */ 0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xC3,0xC3,0xE7,0xFF,0x7E,0x00,0x00,0x00,0x00,
+/* 0x03 */ 0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,
+/* 0x04 */ 0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
+/* 0x05 */ 0x00,0x00,0x00,0x18,0x3C,0x3C,0xE7,0xE7,0xE7,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x06 */ 0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x07 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x08 */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+/* 0x09 */ 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,
+/* 0x0A */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,
+/* 0x0B */ 0x00,0x00,0x3E,0x0E,0x1A,0x32,0x78,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
+/* 0x0C */ 0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x0D */ 0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00,
+/* 0x0E */ 0x00,0x00,0x7F,0x63,0x7F,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00,
+/* 0x0F */ 0x00,0x00,0x00,0x18,0x18,0xDB,0x3C,0xE7,0x3C,0xDB,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x10 */ 0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,
+/* 0x11 */ 0x00,0x02,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,
+/* 0x12 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,
+/* 0x13 */ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
+/* 0x14 */ 0x00,0x00,0x7F,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00,
+/* 0x15 */ 0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,
+/* 0x16 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,
+/* 0x17 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00,
+/* 0x18 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x19 */ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,
+/* 0x1A */ 0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x1B */ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x1C */ 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x1D */ 0x00,0x00,0x00,0x00,0x00,0x28,0x6C,0xFE,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x1E */ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,
+/* 0x1F */ 0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
+/* 0x20 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x21 */ 0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x22 */ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x23 */ 0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00,
+/* 0x24 */ 0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00,
+/* 0x25 */ 0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00,
+/* 0x26 */ 0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x27 */ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x28 */ 0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00,
+/* 0x29 */ 0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00,
+/* 0x2A */ 0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x2B */ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x2C */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,
+/* 0x2D */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x2E */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x2F */ 0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,
+/* 0x30 */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
+/* 0x31 */ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00,
+/* 0x32 */ 0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00,
+/* 0x33 */ 0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x34 */ 0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00,
+/* 0x35 */ 0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x36 */ 0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x37 */ 0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
+/* 0x38 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x39 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00,
+/* 0x3A */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
+/* 0x3B */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
+/* 0x3C */ 0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,
+/* 0x3D */ 0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x3E */ 0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00,
+/* 0x3F */ 0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x40 */ 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00,
+/* 0x41 */ 0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x42 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00,
+/* 0x43 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00,
+/* 0x44 */ 0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00,
+/* 0x45 */ 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
+/* 0x46 */ 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+/* 0x47 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00,
+/* 0x48 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x49 */ 0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x4A */ 0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
+/* 0x4B */ 0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
+/* 0x4C */ 0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
+/* 0x4D */ 0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x4E */ 0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x4F */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x50 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+/* 0x51 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00,
+/* 0x52 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
+/* 0x53 */ 0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x54 */ 0x00,0x00,0x7E,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x55 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x56 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00,
+/* 0x57 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00,
+/* 0x58 */ 0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x59 */ 0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x5A */ 0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00,
+/* 0x5B */ 0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00,
+/* 0x5C */ 0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,
+/* 0x5D */ 0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00,
+/* 0x5E */ 0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x5F */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,
+/* 0x60 */ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x61 */ 0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x62 */ 0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00,
+/* 0x63 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x64 */ 0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x65 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x66 */ 0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+/* 0x67 */ 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,
+/* 0x68 */ 0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
+/* 0x69 */ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x6A */ 0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,
+/* 0x6B */ 0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00,
+/* 0x6C */ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x6D */ 0x00,0x00,0x00,0x00,0x00,0x6C,0xFE,0xD6,0xD6,0xD6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x6E */ 0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
+/* 0x6F */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x70 */ 0x00,0x00,0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,
+/* 0x71 */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00,
+/* 0x72 */ 0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+/* 0x73 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x74 */ 0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00,
+/* 0x75 */ 0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x76 */ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00,
+/* 0x77 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00,
+/* 0x78 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,
+/* 0x79 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00,
+/* 0x7A */ 0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00,
+/* 0x7B */ 0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00,
+/* 0x7C */ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x7D */ 0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
+/* 0x7E */ 0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0x7F */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00,
+/* 0x80 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x06,0x7C,0x00,0x00,
+/* 0x81 */ 0x00,0x00,0xCC,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x82 */ 0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x83 */ 0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x84 */ 0x00,0x00,0xCC,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x85 */ 0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x86 */ 0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x87 */ 0x00,0x00,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x0C,0x06,0x3C,0x00,0x00,0x00,
+/* 0x88 */ 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x89 */ 0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x8A */ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x8B */ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x8C */ 0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x8D */ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0x8E */ 0x00,0xC6,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x8F */ 0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0x90 */ 0x18,0x30,0x60,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00,
+/* 0x91 */ 0x00,0x00,0x00,0x00,0x00,0xCC,0x76,0x36,0x7E,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00,
+/* 0x92 */ 0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00,
+/* 0x93 */ 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x94 */ 0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x95 */ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x96 */ 0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x97 */ 0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0x98 */ 0x00,0x00,0xC6,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
+/* 0x99 */ 0x00,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x9A */ 0x00,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0x9B */ 0x00,0x18,0x18,0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x9C */ 0x00,0x38,0x6C,0x64,0x60,0xF8,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00,
+/* 0x9D */ 0x00,0x00,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0x9E */ 0x00,0xF8,0xCC,0xCC,0xF8,0xC4,0xCC,0xDE,0xCC,0xCC,0xCC,0xC6,0x00,0x00,0x00,0x00,
+/* 0x9F */ 0x00,0x0E,0x1B,0x18,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0xD8,0x70,0x00,0x00,
+/* 0xA0 */ 0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0xA1 */ 0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+/* 0xA2 */ 0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0xA3 */ 0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+/* 0xA4 */ 0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
+/* 0xA5 */ 0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0xA6 */ 0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xA7 */ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xA8 */ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+/* 0xA9 */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,
+/* 0xAA */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,
+/* 0xAB */ 0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x60,0xDC,0x86,0x0C,0x18,0x3E,0x00,0x00,
+/* 0xAC */ 0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x66,0xCE,0x9E,0x3E,0x06,0x06,0x00,0x00,
+/* 0xAD */ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,
+/* 0xAE */ 0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xAF */ 0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xB0 */ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
+/* 0xB1 */ 0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,
+/* 0xB2 */ 0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,
+/* 0xB3 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xB4 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xB5 */ 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xB6 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xB7 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xB8 */ 0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xB9 */ 0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xBA */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xBB */ 0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xBC */ 0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xBD */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xBE */ 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xBF */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xC0 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xC1 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xC2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xC3 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xC4 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xC5 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xC6 */ 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xC7 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xC8 */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xC9 */ 0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xCA */ 0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xCB */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xCC */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xCD */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xCE */ 0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xCF */ 0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xD0 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xD1 */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xD2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xD3 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xD4 */ 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xD5 */ 0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xD6 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xD7 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+/* 0xD8 */ 0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xD9 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xDA */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xDB */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+/* 0xDC */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+/* 0xDD */ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
+/* 0xDE */ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
+/* 0xDF */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xE0 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0xD8,0xD8,0xD8,0xDC,0x76,0x00,0x00,0x00,0x00,
+/* 0xE1 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xFC,0xC6,0xC6,0xC6,0xC6,0xDC,0xC0,0xC0,0x00,0x00,
+/* 0xE2 */ 0x00,0x00,0xFE,0xC6,0xC6,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,
+/* 0xE3 */ 0x00,0x00,0x00,0x00,0x00,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,
+/* 0xE4 */ 0x00,0x00,0xFE,0xC6,0x60,0x30,0x18,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00,
+/* 0xE5 */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,
+/* 0xE6 */ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0xC0,0x00,0x00,0x00,
+/* 0xE7 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/* 0xE8 */ 0x00,0x00,0x7E,0x18,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00,
+/* 0xE9 */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
+/* 0xEA */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x6C,0x6C,0x6C,0xEE,0x00,0x00,0x00,0x00,
+/* 0xEB */ 0x00,0x00,0x1E,0x30,0x18,0x0C,0x3E,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00,
+/* 0xEC */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0xDB,0xDB,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xED */ 0x00,0x00,0x00,0x03,0x06,0x7E,0xDB,0xDB,0xF3,0x7E,0x60,0xC0,0x00,0x00,0x00,0x00,
+/* 0xEE */ 0x00,0x00,0x1C,0x30,0x60,0x60,0x7C,0x60,0x60,0x60,0x30,0x1C,0x00,0x00,0x00,0x00,
+/* 0xEF */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+/* 0xF0 */ 0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,
+/* 0xF1 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,
+/* 0xF2 */ 0x00,0x00,0x00,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00,0x7E,0x00,0x00,0x00,0x00,
+/* 0xF3 */ 0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00,0x7E,0x00,0x00,0x00,0x00,
+/* 0xF4 */ 0x00,0x0E,0x1B,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+/* 0xF5 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,
+/* 0xF6 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7E,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
+/* 0xF7 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xF8 */ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xF9 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xFA */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xFB */ 0x00,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0xEC,0x6C,0x6C,0x3C,0x1C,0x00,0x00,0x00,0x00,
+/* 0xFC */ 0x00,0xD8,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xFD */ 0x00,0x70,0xD8,0x30,0x60,0xC8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+/* 0xFE */ 0x00,0x00,0x00,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x00,0x00,0x00,0x00,
+};
diff --git a/arch/ppc/boot/include/mpc10x.h b/arch/ppc/boot/include/mpc10x.h
new file mode 100644
index 0000000..6cd40ec
--- /dev/null
+++ b/arch/ppc/boot/include/mpc10x.h
@@ -0,0 +1,65 @@
+/*
+ * arch/ppc/boot/include/mpc10.h
+ *
+ * Common defines for the Motorola SPS MPC106/8240/107 Host bridge/Mem
+ * ctrl/EPIC/etc.
+ *
+ * Author: Tom Rini <trini@mvista.com>
+ *
+ * This is a heavily stripped down version of:
+ * include/asm-ppc/mpc10x.h
+ *
+ * Author: Mark A. Greer
+ *         mgreer@mvista.com
+ *
+ * 2001-2002 (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.
+ */
+#ifndef __BOOT_MPC10X_H__
+#define __BOOT_MPC10X_H__
+
+/*
+ * The values here don't completely map everything but should work in most
+ * cases.
+ *
+ * MAP A (PReP Map)
+ *   Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff
+ *   Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff
+ *   PCI MEM:   0x80000000 -> Processor System Memory: 0x00000000
+ *   EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
+ *
+ * MAP B (CHRP Map)
+ *   Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff
+ *   Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff
+ *   PCI MEM:   0x00000000 -> Processor System Memory: 0x00000000
+ *   EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB)
+ */
+
+/* Define the type of map to use */
+#define	MPC10X_MEM_MAP_A		1
+#define	MPC10X_MEM_MAP_B		2
+
+/* Map A (PReP Map) Defines */
+#define	MPC10X_MAPA_CNFG_ADDR		0x80000cf8
+#define	MPC10X_MAPA_CNFG_DATA		0x80000cfc
+
+/* Map B (CHRP Map) Defines */
+#define	MPC10X_MAPB_CNFG_ADDR		0xfec00000
+#define	MPC10X_MAPB_CNFG_DATA		0xfee00000
+
+/* Define offsets for the memory controller registers in the config space */
+#define MPC10X_MCTLR_MEM_START_1	0x80	/* Banks 0-3 */
+#define MPC10X_MCTLR_MEM_START_2	0x84	/* Banks 4-7 */
+#define MPC10X_MCTLR_EXT_MEM_START_1	0x88	/* Banks 0-3 */
+#define MPC10X_MCTLR_EXT_MEM_START_2	0x8c	/* Banks 4-7 */
+
+#define MPC10X_MCTLR_MEM_END_1		0x90	/* Banks 0-3 */
+#define MPC10X_MCTLR_MEM_END_2		0x94	/* Banks 4-7 */
+#define MPC10X_MCTLR_EXT_MEM_END_1	0x98	/* Banks 0-3 */
+#define MPC10X_MCTLR_EXT_MEM_END_2	0x9c	/* Banks 4-7 */
+
+#define MPC10X_MCTLR_MEM_BANK_ENABLES	0xa0
+
+#endif	/* __BOOT_MPC10X_H__ */
diff --git a/arch/ppc/boot/include/mpsc_defs.h b/arch/ppc/boot/include/mpsc_defs.h
new file mode 100644
index 0000000..2ce7bbb
--- /dev/null
+++ b/arch/ppc/boot/include/mpsc_defs.h
@@ -0,0 +1,146 @@
+/*
+ * drivers/serial/mpsc/mpsc_defs.h
+ *
+ * Register definitions for the Marvell Multi-Protocol Serial Controller (MPSC),
+ * Serial DMA Controller (SDMA), and Baud Rate Generator (BRG).
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2004 (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.
+ */
+#ifndef	_PPC_BOOT_MPSC_DEFS_H__
+#define	_PPC_BOOT_MPSC_DEFS_H__
+
+#define	MPSC_NUM_CTLRS		2
+
+/*
+ *****************************************************************************
+ *
+ *	Multi-Protocol Serial Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+/* Main Configuratino Register Offsets */
+#define	MPSC_MMCRL			0x0000
+#define	MPSC_MMCRH			0x0004
+#define	MPSC_MPCR			0x0008
+#define	MPSC_CHR_1			0x000c
+#define	MPSC_CHR_2			0x0010
+#define	MPSC_CHR_3			0x0014
+#define	MPSC_CHR_4			0x0018
+#define	MPSC_CHR_5			0x001c
+#define	MPSC_CHR_6			0x0020
+#define	MPSC_CHR_7			0x0024
+#define	MPSC_CHR_8			0x0028
+#define	MPSC_CHR_9			0x002c
+#define	MPSC_CHR_10			0x0030
+#define	MPSC_CHR_11			0x0034
+
+#define	MPSC_MPCR_CL_5			0
+#define	MPSC_MPCR_CL_6			1
+#define	MPSC_MPCR_CL_7			2
+#define	MPSC_MPCR_CL_8			3
+#define	MPSC_MPCR_SBL_1			0
+#define	MPSC_MPCR_SBL_2			3
+
+#define	MPSC_CHR_2_TEV			(1<<1)
+#define	MPSC_CHR_2_TA			(1<<7)
+#define	MPSC_CHR_2_TTCS			(1<<9)
+#define	MPSC_CHR_2_REV			(1<<17)
+#define	MPSC_CHR_2_RA			(1<<23)
+#define	MPSC_CHR_2_CRD			(1<<25)
+#define	MPSC_CHR_2_EH			(1<<31)
+#define	MPSC_CHR_2_PAR_ODD		0
+#define	MPSC_CHR_2_PAR_SPACE		1
+#define	MPSC_CHR_2_PAR_EVEN		2
+#define	MPSC_CHR_2_PAR_MARK		3
+
+/* MPSC Signal Routing */
+#define	MPSC_MRR			0x0000
+#define	MPSC_RCRR			0x0004
+#define	MPSC_TCRR			0x0008
+
+/*
+ *****************************************************************************
+ *
+ *	Serial DMA Controller Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	SDMA_SDC			0x0000
+#define	SDMA_SDCM			0x0008
+#define	SDMA_RX_DESC			0x0800
+#define	SDMA_RX_BUF_PTR			0x0808
+#define	SDMA_SCRDP			0x0810
+#define	SDMA_TX_DESC			0x0c00
+#define	SDMA_SCTDP			0x0c10
+#define	SDMA_SFTDP			0x0c14
+
+#define	SDMA_DESC_CMDSTAT_PE		(1<<0)
+#define	SDMA_DESC_CMDSTAT_CDL		(1<<1)
+#define	SDMA_DESC_CMDSTAT_FR		(1<<3)
+#define	SDMA_DESC_CMDSTAT_OR		(1<<6)
+#define	SDMA_DESC_CMDSTAT_BR		(1<<9)
+#define	SDMA_DESC_CMDSTAT_MI		(1<<10)
+#define	SDMA_DESC_CMDSTAT_A		(1<<11)
+#define	SDMA_DESC_CMDSTAT_AM		(1<<12)
+#define	SDMA_DESC_CMDSTAT_CT		(1<<13)
+#define	SDMA_DESC_CMDSTAT_C		(1<<14)
+#define	SDMA_DESC_CMDSTAT_ES		(1<<15)
+#define	SDMA_DESC_CMDSTAT_L		(1<<16)
+#define	SDMA_DESC_CMDSTAT_F		(1<<17)
+#define	SDMA_DESC_CMDSTAT_P		(1<<18)
+#define	SDMA_DESC_CMDSTAT_EI		(1<<23)
+#define	SDMA_DESC_CMDSTAT_O		(1<<31)
+
+#define SDMA_DESC_DFLT			(SDMA_DESC_CMDSTAT_O |	\
+					SDMA_DESC_CMDSTAT_EI)
+
+#define	SDMA_SDC_RFT			(1<<0)
+#define	SDMA_SDC_SFM			(1<<1)
+#define	SDMA_SDC_BLMR			(1<<6)
+#define	SDMA_SDC_BLMT			(1<<7)
+#define	SDMA_SDC_POVR			(1<<8)
+#define	SDMA_SDC_RIFB			(1<<9)
+
+#define	SDMA_SDCM_ERD			(1<<7)
+#define	SDMA_SDCM_AR			(1<<15)
+#define	SDMA_SDCM_STD			(1<<16)
+#define	SDMA_SDCM_TXD			(1<<23)
+#define	SDMA_SDCM_AT			(1<<31)
+
+#define	SDMA_0_CAUSE_RXBUF		(1<<0)
+#define	SDMA_0_CAUSE_RXERR		(1<<1)
+#define	SDMA_0_CAUSE_TXBUF		(1<<2)
+#define	SDMA_0_CAUSE_TXEND		(1<<3)
+#define	SDMA_1_CAUSE_RXBUF		(1<<8)
+#define	SDMA_1_CAUSE_RXERR		(1<<9)
+#define	SDMA_1_CAUSE_TXBUF		(1<<10)
+#define	SDMA_1_CAUSE_TXEND		(1<<11)
+
+#define	SDMA_CAUSE_RX_MASK	(SDMA_0_CAUSE_RXBUF | SDMA_0_CAUSE_RXERR | \
+	SDMA_1_CAUSE_RXBUF | SDMA_1_CAUSE_RXERR)
+#define	SDMA_CAUSE_TX_MASK	(SDMA_0_CAUSE_TXBUF | SDMA_0_CAUSE_TXEND | \
+	SDMA_1_CAUSE_TXBUF | SDMA_1_CAUSE_TXEND)
+
+/* SDMA Interrupt registers */
+#define	SDMA_INTR_CAUSE			0x0000
+#define	SDMA_INTR_MASK			0x0080
+
+/*
+ *****************************************************************************
+ *
+ *	Baud Rate Generator Interface Registers
+ *
+ *****************************************************************************
+ */
+
+#define	BRG_BCR				0x0000
+#define	BRG_BTR				0x0004
+
+#endif /*_PPC_BOOT_MPSC_DEFS_H__ */
diff --git a/arch/ppc/boot/include/nonstdio.h b/arch/ppc/boot/include/nonstdio.h
new file mode 100644
index 0000000..f2b5526
--- /dev/null
+++ b/arch/ppc/boot/include/nonstdio.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ *
+ * This is sort of a catchall for I/O related functions.  Stuff that
+ * wouldn't be in 'stdio.h' normally is here, and it's 'nonstdio.h'
+ * for a reason.  -- Tom
+ */
+typedef int FILE;
+extern FILE *stdin, *stdout;
+#define NULL ((void *)0)
+#define EOF (-1)
+#define fopen(n, m) NULL
+#define fflush(f) 0
+#define fclose(f) 0
+#define perror(s) printf("%s: no files!\n", (s))
+
+extern int getc(void);
+extern int printf(const char *format, ...);
+extern int sprintf(char *str, const char *format, ...);
+extern int tstc(void);
+extern void exit(void);
+extern void outb(int port, unsigned char val);
+extern void putc(const char c);
+extern void puthex(unsigned long val);
+extern void puts(const char *);
+extern void udelay(long delay);
+extern unsigned char inb(int port);
+extern void board_isa_init(void);
+extern void ISA_init(unsigned long base);
diff --git a/arch/ppc/boot/include/of1275.h b/arch/ppc/boot/include/of1275.h
new file mode 100644
index 0000000..69173df
--- /dev/null
+++ b/arch/ppc/boot/include/of1275.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+typedef void *prom_handle;
+typedef void *ihandle;
+typedef void *phandle;
+typedef int (*prom_entry)(void *);
+
+#define OF_INVALID_HANDLE	((prom_handle)-1UL)
+
+extern prom_entry of_prom_entry;
+
+/* function declarations */
+
+void *	claim(unsigned int virt, unsigned int size, unsigned int align);
+int	map(unsigned int phys, unsigned int virt, unsigned int size);
+void	enter(void);
+void	exit(void);
+phandle	finddevice(const char *name);
+int	getprop(phandle node, const char *name, void *buf, int buflen);
+void	ofinit(prom_entry entry);
+int	ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr);
+int	read(ihandle instance, void *buf, int buflen);
+void	release(void *virt, unsigned int size);
+int	write(ihandle instance, void *buf, int buflen);
+
+/* inlines */
+
+extern inline void pause(void)
+{
+	enter();
+}
diff --git a/arch/ppc/boot/include/rs6000.h b/arch/ppc/boot/include/rs6000.h
new file mode 100644
index 0000000..433f450
--- /dev/null
+++ b/arch/ppc/boot/include/rs6000.h
@@ -0,0 +1,243 @@
+/* IBM RS/6000 "XCOFF" file definitions for BFD.
+   Copyright (C) 1990, 1991 Free Software Foundation, Inc.
+   FIXME: Can someone provide a transliteration of this name into ASCII?
+   Using the following chars caused a compiler warning on HIUX (so I replaced
+   them with octal escapes), and isn't useful without an understanding of what
+   character set it is.
+   Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM
+   and John Gilmore of Cygnus Support.  */
+
+/********************** FILE HEADER **********************/
+
+struct external_filehdr {
+	char f_magic[2];	/* magic number			*/
+	char f_nscns[2];	/* number of sections		*/
+	char f_timdat[4];	/* time & date stamp		*/
+	char f_symptr[4];	/* file pointer to symtab	*/
+	char f_nsyms[4];	/* number of symtab entries	*/
+	char f_opthdr[2];	/* sizeof(optional hdr)		*/
+	char f_flags[2];	/* flags			*/
+};
+
+        /* IBM RS/6000 */
+#define U802WRMAGIC     0730    /* writeable text segments **chh**      */
+#define U802ROMAGIC     0735    /* readonly sharable text segments      */
+#define U802TOCMAGIC    0737    /* readonly text segments and TOC       */
+
+#define BADMAG(x)	\
+	((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \
+	 (x).f_magic != U802TOCMAGIC)
+
+#define	FILHDR	struct external_filehdr
+#define	FILHSZ	20
+
+
+/********************** AOUT "OPTIONAL HEADER" **********************/
+
+
+typedef struct
+{
+  unsigned char	magic[2];	/* type of file			*/
+  unsigned char	vstamp[2];	/* version stamp		*/
+  unsigned char	tsize[4];	/* text size in bytes, padded to FW bdry */
+  unsigned char	dsize[4];	/* initialized data "  "	*/
+  unsigned char	bsize[4];	/* uninitialized data "   "	*/
+  unsigned char	entry[4];	/* entry pt.			*/
+  unsigned char	text_start[4];	/* base of text used for this file */
+  unsigned char	data_start[4];	/* base of data used for this file */
+  unsigned char	o_toc[4];	/* address of TOC */
+  unsigned char	o_snentry[2];	/* section number of entry point */
+  unsigned char	o_sntext[2];	/* section number of .text section */
+  unsigned char	o_sndata[2];	/* section number of .data section */
+  unsigned char	o_sntoc[2];	/* section number of TOC */
+  unsigned char	o_snloader[2];	/* section number of .loader section */
+  unsigned char	o_snbss[2];	/* section number of .bss section */
+  unsigned char	o_algntext[2];	/* .text alignment */
+  unsigned char	o_algndata[2];	/* .data alignment */
+  unsigned char	o_modtype[2];	/* module type (??) */
+  unsigned char o_cputype[2];	/* cpu type */
+  unsigned char	o_maxstack[4];	/* max stack size (??) */
+  unsigned char o_maxdata[4];	/* max data size (??) */
+  unsigned char	o_resv2[12];	/* reserved */
+}
+AOUTHDR;
+
+#define AOUTSZ 72
+#define SMALL_AOUTSZ (28)
+#define AOUTHDRSZ 72
+
+#define	RS6K_AOUTHDR_OMAGIC	0x0107	/* old: text & data writeable */
+#define	RS6K_AOUTHDR_NMAGIC	0x0108	/* new: text r/o, data r/w */
+#define	RS6K_AOUTHDR_ZMAGIC	0x010B	/* paged: text r/o, both page-aligned */
+
+
+/********************** SECTION HEADER **********************/
+
+
+struct external_scnhdr {
+	char		s_name[8];	/* section name			*/
+	char		s_paddr[4];	/* physical address, aliased s_nlib */
+	char		s_vaddr[4];	/* virtual address		*/
+	char		s_size[4];	/* section size			*/
+	char		s_scnptr[4];	/* file ptr to raw data for section */
+	char		s_relptr[4];	/* file ptr to relocation	*/
+	char		s_lnnoptr[4];	/* file ptr to line numbers	*/
+	char		s_nreloc[2];	/* number of relocation entries	*/
+	char		s_nlnno[2];	/* number of line number entries*/
+	char		s_flags[4];	/* flags			*/
+};
+
+/*
+ * names of "special" sections
+ */
+#define _TEXT	".text"
+#define _DATA	".data"
+#define _BSS	".bss"
+#define _PAD	".pad"
+#define _LOADER	".loader"
+
+#define	SCNHDR	struct external_scnhdr
+#define	SCNHSZ	40
+
+/* XCOFF uses a special .loader section with type STYP_LOADER.  */
+#define STYP_LOADER 0x1000
+
+/* XCOFF uses a special .debug section with type STYP_DEBUG.  */
+#define STYP_DEBUG 0x2000
+
+/* XCOFF handles line number or relocation overflow by creating
+   another section header with STYP_OVRFLO set.  */
+#define STYP_OVRFLO 0x8000
+
+/********************** LINE NUMBERS **********************/
+
+/* 1 line number entry for every "breakpointable" source line in a section.
+ * Line numbers are grouped on a per function basis; first entry in a function
+ * grouping will have l_lnno = 0 and in place of physical address will be the
+ * symbol table index of the function name.
+ */
+struct external_lineno {
+	union {
+		char l_symndx[4];	/* function name symbol index, iff l_lnno == 0*/
+		char l_paddr[4];	/* (physical) address of line number	*/
+	} l_addr;
+	char l_lnno[2];	/* line number		*/
+};
+
+
+#define	LINENO	struct external_lineno
+#define	LINESZ	6
+
+
+/********************** SYMBOLS **********************/
+
+#define E_SYMNMLEN	8	/* # characters in a symbol name	*/
+#define E_FILNMLEN	14	/* # characters in a file name		*/
+#define E_DIMNUM	4	/* # array dimensions in auxiliary entry */
+
+struct external_syment
+{
+  union {
+    char e_name[E_SYMNMLEN];
+    struct {
+      char e_zeroes[4];
+      char e_offset[4];
+    } e;
+  } e;
+  char e_value[4];
+  char e_scnum[2];
+  char e_type[2];
+  char e_sclass[1];
+  char e_numaux[1];
+};
+
+
+
+#define N_BTMASK	(017)
+#define N_TMASK		(060)
+#define N_BTSHFT	(4)
+#define N_TSHIFT	(2)
+
+
+union external_auxent {
+	struct {
+		char x_tagndx[4];	/* str, un, or enum tag indx */
+		union {
+			struct {
+			    char  x_lnno[2]; /* declaration line number */
+			    char  x_size[2]; /* str/union/array size */
+			} x_lnsz;
+			char x_fsize[4];	/* size of function */
+		} x_misc;
+		union {
+			struct {		/* if ISFCN, tag, or .bb */
+			    char x_lnnoptr[4];	/* ptr to fcn line # */
+			    char x_endndx[4];	/* entry ndx past block end */
+			} x_fcn;
+			struct {		/* if ISARY, up to 4 dimen. */
+			    char x_dimen[E_DIMNUM][2];
+			} x_ary;
+		} x_fcnary;
+		char x_tvndx[2];		/* tv index */
+	} x_sym;
+
+	union {
+		char x_fname[E_FILNMLEN];
+		struct {
+			char x_zeroes[4];
+			char x_offset[4];
+		} x_n;
+	} x_file;
+
+	struct {
+		char x_scnlen[4];			/* section length */
+		char x_nreloc[2];	/* # relocation entries */
+		char x_nlinno[2];	/* # line numbers */
+	} x_scn;
+
+        struct {
+		char x_tvfill[4];	/* tv fill value */
+		char x_tvlen[2];	/* length of .tv */
+		char x_tvran[2][2];	/* tv range */
+	} x_tv;		/* info about .tv section (in auxent of symbol .tv)) */
+
+	struct {
+		unsigned char x_scnlen[4];
+		unsigned char x_parmhash[4];
+		unsigned char x_snhash[2];
+		unsigned char x_smtyp[1];
+		unsigned char x_smclas[1];
+		unsigned char x_stab[4];
+		unsigned char x_snstab[2];
+	} x_csect;
+
+};
+
+#define	SYMENT	struct external_syment
+#define	SYMESZ	18
+#define	AUXENT	union external_auxent
+#define	AUXESZ	18
+#define DBXMASK 0x80		/* for dbx storage mask */
+#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK)
+
+
+
+/********************** RELOCATION DIRECTIVES **********************/
+
+
+struct external_reloc {
+  char r_vaddr[4];
+  char r_symndx[4];
+  char r_size[1];
+  char r_type[1];
+};
+
+
+#define RELOC struct external_reloc
+#define RELSZ 10
+
+#define DEFAULT_DATA_SECTION_ALIGNMENT 4
+#define DEFAULT_BSS_SECTION_ALIGNMENT 4
+#define DEFAULT_TEXT_SECTION_ALIGNMENT 4
+/* For new sections we havn't heard of before */
+#define DEFAULT_SECTION_ALIGNMENT 4
diff --git a/arch/ppc/boot/include/serial.h b/arch/ppc/boot/include/serial.h
new file mode 100644
index 0000000..d710eab
--- /dev/null
+++ b/arch/ppc/boot/include/serial.h
@@ -0,0 +1,46 @@
+/*
+ * A really private header file for the (dumb) serial driver in arch/ppc/boot
+ *
+ * Shamelessly taken from include/linux/serialP.h:
+ *
+ * Copyright (C) 1997 by Theodore Ts'o.
+ *
+ * Redistribution of this file is permitted under the terms of the GNU
+ * Public License (GPL)
+ */
+
+#ifndef _PPC_BOOT_SERIALP_H
+#define _PPC_BOOT_SERIALP_H
+
+/*
+ * This is our internal structure for each serial port's state.
+ *
+ * Many fields are paralleled by the structure used by the serial_struct
+ * structure.
+ *
+ * Given that this is how SERIAL_PORT_DFNS are done, and that we need
+ * to use a few of their fields, we need to have our own copy of it.
+ */
+struct serial_state {
+	int	magic;
+	int	baud_base;
+	unsigned long	port;
+	int	irq;
+	int	flags;
+	int	hub6;
+	int	type;
+	int	line;
+	int	revision;	/* Chip revision (950) */
+	int	xmit_fifo_size;
+	int	custom_divisor;
+	int	count;
+	u8	*iomem_base;
+	u16	iomem_reg_shift;
+	unsigned short	close_delay;
+	unsigned short	closing_wait; /* time to wait before closing */
+	unsigned long	icount;
+	int	io_type;
+	void    *info;
+	void    *dev;
+};
+#endif /* _PPC_BOOT_SERIAL_H */
diff --git a/arch/ppc/boot/ld.script b/arch/ppc/boot/ld.script
new file mode 100644
index 0000000..6ee602d
--- /dev/null
+++ b/arch/ppc/boot/ld.script
@@ -0,0 +1,88 @@
+OUTPUT_ARCH(powerpc)
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .plt : { *(.plt) }
+  .text      :
+  {
+    *(.text)
+    *(.fixup)
+    __relocate_start = .;
+    *(.relocate_code)
+    __relocate_end = .;
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+
+  /* Read-write section, merged into data segment: */
+  . = ALIGN(4096);
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.data.boot)
+    *(.sdata)
+    *(.sdata2)
+    *(.got.plt) *(.got)
+    *(.dynamic)
+    *(.rodata)
+    *(.rodata.*)
+    *(.rodata1)
+    *(.got1)
+    __image_begin = .;
+    *(.image)
+    __image_end = .;
+    . = ALIGN(4096);
+    __ramdisk_begin = .;
+    *(.ramdisk)
+    __ramdisk_end = .;
+    . = ALIGN(4096);
+    __sysmap_begin = .;
+    *(.sysmap)
+    __sysmap_end = .;
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  . = ALIGN(4096);
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+
+  /DISCARD/ : {
+    *(__ksymtab)
+    *(__ksymtab_strings)
+    *(__bug_table)
+    *(__kcrctab)
+  }
+
+}
diff --git a/arch/ppc/boot/lib/Makefile b/arch/ppc/boot/lib/Makefile
new file mode 100644
index 0000000..d4077e6
--- /dev/null
+++ b/arch/ppc/boot/lib/Makefile
@@ -0,0 +1,23 @@
+#
+# Makefile for some libs needed by zImage.
+#
+
+CFLAGS_kbd.o	:= -Idrivers/char
+CFLAGS_vreset.o := -I$(srctree)/arch/ppc/boot/include
+
+zlib  := infblock.c infcodes.c inffast.c inflate.c inftrees.c infutil.c
+	 
+lib-y += $(zlib:.c=.o) div64.o
+lib-$(CONFIG_VGA_CONSOLE) += vreset.o kbd.o
+
+
+# zlib files needs header from their original place
+EXTRA_CFLAGS += -Ilib/zlib_inflate
+
+quiet_cmd_copy_zlib = COPY    $@
+      cmd_copy_zlib = cat $< > $@
+
+$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/%
+	$(call cmd,copy_zlib)
+
+clean-files := $(zlib)
diff --git a/arch/ppc/boot/lib/div64.S b/arch/ppc/boot/lib/div64.S
new file mode 100644
index 0000000..3527569
--- /dev/null
+++ b/arch/ppc/boot/lib/div64.S
@@ -0,0 +1,58 @@
+/*
+ * Divide a 64-bit unsigned number by a 32-bit unsigned number.
+ * This routine assumes that the top 32 bits of the dividend are
+ * non-zero to start with.
+ * On entry, r3 points to the dividend, which get overwritten with
+ * the 64-bit quotient, and r4 contains the divisor.
+ * On exit, r3 contains the remainder.
+ *
+ * Copyright (C) 2002 Paul Mackerras, IBM Corp.
+ *
+ * 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.
+ */
+#include <asm/ppc_asm.h>
+#include <asm/processor.h>
+
+_GLOBAL(__div64_32)
+	lwz	r5,0(r3)	# get the dividend into r5/r6
+	lwz	r6,4(r3)
+	cmplw	r5,r4
+	li	r7,0
+	li	r8,0
+	blt	1f
+	divwu	r7,r5,r4	# if dividend.hi >= divisor,
+	mullw	r0,r7,r4	# quotient.hi = dividend.hi / divisor
+	subf.	r5,r0,r5	# dividend.hi %= divisor
+	beq	3f
+1:	mr	r11,r5		# here dividend.hi != 0
+	andis.	r0,r5,0xc000
+	bne	2f
+	cntlzw	r0,r5		# we are shifting the dividend right
+	li	r10,-1		# to make it < 2^32, and shifting
+	srw	r10,r10,r0	# the divisor right the same amount,
+	add	r9,r4,r10	# rounding up (so the estimate cannot
+	andc	r11,r6,r10	# ever be too large, only too small)
+	andc	r9,r9,r10
+	or	r11,r5,r11
+	rotlw	r9,r9,r0
+	rotlw	r11,r11,r0
+	divwu	r11,r11,r9	# then we divide the shifted quantities
+2:	mullw	r10,r11,r4	# to get an estimate of the quotient,
+	mulhwu	r9,r11,r4	# multiply the estimate by the divisor,
+	subfc	r6,r10,r6	# take the product from the divisor,
+	add	r8,r8,r11	# and add the estimate to the accumulated
+	subfe.	r5,r9,r5	# quotient
+	bne	1b
+3:	cmplw	r6,r4
+	blt	4f
+	divwu	r0,r6,r4	# perform the remaining 32-bit division
+	mullw	r10,r0,r4	# and get the remainder
+	add	r8,r8,r0
+	subf	r6,r10,r6
+4:	stw	r7,0(r3)	# return the quotient in *r3
+	stw	r8,4(r3)
+	mr	r3,r6		# return the remainder in r3
+	blr
diff --git a/arch/ppc/boot/lib/kbd.c b/arch/ppc/boot/lib/kbd.c
new file mode 100644
index 0000000..3931727
--- /dev/null
+++ b/arch/ppc/boot/lib/kbd.c
@@ -0,0 +1,248 @@
+#include <linux/keyboard.h>
+
+#include "defkeymap.c"	/* yeah I know it's bad -- Cort */
+
+
+unsigned char shfts, ctls, alts, caps;
+
+#define	KBDATAP		0x60	/* kbd data port */
+#define	KBSTATUSPORT	0x61	/* kbd status */
+#define	KBSTATP		0x64	/* kbd status port */
+#define	KBINRDY		0x01
+#define	KBOUTRDY	0x02
+
+extern unsigned char inb(int port);
+extern void outb(int port, char val);
+extern void puts(const char *);
+extern void puthex(unsigned long val);
+extern void udelay(long x);
+
+static int kbd(int noblock)
+{
+	unsigned char dt, brk, val;
+	unsigned code;
+loop:
+	if (noblock) {
+	    if ((inb(KBSTATP) & KBINRDY) == 0)
+		return (-1);
+	} else while((inb(KBSTATP) & KBINRDY) == 0) ;
+
+	dt = inb(KBDATAP);
+
+	brk = dt & 0x80;	/* brk == 1 on key release */
+	dt = dt & 0x7f;		/* keycode */
+
+	if (shfts)
+	    code = shift_map[dt];
+	else if (ctls)
+	    code = ctrl_map[dt];
+	else
+	    code = plain_map[dt];
+
+	val = KVAL(code);
+	switch (KTYP(code) & 0x0f) {
+	    case KT_LATIN:
+		if (brk)
+		    break;
+		if (alts)
+		    val |= 0x80;
+		if (val == 0x7f)	/* map delete to backspace */
+		    val = '\b';
+		return val;
+
+	    case KT_LETTER:
+		if (brk)
+		    break;
+		if (caps)
+		    val -= 'a'-'A';
+		return val;
+
+	    case KT_SPEC:
+		if (brk)
+		    break;
+		if (val == KVAL(K_CAPS))
+		    caps = !caps;
+		else if (val == KVAL(K_ENTER)) {
+enter:		    /* Wait for key up */
+		    while (1) {
+			while((inb(KBSTATP) & KBINRDY) == 0) ;
+			dt = inb(KBDATAP);
+			if (dt & 0x80) /* key up */ break;
+		    }
+		    return 10;
+		}
+		break;
+
+	    case KT_PAD:
+		if (brk)
+		    break;
+		if (val < 10)
+		    return val;
+		if (val == KVAL(K_PENTER))
+		    goto enter;
+		break;
+
+	    case KT_SHIFT:
+		switch (val) {
+		    case KG_SHIFT:
+		    case KG_SHIFTL:
+		    case KG_SHIFTR:
+			shfts = brk ? 0 : 1;
+			break;
+		    case KG_ALT:
+		    case KG_ALTGR:
+			alts = brk ? 0 : 1;
+			break;
+		    case KG_CTRL:
+		    case KG_CTRLL:
+		    case KG_CTRLR:
+			ctls = brk ? 0 : 1;
+			break;
+		}
+		break;
+
+	    case KT_LOCK:
+		switch (val) {
+		    case KG_SHIFT:
+		    case KG_SHIFTL:
+		    case KG_SHIFTR:
+			if (brk)
+			    shfts = !shfts;
+			break;
+		    case KG_ALT:
+		    case KG_ALTGR:
+			if (brk)
+			    alts = !alts;
+			break;
+		    case KG_CTRL:
+		    case KG_CTRLL:
+		    case KG_CTRLR:
+			if (brk)
+			    ctls = !ctls;
+			break;
+		}
+		break;
+	}
+	if (brk) return (-1);  /* Ignore initial 'key up' codes */
+	goto loop;
+}
+
+static int __kbdreset(void)
+{
+	unsigned char c;
+	int i, t;
+
+	/* flush input queue */
+	t = 2000;
+	while ((inb(KBSTATP) & KBINRDY))
+	{
+		(void)inb(KBDATAP);
+		if (--t == 0)
+			return 1;
+	}
+	/* Send self-test */
+	t = 20000;
+	while (inb(KBSTATP) & KBOUTRDY)
+		if (--t == 0)
+			return 2;
+	outb(KBSTATP,0xAA);
+	t = 200000;
+	while ((inb(KBSTATP) & KBINRDY) == 0)	/* wait input ready */
+		if (--t == 0)
+			return 3;
+	if ((c = inb(KBDATAP)) != 0x55)
+	{
+		puts("Keyboard self test failed - result:");
+		puthex(c);
+		puts("\n");
+	}
+	/* Enable interrupts and keyboard controller */
+	t = 20000;
+	while (inb(KBSTATP) & KBOUTRDY)
+		if (--t == 0) return 4;
+	outb(KBSTATP,0x60);
+	t = 20000;
+	while (inb(KBSTATP) & KBOUTRDY)
+		if (--t == 0) return 5;
+	outb(KBDATAP,0x45);
+	for (i = 0;  i < 10000;  i++) udelay(1);
+
+	t = 20000;
+	while (inb(KBSTATP) & KBOUTRDY)
+		if (--t == 0) return 6;
+	outb(KBSTATP,0x20);
+	t = 200000;
+	while ((inb(KBSTATP) & KBINRDY) == 0)	/* wait input ready */
+		if (--t == 0) return 7;
+	if (! (inb(KBDATAP) & 0x40)) {
+		/*
+		 * Quote from PS/2 System Reference Manual:
+		 *
+		 * "Address hex 0060 and address hex 0064 should be
+		 * written only when the input-buffer-full bit and
+		 * output-buffer-full bit in the Controller Status
+		 * register are set 0." (KBINRDY and KBOUTRDY)
+		 */
+		t = 200000;
+		while (inb(KBSTATP) & (KBINRDY | KBOUTRDY))
+			if (--t == 0) return 8;
+		outb(KBDATAP,0xF0);
+		t = 200000;
+		while (inb(KBSTATP) & (KBINRDY | KBOUTRDY))
+			if (--t == 0) return 9;
+		outb(KBDATAP,0x01);
+	}
+	t = 20000;
+	while (inb(KBSTATP) & KBOUTRDY)
+		if (--t == 0) return 10;
+	outb(KBSTATP,0xAE);
+	return 0;
+}
+
+static void kbdreset(void)
+{
+	int ret = __kbdreset();
+
+	if (ret) {
+		puts("__kbdreset failed: ");
+		puthex(ret);
+		puts("\n");
+	}
+}
+
+/* We have to actually read the keyboard when CRT_tstc is called,
+ * since the pending data might be a key release code, and therefore
+ * not valid data.  In this case, kbd() will return -1, even though there's
+ * data to be read.  Of course, we might actually read a valid key press,
+ * in which case it gets queued into key_pending for use by CRT_getc.
+ */
+
+static int kbd_reset = 0;
+
+static int key_pending = -1;
+
+int CRT_getc(void)
+{
+	int c;
+	if (!kbd_reset) {kbdreset(); kbd_reset++; }
+
+        if (key_pending != -1) {
+                c = key_pending;
+                key_pending = -1;
+                return c;
+        } else {
+	while ((c = kbd(0)) == 0) ;
+                return c;
+        }
+}
+
+int CRT_tstc(void)
+{
+	if (!kbd_reset) {kbdreset(); kbd_reset++; }
+
+        while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) {
+                key_pending = kbd(1);
+        }
+
+        return (key_pending != -1);
+}
diff --git a/arch/ppc/boot/lib/vreset.c b/arch/ppc/boot/lib/vreset.c
new file mode 100644
index 0000000..463ba00
--- /dev/null
+++ b/arch/ppc/boot/lib/vreset.c
@@ -0,0 +1,805 @@
+/*
+ * vreset.c
+ *
+ * Initialize the VGA control registers to 80x25 text mode.
+ *
+ * Adapted from a program by:
+ *                                      Steve Sellgren
+ *                                      San Francisco Indigo Company
+ *                                      sfindigo!sellgren@uunet.uu.net
+ *
+ * Original concept by:
+ *                                      Gary Thomas <gdt@linuxppc.org>
+ * Adapted for Moto boxes by:
+ *                                      Pat Kane & Mark Scott, 1996
+ * Adapted for IBM portables by:
+ *                                      Takeshi Ishimoto
+ * Multi-console support:
+ *                                      Terje Malmedal <terje.malmedal@usit.uio.no>
+ */
+
+#include "iso_font.h"
+#include "nonstdio.h"
+
+extern char *vidmem;
+extern int lines, cols;
+struct VaRegs;
+
+/*
+ * VGA Register
+ */
+struct VgaRegs
+{
+	unsigned short io_port;
+	unsigned char  io_index;
+	unsigned char  io_value;
+};
+
+void unlockVideo(int slot);
+void setTextRegs(struct VgaRegs *svp);
+void setTextCLUT(int shift);
+void clearVideoMemory(void);
+void loadFont(unsigned char *ISA_mem);
+
+static void mdelay(int ms)
+{
+	for (; ms > 0; --ms)
+		udelay(1000);
+}
+
+/*
+ * Default console text mode registers  used to reset
+ * graphics adapter.
+ */
+#define NREGS 54
+#define ENDMK  0xFFFF  /* End marker */
+
+#define S3Vendor	0x5333
+#define CirrusVendor    0x1013
+#define DiamondVendor   0x100E
+#define MatroxVendor    0x102B
+#define ParadiseVendor  0x101C
+
+struct VgaRegs GenVgaTextRegs[NREGS+1] = {
+	/* port		index	value  */
+	/* SR Regs */
+	{ 0x3c4,	0x1,	0x0 },
+	{ 0x3c4,	0x2,	0x3 },
+	{ 0x3c4,	0x3,	0x0 },
+	{ 0x3c4,	0x4,	0x2 },
+	 /* CR Regs */
+	{ 0x3d4,	0x0,	0x5f },
+	{ 0x3d4,	0x1,	0x4f },
+	{ 0x3d4,	0x2,	0x50 },
+	{ 0x3d4,	0x3,	0x82 },
+	{ 0x3d4,	0x4,	0x55 },
+	{ 0x3d4,	0x5,	0x81 },
+	{ 0x3d4,	0x6,	0xbf },
+	{ 0x3d4,	0x7,	0x1f },
+	{ 0x3d4,	0x8,	0x00 },
+	{ 0x3d4,	0x9,	0x4f },
+	{ 0x3d4,	0xa,	0x0d },
+	{ 0x3d4,	0xb,	0x0e },
+	{ 0x3d4,	0xc,	0x00 },
+	{ 0x3d4,	0xd,	0x00 },
+	{ 0x3d4,	0xe,	0x00 },
+	{ 0x3d4,	0xf,	0x00 },
+	{ 0x3d4,	0x10,	0x9c },
+	{ 0x3d4,	0x11,	0x8e },
+	{ 0x3d4,	0x12,	0x8f },
+	{ 0x3d4,	0x13,	0x28 },
+	{ 0x3d4,	0x14,	0x1f },
+	{ 0x3d4,	0x15,	0x96 },
+	{ 0x3d4,	0x16,	0xb9 },
+	{ 0x3d4,	0x17,	0xa3 },
+	 /* GR Regs */
+	{ 0x3ce,	0x0,	0x0 },
+	{ 0x3ce,	0x1,	0x0 },
+	{ 0x3ce,	0x2,	0x0 },
+	{ 0x3ce,	0x3,	0x0 },
+	{ 0x3ce,	0x4,	0x0 },
+	{ 0x3ce,	0x5,	0x10 },
+	{ 0x3ce,	0x6,	0xe },
+	{ 0x3ce,	0x7,	0x0 },
+	{ 0x3ce,	0x8,	0xff },
+	{ ENDMK }
+};
+
+struct RGBColors
+{
+  unsigned char r, g, b;
+};
+
+/*
+ * Default console text mode color table.
+ * These values were obtained by booting Linux with
+ * text mode firmware & then dumping the registers.
+ */
+struct RGBColors TextCLUT[256] =
+{
+	/* red	green	blue  */
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x2a },
+	{ 0x0,	0x2a,	0x0 },
+	{ 0x0,	0x2a,	0x2a },
+	{ 0x2a,	0x0,	0x0 },
+	{ 0x2a,	0x0,	0x2a },
+	{ 0x2a,	0x2a,	0x0 },
+	{ 0x2a,	0x2a,	0x2a },
+	{ 0x0,	0x0,	0x15 },
+	{ 0x0,	0x0,	0x3f },
+	{ 0x0,	0x2a,	0x15 },
+	{ 0x0,	0x2a,	0x3f },
+	{ 0x2a,	0x0,	0x15 },
+	{ 0x2a,	0x0,	0x3f },
+	{ 0x2a,	0x2a,	0x15 },
+	{ 0x2a,	0x2a,	0x3f },
+	{ 0x0,	0x15,	0x0 },
+	{ 0x0,	0x15,	0x2a },
+	{ 0x0,	0x3f,	0x0 },
+	{ 0x0,	0x3f,	0x2a },
+	{ 0x2a,	0x15,	0x0 },
+	{ 0x2a,	0x15,	0x2a },
+	{ 0x2a,	0x3f,	0x0 },
+	{ 0x2a,	0x3f,	0x2a },
+	{ 0x0,	0x15,	0x15 },
+	{ 0x0,	0x15,	0x3f },
+	{ 0x0,	0x3f,	0x15 },
+	{ 0x0,	0x3f,	0x3f },
+	{ 0x2a,	0x15,	0x15 },
+	{ 0x2a,	0x15,	0x3f },
+	{ 0x2a,	0x3f,	0x15 },
+	{ 0x2a,	0x3f,	0x3f },
+	{ 0x15,	0x0,	0x0 },
+	{ 0x15,	0x0,	0x2a },
+	{ 0x15,	0x2a,	0x0 },
+	{ 0x15,	0x2a,	0x2a },
+	{ 0x3f,	0x0,	0x0 },
+	{ 0x3f,	0x0,	0x2a },
+	{ 0x3f,	0x2a,	0x0 },
+	{ 0x3f,	0x2a,	0x2a },
+	{ 0x15,	0x0,	0x15 },
+	{ 0x15,	0x0,	0x3f },
+	{ 0x15,	0x2a,	0x15 },
+	{ 0x15,	0x2a,	0x3f },
+	{ 0x3f,	0x0,	0x15 },
+	{ 0x3f,	0x0,	0x3f },
+	{ 0x3f,	0x2a,	0x15 },
+	{ 0x3f,	0x2a,	0x3f },
+	{ 0x15,	0x15,	0x0 },
+	{ 0x15,	0x15,	0x2a },
+	{ 0x15,	0x3f,	0x0 },
+	{ 0x15,	0x3f,	0x2a },
+	{ 0x3f,	0x15,	0x0 },
+	{ 0x3f,	0x15,	0x2a },
+	{ 0x3f,	0x3f,	0x0 },
+	{ 0x3f,	0x3f,	0x2a },
+	{ 0x15,	0x15,	0x15 },
+	{ 0x15,	0x15,	0x3f },
+	{ 0x15,	0x3f,	0x15 },
+	{ 0x15,	0x3f,	0x3f },
+	{ 0x3f,	0x15,	0x15 },
+	{ 0x3f,	0x15,	0x3f },
+	{ 0x3f,	0x3f,	0x15 },
+	{ 0x3f,	0x3f,	0x3f },
+	{ 0x39,	0xc,	0x5 },
+	{ 0x15,	0x2c,	0xf },
+	{ 0x26,	0x10,	0x3d },
+	{ 0x29,	0x29,	0x38 },
+	{ 0x4,	0x1a,	0xe },
+	{ 0x2,	0x1e,	0x3a },
+	{ 0x3c,	0x25,	0x33 },
+	{ 0x3c,	0xc,	0x2c },
+	{ 0x3f,	0x3,	0x2b },
+	{ 0x1c,	0x9,	0x13 },
+	{ 0x25,	0x2a,	0x35 },
+	{ 0x1e,	0xa,	0x38 },
+	{ 0x24,	0x8,	0x3 },
+	{ 0x3,	0xe,	0x36 },
+	{ 0xc,	0x6,	0x2a },
+	{ 0x26,	0x3,	0x32 },
+	{ 0x5,	0x2f,	0x33 },
+	{ 0x3c,	0x35,	0x2f },
+	{ 0x2d,	0x26,	0x3e },
+	{ 0xd,	0xa,	0x10 },
+	{ 0x25,	0x3c,	0x11 },
+	{ 0xd,	0x4,	0x2e },
+	{ 0x5,	0x19,	0x3e },
+	{ 0xc,	0x13,	0x34 },
+	{ 0x2b,	0x6,	0x24 },
+	{ 0x4,	0x3,	0xd },
+	{ 0x2f,	0x3c,	0xc },
+	{ 0x2a,	0x37,	0x1f },
+	{ 0xf,	0x12,	0x38 },
+	{ 0x38,	0xe,	0x2a },
+	{ 0x12,	0x2f,	0x19 },
+	{ 0x29,	0x2e,	0x31 },
+	{ 0x25,	0x13,	0x3e },
+	{ 0x33,	0x3e,	0x33 },
+	{ 0x1d,	0x2c,	0x25 },
+	{ 0x15,	0x15,	0x5 },
+	{ 0x32,	0x25,	0x39 },
+	{ 0x1a,	0x7,	0x1f },
+	{ 0x13,	0xe,	0x1d },
+	{ 0x36,	0x17,	0x34 },
+	{ 0xf,	0x15,	0x23 },
+	{ 0x2,	0x35,	0xd },
+	{ 0x15,	0x3f,	0xc },
+	{ 0x14,	0x2f,	0xf },
+	{ 0x19,	0x21,	0x3e },
+	{ 0x27,	0x11,	0x2f },
+	{ 0x38,	0x3f,	0x3c },
+	{ 0x36,	0x2d,	0x15 },
+	{ 0x16,	0x17,	0x2 },
+	{ 0x1,	0xa,	0x3d },
+	{ 0x1b,	0x11,	0x3f },
+	{ 0x21,	0x3c,	0xd },
+	{ 0x1a,	0x39,	0x3d },
+	{ 0x8,	0xe,	0xe },
+	{ 0x22,	0x21,	0x23 },
+	{ 0x1e,	0x30,	0x5 },
+	{ 0x1f,	0x22,	0x3d },
+	{ 0x1e,	0x2f,	0xa },
+	{ 0x0,	0x1c,	0xe },
+	{ 0x0,	0x1c,	0x15 },
+	{ 0x0,	0x1c,	0x1c },
+	{ 0x0,	0x15,	0x1c },
+	{ 0x0,	0xe,	0x1c },
+	{ 0x0,	0x7,	0x1c },
+	{ 0xe,	0xe,	0x1c },
+	{ 0x11,	0xe,	0x1c },
+	{ 0x15,	0xe,	0x1c },
+	{ 0x18,	0xe,	0x1c },
+	{ 0x1c,	0xe,	0x1c },
+	{ 0x1c,	0xe,	0x18 },
+	{ 0x1c,	0xe,	0x15 },
+	{ 0x1c,	0xe,	0x11 },
+	{ 0x1c,	0xe,	0xe },
+	{ 0x1c,	0x11,	0xe },
+	{ 0x1c,	0x15,	0xe },
+	{ 0x1c,	0x18,	0xe },
+	{ 0x1c,	0x1c,	0xe },
+	{ 0x18,	0x1c,	0xe },
+	{ 0x15,	0x1c,	0xe },
+	{ 0x11,	0x1c,	0xe },
+	{ 0xe,	0x1c,	0xe },
+	{ 0xe,	0x1c,	0x11 },
+	{ 0xe,	0x1c,	0x15 },
+	{ 0xe,	0x1c,	0x18 },
+	{ 0xe,	0x1c,	0x1c },
+	{ 0xe,	0x18,	0x1c },
+	{ 0xe,	0x15,	0x1c },
+	{ 0xe,	0x11,	0x1c },
+	{ 0x14,	0x14,	0x1c },
+	{ 0x16,	0x14,	0x1c },
+	{ 0x18,	0x14,	0x1c },
+	{ 0x1a,	0x14,	0x1c },
+	{ 0x1c,	0x14,	0x1c },
+	{ 0x1c,	0x14,	0x1a },
+	{ 0x1c,	0x14,	0x18 },
+	{ 0x1c,	0x14,	0x16 },
+	{ 0x1c,	0x14,	0x14 },
+	{ 0x1c,	0x16,	0x14 },
+	{ 0x1c,	0x18,	0x14 },
+	{ 0x1c,	0x1a,	0x14 },
+	{ 0x1c,	0x1c,	0x14 },
+	{ 0x1a,	0x1c,	0x14 },
+	{ 0x18,	0x1c,	0x14 },
+	{ 0x16,	0x1c,	0x14 },
+	{ 0x14,	0x1c,	0x14 },
+	{ 0x14,	0x1c,	0x16 },
+	{ 0x14,	0x1c,	0x18 },
+	{ 0x14,	0x1c,	0x1a },
+	{ 0x14,	0x1c,	0x1c },
+	{ 0x14,	0x1a,	0x1c },
+	{ 0x14,	0x18,	0x1c },
+	{ 0x14,	0x16,	0x1c },
+	{ 0x0,	0x0,	0x10 },
+	{ 0x4,	0x0,	0x10 },
+	{ 0x8,	0x0,	0x10 },
+	{ 0xc,	0x0,	0x10 },
+	{ 0x10,	0x0,	0x10 },
+	{ 0x10,	0x0,	0xc },
+	{ 0x10,	0x0,	0x8 },
+	{ 0x10,	0x0,	0x4 },
+	{ 0x10,	0x0,	0x0 },
+	{ 0x10,	0x4,	0x0 },
+	{ 0x10,	0x8,	0x0 },
+	{ 0x10,	0xc,	0x0 },
+	{ 0x10,	0x10,	0x0 },
+	{ 0xc,	0x10,	0x0 },
+	{ 0x8,	0x10,	0x0 },
+	{ 0x4,	0x10,	0x0 },
+	{ 0x0,	0x10,	0x0 },
+	{ 0x0,	0x10,	0x4 },
+	{ 0x0,	0x10,	0x8 },
+	{ 0x0,	0x10,	0xc },
+	{ 0x0,	0x10,	0x10 },
+	{ 0x0,	0xc,	0x10 },
+	{ 0x0,	0x8,	0x10 },
+	{ 0x0,	0x4,	0x10 },
+	{ 0x8,	0x8,	0x10 },
+	{ 0xa,	0x8,	0x10 },
+	{ 0xc,	0x8,	0x10 },
+	{ 0xe,	0x8,	0x10 },
+	{ 0x10,	0x8,	0x10 },
+	{ 0x10,	0x8,	0xe },
+	{ 0x10,	0x8,	0xc },
+	{ 0x10,	0x8,	0xa },
+	{ 0x10,	0x8,	0x8 },
+	{ 0x10,	0xa,	0x8 },
+	{ 0x10,	0xc,	0x8 },
+	{ 0x10,	0xe,	0x8 },
+	{ 0x10,	0x10,	0x8 },
+	{ 0xe,	0x10,	0x8 },
+	{ 0xc,	0x10,	0x8 },
+	{ 0xa,	0x10,	0x8 },
+	{ 0x8,	0x10,	0x8 },
+	{ 0x8,	0x10,	0xa },
+	{ 0x8,	0x10,	0xc },
+	{ 0x8,	0x10,	0xe },
+	{ 0x8,	0x10,	0x10 },
+	{ 0x8,	0xe,	0x10 },
+	{ 0x8,	0xc,	0x10 },
+	{ 0x8,	0xa,	0x10 },
+	{ 0xb,	0xb,	0x10 },
+	{ 0xc,	0xb,	0x10 },
+	{ 0xd,	0xb,	0x10 },
+	{ 0xf,	0xb,	0x10 },
+	{ 0x10,	0xb,	0x10 },
+	{ 0x10,	0xb,	0xf },
+	{ 0x10,	0xb,	0xd },
+	{ 0x10,	0xb,	0xc },
+	{ 0x10,	0xb,	0xb },
+	{ 0x10,	0xc,	0xb },
+	{ 0x10,	0xd,	0xb },
+	{ 0x10,	0xf,	0xb },
+	{ 0x10,	0x10,	0xb },
+	{ 0xf,	0x10,	0xb },
+	{ 0xd,	0x10,	0xb },
+	{ 0xc,	0x10,	0xb },
+	{ 0xb,	0x10,	0xb },
+	{ 0xb,	0x10,	0xc },
+	{ 0xb,	0x10,	0xd },
+	{ 0xb,	0x10,	0xf },
+	{ 0xb,	0x10,	0x10 },
+	{ 0xb,	0xf,	0x10 },
+	{ 0xb,	0xd,	0x10 },
+	{ 0xb,	0xc,	0x10 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 },
+	{ 0x0,	0x0,	0x0 }
+};
+
+unsigned char AC[21] = {
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+    0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+    0x0C, 0x00, 0x0F, 0x08, 0x00};
+
+static int scanPCI(int start_slt);
+static int PCIVendor(int);
+#ifdef DEBUG
+static void printslots(void);
+#endif
+extern void puthex(unsigned long);
+extern void puts(const char *);
+static void unlockS3(void);
+
+static inline void
+outw(int port, unsigned short val)
+{
+	outb(port, val >> 8);
+	outb(port+1, val);
+}
+
+int
+vga_init(unsigned char *ISA_mem)
+{
+	int slot;
+	struct VgaRegs *VgaTextRegs;
+
+	/* See if VGA already in TEXT mode - exit if so! */
+	outb(0x3CE, 0x06);
+	if ((inb(0x3CF) & 0x01) == 0){
+		puts("VGA already in text mode\n");
+		return 0;
+	}
+
+	/* If no VGA responding in text mode, then we have some work to do...
+	 */
+	slot = -1;
+	while((slot = scanPCI(slot)) > -1) { /* find video card in use  */
+		unlockVideo(slot);           /* enable I/O to card      */
+		VgaTextRegs = GenVgaTextRegs;
+
+		switch (PCIVendor(slot)) {
+		default:
+			break;
+		case(S3Vendor):
+			unlockS3();
+			break;
+
+		case(CirrusVendor):
+			outw(0x3C4, 0x0612);       /* unlock ext regs */
+			outw(0x3C4, 0x0700);       /* reset ext sequence mode */
+			break;
+
+		case(ParadiseVendor):                 /* IBM Portable 850 */
+			outw(0x3ce, 0x0f05);      /* unlock pardise registers */
+			outw(0x3c4, 0x0648);
+			outw(0x3d4, 0x2985);
+			outw(0x3d4, 0x34a6);
+			outb(0x3ce, 0x0b);       /* disable linear addressing */
+			outb(0x3cf, inb(0x3cf) & ~0x30);
+			outw(0x3c4, 0x1400);
+			outb(0x3ce, 0x0e);       /* disable 256 color mode */
+			outb(0x3cf, inb(0x3cf) & ~0x01);
+			outb(0xd00, 0xff);       /* enable auto-centering */
+			if (!(inb(0xd01) & 0x03)) {
+				outb(0x3d4, 0x33);
+				outb(0x3d5, inb(0x3d5) & ~0x90);
+				outb(0x3d4, 0x32);
+				outb(0x3d5, inb(0x3d5) | 0x04);
+				outw(0x3d4, 0x0250);
+				outw(0x3d4, 0x07ba);
+				outw(0x3d4, 0x0900);
+				outw(0x3d4, 0x15e7);
+				outw(0x3d4, 0x2a95);
+			}
+			outw(0x3d4, 0x34a0);
+			break;
+
+	#if 0 /* Untested - probably doesn't work */
+		case(MatroxVendor):
+		case(DiamondVendor):
+			puts("VGA Chip Vendor ID: ");
+			puthex(PCIVendor(slot));
+			puts("\n");
+			mdelay(1000);
+	#endif
+		};
+
+		outw(0x3C4, 0x0120);           /* disable video              */
+		setTextRegs(VgaTextRegs);      /* initial register setup     */
+		setTextCLUT(0);                /* load color lookup table    */
+		loadFont(ISA_mem);             /* load font                  */
+		setTextRegs(VgaTextRegs);      /* reload registers           */
+		outw(0x3C4, 0x0100);           /* re-enable video            */
+		clearVideoMemory();
+
+		if (PCIVendor(slot) == S3Vendor) {
+			outb(0x3c2, 0x63);                  /* MISC */
+		} /* endif */
+
+	#ifdef DEBUG
+		printslots();
+		mdelay(5000);
+	#endif
+
+		mdelay(1000);	/* give time for the video monitor to come up */
+        }
+	return (1);  /* 'CRT' I/O supported */
+}
+
+/*
+ * Write to VGA Attribute registers.
+ */
+void
+writeAttr(unsigned char index, unsigned char data, unsigned char videoOn)
+{
+	unsigned char v;
+	v = inb(0x3da);   /* reset attr. address toggle */
+	if (videoOn)
+		outb(0x3c0, (index & 0x1F) | 0x20);
+	else
+		outb(0x3c0, (index & 0x1F));
+	outb(0x3c0, data);
+}
+
+void
+setTextRegs(struct VgaRegs *svp)
+{
+	int i;
+
+	/*
+	 *  saved settings
+	 */
+	while( svp->io_port != ENDMK ) {
+		outb(svp->io_port,   svp->io_index);
+		outb(svp->io_port+1, svp->io_value);
+		svp++;
+	}
+
+	outb(0x3c2, 0x67);  /* MISC */
+	outb(0x3c6, 0xff);  /* MASK */
+
+	for ( i = 0; i < 0x10; i++)
+		writeAttr(i, AC[i], 0);  /* pallete */
+	writeAttr(0x10, 0x0c, 0);    /* text mode */
+	writeAttr(0x11, 0x00, 0);    /* overscan color (border) */
+	writeAttr(0x12, 0x0f, 0);    /* plane enable */
+	writeAttr(0x13, 0x08, 0);    /* pixel panning */
+	writeAttr(0x14, 0x00, 1);    /* color select; video on  */
+}
+
+void
+setTextCLUT(int shift)
+{
+	int i;
+
+	outb(0x3C6, 0xFF);
+	i = inb(0x3C7);
+	outb(0x3C8, 0);
+	i = inb(0x3C7);
+
+	for ( i = 0; i < 256; i++) {
+		outb(0x3C9, TextCLUT[i].r << shift);
+		outb(0x3C9, TextCLUT[i].g << shift);
+		outb(0x3C9, TextCLUT[i].b << shift);
+	}
+}
+
+void
+loadFont(unsigned char *ISA_mem)
+{
+	int i, j;
+	unsigned char *font_page = (unsigned char *) &ISA_mem[0xA0000];
+
+	outb(0x3C2, 0x67);
+	/*
+	 * Load font
+	 */
+	i = inb(0x3DA);  /* Reset Attr toggle */
+
+	outb(0x3C0,0x30);
+	outb(0x3C0, 0x01);      /* graphics mode */
+
+	outw(0x3C4, 0x0001);    /* reset sequencer */
+	outw(0x3C4, 0x0204);    /* write to plane 2 */
+	outw(0x3C4, 0x0406);    /* enable plane graphics */
+	outw(0x3C4, 0x0003);    /* reset sequencer */
+	outw(0x3CE, 0x0402);    /* read plane 2 */
+	outw(0x3CE, 0x0500);    /* write mode 0, read mode 0 */
+	outw(0x3CE, 0x0605);    /* set graphics mode */
+
+	for (i = 0;  i < sizeof(font);  i += 16) {
+		for (j = 0;  j < 16;  j++) {
+			__asm__ volatile("eieio");
+			font_page[(2*i)+j] = font[i+j];
+		}
+	}
+}
+
+static void
+unlockS3(void)
+{
+        int s3_device_id;
+	outw(0x3d4, 0x3848);
+	outw(0x3d4, 0x39a5);
+	outb(0x3d4, 0x2d);
+	s3_device_id = inb(0x3d5) << 8;
+	outb(0x3d4, 0x2e);
+	s3_device_id |= inb(0x3d5);
+
+	if (s3_device_id != 0x8812) {
+		/* From the S3 manual */
+		outb(0x46E8, 0x10);  /* Put into setup mode */
+		outb(0x3C3, 0x10);
+		outb(0x102, 0x01);   /* Enable registers */
+		outb(0x46E8, 0x08);  /* Enable video */
+		outb(0x3C3, 0x08);
+		outb(0x4AE8, 0x00);
+
+#if 0
+		outb(0x42E8, 0x80);  /* Reset graphics engine? */
+#endif
+
+		outb(0x3D4, 0x38);  /* Unlock all registers */
+		outb(0x3D5, 0x48);
+		outb(0x3D4, 0x39);
+		outb(0x3D5, 0xA5);
+		outb(0x3D4, 0x40);
+		outb(0x3D5, inb(0x3D5)|0x01);
+		outb(0x3D4, 0x33);
+		outb(0x3D5, inb(0x3D5)&~0x52);
+		outb(0x3D4, 0x35);
+		outb(0x3D5, inb(0x3D5)&~0x30);
+		outb(0x3D4, 0x3A);
+		outb(0x3D5, 0x00);
+		outb(0x3D4, 0x53);
+		outb(0x3D5, 0x00);
+		outb(0x3D4, 0x31);
+		outb(0x3D5, inb(0x3D5)&~0x4B);
+		outb(0x3D4, 0x58);
+
+		outb(0x3D5, 0);
+
+		outb(0x3D4, 0x54);
+		outb(0x3D5, 0x38);
+		outb(0x3D4, 0x60);
+		outb(0x3D5, 0x07);
+		outb(0x3D4, 0x61);
+		outb(0x3D5, 0x80);
+		outb(0x3D4, 0x62);
+		outb(0x3D5, 0xA1);
+		outb(0x3D4, 0x69);  /* High order bits for cursor address */
+		outb(0x3D5, 0);
+
+		outb(0x3D4, 0x32);
+		outb(0x3D5, inb(0x3D5)&~0x10);
+	} else {
+                outw(0x3c4, 0x0806);            /* IBM Portable 860 */
+                outw(0x3c4, 0x1041);
+                outw(0x3c4, 0x1128);
+                outw(0x3d4, 0x4000);
+                outw(0x3d4, 0x3100);
+                outw(0x3d4, 0x3a05);
+                outw(0x3d4, 0x6688);
+                outw(0x3d4, 0x5800);            /* disable linear addressing */
+                outw(0x3d4, 0x4500);            /* disable H/W cursor */
+                outw(0x3c4, 0x5410);            /* enable auto-centering */
+                outw(0x3c4, 0x561f);
+                outw(0x3c4, 0x1b80);            /* lock DCLK selection */
+                outw(0x3d4, 0x3900);            /* lock S3 registers */
+                outw(0x3d4, 0x3800);
+	} /* endif */
+}
+
+/*
+ * cursor() sets an offset (0-1999) into the 80x25 text area.
+ */
+void
+cursor(int x, int y)
+{
+	int pos = (y*cols)+x;
+	outb(0x3D4, 14);
+	outb(0x3D5, pos >> 8);
+	outb(0x3D4, 15);
+	outb(0x3D5, pos);
+}
+
+void
+clearVideoMemory(void)
+{
+	int i, j;
+	for (i = 0;  i < lines;  i++) {
+		for (j = 0;  j < cols;  j++) {
+			vidmem[((i*cols)+j)*2] = 0x20;	/* fill with space character */
+			vidmem[((i*cols)+j)*2+1] = 0x07;  /* set bg & fg attributes */
+		}
+	}
+}
+
+/* ============ */
+
+
+#define NSLOTS 8
+#define NPCIREGS  5
+
+
+/*
+ should use devfunc number/indirect method to be totally safe on
+ all machines, this works for now on 3 slot Moto boxes
+*/
+
+struct PCI_ConfigInfo {
+  unsigned long * config_addr;
+  unsigned long regs[NPCIREGS];
+} PCI_slots [NSLOTS] = {
+
+    { (unsigned long *)0x80808000, {0xDEADBEEF,} },   /* onboard */
+    { (unsigned long *)0x80800800, {0xDEADBEEF,} },   /* onboard */
+    { (unsigned long *)0x80801000, {0xDEADBEEF,} },   /* onboard */
+    { (unsigned long *)0x80802000, {0xDEADBEEF,} },   /* onboard */
+    { (unsigned long *)0x80804000, {0xDEADBEEF,} },   /* onboard */
+    { (unsigned long *)0x80810000, {0xDEADBEEF,} },   /* slot A/1 */
+    { (unsigned long *)0x80820000, {0xDEADBEEF,} },   /* slot B/2 */
+    { (unsigned long *)0x80840000, {0xDEADBEEF,} }    /* slot C/3 */
+};
+
+
+
+/*
+ * The following code modifies the PCI Command register
+ * to enable memory and I/O accesses.
+ */
+void
+unlockVideo(int slot)
+{
+       volatile unsigned char * ppci;
+
+        ppci =  (unsigned char * )PCI_slots[slot].config_addr;
+	ppci[4] = 0x0003;         /* enable memory and I/O accesses */
+	ppci[0x10] = 0x00000;     /* turn off memory mapping */
+	ppci[0x11] = 0x00000;     /* mem_base = 0 */
+	ppci[0x12] = 0x00000;
+	ppci[0x13] = 0x00000;
+	__asm__ volatile("eieio");
+
+	outb(0x3d4, 0x11);
+	outb(0x3d5, 0x0e);   /* unlock CR0-CR7 */
+}
+
+long
+SwapBytes(long lv)   /* turn little endian into big indian long */
+{
+    long t;
+    t  = (lv&0x000000FF) << 24;
+    t |= (lv&0x0000FF00) << 8;
+    t |= (lv&0x00FF0000) >> 8;
+    t |= (lv&0xFF000000) >> 24;
+    return(t);
+}
+
+
+#define DEVID   0
+#define CMD     1
+#define CLASS   2
+#define MEMBASE 4
+
+int
+scanPCI(int start_slt)
+{
+	int slt, r;
+	struct PCI_ConfigInfo *pslot;
+	int theSlot = -1;
+	int highVgaSlot = 0;
+
+	for ( slt = start_slt + 1; slt < NSLOTS; slt++) {
+		pslot = &PCI_slots[slt];
+		for ( r = 0; r < NPCIREGS; r++) {
+			pslot->regs[r] = SwapBytes ( pslot->config_addr[r] );
+		}
+		/* card in slot ? */
+		if ( pslot->regs[DEVID] != 0xFFFFFFFF ) {
+			/* VGA ? */
+			if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) ||
+			     ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x00010000)) {
+				highVgaSlot = slt;
+				/* did firmware enable it ? */
+				if ( (pslot->regs[CMD] & 0x03) ) {
+					theSlot = slt;
+					break;
+				}
+			}
+		}
+	}
+
+	return ( theSlot );
+}
+
+/* return Vendor ID of card in the slot */
+static
+int PCIVendor(int slotnum) {
+ struct PCI_ConfigInfo *pslot;
+
+ pslot = &PCI_slots[slotnum];
+
+return (pslot->regs[DEVID] & 0xFFFF);
+}
+
+#ifdef DEBUG
+static
+void printslots(void)
+{
+	int i;
+#if 0
+	struct PCI_ConfigInfo *pslot;
+#endif
+	for(i=0; i < NSLOTS; i++) {
+#if 0
+		pslot = &PCI_slots[i];
+		printf("Slot: %d, Addr: %x, Vendor: %08x, Class: %08x\n",
+		       i, pslot->config_addr, pslot->regs[0], pslot->regs[2]);
+#else
+		puts("PCI Slot number: "); puthex(i);
+		puts(" Vendor ID: ");
+		puthex(PCIVendor(i)); puts("\n");
+#endif
+	}
+}
+#endif /* DEBUG */
diff --git a/arch/ppc/boot/of1275/Makefile b/arch/ppc/boot/of1275/Makefile
new file mode 100644
index 0000000..02e6f23
--- /dev/null
+++ b/arch/ppc/boot/of1275/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile of1275 stuff
+#
+
+lib-y := claim.o enter.o exit.o finddevice.o getprop.o ofinit.o	\
+	 ofstdio.o read.o release.o write.o map.o
diff --git a/arch/ppc/boot/of1275/claim.c b/arch/ppc/boot/of1275/claim.c
new file mode 100644
index 0000000..e060292
--- /dev/null
+++ b/arch/ppc/boot/of1275/claim.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+
+void *
+claim(unsigned int virt, unsigned int size, unsigned int align)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	unsigned int virt;
+	unsigned int size;
+	unsigned int align;
+	void *ret;
+    } args;
+
+    args.service = "claim";
+    args.nargs = 3;
+    args.nret = 1;
+    args.virt = virt;
+    args.size = size;
+    args.align = align;
+    (*of_prom_entry)(&args);
+    return args.ret;
+}
diff --git a/arch/ppc/boot/of1275/enter.c b/arch/ppc/boot/of1275/enter.c
new file mode 100644
index 0000000..abe87a8
--- /dev/null
+++ b/arch/ppc/boot/of1275/enter.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+
+void
+enter(void)
+{
+    struct prom_args {
+	char *service;
+    } args;
+
+    args.service = "enter";
+    (*of_prom_entry)(&args);
+}
diff --git a/arch/ppc/boot/of1275/exit.c b/arch/ppc/boot/of1275/exit.c
new file mode 100644
index 0000000..b9f89b6
--- /dev/null
+++ b/arch/ppc/boot/of1275/exit.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+
+void
+exit(void)
+{
+    struct prom_args {
+	char *service;
+    } args;
+
+    for (;;) {
+	args.service = "exit";
+	(*of_prom_entry)(&args);
+    }
+}
diff --git a/arch/ppc/boot/of1275/finddevice.c b/arch/ppc/boot/of1275/finddevice.c
new file mode 100644
index 0000000..2c0f7cb
--- /dev/null
+++ b/arch/ppc/boot/of1275/finddevice.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+
+phandle
+finddevice(const char *name)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	const char *devspec;
+	phandle device;
+    } args;
+
+    args.service = "finddevice";
+    args.nargs = 1;
+    args.nret = 1;
+    args.devspec = name;
+    args.device = OF_INVALID_HANDLE;
+    (*of_prom_entry)(&args);
+    return args.device;
+}
diff --git a/arch/ppc/boot/of1275/getprop.c b/arch/ppc/boot/of1275/getprop.c
new file mode 100644
index 0000000..0cf75f0
--- /dev/null
+++ b/arch/ppc/boot/of1275/getprop.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+
+int
+getprop(phandle node, const char *name, void *buf, int buflen)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	phandle node;
+	const char *name;
+	void *buf;
+	int buflen;
+	int size;
+    } args;
+
+    args.service = "getprop";
+    args.nargs = 4;
+    args.nret = 1;
+    args.node = node;
+    args.name = name;
+    args.buf = buf;
+    args.buflen = buflen;
+    args.size = -1;
+    (*of_prom_entry)(&args);
+    return args.size;
+}
diff --git a/arch/ppc/boot/of1275/map.c b/arch/ppc/boot/of1275/map.c
new file mode 100644
index 0000000..443256c
--- /dev/null
+++ b/arch/ppc/boot/of1275/map.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+#include "nonstdio.h"
+
+extern ihandle of_prom_mmu;
+
+int
+map(unsigned int phys, unsigned int virt, unsigned int size)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	char *method;
+	ihandle mmu_ihandle;
+	int misc;
+	unsigned int size;
+	unsigned int virt;
+	unsigned int phys;
+	int ret0;
+    } args;
+
+    if (of_prom_mmu == 0) {
+    	printf("map() called, no MMU found\n");
+    	return -1;
+    }
+    args.service = "call-method";
+    args.nargs = 6;
+    args.nret = 1;
+    args.method = "map";
+    args.mmu_ihandle = of_prom_mmu;
+    args.misc = 0;
+    args.phys = phys;
+    args.virt = virt;
+    args.size = size;
+    (*of_prom_entry)(&args);
+
+    return (int)args.ret0;
+}
diff --git a/arch/ppc/boot/of1275/ofinit.c b/arch/ppc/boot/of1275/ofinit.c
new file mode 100644
index 0000000..0ee8af7
--- /dev/null
+++ b/arch/ppc/boot/of1275/ofinit.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+
+prom_entry of_prom_entry;
+ihandle of_prom_mmu;
+
+void
+ofinit(prom_entry prom_ptr)
+{
+    phandle chosen;
+
+    of_prom_entry = prom_ptr;
+
+    if ((chosen = finddevice("/chosen")) == OF_INVALID_HANDLE)
+	return;
+    if (getprop(chosen, "mmu", &of_prom_mmu, sizeof(ihandle)) != 4)
+	return;
+}
diff --git a/arch/ppc/boot/of1275/ofstdio.c b/arch/ppc/boot/of1275/ofstdio.c
new file mode 100644
index 0000000..10abbe3
--- /dev/null
+++ b/arch/ppc/boot/of1275/ofstdio.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+
+int
+ofstdio(ihandle *stdin, ihandle *stdout, ihandle *stderr)
+{
+    ihandle in, out;
+    phandle chosen;
+
+    if ((chosen = finddevice("/chosen")) == OF_INVALID_HANDLE)
+	goto err;
+    if (getprop(chosen, "stdout", &out, sizeof(out)) != 4)
+	goto err;
+    if (getprop(chosen, "stdin", &in, sizeof(in)) != 4)
+	goto err;
+
+    *stdin  = in;
+    *stdout = out;
+    *stderr = out;
+    return 0;
+err:
+    return -1;
+}
diff --git a/arch/ppc/boot/of1275/read.c b/arch/ppc/boot/of1275/read.c
new file mode 100644
index 0000000..1228136
--- /dev/null
+++ b/arch/ppc/boot/of1275/read.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+
+int
+read(ihandle instance, void *buf, int buflen)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	ihandle instance;
+	void *buf;
+	int buflen;
+	int actual;
+    } args;
+
+    args.service = "read";
+    args.nargs = 3;
+    args.nret = 1;
+    args.instance = instance;
+    args.buf = buf;
+    args.buflen = buflen;
+    args.actual = -1;
+    (*of_prom_entry)(&args);
+    return args.actual;
+}
diff --git a/arch/ppc/boot/of1275/release.c b/arch/ppc/boot/of1275/release.c
new file mode 100644
index 0000000..28032d3
--- /dev/null
+++ b/arch/ppc/boot/of1275/release.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+
+void
+release(void *virt, unsigned int size)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	void *virt;
+	unsigned int size;
+    } args;
+
+    args.service = "release";
+    args.nargs = 2;
+    args.nret = 0;
+    args.virt = virt;
+    args.size = size;
+    (*of_prom_entry)(&args);
+}
diff --git a/arch/ppc/boot/of1275/write.c b/arch/ppc/boot/of1275/write.c
new file mode 100644
index 0000000..7361b9b
--- /dev/null
+++ b/arch/ppc/boot/of1275/write.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ * Copyright (C) Leigh Brown 2002.
+ *
+ * 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.
+ */
+
+#include "of1275.h"
+
+int
+write(ihandle instance, void *buf, int buflen)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	ihandle instance;
+	void *buf;
+	int buflen;
+	int actual;
+    } args;
+
+    args.service = "write";
+    args.nargs = 3;
+    args.nret = 1;
+    args.instance = instance;
+    args.buf = buf;
+    args.buflen = buflen;
+    args.actual = -1;
+    (*of_prom_entry)(&args);
+    return args.actual;
+}
diff --git a/arch/ppc/boot/openfirmware/Makefile b/arch/ppc/boot/openfirmware/Makefile
new file mode 100644
index 0000000..4eacbd8
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/Makefile
@@ -0,0 +1,188 @@
+# Makefile for making bootable images on various OpenFirmware machines.
+#
+# Paul Mackerras	January 1997
+#	XCOFF bootable images for PowerMacs
+# Geert Uytterhoeven	September 1997
+#	ELF bootable iamges for CHRP machines.
+# Tom Rini		January 2001
+# 	Cleaned up, moved into arch/ppc/boot/pmac
+# Tom Rini		July/August 2002
+#	Merged 'chrp' and 'pmac' into 'openfirmware', and cleaned up the
+#	rules.
+
+zImage.initrd znetboot.initrd: del-ramdisk-sec	:= -R .ramdisk
+zImage.initrd znetboot.initrd: initrd		:= .initrd
+
+
+boot	:= arch/ppc/boot
+common	:= $(boot)/common
+utils	:= $(boot)/utils
+bootlib	:= $(boot)/lib
+of1275	:= $(boot)/of1275
+images	:= $(boot)/images
+
+OBJCOPY_ARGS	:= -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
+COFF_LD_ARGS	:= -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00500000 \
+			-Bstatic
+CHRP_LD_ARGS	:= -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x00800000
+NEWWORLD_LD_ARGS:= -T $(srctree)/$(boot)/ld.script -e _start -Ttext 0x01000000
+
+COMMONOBJS	:= start.o misc.o common.o
+COFFOBJS	:= coffcrt0.o $(COMMONOBJS) coffmain.o
+CHRPOBJS	:= crt0.o     $(COMMONOBJS) chrpmain.o
+NEWWORLDOBJS	:= crt0.o     $(COMMONOBJS) newworldmain.o
+
+targets 	:= $(COFFOBJS) $(CHRPOBJS) $(NEWWORLDOBJS) dummy.o
+COFFOBJS	:= $(addprefix $(obj)/, $(COFFOBJS))
+CHRPOBJS	:= $(addprefix $(obj)/, $(CHRPOBJS))
+NEWWORLDOBJS	:= $(addprefix $(obj)/, $(NEWWORLDOBJS))
+
+LIBS		:= lib/lib.a $(bootlib)/lib.a $(of1275)/lib.a $(common)/lib.a
+
+HACKCOFF := $(utils)/hack-coff
+
+ifdef CONFIG_SMP
+END := .smp
+endif
+ifdef CONFIG_PPC64BRIDGE
+END += .64
+endif
+
+
+$(images)/ramdisk.image.gz:
+	@echo '  MISSING $@'
+	@echo '          RAM disk image must be provided separately'
+	@/bin/false
+
+objcpxmon-$(CONFIG_XMON) := --add-section=.sysmap=System.map \
+	--set-section-flags=.sysmap=contents,alloc,load,readonly,data
+quiet_cmd_genimage = GEN     $@
+      cmd_genimage = $(OBJCOPY) -R .comment       \
+	--add-section=.image=$(images)/vmlinux.gz \
+	--set-section-flags=.image=contents,alloc,load,readonly,data \
+	$(objcpxmon-y) $< $@
+
+targets += image.o
+$(obj)/image.o: $(obj)/dummy.o $(images)/vmlinux.gz FORCE
+	$(call if_changed,genimage)
+
+# Place the ramdisk in the initrd image.
+quiet_cmd_genimage-initrd = GEN     $@
+      cmd_genimage-initrd = $(OBJCOPY) $< $@ \
+	--add-section=.ramdisk=$(images)/ramdisk.image.gz \
+	--set-section-flags=.ramdisk=contents,alloc,load,readonly,data
+targets += image.initrd.o
+$(obj)/image.initrd.o: $(obj)/image.o $(images)/ramdisk.image.gz FORCE
+	$(call if_changed,genimage-initrd)
+
+# Create the note section for New-World PowerMacs.
+quiet_cmd_mknote = MKNOTE  $@
+     cmd_mknote  = $(utils)/mknote > $@
+targets		+= note
+$(obj)/note: $(utils)/mknote FORCE
+	$(call if_changed,mknote)
+
+
+$(obj)/coffcrt0.o: EXTRA_AFLAGS := -traditional -DXCOFF
+$(obj)/crt0.o:     EXTRA_AFLAGS := -traditional
+targets += coffcrt0.o crt0.o
+$(obj)/coffcrt0.o $(obj)/crt0.o: $(common)/crt0.S FORCE
+	$(call if_changed_dep,as_o_S)
+
+quiet_cmd_gencoffb = COFF    $@
+      cmd_gencoffb = $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) $< $(LIBS) && \
+                     $(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
+targets += coffboot
+$(obj)/coffboot: $(obj)/image.o $(COFFOBJS) $(LIBS) $(srctree)/$(boot)/ld.script FORCE
+	$(call if_changed,gencoffb)
+targets += coffboot.initrd
+$(obj)/coffboot.initrd: $(obj)/image.initrd.o $(COFFOBJS) $(LIBS) \
+			$(srctree)/$(boot)/ld.script FORCE
+	$(call if_changed,gencoffb)
+
+
+quiet_cmd_gen-coff = COFF    $@
+      cmd_gen-coff = $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ && \
+			$(HACKCOFF) $@ && \
+			ln -sf $(notdir $@) $(images)/zImage$(initrd).pmac
+
+$(images)/vmlinux.coff: $(obj)/coffboot
+	$(call cmd,gen-coff)
+
+$(images)/vmlinux.initrd.coff: $(obj)/coffboot.initrd
+	$(call cmd,gen-coff)
+
+quiet_cmd_gen-elf-pmac = ELF     $@
+      cmd_gen-elf-pmac = $(LD) $(NEWWORLD_LD_ARGS) -o $@ \
+				$(NEWWORLDOBJS) $(LIBS) $< && \
+			$(OBJCOPY) $@ $@ --add-section=.note=$(obj)/note \
+					 -R .comment $(del-ramdisk-sec)
+
+$(images)/vmlinux.elf-pmac: $(obj)/image.o $(NEWWORLDOBJS) $(LIBS) \
+			$(obj)/note $(srctree)/$(boot)/ld.script
+	$(call cmd,gen-elf-pmac)
+$(images)/vmlinux.initrd.elf-pmac: $(obj)/image.initrd.o $(NEWWORLDOBJS) \
+				   $(LIBS) $(obj)/note \
+				   $(srctree)/$(boot)/ld.script
+	$(call cmd,gen-elf-pmac)
+
+quiet_cmd_gen-chrp = CHRP    $@
+      cmd_gen-chrp = $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) $< $(LIBS) && \
+			$(OBJCOPY) $@ $@ -R .comment $(del-ramdisk-sec)
+
+$(images)/zImage.chrp: $(obj)/image.o $(CHRPOBJS) $(LIBS) \
+				   $(srctree)/$(boot)/ld.script
+	$(call cmd,gen-chrp)
+$(images)/zImage.initrd.chrp: $(obj)/image.initrd.o $(CHRPOBJS) $(LIBS) \
+				   $(srctree)/$(boot)/ld.script
+	$(call cmd,gen-chrp)
+
+quiet_cmd_addnote = ADDNOTE $@
+      cmd_addnote = cat $< > $@ && $(utils)/addnote $@
+$(images)/zImage.chrp-rs6k $(images)/zImage.initrd.chrp-rs6k: \
+	%-rs6k: %
+	$(call cmd,addnote)
+
+quiet_cmd_gen-miboot = GEN     $@
+      cmd_gen-miboot = $(OBJCOPY) $(OBJCOPY_ARGS) \
+		       --add-section=$1=$(word 2, $^) $< $@
+$(images)/miboot.image: $(obj)/dummy.o $(images)/vmlinux.gz
+	$(call cmd,gen-miboot,image)
+
+$(images)/miboot.initrd.image: $(images)/miboot.image $(images)/ramdisk.image.gz
+	$(call cmd,gen-miboot,initrd)
+
+# The targets used on the make command-line
+
+.PHONY: zImage zImage.initrd
+zImage:		 $(images)/vmlinux.coff 	\
+		 $(images)/vmlinux.elf-pmac	\
+		 $(images)/zImage.chrp		\
+		 $(images)/zImage.chrp-rs6k	\
+		 $(images)/miboot.image
+	@echo '  kernel: $@ is ready ($<)'
+zImage.initrd:	 $(images)/vmlinux.initrd.coff 		\
+		 $(images)/vmlinux.initrd.elf-pmac	\
+		 $(images)/zImage.initrd.chrp		\
+		 $(images)/zImage.initrd.chrp-rs6k	\
+		 $(images)/miboot.initrd.image
+	@echo '  kernel: $@ is ready ($<)'
+
+TFTPIMAGE	:= /tftpboot/zImage
+
+.PHONY: znetboot znetboot.initrd
+znetboot:	$(images)/vmlinux.coff		\
+		$(images)/vmlinux.elf-pmac	\
+		$(images)/zImage.chrp
+	cp $(images)/vmlinux.coff     $(TFTPIMAGE).pmac$(END)
+	cp $(images)/vmlinux.elf-pmac $(TFTPIMAGE).pmac$(END).elf
+	cp $(images)/zImage.chrp      $(TFTPIMAGE).chrp$(END)
+	@echo '  kernel: $@ is ready ($<)'
+znetboot.initrd:$(images)/vmlinux.initrd.coff		\
+		$(images)/vmlinux.initrd.elf-pmac	\
+		$(images)/zImage.initrd.chrp
+	cp $(images)/vmlinux.initrd.coff     $(TFTPIMAGE).pmac$(END)
+	cp $(images)/vmlinux.initrd.elf-pmac $(TFTPIMAGE).pmac$(END).elf
+	cp $(images)/zImage.initrd.chrp      $(TFTPIMAGE).chrp$(END)
+	@echo '  kernel: $@ is ready ($<)'
+
diff --git a/arch/ppc/boot/openfirmware/chrpmain.c b/arch/ppc/boot/openfirmware/chrpmain.c
new file mode 100644
index 0000000..6fb4f73
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/chrpmain.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ */
+#include <linux/string.h>
+#include "nonstdio.h"
+#include "of1275.h"
+#include <asm/processor.h>
+#include <asm/page.h>
+
+/* Passed from the linker */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin, __ramdisk_end;
+extern char _start, _end;
+
+extern unsigned int heap_max;
+extern void flush_cache(void *, unsigned long);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
+		unsigned int progend);
+
+char *avail_ram;
+char *begin_avail, *end_avail;
+char *avail_high;
+
+#define RAM_START	0x00000000
+#define RAM_END		(64<<20)
+
+#define BOOT_START	((unsigned long)_start)
+#define BOOT_END	((unsigned long)(_end + 0xFFF) & ~0xFFF)
+
+#define RAM_FREE	((unsigned long)(_end+0x1000)&~0xFFF)
+#define PROG_START	0x00010000
+#define PROG_SIZE	0x007f0000 /* 8MB */
+
+#define SCRATCH_SIZE	(128 << 10)
+
+static char scratch[SCRATCH_SIZE];	/* 1MB of scratch space for gunzip */
+
+typedef void (*kernel_start_t)(int, int, void *, unsigned int, unsigned int);
+
+void
+boot(int a1, int a2, void *prom)
+{
+    unsigned sa, len;
+    void *dst;
+    unsigned char *im;
+    unsigned int initrd_size, initrd_start;
+
+    printf("chrpboot starting: loaded at 0x%p\n\r", &_start);
+
+    initrd_size = &__ramdisk_end - &__ramdisk_begin;
+    if (initrd_size) {
+	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+	a1 = initrd_start;
+	a2 = initrd_size;
+	claim(initrd_start, RAM_END - initrd_start, 0);
+	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
+	       initrd_start, &__ramdisk_begin, initrd_size);
+	memcpy((char *)initrd_start, &__ramdisk_begin, initrd_size);
+    } else {
+	initrd_start = 0;
+	initrd_size = 0;
+	a2 = 0xdeadbeef;
+    }
+
+    im = &__image_begin;
+    len = &__image_end - &__image_begin;
+    /* claim 4MB starting at PROG_START */
+    claim(PROG_START, PROG_SIZE - PROG_START, 0);
+    dst = (void *) PROG_START;
+    if (im[0] == 0x1f && im[1] == 0x8b) {
+	avail_ram = scratch;
+	begin_avail = avail_high = avail_ram;
+	end_avail = scratch + sizeof(scratch);
+	printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
+	gunzip(dst, 0x400000, im, &len);
+	printf("done %u bytes\n\r", len);
+	printf("%u bytes of heap consumed, max in use %u\n\r",
+	       avail_high - begin_avail, heap_max);
+    } else {
+	memmove(dst, im, len);
+    }
+
+    flush_cache(dst, len);
+    make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_chrp,
+		    (PROG_START + PROG_SIZE));
+
+    sa = PROG_START;
+    printf("start address = 0x%x\n\r", sa);
+
+    (*(kernel_start_t)sa)(a1, a2, prom, initrd_start, initrd_size);
+
+    printf("returned?\n\r");
+
+    pause();
+}
diff --git a/arch/ppc/boot/openfirmware/coffmain.c b/arch/ppc/boot/openfirmware/coffmain.c
new file mode 100644
index 0000000..04ba9d5
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/coffmain.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ */
+#include <linux/string.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+#include "nonstdio.h"
+#include "of1275.h"
+
+/* Passed from the linker */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin[], __ramdisk_end;
+extern char _start, _end;
+
+extern char image_data[], initrd_data[];
+extern int initrd_len, image_len;
+extern unsigned int heap_max;
+extern void flush_cache(void *start, unsigned int len);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
+		unsigned int progend);
+extern void setup_bats(unsigned long start);
+
+char *avail_ram;
+char *begin_avail, *end_avail;
+char *avail_high;
+
+#define SCRATCH_SIZE	(128 << 10)
+
+static char heap[SCRATCH_SIZE];
+
+static unsigned long ram_start = 0;
+static unsigned long ram_end = 0x1000000;
+
+static unsigned long prog_start = 0x900000;
+static unsigned long prog_size = 0x700000;
+
+typedef void (*kernel_start_t)(int, int, void *);
+
+void boot(int a1, int a2, void *prom)
+{
+    unsigned sa, len;
+    void *dst;
+    unsigned char *im;
+    unsigned initrd_start, initrd_size;
+
+    printf("coffboot starting: loaded at 0x%p\n", &_start);
+    setup_bats(ram_start);
+
+    initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
+    if (initrd_size) {
+	initrd_start = (ram_end - initrd_size) & ~0xFFF;
+	a1 = initrd_start;
+	a2 = initrd_size;
+	claim(initrd_start, ram_end - initrd_start, 0);
+	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
+	       initrd_start, (char *)(&__ramdisk_begin), initrd_size);
+	memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
+	prog_size = initrd_start - prog_start;
+    } else
+	a2 = 0xdeadbeef;
+
+    im = (char *)(&__image_begin);
+    len = (char *)(&__image_end) - (char *)(&__image_begin);
+    /* claim 4MB starting at PROG_START */
+    claim(prog_start, prog_size, 0);
+    map(prog_start, prog_start, prog_size);
+    dst = (void *) prog_start;
+    if (im[0] == 0x1f && im[1] == 0x8b) {
+	/* set up scratch space */
+	begin_avail = avail_high = avail_ram = heap;
+	end_avail = heap + sizeof(heap);
+	printf("heap at 0x%p\n", avail_ram);
+	printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
+	gunzip(dst, prog_size, im, &len);
+	printf("done %u bytes\n", len);
+	printf("%u bytes of heap consumed, max in use %u\n",
+	       avail_high - begin_avail, heap_max);
+    } else {
+	memmove(dst, im, len);
+    }
+
+    flush_cache(dst, len);
+    make_bi_recs(((unsigned long) dst + len), "coffboot", _MACH_Pmac,
+		    (prog_start + prog_size));
+
+    sa = (unsigned long)prog_start;
+    printf("start address = 0x%x\n", sa);
+
+    (*(kernel_start_t)sa)(a1, a2, prom);
+
+    printf("returned?\n");
+
+    pause();
+}
diff --git a/arch/ppc/boot/openfirmware/common.c b/arch/ppc/boot/openfirmware/common.c
new file mode 100644
index 0000000..9e69527
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/common.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ */
+
+#include "nonstdio.h"
+#include "of1275.h"
+#include <linux/string.h>
+#include <linux/zlib.h>
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+
+/* Information from the linker */
+extern char __sysmap_begin, __sysmap_end;
+
+extern int strcmp(const char *s1, const char *s2);
+extern char *avail_ram, *avail_high;
+extern char *end_avail;
+
+unsigned int heap_use, heap_max;
+
+struct memchunk {
+    unsigned int size;
+    struct memchunk *next;
+};
+
+static struct memchunk *freechunks;
+
+static void *zalloc(unsigned size)
+{
+    void *p;
+    struct memchunk **mpp, *mp;
+
+    size = (size + 7) & -8;
+    heap_use += size;
+    if (heap_use > heap_max)
+	heap_max = heap_use;
+    for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
+	if (mp->size == size) {
+	    *mpp = mp->next;
+	    return mp;
+	}
+    }
+    p = avail_ram;
+    avail_ram += size;
+    if (avail_ram > avail_high)
+	avail_high = avail_ram;
+    if (avail_ram > end_avail) {
+	printf("oops... out of memory\n\r");
+	pause();
+    }
+    return p;
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+	z_stream s;
+	int r, i, flags;
+
+	/* skip header */
+	i = 10;
+	flags = src[3];
+	if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) {
+		printf("bad gzipped data\n\r");
+		exit();
+	}
+	if ((flags & EXTRA_FIELD) != 0)
+		i = 12 + src[10] + (src[11] << 8);
+	if ((flags & ORIG_NAME) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & COMMENT) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & HEAD_CRC) != 0)
+		i += 2;
+	if (i >= *lenp) {
+		printf("gunzip: ran out of data in header\n\r");
+		exit();
+	}
+
+	/* Initialize ourself. */
+	s.workspace = zalloc(zlib_inflate_workspacesize());
+	r = zlib_inflateInit2(&s, -MAX_WBITS);
+	if (r != Z_OK) {
+		printf("zlib_inflateInit2 returned %d\n\r", r);
+		exit();
+	}
+	s.next_in = src + i;
+	s.avail_in = *lenp - i;
+	s.next_out = dst;
+	s.avail_out = dstlen;
+	r = zlib_inflate(&s, Z_FINISH);
+	if (r != Z_OK && r != Z_STREAM_END) {
+		printf("inflate returned %d msg: %s\n\r", r, s.msg);
+		exit();
+	}
+	*lenp = s.next_out - (unsigned char *) dst;
+	zlib_inflateEnd(&s);
+}
+
+/* Make a bi_rec in OF.  We need to be passed a name for BI_BOOTLOADER_ID,
+ * a machine type for BI_MACHTYPE, and the location where the end of the
+ * bootloader is (PROG_START + PROG_SIZE)
+ */
+void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
+		unsigned long progend)
+{
+	unsigned long sysmap_size;
+	struct bi_record *rec;
+
+	/* Figure out the size of a possible System.map we're going to
+	 * pass along.
+	 * */
+	sysmap_size = (unsigned long)(&__sysmap_end) -
+		(unsigned long)(&__sysmap_begin);
+
+	/* leave a 1MB gap then align to the next 1MB boundary */
+	addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
+	/* oldworld machine seem very unhappy about this. -- Tom */
+	if (addr >= progend)
+		claim(addr, 0x1000, 0);
+
+	rec = (struct bi_record *)addr;
+	rec->tag = BI_FIRST;
+	rec->size = sizeof(struct bi_record);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	rec->tag = BI_BOOTLOADER_ID;
+	sprintf( (char *)rec->data, name);
+	rec->size = sizeof(struct bi_record) + strlen(name) + 1;
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	rec->tag = BI_MACHTYPE;
+	rec->data[0] = mach;
+	rec->data[1] = 1;
+	rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	if (sysmap_size) {
+		rec->tag = BI_SYSMAP;
+		rec->data[0] = (unsigned long)(&__sysmap_begin);
+		rec->data[1] = sysmap_size;
+		rec->size = sizeof(struct bi_record) + 2 *
+			sizeof(unsigned long);
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	}
+
+	rec->tag = BI_LAST;
+	rec->size = sizeof(struct bi_record);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+}
diff --git a/arch/ppc/boot/openfirmware/dummy.c b/arch/ppc/boot/openfirmware/dummy.c
new file mode 100644
index 0000000..31dbf45
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/dummy.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+	return 0;
+}
diff --git a/arch/ppc/boot/openfirmware/misc.S b/arch/ppc/boot/openfirmware/misc.S
new file mode 100644
index 0000000..ab9e897
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/misc.S
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ */
+	.text
+
+/*
+ * Use the BAT2 & 3 registers to map the 1st 16MB of RAM to
+ * the address given as the 1st argument.
+ */
+	.globl	setup_bats
+setup_bats:
+	mfpvr	5
+	rlwinm	5,5,16,16,31		/* r3 = 1 for 601, 4 for 604 */
+	cmpwi	0,5,1
+	li	0,0
+	bne	4f
+	mtibatl	3,0			/* invalidate BAT first */
+	ori	3,3,4			/* set up BAT registers for 601 */
+	li	4,0x7f
+	mtibatu	2,3
+	mtibatl	2,4
+	oris	3,3,0x80
+	oris	4,4,0x80
+	mtibatu	3,3
+	mtibatl	3,4
+	b	5f
+4:	mtdbatu	3,0			/* invalidate BATs first */
+	mtibatu	3,0
+	ori	3,3,0xff		/* set up BAT registers for 604 */
+	li	4,2
+	mtdbatl	2,4
+	mtdbatu	2,3
+	mtibatl	2,4
+	mtibatu	2,3
+	oris	3,3,0x80
+	oris	4,4,0x80
+	mtdbatl	3,4
+	mtdbatu	3,3
+	mtibatl	3,4
+	mtibatu	3,3
+5:	sync
+	isync
+	blr
+
+/*
+ * Flush the dcache and invalidate the icache for a range of addresses.
+ *
+ * flush_cache(addr, len)
+ */
+	.global	flush_cache
+flush_cache:
+	addi	4,4,0x1f	/* len = (len + 0x1f) / 0x20 */
+	rlwinm.	4,4,27,5,31
+	mtctr	4
+	beqlr
+1:	dcbf	0,3
+	icbi	0,3
+	addi	3,3,0x20
+	bdnz	1b
+	sync
+	isync
+	blr
diff --git a/arch/ppc/boot/openfirmware/newworldmain.c b/arch/ppc/boot/openfirmware/newworldmain.c
new file mode 100644
index 0000000..fa8a8f9
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/newworldmain.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ */
+#include <linux/string.h>
+#include "nonstdio.h"
+#include "of1275.h"
+#include <asm/processor.h>
+#include <asm/page.h>
+
+/* Passed from the linker */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin[], __ramdisk_end;
+extern char _start, _end;
+
+extern unsigned int heap_max;
+extern void flush_cache(void *start, unsigned int len);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern void make_bi_recs(unsigned long addr, char *name, unsigned int mach,
+		unsigned int progend);
+
+char *avail_ram;
+char *begin_avail, *end_avail;
+char *avail_high;
+
+
+#define RAM_END		(16 << 20)
+
+#define PROG_START	0x00010000
+#define PROG_SIZE	0x007f0000
+
+#define SCRATCH_SIZE	(128 << 10)
+
+typedef void (*kernel_start_t)(int, int, void *);
+
+void boot(int a1, int a2, void *prom)
+{
+    unsigned sa, len;
+    void *dst;
+    unsigned char *im;
+    unsigned initrd_start, initrd_size;
+
+    printf("chrpboot starting: loaded at 0x%p\n", &_start);
+
+    initrd_size = (char *)(&__ramdisk_end) - (char *)(&__ramdisk_begin);
+    if (initrd_size) {
+	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+	a1 = initrd_start;
+	a2 = initrd_size;
+	claim(initrd_start, RAM_END - initrd_start, 0);
+	printf("initial ramdisk moving 0x%x <- 0x%p (%x bytes)\n\r",
+	       initrd_start, (char *)(&__ramdisk_begin), initrd_size);
+	memcpy((char *)initrd_start, (char *)(&__ramdisk_begin), initrd_size);
+    } else
+	a2 = 0xdeadbeef;
+
+    im = (char *)(&__image_begin);
+    len = (char *)(&__image_end) - (char *)(&__image_begin);
+    /* claim 3MB starting at PROG_START */
+    claim(PROG_START, PROG_SIZE, 0);
+    dst = (void *) PROG_START;
+    if (im[0] == 0x1f && im[1] == 0x8b) {
+	/* claim some memory for scratch space */
+	avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10);
+	begin_avail = avail_high = avail_ram;
+	end_avail = avail_ram + SCRATCH_SIZE;
+	printf("heap at 0x%p\n", avail_ram);
+	printf("gunzipping (0x%p <- 0x%p:0x%p)...", dst, im, im+len);
+	gunzip(dst, PROG_SIZE, im, &len);
+	printf("done %u bytes\n", len);
+	printf("%u bytes of heap consumed, max in use %u\n",
+	       avail_high - begin_avail, heap_max);
+	release(begin_avail, SCRATCH_SIZE);
+    } else {
+	memmove(dst, im, len);
+    }
+
+    flush_cache(dst, len);
+    make_bi_recs(((unsigned long) dst + len), "chrpboot", _MACH_Pmac,
+		    (PROG_START + PROG_SIZE));
+
+    sa = (unsigned long)PROG_START;
+    printf("start address = 0x%x\n", sa);
+
+    (*(kernel_start_t)sa)(a1, a2, prom);
+
+    printf("returned?\n");
+
+    pause();
+}
diff --git a/arch/ppc/boot/openfirmware/start.c b/arch/ppc/boot/openfirmware/start.c
new file mode 100644
index 0000000..1617a26
--- /dev/null
+++ b/arch/ppc/boot/openfirmware/start.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ */
+#include <stdarg.h>
+#include "of1275.h"
+
+extern int strlen(const char *s);
+extern void boot(int a1, int a2, void *prom);
+
+phandle stdin;
+phandle stdout;
+phandle stderr;
+
+void printk(char *fmt, ...);
+
+void
+start(int a1, int a2, void *promptr)
+{
+    ofinit(promptr);
+    if (ofstdio(&stdin, &stdout, &stderr))
+	exit();
+
+    boot(a1, a2, promptr);
+    for (;;)
+	exit();
+}
+
+int writestring(void *f, char *ptr, int nb)
+{
+	int w = 0, i;
+	char *ret = "\r";
+
+	for (i = 0; i < nb; ++i) {
+		if (ptr[i] == '\n') {
+			if (i > w) {
+				write(f, ptr + w, i - w);
+				w = i;
+			}
+			write(f, ret, 1);
+		}
+	}
+	if (w < nb)
+		write(f, ptr + w, nb - w);
+	return nb;
+}
+
+int
+putc(int c, void *f)
+{
+    char ch = c;
+
+    return writestring(f, &ch, 1) == 1? c: -1;
+}
+
+int
+putchar(int c)
+{
+    return putc(c, stdout);
+}
+
+int
+fputs(char *str, void *f)
+{
+    int n = strlen(str);
+
+    return writestring(f, str, n) == n? 0: -1;
+}
+
+int
+readchar(void)
+{
+    char ch;
+
+    for (;;) {
+	switch (read(stdin, &ch, 1)) {
+	case 1:
+	    return ch;
+	case -1:
+	    printk("read(stdin) returned -1\n");
+	    return -1;
+	}
+    }
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int
+getchar(void)
+{
+    int c;
+
+    if (lineleft == 0) {
+	lineptr = line;
+	for (;;) {
+	    c = readchar();
+	    if (c == -1 || c == 4)
+		break;
+	    if (c == '\r' || c == '\n') {
+		*lineptr++ = '\n';
+		putchar('\n');
+		break;
+	    }
+	    switch (c) {
+	    case 0177:
+	    case '\b':
+		if (lineptr > line) {
+		    putchar('\b');
+		    putchar(' ');
+		    putchar('\b');
+		    --lineptr;
+		}
+		break;
+	    case 'U' & 0x1F:
+		while (lineptr > line) {
+		    putchar('\b');
+		    putchar(' ');
+		    putchar('\b');
+		    --lineptr;
+		}
+		break;
+	    default:
+		if (lineptr >= &line[sizeof(line) - 1])
+		    putchar('\a');
+		else {
+		    putchar(c);
+		    *lineptr++ = c;
+		}
+	    }
+	}
+	lineleft = lineptr - line;
+	lineptr = line;
+    }
+    if (lineleft == 0)
+	return -1;
+    --lineleft;
+    return *lineptr++;
+}
+
+extern int vsprintf(char *buf, const char *fmt, va_list args);
+static char sprint_buf[1024];
+
+void
+printk(char *fmt, ...)
+{
+	va_list args;
+	int n;
+
+	va_start(args, fmt);
+	n = vsprintf(sprint_buf, fmt, args);
+	va_end(args);
+	writestring(stdout, sprint_buf, n);
+}
+
+int
+printf(char *fmt, ...)
+{
+	va_list args;
+	int n;
+
+	va_start(args, fmt);
+	n = vsprintf(sprint_buf, fmt, args);
+	va_end(args);
+	writestring(stdout, sprint_buf, n);
+	return n;
+}
diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile
new file mode 100644
index 0000000..d8d801f
--- /dev/null
+++ b/arch/ppc/boot/simple/Makefile
@@ -0,0 +1,252 @@
+# This is far from simple, but I couldn't think of a good name.  This is
+# for making the 'zImage' or 'zImage.initrd' on a number of targets.
+#
+# Author: Tom Rini <trini@mvista.com>
+#
+# Notes:
+# (1) For machines that do not want to use the ELF image directly (including
+# stripping just the ELF header off), they must set the variables
+# zimage-$(CONFIG_MACHINE) and zimagerd-$(CONFIG_MACHINE) to the target
+# that produces the desired image and they must set end-$(CONFIG_MACHINE)
+# to what will be suffixed to the image filename.
+# (2) Regardless of (1), to have the resulting image be something other
+# than 'zImage.elf', set end-$(CONFIG_MACHINE) to be the suffix used for
+# the zImage, znetboot, and znetbootrd targets.
+# (3) For machine targets which use the mktree program, you can optionally
+# set entrypoint-$(CONFIG_MACHINE) to the location which the image should be
+# loaded at.  The optimal setting for entrypoint-$(CONFIG_MACHINE) is the link
+# address.
+# (4) It is advisable to pass in the memory size using BI_MEMSIZE and
+# get_mem_size(), which is memory controller dependent.  Add in the correct
+# XXX_memory.o file for this to work, as well as editing the
+# misc-$(CONFIG_MACHINE) variable.
+
+boot				:= arch/ppc/boot
+common				:= $(boot)/common
+utils				:= $(boot)/utils
+bootlib				:= $(boot)/lib
+images				:= $(boot)/images
+of1275				:= $(boot)/of1275
+tftpboot			:= /tftpboot
+
+# Normally, we use the 'misc.c' file for decompress_kernel and
+# whatnot.  Sometimes we need to override this however.
+misc-y	:= misc.o
+
+# Normally, we have our images end in .elf, but something we want to
+# change this.
+end-y := elf
+
+# Additionally, we normally don't need to mess with the L2 / L3 caches
+# if present on 'classic' PPC.
+cacheflag-y	:= -DCLEAR_CACHES=""
+# This file will flush / disable the L2, and L3 if present.
+clear_L2_L3	:= $(srctree)/$(boot)/simple/clear.S
+
+#
+# See arch/ppc/kconfig and arch/ppc/platforms/Kconfig
+# for definition of what platform each config option refer to.
+#----------------------------------------------------------------------------
+      zimage-$(CONFIG_CPCI690)		:= zImage-STRIPELF
+zimageinitrd-$(CONFIG_CPCI690)		:= zImage.initrd-STRIPELF
+     extra.o-$(CONFIG_CPCI690)		:= misc-cpci690.o
+         end-$(CONFIG_CPCI690)		:= cpci690
+   cacheflag-$(CONFIG_CPCI690)		:= -include $(clear_L2_L3)
+
+      zimage-$(CONFIG_IBM_OPENBIOS)	:= zImage-TREE
+zimageinitrd-$(CONFIG_IBM_OPENBIOS)	:= zImage.initrd-TREE
+         end-$(CONFIG_IBM_OPENBIOS)	:= treeboot
+        misc-$(CONFIG_IBM_OPENBIOS)	:= misc-embedded.o
+
+         end-$(CONFIG_EMBEDDEDBOOT)	:= embedded
+        misc-$(CONFIG_EMBEDDEDBOOT)	:= misc-embedded.o
+
+      zimage-$(CONFIG_EBONY)		:= zImage-TREE
+zimageinitrd-$(CONFIG_EBONY)		:= zImage.initrd-TREE
+         end-$(CONFIG_EBONY)		:= ebony
+  entrypoint-$(CONFIG_EBONY)		:= 0x01000000
+     extra.o-$(CONFIG_EBONY)		:= openbios.o
+
+      zimage-$(CONFIG_LUAN)		:= zImage-TREE
+zimageinitrd-$(CONFIG_LUAN)		:= zImage.initrd-TREE
+         end-$(CONFIG_LUAN)		:= luan
+  entrypoint-$(CONFIG_LUAN)		:= 0x01000000
+     extra.o-$(CONFIG_LUAN)		:= pibs.o
+
+      zimage-$(CONFIG_OCOTEA)		:= zImage-TREE
+zimageinitrd-$(CONFIG_OCOTEA)		:= zImage.initrd-TREE
+         end-$(CONFIG_OCOTEA)		:= ocotea
+  entrypoint-$(CONFIG_OCOTEA)		:= 0x01000000
+     extra.o-$(CONFIG_OCOTEA)		:= pibs.o
+
+     extra.o-$(CONFIG_EV64260)		:= misc-ev64260.o
+         end-$(CONFIG_EV64260)		:= ev64260
+   cacheflag-$(CONFIG_EV64260)		:= -include $(clear_L2_L3)
+
+     extra.o-$(CONFIG_CHESTNUT)		:= misc-chestnut.o
+         end-$(CONFIG_CHESTNUT)		:= chestnut
+
+      zimage-$(CONFIG_GEMINI)		:= zImage-STRIPELF
+zimageinitrd-$(CONFIG_GEMINI)		:= zImage.initrd-STRIPELF
+         end-$(CONFIG_GEMINI)		:= gemini
+
+     extra.o-$(CONFIG_K2)		:= prepmap.o
+         end-$(CONFIG_K2)		:= k2
+   cacheflag-$(CONFIG_K2)		:= -include $(clear_L2_L3)
+
+     extra.o-$(CONFIG_KATANA)		:= misc-katana.o
+         end-$(CONFIG_KATANA)		:= katana
+   cacheflag-$(CONFIG_KATANA)		:= -include $(clear_L2_L3)
+
+     extra.o-$(CONFIG_RADSTONE_PPC7D)	:= misc-radstone_ppc7d.o
+         end-$(CONFIG_RADSTONE_PPC7D)	:= radstone_ppc7d
+   cacheflag-$(CONFIG_RADSTONE_PPC7D)	:= -include $(clear_L2_L3)
+
+# kconfig 'feature', only one of these will ever be 'y' at a time.
+# The rest will be unset.
+motorola := $(CONFIG_MCPN765)$(CONFIG_MVME5100)$(CONFIG_PRPMC750) \
+$(CONFIG_PRPMC800)$(CONFIG_LOPEC)$(CONFIG_PPLUS)
+motorola := $(strip $(motorola))
+pcore := $(CONFIG_PCORE)$(CONFIG_POWERPMC250)
+
+      zimage-$(motorola)		:= zImage-PPLUS
+zimageinitrd-$(motorola)		:= zImage.initrd-PPLUS
+         end-$(motorola)		:= pplus
+
+# Overrides previous assingment
+     extra.o-$(CONFIG_PPLUS)		:= prepmap.o
+     extra.o-$(CONFIG_LOPEC)		:= mpc10x_memory.o
+
+      zimage-$(pcore)			:= zImage-STRIPELF
+zimageinitrd-$(pcore)			:= zImage.initrd-STRIPELF
+     extra.o-$(pcore)			:= chrpmap.o
+         end-$(pcore)			:= pcore
+   cacheflag-$(pcore)			:= -include $(clear_L2_L3)
+
+      zimage-$(CONFIG_PPC_PREP)		:= zImage-PPLUS
+zimageinitrd-$(CONFIG_PPC_PREP)		:= zImage.initrd-PPLUS
+     extra.o-$(CONFIG_PPC_PREP)		:= prepmap.o
+        misc-$(CONFIG_PPC_PREP)		+= misc-prep.o mpc10x_memory.o
+         end-$(CONFIG_PPC_PREP)		:= prep
+
+         end-$(CONFIG_SANDPOINT)	:= sandpoint
+   cacheflag-$(CONFIG_SANDPOINT)	:= -include $(clear_L2_L3)
+
+      zimage-$(CONFIG_SPRUCE)		:= zImage-TREE
+zimageinitrd-$(CONFIG_SPRUCE)		:= zImage.initrd-TREE
+         end-$(CONFIG_SPRUCE)		:= spruce
+  entrypoint-$(CONFIG_SPRUCE)		:= 0x00800000
+        misc-$(CONFIG_SPRUCE)		+= misc-spruce.o
+
+      zimage-$(CONFIG_LITE5200)		:= zImage-STRIPELF
+zimageinitrd-$(CONFIG_LITE5200)		:= zImage.initrd-STRIPELF
+         end-$(CONFIG_LITE5200)		:= lite5200
+   cacheflag-$(CONFIG_LITE5200)		:= -include $(clear_L2_L3)
+
+
+# SMP images should have a '.smp' suffix.
+         end-$(CONFIG_SMP)             := $(end-y).smp
+
+# This is a treeboot that needs init functions until the
+# boot rom is sorted out (i.e. this is short lived)
+extra-aflags-$(CONFIG_REDWOOD_4)	:= -Wa,-m405
+extra.o-$(CONFIG_REDWOOD_4)		:= rw4/rw4_init.o rw4/rw4_init_brd.o
+EXTRA_AFLAGS := $(extra-aflags-y)
+# head.o needs to get the cacheflags defined.
+AFLAGS_head.o				+= $(cacheflag-y)
+
+# Linker args.  This specifies where the image will be run at.
+LD_ARGS					:= -T $(srctree)/$(boot)/ld.script \
+				   -Ttext $(CONFIG_BOOT_LOAD) -Bstatic
+OBJCOPY_ARGS			:= -O elf32-powerpc
+
+# head.o and relocate.o must be at the start.
+boot-y				:= head.o relocate.o $(extra.o-y) $(misc-y)
+boot-$(CONFIG_40x)		+= embed_config.o
+boot-$(CONFIG_8xx)		+= embed_config.o
+boot-$(CONFIG_8260)		+= embed_config.o
+boot-$(CONFIG_BSEIP)		+= iic.o
+boot-$(CONFIG_MBX)		+= iic.o pci.o qspan_pci.o
+boot-$(CONFIG_MV64X60)		+= misc-mv64x60.o
+boot-$(CONFIG_RPXCLASSIC)	+= iic.o pci.o qspan_pci.o
+boot-$(CONFIG_RPXLITE)		+= iic.o
+# Different boards need different serial implementations.
+ifeq ($(CONFIG_SERIAL_CPM_CONSOLE),y)
+boot-$(CONFIG_8xx)		+= m8xx_tty.o
+boot-$(CONFIG_8260)		+= m8260_tty.o
+endif
+boot-$(CONFIG_SERIAL_MPC52xx_CONSOLE)	+= mpc52xx_tty.o
+boot-$(CONFIG_SERIAL_MPSC_CONSOLE)	+= mv64x60_tty.o
+
+LIBS				:= $(common)/lib.a $(bootlib)/lib.a
+ifeq ($(CONFIG_PPC_PREP),y)
+LIBS 				+= $(of1275)/lib.a
+endif
+
+OBJS				:= $(addprefix $(obj)/,$(boot-y))
+
+# Tools
+MKBUGBOOT			:= $(utils)/mkbugboot
+MKPREP				:= $(utils)/mkprep
+MKTREE				:= $(utils)/mktree
+
+targets := dummy.o
+
+$(obj)/zvmlinux: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \
+		$(images)/vmlinux.gz $(obj)/dummy.o
+	$(OBJCOPY) $(OBJCOPY_ARGS) \
+		--add-section=.image=$(images)/vmlinux.gz \
+		--set-section-flags=.image=contents,alloc,load,readonly,data \
+		$(obj)/dummy.o $(obj)/image.o
+	$(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS)
+	$(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \
+		-R .stabstr -R .ramdisk -R .sysmap
+
+$(obj)/zvmlinux.initrd: $(OBJS) $(LIBS) $(srctree)/$(boot)/ld.script \
+		$(images)/vmlinux.gz $(obj)/dummy.o
+	$(OBJCOPY) $(OBJCOPY_ARGS) \
+		--add-section=.ramdisk=$(images)/ramdisk.image.gz \
+		--set-section-flags=.ramdisk=contents,alloc,load,readonly,data \
+		--add-section=.image=$(images)/vmlinux.gz \
+		--set-section-flags=.image=contents,alloc,load,readonly,data \
+		$(obj)/dummy.o $(obj)/image.o
+	$(LD) $(LD_ARGS) -o $@ $(OBJS) $(obj)/image.o $(LIBS)
+	$(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab \
+		-R .stabstr -R .sysmap
+
+# Sort-of dummy rules, that let us format the image we want.
+zImage: $(images)/$(zimage-y) $(obj)/zvmlinux
+	cp -f $(obj)/zvmlinux $(images)/zImage.elf
+	rm -f $(obj)/zvmlinux
+
+zImage.initrd: $(images)/$(zimageinitrd-y) $(obj)/zvmlinux.initrd
+	cp -f $(obj)/zvmlinux.initrd $(images)/zImage.initrd.elf
+	rm -f $(obj)/zvmlinux.initrd
+
+znetboot: zImage
+	cp $(images)/zImage.$(end-y) $(tftpboot)/zImage.$(end-y)
+
+znetboot.initrd: zImage.initrd
+	cp $(images)/zImage.initrd.$(end-y) $(tftpboot)/zImage.initrd.$(end-y)
+
+$(images)/zImage-STRIPELF: $(obj)/zvmlinux
+	dd if=$(obj)/zvmlinux of=$(images)/zImage.$(end-y) skip=64 bs=1k
+
+$(images)/zImage.initrd-STRIPELF: $(obj)/zvmlinux.initrd
+	dd if=$(obj)/zvmlinux.initrd of=$(images)/zImage.initrd.$(end-y) \
+		skip=64 bs=1k
+
+$(images)/zImage-TREE: $(obj)/zvmlinux $(MKTREE)
+	$(MKTREE) $(obj)/zvmlinux $(images)/zImage.$(end-y) $(ENTRYPOINT)
+
+$(images)/zImage.initrd-TREE: $(obj)/zvmlinux.initrd $(MKTREE)
+	$(MKTREE) $(obj)/zvmlinux.initrd $(images)/zImage.initrd.$(end-y) \
+		$(ENTRYPOINT)
+
+$(images)/zImage-PPLUS: $(obj)/zvmlinux $(MKPREP) $(MKBUGBOOT)
+	$(MKPREP) -pbp $(obj)/zvmlinux $(images)/zImage.$(end-y)
+	$(MKBUGBOOT) $(obj)/zvmlinux $(images)/zImage.bugboot
+
+$(images)/zImage.initrd-PPLUS: $(obj)/zvmlinux.initrd $(MKPREP) $(MKBUGBOOT)
+	$(MKPREP) -pbp $(obj)/zvmlinux.initrd $(images)/zImage.initrd.$(end-y)
+	$(MKBUGBOOT) $(obj)/zvmlinux.initrd $(images)/zImage.initrd.bugboot
diff --git a/arch/ppc/boot/simple/chrpmap.c b/arch/ppc/boot/simple/chrpmap.c
new file mode 100644
index 0000000..14d9e05
--- /dev/null
+++ b/arch/ppc/boot/simple/chrpmap.c
@@ -0,0 +1,12 @@
+/*
+ * 2004 (C) IBM. 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 <nonstdio.h>
+
+void board_isa_init(void)
+{
+	ISA_init(0xFE000000);
+}
diff --git a/arch/ppc/boot/simple/clear.S b/arch/ppc/boot/simple/clear.S
new file mode 100644
index 0000000..95c5647
--- /dev/null
+++ b/arch/ppc/boot/simple/clear.S
@@ -0,0 +1,19 @@
+/*
+ * Code to call _setup_L2CR to flus, invalidate and disable the L2,
+ * and if present, do the same to the L3.
+ */
+
+#define CLEAR_CACHES						\
+	bl	_setup_L2CR;					\
+								\
+	/* If 745x, turn off L3CR as well */			\
+	mfspr	r8,SPRN_PVR;					\
+	srwi	r8,r8,16;					\
+								\
+	cmpli	cr0,r8,0x8000;			/* 7450 */	\
+	cmpli	cr1,r8,0x8001;			/* 7455 */	\
+	cmpli	cr2,r8,0x8002;			/* 7457 */	\
+	/* Now test if any are true. */				\
+	cror	4*cr0+eq,4*cr0+eq,4*cr1+eq;			\
+	cror	4*cr0+eq,4*cr0+eq,4*cr2+eq;			\
+	beql	_setup_L3CR
diff --git a/arch/ppc/boot/simple/cpc700_memory.c b/arch/ppc/boot/simple/cpc700_memory.c
new file mode 100644
index 0000000..8c75cf6
--- /dev/null
+++ b/arch/ppc/boot/simple/cpc700_memory.c
@@ -0,0 +1,36 @@
+/*
+ * arch/ppc/boot/common/cpc700_memory.c
+ *
+ * Find memory based upon settings in the CPC700 bridge
+ *
+ * Author: Dan Cox
+ *
+ * 2001-2002 (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 <asm/types.h>
+#include <asm/io.h>
+#include "cpc700.h"
+
+unsigned long
+cpc700_get_mem_size(void)
+{
+	int i;
+	unsigned long len, amt;
+
+	/* Start at MB1EA, since MB0EA will most likely be the ending address
+	   for ROM space. */
+	for(len = 0, i = CPC700_MB1EA; i <= CPC700_MB4EA; i+=4) {
+		amt = cpc700_read_memreg(i);
+		if (amt == 0)
+			break;
+		len = amt;
+	}
+
+	return len;
+}
+
+
diff --git a/arch/ppc/boot/simple/dummy.c b/arch/ppc/boot/simple/dummy.c
new file mode 100644
index 0000000..31dbf45
--- /dev/null
+++ b/arch/ppc/boot/simple/dummy.c
@@ -0,0 +1,4 @@
+int main(void)
+{
+	return 0;
+}
diff --git a/arch/ppc/boot/simple/embed_config.c b/arch/ppc/boot/simple/embed_config.c
new file mode 100644
index 0000000..c342b47
--- /dev/null
+++ b/arch/ppc/boot/simple/embed_config.c
@@ -0,0 +1,981 @@
+/* Board specific functions for those embedded 8xx boards that do
+ * not have boot monitor support for board information.
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <asm/reg.h>
+#ifdef CONFIG_8xx
+#include <asm/mpc8xx.h>
+#endif
+#ifdef CONFIG_8260
+#include <asm/mpc8260.h>
+#include <asm/immap_cpm2.h>
+#endif
+#ifdef CONFIG_40x
+#include <asm/io.h>
+#endif
+extern unsigned long timebase_period_ns;
+
+/* For those boards that don't provide one.
+*/
+#if !defined(CONFIG_MBX)
+static	bd_t	bdinfo;
+#endif
+
+/* IIC functions.
+ * These are just the basic master read/write operations so we can
+ * examine serial EEPROM.
+ */
+extern void	iic_read(uint devaddr, u_char *buf, uint offset, uint count);
+
+/* Supply a default Ethernet address for those eval boards that don't
+ * ship with one.  This is an address from the MBX board I have, so
+ * it is unlikely you will find it on your network.
+ */
+static	ushort	def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 };
+
+#if defined(CONFIG_MBX)
+
+/* The MBX hands us a pretty much ready to go board descriptor.  This
+ * is where the idea started in the first place.
+ */
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*mp;
+	u_char	eebuf[128];
+	int i = 8;
+	bd_t    *bd;
+
+	bd = *bdp;
+
+	/* Read the first 128 bytes of the EEPROM.  There is more,
+	 * but this is all we need.
+	 */
+	iic_read(0xa4, eebuf, 0, 128);
+
+	/* All we are looking for is the Ethernet MAC address.  The
+	 * first 8 bytes are 'MOTOROLA', so check for part of that.
+	 * Next, the VPD describes a MAC 'packet' as being of type 08
+	 * and size 06.  So we look for that and the MAC must follow.
+	 * If there are more than one, we still only care about the first.
+	 * If it's there, assume we have a valid MAC address.  If not,
+	 * grab our default one.
+	 */
+	if ((*(uint *)eebuf) == 0x4d4f544f) {
+		while (i < 127 && !(eebuf[i] == 0x08 && eebuf[i + 1] == 0x06))
+			 i += eebuf[i + 1] + 2;  /* skip this packet */
+
+		if (i == 127)	/* Couldn't find. */
+			mp = (u_char *)def_enet_addr;
+		else
+			mp = &eebuf[i + 2];
+	}
+	else
+		mp = (u_char *)def_enet_addr;
+
+	for (i=0; i<6; i++)
+		bd->bi_enetaddr[i] = *mp++;
+
+	/* The boot rom passes these to us in MHz.  Linux now expects
+	 * them to be in Hz.
+	 */
+	bd->bi_intfreq *= 1000000;
+	bd->bi_busfreq *= 1000000;
+
+	/* Stuff a baud rate here as well.
+	*/
+	bd->bi_baudrate = 9600;
+}
+#endif /* CONFIG_MBX */
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || \
+	defined(CONFIG_RPX8260) || defined(CONFIG_EP405)
+/* Helper functions for Embedded Planet boards.
+*/
+/* Because I didn't find anything that would do this.......
+*/
+u_char
+aschex_to_byte(u_char *cp)
+{
+	u_char	byte, c;
+
+	c = *cp++;
+
+	if ((c >= 'A') && (c <= 'F')) {
+		c -= 'A';
+		c += 10;
+	} else if ((c >= 'a') && (c <= 'f')) {
+		c -= 'a';
+		c += 10;
+	} else
+		c -= '0';
+
+	byte = c * 16;
+
+	c = *cp;
+
+	if ((c >= 'A') && (c <= 'F')) {
+		c -= 'A';
+		c += 10;
+	} else if ((c >= 'a') && (c <= 'f')) {
+		c -= 'a';
+		c += 10;
+	} else
+		c -= '0';
+
+	byte += c;
+
+	return(byte);
+}
+
+static void
+rpx_eth(bd_t *bd, u_char *cp)
+{
+	int	i;
+
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = aschex_to_byte(cp);
+		cp += 2;
+	}
+}
+
+#ifdef CONFIG_RPX8260
+static uint
+rpx_baseten(u_char *cp)
+{
+	uint	retval;
+
+	retval = 0;
+
+	while (*cp != '\n') {
+		retval *= 10;
+		retval += (*cp) - '0';
+		cp++;
+	}
+	return(retval);
+}
+#endif
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+static void
+rpx_brate(bd_t *bd, u_char *cp)
+{
+	uint	rate;
+
+	rate = 0;
+
+	while (*cp != '\n') {
+		rate *= 10;
+		rate += (*cp) - '0';
+		cp++;
+	}
+
+	bd->bi_baudrate = rate * 100;
+}
+
+static void
+rpx_cpuspeed(bd_t *bd, u_char *cp)
+{
+	uint	num, den;
+
+	num = den = 0;
+
+	while (*cp != '\n') {
+		num *= 10;
+		num += (*cp) - '0';
+		cp++;
+		if (*cp == '/') {
+			cp++;
+			den = (*cp) - '0';
+			break;
+		}
+	}
+
+	/* I don't know why the RPX just can't state the actual
+	 * CPU speed.....
+	 */
+	if (den) {
+		num /= den;
+		num *= den;
+	}
+	bd->bi_intfreq = bd->bi_busfreq = num * 1000000;
+
+	/* The 8xx can only run a maximum 50 MHz bus speed (until
+	 * Motorola changes this :-).  Greater than 50 MHz parts
+	 * run internal/2 for bus speed.
+	 */
+	if (num > 50)
+		bd->bi_busfreq /= 2;
+}
+#endif
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_EP405)
+static void
+rpx_memsize(bd_t *bd, u_char *cp)
+{
+	uint	size;
+
+	size = 0;
+
+	while (*cp != '\n') {
+		size *= 10;
+		size += (*cp) - '0';
+		cp++;
+	}
+
+	bd->bi_memsize = size * 1024 * 1024;
+}
+#endif /* LITE || CLASSIC || EP405 */
+#if defined(CONFIG_EP405)
+static void
+rpx_nvramsize(bd_t *bd, u_char *cp)
+{
+	uint	size;
+
+	size = 0;
+
+	while (*cp != '\n') {
+		size *= 10;
+		size += (*cp) - '0';
+		cp++;
+	}
+
+	bd->bi_nvramsize = size * 1024;
+}
+#endif /* CONFIG_EP405 */
+
+#endif	/* Embedded Planet boards */
+
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+
+/* Read the EEPROM on the RPX-Lite board.
+*/
+void
+embed_config(bd_t **bdp)
+{
+	u_char	eebuf[256], *cp;
+	bd_t	*bd;
+
+	/* Read the first 256 bytes of the EEPROM.  I think this
+	 * is really all there is, and I hope if it gets bigger the
+	 * info we want is still up front.
+	 */
+	bd = &bdinfo;
+	*bdp = bd;
+
+#if 1
+	iic_read(0xa8, eebuf, 0, 128);
+	iic_read(0xa8, &eebuf[128], 128, 128);
+
+	/* We look for two things, the Ethernet address and the
+	 * serial baud rate.  The records are separated by
+	 * newlines.
+	 */
+	cp = eebuf;
+	for (;;) {
+		if (*cp == 'E') {
+			cp++;
+			if (*cp == 'A') {
+				cp += 2;
+				rpx_eth(bd, cp);
+			}
+		}
+		if (*cp == 'S') {
+			cp++;
+			if (*cp == 'B') {
+				cp += 2;
+				rpx_brate(bd, cp);
+			}
+		}
+		if (*cp == 'D') {
+			cp++;
+			if (*cp == '1') {
+				cp += 2;
+				rpx_memsize(bd, cp);
+			}
+		}
+		if (*cp == 'H') {
+			cp++;
+			if (*cp == 'Z') {
+				cp += 2;
+				rpx_cpuspeed(bd, cp);
+			}
+		}
+
+		/* Scan to the end of the record.
+		*/
+		while ((*cp != '\n') && (*cp != 0xff))
+			cp++;
+
+		/* If the next character is a 0 or ff, we are done.
+		*/
+		cp++;
+		if ((*cp == 0) || (*cp == 0xff))
+			break;
+	}
+	bd->bi_memstart = 0;
+#else
+	/* For boards without initialized EEPROM.
+	*/
+	bd->bi_memstart = 0;
+	bd->bi_memsize = (8 * 1024 * 1024);
+	bd->bi_intfreq = 48000000;
+	bd->bi_busfreq = 48000000;
+	bd->bi_baudrate = 9600;
+#endif
+}
+#endif /* RPXLITE || RPXCLASSIC */
+
+#ifdef CONFIG_BSEIP
+/* Build a board information structure for the BSE ip-Engine.
+ * There is more to come since we will add some environment
+ * variables and a function to read them.
+ */
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	bd = &bdinfo;
+	*bdp = bd;
+
+	/* Baud rate and processor speed will eventually come
+	 * from the environment variables.
+	 */
+	bd->bi_baudrate = 9600;
+
+	/* Get the Ethernet station address from the Flash ROM.
+	*/
+	cp = (u_char *)0xfe003ffa;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+
+	/* The rest of this should come from the environment as well.
+	*/
+	bd->bi_memstart = 0;
+	bd->bi_memsize = (16 * 1024 * 1024);
+	bd->bi_intfreq = 48000000;
+	bd->bi_busfreq = 48000000;
+}
+#endif /* BSEIP */
+
+#ifdef CONFIG_FADS
+/* Build a board information structure for the FADS.
+ */
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	bd = &bdinfo;
+	*bdp = bd;
+
+	/* Just fill in some known values.
+	 */
+	bd->bi_baudrate = 9600;
+
+	/* Use default enet.
+	*/
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+
+	bd->bi_memstart = 0;
+	bd->bi_memsize = (8 * 1024 * 1024);
+	bd->bi_intfreq = 40000000;
+	bd->bi_busfreq = 40000000;
+}
+#endif /* FADS */
+
+#ifdef CONFIG_8260
+/* Compute 8260 clock values if the rom doesn't provide them.
+ */
+static unsigned char bus2core_8260[] = {
+/*      0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
+	3,  2,  2,  2,  4,  4,  5,  9,  6, 11,  8, 10,  3, 12,  7,  2,
+	6,  5, 13,  2, 14,  4, 15,  2,  3, 11,  8, 10, 16, 12,  7,  2,
+};
+
+static void
+clk_8260(bd_t *bd)
+{
+	uint	scmr, vco_out, clkin;
+	uint	plldf, pllmf, corecnf;
+	volatile cpm2_map_t	*ip;
+
+	ip = (cpm2_map_t *)CPM_MAP_ADDR;
+	scmr = ip->im_clkrst.car_scmr;
+
+	/* The clkin is always bus frequency.
+	*/
+	clkin = bd->bi_busfreq;
+
+	/* Collect the bits from the scmr.
+	*/
+	plldf = (scmr >> 12) & 1;
+	pllmf = scmr & 0xfff;
+	corecnf = (scmr >> 24) &0x1f;
+
+	/* This is arithmetic from the 8260 manual.
+	*/
+	vco_out = clkin / (plldf + 1);
+	vco_out *= 2 * (pllmf + 1);
+	bd->bi_vco = vco_out;		/* Save for later */
+
+	bd->bi_cpmfreq = vco_out / 2;	/* CPM Freq, in MHz */
+	bd->bi_intfreq = bd->bi_busfreq * bus2core_8260[corecnf] / 2;
+
+	/* Set Baud rate divisor.  The power up default is divide by 16,
+	 * but we set it again here in case it was changed.
+	 */
+	ip->im_clkrst.car_sccr = 1;	/* DIV 16 BRG */
+	bd->bi_brgfreq = vco_out / 16;
+}
+
+static unsigned char bus2core_8280[] = {
+/*      0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f */
+	3,  2,  2,  2,  4,  4,  5,  9,  6, 11,  8, 10,  3, 12,  7,  2,
+	6,  5, 13,  2, 14,  2, 15,  2,  3,  2,  2,  2, 16,  2,  2,  2,
+};
+
+static void
+clk_8280(bd_t *bd)
+{
+	uint	scmr, main_clk, clkin;
+	uint	pllmf, corecnf;
+	volatile cpm2_map_t	*ip;
+
+	ip = (cpm2_map_t *)CPM_MAP_ADDR;
+	scmr = ip->im_clkrst.car_scmr;
+
+	/* The clkin is always bus frequency.
+	*/
+	clkin = bd->bi_busfreq;
+
+	/* Collect the bits from the scmr.
+	*/
+	pllmf = scmr & 0xf;
+	corecnf = (scmr >> 24) & 0x1f;
+
+	/* This is arithmetic from the 8280 manual.
+	*/
+	main_clk = clkin * (pllmf + 1);
+
+	bd->bi_cpmfreq = main_clk / 2;	/* CPM Freq, in MHz */
+	bd->bi_intfreq = bd->bi_busfreq * bus2core_8280[corecnf] / 2;
+
+	/* Set Baud rate divisor.  The power up default is divide by 16,
+	 * but we set it again here in case it was changed.
+	 */
+	ip->im_clkrst.car_sccr = (ip->im_clkrst.car_sccr & 0x3) | 0x1;
+	bd->bi_brgfreq = main_clk / 16;
+}
+#endif
+
+#ifdef CONFIG_SBC82xx
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+	unsigned long pvr;
+
+	bd = *bdp;
+
+	bd = &bdinfo;
+	*bdp = bd;
+	bd->bi_baudrate = 9600;
+	bd->bi_memsize = 256 * 1024 * 1024;	/* just a guess */
+
+	cp = (void*)SBC82xx_MACADDR_NVRAM_SCC1;
+	memcpy(bd->bi_enetaddr, cp, 6);
+
+	/* can busfreq be calculated? */
+	pvr = mfspr(SPRN_PVR);
+	if ((pvr & 0xffff0000) == 0x80820000) {
+		bd->bi_busfreq = 100000000;
+		clk_8280(bd);
+	} else {
+		bd->bi_busfreq = 66000000;
+		clk_8260(bd);
+	}
+
+}
+#endif /* SBC82xx */
+
+#if defined(CONFIG_EST8260) || defined(CONFIG_TQM8260)
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	bd = *bdp;
+#if 0
+	/* This is actually provided by my boot rom.  I have it
+	 * here for those people that may load the kernel with
+	 * a JTAG/COP tool and not the rom monitor.
+	 */
+	bd->bi_baudrate = 115200;
+	bd->bi_intfreq = 200000000;
+	bd->bi_busfreq = 66666666;
+	bd->bi_cpmfreq = 66666666;
+	bd->bi_brgfreq = 33333333;
+	bd->bi_memsize = 16 * 1024 * 1024;
+#else
+	/* The boot rom passes these to us in MHz.  Linux now expects
+	 * them to be in Hz.
+	 */
+	bd->bi_intfreq *= 1000000;
+	bd->bi_busfreq *= 1000000;
+	bd->bi_cpmfreq *= 1000000;
+	bd->bi_brgfreq *= 1000000;
+#endif
+
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+}
+#endif /* EST8260 */
+
+#ifdef CONFIG_SBS8260
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	/* This should provided by the boot rom.
+	 */
+	bd = &bdinfo;
+	*bdp = bd;
+	bd->bi_baudrate = 9600;
+	bd->bi_memsize = 64 * 1024 * 1024;
+
+	/* Set all of the clocks.  We have to know the speed of the
+	 * external clock.  The development board had 66 MHz.
+	 */
+	bd->bi_busfreq = 66666666;
+	clk_8260(bd);
+
+	/* I don't know how to compute this yet.
+	*/
+	bd->bi_intfreq = 133000000;
+
+
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+}
+#endif /* SBS8260 */
+
+#ifdef CONFIG_RPX8260
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp, *keyvals;
+	int	i;
+	bd_t	*bd;
+
+	keyvals = (u_char *)*bdp;
+
+	bd = &bdinfo;
+	*bdp = bd;
+
+	/* This is almost identical to the RPX-Lite/Classic functions
+	 * on the 8xx boards.  It would be nice to have a key lookup
+	 * function in a string, but the format of all of the fields
+	 * is slightly different.
+	 */
+	cp = keyvals;
+	for (;;) {
+		if (*cp == 'E') {
+			cp++;
+			if (*cp == 'A') {
+				cp += 2;
+				rpx_eth(bd, cp);
+			}
+		}
+		if (*cp == 'S') {
+			cp++;
+			if (*cp == 'B') {
+				cp += 2;
+				bd->bi_baudrate = rpx_baseten(cp);
+			}
+		}
+		if (*cp == 'D') {
+			cp++;
+			if (*cp == '1') {
+				cp += 2;
+				bd->bi_memsize = rpx_baseten(cp) * 1024 * 1024;
+			}
+		}
+		if (*cp == 'X') {
+			cp++;
+			if (*cp == 'T') {
+				cp += 2;
+				bd->bi_busfreq = rpx_baseten(cp);
+			}
+		}
+		if (*cp == 'N') {
+			cp++;
+			if (*cp == 'V') {
+				cp += 2;
+				bd->bi_nvsize = rpx_baseten(cp) * 1024 * 1024;
+			}
+		}
+
+		/* Scan to the end of the record.
+		*/
+		while ((*cp != '\n') && (*cp != 0xff))
+			cp++;
+
+		/* If the next character is a 0 or ff, we are done.
+		*/
+		cp++;
+		if ((*cp == 0) || (*cp == 0xff))
+			break;
+	}
+	bd->bi_memstart = 0;
+
+	/* The memory size includes both the 60x and local bus DRAM.
+	 * I don't want to use the local bus DRAM for real memory,
+	 * so subtract it out.  It would be nice if they were separate
+	 * keys.
+	 */
+	bd->bi_memsize -= 32 * 1024 * 1024;
+
+	/* Set all of the clocks.  We have to know the speed of the
+	 * external clock.
+	 */
+	clk_8260(bd);
+
+	/* I don't know how to compute this yet.
+	*/
+	bd->bi_intfreq = 200000000;
+}
+#endif /* RPX6 for testing */
+
+#ifdef CONFIG_ADS8260
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	/* This should provided by the boot rom.
+	 */
+	bd = &bdinfo;
+	*bdp = bd;
+	bd->bi_baudrate = 9600;
+	bd->bi_memsize = 16 * 1024 * 1024;
+
+	/* Set all of the clocks.  We have to know the speed of the
+	 * external clock.  The development board had 66 MHz.
+	 */
+	bd->bi_busfreq = 66666666;
+	clk_8260(bd);
+
+	/* I don't know how to compute this yet.
+	*/
+	bd->bi_intfreq = 200000000;
+
+
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+}
+#endif /* ADS8260 */
+
+#ifdef CONFIG_WILLOW
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+
+	/* Willow has Open Firmware....I should learn how to get this
+	 * information from it.
+	 */
+	bd = &bdinfo;
+	*bdp = bd;
+	bd->bi_baudrate = 9600;
+	bd->bi_memsize = 32 * 1024 * 1024;
+
+	/* Set all of the clocks.  We have to know the speed of the
+	 * external clock.  The development board had 66 MHz.
+	 */
+	bd->bi_busfreq = 66666666;
+	clk_8260(bd);
+
+	/* I don't know how to compute this yet.
+	*/
+	bd->bi_intfreq = 200000000;
+
+
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+}
+#endif /* WILLOW */
+
+#ifdef CONFIG_XILINX_ML300
+void
+embed_config(bd_t ** bdp)
+{
+	static const unsigned long line_size = 32;
+	static const unsigned long congruence_classes = 256;
+	unsigned long addr;
+	unsigned long dccr;
+	bd_t *bd;
+
+	/*
+	 * Invalidate the data cache if the data cache is turned off.
+	 * - The 405 core does not invalidate the data cache on power-up
+	 *   or reset but does turn off the data cache. We cannot assume
+	 *   that the cache contents are valid.
+	 * - If the data cache is turned on this must have been done by
+	 *   a bootloader and we assume that the cache contents are
+	 *   valid.
+	 */
+	__asm__("mfdccr %0": "=r" (dccr));
+	if (dccr == 0) {
+		for (addr = 0;
+		     addr < (congruence_classes * line_size);
+		     addr += line_size) {
+			__asm__("dccci 0,%0": :"b"(addr));
+		}
+	}
+
+	bd = &bdinfo;
+	*bdp = bd;
+	bd->bi_memsize = XPAR_DDR_0_SIZE;
+	bd->bi_intfreq = XPAR_CORE_CLOCK_FREQ_HZ;
+	bd->bi_busfreq = XPAR_PLB_CLOCK_FREQ_HZ;
+	bd->bi_pci_busfreq = XPAR_PCI_0_CLOCK_FREQ_HZ;
+	timebase_period_ns = 1000000000 / bd->bi_tbfreq;
+	/* see bi_tbfreq definition in arch/ppc/platforms/4xx/xilinx_ml300.h */
+}
+#endif /* CONFIG_XILINX_ML300 */
+
+#ifdef CONFIG_IBM_OPENBIOS
+/* This could possibly work for all treeboot roms.
+*/
+#if defined(CONFIG_ASH) || defined(CONFIG_BEECH) || defined(CONFIG_BUBINGA)
+#define BOARD_INFO_VECTOR       0xFFF80B50 /* openbios 1.19 moved this vector down  - armin */
+#else
+#define BOARD_INFO_VECTOR	0xFFFE0B50
+#endif
+
+#ifdef CONFIG_BEECH
+static void
+get_board_info(bd_t **bdp)
+{
+	typedef void (*PFV)(bd_t *bd);
+	((PFV)(*(unsigned long *)BOARD_INFO_VECTOR))(*bdp);
+	return;
+}
+
+void
+embed_config(bd_t **bdp)
+{
+        *bdp = &bdinfo;
+	get_board_info(bdp);
+}
+#else /* !CONFIG_BEECH */
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd, *treeboot_bd;
+	bd_t *(*get_board_info)(void) =
+	    (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
+#if !defined(CONFIG_STB03xxx)
+
+	/* shut down the Ethernet controller that the boot rom
+	 * sometimes leaves running.
+	 */
+	mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);     /* 1st reset MAL */
+	while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */	
+	out_be32((volatile u32*)EMAC0_BASE,0x20000000);        /* then reset EMAC */
+#endif
+
+	bd = &bdinfo;
+	*bdp = bd;
+	if ((treeboot_bd = get_board_info()) != NULL) {
+		memcpy(bd, treeboot_bd, sizeof(bd_t));
+	}
+	else {
+		/* Hmmm...better try to stuff some defaults.
+		*/
+		bd->bi_memsize = 16 * 1024 * 1024;
+		cp = (u_char *)def_enet_addr;
+		for (i=0; i<6; i++) {
+			/* I should probably put different ones here,
+			 * hopefully only one is used.
+			 */
+			bd->BD_EMAC_ADDR(0,i) = *cp;
+
+#ifdef CONFIG_PCI
+			bd->bi_pci_enetaddr[i] = *cp++;
+#endif
+		}
+		bd->bi_tbfreq = 200 * 1000 * 1000;
+		bd->bi_intfreq = 200000000;
+		bd->bi_busfreq = 100000000;
+#ifdef CONFIG_PCI
+		bd->bi_pci_busfreq = 66666666;
+#endif
+	}
+	/* Yeah, this look weird, but on Redwood 4 they are
+	 * different object in the structure.  Sincr Redwwood 5
+	 * and Redwood 6 use OpenBIOS, it requires a special value.
+	 */
+#if defined(CONFIG_REDWOOD_5) || defined (CONFIG_REDWOOD_6)
+	bd->bi_tbfreq = 27 * 1000 * 1000;
+#endif
+	timebase_period_ns = 1000000000 / bd->bi_tbfreq;
+}
+#endif /* CONFIG_BEECH */
+#endif /* CONFIG_IBM_OPENBIOS */
+
+#ifdef CONFIG_EP405
+#include <linux/serial_reg.h>
+
+void
+embed_config(bd_t **bdp)
+{
+	u32 chcr0;
+	u_char *cp;
+	bd_t	*bd;
+
+	/* Different versions of the PlanetCore firmware vary in how
+	   they set up the serial port - in particular whether they
+	   use the internal or external serial clock for UART0.  Make
+	   sure the UART is in a known state. */
+	/* FIXME: We should use the board's 11.0592MHz external serial
+	   clock - it will be more accurate for serial rates.  For
+	   now, however the baud rates in ep405.h are for the internal
+	   clock. */
+	chcr0 = mfdcr(DCRN_CHCR0);
+	if ( (chcr0 & 0x1fff) != 0x103e ) {
+		mtdcr(DCRN_CHCR0, (chcr0 & 0xffffe000) | 0x103e);
+		/* The following tricks serial_init() into resetting the baud rate */
+		writeb(0, UART0_IO_BASE + UART_LCR);
+	}
+
+	/* We haven't seen actual problems with the EP405 leaving the
+	 * EMAC running (as we have on Walnut).  But the registers
+	 * suggest it may not be left completely quiescent.  Reset it
+	 * just to be sure. */
+	mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);     /* 1st reset MAL */
+	while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */	
+	out_be32((unsigned *)EMAC0_BASE,0x20000000);        /* then reset EMAC */
+
+	bd = &bdinfo;
+	*bdp = bd;
+#if 1
+	        cp = (u_char *)0xF0000EE0;
+	        for (;;) {
+	                if (*cp == 'E') {
+	                        cp++;
+	                        if (*cp == 'A') {
+                                  cp += 2;
+                                  rpx_eth(bd, cp);
+	                        }
+		         }
+
+	         	if (*cp == 'D') {
+	                        	cp++;
+	                        	if (*cp == '1') {
+		                                cp += 2;
+		                                rpx_memsize(bd, cp);
+	        	                }
+                	}
+
+			if (*cp == 'N') {
+				cp++;
+				if (*cp == 'V') {
+					cp += 2;
+					rpx_nvramsize(bd, cp);
+				}
+			}
+			while ((*cp != '\n') && (*cp != 0xff))
+			      cp++;
+
+	                cp++;
+	                if ((*cp == 0) || (*cp == 0xff))
+	                   break;
+	       }
+	bd->bi_intfreq   = 200000000;
+	bd->bi_busfreq   = 100000000;
+	bd->bi_pci_busfreq= 33000000 ;
+#else
+
+	bd->bi_memsize   = 64000000;
+	bd->bi_intfreq   = 200000000;
+	bd->bi_busfreq   = 100000000;
+	bd->bi_pci_busfreq= 33000000 ;
+#endif
+}
+#endif
+
+#ifdef CONFIG_RAINIER
+/* Rainier uses vxworks bootrom */
+void
+embed_config(bd_t **bdp)
+{
+	u_char	*cp;
+	int	i;
+	bd_t	*bd;
+	
+	bd = &bdinfo;
+	*bdp = bd;
+	
+	for(i=0;i<8192;i+=32) {
+		__asm__("dccci 0,%0" :: "r" (i));
+	}
+	__asm__("iccci 0,0");
+	__asm__("sync;isync");
+
+	/* init ram for parity */
+	memset(0, 0,0x400000);  /* Lo memory */
+
+
+	bd->bi_memsize   = (32 * 1024 * 1024) ;
+	bd->bi_intfreq = 133000000; //the internal clock is 133 MHz
+	bd->bi_busfreq   = 100000000;
+	bd->bi_pci_busfreq= 33000000;
+
+	cp = (u_char *)def_enet_addr;
+	for (i=0; i<6; i++) {
+		bd->bi_enetaddr[i] = *cp++;
+	}
+
+}
+#endif
+
diff --git a/arch/ppc/boot/simple/head.S b/arch/ppc/boot/simple/head.S
new file mode 100644
index 0000000..5240532
--- /dev/null
+++ b/arch/ppc/boot/simple/head.S
@@ -0,0 +1,142 @@
+/*
+ * arch/ppc/boot/simple/head.S
+ *
+ * Initial board bringup code for many different boards.
+ *
+ * Author: Tom Rini
+ *	   trini@mvista.com
+ * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
+ *
+ * 2001-2004 (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/config.h>
+#include <asm/reg.h>
+#include <asm/cache.h>
+#include <asm/ppc_asm.h>
+
+	.text
+
+/*
+ *      Begin at some arbitrary location in RAM or Flash
+ *	  Initialize core registers
+ *	  Configure memory controller (Not executing from RAM)
+ *	Move the boot code to the link address (8M)
+ *	  Setup C stack
+ *	  Initialize UART
+ *      Decompress the kernel to 0x0
+ *      Jump to the kernel entry
+ *
+ */
+
+	.globl	start
+start:
+	bl	start_
+#ifdef CONFIG_IBM_OPENBIOS
+	/* The IBM "Tree" bootrom knows that the address of the bootrom
+	 * read only structure is 4 bytes after _start.
+	 */
+	.long	0x62726f6d		# structure ID - "brom"
+	.long	0x5f726f00		#              - "_ro\0"
+	.long	1			# structure version
+	.long	bootrom_cmdline		# address of *bootrom_cmdline
+#endif
+
+start_:
+#ifdef CONFIG_FORCE
+	/* We have some really bad firmware.  We must disable the L1
+	 * icache/dcache now or the board won't boot.
+	 */
+	li	r4,0x0000
+	isync
+	mtspr	SPRN_HID0,r4
+	sync
+	isync
+#endif
+
+#if defined(CONFIG_MBX) || defined(CONFIG_RPX8260) || defined(CONFIG_PPC_PREP)
+	mr	r29,r3	/* On the MBX860, r3 is the board info pointer.
+			 * On the RPXSUPER, r3 points to the NVRAM
+			 * configuration keys.
+			 * On PReP, r3 is the pointer to the residual data.
+			 */
+#endif
+
+	mflr	r3	/* Save our actual starting address. */
+
+	/* The following functions we call must not modify r3 or r4.....
+	*/
+#ifdef CONFIG_6xx
+	/* On PReP we must look at the OpenFirmware pointer and sanity
+	 * test it.  On other platforms, we disable the MMU right now
+	 * and other bits.
+	 */
+#ifdef CONFIG_PPC_PREP
+/*
+ * 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	r8,0x0fff		/* r8 = 0x0fffffff */
+	ori	r8,r8,0xffff
+
+	subc	r8,r8,r5		/* r8 = (r5 <= r8) ? ~0 : 0 */
+	subfe	r8,r8,r8
+	nand	r8,r8,r8
+
+	and.	r5,r5,r8		/* r5 will be cleared if (r5 > r8) */
+	bne+	haveOF
+
+	li	r8,MSR_IP|MSR_FP	/* Not OF: set MSR immediately */
+  	mtmsr	r8
+	isync
+haveOF:
+	mr	r25,r5
+#else
+	bl	disable_6xx_mmu
+#endif
+	bl	disable_6xx_l1cache
+
+	CLEAR_CACHES
+#endif
+
+#ifdef CONFIG_8xx
+	mfmsr	r8		/* Turn off interrupts */
+	li	r9,0
+	ori	r9,r9,MSR_EE
+	andc	r8,r8,r9
+	mtmsr	r8
+
+	/* We do this because some boot roms don't initialize the
+	 * processor correctly. Don't do this if you want to debug
+	 * using a BDM device.
+	 */
+	li	r4,0		/* Zero DER to prevent FRZ */
+	mtspr	SPRN_DER,r4
+#endif
+
+#ifdef CONFIG_REDWOOD_4
+	/* All of this Redwood 4 stuff will soon disappear when the
+	 * boot rom is straightened out.
+	 */
+	mr	r29, r3		/* Easier than changing the other code */
+	bl	HdwInit
+	mr	r3, r29
+#endif
+
+#if defined(CONFIG_MBX) || defined(CONFIG_RPX8260) || defined(CONFIG_PPC_PREP)
+	mr	r4,r29	/* put the board info pointer where the relocate
+			 * routine will find it
+			 */
+#endif
+
+	/* Get the load address.
+	*/
+	subi	r3, r3, 4	/* Get the actual IP, not NIP */
+	b	relocate
+
diff --git a/arch/ppc/boot/simple/iic.c b/arch/ppc/boot/simple/iic.c
new file mode 100644
index 0000000..e4efd83
--- /dev/null
+++ b/arch/ppc/boot/simple/iic.c
@@ -0,0 +1,214 @@
+/* Minimal support functions to read configuration from IIC EEPROMS
+ * on MPC8xx boards.  Originally written for RPGC RPX-Lite.
+ * Dan Malek (dmalek@jlc.net).
+ */
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+
+
+/* IIC functions.
+ * These are just the basic master read/write operations so we can
+ * examine serial EEPROM.
+ */
+void	iic_read(uint devaddr, u_char *buf, uint offset, uint count);
+
+static	int	iic_init_done;
+
+static void
+iic_init(void)
+{
+	volatile iic_t *iip;
+	volatile i2c8xx_t *i2c;
+	volatile cpm8xx_t	*cp;
+	volatile immap_t	*immap;
+	uint	dpaddr;
+
+	immap = (immap_t *)IMAP_ADDR;
+	cp = (cpm8xx_t *)&(immap->im_cpm);
+
+	/* Reset the CPM.  This is necessary on the 860 processors
+	 * that may have started the SCC1 ethernet without relocating
+	 * the IIC.
+	 * This also stops the Ethernet in case we were loaded by a
+	 * BOOTP rom monitor.
+	 */
+	cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
+
+	/* Wait for it.
+	*/
+	while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG));
+
+	/* Remove any microcode patches.  We will install our own
+	 * later.
+	 */
+	cp->cp_cpmcr1 = 0;
+	cp->cp_cpmcr2 = 0;
+	cp->cp_cpmcr3 = 0;
+	cp->cp_cpmcr4 = 0;
+	cp->cp_rccr = 0;
+
+	iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
+	i2c = (i2c8xx_t *)&(immap->im_i2c);
+
+	/* Initialize Port B IIC pins.
+	*/
+	cp->cp_pbpar |= 0x00000030;
+	cp->cp_pbdir |= 0x00000030;
+	cp->cp_pbodr |= 0x00000030;
+
+	/* Initialize the parameter ram.
+	*/
+
+	/* Allocate space for a two transmit and one receive buffer
+	 * descriptor in the DP ram.
+	 * For now, this address seems OK, but it may have to
+	 * change with newer versions of the firmware.
+	 */
+	dpaddr = 0x0840;
+
+	/* Set up the IIC parameters in the parameter ram.
+	*/
+	iip->iic_tbase = dpaddr;
+	iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t));
+
+	iip->iic_tfcr = SMC_EB;
+	iip->iic_rfcr = SMC_EB;
+
+	/* This should really be done by the reader/writer.
+	*/
+	iip->iic_mrblr = 128;
+
+	/* Initialize Tx/Rx parameters.
+	*/
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+
+	/* Select an arbitrary address.  Just make sure it is unique.
+	*/
+	i2c->i2c_i2add = 0x34;
+
+	/* Make clock run maximum slow.
+	*/
+	i2c->i2c_i2brg = 7;
+
+	/* Disable interrupts.
+	*/
+	i2c->i2c_i2cmr = 0;
+	i2c->i2c_i2cer = 0xff;
+
+	/* Enable SDMA.
+	*/
+	immap->im_siu_conf.sc_sdcr = 1;
+
+	iic_init_done = 1;
+}
+
+/* Read from IIC.
+ * Caller provides device address, memory buffer, and byte count.
+ */
+static	u_char	iitemp[32];
+
+void
+iic_read(uint devaddr, u_char *buf, uint offset, uint count)
+{
+	volatile iic_t		*iip;
+	volatile i2c8xx_t	*i2c;
+	volatile cbd_t		*tbdf, *rbdf;
+	volatile cpm8xx_t	*cp;
+	volatile immap_t	*immap;
+	u_char			*tb;
+	uint			temp;
+
+	/* If the interface has not been initialized, do that now.
+	*/
+	if (!iic_init_done)
+		iic_init();
+
+	immap = (immap_t *)IMAP_ADDR;
+	cp = (cpm8xx_t *)&(immap->im_cpm);
+
+	iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
+	i2c = (i2c8xx_t *)&(immap->im_i2c);
+
+	tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase];
+	rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase];
+
+	/* Send a "dummy write" operation.  This is a write request with
+	 * only the offset sent, followed by another start condition.
+	 * This will ensure we start reading from the first location
+	 * of the EEPROM.
+	 */
+	tb = iitemp;
+	tb = (u_char *)(((uint)tb + 15) & ~15);
+	tbdf->cbd_bufaddr = (int)tb;
+	*tb = devaddr & 0xfe;	/* Device address */
+	*(tb+1) = offset;		/* Offset */
+	tbdf->cbd_datlen = 2;		/* Length */
+	tbdf->cbd_sc =
+	      BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
+
+	i2c->i2c_i2mod = 1;	/* Enable */
+	i2c->i2c_i2cer = 0xff;
+	i2c->i2c_i2com = 0x81;	/* Start master */
+
+	/* Wait for IIC transfer.
+	*/
+#if 0
+	while ((i2c->i2c_i2cer & 3) == 0);
+
+	if (tbdf->cbd_sc & BD_SC_READY)
+		printf("IIC ra complete but tbuf ready\n");
+#else
+	temp = 10000000;
+	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
+		temp--;
+#if 0
+	/* We can't do this...there is no serial port yet!
+	*/
+	if (temp == 0) {
+		printf("Timeout reading EEPROM\n");
+		return;
+	}
+#endif
+#endif
+	
+	/* Chip errata, clear enable.
+	*/
+	i2c->i2c_i2mod = 0;
+
+	/* To read, we need an empty buffer of the proper length.
+	 * All that is used is the first byte for address, the remainder
+	 * is just used for timing (and doesn't really have to exist).
+	 */
+	tbdf->cbd_bufaddr = (int)tb;
+	*tb = devaddr | 1;	/* Device address */
+	rbdf->cbd_bufaddr = (uint)buf;		/* Desination buffer */
+	tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1;	/* Length */
+	tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START;
+	rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP;
+
+	/* Chip bug, set enable here.
+	*/
+	i2c->i2c_i2mod = 1;	/* Enable */
+	i2c->i2c_i2cer = 0xff;
+	i2c->i2c_i2com = 0x81;	/* Start master */
+
+	/* Wait for IIC transfer.
+	*/
+#if 0
+	while ((i2c->i2c_i2cer & 1) == 0);
+
+	if (rbdf->cbd_sc & BD_SC_EMPTY)
+		printf("IIC read complete but rbuf empty\n");
+#else
+	temp = 10000000;
+	while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0))
+		temp--;
+#endif
+	
+	/* Chip errata, clear enable.
+	*/
+	i2c->i2c_i2mod = 0;
+}
diff --git a/arch/ppc/boot/simple/m8260_tty.c b/arch/ppc/boot/simple/m8260_tty.c
new file mode 100644
index 0000000..d770947
--- /dev/null
+++ b/arch/ppc/boot/simple/m8260_tty.c
@@ -0,0 +1,325 @@
+/* Minimal serial functions needed to send messages out the serial
+ * port on SMC1.
+ */
+#include <linux/types.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+#include <asm/immap_cpm2.h>
+
+uint	no_print;
+extern char	*params[];
+extern int	nparams;
+static		u_char	cons_hold[128], *sgptr;
+static		int	cons_hold_cnt;
+
+/* If defined, enables serial console.  The value (1 through 4)
+ * should designate which SCC is used, but this isn't complete.  Only
+ * SCC1 is known to work at this time.
+ * We're only linked if SERIAL_CPM_CONSOLE=y, so we only need to test
+ * SERIAL_CPM_SCC1.
+ */
+#ifdef CONFIG_SERIAL_CPM_SCC1
+#define SCC_CONSOLE 1
+#endif
+
+unsigned long
+serial_init(int ignored, bd_t *bd)
+{
+#ifdef SCC_CONSOLE
+	volatile scc_t		*sccp;
+	volatile scc_uart_t	*sup;
+#else
+	volatile smc_t		*sp;
+	volatile smc_uart_t	*up;
+#endif
+	volatile cbd_t	*tbdf, *rbdf;
+	volatile cpm2_map_t	*ip;
+	volatile iop_cpm2_t	*io;
+	volatile cpm_cpm2_t	*cp;
+	uint	dpaddr, memaddr;
+
+	ip = (cpm2_map_t *)CPM_MAP_ADDR;
+	cp = &ip->im_cpm;
+	io = &ip->im_ioport;
+
+	/* Perform a reset.
+	*/
+	cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
+
+	/* Wait for it.
+	*/
+	while (cp->cp_cpcr & CPM_CR_FLG);
+
+#ifdef CONFIG_ADS8260
+	/* Enable the RS-232 transceivers.
+	*/
+	*(volatile uint *)(BCSR_ADDR + 4) &=
+					~(BCSR1_RS232_EN1 | BCSR1_RS232_EN2);
+#endif
+
+#ifdef SCC_CONSOLE
+	sccp = (scc_t *)&(ip->im_scc[SCC_CONSOLE-1]);
+	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+	sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX);
+	sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+
+	/* Use Port D for SCC1 instead of other functions.
+	*/
+	io->iop_ppard |= 0x00000003;
+	io->iop_psord &= ~0x00000001;	/* Rx */
+	io->iop_psord |= 0x00000002;	/* Tx */
+	io->iop_pdird &= ~0x00000001;	/* Rx */
+	io->iop_pdird |= 0x00000002;	/* Tx */
+
+#else
+	sp = (smc_t*)&(ip->im_smc[0]);
+	*(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1;
+	up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1];
+
+	/* Disable transmitter/receiver.
+	*/
+	sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+	/* Use Port D for SMC1 instead of other functions.
+	*/
+	io->iop_ppard |= 0x00c00000;
+	io->iop_pdird |= 0x00400000;
+	io->iop_pdird &= ~0x00800000;
+	io->iop_psord &= ~0x00c00000;
+#endif
+
+	/* Allocate space for two buffer descriptors in the DP ram.
+	 * For now, this address seems OK, but it may have to
+	 * change with newer versions of the firmware.
+	 */
+	dpaddr = 0x0800;
+
+	/* Grab a few bytes from the top of memory.
+	 */
+	memaddr = (bd->bi_memsize - 256) & ~15;
+
+	/* Set the physical address of the host memory buffers in
+	 * the buffer descriptors.
+	 */
+	rbdf = (cbd_t *)&ip->im_dprambase[dpaddr];
+	rbdf->cbd_bufaddr = memaddr;
+	rbdf->cbd_sc = 0;
+	tbdf = rbdf + 1;
+	tbdf->cbd_bufaddr = memaddr+128;
+	tbdf->cbd_sc = 0;
+
+	/* Set up the uart parameters in the parameter ram.
+	*/
+#ifdef SCC_CONSOLE
+	sup->scc_genscc.scc_rbase = dpaddr;
+	sup->scc_genscc.scc_tbase = dpaddr + sizeof(cbd_t);
+
+	/* Set up the uart parameters in the
+	 * parameter ram.
+	 */
+	sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB;
+	sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB;
+
+	sup->scc_genscc.scc_mrblr = 128;
+	sup->scc_maxidl = 8;
+	sup->scc_brkcr = 1;
+	sup->scc_parec = 0;
+	sup->scc_frmec = 0;
+	sup->scc_nosec = 0;
+	sup->scc_brkec = 0;
+	sup->scc_uaddr1 = 0;
+	sup->scc_uaddr2 = 0;
+	sup->scc_toseq = 0;
+	sup->scc_char1 = 0x8000;
+	sup->scc_char2 = 0x8000;
+	sup->scc_char3 = 0x8000;
+	sup->scc_char4 = 0x8000;
+	sup->scc_char5 = 0x8000;
+	sup->scc_char6 = 0x8000;
+	sup->scc_char7 = 0x8000;
+	sup->scc_char8 = 0x8000;
+	sup->scc_rccm = 0xc0ff;
+
+	/* Send the CPM an initialize command.
+	*/
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0,
+			CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+
+	/* Set UART mode, 8 bit, no parity, one stop.
+	 * Enable receive and transmit.
+	 */
+	sccp->scc_gsmrh = 0;
+	sccp->scc_gsmrl =
+		(SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16);
+
+	/* Disable all interrupts and clear all pending
+	 * events.
+	 */
+	sccp->scc_sccm = 0;
+	sccp->scc_scce = 0xffff;
+	sccp->scc_dsr = 0x7e7e;
+	sccp->scc_psmr = 0x3000;
+
+	/* Wire BRG1 to SCC1.  The console driver will take care of
+	 * others.
+	 */
+	ip->im_cpmux.cmx_scr = 0;
+#else
+	up->smc_rbase = dpaddr;
+	up->smc_tbase = dpaddr+sizeof(cbd_t);
+	up->smc_rfcr = CPMFCR_EB;
+	up->smc_tfcr = CPMFCR_EB;
+	up->smc_brklen = 0;
+	up->smc_brkec = 0;
+	up->smc_brkcr = 0;
+	up->smc_mrblr = 128;
+	up->smc_maxidl = 8;
+
+	/* Set UART mode, 8 bit, no parity, one stop.
+	 * Enable receive and transmit.
+	 */
+	sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
+
+	/* Mask all interrupts and remove anything pending.
+	*/
+	sp->smc_smcm = 0;
+	sp->smc_smce = 0xff;
+
+	/* Set up the baud rate generator.
+	 */
+	ip->im_cpmux.cmx_smr = 0;
+#endif
+
+	/* The baud rate divisor needs to be coordinated with clk_8260().
+	*/
+	ip->im_brgc1 =
+		(((bd->bi_brgfreq/16) / bd->bi_baudrate) << 1) |
+								CPM_BRG_EN;
+
+	/* Make the first buffer the only buffer.
+	*/
+	tbdf->cbd_sc |= BD_SC_WRAP;
+	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+	/* Initialize Tx/Rx parameters.
+	*/
+#ifdef SCC_CONSOLE
+	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#else
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+
+	/* Enable transmitter/receiver.
+	*/
+	sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+#endif
+
+	/* This is ignored.
+	*/
+	return 0;
+}
+
+int
+serial_readbuf(u_char *cbuf)
+{
+	volatile cbd_t		*rbdf;
+	volatile char		*buf;
+#ifdef SCC_CONSOLE
+	volatile scc_uart_t	*sup;
+#else
+	volatile smc_uart_t	*up;
+#endif
+	volatile cpm2_map_t	*ip;
+	int	i, nc;
+
+	ip = (cpm2_map_t *)CPM_MAP_ADDR;
+
+#ifdef SCC_CONSOLE
+	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+	rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase];
+#else
+	up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+	rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
+#endif
+
+	/* Wait for character to show up.
+	*/
+	buf = (char *)rbdf->cbd_bufaddr;
+	while (rbdf->cbd_sc & BD_SC_EMPTY);
+	nc = rbdf->cbd_datlen;
+	for (i=0; i<nc; i++)
+		*cbuf++ = *buf++;
+	rbdf->cbd_sc |= BD_SC_EMPTY;
+
+	return(nc);
+}
+
+void
+serial_putc(void *ignored, const char c)
+{
+	volatile cbd_t		*tbdf;
+	volatile char		*buf;
+#ifdef SCC_CONSOLE
+	volatile scc_uart_t	*sup;
+#else
+	volatile smc_uart_t	*up;
+#endif
+	volatile cpm2_map_t	*ip;
+
+	ip = (cpm2_map_t *)CPM_MAP_ADDR;
+#ifdef SCC_CONSOLE
+	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+	tbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_tbase];
+#else
+	up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+	tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase];
+#endif
+
+	/* Wait for last character to go.
+	*/
+	buf = (char *)tbdf->cbd_bufaddr;
+	while (tbdf->cbd_sc & BD_SC_READY);
+
+	*buf = c;
+	tbdf->cbd_datlen = 1;
+	tbdf->cbd_sc |= BD_SC_READY;
+}
+
+char
+serial_getc(void *ignored)
+{
+	char	c;
+
+	if (cons_hold_cnt <= 0) {
+		cons_hold_cnt = serial_readbuf(cons_hold);
+		sgptr = cons_hold;
+	}
+	c = *sgptr++;
+	cons_hold_cnt--;
+
+	return(c);
+}
+
+int
+serial_tstc(void *ignored)
+{
+	volatile cbd_t		*rbdf;
+#ifdef SCC_CONSOLE
+	volatile scc_uart_t	*sup;
+#else
+	volatile smc_uart_t	*up;
+#endif
+	volatile cpm2_map_t	*ip;
+
+	ip = (cpm2_map_t *)CPM_MAP_ADDR;
+#ifdef SCC_CONSOLE
+	sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)];
+	rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase];
+#else
+	up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]);
+	rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase];
+#endif
+
+	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
+}
diff --git a/arch/ppc/boot/simple/m8xx_tty.c b/arch/ppc/boot/simple/m8xx_tty.c
new file mode 100644
index 0000000..1d2778e
--- /dev/null
+++ b/arch/ppc/boot/simple/m8xx_tty.c
@@ -0,0 +1,290 @@
+/* Minimal serial functions needed to send messages out the serial
+ * port on the MBX console.
+ *
+ * The MBX uxes SMC1 for the serial port.  We reset the port and use
+ * only the first BD that EPPC-Bug set up as a character FIFO.
+ *
+ * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug
+ * use COM1 instead of SMC1 as the console port.  This kinda sucks
+ * for the rest of the kernel, so here we force the use of SMC1 again.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <asm/mpc8xx.h>
+#include <asm/commproc.h>
+
+#ifdef CONFIG_MBX
+#define MBX_CSR1	((volatile u_char *)0xfa100000)
+#define CSR1_COMEN	(u_char)0x02
+#endif
+
+#ifdef TQM_SMC2_CONSOLE
+#define PROFF_CONS	PROFF_SMC2
+#define CPM_CR_CH_CONS	CPM_CR_CH_SMC2
+#define SMC_INDEX	1
+static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport);
+#else
+#define PROFF_CONS	PROFF_SMC1
+#define CPM_CR_CH_CONS	CPM_CR_CH_SMC1
+#define SMC_INDEX	0
+#endif
+
+static cpm8xx_t	*cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
+
+unsigned long
+serial_init(int ignored, bd_t *bd)
+{
+	volatile smc_t		*sp;
+	volatile smc_uart_t	*up;
+	volatile cbd_t	*tbdf, *rbdf;
+	volatile cpm8xx_t	*cp;
+	uint	dpaddr, memaddr;
+#ifndef CONFIG_MBX
+	uint	ui;
+#endif
+
+	cp = cpmp;
+	sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]);
+	up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS];
+
+	/* Disable transmitter/receiver.
+	*/
+	sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
+
+#ifdef CONFIG_FADS
+	/* Enable SMC1/2 transceivers.
+	*/
+	*((volatile uint *)BCSR1) &= ~(BCSR1_RS232EN_1|BCSR1_RS232EN_2);
+#endif
+
+#ifndef CONFIG_MBX
+	{
+	/* Initialize SMCx and use it for the console port.
+	 */
+
+	/* Enable SDMA.
+	*/
+	((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
+
+#ifdef TQM_SMC2_CONSOLE
+	/* Use Port A for SMC2 instead of other functions.
+	*/
+	iopp->iop_papar |=  0x00c0;
+	iopp->iop_padir &= ~0x00c0;
+	iopp->iop_paodr &= ~0x00c0;
+#else
+	/* Use Port B for SMCs instead of other functions.
+	*/
+	cp->cp_pbpar |= 0x00000cc0;
+	cp->cp_pbdir &= ~0x00000cc0;
+	cp->cp_pbodr &= ~0x00000cc0;
+#endif
+
+	/* Allocate space for two buffer descriptors in the DP ram.
+	 * For now, this address seems OK, but it may have to
+	 * change with newer versions of the firmware.
+	 */
+	dpaddr = 0x0800;
+
+	/* Grab a few bytes from the top of memory for SMC FIFOs.
+	 */
+	memaddr = (bd->bi_memsize - 32) & ~15;
+
+	/* Set the physical address of the host memory buffers in
+	 * the buffer descriptors.
+	 */
+	rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
+	rbdf->cbd_bufaddr = memaddr;
+	rbdf->cbd_sc = 0;
+	tbdf = rbdf + 1;
+	tbdf->cbd_bufaddr = memaddr+4;
+	tbdf->cbd_sc = 0;
+
+	/* Set up the uart parameters in the parameter ram.
+	*/
+	up->smc_rbase = dpaddr;
+	up->smc_tbase = dpaddr+sizeof(cbd_t);
+	up->smc_rfcr = SMC_EB;
+	up->smc_tfcr = SMC_EB;
+
+	/* Set UART mode, 8 bit, no parity, one stop.
+	 * Enable receive and transmit.
+	 */
+	sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
+
+	/* Mask all interrupts and remove anything pending.
+	*/
+	sp->smc_smcm = 0;
+	sp->smc_smce = 0xff;
+
+	/* Set up the baud rate generator.
+	 * See 8xx_io/commproc.c for details.
+	 * This wires BRG1 to SMC1 and BRG2 to SMC2;
+	 */
+	cp->cp_simode = 0x10000000;
+	ui = bd->bi_intfreq / 16 / bd->bi_baudrate;
+#ifdef TQM_SMC2_CONSOLE
+	cp->cp_brgc2 =
+#else
+	cp->cp_brgc1 =
+#endif
+		((ui - 1) < 4096)
+		? (((ui - 1) << 1) | CPM_BRG_EN)
+		: ((((ui / 16) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16);
+
+#else /* CONFIG_MBX */
+	if (*MBX_CSR1 & CSR1_COMEN) {
+		/* COM1 is enabled.  Initialize SMC1 and use it for
+		 * the console port.
+		 */
+
+		/* Enable SDMA.
+		*/
+		((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1;
+
+		/* Use Port B for SMCs instead of other functions.
+		*/
+		cp->cp_pbpar |= 0x00000cc0;
+		cp->cp_pbdir &= ~0x00000cc0;
+		cp->cp_pbodr &= ~0x00000cc0;
+
+		/* Allocate space for two buffer descriptors in the DP ram.
+		 * For now, this address seems OK, but it may have to
+		 * change with newer versions of the firmware.
+		 */
+		dpaddr = 0x0800;
+
+		/* Grab a few bytes from the top of memory.  EPPC-Bug isn't
+		 * running any more, so we can do this.
+		 */
+		memaddr = (bd->bi_memsize - 32) & ~15;
+
+		/* Set the physical address of the host memory buffers in
+		 * the buffer descriptors.
+		 */
+		rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr];
+		rbdf->cbd_bufaddr = memaddr;
+		rbdf->cbd_sc = 0;
+		tbdf = rbdf + 1;
+		tbdf->cbd_bufaddr = memaddr+4;
+		tbdf->cbd_sc = 0;
+
+		/* Set up the uart parameters in the parameter ram.
+		*/
+		up->smc_rbase = dpaddr;
+		up->smc_tbase = dpaddr+sizeof(cbd_t);
+		up->smc_rfcr = SMC_EB;
+		up->smc_tfcr = SMC_EB;
+
+		/* Set UART mode, 8 bit, no parity, one stop.
+		 * Enable receive and transmit.
+		 */
+		sp->smc_smcmr = smcr_mk_clen(9) |  SMCMR_SM_UART;
+
+		/* Mask all interrupts and remove anything pending.
+		*/
+		sp->smc_smcm = 0;
+		sp->smc_smce = 0xff;
+
+		/* Set up the baud rate generator.
+		 * See 8xx_io/commproc.c for details.
+		 */
+		cp->cp_simode = 0x10000000;
+		cp->cp_brgc1 =
+			(((bd->bi_intfreq/16) / 9600) << 1) | CPM_BRG_EN;
+
+		/* Enable SMC1 for console output.
+		*/
+		*MBX_CSR1 &= ~CSR1_COMEN;
+	}
+	else {
+#endif /* ndef CONFIG_MBX */
+		/* SMCx is used as console port.
+		*/
+		tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase];
+		rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase];
+
+		/* Issue a stop transmit, and wait for it.
+		*/
+		cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS,
+					CPM_CR_STOP_TX) | CPM_CR_FLG;
+		while (cp->cp_cpcr & CPM_CR_FLG);
+	}
+
+	/* Make the first buffer the only buffer.
+	*/
+	tbdf->cbd_sc |= BD_SC_WRAP;
+	rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP;
+
+	/* Single character receive.
+	*/
+	up->smc_mrblr = 1;
+	up->smc_maxidl = 0;
+
+	/* Initialize Tx/Rx parameters.
+	*/
+	cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG;
+	while (cp->cp_cpcr & CPM_CR_FLG);
+
+	/* Enable transmitter/receiver.
+	*/
+	sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN;
+
+	/* This is ignored.
+	*/
+	return 0;
+}
+
+void
+serial_putc(void *ignored, const char c)
+{
+	volatile cbd_t		*tbdf;
+	volatile char		*buf;
+	volatile smc_uart_t	*up;
+
+	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
+	tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
+
+	/* Wait for last character to go.
+	*/
+	buf = (char *)tbdf->cbd_bufaddr;
+	while (tbdf->cbd_sc & BD_SC_READY);
+
+	*buf = c;
+	tbdf->cbd_datlen = 1;
+	tbdf->cbd_sc |= BD_SC_READY;
+}
+
+char
+serial_getc(void *ignored)
+{
+	volatile cbd_t		*rbdf;
+	volatile char		*buf;
+	volatile smc_uart_t	*up;
+	char			c;
+
+	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
+	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+
+	/* Wait for character to show up.
+	*/
+	buf = (char *)rbdf->cbd_bufaddr;
+	while (rbdf->cbd_sc & BD_SC_EMPTY);
+	c = *buf;
+	rbdf->cbd_sc |= BD_SC_EMPTY;
+
+	return(c);
+}
+
+int
+serial_tstc(void *ignored)
+{
+	volatile cbd_t		*rbdf;
+	volatile smc_uart_t	*up;
+
+	up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS];
+	rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+
+	return(!(rbdf->cbd_sc & BD_SC_EMPTY));
+}
diff --git a/arch/ppc/boot/simple/misc-chestnut.c b/arch/ppc/boot/simple/misc-chestnut.c
new file mode 100644
index 0000000..0dce7f3
--- /dev/null
+++ b/arch/ppc/boot/simple/misc-chestnut.c
@@ -0,0 +1,35 @@
+/*
+ * arch/ppc/boot/simple/misc-chestnut.c
+ *
+ * Setup for the IBM Chestnut (ibm-750fxgx_eval)
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2005 (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/config.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/mv64x60_defs.h>
+#include <platforms/chestnut.h>
+
+/* Not in the kernel so won't include kernel.h to get its 'max' definition */
+#define max(a,b)	(((a) > (b)) ? (a) : (b))
+
+void
+mv64x60_board_init(void __iomem *old_base, void __iomem *new_base)
+{
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	/*
+	 * Change device bus 2 window so that bootoader can do I/O thru
+	 * 8250/16550 UART that's mapped in that window.
+	 */
+	out_le32(new_base + MV64x60_CPU2DEV_2_BASE, CHESTNUT_UART_BASE >> 16);
+	out_le32(new_base + MV64x60_CPU2DEV_2_SIZE, CHESTNUT_UART_SIZE >> 16);
+	__asm__ __volatile__("sync");
+#endif
+}
diff --git a/arch/ppc/boot/simple/misc-cpci690.c b/arch/ppc/boot/simple/misc-cpci690.c
new file mode 100644
index 0000000..ef08e86
--- /dev/null
+++ b/arch/ppc/boot/simple/misc-cpci690.c
@@ -0,0 +1,27 @@
+/*
+ * arch/ppc/boot/simple/misc-cpci690.c
+ *
+ * Add birec data for Force CPCI690 board.
+ *
+ * Author: Mark A. Greer <source@mvista.com>
+ *
+ * 2003 (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>
+#include <platforms/cpci690.h>
+
+extern u32 mv64x60_console_baud;
+extern u32 mv64x60_mpsc_clk_src;
+extern u32 mv64x60_mpsc_clk_freq;
+
+void
+mv64x60_board_init(void __iomem *old_base, void __iomem *new_base)
+{
+	mv64x60_console_baud = CPCI690_MPSC_BAUD;
+	mv64x60_mpsc_clk_src = CPCI690_MPSC_CLK_SRC;
+	mv64x60_mpsc_clk_freq = CPCI690_BUS_FREQ;
+}
diff --git a/arch/ppc/boot/simple/misc-embedded.c b/arch/ppc/boot/simple/misc-embedded.c
new file mode 100644
index 0000000..3865f3f
--- /dev/null
+++ b/arch/ppc/boot/simple/misc-embedded.c
@@ -0,0 +1,275 @@
+/*
+ * Originally adapted by Gary Thomas.  Much additional work by
+ * Cort Dougan <cort@fsmlabs.com>.  On top of that still more work by
+ * Dan Malek <dmalek@jlc.net>.
+ *
+ * Currently maintained by: Tom Rini <trini@kernel.crashing.org>
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <asm/bootinfo.h>
+#include <asm/mmu.h>
+#include <asm/page.h>
+#include <asm/residual.h>
+#if defined(CONFIG_4xx)
+#include <asm/ibm4xx.h>
+#elif defined(CONFIG_8xx)
+#include <asm/mpc8xx.h>
+#elif defined(CONFIG_8260)
+#include <asm/mpc8260.h>
+#endif
+
+#include "nonstdio.h"
+
+/* The linker tells us where the image is. */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin, __ramdisk_end;
+extern char _end[];
+
+/* Because of the limited amount of memory on embedded, it presents
+ * loading problems.  The biggest is that we load this boot program
+ * into a relatively low memory address, and the Linux kernel Bss often
+ * extends into this space when it get loaded.  When the kernel starts
+ * and zeros the BSS space, it also writes over the information we
+ * save here and pass to the kernel (usually board info).
+ * On these boards, we grab some known memory holes to hold this information.
+ */
+char cmd_buf[256];
+char *cmd_line = cmd_buf;
+char *avail_ram;
+char *end_avail;
+char *zimage_start;
+
+/* This is for 4xx treeboot.  It provides a place for the bootrom
+ * give us a pointer to a rom environment command line.
+ */
+char *bootrom_cmdline = "";
+
+/* This is the default cmdline that will be given to the user at boot time..
+ * If none was specified at compile time, we'll give it one that should work.
+ * -- Tom */
+#ifdef CONFIG_CMDLINE_BOOL
+char compiled_string[] = CONFIG_CMDLINE;
+#endif
+char ramroot_string[] = "root=/dev/ram";
+char netroot_string[] = "root=/dev/nfs rw ip=on";
+
+/* Serial port to use. */
+unsigned long com_port;
+
+/* We need to make sure that this is before the images to ensure
+ * that it's in a mapped location. - Tom */
+bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
+bd_t *hold_residual = &hold_resid_buf;
+
+extern unsigned long serial_init(int chan, bd_t *bp);
+extern void serial_close(unsigned long com_port);
+extern unsigned long start;
+extern void flush_instruction_cache(void);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern void embed_config(bd_t **bp);
+
+/* Weak function for boards which don't need to build the
+ * board info struct because they are using PPCBoot/U-Boot.
+ */
+void __attribute__ ((weak))
+embed_config(bd_t **bdp)
+{
+}
+
+unsigned long
+load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp)
+{
+	char *cp, ch;
+	int timer = 0, zimage_size;
+	unsigned long initrd_size;
+
+	/* First, capture the embedded board information.  Then
+	 * initialize the serial console port.
+	 */
+	embed_config(&bp);
+#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE)
+	com_port = serial_init(0, bp);
+#endif
+
+	/* Grab some space for the command line and board info.  Since
+	 * we no longer use the ELF header, but it was loaded, grab
+	 * that space.
+	 */
+#ifdef CONFIG_MBX
+	/* Because of the way the MBX loads the ELF image, we can't
+	 * tell where we started.  We read a magic variable from the NVRAM
+	 * that gives us the intermediate buffer load address.
+	 */
+	load_addr = *(uint *)0xfa000020;
+	load_addr += 0x10000;		/* Skip ELF header */
+#endif
+	/* copy board data */
+	if (bp)
+		memcpy(hold_residual,bp,sizeof(bd_t));
+
+	/* Set end of memory available to us.  It is always the highest
+	 * memory address provided by the board information.
+	 */
+	end_avail = (char *)(bp->bi_memsize);
+
+	puts("\nloaded at:     "); puthex(load_addr);
+	puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
+	if ( (unsigned long)load_addr != (unsigned long)&start ) {
+		puts("relocated to:  "); puthex((unsigned long)&start);
+		puts(" ");
+		puthex((unsigned long)((unsigned long)&start + (4*num_words)));
+		puts("\n");
+	}
+
+	if ( bp ) {
+		puts("board data at: "); puthex((unsigned long)bp);
+		puts(" ");
+		puthex((unsigned long)((unsigned long)bp + sizeof(bd_t)));
+		puts("\nrelocated to:  ");
+		puthex((unsigned long)hold_residual);
+		puts(" ");
+		puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t)));
+		puts("\n");
+	}
+
+	/*
+	 * We link ourself to an arbitrary low address.  When we run, we
+	 * relocate outself to that address.  __image_being points to
+	 * the part of the image where the zImage is. -- Tom
+	 */
+	zimage_start = (char *)(unsigned long)(&__image_begin);
+	zimage_size = (unsigned long)(&__image_end) -
+			(unsigned long)(&__image_begin);
+
+	initrd_size = (unsigned long)(&__ramdisk_end) -
+		(unsigned long)(&__ramdisk_begin);
+
+	/*
+	 * The zImage and initrd will be between start and _end, so they've
+	 * already been moved once.  We're good to go now. -- Tom
+	 */
+	puts("zimage at:     "); puthex((unsigned long)zimage_start);
+	puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
+	puts("\n");
+
+	if ( initrd_size ) {
+		puts("initrd at:     ");
+		puthex((unsigned long)(&__ramdisk_begin));
+		puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
+	}
+
+	/*
+	 * setup avail_ram - this is the first part of ram usable
+	 * by the uncompress code.  Anything after this program in RAM
+	 * is now fair game. -- Tom
+	 */
+	avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
+
+	puts("avail ram:     "); puthex((unsigned long)avail_ram); puts(" ");
+	puthex((unsigned long)end_avail); puts("\n");
+	puts("\nLinux/PPC load: ");
+	cp = cmd_line;
+	/* This is where we try and pick the right command line for booting.
+	 * If we were given one at compile time, use it.  It Is Right.
+	 * If we weren't, see if we have a ramdisk.  If so, thats root.
+	 * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom
+	 */
+#ifdef CONFIG_CMDLINE_BOOL
+	memcpy (cmd_line, compiled_string, sizeof(compiled_string));
+#else
+	if ( initrd_size )
+		memcpy (cmd_line, ramroot_string, sizeof(ramroot_string));
+	else
+		memcpy (cmd_line, netroot_string, sizeof(netroot_string));
+#endif
+	while ( *cp )
+		putc(*cp++);
+	while (timer++ < 5*1000) {
+		if (tstc()) {
+			while ((ch = getc()) != '\n' && ch != '\r') {
+				if (ch == '\b' || ch == '\177') {
+					if (cp != cmd_line) {
+						cp--;
+						puts("\b \b");
+					}
+				} else if (ch == '\030'		/* ^x */
+					   || ch == '\025') {	/* ^u */
+					while (cp != cmd_line) {
+						cp--;
+						puts("\b \b");
+					}
+				} else {
+					*cp++ = ch;
+					putc(ch);
+				}
+			}
+			break;  /* Exit 'timer' loop */
+		}
+		udelay(1000);  /* 1 msec */
+	}
+	*cp = 0;
+	puts("\nUncompressing Linux...");
+
+	gunzip(0, 0x400000, zimage_start, &zimage_size);
+	flush_instruction_cache();
+	puts("done.\n");
+	{
+		struct bi_record *rec;
+		unsigned long initrd_loc = 0;
+		unsigned long rec_loc = _ALIGN((unsigned long)(zimage_size) +
+				(1 << 20) - 1, (1 << 20));
+		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);
+
+		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;
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+		if ( initrd_size ) {
+			rec->tag = BI_INITRD;
+			rec->data[0] = initrd_loc;
+			rec->data[1] = initrd_size;
+			rec->size = sizeof(struct bi_record) + 2 *
+				sizeof(unsigned long);
+			rec = (struct bi_record *)((unsigned long)rec +
+					rec->size);
+		}
+
+		rec->tag = BI_LAST;
+		rec->size = sizeof(struct bi_record);
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	}
+	puts("Now booting the kernel\n");
+#if defined(CONFIG_SERIAL_CPM_CONSOLE) || defined(CONFIG_SERIAL_8250_CONSOLE)
+	serial_close(com_port);
+#endif
+
+	return (unsigned long)hold_residual;
+}
diff --git a/arch/ppc/boot/simple/misc-ev64260.c b/arch/ppc/boot/simple/misc-ev64260.c
new file mode 100644
index 0000000..52ece69
--- /dev/null
+++ b/arch/ppc/boot/simple/misc-ev64260.c
@@ -0,0 +1,57 @@
+/*
+ * arch/ppc/boot/simple/misc-ev64260.c
+ *
+ * Host bridge init code for the Marvell/Galileo EV-64260-BP evaluation board
+ * with a GT64260 onboard.
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 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/config.h>
+#include <linux/types.h>
+#include <asm/reg.h>
+#include <asm/io.h>
+#include <asm/mv64x60_defs.h>
+#include <platforms/ev64260.h>
+
+#ifdef CONFIG_SERIAL_MPSC_CONSOLE
+extern u32 mv64x60_console_baud;
+extern u32 mv64x60_mpsc_clk_src;
+extern u32 mv64x60_mpsc_clk_freq;
+#endif
+
+void
+mv64x60_board_init(void __iomem *old_base, void __iomem *new_base)
+{
+	u32	p, v;
+
+	/* DINK doesn't enable 745x timebase, so enable here (Adrian Cox) */
+	p = mfspr(SPRN_PVR);
+	p >>= 16;
+
+	/* Reasonable SWAG at a 745x PVR value */
+	if (((p & 0xfff0) == 0x8000) && (p != 0x800c)) {
+		v = mfspr(SPRN_HID0);
+		v |= HID0_TBEN;
+		mtspr(SPRN_HID0, v);
+	}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	/*
+	 * Change device bus 2 window so that bootoader can do I/O thru
+	 * 8250/16550 UART that's mapped in that window.
+	 */
+	out_le32(new_base + MV64x60_CPU2DEV_2_BASE, EV64260_UART_BASE >> 20);
+	out_le32(new_base + MV64x60_CPU2DEV_2_SIZE, EV64260_UART_END >> 20);
+	__asm__ __volatile__("sync");
+#elif defined(CONFIG_SERIAL_MPSC_CONSOLE)
+	mv64x60_console_baud = EV64260_DEFAULT_BAUD;
+	mv64x60_mpsc_clk_src = EV64260_MPSC_CLK_SRC;
+	mv64x60_mpsc_clk_freq = EV64260_MPSC_CLK_FREQ;
+#endif
+}
diff --git a/arch/ppc/boot/simple/misc-katana.c b/arch/ppc/boot/simple/misc-katana.c
new file mode 100644
index 0000000..b6e1bb8
--- /dev/null
+++ b/arch/ppc/boot/simple/misc-katana.c
@@ -0,0 +1,37 @@
+/*
+ * arch/ppc/boot/simple/misc-katana.c
+ *
+ * Set up MPSC values to bootwrapper can prompt user.
+ *
+ * Author: Mark A. Greer <source@mvista.com>
+ *
+ * 2004 (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/config.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/mv64x60_defs.h>
+#include <platforms/katana.h>
+
+extern u32 mv64x60_console_baud;
+extern u32 mv64x60_mpsc_clk_src;
+extern u32 mv64x60_mpsc_clk_freq;
+
+/* Not in the kernel so won't include kernel.h to get its 'min' definition */
+#ifndef min
+#define	min(a,b)	(((a) < (b)) ? (a) : (b))
+#endif
+
+void
+mv64x60_board_init(void __iomem *old_base, void __iomem *new_base)
+{
+	mv64x60_console_baud = KATANA_DEFAULT_BAUD;
+	mv64x60_mpsc_clk_src = KATANA_MPSC_CLK_SRC;
+	mv64x60_mpsc_clk_freq =
+		min(katana_bus_freq((void __iomem *)KATANA_CPLD_BASE),
+			MV64x60_TCLK_FREQ_MAX);
+}
diff --git a/arch/ppc/boot/simple/misc-mv64x60.c b/arch/ppc/boot/simple/misc-mv64x60.c
new file mode 100644
index 0000000..7e88fc6
--- /dev/null
+++ b/arch/ppc/boot/simple/misc-mv64x60.c
@@ -0,0 +1,61 @@
+/*
+ * arch/ppc/boot/simple/misc-mv64x60.c
+ *
+ * Relocate bridge's register base and call board specific routine.
+ *
+ * Author: Mark A. Greer <source@mvista.com>
+ *
+ * 2005 (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/config.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/mv64x60_defs.h>
+
+extern struct bi_record *decompress_kernel(unsigned long load_addr,
+	int num_words, unsigned long cksum);
+
+void
+mv64x60_move_base(void __iomem *old_base, void __iomem *new_base)
+{
+	u32	bits, mask, b;
+
+	if (old_base != new_base) {
+#ifdef CONFIG_GT64260
+		bits = 12;
+		mask = 0x07000000;
+#else /* Must be mv64[34]60 */
+		bits = 16;
+		mask = 0x03000000;
+#endif
+		b = in_le32(old_base + MV64x60_INTERNAL_SPACE_DECODE);
+		b &= mask;
+		b |= ((u32)new_base >> (32 - bits));
+		out_le32(old_base + MV64x60_INTERNAL_SPACE_DECODE, b);
+
+		__asm__ __volatile__("sync");
+
+		/* Wait for change to happen (in accordance with the manual) */
+		while (in_le32(new_base + MV64x60_INTERNAL_SPACE_DECODE) != b);
+	}
+}
+
+void __attribute__ ((weak))
+mv64x60_board_init(void __iomem *old_base, void __iomem *new_base)
+{
+}
+
+void *
+load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
+		void *ign1, void *ign2)
+{
+	mv64x60_move_base((void __iomem *)CONFIG_MV64X60_BASE,
+		(void __iomem *)CONFIG_MV64X60_NEW_BASE);
+	mv64x60_board_init((void __iomem *)CONFIG_MV64X60_BASE,
+		(void __iomem *)CONFIG_MV64X60_NEW_BASE);
+	return decompress_kernel(load_addr, num_words, cksum);
+}
diff --git a/arch/ppc/boot/simple/misc-prep.c b/arch/ppc/boot/simple/misc-prep.c
new file mode 100644
index 0000000..75380ac
--- /dev/null
+++ b/arch/ppc/boot/simple/misc-prep.c
@@ -0,0 +1,212 @@
+/*
+ * arch/ppc/boot/simple/misc-prep.c
+ *
+ * Maintainer: Tom Rini <trini@kernel.crashing.org>
+ *
+ * In the past: Gary Thomas, Cort Dougan <cort@cs.nmt.edu>
+ */
+
+#include <linux/config.h>
+#include <linux/pci_ids.h>
+#include <linux/types.h>
+#include <asm/residual.h>
+#include <asm/string.h>
+#include <asm/byteorder.h>
+#include "mpc10x.h"
+#include "of1275.h"
+#include "nonstdio.h"
+
+extern int keyb_present;	/* keyboard controller is present by default */
+RESIDUAL hold_resid_buf;
+RESIDUAL *hold_residual = &hold_resid_buf;
+static void *OFW_interface;	/* Pointer to OF, if available. */
+
+#ifdef CONFIG_VGA_CONSOLE
+char *vidmem = (char *)0xC00B8000;
+int lines = 25, cols = 80;
+int orig_x, orig_y = 24;
+#endif /* CONFIG_VGA_CONSOLE */
+
+extern int CRT_tstc(void);
+extern int vga_init(unsigned char *ISA_mem);
+extern void gunzip(void *, int, unsigned char *, int *);
+extern unsigned long serial_init(int chan, void *ignored);
+extern void serial_fixups(void);
+extern struct bi_record *decompress_kernel(unsigned long load_addr,
+		int num_words, unsigned long cksum);
+extern void disable_6xx_mmu(void);
+extern unsigned long mpc10x_get_mem_size(void);
+
+static void
+writel(unsigned int val, unsigned int address)
+{
+	/* Ensure I/O operations complete */
+	__asm__ volatile("eieio");
+	*(unsigned int *)address = cpu_to_le32(val);
+}
+
+#define PCI_CFG_ADDR(dev,off)	((0x80<<24) | (dev<<8) | (off&0xfc))
+#define PCI_CFG_DATA(off)	(MPC10X_MAPA_CNFG_DATA+(off&3))
+
+static void
+pci_read_config_32(unsigned char devfn,
+		unsigned char offset,
+		unsigned int *val)
+{
+	/* Ensure I/O operations complete */
+	__asm__ volatile("eieio");
+	*(unsigned int *)PCI_CFG_ADDR(devfn,offset) =
+		cpu_to_le32(MPC10X_MAPA_CNFG_ADDR);
+	/* Ensure I/O operations complete */
+	__asm__ volatile("eieio");
+	*val = le32_to_cpu(*(unsigned int *)PCI_CFG_DATA(offset));
+	return;
+}
+
+#ifdef CONFIG_VGA_CONSOLE
+void
+scroll(void)
+{
+	int i;
+
+	memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 );
+	for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 )
+		vidmem[i] = ' ';
+}
+#endif /* CONFIG_VGA_CONSOLE */
+
+unsigned long
+load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
+		  RESIDUAL *residual, void *OFW)
+{
+	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) {
+		OFW_interface = OFW;
+		ofinit(OFW_interface);
+	}
+
+	board_isa_init();
+#if defined(CONFIG_VGA_CONSOLE)
+	vga_init((unsigned char *)0xC0000000);
+#endif /* CONFIG_VGA_CONSOLE */
+
+	if (residual) {
+		/* Is this Motorola PPCBug? */
+		if ((1 & residual->VitalProductData.FirmwareSupports) &&
+		    (1 == residual->VitalProductData.FirmwareSupplier)) {
+			unsigned char base_mod;
+			unsigned char board_type = inb(0x801) & 0xF0;
+
+			/*
+			 * Reset the onboard 21x4x Ethernet
+			 * Motorola Ethernet is at IDSEL 14 (devfn 0x70)
+			 */
+			pci_read_config_32(0x70, 0x00, &pci_viddid);
+			pci_did = (pci_viddid & 0xffff0000) >> 16;
+			/* Be sure we've really found a 21x4x chip */
+			if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_DEC) &&
+				((pci_did == PCI_DEVICE_ID_DEC_TULIP_FAST) ||
+				(pci_did == PCI_DEVICE_ID_DEC_TULIP) ||
+				(pci_did == PCI_DEVICE_ID_DEC_TULIP_PLUS) ||
+				(pci_did == PCI_DEVICE_ID_DEC_21142))) {
+				pci_read_config_32(0x70,
+						0x10,
+						&tulip_pci_base);
+				/* Get the physical base address */
+				tulip_base =
+					(tulip_pci_base & ~0x03UL) + 0x80000000;
+				/* Strobe the 21x4x reset bit in CSR0 */
+				writel(0x1, tulip_base);
+			}
+
+			/* If this is genesis 2 board then check for no
+			 * keyboard controller and more than one processor.
+			 */
+			if (board_type == 0xe0) {
+				base_mod = inb(0x803);
+				/* if a MVME2300/2400 or a Sitka then no keyboard */
+				if((base_mod == 0xFA) || (base_mod == 0xF9) ||
+				   (base_mod == 0xE1)) {
+					keyb_present = 0;	/* no keyboard */
+				}
+			}
+			/* If this is a multiprocessor system then
+			 * park the other processor so that the
+			 * kernel knows where to find them.
+			 */
+			if (residual->MaxNumCpus > 1)
+				start_multi = 1;
+		}
+		memcpy(hold_residual,residual,sizeof(RESIDUAL));
+        }
+
+	/* Call decompress_kernel */
+	decompress_kernel(load_addr, num_words, cksum);
+
+	if (start_multi) {
+		residual->VitalProductData.SmpIar = (unsigned long)0xc0;
+		residual->Cpus[1].CpuState = CPU_GOOD;
+		hold_residual->VitalProductData.Reserved5 = 0xdeadbeef;
+	}
+
+	/* Now go and clear out the BATs and ensure that our MSR is
+	 * correct .*/
+	disable_6xx_mmu();
+
+	/* Make r3 be a pointer to the residual data. */
+	return (unsigned long)hold_residual;
+}
+
+unsigned long
+get_mem_size(void)
+{
+	unsigned int pci_viddid, pci_did;
+
+	/* First, figure out what kind of host bridge we are on.  If it's
+	 * an MPC10x, we can ask it directly how much memory it has.
+	 * Otherwise, see if the residual data has anything.  This isn't
+	 * the best way, but it can be the only way.  If there's nothing,
+	 * assume 32MB. -- Tom.
+	 */
+	/* See what our host bridge is. */
+	pci_read_config_32(0x00, 0x00, &pci_viddid);
+	pci_did = (pci_viddid & 0xffff0000) >> 16;
+	/* See if we are on an MPC10x. */
+	if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)
+			&& ((pci_did == PCI_DEVICE_ID_MOTOROLA_MPC105)
+				|| (pci_did == PCI_DEVICE_ID_MOTOROLA_MPC106)
+				|| (pci_did == PCI_DEVICE_ID_MOTOROLA_MPC107)))
+		return mpc10x_get_mem_size();
+	/* If it's not, see if we have anything in the residual data. */
+	else if (hold_residual && hold_residual->TotalMemory)
+		return hold_residual->TotalMemory;
+	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;
+
+			return mem_info[1];
+		}
+	}
+
+	/* Fall back to hard-coding 32MB. */
+	return 32*1024*1024;
+}
diff --git a/arch/ppc/boot/simple/misc-radstone_ppc7d.c b/arch/ppc/boot/simple/misc-radstone_ppc7d.c
new file mode 100644
index 0000000..569e0d4
--- /dev/null
+++ b/arch/ppc/boot/simple/misc-radstone_ppc7d.c
@@ -0,0 +1,26 @@
+/*
+ * arch/ppc/boot/simple/misc-radstone_ppc7d.c
+ *
+ * Misc data for Radstone PPC7D board.
+ *
+ * Author: James Chapman <jchapman@katalix.com>
+ */
+
+#include <linux/types.h>
+#include <platforms/radstone_ppc7d.h>
+
+#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
+extern u32 mv64x60_console_baud;
+extern u32 mv64x60_mpsc_clk_src;
+extern u32 mv64x60_mpsc_clk_freq;
+#endif
+
+void
+mv64x60_board_init(void __iomem *old_base, void __iomem *new_base)
+{
+#if defined(CONFIG_SERIAL_MPSC_CONSOLE)
+	mv64x60_console_baud = PPC7D_DEFAULT_BAUD;
+	mv64x60_mpsc_clk_src = PPC7D_MPSC_CLK_SRC;
+	mv64x60_mpsc_clk_freq = PPC7D_MPSC_CLK_FREQ;
+#endif
+}
diff --git a/arch/ppc/boot/simple/misc-spruce.c b/arch/ppc/boot/simple/misc-spruce.c
new file mode 100644
index 0000000..d012c39
--- /dev/null
+++ b/arch/ppc/boot/simple/misc-spruce.c
@@ -0,0 +1,274 @@
+/*
+ * arch/ppc/boot/spruce/misc.c
+ *
+ * Misc. bootloader code for IBM Spruce reference platform
+ *
+ * Authors: Johnnie Peters <jpeters@mvista.com>
+ *	    Matt Porter <mporter@mvista.com>
+ *
+ * Derived from arch/ppc/boot/prep/misc.c
+ *
+ * 2000-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>
+#include <linux/config.h>
+#include <linux/pci.h>
+
+#include <asm/bootinfo.h>
+
+extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
+				       unsigned long cksum);
+
+/* Define some important locations of the Spruce. */
+#define SPRUCE_PCI_CONFIG_ADDR	0xfec00000
+#define SPRUCE_PCI_CONFIG_DATA	0xfec00004
+
+/* PCI configuration space access routines. */
+unsigned int *pci_config_address = (unsigned int *)SPRUCE_PCI_CONFIG_ADDR;
+unsigned char *pci_config_data   = (unsigned char *)SPRUCE_PCI_CONFIG_DATA;
+
+void cpc700_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
+			     unsigned char offset, unsigned char *val)
+{
+	out_le32(pci_config_address,
+		 (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000));
+
+	*val= (in_le32((unsigned *)pci_config_data) >> (8 * (offset & 3))) & 0xff;
+}
+
+void cpc700_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
+			     unsigned char offset, unsigned char val)
+{
+	out_le32(pci_config_address,
+		 (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000));
+
+	out_8(pci_config_data + (offset&3), val);
+}
+
+void cpc700_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
+			     unsigned char offset, unsigned short *val)
+{
+	out_le32(pci_config_address,
+		 (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000));
+
+	*val= in_le16((unsigned short *)(pci_config_data + (offset&3)));
+}
+
+void cpc700_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
+			     unsigned char offset, unsigned short val)
+{
+	out_le32(pci_config_address,
+		 (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000));
+
+	out_le16((unsigned short *)(pci_config_data + (offset&3)), val);
+}
+
+void cpc700_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
+			     unsigned char offset, unsigned int *val)
+{
+	out_le32(pci_config_address,
+		 (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000));
+
+	*val= in_le32((unsigned *)pci_config_data);
+}
+
+void cpc700_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
+			     unsigned char offset, unsigned int val)
+{
+	out_le32(pci_config_address,
+		 (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000));
+
+	out_le32((unsigned *)pci_config_data, val);
+}
+
+#define PCNET32_WIO_RDP		0x10
+#define PCNET32_WIO_RAP		0x12
+#define PCNET32_WIO_RESET	0x14
+
+#define PCNET32_DWIO_RDP	0x10
+#define PCNET32_DWIO_RAP	0x14
+#define PCNET32_DWIO_RESET	0x18
+
+/* Processor interface config register access */
+#define PIFCFGADDR 0xff500000
+#define PIFCFGDATA 0xff500004
+
+#define PLBMIFOPT 0x18 /* PLB Master Interface Options */
+
+#define MEM_MBEN	0x24
+#define MEM_TYPE	0x28
+#define MEM_B1SA	0x3c
+#define MEM_B1EA	0x5c
+#define MEM_B2SA	0x40
+#define MEM_B2EA	0x60
+
+unsigned long
+get_mem_size(void)
+{
+	int loop;
+	unsigned long mem_size = 0;
+	unsigned long mem_mben;
+	unsigned long mem_type;
+	unsigned long mem_start;
+	unsigned long mem_end;
+	volatile int *mem_addr = (int *)0xff500008;
+	volatile int *mem_data = (int *)0xff50000c;
+
+	/* Get the size of memory from the memory controller. */
+	*mem_addr = MEM_MBEN;
+	asm("sync");
+	mem_mben = *mem_data;
+	asm("sync");
+	for(loop = 0; loop < 1000; loop++);
+
+	*mem_addr = MEM_TYPE;
+	asm("sync");
+	mem_type = *mem_data;
+	asm("sync");
+	for(loop = 0; loop < 1000; loop++);
+
+	*mem_addr = MEM_TYPE;
+	/* Confirm bank 1 has DRAM memory */
+	if ((mem_mben & 0x40000000) &&
+				((mem_type & 0x30000000) == 0x10000000)) {
+		*mem_addr = MEM_B1SA;
+		asm("sync");
+		mem_start = *mem_data;
+		asm("sync");
+		for(loop = 0; loop < 1000; loop++);
+
+		*mem_addr = MEM_B1EA;
+		asm("sync");
+		mem_end = *mem_data;
+		asm("sync");
+		for(loop = 0; loop < 1000; loop++);
+
+		mem_size = mem_end - mem_start + 0x100000;
+	}
+
+	/* Confirm bank 2 has DRAM memory */
+	if ((mem_mben & 0x20000000) &&
+				((mem_type & 0xc000000) == 0x4000000)) {
+		*mem_addr = MEM_B2SA;
+		asm("sync");
+		mem_start = *mem_data;
+		asm("sync");
+		for(loop = 0; loop < 1000; loop++);
+
+		*mem_addr = MEM_B2EA;
+		asm("sync");
+		mem_end = *mem_data;
+		asm("sync");
+		for(loop = 0; loop < 1000; loop++);
+
+		mem_size += mem_end - mem_start + 0x100000;
+	}
+	return mem_size;
+}
+
+unsigned long
+load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
+		void *ign1, void *ign2)
+{
+	int csr0;
+	int csr_id;
+	int pci_devfn;
+	int found_multi = 0;
+	unsigned short vendor;
+	unsigned short device;
+	unsigned short command;
+	unsigned char header_type;
+	unsigned int bar0;
+	volatile int *pif_addr = (int *)0xff500000;
+	volatile int *pif_data = (int *)0xff500004;
+
+	/*
+	 * Gah, these firmware guys need to learn that hardware
+	 * byte swapping is evil! Disable all hardware byte
+	 * swapping so it doesn't hurt anyone.
+	 */
+	*pif_addr = PLBMIFOPT;
+	asm("sync");
+	*pif_data = 0x00000000;
+	asm("sync");
+
+	/* Search out and turn off the PcNet ethernet boot device. */
+	for (pci_devfn = 1; pci_devfn < 0xff; pci_devfn++) {
+		if (PCI_FUNC(pci_devfn) && !found_multi)
+			continue;
+
+		cpc700_pcibios_read_config_byte(0, pci_devfn,
+				PCI_HEADER_TYPE, &header_type);
+
+		if (!PCI_FUNC(pci_devfn))
+			found_multi = header_type & 0x80;
+
+		cpc700_pcibios_read_config_word(0, pci_devfn, PCI_VENDOR_ID,
+				&vendor);
+
+		if (vendor != 0xffff) {
+			cpc700_pcibios_read_config_word(0, pci_devfn,
+						PCI_DEVICE_ID, &device);
+
+			/* If this PCI device is the Lance PCNet board then turn it off */
+			if ((vendor == PCI_VENDOR_ID_AMD) &&
+					(device == PCI_DEVICE_ID_AMD_LANCE)) {
+
+				/* Turn on I/O Space on the board. */
+				cpc700_pcibios_read_config_word(0, pci_devfn,
+						PCI_COMMAND, &command);
+				command |= 0x1;
+				cpc700_pcibios_write_config_word(0, pci_devfn,
+						PCI_COMMAND, command);
+
+				/* Get the I/O space address */
+				cpc700_pcibios_read_config_dword(0, pci_devfn,
+						PCI_BASE_ADDRESS_0, &bar0);
+				bar0 &= 0xfffffffe;
+
+				/* Reset the PCNet Board */
+				inl (bar0+PCNET32_DWIO_RESET);
+				inw (bar0+PCNET32_WIO_RESET);
+
+				/* First do a work oriented read of csr0.  If the value is
+				 * 4 then this is the correct mode to access the board.
+				 * If not try a double word ortiented read.
+				 */
+				outw(0, bar0 + PCNET32_WIO_RAP);
+				csr0 = inw(bar0 + PCNET32_WIO_RDP);
+
+				if (csr0 == 4) {
+					/* Check the Chip id register */
+					outw(88, bar0 + PCNET32_WIO_RAP);
+					csr_id = inw(bar0 + PCNET32_WIO_RDP);
+
+					if (csr_id) {
+						/* This is the valid mode - set the stop bit */
+						outw(0, bar0 + PCNET32_WIO_RAP);
+						outw(csr0, bar0 + PCNET32_WIO_RDP);
+					}
+				} else {
+					outl(0, bar0 + PCNET32_DWIO_RAP);
+					csr0 = inl(bar0 + PCNET32_DWIO_RDP);
+					if (csr0 == 4) {
+						/* Check the Chip id register */
+						outl(88, bar0 + PCNET32_WIO_RAP);
+						csr_id = inl(bar0 + PCNET32_WIO_RDP);
+
+						if (csr_id) {
+							/* This is the valid mode  - set the stop bit*/
+							outl(0, bar0 + PCNET32_WIO_RAP);
+							outl(csr0, bar0 + PCNET32_WIO_RDP);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return decompress_kernel(load_addr, num_words, cksum);
+}
diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c
new file mode 100644
index 0000000..ab0f990
--- /dev/null
+++ b/arch/ppc/boot/simple/misc.c
@@ -0,0 +1,284 @@
+/*
+ * arch/ppc/simple/misc.c
+ *
+ * Misc. bootloader code for many machines.  This assumes you have are using
+ * a 6xx/7xx/74xx CPU in your machine.  This assumes the chunk of memory
+ * below 8MB is free.  Finally, it assumes you have a NS16550-style uart for
+ * your serial console.  If a machine meets these requirements, it can quite
+ * likely use this code during boot.
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ * Derived from arch/ppc/boot/prep/misc.c
+ *
+ * 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>
+#include <linux/config.h>
+#include <linux/string.h>
+
+#include <asm/page.h>
+#include <asm/mmu.h>
+#include <asm/bootinfo.h>
+#ifdef CONFIG_44x
+#include <asm/ibm4xx.h>
+#endif
+#include <asm/reg.h>
+
+#include "nonstdio.h"
+
+/* Default cmdline */
+#ifdef CONFIG_CMDLINE
+#define CMDLINE CONFIG_CMDLINE
+#else
+#define CMDLINE ""
+#endif
+
+/* Keyboard (and VGA console)? */
+#ifdef CONFIG_VGA_CONSOLE
+#define HAS_KEYB 1
+#else
+#define HAS_KEYB 0
+#endif
+
+/* Will / Can the user give input?
+ * Val Henson has requested that Gemini doesn't wait for the
+ * user to edit the cmdline or not.
+ */
+#if (defined(CONFIG_SERIAL_8250_CONSOLE) \
+	|| defined(CONFIG_VGA_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPC52xx_CONSOLE) \
+	|| defined(CONFIG_SERIAL_MPSC_CONSOLE)) \
+	&& !defined(CONFIG_GEMINI)
+#define INTERACTIVE_CONSOLE	1
+#endif
+
+char *avail_ram;
+char *end_avail;
+char *zimage_start;
+char cmd_preset[] = CMDLINE;
+char cmd_buf[256];
+char *cmd_line = cmd_buf;
+int keyb_present = HAS_KEYB;
+int zimage_size;
+
+unsigned long com_port;
+unsigned long initrd_size = 0;
+
+/* The linker tells us various locations in the image */
+extern char __image_begin, __image_end;
+extern char __ramdisk_begin, __ramdisk_end;
+extern char _end[];
+/* Original location */
+extern unsigned long start;
+
+extern int CRT_tstc(void);
+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 get_mem_size to be hooked into.  This is the default. */
+unsigned long __attribute__ ((weak))
+get_mem_size(void)
+{
+	return 0;
+}
+
+struct bi_record *
+decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
+{
+#ifdef INTERACTIVE_CONSOLE
+	int timer = 0;
+	char ch;
+#endif
+	char *cp;
+	struct bi_record *rec;
+	unsigned long initrd_loc = 0, TotalMemory = 0;
+
+#if defined(CONFIG_SERIAL_8250_CONSOLE) || defined(CONFIG_SERIAL_MPSC_CONSOLE)
+	com_port = serial_init(0, NULL);
+#endif
+
+#if defined(CONFIG_44x) && defined(PPC44x_EMAC0_MR0)
+	/* Reset MAL */
+	mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR);
+	/* Wait for reset */
+	while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {};
+	/* Reset EMAC */
+	*(volatile unsigned long *)PPC44x_EMAC0_MR0 = 0x20000000;
+	__asm__ __volatile__("eieio");
+#endif
+
+	/*
+	 * Call get_mem_size(), which is memory controller dependent,
+	 * and we must have the correct file linked in here.
+	 */
+	TotalMemory = get_mem_size();
+
+	/* assume the chunk below 8M is free */
+	end_avail = (char *)0x00800000;
+
+	/*
+	 * Reveal where we were loaded at and where we
+	 * were relocated to.
+	 */
+	puts("loaded at:     "); puthex(load_addr);
+	puts(" "); puthex((unsigned long)(load_addr + (4*num_words)));
+	puts("\n");
+	if ( (unsigned long)load_addr != (unsigned long)&start )
+	{
+		puts("relocated to:  "); puthex((unsigned long)&start);
+		puts(" ");
+		puthex((unsigned long)((unsigned long)&start + (4*num_words)));
+		puts("\n");
+	}
+
+	/*
+	 * We link ourself to 0x00800000.  When we run, we relocate
+	 * ourselves there.  So we just need __image_begin for the
+	 * start. -- Tom
+	 */
+	zimage_start = (char *)(unsigned long)(&__image_begin);
+	zimage_size = (unsigned long)(&__image_end) -
+			(unsigned long)(&__image_begin);
+
+	initrd_size = (unsigned long)(&__ramdisk_end) -
+		(unsigned long)(&__ramdisk_begin);
+
+	/*
+	 * The zImage and initrd will be between start and _end, so they've
+	 * already been moved once.  We're good to go now. -- Tom
+	 */
+	avail_ram = (char *)PAGE_ALIGN((unsigned long)_end);
+	puts("zimage at:     "); puthex((unsigned long)zimage_start);
+	puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
+	puts("\n");
+
+	if ( initrd_size ) {
+		puts("initrd at:     ");
+		puthex((unsigned long)(&__ramdisk_begin));
+		puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
+	}
+
+	avail_ram = (char *)0x00400000;
+	end_avail = (char *)0x00800000;
+	puts("avail ram:     "); puthex((unsigned long)avail_ram); puts(" ");
+	puthex((unsigned long)end_avail); puts("\n");
+
+	if (keyb_present)
+		CRT_tstc();  /* Forces keyboard to be initialized */
+#ifdef CONFIG_GEMINI
+	/*
+	 * If cmd_line is empty and cmd_preset is not, copy cmd_preset
+	 * to cmd_line.  This way we can override cmd_preset with the
+	 * command line from Smon.
+	 */
+
+	if ( (cmd_line[0] == '\0') && (cmd_preset[0] != '\0'))
+		memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
+#endif
+
+	/* Display standard Linux/PPC boot prompt for kernel args */
+	puts("\nLinux/PPC load: ");
+	cp = cmd_line;
+	memcpy (cmd_line, cmd_preset, sizeof(cmd_preset));
+	while ( *cp ) putc(*cp++);
+
+#ifdef INTERACTIVE_CONSOLE
+	/*
+	 * If they have a console, allow them to edit the command line.
+	 * Otherwise, don't bother wasting the five seconds.
+	 */
+	while (timer++ < 5*1000) {
+		if (tstc()) {
+			while ((ch = getc()) != '\n' && ch != '\r') {
+				/* Test for backspace/delete */
+				if (ch == '\b' || ch == '\177') {
+					if (cp != cmd_line) {
+						cp--;
+						puts("\b \b");
+					}
+				/* Test for ^x/^u (and wipe the line) */
+				} else if (ch == '\030' || ch == '\025') {
+					while (cp != cmd_line) {
+						cp--;
+						puts("\b \b");
+					}
+				} else {
+					*cp++ = ch;
+					putc(ch);
+				}
+			}
+			break;  /* Exit 'timer' loop */
+		}
+		udelay(1000);  /* 1 msec */
+	}
+	*cp = 0;
+#endif
+	puts("\n");
+
+	puts("Uncompressing Linux...");
+	gunzip(0x0, 0x400000, zimage_start, &zimage_size);
+	puts("done.\n");
+
+	/* get the bi_rec address */
+	rec = bootinfo_addr(zimage_size);
+
+	/* We need to make sure that the initrd and bi_recs do not
+	 * overlap. */
+	if ( initrd_size ) {
+		unsigned long rec_loc = (unsigned long) rec;
+		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");
+		}
+	}
+
+	bootinfo_init(rec);
+	if ( TotalMemory )
+		bootinfo_append(BI_MEMSIZE, sizeof(int), (void*)&TotalMemory);
+
+	bootinfo_append(BI_CMD_LINE, strlen(cmd_line)+1, (void*)cmd_line);
+
+	/* add a bi_rec for the initrd if it exists */
+	if (initrd_size) {
+		unsigned long initrd[2];
+
+		initrd[0] = initrd_loc;
+		initrd[1] = initrd_size;
+
+		bootinfo_append(BI_INITRD, sizeof(initrd), &initrd);
+	}
+	puts("Now booting the kernel\n");
+	serial_close(com_port);
+
+	return rec;
+}
+
+void __attribute__ ((weak))
+board_isa_init(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 *ign1, void *ign2)
+{
+		board_isa_init();
+		return decompress_kernel(load_addr, num_words, cksum);
+}
diff --git a/arch/ppc/boot/simple/mpc10x_memory.c b/arch/ppc/boot/simple/mpc10x_memory.c
new file mode 100644
index 0000000..977daed
--- /dev/null
+++ b/arch/ppc/boot/simple/mpc10x_memory.c
@@ -0,0 +1,111 @@
+/*
+ * arch/ppc/boot/common/mpc10x_common.c
+ *
+ * A routine to find out how much memory the machine has.
+ *
+ * Based on:
+ * arch/ppc/kernel/mpc10x_common.c
+ *
+ * Author: Mark A. Greer
+ *         mgreer@mvista.com
+ *
+ * 2001-2002 (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/pci.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include "mpc10x.h"
+
+/*
+ * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs ***
+ */
+
+/*
+ * PCI config space macros, similar to indirect_xxx and early_xxx macros.
+ * We assume bus 0.
+ */
+#define MPC10X_CFG_read(val, addr, type, op)	*val = op((type)(addr))
+#define MPC10X_CFG_write(val, addr, type, op)	op((type *)(addr), (val))
+
+#define MPC10X_PCI_OP(rw, size, type, op, mask)			 	\
+static void								\
+mpc10x_##rw##_config_##size(unsigned int *cfg_addr, 			\
+		unsigned int *cfg_data, int devfn, int offset,		\
+		type val)						\
+{									\
+	out_be32(cfg_addr, 						\
+		 ((offset & 0xfc) << 24) | (devfn << 16)		\
+		 | (0 << 8) | 0x80);					\
+	MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op);	\
+	return;    					 		\
+}
+
+MPC10X_PCI_OP(read, byte,  u8 *, in_8, 3)
+MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0)
+
+/*
+ * Read the memory controller registers to determine the amount of memory in
+ * the system.  This assumes that the firmware has correctly set up the memory
+ * controller registers.  On CONFIG_PPC_PREP, we know we are being called
+ * under a PReP memory map. On all other machines, we assume we are under
+ * a CHRP memory map.  Further, on CONFIG_PPC_MULTIPLATFORM we must rename
+ * this function.
+ */
+#ifdef CONFIG_PPC_MULTIPLATFORM
+#define get_mem_size mpc10x_get_mem_size
+#endif
+unsigned long
+get_mem_size(void)
+{
+	unsigned int *config_addr, *config_data, val;
+	unsigned long start, end, total, offset;
+	int i;
+	unsigned char bank_enables;
+
+#ifdef CONFIG_PPC_PREP
+	config_addr = (unsigned int *)MPC10X_MAPA_CNFG_ADDR;
+	config_data = (unsigned int *)MPC10X_MAPA_CNFG_DATA;
+#else
+	config_addr = (unsigned int *)MPC10X_MAPB_CNFG_ADDR;
+	config_data = (unsigned int *)MPC10X_MAPB_CNFG_DATA;
+#endif
+
+	mpc10x_read_config_byte(config_addr, config_data, PCI_DEVFN(0,0),
+			MPC10X_MCTLR_MEM_BANK_ENABLES, &bank_enables);
+
+	total = 0;
+
+	for (i = 0; i < 8; i++) {
+		if (bank_enables & (1 << i)) {
+			offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0);
+			mpc10x_read_config_dword(config_addr, config_data,
+					PCI_DEVFN(0,0), offset, &val);
+			start = (val >> ((i & 3) << 3)) & 0xff;
+
+			offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0);
+			mpc10x_read_config_dword(config_addr, config_data,
+					PCI_DEVFN(0,0), offset, &val);
+			val = (val >> ((i & 3) << 3)) & 0x03;
+			start = (val << 28) | (start << 20);
+
+			offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0);
+			mpc10x_read_config_dword(config_addr, config_data,
+					PCI_DEVFN(0,0), offset, &val);
+			end = (val >> ((i & 3) << 3)) & 0xff;
+
+			offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0);
+			mpc10x_read_config_dword(config_addr, config_data,
+					PCI_DEVFN(0,0), offset, &val);
+			val = (val >> ((i & 3) << 3)) & 0x03;
+			end = (val << 28) | (end << 20) | 0xfffff;
+
+			total += (end - start + 1);
+		}
+	}
+
+	return total;
+}
diff --git a/arch/ppc/boot/simple/mpc52xx_tty.c b/arch/ppc/boot/simple/mpc52xx_tty.c
new file mode 100644
index 0000000..3acc6b7
--- /dev/null
+++ b/arch/ppc/boot/simple/mpc52xx_tty.c
@@ -0,0 +1,140 @@
+/*
+ * arch/ppc/boot/simple/mpc52xx_tty.c
+ *
+ * Minimal serial functions needed to send messages out a MPC52xx
+ * Programmable Serial Controller (PSC).
+ *
+ * Author: Dale Farnsworth <dfarnsworth@mvista.com>
+ *
+ * 2003-2004 (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/config.h>
+#include <linux/types.h>
+#include <asm/uaccess.h>
+#include <asm/mpc52xx.h>
+#include <asm/mpc52xx_psc.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+#include <asm/time.h>
+
+
+#ifdef MPC52xx_PF_CONSOLE_PORT
+#define MPC52xx_CONSOLE MPC52xx_PSCx_OFFSET(MPC52xx_PF_CONSOLE_PORT)
+#define MPC52xx_PSC_CONFIG_SHIFT ((MPC52xx_PF_CONSOLE_PORT-1)<<2)
+#else
+#error "MPC52xx_PF_CONSOLE_PORT not defined"
+#endif
+
+static struct mpc52xx_psc __iomem *psc =
+	(struct mpc52xx_psc __iomem *) MPC52xx_PA(MPC52xx_CONSOLE);
+
+/* The decrementer counts at the system bus clock frequency
+ * divided by four.  The most accurate time base is connected to the
+ * rtc.  We read the decrementer change during one rtc tick
+ * and multiply by 4 to get the system bus clock frequency. Since a
+ * rtc tick is one seconds, and that's pretty long, we change the rtc
+ * dividers temporarly to set them 64x faster ;)
+ */
+static int
+mpc52xx_ipbfreq(void)
+{
+	struct mpc52xx_rtc __iomem *rtc =
+		(struct mpc52xx_rtc __iomem *) MPC52xx_PA(MPC52xx_RTC_OFFSET);
+	struct mpc52xx_cdm __iomem *cdm =
+		(struct mpc52xx_cdm __iomem *) MPC52xx_PA(MPC52xx_CDM_OFFSET);
+	int current_time, previous_time;
+	int tbl_start, tbl_end;
+	int xlbfreq, ipbfreq;
+
+	out_be32(&rtc->dividers, 0x8f1f0000);	/* Set RTC 64x faster */
+	previous_time = in_be32(&rtc->time);
+	while ((current_time = in_be32(&rtc->time)) == previous_time) ;
+	tbl_start = get_tbl();
+	previous_time = current_time;
+	while ((current_time = in_be32(&rtc->time)) == previous_time) ;
+	tbl_end = get_tbl();
+	out_be32(&rtc->dividers, 0xffff0000);   /* Restore RTC */
+
+	xlbfreq = (tbl_end - tbl_start) << 8;
+	ipbfreq = (in_8(&cdm->ipb_clk_sel) & 1) ? xlbfreq / 2 : xlbfreq;
+
+	return ipbfreq;
+}
+
+unsigned long
+serial_init(int ignored, void *ignored2)
+{
+	struct mpc52xx_gpio __iomem *gpio =
+		(struct mpc52xx_gpio __iomem *) MPC52xx_PA(MPC52xx_GPIO_OFFSET);
+	int divisor;
+	int mode1;
+	int mode2;
+	u32 val32;
+
+	static int been_here = 0;
+
+	if (been_here)
+		return 0;
+
+	been_here = 1;
+
+	val32 = in_be32(&gpio->port_config);
+	val32 &= ~(0x7 << MPC52xx_PSC_CONFIG_SHIFT);
+	val32 |= MPC52xx_GPIO_PSC_CONFIG_UART_WITHOUT_CD
+				<< MPC52xx_PSC_CONFIG_SHIFT;
+	out_be32(&gpio->port_config, val32);
+
+	out_8(&psc->command, MPC52xx_PSC_RST_TX
+			| MPC52xx_PSC_RX_DISABLE | MPC52xx_PSC_TX_ENABLE);
+	out_8(&psc->command, MPC52xx_PSC_RST_RX);
+
+	out_be32(&psc->sicr, 0x0);
+	out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00);
+	out_be16(&psc->tfalarm, 0xf8);
+
+	out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1
+			| MPC52xx_PSC_RX_ENABLE
+			| MPC52xx_PSC_TX_ENABLE);
+
+	divisor = ((mpc52xx_ipbfreq()
+			/ (CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD * 16)) + 1) >> 1;
+
+	mode1 = MPC52xx_PSC_MODE_8_BITS | MPC52xx_PSC_MODE_PARNONE
+			| MPC52xx_PSC_MODE_ERR;
+	mode2 = MPC52xx_PSC_MODE_ONE_STOP;
+
+	out_8(&psc->ctur, divisor>>8);
+	out_8(&psc->ctlr, divisor);
+	out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
+	out_8(&psc->mode, mode1);
+	out_8(&psc->mode, mode2);
+
+	return 0;	/* ignored */
+}
+
+void
+serial_putc(void *ignored, const char c)
+{
+	serial_init(0, NULL);
+
+	while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP)) ;
+	out_8(&psc->mpc52xx_psc_buffer_8, c);
+	while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP)) ;
+}
+
+char
+serial_getc(void *ignored)
+{
+	while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY)) ;
+
+	return in_8(&psc->mpc52xx_psc_buffer_8);
+}
+
+int
+serial_tstc(void *ignored)
+{
+	return (in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY) != 0;
+}
diff --git a/arch/ppc/boot/simple/mv64x60_tty.c b/arch/ppc/boot/simple/mv64x60_tty.c
new file mode 100644
index 0000000..5b45eb4
--- /dev/null
+++ b/arch/ppc/boot/simple/mv64x60_tty.c
@@ -0,0 +1,360 @@
+/*
+ * arch/ppc/boot/simple/mv64x60_tty.c
+ *
+ * Bootloader version of the embedded MPSC/UART driver for the Marvell 64x60.
+ * Note: Due to a GT64260A erratum, DMA will be used for UART input (via SDMA).
+ *
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 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.
+ */
+
+/* This code assumes that the data cache has been disabled (L1, L2, L3). */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+#include <asm/serial.h>
+#include <asm/io.h>
+#include <asm/mv64x60_defs.h>
+#include <mpsc_defs.h>
+
+u32	mv64x60_console_baud = 9600;
+u32	mv64x60_mpsc_clk_src = 8; /* TCLK */
+u32	mv64x60_mpsc_clk_freq = 100000000;
+
+extern void udelay(long);
+static void stop_dma(int chan);
+
+static void __iomem *mv64x60_base = (void __iomem *)CONFIG_MV64X60_NEW_BASE;
+
+struct sdma_regs {
+	u32	sdc;
+	u32	sdcm;
+	u32	rx_desc;
+	u32	rx_buf_ptr;
+	u32	scrdp;
+	u32	tx_desc;
+	u32	sctdp;
+	u32	sftdp;
+};
+
+static struct sdma_regs	sdma_regs[2];
+
+#define	SDMA_REGS_INIT(s, reg_base) {			\
+	(s)->sdc	= (reg_base) + SDMA_SDC;	\
+	(s)->sdcm	= (reg_base) + SDMA_SDCM;	\
+	(s)->rx_desc	= (reg_base) + SDMA_RX_DESC;	\
+	(s)->rx_buf_ptr = (reg_base) + SDMA_RX_BUF_PTR;	\
+	(s)->scrdp	= (reg_base) + SDMA_SCRDP;	\
+	(s)->tx_desc	= (reg_base) + SDMA_TX_DESC;	\
+	(s)->sctdp	= (reg_base) + SDMA_SCTDP;	\
+	(s)->sftdp	= (reg_base) + SDMA_SFTDP;	\
+}
+
+static u32	mpsc_base[2] = { MV64x60_MPSC_0_OFFSET, MV64x60_MPSC_1_OFFSET };
+
+struct mv64x60_rx_desc {
+	u16	bufsize;
+	u16	bytecnt;
+	u32	cmd_stat;
+	u32	next_desc_ptr;
+	u32	buffer;
+};
+
+struct mv64x60_tx_desc {
+	u16	bytecnt;
+	u16	shadow;
+	u32	cmd_stat;
+	u32	next_desc_ptr;
+	u32	buffer;
+};
+
+#define	MAX_RESET_WAIT	10000
+#define	MAX_TX_WAIT	10000
+
+#define	RX_NUM_DESC	2
+#define	TX_NUM_DESC	2
+
+#define	RX_BUF_SIZE	32
+#define	TX_BUF_SIZE	32
+
+static struct mv64x60_rx_desc rd[2][RX_NUM_DESC] __attribute__ ((aligned(32)));
+static struct mv64x60_tx_desc td[2][TX_NUM_DESC] __attribute__ ((aligned(32)));
+
+static char rx_buf[2][RX_NUM_DESC * RX_BUF_SIZE] __attribute__ ((aligned(32)));
+static char tx_buf[2][TX_NUM_DESC * TX_BUF_SIZE] __attribute__ ((aligned(32)));
+
+static int cur_rd[2] = { 0, 0 };
+static int cur_td[2] = { 0, 0 };
+
+static char chan_initialized[2] = { 0, 0 };
+
+
+#define	RX_INIT_RDP(rdp) {			\
+	(rdp)->bufsize = 2;			\
+	(rdp)->bytecnt = 0;			\
+	(rdp)->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F |	\
+		SDMA_DESC_CMDSTAT_O;	\
+}
+
+#ifdef CONFIG_MV64360
+static u32 cpu2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = {
+		{ MV64x60_CPU2MEM_0_BASE, MV64x60_CPU2MEM_0_SIZE },
+		{ MV64x60_CPU2MEM_1_BASE, MV64x60_CPU2MEM_1_SIZE },
+		{ MV64x60_CPU2MEM_2_BASE, MV64x60_CPU2MEM_2_SIZE },
+		{ MV64x60_CPU2MEM_3_BASE, MV64x60_CPU2MEM_3_SIZE }
+};
+
+static u32 com2mem_tab[MV64x60_CPU2MEM_WINDOWS][2] = {
+		{ MV64360_MPSC2MEM_0_BASE, MV64360_MPSC2MEM_0_SIZE },
+		{ MV64360_MPSC2MEM_1_BASE, MV64360_MPSC2MEM_1_SIZE },
+		{ MV64360_MPSC2MEM_2_BASE, MV64360_MPSC2MEM_2_SIZE },
+		{ MV64360_MPSC2MEM_3_BASE, MV64360_MPSC2MEM_3_SIZE }
+};
+
+static u32 dram_selects[MV64x60_CPU2MEM_WINDOWS] = { 0xe, 0xd, 0xb, 0x7 };
+#endif
+
+unsigned long
+serial_init(int chan, void *ignored)
+{
+	u32		mpsc_routing_base, sdma_base, brg_bcr, cdv;
+	int		i;
+
+	chan = (chan == 1); /* default to chan 0 if anything but 1 */
+
+	if (chan_initialized[chan])
+		return chan;
+
+	chan_initialized[chan] = 1;
+
+	if (chan == 0) {
+		sdma_base = MV64x60_SDMA_0_OFFSET;
+		brg_bcr = MV64x60_BRG_0_OFFSET + BRG_BCR;
+		SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_0_OFFSET);
+	} else {
+		sdma_base = MV64x60_SDMA_1_OFFSET;
+		brg_bcr = MV64x60_BRG_1_OFFSET + BRG_BCR;
+		SDMA_REGS_INIT(&sdma_regs[0], MV64x60_SDMA_1_OFFSET);
+	}
+
+	mpsc_routing_base = MV64x60_MPSC_ROUTING_OFFSET;
+
+	stop_dma(chan);
+
+	/* Set up ring buffers */
+	for (i=0; i<RX_NUM_DESC; i++) {
+		RX_INIT_RDP(&rd[chan][i]);
+		rd[chan][i].buffer = (u32)&rx_buf[chan][i * RX_BUF_SIZE];
+		rd[chan][i].next_desc_ptr = (u32)&rd[chan][i+1];
+	}
+	rd[chan][RX_NUM_DESC - 1].next_desc_ptr = (u32)&rd[chan][0];
+
+	for (i=0; i<TX_NUM_DESC; i++) {
+		td[chan][i].bytecnt = 0;
+		td[chan][i].shadow = 0;
+		td[chan][i].buffer = (u32)&tx_buf[chan][i * TX_BUF_SIZE];
+		td[chan][i].cmd_stat = SDMA_DESC_CMDSTAT_F|SDMA_DESC_CMDSTAT_L;
+		td[chan][i].next_desc_ptr = (u32)&td[chan][i+1];
+	}
+	td[chan][TX_NUM_DESC - 1].next_desc_ptr = (u32)&td[chan][0];
+
+	/* Set MPSC Routing */
+	out_le32(mv64x60_base + mpsc_routing_base + MPSC_MRR, 0x3ffffe38);
+
+#ifdef CONFIG_GT64260
+	out_le32(mv64x60_base + GT64260_MPP_SERIAL_PORTS_MULTIPLEX, 0x00001102);
+#else /* Must be MV64360 or MV64460 */
+	{
+	u32	enables, prot_bits, v;
+
+	/* Set up comm unit to memory mapping windows */
+	/* Note: Assumes MV64x60_CPU2MEM_WINDOWS == 4 */
+
+	enables = in_le32(mv64x60_base + MV64360_CPU_BAR_ENABLE) & 0xf;
+	prot_bits = 0;
+
+	for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) {
+		if (!(enables & (1 << i))) {
+			v = in_le32(mv64x60_base + cpu2mem_tab[i][0]);
+			v = ((v & 0xffff) << 16) | (dram_selects[i] << 8);
+			out_le32(mv64x60_base + com2mem_tab[i][0], v);
+
+			v = in_le32(mv64x60_base + cpu2mem_tab[i][1]);
+			v = (v & 0xffff) << 16;
+			out_le32(mv64x60_base + com2mem_tab[i][1], v);
+
+			prot_bits |= (0x3 << (i << 1)); /* r/w access */
+		}
+	}
+
+	out_le32(mv64x60_base + MV64360_MPSC_0_REMAP, 0);
+	out_le32(mv64x60_base + MV64360_MPSC_1_REMAP, 0);
+	out_le32(mv64x60_base + MV64360_MPSC2MEM_ACC_PROT_0, prot_bits);
+	out_le32(mv64x60_base + MV64360_MPSC2MEM_ACC_PROT_1, prot_bits);
+	out_le32(mv64x60_base + MV64360_MPSC2MEM_BAR_ENABLE, enables);
+	}
+#endif
+
+	/* MPSC 0/1 Rx & Tx get clocks BRG0/1 */
+	out_le32(mv64x60_base + mpsc_routing_base + MPSC_RCRR, 0x00000100);
+	out_le32(mv64x60_base + mpsc_routing_base + MPSC_TCRR, 0x00000100);
+
+	/* clear pending interrupts */
+	out_le32(mv64x60_base + MV64x60_SDMA_INTR_OFFSET + SDMA_INTR_MASK, 0);
+
+	out_le32(mv64x60_base + SDMA_SCRDP + sdma_base, (int)&rd[chan][0]);
+	out_le32(mv64x60_base + SDMA_SCTDP + sdma_base,
+		(int)&td[chan][TX_NUM_DESC - 1]);
+	out_le32(mv64x60_base + SDMA_SFTDP + sdma_base,
+		(int)&td[chan][TX_NUM_DESC - 1]);
+
+	out_le32(mv64x60_base + SDMA_SDC + sdma_base,
+		SDMA_SDC_RFT | SDMA_SDC_SFM | SDMA_SDC_BLMR | SDMA_SDC_BLMT |
+		(3 << 12));
+
+	cdv = ((mv64x60_mpsc_clk_freq/(32*mv64x60_console_baud))-1);
+	out_le32(mv64x60_base + brg_bcr,
+		((mv64x60_mpsc_clk_src << 18) | (1 << 16) | cdv));
+
+	/* Put MPSC into UART mode, no null modem, 16x clock mode */
+	out_le32(mv64x60_base + MPSC_MMCRL + mpsc_base[chan], 0x000004c4);
+	out_le32(mv64x60_base + MPSC_MMCRH + mpsc_base[chan], 0x04400400);
+
+	out_le32(mv64x60_base + MPSC_CHR_1 + mpsc_base[chan], 0);
+	out_le32(mv64x60_base + MPSC_CHR_9 + mpsc_base[chan], 0);
+	out_le32(mv64x60_base + MPSC_CHR_10 + mpsc_base[chan], 0);
+	out_le32(mv64x60_base + MPSC_CHR_3 + mpsc_base[chan], 4);
+	out_le32(mv64x60_base + MPSC_CHR_4 + mpsc_base[chan], 0);
+	out_le32(mv64x60_base + MPSC_CHR_5 + mpsc_base[chan], 0);
+	out_le32(mv64x60_base + MPSC_CHR_6 + mpsc_base[chan], 0);
+	out_le32(mv64x60_base + MPSC_CHR_7 + mpsc_base[chan], 0);
+	out_le32(mv64x60_base + MPSC_CHR_8 + mpsc_base[chan], 0);
+
+	/* 8 data bits, 1 stop bit */
+	out_le32(mv64x60_base + MPSC_MPCR + mpsc_base[chan], (3 << 12));
+	out_le32(mv64x60_base + SDMA_SDCM + sdma_base, SDMA_SDCM_ERD);
+	out_le32(mv64x60_base + MPSC_CHR_2 + mpsc_base[chan], MPSC_CHR_2_EH);
+
+	udelay(100);
+
+	return chan;
+}
+
+static void
+stop_dma(int chan)
+{
+	int	i;
+
+	/* Abort MPSC Rx (aborting Tx messes things up) */
+	out_le32(mv64x60_base + MPSC_CHR_2 + mpsc_base[chan], MPSC_CHR_2_RA);
+
+	/* Abort SDMA Rx, Tx */
+	out_le32(mv64x60_base + sdma_regs[chan].sdcm,
+		SDMA_SDCM_AR | SDMA_SDCM_STD);
+
+	for (i=0; i<MAX_RESET_WAIT; i++) {
+		if ((in_le32(mv64x60_base + sdma_regs[chan].sdcm) &
+				(SDMA_SDCM_AR | SDMA_SDCM_AT)) == 0)
+			break;
+
+		udelay(100);
+	}
+}
+
+static int
+wait_for_ownership(int chan)
+{
+	int	i;
+
+	for (i=0; i<MAX_TX_WAIT; i++) {
+		if ((in_le32(mv64x60_base + sdma_regs[chan].sdcm) &
+				SDMA_SDCM_TXD) == 0)
+			break;
+
+		udelay(1000);
+	}
+
+	return (i < MAX_TX_WAIT);
+}
+
+void
+serial_putc(unsigned long com_port, unsigned char c)
+{
+	struct mv64x60_tx_desc	*tdp;
+
+	if (wait_for_ownership(com_port) == 0)
+		return;
+
+	tdp = &td[com_port][cur_td[com_port]];
+	if (++cur_td[com_port] >= TX_NUM_DESC)
+		cur_td[com_port] = 0;
+
+	*(unchar *)(tdp->buffer ^ 7) = c;
+	tdp->bytecnt = 1;
+	tdp->shadow = 1;
+	tdp->cmd_stat = SDMA_DESC_CMDSTAT_L | SDMA_DESC_CMDSTAT_F |
+		SDMA_DESC_CMDSTAT_O;
+
+	out_le32(mv64x60_base + sdma_regs[com_port].sctdp, (int)tdp);
+	out_le32(mv64x60_base + sdma_regs[com_port].sftdp, (int)tdp);
+	out_le32(mv64x60_base + sdma_regs[com_port].sdcm,
+		in_le32(mv64x60_base + sdma_regs[com_port].sdcm) |
+			SDMA_SDCM_TXD);
+}
+
+unsigned char
+serial_getc(unsigned long com_port)
+{
+	struct mv64x60_rx_desc	*rdp;
+	unchar			c = '\0';
+
+	rdp = &rd[com_port][cur_rd[com_port]];
+
+	if ((rdp->cmd_stat & (SDMA_DESC_CMDSTAT_O|SDMA_DESC_CMDSTAT_ES)) == 0) {
+		c = *(unchar *)(rdp->buffer ^ 7);
+		RX_INIT_RDP(rdp);
+		if (++cur_rd[com_port] >= RX_NUM_DESC)
+			cur_rd[com_port] = 0;
+	}
+
+	return c;
+}
+
+int
+serial_tstc(unsigned long com_port)
+{
+	struct mv64x60_rx_desc	*rdp;
+	int			loop_count = 0;
+	int			rc = 0;
+
+	rdp = &rd[com_port][cur_rd[com_port]];
+
+	/* Go thru rcv desc's until empty looking for one with data (no error)*/
+	while (((rdp->cmd_stat & SDMA_DESC_CMDSTAT_O) == 0) &&
+		(loop_count++ < RX_NUM_DESC)) {
+
+		/* If there was an error, reinit the desc & continue */
+		if ((rdp->cmd_stat & SDMA_DESC_CMDSTAT_ES) != 0) {
+			RX_INIT_RDP(rdp);
+			if (++cur_rd[com_port] >= RX_NUM_DESC)
+				cur_rd[com_port] = 0;
+			rdp = (struct mv64x60_rx_desc *)rdp->next_desc_ptr;
+		} else {
+			rc = 1;
+			break;
+		}
+	}
+
+	return rc;
+}
+
+void
+serial_close(unsigned long com_port)
+{
+	stop_dma(com_port);
+}
diff --git a/arch/ppc/boot/simple/openbios.c b/arch/ppc/boot/simple/openbios.c
new file mode 100644
index 0000000..c732b6d
--- /dev/null
+++ b/arch/ppc/boot/simple/openbios.c
@@ -0,0 +1,37 @@
+/*
+ * arch/ppc/boot/simple/openbios.c
+ *
+ * 2005 (c) SYSGO AG - g.jaeger@sysgo.com
+ * 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.
+ *
+ * Derived from arch/ppc/boot/simple/pibs.c (from MontaVista)
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <asm/ppcboot.h>
+#include <platforms/4xx/ebony.h>
+
+extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
+				       unsigned long cksum);
+
+/* We need to make sure that this is before the images to ensure
+ * that it's in a mapped location. */
+bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
+bd_t *hold_residual = &hold_resid_buf;
+
+void *
+load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
+		void *ign1, void *ign2)
+{
+	decompress_kernel(load_addr, num_words, cksum);
+
+	/* simply copy the MAC addresses */
+	memcpy(hold_residual->bi_enetaddr,  (char *)EBONY_OPENBIOS_MAC_BASE, 6);
+	memcpy(hold_residual->bi_enet1addr, (char *)(EBONY_OPENBIOS_MAC_BASE+EBONY_OPENBIOS_MAC_OFFSET), 6);
+
+	return (void *)hold_residual;
+}
diff --git a/arch/ppc/boot/simple/pci.c b/arch/ppc/boot/simple/pci.c
new file mode 100644
index 0000000..b0f673c
--- /dev/null
+++ b/arch/ppc/boot/simple/pci.c
@@ -0,0 +1,274 @@
+/* Stand alone funtions for QSpan Tundra support.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <asm/mpc8xx.h>
+
+extern void puthex(unsigned long val);
+extern void puts(const char *);
+
+/* To map PCI devices, you first write 0xffffffff into the device
+ * base address registers.  When the register is read back, the
+ * number of most significant '1' bits describes the amount of address
+ * space needed for mapping.  If the most significant bit is not set,
+ * either the device does not use that address register, or it has
+ * a fixed address that we can't change.  After the address is assigned,
+ * the command register has to be written to enable the card.
+ */
+typedef struct {
+	u_char	pci_bus;
+	u_char	pci_devfn;
+	ushort	pci_command;
+	uint	pci_addrs[6];
+} pci_map_t;
+
+/* We should probably dynamically allocate these structures.
+*/
+#define MAX_PCI_DEVS	32
+int	pci_dev_cnt;
+pci_map_t	pci_map[MAX_PCI_DEVS];
+
+void pci_conf_write(int bus, int device, int func, int reg, uint writeval);
+void pci_conf_read(int bus, int device, int func, int reg, void *readval);
+void probe_addresses(int bus, int devfn);
+void map_pci_addrs(void);
+
+extern int
+qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
+			unsigned char offset, unsigned char *val);
+extern int
+qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn,
+			unsigned char offset, unsigned short *val);
+extern int
+qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn,
+			 unsigned char offset, unsigned int *val);
+extern int
+qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn,
+			 unsigned char offset, unsigned char val);
+extern int
+qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn,
+			 unsigned char offset, unsigned short val);
+extern int
+qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn,
+			  unsigned char offset, unsigned int val);
+
+
+/* This is a really stripped version of PCI bus scan.  All we are
+ * looking for are devices that exist.
+ */
+void
+pci_scanner(int addr_probe)
+{
+	unsigned int devfn, l, class, bus_number;
+	unsigned char hdr_type, is_multi;
+
+	is_multi = 0;
+	bus_number = 0;
+	for (devfn = 0; devfn < 0xff; ++devfn) {
+		/* The device numbers are comprised of upper 5 bits of
+		 * device number and lower 3 bits of multi-function number.
+		 */
+		if ((devfn & 7) && !is_multi) {
+			/* Don't scan multifunction addresses if this is
+			 * not a multifunction device.
+			 */
+			continue;
+		}
+
+		/* Read the header to determine card type.
+		*/
+		qs_pci_read_config_byte(bus_number, devfn, PCI_HEADER_TYPE,
+								&hdr_type);
+
+		/* If this is a base device number, check the header to
+		 * determine if it is mulifunction.
+		 */
+		if ((devfn & 7) == 0)
+			is_multi = hdr_type & 0x80;
+
+		/* Check to see if the board is really in the slot.
+		*/
+		qs_pci_read_config_dword(bus_number, devfn, PCI_VENDOR_ID, &l);
+		/* some broken boards return 0 if a slot is empty: */
+		if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff ||
+							l == 0xffff0000) {
+			/* Nothing there.
+			*/
+			is_multi = 0;
+			continue;
+		}
+
+		/* If we are not performing an address probe,
+		 * just simply print out some information.
+		 */
+		if (!addr_probe) {
+			qs_pci_read_config_dword(bus_number, devfn,
+						PCI_CLASS_REVISION, &class);
+
+			class >>= 8;	    /* upper 3 bytes */
+
+#if 0
+			printf("Found (%3d:%d): vendor 0x%04x, device 0x%04x, class 0x%06x\n",
+				(devfn >> 3), (devfn & 7),
+				(l & 0xffff),  (l >> 16) & 0xffff, class);
+#else
+			puts("Found ("); puthex(devfn >> 3);
+			puts(":"); puthex(devfn & 7);
+			puts("): vendor "); puthex(l & 0xffff);
+			puts(", device "); puthex((l >> 16) & 0xffff);
+			puts(", class "); puthex(class); puts("\n");
+#endif
+		}
+		else {
+			/* If this is a "normal" device, build address list.
+			*/
+			if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL)
+				probe_addresses(bus_number, devfn);
+		}
+	}
+
+	/* Now map the boards.
+	*/
+	if (addr_probe)
+		map_pci_addrs();
+}
+
+/* Probe addresses for the specified device.  This is a destructive
+ * operation because it writes the registers.
+ */
+void
+probe_addresses(bus, devfn)
+{
+	int	i;
+	uint	pciaddr;
+	ushort	pcicmd;
+	pci_map_t	*pm;
+
+	if (pci_dev_cnt >= MAX_PCI_DEVS) {
+		puts("Too many PCI devices\n");
+		return;
+	}
+
+	pm = &pci_map[pci_dev_cnt++];
+
+	pm->pci_bus = bus;
+	pm->pci_devfn = devfn;
+
+	for (i=0; i<6; i++) {
+		qs_pci_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), -1);
+		qs_pci_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4),
+								&pciaddr);
+		pm->pci_addrs[i] = pciaddr;
+		qs_pci_read_config_word(bus, devfn, PCI_COMMAND, &pcicmd);
+		pm->pci_command = pcicmd;
+	}
+}
+
+/* Map the cards into the PCI space.  The PCI has separate memory
+ * and I/O spaces.  In addition, some memory devices require mapping
+ * below 1M.  The least significant 4 bits of the address register
+ * provide information.  If this is an I/O device, only the LS bit
+ * is used to indicate that, so I/O devices can be mapped to a two byte
+ * boundard.  Memory addresses can be mapped to a 32 byte boundary.
+ * The QSpan implementations usually have a 1Gbyte space for each
+ * memory and I/O spaces.
+ *
+ * This isn't a terribly fancy algorithm.  I just map the spaces from
+ * the top starting with the largest address space.  When finished,
+ * the registers are written and the card enabled.
+ *
+ * While the Tundra can map a large address space on most boards, we
+ * need to be careful because it may overlap other devices (like IMMR).
+ */
+#define MEMORY_SPACE_SIZE	0x20000000
+#define IO_SPACE_SIZE		0x20000000
+
+void
+map_pci_addrs()
+{
+	uint	pci_mem_top, pci_mem_low;
+	uint	pci_io_top;
+	uint	addr_mask, reg_addr, space;
+	int	i, j;
+	pci_map_t *pm;
+
+	pci_mem_top = MEMORY_SPACE_SIZE;
+	pci_io_top = IO_SPACE_SIZE;
+	pci_mem_low = (1 * 1024 * 1024);	/* Below one meg addresses */
+
+	/* We can't map anything more than the maximum space, but test
+	 * for it anyway to catch devices out of range.
+	 */
+	addr_mask = 0x80000000;
+
+	do {
+		space = (~addr_mask) + 1;	/* Size of the space */
+		for (i=0; i<pci_dev_cnt; i++) {
+			pm = &pci_map[i];
+			for (j=0; j<6; j++) {
+				/* If the MS bit is not set, this has either
+				 * already been mapped, or is not used.
+				 */
+				reg_addr = pm->pci_addrs[j];
+				if ((reg_addr & 0x80000000) == 0)
+					continue;
+				if (reg_addr & PCI_BASE_ADDRESS_SPACE_IO) {
+					if ((reg_addr & PCI_BASE_ADDRESS_IO_MASK) != addr_mask)
+						continue;
+					if (pci_io_top < space) {
+						puts("Out of PCI I/O space\n");
+					}
+					else {
+						pci_io_top -= space;
+						pm->pci_addrs[j] = pci_io_top;
+						pm->pci_command |= PCI_COMMAND_IO;
+					}
+				}
+				else {
+					if ((reg_addr & PCI_BASE_ADDRESS_MEM_MASK) != addr_mask)
+						continue;
+
+					/* Memory space.  Test if below 1M.
+					*/
+					if (reg_addr & PCI_BASE_ADDRESS_MEM_TYPE_1M) {
+						if (pci_mem_low < space) {
+							puts("Out of PCI 1M space\n");
+						}
+						else {
+							pci_mem_low -= space;
+							pm->pci_addrs[j] = pci_mem_low;
+						}
+					}
+					else {
+						if (pci_mem_top < space) {
+							puts("Out of PCI Mem space\n");
+						}
+						else {
+							pci_mem_top -= space;
+							pm->pci_addrs[j] = pci_mem_top;
+						}
+					}
+					pm->pci_command |= PCI_COMMAND_MEMORY;
+				}
+			}
+		}
+		addr_mask >>= 1;
+		addr_mask |= 0x80000000;
+	} while (addr_mask != 0xfffffffe);
+	
+	/* Now, run the list one more time and map everything.
+	*/
+	for (i=0; i<pci_dev_cnt; i++) {
+		pm = &pci_map[i];
+		for (j=0; j<6; j++) {
+			qs_pci_write_config_dword(pm->pci_bus, pm->pci_devfn,
+				PCI_BASE_ADDRESS_0 + (j * 4), pm->pci_addrs[j]);
+		}
+
+		/* Enable memory or address mapping.
+		*/
+		qs_pci_write_config_word(pm->pci_bus, pm->pci_devfn, PCI_COMMAND,
+			pm->pci_command);
+	}
+}
+
diff --git a/arch/ppc/boot/simple/pibs.c b/arch/ppc/boot/simple/pibs.c
new file mode 100644
index 0000000..1348740
--- /dev/null
+++ b/arch/ppc/boot/simple/pibs.c
@@ -0,0 +1,103 @@
+/*
+ * 2004-2005 (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>
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <asm/ppcboot.h>
+#include <asm/ibm4xx.h>
+
+extern unsigned long decompress_kernel(unsigned long load_addr, int num_words,
+				       unsigned long cksum);
+
+/* We need to make sure that this is before the images to ensure
+ * that it's in a mapped location. - Tom */
+bd_t hold_resid_buf __attribute__ ((__section__ (".data.boot")));
+bd_t *hold_residual = &hold_resid_buf;
+
+/* String functions lifted from lib/vsprintf.c and lib/ctype.c */
+unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,		/* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,			/* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P,			/* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D,			/* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P,			/* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,	/* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U,			/* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U,			/* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P,			/* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,	/* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L,			/* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L,			/* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C,			/* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
+
+/**
+ * simple_strtoull - convert a string to an unsigned long long
+ * @cp: The start of the string
+ * @endp: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
+{
+	unsigned long long result = 0,value;
+
+	if (!base) {
+		base = 10;
+		if (*cp == '0') {
+			base = 8;
+			cp++;
+			if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
+				cp++;
+				base = 16;
+			}
+		}
+	} else if (base == 16) {
+		if (cp[0] == '0' && toupper(cp[1]) == 'X')
+			cp += 2;
+	}
+	while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+	    ? toupper(*cp) : *cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+	if (endp)
+		*endp = (char *)cp;
+	return result;
+}
+
+void *
+load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
+		void *ign1, void *ign2)
+{
+	unsigned long long mac64;
+
+	decompress_kernel(load_addr, num_words, cksum);
+
+	mac64 = simple_strtoull((char *)PIBS_MAC_BASE, 0, 16);
+	memcpy(hold_residual->bi_enetaddr, (char *)&mac64+2, 6);
+#ifdef CONFIG_440GX
+	mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET), 0, 16);
+	memcpy(hold_residual->bi_enet1addr, (char *)&mac64+2, 6);
+	mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*2), 0, 16);
+	memcpy(hold_residual->bi_enet2addr, (char *)&mac64+2, 6);
+	mac64 = simple_strtoull((char *)(PIBS_MAC_BASE+PIBS_MAC_OFFSET*3), 0, 16);
+	memcpy(hold_residual->bi_enet3addr, (char *)&mac64+2, 6);
+#endif
+	return (void *)hold_residual;
+}
diff --git a/arch/ppc/boot/simple/prepmap.c b/arch/ppc/boot/simple/prepmap.c
new file mode 100644
index 0000000..c871a4d
--- /dev/null
+++ b/arch/ppc/boot/simple/prepmap.c
@@ -0,0 +1,12 @@
+/*
+ * 2004 (C) IBM. 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 <nonstdio.h>
+
+void board_isa_init(void)
+{
+	ISA_init(0x80000000);
+}
diff --git a/arch/ppc/boot/simple/qspan_pci.c b/arch/ppc/boot/simple/qspan_pci.c
new file mode 100644
index 0000000..d2966d0
--- /dev/null
+++ b/arch/ppc/boot/simple/qspan_pci.c
@@ -0,0 +1,269 @@
+/*
+ * LinuxPPC arch/ppc/kernel/qspan_pci.c   Dan Malek (dmalek@jlc.net)
+ *
+ * QSpan Motorola bus to PCI bridge.  The config address register
+ * is located 0x500 from the base of the bridge control/status registers.
+ * The data register is located at 0x504.
+ * This is a two step operation.  First, the address register is written,
+ * then the data register is read/written as required.
+ * I don't know what to do about interrupts (yet).
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/mpc8xx.h>
+
+/*
+ * When reading the configuration space, if something does not respond
+ * the bus times out and we get a machine check interrupt.  So, the
+ * good ol' exception tables come to mind to trap it and return some
+ * value.
+ *
+ * On an error we just return a -1, since that is what the caller wants
+ * returned if nothing is present.  I copied this from __get_user_asm,
+ * with the only difference of returning -1 instead of EFAULT.
+ * There is an associated hack in the machine check trap code.
+ *
+ * The QSPAN is also a big endian device, that is it makes the PCI
+ * look big endian to us.  This presents a problem for the Linux PCI
+ * functions, which assume little endian.  For example, we see the
+ * first 32-bit word like this:
+ *	------------------------
+ *	| Device ID | Vendor ID |
+ *	------------------------
+ * If we read/write as a double word, that's OK.  But in our world,
+ * when read as a word, device ID is at location 0, not location 2 as
+ * the little endian PCI would believe.  We have to switch bits in
+ * the PCI addresses given to us to get the data to/from the correct
+ * byte lanes.
+ *
+ * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5.
+ * It always forces the MS bit to zero.  Therefore, dev_fn values
+ * greater than 128 are returned as "no device found" errors.
+ *
+ * The QSPAN can only perform long word (32-bit) configuration cycles.
+ * The "offset" must have the two LS bits set to zero.  Read operations
+ * require we read the entire word and then sort out what should be
+ * returned.  Write operations other than long word require that we
+ * read the long word, update the proper word or byte, then write the
+ * entire long word back.
+ *
+ * PCI Bridge hack.  We assume (correctly) that bus 0 is the primary
+ * PCI bus from the QSPAN.  If we are called with a bus number other
+ * than zero, we create a Type 1 configuration access that a downstream
+ * PCI bridge will interpret.
+ */
+
+#define __get_pci_config(x, addr, op)		\
+	__asm__ __volatile__(				\
+		"1:	"op" %0,0(%1)\n"		\
+		"	eieio\n"			\
+		"2:\n"					\
+		".section .fixup,\"ax\"\n"		\
+		"3:	li %0,-1\n"			\
+		"	b 2b\n"				\
+		".section __ex_table,\"a\"\n"		\
+		"	.align 2\n"			\
+		"	.long 1b,3b\n"			\
+		".text"					\
+		: "=r"(x) : "r"(addr))
+
+#define QS_CONFIG_ADDR	((volatile uint *)(PCI_CSR_ADDR + 0x500))
+#define QS_CONFIG_DATA	((volatile uint *)(PCI_CSR_ADDR + 0x504))
+
+#define mk_config_addr(bus, dev, offset) \
+	(((bus)<<16) | ((dev)<<8) | (offset & 0xfc))
+
+#define mk_config_type1(bus, dev, offset) \
+	mk_config_addr(bus, dev, offset) | 1;
+
+/* Initialize the QSpan device registers after power up.
+*/
+void
+qspan_init(void)
+{
+	uint	*qptr;
+
+
+
+	qptr = (uint *)PCI_CSR_ADDR;
+
+	/* PCI Configuration/status.  Upper bits written to clear
+	 * pending interrupt or status.  Lower bits enable QSPAN as
+	 * PCI master, enable memory and I/O cycles, and enable PCI
+	 * parity error checking.
+	 * IMPORTANT:  The last two bits of this word enable PCI
+	 * master cycles into the QBus.  The QSpan is broken and can't
+	 * meet the timing specs of the PQ bus for this to work.  Therefore,
+	 * if you don't have external bus arbitration, you can't use
+	 * this function.
+	 */
+#ifdef EXTERNAL_PQ_ARB
+	qptr[1] = 0xf9000147;
+#else
+	qptr[1] = 0xf9000144;
+#endif
+
+	/* PCI Misc configuration.  Set PCI latency timer resolution
+	 * of 8 cycles, set cache size to 4 x 32.
+	 */
+	qptr[3] = 0;
+
+	/* Set up PCI Target address mapping.  Enable, Posted writes,
+	 * 2Gbyte space (processor memory controller determines actual size).
+	 */
+	qptr[64] = 0x8f000080;
+
+	/* Map processor 0x80000000 to PCI 0x00000000.
+	 * Processor address bit 1 determines I/O type access (0x80000000)
+	 * or memory type access (0xc0000000).
+	 */
+	qptr[65] = 0x80000000;
+
+	/* Enable error logging and clear any pending error status.
+	*/
+	qptr[80] = 0x90000000;
+
+	qptr[512] = 0x000c0003;
+
+	/* Set up Qbus slave image.
+	*/
+	qptr[960] = 0x01000000;
+	qptr[961] = 0x000000d1;
+	qptr[964] = 0x00000000;
+	qptr[965] = 0x000000d1;
+
+}
+
+/* Functions to support PCI bios-like features to read/write configuration
+ * space.  If the function fails for any reason, a -1 (0xffffffff) value
+ * must be returned.
+ */
+#define DEVICE_NOT_FOUND	(-1)
+#define SUCCESSFUL		0
+
+int qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
+				  unsigned char offset, unsigned char *val)
+{
+	uint	temp;
+	u_char	*cp;
+
+	if ((bus > 7) || (dev_fn > 127)) {
+		*val = 0xff;
+		return DEVICE_NOT_FOUND;
+	}
+
+	if (bus == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	else
+		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+	__get_pci_config(temp, QS_CONFIG_DATA, "lwz");
+
+	offset ^= 0x03;
+	cp = ((u_char *)&temp) + (offset & 0x03);
+	*val = *cp;
+	return SUCCESSFUL;
+}
+
+int qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn,
+				  unsigned char offset, unsigned short *val)
+{
+	uint	temp;
+	ushort	*sp;
+
+	if ((bus > 7) || (dev_fn > 127)) {
+		*val = 0xffff;
+		return DEVICE_NOT_FOUND;
+	}
+
+	if (bus == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	else
+		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+	__get_pci_config(temp, QS_CONFIG_DATA, "lwz");
+	offset ^= 0x02;
+
+	sp = ((ushort *)&temp) + ((offset >> 1) & 1);
+	*val = *sp;
+	return SUCCESSFUL;
+}
+
+int qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn,
+				   unsigned char offset, unsigned int *val)
+{
+	if ((bus > 7) || (dev_fn > 127)) {
+		*val = 0xffffffff;
+		return DEVICE_NOT_FOUND;
+	}
+	if (bus == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	else
+		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+	__get_pci_config(*val, QS_CONFIG_DATA, "lwz");
+	return SUCCESSFUL;
+}
+
+int qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn,
+				   unsigned char offset, unsigned char val)
+{
+	uint	temp;
+	u_char	*cp;
+
+	if ((bus > 7) || (dev_fn > 127))
+		return DEVICE_NOT_FOUND;
+
+	qs_pci_read_config_dword(bus, dev_fn, offset, &temp);
+
+	offset ^= 0x03;
+	cp = ((u_char *)&temp) + (offset & 0x03);
+	*cp = val;
+
+	if (bus == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	else
+		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+	*QS_CONFIG_DATA = temp;
+
+	return SUCCESSFUL;
+}
+
+int qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn,
+				   unsigned char offset, unsigned short val)
+{
+	uint	temp;
+	ushort	*sp;
+
+	if ((bus > 7) || (dev_fn > 127))
+		return DEVICE_NOT_FOUND;
+
+	qs_pci_read_config_dword(bus, dev_fn, offset, &temp);
+
+	offset ^= 0x02;
+	sp = ((ushort *)&temp) + ((offset >> 1) & 1);
+	*sp = val;
+
+	if (bus == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	else
+		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+	*QS_CONFIG_DATA = temp;
+
+	return SUCCESSFUL;
+}
+
+int qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn,
+				    unsigned char offset, unsigned int val)
+{
+	if ((bus > 7) || (dev_fn > 127))
+		return DEVICE_NOT_FOUND;
+
+	if (bus == 0)
+		*QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
+	else
+		*QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
+	*(unsigned int *)QS_CONFIG_DATA = val;
+
+	return SUCCESSFUL;
+}
+
diff --git a/arch/ppc/boot/simple/relocate.S b/arch/ppc/boot/simple/relocate.S
new file mode 100644
index 0000000..555a216
--- /dev/null
+++ b/arch/ppc/boot/simple/relocate.S
@@ -0,0 +1,216 @@
+/*
+ * arch/ppc/boot/simple/relocate.S
+ *
+ * This is the common part of the loader relocation and initialization
+ * process.  All of the board/processor specific initialization is
+ * done before we get here.
+ *
+ * Author: Tom Rini
+ *	   trini@mvista.com
+ * Derived from arch/ppc/boot/prep/head.S (Cort Dougan, many others).
+ *
+ * 2001-2004 (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/config.h>
+#include <asm/cache.h>
+#include <asm/ppc_asm.h>
+
+#define GETSYM(reg, sym)	\
+	lis	reg, sym@h; ori	reg, reg, sym@l
+
+	.text
+	/* We get called from the early initialization code.
+	 * Register 3 has the address where we were loaded,
+	 * Register 4 contains any residual data passed from the
+	 * boot rom.
+	 */
+	.globl	relocate
+relocate:
+	/* Save r3, r4 for later.
+	 * The r8/r11 are legacy registers so I don't have to
+	 * rewrite the code below :-).
+	 */
+	mr	r8, r3
+	mr	r11, r4
+
+	/* compute the size of the whole image in words. */
+	GETSYM(r4,start)
+	GETSYM(r5,end)
+
+	addi	r5,r5,3		/* round up */
+	sub	r5,r5,r4	/* end - start */
+	srwi	r5,r5,2
+	mr	r7,r5		/* Save for later use. */
+
+	/*
+	 * Check if we need to relocate ourselves to the link addr or were
+	 * we loaded there to begin with.
+	 */
+	cmpw	cr0,r3,r4
+	beq	start_ldr	/* If 0, we don't need to relocate */
+
+	/* Move this code somewhere safe.  This is max(load + size, end)
+	 * r8 == load address
+	 */
+	GETSYM(r4, start)
+	GETSYM(r5, end)
+
+	sub	r6,r5,r4
+	add	r6,r8,r6	/* r6 == phys(load + size) */
+
+	cmpw	r5,r6
+	bgt	1f
+	b	2f
+1:
+	mr	r6, r5
+2:
+	/* dest is in r6 */
+	/* Ensure alignment --- this code is precautionary */
+	addi	r6,r6,4
+	li	r5,0x0003
+	andc	r6,r6,r5
+
+	/* Find physical address and size of do_relocate */
+	GETSYM(r5, __relocate_start)
+	GETSYM(r4, __relocate_end)
+	GETSYM(r3, start)
+
+	/* Size to copy */
+	sub	r4,r4,r5
+	srwi	r4,r4,2
+
+	/* Src addr to copy (= __relocate_start - start + where_loaded) */
+	sub	r3,r5,r3
+	add	r5,r8,r3
+
+	/* Save dest */
+	mr	r3, r6
+
+	/* Do the copy */
+	mtctr	r4
+3:	lwz	r4,0(r5)
+	stw	r4,0(r3)
+	addi	r3,r3,4
+	addi	r5,r5,4
+	bdnz	3b
+
+	GETSYM(r4, __relocate_start)
+	GETSYM(r5, do_relocate)
+
+	sub	r4,r5,r4	/* Get entry point for do_relocate in */
+	add	r6,r6,r4	/* relocated section */
+
+	/* This will return to the relocated do_relocate */
+	mtlr	r6
+	b	flush_instruction_cache
+
+	.section ".relocate_code","xa"
+	
+do_relocate:
+	/* We have 2 cases --- start < load, or start > load
+	 * This determines whether we copy from the end, or the start.
+	 * Its easier to have 2 loops than to have paramaterised
+	 * loops.  Sigh.
+	 */
+	li	r6,0		/* Clear checksum */
+	mtctr	r7		/* Setup for a loop */
+	
+	GETSYM(r4, start)
+	mr	r3,r8		/* Get the load addr */
+
+	cmpw	cr0,r4,r3	/* If we need to copy from the end, do so */
+	bgt	do_relocate_from_end
+
+do_relocate_from_start:
+1:	lwz	r5,0(r3)	/* Load and decrement */
+	stw	r5,0(r4)	/* Store and decrement */
+	addi	r3,r3,4
+	addi	r4,r4,4
+	xor	r6,r6,r5	/* Update checksum */
+	bdnz	1b		/* Are we done? */
+	b	do_relocate_out	/* Finished */
+
+do_relocate_from_end:
+	GETSYM(r3, end)
+	slwi	r4,r7,2
+	add	r4,r8,r4	/* Get the physical end */
+1:	lwzu	r5,-4(r4)
+	stwu	r5, -4(r3)
+	xor	r6,r6,r5
+	bdnz	1b
+
+do_relocate_out:
+	GETSYM(r3,start_ldr)
+	mtlr	r3		/* Easiest way to do an absolute jump */
+/* Some boards don't boot up with the I-cache enabled.  Do that
+ * now because the decompress runs much faster that way.
+ * As a side effect, we have to ensure the data cache is not enabled
+ * so we can access the serial I/O without trouble.
+ */
+	b	flush_instruction_cache
+
+	.previous
+
+start_ldr:
+/* Clear all of BSS and set up stack for C calls */
+	lis	r3,edata@h
+	ori	r3,r3,edata@l
+	lis	r4,end@h
+	ori	r4,r4,end@l
+	subi	r3,r3,4
+	subi	r4,r4,4
+	li	r0,0
+50:	stwu	r0,4(r3)
+	cmpw	cr0,r3,r4
+	bne	50b
+90:	mr	r9,r1		/* Save old stack pointer (in case it matters) */
+	lis	r1,.stack@h
+	ori	r1,r1,.stack@l
+	addi	r1,r1,4096*2
+	subi	r1,r1,256
+	li	r2,0x000F	/* Mask pointer to 16-byte boundary */
+	andc	r1,r1,r2
+
+	/*
+	 * Exec kernel loader
+	 */
+	mr	r3,r8		/* Load point */
+	mr	r4,r7		/* Program length */
+	mr	r5,r6		/* Checksum */
+	mr	r6,r11		/* Residual data */
+	mr	r7,r25		/* Validated OFW interface */
+	bl	load_kernel
+
+	/*
+	 * Make sure the kernel knows we don't have things set in
+	 * registers.  -- Tom
+	 */
+	li	r4,0
+	li	r5,0
+	li	r6,0
+
+	/*
+	 * Start at the begining.
+	 */
+#ifdef CONFIG_PPC_MULTIPLATFORM
+	li	r9,0xc
+	mtlr	r9
+	/* tell kernel we're prep, by putting 0xdeadc0de at KERNELLOAD,
+	 * and tell the kernel to start on the 4th instruction since we
+	 * overwrite the first 3 sometimes (which are 'nop').
+	 */
+	lis	r10,0xdeadc0de@h
+	ori	r10,r10,0xdeadc0de@l
+	li	r9,0
+	stw	r10,0(r9)
+#else
+	li	r9,0
+	mtlr	r9
+#endif
+	blr
+
+	.comm	.stack,4096*2,4
diff --git a/arch/ppc/boot/simple/rw4/ppc_40x.h b/arch/ppc/boot/simple/rw4/ppc_40x.h
new file mode 100644
index 0000000..561fb26
--- /dev/null
+++ b/arch/ppc/boot/simple/rw4/ppc_40x.h
@@ -0,0 +1,664 @@
+/*----------------------------------------------------------------------------+
+|       This source code has been made available to you by IBM on an AS-IS
+|       basis.  Anyone receiving this source is licensed under IBM
+|       copyrights to use it in any way he or she deems fit, including
+|       copying it, modifying it, compiling it, and redistributing it either
+|       with or without modifications.  No license under IBM patents or
+|       patent applications is to be implied by the copyright license.
+|
+|       Any user of this software should understand that IBM cannot provide
+|       technical support for this software and will not be responsible for
+|       any consequences resulting from the use of this software.
+|
+|       Any person who transfers this source code or any derivative work
+|       must include the IBM copyright notice, this paragraph, and the
+|       preceding two paragraphs in the transferred software.
+|
+|       COPYRIGHT   I B M   CORPORATION 1997
+|       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+| Author:    Tony J. Cerreto
+| Component: Assembler include file.
+| File:      ppc_40x.h
+| Purpose:   Include file containing PPC DCR defines.
+|
+| Changes:
+| Date       Author  Comment
+| ---------  ------  --------------------------------------------------------
+| 01-Mar-00  tjc     Created
++----------------------------------------------------------------------------*/
+/* added by linguohui*/
+#define MW
+/*----------------------------------------------------------------------------+
+| PPC Special purpose registers Numbers
++----------------------------------------------------------------------------*/
+#define ccr0            0x3b3               /* core configuration reg        */
+#define ctr             0x009               /* count register                */
+#define ctrreg          0x009               /* count register                */
+#define dbcr0           0x3f2               /* debug control register 0      */
+#define dbcr1           0x3bd               /* debug control register 1      */
+#define dbsr            0x3f0               /* debug status register         */
+#define dccr            0x3fa               /* data cache control reg.       */
+#define dcwr            0x3ba               /* data cache write-thru reg     */
+#define dear            0x3d5               /* data exception address reg    */
+#define esr             0x3d4               /* exception syndrome register   */
+#define evpr            0x3d6               /* exception vector prefix reg   */
+#define iccr            0x3fb               /* instruction cache cntrl re    */
+#define icdbdr          0x3d3               /* instr cache dbug data reg     */
+#define lrreg           0x008               /* link register                 */
+#define pid             0x3b1               /* process id reg                */
+#define pit             0x3db               /* programmable interval time    */
+#define pvr             0x11f               /* processor version register    */
+#define sgr             0x3b9               /* storage guarded reg           */
+#define sler            0x3bb               /* storage little endian reg     */
+#define sprg0           0x110               /* special general purpose 0     */
+#define sprg1           0x111               /* special general purpose 1     */
+#define sprg2           0x112               /* special general purpose 2     */
+#define sprg3           0x113               /* special general purpose 3     */
+#define sprg4           0x114               /* special general purpose 4     */
+#define sprg5           0x115               /* special general purpose 5     */
+#define sprg6           0x116               /* special general purpose 6     */
+#define sprg7           0x117               /* special general purpose 7     */
+#define srr0            0x01a               /* save/restore register 0       */
+#define srr1            0x01b               /* save/restore register 1       */
+#define srr2            0x3de               /* save/restore register 2       */
+#define srr3            0x3df               /* save/restore register 3       */
+#define tbhi            0x11D
+#define tblo            0x11C
+#define tcr             0x3da               /* timer control register        */
+#define tsr             0x3d8               /* timer status register         */
+#define xerreg          0x001               /* fixed point exception         */
+#define xer             0x001               /* fixed point exception         */
+#define zpr             0x3b0               /* zone protection reg           */
+
+/*----------------------------------------------------------------------------+
+| Decompression Controller
++----------------------------------------------------------------------------*/
+#define kiar            0x014               /* Decompression cntl addr reg   */
+#define kidr            0x015               /* Decompression cntl data reg   */
+#define kitor0          0x00                /* index table origin Reg 0      */
+#define kitor1          0x01                /* index table origin Reg 1      */
+#define kitor2          0x02                /* index table origin Reg 2      */
+#define kitor3          0x03                /* index table origin Reg 3      */
+#define kaddr0          0x04                /* addr decode Definition Reg 0  */
+#define kaddr1          0x05                /* addr decode Definition Reg 1  */
+#define kconf           0x40                /* Decompression cntl config reg */
+#define kid             0x41                /* Decompression cntl id reg     */
+#define kver            0x42                /* Decompression cntl ver number */
+#define kpear           0x50                /* bus error addr reg (PLB)      */
+#define kbear           0x51                /* bus error addr reg (DCP-EBC)  */
+#define kesr0           0x52                /* bus error status reg 0        */
+
+/*----------------------------------------------------------------------------+
+| Romeo Specific Device Control Register Numbers.
++----------------------------------------------------------------------------*/
+#ifndef VESTA
+#define cdbcr           0x3d7                   /* cache debug cntrl reg     */
+
+#define a_latcnt        0x1a9                   /* PLB Latency count         */
+#define a_tgval         0x1ac                   /* tone generation value     */
+#define a_plb_pr        0x1bf                   /* PLB priority              */
+
+#define cic_sel1        0x031                   /* select register 1         */
+#define cic_sel2        0x032                   /* select register 2         */
+
+#define clkgcrst        0x122                   /* chip reset register */
+
+#define cp_cpmsr        0x100                   /*rstatus register           */
+#define cp_cpmer        0x101                   /* enable register           */
+
+#define dcp_kiar        0x190                   /* indirect address register */
+#define dcp_kidr        0x191                   /* indirect data register    */
+
+#define hsmc_mcgr       0x1c0                   /* HSMC global register      */
+#define hsmc_mcbesr     0x1c1                   /* bus error status register */
+#define hsmc_mcbear     0x1c2                   /* bus error address register*/
+#define hsmc_mcbr0      0x1c4                   /* SDRAM sub-ctrl bank reg 0 */
+#define hsmc_mccr0      0x1c5                   /* SDRAM sub-ctrl ctrl reg 0 */
+#define hsmc_mcbr1      0x1c7                   /* SDRAM sub-ctrl bank reg 1 */
+#define hsmc_mccr1      0x1c8                   /* SDRAM sub-ctrl ctrl reg 1 */
+#define hsmc_sysr       0x1d1                   /* system register           */
+#define hsmc_data       0x1d2                   /* data register             */
+#define hsmc_mccrr      0x1d3                   /* refresh register          */
+
+#define ocm_pbar        0x1E0                   /* base address register     */
+
+#define plb0_pacr0      0x057                   /* PLB arbiter control reg   */
+#define plb1_pacr1      0x067                   /* PLB arbiter control reg   */
+
+#define v_displb        0x157                   /* set left border of display*/
+#define v_disptb        0x158                   /* top border of display     */
+#define v_osd_la        0x159                   /* first link address for OSD*/
+#define v_ptsdlta       0x15E                   /* PTS delta register        */
+#define v_v0base        0x16C                   /* base mem add for VBI-0    */
+#define v_v1base        0x16D                   /* base mem add for VBI-1    */
+#define v_osbase        0x16E                   /* base mem add for OSD data */
+#endif
+
+/*----------------------------------------------------------------------------+
+| Vesta Device Control Register Numbers.
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+| Cross bar switch.
++----------------------------------------------------------------------------*/
+#define cbs0_cr         0x010               /* CBS configuration register    */
+
+/*----------------------------------------------------------------------------+
+| DCR external master (DCRX).
++----------------------------------------------------------------------------*/
+#define dcrx0_icr       0x020               /* internal control register     */
+#define dcrx0_isr       0x021               /* internal status register      */
+#define dcrx0_ecr       0x022               /* external control register     */
+#define dcrx0_esr       0x023               /* external status register      */
+#define dcrx0_tar       0x024               /* target address register       */
+#define dcrx0_tdr       0x025               /* target data register          */
+#define dcrx0_igr       0x026               /* interrupt generation register */
+#define dcrx0_bcr       0x027               /* buffer control register       */
+
+/*----------------------------------------------------------------------------+
+| Chip interconnect configuration.
++----------------------------------------------------------------------------*/
+#define cic0_cr         0x030               /* CIC control register          */
+#define cic0_vcr        0x033               /* video macro control reg       */
+#define cic0_sel3       0x035               /* select register 3             */
+
+/*----------------------------------------------------------------------------+
+| Chip interconnect configuration.
++----------------------------------------------------------------------------*/
+#define sgpo0_sgpO      0x036               /* simplified GPIO output        */
+#define sgpo0_gpod      0x037               /* simplified GPIO open drain    */
+#define sgpo0_gptc      0x038               /* simplified GPIO tristate cntl */
+#define sgpo0_gpi       0x039               /* simplified GPIO input         */
+
+/*----------------------------------------------------------------------------+
+| Universal interrupt controller.
++----------------------------------------------------------------------------*/
+#define uic0_sr         0x040               /* status register               */
+#define uic0_srs        0x041               /* status register set           */
+#define uic0_er         0x042               /* enable register               */
+#define uic0_cr         0x043               /* critical register             */
+#define uic0_pr         0x044               /* parity register               */
+#define uic0_tr         0x045               /* triggering register           */
+#define uic0_msr        0x046               /* masked status register        */
+#define uic0_vr         0x047               /* vector register               */
+#define uic0_vcr        0x048               /* enable config register        */
+
+/*----------------------------------------------------------------------------+
+| PLB 0 and 1.
++----------------------------------------------------------------------------*/
+#define pb0_pesr        0x054               /* PLB error status reg 0        */
+#define pb0_pesrs       0x055               /* PLB error status reg 0 set    */
+#define pb0_pear        0x056               /* PLB error address reg         */
+
+#define pb1_pesr        0x064               /* PLB error status reg 1        */
+#define pb1_pesrs       0x065               /* PLB error status reg 1 set    */
+#define pb1_pear        0x066               /* PLB error address reg         */
+
+/*----------------------------------------------------------------------------+
+| EBIU DCR registers.
++----------------------------------------------------------------------------*/
+#define ebiu0_brcrh0    0x070               /* bus region register 0 high    */
+#define ebiu0_brcrh1    0x071               /* bus region register 1 high    */
+#define ebiu0_brcrh2    0x072               /* bus region register 2 high    */
+#define ebiu0_brcrh3    0x073               /* bus region register 3 high    */
+#define ebiu0_brcrh4    0x074               /* bus region register 4 high    */
+#define ebiu0_brcrh5    0x075               /* bus region register 5 high    */
+#define ebiu0_brcrh6    0x076               /* bus region register 6 high    */
+#define ebiu0_brcrh7    0x077               /* bus region register 7 high    */
+#define ebiu0_brcr0     0x080               /* bus region register 0         */
+#define ebiu0_brcr1     0x081               /* bus region register 1         */
+#define ebiu0_brcr2     0x082               /* bus region register 2         */
+#define ebiu0_brcr3     0x083               /* bus region register 3         */
+#define ebiu0_brcr4     0x084               /* bus region register 4         */
+#define ebiu0_brcr5     0x085               /* bus region register 5         */
+#define ebiu0_brcr6     0x086               /* bus region register 6         */
+#define ebiu0_brcr7     0x087               /* bus region register 7         */
+#define ebiu0_bear      0x090               /* bus error address register    */
+#define ebiu0_besr      0x091               /* bus error syndrome reg        */
+#define ebiu0_besr0s    0x093               /* bus error syndrome reg        */
+#define ebiu0_biucr     0x09a               /* bus interface control reg     */
+
+/*----------------------------------------------------------------------------+
+| OPB bridge.
++----------------------------------------------------------------------------*/
+#define opbw0_gesr      0x0b0               /* error status reg              */
+#define opbw0_gesrs     0x0b1               /* error status reg              */
+#define opbw0_gear      0x0b2               /* error address reg             */
+
+/*----------------------------------------------------------------------------+
+| DMA.
++----------------------------------------------------------------------------*/
+#define dma0_cr0        0x0c0               /* DMA channel control reg 0     */
+#define dma0_ct0        0x0c1               /* DMA count register 0          */
+#define dma0_da0        0x0c2               /* DMA destination addr reg 0    */
+#define dma0_sa0        0x0c3               /* DMA source addr register 0    */
+#define dma0_cc0        0x0c4               /* DMA chained count 0           */
+#define dma0_cr1        0x0c8               /* DMA channel control reg 1     */
+#define dma0_ct1        0x0c9               /* DMA count register 1          */
+#define dma0_da1        0x0ca               /* DMA destination addr reg 1    */
+#define dma0_sa1        0x0cb               /* DMA source addr register 1    */
+#define dma0_cc1        0x0cc               /* DMA chained count 1           */
+#define dma0_cr2        0x0d0               /* DMA channel control reg 2     */
+#define dma0_ct2        0x0d1               /* DMA count register 2          */
+#define dma0_da2        0x0d2               /* DMA destination addr reg 2    */
+#define dma0_sa2        0x0d3               /* DMA source addr register 2    */
+#define dma0_cc2        0x0d4               /* DMA chained count 2           */
+#define dma0_cr3        0x0d8               /* DMA channel control reg 3     */
+#define dma0_ct3        0x0d9               /* DMA count register 3          */
+#define dma0_da3        0x0da               /* DMA destination addr reg 3    */
+#define dma0_sa3        0x0db               /* DMA source addr register 3    */
+#define dma0_cc3        0x0dc               /* DMA chained count 3           */
+#define dma0_sr         0x0e0               /* DMA status register           */
+#define dma0_srs        0x0e1               /* DMA status register           */
+#define dma0_s1         0x031               /* DMA select1 register          */
+#define dma0_s2         0x032               /* DMA select2 register          */
+
+/*---------------------------------------------------------------------------+
+| Clock and power management.
++----------------------------------------------------------------------------*/
+#define cpm0_fr         0x102               /* force register                */
+
+/*----------------------------------------------------------------------------+
+| Serial Clock Control.
++----------------------------------------------------------------------------*/
+#define ser0_ccr        0x120               /* serial clock control register */
+
+/*----------------------------------------------------------------------------+
+| Audio Clock Control.
++----------------------------------------------------------------------------*/
+#define aud0_apcr       0x121               /* audio clock ctrl register     */
+
+/*----------------------------------------------------------------------------+
+| DENC.
++----------------------------------------------------------------------------*/
+#define denc0_idr       0x130               /* DENC ID register              */
+#define denc0_cr1       0x131               /* control register 1            */
+#define denc0_rr1       0x132               /* microvision 1 (reserved 1)    */
+#define denc0_cr2       0x133               /* control register 2            */
+#define denc0_rr2       0x134               /* microvision 2 (reserved 2)    */
+#define denc0_rr3       0x135               /* microvision 3 (reserved 3)    */
+#define denc0_rr4       0x136               /* microvision 4 (reserved 4)    */
+#define denc0_rr5       0x137               /* microvision 5 (reserved 5)    */
+#define denc0_ccdr      0x138               /* closed caption data           */
+#define denc0_cccr      0x139               /* closed caption control        */
+#define denc0_trr       0x13A               /* teletext request register     */
+#define denc0_tosr      0x13B               /* teletext odd field line se    */
+#define denc0_tesr      0x13C               /* teletext even field line s    */
+#define denc0_rlsr      0x13D               /* RGB rhift left register       */
+#define denc0_vlsr      0x13E               /* video level shift register    */
+#define denc0_vsr       0x13F               /* video scaling register        */
+
+/*----------------------------------------------------------------------------+
+| Video decoder.  Suspect 0x179, 0x169, 0x16a, 0x152 (rc).
++----------------------------------------------------------------------------*/
+#define vid0_ccntl      0x140               /* control decoder operation     */
+#define vid0_cmode      0x141               /* video operational mode        */
+#define vid0_sstc0      0x142               /* STC high order bits 31:0      */
+#define vid0_sstc1      0x143               /* STC low order bit 32          */
+#define vid0_spts0      0x144               /* PTS high order bits 31:0      */
+#define vid0_spts1      0x145               /* PTS low order bit 32          */
+#define vid0_fifo       0x146               /* FIFO data port                */
+#define vid0_fifos      0x147               /* FIFO status                   */
+#define vid0_cmd        0x148               /* send command to decoder       */
+#define vid0_cmdd       0x149               /* port for command params       */
+#define vid0_cmdst      0x14A               /* command status                */
+#define vid0_cmdad      0x14B               /* command address               */
+#define vid0_procia     0x14C               /* instruction store             */
+#define vid0_procid     0x14D               /* data port for I_Store         */
+#define vid0_osdm       0x151               /* OSD mode control              */
+#define vid0_hosti      0x152               /* base interrupt register       */
+#define vid0_mask       0x153               /* interrupt mask register       */
+#define vid0_dispm      0x154               /* operational mode for Disp     */
+#define vid0_dispd      0x155               /* setting for 'Sync' delay      */
+#define vid0_vbctl      0x156               /* VBI                           */
+#define vid0_ttxctl     0x157               /* teletext control              */
+#define vid0_disptb     0x158               /* display left/top border       */
+#define vid0_osdgla     0x159               /* Graphics plane link addr      */
+#define vid0_osdila     0x15A               /* Image plane link addr         */
+#define vid0_rbthr      0x15B               /* rate buffer threshold         */
+#define vid0_osdcla     0x15C               /* Cursor link addr              */
+#define vid0_stcca      0x15D               /* STC common address            */
+#define vid0_ptsctl     0x15F               /* PTS Control                   */
+#define vid0_wprot      0x165               /* write protect for I_Store     */
+#define vid0_vcqa       0x167               /* video clip queued block Ad    */
+#define vid0_vcql       0x168               /* video clip queued block Le    */
+#define vid0_blksz      0x169               /* block size bytes for copy op  */
+#define vid0_srcad      0x16a               /* copy source address bits 6-31 */
+#define vid0_udbas      0x16B               /* base mem add for user data    */
+#define vid0_vbibas     0x16C               /* base mem add for VBI 0/1      */
+#define vid0_osdibas    0x16D               /* Image plane base address      */
+#define vid0_osdgbas    0x16E               /* Graphic plane base address    */
+#define vid0_rbbase     0x16F               /* base mem add for video buf    */
+#define vid0_dramad     0x170               /* DRAM address                  */
+#define vid0_dramdt     0x171               /* data port for DRAM access     */
+#define vid0_dramcs     0x172               /* DRAM command and statusa      */
+#define vid0_vcwa       0x173               /* v clip work address           */
+#define vid0_vcwl       0x174               /* v clip work length            */
+#define vid0_mseg0      0x175               /* segment address 0             */
+#define vid0_mseg1      0x176               /* segment address 1             */
+#define vid0_mseg2      0x177               /* segment address 2             */
+#define vid0_mseg3      0x178               /* segment address 3             */
+#define vid0_fbbase     0x179               /* frame buffer base memory      */
+#define vid0_osdcbas    0x17A               /* Cursor base addr              */
+#define vid0_lboxtb     0x17B               /* top left border               */
+#define vid0_trdly      0x17C               /* transparency gate delay       */
+#define vid0_sbord      0x17D               /* left/top small pict. bord.    */
+#define vid0_zoffs      0x17E               /* hor/ver zoom window           */
+#define vid0_rbsz       0x17F               /* rate buffer size read         */
+
+/*----------------------------------------------------------------------------+
+| Transport demultiplexer.
++----------------------------------------------------------------------------*/
+#define xpt0_lr         0x180               /* demux location register       */
+#define xpt0_data       0x181               /* demux data register           */
+#define xpt0_ir         0x182               /* demux interrupt register      */
+
+#define xpt0_config1    0x0000              /* configuration 1               */
+#define xpt0_control1   0x0001              /* control 1                     */
+#define xpt0_festat     0x0002              /* Front-end status              */
+#define xpt0_feimask    0x0003              /* Front_end interrupt Mask      */
+#define xpt0_ocmcnfg    0x0004              /* OCM Address                   */
+#define xpt0_settapi    0x0005              /* Set TAP Interrupt             */
+
+#define xpt0_pcrhi      0x0010              /* PCR High                      */
+#define xpt0_pcrlow     0x0011              /* PCR Low                       */
+#define xpt0_lstchi     0x0012              /* Latched STC High              */
+#define xpt0_lstclow    0x0013              /* Latched STC Low               */
+#define xpt0_stchi      0x0014              /* STC High                      */
+#define xpt0_stclow     0x0015              /* STC Low                       */
+#define xpt0_pwm        0x0016              /* PWM                           */
+#define xpt0_pcrstct    0x0017              /* PCR-STC Threshold             */
+#define xpt0_pcrstcd    0x0018              /* PCR-STC Delta                 */
+#define xpt0_stccomp    0x0019              /* STC Compare                   */
+#define xpt0_stccmpd    0x001a              /* STC Compare Disarm            */
+
+#define xpt0_dsstat     0x0048              /* Descrambler Status            */
+#define xpt0_dsimask    0x0049              /* Descrambler Interrupt Mask    */
+
+#define xpt0_vcchng     0x01f0              /* Video Channel Change          */
+#define xpt0_acchng     0x01f1              /* Audio Channel Change          */
+#define xpt0_axenable   0x01fe              /* Aux PID Enables               */
+#define xpt0_pcrpid     0x01ff              /* PCR PID                       */
+
+#define xpt0_config2    0x1000              /* Configuration 2               */
+#define xpt0_pbuflvl    0x1002              /* Packet Buffer Level           */
+#define xpt0_intmask    0x1003              /* Interrupt Mask                */
+#define xpt0_plbcnfg    0x1004              /* PLB Configuration             */
+
+#define xpt0_qint       0x1010              /* Queues Interrupts             */
+#define xpt0_qintmsk    0x1011              /* Queues Interrupts Mask        */
+#define xpt0_astatus    0x1012              /* Audio Status                  */
+#define xpt0_aintmask   0x1013              /* Audio Interrupt Mask          */
+#define xpt0_vstatus    0x1014              /* Video Status                  */
+#define xpt0_vintmask   0x1015              /* Video Interrupt Mask          */
+
+#define xpt0_qbase      0x1020              /* Queue Base                    */
+#define xpt0_bucketq    0x1021              /* Bucket Queue                  */
+#define xpt0_qstops     0x1024              /* Queue Stops                   */
+#define xpt0_qresets    0x1025              /* Queue Resets                  */
+#define xpt0_sfchng     0x1026              /* Section Filter Change         */
+
+/*----------------------------------------------------------------------------+
+| Audio decoder. Suspect 0x1ad, 0x1b4, 0x1a3, 0x1a5 (read/write status)
++----------------------------------------------------------------------------*/
+#define aud0_ctrl0      0x1a0               /* control 0                     */
+#define aud0_ctrl1      0x1a1               /* control 1                     */
+#define aud0_ctrl2      0x1a2               /* control 2                     */
+#define aud0_cmd        0x1a3               /* command register              */
+#define aud0_isr        0x1a4               /* interrupt status register     */
+#define aud0_imr        0x1a5               /* interrupt mask register       */
+#define aud0_dsr        0x1a6               /* decoder status register       */
+#define aud0_stc        0x1a7               /* system time clock             */
+#define aud0_csr        0x1a8               /* channel status register       */
+#define aud0_lcnt       0x1a9               /* queued address register 2     */
+#define aud0_pts        0x1aa               /* presentation time stamp       */
+#define aud0_tgctrl     0x1ab               /* tone generation control       */
+#define aud0_qlr2       0x1ac               /* queued length register 2      */
+#define aud0_auxd       0x1ad               /* aux data                      */
+#define aud0_strmid     0x1ae               /* stream ID                     */
+#define aud0_qar        0x1af               /* queued address register       */
+#define aud0_dsps       0x1b0               /* DSP status                    */
+#define aud0_qlr        0x1b1               /* queued len address            */
+#define aud0_dspc       0x1b2               /* DSP control                   */
+#define aud0_wlr2       0x1b3               /* working length register 2     */
+#define aud0_instd      0x1b4               /* instruction download          */
+#define aud0_war        0x1b5               /* working address register      */
+#define aud0_seg1       0x1b6               /* segment 1 base register       */
+#define aud0_seg2       0x1b7               /* segment 2 base register       */
+#define aud0_avf        0x1b9               /* audio att value front         */
+#define aud0_avr        0x1ba               /* audio att value rear          */
+#define aud0_avc        0x1bb               /* audio att value center        */
+#define aud0_seg3       0x1bc               /* segment 3 base register       */
+#define aud0_offset     0x1bd               /* offset address                */
+#define aud0_wrl        0x1be               /* working length register       */
+#define aud0_war2       0x1bf               /* working address register 2    */
+
+/*----------------------------------------------------------------------------+
+| High speed memory controller 0 and 1.
++----------------------------------------------------------------------------*/
+#define hsmc0_gr        0x1e0               /* HSMC global register          */
+#define hsmc0_besr      0x1e1               /* bus error status register     */
+#define hsmc0_bear      0x1e2               /* bus error address register    */
+#define hsmc0_br0       0x1e4               /* SDRAM sub-ctrl bank reg 0     */
+#define hsmc0_cr0       0x1e5               /* SDRAM sub-ctrl ctrl reg 0     */
+#define hsmc0_br1       0x1e7               /* SDRAM sub-ctrl bank reg 1     */
+#define hsmc0_cr1       0x1e8               /* SDRAM sub-ctrl ctrl reg 1     */
+#define hsmc0_sysr      0x1f1               /* system register               */
+#define hsmc0_data      0x1f2               /* data register                 */
+#define hsmc0_crr       0x1f3               /* refresh register              */
+
+#define hsmc1_gr        0x1c0               /* HSMC global register          */
+#define hsmc1_besr      0x1c1               /* bus error status register     */
+#define hsmc1_bear      0x1c2               /* bus error address register    */
+#define hsmc1_br0       0x1c4               /* SDRAM sub-ctrl bank reg 0     */
+#define hsmc1_cr0       0x1c5               /* SDRAM sub-ctrl ctrl reg 0     */
+#define hsmc1_br1       0x1c7               /* SDRAM sub-ctrl bank reg 1     */
+#define hsmc1_cr1       0x1c8               /* SDRAM sub-ctrl ctrl reg 1     */
+#define hsmc1_sysr      0x1d1               /* system register               */
+#define hsmc1_data      0x1d2               /* data register                 */
+#define hsmc1_crr       0x1d3               /* refresh register              */
+
+/*----------------------------------------------------------------------------+
+| Machine State Register bit definitions.
++----------------------------------------------------------------------------*/
+#define msr_ape         0x00100000
+#define msr_apa         0x00080000
+#define msr_we          0x00040000
+#define msr_ce          0x00020000
+#define msr_ile         0x00010000
+#define msr_ee          0x00008000
+#define msr_pr          0x00004000
+#define msr_me          0x00001000
+#define msr_de          0x00000200
+#define msr_ir          0x00000020
+#define msr_dr          0x00000010
+#define msr_le          0x00000001
+
+/*----------------------------------------------------------------------------+
+| Used during interrupt processing.
++----------------------------------------------------------------------------*/
+#define stack_reg_image_size            160
+
+/*----------------------------------------------------------------------------+
+| Function prolog definition and other Metaware (EABI) defines.
++----------------------------------------------------------------------------*/
+#ifdef MW
+
+#define r0              0
+#define r1              1
+#define r2              2
+#define r3              3
+#define r4              4
+#define r5              5
+#define r6              6
+#define r7              7
+#define r8              8
+#define r9              9
+#define r10             10
+#define r11             11
+#define r12             12
+#define r13             13
+#define r14             14
+#define r15             15
+#define r16             16
+#define r17             17
+#define r18             18
+#define r19             19
+#define r20             20
+#define r21             21
+#define r22             22
+#define r23             23
+#define r24             24
+#define r25             25
+#define r26             26
+#define r27             27
+#define r28             28
+#define r29             29
+#define r30             30
+#define r31             31
+
+#define cr0             0
+#define cr1             1
+#define cr2             2
+#define cr3             3
+#define cr4             4
+#define cr5             5
+#define cr6             6
+#define cr7             7
+
+#define function_prolog(func_name)      .text; \
+                                        .align  2; \
+                                        .globl  func_name; \
+                                        func_name:
+#define function_epilog(func_name)      .type func_name,@function; \
+                                        .size func_name,.-func_name
+
+#define function_call(func_name)        bl func_name
+
+#define stack_frame_min                 8
+#define stack_frame_bc                  0
+#define stack_frame_lr                  4
+#define stack_neg_off                   0
+
+#endif
+
+/*----------------------------------------------------------------------------+
+| Function prolog definition and other DIAB (Elf) defines.
++----------------------------------------------------------------------------*/
+#ifdef ELF_DIAB
+
+fprolog:        macro   f_name
+                .text
+                .align  2
+                .globl  f_name
+f_name:
+                endm
+
+fepilog:        macro   f_name
+                .type   f_name,@function
+                .size   f_name,.-f_name
+                endm
+
+#define function_prolog(func_name)      fprolog func_name
+#define function_epilog(func_name)      fepilog func_name
+#define function_call(func_name)        bl func_name
+
+#define stack_frame_min                 8
+#define stack_frame_bc                  0
+#define stack_frame_lr                  4
+#define stack_neg_off                   0
+
+#endif
+
+/*----------------------------------------------------------------------------+
+| Function prolog definition and other Xlc (XCOFF) defines.
++----------------------------------------------------------------------------*/
+#ifdef XCOFF
+
+.machine "403ga"
+
+#define r0              0
+#define r1              1
+#define r2              2
+#define r3              3
+#define r4              4
+#define r5              5
+#define r6              6
+#define r7              7
+#define r8              8
+#define r9              9
+#define r10             10
+#define r11             11
+#define r12             12
+#define r13             13
+#define r14             14
+#define r15             15
+#define r16             16
+#define r17             17
+#define r18             18
+#define r19             19
+#define r20             20
+#define r21             21
+#define r22             22
+#define r23             23
+#define r24             24
+#define r25             25
+#define r26             26
+#define r27             27
+#define r28             28
+#define r29             29
+#define r30             30
+#define r31             31
+
+#define cr0             0
+#define cr1             1
+#define cr2             2
+#define cr3             3
+#define cr4             4
+#define cr5             5
+#define cr6             6
+#define cr7             7
+
+#define function_prolog(func_name)      .csect .func_name[PR]; \
+                                        .globl .func_name[PR]; \
+                                        func_name:
+
+#define function_epilog(func_name)      .toc; \
+                                        .csect  func_name[DS]; \
+                                        .globl  func_name[DS]; \
+                                        .long   .func_name[PR]; \
+                                        .long   TOC[tc0]
+
+#define function_call(func_name)        .extern .func_name[PR]; \
+                                        stw     r2,stack_frame_toc(r1); \
+                                        mfspr   r2,sprg0; \
+                                        bl      .func_name[PR]; \
+                                        lwz     r2,stack_frame_toc(r1)
+
+#define stack_frame_min                 56
+#define stack_frame_bc                  0
+#define stack_frame_lr                  8
+#define stack_frame_toc                 20
+#define stack_neg_off                   276
+
+#endif
+#define function_prolog(func_name)      .text; \
+                                        .align  2; \
+                                        .globl  func_name; \
+                                        func_name:
+#define function_epilog(func_name)      .type func_name,@function; \
+                                        .size func_name,.-func_name
+
+#define function_call(func_name)        bl func_name
+
+/*----------------------------------------------------------------------------+
+| Function prolog definition for GNU
++----------------------------------------------------------------------------*/
+#ifdef _GNU_TOOL
+
+#define function_prolog(func_name)      .globl  func_name; \
+                                        func_name:
+#define function_epilog(func_name)
+
+#endif
diff --git a/arch/ppc/boot/simple/rw4/rw4_init.S b/arch/ppc/boot/simple/rw4/rw4_init.S
new file mode 100644
index 0000000..b106196
--- /dev/null
+++ b/arch/ppc/boot/simple/rw4/rw4_init.S
@@ -0,0 +1,78 @@
+#define VESTA
+#include "ppc_40x.h"
+#
+        .align 2
+        .text
+#
+# added by linguohui
+        .extern   initb_ebiu0, initb_config, hdw_init_finish
+        .extern   initb_hsmc0, initb_hsmc1, initb_cache
+# end added
+       .globl    HdwInit
+#
+HdwInit:
+#
+#-----------------------------------------------------------------------*
+# If we are not executing from the FLASH get out                        *
+#-----------------------------------------------------------------------*
+# SAW keep this or comment out a la Hawthorne?
+# r3 contains NIP when used with Linux
+#        rlwinm r28, r3, 8, 24, 31    # if MSB == 0xFF -> FLASH address
+#        cmpwi  r28, 0xff
+#        bne    locn01
+#
+#
+#------------------------------------------------------------------------
+# Init_cpu. Bank registers are setup for the IBM STB.
+#------------------------------------------------------------------------
+#
+# Setup processor core clock to be driven off chip.  This is GPI4 bit
+# twenty.  Setup Open Drain, Output Select, Three-State Control,  and
+# Three-State Select registers.
+#
+
+
+        pb0pesr  =        0x054
+        pb0pear  =        0x056
+
+	mflr	r30
+
+#-----------------------------------------------------------------------------
+# Vectors will be at 0x1F000000
+# Dummy Machine check handler just does RFI before true handler gets installed
+#-----------------------------------------------------------------------------
+#if 1  /* xuwentao added*/
+#ifdef SDRAM16MB
+         lis     r10,0x0000
+	addi 	r10,r10,0x0000
+#else
+        lis      r10,0x1F00
+	addi	r10,r10,0x0000
+#endif
+
+        mtspr   evpr,r10              #EVPR: 0x0 or 0x1f000000 depending
+        isync                         # on SDRAM memory model used.
+
+        lis     r10,0xFFFF                # clear PB0_PESR because some
+        ori    r10,r10,0xFFFF            #  transitions from flash,changed by linguohui
+        mtdcr   pb0pesr,r10               #  to load RAM image via RiscWatch
+        lis     r10,0x0000                #  cause PB0_PESR machine checks
+        mtdcr   pb0pear,r10
+        addis   r10,r10,0x0000            # clear the
+        mtxer   r10                       #           XER just in case...
+#endif /* xuwentao*/
+
+        bl      initb_ebiu0                      # init EBIU
+
+        bl      initb_config                     # config PPC and board
+
+
+
+
+#------------------------------------------------------------------------
+# EVPR  setup moved to top of this function.
+#------------------------------------------------------------------------
+#
+	mtlr	r30
+	blr
+        .end
diff --git a/arch/ppc/boot/simple/rw4/rw4_init_brd.S b/arch/ppc/boot/simple/rw4/rw4_init_brd.S
new file mode 100644
index 0000000..386afda
--- /dev/null
+++ b/arch/ppc/boot/simple/rw4/rw4_init_brd.S
@@ -0,0 +1,1125 @@
+/*----------------------------------------------------------------------------+
+|       This source code has been made available to you by IBM on an AS-IS
+|       basis.  Anyone receiving this source is licensed under IBM
+|       copyrights to use it in any way he or she deems fit, including
+|       copying it, modifying it, compiling it, and redistributing it either
+|       with or without modifications.  No license under IBM patents or
+|       patent applications is to be implied by the copyright license.
+|
+|       Any user of this software should understand that IBM cannot provide
+|       technical support for this software and will not be responsible for
+|       any consequences resulting from the use of this software.
+|
+|       Any person who transfers this source code or any derivative work
+|       must include the IBM copyright notice, this paragraph, and the
+|       preceding two paragraphs in the transferred software.
+|
+|       COPYRIGHT   I B M   CORPORATION 1997
+|       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+| Author:    Tony J. Cerreto
+| Component: BSPS
+| File:      init_brd.s
+| Purpose:   Vesta Evaluation Board initialization subroutines.  The following
+|            routines are available:
+|              1. INITB_EBIU0:    Initialize EBIU0.
+|              2. INITB_CONFIG:   Configure board.
+|              3. INITB_HSMC0:    Initialize HSMC0 (SDRAM).
+|              4. INITB_HSMC1:    Initialize HSMC1 (SDRAM).
+|              5. INITB_CACHE:    Initialize Data and Instruction Cache.
+|              6. INITB_DCACHE:   Initialize Data Cache.
+|              7. INITB_ICACHE:   Initialize Instruction Cache.
+|              8. INITB_GET_CSPD: Get CPU Speed (Bus Speed and Processor Speed)
+|
+| Changes:
+| Date:      Author  Comment:
+| ---------  ------  --------
+| 01-Mar-00  tjc     Created
+| 04-Mar-00  jfh     Modified CIC_SEL3_VAL to support 1284 (Mux3 & GPIO 21-28)
+| 04-Mar-00  jfh     Modified XILINIX Reg 0 to support 1284 (Mux3 & GPIO 21-28)
+| 04-Mar-00  jfh     Modified XILINIX Reg 1 to support 1284 (Mux3 & GPIO 21-28)
+| 04-Mar-00  jfh     Modified XILINIX Reg 4 to support 1284 (Mux3 & GPIO 21-28)
+| 19-May-00  rlb     Relcoated HSMC0 to 0x1F000000 to support 32MB of contiguous
+|                    SDRAM space.  Changed cache ctl regs to reflect this.
+| 22-May-00  tjc     Changed initb_get_cspd interface and eliminated
+|                    initb_get_bspd routines.
+| 26-May-00  tjc     Added two nop instructions after all mtxxx/mfxxx
+|                    instructions due to PPC405 bug.
++----------------------------------------------------------------------------*/
+#define VESTA
+#include "ppc_40x.h"
+#include "stb.h"
+
+/*----------------------------------------------------------------------------+
+| BOARD CONFIGURATION DEFINES
++----------------------------------------------------------------------------*/
+#define CBS0_CR_VAL          0x00000002          /* CBS control reg value    */
+#define CIC0_CR_VAL          0xD0800448          /* CIC control reg value    */
+#define CIC0_SEL3_VAL        0x11500000          /* CIC select 3 reg value   */
+#define CIC0_VCR_VAL         0x00631700          /* CIC video cntl reg value */
+
+/*----------------------------------------------------------------------------+
+| EBIU0 BANK REGISTERS DEFINES
++----------------------------------------------------------------------------*/
+#define EBIU0_BRCRH0_VAL     0x00000000          /* BR High 0 (Extension Reg)*/
+#define EBIU0_BRCRH1_VAL     0x00000000          /* BR High 1 (Extension Reg)*/
+#define EBIU0_BRCRH2_VAL     0x40000000          /* BR High 2 (Extension Reg)*/
+#define EBIU0_BRCRH3_VAL     0x40000000          /* BR High 3 (Extension Reg)*/
+#define EBIU0_BRCRH4_VAL     0x00000000          /* BR High 4 (Extension Reg)*/
+#define EBIU0_BRCRH5_VAL     0x00000000          /* BR High 5 (Extension Reg)*/
+#define EBIU0_BRCRH6_VAL     0x00000000          /* BR High 6 (Extension Reg)*/
+#define EBIU0_BRCRH7_VAL     0x40000000          /* BR High 7 (Extension Reg)*/
+
+#define EBIU0_BRCR0_VAL      0xFC58BFFE          /* BR 0: 16 bit Flash  4 MB */
+#define EBIU0_BRCR1_VAL      0xFF00BFFE          /* BR 1: Ext Connector 1 MB */
+#if 1
+#define EBIU0_BRCR2_VAL      0x207CFFBE          /* BR 2: Xilinx        8 MB */
+                                                 /* twt == 0x3f              */
+#else
+#define EBIU0_BRCR2_VAL      0x207CCFBE          /* BR 2: Xilinx        8 MB */
+                                                 /* twt == 0x0f              */
+#endif
+#define EBIU0_BRCR3_VAL      0x407CBFBE          /* BR 3: IDE Drive     8 MB */
+#define EBIU0_BRCR4_VAL      0xFF00BFFF          /* BR 4: Disabled.     0 MB */
+#define EBIU0_BRCR5_VAL      0xFF00BFFF          /* BR 5: Disabled.     0 MB */
+#define EBIU0_BRCR6_VAL      0xFF00BFFF          /* BR 6: Disabled.     0 MB */
+#define EBIU0_BRCR7_VAL      0xCE3F0003          /* BR 7: Line Mode DMA 2 MB */
+
+/*----------------------------------------------------------------------------+
+| GPIO DEFINES
++----------------------------------------------------------------------------*/
+#define STB_GPIO0_OUTPUT     (STB_GPIO0_BASE_ADDRESS+ 0x00)
+#define STB_GPIO0_TC         (STB_GPIO0_BASE_ADDRESS+ 0x04)
+#define STB_GPIO0_OS_0_31    (STB_GPIO0_BASE_ADDRESS+ 0x08)
+#define STB_GPIO0_OS_32_63   (STB_GPIO0_BASE_ADDRESS+ 0x0C)
+#define STB_GPIO0_TS_0_31    (STB_GPIO0_BASE_ADDRESS+ 0x10)
+#define STB_GPIO0_TS_32_63   (STB_GPIO0_BASE_ADDRESS+ 0x14)
+#define STB_GPIO0_OD         (STB_GPIO0_BASE_ADDRESS+ 0x18)
+#define STB_GPIO0_INPUT      (STB_GPIO0_BASE_ADDRESS+ 0x1C)
+#define STB_GPIO0_R1         (STB_GPIO0_BASE_ADDRESS+ 0x20)
+#define STB_GPIO0_R2         (STB_GPIO0_BASE_ADDRESS+ 0x24)
+#define STB_GPIO0_R3         (STB_GPIO0_BASE_ADDRESS+ 0x28)
+#define STB_GPIO0_IS_1_0_31  (STB_GPIO0_BASE_ADDRESS+ 0x30)
+#define STB_GPIO0_IS_1_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x34)
+#define STB_GPIO0_IS_2_0_31  (STB_GPIO0_BASE_ADDRESS+ 0x38)
+#define STB_GPIO0_IS_2_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x3C)
+#define STB_GPIO0_IS_3_0_31  (STB_GPIO0_BASE_ADDRESS+ 0x40)
+#define STB_GPIO0_IS_3_32_63 (STB_GPIO0_BASE_ADDRESS+ 0x44)
+#define STB_GPIO0_SS_1       (STB_GPIO0_BASE_ADDRESS+ 0x50)
+#define STB_GPIO0_SS_2       (STB_GPIO0_BASE_ADDRESS+ 0x54)
+#define STB_GPIO0_SS_3       (STB_GPIO0_BASE_ADDRESS+ 0x58)
+
+#define GPIO0_TC_VAL         0x0C020004          /* three-state control val  */
+#define GPIO0_OS_0_31_VAL    0x51A00004          /* output select 0-31  val  */
+#define GPIO0_OS_32_63_VAL   0x0000002F          /* output select 32-63 val  */
+#define GPIO0_TS_0_31_VAL    0x51A00000          /* three-state sel 0-31  val*/
+#define GPIO0_TS_32_63_VAL   0x0000000F          /* three-state sel 32-63 val*/
+#define GPIO0_OD_VAL         0xC0000004          /* open drain val           */
+#define GPIO0_IS_1_0_31_VAL  0x50000151          /* input select 1 0-31  val */
+#define GPIO0_IS_1_32_63_VAL 0x00000000          /* input select 1 32-63 val */
+#define GPIO0_IS_2_0_31_VAL  0x00000000          /* input select 2 0-31  val */
+#define GPIO0_IS_2_32_63_VAL 0x00000000          /* input select 2 32-63 val */
+#define GPIO0_IS_3_0_31_VAL  0x00000440          /* input select 3 0-31  val */
+#define GPIO0_IS_3_32_63_VAL 0x00000000          /* input select 3 32-63 val */
+#define GPIO0_SS_1_VAL       0x00000000          /* sync select 1 val        */
+#define GPIO0_SS_2_VAL       0x00000000          /* sync select 2 val        */
+#define GPIO0_SS_3_VAL       0x00000000          /* sync select 3 val        */
+
+/*----------------------------------------------------------------------------+
+| XILINX DEFINES
++----------------------------------------------------------------------------*/
+#define STB_XILINX_LED       (STB_FPGA_BASE_ADDRESS+ 0x0100)
+#define STB_XILINX1_REG0     (STB_FPGA_BASE_ADDRESS+ 0x40000)
+#define STB_XILINX1_REG1     (STB_FPGA_BASE_ADDRESS+ 0x40002)
+#define STB_XILINX1_REG2     (STB_FPGA_BASE_ADDRESS+ 0x40004)
+#define STB_XILINX1_REG3     (STB_FPGA_BASE_ADDRESS+ 0x40006)
+#define STB_XILINX1_REG4     (STB_FPGA_BASE_ADDRESS+ 0x40008)
+#define STB_XILINX1_REG5     (STB_FPGA_BASE_ADDRESS+ 0x4000A)
+#define STB_XILINX1_REG6     (STB_FPGA_BASE_ADDRESS+ 0x4000C)
+#define STB_XILINX1_ID       (STB_FPGA_BASE_ADDRESS+ 0x4000E)
+#define STB_XILINX1_FLUSH    (STB_FPGA_BASE_ADDRESS+ 0x4000E)
+#define STB_XILINX2_REG0     (STB_FPGA_BASE_ADDRESS+ 0x80000)
+#define STB_XILINX2_REG1     (STB_FPGA_BASE_ADDRESS+ 0x80002)
+#define STB_XILINX2_REG2     (STB_FPGA_BASE_ADDRESS+ 0x80004)
+
+#define XILINX1_R0_VAL       0x2440              /* Xilinx 1 Register 0 Val  */
+#define XILINX1_R1_VAL       0x0025              /* Xilinx 1 Register 1 Val  */
+#define XILINX1_R2_VAL       0x0441              /* Xilinx 1 Register 2 Val  */
+#define XILINX1_R3_VAL       0x0008              /* Xilinx 1 Register 3 Val  */
+#define XILINX1_R4_VAL       0x0100              /* Xilinx 1 Register 4 Val  */
+#define XILINX1_R5_VAL       0x6810              /* Xilinx 1 Register 5 Val  */
+#define XILINX1_R6_VAL       0x0000              /* Xilinx 1 Register 6 Val  */
+#if 0
+#define XILINX2_R0_VAL       0x0008              /* Xilinx 2 Register 0 Val  */
+#define XILINX2_R1_VAL       0x0000              /* Xilinx 2 Register 1 Val  */
+#else
+#define XILINX2_R0_VAL       0x0018              /* disable IBM IrDA RxD     */
+#define XILINX2_R1_VAL       0x0008              /* enable SICC MAX chip     */
+#endif
+#define XILINX2_R2_VAL       0x0000              /* Xilinx 2 Register 2 Val  */
+
+/*----------------------------------------------------------------------------+
+| HSMC BANK REGISTERS DEFINES
++----------------------------------------------------------------------------*/
+#ifdef SDRAM16MB
+#define HSMC0_BR0_VAL        0x000D2D55          /* 0x1F000000-007FFFFF R/W  */
+#define HSMC0_BR1_VAL        0x008D2D55          /* 0x1F800000-1FFFFFFF R/W  */
+#else
+#define HSMC0_BR0_VAL        0x1F0D2D55          /* 0x1F000000-007FFFFF R/W  */
+#define HSMC0_BR1_VAL        0x1F8D2D55          /* 0x1F800000-1FFFFFFF R/W  */
+#endif
+#define HSMC1_BR0_VAL        0xA00D2D55          /* 0xA0000000-A07FFFFF R/W  */
+#define HSMC1_BR1_VAL        0xA08D2D55          /* 0xA0800000-A0FFFFFF R/W  */
+
+/*----------------------------------------------------------------------------+
+| CACHE DEFINES
++----------------------------------------------------------------------------*/
+#define DCACHE_NLINES               128          /* no. D-cache lines        */
+#define DCACHE_NBYTES                32          /* no. bytes/ D-cache line  */
+#define ICACHE_NLINES               256          /* no. I-cache lines        */
+#define ICACHE_NBYTES                32          /* no. bytes/ I-cache line  */
+#ifdef SDRAM16MB
+#define DCACHE_ENABLE        0x80000000          /* D-cache regions to enable*/
+#define ICACHE_ENABLE        0x80000001          /* I-cache regions to enable*/
+#else
+#define DCACHE_ENABLE        0x18000000          /* D-cache regions to enable*/
+#define ICACHE_ENABLE        0x18000001          /* I-cache regions to enable*/
+#endif
+
+/*----------------------------------------------------------------------------+
+| CPU CORE SPEED CALCULATION DEFINES
++----------------------------------------------------------------------------*/
+#define GCS_LCNT                 500000          /* CPU speed loop count     */
+#define GCS_TROW_BYTES                8          /* no. bytes in table row   */
+#define GCS_CTICK_TOL               100          /* allowable clock tick tol */
+#define GCS_NMULT                     4          /* no. of core speed mults  */
+
+        /*--------------------------------------------------------------------+
+        |        No. 13.5Mhz
+        |        Clock Ticks
+        |        based on a
+        |        loop count    Bus
+        |        of 100,000    Speed
+        +--------------------------------------------------------------------*/
+gcs_lookup_table:
+        .int           50000,  54000000          /* 54.0 Mhz                 */
+        .int           66667,  40500000          /* 40.5 Mhz                 */
+        .int           54545,  49500000          /* 49.5 Mhz                 */
+        .int           46154,  58500000          /* 58.5 Mhz                 */
+        .int               0,         0          /* end of table flag        */
+
+
+/*****************************************************************************+
+| XXXXXXX  XXX XXX   XXXXXX  XXXXXXX  XXXXXX   XX   XX     XX    XXXX
+|  XX   X   XX XX    X XX X   XX   X   XX  XX  XXX  XX    XXXX    XX
+|  XX X      XXX       XX     XX X     XX  XX  XXXX XX   XX  XX   XX
+|  XXXX       X        XX     XXXX     XXXXX   XX XXXX   XX  XX   XX
+|  XX X      XXX       XX     XX X     XX XX   XX  XXX   XXXXXX   XX
+|  XX   X   XX XX      XX     XX   X   XX  XX  XX   XX   XX  XX   XX  XX
+| XXXXXXX  XXX XXX    XXXX   XXXXXXX  XXX  XX  XX   XX   XX  XX  XXXXXXX
++*****************************************************************************/
+/******************************************************************************
+|
+| Routine:    INITB_EBIU0.
+|
+| Purpose:    Initialize all the EBIU0 Bank Registers
+| Parameters: None.
+| Returns:    None.
+|
+******************************************************************************/
+        function_prolog(initb_ebiu0)
+        /*--------------------------------------------------------------------+
+        |  Set EBIU0 Bank 0
+        +--------------------------------------------------------------------*/
+        lis     r10,EBIU0_BRCR0_VAL@h
+        ori     r10,r10,EBIU0_BRCR0_VAL@l
+        mtdcr   ebiu0_brcr0,r10
+        lis     r10,EBIU0_BRCRH0_VAL@h
+        ori     r10,r10,EBIU0_BRCRH0_VAL@l
+        mtdcr   ebiu0_brcrh0,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set EBIU0 Bank 1
+        +--------------------------------------------------------------------*/
+        lis     r10,EBIU0_BRCR1_VAL@h
+        ori     r10,r10,EBIU0_BRCR1_VAL@l
+        mtdcr   ebiu0_brcr1,r10
+        lis     r10,EBIU0_BRCRH1_VAL@h
+        ori     r10,r10,EBIU0_BRCRH1_VAL@l
+        mtdcr   ebiu0_brcrh1,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set EBIU0 Bank 2
+        +--------------------------------------------------------------------*/
+        lis     r10,EBIU0_BRCR2_VAL@h
+        ori     r10,r10,EBIU0_BRCR2_VAL@l
+        mtdcr   ebiu0_brcr2,r10
+        lis     r10,EBIU0_BRCRH2_VAL@h
+        ori     r10,r10,EBIU0_BRCRH2_VAL@l
+        mtdcr   ebiu0_brcrh2,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set EBIU0 Bank 3
+        +--------------------------------------------------------------------*/
+        lis     r10,EBIU0_BRCR3_VAL@h
+        ori     r10,r10,EBIU0_BRCR3_VAL@l
+        mtdcr   ebiu0_brcr3,r10
+        lis     r10,EBIU0_BRCRH3_VAL@h
+        ori     r10,r10,EBIU0_BRCRH3_VAL@l
+        mtdcr   ebiu0_brcrh3,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set EBIU0 Bank 4
+        +--------------------------------------------------------------------*/
+        lis     r10,EBIU0_BRCR4_VAL@h
+        ori     r10,r10,EBIU0_BRCR4_VAL@l
+        mtdcr   ebiu0_brcr4,r10
+        lis     r10,EBIU0_BRCRH4_VAL@h
+        ori     r10,r10,EBIU0_BRCRH4_VAL@l
+        mtdcr   ebiu0_brcrh4,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set EBIU0 Bank 5
+        +--------------------------------------------------------------------*/
+        lis     r10,EBIU0_BRCR5_VAL@h
+        ori     r10,r10,EBIU0_BRCR5_VAL@l
+        mtdcr   ebiu0_brcr5,r10
+        lis     r10,EBIU0_BRCRH5_VAL@h
+        ori     r10,r10,EBIU0_BRCRH5_VAL@l
+        mtdcr   ebiu0_brcrh5,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set EBIU0 Bank 6
+        +--------------------------------------------------------------------*/
+        lis     r10,EBIU0_BRCR6_VAL@h
+        ori     r10,r10,EBIU0_BRCR6_VAL@l
+        mtdcr   ebiu0_brcr6,r10
+        lis     r10,EBIU0_BRCRH6_VAL@h
+        ori     r10,r10,EBIU0_BRCRH6_VAL@l
+        mtdcr   ebiu0_brcrh6,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set EBIU0 Bank 7
+        +--------------------------------------------------------------------*/
+        lis     r10,EBIU0_BRCR7_VAL@h
+        ori     r10,r10,EBIU0_BRCR7_VAL@l
+        mtdcr   ebiu0_brcr7,r10
+        lis     r10,EBIU0_BRCRH7_VAL@h
+        ori     r10,r10,EBIU0_BRCRH7_VAL@l
+        mtdcr   ebiu0_brcrh7,r10
+
+        blr
+        function_epilog(initb_ebiu0)
+
+
+/******************************************************************************
+|
+| Routine:    INITB_CONFIG
+|
+| Purpose:    Configure the Vesta Evaluation Board.  The following items
+|             will be configured:
+|               1.  Cross-Bar Switch.
+|               2.  Chip Interconnect.
+|               3.  Clear/reset key PPC registers.
+|               4.  Xilinx and GPIO Registers.
+|
+| Returns:    None.
+|
+******************************************************************************/
+        function_prolog(initb_config)
+        /*--------------------------------------------------------------------+
+        |  Init CROSS-BAR SWITCH
+        +--------------------------------------------------------------------*/
+        lis     r10,CBS0_CR_VAL@h                /* r10 <- CBS Cntl Reg val  */
+        ori     r10,r10,CBS0_CR_VAL@l
+        mtdcr   cbs0_cr,r10
+
+        /*--------------------------------------------------------------------+
+        |  Init Chip-Interconnect (CIC) Registers
+        +--------------------------------------------------------------------*/
+        lis     r10,CIC0_CR_VAL@h                /* r10 <- CIC Cntl Reg val  */
+        ori     r10,r10,CIC0_CR_VAL@l
+        mtdcr   cic0_cr,r10
+
+        lis     r10,CIC0_SEL3_VAL@h              /* r10 <- CIC SEL3 Reg val  */
+        ori     r10,r10,CIC0_SEL3_VAL@l
+        mtdcr   cic0_sel3,r10
+
+        lis     r10,CIC0_VCR_VAL@h               /* r10 <- CIC Vid C-Reg val */
+        ori     r10,r10,CIC0_VCR_VAL@l
+        mtdcr   cic0_vcr,r10
+
+        /*--------------------------------------------------------------------+
+        | Clear SGR and DCWR
+        +--------------------------------------------------------------------*/
+        li      r10,0x0000
+        mtspr   sgr,r10
+        mtspr   dcwr,r10
+
+        /*--------------------------------------------------------------------+
+        | Clear/set up some machine state registers.
+        +--------------------------------------------------------------------*/
+        li      r10,0x0000                       /* r10 <- 0                 */
+        mtdcr   ebiu0_besr,r10                   /* clr Bus Err Syndrome Reg */
+        mtspr   esr,r10                          /* clr Exceptn Syndrome Reg */
+        mttcr   r10                              /* timer control register   */
+
+        mtdcr   uic0_er,r10                      /* disable all interrupts   */
+
+	/* UIC_IIC0 | UIC_IIC1 | UIC_U0 | UIC_IR_RCV | UIC_IR_XMIT */
+	lis	r10,    0x00600e00@h
+	ori	r10,r10,0x00600e00@l
+	mtdcr	uic0_pr,r10
+
+	li	r10,0x00000020			/* UIC_EIR1 */
+	mtdcr	uic0_tr,r10
+
+        lis     r10,0xFFFF                       /* r10 <- 0xFFFFFFFF        */
+        ori     r10,r10,0xFFFF                   /*                          */
+        mtdbsr  r10                              /* clear/reset the dbsr     */
+        mtdcr   uic0_sr,r10                      /* clear pending interrupts */
+
+        li      r10,0x1000                       /* set Machine Exception bit*/
+        oris    r10,r10,0x2                      /* set Criticl Exception bit*/
+        mtmsr   r10                              /* change MSR               */
+
+        /*--------------------------------------------------------------------+
+        |  Clear XER.
+        +--------------------------------------------------------------------*/
+        li      r10,0x0000
+        mtxer   r10
+
+        /*--------------------------------------------------------------------+
+        |  Init GPIO0 Registers
+        +--------------------------------------------------------------------*/
+        lis     r10,    STB_GPIO0_TC@h           /* Three-state control      */
+        ori     r10,r10,STB_GPIO0_TC@l
+        lis     r11,    GPIO0_TC_VAL@h
+        ori     r11,r11,GPIO0_TC_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_OS_0_31@h      /* output select 0-31       */
+        ori     r10,r10,STB_GPIO0_OS_0_31@l
+        lis     r11,    GPIO0_OS_0_31_VAL@h
+        ori     r11,r11,GPIO0_OS_0_31_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_OS_32_63@h     /* output select 32-63      */
+        ori     r10,r10,STB_GPIO0_OS_32_63@l
+        lis     r11,    GPIO0_OS_32_63_VAL@h
+        ori     r11,r11,GPIO0_OS_32_63_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_TS_0_31@h      /* three-state select 0-31  */
+        ori     r10,r10,STB_GPIO0_TS_0_31@l
+        lis     r11,    GPIO0_TS_0_31_VAL@h
+        ori     r11,r11,GPIO0_TS_0_31_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_TS_32_63@h     /* three-state select 32-63 */
+        ori     r10,r10,STB_GPIO0_TS_32_63@l
+        lis     r11,    GPIO0_TS_32_63_VAL@h
+        ori     r11,r11,GPIO0_TS_32_63_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_OD@h           /* open drain               */
+        ori     r10,r10,STB_GPIO0_OD@l
+        lis     r11,    GPIO0_OD_VAL@h
+        ori     r11,r11,GPIO0_OD_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_IS_1_0_31@h    /* input select 1, 0-31     */
+        ori     r10,r10,STB_GPIO0_IS_1_0_31@l
+        lis     r11,    GPIO0_IS_1_0_31_VAL@h
+        ori     r11,r11,GPIO0_IS_1_0_31_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_IS_1_32_63@h   /* input select 1, 32-63    */
+        ori     r10,r10,STB_GPIO0_IS_1_32_63@l
+        lis     r11,    GPIO0_IS_1_32_63_VAL@h
+        ori     r11,r11,GPIO0_IS_1_32_63_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_IS_2_0_31@h    /* input select 2, 0-31     */
+        ori     r10,r10,STB_GPIO0_IS_2_0_31@l
+        lis     r11,    GPIO0_IS_2_0_31_VAL@h
+        ori     r11,r11,GPIO0_IS_2_0_31_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_IS_2_32_63@h   /* input select 2, 32-63    */
+        ori     r10,r10,STB_GPIO0_IS_2_32_63@l
+        lis     r11,    GPIO0_IS_2_32_63_VAL@h
+        ori     r11,r11,GPIO0_IS_2_32_63_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_IS_3_0_31@h    /* input select 3, 0-31     */
+        ori     r10,r10,STB_GPIO0_IS_3_0_31@l
+        lis     r11,    GPIO0_IS_3_0_31_VAL@h
+        ori     r11,r11,GPIO0_IS_3_0_31_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_IS_3_32_63@h   /* input select 3, 32-63    */
+        ori     r10,r10,STB_GPIO0_IS_3_32_63@l
+        lis     r11,    GPIO0_IS_3_32_63_VAL@h
+        ori     r11,r11,GPIO0_IS_3_32_63_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_SS_1@h         /* sync select 1            */
+        ori     r10,r10,STB_GPIO0_SS_1@l
+        lis     r11,    GPIO0_SS_1_VAL@h
+        ori     r11,r11,GPIO0_SS_1_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_SS_2@h         /* sync select 2            */
+        ori     r10,r10,STB_GPIO0_SS_2@l
+        lis     r11,    GPIO0_SS_2_VAL@h
+        ori     r11,r11,GPIO0_SS_2_VAL@l
+        stw     r11,0(r10)
+
+        lis     r10,    STB_GPIO0_SS_3@h         /* sync select 3            */
+        ori     r10,r10,STB_GPIO0_SS_3@l
+        lis     r11,    GPIO0_SS_3_VAL@h
+        ori     r11,r11,GPIO0_SS_3_VAL@l
+        stw     r11,0(r10)
+
+        /*--------------------------------------------------------------------+
+        |  Init Xilinx #1 Registers
+        +--------------------------------------------------------------------*/
+        lis     r10,    STB_XILINX1_REG0@h       /* init Xilinx1 Reg 0       */
+        ori     r10,r10,STB_XILINX1_REG0@l
+        li      r11,XILINX1_R0_VAL
+        sth     r11,0(r10)
+
+        lis     r10,    STB_XILINX1_REG1@h       /* init Xilinx1 Reg 1       */
+        ori     r10,r10,STB_XILINX1_REG1@l
+        li      r11,XILINX1_R1_VAL
+        sth     r11,0(r10)
+
+        lis     r10,    STB_XILINX1_REG2@h       /* init Xilinx1 Reg 2       */
+        ori     r10,r10,STB_XILINX1_REG2@l
+        li      r11,XILINX1_R2_VAL
+        sth     r11,0(r10)
+
+        lis     r10,    STB_XILINX1_REG3@h       /* init Xilinx1 Reg 3       */
+        ori     r10,r10,STB_XILINX1_REG3@l
+        li      r11,XILINX1_R3_VAL
+        sth     r11,0(r10)
+
+        lis     r10,    STB_XILINX1_REG4@h       /* init Xilinx1 Reg 4       */
+        ori     r10,r10,STB_XILINX1_REG4@l
+        li      r11,XILINX1_R4_VAL
+        sth     r11,0(r10)
+
+        lis     r10,    STB_XILINX1_REG5@h       /* init Xilinx1 Reg 5       */
+        ori     r10,r10,STB_XILINX1_REG5@l
+        li      r11,XILINX1_R5_VAL
+        sth     r11,0(r10)
+
+        lis     r10,    STB_XILINX1_REG6@h       /* init Xilinx1 Reg 6       */
+        ori     r10,r10,STB_XILINX1_REG6@l
+        li      r11,XILINX1_R6_VAL
+        sth     r11,0(r10)
+
+        lis     r10,    STB_XILINX1_FLUSH@h      /* latch registers in Xilinx*/
+        ori     r10,r10,STB_XILINX1_FLUSH@l
+        li      r11,0x0000
+        sth     r11,0(r10)
+
+        /*--------------------------------------------------------------------+
+        |  Init Xilinx #2 Registers
+        +--------------------------------------------------------------------*/
+        lis     r10,    STB_XILINX2_REG0@h       /* init Xilinx2 Reg 0       */
+        ori     r10,r10,STB_XILINX2_REG0@l
+        li      r11,XILINX2_R0_VAL
+        sth     r11,0(r10)
+
+        lis     r10,    STB_XILINX2_REG1@h       /* init Xilinx2 Reg 1       */
+        ori     r10,r10,STB_XILINX2_REG1@l
+        li      r11,XILINX2_R1_VAL
+        sth     r11,0(r10)
+
+        lis     r10,    STB_XILINX2_REG2@h       /* init Xilinx2 Reg 2       */
+        ori     r10,r10,STB_XILINX2_REG2@l
+        li      r11,XILINX2_R2_VAL
+        sth     r11,0(r10)
+
+        blr
+        function_epilog(initb_config)
+
+
+/******************************************************************************
+|
+| Routine:    INITB_HSMC0.
+|
+| Purpose:    Initialize the HSMC0 Registers for SDRAM
+| Parameters: None.
+| Returns:    R3 =  0: Successful
+|                = -1: Unsuccessful, SDRAM did not reset properly.
+|
+******************************************************************************/
+        function_prolog(initb_hsmc0)
+        mflr    r0                               /* Save return addr         */
+
+        /*--------------------------------------------------------------------+
+        |  Set Global SDRAM Controller to recommended default
+        +--------------------------------------------------------------------*/
+        lis     r10,0x6C00
+        ori     r10,r10,0x0000
+        mtdcr   hsmc0_gr,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set HSMC0 Data Register to recommended default
+        +--------------------------------------------------------------------*/
+        lis     r10,0x0037
+        ori     r10,r10,0x0000
+        mtdcr   hsmc0_data,r10
+
+        /*--------------------------------------------------------------------+
+        |  Init HSMC0 Bank Register 0
+        +--------------------------------------------------------------------*/
+        lis     r10,HSMC0_BR0_VAL@h
+        ori     r10,r10,HSMC0_BR0_VAL@l
+        mtdcr   hsmc0_br0,r10
+
+        /*--------------------------------------------------------------------+
+        |  Init HSMC0 Bank Register 1
+        +--------------------------------------------------------------------*/
+        lis     r10,HSMC0_BR1_VAL@h
+        ori     r10,r10,HSMC0_BR1_VAL@l
+        mtdcr   hsmc0_br1,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set HSMC0 Control Reg 0
+        +--------------------------------------------------------------------*/
+        lis     r10,0x8077                       /* PRECHARGE ALL DEVICE BKS */
+        ori     r10,r10,0x0000
+        mtdcr   hsmc0_cr0,r10
+        li      r3,0x0000
+        bl      hsmc_cr_wait                     /* wait for op completion   */
+        cmpwi   cr0,r3,0x0000
+        bne     cr0,hsmc0_err
+
+        lis     r10,0x8078                       /* AUTO-REFRESH             */
+        ori     r10,r10,0x0000
+        mtdcr   hsmc0_cr0,r10
+        li      r3,0x0000
+        bl      hsmc_cr_wait                     /* wait for op completion   */
+        cmpwi   cr0,r3,0x0000
+        bne     cr0,hsmc0_err
+
+        lis     r10,0x8070                       /* PROG MODE W/DATA REG VAL */
+        ori     r10,r10,0x8000
+        mtdcr   hsmc0_cr0,r10
+        li      r3,0x0000
+        bl      hsmc_cr_wait                     /* wait for op completion   */
+        cmpwi   cr0,r3,0x0000
+        bne     hsmc0_err
+
+        /*--------------------------------------------------------------------+
+        |  Set HSMC0 Control Reg 1
+        +--------------------------------------------------------------------*/
+        lis     r10,0x8077                       /* PRECHARGE ALL DEVICE BKS */
+        ori     r10,r10,0x0000
+        mtdcr   hsmc0_cr1,r10
+        li      r3,0x0001
+        bl      hsmc_cr_wait                     /* wait for op completion   */
+        cmpwi   cr0,r3,0x0000
+        bne     cr0,hsmc0_err
+
+        lis     r10,0x8078                       /* AUTO-REFRESH             */
+        ori     r10,r10,0x0000
+        mtdcr   hsmc0_cr1,r10
+        li      r3,0x0001
+        bl      hsmc_cr_wait                     /* wait for op completion   */
+        cmpwi   cr0,r3,0x0000
+        bne     cr0,hsmc0_err
+
+        lis     r10,0x8070                       /* PROG MODE W/DATA REG VAL */
+        ori     r10,r10,0x8000
+        mtdcr   hsmc0_cr1,r10
+        li      r3,0x0001
+        bl      hsmc_cr_wait                     /* wait for op completion   */
+        cmpwi   cr0,r3,0x0000
+        bne     cr0,hsmc0_err
+
+        /*--------------------------------------------------------------------+
+        |  Set HSMC0 Refresh Register
+        +--------------------------------------------------------------------*/
+        lis     r10,0x0FE1
+        ori     r10,r10,0x0000
+        mtdcr   hsmc0_crr,r10
+        li      r3,0
+
+hsmc0_err:
+        mtlr    r0
+        blr
+        function_epilog(initb_hsmc0)
+
+
+/******************************************************************************
+|
+| Routine:    INITB_HSMC1.
+|
+| Purpose:    Initialize the HSMC1 Registers for SDRAM
+| Parameters: None.
+| Returns:    R3 =  0: Successful
+|                = -1: Unsuccessful, SDRAM did not reset properly.
+|
+******************************************************************************/
+        function_prolog(initb_hsmc1)
+        mflr    r0                               /* Save return addr         */
+
+        /*--------------------------------------------------------------------+
+        |  Set Global SDRAM Controller to recommended default
+        +--------------------------------------------------------------------*/
+        lis     r10,0x6C00
+        ori     r10,r10,0x0000
+        mtdcr   hsmc1_gr,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set HSMC1 Data Register to recommended default
+        +--------------------------------------------------------------------*/
+        lis     r10,0x0037
+        ori     r10,r10,0x0000
+        mtdcr   hsmc1_data,r10
+
+        /*--------------------------------------------------------------------+
+        |  Init HSMC1 Bank Register 0
+        +--------------------------------------------------------------------*/
+        lis     r10,HSMC1_BR0_VAL@h
+        ori     r10,r10,HSMC1_BR0_VAL@l
+        mtdcr   hsmc1_br0,r10
+
+        /*--------------------------------------------------------------------+
+        |  Init HSMC1 Bank Register 1
+        +--------------------------------------------------------------------*/
+        lis     r10,HSMC1_BR1_VAL@h
+        ori     r10,r10,HSMC1_BR1_VAL@l
+        mtdcr   hsmc1_br1,r10
+
+        /*--------------------------------------------------------------------+
+        |  Set HSMC1 Control Reg 0
+        +--------------------------------------------------------------------*/
+        lis     r10,0x8077                       /* PRECHARGE ALL DEVICE BANKS    */
+        ori     r10,r10,0x0000
+        mtdcr   hsmc1_cr0,r10
+        li      r3,0x0002
+        bl      hsmc_cr_wait                     /* wait for operation completion */
+        cmpwi   cr0,r3,0x0000
+        bne     hsmc1_err
+
+        lis     r10,0x8078                       /* AUTO-REFRESH                  */
+        ori     r10,r10,0x0000
+        mtdcr   hsmc1_cr0,r10
+        li      r3,0x0002
+        bl      hsmc_cr_wait                     /* wait for operation completion */
+        cmpwi   cr0,r3,0x0000
+        bne     hsmc1_err
+
+        lis     r10,0x8070                       /* PROGRAM MODE W/DATA REG VALUE */
+        ori     r10,r10,0x8000
+        mtdcr   hsmc1_cr0,r10
+        li      r3,0x0002
+        bl      hsmc_cr_wait                     /* wait for operation completion */
+        cmpwi   cr0,r3,0x0000
+        bne     hsmc1_err
+
+        /*--------------------------------------------------------------------+
+        |  Set HSMC1 Control Reg 1
+        +--------------------------------------------------------------------*/
+        lis     r10,0x8077                       /* PRECHARGE ALL DEVICE BKS */
+        ori     r10,r10,0x0000
+        mtdcr   hsmc1_cr1,r10
+        li      r3,0x0003
+        bl      hsmc_cr_wait                     /* wait for op completion   */
+        cmpwi   cr0,r3,0x0000
+        bne     hsmc1_err
+
+        lis     r10,0x8078                       /* AUTO-REFRESH             */
+        ori     r10,r10,0x0000
+        mtdcr   hsmc1_cr1,r10
+        li      r3,0x0003
+        bl      hsmc_cr_wait                     /* wait for op completion   */
+        cmpwi   cr0,r3,0x0000
+        bne     hsmc1_err
+
+        lis     r10,0x8070                       /* PROG MODE W/DATA REG VAL */
+        ori     r10,r10,0x8000
+        mtdcr   hsmc1_cr1,r10
+        li      r3,0x0003
+        bl      hsmc_cr_wait                     /* wait for op completion   */
+        cmpwi   cr0,r3,0x0000
+        bne     hsmc1_err
+
+        /*--------------------------------------------------------------------+
+        |  Set HSMC1 Refresh Register
+        +--------------------------------------------------------------------*/
+        lis     r10,0x0FE1
+        ori     r10,r10,0x0000
+        mtdcr   hsmc1_crr,r10
+        xor     r3,r3,r3
+
+hsmc1_err:
+        mtlr    r0
+        blr
+        function_epilog(initb_hsmc1)
+
+
+/******************************************************************************
+|
+| Routine:    INITB_CACHE
+|
+| Purpose:    This routine will enable Data and Instruction Cache.
+|             The Data Cache is an 8K two-way set associative and the
+|             Instruction Cache is an 16K two-way set associative cache.
+|
+| Parameters: None.
+|
+| Returns:    None.
+|
+******************************************************************************/
+        function_prolog(initb_cache)
+        mflr    r0                               /* Save return addr         */
+
+        bl      initb_Dcache                     /* enable D-Cache           */
+        bl      initb_Icache                     /* enable I-Cache           */
+
+        mtlr    r0
+        blr
+       function_epilog(initb_cache)
+
+
+/******************************************************************************
+|
+| Routine:    INITB_DCACHE
+|
+| Purpose:    This routine will invalidate all data in the Data Cache and
+|             then enable D-Cache.  If cache is enabled already, the D-Cache
+|             will be flushed before the data is invalidated.
+|
+| Parameters: None.
+|
+| Returns:    None.
+|
+******************************************************************************/
+        function_prolog(initb_Dcache)
+        /*--------------------------------------------------------------------+
+        |  Flush Data Cache if enabled
+        +--------------------------------------------------------------------*/
+        mfdccr  r10                              /* r10 <- DCCR              */
+        isync                                    /* ensure prev insts done   */
+        cmpwi   r10,0x00
+        beq     ic_dcinv                         /* D-cache off, invalidate  */
+
+        /*--------------------------------------------------------------------+
+        |  Data Cache enabled, force known memory addresses to be Cached
+        +--------------------------------------------------------------------*/
+        lis     r10,HSMC0_BR0_VAL@h              /* r10 <- first memory loc  */
+        andis.  r10,r10,0xFFF0
+        li      r11,DCACHE_NLINES                /* r11 <- # A-way addresses */
+        addi    r11,r11,DCACHE_NLINES            /* r11 <- # B-way addresses */
+        mtctr   r11                              /* set loop counter         */
+
+ic_dcload:
+        lwz     r12,0(r10)                       /* force cache of address   */
+        addi    r10,r10,DCACHE_NBYTES            /* r10 <- next memory loc   */
+        bdnz    ic_dcload
+        sync                                     /* ensure prev insts done   */
+        isync
+
+        /*--------------------------------------------------------------------+
+        |  Flush the known memory addresses from Cache
+        +--------------------------------------------------------------------*/
+        lis     r10,HSMC0_BR0_VAL@h              /* r10 <- first memory loc  */
+        andis.  r10,r10,0xFFF0
+        mtctr   r11                              /* set loop counter         */
+
+ic_dcflush:
+        dcbf    0,r10                            /* flush D-cache line       */
+        addi    r10,r10,DCACHE_NBYTES            /* r10 <- next memory loc   */
+        bdnz    ic_dcflush
+        sync                                     /* ensure prev insts done   */
+        isync
+
+        /*--------------------------------------------------------------------+
+        |  Disable then invalidate Data Cache
+        +--------------------------------------------------------------------*/
+        li      r10,0                            /* r10 <- 0                 */
+        mtdccr  r10                              /* disable the D-Cache      */
+        isync                                    /* ensure prev insts done   */
+
+ic_dcinv:
+        li      r10,0                            /* r10 <- line address      */
+        li      r11,DCACHE_NLINES                /* r11 <- # lines in cache  */
+        mtctr   r11                              /* set loop counter         */
+
+ic_dcloop:
+        dccci   0,r10                            /* invalidate A/B cache lns */
+        addi    r10,r10,DCACHE_NBYTES            /* bump to next line        */
+        bdnz    ic_dcloop
+        sync                                     /* ensure prev insts done   */
+        isync
+
+        /*--------------------------------------------------------------------+
+        |  Enable Data Cache
+        +--------------------------------------------------------------------*/
+        lis     r10,DCACHE_ENABLE@h              /* r10 <- D-cache enable msk*/
+        ori     r10,r10,DCACHE_ENABLE@l
+        mtdccr  r10
+        sync                                     /* ensure prev insts done   */
+        isync
+
+        blr
+        function_epilog(initb_Dcache)
+
+
+/******************************************************************************
+|
+| Routine:    INITB_ICACHE
+|
+| Purpose:    This routine will invalidate all data in the Instruction
+|             Cache then enable I-Cache.
+|
+| Parameters: None.
+|
+| Returns:    None.
+|
+******************************************************************************/
+        function_prolog(initb_Icache)
+        /*--------------------------------------------------------------------+
+        |  Invalidate Instruction Cache
+        +--------------------------------------------------------------------*/
+        li      r10,0                            /* r10 <- lines address     */
+        iccci   0,r10                            /* invalidate all I-cache   */
+        sync                                     /* ensure prev insts done   */
+        isync
+
+        /*--------------------------------------------------------------------+
+        |  Enable Instruction Cache
+        +--------------------------------------------------------------------*/
+        lis     r10,ICACHE_ENABLE@h              /* r10 <- I-cache enable msk*/
+        ori     r10,r10,ICACHE_ENABLE@l
+        mticcr  r10
+        sync                                     /* ensure prev insts done   */
+        isync
+
+        blr
+        function_epilog(initb_Icache)
+
+#if 0
+/******************************************************************************
+|
+| Routine:    INITB_GET_CSPD
+|
+| Purpose:    Determine the CPU Core Speed.  The 13.5 Mhz Time Base
+|             Counter (TBC) is used to measure a conditional branch
+|             instruction.
+|
+| Parameters: R3 = Address of Bus Speed
+|             R4 = Address of Core Speed
+|
+| Returns:    (R3) = >0: Bus Speed.
+|                     0: Bus Speed not found in Look-Up Table.
+|             (R4) = >0: Core Speed.
+|                     0: Core Speed not found in Look-Up Table.
+|
+| Note:       1. This routine assumes the bdnz branch instruction takes
+|                two instruction cycles to complete.
+|             2. This routine must be called before interrupts are enabled.
+|
+******************************************************************************/
+        function_prolog(initb_get_cspd)
+        mflr    r0                               /* Save return address      */
+        /*--------------------------------------------------------------------+
+        |  Set-up timed loop
+        +--------------------------------------------------------------------*/
+        lis     r9,gcs_time_loop@h               /* r9  <- addr loop instr   */
+        ori     r9,r9,gcs_time_loop@l
+        lis     r10,GCS_LCNT@h                   /* r10 <- loop count        */
+        ori     r10,r10,GCS_LCNT@l
+        mtctr   r10                              /* ctr <- loop count        */
+        lis     r11,STB_TIMERS_TBC@h             /* r11 <- TBC register addr */
+        ori     r11,r11,STB_TIMERS_TBC@l
+        li      r12,0                            /* r12 <- 0                 */
+
+        /*--------------------------------------------------------------------+
+        |  Cache timed-loop instruction
+        +--------------------------------------------------------------------*/
+        icbt    0,r9
+        sync
+        isync
+
+        /*--------------------------------------------------------------------+
+        |  Get number of 13.5 Mhz cycles to execute time-loop
+        +--------------------------------------------------------------------*/
+        stw     r12,0(r11)                       /* reset TBC                */
+gcs_time_loop:
+        bdnz+   gcs_time_loop                    /* force branch pred taken  */
+        lwz     r5,0(r11)                        /* r5 <- num 13.5 Mhz ticks */
+        li      r6,5                             /* LUT based on 1/5th the...*/
+        divw    r5,r5,r6                         /*..loop count used         */
+        sync
+        isync
+
+        /*--------------------------------------------------------------------+
+        |  Look-up core speed based on TBC value
+        +--------------------------------------------------------------------*/
+        lis     r6,gcs_lookup_table@h            /* r6 <- pts at core spd LUT*/
+        ori     r6,r6,gcs_lookup_table@l
+        bl      gcs_cspd_lookup                  /* find core speed in LUT   */
+
+        mtlr    r0                               /* set return address       */
+        blr
+        function_epilog(initb_get_cspd)
+
+#endif
+/*****************************************************************************+
+| XXXX   XX   XX   XXXXXX  XXXXXXX  XXXXXX   XX   XX     XX    XXXX
+|  XX    XXX  XX   X XX X   XX   X   XX  XX  XXX  XX    XXXX    XX
+|  XX    XXXX XX     XX     XX X     XX  XX  XXXX XX   XX  XX   XX
+|  XX    XX XXXX     XX     XXXX     XXXXX   XX XXXX   XX  XX   XX
+|  XX    XX  XXX     XX     XX X     XX XX   XX  XXX   XXXXXX   XX
+|  XX    XX   XX     XX     XX   X   XX  XX  XX   XX   XX  XX   XX  XX
+| XXXX   XX   XX    XXXX   XXXXXXX  XXX  XX  XX   XX   XX  XX  XXXXXXX
++*****************************************************************************/
+/******************************************************************************
+|
+| Routine:    HSMC_CR_WAIT
+|
+| Purpose:    Wait for the HSMC Control Register (bits 12-16) to be reset
+|             after an auto-refresh, pre-charge or program mode register
+|             command execution.
+|
+| Parameters: R3 = HSMC Control Register ID.
+|                  0: HSMC0 CR0
+|                  1: HSMC0 CR1
+|                  2: HSMC1 CR0
+|                  3: HSMC1 CR1
+|
+| Returns:    R3 = 0: Successful
+|                 -1: Unsuccessful
+|
+******************************************************************************/
+hsmc_cr_wait:
+
+        li      r11,10                           /* r11 <- retry counter     */
+        mtctr   r11                              /* set retry counter        */
+        mr      r11,r3                           /* r11 <- HSMC CR reg id    */
+
+hsmc_cr_rep:
+        bdz     hsmc_cr_err                      /* branch if max retries hit*/
+
+        /*--------------------------------------------------------------------+
+        |  GET HSMCx_CRx value based on HSMC Control Register ID
+        +--------------------------------------------------------------------*/
+try_hsmc0_cr0:                                   /* CHECK IF ID=HSMC0 CR0 REG*/
+        cmpwi   cr0,r11,0x0000
+        bne     cr0,try_hsmc0_cr1
+        mfdcr   r10,hsmc0_cr0                    /* r11 <- HSMC0 CR0 value   */
+        b       hsmc_cr_read
+
+try_hsmc0_cr1:                                   /* CHECK IF ID=HSMC0 CR1 REG*/
+        cmpwi   cr0,r11,0x0001
+        bne     cr0,try_hsmc1_cr0
+        mfdcr   r10,hsmc0_cr1                    /* r10 <- HSMC0 CR1 value   */
+        b       hsmc_cr_read
+
+try_hsmc1_cr0:                                   /* CHECK IF ID=HSMC1 CR0 REG*/
+        cmpwi   cr0,r11,0x0002
+        bne     cr0,try_hsmc1_cr1
+        mfdcr   r10,hsmc1_cr0                    /* r10 <- HSMC1 CR0 value   */
+        b       hsmc_cr_read
+
+try_hsmc1_cr1:                                   /* CHECK IF ID=HSMC1 CR1 REG*/
+        cmpwi   cr0,r11,0x0003
+        bne     cr0,hsmc_cr_err
+        mfdcr   r10,hsmc1_cr1                    /* r10 <- HSMC1 CR1 value   */
+
+        /*--------------------------------------------------------------------+
+        |  Check if HSMC CR register was reset after command execution
+        +--------------------------------------------------------------------*/
+hsmc_cr_read:
+        lis     r12,0x000F                       /* create "AND" mask        */
+        ori     r12,r12,0x8000
+        and.    r10,r10,r12                      /* r10 <- HSMC CR bits 12-16*/
+        bne     cr0,hsmc_cr_rep                  /* wait for bits to reset   */
+        li      r3,0                             /* set return code = success*/
+        b       hsmc_cr_done
+
+hsmc_cr_err:                                     /* ERROR: SDRAM didn't reset*/
+        li      r3,-1                            /* set RC=unsuccessful      */
+
+hsmc_cr_done:
+        blr
+
+#if 0
+/******************************************************************************
+|
+| Routine:    GCS_CSPD_LOOKUP
+|
+| Purpose:    Uses the number of 13.5 Mhz clock ticks found after executing
+|             the branch instruction time loop to look-up the CPU Core Speed
+|             in the Core Speed Look-up Table.
+|
+| Parameters: R3 = Address of Bus Speed
+|             R4 = Address of Core Speed
+|             R5 = Number of 13.5 Mhz clock ticks found in time loop.
+|             R6 = Pointer to Core-Speed Look-Up Table
+|
+| Returns:    (R3) = >0: Bus Speed.
+|                     0: Bus Speed not found in Look-Up Table.
+|             (R4) = >0: Core Speed.
+|                     0: Core Speed not found in Look-Up Table.
+|
+| Note:       Core Speed = Bus Speed * Mult Factor (1-4x).
+|
+******************************************************************************/
+gcs_cspd_lookup:
+
+        li      r9,1                             /* r9 <- core speed mult    */
+        /*--------------------------------------------------------------------+
+        |  Get theoritical number 13.5 Mhz ticks for a given Bus Speed from
+        |  Look-up Table.  Check all mult factors to determine if calculated
+        |  value matches theoretical value (within a tolerance).
+        +--------------------------------------------------------------------*/
+gcs_cspd_loop:
+        lwz     r10,0(r6)                        /* r10 <- no. ticks from LUT*/
+        divw    r10,r10,r9                       /* r10 <- div mult (1-4x)   */
+        subi    r11,r10,GCS_CTICK_TOL            /* r11 <- no. tks low range */
+        addi    r12,r10,GCS_CTICK_TOL            /* r12 <- no. tks high range*/
+
+        cmpw    cr0,r5,r11                       /* calc value within range? */
+        blt     gcs_cspd_retry                   /* less than low range      */
+        cmpw    cr0,r5,r12
+        bgt     gcs_cspd_retry                   /* greater than high range  */
+        b       gcs_cspd_fnd                     /* calc value within range  */
+
+        /*--------------------------------------------------------------------+
+        |  SO FAR CORE SPEED NOT FOUND: Check next mult factor
+        +--------------------------------------------------------------------*/
+gcs_cspd_retry:
+        addi    r9,r9,1                          /* bump mult factor (1-4x)  */
+        cmpwi   cr0,r9,GCS_NMULT
+        ble     gcs_cspd_loop
+
+        /*--------------------------------------------------------------------+
+        |  SO FAR CORE SPEED NOT FOUND: Point at next Bus Speed in LUT
+        +--------------------------------------------------------------------*/
+        li      r9,1                             /* reset mult factor        */
+        addi    r6,r6,GCS_TROW_BYTES             /* point at next table entry*/
+        lwz     r10,0(r6)
+        cmpwi   cr0,r10,0                        /* check for EOT flag       */
+        bne     gcs_cspd_loop
+
+        /*--------------------------------------------------------------------+
+        |  COMPUTE CORE SPEED AND GET BUS SPEED FROM LOOK-UP TABLE
+        +--------------------------------------------------------------------*/
+gcs_cspd_fnd:
+        lwz     r5,4(r6)                         /*  r5  <- Bus Speed in LUT */
+        mullw   r6,r5,r9                         /*  r6  <- Core speed       */
+        stw     r5,0(r3)                         /* (r3) <- Bus Speed        */
+        stw     r6,0(r4)                         /* (r4) <- Core Speed       */
+
+        blr
+#endif
diff --git a/arch/ppc/boot/simple/rw4/stb.h b/arch/ppc/boot/simple/rw4/stb.h
new file mode 100644
index 0000000..fd98ee0
--- /dev/null
+++ b/arch/ppc/boot/simple/rw4/stb.h
@@ -0,0 +1,239 @@
+/*----------------------------------------------------------------------------+
+|       This source code has been made available to you by IBM on an AS-IS
+|       basis.  Anyone receiving this source is licensed under IBM
+|       copyrights to use it in any way he or she deems fit, including
+|       copying it, modifying it, compiling it, and redistributing it either
+|       with or without modifications.  No license under IBM patents or
+|       patent applications is to be implied by the copyright license.
+|
+|       Any user of this software should understand that IBM cannot provide
+|       technical support for this software and will not be responsible for
+|       any consequences resulting from the use of this software.
+|
+|       Any person who transfers this source code or any derivative work
+|       must include the IBM copyright notice, this paragraph, and the
+|       preceding two paragraphs in the transferred software.
+|
+|       COPYRIGHT   I B M   CORPORATION 1999
+|       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+| Author: Maciej P. Tyrlik
+| Component: Include file.
+| File: stb.h
+| Purpose: Common Set-tob-box definitions.
+| Changes:
+| Date:         Comment:
+| -----         --------
+| 14-Jan-97     Created for ElPaso pass 1                                   MPT
+| 13-May-97     Added function prototype and global variables               MPT
+| 08-Dec-98     Added RAW IR task information                               MPT
+| 19-Jan-99     Port to Romeo                                               MPT
+| 19-May-00     Changed SDRAM to 32MB contiguous 0x1F000000 - 0x20FFFFFF    RLB
++----------------------------------------------------------------------------*/
+
+#ifndef _stb_h_
+#define _stb_h_
+
+/*----------------------------------------------------------------------------+
+| Read/write from I/O macros.
++----------------------------------------------------------------------------*/
+#define inbyte(port)            (*((unsigned char volatile *)(port)))
+#define outbyte(port,data)      *(unsigned char volatile *)(port)=\
+                                (unsigned char)(data)
+
+#define inshort(port)           (*((unsigned short volatile *)(port)))
+#define outshort(port,data)     *(unsigned short volatile *)(port)=\
+                                (unsigned short)(data)
+
+#define inword(port)            (*((unsigned long volatile *)(port)))
+#define outword(port,data)      *(unsigned long volatile *)(port)=\
+                                (unsigned long)(data)
+
+/*----------------------------------------------------------------------------+
+| STB interrupts.
++----------------------------------------------------------------------------*/
+#define STB_XP_TP_INT           0
+#define STB_XP_APP_INT          1
+#define STB_AUD_INT             2
+#define STB_VID_INT             3
+#define STB_DMA0_INT            4
+#define STB_DMA1_INT            5
+#define STB_DMA2_INT            6
+#define STB_DMA3_INT            7
+#define STB_SCI_INT             8
+#define STB_I2C1_INT            9
+#define STB_I2C2_INT            10
+#define STB_GPT_PWM0            11
+#define STB_GPT_PWM1            12
+#define STB_SCP_INT             13
+#define STB_SSP_INT             14
+#define STB_GPT_PWM2            15
+#define STB_EXT5_INT            16
+#define STB_EXT6_INT            17
+#define STB_EXT7_INT            18
+#define STB_EXT8_INT            19
+#define STB_SCC_INT             20
+#define STB_SICC_RECV_INT       21
+#define STB_SICC_TRAN_INT       22
+#define STB_PPU_INT             23
+#define STB_DCRX_INT            24
+#define STB_EXT0_INT            25
+#define STB_EXT1_INT            26
+#define STB_EXT2_INT            27
+#define STB_EXT3_INT            28
+#define STB_EXT4_INT            29
+#define STB_REDWOOD_ENET_INT    STB_EXT1_INT
+
+/*----------------------------------------------------------------------------+
+| STB tasks, task stack sizes, and task priorities.  The actual task priority
+| is 1 more than the specified number since priority 0 is reserved (system
+| internaly adds 1 to supplied priority number).
++----------------------------------------------------------------------------*/
+#define STB_IDLE_TASK_SS        (5* 1024)
+#define STB_IDLE_TASK_PRIO      0
+#define STB_LEDTEST_SS          (2* 1024)
+#define STB_LEDTEST_PRIO        0
+#define STB_CURSOR_TASK_SS      (10* 1024)
+#define STB_CURSOR_TASK_PRIO    7
+#define STB_MPEG_TASK_SS        (10* 1024)
+#define STB_MPEG_TASK_PRIO      9
+#define STB_DEMUX_TASK_SS       (10* 1024)
+#define STB_DEMUX_TASK_PRIO     20
+#define RAW_STB_IR_TASK_SS      (10* 1024)
+#define RAW_STB_IR_TASK_PRIO    20
+
+#define STB_SERIAL_ER_TASK_SS   (10* 1024)
+#define STB_SERIAL_ER_TASK_PRIO 1
+#define STB_CA_TASK_SS          (10* 1024)
+#define STB_CA_TASK_PRIO        8
+
+#define INIT_DEFAULT_VIDEO_SS   (10* 1024)
+#define INIT_DEFAULT_VIDEO_PRIO 8
+#define INIT_DEFAULT_SERVI_SS   (10* 1024)
+#define INIT_DEFAULT_SERVI_PRIO 8
+#define INIT_DEFAULT_POST_SS    (10* 1024)
+#define INIT_DEFAULT_POST_PRIO  8
+#define INIT_DEFAULT_INTER_SS   (10* 1024)
+#define INIT_DEFAULT_INTER_PRIO 8
+#define INIT_DEFAULT_BR_SS      (10* 1024)
+#define INIT_DEFAULT_BR_PRIO    8
+#define INITIAL_TASK_STACK_SIZE (32* 1024)
+
+#ifdef VESTA
+/*----------------------------------------------------------------------------+
+| Vesta Overall Address Map (all addresses are double mapped, bit 0 of the
+| address is not decoded.  Numbers below are dependent on board configuration.
+| FLASH, SDRAM, DRAM numbers can be affected by actual board setup.
+|
+|    FFE0,0000 - FFFF,FFFF        FLASH
+|    F200,0000 - F210,FFFF        FPGA logic
+|                                   Ethernet       = F200,0000
+|                                   LED Display    = F200,0100
+|                                   Xilinx #1 Regs = F204,0000
+|                                   Xilinx #2 Regs = F208,0000
+|                                   Spare          = F20C,0000
+|                                   IDE CS0        = F210,0000
+|    F410,0000 - F410,FFFF        IDE CS1
+|    C000,0000 - C7FF,FFFF        OBP
+|    C000,0000 - C000,0014        SICC  (16550 + infra red)
+|    C001,0000 - C001,0018        PPU   (Parallel Port)
+|    C002,0000 - C002,001B        SC0   (Smart Card 0)
+|    C003,0000 - C003,000F        I2C0
+|    C004,0000 - C004,0009        SCC   (16550 UART)
+|    C005,0000 - C005,0124        GPT   (Timers)
+|    C006,0000 - C006,0058        GPIO0
+|    C007,0000 - C007,001b        SC1   (Smart Card 1)
+|    C008,0000 - C008,FFFF        Unused
+|    C009,0000 - C009,FFFF        Unused
+|    C00A,0000 - C00A,FFFF        Unused
+|    C00B,0000 - C00B,000F        I2C1
+|    C00C,0000 - C00C,0006        SCP
+|    C00D,0000 - C00D,0010        SSP
+|    A000,0000 - A0FF,FFFF        SDRAM1  (16M)
+|    0000,0000 - 00FF,FFFF        SDRAM0  (16M)
++----------------------------------------------------------------------------*/
+#define STB_FLASH_BASE_ADDRESS  0xFFE00000
+#define STB_FPGA_BASE_ADDRESS   0xF2000000
+#define STB_SICC_BASE_ADDRESS   0xC0000000
+#define STB_PPU_BASE_ADDR       0xC0010000
+#define STB_SC0_BASE_ADDRESS    0xC0020000
+#define STB_I2C1_BASE_ADDRESS   0xC0030000
+#define STB_SCC_BASE_ADDRESS    0xC0040000
+#define STB_TIMERS_BASE_ADDRESS 0xC0050000
+#define STB_GPIO0_BASE_ADDRESS  0xC0060000
+#define STB_SC1_BASE_ADDRESS    0xC0070000
+#define STB_I2C2_BASE_ADDRESS   0xC00B0000
+#define STB_SCP_BASE_ADDRESS    0xC00C0000
+#define STB_SSP_BASE_ADDRESS    0xC00D0000
+/*----------------------------------------------------------------------------+
+|The following are used by the IBM RTOS SW.
+|15-May-00 Changed these values to reflect movement of base addresses in
+|order to support 32MB of contiguous SDRAM space.
+|Points to the cacheable region since these values are used in IBM RTOS
+|to establish the vector address.
++----------------------------------------------------------------------------*/
+#define STB_SDRAM1_BASE_ADDRESS 0x20000000
+#define STB_SDRAM1_SIZE         0x01000000
+#define STB_SDRAM0_BASE_ADDRESS 0x1F000000
+#define STB_SDRAM0_SIZE         0x01000000
+
+#else
+/*----------------------------------------------------------------------------+
+| ElPaso Overall Address Map (all addresses are double mapped, bit 0 of the
+| address is not decoded.  Numbers below are dependent on board configuration.
+| FLASH, SDRAM, DRAM numbers can be affected by actual board setup.  OPB
+| devices are inside the ElPaso chip.
+|    FFE0,0000 - FFFF,FFFF        FLASH
+|    F144,0000 - F104,FFFF        FPGA logic
+|    F140,0000 - F100,0000        ethernet (through FPGA logic)
+|    C000,0000 - C7FF,FFFF        OBP
+|    C000,0000 - C000,0014        SICC (16550+ infra red)
+|    C001,0000 - C001,0016        PPU (parallel port)
+|    C002,0000 - C002,001B        SC (smart card)
+|    C003,0000 - C003,000F        I2C 1
+|    C004,0000 - C004,0009        SCC (16550 UART)
+|    C005,0000 - C005,0124        Timers
+|    C006,0000 - C006,0058        GPIO0
+|    C007,0000 - C007,0058        GPIO1
+|    C008,0000 - C008,0058        GPIO2
+|    C009,0000 - C009,0058        GPIO3
+|    C00A,0000 - C00A,0058        GPIO4
+|    C00B,0000 - C00B,000F        I2C 2
+|    C00C,0000 - C00C,0006        SCP
+|    C00D,0000 - C00D,0006        SSP
+|    A000,0000 - A0FF,FFFF        SDRAM 16M
+|    0000,0000 - 00FF,FFFF        DRAM 16M
++----------------------------------------------------------------------------*/
+#define STB_FLASH_BASE_ADDRESS  0xFFE00000
+#define STB_FPGA_BASE_ADDRESS   0xF1440000
+#define STB_ENET_BASE_ADDRESS   0xF1400000
+#define STB_SICC_BASE_ADDRESS   0xC0000000
+#define STB_PPU_BASE_ADDR       0xC0010000
+#define STB_SC_BASE_ADDRESS     0xC0020000
+#define STB_I2C1_BASE_ADDRESS   0xC0030000
+#define STB_SCC_BASE_ADDRESS    0xC0040000
+#define STB_TIMERS_BASE_ADDRESS 0xC0050000
+#define STB_GPIO0_BASE_ADDRESS  0xC0060000
+#define STB_GPIO1_BASE_ADDRESS  0xC0070000
+#define STB_GPIO2_BASE_ADDRESS  0xC0080000
+#define STB_GPIO3_BASE_ADDRESS  0xC0090000
+#define STB_GPIO4_BASE_ADDRESS  0xC00A0000
+#define STB_I2C2_BASE_ADDRESS   0xC00B0000
+#define STB_SCP_BASE_ADDRESS    0xC00C0000
+#define STB_SSP_BASE_ADDRESS    0xC00D0000
+#define STB_SDRAM_BASE_ADDRESS  0xA0000000
+#endif
+
+/*----------------------------------------------------------------------------+
+| Other common defines.
++----------------------------------------------------------------------------*/
+#ifndef TRUE
+#define TRUE    1
+#endif
+
+#ifndef FALSE
+#define FALSE   0
+#endif
+
+#endif /* _stb_h_ */
diff --git a/arch/ppc/boot/utils/addRamDisk.c b/arch/ppc/boot/utils/addRamDisk.c
new file mode 100644
index 0000000..93400df
--- /dev/null
+++ b/arch/ppc/boot/utils/addRamDisk.c
@@ -0,0 +1,203 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#define ElfHeaderSize  (64 * 1024)
+#define ElfPages  (ElfHeaderSize / 4096)
+#define KERNELBASE (0xc0000000)
+
+void get4k(FILE *file, char *buf )
+{
+    unsigned j;
+    unsigned num = fread(buf, 1, 4096, file);
+    for (  j=num; j<4096; ++j )
+	buf[j] = 0;
+}
+
+void put4k(FILE *file, char *buf )
+{
+    fwrite(buf, 1, 4096, file);
+}
+
+void death(const char *msg, FILE *fdesc, const char *fname)
+{
+    printf(msg);
+    fclose(fdesc);
+    unlink(fname);
+    exit(1);
+}
+
+int main(int argc, char **argv)
+{
+    char inbuf[4096];
+    FILE *ramDisk = NULL;
+    FILE *inputVmlinux = NULL;
+    FILE *outputVmlinux = NULL;
+    unsigned i = 0;
+    u_int32_t ramFileLen = 0;
+    u_int32_t ramLen = 0;
+    u_int32_t roundR = 0;
+    u_int32_t kernelLen = 0;
+    u_int32_t actualKernelLen = 0;
+    u_int32_t round = 0;
+    u_int32_t roundedKernelLen = 0;
+    u_int32_t ramStartOffs = 0;
+    u_int32_t ramPages = 0;
+    u_int32_t roundedKernelPages = 0;
+    u_int32_t hvReleaseData = 0;
+    u_int32_t eyeCatcher = 0xc8a5d9c4;
+    u_int32_t naca = 0;
+    u_int32_t xRamDisk = 0;
+    u_int32_t xRamDiskSize = 0;
+    if ( argc < 2 ) {
+	printf("Name of RAM disk file missing.\n");
+	exit(1);
+    }
+
+    if ( argc < 3 ) {
+	printf("Name of vmlinux file missing.\n");
+	exit(1);
+    }
+
+    if ( argc < 4 ) {
+	printf("Name of vmlinux output file missing.\n");
+	exit(1);
+    }
+
+    ramDisk = fopen(argv[1], "r");
+    if ( ! ramDisk ) {
+	printf("RAM disk file \"%s\" failed to open.\n", argv[1]);
+	exit(1);
+    }
+    inputVmlinux = fopen(argv[2], "r");
+    if ( ! inputVmlinux ) {
+	printf("vmlinux file \"%s\" failed to open.\n", argv[2]);
+	exit(1);
+    }
+    outputVmlinux = fopen(argv[3], "w+");
+    if ( ! outputVmlinux ) {
+	printf("output vmlinux file \"%s\" failed to open.\n", argv[3]);
+	exit(1);
+    }
+    fseek(ramDisk, 0, SEEK_END);
+    ramFileLen = ftell(ramDisk);
+    fseek(ramDisk, 0, SEEK_SET);
+    printf("%s file size = %d\n", argv[1], ramFileLen);
+
+    ramLen = ramFileLen;
+
+    roundR = 4096 - (ramLen % 4096);
+    if ( roundR ) {
+	printf("Rounding RAM disk file up to a multiple of 4096, adding %d\n", roundR);
+	ramLen += roundR;
+    }
+
+    printf("Rounded RAM disk size is %d\n", ramLen);
+    fseek(inputVmlinux, 0, SEEK_END);
+    kernelLen = ftell(inputVmlinux);
+    fseek(inputVmlinux, 0, SEEK_SET);
+    printf("kernel file size = %d\n", kernelLen);
+    if ( kernelLen == 0 ) {
+	printf("You must have a linux kernel specified as argv[2]\n");
+	exit(1);
+    }
+
+    actualKernelLen = kernelLen - ElfHeaderSize;
+
+    printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen);
+
+    round = actualKernelLen % 4096;
+    roundedKernelLen = actualKernelLen;
+    if ( round )
+	roundedKernelLen += (4096 - round);
+
+    printf("actual kernel length rounded up to a 4k multiple = %d\n", roundedKernelLen);
+
+    ramStartOffs = roundedKernelLen;
+    ramPages = ramLen / 4096;
+
+    printf("RAM disk pages to copy = %d\n", ramPages);
+
+    // Copy 64K ELF header
+      for (i=0; i<(ElfPages); ++i) {
+	  get4k( inputVmlinux, inbuf );
+	  put4k( outputVmlinux, inbuf );
+      }
+
+    roundedKernelPages = roundedKernelLen / 4096;
+
+    fseek(inputVmlinux, ElfHeaderSize, SEEK_SET);
+
+    for ( i=0; i<roundedKernelPages; ++i ) {
+	get4k( inputVmlinux, inbuf );
+	put4k( outputVmlinux, inbuf );
+    }
+
+    for ( i=0; i<ramPages; ++i ) {
+	get4k( ramDisk, inbuf );
+	put4k( outputVmlinux, inbuf );
+    }
+
+    /* Close the input files */
+    fclose(ramDisk);
+    fclose(inputVmlinux);
+    /* And flush the written output file */
+    fflush(outputVmlinux);
+
+    /* fseek to the hvReleaseData pointer */
+    fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET);
+    if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) {
+        death("Could not read hvReleaseData pointer\n", outputVmlinux, argv[3]);
+    }
+    hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */
+    printf("hvReleaseData is at %08x\n", hvReleaseData);
+
+    /* fseek to the hvReleaseData */
+    fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET);
+    if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) {
+        death("Could not read hvReleaseData\n", outputVmlinux, argv[3]);
+    }
+    /* Check hvReleaseData sanity */
+    if (memcmp(inbuf, &eyeCatcher, 4) != 0) {
+        death("hvReleaseData is invalid\n", outputVmlinux, argv[3]);
+    }
+    /* Get the naca pointer */
+    naca = ntohl(*((u_int32_t *) &inbuf[0x0c])) - KERNELBASE;
+    printf("naca is at %08x\n", naca);
+
+    /* fseek to the naca */
+    fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
+    if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) {
+        death("Could not read naca\n", outputVmlinux, argv[3]);
+    }
+    xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c]));
+    xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14]));
+    /* Make sure a RAM disk isn't already present */
+    if ((xRamDisk != 0) || (xRamDiskSize != 0)) {
+        death("RAM disk is already attached to this kernel\n", outputVmlinux, argv[3]);
+    }
+    /* Fill in the values */
+    *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs);
+    *((u_int32_t *) &inbuf[0x14]) = htonl(ramPages);
+
+    /* Write out the new naca */
+    fflush(outputVmlinux);
+    fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET);
+    if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) {
+        death("Could not write naca\n", outputVmlinux, argv[3]);
+    }
+    printf("RAM Disk of 0x%x pages size is attached to the kernel at offset 0x%08x\n",
+            ramPages, ramStartOffs);
+
+    /* Done */
+    fclose(outputVmlinux);
+    /* Set permission to executable */
+    chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+
+    return 0;
+}
+
diff --git a/arch/ppc/boot/utils/addSystemMap.c b/arch/ppc/boot/utils/addSystemMap.c
new file mode 100644
index 0000000..4654f89
--- /dev/null
+++ b/arch/ppc/boot/utils/addSystemMap.c
@@ -0,0 +1,186 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <byteswap.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+void xlate( char * inb, char * trb, unsigned len )
+{
+    unsigned i;
+    for (  i=0; i<len; ++i ) {
+	char c = *inb++;
+	char c1 = c >> 4;
+	char c2 = c & 0xf;
+	if ( c1 > 9 )
+	    c1 = c1 + 'A' - 10;
+	else
+	    c1 = c1 + '0';
+	if ( c2 > 9 )
+	    c2 = c2 + 'A' - 10;
+	else
+	    c2 = c2 + '0';
+	*trb++ = c1;
+	*trb++ = c2;
+    }
+    *trb = 0;
+}
+
+#define ElfHeaderSize  (64 * 1024)
+#define ElfPages  (ElfHeaderSize / 4096)
+#define KERNELBASE (0xc0000000)
+
+void get4k( /*istream *inf*/FILE *file, char *buf )
+{
+    unsigned j;
+    unsigned num = fread(buf, 1, 4096, file);
+    for (  j=num; j<4096; ++j )
+	buf[j] = 0;
+}
+
+void put4k( /*ostream *outf*/FILE *file, char *buf )
+{
+    fwrite(buf, 1, 4096, file);
+}
+
+int main(int argc, char **argv)
+{
+    char inbuf[4096];
+    FILE *ramDisk = NULL;
+    FILE *inputVmlinux = NULL;
+    FILE *outputVmlinux = NULL;
+    unsigned i = 0;
+    unsigned long ramFileLen = 0;
+    unsigned long ramLen = 0;
+    unsigned long roundR = 0;
+    unsigned long kernelLen = 0;
+    unsigned long actualKernelLen = 0;
+    unsigned long round = 0;
+    unsigned long roundedKernelLen = 0;
+    unsigned long ramStartOffs = 0;
+    unsigned long ramPages = 0;
+    unsigned long roundedKernelPages = 0;
+    if ( argc < 2 ) {
+	printf("Name of System Map file missing.\n");
+	exit(1);
+    }
+
+    if ( argc < 3 ) {
+	printf("Name of vmlinux file missing.\n");
+	exit(1);
+    }
+
+    if ( argc < 4 ) {
+	printf("Name of vmlinux output file missing.\n");
+	exit(1);
+    }
+
+    ramDisk = fopen(argv[1], "r");
+    if ( ! ramDisk ) {
+	printf("System Map file \"%s\" failed to open.\n", argv[1]);
+	exit(1);
+    }
+    inputVmlinux = fopen(argv[2], "r");
+    if ( ! inputVmlinux ) {
+	printf("vmlinux file \"%s\" failed to open.\n", argv[2]);
+	exit(1);
+    }
+    outputVmlinux = fopen(argv[3], "w");
+    if ( ! outputVmlinux ) {
+	printf("output vmlinux file \"%s\" failed to open.\n", argv[3]);
+	exit(1);
+    }
+    fseek(ramDisk, 0, SEEK_END);
+    ramFileLen = ftell(ramDisk);
+    fseek(ramDisk, 0, SEEK_SET);
+    printf("%s file size = %ld\n", argv[1], ramFileLen);
+
+    ramLen = ramFileLen;
+
+    roundR = 4096 - (ramLen % 4096);
+    if ( roundR ) {
+	printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR);
+	ramLen += roundR;
+    }
+
+    printf("Rounded System Map size is %ld\n", ramLen);
+    fseek(inputVmlinux, 0, SEEK_END);
+    kernelLen = ftell(inputVmlinux);
+    fseek(inputVmlinux, 0, SEEK_SET);
+    printf("kernel file size = %ld\n", kernelLen);
+    if ( kernelLen == 0 ) {
+	printf("You must have a linux kernel specified as argv[2]\n");
+	exit(1);
+    }
+
+    actualKernelLen = kernelLen - ElfHeaderSize;
+
+    printf("actual kernel length (minus ELF header) = %ld\n", actualKernelLen);
+
+    round = actualKernelLen % 4096;
+    roundedKernelLen = actualKernelLen;
+    if ( round )
+	roundedKernelLen += (4096 - round);
+
+    printf("actual kernel length rounded up to a 4k multiple = %ld\n", roundedKernelLen);
+
+    ramStartOffs = roundedKernelLen;
+    ramPages = ramLen / 4096;
+
+    printf("System map pages to copy = %ld\n", ramPages);
+
+    // Copy 64K ELF header
+      for (i=0; i<(ElfPages); ++i) {
+	  get4k( inputVmlinux, inbuf );
+	  put4k( outputVmlinux, inbuf );
+      }
+
+
+
+    roundedKernelPages = roundedKernelLen / 4096;
+
+    fseek(inputVmlinux, ElfHeaderSize, SEEK_SET);
+
+    {
+	for ( i=0; i<roundedKernelPages; ++i ) {
+	    get4k( inputVmlinux, inbuf );
+	    if ( i == 0 ) {
+		unsigned long * p;
+		printf("Storing embedded_sysmap_start at 0x3c\n");
+		p = (unsigned long *)(inbuf + 0x3c);
+
+#if (BYTE_ORDER == __BIG_ENDIAN)
+		*p = ramStartOffs;
+#else
+		*p = bswap_32(ramStartOffs);
+#endif
+
+		printf("Storing embedded_sysmap_end at 0x44\n");
+		p = (unsigned long *)(inbuf + 0x44);
+#if (BYTE_ORDER == __BIG_ENDIAN)
+		*p = ramStartOffs + ramFileLen;
+#else
+		*p = bswap_32(ramStartOffs + ramFileLen);
+#endif
+	    }
+	    put4k( outputVmlinux, inbuf );
+	}
+    }
+
+    {
+	for ( i=0; i<ramPages; ++i ) {
+	    get4k( ramDisk, inbuf );
+	    put4k( outputVmlinux, inbuf );
+	}
+    }
+
+
+    fclose(ramDisk);
+    fclose(inputVmlinux);
+    fclose(outputVmlinux);
+    /* Set permission to executable */
+    chmod(argv[3], S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
+
+    return 0;
+
+}
+
diff --git a/arch/ppc/boot/utils/addnote.c b/arch/ppc/boot/utils/addnote.c
new file mode 100644
index 0000000..6c52b18
--- /dev/null
+++ b/arch/ppc/boot/utils/addnote.c
@@ -0,0 +1,175 @@
+/*
+ * Program to hack in a PT_NOTE program header entry in an ELF file.
+ * This is needed for OF on RS/6000s to load an image correctly.
+ * Note that OF needs a program header entry for the note, not an
+ * ELF section.
+ *
+ * Copyright 2000 Paul Mackerras.
+ *
+ * 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.
+ *
+ * Usage: addnote zImage
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+char arch[] = "PowerPC";
+
+#define N_DESCR	6
+unsigned int descr[N_DESCR] = {
+#if 1
+	/* values for IBM RS/6000 machines */
+	0xffffffff,		/* real-mode = true */
+	0x00c00000,		/* real-base, i.e. where we expect OF to be */
+	0xffffffff,		/* real-size */
+	0xffffffff,		/* virt-base */
+	0xffffffff,		/* virt-size */
+	0x4000,			/* load-base */
+#else
+	/* values for longtrail CHRP */
+	0,			/* real-mode = false */
+	0xffffffff,		/* real-base */
+	0xffffffff,		/* real-size */
+	0xffffffff,		/* virt-base */
+	0xffffffff,		/* virt-size */
+	0x00600000,		/* load-base */
+#endif
+};
+
+unsigned char buf[512];
+
+#define GET_16BE(off)	((buf[off] << 8) + (buf[(off)+1]))
+#define GET_32BE(off)	((GET_16BE(off) << 16) + GET_16BE((off)+2))
+
+#define PUT_16BE(off, v)	(buf[off] = ((v) >> 8) & 0xff, \
+				 buf[(off) + 1] = (v) & 0xff)
+#define PUT_32BE(off, v)	(PUT_16BE((off), (v) >> 16), \
+				 PUT_16BE((off) + 2, (v)))
+
+/* Structure of an ELF file */
+#define E_IDENT		0	/* ELF header */
+#define	E_PHOFF		28
+#define E_PHENTSIZE	42
+#define E_PHNUM		44
+#define E_HSIZE		52	/* size of ELF header */
+
+#define EI_MAGIC	0	/* offsets in E_IDENT area */
+#define EI_CLASS	4
+#define EI_DATA		5
+
+#define PH_TYPE		0	/* ELF program header */
+#define PH_OFFSET	4
+#define PH_FILESZ	16
+#define PH_HSIZE	32	/* size of program header */
+
+#define PT_NOTE		4	/* Program header type = note */
+
+#define ELFCLASS32	1
+#define ELFDATA2MSB	2
+
+unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
+
+int main(int ac, char **av)
+{
+	int fd, n, i;
+	int ph, ps, np;
+	int nnote, ns;
+
+	if (ac != 2) {
+		fprintf(stderr, "Usage: %s elf-file\n", av[0]);
+		exit(1);
+	}
+	fd = open(av[1], O_RDWR);
+	if (fd < 0) {
+		perror(av[1]);
+		exit(1);
+	}
+
+	nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4;
+
+	n = read(fd, buf, sizeof(buf));
+	if (n < 0) {
+		perror("read");
+		exit(1);
+	}
+
+	if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0)
+		goto notelf;
+
+	if (buf[E_IDENT+EI_CLASS] != ELFCLASS32
+	    || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) {
+		fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n",
+			av[1]);
+		exit(1);
+	}
+
+	ph = GET_32BE(E_PHOFF);
+	ps = GET_16BE(E_PHENTSIZE);
+	np = GET_16BE(E_PHNUM);
+	if (ph < E_HSIZE || ps < PH_HSIZE || np < 1)
+		goto notelf;
+	if (ph + (np + 1) * ps + nnote > n)
+		goto nospace;
+
+	for (i = 0; i < np; ++i) {
+		if (GET_32BE(ph + PH_TYPE) == PT_NOTE) {
+			fprintf(stderr, "%s already has a note entry\n",
+				av[1]);
+			exit(0);
+		}
+		ph += ps;
+	}
+
+	/* XXX check that the area we want to use is all zeroes */
+	for (i = 0; i < ps + nnote; ++i)
+		if (buf[ph + i] != 0)
+			goto nospace;
+
+	/* fill in the program header entry */
+	ns = ph + ps;
+	PUT_32BE(ph + PH_TYPE, PT_NOTE);
+	PUT_32BE(ph + PH_OFFSET, ns);
+	PUT_32BE(ph + PH_FILESZ, nnote);
+
+	/* fill in the note area we point to */
+	/* XXX we should probably make this a proper section */
+	PUT_32BE(ns, strlen(arch) + 1);
+	PUT_32BE(ns + 4, N_DESCR * 4);
+	PUT_32BE(ns + 8, 0x1275);
+	strcpy(&buf[ns + 12], arch);
+	ns += 12 + strlen(arch) + 1;
+	for (i = 0; i < N_DESCR; ++i)
+		PUT_32BE(ns + i * 4, descr[i]);
+
+	/* Update the number of program headers */
+	PUT_16BE(E_PHNUM, np + 1);
+
+	/* write back */
+	lseek(fd, (long) 0, SEEK_SET);
+	i = write(fd, buf, n);
+	if (i < 0) {
+		perror("write");
+		exit(1);
+	}
+	if (i < n) {
+		fprintf(stderr, "%s: write truncated\n", av[1]);
+		exit(1);
+	}
+
+	exit(0);
+
+ notelf:
+	fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]);
+	exit(1);
+
+ nospace:
+	fprintf(stderr, "sorry, I can't find space in %s to put the note\n",
+		av[0]);
+	exit(1);
+}
diff --git a/arch/ppc/boot/utils/elf.pl b/arch/ppc/boot/utils/elf.pl
new file mode 100644
index 0000000..d3e9d9d
--- /dev/null
+++ b/arch/ppc/boot/utils/elf.pl
@@ -0,0 +1,33 @@
+#
+# ELF header field numbers
+#
+
+$e_ident	=  0;	# Identification bytes / magic number
+$e_type		=  1;	# ELF file type
+$e_machine	=  2;	# Target machine type
+$e_version	=  3;	# File version
+$e_entry	=  4;	# Start address
+$e_phoff	=  5;	# Program header file offset
+$e_shoff	=  6;	# Section header file offset
+$e_flags	=  7;	# File flags
+$e_ehsize	=  8;	# Size of ELF header
+$e_phentsize	=  9;	# Size of program header
+$e_phnum	= 10;	# Number of program header entries
+$e_shentsize	= 11;	# Size of section header
+$e_shnum	= 12;	# Number of section header entries
+$e_shstrndx	= 13;	# Section header table string index
+
+#
+# Section header field numbers
+#
+
+$sh_name	=  0;	# Section name
+$sh_type	=  1;	# Section header type
+$sh_flags	=  2;	# Section header flags
+$sh_addr	=  3;	# Virtual address
+$sh_offset	=  4;	# File offset
+$sh_size	=  5;	# Section size
+$sh_link	=  6;	# Miscellaneous info
+$sh_info	=  7;	# More miscellaneous info
+$sh_addralign	=  8;	# Memory alignment
+$sh_entsize	=  9;	# Entry size if this is a table
diff --git a/arch/ppc/boot/utils/hack-coff.c b/arch/ppc/boot/utils/hack-coff.c
new file mode 100644
index 0000000..5e5a657
--- /dev/null
+++ b/arch/ppc/boot/utils/hack-coff.c
@@ -0,0 +1,84 @@
+/*
+ * hack-coff.c - hack the header of an xcoff file to fill in
+ * a few fields needed by the Open Firmware xcoff loader on
+ * Power Macs but not initialized by objcopy.
+ *
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include "rs6000.h"
+
+#define AOUT_MAGIC	0x010b
+
+#define get_16be(x)	((((unsigned char *)(x))[0] << 8) \
+			 + ((unsigned char *)(x))[1])
+#define put_16be(x, v)	(((unsigned char *)(x))[0] = (v) >> 8, \
+			 ((unsigned char *)(x))[1] = (v) & 0xff)
+#define get_32be(x)	((((unsigned char *)(x))[0] << 24) \
+			 + (((unsigned char *)(x))[1] << 16) \
+			 + (((unsigned char *)(x))[2] << 8) \
+			 + ((unsigned char *)(x))[3])
+
+int
+main(int ac, char **av)
+{
+    int fd;
+    int i, nsect;
+    int aoutsz;
+    struct external_filehdr fhdr;
+    AOUTHDR aout;
+    struct external_scnhdr shdr;
+
+    if (ac != 2) {
+	fprintf(stderr, "Usage: hack-coff coff-file\n");
+	exit(1);
+    }
+    if ((fd = open(av[1], 2)) == -1) {
+	perror(av[2]);
+	exit(1);
+    }
+    if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr))
+	goto readerr;
+    i = get_16be(fhdr.f_magic);
+    if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) {
+	fprintf(stderr, "%s: not an xcoff file\n", av[1]);
+	exit(1);
+    }
+    aoutsz = get_16be(fhdr.f_opthdr);
+    if (read(fd, &aout, aoutsz) != aoutsz)
+	goto readerr;
+    nsect = get_16be(fhdr.f_nscns);
+    for (i = 0; i < nsect; ++i) {
+	if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr))
+	    goto readerr;
+	if (strcmp(shdr.s_name, ".text") == 0) {
+	    put_16be(aout.o_snentry, i+1);
+	    put_16be(aout.o_sntext, i+1);
+	} else if (strcmp(shdr.s_name, ".data") == 0) {
+	    put_16be(aout.o_sndata, i+1);
+	} else if (strcmp(shdr.s_name, ".bss") == 0) {
+	    put_16be(aout.o_snbss, i+1);
+	}
+    }
+    put_16be(aout.magic, AOUT_MAGIC);
+    if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1
+	|| write(fd, &aout, aoutsz) != aoutsz) {
+	fprintf(stderr, "%s: write error\n", av[1]);
+	exit(1);
+    }
+    close(fd);
+    exit(0);
+
+readerr:
+    fprintf(stderr, "%s: read error or file too short\n", av[1]);
+    exit(1);
+}
diff --git a/arch/ppc/boot/utils/mkbugboot.c b/arch/ppc/boot/utils/mkbugboot.c
new file mode 100644
index 0000000..8861222
--- /dev/null
+++ b/arch/ppc/boot/utils/mkbugboot.c
@@ -0,0 +1,187 @@
+/*
+ * arch/ppc/boot/utils/mkbugboot.c
+ *
+ * Makes a Motorola PPCBUG ROM bootable image which can be flashed
+ * into one of the FLASH banks on a Motorola PowerPlus board.
+ *
+ * Author: Matt Porter <mporter@mvista.com>
+ *
+ * 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.
+ */
+
+#define ELF_HEADER_SIZE	65536
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#ifdef __sun__
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
+#ifdef __i386__
+#define cpu_to_be32(x) le32_to_cpu(x)
+#define cpu_to_be16(x) le16_to_cpu(x)
+#else
+#define cpu_to_be32(x) (x)
+#define cpu_to_be16(x) (x)
+#endif
+
+#define cpu_to_le32(x) le32_to_cpu((x))
+unsigned long le32_to_cpu(unsigned long x)
+{
+     	return (((x & 0x000000ffU) << 24) |
+		((x & 0x0000ff00U) <<  8) |
+		((x & 0x00ff0000U) >>  8) |
+		((x & 0xff000000U) >> 24));
+}
+
+#define cpu_to_le16(x) le16_to_cpu((x))
+unsigned short le16_to_cpu(unsigned short x)
+{
+	return (((x & 0x00ff) << 8) |
+		((x & 0xff00) >> 8));
+}
+
+/* size of read buffer */
+#define SIZE 0x1000
+
+/* PPCBUG ROM boot header */
+typedef struct bug_boot_header {
+  uint8_t	magic_word[4];		/* "BOOT" */
+  uint32_t	entry_offset;		/* Offset from top of header to code */
+  uint32_t	routine_length;		/* Length of code */
+  uint8_t	routine_name[8];	/* Name of the boot code */
+} bug_boot_header_t;
+
+#define HEADER_SIZE	sizeof(bug_boot_header_t)
+
+uint32_t copy_image(int32_t in_fd, int32_t out_fd)
+{
+  uint8_t buf[SIZE];
+  int n;
+  uint32_t image_size = 0;
+  uint8_t zero = 0;
+
+  lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET);
+
+  /* Copy an image while recording its size */
+  while ( (n = read(in_fd, buf, SIZE)) > 0 )
+    {
+    image_size = image_size + n;
+    write(out_fd, buf, n);
+    }
+
+  /* BUG romboot requires that our size is divisible by 2 */
+  /* align image to 2 byte boundary */
+  if (image_size % 2)
+    {
+    image_size++;
+    write(out_fd, &zero, 1);
+    }
+
+  return image_size;
+}
+
+void write_bugboot_header(int32_t out_fd, uint32_t boot_size)
+{
+  uint8_t header_block[HEADER_SIZE];
+  bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0];
+
+  memset(header_block, 0, HEADER_SIZE);
+
+  /* Fill in the PPCBUG ROM boot header */
+  strncpy(bbh->magic_word, "BOOT", 4);		/* PPCBUG magic word */
+  bbh->entry_offset = cpu_to_be32(HEADER_SIZE);	/* Entry address */
+  bbh->routine_length= cpu_to_be32(HEADER_SIZE+boot_size+2);	/* Routine length */
+  strncpy(bbh->routine_name, "LINUXROM", 8);		/* Routine name   */
+
+  /* Output the header and bootloader to the file */
+  write(out_fd, header_block, HEADER_SIZE);
+}
+
+uint16_t calc_checksum(int32_t bug_fd)
+{
+  uint32_t checksum_var = 0;
+  uint8_t buf[2];
+  int n;
+
+  /* Checksum loop */
+  while ( (n = read(bug_fd, buf, 2) ) )
+  {
+    checksum_var = checksum_var + *(uint16_t *)buf;
+
+    /* If we carry out, mask it and add one to the checksum */
+    if (checksum_var >> 16)
+      checksum_var = (checksum_var & 0x0000ffff) + 1;
+  }
+
+  return checksum_var;
+}
+
+int main(int argc, char *argv[])
+{
+  int32_t image_fd, bugboot_fd;
+  int argptr = 1;
+  uint32_t kernel_size = 0;
+  uint16_t checksum = 0;
+  uint8_t bugbootname[256];
+
+  if ( (argc != 3) )
+  {
+    fprintf(stderr, "usage: %s <kernel_image> <bugboot>\n",argv[0]);
+    exit(-1);
+  }
+
+  /* Get file args */
+
+  /* kernel image file */
+    if ((image_fd = open( argv[argptr] , 0)) < 0)
+      exit(-1);
+  argptr++;
+
+  /* bugboot file */
+  if ( !strcmp( argv[argptr], "-" ) )
+    bugboot_fd = 1;			/* stdout */
+  else
+    if ((bugboot_fd = creat( argv[argptr] , 0755)) < 0)
+      exit(-1);
+    else
+      strcpy(bugbootname, argv[argptr]);
+  argptr++;
+
+  /* Set file position after ROM header block where zImage will be written */
+  lseek(bugboot_fd, HEADER_SIZE, SEEK_SET);
+
+  /* Copy kernel image into bugboot image */
+  kernel_size = copy_image(image_fd, bugboot_fd);
+  close(image_fd);
+
+  /* Set file position to beginning where header/romboot will be written */
+  lseek(bugboot_fd, 0, SEEK_SET);
+
+  /* Write out BUG header/romboot */
+  write_bugboot_header(bugboot_fd, kernel_size);
+
+  /* Close bugboot file */
+  close(bugboot_fd);
+
+  /* Reopen it as read/write */
+  bugboot_fd = open(bugbootname, O_RDWR);
+
+  /* Calculate checksum */
+  checksum = calc_checksum(bugboot_fd);
+
+  /* Write out the calculated checksum */
+  write(bugboot_fd, &checksum, 2);
+
+  return 0;
+}
diff --git a/arch/ppc/boot/utils/mknote.c b/arch/ppc/boot/utils/mknote.c
new file mode 100644
index 0000000..b9fbb2c
--- /dev/null
+++ b/arch/ppc/boot/utils/mknote.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) Cort Dougan 1999.
+ *
+ * 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.
+ *
+ * Generate a note section as per the CHRP specification.
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
+
+int main(void)
+{
+/* header */
+	/* namesz */
+	PL(strlen("PowerPC")+1);
+	/* descrsz */
+	PL(6*4);
+	/* type */
+	PL(0x1275);
+	/* name */
+	printf("PowerPC"); printf("%c", 0);
+	
+/* descriptor */
+	/* real-mode */
+	PL(0xffffffff);
+	/* real-base */
+	PL(0x00c00000);
+	/* real-size */
+	PL(0xffffffff);
+	/* virt-base */
+	PL(0xffffffff);
+	/* virt-size */
+	PL(0xffffffff);
+	/* load-base */
+	PL(0x4000);
+	return 0;
+}
diff --git a/arch/ppc/boot/utils/mkprep.c b/arch/ppc/boot/utils/mkprep.c
new file mode 100644
index 0000000..f6d5a2f
--- /dev/null
+++ b/arch/ppc/boot/utils/mkprep.c
@@ -0,0 +1,293 @@
+/*
+ * Makes a prep bootable image which can be dd'd onto
+ * a disk device to make a bootdisk.  Will take
+ * as input a elf executable, strip off the header
+ * and write out a boot image as:
+ * 1) default - strips elf header
+ *      suitable as a network boot image
+ * 2) -pbp - strips elf header and writes out prep boot partition image
+ *      cat or dd onto disk for booting
+ * 3) -asm - strips elf header and writes out as asm data
+ *      useful for generating data for a compressed image
+ *                  -- Cort
+ *
+ * Modified for x86 hosted builds by Matt Porter <porter@neta.com>
+ * Modified for Sparc hosted builds by Peter Wahl <PeterWahl@web.de>
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define cpu_to_le32(x) le32_to_cpu((x))
+unsigned long le32_to_cpu(unsigned long x)
+{
+     	return (((x & 0x000000ffU) << 24) |
+		((x & 0x0000ff00U) <<  8) |
+		((x & 0x00ff0000U) >>  8) |
+		((x & 0xff000000U) >> 24));
+}
+
+
+#define cpu_to_le16(x) le16_to_cpu((x))
+unsigned short le16_to_cpu(unsigned short x)
+{
+	return (((x & 0x00ff) << 8) |
+		((x & 0xff00) >> 8));
+}
+
+#define cpu_to_be32(x) (x)
+#define be32_to_cpu(x) (x)
+#define cpu_to_be16(x) (x)
+#define be16_to_cpu(x) (x)
+
+/* size of read buffer */
+#define SIZE 0x1000
+
+
+typedef unsigned long dword_t;
+typedef unsigned short word_t;
+typedef unsigned char byte_t;
+typedef byte_t block_t[512];
+typedef byte_t page_t[4096];
+
+
+/*
+ * Partition table entry
+ *  - from the PReP spec
+ */
+typedef struct partition_entry {
+  byte_t	boot_indicator;
+  byte_t	starting_head;
+  byte_t	starting_sector;
+  byte_t	starting_cylinder;
+
+  byte_t	system_indicator;
+  byte_t	ending_head;
+  byte_t	ending_sector;
+  byte_t	ending_cylinder;
+
+  dword_t	beginning_sector;
+  dword_t	number_of_sectors;
+} partition_entry_t;
+
+#define BootActive	0x80
+#define SystemPrep	0x41
+
+void copy_image(int , int);
+void write_prep_partition(int , int );
+void write_asm_data( int in, int out );
+
+unsigned int elfhdr_size = 65536;
+
+int main(int argc, char *argv[])
+{
+  int in_fd, out_fd;
+  int argptr = 1;
+  unsigned int prep = 0;
+  unsigned int asmoutput = 0;
+
+  if ( (argc < 3) || (argc > 4) )
+  {
+    fprintf(stderr, "usage: %s [-pbp] [-asm] <boot-file> <image>\n",argv[0]);
+    exit(-1);
+  }
+
+  /* needs to handle args more elegantly -- but this is a small/simple program */
+
+  /* check for -pbp */
+  if ( !strcmp( argv[argptr], "-pbp" ) )
+  {
+    prep = 1;
+    argptr++;
+  }
+
+  /* check for -asm */
+  if ( !strcmp( argv[argptr], "-asm" ) )
+  {
+    asmoutput = 1;
+    argptr++;
+  }
+
+  /* input file */
+  if ( !strcmp( argv[argptr], "-" ) )
+    in_fd = 0;			/* stdin */
+  else
+    if ((in_fd = open( argv[argptr] , 0)) < 0)
+      exit(-1);
+  argptr++;
+
+  /* output file */
+  if ( !strcmp( argv[argptr], "-" ) )
+    out_fd = 1;			/* stdout */
+  else
+    if ((out_fd = creat( argv[argptr] , 0755)) < 0)
+      exit(-1);
+  argptr++;
+
+  /* skip elf header in input file */
+  /*if ( !prep )*/
+  lseek(in_fd, elfhdr_size, SEEK_SET);
+
+  /* write prep partition if necessary */
+  if ( prep )
+	  write_prep_partition( in_fd, out_fd );
+
+  /* write input image to bootimage */
+  if ( asmoutput )
+	  write_asm_data( in_fd, out_fd );
+  else
+	  copy_image(in_fd, out_fd);
+
+  return 0;
+}
+
+void write_prep_partition(int in, int out)
+{
+  unsigned char block[512];
+  partition_entry_t pe;
+  dword_t *entry  = (dword_t *)&block[0];
+  dword_t *length = (dword_t *)&block[sizeof(long)];
+  struct stat info;
+
+  if (fstat(in, &info) < 0)
+  {
+    fprintf(stderr,"info failed\n");
+    exit(-1);
+  }
+
+  bzero( block, sizeof block );
+
+  /* set entry point and boot image size skipping over elf header */
+#ifdef __i386__
+  *entry = 0x400/*+65536*/;
+  *length = info.st_size-elfhdr_size+0x400;
+#else
+  *entry = cpu_to_le32(0x400/*+65536*/);
+  *length = cpu_to_le32(info.st_size-elfhdr_size+0x400);
+#endif /* __i386__ */
+
+  /* sets magic number for msdos partition (used by linux) */
+  block[510] = 0x55;
+  block[511] = 0xAA;
+
+  /*
+   * Build a "PReP" partition table entry in the boot record
+   *  - "PReP" may only look at the system_indicator
+   */
+  pe.boot_indicator   = BootActive;
+  pe.system_indicator = SystemPrep;
+  /*
+   * The first block of the diskette is used by this "boot record" which
+   * actually contains the partition table. (The first block of the
+   * partition contains the boot image, but I digress...)  We'll set up
+   * one partition on the diskette and it shall contain the rest of the
+   * diskette.
+   */
+  pe.starting_head     = 0;	/* zero-based			     */
+  pe.starting_sector   = 2;	/* one-based			     */
+  pe.starting_cylinder = 0;	/* zero-based			     */
+  pe.ending_head       = 1;	/* assumes two heads		     */
+  pe.ending_sector     = 18;	/* assumes 18 sectors/track	     */
+  pe.ending_cylinder   = 79;	/* assumes 80 cylinders/diskette     */
+
+  /*
+   * The "PReP" software ignores the above fields and just looks at
+   * the next two.
+   *   - size of the diskette is (assumed to be)
+   *     (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette)
+   *   - unlike the above sector numbers, the beginning sector is zero-based!
+   */
+#if 0
+  pe.beginning_sector  = cpu_to_le32(1);
+#else
+  /* This has to be 0 on the PowerStack? */
+#ifdef __i386__
+  pe.beginning_sector  = 0;
+#else
+  pe.beginning_sector  = cpu_to_le32(0);
+#endif /* __i386__ */
+#endif
+
+#ifdef __i386__
+  pe.number_of_sectors = 2*18*80-1;
+#else
+  pe.number_of_sectors = cpu_to_le32(2*18*80-1);
+#endif /* __i386__ */
+
+  memcpy(&block[0x1BE], &pe, sizeof(pe));
+
+  write( out, block, sizeof(block) );
+  write( out, entry, sizeof(*entry) );
+  write( out, length, sizeof(*length) );
+  /* set file position to 2nd sector where image will be written */
+  lseek( out, 0x400, SEEK_SET );
+}
+
+
+
+void
+copy_image(int in, int out)
+{
+  char buf[SIZE];
+  int n;
+
+  while ( (n = read(in, buf, SIZE)) > 0 )
+    write(out, buf, n);
+}
+
+
+void
+write_asm_data( int in, int out )
+{
+  int i, cnt, pos, len;
+  unsigned int cksum, val;
+  unsigned char *lp;
+  unsigned char buf[SIZE];
+  unsigned char str[256];
+
+  write( out, "\t.data\n\t.globl input_data\ninput_data:\n",
+	 strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) );
+  pos = 0;
+  cksum = 0;
+  while ((len = read(in, buf, sizeof(buf))) > 0)
+  {
+    cnt = 0;
+    lp = (unsigned char *)buf;
+    len = (len + 3) & ~3;  /* Round up to longwords */
+    for (i = 0;  i < len;  i += 4)
+    {
+      if (cnt == 0)
+      {
+	write( out, "\t.long\t", strlen( "\t.long\t" ) );
+      }
+      sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
+      write( out, str, strlen(str) );
+      val = *(unsigned long *)lp;
+      cksum ^= val;
+      lp += 4;
+      if (++cnt == 4)
+      {
+	cnt = 0;
+	sprintf( str, " # %x \n", pos+i-12);
+	write( out, str, strlen(str) );
+      } else
+      {
+	write( out, ",", 1 );
+      }
+    }
+    if (cnt)
+    {
+      write( out, "0\n", 2 );
+    }
+    pos += len;
+  }
+  sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos);
+  write( out, str, strlen(str) );
+
+  fprintf(stderr, "cksum = %x\n", cksum);
+}
diff --git a/arch/ppc/boot/utils/mktree.c b/arch/ppc/boot/utils/mktree.c
new file mode 100644
index 0000000..2be22e2
--- /dev/null
+++ b/arch/ppc/boot/utils/mktree.c
@@ -0,0 +1,152 @@
+/*
+ * Makes a tree bootable image for IBM Evaluation boards.
+ * Basically, just take a zImage, skip the ELF header, and stuff
+ * a 32 byte header on the front.
+ *
+ * We use htonl, which is a network macro, to make sure we're doing
+ * The Right Thing on an LE machine.  It's non-obvious, but it should
+ * work on anything BSD'ish.
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#ifdef __sun__
+#include <inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
+/* This gets tacked on the front of the image.  There are also a few
+ * bytes allocated after the _start label used by the boot rom (see
+ * head.S for details).
+ */
+typedef struct boot_block {
+	uint32_t bb_magic;		/* 0x0052504F */
+	uint32_t bb_dest;		/* Target address of the image */
+	uint32_t bb_num_512blocks;	/* Size, rounded-up, in 512 byte blks */
+	uint32_t bb_debug_flag;	/* Run debugger or image after load */
+	uint32_t bb_entry_point;	/* The image address to start */
+	uint32_t bb_checksum;	/* 32 bit checksum including header */
+	uint32_t reserved[2];
+} boot_block_t;
+
+#define IMGBLK	512
+char	tmpbuf[IMGBLK];
+
+int main(int argc, char *argv[])
+{
+	int	in_fd, out_fd;
+	int	nblks, i;
+	uint	cksum, *cp;
+	struct	stat	st;
+	boot_block_t	bt;
+
+	if (argc < 3) {
+		fprintf(stderr, "usage: %s <zImage-file> <boot-image> [entry-point]\n",argv[0]);
+		exit(1);
+	}
+
+	if (stat(argv[1], &st) < 0) {
+		perror("stat");
+		exit(2);
+	}
+
+	nblks = (st.st_size + IMGBLK) / IMGBLK;
+
+	bt.bb_magic = htonl(0x0052504F);
+
+	/* If we have the optional entry point parameter, use it */
+	if (argc == 4)
+		bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0));
+	else
+		bt.bb_dest = bt.bb_entry_point = htonl(0x500000);
+
+	/* We know these from the linker command.
+	 * ...and then move it up into memory a little more so the
+	 * relocation can happen.
+	 */
+	bt.bb_num_512blocks = htonl(nblks);
+	bt.bb_debug_flag = 0;
+
+	bt.bb_checksum = 0;
+
+	/* To be neat and tidy :-).
+	*/
+	bt.reserved[0] = 0;
+	bt.reserved[1] = 0;
+
+	if ((in_fd = open(argv[1], O_RDONLY)) < 0) {
+		perror("zImage open");
+		exit(3);
+	}
+
+	if ((out_fd = open(argv[2], (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) {
+		perror("bootfile open");
+		exit(3);
+	}
+
+	cksum = 0;
+	cp = (void *)&bt;
+	for (i=0; i<sizeof(bt)/sizeof(uint); i++)
+		cksum += *cp++;
+	
+	/* Assume zImage is an ELF file, and skip the 64K header.
+	*/
+	if (read(in_fd, tmpbuf, IMGBLK) != IMGBLK) {
+		fprintf(stderr, "%s is too small to be an ELF image\n",
+				argv[1]);
+		exit(4);
+	}
+
+	if ((*(uint *)tmpbuf) != htonl(0x7f454c46)) {
+		fprintf(stderr, "%s is not an ELF image\n", argv[1]);
+		exit(4);
+	}
+
+	if (lseek(in_fd, (64 * 1024), SEEK_SET) < 0) {
+		fprintf(stderr, "%s failed to seek in ELF image\n", argv[1]);
+		exit(4);
+	}
+
+	nblks -= (64 * 1024) / IMGBLK;
+
+	/* And away we go......
+	*/
+	if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
+		perror("boot-image write");
+		exit(5);
+	}
+
+	while (nblks-- > 0) {
+		if (read(in_fd, tmpbuf, IMGBLK) < 0) {
+			perror("zImage read");
+			exit(5);
+		}
+		cp = (uint *)tmpbuf;
+		for (i=0; i<sizeof(tmpbuf)/sizeof(uint); i++)
+			cksum += *cp++;
+		if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
+			perror("boot-image write");
+			exit(5);
+		}
+	}
+
+	/* rewrite the header with the computed checksum.
+	*/
+	bt.bb_checksum = htonl(cksum);
+	if (lseek(out_fd, 0, SEEK_SET) < 0) {
+		perror("rewrite seek");
+		exit(1);
+	}
+	if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
+		perror("boot-image rewrite");
+		exit(1);
+	}
+
+	exit(0);
+}