i386: Move cpu/i386/* to arch/i386/cpu/*

Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
diff --git a/arch/i386/cpu/Makefile b/arch/i386/cpu/Makefile
new file mode 100644
index 0000000..c658c6e
--- /dev/null
+++ b/arch/i386/cpu/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2002
+# Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(CPU).a
+
+START	= start.o start16.o resetvec.o
+COBJS	= serial.o interrupts.o cpu.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/i386/cpu/config.mk b/arch/i386/cpu/config.mk
new file mode 100644
index 0000000..16a160d
--- /dev/null
+++ b/arch/i386/cpu/config.mk
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2002
+# Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+PLATFORM_RELFLAGS +=
+
+PLATFORM_CPPFLAGS += -march=i386 -Werror
diff --git a/arch/i386/cpu/cpu.c b/arch/i386/cpu/cpu.c
new file mode 100644
index 0000000..3010519
--- /dev/null
+++ b/arch/i386/cpu/cpu.c
@@ -0,0 +1,92 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/interrupt.h>
+
+int cpu_init_f(void)
+{
+	/* initialize FPU, reset EM, set MP and NE */
+	asm ("fninit\n" \
+	     "movl %cr0, %eax\n" \
+	     "andl $~0x4, %eax\n" \
+	     "orl  $0x22, %eax\n" \
+	     "movl %eax, %cr0\n" );
+
+	return 0;
+}
+
+int cpu_init_r(void)
+{
+	/* Initialize core interrupt and exception functionality of CPU */
+	cpu_init_interrupts ();
+	return 0;
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	printf ("resetting ...\n");
+	udelay(50000);				/* wait 50 ms */
+	disable_interrupts();
+	reset_cpu(0);
+
+	/*NOTREACHED*/
+	return 0;
+}
+
+void  flush_cache (unsigned long dummy1, unsigned long dummy2)
+{
+	asm("wbinvd\n");
+	return;
+}
+
+void __attribute__ ((regparm(0))) generate_gpf(void);
+
+/* segment 0x70 is an arbitrary segment which does not exist */
+asm(".globl generate_gpf\n"
+    ".hidden generate_gpf\n"
+    ".type generate_gpf, @function\n"
+    "generate_gpf:\n"
+    "ljmp   $0x70, $0x47114711\n");
+
+void __reset_cpu(ulong addr)
+{
+	printf("Resetting using i386 Triple Fault\n");
+	set_vector(13, generate_gpf);  /* general protection fault handler */
+	set_vector(8, generate_gpf);   /* double fault handler */
+	generate_gpf();                /* start the show */
+}
+void reset_cpu(ulong addr) __attribute__((weak, alias("__reset_cpu")));
diff --git a/arch/i386/cpu/interrupts.c b/arch/i386/cpu/interrupts.c
new file mode 100644
index 0000000..4b57437
--- /dev/null
+++ b/arch/i386/cpu/interrupts.c
@@ -0,0 +1,501 @@
+/*
+ * (C) Copyright 2008
+ * Graeme Russ, graeme.russ@gmail.com.
+ *
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/interrupt.h>
+
+#define DECLARE_INTERRUPT(x) \
+	".globl irq_"#x"\n" \
+	".hidden irq_"#x"\n" \
+	".type irq_"#x", @function\n" \
+	"irq_"#x":\n" \
+	"pushl %ebp\n" \
+	"movl %esp,%ebp\n" \
+	"pusha\n" \
+	"pushl $"#x"\n" \
+	"jmp irq_common_entry\n"
+
+struct idt_entry {
+	u16	base_low;
+	u16	selector;
+	u8	res;
+	u8	access;
+	u16	base_high;
+} __attribute__ ((packed));
+
+struct desc_ptr {
+	unsigned short size;
+	unsigned long address;
+	unsigned short segment;
+} __attribute__((packed));
+
+struct idt_entry idt[256];
+
+struct desc_ptr idt_ptr;
+
+static inline void load_idt(const struct desc_ptr *dtr)
+{
+	asm volatile("cs lidt %0"::"m" (*dtr));
+}
+
+void set_vector(u8 intnum, void *routine)
+{
+	idt[intnum].base_high = (u16)((u32)(routine) >> 16);
+	idt[intnum].base_low = (u16)((u32)(routine) & 0xffff);
+}
+
+void irq_0(void);
+void irq_1(void);
+
+int cpu_init_interrupts(void)
+{
+	int i;
+
+	int irq_entry_size = irq_1 - irq_0;
+	void *irq_entry = (void *)irq_0;
+
+	/* Just in case... */
+	disable_interrupts();
+
+	/* Setup the IDT */
+	for (i=0;i<256;i++) {
+		idt[i].access = 0x8e;
+		idt[i].res = 0;
+		idt[i].selector = 0x10;
+		set_vector(i, irq_entry);
+		irq_entry += irq_entry_size;
+	}
+
+	idt_ptr.size = 256 * 8;
+	idt_ptr.address = (unsigned long) idt;
+	idt_ptr.segment = 0x18;
+
+	load_idt(&idt_ptr);
+
+	/* It is now safe to enable interrupts */
+	enable_interrupts();
+
+	return 0;
+}
+
+void __do_irq(int irq)
+{
+	printf("Unhandled IRQ : %d\n", irq);
+}
+void do_irq(int irq) __attribute__((weak, alias("__do_irq")));
+
+void enable_interrupts(void)
+{
+	asm("sti\n");
+}
+
+int disable_interrupts(void)
+{
+	long flags;
+
+	asm volatile ("pushfl ; popl %0 ; cli\n" : "=g" (flags) : );
+
+	return (flags&0x200); /* IE flags is bit 9 */
+}
+
+/* IRQ Low-Level Service Routine */
+__isr__ irq_llsr(int ip, int seg, int irq)
+{
+	/*
+	 * For detailed description of each exception, refer to:
+	 * Intel® 64 and IA-32 Architectures Software Developer's Manual
+	 * Volume 1: Basic Architecture
+	 * Order Number: 253665-029US, November 2008
+	 * Table 6-1. Exceptions and Interrupts
+	 */
+	switch (irq) {
+	case 0x00:
+		printf("Divide Error (Division by zero) at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x01:
+		printf("Debug Interrupt (Single step) at %04x:%08x\n", seg, ip);
+		break;
+	case 0x02:
+		printf("NMI Interrupt at %04x:%08x\n", seg, ip);
+		break;
+	case 0x03:
+		printf("Breakpoint at %04x:%08x\n", seg, ip);
+		break;
+	case 0x04:
+		printf("Overflow at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x05:
+		printf("BOUND Range Exceeded at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x06:
+		printf("Invalid Opcode (UnDefined Opcode) at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x07:
+		printf("Device Not Available (No Math Coprocessor) at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x08:
+		printf("Double fault at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x09:
+		printf("Co-processor segment overrun at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x0a:
+		printf("Invalid TSS at %04x:%08x\n", seg, ip);
+		break;
+	case 0x0b:
+		printf("Segment Not Present at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x0c:
+		printf("Stack Segment Fault at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x0d:
+		printf("General Protection at %04x:%08x\n", seg, ip);
+		break;
+	case 0x0e:
+		printf("Page fault at %04x:%08x\n", seg, ip);
+		while(1);
+		break;
+	case 0x0f:
+		printf("Floating-Point Error (Math Fault) at %04x:%08x\n", seg, ip);
+		break;
+	case 0x10:
+		printf("Alignment check at %04x:%08x\n", seg, ip);
+		break;
+	case 0x11:
+		printf("Machine Check at %04x:%08x\n", seg, ip);
+		break;
+	case 0x12:
+		printf("SIMD Floating-Point Exception at %04x:%08x\n", seg, ip);
+		break;
+	case 0x13:
+	case 0x14:
+	case 0x15:
+	case 0x16:
+	case 0x17:
+	case 0x18:
+	case 0x19:
+	case 0x1a:
+	case 0x1b:
+	case 0x1c:
+	case 0x1d:
+	case 0x1e:
+	case 0x1f:
+		printf("Reserved Exception %d at %04x:%08x\n", irq, seg, ip);
+		break;
+
+	default:
+		/* Hardware or User IRQ */
+		do_irq(irq);
+	}
+}
+
+/*
+ * OK - This looks really horrible, but it serves a purpose - It helps create
+ * fully relocatable code.
+ *  - The call to irq_llsr will be a relative jump
+ *  - The IRQ entries will be guaranteed to be in order
+ * It's a bit annoying that we need to waste 3 bytes per interrupt entry
+ * (total of 768 code bytes), but we MUST create a Stack Frame and this is
+ * the easiest way I could do it. Maybe it can be made better later.
+ */
+asm(".globl irq_common_entry\n" \
+	".hidden irq_common_entry\n" \
+	".type irq_common_entry, @function\n" \
+	"irq_common_entry:\n" \
+	"pushl $0\n" \
+	"pushl $0\n" \
+	"call irq_llsr\n" \
+	"popl %eax\n" \
+	"popl %eax\n" \
+	"popl %eax\n" \
+	"popa\n" \
+	"leave\n"\
+	"iret\n" \
+	DECLARE_INTERRUPT(0) \
+	DECLARE_INTERRUPT(1) \
+	DECLARE_INTERRUPT(2) \
+	DECLARE_INTERRUPT(3) \
+	DECLARE_INTERRUPT(4) \
+	DECLARE_INTERRUPT(5) \
+	DECLARE_INTERRUPT(6) \
+	DECLARE_INTERRUPT(7) \
+	DECLARE_INTERRUPT(8) \
+	DECLARE_INTERRUPT(9) \
+	DECLARE_INTERRUPT(10) \
+	DECLARE_INTERRUPT(11) \
+	DECLARE_INTERRUPT(12) \
+	DECLARE_INTERRUPT(13) \
+	DECLARE_INTERRUPT(14) \
+	DECLARE_INTERRUPT(15) \
+	DECLARE_INTERRUPT(16) \
+	DECLARE_INTERRUPT(17) \
+	DECLARE_INTERRUPT(18) \
+	DECLARE_INTERRUPT(19) \
+	DECLARE_INTERRUPT(20) \
+	DECLARE_INTERRUPT(21) \
+	DECLARE_INTERRUPT(22) \
+	DECLARE_INTERRUPT(23) \
+	DECLARE_INTERRUPT(24) \
+	DECLARE_INTERRUPT(25) \
+	DECLARE_INTERRUPT(26) \
+	DECLARE_INTERRUPT(27) \
+	DECLARE_INTERRUPT(28) \
+	DECLARE_INTERRUPT(29) \
+	DECLARE_INTERRUPT(30) \
+	DECLARE_INTERRUPT(31) \
+	DECLARE_INTERRUPT(32) \
+	DECLARE_INTERRUPT(33) \
+	DECLARE_INTERRUPT(34) \
+	DECLARE_INTERRUPT(35) \
+	DECLARE_INTERRUPT(36) \
+	DECLARE_INTERRUPT(37) \
+	DECLARE_INTERRUPT(38) \
+	DECLARE_INTERRUPT(39) \
+	DECLARE_INTERRUPT(40) \
+	DECLARE_INTERRUPT(41) \
+	DECLARE_INTERRUPT(42) \
+	DECLARE_INTERRUPT(43) \
+	DECLARE_INTERRUPT(44) \
+	DECLARE_INTERRUPT(45) \
+	DECLARE_INTERRUPT(46) \
+	DECLARE_INTERRUPT(47) \
+	DECLARE_INTERRUPT(48) \
+	DECLARE_INTERRUPT(49) \
+	DECLARE_INTERRUPT(50) \
+	DECLARE_INTERRUPT(51) \
+	DECLARE_INTERRUPT(52) \
+	DECLARE_INTERRUPT(53) \
+	DECLARE_INTERRUPT(54) \
+	DECLARE_INTERRUPT(55) \
+	DECLARE_INTERRUPT(56) \
+	DECLARE_INTERRUPT(57) \
+	DECLARE_INTERRUPT(58) \
+	DECLARE_INTERRUPT(59) \
+	DECLARE_INTERRUPT(60) \
+	DECLARE_INTERRUPT(61) \
+	DECLARE_INTERRUPT(62) \
+	DECLARE_INTERRUPT(63) \
+	DECLARE_INTERRUPT(64) \
+	DECLARE_INTERRUPT(65) \
+	DECLARE_INTERRUPT(66) \
+	DECLARE_INTERRUPT(67) \
+	DECLARE_INTERRUPT(68) \
+	DECLARE_INTERRUPT(69) \
+	DECLARE_INTERRUPT(70) \
+	DECLARE_INTERRUPT(71) \
+	DECLARE_INTERRUPT(72) \
+	DECLARE_INTERRUPT(73) \
+	DECLARE_INTERRUPT(74) \
+	DECLARE_INTERRUPT(75) \
+	DECLARE_INTERRUPT(76) \
+	DECLARE_INTERRUPT(77) \
+	DECLARE_INTERRUPT(78) \
+	DECLARE_INTERRUPT(79) \
+	DECLARE_INTERRUPT(80) \
+	DECLARE_INTERRUPT(81) \
+	DECLARE_INTERRUPT(82) \
+	DECLARE_INTERRUPT(83) \
+	DECLARE_INTERRUPT(84) \
+	DECLARE_INTERRUPT(85) \
+	DECLARE_INTERRUPT(86) \
+	DECLARE_INTERRUPT(87) \
+	DECLARE_INTERRUPT(88) \
+	DECLARE_INTERRUPT(89) \
+	DECLARE_INTERRUPT(90) \
+	DECLARE_INTERRUPT(91) \
+	DECLARE_INTERRUPT(92) \
+	DECLARE_INTERRUPT(93) \
+	DECLARE_INTERRUPT(94) \
+	DECLARE_INTERRUPT(95) \
+	DECLARE_INTERRUPT(97) \
+	DECLARE_INTERRUPT(96) \
+	DECLARE_INTERRUPT(98) \
+	DECLARE_INTERRUPT(99) \
+	DECLARE_INTERRUPT(100) \
+	DECLARE_INTERRUPT(101) \
+	DECLARE_INTERRUPT(102) \
+	DECLARE_INTERRUPT(103) \
+	DECLARE_INTERRUPT(104) \
+	DECLARE_INTERRUPT(105) \
+	DECLARE_INTERRUPT(106) \
+	DECLARE_INTERRUPT(107) \
+	DECLARE_INTERRUPT(108) \
+	DECLARE_INTERRUPT(109) \
+	DECLARE_INTERRUPT(110) \
+	DECLARE_INTERRUPT(111) \
+	DECLARE_INTERRUPT(112) \
+	DECLARE_INTERRUPT(113) \
+	DECLARE_INTERRUPT(114) \
+	DECLARE_INTERRUPT(115) \
+	DECLARE_INTERRUPT(116) \
+	DECLARE_INTERRUPT(117) \
+	DECLARE_INTERRUPT(118) \
+	DECLARE_INTERRUPT(119) \
+	DECLARE_INTERRUPT(120) \
+	DECLARE_INTERRUPT(121) \
+	DECLARE_INTERRUPT(122) \
+	DECLARE_INTERRUPT(123) \
+	DECLARE_INTERRUPT(124) \
+	DECLARE_INTERRUPT(125) \
+	DECLARE_INTERRUPT(126) \
+	DECLARE_INTERRUPT(127) \
+	DECLARE_INTERRUPT(128) \
+	DECLARE_INTERRUPT(129) \
+	DECLARE_INTERRUPT(130) \
+	DECLARE_INTERRUPT(131) \
+	DECLARE_INTERRUPT(132) \
+	DECLARE_INTERRUPT(133) \
+	DECLARE_INTERRUPT(134) \
+	DECLARE_INTERRUPT(135) \
+	DECLARE_INTERRUPT(136) \
+	DECLARE_INTERRUPT(137) \
+	DECLARE_INTERRUPT(138) \
+	DECLARE_INTERRUPT(139) \
+	DECLARE_INTERRUPT(140) \
+	DECLARE_INTERRUPT(141) \
+	DECLARE_INTERRUPT(142) \
+	DECLARE_INTERRUPT(143) \
+	DECLARE_INTERRUPT(144) \
+	DECLARE_INTERRUPT(145) \
+	DECLARE_INTERRUPT(146) \
+	DECLARE_INTERRUPT(147) \
+	DECLARE_INTERRUPT(148) \
+	DECLARE_INTERRUPT(149) \
+	DECLARE_INTERRUPT(150) \
+	DECLARE_INTERRUPT(151) \
+	DECLARE_INTERRUPT(152) \
+	DECLARE_INTERRUPT(153) \
+	DECLARE_INTERRUPT(154) \
+	DECLARE_INTERRUPT(155) \
+	DECLARE_INTERRUPT(156) \
+	DECLARE_INTERRUPT(157) \
+	DECLARE_INTERRUPT(158) \
+	DECLARE_INTERRUPT(159) \
+	DECLARE_INTERRUPT(160) \
+	DECLARE_INTERRUPT(161) \
+	DECLARE_INTERRUPT(162) \
+	DECLARE_INTERRUPT(163) \
+	DECLARE_INTERRUPT(164) \
+	DECLARE_INTERRUPT(165) \
+	DECLARE_INTERRUPT(166) \
+	DECLARE_INTERRUPT(167) \
+	DECLARE_INTERRUPT(168) \
+	DECLARE_INTERRUPT(169) \
+	DECLARE_INTERRUPT(170) \
+	DECLARE_INTERRUPT(171) \
+	DECLARE_INTERRUPT(172) \
+	DECLARE_INTERRUPT(173) \
+	DECLARE_INTERRUPT(174) \
+	DECLARE_INTERRUPT(175) \
+	DECLARE_INTERRUPT(176) \
+	DECLARE_INTERRUPT(177) \
+	DECLARE_INTERRUPT(178) \
+	DECLARE_INTERRUPT(179) \
+	DECLARE_INTERRUPT(180) \
+	DECLARE_INTERRUPT(181) \
+	DECLARE_INTERRUPT(182) \
+	DECLARE_INTERRUPT(183) \
+	DECLARE_INTERRUPT(184) \
+	DECLARE_INTERRUPT(185) \
+	DECLARE_INTERRUPT(186) \
+	DECLARE_INTERRUPT(187) \
+	DECLARE_INTERRUPT(188) \
+	DECLARE_INTERRUPT(189) \
+	DECLARE_INTERRUPT(190) \
+	DECLARE_INTERRUPT(191) \
+	DECLARE_INTERRUPT(192) \
+	DECLARE_INTERRUPT(193) \
+	DECLARE_INTERRUPT(194) \
+	DECLARE_INTERRUPT(195) \
+	DECLARE_INTERRUPT(196) \
+	DECLARE_INTERRUPT(197) \
+	DECLARE_INTERRUPT(198) \
+	DECLARE_INTERRUPT(199) \
+	DECLARE_INTERRUPT(200) \
+	DECLARE_INTERRUPT(201) \
+	DECLARE_INTERRUPT(202) \
+	DECLARE_INTERRUPT(203) \
+	DECLARE_INTERRUPT(204) \
+	DECLARE_INTERRUPT(205) \
+	DECLARE_INTERRUPT(206) \
+	DECLARE_INTERRUPT(207) \
+	DECLARE_INTERRUPT(208) \
+	DECLARE_INTERRUPT(209) \
+	DECLARE_INTERRUPT(210) \
+	DECLARE_INTERRUPT(211) \
+	DECLARE_INTERRUPT(212) \
+	DECLARE_INTERRUPT(213) \
+	DECLARE_INTERRUPT(214) \
+	DECLARE_INTERRUPT(215) \
+	DECLARE_INTERRUPT(216) \
+	DECLARE_INTERRUPT(217) \
+	DECLARE_INTERRUPT(218) \
+	DECLARE_INTERRUPT(219) \
+	DECLARE_INTERRUPT(220) \
+	DECLARE_INTERRUPT(221) \
+	DECLARE_INTERRUPT(222) \
+	DECLARE_INTERRUPT(223) \
+	DECLARE_INTERRUPT(224) \
+	DECLARE_INTERRUPT(225) \
+	DECLARE_INTERRUPT(226) \
+	DECLARE_INTERRUPT(227) \
+	DECLARE_INTERRUPT(228) \
+	DECLARE_INTERRUPT(229) \
+	DECLARE_INTERRUPT(230) \
+	DECLARE_INTERRUPT(231) \
+	DECLARE_INTERRUPT(232) \
+	DECLARE_INTERRUPT(233) \
+	DECLARE_INTERRUPT(234) \
+	DECLARE_INTERRUPT(235) \
+	DECLARE_INTERRUPT(236) \
+	DECLARE_INTERRUPT(237) \
+	DECLARE_INTERRUPT(238) \
+	DECLARE_INTERRUPT(239) \
+	DECLARE_INTERRUPT(240) \
+	DECLARE_INTERRUPT(241) \
+	DECLARE_INTERRUPT(242) \
+	DECLARE_INTERRUPT(243) \
+	DECLARE_INTERRUPT(244) \
+	DECLARE_INTERRUPT(245) \
+	DECLARE_INTERRUPT(246) \
+	DECLARE_INTERRUPT(247) \
+	DECLARE_INTERRUPT(248) \
+	DECLARE_INTERRUPT(249) \
+	DECLARE_INTERRUPT(250) \
+	DECLARE_INTERRUPT(251) \
+	DECLARE_INTERRUPT(252) \
+	DECLARE_INTERRUPT(253) \
+	DECLARE_INTERRUPT(254) \
+	DECLARE_INTERRUPT(255));
diff --git a/arch/i386/cpu/resetvec.S b/arch/i386/cpu/resetvec.S
new file mode 100644
index 0000000..d9222dd
--- /dev/null
+++ b/arch/i386/cpu/resetvec.S
@@ -0,0 +1,37 @@
+/*
+ *  U-boot - i386 Startup Code
+ *
+ *  Copyright (c) 2002	Omicron Ceti AB, Daniel Engström <denaiel@omicron.se>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* Reset vector, jumps to start16.S */
+
+.extern start16
+
+.section .resetvec, "ax"
+.code16
+reset_vector:
+	cli
+	cld
+	jmp start16
+
+	.org 0xf
+	nop
diff --git a/arch/i386/cpu/sc520/Makefile b/arch/i386/cpu/sc520/Makefile
new file mode 100644
index 0000000..87835b2
--- /dev/null
+++ b/arch/i386/cpu/sc520/Makefile
@@ -0,0 +1,56 @@
+#
+# (C) Copyright 2008
+# Graeme Russ, graeme.russ@gmail.com.
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# (C) Copyright 2002
+# Daniel Engström, Omicron Ceti AB, daniel@omicron.se.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)lib$(SOC).a
+
+COBJS-$(CONFIG_SYS_SC520) += sc520.o
+COBJS-$(CONFIG_SYS_SC520_SSI) += sc520_ssi.o
+COBJS-$(CONFIG_SYS_SC520_TIMER) += sc520_timer.o
+COBJS-$(CONFIG_PCI) += sc520_pci.o
+
+SOBJS-$(CONFIG_SYS_SC520) += sc520_asm.o
+
+SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
+
+all: $(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
\ No newline at end of file
diff --git a/arch/i386/cpu/sc520/sc520.c b/arch/i386/cpu/sc520/sc520.c
new file mode 100644
index 0000000..4b566a7
--- /dev/null
+++ b/arch/i386/cpu/sc520/sc520.c
@@ -0,0 +1,198 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* stuff specific for the sc520,
+ * but idependent of implementation */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/ic/sc520.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * utility functions for boards based on the AMD sc520
+ *
+ * void init_sc520(void)
+ * unsigned long init_sc520_dram(void)
+ */
+
+volatile sc520_mmcr_t *sc520_mmcr = (sc520_mmcr_t *)0xfffef000;
+
+void init_sc520(void)
+{
+	/* Set the UARTxCTL register at it's slower,
+	 * baud clock giving us a 1.8432 MHz reference
+	 */
+	sc520_mmcr->uart1ctl = 0x07;
+	sc520_mmcr->uart2ctl = 0x07;
+
+	/* first set the timer pin mapping */
+	sc520_mmcr->clksel = 0x72;	/* no clock frequency selected, use 1.1892MHz */
+
+	/* enable PCI bus arbitrer */
+	sc520_mmcr->sysarbctl = 0x02;	/* enable concurrent mode */
+
+	sc520_mmcr->sysarbmenb = 0x1f;	/* enable external grants */
+	sc520_mmcr->hbctl = 0x04;	/* enable posted-writes */
+
+	if (CONFIG_SYS_SC520_HIGH_SPEED) {
+		sc520_mmcr->cpuctl = 0x02;	/* set it to 133 MHz and write back */
+		gd->cpu_clk = 133000000;
+		printf("## CPU Speed set to 133MHz\n");
+	} else {
+		sc520_mmcr->cpuctl = 0x01;	/* set it to 100 MHz and write back */
+		printf("## CPU Speed set to 100MHz\n");
+		gd->cpu_clk = 100000000;
+	}
+
+
+	/* wait at least one millisecond */
+	asm("movl	$0x2000,%%ecx\n"
+	    "0:		pushl %%ecx\n"
+	    "popl	%%ecx\n"
+	    "loop 0b\n": : : "ecx");
+
+	/* turn on the SDRAM write buffer */
+	sc520_mmcr->dbctl = 0x11;
+
+	/* turn on the cache and disable write through */
+	asm("movl	%%cr0, %%eax\n"
+	    "andl	$0x9fffffff, %%eax\n"
+	    "movl	%%eax, %%cr0\n"  : : : "eax");
+}
+
+unsigned long init_sc520_dram(void)
+{
+	bd_t *bd = gd->bd;
+
+	u32 dram_present=0;
+	u32 dram_ctrl;
+#ifdef CONFIG_SYS_SDRAM_DRCTMCTL
+	/* these memory control registers are set up in the assember part,
+	 * in sc520_asm.S, during 'mem_init'.  If we muck with them here,
+	 * after we are running a stack in RAM, we have troubles.  Besides,
+	 * these refresh and delay values are better ? simply specified
+	 * outright in the include/configs/{cfg} file since the HW designer
+	 * simply dictates it.
+	 */
+#else
+	int val;
+
+	int cas_precharge_delay = CONFIG_SYS_SDRAM_PRECHARGE_DELAY;
+	int refresh_rate        = CONFIG_SYS_SDRAM_REFRESH_RATE;
+	int ras_cas_delay       = CONFIG_SYS_SDRAM_RAS_CAS_DELAY;
+
+	/* set SDRAM speed here */
+
+	refresh_rate/=78;
+	if (refresh_rate<=1) {
+		val = 0;  /* 7.8us */
+	} else if (refresh_rate==2) {
+		val = 1;  /* 15.6us */
+	} else if (refresh_rate==3 || refresh_rate==4) {
+		val = 2;  /* 31.2us */
+	} else {
+		val = 3;  /* 62.4us */
+	}
+
+	sc520_mmcr->drcctl = (sc520_mmcr->drcctl & 0xcf) | (val<<4);
+
+	val = sc520_mmcr->drctmctl & 0xf0;
+
+	if (cas_precharge_delay==3) {
+		val |= 0x04;   /* 3T */
+	} else if (cas_precharge_delay==4) {
+		val |= 0x08;   /* 4T */
+	} else if (cas_precharge_delay>4) {
+		val |= 0x0c;
+	}
+
+	if (ras_cas_delay > 3) {
+		val |= 2;
+	} else {
+		val |= 1;
+	}
+	sc520_mmcr->drctmctl = val;
+#endif
+
+	/* We read-back the configuration of the dram
+	 * controller that the assembly code wrote */
+	dram_ctrl = sc520_mmcr->drcbendadr;
+
+	bd->bi_dram[0].start = 0;
+	if (dram_ctrl & 0x80) {
+		/* bank 0 enabled */
+		dram_present = bd->bi_dram[1].start = (dram_ctrl & 0x7f) << 22;
+		bd->bi_dram[0].size = bd->bi_dram[1].start;
+
+	} else {
+		bd->bi_dram[0].size = 0;
+		bd->bi_dram[1].start = bd->bi_dram[0].start;
+	}
+
+	if (dram_ctrl & 0x8000) {
+		/* bank 1 enabled */
+		dram_present = bd->bi_dram[2].start = (dram_ctrl & 0x7f00) << 14;
+		bd->bi_dram[1].size = bd->bi_dram[2].start -  bd->bi_dram[1].start;
+	} else {
+		bd->bi_dram[1].size = 0;
+		bd->bi_dram[2].start = bd->bi_dram[1].start;
+	}
+
+	if (dram_ctrl & 0x800000) {
+		/* bank 2 enabled */
+		dram_present = bd->bi_dram[3].start = (dram_ctrl & 0x7f0000) << 6;
+		bd->bi_dram[2].size = bd->bi_dram[3].start -  bd->bi_dram[2].start;
+	} else {
+		bd->bi_dram[2].size = 0;
+		bd->bi_dram[3].start = bd->bi_dram[2].start;
+	}
+
+	if (dram_ctrl & 0x80000000) {
+		/* bank 3 enabled */
+		dram_present  = (dram_ctrl & 0x7f000000) >> 2;
+		bd->bi_dram[3].size = dram_present -  bd->bi_dram[3].start;
+	} else {
+		bd->bi_dram[3].size = 0;
+	}
+
+
+#if 0
+	printf("Configured %d bytes of dram\n", dram_present);
+#endif
+	gd->ram_size = dram_present;
+
+	return dram_present;
+}
+
+#ifdef CONFIG_SYS_SC520_RESET
+void reset_cpu(ulong addr)
+{
+	printf("Resetting using SC520 MMCR\n");
+	/* Write a '1' to the SYS_RST of the RESCFG MMCR */
+	sc520_mmcr->rescfg = 0x01;
+
+	/* NOTREACHED */
+}
+#endif
diff --git a/arch/i386/cpu/sc520/sc520_asm.S b/arch/i386/cpu/sc520/sc520_asm.S
new file mode 100644
index 0000000..2042d9b
--- /dev/null
+++ b/arch/i386/cpu/sc520/sc520_asm.S
@@ -0,0 +1,581 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* This file is largely based on code obtned from AMD. AMD's original
+ * copyright is included below
+ */
+
+/*
+ *  =============================================================================
+ *
+ *   Copyright 1999 Advanced Micro Devices, Inc.
+ *
+ *  This software is the property of Advanced Micro Devices, Inc  (AMD)  which
+ *  specifically grants the user the right to modify, use and distribute this
+ *  software provided this COPYRIGHT NOTICE is not removed or altered.  All
+ *  other rights are reserved by AMD.
+ *
+ *  THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY
+ *  OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT OF
+ *  THIRD-PARTY INTELLECTUAL PROPERTY, OR FITNESS FOR ANY PARTICULAR PURPOSE.
+ *  IN NO EVENT SHALL AMD OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER
+ *  (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
+ *  INTERRUPTION, LOSS OF INFORMAITON) ARISING OUT OF THE USE OF OR INABILITY
+ *  TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY OF
+ *  SUCH DAMAGES.  BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR
+ *  LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
+ *  LIMITATION MAY NOT APPLY TO YOU.
+ *
+ *  AMD does not assume any responsibility for any errors that may appear in
+ *  the Materials nor any responsibility to support or update the Materials.
+ *  AMD retains the right to make changes to its test specifications at any
+ *  time, without notice.
+ *
+ *  So that all may benefit from your experience, please report  any  problems
+ *  or suggestions about this software back to AMD.  Please include your name,
+ *  company,  telephone number,  AMD product requiring support and question or
+ *  problem encountered.
+ *
+ *  Advanced Micro Devices, Inc.         Worldwide support and contact
+ *  Embedded Processor Division            information available at:
+ *  Systems Engineering                       epd.support@amd.com
+ *  5204 E. Ben White Blvd.                          -or-
+ *  Austin, TX 78741                http://www.amd.com/html/support/techsup.html
+ *  ============================================================================
+ */
+
+
+/*******************************************************************************
+ *	 AUTHOR      : Buddy Fey - Original.
+ *******************************************************************************
+ */
+
+
+/*******************************************************************************
+ *       FUNCTIONAL DESCRIPTION:
+ * This routine is called to autodetect the geometry of the DRAM.
+ *
+ * This routine is called to determine the number of column bits for the DRAM
+ * devices in this external bank. This routine assumes that the external bank
+ * has been configured for an 11-bit column and for 4 internal banks. This gives
+ * us the maximum address reach in memory. By writing a test value to the max
+ * address and locating where it aliases to, we can determine the number of valid
+ * column bits.
+ *
+ * This routine is called to determine the number of internal banks each DRAM
+ * device has. The external bank (under test) is configured for maximum reach
+ * with 11-bit columns and 4 internal banks. This routine will write to a max
+ * address (BA1 and BA0 = 1) and then read from an address with BA1=0 to see if
+ * that column is a "don't care". If BA1 does not affect write/read of data,
+ * then this device has only 2 internal banks.
+ *
+ * This routine is called to determine the ending address for this external
+ * bank of SDRAM. We write to a max address with a data value and then disable
+ * row address bits looking for "don't care" locations. Each "don't care" bit
+ * represents a dividing of the maximum density (128M) by 2. By dividing the
+ * maximum of 32 4M chunks in an external bank down by all the "don't care" bits
+ * determined during sizing, we set the proper density.
+ *
+ * WARNINGS.
+ * bp must be preserved because it is used for return linkage.
+ *
+ * EXIT
+ * nothing returned - but the memory subsystem is enabled
+ *******************************************************************************
+ */
+
+#include <config.h>
+
+.section .text
+.equ            DRCCTL,     0x0fffef010   /* DRAM control register */
+.equ            DRCTMCTL,   0x0fffef012   /* DRAM timing control register */
+.equ            DRCCFG,     0x0fffef014   /* DRAM bank configuration register */
+.equ            DRCBENDADR, 0x0fffef018   /* DRAM bank ending address register */
+.equ            ECCCTL,     0x0fffef020   /* DRAM ECC control register */
+.equ            ECCINT,     0x0fffefd18   /* DRAM ECC nmi-INT mapping */
+.equ            DBCTL,      0x0fffef040   /* DRAM buffer control register */
+
+.equ            CACHELINESZ, 0x00000010   /* size of our cache line (read buffer) */
+.equ            COL11_ADR,  0x0e001e00    /* 11 col addrs */
+.equ            COL10_ADR,  0x0e000e00    /* 10 col addrs */
+.equ            COL09_ADR,  0x0e000600    /*  9 col addrs */
+.equ            COL08_ADR,  0x0e000200    /*  8 col addrs */
+.equ            ROW14_ADR,  0x0f000000    /* 14 row addrs */
+.equ            ROW13_ADR,  0x07000000    /* 13 row addrs */
+.equ            ROW12_ADR,  0x03000000    /* 12 row addrs */
+.equ            ROW11_ADR,  0x01000000    /* 11 row addrs/also bank switch */
+.equ            ROW10_ADR,  0x00000000    /* 10 row addrs/also bank switch */
+.equ            COL11_DATA, 0x0b0b0b0b    /* 11 col addrs */
+.equ            COL10_DATA, 0x0a0a0a0a    /* 10 col data */
+.equ            COL09_DATA, 0x09090909    /*  9 col data */
+.equ            COL08_DATA, 0x08080808    /*  8 col data */
+.equ            ROW14_DATA, 0x3f3f3f3f    /* 14 row data (MASK) */
+.equ            ROW13_DATA, 0x1f1f1f1f    /* 13 row data (MASK) */
+.equ            ROW12_DATA, 0x0f0f0f0f    /* 12 row data (MASK) */
+.equ            ROW11_DATA, 0x07070707    /* 11 row data/also bank switch (MASK) */
+.equ            ROW10_DATA, 0xaaaaaaaa    /* 10 row data/also bank switch (MASK) */
+
+
+ /*
+  * initialize dram controller registers
+  */
+.globl mem_init
+mem_init:
+	xorw    %ax,%ax
+	movl    $DBCTL, %edi
+	movb     %al, (%edi)             /* disable write buffer */
+
+	movl    $ECCCTL, %edi
+	movb     %al, (%edi)             /* disable ECC */
+
+	movl    $DRCTMCTL, %edi
+	movb    $0x1E,%al                /* Set SDRAM timing for slowest */
+	movb     %al, (%edi)
+
+ /*
+  * setup loop to do 4 external banks starting with bank 3
+  */
+	movl    $0xff000000,%eax         /* enable last bank and setup */
+	movl    $DRCBENDADR, %edi        /* ending address register */
+	movl     %eax, (%edi)
+
+	movl    $DRCCFG, %edi            /* setup */
+	movw    $0xbbbb,%ax              /* dram config register for  */
+	movw    %ax, (%edi)
+
+ /*
+  * issue a NOP to all DRAMs
+  */
+	movl    $DRCCTL, %edi            /* setup DRAM control register with */
+	movb    $0x1,%al                 /* Disable refresh,disable write buffer */
+	movb     %al, (%edi)
+	movl    $CACHELINESZ, %esi       /* just a dummy address to write for */
+	movw     %ax, (%esi)
+ /*
+  * delay for 100 usec? 200?
+  * ******this is a cludge for now *************
+  */
+	movw    $100,%cx
+sizdelay:
+	loop    sizdelay                 /* we need 100 usec here */
+ /***********************************************/
+
+ /*
+  * issue all banks precharge
+  */
+	movb    $0x2,%al                 /* All banks precharge */
+	movb     %al, (%edi)
+	movw     %ax, (%esi)
+
+ /*
+  * issue 2 auto refreshes to all banks
+  */
+	movb    $0x4,%al                 /* Auto refresh cmd */
+	movb     %al, (%edi)
+	movw    $2,%cx
+refresh1:
+	movw     %ax, (%esi)
+	loop    refresh1
+
+ /*
+  * issue LOAD MODE REGISTER command
+  */
+	movb    $0x3,%al                 /* Load mode register cmd */
+	movb     %al, (%edi)
+	movw     %ax, (%esi)
+
+ /*
+  * issue 8 more auto refreshes to all banks
+  */
+	movb    $0x4,%al                 /* Auto refresh cmd */
+	movb     %al, (%edi)
+	movw    $8,%cx
+refresh2:
+	movw     %ax, (%esi)
+	loop    refresh2
+
+ /*
+  * set control register to NORMAL mode
+  */
+	movb    $0x0,%al                 /* Normal mode value */
+	movb     %al, (%edi)
+
+ /*
+  * size dram starting with external bank 3 moving to external bank 0
+  */
+	movl    $0x3,%ecx                /* start with external bank 3 */
+
+nextbank:
+
+ /*
+  * write col 11 wrap adr
+  */
+	movl    $COL11_ADR, %esi         /* set address to max col (11) wrap addr */
+	movl    $COL11_DATA, %eax        /* pattern for max supported columns(11) */
+	movl    %eax, (%esi)             /* write max col pattern at max col adr */
+	movl    (%esi), %ebx             /* optional read */
+	cmpl    %ebx,%eax                /* to verify write */
+	jnz     bad_ram                  /* this ram is bad */
+ /*
+  * write col 10 wrap adr
+  */
+
+	movl    $COL10_ADR, %esi         /* set address to 10 col wrap address */
+	movl    $COL10_DATA, %eax        /* pattern for 10 col wrap */
+	movl    %eax, (%esi)             /* write 10 col pattern @ 10 col wrap adr */
+	movl    (%esi), %ebx             /* optional read */
+	cmpl    %ebx,%eax                /* to verify write */
+	jnz     bad_ram                  /* this ram is bad */
+ /*
+  * write col 9 wrap adr
+  */
+	movl    $COL09_ADR, %esi         /* set address to 9 col wrap address */
+	movl    $COL09_DATA, %eax        /* pattern for 9 col wrap */
+	movl    %eax, (%esi)             /* write 9 col pattern @ 9 col wrap adr */
+	movl    (%esi), %ebx             /* optional read */
+	cmpl    %ebx,%eax                /* to verify write */
+	jnz     bad_ram                  /* this ram is bad */
+ /*
+  * write col 8 wrap adr
+  */
+	movl    $COL08_ADR, %esi         /* set address to min(8) col wrap address */
+	movl    $COL08_DATA, %eax        /* pattern for min (8) col wrap */
+	movl    %eax, (%esi)             /* write min col pattern @ min col adr */
+	movl    (%esi), %ebx             /* optional read */
+	cmpl    %ebx,%eax                /* to verify write */
+	jnz     bad_ram                  /* this ram is bad */
+ /*
+  * write row 14 wrap adr
+  */
+	movl    $ROW14_ADR, %esi         /* set address to max row (14) wrap addr */
+	movl    $ROW14_DATA, %eax        /* pattern for max supported rows(14) */
+	movl    %eax, (%esi)             /* write max row pattern at max row adr */
+	movl    (%esi), %ebx             /* optional read */
+	cmpl    %ebx,%eax                /* to verify write */
+	jnz     bad_ram                  /* this ram is bad */
+ /*
+  * write row 13 wrap adr
+  */
+	movl    $ROW13_ADR, %esi         /* set address to 13 row wrap address */
+	movl    $ROW13_DATA, %eax        /* pattern for 13 row wrap */
+	movl    %eax, (%esi)             /* write 13 row pattern @ 13 row wrap adr */
+	movl    (%esi), %ebx             /* optional read */
+	cmpl    %ebx,%eax                /* to verify write */
+	jnz     bad_ram                  /* this ram is bad */
+ /*
+  * write row 12 wrap adr
+  */
+	movl    $ROW12_ADR, %esi         /* set address to 12 row wrap address */
+	movl    $ROW12_DATA, %eax        /* pattern for 12 row wrap */
+	movl    %eax, (%esi)             /* write 12 row pattern @ 12 row wrap adr */
+	movl    (%esi), %ebx             /* optional read */
+	cmpl    %ebx,%eax                /* to verify write */
+	jnz     bad_ram                  /* this ram is bad */
+ /*
+  * write row 11 wrap adr
+  */
+	movl    $ROW11_ADR, %edi         /* set address to 11 row wrap address */
+	movl    $ROW11_DATA, %eax        /* pattern for 11 row wrap */
+	movl    %eax, (%edi)             /* write 11 row pattern @ 11 row wrap adr */
+	movl    (%edi), %ebx             /* optional read */
+	cmpl    %ebx,%eax                /* to verify write */
+	jnz     bad_ram                  /* this ram is bad */
+ /*
+  * write row 10 wrap adr --- this write is really to determine number of banks
+  */
+	movl    $ROW10_ADR, %edi         /* set address to 10 row wrap address */
+	movl    $ROW10_DATA, %eax        /* pattern for 10 row wrap (AA) */
+	movl    %eax, (%edi)             /* write 10 row pattern @ 10 row wrap adr */
+	movl    (%edi), %ebx             /* optional read */
+	cmpl    %ebx,%eax                /* to verify write */
+	jnz     bad_ram                  /* this ram is bad */
+ /*
+  * read data @ row 12 wrap adr to determine  * banks,
+  * and read data @ row 14 wrap adr to determine  * rows.
+  * if data @ row 12 wrap adr is not AA, 11 or 12 we have bad RAM.
+  * if data @ row 12 wrap == AA, we only have 2 banks, NOT 4
+  * if data @ row 12 wrap == 11 or 12, we have 4 banks,
+  */
+	xorw    %di,%di                  /* value for 2 banks in DI */
+	movl    (%esi), %ebx             /* read from 12 row wrap to check banks
+					  * (esi is setup from the write to row 12 wrap) */
+	cmpl    %ebx,%eax                /* check for AA pattern  (eax holds the aa pattern) */
+	jz      only2                    /* if pattern == AA, we only have 2 banks */
+
+	/* 4 banks */
+
+	movw    $8,%di                   /* value for 4 banks in DI (BNK_CNT bit) */
+	cmpl    $ROW11_DATA, %ebx        /* only other legitimate values are 11 */
+	jz      only2
+	cmpl    $ROW12_DATA, %ebx        /* and 12 */
+	jnz     bad_ram                  /* its bad if not 11 or 12! */
+
+	/* fall through */
+only2:
+ /*
+  * validate row mask
+  */
+	movl    $ROW14_ADR, %esi         /* set address back to max row wrap addr */
+	movl    (%esi), %eax             /* read actual number of rows @ row14 adr */
+
+	cmpl    $ROW11_DATA, %eax        /* row must be greater than 11 pattern */
+	jb      bad_ram
+
+	cmpl    $ROW14_DATA, %eax        /* and row must be less than 14 pattern */
+	ja      bad_ram
+
+	cmpb    %ah,%al                  /* verify all 4 bytes of dword same */
+	jnz     bad_ram
+	movl    %eax,%ebx
+	shrl    $16,%ebx
+	cmpw    %bx,%ax
+	jnz     bad_ram
+ /*
+  * read col 11 wrap adr for real column data value
+  */
+	movl    $COL11_ADR, %esi         /* set address to max col (11) wrap addr */
+	movl    (%esi), %eax             /* read real col number at max col adr */
+ /*
+  * validate column data
+  */
+	cmpl    $COL08_DATA, %eax        /* col must be greater than 8 pattern */
+	jb      bad_ram
+
+	cmpl    $COL11_DATA, %eax        /* and row must be less than 11 pattern */
+	ja      bad_ram
+
+	subl    $COL08_DATA, %eax        /* normalize column data to zero */
+	jc      bad_ram
+	cmpb    %ah,%al                  /* verify all 4 bytes of dword equal */
+	jnz     bad_ram
+	movl    %eax,%edx
+	shrl    $16,%edx
+	cmpw    %dx,%ax
+	jnz     bad_ram
+ /*
+  * merge bank and col data together
+  */
+	addw    %di,%dx                  /* merge of bank and col info in dl */
+ /*
+  * fix ending addr mask based upon col info
+  */
+	movb    $3,%al
+	subb    %dh,%al                  /* dh contains the overflow from the bank/col merge  */
+	movb    %bl,%dh                  /* bl contains the row mask (aa, 07, 0f, 1f or 3f) */
+	xchgw   %cx,%ax                  /* cx = ax = 3 or 2 depending on 2 or 4 bank device */
+	shrb    %cl,%dh	                 /*  */
+	incb    %dh                      /* ending addr is 1 greater than real end */
+	xchgw   %cx,%ax                  /* cx is bank number again */
+ /*
+  * issue all banks precharge
+  */
+bad_reint:
+	movl    $DRCCTL, %esi            /* setup DRAM control register with */
+	movb    $0x2,%al                 /* All banks precharge */
+	movb     %al, (%esi)
+	movl    $CACHELINESZ, %esi       /* address to init read buffer */
+	movw     %ax, (%esi)
+
+ /*
+  * update ENDING ADDRESS REGISTER
+  */
+	movl    $DRCBENDADR, %edi        /* DRAM ending address register */
+	movl    %ecx,%ebx
+	addl	%ebx, %edi
+	movb    %dh, (%edi)
+ /*
+  * update CONFIG REGISTER
+  */
+	xorb    %dh,%dh
+	movw    $0x00f,%bx
+	movw    %cx,%ax
+	shlw    $2,%ax
+	xchgw   %cx,%ax
+	shlw    %cl,%dx
+	shlw    %cl,%bx
+	notw    %bx
+	xchgw   %cx,%ax
+	movl    $DRCCFG, %edi
+	mov     (%edi), %ax
+	andw    %bx,%ax
+	orw     %dx,%ax
+	movw    %ax, (%edi)
+	jcxz    cleanup
+
+	decw    %cx
+	movl    %ecx,%ebx
+	movl    $DRCBENDADR, %edi        /* DRAM ending address register */
+	movb    $0xff,%al
+	addl	%ebx, %edi
+	movb    %al, (%edi)
+ /*
+  * set control register to NORMAL mode
+  */
+	movl    $DRCCTL, %esi            /* setup DRAM control register with */
+	movb    $0x0,%al                 /* Normal mode value */
+	movb    %al, (%esi)
+	movl    $CACHELINESZ, %esi       /* address to init read buffer */
+	movw    %ax, (%esi)
+	jmp     nextbank
+
+cleanup:
+	movl    $DRCBENDADR, %edi        /* DRAM ending address register  */
+	movw    $4,%cx
+	xorw    %ax,%ax
+cleanuplp:
+	movb   (%edi), %al
+	orb     %al,%al
+	jz      emptybank
+
+	addb    %ah,%al
+	jns     nottoomuch
+
+	movb    $0x7f,%al
+nottoomuch:
+	movb    %al,%ah
+	orb     $0x80,%al
+	movb    %al, (%edi)
+emptybank:
+	incl    %edi
+	loop    cleanuplp
+
+#if defined CONFIG_SYS_SDRAM_DRCTMCTL
+	/* just have your hardware desinger _GIVE_ you what you need here! */
+	movl    $DRCTMCTL, %edi
+	movb    $CONFIG_SYS_SDRAM_DRCTMCTL,%al
+	movb    (%edi), %al
+#else
+#if defined(CONFIG_SYS_SDRAM_CAS_LATENCY_2T) || defined(CONFIG_SYS_SDRAM_CAS_LATENCY_3T)
+	/* set the CAS latency now since it is hard to do
+	 * when we run from the RAM */
+	movl    $DRCTMCTL, %edi          /* DRAM timing register */
+	movb    (%edi), %al
+#ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_2T
+	andb    $0xef, %al
+#endif
+#ifdef CONFIG_SYS_SDRAM_CAS_LATENCY_3T
+	orb     $0x10, %al
+#endif
+	movb    %al, (%edi)
+#endif
+#endif
+	movl    $DRCCTL, %edi            /* DRAM Control register */
+	movb    $0x3,%al                 /* Load mode register cmd */
+	movb     %al, (%edi)
+	movw     %ax, (%esi)
+
+
+	movl    $DRCCTL, %edi            /* DRAM Control register */
+	movb    $0x18,%al                /*  Enable refresh and NORMAL mode */
+	movb    %al, (%edi)
+
+	jmp     dram_done
+
+bad_ram:
+	xorl    %edx,%edx
+	xorl    %edi,%edi
+	jmp     bad_reint
+
+dram_done:
+
+	/* readback DRCBENDADR and return the number
+	 * of available ram bytes in %eax */
+
+	movl    $DRCBENDADR, %edi        /* DRAM ending address register  */
+
+	movl	(%edi), %eax
+	movl	%eax, %ecx
+	andl	$0x80000000, %ecx
+	jz	bank2
+	andl	$0x7f000000, %eax
+	shrl	$2, %eax
+	movl	%eax, %ebx
+
+bank2:	movl	(%edi), %eax
+	movl	%eax, %ecx
+	andl	$0x00800000, %ecx
+	jz	bank1
+	andl	$0x007f0000, %eax
+	shll	$6, %eax
+	movl	%eax, %ebx
+
+bank1:	movl	(%edi), %eax
+	movl	%eax, %ecx
+	andl	$0x00008000, %ecx
+	jz	bank0
+	andl	$0x00007f00, %eax
+	shll	$14, %eax
+	movl	%eax, %ebx
+
+bank0:	movl	(%edi), %eax
+	movl	%eax, %ecx
+	andl	$0x00000080, %ecx
+	jz	done
+	andl	$0x0000007f, %eax
+	shll	$22, %eax
+	movl	%eax, %ebx
+
+
+done:
+	movl	%ebx, %eax
+
+#if CONFIG_SYS_SDRAM_ECC_ENABLE
+	/* A nominal memory test: just a byte at each address line */
+	movl    %eax, %ecx
+	shrl    $0x1, %ecx
+	movl	$0x1, %edi
+memtest0:
+	movb	$0xa5, (%edi)
+	cmpb    $0xa5, (%edi)
+	jne	out
+	shrl	$1, %ecx
+	andl	%ecx,%ecx
+	jz	set_ecc
+	shll	$1, %edi
+	jmp	memtest0
+
+set_ecc:
+	/* clear all ram with a memset */
+	movl	%eax, %ecx
+	xorl	%esi, %esi
+	xorl	%edi, %edi
+	xorl	%eax, %eax
+	shrl	$2, %ecx
+	cld
+	rep	stosl
+			/* enable read, write buffers */
+	movb    $0x11, %al
+	movl    $DBCTL, %edi
+	movb    %al, (%edi)
+			/* enable NMI mapping for ECC */
+	movl    $ECCINT, %edi
+	mov	$0x10, %al
+	movb    %al, (%edi)
+			/* Turn on ECC */
+	movl    $ECCCTL, %edi
+	mov	$0x05, %al
+	movb    %al, (%edi)
+#endif
+out:
+	movl	%ebx, %eax
+	jmp	*%ebp
diff --git a/arch/i386/cpu/sc520/sc520_pci.c b/arch/i386/cpu/sc520/sc520_pci.c
new file mode 100644
index 0000000..f446c6d
--- /dev/null
+++ b/arch/i386/cpu/sc520/sc520_pci.c
@@ -0,0 +1,171 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* stuff specific for the sc520, but independent of implementation */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/pci.h>
+#include <asm/ic/sc520.h>
+
+static struct {
+	u8 priority;
+	u16 level_reg;
+	u8 level_bit;
+} sc520_irq[] = {
+	{ SC520_IRQ0,  0, 0x01 },
+	{ SC520_IRQ1,  0, 0x02 },
+	{ SC520_IRQ2,  1, 0x02 },
+	{ SC520_IRQ3,  0, 0x08 },
+	{ SC520_IRQ4,  0, 0x10 },
+	{ SC520_IRQ5,  0, 0x20 },
+	{ SC520_IRQ6,  0, 0x40 },
+	{ SC520_IRQ7,  0, 0x80 },
+
+	{ SC520_IRQ8,  1, 0x01 },
+	{ SC520_IRQ9,  1, 0x02 },
+	{ SC520_IRQ10, 1, 0x04 },
+	{ SC520_IRQ11, 1, 0x08 },
+	{ SC520_IRQ12, 1, 0x10 },
+	{ SC520_IRQ13, 1, 0x20 },
+	{ SC520_IRQ14, 1, 0x40 },
+	{ SC520_IRQ15, 1, 0x80 }
+};
+
+
+/* The interrupt used for PCI INTA-INTD  */
+int sc520_pci_ints[15] = {
+	-1, -1, -1, -1, -1, -1, -1, -1,
+		-1, -1, -1, -1, -1, -1, -1
+};
+
+/* utility function to configure a pci interrupt */
+int pci_sc520_set_irq(int pci_pin, int irq)
+{
+	int i;
+
+# if 1
+	printf("set_irq(): map INT%c to IRQ%d\n", pci_pin + 'A', irq);
+#endif
+	if (irq < 0 || irq > 15) {
+		return -1; /* illegal irq */
+	}
+
+	if (pci_pin < 0 || pci_pin > 15) {
+		return -1; /* illegal pci int pin */
+	}
+
+	/* first disable any non-pci interrupt source that use
+	 * this level */
+
+	/* PCI interrupt mapping (A through D)*/
+	for (i=0; i<=3 ;i++) {
+		if (sc520_mmcr->pci_int_map[i] == sc520_irq[irq].priority)
+			sc520_mmcr->pci_int_map[i] = SC520_IRQ_DISABLED;
+	}
+
+	/* GP IRQ interrupt mapping */
+	for (i=0; i<=10 ;i++) {
+		if (sc520_mmcr->gp_int_map[i] == sc520_irq[irq].priority)
+			sc520_mmcr->gp_int_map[i] = SC520_IRQ_DISABLED;
+	}
+
+	/* Set the trigger to level */
+	sc520_mmcr->pic_mode[sc520_irq[irq].level_reg] =
+		sc520_mmcr->pic_mode[sc520_irq[irq].level_reg] | sc520_irq[irq].level_bit;
+
+
+	if (pci_pin < 4) {
+		/* PCI INTA-INTD */
+		/* route the interrupt */
+		sc520_mmcr->pci_int_map[pci_pin] = sc520_irq[irq].priority;
+	} else {
+		/* GPIRQ0-GPIRQ10 used for additional PCI INTS */
+		sc520_mmcr->gp_int_map[pci_pin - 4] = sc520_irq[irq].priority;
+
+		/* also set the polarity in this case */
+		sc520_mmcr->intpinpol = sc520_mmcr->intpinpol | (1 << (pci_pin-4));
+	}
+
+	/* register the pin */
+	sc520_pci_ints[pci_pin] = irq;
+
+
+	return 0; /* OK */
+}
+
+void pci_sc520_init(struct pci_controller *hose)
+{
+	hose->first_busno = 0;
+	hose->last_busno = 0xff;
+
+	/* System memory space */
+	pci_set_region(hose->regions + 0,
+		       SC520_PCI_MEMORY_BUS,
+		       SC520_PCI_MEMORY_PHYS,
+		       SC520_PCI_MEMORY_SIZE,
+		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+	/* PCI memory space */
+	pci_set_region(hose->regions + 1,
+		       SC520_PCI_MEM_BUS,
+		       SC520_PCI_MEM_PHYS,
+		       SC520_PCI_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	/* ISA/PCI memory space */
+	pci_set_region(hose->regions + 2,
+		       SC520_ISA_MEM_BUS,
+		       SC520_ISA_MEM_PHYS,
+		       SC520_ISA_MEM_SIZE,
+		       PCI_REGION_MEM);
+
+	/* PCI I/O space */
+	pci_set_region(hose->regions + 3,
+		       SC520_PCI_IO_BUS,
+		       SC520_PCI_IO_PHYS,
+		       SC520_PCI_IO_SIZE,
+		       PCI_REGION_IO);
+
+	/* ISA/PCI I/O space */
+	pci_set_region(hose->regions + 4,
+		       SC520_ISA_IO_BUS,
+		       SC520_ISA_IO_PHYS,
+		       SC520_ISA_IO_SIZE,
+		       PCI_REGION_IO);
+
+	hose->region_count = 5;
+
+	pci_setup_type1(hose,
+			SC520_REG_ADDR,
+			SC520_REG_DATA);
+
+	pci_register_hose(hose);
+
+	hose->last_busno = pci_hose_scan(hose);
+
+	/* enable target memory acceses on host brige */
+	pci_write_config_word(0, PCI_COMMAND,
+			      PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+}
diff --git a/arch/i386/cpu/sc520/sc520_ssi.c b/arch/i386/cpu/sc520/sc520_ssi.c
new file mode 100644
index 0000000..8dbe17a
--- /dev/null
+++ b/arch/i386/cpu/sc520/sc520_ssi.c
@@ -0,0 +1,94 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* stuff specific for the sc520, but independent of implementation */
+
+#include <common.h>
+#include <asm/ic/ssi.h>
+#include <asm/ic/sc520.h>
+
+int ssi_set_interface(int freq, int lsb_first, int inv_clock, int inv_phase)
+{
+	u8 temp=0;
+
+	if (freq >= 8192) {
+		temp |= CTL_CLK_SEL_4;
+	} else if (freq >= 4096) {
+		temp |= CTL_CLK_SEL_8;
+	} else if (freq >= 2048) {
+		temp |= CTL_CLK_SEL_16;
+	} else if (freq >= 1024) {
+		temp |= CTL_CLK_SEL_32;
+	} else if (freq >= 512) {
+		temp |= CTL_CLK_SEL_64;
+	} else if (freq >= 256) {
+		temp |= CTL_CLK_SEL_128;
+	} else if (freq >= 128) {
+		temp |= CTL_CLK_SEL_256;
+	} else {
+		temp |= CTL_CLK_SEL_512;
+	}
+
+	if (!lsb_first) {
+		temp |= MSBF_ENB;
+	}
+
+	if (inv_clock) {
+		temp |= CLK_INV_ENB;
+	}
+
+	if (inv_phase) {
+		temp |= PHS_INV_ENB;
+	}
+
+	sc520_mmcr->ssictl = temp;
+
+	return 0;
+}
+
+u8 ssi_txrx_byte(u8 data)
+{
+	sc520_mmcr->ssixmit = data;
+	while (sc520_mmcr->ssista & SSISTA_BSY);
+	sc520_mmcr->ssicmd = SSICMD_CMD_SEL_XMITRCV;
+	while (sc520_mmcr->ssista & SSISTA_BSY);
+
+	return sc520_mmcr->ssircv;
+}
+
+
+void ssi_tx_byte(u8 data)
+{
+	sc520_mmcr->ssixmit = data;
+	while (sc520_mmcr->ssista & SSISTA_BSY);
+	sc520_mmcr->ssicmd = SSICMD_CMD_SEL_XMIT;
+}
+
+u8 ssi_rx_byte(void)
+{
+	while (sc520_mmcr->ssista & SSISTA_BSY);
+	sc520_mmcr->ssicmd = SSICMD_CMD_SEL_RCV;
+	while (sc520_mmcr->ssista & SSISTA_BSY);
+
+	return sc520_mmcr->ssircv;
+}
diff --git a/arch/i386/cpu/sc520/sc520_timer.c b/arch/i386/cpu/sc520/sc520_timer.c
new file mode 100644
index 0000000..93b5b55
--- /dev/null
+++ b/arch/i386/cpu/sc520/sc520_timer.c
@@ -0,0 +1,84 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* stuff specific for the sc520, but independent of implementation */
+
+#include <common.h>
+#include <asm/interrupt.h>
+#include <asm/ic/sc520.h>
+
+void sc520_timer_isr(void)
+{
+	/* Ack the GP Timer Interrupt */
+	sc520_mmcr->gptmrsta = 0x02;
+}
+
+int timer_init(void)
+{
+	/* Register the SC520 specific timer interrupt handler */
+	register_timer_isr (sc520_timer_isr);
+
+	/* Install interrupt handler for GP Timer 1 */
+	irq_install_handler (0, timer_isr, NULL);
+
+	/* Map GP Timer 1 to Master PIC IR0  */
+	sc520_mmcr->gp_tmr_int_map[1] = 0x01;
+
+	/* Disable GP Timers 1 & 2 - Allow configuration writes */
+	sc520_mmcr->gptmr1ctl = 0x4000;
+	sc520_mmcr->gptmr2ctl = 0x4000;
+
+	/* Reset GP Timers 1 & 2 */
+	sc520_mmcr->gptmr1cnt = 0x0000;
+	sc520_mmcr->gptmr2cnt = 0x0000;
+
+	/* Setup GP Timer 2 as a 100kHz (10us) prescaler */
+	sc520_mmcr->gptmr2maxcmpa = 83;
+	sc520_mmcr->gptmr2ctl = 0xc001;
+
+	/* Setup GP Timer 1 as a 1000 Hz (1ms) interrupt generator */
+	sc520_mmcr->gptmr1maxcmpa = 100;
+	sc520_mmcr->gptmr1ctl = 0xe009;
+
+	unmask_irq (0);
+
+	/* Clear the GP Timer 1 status register to get the show rolling*/
+	sc520_mmcr->gptmrsta = 0x02;
+
+	return 0;
+}
+
+void __udelay(unsigned long usec)
+{
+	int m = 0;
+	long u;
+	long temp;
+
+	temp = sc520_mmcr->swtmrmilli;
+	temp = sc520_mmcr->swtmrmicro;
+
+	do {
+		m += sc520_mmcr->swtmrmilli;
+		u = sc520_mmcr->swtmrmicro + (m * 1000);
+	} while (u < usec);
+}
diff --git a/arch/i386/cpu/serial.c b/arch/i386/cpu/serial.c
new file mode 100644
index 0000000..e7025a3
--- /dev/null
+++ b/arch/i386/cpu/serial.c
@@ -0,0 +1,506 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+/*------------------------------------------------------------------------------+ */
+
+/*
+ * This source code is dual-licensed.  You may use it under the terms of the
+ * GNU General Public License version 2, or under the license below.
+ *
+ * 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 1995
+ * LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
+ */
+/*------------------------------------------------------------------------------- */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <asm/ibmpc.h>
+
+#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
+#include <malloc.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define UART_RBR    0x00
+#define UART_THR    0x00
+#define UART_IER    0x01
+#define UART_IIR    0x02
+#define UART_FCR    0x02
+#define UART_LCR    0x03
+#define UART_MCR    0x04
+#define UART_LSR    0x05
+#define UART_MSR    0x06
+#define UART_SCR    0x07
+#define UART_DLL    0x00
+#define UART_DLM    0x01
+
+/*-----------------------------------------------------------------------------+
+  | Line Status Register.
+  +-----------------------------------------------------------------------------*/
+#define asyncLSRDataReady1            0x01
+#define asyncLSROverrunError1         0x02
+#define asyncLSRParityError1          0x04
+#define asyncLSRFramingError1         0x08
+#define asyncLSRBreakInterrupt1       0x10
+#define asyncLSRTxHoldEmpty1          0x20
+#define asyncLSRTxShiftEmpty1         0x40
+#define asyncLSRRxFifoError1          0x80
+
+
+#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
+/*-----------------------------------------------------------------------------+
+  | Fifo
+  +-----------------------------------------------------------------------------*/
+typedef struct {
+	char *rx_buffer;
+	ulong rx_put;
+	ulong rx_get;
+	int cts;
+} serial_buffer_t;
+
+volatile serial_buffer_t buf_info;
+static int serial_buffer_active=0;
+#endif
+
+
+static int serial_div(int baudrate)
+{
+
+	switch (baudrate) {
+	case 1200:
+		return 96;
+	case 9600:
+		return 12;
+	case 19200:
+		return 6;
+	case 38400:
+		return 3;
+	case 57600:
+		return 2;
+	case 115200:
+		return 1;
+	}
+
+	return 12;
+}
+
+
+/*
+ * Minimal serial functions needed to use one of the SMC ports
+ * as serial console interface.
+ */
+
+int serial_init(void)
+{
+	volatile char val;
+	int bdiv = serial_div(gd->baudrate);
+
+	outb(0x80, UART0_BASE + UART_LCR);	/* set DLAB bit */
+	outb(bdiv, UART0_BASE + UART_DLL);	/* set baudrate divisor */
+	outb(bdiv >> 8, UART0_BASE + UART_DLM);/* set baudrate divisor */
+	outb(0x03, UART0_BASE + UART_LCR);	/* clear DLAB; set 8 bits, no parity */
+	outb(0x01, UART0_BASE + UART_FCR);	/* enable FIFO */
+	outb(0x0b, UART0_BASE + UART_MCR);	/* Set DTR and RTS active */
+	val = inb(UART0_BASE + UART_LSR);	/* clear line status */
+	val = inb(UART0_BASE + UART_RBR);	/* read receive buffer */
+	outb(0x00, UART0_BASE + UART_SCR);	/* set scratchpad */
+	outb(0x00, UART0_BASE + UART_IER);	/* set interrupt enable reg */
+
+	return 0;
+}
+
+
+void serial_setbrg(void)
+{
+	unsigned short bdiv;
+
+	bdiv = serial_div(gd->baudrate);
+
+	outb(0x80, UART0_BASE + UART_LCR);	/* set DLAB bit */
+	outb(bdiv&0xff, UART0_BASE + UART_DLL);	/* set baudrate divisor */
+	outb(bdiv >> 8, UART0_BASE + UART_DLM);/* set baudrate divisor */
+	outb(0x03, UART0_BASE + UART_LCR);	/* clear DLAB; set 8 bits, no parity */
+}
+
+
+void serial_putc(const char c)
+{
+	int i;
+
+	if (c == '\n')
+		serial_putc ('\r');
+
+	/* check THRE bit, wait for transmiter available */
+	for (i = 1; i < 3500; i++) {
+		if ((inb (UART0_BASE + UART_LSR) & 0x20) == 0x20) {
+			break;
+		}
+		udelay(100);
+	}
+	outb(c, UART0_BASE + UART_THR);	/* put character out */
+}
+
+
+void serial_puts(const char *s)
+{
+	while (*s) {
+		serial_putc(*s++);
+	}
+}
+
+
+int serial_getc(void)
+{
+	unsigned char status = 0;
+
+#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
+	if (serial_buffer_active) {
+		return serial_buffered_getc();
+	}
+#endif
+
+	while (1) {
+#if defined(CONFIG_HW_WATCHDOG)
+		WATCHDOG_RESET();	/* Reset HW Watchdog, if needed */
+#endif	/* CONFIG_HW_WATCHDOG */
+		status = inb(UART0_BASE + UART_LSR);
+		if ((status & asyncLSRDataReady1) != 0x0) {
+			break;
+		}
+		if ((status & ( asyncLSRFramingError1 |
+				asyncLSROverrunError1 |
+				asyncLSRParityError1  |
+				asyncLSRBreakInterrupt1 )) != 0) {
+			outb(asyncLSRFramingError1 |
+			      asyncLSROverrunError1 |
+			      asyncLSRParityError1  |
+			      asyncLSRBreakInterrupt1, UART0_BASE + UART_LSR);
+		}
+	}
+	return (0x000000ff & (int) inb (UART0_BASE));
+}
+
+
+int serial_tstc(void)
+{
+	unsigned char status;
+
+#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
+	if (serial_buffer_active) {
+		return serial_buffered_tstc();
+	}
+#endif
+
+	status = inb(UART0_BASE + UART_LSR);
+	if ((status & asyncLSRDataReady1) != 0x0) {
+		return (1);
+	}
+	if ((status & ( asyncLSRFramingError1 |
+			asyncLSROverrunError1 |
+			asyncLSRParityError1  |
+			asyncLSRBreakInterrupt1 )) != 0) {
+		outb(asyncLSRFramingError1 |
+		      asyncLSROverrunError1 |
+		      asyncLSRParityError1  |
+		      asyncLSRBreakInterrupt1, UART0_BASE + UART_LSR);
+	}
+	return 0;
+}
+
+
+#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
+
+void serial_isr(void *arg)
+{
+	int space;
+	int c;
+	int rx_put = buf_info.rx_put;
+
+	if (buf_info.rx_get <= rx_put) {
+		space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - buf_info.rx_get);
+	} else {
+		space = buf_info.rx_get - rx_put;
+	}
+
+	while (inb(UART0_BASE + UART_LSR) & 1) {
+		c = inb(UART0_BASE);
+		if (space) {
+			buf_info.rx_buffer[rx_put++] = c;
+			space--;
+
+			if (rx_put == buf_info.rx_get) {
+				buf_info.rx_get++;
+				if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO) {
+					buf_info.rx_get = 0;
+				}
+			}
+
+			if (rx_put == CONFIG_SERIAL_SOFTWARE_FIFO) {
+				rx_put = 0;
+				if (0 == buf_info.rx_get) {
+					buf_info.rx_get = 1;
+				}
+
+			}
+
+		}
+		if (space < CONFIG_SERIAL_SOFTWARE_FIFO / 4) {
+			/* Stop flow by setting RTS inactive */
+			outb(inb(UART0_BASE + UART_MCR) & (0xFF ^ 0x02),
+			      UART0_BASE + UART_MCR);
+		}
+	}
+	buf_info.rx_put = rx_put;
+}
+
+void serial_buffered_init(void)
+{
+	serial_puts ("Switching to interrupt driven serial input mode.\n");
+	buf_info.rx_buffer = malloc (CONFIG_SERIAL_SOFTWARE_FIFO);
+	buf_info.rx_put = 0;
+	buf_info.rx_get = 0;
+
+	if (inb (UART0_BASE + UART_MSR) & 0x10) {
+		serial_puts ("Check CTS signal present on serial port: OK.\n");
+		buf_info.cts = 1;
+	} else {
+		serial_puts ("WARNING: CTS signal not present on serial port.\n");
+		buf_info.cts = 0;
+	}
+
+	irq_install_handler ( VECNUM_U0 /*UART0 */ /*int vec */ ,
+			      serial_isr /*interrupt_handler_t *handler */ ,
+			      (void *) &buf_info /*void *arg */ );
+
+	/* Enable "RX Data Available" Interrupt on UART */
+	/* outb(inb(UART0_BASE + UART_IER) |0x01, UART0_BASE + UART_IER); */
+	outb(0x01, UART0_BASE + UART_IER);
+
+	/* Set DTR and RTS active, enable interrupts  */
+	outb(inb (UART0_BASE + UART_MCR) | 0x0b, UART0_BASE + UART_MCR);
+
+	/* Setup UART FIFO: RX trigger level: 1 byte, Enable FIFO */
+	outb( /*(1 << 6) |*/  1, UART0_BASE + UART_FCR);
+
+	serial_buffer_active = 1;
+}
+
+void serial_buffered_putc (const char c)
+{
+	int i;
+	/* Wait for CTS */
+#if defined(CONFIG_HW_WATCHDOG)
+	while (!(inb (UART0_BASE + UART_MSR) & 0x10))
+		WATCHDOG_RESET ();
+#else
+	if (buf_info.cts)  {
+		for (i=0;i<1000;i++) {
+			if ((inb (UART0_BASE + UART_MSR) & 0x10)) {
+				break;
+			}
+		}
+		if (i!=1000) {
+			buf_info.cts = 0;
+		}
+	} else {
+		if ((inb (UART0_BASE + UART_MSR) & 0x10)) {
+			buf_info.cts = 1;
+		}
+	}
+
+#endif
+	serial_putc (c);
+}
+
+void serial_buffered_puts(const char *s)
+{
+	serial_puts (s);
+}
+
+int serial_buffered_getc(void)
+{
+	int space;
+	int c;
+	int rx_get = buf_info.rx_get;
+	int rx_put;
+
+#if defined(CONFIG_HW_WATCHDOG)
+	while (rx_get == buf_info.rx_put)
+		WATCHDOG_RESET ();
+#else
+	while (rx_get == buf_info.rx_put);
+#endif
+	c = buf_info.rx_buffer[rx_get++];
+	if (rx_get == CONFIG_SERIAL_SOFTWARE_FIFO) {
+		rx_get = 0;
+	}
+	buf_info.rx_get = rx_get;
+
+	rx_put = buf_info.rx_put;
+	if (rx_get <= rx_put) {
+		space = CONFIG_SERIAL_SOFTWARE_FIFO - (rx_put - rx_get);
+	} else {
+		space = rx_get - rx_put;
+	}
+	if (space > CONFIG_SERIAL_SOFTWARE_FIFO / 2) {
+		/* Start flow by setting RTS active */
+		outb(inb (UART0_BASE + UART_MCR) | 0x02, UART0_BASE + UART_MCR);
+	}
+
+	return c;
+}
+
+int serial_buffered_tstc(void)
+{
+	return (buf_info.rx_get != buf_info.rx_put) ? 1 : 0;
+}
+
+#endif	/* CONFIG_SERIAL_SOFTWARE_FIFO */
+
+
+#if defined(CONFIG_CMD_KGDB)
+/*
+  AS HARNOIS : according to CONFIG_KGDB_SER_INDEX kgdb uses serial port
+  number 0 or number 1
+  - if CONFIG_KGDB_SER_INDEX = 1 => serial port number 0 :
+  configuration has been already done
+  - if CONFIG_KGDB_SER_INDEX = 2 => serial port number 1 :
+  configure port 1 for serial I/O with rate = CONFIG_KGDB_BAUDRATE
+*/
+#if (CONFIG_KGDB_SER_INDEX & 2)
+void kgdb_serial_init(void)
+{
+	volatile char val;
+	bdiv = serial_div (CONFIG_KGDB_BAUDRATE);
+
+	/*
+	 * Init onboard 16550 UART
+	 */
+	outb(0x80, UART1_BASE + UART_LCR);	/* set DLAB bit */
+	outb((bdiv & 0xff), UART1_BASE + UART_DLL);	/* set divisor for 9600 baud */
+	outb((bdiv >> 8  ), UART1_BASE + UART_DLM);	/* set divisor for 9600 baud */
+	outb(0x03, UART1_BASE + UART_LCR);	/* line control 8 bits no parity */
+	outb(0x00, UART1_BASE + UART_FCR);	/* disable FIFO */
+	outb(0x00, UART1_BASE + UART_MCR);	/* no modem control DTR RTS */
+	val = inb(UART1_BASE + UART_LSR);	/* clear line status */
+	val = inb(UART1_BASE + UART_RBR);	/* read receive buffer */
+	outb(0x00, UART1_BASE + UART_SCR);	/* set scratchpad */
+	outb(0x00, UART1_BASE + UART_IER);	/* set interrupt enable reg */
+}
+
+
+void putDebugChar(const char c)
+{
+	if (c == '\n')
+		serial_putc ('\r');
+
+	outb(c, UART1_BASE + UART_THR);	/* put character out */
+
+	/* check THRE bit, wait for transfer done */
+	while ((inb(UART1_BASE + UART_LSR) & 0x20) != 0x20);
+}
+
+
+void putDebugStr(const char *s)
+{
+	while (*s) {
+		serial_putc(*s++);
+	}
+}
+
+
+int getDebugChar(void)
+{
+	unsigned char status = 0;
+
+	while (1) {
+		status = inb(UART1_BASE + UART_LSR);
+		if ((status & asyncLSRDataReady1) != 0x0) {
+			break;
+		}
+		if ((status & ( asyncLSRFramingError1 |
+				asyncLSROverrunError1 |
+				asyncLSRParityError1  |
+				asyncLSRBreakInterrupt1 )) != 0) {
+			outb(asyncLSRFramingError1 |
+			     asyncLSROverrunError1 |
+			     asyncLSRParityError1  |
+			     asyncLSRBreakInterrupt1, UART1_BASE + UART_LSR);
+		}
+	}
+	return (0x000000ff & (int) inb(UART1_BASE));
+}
+
+
+void kgdb_interruptible(int yes)
+{
+	return;
+}
+
+#else	/* ! (CONFIG_KGDB_SER_INDEX & 2) */
+
+void kgdb_serial_init(void)
+{
+	serial_printf ("[on serial] ");
+}
+
+void putDebugChar(int c)
+{
+	serial_putc (c);
+}
+
+void putDebugStr(const char *str)
+{
+	serial_puts (str);
+}
+
+int getDebugChar(void)
+{
+	return serial_getc ();
+}
+
+void kgdb_interruptible(int yes)
+{
+	return;
+}
+#endif	/* (CONFIG_KGDB_SER_INDEX & 2) */
+#endif
diff --git a/arch/i386/cpu/start.S b/arch/i386/cpu/start.S
new file mode 100644
index 0000000..25d32e6
--- /dev/null
+++ b/arch/i386/cpu/start.S
@@ -0,0 +1,135 @@
+/*
+ *  U-boot - i386 Startup Code
+ *
+ *  Copyright (c) 2002	Omicron Ceti AB, Daniel Engström <denaiel@omicron.se>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#include <config.h>
+#include <version.h>
+
+
+.section .text
+.code32
+.globl _start
+.type _start, @function
+.globl _i386boot_start
+_i386boot_start:
+_start:
+	movl    $0x18,%eax	/* Load our segement registes, the
+				 * gdt have already been loaded by start16.S */
+	movw    %ax,%fs
+	movw	%ax,%ds
+	movw    %ax,%gs
+	movw    %ax,%es
+	movw    %ax,%ss
+
+	/* We call a few functions in the board support package
+	 * since we have no stack yet we'll have to use %ebp
+	 * to store the return address */
+
+	/* Early platform init (setup gpio, etc ) */
+	mov     $early_board_init_ret, %ebp
+	jmp	early_board_init
+early_board_init_ret:
+
+	/* The __port80 entry-point should be usabe by now */
+	/* so we try to indicate progress */
+	movw	$0x01, %ax
+	movl	$.progress0, %ebp
+	jmp	show_boot_progress_asm
+.progress0:
+
+	/* size memory */
+	mov	$mem_init_ret, %ebp
+	jmp     mem_init
+mem_init_ret:
+
+	/* Check we have enough memory for stack */
+	movl	$CONFIG_SYS_STACK_SIZE, %ecx
+	cmpl	%ecx, %eax
+	jae	mem_ok
+
+	/* indicate (lack of) progress */
+	movw	$0x81, %ax
+	movl	$.progress0a, %ebp
+	jmp	show_boot_progress_asm
+.progress0a:
+	jmp	die
+mem_ok:
+	/* Set stack pointer to upper memory limit*/
+	movl    %eax, %esp
+
+	/* indicate progress */
+	movw	$0x02, %ax
+	movl	$.progress1, %ebp
+	jmp	show_boot_progress_asm
+.progress1:
+
+	/* Test the stack */
+	pushl	$0
+	popl	%eax
+	cmpl	$0, %eax
+	jne	no_stack
+	push	$0x55aa55aa
+	popl	%ebx
+	cmpl	$0x55aa55aa, %ebx
+	je	stack_ok
+
+no_stack:
+	/* indicate (lack of) progress */
+	movw	$0x82, %ax
+	movl	$.progress1a, %ebp
+	jmp	show_boot_progress_asm
+.progress1a:
+	jmp die
+
+
+stack_ok:
+	/* indicate progress */
+	movw	$0x03, %ax
+	movl	$.progress2, %ebp
+	jmp	show_boot_progress_asm
+.progress2:
+
+	wbinvd
+
+	/* Get upper memory limit */
+	movl %esp, %ecx
+	subl $CONFIG_SYS_STACK_SIZE, %ecx
+
+	/* Create a Stack Frame */
+	pushl %ebp
+	movl %esp, %ebp
+
+	/* stack_limit parameter */
+	pushl	%ecx
+	call	board_init_f	/* Enter, U-boot! */
+
+	/* indicate (lack of) progress */
+	movw	$0x85, %ax
+	movl	$.progress4a, %ebp
+	jmp	show_boot_progress_asm
+.progress4a:
+
+die:	hlt
+	jmp	die
+	hlt
diff --git a/arch/i386/cpu/start16.S b/arch/i386/cpu/start16.S
new file mode 100644
index 0000000..1ebb6bc
--- /dev/null
+++ b/arch/i386/cpu/start16.S
@@ -0,0 +1,112 @@
+/*
+ *  U-boot - i386 Startup Code
+ *
+ *  Copyright (c) 2002, 2003 Omicron Ceti AB, Daniel Engström <denaiel@omicron.se>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#define BOOT_SEG	0xffff0000	/* linear segment of boot code */
+#define a32		.byte 0x67;
+#define o32		.byte 0x66;
+
+.section .start16, "ax"
+.code16
+.globl start16
+start16:
+	/* First we let the BSP do some early initialization
+	 * this code have to map the flash to its final position
+	 */
+	mov	$board_init16_ret, %bp
+	jmp	board_init16
+board_init16_ret:
+
+	/* Turn of cache (this might require a 486-class CPU) */
+	movl	%cr0, %eax
+	orl	$0x60000000,%eax
+	movl	%eax, %cr0
+	wbinvd
+
+	/* load the descriptor tables */
+o32 cs	lidt	idt_ptr
+o32 cs	lgdt	gdt_ptr
+
+
+	/* Now, we enter protected mode */
+	movl	%cr0, %eax
+	orl	$1,%eax
+	movl	%eax, %cr0
+
+	/* Flush the prefetch queue */
+	jmp	ff
+ff:
+
+	/* Finally jump to the 32bit initialization code */
+	movw	$code32start, %ax
+	movw	%ax,%bp
+o32 cs	ljmp	*(%bp)
+
+	/* 48-bit far pointer */
+code32start:
+	.long	_start		/* offset */
+	.word	0x10		/* segment */
+
+idt_ptr:
+	.word	0		/* limit */
+	.long	0		/* base */
+
+gdt_ptr:
+	.word	0x30		/* limit (48 bytes = 6 GDT entries) */
+	.long	BOOT_SEG + gdt	/* base */
+
+	/* The GDT table ...
+	 *
+	 *	 Selector	Type
+	 *	 0x00		NULL
+	 *	 0x08		Unused
+	 *	 0x10		32bit code
+	 *	 0x18		32bit data/stack
+	 *	 0x20		16bit code
+	 *	 0x28		16bit data/stack
+	 */
+
+gdt:
+	.word	0, 0, 0, 0	/* NULL  */
+	.word	0, 0, 0, 0	/* unused */
+
+	.word	0xFFFF		/* 4Gb - (0x100000*0x1000 = 4Gb) */
+	.word	0		/* base address = 0 */
+	.word	0x9B00		/* code read/exec */
+	.word	0x00CF		/* granularity = 4096, 386 (+5th nibble of limit) */
+
+	.word	0xFFFF		/* 4Gb - (0x100000*0x1000 = 4Gb) */
+	.word	0x0		/* base address = 0 */
+	.word	0x9300		/* data read/write */
+	.word	0x00CF		/* granularity = 4096, 386 (+5th nibble of limit) */
+
+	.word	0xFFFF		/* 64kb */
+	.word	0		/* base address = 0 */
+	.word	0x9b00		/* data read/write */
+	.word	0x0010		/* granularity = 1  (+5th nibble of limit) */
+
+	.word	0xFFFF		/* 64kb */
+	.word	0		/* base address = 0 */
+	.word	0x9300		/* data read/write */
+	.word	0x0010		/* granularity = 1 (+5th nibble of limit) */
diff --git a/arch/i386/include/asm/interrupt.h b/arch/i386/include/asm/interrupt.h
index 8d324d9..07426fe 100644
--- a/arch/i386/include/asm/interrupt.h
+++ b/arch/i386/include/asm/interrupt.h
@@ -27,7 +27,7 @@
 #ifndef __ASM_INTERRUPT_H_
 #define __ASM_INTERRUPT_H_ 1
 
-/* cpu/i386/interrupts.c */
+/* arch/i386/cpu/interrupts.c */
 void set_vector(u8 intnum, void *routine);
 
 /* arch/i386/lib/interupts.c */
diff --git a/arch/i386/include/asm/u-boot-i386.h b/arch/i386/include/asm/u-boot-i386.h
index a08632d..521fd35 100644
--- a/arch/i386/include/asm/u-boot-i386.h
+++ b/arch/i386/include/asm/u-boot-i386.h
@@ -33,7 +33,7 @@
 typedef void (timer_fnc_t) (void);
 int register_timer_isr (timer_fnc_t *isr_func);
 
-/* Architecture specific - can be in cpu/i386/, arch/i386/lib/, or $(BOARD)/ */
+/* Architecture specific - can be in arch/i386/cpu/, arch/i386/lib/, or $(BOARD)/ */
 int timer_init(void);
 
 /* cpu/.../interrupts.c */