[U-Boot] [PATCH v3 0/5] arm64 patch

From: David Feng fenghua@phytium.com.cn
*** BLURB HERE *** Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok. - according to scott wood's advice, make the fdt 64bit initrd start address support a seperate patch.
David Feng (5): core support of arm64 board support of arm64 arch support 1 of arm64 arch support 2 of arm64 64bit initrd start address support
arch/arm64/config.mk | 32 +++ arch/arm64/cpu/armv8/Makefile | 51 ++++ arch/arm64/cpu/armv8/cache.S | 144 ++++++++++ arch/arm64/cpu/armv8/config.mk | 29 ++ arch/arm64/cpu/armv8/cpu.c | 108 ++++++++ arch/arm64/cpu/armv8/exceptions.S | 189 +++++++++++++ arch/arm64/cpu/armv8/start.S | 197 ++++++++++++++ arch/arm64/cpu/armv8/tlb.S | 38 +++ arch/arm64/cpu/u-boot.lds | 73 +++++ arch/arm64/dts/aemv8a.dtsi | 234 ++++++++++++++++ arch/arm64/include/asm/arch-armv8/mmu.h | 117 ++++++++ arch/arm64/include/asm/atomic.h | 115 ++++++++ arch/arm64/include/asm/bitops.h | 153 +++++++++++ arch/arm64/include/asm/byteorder.h | 31 +++ arch/arm64/include/asm/cache.h | 53 ++++ arch/arm64/include/asm/config.h | 41 +++ arch/arm64/include/asm/errno.h | 1 + arch/arm64/include/asm/global_data.h | 38 +++ arch/arm64/include/asm/gpio.h | 1 + arch/arm64/include/asm/io.h | 193 +++++++++++++ arch/arm64/include/asm/linkage.h | 49 ++++ arch/arm64/include/asm/posix_types.h | 61 +++++ arch/arm64/include/asm/processor.h | 59 ++++ arch/arm64/include/asm/ptrace.h | 64 +++++ arch/arm64/include/asm/sections.h | 27 ++ arch/arm64/include/asm/string.h | 49 ++++ arch/arm64/include/asm/system.h | 106 ++++++++ arch/arm64/include/asm/types.h | 67 +++++ arch/arm64/include/asm/u-boot.h | 38 +++ arch/arm64/include/asm/unaligned.h | 28 ++ arch/arm64/include/asm/utils.h | 56 ++++ arch/arm64/lib/Makefile | 64 +++++ arch/arm64/lib/board.c | 453 +++++++++++++++++++++++++++++++ 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 | 4 - 52 files changed, 4509 insertions(+), 38 deletions(-) create mode 100644 arch/arm64/config.mk create mode 100644 arch/arm64/cpu/armv8/Makefile create mode 100644 arch/arm64/cpu/armv8/cache.S create mode 100644 arch/arm64/cpu/armv8/config.mk create mode 100644 arch/arm64/cpu/armv8/cpu.c create mode 100644 arch/arm64/cpu/armv8/exceptions.S create mode 100644 arch/arm64/cpu/armv8/start.S create mode 100644 arch/arm64/cpu/armv8/tlb.S create mode 100644 arch/arm64/cpu/u-boot.lds create mode 100644 arch/arm64/dts/aemv8a.dtsi create mode 100644 arch/arm64/include/asm/arch-armv8/mmu.h create mode 100644 arch/arm64/include/asm/atomic.h create mode 100644 arch/arm64/include/asm/bitops.h create mode 100644 arch/arm64/include/asm/byteorder.h create mode 100644 arch/arm64/include/asm/cache.h create mode 100644 arch/arm64/include/asm/config.h create mode 100644 arch/arm64/include/asm/errno.h create mode 100644 arch/arm64/include/asm/global_data.h create mode 100644 arch/arm64/include/asm/gpio.h create mode 100644 arch/arm64/include/asm/io.h create mode 100644 arch/arm64/include/asm/linkage.h create mode 100644 arch/arm64/include/asm/posix_types.h create mode 100644 arch/arm64/include/asm/processor.h create mode 100644 arch/arm64/include/asm/ptrace.h create mode 100644 arch/arm64/include/asm/sections.h create mode 100644 arch/arm64/include/asm/string.h create mode 100644 arch/arm64/include/asm/system.h create mode 100644 arch/arm64/include/asm/types.h create mode 100644 arch/arm64/include/asm/u-boot.h create mode 100644 arch/arm64/include/asm/unaligned.h create mode 100644 arch/arm64/include/asm/utils.h 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

From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn --- Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
common/cmd_bdinfo.c | 32 ++++++++++++++++++++++++++++++++ common/image.c | 5 +++-- doc/README.arm64 | 10 ++++++++++ examples/standalone/stubs.c | 13 +++++++++++++ include/image.h | 1 + lib/asm-offsets.c | 4 ---- 6 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 doc/README.arm64
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/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..578985a 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, x9 is a call-clobbered + * register + */ +#define EXPORT_FUNC(x) \ + asm volatile ( \ +" .globl " #x "\n" \ +#x ":\n" \ +" ldr x9, [x18, %0]\n" \ +" ldr x9, [x9, %1]\n" \ +" br x9\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/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..450514d 100644 --- a/lib/asm-offsets.c +++ b/lib/asm-offsets.c @@ -29,15 +29,11 @@ int main(void)
DEFINE(GD_BD, offsetof(struct global_data, bd));
-#if defined(CONFIG_ARM) - DEFINE(GD_RELOCADDR, offsetof(struct global_data, relocaddr));
DEFINE(GD_RELOC_OFF, offsetof(struct global_data, reloc_off));
DEFINE(GD_START_ADDR_SP, offsetof(struct global_data, start_addr_sp));
-#endif - return 0; }

From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn --- Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
board/armltd/dts/vexpress64.dts | 215 ++++++++++++++++++++++++++++++++++ board/armltd/vexpress64/Makefile | 43 +++++++ board/armltd/vexpress64/vexpress64.c | 63 ++++++++++ boards.cfg | 1 + include/configs/vexpress_aemv8a.h | 200 +++++++++++++++++++++++++++++++ 5 files changed, 522 insertions(+) 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 include/configs/vexpress_aemv8a.h
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/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h new file mode 100644 index 0000000..d920333 --- /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 " vexpress_aemv8a" +#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 */

On Thu, Aug 15, 2013 at 8:47 AM, fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn
Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
board/armltd/dts/vexpress64.dts | 215 ++++++++++++++++++++++++++++++++++
Why is the device tree source in u-boot (instead of in the kernel)? Is this temporary? It looks like this device tree is just a copy from somewhere else.
Would suggest removing this from this patch series and keep the dts maintained in the Linux kernel.
Stuart

On Fri, 2013-08-16 at 09:14 -0500, Stuart Yoder wrote:
On Thu, Aug 15, 2013 at 8:47 AM, fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn
Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
board/armltd/dts/vexpress64.dts | 215 ++++++++++++++++++++++++++++++++++
Why is the device tree source in u-boot (instead of in the kernel)? Is this temporary? It looks like this device tree is just a copy from somewhere else.
Would suggest removing this from this patch series and keep the dts maintained in the Linux kernel.
U-Boot itself uses the device tree (not just to patch up for Linux) on some targets.
Even with the way PPC uses device trees, it doesn't really make sense to keep them in the kernel given that they're meant to be OS-neutral, and have ties to U-Boot in terms of what gets fixed up at runtime.
-Scott

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 08/19/2013 03:59 PM, Scott Wood wrote:
On Fri, 2013-08-16 at 09:14 -0500, Stuart Yoder wrote:
On Thu, Aug 15, 2013 at 8:47 AM, fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn --- Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
board/armltd/dts/vexpress64.dts | 215 ++++++++++++++++++++++++++++++++++
Why is the device tree source in u-boot (instead of in the kernel)? Is this temporary? It looks like this device tree is just a copy from somewhere else.
Would suggest removing this from this patch series and keep the dts maintained in the Linux kernel.
U-Boot itself uses the device tree (not just to patch up for Linux) on some targets.
Even with the way PPC uses device trees, it doesn't really make sense to keep them in the kernel given that they're meant to be OS-neutral, and have ties to U-Boot in terms of what gets fixed up at runtime.
Longer term, I want us to be able to make more use of device trees, where possible and bindings are complete and stable. And at that point we'll have to deal with "how do we get a DT from $where-ever to here to use.
- -- Tom

On Mon, Aug 19, 2013 at 2:59 PM, Scott Wood scottwood@freescale.com wrote:
On Fri, 2013-08-16 at 09:14 -0500, Stuart Yoder wrote:
On Thu, Aug 15, 2013 at 8:47 AM, fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn
Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
board/armltd/dts/vexpress64.dts | 215 ++++++++++++++++++++++++++++++++++
Why is the device tree source in u-boot (instead of in the kernel)? Is this temporary? It looks like this device tree is just a copy from somewhere else.
Would suggest removing this from this patch series and keep the dts maintained in the Linux kernel.
U-Boot itself uses the device tree (not just to patch up for Linux) on some targets.
Even with the way PPC uses device trees, it doesn't really make sense to keep them in the kernel given that they're meant to be OS-neutral, and have ties to U-Boot in terms of what gets fixed up at runtime.
It may not make sense, but that is where they are kept currently. It doesn't make sense to maintain 2 copies of a vexpress64.dts device tree in 2 different places...or to maintain 1 lone device tree in u-boot.
Maybe we need a git repo for device trees that could be included in Linux, u-boot, and other things a submodule.
Stuart

On Thu, 2013-08-22 at 11:15 -0500, Stuart Yoder wrote:
On Mon, Aug 19, 2013 at 2:59 PM, Scott Wood scottwood@freescale.com wrote:
On Fri, 2013-08-16 at 09:14 -0500, Stuart Yoder wrote:
On Thu, Aug 15, 2013 at 8:47 AM, fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn
Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
board/armltd/dts/vexpress64.dts | 215 ++++++++++++++++++++++++++++++++++
Why is the device tree source in u-boot (instead of in the kernel)? Is this temporary? It looks like this device tree is just a copy from somewhere else.
Would suggest removing this from this patch series and keep the dts maintained in the Linux kernel.
U-Boot itself uses the device tree (not just to patch up for Linux) on some targets.
Even with the way PPC uses device trees, it doesn't really make sense to keep them in the kernel given that they're meant to be OS-neutral, and have ties to U-Boot in terms of what gets fixed up at runtime.
It may not make sense, but that is where they are kept currently.
For PPC.
It doesn't make sense to maintain 2 copies of a vexpress64.dts device tree in 2 different places...or to maintain 1 lone device tree in u-boot.
Why does it not make sense for there to be one lone device tree in U-Boot?
A device tree that is not used with U-Boot may not look the same, since U-Boot is (at least on some platforms) responsible for filling in parts of the tree, and (again on some platforms) for setting up the address map.
Maybe we need a git repo for device trees that could be included in Linux, u-boot, and other things a submodule.
Submodules can be a pain. If we don't use them for DTC, why would we use them for this? Since they require extra commands, you'd be modifying the workflow of everyone that builds U-Boot and/or Linux for affected platforms.
-Scott

On Thu, Aug 22, 2013 at 11:23 AM, Scott Wood scottwood@freescale.com wrote:
On Thu, 2013-08-22 at 11:15 -0500, Stuart Yoder wrote:
On Mon, Aug 19, 2013 at 2:59 PM, Scott Wood scottwood@freescale.com wrote:
On Fri, 2013-08-16 at 09:14 -0500, Stuart Yoder wrote:
On Thu, Aug 15, 2013 at 8:47 AM, fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn
Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
board/armltd/dts/vexpress64.dts | 215 ++++++++++++++++++++++++++++++++++
Why is the device tree source in u-boot (instead of in the kernel)? Is this temporary? It looks like this device tree is just a copy from somewhere else.
Would suggest removing this from this patch series and keep the dts maintained in the Linux kernel.
U-Boot itself uses the device tree (not just to patch up for Linux) on some targets.
Even with the way PPC uses device trees, it doesn't really make sense to keep them in the kernel given that they're meant to be OS-neutral, and have ties to U-Boot in terms of what gets fixed up at runtime.
It may not make sense, but that is where they are kept currently.
For PPC.
$ find arch/arm/boot/dts | wc -l 425 $ find arch/powerpc/boot/dts | wc -l 315
There are also a handful of device trees under arch/arm64/boot/dts, including what looks like a vexpress board.
It doesn't make sense to maintain 2 copies of a vexpress64.dts device tree in 2 different places...or to maintain 1 lone device tree in u-boot.
Why does it not make sense for there to be one lone device tree in U-Boot?
It doesn't make sense to me to keep one device tree in u-boot and the rest in the kernel.
I don't know where that vexpress64.dts came from, but I'm guessing it's a copy from the Linux kernel.
A device tree that is not used with U-Boot may not look the same, since U-Boot is (at least on some platforms) responsible for filling in parts of the tree, and (again on some platforms) for setting up the address map.
Maybe we need a git repo for device trees that could be included in Linux, u-boot, and other things a submodule.
Submodules can be a pain. If we don't use them for DTC, why would we use them for this? Since they require extra commands, you'd be modifying the workflow of everyone that builds U-Boot and/or Linux for affected platforms.
You shouldn't need device trees for building u-boot or the kernel. I don't think a couple of extra commands is that burdensome.
I agree the DTS files really don't belong in the kernel, but there is currently no better repository that has been proposed. I'm not sure u-boot is a better place. Device trees should be independent of any particular bootloader or OS.
Stuart

On Thu, 2013-08-22 at 12:44 -0500, Stuart Yoder wrote:
On Thu, Aug 22, 2013 at 11:23 AM, Scott Wood scottwood@freescale.com wrote:
On Thu, 2013-08-22 at 11:15 -0500, Stuart Yoder wrote:
On Mon, Aug 19, 2013 at 2:59 PM, Scott Wood scottwood@freescale.com wrote:
On Fri, 2013-08-16 at 09:14 -0500, Stuart Yoder wrote:
Why is the device tree source in u-boot (instead of in the kernel)? Is this temporary? It looks like this device tree is just a copy from somewhere else.
Would suggest removing this from this patch series and keep the dts maintained in the Linux kernel.
U-Boot itself uses the device tree (not just to patch up for Linux) on some targets.
Even with the way PPC uses device trees, it doesn't really make sense to keep them in the kernel given that they're meant to be OS-neutral, and have ties to U-Boot in terms of what gets fixed up at runtime.
It may not make sense, but that is where they are kept currently.
For PPC.
$ find arch/arm/boot/dts | wc -l 425 $ find arch/powerpc/boot/dts | wc -l 315
My point is this isn't the first device tree to go into U-Boot for ARM.
It doesn't make sense to maintain 2 copies of a vexpress64.dts device tree in 2 different places...or to maintain 1 lone device tree in u-boot.
Why does it not make sense for there to be one lone device tree in U-Boot?
It doesn't make sense to me to keep one device tree in u-boot and the rest in the kernel.
That's not what's being proposed.
Submodules can be a pain. If we don't use them for DTC, why would we use them for this? Since they require extra commands, you'd be modifying the workflow of everyone that builds U-Boot and/or Linux for affected platforms.
You shouldn't need device trees for building u-boot or the kernel.
Then why mess around with submodules instead of just a separate repository?
I don't think a couple of extra commands is that burdensome.
I disagree, and at the least don't want to be the one to advocate such a change. :-)
I agree the DTS files really don't belong in the kernel, but there is currently no better repository that has been proposed. I'm not sure u-boot is a better place. Device trees should be independent of any particular bootloader or OS.
The final device tree that the OS sees should be independent of the OS. The dts is not the final device tree, and is tied to U-Boot. The device tree in general is also tied to the bootloader in other ways -- U-Boot expects certain aliases, configurable addresses must match, etc.
-Scott

On Thu, Aug 22, 2013 at 12:50:44PM -0500, Scott Wood wrote:
On Thu, 2013-08-22 at 12:44 -0500, Stuart Yoder wrote:
On Thu, Aug 22, 2013 at 11:23 AM, Scott Wood scottwood@freescale.com wrote:
On Thu, 2013-08-22 at 11:15 -0500, Stuart Yoder wrote:
On Mon, Aug 19, 2013 at 2:59 PM, Scott Wood scottwood@freescale.com wrote:
On Fri, 2013-08-16 at 09:14 -0500, Stuart Yoder wrote:
Why is the device tree source in u-boot (instead of in the kernel)? Is this temporary? It looks like this device tree is just a copy from somewhere else.
Would suggest removing this from this patch series and keep the dts maintained in the Linux kernel.
U-Boot itself uses the device tree (not just to patch up for Linux) on some targets.
Even with the way PPC uses device trees, it doesn't really make sense to keep them in the kernel given that they're meant to be OS-neutral, and have ties to U-Boot in terms of what gets fixed up at runtime.
It may not make sense, but that is where they are kept currently.
For PPC.
$ find arch/arm/boot/dts | wc -l 425 $ find arch/powerpc/boot/dts | wc -l 315
My point is this isn't the first device tree to go into U-Boot for ARM.
Right, but a problem we have today is that the existing ones are incompatible with the real device trees for the devices in question.
It doesn't make sense to maintain 2 copies of a vexpress64.dts device tree in 2 different places...or to maintain 1 lone device tree in u-boot.
Why does it not make sense for there to be one lone device tree in U-Boot?
It doesn't make sense to me to keep one device tree in u-boot and the rest in the kernel.
That's not what's being proposed.
Submodules can be a pain. If we don't use them for DTC, why would we use them for this? Since they require extra commands, you'd be modifying the workflow of everyone that builds U-Boot and/or Linux for affected platforms.
You shouldn't need device trees for building u-boot or the kernel.
Then why mess around with submodules instead of just a separate repository?
I don't think a couple of extra commands is that burdensome.
I disagree, and at the least don't want to be the one to advocate such a change. :-)
I agree the DTS files really don't belong in the kernel, but there is currently no better repository that has been proposed. I'm not sure u-boot is a better place. Device trees should be independent of any particular bootloader or OS.
The final device tree that the OS sees should be independent of the OS. The dts is not the final device tree, and is tied to U-Boot. The device tree in general is also tied to the bootloader in other ways -- U-Boot expects certain aliases, configurable addresses must match, etc.
I really hope that when the data gets pulled out of the kernel we'll have a useable central repository somewhere that can be used and various problems like this are taken into consideration.

From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn --- Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
arch/arm64/lib/Makefile | 64 ++++++ arch/arm64/lib/board.c | 453 +++++++++++++++++++++++++++++++++++++++++++ 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 +++++++++ 9 files changed, 1452 insertions(+) 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
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..19e6543 --- /dev/null +++ b/arch/arm64/lib/board.c @@ -0,0 +1,453 @@ +/* + * (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")));

From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn --- Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
arch/arm64/config.mk | 32 +++++ arch/arm64/cpu/armv8/Makefile | 51 +++++++ arch/arm64/cpu/armv8/cache.S | 144 +++++++++++++++++++ arch/arm64/cpu/armv8/config.mk | 29 ++++ arch/arm64/cpu/armv8/cpu.c | 108 ++++++++++++++ arch/arm64/cpu/armv8/exceptions.S | 189 +++++++++++++++++++++++++ arch/arm64/cpu/armv8/start.S | 197 ++++++++++++++++++++++++++ arch/arm64/cpu/armv8/tlb.S | 38 +++++ arch/arm64/cpu/u-boot.lds | 73 ++++++++++ arch/arm64/dts/aemv8a.dtsi | 234 +++++++++++++++++++++++++++++++ arch/arm64/include/asm/arch-armv8/mmu.h | 117 ++++++++++++++++ arch/arm64/include/asm/atomic.h | 115 +++++++++++++++ arch/arm64/include/asm/bitops.h | 153 ++++++++++++++++++++ arch/arm64/include/asm/byteorder.h | 31 ++++ arch/arm64/include/asm/cache.h | 53 +++++++ arch/arm64/include/asm/config.h | 41 ++++++ arch/arm64/include/asm/errno.h | 1 + arch/arm64/include/asm/global_data.h | 38 +++++ arch/arm64/include/asm/gpio.h | 1 + arch/arm64/include/asm/io.h | 193 +++++++++++++++++++++++++ arch/arm64/include/asm/linkage.h | 49 +++++++ arch/arm64/include/asm/posix_types.h | 61 ++++++++ arch/arm64/include/asm/processor.h | 59 ++++++++ arch/arm64/include/asm/ptrace.h | 64 +++++++++ arch/arm64/include/asm/sections.h | 27 ++++ arch/arm64/include/asm/string.h | 49 +++++++ arch/arm64/include/asm/system.h | 106 ++++++++++++++ arch/arm64/include/asm/types.h | 67 +++++++++ arch/arm64/include/asm/u-boot.h | 38 +++++ arch/arm64/include/asm/unaligned.h | 28 ++++ arch/arm64/include/asm/utils.h | 56 ++++++++ 31 files changed, 2442 insertions(+) create mode 100644 arch/arm64/config.mk create mode 100644 arch/arm64/cpu/armv8/Makefile create mode 100644 arch/arm64/cpu/armv8/cache.S create mode 100644 arch/arm64/cpu/armv8/config.mk create mode 100644 arch/arm64/cpu/armv8/cpu.c create mode 100644 arch/arm64/cpu/armv8/exceptions.S create mode 100644 arch/arm64/cpu/armv8/start.S create mode 100644 arch/arm64/cpu/armv8/tlb.S create mode 100644 arch/arm64/cpu/u-boot.lds create mode 100644 arch/arm64/dts/aemv8a.dtsi create mode 100644 arch/arm64/include/asm/arch-armv8/mmu.h create mode 100644 arch/arm64/include/asm/atomic.h create mode 100644 arch/arm64/include/asm/bitops.h create mode 100644 arch/arm64/include/asm/byteorder.h create mode 100644 arch/arm64/include/asm/cache.h create mode 100644 arch/arm64/include/asm/config.h create mode 100644 arch/arm64/include/asm/errno.h create mode 100644 arch/arm64/include/asm/global_data.h create mode 100644 arch/arm64/include/asm/gpio.h create mode 100644 arch/arm64/include/asm/io.h create mode 100644 arch/arm64/include/asm/linkage.h create mode 100644 arch/arm64/include/asm/posix_types.h create mode 100644 arch/arm64/include/asm/processor.h create mode 100644 arch/arm64/include/asm/ptrace.h create mode 100644 arch/arm64/include/asm/sections.h create mode 100644 arch/arm64/include/asm/string.h create mode 100644 arch/arm64/include/asm/system.h create mode 100644 arch/arm64/include/asm/types.h create mode 100644 arch/arm64/include/asm/u-boot.h create mode 100644 arch/arm64/include/asm/unaligned.h create mode 100644 arch/arm64/include/asm/utils.h
diff --git a/arch/arm64/config.mk b/arch/arm64/config.mk new file mode 100644 index 0000000..6ca9a04 --- /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 ?= 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/cpu/armv8/Makefile b/arch/arm64/cpu/armv8/Makefile new file mode 100644 index 0000000..1a8cdd7 --- /dev/null +++ b/arch/arm64/cpu/armv8/Makefile @@ -0,0 +1,51 @@ +# +# 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 Foundatio; 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$(CPU).o + +START := start.o + +COBJS += cpu.o + +SOBJS += exceptions.o +SOBJS += cache.o +SOBJS += tlb.o + +SRCS := $(START:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm64/cpu/armv8/cache.S b/arch/arm64/cpu/armv8/cache.S new file mode 100644 index 0000000..104d15c --- /dev/null +++ b/arch/arm64/cpu/armv8/cache.S @@ -0,0 +1,144 @@ +/* + * 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 <version.h> +#include <linux/linkage.h> + +/* + * void __flush_dcache_level(level) + * + * clean and invalidate one level cache. + * + * x0: cache level + * x1~x9: clobbered + */ +ENTRY(__flush_dcache_level) + lsl x1, x0, #1 + msr csselr_el1, x1 /* select cache level */ + isb /* isb to sych the new cssr&csidr */ + mrs x6, ccsidr_el1 /* read the new ccsidr */ + and x2, x6, #7 /* x2 = length of the cache lines */ + add x2, x2, #4 /* add 4 (line length offset) */ + mov x3, #0x3ff + and x3, x3, x6, lsr #3 /* x3 = maximum number of the way size */ + clz w5, w3 /* bit position of way size */ + mov x4, #0x7fff + and x4, x4, x1, lsr #13 /* x4 = max number of the set size */ + /* x1 = cache level << 1 */ + /* x2 = line length offset */ + /* x3 = number of cache ways */ + /* x4 = number of cache sets */ + /* x5 = bit position of way size */ + +loop_set: + mov x6, x3 /* create working copy of way size */ +loop_way: + lsl x7, x6, x5 + orr x9, x0, x7 /* map way and level to cisw value */ + lsl x7, x4, x2 + orr x9, x9, x7 /* map set number to cisw value */ + dc cisw, x9 /* clean & invalidate by set/way */ + subs x6, x6, #1 /* decrement the way */ + b.ge loop_way + subs x4, x4, #1 /* decrement the set */ + b.ge loop_set + + ret +ENDPROC(__flush_dcache_level) + +/* + * void __flush_dcache_all(void) + * + * clean and invalidate all data cache by SET/WAY. + */ +ENTRY(__flush_dcache_all) + dsb sy + mov x15, lr + mrs x10, clidr_el1 /* read clidr */ + lsr x11, x10, #24 + and x11, x11, #0x7 /* x11 = loc */ + cbz x11, finished /* if loc = 0, no need to clean */ + mov x0, #0 /* start flush at cache level 0 */ + /* x0 = level */ + /* x10 = clidr_el1 */ + /* x11 = loc */ + +loop_level: + lsl x1, x0, #1 + add x1, x1, x0 /* x0 = 3x cache level */ + lsr x1, x10, x1 + and x1, x1, #7 /* x1 = cache type */ + cmp x1, #2 + b.lt skip /* skip if no cache or icache */ + bl __flush_dcache_level /* flush dcache of level */ +skip: + add x0, x0, #1 /* increment cache level */ + cmp x11, x0 + b.gt loop_level + +finished: + mov x0, #0 + msr csselr_el1, x0 /* swith back to cache level 0 */ + dsb sy + isb + mov lr, x15 + ret +ENDPROC(__flush_dcache_all) + +/* + * void __flush_dcache_range(start, end) + * + * clean & invalidate data cache in the range + * + * x0: start address + * x1: end address + */ +ENTRY(__flush_dcache_range) + mrs x3, ctr_el0 /* read CTR */ + lsr x3, x3, #16 + and x3, x3, #0xf /* cache line size encoding */ + mov x2, #4 /* bytes per word */ + lsl x2, x2, x3 /* actual cache line size */ + + /* x2 = minimal cache line size in cache system */ + sub x3, x2, #1 + bic x0, x0, x3 +1: dc civac, x0 /* clean & invalidate D line / unified line */ + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret +ENDPROC(__flush_dcache_range) + +/* + * void __invalidate_icache_all(void) + * + * invalidate all tlb entries. + */ +ENTRY(__invalidate_icache_all) + ic ialluis + isb sy + ret +ENDPROC(__invalidate_icache_all) diff --git a/arch/arm64/cpu/armv8/config.mk b/arch/arm64/cpu/armv8/config.mk new file mode 100644 index 0000000..113075c --- /dev/null +++ b/arch/arm64/cpu/armv8/config.mk @@ -0,0 +1,29 @@ +# +# 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 +# +PLATFORM_RELFLAGS += -fno-common -ffixed-x18 + +PF_CPPFLAGS_ARMV8 := $(call cc-option, -march=armv8-a) +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARMV8) + +# SEE README.arm-unaligned-accesses +PF_NO_UNALIGNED := $(call cc-option, -mstrict-align) +PLATFORM_NO_UNALIGNED := $(PF_NO_UNALIGNED) diff --git a/arch/arm64/cpu/armv8/cpu.c b/arch/arm64/cpu/armv8/cpu.c new file mode 100644 index 0000000..7c6f158 --- /dev/null +++ b/arch/arm64/cpu/armv8/cpu.c @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2008 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, garyj@denx.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <asm/cache.h> +#include <linux/compiler.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Default implementation of arch_cpu_init() + * Real implementation should be in platform code + */ +int __arch_cpu_init(void) +{ + return 0; +} +int arch_cpu_init(void) + __attribute__((weak, alias("__arch_cpu_init"))); + +/* + * Default implementation of dram_init() + * Real implementation should be in platform code + */ +int __dram_init(void) +{ + int i; + + gd->ram_size = PHYS_SDRAM_1_SIZE; + + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + + puts("RAM Configuration:\n"); + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + printf(" Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); + print_size(gd->bd->bi_dram[i].size, "\n"); + } + + return 0; +} +int dram_init(void) + __attribute__((weak, alias("__dram_init"))); + + +int cleanup_before_linux(void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + */ + disable_interrupts(); + + /* + * Turn off I-cache and invalidate it + */ + icache_disable(); + invalidate_icache_all(); + + /* + * turn off D-cache + * dcache_disable() in turn flushes the d-cache and disables MMU + */ + dcache_disable(); + outer_cache_disable(); + + /* + * After D-cache is flushed and before it is disabled there may + * be some new valid entries brought into the cache. We are sure + * that these lines are not dirty and will not affect our execution. + * (because unwinding the call-stack and setting a bit in CP15 SCTRL + * is all we did during this. We have not pushed anything on to the + * stack. Neither have we affected any static data) + * So just invalidate the entire d-cache again to avoid coherency + * problems for kernel + */ + invalidate_dcache_all(); + + return 0; +} diff --git a/arch/arm64/cpu/armv8/exceptions.S b/arch/arm64/cpu/armv8/exceptions.S new file mode 100644 index 0000000..060bd22 --- /dev/null +++ b/arch/arm64/cpu/armv8/exceptions.S @@ -0,0 +1,189 @@ +/* + * 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 <version.h> +#include <asm/ptrace.h> +#include <linux/linkage.h> + +/* + * Exception vectors. + */ + .align 11 +ENTRY(vectors) + ventry el_current_sync_invalid /* Current EL Synchronous Thread */ + ventry el_current_irq_invalid /* Current EL IRQ Thread */ + ventry el_current_fiq_invalid /* Current EL FIQ Thread */ + ventry el_current_error_invalid /* Current EL Error Thread */ + + ventry el_current_sync_invalid /* Current EL Synchronous Handler */ + ventry el_current_irq_invalid /* Current EL IRQ Handler */ + ventry el_current_fiq_invalid /* Current EL FIQ Handler */ + ventry el_current_error_invalid /* Current EL Error Handler */ + + ventry el_lower_sync_invalid /* Lower EL Synchronous 64-bit Handler */ + ventry el_lower_irq_invalid /* Lower EL IRQ 64-bit Handler */ + ventry el_lower_fiq_invalid /* Lower EL FIQ 64-bit Handler */ + ventry el_lower_error_invalid /* Lower EL Error 64-bit Handler */ + + ventry el_lower_sync_invalid /* Lower EL Synchronous 32-bit Handler */ + ventry el_lower_irq_invalid /* Lower EL IRQ 32-bit Handler */ + ventry el_lower_fiq_invalid /* Lower EL FIQ 32-bit Handler */ + ventry el_lower_error_invalid /* Lower EL Error 32-bit Handler */ +END(vectors) + +/* + * Enter Exception. + * This will save the processor state that is X0~X29/LR/SP/ELR/PSTATE + * to the stack frame. + */ +.macro exception_entry, el + sub sp, sp, #S_FRAME_SIZE - S_LR /* LR,SP,ELR,PSTATE will be saved later */ + push x28, x29 + push x26, x27 + push x24, x25 + push x22, x23 + push x20, x21 + push x18, x19 + push x16, x17 + push x14, x15 + push x12, x13 + push x10, x11 + push x8, x9 + push x6, x7 + push x4, x5 + push x2, x3 + push x0, x1 + .if \el == 2 + add x21, sp, #S_FRAME_SIZE + .else + mrs x21, sp_el1 + .endif + mrs x22, elr_el2 + mrs x23, spsr_el2 + stp lr, x21, [sp, #S_LR] + stp x22, x23, [sp, #S_PC] +.endm + +/* + * Exit Exception. + * This will restore the processor state that is X0~X29/LR/SP/ELR/PSTATE + * from the stack frame and return from exceprion. + */ +.macro exception_exit, el + ldp x21, x22, [sp, #S_PC] + msr elr_el2, x21 /* restore elr register */ + msr spsr_el2, x22 /* restore spsr register */ + .if \el == 1 + ldr x23, [sp, #S_SP] + msr sp_el1, x23 /* restore return stack pointer */ + .endif + pop x0, x1 /* restore the general registers */ + pop x2, x3 + pop x4, x5 + pop x6, x7 + pop x8, x9 + pop x10, x11 + pop x12, x13 + pop x14, x15 + pop x16, x17 + pop x18, x19 + pop x20, x21 + pop x22, x23 + pop x24, x25 + pop x26, x27 + pop x28, x29 + ldr lr, [sp], #S_FRAME_SIZE - S_LR /* restore LR and SP */ + eret /* exception return */ +.endm + +/* + * Current EL exception entry + */ +ENTRY(el_current_sync_invalid) + exception_entry 2 + mov x0, sp + mov x1, #EXCEPTION_SYNC + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_current_sync_invalid) + +ENTRY(el_current_irq_invalid) + exception_entry 2 + mov x0, sp + mov x1, #EXCEPTION_IRQ + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_current_irq_invalid) + +ENTRY(el_current_fiq_invalid) + exception_entry 2 + mov x0, sp + mov x1, #EXCEPTION_FIQ + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_current_fiq_invalid) + +ENTRY(el_current_error_invalid) + exception_entry 2 + mov x0, sp + mov x1, #EXCEPTION_ERROR + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_current_error_invalid) + + +/* + * Lower EL exception entry + */ +ENTRY(el_lower_sync_invalid) + exception_entry 1 + mov x0, sp + mov x1, #EXCEPTION_SYNC + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_lower_sync_invalid) + +ENTRY(el_lower_irq_invalid) + exception_entry 1 + mov x0, sp + mov x1, #EXCEPTION_IRQ + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_lower_irq_invalid) + +ENTRY(el_lower_fiq_invalid) + exception_entry 1 + mov x0, sp + mov x1, #EXCEPTION_FIQ + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_lower_fiq_invalid) + +ENTRY(el_lower_error_invalid) + exception_entry 1 + mov x0, sp + mov x1, #EXCEPTION_ERROR + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_lower_error_invalid) diff --git a/arch/arm64/cpu/armv8/start.S b/arch/arm64/cpu/armv8/start.S new file mode 100644 index 0000000..06d8caa --- /dev/null +++ b/arch/arm64/cpu/armv8/start.S @@ -0,0 +1,197 @@ +/* + * 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 <version.h> +#include <linux/linkage.h> +#include <asm/arch/mmu.h> + +/************************************************************************* + * + * Startup Code (reset vector) + * + *************************************************************************/ + +.globl _start +_start: + b reset + + .align 3 + +.globl _TEXT_BASE +_TEXT_BASE: + .quad CONFIG_SYS_TEXT_BASE + +.globl _end_ofs +_end_ofs: + .quad _end - _start + +.globl _bss_start_ofs +_bss_start_ofs: + .quad __bss_start - _start + +.globl _bss_end_ofs +_bss_end_ofs: + .quad __bss_end - _start + +reset: + /* + * EL3 initialisation + */ + mrs x0, CurrentEL + cmp x0, #0xc /* EL3? */ + b.ne reset_nonsecure /* skip EL3 initialisation */ + + mov x0, #0x30 /* RES1 */ + orr x0, x0, #(1 << 0) /* Non-secure EL1 */ + orr x0, x0, #(1 << 8) /* HVC enable */ + orr x0, x0, #(1 << 10) /* 64-bit EL2 */ + msr scr_el3, x0 + + msr cptr_el3, xzr /* Disable copro. traps to EL3 */ + + /* Counter frequency initialisation */ + ldr x0, =CONFIG_SYS_CNTFRQ + msr cntfrq_el0, x0 + + /* GIC initialisation */ + mrs x0, mpidr_el1 + tst x0, #15 + b.ne 1f /* secondary CPU */ + + ldr x1, =GIC_DIST_BASE /* GICD_CTLR */ + mov w0, #3 /* EnableGrp0 | EnableGrp1 */ + str w0, [x1] + +1: ldr x1, =GIC_DIST_BASE + 0x80 /* GICD_IGROUPR */ + mov w0, #~0 /* Grp1 interrupts */ + str w0, [x1], #4 + b.ne 2f /* Only local interrupts for secondary CPUs */ + str w0, [x1], #4 + str w0, [x1], #4 + +2: ldr x1, =GIC_CPU_BASE /* GICC_CTLR */ + ldr w0, [x1] + mov w0, #3 /* EnableGrp0 | EnableGrp1 */ + str w0, [x1] + + mov w0, #1 << 7 /* allow NS access to GICC_PMR */ + str w0, [x1, #4] /* GICC_PMR */ + + /* SCTLR_EL2 initialisation */ + msr sctlr_el2, xzr + + /* Return to the EL2_SP1 mode from EL3 */ + adr x0, reset_nonsecure + mov x1, #0x3c9 /* EL2_SP1 | D | A | I | F */ + msr elr_el3, x0 + msr spsr_el3, x1 + eret + + /* + * EL2 initialisation: + * MMU Disabled, iCache Disabled, dCache Disabled + */ +reset_nonsecure: + /* SCTLR_EL2 initialisation */ + mov x0, #0x2 /* Alignment check enable */ + msr sctlr_el2, x0 + + /* Initialize vBAR */ + adr x0, vectors + msr vbar_el2, x0 + + /* Cache/BPB/TLB Invalidate */ + bl __flush_dcache_all /* dCache invalidate */ + bl __invalidate_icache_all /* iCache invalidate */ + bl __invalidate_tlb_all /* invalidate I + D TLBs */ + + /* Processor specific initialisation */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl lowlevel_init +#endif + + mrs x0, mpidr_el1 + tst x0, #15 + b.eq master_cpu + + /* + * Secondary CPUs + */ +slave_cpu: + + wfe + ldr x1, =SECONDARY_CPU_MAILBOX + ldr x0, [x1] + cbz x0, slave_cpu + br x0 /* branch to the given address */ + + /* + * Primary CPU + */ +master_cpu: + + bl _main + +/*------------------------------------------------------------------------------*/ + +ENTRY(c_runtime_cpu_setup) + /* If I-cache is enabled invalidate it */ +#ifndef CONFIG_SYS_ICACHE_OFF + ic iallu /* I+BTB cache invalidate */ + isb sy +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF + /* + * Memory region attributes: + * + * n = AttrIndx[2:0] + * n MAIR + * DEVICE_nGnRnE 000 00000000 + * DEVICE_nGnRE 001 00000100 + * DEVICE_GRE 010 00001100 + * NORMAL_NC 011 01000100 + * NORMAL 100 11111111 + */ + ldr x0, =MAIR(0x00, MT_DEVICE_nGnRnE) | \ + MAIR(0x04, MT_DEVICE_nGnRE) | \ + MAIR(0x0c, MT_DEVICE_GRE) | \ + MAIR(0x44, MT_NORMAL_NC) | \ + MAIR(0xff, MT_NORMAL) + msr mair_el2, x0 + + /* + * Set/prepare TCR and TTBR. Using 512GB (39-bit) address range. + */ + ldr x0, =TCR_T0SZ(VA_BITS) | TCR_FLAGS | TCR_IPS_40BIT + orr x0, x0, TCR_TG0_64K + msr tcr_el2, x0 +#endif + + /* Relocate vBAR */ + adr x0, vectors + msr vbar_el2, x0 + + ret +ENDPROC(c_runtime_cpu_setup) diff --git a/arch/arm64/cpu/armv8/tlb.S b/arch/arm64/cpu/armv8/tlb.S new file mode 100644 index 0000000..8622157 --- /dev/null +++ b/arch/arm64/cpu/armv8/tlb.S @@ -0,0 +1,38 @@ +/* + * 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 <version.h> +#include <linux/linkage.h> + +/* + * void __invalidate_tlb_all(void) + * + * invalidate all tlb entries. + */ +ENTRY(__invalidate_tlb_all) + tlbi alle2 + dsb sy + isb + ret +ENDPROC(__invalidate_tlb_all) diff --git a/arch/arm64/cpu/u-boot.lds b/arch/arm64/cpu/u-boot.lds new file mode 100644 index 0000000..98d01d2 --- /dev/null +++ b/arch/arm64/cpu/u-boot.lds @@ -0,0 +1,73 @@ +/* + * 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 + */ + +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SECTIONS +{ + . = ALIGN(8); + .text : + { + __image_copy_start = .; + CPUDIR/start.o (.text*) + *(.text*) + } + + . = ALIGN(8); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(8); + .data : { + *(.data*) + } + + . = ALIGN(8); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + . = ALIGN(8); + .reloc : { + __rel_got_start = .; + *(.got) + __rel_got_end = .; + } + + __image_copy_end = .; + _end = .; + + . = ALIGN(8); + .bss : { + __bss_start = .; + *(.bss*) + . = ALIGN(8); + __bss_end = .; + } + + /DISCARD/ : { *(.dynsym) } + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } +} diff --git a/arch/arm64/dts/aemv8a.dtsi b/arch/arm64/dts/aemv8a.dtsi new file mode 100644 index 0000000..b45e5f3 --- /dev/null +++ b/arch/arm64/dts/aemv8a.dtsi @@ -0,0 +1,234 @@ +/* + * ARM Ltd. Fast Models + * + * Versatile Express (VE) system model + * Motherboard component + * + * VEMotherBoard.lisa + */ + + motherboard { + arm,v2m-memory-map = "rs1"; + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + ranges; + + flash@0,00000000 { + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>, + <4 0x00000000 0x04000000>; + bank-width = <4>; + }; + + vram@2,00000000 { + compatible = "arm,vexpress-vram"; + reg = <2 0x00000000 0x00800000>; + }; + + ethernet@2,02000000 { + compatible = "smsc,lan91c111"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + }; + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + iofpga@3,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysreg: sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + gpio-controller; + #gpio-cells = <2>; + }; + + v2m_sysctl: sysctl@020000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x020000 0x1000>; + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>; + clock-names = "refclk", "timclk", "apb_pclk"; + #clock-cells = <1>; + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; + }; + + aaci@040000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x040000 0x1000>; + interrupts = <11>; + clocks = <&v2m_clk24mhz>; + clock-names = "apb_pclk"; + }; + + mmci@050000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x050000 0x1000>; + interrupts = <9 10>; + cd-gpios = <&v2m_sysreg 0 0>; + wp-gpios = <&v2m_sysreg 1 0>; + max-frequency = <12000000>; + vmmc-supply = <&v2m_fixed_3v3>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "mclk", "apb_pclk"; + }; + + kmi@060000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x060000 0x1000>; + interrupts = <12>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + kmi@070000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x070000 0x1000>; + interrupts = <13>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + wdt@0f0000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f0000 0x1000>; + interrupts = <0>; + clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>; + clock-names = "wdogclk", "apb_pclk"; + }; + + v2m_timer01: timer@110000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x110000 0x1000>; + interrupts = <2>; + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + v2m_timer23: timer@120000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x120000 0x1000>; + interrupts = <3>; + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + rtc@170000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x170000 0x1000>; + interrupts = <4>; + clocks = <&v2m_clk24mhz>; + clock-names = "apb_pclk"; + }; + + clcd@1f0000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x1f0000 0x1000>; + interrupts = <14>; + clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>; + clock-names = "clcdclk", "apb_pclk"; + }; + }; + + v2m_fixed_3v3: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + mcc { + compatible = "arm,vexpress,config-bus", "simple-bus"; + arm,vexpress,config-bridge = <&v2m_sysreg>; + + v2m_oscclk1: osc@1 { + /* CLCD clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 1>; + freq-range = <23750000 63500000>; + #clock-cells = <0>; + clock-output-names = "v2m:oscclk1"; + }; + + reset@0 { + compatible = "arm,vexpress-reset"; + arm,vexpress-sysreg,func = <5 0>; + }; + + muxfpga@0 { + compatible = "arm,vexpress-muxfpga"; + arm,vexpress-sysreg,func = <7 0>; + }; + + shutdown@0 { + compatible = "arm,vexpress-shutdown"; + arm,vexpress-sysreg,func = <8 0>; + }; + + reboot@0 { + compatible = "arm,vexpress-reboot"; + arm,vexpress-sysreg,func = <9 0>; + }; + + dvimode@0 { + compatible = "arm,vexpress-dvimode"; + arm,vexpress-sysreg,func = <11 0>; + }; + }; + }; diff --git a/arch/arm64/include/asm/arch-armv8/mmu.h b/arch/arm64/include/asm/arch-armv8/mmu.h new file mode 100644 index 0000000..2127649 --- /dev/null +++ b/arch/arm64/include/asm/arch-armv8/mmu.h @@ -0,0 +1,117 @@ +/* + * 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 + */ + +#ifndef _ASM_ARMV8_MMU_H_ +#define _ASM_ARMV8_MMU_H_ + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) +#define _AT(T,X) ((T)(X)) +#endif + +#define UL(x) _AC(x, UL) + +/***************************************************************/ +/* + * The following definitions are related each other, shoud be + * calculated specifically. + */ +#define VA_BITS (39) + +/* PAGE_SHIFT determines the page size */ +#undef PAGE_SIZE +#define PAGE_SHIFT 16 +#define PAGE_SIZE (1 << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +/* + * section address mask and size definitions. + */ +#define SECTION_SHIFT 29 +#define SECTION_SIZE (_AC(1, UL) << SECTION_SHIFT) +#define SECTION_MASK (~(SECTION_SIZE-1)) +/***************************************************************/ + +/* + * Memory types available. + */ +#define MT_DEVICE_nGnRnE 0 +#define MT_DEVICE_nGnRE 1 +#define MT_DEVICE_GRE 2 +#define MT_NORMAL_NC 3 +#define MT_NORMAL 4 + +#define MAIR(attr, mt) ((attr) << ((mt) * 8)) + +/* + * Hardware page table definitions. + * + * Level 2 descriptor (PMD). + */ +#define PMD_TYPE_MASK (3 << 0) +#define PMD_TYPE_FAULT (0 << 0) +#define PMD_TYPE_TABLE (3 << 0) +#define PMD_TYPE_SECT (1 << 0) + +/* + * Section + */ +#define PMD_SECT_S (UL(3) << 8) +#define PMD_SECT_AF (UL(1) << 10) +#define PMD_SECT_NG (UL(1) << 11) +#define PMD_SECT_PXN (UL(1) << 53) +#define PMD_SECT_UXN (UL(1) << 54) + +/* + * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). + */ +#define PMD_ATTRINDX(t) ((t) << 2) +#define PMD_ATTRINDX_MASK (7 << 2) + +/* + * TCR_EL2 flags. + */ +#define TCR_T0SZ(x) ((64 - (x)) << 0) +#define TCR_IRGN_NC (0 << 8) +#define TCR_IRGN_WBWA (1 << 8) +#define TCR_IRGN_WT (2 << 8) +#define TCR_IRGN_WBnWA (3 << 8) +#define TCR_IRGN_MASK (3 << 8) +#define TCR_ORGN_NC (0 << 10) +#define TCR_ORGN_WBWA (1 << 10) +#define TCR_ORGN_WT (2 << 10) +#define TCR_ORGN_WBnWA (3 << 10) +#define TCR_ORGN_MASK (3 << 10) +#define TCR_SHARED (3 << 12) +#define TCR_TG0_4K (0 << 14) +#define TCR_TG0_64K (1 << 14) +#define TCR_TG0_16K (2 << 14) +#define TCR_IPS_40BIT (2 << 16) + +/* PTWs cacheable, inner/outer WBWA not shareable */ +#define TCR_FLAGS TCR_IRGN_WBWA | TCR_ORGN_WBWA + +#endif /* _ASM_ARMV8_MMU_H_ */ diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h new file mode 100644 index 0000000..2117ec1 --- /dev/null +++ b/arch/arm64/include/asm/atomic.h @@ -0,0 +1,115 @@ +/* + * linux/include/asm-arm/atomic.h + * + * Copyright (c) 1996 Russell King. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * 27-06-1996 RMK Created + * 13-04-1997 RMK Made functions atomic! + * 07-12-1997 RMK Upgraded for v2.1. + * 26-08-1998 PJB Added #ifdef __KERNEL__ + */ +#ifndef __ASM_ARM64_ATOMIC_H +#define __ASM_ARM64_ATOMIC_H + +#include <linux/config.h> + +#ifdef CONFIG_SMP +#error SMP not supported +#endif + +typedef struct { volatile int counter; } atomic_t; + +#define ATOMIC_INIT(i) { (i) } + +#ifdef __KERNEL__ + +#include <asm/system.h> + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v,i) (((v)->counter) = (i)) + +static inline void atomic_add(int i, volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter += i; + local_irq_restore(flags); +} + +static inline void atomic_sub(int i, volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter -= i; + local_irq_restore(flags); +} + +static inline void atomic_inc(volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter += 1; + local_irq_restore(flags); +} + +static inline void atomic_dec(volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter -= 1; + local_irq_restore(flags); +} + +static inline int atomic_dec_and_test(volatile atomic_t *v) +{ + unsigned long flags; + int val; + + local_irq_save(flags); + val = v->counter; + v->counter = val -= 1; + local_irq_restore(flags); + + return val == 0; +} + +static inline int atomic_add_negative(int i, volatile atomic_t *v) +{ + unsigned long flags; + int val; + + local_irq_save(flags); + val = v->counter; + v->counter = val += i; + local_irq_restore(flags); + + return val < 0; +} + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ + unsigned long flags; + + local_irq_save(flags); + *addr &= ~mask; + local_irq_restore(flags); +} + +/* Atomic operations are already serializing on ARM */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARM64_ATOMIC_H */ diff --git a/arch/arm64/include/asm/bitops.h b/arch/arm64/include/asm/bitops.h new file mode 100644 index 0000000..a1d53eb --- /dev/null +++ b/arch/arm64/include/asm/bitops.h @@ -0,0 +1,153 @@ +/* + * 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 + */ + +#ifndef __ASM_ARM64_BITOPS_H +#define __ASM_ARM64_BITOPS_H + +#ifdef __KERNEL__ + +#include <asm/system.h> + +/* + * Function prototypes to keep gcc -Wall happy. + */ +static inline void __change_bit(int nr, volatile void *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + *p ^= mask; +} + +static inline int __test_and_set_bit(int nr, volatile void *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old = *p; + + *p = old | mask; + return (old & mask) != 0; +} + +static inline int test_and_set_bit(int nr, volatile void * addr) +{ + unsigned long flags; + int out; + + local_irq_save(flags); + out = __test_and_set_bit(nr, addr); + local_irq_restore(flags); + + return out; +} + +static inline int __test_and_clear_bit(int nr, volatile void *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old = *p; + + *p = old & ~mask; + return (old & mask) != 0; +} + +static inline int test_and_clear_bit(int nr, volatile void * addr) +{ + unsigned long flags; + int out; + + local_irq_save(flags); + out = __test_and_clear_bit(nr, addr); + local_irq_restore(flags); + + return out; +} + +static inline int __test_and_change_bit(int nr, volatile void *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old = *p; + + *p = old ^ mask; + return (old & mask) != 0; +} + +static inline int test_and_change_bit(int nr, volatile void * addr) +{ + unsigned long flags; + int out; + + local_irq_save(flags); + out = __test_and_change_bit(nr, addr); + local_irq_restore(flags); + + return out; +} + +/* + * This routine doesn't need to be atomic. + */ +static inline int test_bit(int nr, const void * addr) +{ + return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7)); +} + +static inline int __ilog2(unsigned int x) +{ + return generic_fls(x) - 1; +} + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +static inline unsigned long ffz(unsigned long word) +{ + int k; + + word = ~word; + k = 31; + if (word & 0x0000ffff) { k -= 16; word <<= 16; } + if (word & 0x00ff0000) { k -= 8; word <<= 8; } + if (word & 0x0f000000) { k -= 4; word <<= 4; } + if (word & 0x30000000) { k -= 2; word <<= 2; } + if (word & 0x40000000) { k -= 1; } + return k; +} + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#define ext2_set_bit test_and_set_bit +#define ext2_clear_bit test_and_clear_bit +#define ext2_test_bit test_bit + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARM64_BITOPS_H */ diff --git a/arch/arm64/include/asm/byteorder.h b/arch/arm64/include/asm/byteorder.h new file mode 100644 index 0000000..d5edfe8 --- /dev/null +++ b/arch/arm64/include/asm/byteorder.h @@ -0,0 +1,31 @@ +/* + * linux/include/asm-arm/byteorder.h + * + * ARM Endian-ness. In little endian mode, the data bus is connected such + * that byte accesses appear as: + * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 + * and word accesses (data or instruction) appear as: + * d0...d31 + * + * When in big endian mode, byte accesses appear as: + * 0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7 + * and word accesses (data or instruction) appear as: + * d0...d31 + */ +#ifndef __ASM_ARM64_BYTEORDER_H +#define __ASM_ARM64_BYTEORDER_H + +#include <asm/types.h> + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#ifdef __BIG_ENDIAN__ +#include <linux/byteorder/big_endian.h> +#else +#include <linux/byteorder/little_endian.h> +#endif + +#endif /* __ASM_ARM64_BYTEORDER_H */ diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h new file mode 100644 index 0000000..e49d2e0 --- /dev/null +++ b/arch/arm64/include/asm/cache.h @@ -0,0 +1,53 @@ +/* + * 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 + */ + +#ifndef _ASM_ARM64_CACHE_H +#define _ASM_ARM64_CACHE_H + +/* + * The current upper bound for ARM L1 data cache line sizes is 64 bytes. We + * use that value for aligning DMA buffers unless the board config has specified + * an alternate cache line size. + */ +#ifdef CONFIG_SYS_CACHELINE_SIZE +#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE +#else +#define ARCH_DMA_MINALIGN 64 +#endif + +#ifndef __ASSEMBLY__ + +void __flush_dcache_all(void); +void __flush_dcache_range(unsigned long start, unsigned long stop); +void __invalidate_icache_all(void); +void __invalidate_tlb_all(void); + +void outer_cache_enable(void); +void outer_cache_disable(void); +void outer_cache_flush_all(void); +void outer_cache_inval_all(void); +void outer_cache_flush_range(unsigned long start, unsigned long end); +void outer_cache_inval_range(unsigned long start, unsigned long end); + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_ARM64_CACHE_H */ diff --git a/arch/arm64/include/asm/config.h b/arch/arm64/include/asm/config.h new file mode 100644 index 0000000..8fa1b56 --- /dev/null +++ b/arch/arm64/include/asm/config.h @@ -0,0 +1,41 @@ +/* + * 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 + */ + +#ifndef _ASM_ARM64_CONFIG_H_ +#define _ASM_ARM64_CONFIG_H_ + +#define CONFIG_LMB + +#define CONFIG_SYS_BOOT_RAMDISK_HIGH + +/* + * Currently, gcc-aarch64 produce error when compiling with + * -pie and rel_dyn. So, GOT is used to relocate u-boot and + * configuration CONFIG_NEEDS_MANUAL_RELOC is needed. + */ +#define CONFIG_NEEDS_MANUAL_RELOC + +#define CONFIG_SYS_HZ 1000 + +#define CONFIG_PHYS_64BIT + +#endif /* _ASM_ARM64_CONFIG_H_ */ diff --git a/arch/arm64/include/asm/errno.h b/arch/arm64/include/asm/errno.h new file mode 100644 index 0000000..4c82b50 --- /dev/null +++ b/arch/arm64/include/asm/errno.h @@ -0,0 +1 @@ +#include <asm-generic/errno.h> diff --git a/arch/arm64/include/asm/global_data.h b/arch/arm64/include/asm/global_data.h new file mode 100644 index 0000000..13b66d4 --- /dev/null +++ b/arch/arm64/include/asm/global_data.h @@ -0,0 +1,38 @@ +/* + * 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 + */ + +#ifndef __ASM_ARM64_GBL_DATA_H +#define __ASM_ARM64_GBL_DATA_H + +/* Architecture-specific global data */ +struct arch_global_data { +#ifndef CONFIG_SYS_DCACHE_OFF + unsigned long tlb_addr; + unsigned long tlb_size; +#endif +}; + +#include <asm-generic/global_data.h> + +#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("x18") + +#endif /* __ASM_ARM64_GBL_DATA_H */ diff --git a/arch/arm64/include/asm/gpio.h b/arch/arm64/include/asm/gpio.h new file mode 100644 index 0000000..306ab4c --- /dev/null +++ b/arch/arm64/include/asm/gpio.h @@ -0,0 +1 @@ +#include <asm-generic/gpio.h> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h new file mode 100644 index 0000000..398ae53 --- /dev/null +++ b/arch/arm64/include/asm/io.h @@ -0,0 +1,193 @@ +/* + * linux/include/asm-arm/io.h + * + * Copyright (C) 1996-2000 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Modifications: + * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both + * constant addresses and variable addresses. + * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture + * specific IO header files. + * 27-Mar-1999 PJB Second parameter of memcpy_toio is const.. + * 04-Apr-1999 PJB Added check_signature. + * 12-Dec-1999 RMK More cleanups + * 18-Jun-2000 RMK Removed virt_to_* and friends definitions + */ + +#ifndef __ASM_ARM64_IO_H +#define __ASM_ARM64_IO_H + +#ifdef __KERNEL__ + +#include <linux/types.h> +#include <asm/byteorder.h> + +/* + * Given a physical address and a length, return a virtual address + * that can be used to access the memory range with the caching + * properties specified by "flags". + */ +#define MAP_NOCACHE (0) +#define MAP_WRCOMBINE (0) +#define MAP_WRBACK (0) +#define MAP_WRTHROUGH (0) + +static inline void * +map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ + return (void *)paddr; +} + +/* + * Take down a mapping set up by map_physmem(). + */ +static inline void unmap_physmem(void *vaddr, unsigned long flags) +{ +} + +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + +/* + * Generic virtual read/write. Note that we don't support half-word + * read/writes. We define __arch_*[bl] here, and leave __arch_*w + * to the architecture specific code. + */ +#define __arch_getb(a) (*(volatile unsigned char *)(a)) +#define __arch_getw(a) (*(volatile unsigned short *)(a)) +#define __arch_getl(a) (*(volatile unsigned int *)(a)) + +#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v)) +#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) +#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) + +extern inline void __raw_writesb(unsigned long addr, const void *data, int bytelen) +{ + uint8_t *buf = (uint8_t *)data; + while(bytelen--) + __arch_putb(*buf++, addr); +} + +extern inline void __raw_writesw(unsigned long addr, const void *data, int wordlen) +{ + uint16_t *buf = (uint16_t *)data; + while(wordlen--) + __arch_putw(*buf++, addr); +} + +extern inline void __raw_writesl(unsigned long addr, const void *data, int longlen) +{ + uint32_t *buf = (uint32_t *)data; + while(longlen--) + __arch_putl(*buf++, addr); +} + +extern inline void __raw_readsb(unsigned long addr, void *data, int bytelen) +{ + uint8_t *buf = (uint8_t *)data; + while(bytelen--) + *buf++ = __arch_getb(addr); +} + +extern inline void __raw_readsw(unsigned long addr, void *data, int wordlen) +{ + uint16_t *buf = (uint16_t *)data; + while(wordlen--) + *buf++ = __arch_getw(addr); +} + +extern inline void __raw_readsl(unsigned long addr, void *data, int longlen) +{ + uint32_t *buf = (uint32_t *)data; + while(longlen--) + *buf++ = __arch_getl(addr); +} + +#define __raw_writeb(v,a) __arch_putb(v,a) +#define __raw_writew(v,a) __arch_putw(v,a) +#define __raw_writel(v,a) __arch_putl(v,a) + +#define __raw_readb(a) __arch_getb(a) +#define __raw_readw(a) __arch_getw(a) +#define __raw_readl(a) __arch_getl(a) + +/* + * TODO: The kernel offers some more advanced versions of barriers, it might + * have some advantages to use them instead of the simple one here. + */ +#define dmb() __asm__ __volatile__ ("" : : : "memory") +#define __iormb() dmb() +#define __iowmb() dmb() + +#define writeb(v,c) ({ u8 __v = v; __iowmb(); __arch_putb(__v,c); __v; }) +#define writew(v,c) ({ u16 __v = v; __iowmb(); __arch_putw(__v,c); __v; }) +#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; }) + +#define readb(c) ({ u8 __v = __arch_getb(c); __iormb(); __v; }) +#define readw(c) ({ u16 __v = __arch_getw(c); __iormb(); __v; }) +#define readl(c) ({ u32 __v = __arch_getl(c); __iormb(); __v; }) + +/* + * Clear and set bits in one shot. These macros can be used to clear and + * set multiple bits in a register using a single call. These macros can + * also be used to set a multiple-bit bit pattern using a mask, by + * specifying the mask in the 'clear' parameter and the new bit pattern + * in the 'set' parameter. + */ + +#define out_arch(type,endian,a,v) __raw_write##type(cpu_to_##endian(v),a) +#define in_arch(type,endian,a) endian##_to_cpu(__raw_read##type(a)) + +#define out_le32(a,v) out_arch(l,le32,a,v) +#define out_le16(a,v) out_arch(w,le16,a,v) + +#define in_le32(a) in_arch(l,le32,a) +#define in_le16(a) in_arch(w,le16,a) + +#define out_be32(a,v) out_arch(l,be32,a,v) +#define out_be16(a,v) out_arch(w,be16,a,v) + +#define in_be32(a) in_arch(l,be32,a) +#define in_be16(a) in_arch(w,be16,a) + +#define out_8(a,v) __raw_writeb(v,a) +#define in_8(a) __raw_readb(a) + +#define clrbits(type, addr, clear) \ + out_##type((addr), in_##type(addr) & ~(clear)) + +#define setbits(type, addr, set) \ + out_##type((addr), in_##type(addr) | (set)) + +#define clrsetbits(type, addr, clear, set) \ + out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) + +#define clrbits_be32(addr, clear) clrbits(be32, addr, clear) +#define setbits_be32(addr, set) setbits(be32, addr, set) +#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) + +#define clrbits_le32(addr, clear) clrbits(le32, addr, clear) +#define setbits_le32(addr, set) setbits(le32, addr, set) +#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) + +#define clrbits_be16(addr, clear) clrbits(be16, addr, clear) +#define setbits_be16(addr, set) setbits(be16, addr, set) +#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) + +#define clrbits_le16(addr, clear) clrbits(le16, addr, clear) +#define setbits_le16(addr, set) setbits(le16, addr, set) +#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) + +#define clrbits_8(addr, clear) clrbits(8, addr, clear) +#define setbits_8(addr, set) setbits(8, addr, set) +#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARM64_IO_H */ diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h new file mode 100644 index 0000000..05e909e --- /dev/null +++ b/arch/arm64/include/asm/linkage.h @@ -0,0 +1,49 @@ +/* + * 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 + */ + +#ifndef __ASM_ARM64_LINKAGE_H +#define __ASM_ARM64_LINKAGE_H + +/* + * Register aliases. + */ +lr .req x30 // link register + +/* + * Stack pushing/popping (register pairs only). + * Equivalent to store decrement before, + * load increment after. + */ +.macro push, xreg1, xreg2 + stp \xreg1, \xreg2, [sp, #-16]! +.endm + +.macro pop, xreg1, xreg2 + ldp \xreg1, \xreg2, [sp], #16 +.endm + +.macro ventry label + .align 7 + b \label +.endm + +#endif /* __ASM_ARM64_LINKAGE_H */ diff --git a/arch/arm64/include/asm/posix_types.h b/arch/arm64/include/asm/posix_types.h new file mode 100644 index 0000000..d272a35 --- /dev/null +++ b/arch/arm64/include/asm/posix_types.h @@ -0,0 +1,61 @@ +/* + * 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 + */ + +#ifndef __ARCH_ARM64_POSIX_TYPES_H +#define __ARCH_ARM64_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef long __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef __kernel_uid_t __kernel_old_uid_t; +typedef __kernel_gid_t __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +#endif /* __ARCH_ARM64_POSIX_TYPES_H */ diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h new file mode 100644 index 0000000..67c0233 --- /dev/null +++ b/arch/arm64/include/asm/processor.h @@ -0,0 +1,59 @@ +/* + * 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 + */ + +#ifndef __ASM_ARM64_PROCESSOR_H +#define __ASM_ARM64_PROCESSOR_H + +/* CCSIDR */ +#define CCSIDR_LINE_SIZE_OFFSET 0 +#define CCSIDR_LINE_SIZE_MASK 0x7 +#define CCSIDR_ASSOCIATIVITY_OFFSET 3 +#define CCSIDR_ASSOCIATIVITY_MASK (0x3FF << 3) +#define CCSIDR_NUM_SETS_OFFSET 13 +#define CCSIDR_NUM_SETS_MASK (0x7FFF << 13) + +/* + * Values for InD field in CSSELR + * Selects the type of cache + */ +#define CSSELR_IND_DATA_UNIFIED 0 +#define CSSELR_IND_INSTRUCTION 1 + +/* Values for Ctype fields in CLIDR */ +#define CLIDR_CTYPE_NO_CACHE 0 +#define CLIDR_CTYPE_INSTRUCTION_ONLY 1 +#define CLIDR_CTYPE_DATA_ONLY 2 +#define CLIDR_CTYPE_INSTRUCTION_DATA 3 +#define CLIDR_CTYPE_UNIFIED 4 + +/* + * SCTLR_EL2 bits definitions + */ +#define CR_M (1 << 0) /* MMU enable */ +#define CR_A (1 << 1) /* Alignment abort enable */ +#define CR_C (1 << 2) /* Dcache enable */ +#define CR_SA (1 << 3) /* Stack Alignment Check Enable */ +#define CR_I (1 << 12) /* Icache enable */ +#define CR_WXN (1 << 19) /* Write Permision Imply XN */ +#define CR_EE (1 << 25) /* Exception (Big) Endian */ + +#endif /* __ASM_ARM64_PROCESSOR_H */ diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h new file mode 100644 index 0000000..ed4eee3 --- /dev/null +++ b/arch/arm64/include/asm/ptrace.h @@ -0,0 +1,64 @@ +/* + * 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 + */ + +#ifndef __ASM_ARM64_PTRACE_H +#define __ASM_ARM64_PTRACE_H + +/* + * exception type numbers + */ +#define EXCEPTION_SYNC 0 +#define EXCEPTION_IRQ 1 +#define EXCEPTION_FIQ 2 +#define EXCEPTION_ERROR 3 + +#define S_X0 (0) /* offsetof(struct pt_regs, regs[0]) */ +#define S_X1 (8) /* offsetof(struct pt_regs, regs[1]) */ +#define S_X2 (16) /* offsetof(struct pt_regs, regs[2]) */ +#define S_X3 (24 /* offsetof(struct pt_regs, regs[3]) */ +#define S_X4 (32) /* offsetof(struct pt_regs, regs[4]) */ +#define S_X5 (40) /* offsetof(struct pt_regs, regs[5]) */ +#define S_X6 (48) /* offsetof(struct pt_regs, regs[6]) */ +#define S_X7 (56) /* offsetof(struct pt_regs, regs[7]) */ +#define S_LR (240) /* offsetof(struct pt_regs, regs[30]) */ +#define S_SP (248) /* offsetof(struct pt_regs, sp) */ +#define S_PC (256) /* offsetof(struct pt_regs, pc) */ +#define S_PSTATE (264) /* offsetof(struct pt_regs, pstate) */ +#define S_FRAME_SIZE (272) /* sizeof(struct pt_regs) */ + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored on the stack during an + * exception. Note that sizeof(struct pt_regs) has to be a multiple of 16 (for + * stack alignment). struct user_pt_regs must form a prefix of struct pt_regs. + */ +struct pt_regs { + u64 regs[31]; + u64 sp; + u64 pc; + u64 pstate; +}; + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_ARM64_PTRACE_H */ diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h new file mode 100644 index 0000000..c042cb6 --- /dev/null +++ b/arch/arm64/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * 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 __ASM_ARM_SECTIONS_H +#define __ASM_ARM_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h new file mode 100644 index 0000000..550201f --- /dev/null +++ b/arch/arm64/include/asm/string.h @@ -0,0 +1,49 @@ +/* + * 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 + */ + +#ifndef __ASM_ARM64_STRING_H +#define __ASM_ARM64_STRING_H + +#include <config.h> + +#undef __HAVE_ARCH_STRRCHR +extern char * strrchr(const char * s, int c); + +#undef __HAVE_ARCH_STRCHR +extern char * strchr(const char * s, int c); + +#undef __HAVE_ARCH_MEMCPY +extern void * memcpy(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMMOVE +extern void * memmove(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMCHR +extern void * memchr(const void *, int, __kernel_size_t); + +#undef __HAVE_ARCH_MEMZERO +extern void memzero(void *ptr, __kernel_size_t n); + +#undef __HAVE_ARCH_MEMSET +extern void * memset(void *, int, __kernel_size_t); + +#endif /* __ASM_ARM64_STRING_H */ diff --git a/arch/arm64/include/asm/system.h b/arch/arm64/include/asm/system.h new file mode 100644 index 0000000..135c5e1 --- /dev/null +++ b/arch/arm64/include/asm/system.h @@ -0,0 +1,106 @@ +/* + * 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 + */ + +#ifndef __ASM_ARM64_ARCH_SYSTEM_H +#define __ASM_ARM64_ARCH_SYSTEM_H + +#include <linux/types.h> + +#ifndef __ASSEMBLY__ + +/* + * Save the current interrupt enable state + * and disable IRQs/FIQs + */ +#define local_irq_save(flags) \ + { \ + asm volatile( \ + "mrs %0, daif" \ + "msr daifset, #3" \ + : "=r" (flags) \ + : \ + : "memory"); \ + } + +/* + * restore saved IRQ & FIQ state + */ +#define local_irq_restore(flags) \ + { \ + asm volatile( \ + "msr daif, %0" \ + : \ + : "r" (flags) \ + : "memory"); \ + } + +/* + * Enable IRQs/FIQs + */ +#define local_irq_enable() \ + { \ + asm volatile( \ + "msr daifclr, #3" \ + : \ + : \ + : "memory"); \ + } + +/* + * Disable IRQs/FIQs + */ +#define local_irq_disable() \ + { \ + asm volatile( \ + "msr daifset, #3" \ + : \ + : \ + : "memory"); \ + } + +#define sev() asm volatile("sev" : : : "memory") +#define wfe() asm volatile("wfe" : : : "memory") +#define wfi() asm volatile("wfi" : : : "memory") + +#define isb() asm volatile("isb" : : : "memory") +#define dsb() asm volatile("dsb sy" : : : "memory") + +#define mb() dsb() +#define rmb() asm volatile("dsb ld" : : : "memory") +#define wmb() asm volatile("dsb st" : : : "memory") + +static inline unsigned int get_sctlr(void) +{ + unsigned int val; + asm volatile("mrs %0, sctlr_el2" : "=r" (val) : : "cc"); + return val; +} + +static inline void set_sctlr(unsigned int val) +{ + asm volatile("msr sctlr_el2, %0" : : "r" (val) : "cc"); + asm volatile("isb"); +} + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_ARM64_ARCH_SYSTEM_H */ diff --git a/arch/arm64/include/asm/types.h b/arch/arm64/include/asm/types.h new file mode 100644 index 0000000..7aa08cb --- /dev/null +++ b/arch/arm64/include/asm/types.h @@ -0,0 +1,67 @@ +/* + * 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 + */ + +#ifndef __ASM_ARM64_TYPES_H +#define __ASM_ARM64_TYPES_H + +#define BITS_PER_LONG 64 + +typedef unsigned short umode_t; + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long __s64; +typedef unsigned long __u64; + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long s64; +typedef unsigned long u64; + +/* Dma addresses are 32-bits wide. */ +typedef u32 dma_addr_t; + +typedef unsigned long phys_addr_t; +typedef unsigned long phys_size_t; + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARM64_TYPES_H */ diff --git a/arch/arm64/include/asm/u-boot.h b/arch/arm64/include/asm/u-boot.h new file mode 100644 index 0000000..c0cf855 --- /dev/null +++ b/arch/arm64/include/asm/u-boot.h @@ -0,0 +1,38 @@ +/* + * 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 + */ + +#ifndef _U_BOOT_ARM64_H_ +#define _U_BOOT_ARM64_H_ + +typedef struct bd_info { + unsigned long bi_baudrate; /* serial console baudrate */ + struct /* RAM configuration */ + { + unsigned long start; + unsigned long size; + } bi_dram[CONFIG_NR_DRAM_BANKS]; +} bd_t; + +/* For image.h:image_check_target_arch() */ +#define IH_ARCH_DEFAULT IH_ARCH_ARM64 + +#endif /* _U_BOOT_ARM64_H_ */ diff --git a/arch/arm64/include/asm/unaligned.h b/arch/arm64/include/asm/unaligned.h new file mode 100644 index 0000000..39b509a --- /dev/null +++ b/arch/arm64/include/asm/unaligned.h @@ -0,0 +1,28 @@ +/* + * 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 + */ + +#ifndef _ASM_ARM64_UNALIGNED_H +#define _ASM_ARM64_UNALIGNED_H + +#include <asm-generic/unaligned.h> + +#endif /* _ASM_ARM64_UNALIGNED_H */ diff --git a/arch/arm64/include/asm/utils.h b/arch/arm64/include/asm/utils.h new file mode 100644 index 0000000..828b86c --- /dev/null +++ b/arch/arm64/include/asm/utils.h @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V aneesh@ti.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +static inline s32 log_2_n_round_up(u32 n) +{ + s32 log2n = -1; + u32 temp = n; + + while (temp) { + log2n++; + temp >>= 1; + } + + if (n & (n - 1)) + return log2n + 1; /* not power of 2 - round up */ + else + return log2n; /* power of 2 */ +} + +static inline s32 log_2_n_round_down(u32 n) +{ + s32 log2n = -1; + u32 temp = n; + + while (temp) { + log2n++; + temp >>= 1; + } + + return log2n; +} + +#endif

From: David Feng fenghua@phytium.com.cn
This patch fix the fdt_initrd function. It will get #address_cells property first, then write "linux,initrd-start" and "linux,initrd-end" property value to fdt according to address cell size. So, the 64bit initrd start address could be supported.
Signed-off-by: David Feng fenghua@phytium.com.cn --- common/fdt_support.c | 66 ++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 32 deletions(-)
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

Hi David,
On Thu, Aug 15, 2013 at 7:47 AM, fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
*** BLURB HERE *** Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok. - according to scott wood's advice, make the fdt 64bit initrd start address support a seperate patch.
David Feng (5): core support of arm64 board support of arm64 arch support 1 of arm64 arch support 2 of arm64 64bit initrd start address support
arch/arm64/config.mk | 32 +++ arch/arm64/cpu/armv8/Makefile | 51 ++++ arch/arm64/cpu/armv8/cache.S | 144 ++++++++++ arch/arm64/cpu/armv8/config.mk | 29 ++ arch/arm64/cpu/armv8/cpu.c | 108 ++++++++ arch/arm64/cpu/armv8/exceptions.S | 189 +++++++++++++ arch/arm64/cpu/armv8/start.S | 197 ++++++++++++++ arch/arm64/cpu/armv8/tlb.S | 38 +++ arch/arm64/cpu/u-boot.lds | 73 +++++ arch/arm64/dts/aemv8a.dtsi | 234 ++++++++++++++++ arch/arm64/include/asm/arch-armv8/mmu.h | 117 ++++++++ arch/arm64/include/asm/atomic.h | 115 ++++++++ arch/arm64/include/asm/bitops.h | 153 +++++++++++ arch/arm64/include/asm/byteorder.h | 31 +++ arch/arm64/include/asm/cache.h | 53 ++++ arch/arm64/include/asm/config.h | 41 +++ arch/arm64/include/asm/errno.h | 1 + arch/arm64/include/asm/global_data.h | 38 +++ arch/arm64/include/asm/gpio.h | 1 + arch/arm64/include/asm/io.h | 193 +++++++++++++ arch/arm64/include/asm/linkage.h | 49 ++++ arch/arm64/include/asm/posix_types.h | 61 +++++ arch/arm64/include/asm/processor.h | 59 ++++ arch/arm64/include/asm/ptrace.h | 64 +++++ arch/arm64/include/asm/sections.h | 27 ++ arch/arm64/include/asm/string.h | 49 ++++ arch/arm64/include/asm/system.h | 106 ++++++++ arch/arm64/include/asm/types.h | 67 +++++ arch/arm64/include/asm/u-boot.h | 38 +++ arch/arm64/include/asm/unaligned.h | 28 ++ arch/arm64/include/asm/utils.h | 56 ++++ arch/arm64/lib/Makefile | 64 +++++ arch/arm64/lib/board.c | 453 +++++++++++++++++++++++++++++++
Instead of this file, it would be good if you could make it use generic board - see CONFIG_SYS_GENERIC_BOARD in the README.
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 | 4 - 52 files changed, 4509 insertions(+), 38 deletions(-) create mode 100644 arch/arm64/config.mk create mode 100644 arch/arm64/cpu/armv8/Makefile create mode 100644 arch/arm64/cpu/armv8/cache.S create mode 100644 arch/arm64/cpu/armv8/config.mk create mode 100644 arch/arm64/cpu/armv8/cpu.c create mode 100644 arch/arm64/cpu/armv8/exceptions.S create mode 100644 arch/arm64/cpu/armv8/start.S create mode 100644 arch/arm64/cpu/armv8/tlb.S create mode 100644 arch/arm64/cpu/u-boot.lds create mode 100644 arch/arm64/dts/aemv8a.dtsi create mode 100644 arch/arm64/include/asm/arch-armv8/mmu.h create mode 100644 arch/arm64/include/asm/atomic.h create mode 100644 arch/arm64/include/asm/bitops.h create mode 100644 arch/arm64/include/asm/byteorder.h create mode 100644 arch/arm64/include/asm/cache.h create mode 100644 arch/arm64/include/asm/config.h create mode 100644 arch/arm64/include/asm/errno.h create mode 100644 arch/arm64/include/asm/global_data.h create mode 100644 arch/arm64/include/asm/gpio.h create mode 100644 arch/arm64/include/asm/io.h create mode 100644 arch/arm64/include/asm/linkage.h create mode 100644 arch/arm64/include/asm/posix_types.h create mode 100644 arch/arm64/include/asm/processor.h create mode 100644 arch/arm64/include/asm/ptrace.h create mode 100644 arch/arm64/include/asm/sections.h create mode 100644 arch/arm64/include/asm/string.h create mode 100644 arch/arm64/include/asm/system.h create mode 100644 arch/arm64/include/asm/types.h create mode 100644 arch/arm64/include/asm/u-boot.h create mode 100644 arch/arm64/include/asm/unaligned.h create mode 100644 arch/arm64/include/asm/utils.h 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
Regards, Simon

hi Simon, I have worked on generic board for a few days, but something confuse me. Why it is needed? Each processor architecture has different features, this will affect processor specific and board specific code. Putting board_init_* code of each platform into one file with many macro switch make things messy, the board_f.c and board_r.c become very complicated and less readable. Is it really needed? We should make it clear that what parts are common between architecture and what parts are specific. Actually, I have different opinion with this. Architecture specific board.c file have more advantages. how ahout your opinion? Best Regards. David
-----原始邮件----- 发件人: "Simon Glass" sjg@chromium.org 发送时间: 2013年8月16日 星期五 收件人: fenghua@phytium.com.cn 抄送: "U-Boot Mailing List" u-boot@lists.denx.de, "trini@ti.com" trini@ti.com 主题: Re: [U-Boot] [PATCH v3 0/5] arm64 patch
Hi David,
On Thu, Aug 15, 2013 at 7:47 AM, fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
*** BLURB HERE *** Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok. - according to scott wood's advice, make the fdt 64bit initrd start address support a seperate patch.
David Feng (5): core support of arm64 board support of arm64 arch support 1 of arm64 arch support 2 of arm64 64bit initrd start address support
arch/arm64/config.mk | 32 +++ arch/arm64/cpu/armv8/Makefile | 51 ++++ arch/arm64/cpu/armv8/cache.S | 144 ++++++++++ arch/arm64/cpu/armv8/config.mk | 29 ++ arch/arm64/cpu/armv8/cpu.c | 108 ++++++++ arch/arm64/cpu/armv8/exceptions.S | 189 +++++++++++++ arch/arm64/cpu/armv8/start.S | 197 ++++++++++++++ arch/arm64/cpu/armv8/tlb.S | 38 +++ arch/arm64/cpu/u-boot.lds | 73 +++++ arch/arm64/dts/aemv8a.dtsi | 234 ++++++++++++++++ arch/arm64/include/asm/arch-armv8/mmu.h | 117 ++++++++ arch/arm64/include/asm/atomic.h | 115 ++++++++ arch/arm64/include/asm/bitops.h | 153 +++++++++++ arch/arm64/include/asm/byteorder.h | 31 +++ arch/arm64/include/asm/cache.h | 53 ++++ arch/arm64/include/asm/config.h | 41 +++ arch/arm64/include/asm/errno.h | 1 + arch/arm64/include/asm/global_data.h | 38 +++ arch/arm64/include/asm/gpio.h | 1 + arch/arm64/include/asm/io.h | 193 +++++++++++++ arch/arm64/include/asm/linkage.h | 49 ++++ arch/arm64/include/asm/posix_types.h | 61 +++++ arch/arm64/include/asm/processor.h | 59 ++++ arch/arm64/include/asm/ptrace.h | 64 +++++ arch/arm64/include/asm/sections.h | 27 ++ arch/arm64/include/asm/string.h | 49 ++++ arch/arm64/include/asm/system.h | 106 ++++++++ arch/arm64/include/asm/types.h | 67 +++++ arch/arm64/include/asm/u-boot.h | 38 +++ arch/arm64/include/asm/unaligned.h | 28 ++ arch/arm64/include/asm/utils.h | 56 ++++ arch/arm64/lib/Makefile | 64 +++++ arch/arm64/lib/board.c | 453 +++++++++++++++++++++++++++++++
Instead of this file, it would be good if you could make it use generic board - see CONFIG_SYS_GENERIC_BOARD in the README.
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 | 4 - 52 files changed, 4509 insertions(+), 38 deletions(-) create mode 100644 arch/arm64/config.mk create mode 100644 arch/arm64/cpu/armv8/Makefile create mode 100644 arch/arm64/cpu/armv8/cache.S create mode 100644 arch/arm64/cpu/armv8/config.mk create mode 100644 arch/arm64/cpu/armv8/cpu.c create mode 100644 arch/arm64/cpu/armv8/exceptions.S create mode 100644 arch/arm64/cpu/armv8/start.S create mode 100644 arch/arm64/cpu/armv8/tlb.S create mode 100644 arch/arm64/cpu/u-boot.lds create mode 100644 arch/arm64/dts/aemv8a.dtsi create mode 100644 arch/arm64/include/asm/arch-armv8/mmu.h create mode 100644 arch/arm64/include/asm/atomic.h create mode 100644 arch/arm64/include/asm/bitops.h create mode 100644 arch/arm64/include/asm/byteorder.h create mode 100644 arch/arm64/include/asm/cache.h create mode 100644 arch/arm64/include/asm/config.h create mode 100644 arch/arm64/include/asm/errno.h create mode 100644 arch/arm64/include/asm/global_data.h create mode 100644 arch/arm64/include/asm/gpio.h create mode 100644 arch/arm64/include/asm/io.h create mode 100644 arch/arm64/include/asm/linkage.h create mode 100644 arch/arm64/include/asm/posix_types.h create mode 100644 arch/arm64/include/asm/processor.h create mode 100644 arch/arm64/include/asm/ptrace.h create mode 100644 arch/arm64/include/asm/sections.h create mode 100644 arch/arm64/include/asm/string.h create mode 100644 arch/arm64/include/asm/system.h create mode 100644 arch/arm64/include/asm/types.h create mode 100644 arch/arm64/include/asm/u-boot.h create mode 100644 arch/arm64/include/asm/unaligned.h create mode 100644 arch/arm64/include/asm/utils.h 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
Regards, Simon

On Fri, 2013-08-16 at 13:02 +0800, FengHua wrote:
hi Simon, I have worked on generic board for a few days, but something confuse me. Why it is needed? Each processor architecture has different features, this will affect processor specific and board specific code. Putting board_init_* code of each platform into one file with many macro switch make things messy, the board_f.c and board_r.c become very complicated and less readable. Is it really needed?
Most of the stuff in arch/arm/lib/board.c is not processor specific (and certainly not board specific). It's poorly named and should have been called something like "init.c".
-Scott

Hi David,
On Thu, Aug 15, 2013 at 11:02 PM, FengHua fenghua@phytium.com.cn wrote:
hi Simon, I have worked on generic board for a few days, but something confuse me. Why it is needed? Each processor architecture has different features, this will affect processor specific and board specific code. Putting board_init_* code of each platform into one file with many macro switch make things messy, the board_f.c and board_r.c become very complicated and less readable. Is it really needed? We should make it clear that what parts are common between architecture and what parts are specific. Actually, I have different opinion with this. Architecture specific board.c file have more advantages. how ahout your opinion?
Scott's reply jogged my memory to reply to this.
I suspect having a board.c for each arch was a good idea at the start, and it was hard to reconcile the different ordering and init needs of each arch as it was added. It was much each when porting to a new arch to just copy one of the existing archs and modify the code until it works.
Unfortunately, this means we have about 10 different versions of what turns out to be mostly the same code. The generic board effort was an attempt to unify these into one. While I agree there are lots of #idefs I think that is a separate problem, and at least the code is now all in one file. As a first step it would be nice to sort through and weed out the arch-specific #idefs in common/board_{f,r}.c.
Related to this is global_data and the board data in bd_t. These structures have been unified and again found to contain a lot of common elements across archs.
As a specific example of where having generic board init helps, it is now possible to add a new feature to all archs without changing 10 different files. For example the trace feature was added that way. Decide tree support (CONFIG_OF_CONTROL) can in principle be turned on for any arch by porting it to generic board.
So far ARM and PowerPC support generic board, and x86 and sandbox use it exclusively (i.e. their old board.c code is removed).
As it turns out, this board.c file is not really very arch-specific, as Scott says. It should not be a huge job to make aarch64 use it instead of its own board.c although I am sure there will be a few curly problems.
We have not talked about this on the list, and it is far to early yet, but at some point it would be nice to deprecate the old board.c files.
Regards, Simon
Best Regards. David
-----原始邮件----- 发件人: "Simon Glass" sjg@chromium.org 发送时间: 2013年8月16日 星期五 收件人: fenghua@phytium.com.cn 抄送: "U-Boot Mailing List" u-boot@lists.denx.de, "trini@ti.com" trini@ti.com 主题: Re: [U-Boot] [PATCH v3 0/5] arm64 patch
Hi David,
On Thu, Aug 15, 2013 at 7:47 AM, fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
*** BLURB HERE *** Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok. - according to scott wood's advice, make the fdt 64bit initrd start address support a seperate patch.
David Feng (5): core support of arm64 board support of arm64 arch support 1 of arm64 arch support 2 of arm64 64bit initrd start address support
arch/arm64/config.mk | 32 +++ arch/arm64/cpu/armv8/Makefile | 51 ++++ arch/arm64/cpu/armv8/cache.S | 144 ++++++++++ arch/arm64/cpu/armv8/config.mk | 29 ++ arch/arm64/cpu/armv8/cpu.c | 108 ++++++++ arch/arm64/cpu/armv8/exceptions.S | 189 +++++++++++++ arch/arm64/cpu/armv8/start.S | 197 ++++++++++++++ arch/arm64/cpu/armv8/tlb.S | 38 +++ arch/arm64/cpu/u-boot.lds | 73 +++++ arch/arm64/dts/aemv8a.dtsi | 234 ++++++++++++++++ arch/arm64/include/asm/arch-armv8/mmu.h | 117 ++++++++ arch/arm64/include/asm/atomic.h | 115 ++++++++ arch/arm64/include/asm/bitops.h | 153 +++++++++++ arch/arm64/include/asm/byteorder.h | 31 +++ arch/arm64/include/asm/cache.h | 53 ++++ arch/arm64/include/asm/config.h | 41 +++ arch/arm64/include/asm/errno.h | 1 + arch/arm64/include/asm/global_data.h | 38 +++ arch/arm64/include/asm/gpio.h | 1 + arch/arm64/include/asm/io.h | 193 +++++++++++++ arch/arm64/include/asm/linkage.h | 49 ++++ arch/arm64/include/asm/posix_types.h | 61 +++++ arch/arm64/include/asm/processor.h | 59 ++++ arch/arm64/include/asm/ptrace.h | 64 +++++ arch/arm64/include/asm/sections.h | 27 ++ arch/arm64/include/asm/string.h | 49 ++++ arch/arm64/include/asm/system.h | 106 ++++++++ arch/arm64/include/asm/types.h | 67 +++++ arch/arm64/include/asm/u-boot.h | 38 +++ arch/arm64/include/asm/unaligned.h | 28 ++ arch/arm64/include/asm/utils.h | 56 ++++ arch/arm64/lib/Makefile | 64 +++++ arch/arm64/lib/board.c | 453 +++++++++++++++++++++++++++++++
Instead of this file, it would be good if you could make it use generic board - see CONFIG_SYS_GENERIC_BOARD in the README.
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 | 4 - 52 files changed, 4509 insertions(+), 38 deletions(-) create mode 100644 arch/arm64/config.mk create mode 100644 arch/arm64/cpu/armv8/Makefile create mode 100644 arch/arm64/cpu/armv8/cache.S create mode 100644 arch/arm64/cpu/armv8/config.mk create mode 100644 arch/arm64/cpu/armv8/cpu.c create mode 100644 arch/arm64/cpu/armv8/exceptions.S create mode 100644 arch/arm64/cpu/armv8/start.S create mode 100644 arch/arm64/cpu/armv8/tlb.S create mode 100644 arch/arm64/cpu/u-boot.lds create mode 100644 arch/arm64/dts/aemv8a.dtsi create mode 100644 arch/arm64/include/asm/arch-armv8/mmu.h create mode 100644 arch/arm64/include/asm/atomic.h create mode 100644 arch/arm64/include/asm/bitops.h create mode 100644 arch/arm64/include/asm/byteorder.h create mode 100644 arch/arm64/include/asm/cache.h create mode 100644 arch/arm64/include/asm/config.h create mode 100644 arch/arm64/include/asm/errno.h create mode 100644 arch/arm64/include/asm/global_data.h create mode 100644 arch/arm64/include/asm/gpio.h create mode 100644 arch/arm64/include/asm/io.h create mode 100644 arch/arm64/include/asm/linkage.h create mode 100644 arch/arm64/include/asm/posix_types.h create mode 100644 arch/arm64/include/asm/processor.h create mode 100644 arch/arm64/include/asm/ptrace.h create mode 100644 arch/arm64/include/asm/sections.h create mode 100644 arch/arm64/include/asm/string.h create mode 100644 arch/arm64/include/asm/system.h create mode 100644 arch/arm64/include/asm/types.h create mode 100644 arch/arm64/include/asm/u-boot.h create mode 100644 arch/arm64/include/asm/unaligned.h create mode 100644 arch/arm64/include/asm/utils.h 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
Regards, Simon

On Fri, Aug 16, 2013 at 01:28:26PM -0600, Simon Glass wrote:
Hi David,
On Thu, Aug 15, 2013 at 11:02 PM, FengHua fenghua@phytium.com.cn wrote:
hi Simon, I have worked on generic board for a few days, but something confuse me. Why it is needed? Each processor architecture has different features, this will affect processor specific and board specific code. Putting board_init_* code of each platform into one file with many macro switch make things messy, the board_f.c and board_r.c become very complicated and less readable. Is it really needed? We should make it clear that what parts are common between architecture and what parts are specific. Actually, I have different opinion with this. Architecture specific board.c file have more advantages. how ahout your opinion?
Scott's reply jogged my memory to reply to this.
I suspect having a board.c for each arch was a good idea at the start, and it was hard to reconcile the different ordering and init needs of each arch as it was added. It was much each when porting to a new arch to just copy one of the existing archs and modify the code until it works.
Unfortunately, this means we have about 10 different versions of what turns out to be mostly the same code. The generic board effort was an attempt to unify these into one. While I agree there are lots of #idefs I think that is a separate problem, and at least the code is now all in one file. As a first step it would be nice to sort through and weed out the arch-specific #idefs in common/board_{f,r}.c.
Related to this is global_data and the board data in bd_t. These structures have been unified and again found to contain a lot of common elements across archs.
As a specific example of where having generic board init helps, it is now possible to add a new feature to all archs without changing 10 different files. For example the trace feature was added that way. Decide tree support (CONFIG_OF_CONTROL) can in principle be turned on for any arch by porting it to generic board.
So far ARM and PowerPC support generic board, and x86 and sandbox use it exclusively (i.e. their old board.c code is removed).
As it turns out, this board.c file is not really very arch-specific, as Scott says. It should not be a huge job to make aarch64 use it instead of its own board.c although I am sure there will be a few curly problems.
We have not talked about this on the list, and it is far to early yet, but at some point it would be nice to deprecate the old board.c files.
And this would be another reason to place this in arch/arm to start with, rather than split-arch, leveraging this otherwise generic stuff should just be a matter of setting the define, and one less thing for you to worry about having to cover. It's on my plate to confirm that for example, the trivial convert and boot test I did on am335x was enough.

On Thu, 15 Aug 2013 21:47:09 +0800 fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
*** BLURB HERE *** Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok. - according to scott wood's advice, make the fdt 64bit initrd start address support a seperate patch.
David Feng (5): core support of arm64 board support of arm64 arch support 1 of arm64 arch support 2 of arm64 64bit initrd start address support
nitpick but the arch is aarch64 not arm64
Dennis

On Thu, 2013-08-15 at 23:32 -0500, Dennis Gilmore wrote:
On Thu, 15 Aug 2013 21:47:09 +0800 fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
*** BLURB HERE *** Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok. - according to scott wood's advice, make the fdt 64bit initrd start address support a seperate patch.
David Feng (5): core support of arm64 board support of arm64 arch support 1 of arm64 arch support 2 of arm64 64bit initrd start address support
nitpick but the arch is aarch64 not arm64
powerpc is Power Architecture these days but we still call it powerpc. arm64 is a sensible name that doesn't reduce the meaningful part of the name (excluding the word size suffix) down to a single character.
-Scott

-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Scott Wood Sent: Saturday, August 17, 2013 1:23 AM To: Dennis Gilmore Cc: trini@ti.com; u-boot@lists.denx.de; fenghua@phytium.com.cn Subject: Re: [U-Boot] [PATCH v3 0/5] arm64 patch
On Thu, 2013-08-15 at 23:32 -0500, Dennis Gilmore wrote:
On Thu, 15 Aug 2013 21:47:09 +0800 fenghua@phytium.com.cn wrote:
From: David Feng fenghua@phytium.com.cn
*** BLURB HERE *** Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok. - according to scott wood's advice, make the fdt 64bit initrd start address support a seperate patch.
David Feng (5): core support of arm64 board support of arm64 arch support 1 of arm64 arch support 2 of arm64 64bit initrd start address support
nitpick but the arch is aarch64 not arm64
powerpc is Power Architecture these days but we still call it powerpc. arm64 is a sensible name that doesn't reduce the meaningful part of the name (excluding the word size suffix) down to a single character.
Arm64 seems more simple and sensible and in-line with the naming convention used across linux (arch/arm64). I remember reading Linus's comments in favor of keeping a arm64 naming convention in the past (instead of Armv8 or AArch64). Here is that mail thread for reference:
https://lkml.org/lkml/2012/7/15/133
Regards, Bhupesh
participants (8)
-
Dennis Gilmore
-
FengHua
-
fenghua@phytium.com.cn
-
Scott Wood
-
Sharma Bhupesh-B45370
-
Simon Glass
-
Stuart Yoder
-
Tom Rini