[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.
fenghua at phytium.com.cn
fenghua at phytium.com.cn
Sun Aug 11 18:05:23 CEST 2013
From: fenghua <fenghua at 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 at 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
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 at 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 at 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 at phytium.com.cn>
+ *
+ * (C) Copyright 2002-2006
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger at 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 at 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 at sysgo.de>
+ *
+ * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw at 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 at 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 at phytium.com.cn>
+ *
+ * Bsed on arm/lib/crt0.S by Albert ARIBAUD <albert.u.boot at 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 at 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 at 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 at 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 at 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 at 0 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <0>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x0 0x8000fff8>;
+ };
+ cpu at 1 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <1>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x0 0x8000fff8>;
+ };
+ cpu at 2 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <2>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x0 0x8000fff8>;
+ };
+ cpu at 3 {
+ device_type = "cpu";
+ compatible = "arm,armv8";
+ reg = <3>;
+ enable-method = "spin-table";
+ cpu-release-addr = <0x0 0x8000fff8>;
+ };
+ };
+
+ memory at 80000000 {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000 0 0x80000000>,
+ <0x00000008 0x80000000 0 0x80000000>;
+ };
+
+ gic: interrupt-controller at 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 at 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 at 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 at 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 at 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));
--
1.7.9.5
More information about the U-Boot
mailing list