[U-Boot] [PATCH] Marvell Kirkwood family SOC support

Prafulla Wadaskar prafulla at marvell.com
Sat Apr 4 00:39:27 CEST 2009


From: prafulla_wadaskar <prafulla at marvell.com>

Kirkwood family controllers are highly integrated SOCs
based on Feroceon-88FR131/Sheeva-88SV131 cpu core.

SOC versions supported:-
1) 88F6281-Z0       define CONFIG_KW88F6281_Z0
2) 88F6281-A0       define CONFIG_KW88F6281_A0
3) 88F6192-A0       define CONFIG_KW88F6192_A0

Other supported features:-
1) Doimage utility needed to create binaries with
   bootROM header
2) get_random_hex() fucntion
3) SPI port controller driver
4) PCI Express port initialization

Contributors:
Yotam Admon <yotam at marvell.com>
Michael Blostein <michaelbl at marvell.com

Signed-off-by: prafulla_wadaskar <prafulla at marvell.com>
Reviewed by: Ronen Shitrit <rshitrit at marvell.com>
---
 board/Marvell/common/kw_lowlevel_init.S        |   45 +
 board/Marvell/include/core.h                   |    4 +
 cpu/arm926ejs/kirkwood/Makefile                |   52 +
 cpu/arm926ejs/kirkwood/bin_dep.sh              |   50 +
 cpu/arm926ejs/kirkwood/config.mk               |   25 +
 cpu/arm926ejs/kirkwood/doimage/Makefile        |  112 ++
 cpu/arm926ejs/kirkwood/doimage/bootstrap_def.h |   88 ++
 cpu/arm926ejs/kirkwood/doimage/doimage         |  Bin 0 -> 17712 bytes
 cpu/arm926ejs/kirkwood/doimage/doimage.c       | 1341 ++++++++++++++++++++++++
 cpu/arm926ejs/kirkwood/dram.c                  |   49 +
 cpu/arm926ejs/kirkwood/kw88f6192.h             |   34 +
 cpu/arm926ejs/kirkwood/kw88f6281.h             |   34 +
 cpu/arm926ejs/kirkwood/kwcore.c                |  262 +++++
 cpu/arm926ejs/kirkwood/kwcore.h                |  141 +++
 cpu/arm926ejs/kirkwood/serial.c                |  187 ++++
 cpu/arm926ejs/kirkwood/soc_init.S              |  156 +++
 cpu/arm926ejs/kirkwood/spi.c                   |  213 ++++
 cpu/arm926ejs/kirkwood/timer.c                 |  165 +++
 include/configs/kirkwood.h                     |   46 +
 19 files changed, 3004 insertions(+), 0 deletions(-)
 create mode 100644 board/Marvell/common/kw_lowlevel_init.S
 create mode 100644 cpu/arm926ejs/kirkwood/Makefile
 create mode 100755 cpu/arm926ejs/kirkwood/bin_dep.sh
 create mode 100644 cpu/arm926ejs/kirkwood/config.mk
 create mode 100644 cpu/arm926ejs/kirkwood/doimage/Makefile
 create mode 100644 cpu/arm926ejs/kirkwood/doimage/bootstrap_def.h
 create mode 100755 cpu/arm926ejs/kirkwood/doimage/doimage
 create mode 100644 cpu/arm926ejs/kirkwood/doimage/doimage.c
 create mode 100644 cpu/arm926ejs/kirkwood/dram.c
 create mode 100644 cpu/arm926ejs/kirkwood/kw88f6192.h
 create mode 100644 cpu/arm926ejs/kirkwood/kw88f6281.h
 create mode 100644 cpu/arm926ejs/kirkwood/kwcore.c
 create mode 100644 cpu/arm926ejs/kirkwood/kwcore.h
 create mode 100644 cpu/arm926ejs/kirkwood/serial.c
 create mode 100644 cpu/arm926ejs/kirkwood/soc_init.S
 create mode 100644 cpu/arm926ejs/kirkwood/spi.c
 create mode 100644 cpu/arm926ejs/kirkwood/timer.c
 create mode 100644 include/configs/kirkwood.h

diff --git a/board/Marvell/common/kw_lowlevel_init.S b/board/Marvell/common/kw_lowlevel_init.S
new file mode 100644
index 0000000..61453a7
--- /dev/null
+++ b/board/Marvell/common/kw_lowlevel_init.S
@@ -0,0 +1,45 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#define KW_ASMLANGUAGE
+#include <config.h>
+
+.globl lowlevel_init
+lowlevel_init:
+    /* Linux expects` the internal registers to be at 0xf1000000 */
+    ldr r1, = KW_OFFSET_REG
+    ldr r3, = KW_REGS_PHY_BASE
+    str r3,[r1]
+
+    /* save Link Registers */
+    mov r2, lr
+
+    /* Enable L2 cache in write through mode */
+    bl kw_enable_invalidate_l2_cache
+
+    /* Initialize BUS-L to DDR configuration parameters     */
+    /* Must be done prior to DDR operation                  */
+    bl kw_cpu_if_pre_init
+    mov lr, r2
+    mov pc, lr
diff --git a/board/Marvell/include/core.h b/board/Marvell/include/core.h
index c413439..ecc4682 100644
--- a/board/Marvell/include/core.h
+++ b/board/Marvell/include/core.h
@@ -12,9 +12,11 @@ space). The macros take care of Big/Little endian conversions.
 #ifndef __INCcoreh
 #define __INCcoreh
 
+#ifndef CONFIG_KIRKWOOD
 #include "mv_gen_reg.h"
 
 extern unsigned int INTERNAL_REG_BASE_ADDR;
+#endif /* CONFIG_KIRKWOOD */
 
 /****************************************/
 /*	    GENERAL Definitions			*/
@@ -91,10 +93,12 @@ extern unsigned int INTERNAL_REG_BASE_ADDR;
 #define _1G		0x40000000
 #define _2G		0x80000000
 
+#ifndef __ASSEMBLY__
 #ifndef	BOOL_WAS_DEFINED
 #define BOOL_WAS_DEFINED
 typedef enum _bool{false,true} bool;
 #endif
+#endif
 
 /* Little to Big endian conversion macros */
 
diff --git a/cpu/arm926ejs/kirkwood/Makefile b/cpu/arm926ejs/kirkwood/Makefile
new file mode 100644
index 0000000..41ac8d7
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Prafulla Wadaskar <prafulla at marvell.com>
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).a
+
+COBJS-y	= timer.o
+COBJS-y	+= serial.o
+COBJS-y	+= kwcore.o
+COBJS-y	+= dram.o
+COBJS-$(CONFIG_KIRKWOOD_SPI)		+= spi.o
+
+SOBJS	= soc_init.o
+
+SRCS    := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS    := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm926ejs/kirkwood/bin_dep.sh b/cpu/arm926ejs/kirkwood/bin_dep.sh
new file mode 100755
index 0000000..1b36e91
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/bin_dep.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Prafulla Wadaskar <prafulla at marvell.com>
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+# Kirkwood SOC has BootROM
+# On power on Reset BootROM will be executed if enabled
+# BootROM looks for valid BootROM header and header extensions (optional)
+# on the configured boot media to achieve sucessfull "boot from" operation
+#
+# This script builds/cleans doimage utility
+
+TOP_DIR=`pwd`
+CUR_DIR=$2
+BIN_FILE=$TOP_DIR/$1
+
+if [ "clean" == "$1" ]; then
+	# erase created doimage utility
+	rm -f $CUR_DIR/doimage/doimage
+	exit 0
+fi
+
+if [ ! -f $BIN_FILE ]; then
+	echo Error.. could not find $BIN_FILE
+	exit 1
+else
+	make -C $CUR_DIR/doimage
+	exit 0
+fi
+
diff --git a/cpu/arm926ejs/kirkwood/config.mk b/cpu/arm926ejs/kirkwood/config.mk
new file mode 100644
index 0000000..000eeb4
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Prafulla Wadaskar <prafulla at marvell.com>
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+PLATFORM_CPPFLAGS += -march=armv5te
diff --git a/cpu/arm926ejs/kirkwood/doimage/Makefile b/cpu/arm926ejs/kirkwood/doimage/Makefile
new file mode 100644
index 0000000..219ae1e
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/doimage/Makefile
@@ -0,0 +1,112 @@
+#
+# (C) Copyright 2009
+# Marvell Semiconductor <www.marvell.com>
+# Prafulla Wadaskar <prafulla at marvell.com>
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+#
+
+# Kirkwood SOC has BootROM
+# On power on Reset BootROM will be executed if enabled
+# BootROM looks for valid BootROM header and header extensions (optional)
+# on the configured boot media to achieve sucessfull "boot from" operation
+#
+# This Makefile builds/cleans doimage utility
+
+BIN_FILES	= doimage$(SFX)
+
+OBJ_LINKS	=
+OBJ_FILES	= doimage.o
+
+LIBFDT_OBJ_FILES	=
+
+#-------------------------------------------------------------------------
+
+HOSTARCH := $(shell uname -m | \
+	sed -e s/i.86/i386/ \
+	    -e s/sun4u/sparc64/ \
+	    -e s/arm.*/arm/ \
+	    -e s/sa110/arm/ \
+	    -e s/powerpc/ppc/ \
+	    -e s/Power\ Macintosh/ppc/ \
+	    -e s/macppc/ppc/)
+
+HOSTOS := $(shell uname -s | tr A-Z a-z | \
+	sed -e 's/\(cygwin\).*/cygwin/')
+
+TOOLSUBDIRS =
+
+#
+# Everyone else
+#
+HOST_CFLAGS = -Wall -pedantic
+HOST_LDFLAGS =
+HOST_ENVIRO_CFLAGS =
+
+#
+# Cygwin needs .exe files :-(
+#
+ifeq ($(HOSTOS),cygwin)
+SFX = .exe
+HOST_CFLAGS += -ansi
+else
+SFX =
+endif
+
+#
+# Include this after HOSTOS HOSTARCH check
+# so that we can act intelligently.
+#
+include $(TOPDIR)/config.mk
+
+# now $(obj) is defined
+SRCS	:= $(addprefix $(obj),$(OBJ_LINKS:.o=.c)) $(OBJ_FILES:.o=.c)
+BINS	:= $(addprefix $(obj),$(BIN_FILES))
+
+#
+# Use native tools and options
+#
+CPPFLAGS   = -idirafter $(SRCTREE)/include \
+		-idirafter $(OBJTREE)/include2 \
+		-idirafter $(OBJTREE)/include \
+		-DTEXT_BASE=$(TEXT_BASE) -DUSE_HOSTCC
+CFLAGS     = $(HOST_CFLAGS) $(CPPFLAGS) -O
+
+# No -pedantic switch to avoid libfdt compilation warnings
+FIT_CFLAGS = -Wall $(CPPFLAGS) -O
+
+AFLAGS	   = -D__ASSEMBLY__ $(CPPFLAGS)
+CC	   = $(HOSTCC)
+STRIP	   = $(HOSTSTRIP)
+MAKEDEPEND = makedepend
+
+all:	$(obj).depend $(BINS)
+
+$(obj)doimage$(SFX):	$(obj)doimage.o
+		$(CC) $(CFLAGS) $(HOST_LDFLAGS) -o $@ $^
+		$(STRIP) $@
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm926ejs/kirkwood/doimage/bootstrap_def.h b/cpu/arm926ejs/kirkwood/doimage/bootstrap_def.h
new file mode 100644
index 0000000..8782206
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/doimage/bootstrap_def.h
@@ -0,0 +1,88 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _INC_BOOTSTRAP__DEF_H
+#define _INC_BOOTSTRAP__DEF_H
+
+#ifndef MV_ASMLANGUAGE
+/* typedefs */
+
+typedef char s8;
+typedef unsigned char u8;
+
+typedef int s32;
+typedef unsigned int u32;
+
+typedef short s16;
+typedef unsigned short u16;
+
+typedef long s64;
+typedef unsigned long u64;
+
+typedef struct BHR_t {
+	u8 blockID;		/*0     */
+	u8 nandEccMode;		/*1     */
+	u16 nandPageSize;	/*2-3   */
+	u32 blockSize;		/*4-7   */
+	u32 rsvd1;		/*8-11  */
+	u32 sourceAddr;		/*12-15 */
+	u32 destinationAddr;	/*16-19 */
+	u32 executionAddr;	/*20-23 */
+	u8 sataPioMode;		/*24    */
+	u8 rsvd3;		/*25    */
+	u16 ddrInitDelay;	/*26-27 */
+	u16 rsvd2;		/*28-29 */
+	u8 ext;			/*30    */
+	u8 checkSum;		/*31    */
+} BHR_t, *pBHR_t;
+
+typedef struct ExtBHR_t {
+	u32 dramRegsOffs;	/*0-3   */
+	u32 rsrvd1;		/*4-7   */
+	u32 rsrvd2;		/*8-11  */
+	u32 rsrvd3;		/*12-15 */
+	u32 rsrvd4;		/*16-19 */
+	u32 rsrvd5;		/*20-23 */
+	u32 rsrvd6;		/*24-27 */
+	u16 rsrvd7;		/*28-29 */
+	u8 rsrvd8;		/*30    */
+	u8 checkSum;		/*31    */
+} ExtBHR_t, *pExtBHR_t;
+
+#define BOOTROM_SIZE			(12 * 1024)
+#define HEADER_SIZE			512
+#define BHR_HDR_SIZE        		0x20
+#define EXT_HEADER_SIZE			(HEADER_SIZE - BHR_HDR_SIZE)
+
+/* Boot Type - block ID */
+#define IBR_HDR_I2C_ID			0x4D
+#define IBR_HDR_SPI_ID    		0x5A
+#define IBR_HDR_NAND_ID     		0x8B
+#define IBR_HDR_SATA_ID     		0x78
+#define IBR_HDR_PEX_ID			0x9C
+#define IBR_HDR_UART_ID     		0x69
+#define IBR_DEF_ATTRIB      		0x00
+
+#endif /* MV_ASMLANGUAGE */
+#endif /* _INC_BOOTSTRAP_H */
diff --git a/cpu/arm926ejs/kirkwood/doimage/doimage b/cpu/arm926ejs/kirkwood/doimage/doimage
new file mode 100755
index 0000000000000000000000000000000000000000..9fee11740454ff880c081a64be0d692b1da4c19a
GIT binary patch
literal 17712
zcmcIse|%KcmA{h=Fd#ayQbf(l!zLA42nnP#P^kP$gccORAQmtT$%Gl3WMbxx1Q%-J
zWR$m$X;~#*yJ8DU`*B;_;#LAEQxjlGw01XGYjJg3RMZ)RHtSDnquKBG-uEVNNWk`w
zeSB{2Irp4<?m6e4d+vR2-s8^FC1oy`OW0SI$QH!5-{bZaqwb!oD8)h(9x+kmiYvr$
zG?7-^1RfOG0iA}S&5e>x8t~#~&`~Y{&O#bxv&f5mQR?Ri!NUF`N6}^5Z$U#@hYmYY
zI4<c~s9M0^0vbyfa2C=z2FoJwFT&U?3xTuPv}LdBReiIC=sV>0u;hZqV$*K`9q6FT
zmOr&7xPEF))s&iGU8J!f94eTm`a(5n+qKt~%f8f;eMX{C_81iUhV+Mi@$Rxm`Yxz`
zCi&2W<y(JphjDNBc+xIMp?~O$rY~n*Mf?gBUX%V|TkfOZe679YT{Cw>xsStTTvILV
z4%DARxz at sc7EZbLr2&{}A)J2l at 3e5c{}KydfSU9tEWFL)|EYz)Y0;mx at KY9jgM}w8
ze4T|~jhgc6EWFIZ3oLw^g+FZJ)RX)H3lCZN0~TIk$$!Yg^DO%97QWG<f6Kx at wCIds
zUf;9m_bOEU2sOtuE!>vZV&MoqN&l6F=UezB3;&CSuOR+kZV%`FVsV+A+xz$0xL0gJ
z`^o>b at yo<K;HMn8sHoUb8>*`a>%IoPqCz0-Dj9AwM8)Fk(OMO(tB8dCRl?sG)J1iu
z-d`u`BYK#BDg(X-Az4Iit*>6x`fI~}oh_jVc*()G%KA;By0Rt|_Jh=*haxqi)>l&#
zswAhsp+VF}>e#(HT<NQ;hC<bi&;|lFHUxD)<TM29bhJaC4StA(kjmP6 at KIMw@mgQ7
zPE<Ge{o>jsi{~$>m{w4fh6-Ua)-zWM|JwhuC8Yk^ZJD)8a&WC=F(t at CSr-R`7jl&y
zx7u<fo+Vx)5!Vv<cQ_Ur{XPtfp8g*84<KNkhFvbi8sH-k59?S%tt!^w53t5W*09Fn
ztY?kIt+O5>L?dgD5Sv+J!8frUg&f8D0wK1t9xcQ+*3fV}>x+cg!P+at{j6cgPSzI-
zv5Pf=a1U!F&qr7zfjr9k^Fr)pJywXvSzju|0oLP$IK=ugA<B){qo+N|<1i(;3U(wb
zza+%dM at 0WuZUjev{wn;XKl<}&v0PcHll{2zX?cLORJX+GfdE~cYL_ at Y5x__ywO8Ww
zNI)aLOXBoQU?TDD5~qg(oaa=N#ObL(3GsS~(_?|T#Meojo(n7 at zD(luU|<>Xxe})*
z1FMJ^N}L`ItRt>ToSqHPpj3{;>ES><aUpSfI?zbG_fs_F)8m0A;wL3e&j+>=@0K`c
zAh4ZyyTmyYf%}Q?l{jZ4u#5OEiF0NGj}YH3an4X+FYzXcbEX0Zh}TP;GZttkz7BZN
z+qW36L{IfDyK#A-`<I}c#Ge~h2L8Cs?MeO;4DWB>j=5bCJ?&1Sk67J&WIOVwd0!uF
zi9M$eOMU}Pt5!dKWV^g9-ljPo1h|M?b6_(z%qfld({Uy%zN&w>8|^cX+&(`3_!lWJ
z+U|OoP5onHWU|N`lgEZpfGc{`y?X7Dxc)^EKg2X{#o6vA at W$Hp&(SUcU}UE|k8S<k
zP=q>|OGlgK9&g*)9B*5e>qzvlE1Gge-t)E{fjlsnOFd@!XtOjY+ZF9_N8fVCp1bpX
zNx5m|3c2w-NzqS@$Ddy#sD-!fuG84NjlWFlFnWJ?a-<ab at kNn050cO5l6@X=>BEmF
zi%#@p9Zzz|k3EsoP{VNlQ?$d?{1@)Dk>^+6QXvOgxuW^B8%x|=JKBuo#A9dv+TU-u
z^OBA5tXb+YIzBoc{d9!)Zb~*UDSD>))qXirN76IBrIp;~3U|?A)$DBa4AnS#sK%V3
z8pjOPIBuxMTt}nPF at 2j<DtbhVzT=_h_mnY4KGesX*+pIXQu${(-trj7r*D(SMvu6o
z at 3<nb7+oKAHy@=dR^K8$gG_??L^c!2KA73LFweaU`xx44{vBbt6|o2S$7o8vtl$LU
zZUw(U_^5*aO!$C;J&yr?RKXJn?^3WFX9ve|=gnffC4W1|+N^j^5Uy8n&aVJhDR>d#
zRSIq)yhOo|5}vEzlZ1;EJmzu06BWFMaIS)P5YAEX3Bqm#=k5c{sfKO=!lxDdIN_5D
zP7;1z!6j{gyDWafhZMY*@LmPKPk4`l3-<%QU%_h#Z&UDA!c7XEPoL-(58;4<50Gb#
zf=?1&reN&=;DrjVCtRZ7M+r|>@J7nf6r5!H7zK|x2-u_G*@XK(mbUAJdlmdB;Zq7u
z5<a2eaZdn#*3sUs;Du~|+|mAsg151Kr=xwlf~A}mM|-1!50Jmc(Y{W>|4dtM1pM at o
z_>w#~l4<{KeMm7#BsVml-ipoKbQv)Qm3gzfv-C8=T6C7mY}y&)9wQrKvn?oIdfJE;
z1BsU=jaUhREl2xgqC4mT>w7<oZ`t#h=e?gr6O`%lw(wlq8QTd&N!pW!9!W!tdqw4H
zP|%??^lTd98dB8f)6j`D^fDkO!_L^rblaIU)R%_DCrV1{w>YvSzl3(gFFPhT{{?Qy
z_O^*=a>4Ae-g_PZgSV}{KQC5;>>B;KG)Y+|?z}kpXB7&v>pXNt$}p!J`)KQjF>3A7
zFHSz=V9F&^TvAfkK=vSs4?39td<M=fKSiP0NHU%rXlUG+=Vlhp2F*BZmY!-V5g4P|
z(d__8YV<5nmN+Os1VxRWWwde{QcvRSHb{rd99_PB9v$xdC_{%=RlG at O6sL7?Lx(O0
z<?^%+Zljd}koxLSI<z{vyoqtn<%hq1n4!Zhj&6I=?ISr0yxoKv^BlzcsCz2|p;=A`
zSvq437V4jR80a9sxE%dgoJXe(nL0g#Ik)30cR(jB7U=YI2eF_1oH~J}Gsdu$I(ey+
zTvQA_-O=$FI$D+ at Mj-Vj2l3xPv}^=1^)wdzAj__H at NWYDxx5|!Aj8|em`mHT`RJyi
z&I1Kra8M?KqN2`Yv~r=RN{7<nVMmt_Fpg6P?tymXkIdAe#?kH9ASoT at LWkuJ${tXZ
z4s(rGCXrMJ?g9q+VZ5WuZRgP;_I`#Rl9*N753|xbXwcz59TY9CgJ!fceWm6MrNaY`
zE^lL;bNRuQsY8{cTN_ALJZLf=u5}Q90HPHSAR4Vqm8oAL!UlQcVn?sa^Jud1y$o;s
zH|E>+#^eD_FajKsa1gx%nt*7uGLfey4W-FFj$SWfv~&67?RPUYS?1{W5V~1Df!CqQ
zbO$j8qU941jaF_XsUIQe2KnR at OrmYv_2|Xq{52zS03B51<v{ca2h*3xBvVXI&$2<{
ze&OI0mbh#qb_n8{5^~$ybaB#fFueo|m8MNl&%7i)-(_Ss-Qg16*g`Dg%mKbLO70y^
zB~$d at o6;zwbsSQj8E4`%;<@-6{WvRfjkRziGj^ZE?U%7IZ#4HCgooha7BeDX^BEp6
ze)GTm{mC<!INJ%|fI^mEIm2IxCOC~AeX;^_^e-qt(=S&5m*#$lfRPZO#>ZLVR=D4k
zXN9MB;M{T$TZ8B`j=lF2 at 4p=O-rL?8<DnRB;vgOph?2wJmc;`-esInn$eiNfwN{Ty
z*(1R{+DL4}UvJx`-nL;sMCX}@BiDG_ZgK(rkwOcBW&z!$&<Q|sIvBPasM3WBRv&b^
zW<nL-h?y}Z68Ck(9#Wmk%(!a1fr1}ajYZzJ8z^{>Lazc!!9Pw5#^FFfE*?ula+Q=!
zm7n+tIBd5Vf5>zUxWqv`eUXkS9O&~i_Mt$y^6Wlv#z3DwAj<tuJjOme&<)WC=^MJ?
z4=12Y_8GAHAUeX4^E0e|LN!jYtbS6VS6Wsd0;=3e<)sBP59<x)J|%T59FtHzW_#OK
z(u==N%Uek=K9!cYl3r|2%cB7Y at 4+9)yDB*sp=QVJy?;g^Pjxgjqam8$@^DA8qp$2X
z<<Vh6*UT;i>~II;DlmHYCzv;@jV*sPV?0S2rO%u4IAfHb=!}hq6by>(n(^xK-t!hG
zBTl40FW!Zt<N!}+jM;_}n))rcj+Gv5j3ypMlh7|P_Yp86-8~~ZOS?H$11T&rO7&!`
zB at LiO$4>8UiAZrTy9TJK^=gEmGA?>DCwj(pS%34Jd=}H(iHC>6NKkoWOLuC9;{8?z
zZ+pH5)?t!UnrZ7gc4myaHe6)NJ>DqqPJIB)%(xV{v^(`CFc at cMi2Jbl4a#diCI#*z
zuPyMBnbP=%3ry(^Xw);(ltUV&-QN9j7q2$Tk9phT+)TGF{f|_O8e(V05Dtw8L at Qk#
z{>_F^Xty+ at D;y)Wb2w%|gwzV!Nm1wx?OLU+<=xQ)r!<QhPtL73b{l-Df?>Ef#?`D2
za&B+z*L2baMtm=Nm|?epCo=!&F}5Vl)uW9EA4j91<HSEYFM0elo>sK$>x|8LZZk%9
z-UmFXTEAheL8}x(-XE*hV)7crdC69V=aGweOyOfBK07ZNk+?Uu0GefN0Y%Wxu?6Hl
zi7lY3XJ8dAK}TgucI3{p%vkL))+TN3FHs|YN$Q!9+GE^LAPP1qJ)qay68FX)!?2&J
z$6SXVM*$~&?+hsRD>Nv at vLfXswp8ig1#Sbkuh`PeR;j|6yyP8n$jJQ99PapA1JcVm
z+`DfNG%Q3zXN=PY&D9gRcw!+|ySZ~8pUaxrv376EeU>-L!^!(@s=xo?F6_9`GyVE)
zY+1uWhOr5q&<nbH=>KJKywVU%H-TyQDQ?t2o`8(m*Xi!rb&+w%Z5>E`$!eu4he`g_
z$s7lB=feGcm}b!f!TXu;Mf8{}`f0W|#s|zQVza$1OTfdC$uJODFDDUphaWzwbdG%4
z+$a60D=q(k!P8nk#<ARa?4Qhs67kp)$frR($%DdOB>5X~8AlKUvv*S{En3B<HF={=
z6(*aN?9EOOlq=aZBl$F7v$YYjn?DwXLVRb2T4>pkDN=tlVX$3{+;^aTdYJzO0)mtg
zqr8QA{6$hIhJ|@KXc$c at Y7c8mZSo{fy$Ky-?U?Uad!)cxj at Deg?exOWFiProNXMO$
zo1LRFFht}k3g(Z8sNM6CdQHS8>~Dl at 85KR_NMU}rD7V;@=o}d$kz5k2VTa)vVA}b`
z7}m-{kz1pQMexp$1134(2#S3c-ggctDQ~}FQKEB5 at 5hAWsn1XY9)XOW3+;T at G7A=)
zF;0q6+GVyr3r9s?%`sZH1JK>aN?&!UNy^gm6yVmcP=L at sr+^XqNCkKz?r3S3JDT8e
zRp|L<t30>9nyp`K#w6J8p44r`c&1e+Ti4Pqv%IS__P(_qKRleR7hCE;d21q1FeF}r
zg=T4&(Gh(m`w0g7q-Ts)_H%VZbH;BkruzeM8L=)jbI#brnc-Te|1Jg9I<0$+QJBzZ
z;t)snwtNB(a$bqKG54{N+4m+&J7zvec~5}@zYxH&vJVorT<;kxX#@D}NTt459Fj?c
zRLc7ov at wHx6$zM6u$x~MP|fJ-NRAtM7}ZHnK7QE}BM*1HGH&EE#wF2CS98CZjnn!t
z+#mGprHuPt#|q6&@VwOgn&6gvL~h9#%9Ms<*4?`qb+q{N;GTIxpWq0;JZJdr13mRW
z_+8K15|L;B9Zg2;C``7F1WS|=w4WlMJ7qZ+I9;Zpj+Y)K={K-%Yw2qy4iEb%z!=UM
zD|4Hr&l+VOv$WeN!%rp88)Z3W=?SB3j9L1!Q8vyjJ!zEXMiUG<OvPn#UU;7dWS2FF
zoELfXW?(mZ3Mv at KFd6wnPQyuRXeEprVU3)+_=Ckfvvj)7o|G(bz`K|i{DJ at nPeX50
z+8=G78y}N^BK`3=J0l!D2A<5))Lf2Hx at Ru*Gh1nE^sr`@?lI%i?s<S8G3LYYM~(R~
ze6KMdhCgo1hv5f|`7r#DF&~Dv8}oBzpi+!Fr6n~^pn-|l0>zXcO?lMYy724iR1vTa
zSO{`8JeSIDE`2ID{<Z%8uSs#7`E(x0nE5BclX at 1v@H!Y~Gc@>%GKKsr7<z6RhyiO#
zamYzW*Zx<X<D?T@#yBfDP8G&UZ&)`;ghy;_Wpd%U^ZM`(NU{X1oK|m3G4)bei54c9
zzwIN^Ll{(TBL~=PQn%|}JJG?5f}WcSmQLB79CR>io^aBt_q_s%N0c0+yW`CGj^vdt
z)LE28PG%Hb$p;u~^6@$;X{AW_;PxQ70AoevSZ)r)%oMlT2ZoDdxOnb3#@AthN=#}L
z9+#=qIShwQZY&Qn6LVE9Wg=4B%yFt38-oC(Yc7+0c<Y{{2d!K8jTb1u6UpsCnkG^6
zw)_`VvF_x(Ej%#Fb&%pu>*hXs)Y~@P_T2RxPL9E;{}D#yS)&Ix`qMC8&+k<SDM0xw
z`l?G`5MPjG9GUbxBR4O(nM!uzuGLC;^c_X*IcZxf-PbB-60yo<d;&D@{^8MMS>FBa
zwkGA&Bu;C2KK?v4>B;i8Tmh|np36`mTb~!lInh$!uMh?W&Kf>Hb9iaCJn3Tin at N)`
zCUkJy3arj>#SSn<d)(fZe}zFkFJve%f(m$S1 at 0J9fjxgZkNu=s3fQCjGRz-K70cYw
zV|>&jw~|clK7 at p5k0<h!3Y=KK?xABVD7aPn5UatLRw4BR+_tNL!`;nvJQ6YY4H0nb
z(7}kELWD5j9zmahh?J*|Ya~O`Vz@^Nl}BoQcA7KJ22SDUB=c#D`CDLqVr6-GxzYR4
zTSjlknemej8?7EpchB6FFS+yLReA0c7Y4AhUQ86A)w at 5&>haOlMr<;G7k|#bFFnW}
zFaDgQ&KPAg-mKN&Z8<Z5Z1h at 7!yEem=h&X{>E-cnh$wq`#9jm~^;7&YRfM+YL9!X=
zUvJxGa at J?=<Ct5 at j1&1ykl%4;ggqzKGGgd2M*R9e;!N at qHkxR^C-R)xD%%n9NEm!N
zF6liB&mkpFr_yV=nNkw69XE-#6w>jdx3}d%{x}t*qOR08`=PWvz8bM!2<nWv(T+i3
z7U!9Z_J(*_mT_#-3rt0w|HFwUkK)J5kU_>CH08~gDNh~_nfu~$@nQos6S5B??emae
z%CWrr$4NKAFwsQ!cr)Ci+<<6YfF726a^Rl0bPr_OhLIk92P=LV@?lhp&g$7Y*ph7h
zoAENYZOJFl)UxC(8@`ZfLwYMQmEExN269-_o&#T)aZa at BX(PU)4_HFBA#P-Zdt2Us
zbH28Zr0*=YEbd5-&oEZ59XfC&L|evckv|NM1=3SjArPGrhS)e;U^*;@WeOY=7Nn>6
z4%uKCa+y%6j+Zi(;_|Uh+A=^%PsJg_snoo|0 at c(ZR_ikbCghYlVwLosYX%F5$)JWt
zQ!@p$%67++AwBwzTb~<^aWdSg4WHuv(D?+MuS7ESz?Hm-EacAo^nb&S?_f<kf=BMJ
zQ5n8MzsQWsIED#Rz-#W4iep_&C8m6f7 at t5)u7cFfjLC%jRodGcdjO7$CeGlm(C=tU
z5Ec4uro6wQqXXzDZ<*Jc^2b7+AE_iCMU%euMF>_;_;JR@)-`ZmSPPQTY1#(~+>^*3
z0&p(jX4?XPSZ9)Vdq&A=lCKRZEnP^c8soTiF4jB;{j$8lLWtsdlw89Yd~RAsH1R$)
zS5H0S56+fJgo|Ev!vhhJO?j_HVH86pE~oZs1!))0KBT-(yCr3)<dHstZ8`zAW2UWJ
zrUTZ1=<1CZmmpPITc0{wQ9U}ZX{bTeDn{g_2N?r7kYdkHeKgTWWAzP|<1zOg)Pqkp
zR+w^XT?u;6zO&$x;CL_nLA7N}QyUsxFhM#RYRWSzJn$N)PqxA@=Q<N^Lg#pHp&8?F
z(RTODBl?x+x=*_hI`&L3<@+3_usxD-UVjVXqKTu at x{K5e4E0`tX6X&yc*=wQZnp4N
zA>Hyl*_G2Q^l|Aq!?QOTEJ)h#u#5F9NuNovYtYg&wNu_F!9!SMGKc`BH2h|y&LgRf
zAEm(`Lb`nUr1>acWx1Jeuf=_R*6V(J*KX}u at 8{vYm*g!F*nGr)C6?Xk+~l8r506DP
zMnGw=0w$IAc5La*GRu4M65*GN5K!?p>Vr4(c(2E8t8_F&mT$tj^ZLi)q&IU*Z{$zW
zqq*`0Ix{zqI`Cb;C;8GoUQpaEYq)DPPJaE}W;X8)-;c^y2+8Mohw)jwf}30hU)+p0
z7h#rsub1N&6%-bV6_NV-P=oHT(pH2PXjT5(gO&d9EKO**miiiQ_t(^DB_(Au3QMMG
zQ?z+Sg9t?>g(MUXCd`yQh9aD!$F!0nB`Om3ZSX^hDXX;l27g7puL|#DZ>R_d at 9=9A
z1OCQIV#>{0eJHFCMH*EZ!fV-eRb&VU*9U8YdXOfK61bNM`*feE164qbSdX`-BX|K^
zRM+^z0kJ+5(i=jxq8_B+v`YEzcR_(x7t#Y5UaJb#`3p2r7Oe4WSLcVXCPAwXMKIJT
zQQFWDYS8dLcRgA2!&)`j>~_9CUYAK|5c!QZnQwe&QXycYFRWEI_<fw4QDURWFPye&
z6#f>=za`dRkzd8Rw5O^n6s(2sv>QXA8try}LpT_!gEq_%!luoxjlgrEdL6Xz*R|C!
z&);C<Yc(mLB3Neuc&A-k9q{|`%6bLhwL*+KOTZKjFR*Lt{TlqE(Fvgj)YTfq!aaE7
zeIsm}HA+mm(Gsa|s>keV8Yg27{l7-~e~sn;HJqO{n4dMA2q6Ot+yhsz+95~_hNYm%
zay+Fxb>0}PsTrzoU1d$A%C9MlpmNP7ej71mp(V1)AJ(axawD-|osXW<;E}2ZU#&I~
zfQrFVtB=3YU&%hKBa#;Z+u#p}2lp8;!h#0ba<%lu)fyvMSwkggWnp8rbq!$`oLx7B
z0?=DdgN$$5xxx|}4n-O&F$;sn=cKTY>L|aDU}%Q at l{)4&R6X?Anv!R^%^I~T82&aE
zG#8@}oi`yG8suCJA!CppDkK;RLueDKuEr-9Qkx-U(c%n!eENVFppXiEUyamfU>vwd
zOu313Td^@%r3W<5>7vqAYAMU6$#$rhOfH%+dHS@;Gm4R=mTLOOaIk_ao?SFwxH1 at 2
zz3P0mevAzTDnoTTzSam!O%_jEfY=D?T7!QB!WX8j-=qbmZj_(tSdlSMA^jkf!WutF
zVMrl2X<REZdbu7mR`A!I7Serx+v<ev%VmIDc6_!GH9^EB*1232G=%<Jrg6%UmpAyW
zd|l<QL>$*>Un!b4S({c^TrycJD3~-$yKdff3$<lTR?O?{yFm5zS5{WkhOkB_7R_1Y
ztF1-&q2rw8D<*5x=Uj&*gO7oxEWut?<J&}c)FQ<*K0|d?VWc4hnO|GDeBM&&Vai<$
z=huT(W=3>aw)lD^DGqSEuO?U}!(hd{8|O)XVsBYwWe2InENziYezJ!>|Fa-gV1mF}
zq|IWgu~N0nfim?^RErm>Xp$VjN;sSlNwND+%j~aj49Um|Pe!7l!c4kKg3=%D1KHRq
z+R|rwrab24^XbC`sM)#{|BZc>CRW$<zJmOYwWDDPspX^8XS~{W4D3PRwX(fM&17 at R
zlnDuW%gR6*nOd9T%)x3-)Vlc_cC`UFj&hDC6M}Z0VYJoI#>(*64(WGwefF3c`!IZf
z4eq=nIrWmM at NZR1!$M52LFj1j{TP!Q?)e6F at -ow$Z%8}!F_+1_fuYn<XqE;isYJ`v
zRU5=vtZu_7UJjncb@*CNZgq%qf-+Qa?(x-Kjhx8TiS&RR%1&kJgO{%c=c1}j*zb^n
zCTJlXbQ*$O&zq*!O}d8itNAINR_#L<wZ2tymd7?Q&&jXC*=zao>z5<RGZ67{ov*$C
z=Rui_sPX#Xh7JA(=58FIs*s;`e;DU5T!E^Fg7x^0 at 7pVQ9-V`IIlob>4)c>dy#OaG
zc}!K!l7F$xI|~B7%5R4wI6qkQ{HjT+b72V%g1F=na+ZcIWj=NWsKE1OIDJ0n<_QIT
z+(%(nIPFVxz2=>N#`nD6b$i}N`Q;8(?!M3M*|mKDZ at Aa(sjz6|xfOj_=b*d+zAGJl
z`@q}yJ-25x+V8sG?Ky>#^8>dhh`Pe62_FXh35sxKxrdGLjJjZS&e%&Y$34as*<Tw6
z#rT8s^LXEh4?j+!UWQu!GLG7H$8zD?>~UQ&+U?$ory}IXXM^H?@bUSBn0JvUmNoxE
z!fY==*#=q=b(*#yI_z%uJ-n?ExaaD3)`a=61wS7Pd>$xH#M~bIj3^rMq09%L_J_9N
z`(?`B8O3*ts1E_>M7)lIA9rLwd=4lt4zLXOqqK)FsnG^}N+|GopvZw-!o4kS55H~I
zQ1DqHzUdbH at iWwpcBmGjF1@Jl0uJ!+zFKhWXLlNYx7#xo<%=jYP|8qNqEw^Yj&e83
z_fdX=(uQ&j<pq>CP(DN%j&IP%qI?l$21*&qN|b7p+fnXD;aK#keTi!qESRND#3$C1
zwBmxIf@#>z3%^=8bJ|z5iOaFf7GcH7_9 at e+VT=C%;-3C@$^QT3rj-TZ0Ke|_trrFO
zT-V=FFAA`1{RQ*pFP at _NHdxq(x=6wLNDv>k2dhK at u>fy43#vBNg*VlzT5nJk>#i*W
zsQ|6PUqgNc)Ys at 75Z@*j=>A6htp);82q$fyDDVd=s&TL4uRyLEz(fJh at L>$6s#_~T
zgh*d)uoA<CAO?R5q--T;eHh%lpZ3 at 3cIbU(&9%c==US2fPXQ3F2m2z87u)bti{z94
zp8yCNaQouJG+q->Y`y^2XaIb9lA`|De9SR;4?Dzhxwf}~uMn`zC8){A@^uvINItIl
zL*P4!!W at 7~@-SzVp>W-kk2zu|5atH^A}_D&P_RbixLn(JVGz6!ksg=*SyrPk9}s3v
zXa^tlbB+sC+=?<1g?!8 at z2MUTJMG}&<ayiXV-CszLzl(Jd`DZ!w;6 at HavbKs6X0Xs
zvM=)S+K6KF^@6V#e7kHTK_ef_T at F6}Ul!XjImwA=v at ZIN*H#o;9&>IZjAb6TFMHhY
zqJez0cL(@(fUlYcSeMQBec(2q{Qo83<e}v4aqx{xxIN?M2(ii*hT4|*3yY6)%*Sc`
ze=+DU`?C4=p at HL)k00(fo`dg at gO4BRHi6HU0a6<70L;0dJmz%%e;Zv^8!E|1J)S|a
z$6bQGX9)uLY<a}_Bf8DUJ!%>F>d|Ij<Y761V)M0wuN{2$T#?t7{YStYpZf6!jBfBv
i25euN1-you^6ZOzV;l`OXpd?0ox%z2w2h#)`Th^~{+Sp6

literal 0
HcmV?d00001

diff --git a/cpu/arm926ejs/kirkwood/doimage/doimage.c b/cpu/arm926ejs/kirkwood/doimage/doimage.c
new file mode 100644
index 0000000..0c484b2
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/doimage/doimage.c
@@ -0,0 +1,1341 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Maen Suleiman <maen at marvell.com>
+ * Tawfik Bayouk <tawfik at marvell.com>
+ *
+ * Updated by
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+#define _HOST_COMPILER
+#include "bootstrap_def.h"
+
+#ifndef O_BINARY		/* should be define'd on __WIN32__ */
+#define O_BINARY        0
+#endif /*  */
+
+#define DOIMAGE_VERSION		"1.00"
+void print_usage(void);
+int f_in = -1;
+int f_out = -1;
+int f_header = -1;
+typedef enum { IMG_SATA, IMG_UART, IMG_FLASH, IMG_BOOTROM, IMG_NAND, IMG_HEX,
+	IMG_BIN, IMG_PEX, IMG_I2C
+} IMG_TYPE;
+typedef enum { HDR_IMG_ONE_FILE = 1,	/* Create one file with header and image */
+	HDR_IMG_TWO_FILES = 2,	/* Create seperate header and image files */
+	HDR_ONLY = 3,		/* Create only header */
+	IMG_ONLY = 4		/* Create only image */
+} HEADER_MODE;
+
+#define T_OPTION_MASK		0x1	/* image type */
+#define D_OPTION_MASK		0x2	/* image destination */
+#define E_OPTION_MASK		0x4	/* image execution address */
+#define S_OPTION_MASK		0x8	/* image source */
+#define R_OPTION_MASK		0x10	/* DRAM file */
+#define C_OPTION_MASK		0x20	/* NAND ECC mode */
+#define P_OPTION_MASK		0x40	/* NAND Page size */
+#define M_OPTION_MASK		0x80	/* TWSI serial init file */
+#define W_OPTION_MASK		0x100	/* HEX file width */
+#define H_OPTION_MASK		0x200	/* Header mode */
+#define X_OPTION_MASK		0x400	/* Pre padding */
+#define Y_OPTION_MASK		0x800	/* Post padding */
+#define I_OPTION_MASK		0x1000	/* SATA PIO mode */
+#define L_OPTION_MASK		0x2000	/* delay time in mseconds */
+
+#define SATA_MUST_OPT		(D_OPTION_MASK|T_OPTION_MASK|E_OPTION_MASK|S_OPTION_MASK)
+#define UART_MUST_OPT		(D_OPTION_MASK|T_OPTION_MASK|E_OPTION_MASK)
+#define FLASH_MUST_OPT		(D_OPTION_MASK|T_OPTION_MASK|E_OPTION_MASK)
+#define PEX_MUST_OPT		(D_OPTION_MASK|T_OPTION_MASK|E_OPTION_MASK)
+#define I2C_MUST_OPT		(D_OPTION_MASK|T_OPTION_MASK|E_OPTION_MASK|M_OPTION_MASK)
+#define MAX_TWSI_HDR_SIZE	(60*1024)	/* MAX eeprom is 64K & leave 4K for image and header */
+#define BOOTROM_MUST_OPT 	(T_OPTION_MASK)
+
+#define NAND_MUST_OPT		(D_OPTION_MASK|T_OPTION_MASK|E_OPTION_MASK|P_OPTION_MASK)
+#define HEX_MUST_OPT 		(T_OPTION_MASK|W_OPTION_MASK)
+#define BIN_MUST_OPT 		(T_OPTION_MASK|W_OPTION_MASK)
+
+/* 8 bit checksum */
+u8 checksum8(void *start, u32 len, u8 csum)
+{
+	register u8 sum = csum;
+	volatile u8 *startp = (volatile u8 *)start;
+
+	do {
+		sum += *startp;
+		startp++;
+	} while (--len);
+	return (sum);
+}
+
+/* 32 bit checksum */
+u32 checksum32(void *start, u32 len, u32 csum)
+{
+	register u32 sum = csum;
+	volatile u32 *startp = (volatile u32 *)start;
+	int currLen = len;
+
+	do {
+		sum += *(u32 *) startp;
+		startp++;
+		currLen -= 4;
+	} while (currLen > 0);
+	return (sum);
+}
+
+void make_crc_table(u32 * crc_table)
+{
+	u32 c;
+	int n, k;
+	u32 poly;
+
+	/* terms of polynomial defining this crc (except x^32): */
+	static const u8 p[] =
+	    { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
+
+	/* make exclusive-or pattern from polynomial (0xedb88320L) */
+	poly = 0L;
+	for (n = 0; n < sizeof(p) / sizeof(u8); n++)
+		poly |= 1L << (31 - p[n]);
+	for (n = 0; n < 256; n++) {
+		c = (u32) n;
+		for (k = 0; k < 8; k++)
+			c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+		crc_table[n] = c;
+	}
+}
+
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+u32 crc32(u32 crc, volatile u32 * buf, u32 len)
+{
+	u32 crc_table[256];
+
+	/* Create the CRC table */
+	make_crc_table(crc_table);
+	crc = crc ^ 0xffffffffL;
+	while (len >= 8) {
+		DO8(buf);
+		len -= 8;
+	}
+	if (len)
+		do {
+			DO1(buf);
+		} while (--len);
+	return crc ^ 0xffffffffL;
+}
+
+int main(int argc, char **argv)
+{
+	char *image_type = NULL;
+	IMG_TYPE img;
+	u32 image_dest = 0, image_exec = 0, header_size =
+	    0, image_source = 0, twsi_size = 0;
+	char *fname_in, *fname_out = NULL, *fname_hdr_out = NULL, *fname_romc =
+	    NULL, *fname_dram = NULL, *fname_twsi = NULL;
+	u8 *ptr;
+	BHR_t hdr;
+	ExtBHR_t extHdr;
+	struct stat fs_stat;
+	char *buf_in = NULL;
+	int override[2];
+	int err, size_written = 0;
+	char *tmpHeader = NULL;
+	char *tmpTwsi = NULL;
+	u32 opts = 0, required_opts = 0;
+	u32 chsum32 = 0;
+	u32 nandPageSize = 0, nandEccMode = 0, hex_width =
+	    0, header_mode = HDR_IMG_ONE_FILE, ms_delay = 0;
+	FILE *f_hex = NULL;
+	FILE *f_dram = NULL, *f_hex2 = NULL, *f_hex3 = NULL, *f_twsi = NULL;
+	u8 *hex8 = NULL, tmp8;
+	u16 *hex16 = NULL, tmp16;
+	u32 *hex32 = NULL, tmp32;
+	u32 lastDword = 0;
+	int i = 0;
+	u32 bytesToAlign = 0;
+	char **f_out_names[2];
+	int pre_padding = 0, post_padding = 0, padding_size = 0;
+
+#define IMG_FILE_INDX	0
+#define HDR_FILE_INDX	1
+	f_out_names[IMG_FILE_INDX] = &fname_out;
+	f_out_names[HDR_FILE_INDX] = &fname_hdr_out;
+	memset((void *)&hdr, 0, sizeof(BHR_t));
+	memset((void *)&extHdr, 0, sizeof(ExtBHR_t));
+	if (argc == 1) {
+		print_usage();
+		exit(1);
+	}
+	while (--argc > 0 && **++argv == '-') {
+		while (*++*argv) {
+			switch (**argv) {
+			case 'T':	/* image type */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				image_type = *++argv;
+				if (opts & T_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= T_OPTION_MASK;
+				break;
+			case 'D':	/* image destination  */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				image_dest =
+				    strtoul(*++argv, (char **)&ptr, 16);
+				if (*ptr) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & D_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= D_OPTION_MASK;
+				break;
+			case 'E':	/* image execution  */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				image_exec =
+				    strtoul(*++argv, (char **)&ptr, 16);
+				if (*ptr) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & E_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= E_OPTION_MASK;
+				break;
+			case 'X':	/* Pre - Padding */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				padding_size =
+				    strtoul(*++argv, (char **)&ptr, 16);
+				pre_padding = 1;
+				if (*ptr) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & X_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= X_OPTION_MASK;
+				break;
+			case 'Y':	/* Post - Padding */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				padding_size =
+				    strtoul(*++argv, (char **)&ptr, 16);
+				post_padding = 1;
+				if (*ptr) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & Y_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= Y_OPTION_MASK;
+				break;
+			case 'I':	/* PIO */
+				if (argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & I_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= I_OPTION_MASK;
+				break;
+			case 'S':	/* starting sector */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				image_source =
+				    strtoul(*++argv, (char **)&ptr, 16);
+				if (*ptr) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & S_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= S_OPTION_MASK;
+				break;
+			case 'P':	/* NAND Page Size */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				nandPageSize =
+				    strtoul(*++argv, (char **)&ptr, 10);
+				if (*ptr) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & P_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= P_OPTION_MASK;
+				break;
+			case 'C':	/* NAND ECC mode */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				nandEccMode =
+				    strtoul(*++argv, (char **)&ptr, 10);
+				if (*ptr) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & C_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= C_OPTION_MASK;
+				break;
+			case 'L':	/* Delay time */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				ms_delay = strtoul(*++argv, (char **)&ptr, 10);
+				if (*ptr) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & L_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= L_OPTION_MASK;
+				break;
+			case 'W':	/* HEX file width */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				hex_width = strtoul(*++argv, (char **)&ptr, 10);
+				if (*ptr) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & W_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= W_OPTION_MASK;
+				break;
+			case 'H':	/* Header file mode */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				header_mode =
+				    strtoul(*++argv, (char **)&ptr, 10);
+				if (*ptr) {
+					print_usage();
+					exit(1);
+				}
+				if (opts & H_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= H_OPTION_MASK;
+				break;
+			case 'R':	/* dram file */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				fname_dram = *++argv;
+				if (opts & R_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= R_OPTION_MASK;
+				break;
+			case 'M':	/* TWSI serial init file */
+				if (--argc <= 0) {
+					print_usage();
+					exit(1);
+				}
+				fname_twsi = *++argv;
+				if (opts & M_OPTION_MASK) {
+					print_usage();
+					exit(1);
+				}
+				opts |= M_OPTION_MASK;
+				break;
+			}
+		}
+	}
+
+	/* 2 sperate images is used with SATA only */
+	if (header_mode == HDR_IMG_TWO_FILES) {
+		if (!(opts & S_OPTION_MASK)) {
+			fprintf(stderr,
+				"Error: -S option is missing\n\n\n\n\n");
+			print_usage();
+			exit(1);
+		}
+	}
+
+	/* verify HEX file width selection to be valid */
+	if (opts & W_OPTION_MASK) {
+		if ((hex_width != 8) && (hex_width != 16) && (hex_width != 32)
+		    && (hex_width != 64)) {
+			print_usage();
+			exit(1);
+		}
+	}
+
+	/* get the minimum option set based on boot mode */
+	if (opts & T_OPTION_MASK) {
+		if (strcmp(image_type, "sata") == 0) {
+			img = IMG_SATA;
+			required_opts = SATA_MUST_OPT;
+		}
+
+		else if (strcmp(image_type, "nand") == 0) {
+			img = IMG_NAND;
+			required_opts = NAND_MUST_OPT;
+		}
+
+		else if (strcmp(image_type, "hex") == 0) {
+			img = IMG_HEX;
+			required_opts = HEX_MUST_OPT;
+		}
+
+		else if (strcmp(image_type, "bin") == 0) {
+			img = IMG_BIN;
+			required_opts = BIN_MUST_OPT;
+		}
+
+		else if (strcmp(image_type, "uart") == 0) {
+			img = IMG_UART;
+			required_opts = UART_MUST_OPT;
+		}
+
+		else if (strcmp(image_type, "flash") == 0) {
+			img = IMG_FLASH;
+			required_opts = FLASH_MUST_OPT;
+		}
+
+		else if (strcmp(image_type, "bootrom") == 0) {
+			img = IMG_BOOTROM;
+			required_opts = BOOTROM_MUST_OPT;
+		}
+
+		else if (strcmp(image_type, "pex") == 0) {
+			img = IMG_PEX;
+			required_opts = PEX_MUST_OPT;
+		}
+
+		else if (strcmp(image_type, "i2c") == 0) {
+			img = IMG_I2C;
+			required_opts = I2C_MUST_OPT;
+		}
+
+		else {
+			print_usage();
+			exit(1);
+		}
+	}
+
+	else {
+		print_usage();
+		exit(1);
+	}
+	if (header_mode == IMG_ONLY) {
+		required_opts &=
+		    ~(D_OPTION_MASK | E_OPTION_MASK | S_OPTION_MASK |
+		      R_OPTION_MASK | P_OPTION_MASK);
+	}
+	if (required_opts != (opts & required_opts)) {
+		print_usage();
+		exit(1);
+	}
+	hdr.ddrInitDelay = ms_delay;
+	hdr.destinationAddr = image_dest;
+	hdr.executionAddr = image_exec;
+	switch (img) {
+	case IMG_BOOTROM:
+		header_mode = IMG_ONLY;
+		break;
+	case IMG_HEX:
+		header_mode = IMG_ONLY;
+		break;
+	case IMG_BIN:
+		header_mode = IMG_ONLY;
+		break;
+	case IMG_SATA:
+		hdr.blockID = IBR_HDR_SATA_ID;
+		header_size = 512;
+		if (image_source)
+			hdr.sourceAddr = image_source;
+
+		else
+			hdr.sourceAddr = 2;	/* default */
+		if (!(opts & H_OPTION_MASK)) {
+			header_mode = HDR_IMG_TWO_FILES /*HDR_ONLY */ ;
+		}
+		if (opts & I_OPTION_MASK) {
+			hdr.sataPioMode = 1;
+		}
+		break;
+	case IMG_UART:
+		hdr.blockID = IBR_HDR_UART_ID;
+		if (opts & R_OPTION_MASK) {
+			header_size = 512;
+		} else
+			header_size = 128;
+		hdr.sourceAddr = header_size;
+		break;
+	case IMG_FLASH:
+		hdr.blockID = IBR_HDR_SPI_ID;
+		if (opts & R_OPTION_MASK) {
+			header_size = 512;
+		} else
+			header_size = sizeof(BHR_t);
+		if ((image_source) && (image_source >= header_size)) {
+			hdr.sourceAddr = image_source;
+		} else {
+			hdr.sourceAddr = header_size;	/* default */
+		}
+		break;
+	case IMG_NAND:
+		hdr.blockID = IBR_HDR_NAND_ID;
+		if (opts & R_OPTION_MASK) {
+			header_size = 512;
+		} else
+			header_size = sizeof(BHR_t);
+		if ((image_source) && (image_source >= header_size)) {
+			hdr.sourceAddr = image_source;
+		} else {
+			hdr.sourceAddr = header_size;	/* default */
+		}
+		hdr.nandPageSize = (u16) nandPageSize;
+		hdr.nandEccMode = (u8) nandEccMode;
+		break;
+	case IMG_PEX:
+		hdr.blockID = IBR_HDR_PEX_ID;
+		if (opts & R_OPTION_MASK) {
+			header_size = 512;
+		} else
+			header_size = sizeof(BHR_t);
+		if ((image_source) && (image_source >= header_size)) {
+			hdr.sourceAddr = image_source;
+		} else {
+			hdr.sourceAddr = header_size;	/* default */
+		}
+	case IMG_I2C:
+		hdr.blockID = IBR_HDR_I2C_ID;
+		if (opts & R_OPTION_MASK) {
+			header_size = 512;
+		} else
+			header_size = sizeof(BHR_t);
+		if ((image_source) && (image_source >= header_size)) {
+			hdr.sourceAddr = image_source;
+		} else {
+			hdr.sourceAddr = header_size;	/* default */
+		}
+	}
+	if ((header_mode == HDR_IMG_TWO_FILES)
+	    || ((header_mode == IMG_ONLY) && (img == IMG_BIN))) {
+		if (argc == 4) {	/* In case ROMC is needed */
+			fname_in = *argv++;
+			fname_out = *argv++;
+			fname_hdr_out = *argv++;
+			fname_romc = *argv++;
+			if ((0 == strcmp(fname_in, fname_out)) ||
+			    (0 == strcmp(fname_in, fname_hdr_out)) ||
+			    (0 == strcmp(fname_in, fname_romc)) ||
+			    (0 == strcmp(fname_out, fname_hdr_out)) ||
+			    (0 == strcmp(fname_out, fname_romc)) ||
+			    (0 == strcmp(fname_hdr_out, fname_romc))) {
+				fprintf(stderr,
+					"Error: Input and output images can't be the same\n");
+				exit(1);
+			}
+		}
+
+		else if (argc == 3) {
+			fname_in = *argv++;
+			fname_out = *argv++;
+			fname_hdr_out = *argv++;
+			if ((0 == strcmp(fname_in, fname_out)) ||
+			    (0 == strcmp(fname_in, fname_hdr_out)) ||
+			    (0 == strcmp(fname_out, fname_hdr_out))) {
+				fprintf(stderr,
+					"Error: Input and output images can't be the same\n");
+				exit(1);
+			}
+		}
+
+		else {
+			print_usage();
+			exit(1);
+		}
+	}
+
+	else {
+		if (argc == 2) {
+			fname_in = *argv++;
+			fname_out = *argv++;
+			if (0 == strcmp(fname_in, fname_out)) {
+				fprintf(stderr,
+					"Error: Input and output images can't be the same\n");
+				exit(1);
+			}
+		}
+
+		else {
+			print_usage();
+			exit(1);
+		}
+	}
+
+	/* check if the output image exist */
+	i = 0;
+
+	do {
+		if (*f_out_names[i]) {
+			f_out = open(*f_out_names[i], O_RDONLY | O_BINARY);
+			if (f_out != -1) {
+				char c;
+				close(f_out);
+				f_out = -1;
+				fprintf(stderr,
+					"File '%s' already exist! override (y/n)?",
+					*f_out_names[i]);
+				c = getc(stdin);
+				if ((c == 'N') || (c == 'n')) {
+					printf("exit.. nothing done. \n");
+					exit(0);
+				}
+
+				/* for the Enter */
+				c = getc(stdin);
+				override[i] = 1;
+			}
+
+			else {
+				override[i] = 0;
+			}
+		}
+		i++;
+		if (i == 2)
+			break;
+	} while (1);
+	if (header_mode != HDR_ONLY) {
+
+		/* open input image */
+		f_in = open(fname_in, O_RDONLY | O_BINARY);
+		if (f_in == -1) {
+			fprintf(stderr, "File '%s' not found \n", fname_in);
+			exit(0);
+		}
+
+		/* get the size of the input image */
+		err = fstat(f_in, &fs_stat);
+		if (0 != err) {
+			close(f_in);
+			fprintf(stderr, "fstat failed for file: '%s' err=%d\n",
+				fname_in, err);
+			exit(1);
+		}
+		if ((fs_stat.st_size > BOOTROM_SIZE) && (img == IMG_BOOTROM)) {
+			printf
+			    ("ERROR : bootstrap.bin size is bigger than %d bytes \n",
+			     BOOTROM_SIZE);
+			close(f_in);
+			exit(1);
+		}
+
+		/* map the input image */
+		buf_in =
+		    mmap(0, fs_stat.st_size, PROT_READ, MAP_SHARED, f_in, 0);
+		if (!buf_in) {
+			fprintf(stderr, "Error mapping %s file \n", fname_in);
+			goto end;
+		}
+	}
+
+	/* open the output image */
+	if (override[IMG_FILE_INDX] == 0) {
+		f_out =
+		    open(fname_out, O_RDWR | O_TRUNC | O_CREAT | O_BINARY,
+			 0666);
+	}
+
+	else
+		f_out = open(fname_out, O_RDWR | O_BINARY);
+	if (f_out == -1) {
+		fprintf(stderr, "Error openning %s file \n", fname_out);
+	}
+	if (header_mode == HDR_IMG_TWO_FILES) {
+
+		/* open the output header file */
+		if (override[HDR_FILE_INDX] == 0) {
+			f_header =
+			    open(fname_hdr_out,
+				 O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0666);
+		}
+
+		else
+			f_header = open(fname_hdr_out, O_RDWR | O_BINARY);
+		if (f_header == -1) {
+			fprintf(stderr, "Error openning %s file \n",
+				fname_hdr_out);
+		}
+	}
+
+	/* Image Header  */
+	if (header_mode != IMG_ONLY) {
+		hdr.blockSize = fs_stat.st_size;
+		if (opts & R_OPTION_MASK) {
+			hdr.ext = 1;
+		}
+
+		/* for FLASH\NAND , we have extra word for checksum */
+		if ((img == IMG_FLASH) || (img == IMG_NAND)
+		    || (img == IMG_SATA) || (img == IMG_PEX)
+		    || (img == IMG_I2C)) {
+
+			/*hdr.blockSize++; */
+			hdr.blockSize += 4;
+		}
+
+		/* in sata headers, blocksize is in sectors (512 byte) */
+		if (img == IMG_SATA) {
+
+			/*hdr.blockSize = (hdr.blockSize + 511) >> 9; */
+		}
+
+		/* Update Block size address */
+		if (padding_size) {
+
+			/* Align padding to 32 bit */
+			if (padding_size & 0x3) {
+				padding_size += (4 - (padding_size & 0x3));
+			}
+			hdr.blockSize += padding_size;
+		}
+
+		/* Align size to 4 byte */
+		if (hdr.blockSize & 0x3) {
+			printf("hdr.blockSize = 0x%x fs_stat.st_size = 0x%x\n",
+			       (u32)hdr.blockSize, (u32)fs_stat.st_size);
+			bytesToAlign = (4 - (hdr.blockSize & 0x3));
+			hdr.blockSize += bytesToAlign;
+		}
+		tmpTwsi = malloc(MAX_TWSI_HDR_SIZE);
+		memset(tmpTwsi, 0xFF, MAX_TWSI_HDR_SIZE);
+		if (opts & M_OPTION_MASK) {
+			if (fname_twsi) {
+				int i;
+				u32 *twsi_reg = (u32 *) tmpTwsi;;
+				f_twsi = fopen(fname_twsi, "r");
+				if (f_twsi == NULL) {
+					fprintf(stderr,
+						"File '%s' not found \n",
+						fname_twsi);
+					exit(1);
+				}
+				for (i = 0; i < (MAX_TWSI_HDR_SIZE / 4); i++) {
+					if (EOF ==
+					    fscanf(f_twsi, "%x\n", twsi_reg))
+						break;
+
+					/* Swap Enianess */
+					*twsi_reg =
+					    (((*twsi_reg >> 24) & 0xFF) |
+					     ((*twsi_reg >> 8) & 0xFF00) |
+					     ((*twsi_reg << 8) & 0xFF0000) |
+					     ((*twsi_reg << 24) & 0xFF000000));
+					twsi_reg++;
+				}
+				fclose(f_twsi);
+				twsi_size = ((((i + 2) * 4) & ~0x1FF) + 0x200);	/*size=512,1024,.. with at least 8 0xFF bytes */
+				if ((write(f_out, tmpTwsi, twsi_size)) !=
+				    twsi_size) {
+					fprintf(stderr,
+						"Error writing %s file \n",
+						fname_out);
+					goto end;
+				}
+			}
+		}
+		tmpHeader = malloc(header_size);
+		memset(tmpHeader, 0, header_size);
+		hdr.checkSum = checksum8((void *)&hdr, sizeof(BHR_t), 0);
+		memcpy(tmpHeader, &hdr, sizeof(BHR_t));
+
+		/* Header extension */
+		if (opts & R_OPTION_MASK) {
+			int dram_buf_size = 0;
+
+			/* First we will take of DRAM */
+			if (fname_dram) {
+				int i;
+
+				/*u32 dram_reg[DRAM_REGS_NUM]; */
+				u32 dram_reg[(512 >> 2)];
+				f_dram = fopen(fname_dram, "r");
+				if (f_dram == NULL) {
+					fprintf(stderr,
+						"File '%s' not found \n",
+						fname_dram);
+					exit(1);
+				}
+
+				/*for (i=0; i< DRAM_REGS_NUM ; i++) */
+				i = 0;
+				while (EOF !=
+				       fscanf(f_dram, "%x\n", &dram_reg[i++])) ;
+				fclose(f_dram);
+
+				/*dram_buf_size = DRAM_REGS_NUM * 4; */
+				dram_buf_size = (i - 1) * 4;
+				memcpy(tmpHeader + sizeof(BHR_t) +
+				       sizeof(ExtBHR_t), dram_reg,
+				       dram_buf_size);
+				extHdr.dramRegsOffs =
+				    sizeof(BHR_t) + sizeof(ExtBHR_t);
+			}
+			memcpy(tmpHeader + sizeof(BHR_t), &extHdr,
+			       sizeof(ExtBHR_t));
+			*(u8 *) (tmpHeader + header_size - 1) =
+			    checksum8((void *) (tmpHeader + sizeof(BHR_t)),
+				      header_size - sizeof(BHR_t), (u8)0);
+		}
+		if (header_mode == HDR_IMG_TWO_FILES) {
+
+			/* copy header to output image */
+			size_written = write(f_header, tmpHeader, header_size);
+			if (size_written != header_size) {
+				fprintf(stderr, "Error writing %s file \n",
+					fname_hdr_out);
+				goto end;
+			}
+			fprintf(stdout, "%s was created \n",
+				*f_out_names[HDR_FILE_INDX]);
+		}
+
+		else {
+
+			/* copy header to output image */
+			size_written = write(f_out, tmpHeader, header_size);
+			if (size_written != header_size) {
+				fprintf(stderr, "Error writing %s file \n",
+					fname_out);
+				goto end;
+			}
+		}
+	}
+	if (header_mode != HDR_ONLY) {
+		char *padding = NULL;
+		int new_file_size = 0;
+		if (img == IMG_BOOTROM) {
+			char *tmp1;
+			int tmpSize = BOOTROM_SIZE - sizeof(chsum32);
+
+			/* PAD image with Zeros until BOOTROM_SIZE */
+			tmp1 = malloc(tmpSize);
+			if (tmp1 == NULL)
+				goto end;
+			memcpy(tmp1, buf_in, fs_stat.st_size);
+			memset(tmp1 + fs_stat.st_size, 0,
+			       tmpSize - fs_stat.st_size);
+			fs_stat.st_size = tmpSize;
+
+			/* copy input image to output image */
+			size_written = write(f_out, tmp1, fs_stat.st_size);
+
+			/* calculate checsum */
+			chsum32 = crc32(0, (u32 *) tmp1, (fs_stat.st_size / 4));
+			printf("Image Chacksum (size = %d) = 0x%08x\n",
+			       (int)fs_stat.st_size, chsum32);
+			fs_stat.st_size += sizeof(chsum32);
+			size_written += write(f_out, &chsum32, sizeof(chsum32));
+			if (tmp1)
+				free(tmp1);
+			new_file_size = fs_stat.st_size;
+		}
+
+		else if (img == IMG_HEX) {
+			char *tmp1 = NULL;
+			int hex_unaligned_len = 0;
+			int hex_len = fs_stat.st_size;
+			f_hex = fopen(fname_out, "w");
+			if (f_hex == NULL)
+				goto end;
+			switch (hex_width) {
+			case 8:
+				hex8 = (u8 *) buf_in;
+
+				do {
+					fprintf(f_hex, "%02X\n", *hex8);
+					hex8++;
+					size_written += 1;
+					hex_len--;
+				} while (hex_len);
+				break;
+			case 16:
+				hex16 = (u16 *) buf_in;
+				hex_unaligned_len = (fs_stat.st_size & 0x1);
+				if (hex_unaligned_len) {
+					hex_len -= hex_unaligned_len;
+					hex_len += 2;
+					tmp1 = malloc(hex_len);
+					hex16 = (u16 *) tmp1;
+					memset(tmp1, 0, (hex_len));
+					memcpy(tmp1, buf_in, fs_stat.st_size);
+				}
+
+				do {
+					fprintf(f_hex, "%04X\n", *hex16++);
+					size_written += 2;
+					hex_len -= 2;
+				} while (hex_len);
+				break;
+			case 32:
+				hex32 = (u32 *)buf_in;
+				hex_unaligned_len = (fs_stat.st_size & 0x3);
+				if (hex_unaligned_len) {
+					hex_len -= hex_unaligned_len;
+					hex_len += 4;
+					tmp1 = malloc(hex_len);
+					hex16 = (u16 *) tmp1;
+					memset(tmp1, 0, (hex_len));
+					memcpy(tmp1, buf_in, fs_stat.st_size);
+				}
+
+				do {
+					fprintf(f_hex, "%08X\n", (u32)*hex32++);
+					size_written += 4;
+					hex_len -= 4;
+				} while (hex_len);
+				break;
+			case 64:
+				hex32 = (u32 *)buf_in;
+				hex_unaligned_len = (fs_stat.st_size & 0x7);
+				if (hex_unaligned_len) {
+					hex_len -= hex_unaligned_len;
+					hex_len += 8;
+					tmp1 = malloc(hex_len);
+					hex16 = (u16 *) tmp1;
+					memset(tmp1, 0, (hex_len));
+					memcpy(tmp1, buf_in, fs_stat.st_size);
+				}
+
+				do {
+					fprintf(f_hex, "%08X", (u32)*hex32++);
+					fprintf(f_hex, "%08X\n", (u32)*hex32++);
+					size_written += 8;
+					hex_len -= 8;
+				} while (hex_len);
+				break;
+			}
+			size_written = fs_stat.st_size;
+			if (tmp1)
+				free(tmp1);
+			fclose(f_hex);
+			new_file_size = fs_stat.st_size;
+		}
+
+		else if (img == IMG_BIN) {
+			char *tmp1 = NULL;
+			int one_file_len;
+			int hex_len = fs_stat.st_size;
+			f_hex = fopen(fname_out, "w");
+			if (f_hex == NULL)
+				goto end;
+			f_hex2 = fopen(fname_hdr_out, "w");
+			if (f_hex2 == NULL)
+				goto end;
+			if (fname_romc) {
+				f_hex3 = fopen(fname_romc, "w");
+				if (f_hex3 == NULL)
+					goto end;
+				one_file_len = (hex_len / 3);
+			}
+
+			else {
+				one_file_len = hex_len * 0.5;
+			}
+			switch (hex_width) {
+				int hex_unaligned_len = 0;
+			case 8:
+				hex8 = (u8 *) buf_in;
+
+				do {
+					tmp8 = *hex8;
+					if (hex_len > one_file_len) {
+						for (i = 0; i < hex_width; i++) {
+							fprintf(f_hex, "%d",
+								((tmp8 & 0x80)
+								 >> 7));
+							tmp8 <<= 1;
+						}
+						fprintf(f_hex, "\n");
+					}
+
+					else {
+						for (i = 0; i < hex_width; i++) {
+							fprintf(f_hex2, "%d",
+								((tmp8 & 0x80)
+								 >> 7));
+							tmp8 <<= 1;
+						}
+						fprintf(f_hex2, "\n");
+					}
+					hex8++;
+					size_written += 1;
+					hex_len--;
+				} while (hex_len);
+				break;
+			case 16:
+				hex16 = (u16 *) buf_in;
+				hex_unaligned_len = (fs_stat.st_size & 0x1);
+				if (hex_unaligned_len) {
+					hex_len -= hex_unaligned_len;
+					hex_len += 2;
+					tmp1 = malloc(hex_len);
+					hex16 = (u16 *) tmp1;
+					memset(tmp1, 0, (hex_len));
+					memcpy(tmp1, buf_in, fs_stat.st_size);
+				}
+
+				do {
+					tmp16 = *hex16;
+					for (i = 0; i < hex_width; i++) {
+						fprintf(f_hex, "%d",
+							((tmp16 & 0x8000) >>
+							 15));
+						tmp16 <<= 1;
+					}
+					fprintf(f_hex, "\n");
+					hex16++;
+					size_written += 2;
+					hex_len -= 2;
+				} while (hex_len);
+				break;
+			case 32:
+				hex32 = (u32 *)buf_in;
+				hex_unaligned_len = (fs_stat.st_size & 0x3);
+				if (hex_unaligned_len) {
+					hex_len -= hex_unaligned_len;
+					hex_len += 4;
+					tmp1 = malloc(hex_len);
+					hex16 = (u16 *) tmp1;
+					memset(tmp1, 0, (hex_len));
+					memcpy(tmp1, buf_in, fs_stat.st_size);
+				}
+
+				do {
+					tmp32 = *hex32;
+					if (fname_romc) {
+						if (hex_len >
+						    (2 * one_file_len)) {
+							for (i = 0;
+							     i < hex_width;
+							     i++) {
+								fprintf(f_hex,
+									"%d", (int)
+									((tmp32
+									  &
+									  0x80000000)
+									 >>
+									 31));
+								tmp32 <<= 1;
+							}
+							fprintf(f_hex, "\n");
+						}
+
+						else if (hex_len > one_file_len) {
+							for (i = 0;
+							     i < hex_width;
+							     i++) {
+								fprintf(f_hex2,
+									"%d", (int)
+									((tmp32
+									  &
+									  0x80000000)
+									 >>
+									 31));
+								tmp32 <<= 1;
+							}
+							fprintf(f_hex2, "\n");
+						}
+
+						else {
+							for (i = 0;
+							     i < hex_width;
+							     i++) {
+								fprintf(f_hex3,
+									"%d", (int)
+									((tmp32
+									  &
+									  0x80000000)
+									 >>
+									 31));
+								tmp32 <<= 1;
+							}
+							fprintf(f_hex3, "\n");
+						}
+					}
+
+					else {
+						if (hex_len > one_file_len) {
+							for (i = 0;
+							     i < hex_width;
+							     i++) {
+								fprintf(f_hex,
+									"%d", (int)
+									((tmp32
+									  &
+									  0x80000000)
+									 >>
+									 31));
+								tmp32 <<= 1;
+							}
+							fprintf(f_hex, "\n");
+						}
+
+						else {
+							for (i = 0;
+							     i < hex_width;
+							     i++) {
+								fprintf(f_hex2,
+									"%d", (int)
+									((tmp32
+									  &
+									  0x80000000)
+									 >>
+									 31));
+								tmp32 <<= 1;
+							}
+							fprintf(f_hex2, "\n");
+						}
+					}
+					hex32++;
+					size_written += 4;
+					hex_len -= 4;
+				} while (hex_len);
+				break;
+			case 64:
+				fprintf(stderr,
+					"Error: 64 Bit is not supported for binary files\n\n\n\n\n");
+				break;
+			}
+			size_written = fs_stat.st_size;
+			if (tmp1)
+				free(tmp1);
+			fclose(f_hex);
+			fclose(f_hex2);
+			new_file_size = fs_stat.st_size;
+		}
+
+		else {
+			size_written = 0;
+			if ((pre_padding) && (padding_size)) {
+				padding = malloc(padding_size);
+				if (padding) {
+					new_file_size += padding_size;
+					memset((void *)padding, 0x5,
+					       padding_size);
+					size_written +=
+					    write(f_out, padding, padding_size);
+					chsum32 =
+					    checksum32( /*(u32) */ (void *)
+						       padding, padding_size,
+						       chsum32);
+				}
+			}
+			new_file_size += fs_stat.st_size;
+
+			/* Calculate checksum */
+			chsum32 = checksum32( /*(u32) */ (void *)buf_in,
+					     (u32) ((u32) fs_stat.st_size -
+						    bytesToAlign), chsum32);
+			if (bytesToAlign) {
+				memcpy(&lastDword,
+				       (buf_in +
+					(fs_stat.st_size - bytesToAlign)),
+				       bytesToAlign);
+			}
+			chsum32 = checksum32( /*(u32) */ (void *)&lastDword, 4,
+					     chsum32);
+
+			/* copy input image to output image */
+			size_written += write(f_out, buf_in, fs_stat.st_size);
+			if (bytesToAlign) {
+				size_written +=
+				    write(f_out, &lastDword, bytesToAlign);
+			}
+			if ((post_padding) && (padding_size)) {
+				padding = malloc(padding_size);
+				if (padding) {
+					new_file_size += padding_size;
+					memset((void *)padding, 0xa,
+					       padding_size);
+					size_written +=
+					    write(f_out, padding, padding_size);
+					chsum32 =
+					    checksum32( /*(u32) */ (void *)
+						       padding, padding_size,
+						       chsum32);
+				}
+			}
+
+			/* write checksum */
+			size_written += write(f_out, &chsum32, sizeof(chsum32));
+			new_file_size += 4;
+		}
+		if (size_written != new_file_size) {
+			fprintf(stderr, "Error writing %s file \n", fname_out);
+			goto end;
+		}
+		fprintf(stdout, "%s was created \n",
+			*f_out_names[IMG_FILE_INDX]);
+	}
+      end:if (tmpHeader)
+		free(tmpHeader);
+
+	/* close handles */
+	if (f_out != -1)
+		close(f_out);
+	if (f_header != -1)
+		close(f_header);
+	if (buf_in)
+		munmap((void *)buf_in, fs_stat.st_size);
+	if (f_in != -1)
+		close(f_in);
+	return 0;
+}
+void print_usage(void)
+{
+	printf("\n");
+	printf("Marvell doimage Tool version %s\n", DOIMAGE_VERSION);
+	printf("Supported SoC devices: \n");
+	printf("    Marvell 88F6082 - A1\n");
+	printf("    Marvell 88F6180 - A0\n");
+	printf("    Marvell 88F6192 - A0\n");
+	printf("    Marvell 88F6190 - A0\n");
+	printf("    Marvell 88F6281 - A0\n");
+	printf("\n");
+	printf("usage: \n");
+	printf
+	    ("doimage <must_options> [other_options] image_in image_out [header_out]\n");
+	printf("\n<must_options> - can be one or more of the following:\n\n");
+	printf("-T image_type:   sata\\uart\\flash\\bootrom\\nand\\hex\\pex\n");
+	printf("                 if image_type is sata, the image_out will\n");
+	printf("                 include header only.\n");
+	printf("-D image_dest:   image destination in dram (in hex)\n");
+	printf("-E image_exec:   execution address in dram (in hex)\n");
+	printf
+	    ("                 if image_type is 'flash' and image_dest is 0xffffffff\n");
+	printf("                 then execution address on the flash\n");
+	printf
+	    ("-S image_source: if image_type is sata then the starting sector of\n");
+	printf
+	    ("                 the source image on the disk - mandatory for sata\n");
+	printf
+	    ("                 if image_type is flash\\nand then the starting offset of\n");
+	printf
+	    ("                 the source image at the flash - optional for flash\\nand\n");
+	printf("-W hex_width :   HEX file width, can be 8,16,32,64 \n");
+	printf
+	    ("-M twsi_file:    ascii file name that contains the I2C init regs set by h/w.\n");
+	printf("                 this is used in i2c boot only\n");
+	printf
+	    ("\n<other_options> - optional and can be one or more of the following:\n\n");
+	printf
+	    ("-R dram_file: ascii file name that contains the list of dram regs\n");
+	printf("-P nand_page_size (decimal 512, 2048, ..): NAND Page size\n");
+	printf("-C nand_ecc_mode (1=Hamming, 2=RS, 3=None)\n");
+	printf("-L delay in mili seconds before DRAM init\n");
+	printf("-I copy image in PIO mode (valid for SATA only)\n");
+	printf("-X pre_padding_size (hex)\n");
+	printf("-Y post_padding_size (hex)\n");
+	printf("-H header_mode: Header mode, can be:\n");
+	printf
+	    ("   -H 1 :will create one file (image_out) for header and image\n");
+	printf
+	    ("   -H 2 :will create two files, (image_out) for image , (header_out) for header\n");
+	printf("   -H 3 :will create one file (image_out) for header only \n");
+	printf("   -H 4 :will create one file (image_out) for image only \n");
+	printf("\ncommand possibilities: \n\n");
+	printf("doimage -T hex -W width image_in image_out\n");
+	printf("doimage -T bootrom image_in image_out\n");
+	printf("doimage -T sata -S sector -D image_dest -E image_exec\n");
+	printf("         [other_options] image_in image_out header_out\n\n");
+	printf("doimage -T flash -D image_dest -E image_exec [-S address]\n");
+	printf("         [other_options] image_in image_out\n\n");
+	printf("doimage -T pex -D image_dest -E image_exec \n");
+	printf("         [other_options] image_in image_out\n\n");
+	printf
+	    ("doimage -T nand -D image_dest -E image_exec [-S address] -P page_size\n");
+	printf("         [other_options] image_in image_out\n\n");
+	printf("doimage -T uart -D image_dest -E image_exec\n");
+	printf("         [other_options] image_in image_out\n\n");
+	printf("doimage -T pex -D image_dest -E image_exec \n");
+	printf("         [other_options] image_in image_out\n\n");
+	printf
+	    ("doimage -T i2c -D image_dest -E image_exec -M twsi_init_file\n");
+	printf("         [other_options] image_in image_out\n\n");
+	printf("\n\n\n");
+}
diff --git a/cpu/arm926ejs/kirkwood/dram.c b/cpu/arm926ejs/kirkwood/dram.c
new file mode 100644
index 0000000..41f1316
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/dram.c
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+u32 kw_get_dram_bank_base_addr(MEMORY_BANK bank)
+{
+	u32 result = 0;
+	u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
+
+	if ((!enable) || (bank > BANK3))
+		return 0;
+
+	result = KW_REG_READ((0x1500 + bank * 8));
+	return result;
+}
+
+u32 kw_get_dram_bank_size(MEMORY_BANK bank)
+{
+	u32 result = 0;
+	u32 enable = (0x01 & KW_REG_READ((0x1504 + bank * 8)));
+
+	if ((!enable) || (bank > BANK3))
+		return 0;
+	result = (0xff000000 & KW_REG_READ((0x1504 + bank * 8)));
+	result += 0x01000000;
+	return result;
+}
diff --git a/cpu/arm926ejs/kirkwood/kw88f6192.h b/cpu/arm926ejs/kirkwood/kw88f6192.h
new file mode 100644
index 0000000..566c471
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/kw88f6192.h
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * Header file for Feroceon CPU core 88FR131 Based KW88F6192 SOC.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _CONFIG_KW88F6192_H
+#define _CONFIG_KW88F6192_H
+
+/* SOC specific definations */
+#define KW88F6192_REGS_PHYS_BASE	0xf1000000
+#define KW_REGS_PHY_BASE		KW88F6192_REGS_PHYS_BASE
+
+#endif /* _CONFIG_KW88F6192_H */
diff --git a/cpu/arm926ejs/kirkwood/kw88f6281.h b/cpu/arm926ejs/kirkwood/kw88f6281.h
new file mode 100644
index 0000000..3c0795a
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/kw88f6281.h
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * Header file for Feroceon CPU core 88FR131 Based KW88F6281 SOC.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _CONFIG_KW88F6281_H
+#define _CONFIG_KW88F6281_H
+
+/* SOC specific definations */
+#define KW88F6281_REGS_PHYS_BASE	0xf1000000
+#define KW_REGS_PHY_BASE		KW88F6281_REGS_PHYS_BASE
+
+#endif /* _CONFIG_KW88F6281_H */
diff --git a/cpu/arm926ejs/kirkwood/kwcore.c b/cpu/arm926ejs/kirkwood/kwcore.c
new file mode 100644
index 0000000..5085782
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/kwcore.c
@@ -0,0 +1,262 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+#ifndef KWCORE_DEBUG
+#define KWCORE_DEBUG		0
+#endif
+#define DEBUG_PRINT		KWCORE_DEBUG
+
+#include <common.h>
+#include <debug_prints.h>
+#include <u-boot/md5.h>
+
+void reset_cpu(unsigned long ignored)
+{
+	debug_print_ftrace();
+	KW_REG_BITS_SET(KW_REG_CPU_RSTOUTN_MASK, BIT2);
+	KW_REG_BITS_SET(KW_REG_CPU_SYS_SOFT_RST, BIT0);
+	while (1) ;
+}
+
+/*
+ * Generates Ramdom hex number reading some time varient system registers
+ * and using md5 algorithm
+ */
+unsigned char get_random_hex(void)
+{
+	int i;
+	u32 inbuf[16];
+	u8 outbuf[16];
+
+	debug_print_ftrace();
+#if defined (CONFIG_KW88F6281_Z0)
+	KW_REG_BITS_SET(0x1478, BIT7);
+#elif defined (CONFIG_KW88F6281_A0) || defined (CONFIG_KW88F6192_A0)
+	/*
+	 * in case of 88F6281/88F6192 A0,
+	 * BIT7 need to reset to generate random values in 0x1470
+	 */
+	KW_REG_BITS_RESET(0x1478, BIT7);
+#else
+#error Undefined SOC Revision
+#endif
+	for (i = 0; i < 16; i++) {
+		inbuf[i] = KW_REG_READ(0x1470);
+	}
+	md5((u8 *) inbuf, 64, outbuf);
+	return outbuf[outbuf[7] % 0x0f];
+}
+
+/*
+ * kw_window_ctrl_reg_init - Mbus-L to Mbus Bridge Registers init.
+ */
+int kw_window_ctrl_reg_init(void)
+{
+	debug_print_ftrace();
+
+	KW_REG_WRITE(KW_REG_WIN_CTRL(0), 0x0fffe841);
+	KW_REG_WRITE(KW_REG_WIN_BASE(0), 0x90000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(0), 0x90000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(0), 0x00000000);
+
+	KW_REG_WRITE(KW_REG_WIN_CTRL(1), 0x007f2f11);
+	KW_REG_WRITE(KW_REG_WIN_BASE(1), 0xF9000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(1), 0xF9000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(1), 0x00000000);
+
+	KW_REG_WRITE(KW_REG_WIN_CTRL(2), 0x00ffe041);
+	KW_REG_WRITE(KW_REG_WIN_BASE(2), 0xF0000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(2), 0xC0000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(2), 0x00000000);
+
+	KW_REG_WRITE(KW_REG_WIN_CTRL(3), 0x00ff1e11);
+	KW_REG_WRITE(KW_REG_WIN_BASE(3), 0xF8000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(3), 0x00000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(3), 0x00000000);
+
+	KW_REG_WRITE(KW_REG_WIN_CTRL(4), 0x00ff1d11);
+	KW_REG_WRITE(KW_REG_WIN_BASE(4), 0xFF000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(4), 0x00000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(4), 0x00000000);
+
+	KW_REG_WRITE(KW_REG_WIN_CTRL(5), 0x07ff1e10);
+	KW_REG_WRITE(KW_REG_WIN_BASE(5), 0xE8000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(5), 0x00000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(5), 0x00000000);
+
+	KW_REG_WRITE(KW_REG_WIN_CTRL(6), 0x07ff1d10);
+	KW_REG_WRITE(KW_REG_WIN_BASE(6), 0xF0000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(6), 0x00000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(6), 0x00000000);
+
+	KW_REG_WRITE(KW_REG_WIN_CTRL(7), 0x00000131);
+	KW_REG_WRITE(KW_REG_WIN_BASE(7), 0xFB000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_LOW(7), 0x00000000);
+	KW_REG_WRITE(KW_REG_WIN_REMAP_HIGH(7), 0x00000000);
+
+	return KW_OK;
+}
+
+/*
+ * kw_gpio_init - Init gpios for default values
+ */
+void kw_gpio_init(u32 gpp0_oe_val, u32 gpp1_oe_val, u32 gpp0_oe, u32 gpp1_oe)
+{
+	debug_print_ftrace();
+	/* Init GPIOS to default values as per board requirement */
+	KW_REG_WRITE(KW_REG_GPP0_DATA_OUT, gpp0_oe_val);
+	KW_REG_WRITE(KW_REG_GPP1_DATA_OUT, gpp1_oe_val);
+	KW_REG_WRITE(KW_REG_GPP0_DATA_OUT_EN, gpp0_oe);
+	KW_REG_WRITE(KW_REG_GPP1_DATA_OUT_EN, gpp1_oe);
+}
+
+/*
+ * kw_mpp_control_init - initialize mpp for board specific functionality
+ */
+int kw_mpp_control_init(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, u32 mpp24_31,
+			u32 mpp32_39, u32 mpp40_47, u32 mpp48_55)
+{
+	debug_print_ftrace();
+	/* program mpp registers */
+	KW_REG_WRITE(KW_REG_MPP_CONTROL0, mpp0_7);
+	KW_REG_WRITE(KW_REG_MPP_CONTROL1, mpp8_15);
+	KW_REG_WRITE(KW_REG_MPP_CONTROL2, mpp16_23);
+	KW_REG_WRITE(KW_REG_MPP_CONTROL3, mpp24_31);
+	KW_REG_WRITE(KW_REG_MPP_CONTROL4, mpp32_39);
+	KW_REG_WRITE(KW_REG_MPP_CONTROL5, mpp40_47);
+	KW_REG_WRITE(KW_REG_MPP_CONTROL6, mpp48_55);
+	return KW_OK;
+}
+
+/*
+ * kw_misc_init_r - SOC specific misc init (mainly cache initialization)
+ */
+int kw_misc_init_r(void)
+{
+	char *env;
+	volatile unsigned int temp;
+
+	debug_print_ftrace();
+	/*CPU streaming & write allocate */
+	env = getenv("enaWrAllo");
+	if (env && ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+		__asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+		temp |= BIT28;
+		__asm__ __volatile__("mcr p15, 1, %0, c15, c1, 0"::"r"(temp));
+
+	} else {
+		__asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+		temp &= ~BIT28;
+		__asm__ __volatile__("mcr p15, 1, %0, c15, c1, 0"::"r"(temp));
+	}
+
+	env = getenv("enaCpuStream");
+	if (!env || (strcmp(env, "no") == 0) || (strcmp(env, "No") == 0)) {
+		__asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+		temp &= ~BIT29;
+		__asm__ __volatile__("mcr p15, 1, %0, c15, c1, 0"::"r"(temp));
+	} else {
+		__asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+		temp |= BIT29;
+		__asm__ __volatile__("mcr p15, 1, %0, c15, c1, 0"::"r"(temp));
+	}
+
+	/* Verify write allocate and streaming */
+	printf("\n");
+	__asm__ __volatile__("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+	if (temp & BIT29)
+		info_print("Streaming enabled");
+	else
+		info_print("Streaming disabled");
+	if (temp & BIT28)
+		info_print("Write allocate enabled");
+	else
+		info_print("Write allocate disabled");
+
+	/* DCache Pref  */
+	env = getenv("enaDCPref");
+	if (env && ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+		temp = KW_REG_READ(KW_REG_CPU_CONFIG);
+		temp |= BIT17; /* Set CCR_DCACH_PREF_BUF_ENABLE */
+		KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
+	}
+
+	if (env && ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0))) {
+		temp = KW_REG_READ(KW_REG_CPU_CONFIG);
+		temp &= ~BIT17; /* Reset CCR_DCACH_PREF_BUF_ENABLE */
+		KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
+	}
+
+	/* ICache Pref  */
+	env = getenv("enaICPref");
+	if (env && ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+		temp = KW_REG_READ(KW_REG_CPU_CONFIG);
+		temp |= BIT16; /* Set CCR_ICACH_PREF_BUF_ENABLE */
+		KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
+	}
+
+	if (env && ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0))) {
+		temp = KW_REG_READ(KW_REG_CPU_CONFIG);
+		temp &= ~BIT16; /* Reset CCR_ICACH_PREF_BUF_ENABLE */
+		KW_REG_WRITE(KW_REG_CPU_CONFIG, temp);
+	}
+	/* Set L2C WT mode - Set bit 4 */
+	temp = KW_REG_READ(KW_REG_CPU_L2_CONFIG);
+	env = getenv("setL2CacheWT");
+	if (!env || ((strcmp(env, "yes") == 0) || (strcmp(env, "Yes") == 0))) {
+		temp |= BIT4;
+	} else
+		temp &= ~BIT4;
+	KW_REG_WRITE(KW_REG_CPU_L2_CONFIG, temp);
+
+	/* L2Cache settings */
+	asm("mrc p15, 1, %0, c15, c1, 0":"=r"(temp));
+
+	/* Disable L2C pre fetch - Set bit 24 */
+	env = getenv("disL2Prefetch");
+	if (env && ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0)))
+		temp &= ~BIT24;
+	else
+		temp |= BIT24;
+
+	/* enable L2C - Set bit 22 */
+	env = getenv("disL2Cache");
+	if (!env || ((strcmp(env, "no") == 0) || (strcmp(env, "No") == 0)))
+		temp |= BIT22;
+	else
+		temp &= ~BIT22;
+
+	asm("mcr p15, 1, %0, c15, c1, 0": :"r"(temp));
+
+	/* Enable i cache */
+	asm("mrc p15, 0, %0, c1, c0, 0":"=r"(temp));
+	temp |= BIT12;
+	asm("mcr p15, 0, %0, c1, c0, 0": :"r"(temp));
+	/* Change reset vector to address 0x0 */
+	asm("mrc p15, 0, %0, c1, c0, 0":"=r"(temp));
+	temp &= ~BIT13;
+	asm("mcr p15, 0, %0, c1, c0, 0": :"r"(temp));
+
+	return (0);
+}
+
diff --git a/cpu/arm926ejs/kirkwood/kwcore.h b/cpu/arm926ejs/kirkwood/kwcore.h
new file mode 100644
index 0000000..0ddc6a8
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/kwcore.h
@@ -0,0 +1,141 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _CONFIG_KWCORE_H
+#define _CONFIG_KWCORE_H
+
+/* SOC specific definations */
+#define INTREG_BASE			0xd0000000
+#define KW_REGISTER(x)			(KW_REGS_PHY_BASE | x)
+#define KW_OFFSET_REG			(INTREG_BASE | 0x20080)
+
+#define KW_UART0_BASE			(0x12000)	/* UArt 0 */
+#define KW_UART1_BASE			(0x13000)	/* UArt 1 */
+
+/* Controler environment registers offsets */
+#define KW_REG_MPP_CONTROL0		(0x10000)
+#define KW_REG_MPP_CONTROL1		(0x10004)
+#define KW_REG_MPP_CONTROL2		(0x10008)
+#define KW_REG_MPP_CONTROL3		(0x1000C)
+#define KW_REG_MPP_CONTROL4		(0x10010)
+#define KW_REG_MPP_CONTROL5		(0x10014)
+#define KW_REG_MPP_CONTROL6		(0x10018)
+#define KW_REG_MPP_SMPL_AT_RST		(0x10030)
+#define KW_REG_CHIP_BOND		(0x10034)
+#define KW_REG_MPP_OUT_DRV_REG		(0x100E0)
+
+#define KW_REG_GPP0_DATA_OUT		(0x10100)
+#define KW_REG_GPP0_DATA_OUT_EN		(0x10104)
+#define KW_REG_GPP0_BLINK_EN		(0x10108)
+#define KW_REG_GPP0_DATA_IN_POL		(0x1010C)
+#define KW_REG_GPP0_DATA_IN		(0x10110)
+#define KW_REG_GPP0_INT_CAUSE		(0x10114)
+#define KW_REG_GPP0_INT_MASK		(0x10118)
+#define KW_REG_GPP0_INT_LVL		(0x1011c)
+
+#define KW_REG_GPP1_DATA_OUT		(0x10140)
+#define KW_REG_GPP1_DATA_OUT_EN		(0x10144)
+#define KW_REG_GPP1_BLINK_EN		(0x10148)
+#define KW_REG_GPP1_DATA_IN_POL		(0x1014C)
+#define KW_REG_GPP1_DATA_IN		(0x10150)
+#define KW_REG_GPP1_INT_CAUSE		(0x10154)
+#define KW_REG_GPP1_INT_MASK		(0x10158)
+#define KW_REG_GPP1_INT_LVL		(0x1015c)
+
+#define KW_REG_NAND_READ_PARAM		(0x10418)
+#define KW_REG_NAND_WRITE_PARAM		(0x1041c)
+#define KW_REG_NAND_CTRL		(0x10470)
+
+#define KW_REG_WIN_CTRL(x)		(0x20000+(x*0x10))
+#define KW_REG_WIN_BASE(x)		(0x20004+(x*0x10))
+#define KW_REG_WIN_REMAP_LOW(x)		(0x20008+(x*0x10))
+#define KW_REG_WIN_REMAP_HIGH(x)	(0x2000c+(x*0x10))
+
+#define KW_REG_CPU_CONFIG		(0x20100)
+#define KW_REG_CPU_CTRL_STAT		(0x20104)
+#define KW_REG_CPU_RSTOUTN_MASK		(0x20108)
+#define KW_REG_CPU_SYS_SOFT_RST		(0x2010C)
+#define KW_REG_CPU_AHB_MBUS_CAUSE_INT	(0x20110)
+#define KW_REG_CPU_AHB_MBUS_MASK_INT	(0x20114)
+#define KW_REG_CPU_FTDLL_CONFIG		(0x20120)
+#define KW_REG_CPU_L2_CONFIG		(0x20128)
+#define KW_REG_L2_RAM_TIMING0		(0x20134)
+#define KW_REG_L2_RAM_TIMING1		(0x20138)
+
+#define KW_REG_TMR_CTRL			(0x20300)
+#define KW_REG_TMR_RELOAD		(0x20310)
+#define KW_REG_TMR_VAL			(0x20314)
+
+/*
+ * Macros
+ * CPU architecture dependent I/O read/write
+ */
+#define KW_REG_WRITE(addr, data)	\
+    ((*((volatile unsigned int*)(KW_REGISTER(addr)))) \
+		 = ((unsigned int)WORD_SWAP((data))))
+
+#define KW_REG_READ(addr)       	\
+    WORD_SWAP(((*((volatile unsigned int*)(KW_REGISTER(addr))))))
+
+#define KW_REG_BITS_SET(adr, bits)	(KW_REG_WRITE(adr, KW_REG_READ(adr)\
+					| ((unsigned int)WORD_SWAP(bits))))
+
+#define KW_REG_BITS_RESET(adr, bits)	(KW_REG_WRITE(adr, KW_REG_READ(adr)\
+					& ~((unsigned int)WORD_SWAP(bits))))
+
+#define KW_REG_READ_ASM(toReg, tmpReg, regOffs)	\
+        ldr     tmpReg, =KW_REGISTER(regOffs);  	\
+        ldr     toReg, [tmpReg];  			\
+				/*WORD_SWAP_ASM(toReg,tmpReg) */
+
+#define KW_REG_WRITE_ASM(fromReg, tmpReg, regOffs)	\
+        /*WORD_SWAP_ASM(fromReg,tmpReg)*/;  		\
+        ldr     tmpReg, =KW_REGISTER(regOffs);		\
+        str     fromReg, [tmpReg]
+
+/*
+ * functions
+ */
+#ifndef __ASSEMBLY__
+void reset_cpu(unsigned long ignored);
+unsigned char get_random_hex(void);
+typedef enum _memory_bank { BANK0, BANK1, BANK2, BANK3 } MEMORY_BANK;
+unsigned int kw_get_dram_bank_base_addr(MEMORY_BANK bank);
+unsigned int kw_get_dram_bank_size(MEMORY_BANK bank);
+int kw_window_ctrl_reg_init(void);
+void kw_gpio_init(unsigned int gpp0_oe_val, unsigned int gpp1_oe_val,
+		  unsigned int gpp0_oe, unsigned int gpp1_oe);
+int kw_mpp_control_init(unsigned int mpp0_7, unsigned int mpp8_15,
+			unsigned int mpp16_23, unsigned int mpp24_31,
+			unsigned int mpp32_39, unsigned int mpp40_47,
+			unsigned int mpp48_55);
+int kw_misc_init_r(void);
+#endif
+
+/*
+ * Error codes
+ */
+#define KW_ERROR	(-1)
+#define KW_OK		(0)
+#endif				/* _CONFIG_KWCORE_H */
diff --git a/cpu/arm926ejs/kirkwood/serial.c b/cpu/arm926ejs/kirkwood/serial.c
new file mode 100644
index 0000000..6422ab2
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/serial.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+
+/* registers feilds */
+#define FCR_FIFO_EN     	BIT0	/* fifo enable */
+#define FCR_RXSR        	BIT1	/* receiver soft reset */
+#define FCR_TXSR        	BIT2	/* transmitter soft reset */
+#define MCR_RTS         	BIT1	/* ready to send */
+
+#define LCR_WLS_OFFS		0
+#define LCR_WLS_MASK 		0x3 << LCR_WLS_OFFS	/* character length mask  */
+#define LCR_WLS_5   		0x0 << LCR_WLS_OFFS	/* 5 bit character length */
+#define LCR_WLS_6   		0x1 << LCR_WLS_OFFS	/* 6 bit character length */
+#define LCR_WLS_7   		0x2 << LCR_WLS_OFFS	/* 7 bit character length */
+#define LCR_WLS_8   		0x3 << LCR_WLS_OFFS	/* 8 bit character length */
+#define LCR_STP_OFFS		2
+#define LCR_1_STB     		0x0 << LCR_STP_OFFS	/* Number of stop Bits */
+#define LCR_2_STB     		0x1 << LCR_STP_OFFS	/* Number of stop Bits */
+#define LCR_PEN     		0x8	/* Parity enable */
+#define LCR_PS_OFFS		4
+#define LCR_EPS     		0x1 << LCR_PS_OFFS	/* Even Parity Select */
+#define LCR_OPS     		0x0 << LCR_PS_OFFS	/* Odd Parity Select */
+#define LCR_SBRK_OFFS		0x6
+#define LCR_SBRK    		0x1 << LCR_SBRK_OFFS	/* Set Break */
+#define LCR_DIVL_OFFS		7
+#define LCR_DIVL_EN    		0x1 << LCR_DIVL_OFFS	/* Divisior latch enable */
+
+#define LSR_DR      		BIT0	/* Data ready */
+#define LSR_OE      		BIT1	/* Overrun */
+#define LSR_PE      		BIT2	/* Parity error */
+#define LSR_FE      		BIT3	/* Framing error */
+#define LSR_BI      		BIT4	/* Break */
+#define LSR_THRE    		BIT5	/* Xmit holding register empty */
+#define LSR_TEMT    		BIT6	/* Xmitter empty */
+#define LSR_ERR     		BIT7	/* Error */
+
+/* useful defaults for LCR*/
+#define LCR_8N1     		LCR_WLS_8 | LCR_1_STB
+
+/* This structure describes the registers offsets for one UART port/channel */
+typedef struct kwUartPort {
+	u8 rbr;			/* 0 = 0-3 */
+	u8 pad1[3];
+	u8 ier;			/* 1 = 4-7 */
+	u8 pad2[3];
+	u8 fcr;			/* 2 = 8-b */
+	u8 pad3[3];
+	u8 lcr;			/* 3 = c-f */
+	u8 pad4[3];
+	u8 mcr;			/* 4 = 10-13 */
+	u8 pad5[3];
+	u8 lsr;			/* 5 = 14-17 */
+	u8 pad6[3];
+	u8 msr;			/* 6 =18-1b */
+	u8 pad7[3];
+	u8 scr;			/* 7 =1c-1f */
+	u8 pad8[3];
+} kw_uart_port;
+
+/* aliases - for registers which has the same offsets */
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+/* static variables */
+#if defined (CONFIG_CONS_INDEX)	/* comes from board config */
+#if (CONFIG_CONS_INDEX == 0 )
+static volatile kw_uart_port *p_uart_port = (void *)KW_REGISTER(KW_UART0_BASE);
+#elif (CONFIG_CONS_INDEX == 1 )
+static volatile kw_uart_port *p_uart_port = (void *)KW_REGISTER(KW_UART1_BASE);
+#endif
+#else
+#error CONFIG_CONS_INDEX not defined correctly
+#endif
+
+#define CONFIG_KW_UART_PORTS	{ (void *)KW_UART0_BASE, \
+				  (void *)KW_UART1_BASE }
+
+/*
+ * Serial init banner is kept simplest one
+ * if required can be created good one
+ */
+int serial_init(void)
+{
+	serial_setbrg();
+	printf
+	    ("\n*************************************************************");
+	return (0);
+}
+
+void kwUartPutc(u8 c)
+{
+	while ((p_uart_port->lsr & LSR_THRE) == 0) ;
+	p_uart_port->thr = c;
+	return;
+}
+
+void serial_putc(const char c)
+{
+	if (c == '\n')
+		kwUartPutc('\r');
+
+	kwUartPutc(c);
+}
+
+int serial_getc(void)
+{
+	while ((p_uart_port->lsr & LSR_DR) == 0) ;
+	return (p_uart_port->rbr);
+}
+
+int serial_tstc(void)
+{
+	return ((p_uart_port->lsr & LSR_DR) != 0);
+}
+
+void serial_setbrg(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	int clock_divisor = (CONFIG_SYS_TCLK / 16) / gd->baudrate;
+
+	p_uart_port->ier = 0x00;
+	p_uart_port->lcr = LCR_DIVL_EN;	/* Access baud rate */
+	p_uart_port->dll = clock_divisor & 0xff;	/* 9600 baud */
+	p_uart_port->dlm = (clock_divisor >> 8) & 0xff;
+	p_uart_port->lcr = LCR_8N1;	/* 8 data, 1 stop, no parity */
+	/* Clear & enable FIFOs */
+	p_uart_port->fcr = FCR_FIFO_EN | FCR_RXSR | FCR_TXSR;
+	return;
+}
+
+void serial_puts(const char *s)
+{
+	while (*s) {
+		serial_putc(*s++);
+	}
+}
+
+#ifdef CONFIG_CMD_KGDB
+void kgdb_serial_init(void)
+{
+}
+
+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_CMD_KGDB */
diff --git a/cpu/arm926ejs/kirkwood/soc_init.S b/cpu/arm926ejs/kirkwood/soc_init.S
new file mode 100644
index 0000000..e9701d2
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/soc_init.S
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <config.h>
+
+#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS		8
+#define CCR_CPU_2_MBUSL_TICK_DRV_MASK		(0xF << CCR_CPU_2_MBUSL_TICK_DRV_OFFS)
+#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS		12
+#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK		(0xF << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)
+
+#define MSAR_DDRCLCK_RTIO_OFFS			5
+#define MSAR_DDRCLCK_RTIO_MASK			(0xF << MSAR_DDRCLCK_RTIO_OFFS)
+
+
+/* Ratio options for CPU to DDR for 6281/6192/6180 */
+#define CPU_2_DDR_CLK_1x2	    		2
+#define CPU_2_DDR_CLK_1x3	    		4
+#define CPU_2_DDR_CLK_1x4	    		6
+
+/* Default values for CPU to Mbus-L DDR Interface Tick Driver and 	*/
+/* CPU to Mbus-L Tick Sample fields in CPU config register		*/
+
+#define TICK_DRV_1x1				0
+#define TICK_DRV_1x2				0
+#define TICK_DRV_1x3				1
+#define TICK_DRV_1x4				2
+#define TICK_SMPL_1x1				0
+#define TICK_SMPL_1x2				1
+#define TICK_SMPL_1x3				2
+#define TICK_SMPL_1x4				3
+#define CPU_2_MBUSL_DDR_CLK_1x2						\
+		 ((TICK_DRV_1x2  << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | 	\
+		  (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
+#define CPU_2_MBUSL_DDR_CLK_1x3						\
+		 ((TICK_DRV_1x3  << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | 	\
+		  (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
+#define CPU_2_MBUSL_DDR_CLK_1x4						\
+		 ((TICK_DRV_1x4  << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | 	\
+		  (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
+
+
+	.globl kw_cpu_if_pre_init
+kw_cpu_if_pre_init:
+
+        mov     r11, LR     		/* Save link register */
+
+        /*
+	 * Configures the I/O voltage of the pads connected to Egigabit
+	 * Ethernet interface to 1.8V
+	 * By defult it is set to 3.3V
+	 */
+#ifdef CONFIG_KIRKWOOD_RGMII_PAD_1V8
+        KW_REG_READ_ASM (r7, r5, KW_REG_MPP_OUT_DRV_REG)
+        ldr    r5, =BIT7
+        orr    r7, r7, r5       /* Set RGMII PADS Voltage to 1.8V */
+        KW_REG_WRITE_ASM (r7, r5, KW_REG_MPP_OUT_DRV_REG)
+#endif
+        /*
+	 * Set egiga port0/1 in normal functional mode
+	 * This is required becasue on kirkwood by default ports are in reset mode
+	 * OS egiga driver may not have provision to set them in normal mode
+	 * and if u-boot is build without network support, network may fail at OS level
+	 */
+#ifdef CONFIG_KIRKWOOD_EGIGA_INIT
+        KW_REG_READ_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(0))
+        ldr    r5, =~(BIT4)
+        and    r7, r7, r5       /* Clear PortReset Bit */
+        KW_REG_WRITE_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(0))
+
+        KW_REG_READ_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(1))
+        ldr    r5, =~(BIT4)
+        and    r7, r7, r5       /* Clear PortReset Bit */
+        KW_REG_WRITE_ASM (r7, r5, KW_ETH_PORT_SERIAL_CONTROL1_REG(1))
+#endif
+
+	/*
+	 * Enable PCI Express Port0
+	 */
+#ifdef CONFIG_KIRKWOOD_PCIE_INIT
+        KW_REG_READ_ASM (r7, r5, KW_REG_CPU_CTRL_STAT)
+        ldr    r5, =BIT0
+        orr    r7, r7, r5       /* Set PEX0En Bit */
+        KW_REG_WRITE_ASM (r7, r5, KW_REG_CPU_CTRL_STAT)
+#endif
+
+#ifdef CONFIG_KW88F6281_Z0
+        /* Get the "sample on reset" register */
+	KW_REG_READ_ASM (r4, r5, KW_REG_MPP_SMPL_AT_RST)
+        ldr    r5, =MSAR_DDRCLCK_RTIO_MASK
+        and    r5, r4, r5
+	mov    r5, r5, lsr #MSAR_DDRCLCK_RTIO_OFFS
+
+        ldr    r4, =CPU_2_MBUSL_DDR_CLK_1x2
+        cmp    r5, #CPU_2_DDR_CLK_1x2
+        beq    set_config_reg
+
+        ldr    r4, =CPU_2_MBUSL_DDR_CLK_1x3
+        cmp    r5, #CPU_2_DDR_CLK_1x3
+        beq    set_config_reg
+
+        ldr    r4, =CPU_2_MBUSL_DDR_CLK_1x4
+        cmp    r5, #CPU_2_DDR_CLK_1x4
+        beq    set_config_reg
+
+        ldr    r4, =0
+
+set_config_reg:
+        /* Read CPU Config register */
+        KW_REG_READ_ASM (r7, r5, KW_REG_CPU_CONFIG)
+        ldr    r5, =~(CCR_CPU_2_MBUSL_TICK_DRV_MASK | CCR_CPU_2_MBUSL_TICK_SMPL_MASK)
+        and    r7, r7, r5       /* Clear register fields */
+        orr    r7, r7, r4       /* Set the values according to the findings */
+        KW_REG_WRITE_ASM (r7, r5, KW_REG_CPU_CONFIG)
+
+done:
+#endif
+        mov     PC, r11         /* r11 is saved link register */
+
+	.globl kw_enable_invalidate_l2_cache
+kw_enable_invalidate_l2_cache:
+        mov     r11, LR     	/* Save link register */
+
+	/* Enable L2 cache in write through mode */
+	KW_REG_READ_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
+	orr     r4, r4, #0x18
+	KW_REG_WRITE_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
+	/* Read operation to make sure the L2 bit is set */
+	KW_REG_READ_ASM(r4, r1, KW_REG_CPU_L2_CONFIG)
+
+	/* invalidate L2 cache */
+	mov	r0, #0
+	mcr	p15, 1, r0, c15, c11, 0
+
+        mov     PC, r11         /* r11 is saved link register */
+
diff --git a/cpu/arm926ejs/kirkwood/spi.c b/cpu/arm926ejs/kirkwood/spi.c
new file mode 100644
index 0000000..a334d95
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/spi.c
@@ -0,0 +1,213 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * Derived from drivers/spi/mpc8xxx_spi.c
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef KWSPI_DEBUG
+#define KWSPI_DEBUG		0
+#endif
+#define DEBUG_PRINT		KWSPI_DEBUG
+
+#include <common.h>
+#include <debug_prints.h>
+#include <malloc.h>
+#include <spi.h>
+
+/* SPI Registers on kirkwood SOC */
+#define KW_REG_SPI_CTRL		(0x10600)
+#define KW_REG_SPI_CONFIG	(0x10604)
+#define KW_REG_SPI_DATA_OUT	(0x10608)
+#define KW_REG_SPI_DATA_IN	(0x1060c)
+#define KW_REG_SPI_IRQ_CAUSE	(0x10610)
+#define KW_REG_SPI_IRQ_MASK	(0x10614)
+
+#define KW_SPI_TIMEOUT		10000
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+				  unsigned int max_hz, unsigned int mode)
+{
+	struct spi_slave *slave;
+	u32 data;
+
+	debug_print_ftrace();
+	if (!spi_cs_is_valid(bus, cs))
+		return NULL;
+
+	slave = malloc(sizeof(struct spi_slave));
+	if (!slave)
+		return NULL;
+
+	slave->bus = bus;
+	slave->cs = cs;
+
+	KW_REG_WRITE(KW_REG_SPI_CTRL, 0x00000002);
+	/* program spi clock prescaller using max_hz */
+	data = ((CONFIG_SYS_TCLK / 2) / max_hz) & 0x0000000f;
+	debug_print("data = 0x%08x \n", data);
+	KW_REG_WRITE(KW_REG_SPI_CONFIG, 0x00000210 | data);
+	KW_REG_WRITE(KW_REG_SPI_IRQ_CAUSE, 0x00000001);
+	KW_REG_WRITE(KW_REG_SPI_IRQ_MASK, 0x00000000);
+
+	/* program mpp registers to select  SPI_CSn */
+	if (cs)
+		KW_REG_WRITE(KW_REG_MPP_CONTROL0,
+			     ((KW_REG_READ(KW_REG_MPP_CONTROL0) & 0x0fffffff) |
+			      0x20000000));
+	else
+		KW_REG_WRITE(KW_REG_MPP_CONTROL0,
+			     ((KW_REG_READ(KW_REG_MPP_CONTROL0) & 0xfffffff0) |
+			      0x00000002));
+
+	return slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+	debug_print_ftrace();
+	free(slave);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	debug_print_ftrace();
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+	debug_print_ftrace();
+}
+
+#ifndef CONFIG_SPI_CS_IS_VALID
+/*
+ * you can define this function board specific
+ * define above CONFIG in board specific config file and
+ * provide the function in board specific src file
+ */
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+	debug_print_ftrace();
+	return (bus == 0 && (cs == 0 || cs == 1));
+}
+#endif
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+	debug_print_ftrace();
+	KW_REG_BITS_SET(KW_REG_SPI_CTRL, BIT0);
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+	debug_print_ftrace();
+	KW_REG_BITS_RESET(KW_REG_SPI_CTRL, BIT0);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+	     void *din, unsigned long flags)
+{
+	unsigned int tmpdout, tmpdin;
+	int tm, isRead = 0;
+
+	debug_print_ftrace();
+	debug_print("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
+		    slave->bus, slave->cs, dout, din, bitlen);
+
+	if (flags & SPI_XFER_BEGIN)
+		spi_cs_activate(slave);
+
+	/*
+	 * handle data in 8-bit chunks
+	 * TBD: 2byte xfer mode to be enabled
+	 */
+	while (bitlen > 4) {
+		debug_print("loopstart bitlen %d\n", bitlen);
+		tmpdout = 0;
+		if (1) {	//bitlen <= 8) {
+			/*1 byte xfer mode */
+			KW_REG_BITS_RESET(KW_REG_SPI_CONFIG, BIT5);
+			/* Shift data so it's msb-justified */
+			if (dout) {
+				tmpdout = *(u32 *) dout & 0x0ff;
+			}
+		} else {
+			/*2 byte xfer mode */
+			KW_REG_BITS_SET(KW_REG_SPI_CONFIG, BIT5);
+			/* Shift data so it's msb-justified */
+			if (dout) {
+				tmpdout = *(u32 *) dout & 0x0ffff;
+			}
+		}
+
+		KW_REG_WRITE(KW_REG_SPI_IRQ_CAUSE, 0x0);	/* clear bit */
+		KW_REG_WRITE(KW_REG_SPI_DATA_OUT, tmpdout);	/* Write the data out */
+		debug_print("*** spi_xfer: ... %08x written, bitlen %d\n",
+			    tmpdout, bitlen);
+
+		/*
+		 * Wait for SPI transmit to get out
+		 * or time out (1 second = 1000 ms)
+		 * The NE event must be read and cleared first
+		 */
+		for (tm = 0, isRead = 0; tm < KW_SPI_TIMEOUT; ++tm) {
+			if (KW_REG_READ(KW_REG_SPI_IRQ_CAUSE)) {
+				isRead = 1;
+				tmpdin = KW_REG_READ(KW_REG_SPI_DATA_IN);
+				debug_print
+				    ("*** spi_xfer: din %08X ... %08x read\n",
+				     din, tmpdin);
+
+				if (1) {	//bitlen <= 8) {
+					if (din) {
+						*((u8 *) din) = (u8) tmpdin;
+						din += 1;
+					}
+					if (dout)
+						dout += 1;
+					bitlen -= 8;
+				} else {
+					if (din) {
+						*((u16 *) din) = (u16) tmpdin;
+						din += 1;
+					}
+					if (dout)
+						dout += 1;
+					bitlen -= 16;
+				}
+			}
+			if (isRead)
+				break;
+		}
+		if (tm >= KW_SPI_TIMEOUT)
+			error_print
+			    ("*** spi_xfer: Time out during SPI transfer");
+
+		debug_print("loopend bitlen %d\n", bitlen);
+	}
+
+	if (flags & SPI_XFER_END)
+		spi_cs_deactivate(slave);
+
+	return 0;
+}
diff --git a/cpu/arm926ejs/kirkwood/timer.c b/cpu/arm926ejs/kirkwood/timer.c
new file mode 100644
index 0000000..4ab1a54
--- /dev/null
+++ b/cpu/arm926ejs/kirkwood/timer.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+
+#define UBOOT_CNTR	0	/* counter to use for uboot timer */
+
+/*
+ * ARM Timers Registers Map
+ */
+#define CNTMR_CTRL_REG			KW_REG_TMR_CTRL
+#define CNTMR_RELOAD_REG(tmrNum)	(KW_REG_TMR_RELOAD + tmrNum*8)
+#define CNTMR_VAL_REG(tmrNum)		(KW_REG_TMR_VAL + tmrNum*8)
+
+/*
+ * ARM Timers Control Register
+ * CPU_TIMERS_CTRL_REG (CTCR)
+ */
+#define TIMER0_NUM				0
+#define TIMER1_NUM				1
+#define WATCHDOG_NUM				2
+
+#define CTCR_ARM_TIMER_EN_OFFS(cntr)		(cntr * 2)
+#define CTCR_ARM_TIMER_EN_MASK(cntr)		(1 << CTCR_ARM_TIMER_EN_OFFS)
+#define CTCR_ARM_TIMER_EN(cntr)			(1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
+#define CTCR_ARM_TIMER_DIS(cntr)		(0 << CTCR_ARM_TIMER_EN_OFFS(cntr))
+
+#define CTCR_ARM_TIMER_AUTO_OFFS(cntr)	((cntr * 2) + 1)
+#define CTCR_ARM_TIMER_AUTO_MASK(cntr)	BIT1
+#define CTCR_ARM_TIMER_AUTO_EN(cntr)	(1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
+#define CTCR_ARM_TIMER_AUTO_DIS(cntr)	(0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
+
+/*
+ * ARM Timer\Watchdog Reload Register
+ * CNTMR_RELOAD_REG (TRR)
+ */
+#define TRG_ARM_TIMER_REL_OFFS			0
+#define TRG_ARM_TIMER_REL_MASK			0xffffffff
+
+/*
+ * ARM Timer\Watchdog Register
+ * CNTMR_VAL_REG (TVRG)
+ */
+#define TVR_ARM_TIMER_OFFS			0
+#define TVR_ARM_TIMER_MASK			0xffffffff
+#define TVR_ARM_TIMER_MAX			0xffffffff
+#define TIMER_LOAD_VAL 				0xffffffff
+
+/* This enumerator describe counters\watchdog numbers       */
+typedef enum _kwCntmrID {
+	TIMER0 = 0,
+	TIMER1,
+	WATCHDOG
+} KW_CNTMR_ID;
+
+#define READ_TIMER	(KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR))/(CONFIG_SYS_TCLK/1000))
+
+static ulong timestamp;
+static ulong lastdec;
+
+void reset_timer_masked(void)
+{
+	/* reset time */
+	lastdec = READ_TIMER;
+	timestamp = 0;
+}
+
+ulong get_timer_masked(void)
+{
+	ulong now = READ_TIMER;
+
+	if (lastdec >= now) {
+		/* normal mode */
+		timestamp += lastdec - now;
+	} else {
+		/* we have an overflow ... */
+		timestamp +=
+		    lastdec + (TIMER_LOAD_VAL / (CONFIG_SYS_TCLK / 1000)) - now;
+	}
+	lastdec = now;
+
+	return timestamp;
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	timestamp = t;
+}
+
+void udelay(unsigned long usec)
+{
+	uint current;
+	ulong delayticks;
+
+	current = KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR));
+	delayticks = (usec * (CONFIG_SYS_TCLK / 1000000));
+
+	if (current < delayticks) {
+		delayticks -= current;
+		while (KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR)) < current) ;
+		while ((TIMER_LOAD_VAL - delayticks) <
+		       KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR))) ;
+	} else {
+		while (KW_REG_READ(CNTMR_VAL_REG(UBOOT_CNTR)) >
+		       (current - delayticks)) ;
+	}
+}
+
+/*
+ * init the counter
+ */
+int timer_init(void)
+{
+	unsigned int cntmrCtrl;
+
+	/* load value onto counter\timer */
+	KW_REG_WRITE(CNTMR_RELOAD_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
+	KW_REG_WRITE(CNTMR_VAL_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
+
+	/* set the counter to load in the first time */
+	KW_REG_WRITE(CNTMR_VAL_REG(UBOOT_CNTR), TIMER_LOAD_VAL);
+
+	/* set control for timer \ cunter and enable */
+	/* read control register */
+	cntmrCtrl = KW_REG_READ(CNTMR_CTRL_REG);
+	cntmrCtrl |= CTCR_ARM_TIMER_EN(UBOOT_CNTR);	/* enable cnt\timer */
+	cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(UBOOT_CNTR);	/* Auto mode */
+
+	KW_REG_WRITE(CNTMR_CTRL_REG, cntmrCtrl);
+
+	/* init the timestamp and lastdec value */
+	reset_timer_masked();
+
+	return 0;
+}
diff --git a/include/configs/kirkwood.h b/include/configs/kirkwood.h
new file mode 100644
index 0000000..eec04c2
--- /dev/null
+++ b/include/configs/kirkwood.h
@@ -0,0 +1,46 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla at marvell.com>
+ *
+ * Header file for the Marvell's Feroceon CPU core.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _CONFIG_KIRKWOOD_H
+#define _CONFIG_KIRKWOOD_H
+
+#ifndef __ASSEMBLY__
+#include <asm-arm/types.h>
+#endif /* __ASSEMBLY__ */
+#include <../board/Marvell/include/core.h>
+
+#if defined (CONFIG_FEROCEON_88FR131) || defined (CONFIG_SHEEVA_88SV131)
+#if defined (CONFIG_KIRKWOOD)
+#include <../cpu/arm926ejs/kirkwood/kwcore.h>
+#endif /* CONFIG_KIRKWOOD */
+#if defined (CONFIG_KW88F6281)
+#include <../cpu/arm926ejs/kirkwood/kw88f6281.h>
+#endif /* CONFIG_KW88F6281 */
+#if defined (CONFIG_KW88F6192)
+#include <../cpu/arm926ejs/kirkwood/kw88f6192.h>
+#endif /* CONFIG_KW88F6192 */
+#endif /* CONFIG_FEROCEON_88FR131 */
+#endif /* _CONFIG_KIRKWOOD_H */
-- 
1.5.3.3



More information about the U-Boot mailing list