[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