diff mbox

[U-Boot] part1 of arm64. This patch provide u-boot with arm64 support. Currently it works on Foundation Model for armv8 or Fast Model for armv8.

Message ID 1376237123-13086-1-git-send-email-fenghua@phytium.com.cn
State Superseded
Headers show

Commit Message

fenghua@phytium.com.cn Aug. 11, 2013, 4:05 p.m. UTC
From: fenghua <fenghua@ligen-virtual-machine.(none)>

This patch provide u-boot with arm64 support. Currently, it works on
Foundation Model for armv8 or Fast Model for armv8.

Signed-off-by: fenghua <fenghua@ligen-virtual-machine.(none)>
---
 arch/arm64/config.mk                 |   32 +++
 arch/arm64/lib/Makefile              |   64 +++++
 arch/arm64/lib/board.c               |  456 ++++++++++++++++++++++++++++++++++
 arch/arm64/lib/bootm.c               |  211 ++++++++++++++++
 arch/arm64/lib/cache.c               |  282 +++++++++++++++++++++
 arch/arm64/lib/crt0.S                |  129 ++++++++++
 arch/arm64/lib/interrupts.c          |  109 ++++++++
 arch/arm64/lib/relocate.S            |   72 ++++++
 arch/arm64/lib/reset.c               |   37 +++
 arch/arm64/lib/timer.c               |   95 +++++++
 board/armltd/dts/vexpress64.dts      |  215 ++++++++++++++++
 board/armltd/vexpress64/Makefile     |   43 ++++
 board/armltd/vexpress64/vexpress64.c |   63 +++++
 boards.cfg                           |    1 +
 common/cmd_bdinfo.c                  |   32 +++
 common/fdt_support.c                 |   66 ++---
 common/image.c                       |    5 +-
 doc/README.arm64                     |   10 +
 examples/standalone/stubs.c          |   13 +
 include/configs/vexpress_aemv8a.h    |  200 +++++++++++++++
 include/image.h                      |    1 +
 lib/asm-offsets.c                    |    2 +-
 22 files changed, 2103 insertions(+), 35 deletions(-)
 create mode 100644 arch/arm64/config.mk
 create mode 100644 arch/arm64/lib/Makefile
 create mode 100644 arch/arm64/lib/board.c
 create mode 100644 arch/arm64/lib/bootm.c
 create mode 100644 arch/arm64/lib/cache.c
 create mode 100644 arch/arm64/lib/crt0.S
 create mode 100644 arch/arm64/lib/interrupts.c
 create mode 100644 arch/arm64/lib/relocate.S
 create mode 100644 arch/arm64/lib/reset.c
 create mode 100644 arch/arm64/lib/timer.c
 create mode 100644 board/armltd/dts/vexpress64.dts
 create mode 100644 board/armltd/vexpress64/Makefile
 create mode 100644 board/armltd/vexpress64/vexpress64.c
 create mode 100644 doc/README.arm64
 create mode 100644 include/configs/vexpress_aemv8a.h

Comments

York Sun Aug. 13, 2013, 3:36 p.m. UTC | #1
On 08/11/2013 09:05 AM, fenghua@phytium.com.cn wrote:
> From: fenghua <fenghua@ligen-virtual-machine.(none)>
> 
> This patch provide u-boot with arm64 support. Currently, it works on
> Foundation Model for armv8 or Fast Model for armv8.
> 
> Signed-off-by: fenghua <fenghua@ligen-virtual-machine.(none)>


It boots! Even it has a lot of compiling warning, but it is really a
good start. Thanks for sharing!

York
Scott Wood Aug. 13, 2013, 11:06 p.m. UTC | #2
On Mon, 2013-08-12 at 00:05 +0800, fenghua@phytium.com.cn wrote:
> From: fenghua <fenghua@ligen-virtual-machine.(none)>
> 
> This patch provide u-boot with arm64 support. Currently, it works on
> Foundation Model for armv8 or Fast Model for armv8.
> 
> Signed-off-by: fenghua <fenghua@ligen-virtual-machine.(none)>

Could you provide a proper signoff (full name and valid e-mail address)?

> ---
>  arch/arm64/config.mk                 |   32 +++
>  arch/arm64/lib/Makefile              |   64 +++++
>  arch/arm64/lib/board.c               |  456 ++++++++++++++++++++++++++++++++++
>  arch/arm64/lib/bootm.c               |  211 ++++++++++++++++
>  arch/arm64/lib/cache.c               |  282 +++++++++++++++++++++
>  arch/arm64/lib/crt0.S                |  129 ++++++++++
>  arch/arm64/lib/interrupts.c          |  109 ++++++++
>  arch/arm64/lib/relocate.S            |   72 ++++++
>  arch/arm64/lib/reset.c               |   37 +++
>  arch/arm64/lib/timer.c               |   95 +++++++
>  board/armltd/dts/vexpress64.dts      |  215 ++++++++++++++++
>  board/armltd/vexpress64/Makefile     |   43 ++++
>  board/armltd/vexpress64/vexpress64.c |   63 +++++
>  boards.cfg                           |    1 +
>  common/cmd_bdinfo.c                  |   32 +++
>  common/fdt_support.c                 |   66 ++---
>  common/image.c                       |    5 +-
>  doc/README.arm64                     |   10 +
>  examples/standalone/stubs.c          |   13 +
>  include/configs/vexpress_aemv8a.h    |  200 +++++++++++++++
>  include/image.h                      |    1 +
>  lib/asm-offsets.c                    |    2 +-
>  22 files changed, 2103 insertions(+), 35 deletions(-)
>  create mode 100644 arch/arm64/config.mk
>  create mode 100644 arch/arm64/lib/Makefile
>  create mode 100644 arch/arm64/lib/board.c
>  create mode 100644 arch/arm64/lib/bootm.c
>  create mode 100644 arch/arm64/lib/cache.c
>  create mode 100644 arch/arm64/lib/crt0.S
>  create mode 100644 arch/arm64/lib/interrupts.c
>  create mode 100644 arch/arm64/lib/relocate.S
>  create mode 100644 arch/arm64/lib/reset.c
>  create mode 100644 arch/arm64/lib/timer.c
>  create mode 100644 board/armltd/dts/vexpress64.dts
>  create mode 100644 board/armltd/vexpress64/Makefile
>  create mode 100644 board/armltd/vexpress64/vexpress64.c
>  create mode 100644 doc/README.arm64
>  create mode 100644 include/configs/vexpress_aemv8a.h

It would be nice if the patches were separated into arch support, core
support, board support, anything specific to the foundation/fast models,
etc.

> 
> diff --git a/arch/arm64/config.mk b/arch/arm64/config.mk
> new file mode 100644
> index 0000000..e40e983
> --- /dev/null
> +++ b/arch/arm64/config.mk

Does there really need to be a separate arch/arm64?  I know this is what
Linux does, but on every other 32/64 architecture that decision has been
eventually reversed (even on x86, which has about as much difference
between 32 and 64 bit as ARM does).

We started working on armv8 U-Boot using a unified arch/arm, and at
least got to the point of something that builds, so it doesn't seem
impractical.  Besides making maintenance easier, it would also make it
much easier to review what is being done differently for arm64 (and for
any files that do need to be moved or copied, be sure to pass -M -C to
git format-patch).

> @@ -0,0 +1,32 @@
> +#
> +# Copyright (c) 2013	FengHua <fenghua@phytium.com.cn>
> +#
> +# 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
> +#
> +
> +CROSS_COMPILE ?= /home/fenghua/DS-5-Workspace/gcc-linaro-aarch64-linux-gnu-4.8-2013.05_linux/bin/aarch64-linux-gnu-

Please don't insert references to paths that only work on your computer.

Plus, what about native builds that don't need a cross compiler?

> diff --git a/common/fdt_support.c b/common/fdt_support.c
> index b034c98..9bc5821 100644
> --- a/common/fdt_support.c
> +++ b/common/fdt_support.c
> @@ -21,6 +21,34 @@
>   */
>  DECLARE_GLOBAL_DATA_PTR;
>  
> +/*
> + * Get cells len in bytes
> + *     if #NNNN-cells property is 2 then len is 8
> + *     otherwise len is 4
> + */
> +static int get_cells_len(void *blob, char *nr_cells_name)
> +{
> +	const fdt32_t *cell;
> +
> +	cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
> +	if (cell && fdt32_to_cpu(*cell) == 2)
> +		return 8;
> +
> +	return 4;
> +}
> +
> +/*
> + * Write a 4 or 8 byte big endian cell
> + */
> +static void write_cell(u8 *addr, u64 val, int size)
> +{
> +	int shift = (size - 1) * 8;
> +	while (size-- > 0) {
> +		*addr++ = (val >> shift) & 0xff;
> +		shift -= 8;
> +	}
> +}
> +
>  /**
>   * fdt_getprop_u32_default - Find a node and return it's property or a default
>   *
> @@ -131,9 +159,9 @@ static int fdt_fixup_stdout(void *fdt, int chosenoff)
>  
>  int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
>  {
> -	int   nodeoffset;
> +	int   nodeoffset, addr_cell_len;
>  	int   err, j, total;
> -	fdt32_t  tmp;
> +	fdt64_t  tmp;
>  	const char *path;
>  	uint64_t addr, size;
>  
> @@ -170,9 +198,11 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
>  		return err;
>  	}
>  
> +	addr_cell_len = get_cells_len(fdt, "#address-cells");
> +
>  	path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL);
>  	if ((path == NULL) || force) {
> -		tmp = cpu_to_fdt32(initrd_start);
> +		write_cell((u8 *)&tmp, initrd_start, addr_cell_len);
>  		err = fdt_setprop(fdt, nodeoffset,
>  			"linux,initrd-start", &tmp, sizeof(tmp));
>  		if (err < 0) {
> @@ -181,7 +211,7 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
>  				fdt_strerror(err));
>  			return err;
>  		}
> -		tmp = cpu_to_fdt32(initrd_end);
> +		write_cell((u8 *)&tmp, initrd_end, addr_cell_len);
>  		err = fdt_setprop(fdt, nodeoffset,
>  			"linux,initrd-end", &tmp, sizeof(tmp));
>  		if (err < 0) {
> @@ -343,34 +373,6 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat,
>  	do_fixup_by_compat(fdt, compat, prop, &tmp, 4, create);
>  }
>  
> -/*
> - * Get cells len in bytes
> - *     if #NNNN-cells property is 2 then len is 8
> - *     otherwise len is 4
> - */
> -static int get_cells_len(void *blob, char *nr_cells_name)
> -{
> -	const fdt32_t *cell;
> -
> -	cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
> -	if (cell && fdt32_to_cpu(*cell) == 2)
> -		return 8;
> -
> -	return 4;
> -}
> -
> -/*
> - * Write a 4 or 8 byte big endian cell
> - */
> -static void write_cell(u8 *addr, u64 val, int size)
> -{
> -	int shift = (size - 1) * 8;
> -	while (size-- > 0) {
> -		*addr++ = (val >> shift) & 0xff;
> -		shift -= 8;
> -	}
> -}
> -
>  #ifdef CONFIG_NR_DRAM_BANKS
>  #define MEMORY_BANKS_MAX CONFIG_NR_DRAM_BANKS
>  #else

What's going on here?

> @@ -422,7 +423,7 @@ ulong getenv_bootm_low(void)
>  
>  #if defined(CONFIG_SYS_SDRAM_BASE)
>  	return CONFIG_SYS_SDRAM_BASE;
> -#elif defined(CONFIG_ARM)
> +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
>  	return gd->bd->bi_dram[0].start;
>  #else
>  	return 0;
> @@ -444,7 +445,7 @@ phys_size_t getenv_bootm_size(void)
>  		tmp = 0;
>  
> 
> -#if defined(CONFIG_ARM)
> +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
>  	return gd->bd->bi_dram[0].size - tmp;
>  #else
>  	return gd->bd->bi_memsize - tmp;

Ignoring the issue of why CONFIG_ARM is not defined here, why is ARM
special?

> diff --git a/doc/README.arm64 b/doc/README.arm64
> new file mode 100644
> index 0000000..8fef26d
> --- /dev/null
> +++ b/doc/README.arm64
> @@ -0,0 +1,10 @@
> +Notes:
> +
> +1. Currenly, u-boot running at EL2.
> +
> +2. Currently, gcc-aarch64 produce error when compiling with pie and rel_dyn.

arm64 uses rela, not rel.  This requires a small change to the
relocation code and the linker script.

> +   So, GOT is used to relocate u-boot and CONFIG_NEEDS_MANUAL_RELOC is needed.

:-(

> +3. Currently, fdt should be in the first 512MB of RAM, so, fdt_high should be handled specially.
> +   I define fdt_high as 0xa0000000 when CONFIG_SYS_SDRAM_BASE is 0x80000000.
> +
> diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c
> index 8fb1765..4e39b1b 100644
> --- a/examples/standalone/stubs.c
> +++ b/examples/standalone/stubs.c
> @@ -195,6 +195,19 @@ gd_t *global_data;
>  "	l.jr	r13\n"		\
>  "	l.nop\n"				\
>  	: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r13");
> +#elif defined(CONFIG_ARM64)
> +/*
> + * x18 holds the pointer to the global_data, ip is a call-clobbered
> + * register
> + */
> +#define EXPORT_FUNC(x) \
> +	asm volatile (			\
> +"	.globl " #x "\n"		\
> +#x ":\n"				\
> +"	ldr	x19, [x18, %0]\n"		\
> +"	ldr	x19, [x19, %1]\n"		\
> +"	br	x19\n"		\
> +	: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "x19");

Why use a nonvolate register here?

>  #else
>  /*"	addi	$sp, $sp, -24\n"	\
>  "	br	$r16\n"			\*/
> diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h
> new file mode 100644
> index 0000000..3c96987
> --- /dev/null
> +++ b/include/configs/vexpress_aemv8a.h
> @@ -0,0 +1,200 @@
> +/*
> + * Configuration for Versatile Express. Parts were derived from other ARM
> + *   configurations.
> + *
> + * 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
> + */
> +
> +#ifndef __VEXPRESS_AEMV8A_H
> +#define __VEXPRESS_AEMV8A_H
> +
> +#define DEBUG
> +
> +#define CONFIG_SYS_NO_FLASH
> +
> +#define CONFIG_SUPPORT_RAW_INITRD
> +
> +#define CONFIG_SKIP_LOWLEVEL_INIT
> +
> +/* Cache Definitions */
> +//#define CONFIG_SYS_DCACHE_OFF
> +//#define CONFIG_SYS_ICACHE_OFF
> +
> +#define CONFIG_IDENT_STRING		" aarch64"

Shouldn't CONFIG_IDENT_STRING be the target name (i.e. the board name)?

-Scott
fenghua@phytium.com.cn Aug. 14, 2013, 4:43 a.m. UTC | #3
> -----原始邮件-----
> 发件人: "Scott Wood" <scottwood@freescale.com>
> 发送时间: 2013年8月14日 星期三
> 收件人: fenghua@phytium.com.cn
> 抄送: u-boot@lists.denx.de, trini@ti.com
> 主题: Re: [U-Boot] [PATCH] part1 of arm64. This patch provide u-boot with arm64 support. Currently it works on Foundation Model for armv8 or Fast Model for armv8.
> 
> On Mon, 2013-08-12 at 00:05 +0800, fenghua@phytium.com.cn wrote:
> > From: fenghua <fenghua@ligen-virtual-machine.(none)>
> > 
> > This patch provide u-boot with arm64 support. Currently, it works on
> > Foundation Model for armv8 or Fast Model for armv8.
> > 
> > Signed-off-by: fenghua <fenghua@ligen-virtual-machine.(none)>
> 
> Could you provide a proper signoff (full name and valid e-mail address)?

    I will fix it.

> 
> > ---
> >  arch/arm64/config.mk                 |   32 +++
> >  arch/arm64/lib/Makefile              |   64 +++++
> >  arch/arm64/lib/board.c               |  456 ++++++++++++++++++++++++++++++++++
> >  arch/arm64/lib/bootm.c               |  211 ++++++++++++++++
> >  arch/arm64/lib/cache.c               |  282 +++++++++++++++++++++
> >  arch/arm64/lib/crt0.S                |  129 ++++++++++
> >  arch/arm64/lib/interrupts.c          |  109 ++++++++
> >  arch/arm64/lib/relocate.S            |   72 ++++++
> >  arch/arm64/lib/reset.c               |   37 +++
> >  arch/arm64/lib/timer.c               |   95 +++++++
> >  board/armltd/dts/vexpress64.dts      |  215 ++++++++++++++++
> >  board/armltd/vexpress64/Makefile     |   43 ++++
> >  board/armltd/vexpress64/vexpress64.c |   63 +++++
> >  boards.cfg                           |    1 +
> >  common/cmd_bdinfo.c                  |   32 +++
> >  common/fdt_support.c                 |   66 ++---
> >  common/image.c                       |    5 +-
> >  doc/README.arm64                     |   10 +
> >  examples/standalone/stubs.c          |   13 +
> >  include/configs/vexpress_aemv8a.h    |  200 +++++++++++++++
> >  include/image.h                      |    1 +
> >  lib/asm-offsets.c                    |    2 +-
> >  22 files changed, 2103 insertions(+), 35 deletions(-)
> >  create mode 100644 arch/arm64/config.mk
> >  create mode 100644 arch/arm64/lib/Makefile
> >  create mode 100644 arch/arm64/lib/board.c
> >  create mode 100644 arch/arm64/lib/bootm.c
> >  create mode 100644 arch/arm64/lib/cache.c
> >  create mode 100644 arch/arm64/lib/crt0.S
> >  create mode 100644 arch/arm64/lib/interrupts.c
> >  create mode 100644 arch/arm64/lib/relocate.S
> >  create mode 100644 arch/arm64/lib/reset.c
> >  create mode 100644 arch/arm64/lib/timer.c
> >  create mode 100644 board/armltd/dts/vexpress64.dts
> >  create mode 100644 board/armltd/vexpress64/Makefile
> >  create mode 100644 board/armltd/vexpress64/vexpress64.c
> >  create mode 100644 doc/README.arm64
> >  create mode 100644 include/configs/vexpress_aemv8a.h
> 
> It would be nice if the patches were separated into arch support, core
> support, board support, anything specific to the foundation/fast models,
> etc.

   Actually, I prefered to generate one patch file. but, it's size is out of 100KB.
so, I split it to two part. I will try to generate patch as you recommended.

> 
> > 
> > diff --git a/arch/arm64/config.mk b/arch/arm64/config.mk
> > new file mode 100644
> > index 0000000..e40e983
> > --- /dev/null
> > +++ b/arch/arm64/config.mk
> 
> Does there really need to be a separate arch/arm64?  I know this is what
> Linux does, but on every other 32/64 architecture that decision has been
> eventually reversed (even on x86, which has about as much difference
> between 32 and 64 bit as ARM does).
> 
> We started working on armv8 U-Boot using a unified arch/arm, and at
> least got to the point of something that builds, so it doesn't seem
> impractical.  Besides making maintenance easier, it would also make it
> much easier to review what is being done differently for arm64 (and for
> any files that do need to be moved or copied, be sure to pass -M -C to
> git format-patch).
> 

   The porting is performed as a seperate architecture due to a few considerations,
   1. The porting will be simple and clear. There's no need to touch any original ARM code and less macro switch is needed.
   2. There's no any real chip of armv8 until now.  Many aspect of armv8 are not completely confirmed.

   Of course, it could be merged with ARM at a proper time in the later. Actually, linux kernel follow this mode.

> > @@ -0,0 +1,32 @@
> > +#
> > +# Copyright (c) 2013	FengHua <fenghua@phytium.com.cn>
> > +#
> > +# 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
> > +#
> > +
> > +CROSS_COMPILE ?= /home/fenghua/DS-5-Workspace/gcc-linaro-aarch64-linux-gnu-4.8-2013.05_linux/bin/aarch64-linux-gnu-
> 
> Please don't insert references to paths that only work on your computer.
>
    I will fix it.

> Plus, what about native builds that don't need a cross compiler?
   Currently, there's no real chip of armv8. so,cross compiler is needed.

> 
> > diff --git a/common/fdt_support.c b/common/fdt_support.c
> > index b034c98..9bc5821 100644
> > --- a/common/fdt_support.c
> > +++ b/common/fdt_support.c
> > @@ -21,6 +21,34 @@
> >   */
> >  DECLARE_GLOBAL_DATA_PTR;
> >  
> > +/*
> > + * Get cells len in bytes
> > + *     if #NNNN-cells property is 2 then len is 8
> > + *     otherwise len is 4
> > + */
> > +static int get_cells_len(void *blob, char *nr_cells_name)
> > +{
> > +	const fdt32_t *cell;
> > +
> > +	cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
> > +	if (cell && fdt32_to_cpu(*cell) == 2)
> > +		return 8;
> > +
> > +	return 4;
> > +}
> > +
> > +/*
> > + * Write a 4 or 8 byte big endian cell
> > + */
> > +static void write_cell(u8 *addr, u64 val, int size)
> > +{
> > +	int shift = (size - 1) * 8;
> > +	while (size-- > 0) {
> > +		*addr++ = (val >> shift) & 0xff;
> > +		shift -= 8;
> > +	}
> > +}
> > +
> >  /**
> >   * fdt_getprop_u32_default - Find a node and return it's property or a default
> >   *
> > @@ -131,9 +159,9 @@ static int fdt_fixup_stdout(void *fdt, int chosenoff)
> >  
> >  int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
> >  {
> > -	int   nodeoffset;
> > +	int   nodeoffset, addr_cell_len;
> >  	int   err, j, total;
> > -	fdt32_t  tmp;
> > +	fdt64_t  tmp;
> >  	const char *path;
> >  	uint64_t addr, size;
> >  
> > @@ -170,9 +198,11 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
> >  		return err;
> >  	}
> >  
> > +	addr_cell_len = get_cells_len(fdt, "#address-cells");
> > +
> >  	path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL);
> >  	if ((path == NULL) || force) {
> > -		tmp = cpu_to_fdt32(initrd_start);
> > +		write_cell((u8 *)&tmp, initrd_start, addr_cell_len);
> >  		err = fdt_setprop(fdt, nodeoffset,
> >  			"linux,initrd-start", &tmp, sizeof(tmp));
> >  		if (err < 0) {
> > @@ -181,7 +211,7 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
> >  				fdt_strerror(err));
> >  			return err;
> >  		}
> > -		tmp = cpu_to_fdt32(initrd_end);
> > +		write_cell((u8 *)&tmp, initrd_end, addr_cell_len);
> >  		err = fdt_setprop(fdt, nodeoffset,
> >  			"linux,initrd-end", &tmp, sizeof(tmp));
> >  		if (err < 0) {
> > @@ -343,34 +373,6 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat,
> >  	do_fixup_by_compat(fdt, compat, prop, &tmp, 4, create);
> >  }
> >  
> > -/*
> > - * Get cells len in bytes
> > - *     if #NNNN-cells property is 2 then len is 8
> > - *     otherwise len is 4
> > - */
> > -static int get_cells_len(void *blob, char *nr_cells_name)
> > -{
> > -	const fdt32_t *cell;
> > -
> > -	cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
> > -	if (cell && fdt32_to_cpu(*cell) == 2)
> > -		return 8;
> > -
> > -	return 4;
> > -}
> > -
> > -/*
> > - * Write a 4 or 8 byte big endian cell
> > - */
> > -static void write_cell(u8 *addr, u64 val, int size)
> > -{
> > -	int shift = (size - 1) * 8;
> > -	while (size-- > 0) {
> > -		*addr++ = (val >> shift) & 0xff;
> > -		shift -= 8;
> > -	}
> > -}
> > -
> >  #ifdef CONFIG_NR_DRAM_BANKS
> >  #define MEMORY_BANKS_MAX CONFIG_NR_DRAM_BANKS
> >  #else
> 
> What's going on here?
> 

   Whitout this the initrd represented by "linux,initrd-start" could only be placed under 4G address space.
   This part fix it to 64 bit address space.

> > @@ -422,7 +423,7 @@ ulong getenv_bootm_low(void)
> >  
> >  #if defined(CONFIG_SYS_SDRAM_BASE)
> >  	return CONFIG_SYS_SDRAM_BASE;
> > -#elif defined(CONFIG_ARM)
> > +#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
> >  	return gd->bd->bi_dram[0].start;
> >  #else
> >  	return 0;
> > @@ -444,7 +445,7 @@ phys_size_t getenv_bootm_size(void)
> >  		tmp = 0;
> >  
> > 
> > -#if defined(CONFIG_ARM)
> > +#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
> >  	return gd->bd->bi_dram[0].size - tmp;
> >  #else
> >  	return gd->bd->bi_memsize - tmp;
> 
> Ignoring the issue of why CONFIG_ARM is not defined here, why is ARM
> special?
> 
> > diff --git a/doc/README.arm64 b/doc/README.arm64
> > new file mode 100644
> > index 0000000..8fef26d
> > --- /dev/null
> > +++ b/doc/README.arm64
> > @@ -0,0 +1,10 @@
> > +Notes:
> > +
> > +1. Currenly, u-boot running at EL2.
> > +
> > +2. Currently, gcc-aarch64 produce error when compiling with pie and rel_dyn.
> 
> arm64 uses rela, not rel.  This requires a small change to the
> relocation code and the linker script.
> 
   I also try to use rela but it not works. maybe something is wrong with the code.

> > +   So, GOT is used to relocate u-boot and CONFIG_NEEDS_MANUAL_RELOC is needed.
> 
> :-(
> 
> > +3. Currently, fdt should be in the first 512MB of RAM, so, fdt_high should be handled specially.
> > +   I define fdt_high as 0xa0000000 when CONFIG_SYS_SDRAM_BASE is 0x80000000.
> > +
> > diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c
> > index 8fb1765..4e39b1b 100644
> > --- a/examples/standalone/stubs.c
> > +++ b/examples/standalone/stubs.c
> > @@ -195,6 +195,19 @@ gd_t *global_data;
> >  "	l.jr	r13\n"		\
> >  "	l.nop\n"				\
> >  	: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r13");
> > +#elif defined(CONFIG_ARM64)
> > +/*
> > + * x18 holds the pointer to the global_data, ip is a call-clobbered
> > + * register
> > + */
> > +#define EXPORT_FUNC(x) \
> > +	asm volatile (			\
> > +"	.globl " #x "\n"		\
> > +#x ":\n"				\
> > +"	ldr	x19, [x18, %0]\n"		\
> > +"	ldr	x19, [x19, %1]\n"		\
> > +"	br	x19\n"		\
> > +	: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "x19");
> 
> Why use a nonvolate register here?

You are right. it's a bug. x19 is defined as a callee-saved register in the ABI.

> 
> >  #else
> >  /*"	addi	$sp, $sp, -24\n"	\
> >  "	br	$r16\n"			\*/
> > diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h
> > new file mode 100644
> > index 0000000..3c96987
> > --- /dev/null
> > +++ b/include/configs/vexpress_aemv8a.h
> > @@ -0,0 +1,200 @@
> > +/*
> > + * Configuration for Versatile Express. Parts were derived from other ARM
> > + *   configurations.
> > + *
> > + * 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
> > + */
> > +
> > +#ifndef __VEXPRESS_AEMV8A_H
> > +#define __VEXPRESS_AEMV8A_H
> > +
> > +#define DEBUG
> > +
> > +#define CONFIG_SYS_NO_FLASH
> > +
> > +#define CONFIG_SUPPORT_RAW_INITRD
> > +
> > +#define CONFIG_SKIP_LOWLEVEL_INIT
> > +
> > +/* Cache Definitions */
> > +//#define CONFIG_SYS_DCACHE_OFF
> > +//#define CONFIG_SYS_ICACHE_OFF
> > +
> > +#define CONFIG_IDENT_STRING		" aarch64"
> 
> Shouldn't CONFIG_IDENT_STRING be the target name (i.e. the board name)?
> 
    right, it's better to be defined as vexpress**.

> -Scott
> 
> 
>
Scott Wood Aug. 14, 2013, 6:39 p.m. UTC | #4
On Wed, 2013-08-14 at 12:43 +0800, FengHua wrote:
> 
> 
> > -----原始邮件-----
> > 发件人: "Scott Wood" <scottwood@freescale.com>
> > 发送时间: 2013年8月14日 星期三
> > 收件人: fenghua@phytium.com.cn
> > 抄送: u-boot@lists.denx.de, trini@ti.com
> > 主题: Re: [U-Boot] [PATCH] part1 of arm64. This patch provide u-boot with arm64 support. Currently it works on Foundation Model for armv8 or Fast Model for armv8.
> > 
> > On Mon, 2013-08-12 at 00:05 +0800, fenghua@phytium.com.cn wrote:
> > > diff --git a/arch/arm64/config.mk b/arch/arm64/config.mk
> > > new file mode 100644
> > > index 0000000..e40e983
> > > --- /dev/null
> > > +++ b/arch/arm64/config.mk
> > 
> > Does there really need to be a separate arch/arm64?  I know this is what
> > Linux does, but on every other 32/64 architecture that decision has been
> > eventually reversed (even on x86, which has about as much difference
> > between 32 and 64 bit as ARM does).
> > 
> > We started working on armv8 U-Boot using a unified arch/arm, and at
> > least got to the point of something that builds, so it doesn't seem
> > impractical.  Besides making maintenance easier, it would also make it
> > much easier to review what is being done differently for arm64 (and for
> > any files that do need to be moved or copied, be sure to pass -M -C to
> > git format-patch).
> > 
> 
>    The porting is performed as a seperate architecture due to a few considerations,
>    1. The porting will be simple and clear.

No, it's the opposite.  It's hard to review what you changed from arm to
arm64.

>    2. There's no any real chip of armv8 until now.  Many aspect of armv8 are not completely confirmed.

I'm not sure why that makes a difference.

>    Of course, it could be merged with ARM at a proper time in the later. Actually, linux kernel follow this mode.

Let's do it the right way from the start.

> > > @@ -0,0 +1,32 @@
> > > +#
> > > +# Copyright (c) 2013	FengHua <fenghua@phytium.com.cn>
> > > +#
> > > +# 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
> > > +#
> > > +
> > > +CROSS_COMPILE ?= /home/fenghua/DS-5-Workspace/gcc-linaro-aarch64-linux-gnu-4.8-2013.05_linux/bin/aarch64-linux-gnu-
> > 
> > Please don't insert references to paths that only work on your computer.
> >
>     I will fix it.
> 
> > Plus, what about native builds that don't need a cross compiler?
>    Currently, there's no real chip of armv8. so,cross compiler is needed.

Eventually there will be (or someone could be masochistic enough to
build inside the emulator).  The point remains that default
CROSS_COMPILE is a bad idea.

> > > diff --git a/common/fdt_support.c b/common/fdt_support.c
> > > index b034c98..9bc5821 100644
> > > --- a/common/fdt_support.c
> > > +++ b/common/fdt_support.c
> > > @@ -21,6 +21,34 @@
> > >   */
> > >  DECLARE_GLOBAL_DATA_PTR;
> > >  
> > > +/*
> > > + * Get cells len in bytes
> > > + *     if #NNNN-cells property is 2 then len is 8
> > > + *     otherwise len is 4
> > > + */
> > > +static int get_cells_len(void *blob, char *nr_cells_name)
> > > +{
> > > +	const fdt32_t *cell;
> > > +
> > > +	cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
> > > +	if (cell && fdt32_to_cpu(*cell) == 2)
> > > +		return 8;
> > > +
> > > +	return 4;
> > > +}
> > > +
> > > +/*
> > > + * Write a 4 or 8 byte big endian cell
> > > + */
> > > +static void write_cell(u8 *addr, u64 val, int size)
> > > +{
> > > +	int shift = (size - 1) * 8;
> > > +	while (size-- > 0) {
> > > +		*addr++ = (val >> shift) & 0xff;
> > > +		shift -= 8;
> > > +	}
> > > +}
> > > +
> > >  /**
> > >   * fdt_getprop_u32_default - Find a node and return it's property or a default
> > >   *
> > > @@ -131,9 +159,9 @@ static int fdt_fixup_stdout(void *fdt, int chosenoff)
> > >  
> > >  int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
> > >  {
> > > -	int   nodeoffset;
> > > +	int   nodeoffset, addr_cell_len;
> > >  	int   err, j, total;
> > > -	fdt32_t  tmp;
> > > +	fdt64_t  tmp;
> > >  	const char *path;
> > >  	uint64_t addr, size;
> > >  
> > > @@ -170,9 +198,11 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
> > >  		return err;
> > >  	}
> > >  
> > > +	addr_cell_len = get_cells_len(fdt, "#address-cells");
> > > +
> > >  	path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL);
> > >  	if ((path == NULL) || force) {
> > > -		tmp = cpu_to_fdt32(initrd_start);
> > > +		write_cell((u8 *)&tmp, initrd_start, addr_cell_len);
> > >  		err = fdt_setprop(fdt, nodeoffset,
> > >  			"linux,initrd-start", &tmp, sizeof(tmp));
> > >  		if (err < 0) {
> > > @@ -181,7 +211,7 @@ int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
> > >  				fdt_strerror(err));
> > >  			return err;
> > >  		}
> > > -		tmp = cpu_to_fdt32(initrd_end);
> > > +		write_cell((u8 *)&tmp, initrd_end, addr_cell_len);
> > >  		err = fdt_setprop(fdt, nodeoffset,
> > >  			"linux,initrd-end", &tmp, sizeof(tmp));
> > >  		if (err < 0) {
> > > @@ -343,34 +373,6 @@ void do_fixup_by_compat_u32(void *fdt, const char *compat,
> > >  	do_fixup_by_compat(fdt, compat, prop, &tmp, 4, create);
> > >  }
> > >  
> > > -/*
> > > - * Get cells len in bytes
> > > - *     if #NNNN-cells property is 2 then len is 8
> > > - *     otherwise len is 4
> > > - */
> > > -static int get_cells_len(void *blob, char *nr_cells_name)
> > > -{
> > > -	const fdt32_t *cell;
> > > -
> > > -	cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
> > > -	if (cell && fdt32_to_cpu(*cell) == 2)
> > > -		return 8;
> > > -
> > > -	return 4;
> > > -}
> > > -
> > > -/*
> > > - * Write a 4 or 8 byte big endian cell
> > > - */
> > > -static void write_cell(u8 *addr, u64 val, int size)
> > > -{
> > > -	int shift = (size - 1) * 8;
> > > -	while (size-- > 0) {
> > > -		*addr++ = (val >> shift) & 0xff;
> > > -		shift -= 8;
> > > -	}
> > > -}
> > > -
> > >  #ifdef CONFIG_NR_DRAM_BANKS
> > >  #define MEMORY_BANKS_MAX CONFIG_NR_DRAM_BANKS
> > >  #else
> > 
> > What's going on here?
> > 
> 
>    Whitout this the initrd represented by "linux,initrd-start" could only be placed under 4G address space.
>    This part fix it to 64 bit address space.

Make it a separate patch with a more detailed explanation.

> > > diff --git a/doc/README.arm64 b/doc/README.arm64
> > > new file mode 100644
> > > index 0000000..8fef26d
> > > --- /dev/null
> > > +++ b/doc/README.arm64
> > > @@ -0,0 +1,10 @@
> > > +Notes:
> > > +
> > > +1. Currenly, u-boot running at EL2.
> > > +
> > > +2. Currently, gcc-aarch64 produce error when compiling with pie and rel_dyn.
> > 
> > arm64 uses rela, not rel.  This requires a small change to the
> > relocation code and the linker script.
> > 
>    I also try to use rela but it not works. maybe something is wrong with the code.

Was it a build error or a runtime problem?

-Scott
diff mbox

Patch

diff --git a/arch/arm64/config.mk b/arch/arm64/config.mk
new file mode 100644
index 0000000..e40e983
--- /dev/null
+++ b/arch/arm64/config.mk
@@ -0,0 +1,32 @@ 
+#
+# Copyright (c) 2013	FengHua <fenghua@phytium.com.cn>
+#
+# 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
+#
+
+CROSS_COMPILE ?= /home/fenghua/DS-5-Workspace/gcc-linaro-aarch64-linux-gnu-4.8-2013.05_linux/bin/aarch64-linux-gnu-
+
+ifndef CONFIG_STANDALONE_LOAD_ADDR
+CONFIG_STANDALONE_LOAD_ADDR = 0x81000000
+endif
+
+PLATFORM_CPPFLAGS += -DCONFIG_ARM64 -fpic -mstrict-align
+
+# needed for relocation
+LDFLAGS_u-boot +=
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
new file mode 100644
index 0000000..87fa803
--- /dev/null
+++ b/arch/arm64/lib/Makefile
@@ -0,0 +1,64 @@ 
+#
+# (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
+
+COBJS-y	+= board.o
+COBJS-y	+= interrupts.o
+COBJS-y	+= reset.o
+COBJS-y	+= cache.o
+COBJS-y	+= timer.o
+
+COBJS-$(CONFIG_CMD_BOOTM) += bootm.o
+
+SOBJS-y += crt0.o
+SOBJS-y += relocate.o
+
+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 libarm64.o
+TARGETS	:= $(LIB)
+
+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/arch/arm64/lib/board.c b/arch/arm64/lib/board.c
new file mode 100644
index 0000000..a8147a5
--- /dev/null
+++ b/arch/arm64/lib/board.c
@@ -0,0 +1,456 @@ 
+/*
+ * (C) Copyright 2013
+ * David Feng, Phytium Technology <fenghua@phytium.com.cn>
+ *
+ * (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>
+ *
+ * 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 <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 <libfdt.h>
+#include <fdtdec.h>
+#include <post.h>
+#include <logbuff.h>
+#include <pci.h>
+#include <fdt_support.h>
+#include <asm/arch/mmu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+ulong monitor_flash_len;
+
+/* The following functions defined in platform code */
+extern int dram_init(void);
+extern int arch_cpu_init(void);
+
+/* for the following variables, see start.S */
+extern ulong _bss_start_ofs;	/* BSS start relative to _start */
+extern ulong _bss_end_ofs;	/* BSS end relative to _start */
+extern ulong _end_ofs;		/* end of image relative to _start */
+
+static int init_baudrate(void)
+{
+	gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
+	return 0;
+}
+
+static int display_banner(void)
+{
+	printf("\n\n%s\n\n", version_string);
+	debug("U-Boot code: %lx -> %lx  BSS: -> %lx\n",
+		(ulong)CONFIG_SYS_TEXT_BASE,
+		(ulong)(CONFIG_SYS_TEXT_BASE + _bss_start_ofs),
+		(ulong)(CONFIG_SYS_TEXT_BASE + _bss_end_ofs));
+
+	return (0);
+}
+
+/*
+ * Default implementation of display_cpuinfo()
+ * Real implementation should be in platform code
+ */
+int __display_cpuinfo(void)
+{
+	return 0;
+}
+int display_cpuinfo(void)
+	__attribute__((weak, alias("__display_cpuinfo")));
+
+/*
+ * Default implementation of display_boardinfo()
+ * Real implementation should be in platform code
+ */
+static int __display_boardinfo(void)
+{
+	return 0;
+}
+int display_boardinfo(void)
+	__attribute__((weak, alias("__display_boardinfo")));
+
+/*
+ * Default implementation of board_early_init_f()
+ * Real implementation should be in platform code
+ */
+static int __board_early_init_f(void)
+{
+	return 0;
+}
+int board_early_init_f(void)
+	__attribute__((weak, alias("__board_early_init_f")));
+
+/*
+ * Default implementation of board_late_init()
+ * Real implementation should be in platform code
+ */
+static int __board_late_init(void)
+{
+	return 0;
+}
+int board_late_init(void)
+	__attribute__((weak, alias("__board_late_init")));
+
+/*
+ * All attempts to come up with a "common" initialization sequence
+ * that works for all boards and architectures failed: some of the
+ * requirements are just _too_ different. To get rid of the resulting
+ * mess of board dependent #ifdef'ed code we now make the whole
+ * initialization sequence configurable to the user.
+ *
+ * The requirements for any new initalization function is simple: it
+ * receives a pointer to the "global data" structure as it's only
+ * argument, and returns an integer return code, where 0 means
+ * "continue" and != 0 means "fatal error, hang the system".
+ */
+typedef int (init_fnc_t) (void);
+
+init_fnc_t *init_sequence[] = {
+	arch_cpu_init,		/* basic arch cpu dependent setup */
+	board_early_init_f,
+#ifdef CONFIG_OF_CONTROL
+	fdtdec_check_fdt,
+#endif
+	env_init,		/* initialize environment */
+	init_baudrate,		/* initialze baudrate settings */
+	serial_init,		/* serial communications setup */
+	console_init_f,		/* stage 1 init of console */
+	display_banner,		/* say that we are here */
+	display_cpuinfo,	/* display cpu info (and speed) */
+	display_boardinfo,	/* display board info */
+	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;
+	void *new_fdt = NULL;
+	size_t fdt_size = 0;
+
+	bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_F, "board_init_f");
+
+	/* Pointer is writable since we allocated a register for it */
+	memset((void *)gd, 0, sizeof(gd_t));
+
+	gd->bd = (bd_t *)(gd + 1);
+	gd->mon_len = _bss_end_ofs;
+
+	/*
+	 * Device Tree file can be merged in uboot.bin or appended after
+	 * uboot.bin as a seperate file. The following code initialize 
+	 * fdt block base address.
+	 */
+#ifdef CONFIG_OF_EMBED
+	/* Get a pointer to the FDT */
+	gd->fdt_blob = _binary_dt_dtb_start;
+#elif defined(CONFIG_OF_SEPARATE)
+	/* FDT is at end of image */
+	gd->fdt_blob = (void *)(CONFIG_SYS_TEXT_BASE + _end_ofs);
+#endif
+	/* Allow the early environment to override the fdt address */
+	gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
+						(uintptr_t)gd->fdt_blob);
+
+	/*
+	 * Calling system initialization functions in sequence.
+	 */
+	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+		if ((*init_fnc_ptr)() != 0) {
+			hang ();
+		}
+	}
+
+#if defined(CONFIG_OF_CONTROL) || defined(CONFIG_OF_LIBFDT)
+	/* For now, put this check after the console is ready */
+	if (fdtdec_prepare_fdt()) {
+		panic("** CONFIG_OF_CONTROL defined but no FDT - please see doc/README.fdt-control");
+	}
+#endif
+
+	/*
+	 * Console has beeb setup, output debug messages
+	 */
+	debug("U-Boot code len: %08lX\n", gd->mon_len);
+
+	addr = CONFIG_SYS_SDRAM_BASE + gd->ram_size;
+
+	debug("Top of RAM usable for U-Boot at: %08lx\n", addr);
+
+#ifdef CONFIG_LOGBUFFER
+#ifndef CONFIG_ALT_LB_ADDR
+	/* reserve kernel log buffer */
+	addr -= (LOGBUFF_RESERVE);
+	debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr);
+#endif
+#endif
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+	/* reserve MMU table and align it to PAGE_SIZE */
+	addr -= PAGE_SIZE;
+	addr &= PAGE_MASK;
+	gd->arch.tlb_addr = addr;
+	gd->arch.tlb_size = PAGE_SIZE;
+	debug("MMU table at: %08lx\n", addr);
+#endif
+
+	/*
+	 * reserve memory for U-Boot code, data & bss
+	 * align it to PAGE_SIZE
+	 */
+	addr -= gd->mon_len;
+	addr &= PAGE_MASK;
+	debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, addr);
+
+	/*
+	 * reserve memory for malloc() arena
+	 */
+	addr_sp = addr - TOTAL_MALLOC_LEN;
+	debug("Reserving %dk for malloc() at: %08lx\n", TOTAL_MALLOC_LEN >> 10, addr_sp);
+
+	/*
+	 * (permanently) allocate a Board Info struct
+	 */
+	addr_sp -= sizeof(bd_t);
+	bd = (bd_t *)addr_sp;
+	memcpy(bd, (void *)gd->bd, sizeof(bd_t));
+	gd->bd = bd;
+	gd->bd->bi_baudrate = gd->baudrate;
+	debug("Reserving %zu Bytes for Board Info at: %08lx\n", sizeof(bd_t), addr_sp);
+
+	/*
+	 * (permanently) allocate a Global Data struct
+	 */
+	addr_sp -= sizeof(gd_t);
+	id = (gd_t *)addr_sp;
+	debug("Reserving %zu Bytes for Global Data at: %08lx\n", sizeof(gd_t), addr_sp);
+
+#if defined(CONFIG_OF_CONTROL) || defined(CONFIG_OF_LIBFDT)
+	/*
+	 * If the device tree is sitting immediate above our image then we
+	 * must relocate it. If it is embedded in the data section, then it
+	 * will be relocated with other data.
+	 */
+	if (gd->fdt_blob) {
+		fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
+
+		addr_sp -= fdt_size;
+		new_fdt = (void *)addr_sp;
+		debug("Reserving %zu Bytes for FDT at: %08lx\n", fdt_size, addr_sp);
+	}
+#endif
+
+	/* 16-byte alignment for ABI compliance */
+	addr_sp &= ~0xf;
+	debug("New Stack Pointer is: %08lx\n", addr_sp);
+
+	gd->relocaddr = addr;
+	gd->start_addr_sp = addr_sp;
+	gd->reloc_off = addr - CONFIG_SYS_TEXT_BASE;
+	debug("Relocation Offset: %08lx\n", gd->reloc_off);
+
+	if (new_fdt) {
+		memcpy(new_fdt, gd->fdt_blob, fdt_size);
+		gd->fdt_blob = new_fdt;
+	}
+
+	memcpy(id, (void *)gd, sizeof(gd_t));
+}
+
+
+/*
+ ************************************************************************
+ *
+ * This is the next part of the initialization sequence: we are now
+ * running from RAM and have a "normal" C environment, i. e. global
+ * data can be written, BSS has been cleared, the stack size in not
+ * that critical any more, etc.
+ *
+ ************************************************************************
+ */
+
+void board_init_r(gd_t *id, ulong dest_addr)
+{
+#ifndef CONFIG_SYS_NO_FLASH
+	ulong flash_size;
+#endif
+
+	gd = id;
+
+	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
+	bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
+
+	/* before here, printf can not be used */
+	serial_initialize();
+
+	debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);
+
+	monitor_flash_len = _end_ofs;
+
+	/* Enable caches */
+	enable_caches();
+
+#ifdef CONFIG_NEEDS_MANUAL_RELOC
+	/*
+	 * We have to relocate the command table manually
+	 */
+	fixup_cmdtable(ll_entry_start(cmd_tbl_t, cmd),
+			ll_entry_count(cmd_tbl_t, cmd));
+#endif /* CONFIG_NEEDS_MANUAL_RELOC */
+
+	/* there are some other pointer constants we must deal with */
+#ifndef CONFIG_ENV_IS_NOWHERE
+	env_name_spec += gd->reloc_off;
+#endif
+
+#ifdef CONFIG_LOGBUFFER
+	logbuff_init_ptrs();
+#endif
+
+	/* The Malloc area is immediately below the monitor copy in DRAM */
+	mem_malloc_init (dest_addr - TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN);
+
+#ifndef CONFIG_SYS_NO_FLASH
+	puts("Flash: ");
+
+	flash_size = flash_init();
+	if (flash_size > 0) {
+# ifdef CONFIG_SYS_FLASH_CHECKSUM
+		char *s = getenv("flashchecksum");
+
+		print_size(flash_size, "");
+		/*
+		 * Compute and print flash CRC if flashchecksum is set to 'y'
+		 *
+		 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
+		 */
+		if (s && (*s == 'y')) {
+			printf("  CRC: %08X", crc32(0,
+				(const unsigned char *) CONFIG_SYS_FLASH_BASE,
+				flash_size));
+		}
+		putc('\n');
+# else	/* !CONFIG_SYS_FLASH_CHECKSUM */
+		print_size(flash_size, "\n");
+# endif /* CONFIG_SYS_FLASH_CHECKSUM */
+	} else {
+		puts("*** failed ***\n");
+		hang();
+	}
+#endif
+
+#ifdef CONFIG_CMD_NAND
+	puts("NAND:  ");
+	nand_init();		/* go init the NAND */
+#endif
+
+#ifdef CONFIG_CMD_ONENAND
+	onenand_init();
+#endif
+
+#ifdef CONFIG_GENERIC_MMC
+	puts("MMC:   ");
+	mmc_initialize(gd->bd);
+#endif
+
+	/* initialize environment */
+	env_relocate();
+
+#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)
+	pci_init();
+#endif
+
+	stdio_init();	/* get the devices list going. */
+
+	jumptable_init();
+
+#if defined(CONFIG_API)
+	/* Initialize API */
+	api_init();
+#endif
+
+	console_init_r();	/* fully init console as a device */
+
+	/* set up and enable exceptions */
+	interrupt_init();
+	enable_interrupts();
+
+	/* Initialize from environment */
+	load_addr = getenv_ulong("loadaddr", 16, load_addr);
+
+	board_late_init();
+
+#if defined(CONFIG_CMD_NET)
+	puts("Net:   ");
+	eth_initialize(gd->bd);
+#if defined(CONFIG_RESET_PHY_R)
+	debug("Reset Ethernet PHY\n");
+	reset_phy();
+#endif
+#endif
+
+#ifdef CONFIG_POST
+	post_run(NULL, POST_RAM | post_bootmode_get(0));
+#endif
+
+#ifdef CONFIG_OF_LIBFDT
+	set_working_fdt_addr((void *)gd->fdt_blob);
+#endif
+
+#ifdef CONFIG_LOGBUFFER
+	/*
+	 * Export available size of memory for Linux,
+	 * taking into account the protected RAM at top of memory
+	 */
+	{
+		ulong pram = 0;
+		uchar memsz[32];
+
+#ifndef CONFIG_ALT_LB_ADDR
+		/* Also take the logbuffer into account (pram is in kB) */
+		pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024;
+#endif
+		sprintf((char *)memsz, "%ldk", (gd->ram_size / 1024) - pram);
+		setenv("mem", (char *)memsz);
+	}
+#endif
+
+	/* main_loop() can return to retry autoboot, if so just run it again. */
+	for (;;) {
+		main_loop();
+	}
+
+	/* NOTREACHED - no way out of command loop except booting */
+}
diff --git a/arch/arm64/lib/bootm.c b/arch/arm64/lib/bootm.c
new file mode 100644
index 0000000..af3bc09
--- /dev/null
+++ b/arch/arm64/lib/bootm.c
@@ -0,0 +1,211 @@ 
+/*
+ * Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
+ *  - Added prep subcommand support
+ *  - Reorganized source - modeled after powerpc version
+ *
+ * (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 <libfdt.h>
+#include <fdt_support.h>
+
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern int cleanup_before_linux(void);
+
+
+static ulong get_sp(void)
+{
+	ulong ret;
+
+	asm("mov %0, sp" : "=r"(ret) : );
+	return ret;
+}
+
+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 4K to be safe */
+	sp -= 4096;
+	lmb_reserve(lmb, sp,
+		    gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
+}
+
+#ifdef CONFIG_OF_LIBFDT
+int arch_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;
+	}
+
+	return fdt_fixup_memory_banks(blob, start, size, CONFIG_NR_DRAM_BANKS);
+}
+#endif
+
+/**
+ * announce_and_cleanup() - Print message and prepare for kernel boot
+ *
+ * @fake: non-zero to do everything except actually boot
+ */
+static void announce_and_cleanup(int fake)
+{
+	printf("\nStarting kernel ...%s\n\n", fake ?
+		"(fake run for tracing)" : "");
+	bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
+#ifdef CONFIG_BOOTSTAGE_FDT
+	if (flag == BOOTM_STATE_OS_FAKE_GO)
+		bootstage_fdt_add_report();
+#endif
+#ifdef CONFIG_BOOTSTAGE_REPORT
+	bootstage_report();
+#endif
+
+#ifdef CONFIG_USB_DEVICE
+	udc_disconnect();
+#endif
+	cleanup_before_linux();
+}
+
+/* Subcommand: PREP */
+static void boot_prep_linux(bootm_headers_t *images)
+{
+	if (!images->ft_len && gd->fdt_blob) {
+		images->ft_addr = (void *)gd->fdt_blob;
+		images->ft_len = fdt_totalsize(gd->fdt_blob);
+	}
+
+	if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
+#ifdef CONFIG_OF_LIBFDT
+		debug("using: FDT\n");
+		if (image_setup_linux(images)) {
+			printf("FDT creation failed! hanging...");
+			hang();
+		}
+#endif
+	} else {
+		printf("FDT support not compiled in - hanging\n");
+		hang();
+	}
+}
+
+/* Subcommand: GO */
+static void boot_jump_linux(bootm_headers_t *images, int flag)
+{
+	void (*kernel_entry)(void *fdt_addr);
+	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
+
+	kernel_entry = (void (*)(void *fdt_addr))images->ep;
+
+	debug("## Transferring control to Linux (at address %lx)" \
+		"...\n", (ulong)kernel_entry);
+	bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+	announce_and_cleanup(fake);
+
+	if (!fake)
+		kernel_entry(images->ft_addr);
+}
+
+/* Main Entry point for arm bootm implementation
+ *
+ * Modeled after the powerpc implementation
+ * DIFFERENCE: Instead of calling prep and go at the end
+ * they are called if subcommand is equal 0.
+ */
+int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
+{
+	/* No need for those on ARM */
+	if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE)
+		return -1;
+
+	if (flag & BOOTM_STATE_OS_PREP) {
+		boot_prep_linux(images);
+		return 0;
+	}
+
+	if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
+		boot_jump_linux(images, flag);
+		return 0;
+	}
+
+	boot_prep_linux(images);
+	boot_jump_linux(images, flag);
+	return 0;
+}
+
+#ifdef CONFIG_CMD_BOOTZ
+
+struct zimage_header {
+	uint32_t	code[9];
+	uint32_t	zi_magic;
+	uint32_t	zi_start;
+	uint32_t	zi_end;
+};
+
+#define	LINUX_ARM_ZIMAGE_MAGIC	0x016f2818
+
+int bootz_setup(ulong image, ulong *start, ulong *end)
+{
+	struct zimage_header *zi;
+
+	zi = (struct zimage_header *)map_sysmem(image, 0);
+	if (zi->zi_magic != LINUX_ARM_ZIMAGE_MAGIC) {
+		puts("Bad Linux ARM zImage magic!\n");
+		return 1;
+	}
+
+	*start = zi->zi_start;
+	*end = zi->zi_end;
+
+	printf("Kernel image @ %#08lx [ %#08lx - %#08lx ]\n", image, *start,
+	      *end);
+
+	return 0;
+}
+
+#endif	/* CONFIG_CMD_BOOTZ */
diff --git a/arch/arm64/lib/cache.c b/arch/arm64/lib/cache.c
new file mode 100644
index 0000000..29c1ab2
--- /dev/null
+++ b/arch/arm64/lib/cache.c
@@ -0,0 +1,282 @@ 
+/*
+ * Copyright (c) 2013	David Feng <fenghua@phytium.com.cn>
+ *
+ * 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 <asm/processor.h>
+#include <asm/arch/mmu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/********************************************************************/
+
+/*
+ * Stub implementations for outer cache operations
+ */
+void __outer_cache_enable(void) {}
+void outer_cache_enable(void)
+	__attribute__((weak, alias("__outer_cache_enable")));
+
+void __outer_cache_disable(void) {}
+void outer_cache_disable(void)
+	__attribute__((weak, alias("__outer_cache_disable")));
+
+void __outer_cache_flush_all(void) {}
+void outer_cache_flush_all(void)
+ 	__attribute__((weak, alias("__outer_cache_flush_all")));
+
+void __outer_cache_inval_all(void) {}
+void outer_cache_inval_all(void)
+	__attribute__((weak, alias("__outer_cache_inval_all")));
+
+void __outer_cache_flush_range(unsigned long start, unsigned long end) {}
+void outer_cache_flush_range(unsigned long start, unsigned long end)
+	__attribute__((weak, alias("__outer_cache_flush_range")));
+
+void __outer_cache_inval_range(unsigned long start, unsigned long end) {}
+void outer_cache_inval_range(unsigned long start, unsigned long end)
+	__attribute__((weak, alias("__outer_cache_inval_range")));
+
+/********************************************************************/
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+
+static void set_section_dcache(u64 section, u64 memory_type)
+{
+	u64 *page_table = (u64 *)gd->arch.tlb_addr;
+	u64 value;
+
+	value = (section << SECTION_SHIFT) | PMD_TYPE_SECT | PMD_SECT_AF;
+	value |= PMD_ATTRINDX(memory_type);
+	page_table[section] = value;
+}
+
+/* to activate the MMU we need to set up virtual memory */
+static inline void mmu_setup(void)
+{
+	int i, j;
+	bd_t *bd = gd->bd;
+	static int table_initialized = 0;
+
+	if (!table_initialized) {
+		/* Setup an identity-mapping for all spaces */
+		for (i = 0; i < (PAGE_SIZE >> 3); i++)
+			set_section_dcache(i, MT_DEVICE_nGnRnE);
+
+		/* Setup an identity-mapping for all RAM space */
+		for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+			debug("%s: bank: %d\n", __func__, i);
+			for (j = bd->bi_dram[i].start >> SECTION_SHIFT;
+				 j < (bd->bi_dram[i].start + bd->bi_dram[i].size) >> SECTION_SHIFT;
+				 j++) {
+				set_section_dcache(i, MT_NORMAL);
+			}
+		}
+
+		/* load TTBR0 */
+		asm volatile("msr ttbr0_el2, %0" : : "r" (gd->arch.tlb_addr) : "memory");
+
+		table_initialized = 1;
+	}
+
+	/* and enable the mmu */
+	set_sctlr(get_sctlr() | CR_M);
+}
+
+/*
+ * Performs a invalidation of the entire data cache
+ * at all levels
+ */
+void invalidate_dcache_all(void)
+{
+	__flush_dcache_all();
+	outer_cache_inval_all();
+}
+
+/*
+ * Performs a clean & invalidation of the entire data cache
+ * at all levels
+ */
+void flush_dcache_all(void)
+{
+	__flush_dcache_all();
+	outer_cache_flush_all();
+}
+
+/*
+ * Invalidates range in all levels of D-cache/unified cache used:
+ * Affects the range [start, stop - 1]
+ */
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+	__flush_dcache_range(start, stop);
+	outer_cache_inval_range(start, stop);
+}
+
+/*
+ * Flush range(clean & invalidate) from all levels of D-cache/unified
+ * cache used:
+ * Affects the range [start, stop - 1]
+ */
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+	__flush_dcache_range(start, stop);
+	outer_cache_flush_range(start, stop);
+}
+
+void dcache_enable(void)
+{
+	uint32_t sctlr;
+
+	sctlr = get_sctlr();
+
+	/* The data cache is not active unless the mmu is enabled too */
+	if (!(sctlr & CR_M)) {
+		outer_cache_enable();
+		invalidate_dcache_all();
+		__invalidate_tlb_all();
+
+		mmu_setup();
+	}
+
+	set_sctlr(sctlr | CR_C);
+}
+
+void dcache_disable(void)
+{
+	uint32_t sctlr;
+
+	sctlr = get_sctlr();
+
+	/* if cache isn't enabled no need to disable */
+	if (!(sctlr & CR_C))
+		return;
+
+	set_sctlr(sctlr & ~(CR_C|CR_M));
+
+	flush_dcache_all();
+	__invalidate_tlb_all();
+}
+
+int dcache_status(void)
+{
+	return (get_sctlr() & CR_C) != 0;
+}
+
+#else
+
+void invalidate_dcache_all(void)
+{
+}
+
+void flush_dcache_all(void)
+{
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void dcache_enable(void)
+{
+}
+
+void dcache_disable(void)
+{
+}
+
+int dcache_status(void)
+{
+	return 0;
+}
+
+#endif /* CONFIG_SYS_DCACHE_OFF */
+
+/********************************************************************/
+
+#ifndef CONFIG_SYS_ICACHE_OFF
+
+void icache_enable(void)
+{
+	set_sctlr(get_sctlr() | CR_I);
+}
+
+void icache_disable(void)
+{
+	set_sctlr(get_sctlr() & ~CR_I);
+}
+
+int icache_status(void)
+{
+	return (get_sctlr() & CR_I) != 0;
+}
+
+void invalidate_icache_all(void)
+{
+	__invalidate_icache_all();
+}
+
+#else
+
+void icache_enable(void)
+{
+}
+
+void icache_disable(void)
+{
+}
+
+int icache_status(void)
+{
+	return 0;
+}
+
+void invalidate_icache_all(void)
+{
+}
+
+#endif /* CONFIG_SYS_ICACHE_OFF */
+
+/********************************************************************/
+
+/*
+ * Enable dCache & iCache, whether cache is actually enabled
+ * depend on CONFIG_SYS_DCACHE_OFF and CONFIG_SYS_ICACHE_OFF
+ */
+void enable_caches(void)
+{
+	icache_enable();
+	dcache_enable();
+}
+
+/*
+ * Flush range from all levels of d-cache/unified-cache used:
+ * Affects the range [start, start + size - 1]
+ */
+void flush_cache(unsigned long start, unsigned long size)
+{
+	flush_dcache_range(start, start + size);
+}
diff --git a/arch/arm64/lib/crt0.S b/arch/arm64/lib/crt0.S
new file mode 100644
index 0000000..d18a2dd
--- /dev/null
+++ b/arch/arm64/lib/crt0.S
@@ -0,0 +1,129 @@ 
+/*
+ * crt0 - C-runtime startup Code for ARM64 U-Boot
+ *
+ * Copyright (c) 2013  David Feng <fenghua@phytium.com.cn>
+ *
+ * Bsed on arm/lib/crt0.S by Albert ARIBAUD <albert.u.boot@aribaud.net>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <config.h>
+#include <asm-offsets.h>
+#include <linux/linkage.h>
+
+/*
+ * This file handles the target-independent stages of the U-Boot
+ * start-up where a C runtime environment is needed. Its entry point
+ * is _main and is branched into from the target's start.S file.
+ *
+ * _main execution sequence is:
+ *
+ * 1. Set up initial environment for calling board_init_f().
+ *    This environment only provides a stack and a place to store
+ *    the GD ('global data') structure, both located in some readily
+ *    available RAM (SRAM, locked cache...). In this context, VARIABLE
+ *    global data, initialized or not (BSS), are UNAVAILABLE; only
+ *    CONSTANT initialized data are available.
+ *
+ * 2. Call board_init_f(). This function prepares the hardware for
+ *    execution from system RAM (DRAM, DDR...) As system RAM may not
+ *    be available yet, , board_init_f() must use the current GD to
+ *    store any data which must be passed on to later stages. These
+ *    data include the relocation destination, the future stack, and
+ *    the future GD location.
+ *
+ * (the following applies only to non-SPL builds)
+ *
+ * 3. Set up intermediate environment where the stack and GD are the
+ *    ones allocated by board_init_f() in system RAM, but BSS and
+ *    initialized non-const data are still not available.
+ *
+ * 4. Call relocate_code(). This function relocates U-Boot from its
+ *    current location into the relocation destination computed by
+ *    board_init_f().
+ *
+ * 5. Set up final environment for calling board_init_r(). This
+ *    environment has BSS (initialized to 0), initialized non-const
+ *    data (initialized to their intended value), and stack in system
+ *    RAM. GD has retained values set by board_init_f(). Some CPUs
+ *    have some work left to do at this point regarding memory, so
+ *    call c_runtime_cpu_setup.
+ *
+ * 6. Branch to board_init_r().
+ */
+
+ENTRY(_main)
+
+/*
+ * Set up initial C runtime environment and call board_init_f(0).
+ */
+	ldr	x0, =(CONFIG_SYS_INIT_SP_ADDR)
+	sub	x0, x0, #GD_SIZE	/* allocate one GD above SP */
+	bic	sp, x0, #0xf		/* 16-byte alignment for ABI compliance */
+	mov	x18, sp			/* GD is above SP */
+	mov	x0, #0
+	bl	board_init_f
+
+/*
+ * Set up intermediate environment (new sp and gd) and call
+ * relocate_code(addr_moni). Trick here is that we'll return
+ * 'here' but relocated.
+ */
+	ldr	x0, [x18, #GD_START_ADDR_SP]	/* x0 = gd->start_addr_sp */
+	bic	sp, x0, #0xf			/* 16-byte alignment for ABI compliance */
+	ldr	x18, [x18, #GD_BD]		/* x18 = gd->bd */
+	sub	x18, x18, #GD_SIZE		/* new GD is below bd */
+
+	adr	lr, relocation_return
+	ldr	x9, [x18, #GD_RELOC_OFF]	/* x0 = gd->reloc_off */
+	add	lr, lr, x9			/* new return address after relocation */
+	ldr	x0, [x18, #GD_RELOCADDR]	/* x0 = gd->relocaddr */
+	b	relocate_code
+
+relocation_return:
+
+/*
+ * Set up final (full) environment
+ */
+	bl	c_runtime_cpu_setup		/* we still call old routine here */
+
+/*
+ * Clear BSS section
+ */
+	ldr	x9, [x18, #GD_RELOC_OFF]	/* x9 = gd->reloc_off */
+	ldr	x0, =__bss_start		/* x0 = __bss_start in FLASH */
+	add	x0, x0, x9			/* x0 = __bss_start in RAM */
+	ldr	x1, =__bss_end			/* x1 = __bss_end in FLASH */
+	add	x1, x1, x9			/* x1 = __bss_end in RAM */
+	mov	x2, #0
+clear_loop:
+	str	x2, [x0]
+	add	x0, x0, #8
+	cmp	x0, x1
+	b.lo	clear_loop
+
+	/* call board_init_r(gd_t *id, ulong dest_addr) */
+	mov	x0, x18				/* gd_t */
+	ldr	x1, [x18, #GD_RELOCADDR]	/* dest_addr */
+	b	board_init_r			/* PC relative jump */
+
+	/* NOTREACHED - board_init_r() does not return */
+
+ENDPROC(_main)
diff --git a/arch/arm64/lib/interrupts.c b/arch/arm64/lib/interrupts.c
new file mode 100644
index 0000000..b843785
--- /dev/null
+++ b/arch/arm64/lib/interrupts.c
@@ -0,0 +1,109 @@ 
+/*
+ * Copyright (c) 2013	David Feng <fenghua@phytium.com.cn>
+ *
+ * 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>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const char *handler[]= {
+	"Synchronous Abort",
+	"IRQ",
+	"FIQ",
+	"Error"
+};
+
+#ifdef CONFIG_USE_IRQ
+int interrupt_init (void)
+{
+	return 0;
+}
+
+/* enable IRQ interrupts */
+void enable_interrupts (void)
+{
+}
+
+/*
+ * disable IRQ/FIQ interrupts
+ * returns true if interrupts had been enabled before we disabled them
+ */
+int disable_interrupts (void)
+{
+	return 0;
+}
+#else
+int interrupt_init (void)
+{
+	return 0;
+}
+
+void enable_interrupts (void)
+{
+	return;
+}
+int disable_interrupts (void)
+{
+	return 0;
+}
+#endif /* CONFIG_USE_IRQ */
+
+
+void show_regs (struct pt_regs *regs)
+{
+	int i;
+
+	printf("PC is at %lx\n", regs->pc);
+	printf("LR is at %lx\n", regs->regs[30]);
+	printf("PSTATE: %08lx\n", regs->pstate);
+	printf("SP : %lx\n", regs->sp);
+	for (i = 29; i >= 0; i--) {
+		printf("x%-2d: %016lx ", i, regs->regs[i]);
+		if (i % 2 == 0)
+			printf("\n");
+	}
+	printf("\n");
+}
+
+/*
+ * bad_mode handles the impossible case in the exception vector.
+ */
+void bad_mode(struct pt_regs *pt_regs, int reason, unsigned int esr)
+{
+#ifdef CONFIG_NEEDS_MANUAL_RELOC
+	static int relocated = 0;
+
+	/* relocate boot function table */
+	if (!relocated) {
+		int i;
+		for (i = 0; i < ARRAY_SIZE(handler); i++)
+			handler[i] += gd->reloc_off;
+		relocated = 1;
+	}
+#endif
+
+	printf("Bad mode in \"%s\" handler detected, esr 0x%08x\n",
+		handler[reason], esr);
+
+	show_regs(pt_regs);
+
+	panic("Resetting CPU ...\n");
+}
diff --git a/arch/arm64/lib/relocate.S b/arch/arm64/lib/relocate.S
new file mode 100644
index 0000000..6bbcc2a
--- /dev/null
+++ b/arch/arm64/lib/relocate.S
@@ -0,0 +1,72 @@ 
+/*
+ * relocate - common relocation function for ARM64 U-Boot
+ *
+ * Copyright (c) 2013	David Feng <fenghua@phytium.com.cn>
+ *
+ * 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 <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+/*
+ * void relocate_code (addr_moni)
+ *
+ * This function relocates the monitor code.
+ *
+ * NOTE:
+ * Currently, ld with -pie produce errors. So, GOT is used
+ * and configuration CONFIG_NEEDS_MANUAL_RELOC is needed.
+ */
+ENTRY(relocate_code)
+	/*
+	 * Copy u-boot from flash to RAM
+	 */
+	ldr	x1, =__image_copy_start	/* x1 <- copy source */
+	cmp	x1, x0
+	b.eq	relocate_done		/* skip relocation */
+	mov	x2, x0			/* x2 <- copy destination */
+	ldr	x3, =__image_copy_end	/* x3 <- source end address */
+
+copy_loop:
+	ldp	x10, x11, [x1], #16	/* copy from source address [x1] */
+	stp	x10, x11, [x2], #16	/* copy to   target address [x2] */
+	cmp	x1, x3			/* until source end address [x3] */
+	b.lo	copy_loop
+
+	/*
+	 * Fix .reloc relocations
+	 */
+	ldr	x9, [x18, #GD_RELOC_OFF]/* x9 <- relocation offset */
+	ldr	x1, =__rel_got_start	/* x1 <- rel got start ofs */
+	add	x1, x1, x9		/* x1 <- rel got start in RAM */
+	ldr	x2, =__rel_got_end	/* x2 <- rel got end ofs */
+	add	x2, x2, x9		/* x2 <- rel got end in RAM */
+fixloop:
+	ldr	x10, [x1]		/* x10 <- address to be fixed up */
+	add	x10, x10, x9		/* x10 <- address to be fixed up in RAM*/
+	str	x10, [x1]
+	add	x1, x1, #8		/* each gotn entry is 8 bytes */
+	cmp	x1, x2
+	b.lo	fixloop
+
+relocate_done:
+	ret
+ENDPROC(relocate_code)
diff --git a/arch/arm64/lib/reset.c b/arch/arm64/lib/reset.c
new file mode 100644
index 0000000..32de7a3
--- /dev/null
+++ b/arch/arm64/lib/reset.c
@@ -0,0 +1,37 @@ 
+/*
+ * Copyright (c) 2013	David Feng <fenghua@phytium.com.cn>
+ *
+ * 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>
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	puts("Resetting system ...\n");
+
+	udelay(50000);		/* wait 50 ms */
+
+	disable_interrupts();
+
+	reset_cpu(0);
+
+	/*NOTREACHED*/
+	return 0;
+}
diff --git a/arch/arm64/lib/timer.c b/arch/arm64/lib/timer.c
new file mode 100644
index 0000000..8c0cfcb
--- /dev/null
+++ b/arch/arm64/lib/timer.c
@@ -0,0 +1,95 @@ 
+/*
+ * Copyright (c) 2013	David Feng <fenghua@phytium.com.cn>
+ *
+ * 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 <div64.h>
+
+/*
+ * Genertic Timer implementation of __udelay/get_timer/get_ticks/get_tbclk
+ * functions. If any other timers used, another implementation should be
+ * placed in platform code.
+ */
+
+static inline unsigned long tick_to_time(unsigned long tick)
+{
+	tick *= CONFIG_SYS_HZ;
+	do_div(tick, CONFIG_SYS_CNTFRQ);
+	return tick;
+}
+
+static inline unsigned long time_to_tick(unsigned long time)
+{
+	time *= CONFIG_SYS_CNTFRQ;
+	do_div(time, CONFIG_SYS_HZ);
+	return time;
+}
+
+/*
+ * Generic timer implementation of get_tbclk()
+ */
+ulong __get_tbclk (void)
+{
+	return CONFIG_SYS_HZ;
+}
+ulong get_tbclk(void)
+	__attribute__((weak, alias("__get_tbclk")));
+
+/*
+ * Generic timer implementation of get_timer()
+ */
+ulong __get_timer(ulong base)
+{
+	u64 cval;
+
+	isb();
+	asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
+
+	tick_to_time(cval);
+
+	return tick_to_time(cval) - base;
+}
+ulong get_timer(ulong base)
+	__attribute__((weak, alias("__get_timer")));
+
+/*
+ * Generic timer implementation of get_ticks()
+ */
+unsigned long long __get_ticks(void)
+{
+	return get_timer(0);
+}
+unsigned long long get_ticks(void)
+	__attribute__((weak, alias("__get_ticks")));
+
+/*
+ * Generic timer implementation of __udelay()
+ */
+void ___udelay(ulong usec)
+{
+	unsigned long tmp;
+
+	tmp = get_ticks() + usec/1000;
+
+	while (get_ticks() < tmp);
+}
+void __udelay(ulong usec)
+	__attribute__((weak, alias("___udelay")));
diff --git a/board/armltd/dts/vexpress64.dts b/board/armltd/dts/vexpress64.dts
new file mode 100644
index 0000000..3814e01
--- /dev/null
+++ b/board/armltd/dts/vexpress64.dts
@@ -0,0 +1,215 @@ 
+/*
+ * ARM Ltd. Fast Models
+ *
+ * Architecture Envelope Model (AEM) ARMv8-A
+ * ARMAEMv8AMPCT
+ *
+ * RTSM_VE_AEMv8A.lisa
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x80000000 0x00010000;
+
+/ {
+	/* boot configurations for u-boot */
+	config {
+		/*bootdelay = <1>;*/
+		kernel-offset = <0x100000>;
+		rootdisk-offset = <0x800000>;
+		bootcmd = "bootm 0x100000 0x800000:0x2000000";
+	};
+};
+
+/ {
+	model = "RTSM_VE_AEMv8A";
+	compatible = "arm,rtsm_ve,aemv8a", "arm,vexpress";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	/* chosen */
+	/* generated by u-boot */
+
+
+	aliases {
+		serial0 = &v2m_serial0;
+		serial1 = &v2m_serial1;
+		serial2 = &v2m_serial2;
+		serial3 = &v2m_serial3;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x0 0x8000fff8>;
+		};
+		cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <1>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x0 0x8000fff8>;
+		};
+		cpu@2 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <2>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x0 0x8000fff8>;
+		};
+		cpu@3 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <3>;
+			enable-method = "spin-table";
+			cpu-release-addr = <0x0 0x8000fff8>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x00000000 0x80000000 0 0x80000000>,
+		      <0x00000008 0x80000000 0 0x80000000>;
+	};
+
+	gic: interrupt-controller@2c001000 {
+		compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+		interrupt-controller;
+		reg = <0x0 0x2c001000 0 0x1000>,
+		      <0x0 0x2c002000 0 0x1000>,
+		      <0x0 0x2c004000 0 0x2000>,
+		      <0x0 0x2c006000 0 0x2000>;
+		interrupts = <1 9 0xf04>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <1 13 0xff01>,
+			     <1 14 0xff01>,
+			     <1 11 0xff01>,
+			     <1 10 0xff01>;
+		clock-frequency = <100000000>;
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <0 60 4>,
+			     <0 61 4>,
+			     <0 62 4>,
+			     <0 63 4>;
+	};
+
+	smb {
+		compatible = "simple-bus";
+
+		#address-cells = <2>;
+		#size-cells = <1>;
+		ranges = <0 0 0 0x08000000 0x04000000>,
+			 <1 0 0 0x14000000 0x04000000>,
+			 <2 0 0 0x18000000 0x04000000>,
+			 <3 0 0 0x1c000000 0x04000000>,
+			 <4 0 0 0x0c000000 0x04000000>,
+			 <5 0 0 0x10000000 0x04000000>;
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 63>;
+		interrupt-map = <0 0  0 &gic 0  0 4>,
+				<0 0  1 &gic 0  1 4>,
+				<0 0  2 &gic 0  2 4>,
+				<0 0  3 &gic 0  3 4>,
+				<0 0  4 &gic 0  4 4>,
+				<0 0  5 &gic 0  5 4>,
+				<0 0  6 &gic 0  6 4>,
+				<0 0  7 &gic 0  7 4>,
+				<0 0  8 &gic 0  8 4>,
+				<0 0  9 &gic 0  9 4>,
+				<0 0 10 &gic 0 10 4>,
+				<0 0 11 &gic 0 11 4>,
+				<0 0 12 &gic 0 12 4>,
+				<0 0 13 &gic 0 13 4>,
+				<0 0 14 &gic 0 14 4>,
+				<0 0 15 &gic 0 15 4>,
+				<0 0 16 &gic 0 16 4>,
+				<0 0 17 &gic 0 17 4>,
+				<0 0 18 &gic 0 18 4>,
+				<0 0 19 &gic 0 19 4>,
+				<0 0 20 &gic 0 20 4>,
+				<0 0 21 &gic 0 21 4>,
+				<0 0 22 &gic 0 22 4>,
+				<0 0 23 &gic 0 23 4>,
+				<0 0 24 &gic 0 24 4>,
+				<0 0 25 &gic 0 25 4>,
+				<0 0 26 &gic 0 26 4>,
+				<0 0 27 &gic 0 27 4>,
+				<0 0 28 &gic 0 28 4>,
+				<0 0 29 &gic 0 29 4>,
+				<0 0 30 &gic 0 30 4>,
+				<0 0 31 &gic 0 31 4>,
+				<0 0 32 &gic 0 32 4>,
+				<0 0 33 &gic 0 33 4>,
+				<0 0 34 &gic 0 34 4>,
+				<0 0 35 &gic 0 35 4>,
+				<0 0 36 &gic 0 36 4>,
+				<0 0 37 &gic 0 37 4>,
+				<0 0 38 &gic 0 38 4>,
+				<0 0 39 &gic 0 39 4>,
+				<0 0 40 &gic 0 40 4>,
+				<0 0 41 &gic 0 41 4>,
+				<0 0 42 &gic 0 42 4>;
+
+		/include/ "aemv8a.dtsi"
+	};
+
+	panels {
+		panel@0 {
+			compatible	= "panel";
+			mode		= "VGA";
+			refresh		= <60>;
+			xres		= <640>;
+			yres		= <480>;
+			pixclock	= <39721>;
+			left_margin	= <40>;
+			right_margin	= <24>;
+			upper_margin	= <32>;
+			lower_margin	= <11>;
+			hsync_len	= <96>;
+			vsync_len	= <2>;
+			sync		= <0>;
+			vmode		= "FB_VMODE_NONINTERLACED";
+			tim2		= "TIM2_BCD", "TIM2_IPC";
+			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
+			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
+			bpp		= <16>;
+		};
+
+		panel@1 {
+			compatible	= "panel";
+			mode		= "XVGA";
+			refresh		= <60>;
+			xres		= <1024>;
+			yres		= <768>;
+			pixclock	= <15748>;
+			left_margin	= <152>;
+			right_margin	= <48>;
+			upper_margin	= <23>;
+			lower_margin	= <3>;
+			hsync_len	= <104>;
+			vsync_len	= <4>;
+			sync		= <0>;
+			vmode		= "FB_VMODE_NONINTERLACED";
+			tim2		= "TIM2_BCD", "TIM2_IPC";
+			cntl		= "CNTL_LCDTFT", "CNTL_BGR", "CNTL_LCDVCOMP(1)";
+			caps		= "CLCD_CAP_5551", "CLCD_CAP_565", "CLCD_CAP_888";
+			bpp		= <16>;
+		};
+	};
+};
diff --git a/board/armltd/vexpress64/Makefile b/board/armltd/vexpress64/Makefile
new file mode 100644
index 0000000..77f0c3f
--- /dev/null
+++ b/board/armltd/vexpress64/Makefile
@@ -0,0 +1,43 @@ 
+#
+# (C) Copyright 2000-2004
+# 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$(BOARD).o
+
+COBJS	:= vexpress64.o
+
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c
new file mode 100644
index 0000000..b86736d
--- /dev/null
+++ b/board/armltd/vexpress64/vexpress64.c
@@ -0,0 +1,63 @@ 
+/*
+ * (C) Copyright 2013
+ * Phytium Technology, <www.phytium.com.cn>
+ * David Feng, fenghua@phytium.com.cn
+ *
+ * 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 <malloc.h>
+#include <errno.h>
+#include <netdev.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Board specific reset that is system reset.
+ */
+void reset_cpu(ulong addr)
+{
+}
+
+/*
+ * Default implementation of gpio related functiuons
+ * Real implementation should be in gpio driver.
+ * fdtdec.c need this function, but currenty no gpio driver defined
+ */
+int __gpio_get_value(unsigned gpio)
+{
+	return 0;
+}
+int gpio_get_value(unsigned gpio)
+	__attribute__((weak, alias("__gpio_get_value")));
+
+void __gpio_set_value(unsigned gpio, int vlaue)
+{
+	return;
+}
+void gpio_set_value(unsigned gpio, int vlaue)
+	__attribute__((weak, alias("__gpio_set_value")));
+
+void __gpio_request(unsigned gpio, const char *label)
+{
+	return;
+}
+void gpio_request(unsigned gpio, const char *label)
+	__attribute__((weak, alias("__gpio_request")));
diff --git a/boards.cfg b/boards.cfg
index 944ed4c..561b0d6 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -1182,5 +1182,6 @@  gr_ep2s60                    sparc       leon3       -                   gaisler
 grsim                        sparc       leon3       -                   gaisler
 gr_xc3s_1500                 sparc       leon3       -                   gaisler
 coreboot-x86                 x86         x86        coreboot            chromebook-x86 coreboot    coreboot:SYS_TEXT_BASE=0x01110000
+vexpress_aemv8a              arm64       armv8       vexpress64          armltd
 # Target                     ARCH        CPU         Board name          Vendor	        SoC         Options
 ########################################################################################################################
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index af884b8..4a7b61b 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -517,6 +517,38 @@  int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	return 0;
 }
 
+#elif defined(CONFIG_ARM64)
+
+int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	int i;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) {
+		print_num("DRAM bank",	i);
+		print_num("  -> start",	gd->bd->bi_dram[i].start);
+		print_num("  -> size",	gd->bd->bi_dram[i].size);
+	}
+
+	printf("baudrate    = %ld bps\n", gd->bd->bi_baudrate);
+
+	print_num("relocaddr", gd->relocaddr);
+	print_num("reloc off", gd->reloc_off);
+	print_num("sp start ", gd->start_addr_sp);
+#ifndef CONFIG_SYS_DCACHE_OFF
+	print_num("TLB addr", gd->arch.tlb_addr);
+#endif
+
+	printf("CPU frequency = %ld MHz\n", gd->cpu_clk);
+	printf("DDR frequency = %ld MHz\n", gd->mem_clk);
+
+#if defined(CONFIG_CMD_NET)
+	print_eth(0);
+	printf("ip_addr     = %s\n", getenv("ipaddr"));
+#endif
+
+	return 0;
+}
+
 #else
  #error "a case for this architecture does not exist!"
 #endif
diff --git a/common/fdt_support.c b/common/fdt_support.c
index b034c98..9bc5821 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -21,6 +21,34 @@ 
  */
 DECLARE_GLOBAL_DATA_PTR;
 
+/*
+ * Get cells len in bytes
+ *     if #NNNN-cells property is 2 then len is 8
+ *     otherwise len is 4
+ */
+static int get_cells_len(void *blob, char *nr_cells_name)
+{
+	const fdt32_t *cell;
+
+	cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
+	if (cell && fdt32_to_cpu(*cell) == 2)
+		return 8;
+
+	return 4;
+}
+
+/*
+ * Write a 4 or 8 byte big endian cell
+ */
+static void write_cell(u8 *addr, u64 val, int size)
+{
+	int shift = (size - 1) * 8;
+	while (size-- > 0) {
+		*addr++ = (val >> shift) & 0xff;
+		shift -= 8;
+	}
+}
+
 /**
  * fdt_getprop_u32_default - Find a node and return it's property or a default
  *
@@ -131,9 +159,9 @@  static int fdt_fixup_stdout(void *fdt, int chosenoff)
 
 int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
 {
-	int   nodeoffset;
+	int   nodeoffset, addr_cell_len;
 	int   err, j, total;
-	fdt32_t  tmp;
+	fdt64_t  tmp;
 	const char *path;
 	uint64_t addr, size;
 
@@ -170,9 +198,11 @@  int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
 		return err;
 	}
 
+	addr_cell_len = get_cells_len(fdt, "#address-cells");
+
 	path = fdt_getprop(fdt, nodeoffset, "linux,initrd-start", NULL);
 	if ((path == NULL) || force) {
-		tmp = cpu_to_fdt32(initrd_start);
+		write_cell((u8 *)&tmp, initrd_start, addr_cell_len);
 		err = fdt_setprop(fdt, nodeoffset,
 			"linux,initrd-start", &tmp, sizeof(tmp));
 		if (err < 0) {
@@ -181,7 +211,7 @@  int fdt_initrd(void *fdt, ulong initrd_start, ulong initrd_end, int force)
 				fdt_strerror(err));
 			return err;
 		}
-		tmp = cpu_to_fdt32(initrd_end);
+		write_cell((u8 *)&tmp, initrd_end, addr_cell_len);
 		err = fdt_setprop(fdt, nodeoffset,
 			"linux,initrd-end", &tmp, sizeof(tmp));
 		if (err < 0) {
@@ -343,34 +373,6 @@  void do_fixup_by_compat_u32(void *fdt, const char *compat,
 	do_fixup_by_compat(fdt, compat, prop, &tmp, 4, create);
 }
 
-/*
- * Get cells len in bytes
- *     if #NNNN-cells property is 2 then len is 8
- *     otherwise len is 4
- */
-static int get_cells_len(void *blob, char *nr_cells_name)
-{
-	const fdt32_t *cell;
-
-	cell = fdt_getprop(blob, 0, nr_cells_name, NULL);
-	if (cell && fdt32_to_cpu(*cell) == 2)
-		return 8;
-
-	return 4;
-}
-
-/*
- * Write a 4 or 8 byte big endian cell
- */
-static void write_cell(u8 *addr, u64 val, int size)
-{
-	int shift = (size - 1) * 8;
-	while (size-- > 0) {
-		*addr++ = (val >> shift) & 0xff;
-		shift -= 8;
-	}
-}
-
 #ifdef CONFIG_NR_DRAM_BANKS
 #define MEMORY_BANKS_MAX CONFIG_NR_DRAM_BANKS
 #else
diff --git a/common/image.c b/common/image.c
index 56a5a62..7a24550 100644
--- a/common/image.c
+++ b/common/image.c
@@ -81,6 +81,7 @@  static const table_entry_t uimage_arch[] = {
 	{	IH_ARCH_NDS32,		"nds32",	"NDS32",	},
 	{	IH_ARCH_OPENRISC,	"or1k",		"OpenRISC 1000",},
 	{	IH_ARCH_SANDBOX,	"sandbox",	"Sandbox",	},
+	{	IH_ARCH_ARM64,		"arm64",	"ARM64",	},
 	{	-1,			"",		"",		},
 };
 
@@ -422,7 +423,7 @@  ulong getenv_bootm_low(void)
 
 #if defined(CONFIG_SYS_SDRAM_BASE)
 	return CONFIG_SYS_SDRAM_BASE;
-#elif defined(CONFIG_ARM)
+#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
 	return gd->bd->bi_dram[0].start;
 #else
 	return 0;
@@ -444,7 +445,7 @@  phys_size_t getenv_bootm_size(void)
 		tmp = 0;
 
 
-#if defined(CONFIG_ARM)
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
 	return gd->bd->bi_dram[0].size - tmp;
 #else
 	return gd->bd->bi_memsize - tmp;
diff --git a/doc/README.arm64 b/doc/README.arm64
new file mode 100644
index 0000000..8fef26d
--- /dev/null
+++ b/doc/README.arm64
@@ -0,0 +1,10 @@ 
+Notes:
+
+1. Currenly, u-boot running at EL2.
+
+2. Currently, gcc-aarch64 produce error when compiling with pie and rel_dyn.
+   So, GOT is used to relocate u-boot and CONFIG_NEEDS_MANUAL_RELOC is needed.
+
+3. Currently, fdt should be in the first 512MB of RAM, so, fdt_high should be handled specially.
+   I define fdt_high as 0xa0000000 when CONFIG_SYS_SDRAM_BASE is 0x80000000.
+
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c
index 8fb1765..4e39b1b 100644
--- a/examples/standalone/stubs.c
+++ b/examples/standalone/stubs.c
@@ -195,6 +195,19 @@  gd_t *global_data;
 "	l.jr	r13\n"		\
 "	l.nop\n"				\
 	: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r13");
+#elif defined(CONFIG_ARM64)
+/*
+ * x18 holds the pointer to the global_data, ip is a call-clobbered
+ * register
+ */
+#define EXPORT_FUNC(x) \
+	asm volatile (			\
+"	.globl " #x "\n"		\
+#x ":\n"				\
+"	ldr	x19, [x18, %0]\n"		\
+"	ldr	x19, [x19, %1]\n"		\
+"	br	x19\n"		\
+	: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "x19");
 #else
 /*"	addi	$sp, $sp, -24\n"	\
 "	br	$r16\n"			\*/
diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h
new file mode 100644
index 0000000..3c96987
--- /dev/null
+++ b/include/configs/vexpress_aemv8a.h
@@ -0,0 +1,200 @@ 
+/*
+ * Configuration for Versatile Express. Parts were derived from other ARM
+ *   configurations.
+ *
+ * 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
+ */
+
+#ifndef __VEXPRESS_AEMV8A_H
+#define __VEXPRESS_AEMV8A_H
+
+#define DEBUG
+
+#define CONFIG_SYS_NO_FLASH
+
+#define CONFIG_SUPPORT_RAW_INITRD
+
+#define CONFIG_SKIP_LOWLEVEL_INIT
+
+/* Cache Definitions */
+//#define CONFIG_SYS_DCACHE_OFF
+//#define CONFIG_SYS_ICACHE_OFF
+
+#define CONFIG_IDENT_STRING		" aarch64"
+#define CONFIG_BOOTP_VCI_STRING    	"U-boot.armv8.vexpress_aemv8a"
+
+/* Link Definitions */
+#define CONFIG_SYS_TEXT_BASE		0x80000000
+#define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SYS_SDRAM_BASE + 0x400000)
+
+/* Flat Device Tree Definitions */
+#define CONFIG_OF_EMBED
+#define CONFIG_OF_CONTROL
+#define CONFIG_OF_LIBFDT
+
+#define CONFIG_DEFAULT_DEVICE_TREE	vexpress64
+
+/* SMP Definitions */
+#define SECONDARY_CPU_MAILBOX		0x8000fff8
+
+/* CS register bases for the original memory map. */
+#define V2M_PA_CS0			0x00000000
+#define V2M_PA_CS1			0x14000000
+#define V2M_PA_CS2			0x18000000
+#define V2M_PA_CS3			0x1c000000
+#define V2M_PA_CS4			0x0c000000
+#define V2M_PA_CS5			0x10000000
+
+#define V2M_PERIPH_OFFSET(x)		(x << 16)
+#define V2M_SYSREGS			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(1))
+#define V2M_SYSCTL			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(2))
+#define V2M_SERIAL_BUS_PCI		(V2M_PA_CS3 + V2M_PERIPH_OFFSET(3))
+
+#define V2M_BASE			0x80000000
+
+/*
+ * Physical addresses, offset from V2M_PA_CS0-3
+ */
+#define V2M_NOR0			(V2M_PA_CS0)
+#define V2M_NOR1			(V2M_PA_CS4)
+#define V2M_SRAM			(V2M_PA_CS1)
+
+/* Common peripherals relative to CS7. */
+#define V2M_AACI			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(4))
+#define V2M_MMCI			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(5))
+#define V2M_KMI0			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(6))
+#define V2M_KMI1			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(7))
+
+#define V2M_UART0			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(9))
+#define V2M_UART1			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(10))
+#define V2M_UART2			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(11))
+#define V2M_UART3			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(12))
+
+#define V2M_WDT				(V2M_PA_CS3 + V2M_PERIPH_OFFSET(15))
+
+#define V2M_TIMER01			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(17))
+#define V2M_TIMER23			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(18))
+
+#define V2M_SERIAL_BUS_DVI		(V2M_PA_CS3 + V2M_PERIPH_OFFSET(22))
+#define V2M_RTC				(V2M_PA_CS3 + V2M_PERIPH_OFFSET(23))
+
+#define V2M_CF				(V2M_PA_CS3 + V2M_PERIPH_OFFSET(26))
+
+#define V2M_CLCD			(V2M_PA_CS3 + V2M_PERIPH_OFFSET(31))
+
+/* System register offsets. */
+#define V2M_SYS_CFGDATA			(V2M_SYSREGS + 0x0a0)
+#define V2M_SYS_CFGCTRL			(V2M_SYSREGS + 0x0a4)
+#define V2M_SYS_CFGSTAT			(V2M_SYSREGS + 0x0a8)
+
+/* Generic Timer Definitions */
+#define CONFIG_SYS_CNTFRQ		(0x1800000)	/* 24MHz */
+
+/* Generic Interrupt Controller Definitions */
+#define GIC_DIST_BASE			(0x2C001000)
+#define GIC_CPU_BASE			(0x2C002000)
+
+#define CONFIG_SYS_MEMTEST_START	V2M_BASE
+#define CONFIG_SYS_MEMTEST_END		(V2M_BASE + 0x80000000)
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 128 * 1024)
+
+/* PL011 Serial Configuration */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_CLOCK		24000000
+#define CONFIG_PL01x_PORTS		{(void *)CONFIG_SYS_SERIAL0, \
+					 (void *)CONFIG_SYS_SERIAL1}
+#define CONFIG_CONS_INDEX		0
+
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+#define CONFIG_SYS_SERIAL0		V2M_UART0
+#define CONFIG_SYS_SERIAL1		V2M_UART1
+
+/* Command line configuration */
+#define CONFIG_MENU
+//#define CONFIG_MENU_SHOW
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_BDI
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_PXE
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_FLASH
+#define CONFIG_CMD_IMI
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SAVEENV
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_BOOTD
+#define CONFIG_CMD_ECHO
+#define CONFIG_CMD_SOURCE
+#define CONFIG_CMD_FAT
+#define CONFIG_DOS_PARTITION
+
+/* BOOTP options */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_PXE
+#define CONFIG_BOOTP_PXE_CLIENTARCH	0x100
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_LOAD_ADDR		(V2M_BASE + 0x10000000)	/* load address */
+
+/* Physical Memory Map */
+#define CONFIG_NR_DRAM_BANKS		1
+#define PHYS_SDRAM_1			(V2M_BASE)	/* SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE		0x80000000	/* 2048 MB */
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+
+
+/* Initial environment variables */
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+					"loadaddr=0x80100000\0"		\
+					"kernel_addr=0x100000\0"	\
+					"ramdisk_addr=0x800000\0"	\
+					"ramdisk_size=0x2000000\0"	\
+					"fdt_high=0xa0000000\0"		\
+					"console=ttyAMA0,38400n8\0"
+
+#define CONFIG_BOOTARGS			"console=ttyAMA0 root=/dev/ram0"
+#define CONFIG_BOOTCOMMAND		"bootm $kernel_addr $ramdisk_addr:$ramdisk_size"
+#define CONFIG_BOOTDELAY		-1
+
+/* Store environment at top of flash */
+#define CONFIG_ENV_IS_NOWHERE		1
+#define CONFIG_ENV_SIZE			0x1000
+
+/* Monitor Command Prompt */
+#define CONFIG_SYS_CBSIZE		512	/* Console I/O Buffer Size */
+#define CONFIG_SYS_PROMPT		"VExpress# "
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE + \
+					sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE /* Boot args buffer */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_CMDLINE_EDITING		1
+#define CONFIG_SYS_MAXARGS		64	/* max command args */
+
+#endif /* __VEXPRESS_AEMV8A_H */
diff --git a/include/image.h b/include/image.h
index f93a393..491e547 100644
--- a/include/image.h
+++ b/include/image.h
@@ -156,6 +156,7 @@  struct lmb;
 #define IH_ARCH_SANDBOX		19	/* Sandbox architecture (test only) */
 #define IH_ARCH_NDS32	        20	/* ANDES Technology - NDS32  */
 #define IH_ARCH_OPENRISC        21	/* OpenRISC 1000  */
+#define IH_ARCH_ARM64		22	/* ARM64  */
 
 /*
  * Image Types
diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c
index 6ea7b03..6c53b62 100644
--- a/lib/asm-offsets.c
+++ b/lib/asm-offsets.c
@@ -29,7 +29,7 @@  int main(void)
 
 	DEFINE(GD_BD, offsetof(struct global_data, bd));
 
-#if defined(CONFIG_ARM)
+#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
 
 	DEFINE(GD_RELOCADDR, offsetof(struct global_data, relocaddr));