[Feature][T106]ZXW P56U09 code

Only Configure: Yes
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: No
Doc Update: No

Change-Id: I3cbd8b420271eb20c2b40ebe5c78f83059cd42f3
diff --git a/boot/common/src/uboot/arch/arm/lib/Makefile b/boot/common/src/uboot/arch/arm/lib/Makefile
new file mode 100644
index 0000000..8a07839
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/Makefile
@@ -0,0 +1,86 @@
+#
+# (C) Copyright 2002-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(ARCH).o
+LIBGCC	= $(obj)libgcc.o
+
+ifndef CONFIG_SPL_BUILD
+GLSOBJS	+= _ashldi3.o
+GLSOBJS	+= _ashrdi3.o
+GLSOBJS	+= _divsi3.o
+GLSOBJS	+= _lshrdi3.o
+GLSOBJS	+= _modsi3.o
+GLSOBJS	+= _udivsi3.o
+GLSOBJS	+= _umodsi3.o
+
+GLCOBJS	+= div0.o
+
+COBJS-y	+= board.o
+
+COBJS-y	+= bootm.o
+COBJS-y	+= cache.o
+COBJS-y	+= cache-cp15.o
+COBJS-$(CONFIG_SYS_L2_PL310) += cache-pl310.o
+COBJS-y	+= interrupts.o
+COBJS-y	+= reset.o
+SOBJS-$(CONFIG_USE_ARCH_MEMSET) += memset.o
+SOBJS-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o
+endif
+
+SRCS	:= $(GLSOBJS:.o=.S) $(GLCOBJS:.o=.c) \
+	   $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
+LGOBJS	:= $(addprefix $(obj),$(GLSOBJS)) \
+	   $(addprefix $(obj),$(GLCOBJS))
+
+# Always build libarm.o
+TARGETS	:= $(LIB)
+
+# Build private libgcc only when asked for
+ifdef USE_PRIVATE_LIBGCC
+TARGETS	+= $(LIBGCC)
+endif
+
+# For EABI conformant tool chains, provide eabi_compat()
+ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS)))
+TARGETS	+= $(obj)eabi_compat.o
+endif
+
+all:	$(TARGETS)
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+$(LIBGCC): $(obj).depend $(LGOBJS)
+	$(call cmd_link_o_target, $(LGOBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/boot/common/src/uboot/arch/arm/lib/_ashldi3.S b/boot/common/src/uboot/arch/arm/lib/_ashldi3.S
new file mode 100644
index 0000000..834ddc2
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/_ashldi3.S
@@ -0,0 +1,48 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+   Free Software Foundation, Inc.
+
+This file 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file 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; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+.globl __ashldi3
+.globl	__aeabi_llsl
+__ashldi3:
+__aeabi_llsl:
+
+	subs	r3, r2, #32
+	rsb	ip, r2, #32
+	movmi	ah, ah, lsl r2
+	movpl	ah, al, lsl r3
+	orrmi	ah, ah, al, lsr ip
+	mov	al, al, lsl r2
+	mov	pc, lr
diff --git a/boot/common/src/uboot/arch/arm/lib/_ashrdi3.S b/boot/common/src/uboot/arch/arm/lib/_ashrdi3.S
new file mode 100644
index 0000000..671ac87
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/_ashrdi3.S
@@ -0,0 +1,48 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+   Free Software Foundation, Inc.
+
+This file 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file 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; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+.globl __ashrdi3
+.globl __aeabi_lasr
+__ashrdi3:
+__aeabi_lasr:
+
+	subs	r3, r2, #32
+	rsb	ip, r2, #32
+	movmi	al, al, lsr r2
+	movpl	al, ah, asr r3
+	orrmi	al, al, ah, lsl ip
+	mov	ah, ah, asr r2
+	mov	pc, lr
diff --git a/boot/common/src/uboot/arch/arm/lib/_divsi3.S b/boot/common/src/uboot/arch/arm/lib/_divsi3.S
new file mode 100644
index 0000000..cfbadb2
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/_divsi3.S
@@ -0,0 +1,142 @@
+
+.macro ARM_DIV_BODY dividend, divisor, result, curbit
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+	clz	\curbit, \divisor
+	clz	\result, \dividend
+	sub	\result, \curbit, \result
+	mov	\curbit, #1
+	mov	\divisor, \divisor, lsl \result
+	mov	\curbit, \curbit, lsl \result
+	mov	\result, #0
+
+#else
+
+	@ Initially shift the divisor left 3 bits if possible,
+	@ set curbit accordingly.  This allows for curbit to be located
+	@ at the left end of each 4 bit nibbles in the division loop
+	@ to save one loop in most cases.
+	tst	\divisor, #0xe0000000
+	moveq	\divisor, \divisor, lsl #3
+	moveq	\curbit, #8
+	movne	\curbit, #1
+
+	@ Unless the divisor is very big, shift it up in multiples of
+	@ four bits, since this is the amount of unwinding in the main
+	@ division loop.  Continue shifting until the divisor is
+	@ larger than the dividend.
+1:	cmp	\divisor, #0x10000000
+	cmplo	\divisor, \dividend
+	movlo	\divisor, \divisor, lsl #4
+	movlo	\curbit, \curbit, lsl #4
+	blo	1b
+
+	@ For very big divisors, we must shift it a bit at a time, or
+	@ we will be in danger of overflowing.
+1:	cmp	\divisor, #0x80000000
+	cmplo	\divisor, \dividend
+	movlo	\divisor, \divisor, lsl #1
+	movlo	\curbit, \curbit, lsl #1
+	blo	1b
+
+	mov	\result, #0
+
+#endif
+
+	@ Division loop
+1:	cmp	\dividend, \divisor
+	subhs	\dividend, \dividend, \divisor
+	orrhs	\result,   \result,   \curbit
+	cmp	\dividend, \divisor,  lsr #1
+	subhs	\dividend, \dividend, \divisor, lsr #1
+	orrhs	\result,   \result,   \curbit,  lsr #1
+	cmp	\dividend, \divisor,  lsr #2
+	subhs	\dividend, \dividend, \divisor, lsr #2
+	orrhs	\result,   \result,   \curbit,  lsr #2
+	cmp	\dividend, \divisor,  lsr #3
+	subhs	\dividend, \dividend, \divisor, lsr #3
+	orrhs	\result,   \result,   \curbit,  lsr #3
+	cmp	\dividend, #0			@ Early termination?
+	movnes	\curbit,   \curbit,  lsr #4	@ No, any more bits to do?
+	movne	\divisor,  \divisor, lsr #4
+	bne	1b
+
+.endm
+
+.macro ARM_DIV2_ORDER divisor, order
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+	clz	\order, \divisor
+	rsb	\order, \order, #31
+
+#else
+
+	cmp	\divisor, #(1 << 16)
+	movhs	\divisor, \divisor, lsr #16
+	movhs	\order, #16
+	movlo	\order, #0
+
+	cmp	\divisor, #(1 << 8)
+	movhs	\divisor, \divisor, lsr #8
+	addhs	\order, \order, #8
+
+	cmp	\divisor, #(1 << 4)
+	movhs	\divisor, \divisor, lsr #4
+	addhs	\order, \order, #4
+
+	cmp	\divisor, #(1 << 2)
+	addhi	\order, \order, #3
+	addls	\order, \order, \divisor, lsr #1
+
+#endif
+
+.endm
+
+	.align	5
+.globl __divsi3
+.globl __aeabi_idiv
+__divsi3:
+__aeabi_idiv:
+	cmp	r1, #0
+	eor	ip, r0, r1			@ save the sign of the result.
+	beq	Ldiv0
+	rsbmi	r1, r1, #0			@ loops below use unsigned.
+	subs	r2, r1, #1			@ division by 1 or -1 ?
+	beq	10f
+	movs	r3, r0
+	rsbmi	r3, r0, #0			@ positive dividend value
+	cmp	r3, r1
+	bls	11f
+	tst	r1, r2				@ divisor is power of 2 ?
+	beq	12f
+
+	ARM_DIV_BODY r3, r1, r0, r2
+
+	cmp	ip, #0
+	rsbmi	r0, r0, #0
+	mov	pc, lr
+
+10:	teq	ip, r0				@ same sign ?
+	rsbmi	r0, r0, #0
+	mov	pc, lr
+
+11:	movlo	r0, #0
+	moveq	r0, ip, asr #31
+	orreq	r0, r0, #1
+	mov	pc, lr
+
+12:	ARM_DIV2_ORDER r1, r2
+
+	cmp	ip, #0
+	mov	r0, r3, lsr r2
+	rsbmi	r0, r0, #0
+	mov	pc, lr
+
+Ldiv0:
+
+	str	lr, [sp, #-4]!
+	bl	__div0
+	mov	r0, #0			@ About as wrong as it could be.
+	ldr	pc, [sp], #4
diff --git a/boot/common/src/uboot/arch/arm/lib/_lshrdi3.S b/boot/common/src/uboot/arch/arm/lib/_lshrdi3.S
new file mode 100644
index 0000000..e7fa799
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/_lshrdi3.S
@@ -0,0 +1,48 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+   Free Software Foundation, Inc.
+
+This file 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, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file.  (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file 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; see the file COPYING.  If not, write to
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
+
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+.globl __lshrdi3
+.globl __aeabi_llsr
+__lshrdi3:
+__aeabi_llsr:
+
+	subs	r3, r2, #32
+	rsb	ip, r2, #32
+	movmi	al, al, lsr r2
+	movpl	al, ah, lsr r3
+	orrmi	al, al, ah, lsl ip
+	mov	ah, ah, lsr r2
+	mov	pc, lr
diff --git a/boot/common/src/uboot/arch/arm/lib/_modsi3.S b/boot/common/src/uboot/arch/arm/lib/_modsi3.S
new file mode 100644
index 0000000..539c584
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/_modsi3.S
@@ -0,0 +1,99 @@
+
+.macro ARM_MOD_BODY dividend, divisor, order, spare
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+	clz	\order, \divisor
+	clz	\spare, \dividend
+	sub	\order, \order, \spare
+	mov	\divisor, \divisor, lsl \order
+
+#else
+
+	mov	\order, #0
+
+	@ Unless the divisor is very big, shift it up in multiples of
+	@ four bits, since this is the amount of unwinding in the main
+	@ division loop.  Continue shifting until the divisor is
+	@ larger than the dividend.
+1:	cmp	\divisor, #0x10000000
+	cmplo	\divisor, \dividend
+	movlo	\divisor, \divisor, lsl #4
+	addlo	\order, \order, #4
+	blo	1b
+
+	@ For very big divisors, we must shift it a bit at a time, or
+	@ we will be in danger of overflowing.
+1:	cmp	\divisor, #0x80000000
+	cmplo	\divisor, \dividend
+	movlo	\divisor, \divisor, lsl #1
+	addlo	\order, \order, #1
+	blo	1b
+
+#endif
+
+	@ Perform all needed substractions to keep only the reminder.
+	@ Do comparisons in batch of 4 first.
+	subs	\order, \order, #3		@ yes, 3 is intended here
+	blt	2f
+
+1:	cmp	\dividend, \divisor
+	subhs	\dividend, \dividend, \divisor
+	cmp	\dividend, \divisor,  lsr #1
+	subhs	\dividend, \dividend, \divisor, lsr #1
+	cmp	\dividend, \divisor,  lsr #2
+	subhs	\dividend, \dividend, \divisor, lsr #2
+	cmp	\dividend, \divisor,  lsr #3
+	subhs	\dividend, \dividend, \divisor, lsr #3
+	cmp	\dividend, #1
+	mov	\divisor, \divisor, lsr #4
+	subges	\order, \order, #4
+	bge	1b
+
+	tst	\order, #3
+	teqne	\dividend, #0
+	beq	5f
+
+	@ Either 1, 2 or 3 comparison/substractions are left.
+2:	cmn	\order, #2
+	blt	4f
+	beq	3f
+	cmp	\dividend, \divisor
+	subhs	\dividend, \dividend, \divisor
+	mov	\divisor,  \divisor,  lsr #1
+3:	cmp	\dividend, \divisor
+	subhs	\dividend, \dividend, \divisor
+	mov	\divisor,  \divisor,  lsr #1
+4:	cmp	\dividend, \divisor
+	subhs	\dividend, \dividend, \divisor
+5:
+.endm
+
+	.align	5
+.globl __modsi3
+__modsi3:
+	cmp	r1, #0
+	beq	Ldiv0
+	rsbmi	r1, r1, #0			@ loops below use unsigned.
+	movs	ip, r0				@ preserve sign of dividend
+	rsbmi	r0, r0, #0			@ if negative make positive
+	subs	r2, r1, #1			@ compare divisor with 1
+	cmpne	r0, r1				@ compare dividend with divisor
+	moveq	r0, #0
+	tsthi	r1, r2				@ see if divisor is power of 2
+	andeq	r0, r0, r2
+	bls	10f
+
+	ARM_MOD_BODY r0, r1, r2, r3
+
+10:	cmp	ip, #0
+	rsbmi	r0, r0, #0
+	mov	pc, lr
+
+
+Ldiv0:
+
+	str	lr, [sp, #-4]!
+	bl	__div0
+	mov	r0, #0			@ About as wrong as it could be.
+	ldr	pc, [sp], #4
diff --git a/boot/common/src/uboot/arch/arm/lib/_udivsi3.S b/boot/common/src/uboot/arch/arm/lib/_udivsi3.S
new file mode 100644
index 0000000..1309802
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/_udivsi3.S
@@ -0,0 +1,93 @@
+/* # 1 "libgcc1.S" */
+@ libgcc1 routines for ARM cpu.
+@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
+dividend	.req	r0
+divisor		.req	r1
+result		.req	r2
+curbit		.req	r3
+/* ip		.req	r12	*/
+/* sp		.req	r13	*/
+/* lr		.req	r14	*/
+/* pc		.req	r15	*/
+	.text
+	.globl	 __udivsi3
+	.type	__udivsi3 ,function
+	.globl	__aeabi_uidiv
+	.type	__aeabi_uidiv ,function
+	.align	0
+ __udivsi3:
+ __aeabi_uidiv:
+	cmp	divisor, #0
+	beq	Ldiv0
+	mov	curbit, #1
+	mov	result, #0
+	cmp	dividend, divisor
+	bcc	Lgot_result
+Loop1:
+	@ Unless the divisor is very big, shift it up in multiples of
+	@ four bits, since this is the amount of unwinding in the main
+	@ division loop.  Continue shifting until the divisor is
+	@ larger than the dividend.
+	cmp	divisor, #0x10000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #4
+	movcc	curbit, curbit, lsl #4
+	bcc	Loop1
+Lbignum:
+	@ For very big divisors, we must shift it a bit at a time, or
+	@ we will be in danger of overflowing.
+	cmp	divisor, #0x80000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #1
+	movcc	curbit, curbit, lsl #1
+	bcc	Lbignum
+Loop3:
+	@ Test for possible subtractions, and note which bits
+	@ are done in the result.  On the final pass, this may subtract
+	@ too much from the dividend, but the result will be ok, since the
+	@ "bit" will have been shifted out at the bottom.
+	cmp	dividend, divisor
+	subcs	dividend, dividend, divisor
+	orrcs	result, result, curbit
+	cmp	dividend, divisor, lsr #1
+	subcs	dividend, dividend, divisor, lsr #1
+	orrcs	result, result, curbit, lsr #1
+	cmp	dividend, divisor, lsr #2
+	subcs	dividend, dividend, divisor, lsr #2
+	orrcs	result, result, curbit, lsr #2
+	cmp	dividend, divisor, lsr #3
+	subcs	dividend, dividend, divisor, lsr #3
+	orrcs	result, result, curbit, lsr #3
+	cmp	dividend, #0			@ Early termination?
+	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+	movne	divisor, divisor, lsr #4
+	bne	Loop3
+Lgot_result:
+	mov	r0, result
+	mov	pc, lr
+Ldiv0:
+	str	lr, [sp, #-4]!
+	bl	 __div0       (PLT)
+	mov	r0, #0			@ about as wrong as it could be
+	ldmia	sp!, {pc}
+	.size  __udivsi3       , . -  __udivsi3
+
+.globl __aeabi_uidivmod
+__aeabi_uidivmod:
+
+	stmfd	sp!, {r0, r1, ip, lr}
+	bl	__aeabi_uidiv
+	ldmfd	sp!, {r1, r2, ip, lr}
+	mul	r3, r0, r2
+	sub	r1, r1, r3
+	mov	pc, lr
+
+.globl __aeabi_idivmod
+__aeabi_idivmod:
+
+	stmfd	sp!, {r0, r1, ip, lr}
+	bl	__aeabi_idiv
+	ldmfd	sp!, {r1, r2, ip, lr}
+	mul	r3, r0, r2
+	sub	r1, r1, r3
+	mov	pc, lr
diff --git a/boot/common/src/uboot/arch/arm/lib/_umodsi3.S b/boot/common/src/uboot/arch/arm/lib/_umodsi3.S
new file mode 100644
index 0000000..8465ef0
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/_umodsi3.S
@@ -0,0 +1,88 @@
+/* # 1 "libgcc1.S" */
+@ libgcc1 routines for ARM cpu.
+@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk)
+/* # 145 "libgcc1.S" */
+dividend	.req	r0
+divisor		.req	r1
+overdone	.req	r2
+curbit		.req	r3
+/* ip		.req	r12	*/
+/* sp		.req	r13	*/
+/* lr		.req	r14	*/
+/* pc		.req	r15	*/
+	.text
+	.globl	 __umodsi3
+	.type  __umodsi3       ,function
+	.align 0
+ __umodsi3      :
+	cmp	divisor, #0
+	beq	Ldiv0
+	mov	curbit, #1
+	cmp	dividend, divisor
+	movcc	pc, lr
+Loop1:
+	@ Unless the divisor is very big, shift it up in multiples of
+	@ four bits, since this is the amount of unwinding in the main
+	@ division loop.  Continue shifting until the divisor is
+	@ larger than the dividend.
+	cmp	divisor, #0x10000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #4
+	movcc	curbit, curbit, lsl #4
+	bcc	Loop1
+Lbignum:
+	@ For very big divisors, we must shift it a bit at a time, or
+	@ we will be in danger of overflowing.
+	cmp	divisor, #0x80000000
+	cmpcc	divisor, dividend
+	movcc	divisor, divisor, lsl #1
+	movcc	curbit, curbit, lsl #1
+	bcc	Lbignum
+Loop3:
+	@ Test for possible subtractions.  On the final pass, this may
+	@ subtract too much from the dividend, so keep track of which
+	@ subtractions are done, we can fix them up afterwards...
+	mov	overdone, #0
+	cmp	dividend, divisor
+	subcs	dividend, dividend, divisor
+	cmp	dividend, divisor, lsr #1
+	subcs	dividend, dividend, divisor, lsr #1
+	orrcs	overdone, overdone, curbit, ror #1
+	cmp	dividend, divisor, lsr #2
+	subcs	dividend, dividend, divisor, lsr #2
+	orrcs	overdone, overdone, curbit, ror #2
+	cmp	dividend, divisor, lsr #3
+	subcs	dividend, dividend, divisor, lsr #3
+	orrcs	overdone, overdone, curbit, ror #3
+	mov	ip, curbit
+	cmp	dividend, #0			@ Early termination?
+	movnes	curbit, curbit, lsr #4		@ No, any more bits to do?
+	movne	divisor, divisor, lsr #4
+	bne	Loop3
+	@ Any subtractions that we should not have done will be recorded in
+	@ the top three bits of "overdone".  Exactly which were not needed
+	@ are governed by the position of the bit, stored in ip.
+	@ If we terminated early, because dividend became zero,
+	@ then none of the below will match, since the bit in ip will not be
+	@ in the bottom nibble.
+	ands	overdone, overdone, #0xe0000000
+	moveq	pc, lr				@ No fixups needed
+	tst	overdone, ip, ror #3
+	addne	dividend, dividend, divisor, lsr #3
+	tst	overdone, ip, ror #2
+	addne	dividend, dividend, divisor, lsr #2
+	tst	overdone, ip, ror #1
+	addne	dividend, dividend, divisor, lsr #1
+	mov	pc, lr
+Ldiv0:
+	str	lr, [sp, #-4]!
+	bl	 __div0       (PLT)
+	mov	r0, #0			@ about as wrong as it could be
+	ldmia	sp!, {pc}
+	.size  __umodsi3       , . -  __umodsi3
+/* # 320 "libgcc1.S" */
+/* # 421 "libgcc1.S" */
+/* # 433 "libgcc1.S" */
+/* # 456 "libgcc1.S" */
+/* # 500 "libgcc1.S" */
+/* # 580 "libgcc1.S" */
diff --git a/boot/common/src/uboot/arch/arm/lib/board.c b/boot/common/src/uboot/arch/arm/lib/board.c
new file mode 100755
index 0000000..6a2f577
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/board.c
@@ -0,0 +1,417 @@
+/*  
+ * (C) Copyright 2016, ZIXC Corporation.
+ *
+ * (C) Copyright 2002-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ */
+#include <common.h>
+#include <command.h>
+#include <malloc.h>
+#include <stdio_dev.h>
+#include <version.h>
+#include <net.h>
+#include <serial.h>
+#include <nand.h>
+#include <onenand_uboot.h>
+#include <mmc.h>
+#include <timer.h>
+#include <asm/arch/lsp_crpm.h>
+#include <asm/arch/cpu.h>
+#include <config.h>
+#include <drvs_gpio.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+ulong monitor_flash_len;
+
+#if defined(CONFIG_HARD_I2C) || \
+    defined(CONFIG_SOFT_I2C)
+#include <i2c.h>
+#endif
+
+/*
+ ************************************************************************
+ * Init Utilities							*
+ ************************************************************************
+ * Some of this code should be moved into the core functions,
+ * or dropped completely,
+ * but let's get it working (again) first...
+ */
+
+#if defined(CONFIG_ARM_DCC) && !defined(CONFIG_BAUDRATE)
+#define CONFIG_BAUDRATE 115200
+#endif
+static int init_baudrate(void)
+{
+	char tmp[64];	/* long enough for environment variables */
+	int i = getenv_f("baudrate", tmp, sizeof(tmp));
+
+	gd->baudrate = (i > 0)
+			? (int) simple_strtoul(tmp, NULL, 10)
+			: CONFIG_BAUDRATE;
+
+	return (0);
+}
+
+static int display_banner(void)
+{
+	printf("\n\n%s\n\n", version_string);
+	debug("U-Boot code: 0x%08lX -> 0x%08lX  BSS: -> 0x%08lX\n",
+	       _TEXT_BASE,
+	       _bss_start_ofs + _TEXT_BASE, _bss_end_ofs + _TEXT_BASE);
+#ifdef CONFIG_MODEM_SUPPORT
+	debug("Modem Support enabled\n");
+#endif
+#if CONFIG_USE_IRQ
+	debug("IRQ Stack: 0x%08lx\n", IRQ_STACK_START);
+	debug("FIQ Stack: 0x%08lx\n", FIQ_STACK_START);
+#endif
+
+	return (0);
+}
+
+/*
+ * WARNING: this code looks "cleaner" than the PowerPC version, but
+ * has the disadvantage that you either get nothing, or everything.
+ * On PowerPC, you might see "DRAM: " before the system hangs - which
+ * gives a simple yet clear indication which part of the
+ * initialization if failing.
+ */
+static int display_dram_config(void)
+{
+	int i;
+
+#if DEBUG
+	puts("RAM Configuration:\n");
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		printf("Bank #%d: 0x%08lx ", i, gd->bd->bi_dram[i].start);
+		print_size(gd->bd->bi_dram[i].size, "\n");
+	}
+#else
+	ulong size = 0;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
+		size += gd->bd->bi_dram[i].size;
+
+	puts("DRAM:  ");
+	print_size(size, "\n");
+#endif
+
+	return (0);
+}
+
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+static int init_func_i2c(void)
+{
+	puts("I2C:   ");
+	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+	puts("ready\n");
+	return (0);
+}
+#endif
+
+
+/*
+ * Breathe some life into the board...
+ *
+ * Initialize a serial port as console, and carry out some hardware
+ * tests.
+ *
+ * The first part of initialization is running from Flash memory;
+ * its main purpose is to initialize the RAM so that we
+ * can relocate the monitor code to RAM.
+ */
+
+typedef int (init_fnc_t) (void);
+
+int print_cpuinfo(void);
+
+/* ================================================================================
+ * 
+ */
+void __dram_init_banksize(void)
+{
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+	gd->bd->bi_dram[0].size =  gd->ram_size;
+}
+
+/* ================================================================================
+ * 
+ */
+void dram_init_banksize(void)
+	__attribute__((weak, alias("__dram_init_banksize")));
+
+
+/* ================================================================================
+ * 
+ */
+init_fnc_t *init_sequence[] = {
+#if defined(CONFIG_ARCH_CPU_INIT)
+	arch_cpu_init,		/* basic arch cpu dependent setup */
+#endif
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+	board_early_init_f,
+#endif
+	gpio_pad_init2rst,
+	//clk_init,
+	timer_init,		/* initialize timer */
+#ifdef CONFIG_FSL_ESDHC
+	get_clocks,
+#endif
+	env_init,		/* initialize environment */
+	init_baudrate,		/* initialze baudrate settings */
+#if (CONFIG_PRINTF||CONFIG_UART_DL)
+	serial_init,		/* serial communications setup */
+#endif	
+	console_init_f,		/* stage 1 init of console */
+	display_banner,		/* say that we are here */
+#if defined(CONFIG_DISPLAY_CPUINFO)
+	print_cpuinfo,		/* display cpu info (and speed) */
+#endif
+#if defined(CONFIG_DISPLAY_BOARDINFO)
+	checkboard,		/* display board info */
+#endif
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
+	init_func_i2c,
+#endif
+	dram_init,		/* configure available RAM banks */
+	NULL,
+};
+
+
+/* ================================================================================
+ * 
+ */
+void board_init_f(ulong bootflag)
+{
+	bd_t *bd;
+	init_fnc_t **init_fnc_ptr;
+	gd_t *id;
+	ulong addr, addr_sp;
+
+	/* Pointer is writable since we allocated a register for it */
+	gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);
+	/* compiler optimization barrier needed for GCC >= 3.4 */
+	__asm__ __volatile__("": : :"memory");
+
+	memset((void *)gd, 0, sizeof(gd_t));
+
+	gd->mon_len = CONFIG_SYS_UBOOT_SIZE; //zhouqi gd->mon_len = _bss_end_ofs;
+
+	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+		if ((*init_fnc_ptr)() != 0) {
+			hang ();
+		}
+	}
+
+	debug("monitor len: 0x%08lX\n", gd->mon_len);
+	/*
+	 * Ram is setup, size stored in gd !!
+	 */
+	debug("ramsize: 0x%08lX\n", gd->ram_size);
+
+	addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
+
+//#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
+	/* reserve TLB table */
+	addr -= (4096 * 4);
+
+	/* round down to next 64 kB limit */
+	addr &= ~(0x10000 - 1);
+
+	gd->tlb_addr = addr;
+	debug("TLB table at: 0x%08lx\n", addr);
+//#endif
+
+	/* round down to next 4 kB limit */
+	addr &= ~(4096 - 1);
+	debug("Top of RAM usable for U-Boot at: 0x%08lx\n", addr);
+
+	/*
+	 * reserve memory for U-Boot code, data & bss
+	 * round down to next 4 kB limit
+	 */
+	addr -= gd->mon_len;
+	addr &= ~(4096 - 1);
+
+	debug("Reserving %ldk for U-Boot at: 0x%08lx\n", gd->mon_len >> 10, addr);
+    
+	addr_sp = addr - CFG_DENALI_DMA_BUF_SIZE; //zhouqi for nand dma buffer 
+	debug("Reserving %dk for nand dma buffer at: 0x%08lx\n", CFG_DENALI_DMA_BUF_SIZE >> 10, addr_sp);
+
+#ifdef CONFIG_LCD                   //zhouqi exchange with u-boot code
+#ifdef CONFIG_FB_ADDR
+	gd->fb_base = CONFIG_FB_ADDR;
+#else
+	/* reserve memory for LCD display (always full pages) */
+	addr = lcd_setmem(addr);
+	gd->fb_base = addr;
+#endif /* CONFIG_FB_ADDR */
+#endif /* CONFIG_LCD */
+
+#ifndef CONFIG_SPL_BUILD
+	/*
+	 * reserve memory for malloc() arena
+	 */
+	addr_sp = addr - TOTAL_MALLOC_LEN - CFG_DENALI_DMA_BUF_SIZE;    /* zhouqi */
+	debug("Reserving %dk for malloc() at: 0x%08lx\n",
+			TOTAL_MALLOC_LEN >> 10, addr_sp);
+	/*
+	 * (permanently) allocate a Board Info struct
+	 * and a permanent copy of the "global" data
+	 */
+	addr_sp -= sizeof (bd_t);
+	bd = (bd_t *) addr_sp;
+	gd->bd = bd;
+	debug("Reserving %zu Bytes for Board Info at: 0x%08lx\n",
+			sizeof (bd_t), addr_sp);
+
+#ifdef CONFIG_MACH_TYPE
+	gd->bd->bi_arch_number = CONFIG_MACH_TYPE; /* board id for Linux */ 
+#endif
+
+	addr_sp -= sizeof (gd_t);
+	id = (gd_t *) addr_sp;
+	debug("Reserving %zu Bytes for Global Data at: 0x%08lx\n",
+			sizeof (gd_t), addr_sp);
+
+	/* setup stackpointer for exeptions */
+	gd->irq_sp = addr_sp;
+#if CONFIG_USE_IRQ
+	addr_sp -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
+	debug("Reserving %zu Bytes for IRQ stack at: 0x%08lx\n",
+		CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ, addr_sp);
+#endif
+	/* leave 3 words for abort-stack    */
+	addr_sp -= 12;
+
+	/* 8-byte alignment for ABI compliance */
+	addr_sp &= ~0x07;
+#else   //define CONFIG_SPL_BUILD
+	addr_sp += 128;	/* leave 32 words for abort-stack   */
+	gd->irq_sp = addr_sp;
+#endif
+
+	debug("New Stack Pointer is: 0x%08lx\n", addr_sp);
+
+#ifdef CONFIG_POST
+	post_bootmode_init();
+	post_run(NULL, POST_ROM | post_bootmode_get(0));
+#endif
+
+	gd->bd->bi_baudrate = gd->baudrate;
+	/* Ram ist board specific, so move it to board code ... */
+	dram_init_banksize();
+	display_dram_config();	/* and display it */
+
+	gd->relocaddr = addr;
+	gd->start_addr_sp = addr_sp;
+	gd->reloc_off = addr - _TEXT_BASE;
+	debug("relocation Offset is: 0x%08lx\n", gd->reloc_off);
+	memcpy(id, (void *)gd, sizeof(gd_t));
+
+	relocate_code(addr_sp, id, addr);
+
+	/* NOTREACHED - relocate_code() does not return */
+}
+
+#if !defined(CONFIG_SYS_NO_FLASH)
+static char *failed = "*** failed ***\n";
+#endif
+
+
+
+
+extern void pinmux_reset(void);
+extern void gpio_reset(void);
+extern void pcu_clear_8in1_Int(void);
+
+
+/* ================================================================================
+ * 
+ */
+void board_init_r(gd_t *id, ulong dest_addr)
+{
+	char *s;
+	//bd_t *bd;
+	ulong malloc_start;
+	u32 nand_status = 0;
+
+	gd = id;
+	//bd = gd->bd;
+
+	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
+
+	monitor_flash_len = _end_ofs;
+	//if flash type is nand flash,close I&D cache
+	get_boot_flashtype();
+	if(read_boot_flashtype()==IF_TYPE_NAND)
+	{
+		/* Disable caches */
+		icache_disable();
+		dcache_disable();
+	}
+	else
+	{
+		/* Enable caches */
+		icache_enable();
+		dcache_enable();
+		nand_status = readl(0x1306058);
+		nand_status &= ~(0x7 << 4);
+		writel(nand_status, 0x1306058); /* nand contrl reset, Solve the problems of pull high and self-excited vibration of NAND controller pin. */
+	}
+
+	debug("monitor flash len: 0x%08lX\n", monitor_flash_len);
+	board_init();	/* Setup chipselects */
+
+	debug("Now running in RAM - U-Boot at: 0x%08lX\n", dest_addr);
+
+	/* The Malloc area is immediately below the monitor copy in DRAM */
+	malloc_start = dest_addr - TOTAL_MALLOC_LEN;
+	mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN);
+
+	/* initialize environment */
+	env_relocate();
+
+	/* IP Address */
+	gd->bd->bi_ip_addr = getenv_IPaddr("ipaddr");
+
+	stdio_init();	/* get the devices list going. */
+
+	jumptable_init();
+
+	console_init_r();	/* fully init console as a device */
+
+	/* set up exceptions */
+	interrupt_init();
+	/* enable exceptions */
+	enable_interrupts();
+
+	/* Initialize from environment */
+	s = getenv("loadaddr");
+	if (s != NULL)
+	{
+		load_addr = simple_strtoul(s, NULL, 16);
+	}
+
+	//gpio_reset();
+	//pinmux_reset();
+	//pcu_clear_8in1_Int();
+	
+	sys_entry();
+    
+}
+
+
+void hang(void)
+{
+	puts("### [u-boot] ERROR ### Please RESET the board ###\n");
+	for (;;);
+}
+
diff --git a/boot/common/src/uboot/arch/arm/lib/bootm.c b/boot/common/src/uboot/arch/arm/lib/bootm.c
new file mode 100755
index 0000000..914259d
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/bootm.c
@@ -0,0 +1,491 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Copyright (C) 2001  Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <image.h>
+#include <u-boot/zlib.h>
+#include <asm/byteorder.h>
+#include <fdt.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <bootimg.h>
+#include <load_image.h> 
+#include <asm/arch/cpu.h>
+#include <asm/io.h>
+#include <fdt_support.h>
+#include <asm/arch/efuse.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+    defined (CONFIG_CMDLINE_TAG) || \
+    defined (CONFIG_INITRD_TAG) || \
+    defined (CONFIG_SERIAL_TAG) || \
+    defined (CONFIG_REVISION_TAG)
+static void setup_start_tag (bd_t *bd);
+
+# ifdef CONFIG_SETUP_MEMORY_TAGS
+static void setup_memory_tags (bd_t *bd);
+# endif
+static void setup_commandline_tag (bd_t *bd, char *commandline);
+
+# ifdef CONFIG_INITRD_TAG
+static void setup_initrd_tag (bd_t *bd, ulong initrd_start,
+			      ulong initrd_end);
+# endif
+static void setup_end_tag (bd_t *bd);
+
+static struct tag *params;
+#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
+
+static ulong get_sp(void);
+#if defined(CONFIG_OF_LIBFDT)
+static int bootm_linux_fdt(int machid, bootm_headers_t *images);
+#endif
+extern int rd_offset ;
+extern int rd_size;
+extern unsigned int g_sys_kernel_sdram_size;
+extern unsigned char g_ddr_size_flag;
+
+#define reg32(addr)			(*(volatile unsigned long *)(addr))
+
+void arch_lmb_reserve(struct lmb *lmb)
+{
+	ulong sp;
+
+	/*
+	 * Booting a (Linux) kernel image
+	 *
+	 * Allocate space for command line and board info - the
+	 * address should be as high as possible within the reach of
+	 * the kernel (see CONFIG_SYS_BOOTMAPSZ settings), but in unused
+	 * memory, which means far enough below the current stack
+	 * pointer.
+	 */
+	sp = get_sp();
+	debug("## Current stack ends at 0x%08lx ", sp);
+
+	/* adjust sp by 1K to be safe */
+	sp -= 1024;
+	lmb_reserve(lmb, sp,
+		    gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
+}
+
+static void announce_and_cleanup(void)
+{
+	printf("\nStarting kernel ...\n");
+
+#ifdef CONFIG_USB_DEVICE
+	{
+		extern void udc_disconnect(void);
+		udc_disconnect();
+	}
+#endif
+	cleanup_before_linux();
+}
+
+//#ifdef CONFIG_ZX297520V3E_WATCH_CAP
+#if defined(CONFIG_ZX297520V3E_WATCH_CAP) || defined (CONFIG_ZX297520V3E_VEHICLE_DC) || defined (CONFIG_ZX297520V3E_VEHICLE_DC_REF)
+#define SYS_CPUCAP_PARAM_ADDR	0x10200C
+extern uint32_t arm_cpucap_ep;
+void set_cpucap_tag(int arch, uint parameter)
+{
+	uint32_t cap_tag_addr = 0;
+	
+	cap_tag_addr = arm_cpucap_ep - 0x8000 + 0x100;
+	
+	writel(0x0, SYS_CPUCAP_PARAM_ADDR);
+	writel(arch, SYS_CPUCAP_PARAM_ADDR+0x4);
+	writel(cap_tag_addr, SYS_CPUCAP_PARAM_ADDR+0x8);
+
+	memcpy(cap_tag_addr, parameter, 0x800);
+}
+#endif
+
+int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
+{
+	bd_t	*bd = gd->bd;
+	char	*s;
+	int machid = bd->bi_arch_number; 
+	void	(*kernel_entry)(int zero, int arch, uint params);
+	
+
+#ifdef CONFIG_CMDLINE_TAG
+	char *commandline = getenv ("bootargs");
+#endif
+
+	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
+	{
+		return 1;
+	}
+
+	
+	s = getenv ("machid");
+	if (s)
+	{
+		machid = simple_strtoul (s, NULL, 16);
+		printf ("Using machid 0x%x from environment\n", machid);
+	}
+
+	show_boot_progress (15);
+
+#ifdef CONFIG_OF_LIBFDT
+#if 0
+	if (images->ft_len)
+	{
+        debug("start device tree...\n");
+		//return bootm_linux_fdt(machid, images);
+		bootm_linux_fdt(machid, images);
+	}
+#endif
+#if defined(CONFIG_ZX297520V3E_VEHICLE_DC) || defined(CONFIG_ZX297520V3E_VEHICLE_DC_REF)
+        debug("start device tree...\n");
+		bootm_linux_fdt(machid, images);
+		//fdt_chosen(images->ft_addr, 1);
+#endif
+
+#endif
+
+	kernel_entry = (void (*)(int, int, uint))images->ep;
+
+	debug ("## Transferring control to Linux (at address %08lx) ...\n",
+	       (ulong) kernel_entry);
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+    defined (CONFIG_CMDLINE_TAG) || \
+    defined (CONFIG_INITRD_TAG) || \
+    defined (CONFIG_SERIAL_TAG) || \
+    defined (CONFIG_REVISION_TAG)
+	setup_start_tag (bd);
+#ifdef CONFIG_SERIAL_TAG
+	setup_serial_tag (&params);
+#endif
+#ifdef CONFIG_REVISION_TAG
+	setup_revision_tag (&params);
+#endif
+#ifdef CONFIG_SETUP_MEMORY_TAGS
+	setup_memory_tags (bd);
+#endif
+#ifdef CONFIG_CMDLINE_TAG
+	setup_commandline_tag (bd, commandline);
+#endif
+#ifdef CONFIG_INITRD_TAG
+	if (images->rd_start && images->rd_end)
+		setup_initrd_tag (bd, images->rd_start, images->rd_end);
+#endif
+	setup_end_tag(bd);
+#endif
+
+//#ifdef CONFIG_ZX297520V3E_WATCH_CAP	
+#if defined(CONFIG_ZX297520V3E_WATCH_CAP) || defined (CONFIG_ZX297520V3E_VEHICLE_DC) || defined (CONFIG_ZX297520V3E_VEHICLE_DC_REF)
+	memset(ICP_CAP_BUF_ADDR, 0, ICP_CAP_BUF_LEN);
+	memset(IRAM_BASE_ADDR_SYS_TRACE, 0, IRAM_BASE_LEN_SYS_TRACE);
+	if(!read_fota_update_flag())
+	{		
+		cap_poweron();
+		set_cpucap_tag(machid, bd->bi_boot_params);
+		start_cpucap_cores();
+	}
+#endif
+	printf("===chiid=0x%x,boot_params=0x%x\n", machid, bd->bi_boot_params);
+	announce_and_cleanup();
+	kernel_entry(0, machid, bd->bi_boot_params);
+
+	/* does not return */
+	return 1;
+}
+
+//add by zhouqi
+int do_booti_linux( boot_img_hdr *hdr )
+{
+	bd_t	*bd = gd->bd;
+	char	*s;
+	int	machid = bd->bi_arch_number;
+	void	(*kernel_entry)(int zero, int arch, uint params);
+
+#ifdef CONFIG_CMDLINE_TAG
+	char *commandline = getenv ("bootargs");
+#endif
+
+	s = getenv ("machid");
+	if (s) {
+		machid = simple_strtoul (s, NULL, 16);
+		printf ("Using machid 0x%x from environment\n", machid);
+	}
+
+	show_boot_progress (15);
+
+#ifdef CONFIG_OF_LIBFDT
+	//if (images->ft_len)
+		//return bootm_linux_fdt(machid, images);
+#endif
+
+	kernel_entry = (void (*)(int, int, uint))hdr->kernel_addr;
+
+	debug ("## Transferring control to Linux (at address %08lx) ...\n",
+	       (ulong) kernel_entry);
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+    defined (CONFIG_CMDLINE_TAG) || \
+    defined (CONFIG_INITRD_TAG) || \
+    defined (CONFIG_SERIAL_TAG) || \
+    defined (CONFIG_REVISION_TAG)
+	setup_start_tag (bd);
+#ifdef CONFIG_SERIAL_TAG
+	setup_serial_tag (&params);
+#endif
+#ifdef CONFIG_REVISION_TAG
+	setup_revision_tag (&params);
+#endif
+#ifdef CONFIG_SETUP_MEMORY_TAGS
+	setup_memory_tags (bd);
+#endif
+#ifdef CONFIG_CMDLINE_TAG
+	setup_commandline_tag (bd, commandline);
+#endif
+#ifdef CONFIG_INITRD_TAG
+	if (hdr->ramdisk_size)
+		setup_initrd_tag (bd, hdr->ramdisk_addr, hdr->ramdisk_size + hdr->ramdisk_addr);
+#endif
+	setup_end_tag(bd);
+#endif
+
+	announce_and_cleanup();
+
+	kernel_entry(0, machid, bd->bi_boot_params);
+	/* does not return */
+
+	return 1;
+}
+
+
+#if defined(CONFIG_OF_LIBFDT)
+static int fixup_memory_node(void *blob)
+{
+	bd_t	*bd = gd->bd;
+	int bank;
+	u64 start[CONFIG_NR_DRAM_BANKS];
+	u64 size[CONFIG_NR_DRAM_BANKS];
+
+	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
+		//start[bank] = bd->bi_dram[bank].start;
+		//size[bank] = bd->bi_dram[bank].size;
+		start[bank] = DDR_BASE_ADDR_CAP;
+		if(g_ddr_size_flag == CHIP_DDR_IS_128M)
+		{
+			size[bank] = DDR_BASE_LEN_CAP;
+			reg32(IRAM_BASE_ADDR_BOOT_DDR) = DDR_BASE_LEN_CAP;
+		}		
+		else if(g_ddr_size_flag == CHIP_DDR_IS_256M) 
+		{
+			size[bank] = DDR_BASE_LEN_CAP + 0x8000000;
+			reg32(IRAM_BASE_ADDR_BOOT_DDR) = (DDR_BASE_LEN_CAP + 0x8000000);
+		}
+		else if(g_ddr_size_flag == CHIP_DDR_IS_512M) 
+		{
+			size[bank] = DDR_BASE_LEN_CAP + 0x18000000;
+			reg32(IRAM_BASE_ADDR_BOOT_DDR) = (DDR_BASE_LEN_CAP + 0x18000000);
+		}
+		else
+		{
+            debug("ddr size is error.\n");
+			return 0;
+		}
+	}
+	debug("size is 0x%llx\n",size[0]);
+	return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
+}
+
+static int bootm_linux_fdt(int machid, bootm_headers_t *images)
+{
+	ulong rd_len;
+	void (*kernel_entry)(int zero, int dt_machid, void *dtblob);
+	ulong of_size = images->ft_len;
+	char **of_flat_tree = &images->ft_addr;
+	ulong *initrd_start = &images->initrd_start;
+	ulong *initrd_end = &images->initrd_end;
+	struct lmb *lmb = &images->lmb;
+	int ret;
+
+	kernel_entry = (void (*)(int, int, void *))images->ep;
+
+	boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);
+
+	rd_len = images->rd_end - images->rd_start;
+	ret = boot_ramdisk_high(lmb, images->rd_start, rd_len,
+				initrd_start, initrd_end);
+	if (ret)
+		return ret;
+
+	ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
+	if (ret)
+		return ret;
+
+	debug("## Transferring control to Linux (at address %08lx) ...\n",
+	       (ulong) kernel_entry);
+
+	fdt_chosen(*of_flat_tree, 1);
+	
+	fixup_memory_node(*of_flat_tree);
+
+#if 0
+	fdt_initrd(*of_flat_tree, *initrd_start, *initrd_end, 1);
+
+	announce_and_cleanup();
+
+	kernel_entry(0, machid, *of_flat_tree);
+	/* does not return */
+#endif 
+	return 1;
+}
+#endif
+
+#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
+    defined (CONFIG_CMDLINE_TAG) || \
+    defined (CONFIG_INITRD_TAG) || \
+    defined (CONFIG_SERIAL_TAG) || \
+    defined (CONFIG_REVISION_TAG)
+static void setup_start_tag (bd_t *bd)
+{
+	params = (struct tag *) bd->bi_boot_params;
+
+	params->hdr.tag = ATAG_CORE;
+	params->hdr.size = tag_size (tag_core);
+
+	params->u.core.flags = 0x1;//0;
+	params->u.core.pagesize =0x1000; //0;
+	params->u.core.rootdev = 0x0;//0;
+
+	params = tag_next (params);
+}
+
+
+#ifdef CONFIG_SETUP_MEMORY_TAGS
+static void setup_memory_tags (bd_t *bd)
+{
+	int i;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
+	{
+		params->hdr.tag = ATAG_MEM;
+		params->hdr.size = tag_size (tag_mem32);
+
+		/* modify by zhouqi  2013/06/27 */
+		params->u.mem.start = read_sys_ddr_kernel_start();
+		params->u.mem.size = g_sys_kernel_sdram_size; //CONFIG_SYS_SDRAM_A9_SIZE;
+       
+		params = tag_next (params);
+	}
+}
+#endif /* CONFIG_SETUP_MEMORY_TAGS */
+
+
+static void setup_commandline_tag (bd_t *bd, char *commandline)
+{
+	char *p;
+
+	if (!commandline)
+		return;
+
+	/* eat leading white space */
+	for (p = commandline; *p == ' '; p++);
+
+	/* skip non-existent command lines so the kernel will still
+	 * use its default command line.
+	 */
+	if (*p == '\0')
+		return;
+
+	params->hdr.tag = ATAG_CMDLINE;
+	params->hdr.size =
+		(sizeof (struct tag_header) + strlen (p) + 1 + 4) >> 2;
+
+	strcpy (params->u.cmdline.cmdline, p);
+
+	params = tag_next (params);
+}
+
+
+#ifdef CONFIG_INITRD_TAG
+static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
+{
+	/* an ATAG_INITRD node tells the kernel where the compressed
+	 * ramdisk can be found. ATAG_RDIMG is a better name, actually.
+	 */
+	params->hdr.tag = ATAG_INITRD2;
+	params->hdr.size = tag_size (tag_initrd);
+
+	params->u.initrd.start = rd_offset;//initrd_start;
+	params->u.initrd.size =rd_size;//initrd_end - initrd_start;
+
+
+	params = tag_next (params);
+}
+#endif /* CONFIG_INITRD_TAG */
+
+#ifdef CONFIG_SERIAL_TAG
+void setup_serial_tag (struct tag **tmp)
+{
+	struct tag *params = *tmp;
+	struct tag_serialnr serialnr;
+	void get_board_serial(struct tag_serialnr *serialnr);
+
+	get_board_serial(&serialnr);
+	params->hdr.tag = ATAG_SERIAL;
+	params->hdr.size = tag_size (tag_serialnr);
+	params->u.serialnr.low = serialnr.low;
+	params->u.serialnr.high= serialnr.high;
+	params = tag_next (params);
+	*tmp = params;
+}
+#endif
+
+#ifdef CONFIG_REVISION_TAG
+void setup_revision_tag(struct tag **in_params)
+{
+	u32 rev = 0;
+	u32 get_board_rev(void);
+
+	rev = get_board_rev();
+	params->hdr.tag = ATAG_REVISION;
+	params->hdr.size = tag_size (tag_revision);
+	params->u.revision.rev = rev;
+	params = tag_next (params);
+}
+#endif  /* CONFIG_REVISION_TAG */
+
+static void setup_end_tag (bd_t *bd)
+{
+	params->hdr.tag = ATAG_NONE;
+	params->hdr.size = 0;
+}
+#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
+
+static ulong get_sp(void)
+{
+	ulong ret;
+
+	asm("mov %0, sp" : "=r"(ret) : );
+	return ret;
+}
diff --git a/boot/common/src/uboot/arch/arm/lib/cache-cp15.c b/boot/common/src/uboot/arch/arm/lib/cache-cp15.c
new file mode 100644
index 0000000..a73e7f9
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/cache-cp15.c
@@ -0,0 +1,229 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/system.h>
+#include <boot_mode.h>
+#include <mpu.h>
+
+#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
+
+#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH)
+#define CACHE_SETUP	0x1a
+#else
+#define CACHE_SETUP	0x1e
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+extern void invalidate_dcache_all(void);
+
+void __arm_init_before_mmu(void)
+{
+}
+void arm_init_before_mmu(void)
+	__attribute__((weak, alias("__arm_init_before_mmu")));
+
+static void cp_delay (void)
+{
+	volatile int i;
+
+	/* copro seems to need some delay between reading and writing */
+	for (i = 0; i < 100; i++)
+		nop();
+	asm volatile("" : : : "memory");
+}
+
+static inline void dram_bank_mmu_setup(int bank)
+{
+	u32 *page_table = (u32 *)gd->tlb_addr;
+	bd_t *bd = gd->bd;
+	int	i;
+
+	debug("%s: bank: %d\n", __func__, bank);
+
+    for (i = bd->bi_dram[bank].start >> 20;
+	            i < (bd->bi_dram[bank].start + bd->bi_dram[bank].size) >> 20;
+	            i++) 
+    {
+		page_table[i] = i << 20 | (3 << 10) | 
+                            (0 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1);
+                          /* D                                           C          B */
+	}    
+
+    /* for nand DMA addr ,no cache 21B00000--21C00000 */
+    i = CONFIG_NAND_DMA_BUF_ADDR >> 20;
+    page_table[i] = i << 20 | (3 << 10) | 
+	                    (0 << 5) | (1 << 4) | (0 << 3) | (0 << 2) | (1 << 1);
+                      /* D                                         C          B */
+	/* for USB addr ,no cache 22000000--24000000*/
+#if 0					  
+	for (i = CONFIG_USB_DMA_BUF_ADDR >> 20;i <= ((CONFIG_USB_DMA_BUF_ADDR+32*1024*1024) >> 20);i++) 
+	{
+		page_table[i] = i << 20 | (3 << 10) | 
+	                    (0 << 5) | (1 << 4) | (0 << 3) | (0 << 2) | (1 << 1);
+                      /* D                                         C          B */
+	}
+#endif
+}
+
+
+/* to activate the MMU we need to set up virtual memory: use 1M areas */
+static inline void mmu_setup(void)
+{
+	u32 *page_table = (u32 *)gd->tlb_addr;
+	int i;
+	u32 reg;
+
+	arm_init_before_mmu();
+	/* Set up an identity-mapping for all 4GB, rw for everyone */
+	
+	for (i = 0; i < 4096; i++)
+		page_table[i] = i << 20 | (3 << 10) | 
+		                    (0 << 5) | (1 << 4) | (0 << 3) | (0 << 2) | (1 << 1);
+                          /* D                     C          B */
+    #if 1
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		dram_bank_mmu_setup(i);
+	}
+	#endif
+
+	/* Copy the page table address to cp15 */
+	asm volatile("mcr p15, 0, %0, c2, c0, 0"
+		     : : "r" (page_table) : "memory");
+	/* Set the access control to all-supervisor */
+	asm volatile("mcr p15, 0, %0, c3, c0, 0"
+		     : : "r" (~0));
+	/* and enable the mmu */
+	reg = get_cr();	/* get control reg. */
+	cp_delay();
+	set_cr(reg | CR_M);
+}
+
+static int mmu_enabled(void)
+{
+	return get_cr() & CR_M;
+}
+
+/* cache_bit must be either CR_I or CR_C */
+static void cache_enable(uint32_t cache_bit)
+{
+	uint32_t reg;
+
+    invalidate_dcache_all();
+	/* The data cache is not active unless the mmu is enabled too */
+	if ((cache_bit == CR_C) && !mmu_enabled())
+	{
+		mmu_setup();	
+	}
+	reg = get_cr();	/* get control reg. */
+	cp_delay();
+	set_cr(reg | cache_bit);
+	return;
+}
+
+/* cache_bit must be either CR_I or CR_C */
+static void cache_disable(uint32_t cache_bit)
+{
+	uint32_t reg;
+
+	if (cache_bit == CR_C) {
+		/* if cache isn;t enabled no need to disable */
+		reg = get_cr();
+		if ((reg & CR_C) != CR_C)
+		{
+			return;
+		}
+			
+		/* if disabling data cache, disable mmu too */
+		cache_bit |= CR_M;
+		flush_dcache_all();
+	}
+	reg = get_cr();
+	cp_delay();
+	set_cr(reg & ~cache_bit);
+}
+#endif
+
+#ifdef CONFIG_SYS_ICACHE_OFF
+void icache_enable (void)
+{
+	return;
+}
+
+void icache_disable (void)
+{
+	return;
+}
+
+int icache_status (void)
+{
+	return 0;					/* always off */
+}
+#else
+void icache_enable(void)
+{
+	cache_enable(CR_I);
+}
+
+void icache_disable(void)
+{
+	cache_disable(CR_I);
+}
+
+int icache_status(void)
+{
+	return (get_cr() & CR_I) != 0;
+}
+#endif
+
+#ifdef CONFIG_SYS_DCACHE_OFF
+void dcache_enable (void)
+{
+	return;
+}
+
+void dcache_disable (void)
+{
+	return;
+}
+
+int dcache_status (void)
+{
+	return 0;					/* always off */
+}
+#else
+void dcache_enable(void)
+{
+	cache_enable(CR_C);
+}
+
+void dcache_disable(void)
+{
+	cache_disable(CR_C);
+}
+
+int dcache_status(void)
+{
+	return (get_cr() & CR_C) != 0;
+}
+#endif
diff --git a/boot/common/src/uboot/arch/arm/lib/cache-pl310.c b/boot/common/src/uboot/arch/arm/lib/cache-pl310.c
new file mode 100644
index 0000000..8337cc3
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/cache-pl310.c
@@ -0,0 +1,147 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh@ti.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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/armv7.h>
+#include <asm/pl310.h>
+#include <config.h>
+#include <common.h>
+
+struct pl310_regs *const pl310 = (struct pl310_regs *)CONFIG_SYS_PL310_BASE;
+
+#if 0
+static void pl310_cache_sync(void)
+{
+	writel(0, &pl310->pl310_cache_sync);
+}
+
+static void pl310_background_op_all_ways(u32 *op_reg)
+{
+	u32 assoc_16, associativity, way_mask;
+
+	assoc_16 = readl(&pl310->pl310_aux_ctrl) &
+			PL310_AUX_CTRL_ASSOCIATIVITY_MASK;
+	if (assoc_16)
+		associativity = 16;
+	else
+		associativity = 8;
+
+	way_mask = (1 << associativity) - 1;
+	/* Invalidate all ways */
+	writel(way_mask, op_reg);
+	/* Wait for all ways to be invalidated */
+	while (readl(op_reg) && way_mask)
+		;
+	pl310_cache_sync();
+}
+
+void v7_outer_cache_inval_all(void)
+{
+	pl310_background_op_all_ways(&pl310->pl310_inv_way);
+}
+
+void v7_outer_cache_flush_all(void)
+{
+	pl310_background_op_all_ways(&pl310->pl310_clean_inv_way);
+}
+
+/* Flush(clean invalidate) memory from start to stop-1 */
+void v7_outer_cache_flush_range(u32 start, u32 stop)
+{
+	/* PL310 currently supports only 32 bytes cache line */
+	u32 pa, line_size = 32;
+
+	/*
+	 * Align to the beginning of cache-line - this ensures that
+	 * the first 5 bits are 0 as required by PL310 TRM
+	 */
+	start &= ~(line_size - 1);
+
+	for (pa = start; pa < stop; pa = pa + line_size)
+		writel(pa, &pl310->pl310_clean_inv_line_pa);
+
+	pl310_cache_sync();
+}
+
+/* invalidate memory from start to stop-1 */
+void v7_outer_cache_inval_range(u32 start, u32 stop)
+{
+	/* PL310 currently supports only 32 bytes cache line */
+	u32 pa, line_size = 32;
+
+	/*
+	 * If start address is not aligned to cache-line do not
+	 * invalidate the first cache-line
+	 */
+	if (start & (line_size - 1)) {
+		printf("ERROR: %s - start address is not aligned - 0x%08x\n",
+			__func__, start);
+		/* move to next cache line */
+		start = (start + line_size - 1) & ~(line_size - 1);
+	}
+
+	/*
+	 * If stop address is not aligned to cache-line do not
+	 * invalidate the last cache-line
+	 */
+	if (stop & (line_size - 1)) {
+		printf("ERROR: %s - stop address is not aligned - 0x%08x\n",
+			__func__, stop);
+		/* align to the beginning of this cache line */
+		stop &= ~(line_size - 1);
+	}
+
+	for (pa = start; pa < stop; pa = pa + line_size)
+		writel(pa, &pl310->pl310_inv_line_pa);
+
+	pl310_cache_sync();
+}
+#else
+static void pl310_cache_sync(void)
+{
+}
+
+static void pl310_background_op_all_ways(u32 *op_reg)
+{
+}
+
+void v7_outer_cache_inval_all(void)
+{
+}
+
+void v7_outer_cache_flush_all(void)
+{
+}
+
+/* Flush(clean invalidate) memory from start to stop-1 */
+void v7_outer_cache_flush_range(u32 start, u32 stop)
+{
+}
+
+/* invalidate memory from start to stop-1 */
+void v7_outer_cache_inval_range(u32 start, u32 stop)
+{
+}
+#endif
+
diff --git a/boot/common/src/uboot/arch/arm/lib/cache.c b/boot/common/src/uboot/arch/arm/lib/cache.c
new file mode 100644
index 0000000..b545fb7
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/cache.c
@@ -0,0 +1,67 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* for now: just dummy functions to satisfy the linker */
+
+#include <common.h>
+
+void  __flush_cache(unsigned long start, unsigned long size)
+{
+#if defined(CONFIG_OMAP2420) || defined(CONFIG_ARM1136)
+	void arm1136_cache_flush(void);
+
+	arm1136_cache_flush();
+#endif
+#ifdef CONFIG_ARM926EJS
+	/* test and clean, page 2-23 of arm926ejs manual */
+	asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory");
+	/* disable write buffer as well (page 2-22) */
+	asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
+#endif
+	return;
+}
+void  flush_cache(unsigned long start, unsigned long size)
+	__attribute__((weak, alias("__flush_cache")));
+
+/*
+ * Default implementation:
+ * do a range flush for the entire range
+ */
+void	__flush_dcache_all(void)
+{
+	flush_cache(0, ~0);
+}
+void	flush_dcache_all(void)
+	__attribute__((weak, alias("__flush_dcache_all")));
+
+
+/*
+ * Default implementation of enable_caches()
+ * Real implementation should be in platform code
+ */
+void __enable_caches(void)
+{
+	puts("WARNING: Caches not enabled\n");
+}
+void enable_caches(void)
+	__attribute__((weak, alias("__enable_caches")));
diff --git a/boot/common/src/uboot/arch/arm/lib/div0.c b/boot/common/src/uboot/arch/arm/lib/div0.c
new file mode 100644
index 0000000..6267bf1
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/div0.c
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* Replacement (=dummy) for GNU/Linux division-by zero handler */
+void __div0 (void)
+{
+	extern void hang (void);
+
+	hang();
+}
diff --git a/boot/common/src/uboot/arch/arm/lib/eabi_compat.c b/boot/common/src/uboot/arch/arm/lib/eabi_compat.c
new file mode 100644
index 0000000..eb3e26d
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/eabi_compat.c
@@ -0,0 +1,23 @@
+/*
+ * Utility functions needed for (some) EABI conformant tool chains.
+ *
+ * (C) Copyright 2009 Wolfgang Denk <wd@denx.de>
+ *
+ * This program is Free Software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <common.h>
+
+int raise (int signum)
+{
+	printf("raise: Signal # %d caught\n", signum);
+	return 0;
+}
+
+/* Dummy function to avoid linker complaints */
+void __aeabi_unwind_cpp_pr0(void)
+{
+};
diff --git a/boot/common/src/uboot/arch/arm/lib/interrupts.c b/boot/common/src/uboot/arch/arm/lib/interrupts.c
new file mode 100644
index 0000000..b3e6286
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/interrupts.c
@@ -0,0 +1,197 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/proc-armv/ptrace.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if CONFIG_USE_IRQ
+int interrupt_init (void)
+{
+	/*
+	 * setup up stacks if necessary
+	 */
+	IRQ_STACK_START = gd->irq_sp - 4;
+	IRQ_STACK_START_IN = gd->irq_sp + 8;
+	FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
+
+	return arch_interrupt_init();
+}
+
+/* enable IRQ interrupts */
+void enable_interrupts (void)
+{
+	unsigned long temp;
+	__asm__ __volatile__("mrs %0, cpsr\n"
+			     "bic %0, %0, #0x80\n"
+			     "msr cpsr_c, %0"
+			     : "=r" (temp)
+			     :
+			     : "memory");
+}
+
+
+/*
+ * disable IRQ/FIQ interrupts
+ * returns true if interrupts had been enabled before we disabled them
+ */
+int disable_interrupts (void)
+{
+	unsigned long old,temp;
+	__asm__ __volatile__("mrs %0, cpsr\n"
+			     "orr %1, %0, #0xc0\n"
+			     "msr cpsr_c, %1"
+			     : "=r" (old), "=r" (temp)
+			     :
+			     : "memory");
+	return (old & 0x80) == 0;
+}
+#else
+int interrupt_init (void)
+{
+	/*
+	 * setup up stacks if necessary
+	 */
+	IRQ_STACK_START_IN = gd->irq_sp + 8;
+
+	return 0;
+}
+
+void enable_interrupts (void)
+{
+	return;
+}
+int disable_interrupts (void)
+{
+	return 0;
+}
+#endif
+
+
+void bad_mode (void)
+{
+	panic ("Resetting CPU ...\n");
+}
+
+void show_regs (struct pt_regs *regs)
+{
+	unsigned long flags;
+	const char *processor_modes[] = {
+	"USER_26",	"FIQ_26",	"IRQ_26",	"SVC_26",
+	"UK4_26",	"UK5_26",	"UK6_26",	"UK7_26",
+	"UK8_26",	"UK9_26",	"UK10_26",	"UK11_26",
+	"UK12_26",	"UK13_26",	"UK14_26",	"UK15_26",
+	"USER_32",	"FIQ_32",	"IRQ_32",	"SVC_32",
+	"UK4_32",	"UK5_32",	"UK6_32",	"ABT_32",
+	"UK8_32",	"UK9_32",	"UK10_32",	"UND_32",
+	"UK12_32",	"UK13_32",	"UK14_32",	"SYS_32",
+	};
+
+	flags = condition_codes (regs);
+
+	printf ("pc : [<%08lx>]	   lr : [<%08lx>]\n"
+		"sp : %08lx  ip : %08lx	 fp : %08lx\n",
+		instruction_pointer (regs),
+		regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+	printf ("r10: %08lx  r9 : %08lx	 r8 : %08lx\n",
+		regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
+	printf ("r7 : %08lx  r6 : %08lx	 r5 : %08lx  r4 : %08lx\n",
+		regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+	printf ("r3 : %08lx  r2 : %08lx	 r1 : %08lx  r0 : %08lx\n",
+		regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+	printf ("Flags: %c%c%c%c",
+		flags & CC_N_BIT ? 'N' : 'n',
+		flags & CC_Z_BIT ? 'Z' : 'z',
+		flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+	printf ("  IRQs %s  FIQs %s  Mode %s%s\n",
+		interrupts_enabled (regs) ? "on" : "off",
+		fast_interrupts_enabled (regs) ? "on" : "off",
+		processor_modes[processor_mode (regs)],
+		thumb_mode (regs) ? " (T)" : "");
+}
+
+void do_undefined_instruction (struct pt_regs *pt_regs)
+{
+	printf ("undefined instruction\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_software_interrupt (struct pt_regs *pt_regs)
+{
+	printf ("software interrupt\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_prefetch_abort (struct pt_regs *pt_regs)
+{
+	printf ("prefetch abort\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_data_abort (struct pt_regs *pt_regs)
+{
+	printf ("data abort\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_not_used (struct pt_regs *pt_regs)
+{
+	printf ("not used\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+void do_fiq (struct pt_regs *pt_regs)
+{
+	printf ("fast interrupt request\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+
+#if !CONFIG_USE_IRQ
+void do_irq (struct pt_regs *pt_regs)
+{
+	printf ("interrupt request\n");
+	show_regs (pt_regs);
+	bad_mode ();
+}
+#endif
diff --git a/boot/common/src/uboot/arch/arm/lib/memcpy.S b/boot/common/src/uboot/arch/arm/lib/memcpy.S
new file mode 100644
index 0000000..f655256
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/memcpy.S
@@ -0,0 +1,243 @@
+/*
+ *  linux/arch/arm/lib/memcpy.S
+ *
+ *  Author:	Nicolas Pitre
+ *  Created:	Sep 28, 2005
+ *  Copyright:	MontaVista Software, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <asm/assembler.h>
+
+#define W(instr)	instr
+
+#define LDR1W_SHIFT	0
+#define STR1W_SHIFT	0
+
+	.macro ldr1w ptr reg abort
+	W(ldr) \reg, [\ptr], #4
+	.endm
+
+	.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+	ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
+	.endm
+
+	.macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+	ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+	.endm
+
+	.macro ldr1b ptr reg cond=al abort
+	ldr\cond\()b \reg, [\ptr], #1
+	.endm
+
+	.macro str1w ptr reg abort
+	W(str) \reg, [\ptr], #4
+	.endm
+
+	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+	stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+	.endm
+
+	.macro str1b ptr reg cond=al abort
+	str\cond\()b \reg, [\ptr], #1
+	.endm
+
+	.macro enter reg1 reg2
+	stmdb sp!, {r0, \reg1, \reg2}
+	.endm
+
+	.macro exit reg1 reg2
+	ldmfd sp!, {r0, \reg1, \reg2}
+	.endm
+
+	.text
+
+/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
+
+.globl memcpy
+memcpy:
+
+		cmp	r0, r1
+		moveq	pc, lr
+
+		enter	r4, lr
+
+		subs	r2, r2, #4
+		blt	8f
+		ands	ip, r0, #3
+	PLD(	pld	[r1, #0]		)
+		bne	9f
+		ands	ip, r1, #3
+		bne	10f
+
+1:		subs	r2, r2, #(28)
+		stmfd	sp!, {r5 - r8}
+		blt	5f
+
+	CALGN(	ands	ip, r0, #31		)
+	CALGN(	rsb	r3, ip, #32		)
+	CALGN(	sbcnes	r4, r3, r2		)  @ C is always set here
+	CALGN(	bcs	2f			)
+	CALGN(	adr	r4, 6f			)
+	CALGN(	subs	r2, r2, r3		)  @ C gets set
+	CALGN(	add	pc, r4, ip		)
+
+	PLD(	pld	[r1, #0]		)
+2:	PLD(	subs	r2, r2, #96		)
+	PLD(	pld	[r1, #28]		)
+	PLD(	blt	4f			)
+	PLD(	pld	[r1, #60]		)
+	PLD(	pld	[r1, #92]		)
+
+3:	PLD(	pld	[r1, #124]		)
+4:		ldr8w	r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+		subs	r2, r2, #32
+		str8w	r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+		bge	3b
+	PLD(	cmn	r2, #96			)
+	PLD(	bge	4b			)
+
+5:		ands	ip, r2, #28
+		rsb	ip, ip, #32
+#if LDR1W_SHIFT > 0
+		lsl	ip, ip, #LDR1W_SHIFT
+#endif
+		addne	pc, pc, ip		@ C is always clear here
+		b	7f
+6:
+		.rept	(1 << LDR1W_SHIFT)
+		W(nop)
+		.endr
+		ldr1w	r1, r3, abort=20f
+		ldr1w	r1, r4, abort=20f
+		ldr1w	r1, r5, abort=20f
+		ldr1w	r1, r6, abort=20f
+		ldr1w	r1, r7, abort=20f
+		ldr1w	r1, r8, abort=20f
+		ldr1w	r1, lr, abort=20f
+
+#if LDR1W_SHIFT < STR1W_SHIFT
+		lsl	ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
+#elif LDR1W_SHIFT > STR1W_SHIFT
+		lsr	ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
+#endif
+		add	pc, pc, ip
+		nop
+		.rept	(1 << STR1W_SHIFT)
+		W(nop)
+		.endr
+		str1w	r0, r3, abort=20f
+		str1w	r0, r4, abort=20f
+		str1w	r0, r5, abort=20f
+		str1w	r0, r6, abort=20f
+		str1w	r0, r7, abort=20f
+		str1w	r0, r8, abort=20f
+		str1w	r0, lr, abort=20f
+
+	CALGN(	bcs	2b			)
+
+7:		ldmfd	sp!, {r5 - r8}
+
+8:		movs	r2, r2, lsl #31
+		ldr1b	r1, r3, ne, abort=21f
+		ldr1b	r1, r4, cs, abort=21f
+		ldr1b	r1, ip, cs, abort=21f
+		str1b	r0, r3, ne, abort=21f
+		str1b	r0, r4, cs, abort=21f
+		str1b	r0, ip, cs, abort=21f
+
+		exit	r4, pc
+
+9:		rsb	ip, ip, #4
+		cmp	ip, #2
+		ldr1b	r1, r3, gt, abort=21f
+		ldr1b	r1, r4, ge, abort=21f
+		ldr1b	r1, lr, abort=21f
+		str1b	r0, r3, gt, abort=21f
+		str1b	r0, r4, ge, abort=21f
+		subs	r2, r2, ip
+		str1b	r0, lr, abort=21f
+		blt	8b
+		ands	ip, r1, #3
+		beq	1b
+
+10:		bic	r1, r1, #3
+		cmp	ip, #2
+		ldr1w	r1, lr, abort=21f
+		beq	17f
+		bgt	18f
+
+
+		.macro	forward_copy_shift pull push
+
+		subs	r2, r2, #28
+		blt	14f
+
+	CALGN(	ands	ip, r0, #31		)
+	CALGN(	rsb	ip, ip, #32		)
+	CALGN(	sbcnes	r4, ip, r2		)  @ C is always set here
+	CALGN(	subcc	r2, r2, ip		)
+	CALGN(	bcc	15f			)
+
+11:		stmfd	sp!, {r5 - r9}
+
+	PLD(	pld	[r1, #0]		)
+	PLD(	subs	r2, r2, #96		)
+	PLD(	pld	[r1, #28]		)
+	PLD(	blt	13f			)
+	PLD(	pld	[r1, #60]		)
+	PLD(	pld	[r1, #92]		)
+
+12:	PLD(	pld	[r1, #124]		)
+13:		ldr4w	r1, r4, r5, r6, r7, abort=19f
+		mov	r3, lr, pull #\pull
+		subs	r2, r2, #32
+		ldr4w	r1, r8, r9, ip, lr, abort=19f
+		orr	r3, r3, r4, push #\push
+		mov	r4, r4, pull #\pull
+		orr	r4, r4, r5, push #\push
+		mov	r5, r5, pull #\pull
+		orr	r5, r5, r6, push #\push
+		mov	r6, r6, pull #\pull
+		orr	r6, r6, r7, push #\push
+		mov	r7, r7, pull #\pull
+		orr	r7, r7, r8, push #\push
+		mov	r8, r8, pull #\pull
+		orr	r8, r8, r9, push #\push
+		mov	r9, r9, pull #\pull
+		orr	r9, r9, ip, push #\push
+		mov	ip, ip, pull #\pull
+		orr	ip, ip, lr, push #\push
+		str8w	r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
+		bge	12b
+	PLD(	cmn	r2, #96			)
+	PLD(	bge	13b			)
+
+		ldmfd	sp!, {r5 - r9}
+
+14:		ands	ip, r2, #28
+		beq	16f
+
+15:		mov	r3, lr, pull #\pull
+		ldr1w	r1, lr, abort=21f
+		subs	ip, ip, #4
+		orr	r3, r3, lr, push #\push
+		str1w	r0, r3, abort=21f
+		bgt	15b
+	CALGN(	cmp	r2, #0			)
+	CALGN(	bge	11b			)
+
+16:		sub	r1, r1, #(\push / 8)
+		b	8b
+
+		.endm
+
+
+		forward_copy_shift	pull=8	push=24
+
+17:		forward_copy_shift	pull=16	push=16
+
+18:		forward_copy_shift	pull=24	push=8
diff --git a/boot/common/src/uboot/arch/arm/lib/memset.S b/boot/common/src/uboot/arch/arm/lib/memset.S
new file mode 100644
index 0000000..0cdf895
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/memset.S
@@ -0,0 +1,126 @@
+/*
+ *  linux/arch/arm/lib/memset.S
+ *
+ *  Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  ASM optimised string functions
+ */
+#include <asm/assembler.h>
+
+	.text
+	.align	5
+	.word	0
+
+1:	subs	r2, r2, #4		@ 1 do we have enough
+	blt	5f			@ 1 bytes to align with?
+	cmp	r3, #2			@ 1
+	strltb	r1, [r0], #1		@ 1
+	strleb	r1, [r0], #1		@ 1
+	strb	r1, [r0], #1		@ 1
+	add	r2, r2, r3		@ 1 (r2 = r2 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted.  Try doing the
+ * memset again.
+ */
+
+.globl memset
+memset:
+	ands	r3, r0, #3		@ 1 unaligned?
+	bne	1b			@ 1
+/*
+ * we know that the pointer in r0 is aligned to a word boundary.
+ */
+	orr	r1, r1, r1, lsl #8
+	orr	r1, r1, r1, lsl #16
+	mov	r3, r1
+	cmp	r2, #16
+	blt	4f
+
+#if ! CALGN(1)+0
+
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+	str	lr, [sp, #-4]!
+	mov	ip, r1
+	mov	lr, r1
+
+2:	subs	r2, r2, #64
+	stmgeia	r0!, {r1, r3, ip, lr}	@ 64 bytes at a time.
+	stmgeia	r0!, {r1, r3, ip, lr}
+	stmgeia	r0!, {r1, r3, ip, lr}
+	stmgeia	r0!, {r1, r3, ip, lr}
+	bgt	2b
+	ldmeqfd	sp!, {pc}		@ Now <64 bytes to go.
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+	tst	r2, #32
+	stmneia	r0!, {r1, r3, ip, lr}
+	stmneia	r0!, {r1, r3, ip, lr}
+	tst	r2, #16
+	stmneia	r0!, {r1, r3, ip, lr}
+	ldr	lr, [sp], #4
+
+#else
+
+/*
+ * This version aligns the destination pointer in order to write
+ * whole cache lines at once.
+ */
+
+	stmfd	sp!, {r4-r7, lr}
+	mov	r4, r1
+	mov	r5, r1
+	mov	r6, r1
+	mov	r7, r1
+	mov	ip, r1
+	mov	lr, r1
+
+	cmp	r2, #96
+	tstgt	r0, #31
+	ble	3f
+
+	and	ip, r0, #31
+	rsb	ip, ip, #32
+	sub	r2, r2, ip
+	movs	ip, ip, lsl #(32 - 4)
+	stmcsia	r0!, {r4, r5, r6, r7}
+	stmmiia	r0!, {r4, r5}
+	tst	ip, #(1 << 30)
+	mov	ip, r1
+	strne	r1, [r0], #4
+
+3:	subs	r2, r2, #64
+	stmgeia	r0!, {r1, r3-r7, ip, lr}
+	stmgeia	r0!, {r1, r3-r7, ip, lr}
+	bgt	3b
+	ldmeqfd	sp!, {r4-r7, pc}
+
+	tst	r2, #32
+	stmneia	r0!, {r1, r3-r7, ip, lr}
+	tst	r2, #16
+	stmneia	r0!, {r4-r7}
+	ldmfd	sp!, {r4-r7, lr}
+
+#endif
+
+4:	tst	r2, #8
+	stmneia	r0!, {r1, r3}
+	tst	r2, #4
+	strne	r1, [r0], #4
+/*
+ * When we get here, we've got less than 4 bytes to zero.  We
+ * may have an unaligned pointer as well.
+ */
+5:	tst	r2, #2
+	strneb	r1, [r0], #1
+	strneb	r1, [r0], #1
+	tst	r2, #1
+	strneb	r1, [r0], #1
+	mov	pc, lr
diff --git a/boot/common/src/uboot/arch/arm/lib/reset.c b/boot/common/src/uboot/arch/arm/lib/reset.c
new file mode 100755
index 0000000..445dbf9
--- /dev/null
+++ b/boot/common/src/uboot/arch/arm/lib/reset.c
@@ -0,0 +1,72 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * (C) Copyright 2004
+ * DAVE Srl
+ * http://www.dave-tech.it
+ * http://www.wawnet.biz
+ * mailto:info@wawnet.biz
+ *
+ * (C) Copyright 2004 Texas Insturments
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/lsp_crpm.h>
+#include <asm/io.h>
+
+#if ZX_RM_WDT_RESTART
+extern void wdt_restart(void);
+#endif
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	puts ("resetting ...\n");
+
+	udelay (20000);				/* wait 600 ms */
+#if ZX_RM_WDT_RESTART
+wdt_restart();
+#else
+    writel(0x1,TOP_SYSCLK_BASE);
+#endif
+	
+	//disable_interrupts();
+	//reset_cpu(0);
+
+	/*NOTREACHED*/
+	return 0;
+}
+
+void system_reset(void)
+{
+    udelay (600000);				/* wait 600 ms */
+    printf("resetting ...\n");
+    //writel(0x1<<31,TOP_SYSCLK_BASE);
+	writel(0x1,TOP_SYSCLK_BASE);
+}