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/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
+