
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
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));