summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorStefano Babic <sbabic@denx.de>2014-01-26 12:11:54 +0100
committerStefano Babic <sbabic@denx.de>2014-01-26 12:11:54 +0100
commit707acd01ded3c60a4e277f7c5432d397897b4dfd (patch)
tree5730e1e1f0bac6c1aeddc261cb412fc3d5f220fd /arch
parentbe2a3bb39adf1fdd274fc427e30ef62eb86441a1 (diff)
parentc71b4dd2da0dcddabd7c29e6c3dc8a495d4bd928 (diff)
downloadtalos-obmc-uboot-707acd01ded3c60a4e277f7c5432d397897b4dfd.tar.gz
talos-obmc-uboot-707acd01ded3c60a4e277f7c5432d397897b4dfd.zip
Merge branch 'master' of git://git.denx.de/u-boot-arm
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/config.mk9
-rw-r--r--arch/arm/cpu/armv7/exynos/config.mk7
-rw-r--r--arch/arm/cpu/armv7/lowlevel_init.S2
-rw-r--r--arch/arm/cpu/armv7/zynq/slcr.c6
-rw-r--r--arch/arm/cpu/armv7/zynq/timer.c3
-rw-r--r--arch/arm/cpu/armv8/Makefile17
-rw-r--r--arch/arm/cpu/armv8/cache.S136
-rw-r--r--arch/arm/cpu/armv8/cache_v8.c219
-rw-r--r--arch/arm/cpu/armv8/config.mk15
-rw-r--r--arch/arm/cpu/armv8/cpu.c43
-rw-r--r--arch/arm/cpu/armv8/exceptions.S113
-rw-r--r--arch/arm/cpu/armv8/generic_timer.c31
-rw-r--r--arch/arm/cpu/armv8/gic.S106
-rw-r--r--arch/arm/cpu/armv8/start.S164
-rw-r--r--arch/arm/cpu/armv8/tlb.S34
-rw-r--r--arch/arm/cpu/armv8/transition.S83
-rw-r--r--arch/arm/cpu/armv8/u-boot.lds89
-rw-r--r--arch/arm/cpu/pxa/config.mk13
-rw-r--r--arch/arm/cpu/pxa/timer.c4
-rw-r--r--arch/arm/cpu/u-boot.lds3
-rw-r--r--arch/arm/dts/zynq-7000.dtsi13
-rw-r--r--arch/arm/include/asm/arch-rmobile/r8a7790.h1
-rw-r--r--arch/arm/include/asm/arch-rmobile/r8a7791.h1
-rw-r--r--arch/arm/include/asm/arch-socfpga/dwmmc.h12
-rw-r--r--arch/arm/include/asm/arch-socfpga/system_manager.h65
-rw-r--r--arch/arm/include/asm/arch-zynq/gpio.h25
-rw-r--r--arch/arm/include/asm/arch-zynq/sys_proto.h1
-rw-r--r--arch/arm/include/asm/armv8/mmu.h111
-rw-r--r--arch/arm/include/asm/byteorder.h2
-rw-r--r--arch/arm/include/asm/cache.h5
-rw-r--r--arch/arm/include/asm/config.h6
-rw-r--r--arch/arm/include/asm/gic.h49
-rw-r--r--arch/arm/include/asm/global_data.h6
-rw-r--r--arch/arm/include/asm/io.h15
-rw-r--r--arch/arm/include/asm/macro.h53
-rw-r--r--arch/arm/include/asm/posix_types.h8
-rw-r--r--arch/arm/include/asm/proc-armv/ptrace.h21
-rw-r--r--arch/arm/include/asm/proc-armv/system.h59
-rw-r--r--arch/arm/include/asm/system.h84
-rw-r--r--arch/arm/include/asm/types.h4
-rw-r--r--arch/arm/include/asm/u-boot.h4
-rw-r--r--arch/arm/include/asm/unaligned.h2
-rw-r--r--arch/arm/lib/Makefile20
-rw-r--r--arch/arm/lib/board.c7
-rw-r--r--arch/arm/lib/bootm.c47
-rw-r--r--arch/arm/lib/crt0.S2
-rw-r--r--arch/arm/lib/crt0_64.S113
-rw-r--r--arch/arm/lib/interrupts_64.c120
-rw-r--r--arch/arm/lib/relocate_64.S58
-rw-r--r--arch/blackfin/config.mk4
-rw-r--r--arch/blackfin/cpu/initcode.c18
-rw-r--r--arch/blackfin/include/asm/blackfin_local.h7
-rw-r--r--arch/blackfin/lib/board.c1
-rw-r--r--arch/blackfin/lib/clocks.c5
-rw-r--r--arch/powerpc/config.mk5
-rw-r--r--arch/powerpc/cpu/74xx_7xx/config.mk4
-rw-r--r--arch/powerpc/cpu/Makefile6
-rw-r--r--arch/powerpc/cpu/mpc512x/config.mk5
-rw-r--r--arch/powerpc/cpu/mpc5xx/config.mk4
-rw-r--r--arch/powerpc/cpu/mpc5xxx/config.mk4
-rw-r--r--arch/powerpc/cpu/mpc824x/config.mk4
-rw-r--r--arch/powerpc/cpu/mpc8260/config.mk4
-rw-r--r--arch/powerpc/cpu/mpc83xx/config.mk5
-rw-r--r--arch/powerpc/cpu/mpc85xx/config.mk7
-rw-r--r--arch/powerpc/cpu/mpc85xx/speed.c28
-rw-r--r--arch/powerpc/cpu/mpc86xx/config.mk5
-rw-r--r--arch/powerpc/cpu/mpc8xx/config.mk4
-rw-r--r--arch/powerpc/cpu/mpc8xxx/Makefile6
-rw-r--r--arch/powerpc/cpu/ppc4xx/config.mk3
-rw-r--r--arch/powerpc/include/asm/config_mpc85xx.h5
-rw-r--r--arch/powerpc/include/asm/immap_85xx.h3
-rw-r--r--arch/powerpc/lib/bootm.c56
-rw-r--r--arch/sandbox/cpu/cpu.c21
-rw-r--r--arch/sandbox/cpu/os.c95
-rw-r--r--arch/sandbox/cpu/start.c96
-rw-r--r--arch/sandbox/cpu/state.c353
-rw-r--r--arch/sandbox/include/asm/global_data.h2
-rw-r--r--arch/sandbox/include/asm/state.h128
-rw-r--r--arch/sandbox/include/asm/u-boot-sandbox.h2
-rw-r--r--arch/sh/cpu/sh2/config.mk2
-rw-r--r--arch/sh/cpu/sh2/cpu.c4
-rw-r--r--arch/sh/cpu/sh3/config.mk2
-rw-r--r--arch/sh/cpu/sh4/config.mk2
-rw-r--r--arch/sh/cpu/sh4/cpu.c4
-rw-r--r--arch/sh/include/asm/cache.h4
-rw-r--r--arch/sh/include/asm/cpu_sh4.h2
-rw-r--r--arch/sh/include/asm/cpu_sh7753.h197
-rw-r--r--arch/sh/include/asm/processor.h8
-rw-r--r--arch/sh/lib/time_sh2.c2
89 files changed, 2997 insertions, 131 deletions
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index fd3e5fb661..cfa42094ca 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -17,7 +17,8 @@ endif
LDFLAGS_FINAL += --gc-sections
PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \
- -fno-common -ffixed-r9 -msoft-float
+ -fno-common -ffixed-r9
+PLATFORM_RELFLAGS += $(call cc-option, -msoft-float)
# Support generic board on ARM
__HAVE_ARCH_GENERIC_BOARD := y
@@ -105,4 +106,8 @@ PLATFORM_CPPFLAGS += $(call cc-option, -mword-relocations)
endif
# limit ourselves to the sections we want in the .bin.
-OBJCFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rel.dyn
+ifdef CONFIG_ARM64
+OBJCFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn
+else
+OBJCFLAGS += -j .text -j .rodata -j .hash -j .data -j .got.plt -j .u_boot_list -j .rel.dyn
+endif
diff --git a/arch/arm/cpu/armv7/exynos/config.mk b/arch/arm/cpu/armv7/exynos/config.mk
new file mode 100644
index 0000000000..ee0d2dab7b
--- /dev/null
+++ b/arch/arm/cpu/armv7/exynos/config.mk
@@ -0,0 +1,7 @@
+#
+# Copyright (C) Albert ARIBAUD <albert.u.boot@aribaud.net>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+SPL_OBJCFLAGS += -j .machine_param
diff --git a/arch/arm/cpu/armv7/lowlevel_init.S b/arch/arm/cpu/armv7/lowlevel_init.S
index 69e3053a42..f1aea05c90 100644
--- a/arch/arm/cpu/armv7/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/lowlevel_init.S
@@ -24,7 +24,7 @@ ENTRY(lowlevel_init)
#ifdef CONFIG_SPL_BUILD
ldr r9, =gdata
#else
- sub sp, #GD_SIZE
+ sub sp, sp, #GD_SIZE
bic sp, sp, #7
mov r9, sp
#endif
diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c
index 717ec65aee..b4c11c324c 100644
--- a/arch/arm/cpu/armv7/zynq/slcr.c
+++ b/arch/arm/cpu/armv7/zynq/slcr.c
@@ -101,6 +101,12 @@ void zynq_slcr_devcfg_enable(void)
zynq_slcr_lock();
}
+u32 zynq_slcr_get_boot_mode(void)
+{
+ /* Get the bootmode register value */
+ return readl(&slcr_base->boot_mode);
+}
+
u32 zynq_slcr_get_idcode(void)
{
return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >>
diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/cpu/armv7/zynq/timer.c
index 636322a8e5..2be253c2c3 100644
--- a/arch/arm/cpu/armv7/zynq/timer.c
+++ b/arch/arm/cpu/armv7/zynq/timer.c
@@ -107,8 +107,7 @@ void __udelay(unsigned long usec)
if (usec == 0)
return;
- countticks = (u32) (((unsigned long long) TIMER_TICK_HZ * usec) /
- 1000000);
+ countticks = lldiv(TIMER_TICK_HZ * usec, 1000000);
/* decrementing timer */
timeend = readl(&timer_base->counter) - countticks;
diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
new file mode 100644
index 0000000000..b6eb6de5e3
--- /dev/null
+++ b/arch/arm/cpu/armv8/Makefile
@@ -0,0 +1,17 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+extra-y := start.o
+
+obj-y += cpu.o
+obj-y += generic_timer.o
+obj-y += cache_v8.o
+obj-y += exceptions.o
+obj-y += cache.o
+obj-y += tlb.o
+obj-y += gic.o
+obj-y += transition.o
diff --git a/arch/arm/cpu/armv8/cache.S b/arch/arm/cpu/armv8/cache.S
new file mode 100644
index 0000000000..546a83e8f8
--- /dev/null
+++ b/arch/arm/cpu/armv8/cache.S
@@ -0,0 +1,136 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * This file is based on sample code from ARMv8 ARM.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <version.h>
+#include <asm/macro.h>
+#include <linux/linkage.h>
+
+/*
+ * void __asm_flush_dcache_level(level)
+ *
+ * clean and invalidate one level cache.
+ *
+ * x0: cache level
+ * x1~x9: clobbered
+ */
+ENTRY(__asm_flush_dcache_level)
+ lsl x1, x0, #1
+ msr csselr_el1, x1 /* select cache level */
+ isb /* sync change of cssidr_el1 */
+ mrs x6, ccsidr_el1 /* read the new cssidr_el1 */
+ and x2, x6, #7 /* x2 <- log2(cache line size)-4 */
+ add x2, x2, #4 /* x2 <- log2(cache line size) */
+ mov x3, #0x3ff
+ and x3, x3, x6, lsr #3 /* x3 <- max number of #ways */
+ add w4, w3, w3
+ sub w4, w4, 1 /* round up log2(#ways + 1) */
+ clz w5, w4 /* bit position of #ways */
+ mov x4, #0x7fff
+ and x4, x4, x6, lsr #13 /* x4 <- max number of #sets */
+ /* x1 <- cache level << 1 */
+ /* x2 <- line length offset */
+ /* x3 <- number of cache ways - 1 */
+ /* x4 <- number of cache sets - 1 */
+ /* x5 <- bit position of #ways */
+
+loop_set:
+ mov x6, x3 /* x6 <- working copy of #ways */
+loop_way:
+ lsl x7, x6, x5
+ orr x9, x1, 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(__asm_flush_dcache_level)
+
+/*
+ * void __asm_flush_dcache_all(void)
+ *
+ * clean and invalidate all data cache by SET/WAY.
+ */
+ENTRY(__asm_flush_dcache_all)
+ dsb sy
+ mrs x10, clidr_el1 /* read clidr_el1 */
+ lsr x11, x10, #24
+ and x11, x11, #0x7 /* x11 <- loc */
+ cbz x11, finished /* if loc is 0, exit */
+ mov x15, lr
+ mov x0, #0 /* start flush at cache level 0 */
+ /* x0 <- cache level */
+ /* x10 <- clidr_el1 */
+ /* x11 <- loc */
+ /* x15 <- return address */
+
+loop_level:
+ lsl x1, x0, #1
+ add x1, x1, x0 /* x0 <- tripled 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 __asm_flush_dcache_level
+skip:
+ add x0, x0, #1 /* increment cache level */
+ cmp x11, x0
+ b.gt loop_level
+
+ mov x0, #0
+ msr csselr_el1, x0 /* resotre csselr_el1 */
+ dsb sy
+ isb
+ mov lr, x15
+
+finished:
+ ret
+ENDPROC(__asm_flush_dcache_all)
+
+/*
+ * void __asm_flush_dcache_range(start, end)
+ *
+ * clean & invalidate data cache in the range
+ *
+ * x0: start address
+ * x1: end address
+ */
+ENTRY(__asm_flush_dcache_range)
+ mrs x3, ctr_el0
+ lsr x3, x3, #16
+ and x3, x3, #0xf
+ mov x2, #4
+ lsl x2, x2, x3 /* 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 data or unified cache */
+ add x0, x0, x2
+ cmp x0, x1
+ b.lo 1b
+ dsb sy
+ ret
+ENDPROC(__asm_flush_dcache_range)
+
+/*
+ * void __asm_invalidate_icache_all(void)
+ *
+ * invalidate all tlb entries.
+ */
+ENTRY(__asm_invalidate_icache_all)
+ ic ialluis
+ isb sy
+ ret
+ENDPROC(__asm_invalidate_icache_all)
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
new file mode 100644
index 0000000000..131fdaba3f
--- /dev/null
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -0,0 +1,219 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/system.h>
+#include <asm/armv8/mmu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+
+static void set_pgtable_section(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 void mmu_setup(void)
+{
+ int i, j, el;
+ bd_t *bd = gd->bd;
+
+ /* Setup an identity-mapping for all spaces */
+ for (i = 0; i < (PGTABLE_SIZE >> 3); i++)
+ set_pgtable_section(i, MT_DEVICE_NGNRNE);
+
+ /* Setup an identity-mapping for all RAM space */
+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ ulong start = bd->bi_dram[i].start;
+ ulong end = bd->bi_dram[i].start + bd->bi_dram[i].size;
+ for (j = start >> SECTION_SHIFT;
+ j < end >> SECTION_SHIFT; j++) {
+ set_pgtable_section(j, MT_NORMAL);
+ }
+ }
+
+ /* load TTBR0 */
+ el = current_el();
+ if (el == 1)
+ asm volatile("msr ttbr0_el1, %0"
+ : : "r" (gd->arch.tlb_addr) : "memory");
+ else if (el == 2)
+ asm volatile("msr ttbr0_el2, %0"
+ : : "r" (gd->arch.tlb_addr) : "memory");
+ else
+ asm volatile("msr ttbr0_el3, %0"
+ : : "r" (gd->arch.tlb_addr) : "memory");
+
+ /* 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)
+{
+ __asm_flush_dcache_all();
+}
+
+/*
+ * Performs a clean & invalidation of the entire data cache at all levels
+ */
+void flush_dcache_all(void)
+{
+ __asm_flush_dcache_all();
+}
+
+/*
+ * Invalidates range in all levels of D-cache/unified cache
+ */
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+ __asm_flush_dcache_range(start, stop);
+}
+
+/*
+ * Flush range(clean & invalidate) from all levels of D-cache/unified cache
+ */
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+ __asm_flush_dcache_range(start, stop);
+}
+
+void dcache_enable(void)
+{
+ /* The data cache is not active unless the mmu is enabled */
+ if (!(get_sctlr() & CR_M)) {
+ invalidate_dcache_all();
+ __asm_invalidate_tlb_all();
+ mmu_setup();
+ }
+
+ set_sctlr(get_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();
+ __asm_invalidate_tlb_all();
+}
+
+int dcache_status(void)
+{
+ return (get_sctlr() & CR_C) != 0;
+}
+
+#else /* CONFIG_SYS_DCACHE_OFF */
+
+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)
+{
+ __asm_invalidate_icache_all();
+}
+
+#else /* CONFIG_SYS_ICACHE_OFF */
+
+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
+ */
+void flush_cache(unsigned long start, unsigned long size)
+{
+ flush_dcache_range(start, start + size);
+}
diff --git a/arch/arm/cpu/armv8/config.mk b/arch/arm/cpu/armv8/config.mk
new file mode 100644
index 0000000000..027a68ca57
--- /dev/null
+++ b/arch/arm/cpu/armv8/config.mk
@@ -0,0 +1,15 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+PLATFORM_RELFLAGS += -fno-common -ffixed-x18
+
+# SEE README.arm-unaligned-accesses
+PF_NO_UNALIGNED := $(call cc-option, -mstrict-align)
+PLATFORM_NO_UNALIGNED := $(PF_NO_UNALIGNED)
+
+PF_CPPFLAGS_ARMV8 := $(call cc-option, -march=armv8-a)
+PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARMV8)
+PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED)
diff --git a/arch/arm/cpu/armv8/cpu.c b/arch/arm/cpu/armv8/cpu.c
new file mode 100644
index 0000000000..e06c3cc04d
--- /dev/null
+++ b/arch/arm/cpu/armv8/cpu.c
@@ -0,0 +1,43 @@
+/*
+ * (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>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/system.h>
+#include <linux/compiler.h>
+
+int cleanup_before_linux(void)
+{
+ /*
+ * this function is called just before we call linux
+ * it prepares the processor for linux
+ *
+ * disable interrupt and turn off caches etc ...
+ */
+ 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();
+ invalidate_dcache_all();
+
+ return 0;
+}
diff --git a/arch/arm/cpu/armv8/exceptions.S b/arch/arm/cpu/armv8/exceptions.S
new file mode 100644
index 0000000000..b91a1b662f
--- /dev/null
+++ b/arch/arm/cpu/armv8/exceptions.S
@@ -0,0 +1,113 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <version.h>
+#include <asm/ptrace.h>
+#include <asm/macro.h>
+#include <linux/linkage.h>
+
+/*
+ * Enter Exception.
+ * This will save the processor state that is ELR/X0~X30
+ * to the stack frame.
+ */
+.macro exception_entry
+ stp x29, x30, [sp, #-16]!
+ stp x27, x28, [sp, #-16]!
+ stp x25, x26, [sp, #-16]!
+ stp x23, x24, [sp, #-16]!
+ stp x21, x22, [sp, #-16]!
+ stp x19, x20, [sp, #-16]!
+ stp x17, x18, [sp, #-16]!
+ stp x15, x16, [sp, #-16]!
+ stp x13, x14, [sp, #-16]!
+ stp x11, x12, [sp, #-16]!
+ stp x9, x10, [sp, #-16]!
+ stp x7, x8, [sp, #-16]!
+ stp x5, x6, [sp, #-16]!
+ stp x3, x4, [sp, #-16]!
+ stp x1, x2, [sp, #-16]!
+
+ /* Could be running at EL3/EL2/EL1 */
+ switch_el x11, 3f, 2f, 1f
+3: mrs x1, esr_el3
+ mrs x2, elr_el3
+ b 0f
+2: mrs x1, esr_el2
+ mrs x2, elr_el2
+ b 0f
+1: mrs x1, esr_el1
+ mrs x2, elr_el1
+0:
+ stp x2, x0, [sp, #-16]!
+ mov x0, sp
+.endm
+
+/*
+ * Exception vectors.
+ */
+ .align 11
+ .globl vectors
+vectors:
+ .align 7
+ b _do_bad_sync /* Current EL Synchronous Thread */
+
+ .align 7
+ b _do_bad_irq /* Current EL IRQ Thread */
+
+ .align 7
+ b _do_bad_fiq /* Current EL FIQ Thread */
+
+ .align 7
+ b _do_bad_error /* Current EL Error Thread */
+
+ .align 7
+ b _do_sync /* Current EL Synchronous Handler */
+
+ .align 7
+ b _do_irq /* Current EL IRQ Handler */
+
+ .align 7
+ b _do_fiq /* Current EL FIQ Handler */
+
+ .align 7
+ b _do_error /* Current EL Error Handler */
+
+
+_do_bad_sync:
+ exception_entry
+ bl do_bad_sync
+
+_do_bad_irq:
+ exception_entry
+ bl do_bad_irq
+
+_do_bad_fiq:
+ exception_entry
+ bl do_bad_fiq
+
+_do_bad_error:
+ exception_entry
+ bl do_bad_error
+
+_do_sync:
+ exception_entry
+ bl do_sync
+
+_do_irq:
+ exception_entry
+ bl do_irq
+
+_do_fiq:
+ exception_entry
+ bl do_fiq
+
+_do_error:
+ exception_entry
+ bl do_error
diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c
new file mode 100644
index 0000000000..223b95e210
--- /dev/null
+++ b/arch/arm/cpu/armv8/generic_timer.c
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/system.h>
+
+/*
+ * Generic timer implementation of get_tbclk()
+ */
+unsigned long get_tbclk(void)
+{
+ unsigned long cntfrq;
+ asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq));
+ return cntfrq;
+}
+
+/*
+ * Generic timer implementation of timer_read_counter()
+ */
+unsigned long timer_read_counter(void)
+{
+ unsigned long cntpct;
+ isb();
+ asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
+ return cntpct;
+}
diff --git a/arch/arm/cpu/armv8/gic.S b/arch/arm/cpu/armv8/gic.S
new file mode 100644
index 0000000000..599aa8f2ba
--- /dev/null
+++ b/arch/arm/cpu/armv8/gic.S
@@ -0,0 +1,106 @@
+/*
+ * GIC Initialization Routines.
+ *
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+#include <asm/gic.h>
+
+
+/*************************************************************************
+ *
+ * void gic_init(void) __attribute__((weak));
+ *
+ * Currently, this routine only initialize secure copy of GIC
+ * with Security Extensions at EL3.
+ *
+ *************************************************************************/
+WEAK(gic_init)
+ branch_if_slave x0, 2f
+
+ /* Initialize Distributor and SPIs */
+ ldr x1, =GICD_BASE
+ mov w0, #0x3 /* EnableGrp0 | EnableGrp1 */
+ str w0, [x1, GICD_CTLR] /* Secure GICD_CTLR */
+ ldr w0, [x1, GICD_TYPER]
+ and w2, w0, #0x1f /* ITLinesNumber */
+ cbz w2, 2f /* No SPIs */
+ add x1, x1, (GICD_IGROUPRn + 4)
+ mov w0, #~0 /* Config SPIs as Grp1 */
+1: str w0, [x1], #0x4
+ sub w2, w2, #0x1
+ cbnz w2, 1b
+
+ /* Initialize SGIs and PPIs */
+2: ldr x1, =GICD_BASE
+ mov w0, #~0 /* Config SGIs and PPIs as Grp1 */
+ str w0, [x1, GICD_IGROUPRn] /* GICD_IGROUPR0 */
+ mov w0, #0x1 /* Enable SGI 0 */
+ str w0, [x1, GICD_ISENABLERn]
+
+ /* Initialize Cpu Interface */
+ ldr x1, =GICC_BASE
+ mov w0, #0x1e7 /* Disable IRQ/FIQ Bypass & */
+ /* Enable Ack Group1 Interrupt & */
+ /* EnableGrp0 & EnableGrp1 */
+ str w0, [x1, GICC_CTLR] /* Secure GICC_CTLR */
+
+ mov w0, #0x1 << 7 /* Non-Secure access to GICC_PMR */
+ str w0, [x1, GICC_PMR]
+
+ ret
+ENDPROC(gic_init)
+
+
+/*************************************************************************
+ *
+ * void gic_send_sgi(u64 sgi) __attribute__((weak));
+ *
+ *************************************************************************/
+WEAK(gic_send_sgi)
+ ldr x1, =GICD_BASE
+ mov w2, #0x8000
+ movk w2, #0x100, lsl #16
+ orr w2, w2, w0
+ str w2, [x1, GICD_SGIR]
+ ret
+ENDPROC(gic_send_sgi)
+
+
+/*************************************************************************
+ *
+ * void wait_for_wakeup(void) __attribute__((weak));
+ *
+ * Wait for SGI 0 from master.
+ *
+ *************************************************************************/
+WEAK(wait_for_wakeup)
+ ldr x1, =GICC_BASE
+0: wfi
+ ldr w0, [x1, GICC_AIAR]
+ str w0, [x1, GICC_AEOIR]
+ cbnz w0, 0b
+ ret
+ENDPROC(wait_for_wakeup)
+
+
+/*************************************************************************
+ *
+ * void smp_kick_all_cpus(void) __attribute__((weak));
+ *
+ *************************************************************************/
+WEAK(smp_kick_all_cpus)
+ /* Kick secondary cpus up by SGI 0 interrupt */
+ mov x0, xzr /* SGI 0 */
+ mov x29, lr /* Save LR */
+ bl gic_send_sgi
+ mov lr, x29 /* Restore LR */
+ ret
+ENDPROC(smp_kick_all_cpus)
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
new file mode 100644
index 0000000000..bcc2603098
--- /dev/null
+++ b/arch/arm/cpu/armv8/start.S
@@ -0,0 +1,164 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <version.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+#include <asm/armv8/mmu.h>
+
+/*************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ *************************************************************************/
+
+.globl _start
+_start:
+ b reset
+
+ .align 3
+
+.globl _TEXT_BASE
+_TEXT_BASE:
+ .quad CONFIG_SYS_TEXT_BASE
+
+/*
+ * These are defined in the linker script.
+ */
+.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:
+ /*
+ * Could be EL3/EL2/EL1, Initial State:
+ * Little Endian, MMU Disabled, i/dCache Disabled
+ */
+ adr x0, vectors
+ switch_el x1, 3f, 2f, 1f
+3: msr vbar_el3, x0
+ msr cptr_el3, xzr /* Enable FP/SIMD */
+ ldr x0, =COUNTER_FREQUENCY
+ msr cntfrq_el0, x0 /* Initialize CNTFRQ */
+ b 0f
+2: msr vbar_el2, x0
+ mov x0, #0x33ff
+ msr cptr_el2, x0 /* Enable FP/SIMD */
+ b 0f
+1: msr vbar_el1, x0
+ mov x0, #3 << 20
+ msr cpacr_el1, x0 /* Enable FP/SIMD */
+0:
+
+ /* Cache/BPB/TLB Invalidate */
+ bl __asm_flush_dcache_all /* dCache clean&invalidate */
+ bl __asm_invalidate_icache_all /* iCache invalidate */
+ bl __asm_invalidate_tlb_all /* invalidate TLBs */
+
+ /* Processor specific initialization */
+ bl lowlevel_init
+
+ branch_if_master x0, x1, master_cpu
+
+ /*
+ * Slave CPUs
+ */
+slave_cpu:
+ wfe
+ ldr x1, =CPU_RELEASE_ADDR
+ ldr x0, [x1]
+ cbz x0, slave_cpu
+ br x0 /* branch to the given address */
+
+ /*
+ * Master CPU
+ */
+master_cpu:
+ bl _main
+
+/*-----------------------------------------------------------------------*/
+
+WEAK(lowlevel_init)
+ /* Initialize GIC Secure Bank Status */
+ mov x29, lr /* Save LR */
+ bl gic_init
+
+ branch_if_master x0, x1, 1f
+
+ /*
+ * Slave should wait for master clearing spin table.
+ * This sync prevent salves observing incorrect
+ * value of spin table and jumping to wrong place.
+ */
+ bl wait_for_wakeup
+
+ /*
+ * All processors will enter EL2 and optionally EL1.
+ */
+ bl armv8_switch_to_el2
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+ bl armv8_switch_to_el1
+#endif
+
+1:
+ mov lr, x29 /* Restore LR */
+ ret
+ENDPROC(lowlevel_init)
+
+/*-----------------------------------------------------------------------*/
+
+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
+ /*
+ * Setup MAIR and TCR.
+ */
+ ldr x0, =MEMORY_ATTRIBUTES
+ ldr x1, =TCR_FLAGS
+
+ switch_el x2, 3f, 2f, 1f
+3: orr x1, x1, TCR_EL3_IPS_BITS
+ msr mair_el3, x0
+ msr tcr_el3, x1
+ b 0f
+2: orr x1, x1, TCR_EL2_IPS_BITS
+ msr mair_el2, x0
+ msr tcr_el2, x1
+ b 0f
+1: orr x1, x1, TCR_EL1_IPS_BITS
+ msr mair_el1, x0
+ msr tcr_el1, x1
+0:
+#endif
+
+ /* Relocate vBAR */
+ adr x0, vectors
+ switch_el x1, 3f, 2f, 1f
+3: msr vbar_el3, x0
+ b 0f
+2: msr vbar_el2, x0
+ b 0f
+1: msr vbar_el1, x0
+0:
+
+ ret
+ENDPROC(c_runtime_cpu_setup)
diff --git a/arch/arm/cpu/armv8/tlb.S b/arch/arm/cpu/armv8/tlb.S
new file mode 100644
index 0000000000..f840b04df5
--- /dev/null
+++ b/arch/arm/cpu/armv8/tlb.S
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <version.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+
+/*
+ * void __asm_invalidate_tlb_all(void)
+ *
+ * invalidate all tlb entries.
+ */
+ENTRY(__asm_invalidate_tlb_all)
+ switch_el x9, 3f, 2f, 1f
+3: tlbi alle3
+ dsb sy
+ isb
+ b 0f
+2: tlbi alle2
+ dsb sy
+ isb
+ b 0f
+1: tlbi vmalle1
+ dsb sy
+ isb
+0:
+ ret
+ENDPROC(__asm_invalidate_tlb_all)
diff --git a/arch/arm/cpu/armv8/transition.S b/arch/arm/cpu/armv8/transition.S
new file mode 100644
index 0000000000..e0a5946009
--- /dev/null
+++ b/arch/arm/cpu/armv8/transition.S
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <version.h>
+#include <linux/linkage.h>
+#include <asm/macro.h>
+
+ENTRY(armv8_switch_to_el2)
+ switch_el x0, 1f, 0f, 0f
+0: ret
+1:
+ mov x0, #0x5b1 /* Non-secure EL0/EL1 | HVC | 64bit EL2 */
+ msr scr_el3, x0
+ msr cptr_el3, xzr /* Disable coprocessor traps to EL3 */
+ mov x0, #0x33ff
+ msr cptr_el2, x0 /* Disable coprocessor traps to EL2 */
+
+ /* Initialize SCTLR_EL2 */
+ msr sctlr_el2, xzr
+
+ /* Return to the EL2_SP2 mode from EL3 */
+ mov x0, sp
+ msr sp_el2, x0 /* Migrate SP */
+ mrs x0, vbar_el3
+ msr vbar_el2, x0 /* Migrate VBAR */
+ mov x0, #0x3c9
+ msr spsr_el3, x0 /* EL2_SP2 | D | A | I | F */
+ msr elr_el3, lr
+ eret
+ENDPROC(armv8_switch_to_el2)
+
+ENTRY(armv8_switch_to_el1)
+ switch_el x0, 0f, 1f, 0f
+0: ret
+1:
+ /* Initialize Generic Timers */
+ mrs x0, cnthctl_el2
+ orr x0, x0, #0x3 /* Enable EL1 access to timers */
+ msr cnthctl_el2, x0
+ msr cntvoff_el2, x0
+ mrs x0, cntkctl_el1
+ orr x0, x0, #0x3 /* Enable EL0 access to timers */
+ msr cntkctl_el1, x0
+
+ /* Initilize MPID/MPIDR registers */
+ mrs x0, midr_el1
+ mrs x1, mpidr_el1
+ msr vpidr_el2, x0
+ msr vmpidr_el2, x1
+
+ /* Disable coprocessor traps */
+ mov x0, #0x33ff
+ msr cptr_el2, x0 /* Disable coprocessor traps to EL2 */
+ msr hstr_el2, xzr /* Disable coprocessor traps to EL2 */
+ mov x0, #3 << 20
+ msr cpacr_el1, x0 /* Enable FP/SIMD at EL1 */
+
+ /* Initialize HCR_EL2 */
+ mov x0, #(1 << 31) /* 64bit EL1 */
+ orr x0, x0, #(1 << 29) /* Disable HVC */
+ msr hcr_el2, x0
+
+ /* SCTLR_EL1 initialization */
+ mov x0, #0x0800
+ movk x0, #0x30d0, lsl #16
+ msr sctlr_el1, x0
+
+ /* Return to the EL1_SP1 mode from EL2 */
+ mov x0, sp
+ msr sp_el1, x0 /* Migrate SP */
+ mrs x0, vbar_el2
+ msr vbar_el1, x0 /* Migrate VBAR */
+ mov x0, #0x3c5
+ msr spsr_el2, x0 /* EL1_SP1 | D | A | I | F */
+ msr elr_el2, lr
+ eret
+ENDPROC(armv8_switch_to_el1)
diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds
new file mode 100644
index 0000000000..4c12222370
--- /dev/null
+++ b/arch/arm/cpu/armv8/u-boot.lds
@@ -0,0 +1,89 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+
+ . = 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);
+
+ . = .;
+
+ . = ALIGN(8);
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*)));
+ }
+
+ . = ALIGN(8);
+
+ .image_copy_end :
+ {
+ *(.__image_copy_end)
+ }
+
+ . = ALIGN(8);
+
+ .rel_dyn_start :
+ {
+ *(.__rel_dyn_start)
+ }
+
+ .rela.dyn : {
+ *(.rela*)
+ }
+
+ .rel_dyn_end :
+ {
+ *(.__rel_dyn_end)
+ }
+
+ _end = .;
+
+ . = ALIGN(8);
+
+ .bss_start : {
+ KEEP(*(.__bss_start));
+ }
+
+ .bss : {
+ *(.bss*)
+ . = ALIGN(8);
+ }
+
+ .bss_end : {
+ KEEP(*(.__bss_end));
+ }
+
+ /DISCARD/ : { *(.dynsym) }
+ /DISCARD/ : { *(.dynstr*) }
+ /DISCARD/ : { *(.dynamic*) }
+ /DISCARD/ : { *(.plt*) }
+ /DISCARD/ : { *(.interp*) }
+ /DISCARD/ : { *(.gnu*) }
+}
diff --git a/arch/arm/cpu/pxa/config.mk b/arch/arm/cpu/pxa/config.mk
index d8d263d404..f2befbe515 100644
--- a/arch/arm/cpu/pxa/config.mk
+++ b/arch/arm/cpu/pxa/config.mk
@@ -14,3 +14,16 @@ PLATFORM_CPPFLAGS += -mcpu=xscale
# ========================================================================
PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
+
+#
+# !WARNING!
+# The PXA's OneNAND SPL uses .text.0 and .text.1 segments to allow booting from
+# really small OneNAND memories where the mmap'd window is only 1KiB big. The
+# .text.0 contains only the bare minimum needed to load the real SPL into SRAM.
+# Add .text.0 and .text.1 into OBJFLAGS, so when the SPL is being objcopy'd,
+# they are not discarded.
+#
+
+#ifdef CONFIG_SPL_BUILD
+OBJCFLAGS += -j .text.0 -j .text.1
+#endif
diff --git a/arch/arm/cpu/pxa/timer.c b/arch/arm/cpu/pxa/timer.c
index 78d9f32745..c4717de6a9 100644
--- a/arch/arm/cpu/pxa/timer.c
+++ b/arch/arm/cpu/pxa/timer.c
@@ -28,12 +28,12 @@ DECLARE_GLOBAL_DATA_PTR;
static unsigned long long tick_to_time(unsigned long long tick)
{
- return tick * CONFIG_SYS_HZ / TIMER_FREQ_HZ;
+ return lldiv(tick * CONFIG_SYS_HZ, TIMER_FREQ_HZ);
}
static unsigned long long us_to_tick(unsigned long long us)
{
- return (us * TIMER_FREQ_HZ) / 1000000;
+ return lldiv(us * TIMER_FREQ_HZ, 1000000);
}
int timer_init(void)
diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds
index 9463a33dcb..4da5d246e0 100644
--- a/arch/arm/cpu/u-boot.lds
+++ b/arch/arm/cpu/u-boot.lds
@@ -92,8 +92,6 @@ SECTIONS
}
.dynsym _end : { *(.dynsym) }
- .hash : { *(.hash) }
- .got.plt : { *(.got.plt) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
@@ -101,4 +99,5 @@ SECTIONS
.interp : { *(.interp*) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
+ .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
}
diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi
new file mode 100644
index 0000000000..f20b8bd604
--- /dev/null
+++ b/arch/arm/dts/zynq-7000.dtsi
@@ -0,0 +1,13 @@
+/*
+ * Xilinx Zynq 7000 DTSI
+ * Describes the hardware common to all Zynq 7000-based boards.
+ *
+ * Copyright (C) 2013 Xilinx, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "xlnx,zynq-7000";
+};
diff --git a/arch/arm/include/asm/arch-rmobile/r8a7790.h b/arch/arm/include/asm/arch-rmobile/r8a7790.h
index 42d65d356d..d9ea71fa14 100644
--- a/arch/arm/include/asm/arch-rmobile/r8a7790.h
+++ b/arch/arm/include/asm/arch-rmobile/r8a7790.h
@@ -19,6 +19,7 @@
#define DBSC3_1_BASE 0xE67A0000
#define TMU_BASE 0xE61E0000
#define GPIO5_BASE 0xE6055000
+#define SH_QSPI_BASE 0xE6B10000
#define S3C_BASE 0xE6784000
#define S3C_INT_BASE 0xE6784A00
diff --git a/arch/arm/include/asm/arch-rmobile/r8a7791.h b/arch/arm/include/asm/arch-rmobile/r8a7791.h
index 2afda0a62f..ff30180591 100644
--- a/arch/arm/include/asm/arch-rmobile/r8a7791.h
+++ b/arch/arm/include/asm/arch-rmobile/r8a7791.h
@@ -19,6 +19,7 @@
#define DBSC3_1_BASE 0xE67A0000
#define TMU_BASE 0xE61E0000
#define GPIO5_BASE 0xE6055000
+#define SH_QSPI_BASE 0xE6B10000
#define S3C_BASE 0xE6784000
#define S3C_INT_BASE 0xE6784A00
diff --git a/arch/arm/include/asm/arch-socfpga/dwmmc.h b/arch/arm/include/asm/arch-socfpga/dwmmc.h
new file mode 100644
index 0000000000..945eb646ce
--- /dev/null
+++ b/arch/arm/include/asm/arch-socfpga/dwmmc.h
@@ -0,0 +1,12 @@
+/*
+ * (C) Copyright 2013 Altera Corporation <www.altera.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _SOCFPGA_DWMMC_H_
+#define _SOCFPGA_DWMMC_H_
+
+extern int socfpga_dwmmc_init(u32 regbase, int bus_width, int index);
+
+#endif /* _SOCFPGA_SDMMC_H_ */
diff --git a/arch/arm/include/asm/arch-socfpga/system_manager.h b/arch/arm/include/asm/arch-socfpga/system_manager.h
index d965d25eff..838d21053e 100644
--- a/arch/arm/include/asm/arch-socfpga/system_manager.h
+++ b/arch/arm/include/asm/arch-socfpga/system_manager.h
@@ -19,4 +19,69 @@ extern unsigned long sys_mgr_init_table[CONFIG_HPS_PINMUX_NUM];
#define CONFIG_SYSMGR_PINMUXGRP_OFFSET (0x400)
+#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \
+ ((((drvsel) << 0) & 0x7) | (((smplsel) << 3) & 0x38))
+
+struct socfpga_system_manager {
+ u32 siliconid1;
+ u32 siliconid2;
+ u32 _pad_0x8_0xf[2];
+ u32 wddbg;
+ u32 bootinfo;
+ u32 hpsinfo;
+ u32 parityinj;
+ u32 fpgaintfgrp_gbl;
+ u32 fpgaintfgrp_indiv;
+ u32 fpgaintfgrp_module;
+ u32 _pad_0x2c_0x2f;
+ u32 scanmgrgrp_ctrl;
+ u32 _pad_0x34_0x3f[3];
+ u32 frzctrl_vioctrl;
+ u32 _pad_0x44_0x4f[3];
+ u32 frzctrl_hioctrl;
+ u32 frzctrl_src;
+ u32 frzctrl_hwctrl;
+ u32 _pad_0x5c_0x5f;
+ u32 emacgrp_ctrl;
+ u32 emacgrp_l3master;
+ u32 _pad_0x68_0x6f[2];
+ u32 dmagrp_ctrl;
+ u32 dmagrp_persecurity;
+ u32 _pad_0x78_0x7f[2];
+ u32 iswgrp_handoff[8];
+ u32 _pad_0xa0_0xbf[8];
+ u32 romcodegrp_ctrl;
+ u32 romcodegrp_cpu1startaddr;
+ u32 romcodegrp_initswstate;
+ u32 romcodegrp_initswlastld;
+ u32 romcodegrp_bootromswstate;
+ u32 __pad_0xd4_0xdf[3];
+ u32 romcodegrp_warmramgrp_enable;
+ u32 romcodegrp_warmramgrp_datastart;
+ u32 romcodegrp_warmramgrp_length;
+ u32 romcodegrp_warmramgrp_execution;
+ u32 romcodegrp_warmramgrp_crc;
+ u32 __pad_0xf4_0xff[3];
+ u32 romhwgrp_ctrl;
+ u32 _pad_0x104_0x107;
+ u32 sdmmcgrp_ctrl;
+ u32 sdmmcgrp_l3master;
+ u32 nandgrp_bootstrap;
+ u32 nandgrp_l3master;
+ u32 usbgrp_l3master;
+ u32 _pad_0x11c_0x13f[9];
+ u32 eccgrp_l2;
+ u32 eccgrp_ocram;
+ u32 eccgrp_usb0;
+ u32 eccgrp_usb1;
+ u32 eccgrp_emac0;
+ u32 eccgrp_emac1;
+ u32 eccgrp_dma;
+ u32 eccgrp_can0;
+ u32 eccgrp_can1;
+ u32 eccgrp_nand;
+ u32 eccgrp_qspi;
+ u32 eccgrp_sdmmc;
+};
+
#endif /* _SYSTEM_MANAGER_H_ */
diff --git a/arch/arm/include/asm/arch-zynq/gpio.h b/arch/arm/include/asm/arch-zynq/gpio.h
new file mode 100644
index 0000000000..2dbba756d7
--- /dev/null
+++ b/arch/arm/include/asm/arch-zynq/gpio.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013 Xilinx, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ZYNQ_GPIO_H
+#define _ZYNQ_GPIO_H
+
+inline int gpio_get_value(unsigned gpio)
+{
+ return 0;
+}
+
+inline int gpio_set_value(unsigned gpio, int val)
+{
+ return 0;
+}
+
+inline int gpio_request(unsigned gpio, const char *label)
+{
+ return 0;
+}
+
+#endif /* _ZYNQ_GPIO_H */
diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h
index 110de90922..8f925af8a4 100644
--- a/arch/arm/include/asm/arch-zynq/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynq/sys_proto.h
@@ -13,6 +13,7 @@ extern void zynq_slcr_cpu_reset(void);
extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk);
extern void zynq_slcr_devcfg_disable(void);
extern void zynq_slcr_devcfg_enable(void);
+extern u32 zynq_slcr_get_boot_mode(void);
extern u32 zynq_slcr_get_idcode(void);
extern void zynq_ddrc_init(void);
diff --git a/arch/arm/include/asm/armv8/mmu.h b/arch/arm/include/asm/armv8/mmu.h
new file mode 100644
index 0000000000..1193e76a82
--- /dev/null
+++ b/arch/arm/include/asm/armv8/mmu.h
@@ -0,0 +1,111 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_ARMV8_MMU_H_
+#define _ASM_ARMV8_MMU_H_
+
+#ifdef __ASSEMBLY__
+#define _AC(X, Y) X
+#else
+#define _AC(X, Y) (X##Y)
+#endif
+
+#define UL(x) _AC(x, UL)
+
+/***************************************************************/
+/*
+ * The following definitions are related each other, shoud be
+ * calculated specifically.
+ */
+#define VA_BITS (42) /* 42 bits virtual address */
+
+/* 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 (UL(1) << SECTION_SHIFT)
+#define SECTION_MASK (~(SECTION_SIZE-1))
+/***************************************************************/
+
+/*
+ * Memory types
+ */
+#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 MEMORY_ATTRIBUTES ((0x00 << (MT_DEVICE_NGNRNE*8)) | \
+ (0x04 << (MT_DEVICE_NGNRE*8)) | \
+ (0x0c << (MT_DEVICE_GRE*8)) | \
+ (0x44 << (MT_NORMAL_NC*8)) | \
+ (UL(0xff) << (MT_NORMAL*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 (3 << 8)
+#define PMD_SECT_AF (1 << 10)
+#define PMD_SECT_NG (1 << 11)
+#define PMD_SECT_PXN (UL(1) << 53)
+#define PMD_SECT_UXN (UL(1) << 54)
+
+/*
+ * AttrIndx[2:0]
+ */
+#define PMD_ATTRINDX(t) ((t) << 2)
+#define PMD_ATTRINDX_MASK (7 << 2)
+
+/*
+ * TCR 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_NON (0 << 12)
+#define TCR_SHARED_OUTER (1 << 12)
+#define TCR_SHARED_INNER (2 << 12)
+#define TCR_TG0_4K (0 << 14)
+#define TCR_TG0_64K (1 << 14)
+#define TCR_TG0_16K (2 << 14)
+#define TCR_EL1_IPS_BITS (UL(3) << 32) /* 42 bits physical address */
+#define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */
+#define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */
+
+/* PTWs cacheable, inner/outer WBWA and non-shareable */
+#define TCR_FLAGS (TCR_TG0_64K | \
+ TCR_SHARED_NON | \
+ TCR_ORGN_WBWA | \
+ TCR_IRGN_WBWA | \
+ TCR_T0SZ(VA_BITS))
+
+#endif /* _ASM_ARMV8_MMU_H_ */
diff --git a/arch/arm/include/asm/byteorder.h b/arch/arm/include/asm/byteorder.h
index c3489f1e1f..20cce7657e 100644
--- a/arch/arm/include/asm/byteorder.h
+++ b/arch/arm/include/asm/byteorder.h
@@ -23,7 +23,7 @@
# define __SWAB_64_THRU_32__
#endif
-#ifdef __ARMEB__
+#if defined(__ARMEB__) || defined(__AARCH64EB__)
#include <linux/byteorder/big_endian.h>
#else
#include <linux/byteorder/little_endian.h>
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index 6d60a4a6d9..ddebbc8fcd 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -11,6 +11,8 @@
#include <asm/system.h>
+#ifndef CONFIG_ARM64
+
/*
* Invalidate L2 Cache using co-proc instruction
*/
@@ -28,6 +30,9 @@ void l2_cache_disable(void);
void set_section_dcache(int section, enum dcache_option option);
void dram_bank_mmu_setup(int bank);
+
+#endif
+
/*
* 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
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h
index 99b703e1e4..abf79e5c9e 100644
--- a/arch/arm/include/asm/config.h
+++ b/arch/arm/include/asm/config.h
@@ -9,4 +9,10 @@
#define CONFIG_LMB
#define CONFIG_SYS_BOOT_RAMDISK_HIGH
+
+#ifdef CONFIG_ARM64
+#define CONFIG_PHYS_64BIT
+#define CONFIG_STATIC_RELA
+#endif
+
#endif
diff --git a/arch/arm/include/asm/gic.h b/arch/arm/include/asm/gic.h
index a0891cc09c..ac2b2bfbed 100644
--- a/arch/arm/include/asm/gic.h
+++ b/arch/arm/include/asm/gic.h
@@ -1,19 +1,54 @@
-#ifndef __GIC_V2_H__
-#define __GIC_V2_H__
+#ifndef __GIC_H__
+#define __GIC_H__
-/* register offsets for the ARM generic interrupt controller (GIC) */
+/* Register offsets for the ARM generic interrupt controller (GIC) */
#define GIC_DIST_OFFSET 0x1000
+#define GIC_CPU_OFFSET_A9 0x0100
+#define GIC_CPU_OFFSET_A15 0x2000
+
+/* Distributor Registers */
#define GICD_CTLR 0x0000
#define GICD_TYPER 0x0004
+#define GICD_IIDR 0x0008
+#define GICD_STATUSR 0x0010
+#define GICD_SETSPI_NSR 0x0040
+#define GICD_CLRSPI_NSR 0x0048
+#define GICD_SETSPI_SR 0x0050
+#define GICD_CLRSPI_SR 0x0058
+#define GICD_SEIR 0x0068
#define GICD_IGROUPRn 0x0080
-#define GICD_SGIR 0x0F00
+#define GICD_ISENABLERn 0x0100
+#define GICD_ICENABLERn 0x0180
+#define GICD_ISPENDRn 0x0200
+#define GICD_ICPENDRn 0x0280
+#define GICD_ISACTIVERn 0x0300
+#define GICD_ICACTIVERn 0x0380
+#define GICD_IPRIORITYRn 0x0400
+#define GICD_ITARGETSRn 0x0800
+#define GICD_ICFGR 0x0c00
+#define GICD_IGROUPMODRn 0x0d00
+#define GICD_NSACRn 0x0e00
+#define GICD_SGIR 0x0f00
+#define GICD_CPENDSGIRn 0x0f10
+#define GICD_SPENDSGIRn 0x0f20
+#define GICD_IROUTERn 0x6000
-#define GIC_CPU_OFFSET_A9 0x0100
-#define GIC_CPU_OFFSET_A15 0x2000
+/* Cpu Interface Memory Mapped Registers */
#define GICC_CTLR 0x0000
#define GICC_PMR 0x0004
+#define GICC_BPR 0x0008
#define GICC_IAR 0x000C
#define GICC_EOIR 0x0010
+#define GICC_RPR 0x0014
+#define GICC_HPPIR 0x0018
+#define GICC_ABPR 0x001c
+#define GICC_AIAR 0x0020
+#define GICC_AEOIR 0x0024
+#define GICC_AHPPIR 0x0028
+#define GICC_APRn 0x00d0
+#define GICC_NSAPRn 0x00e0
+#define GICC_IIDR 0x00fc
+#define GICC_DIR 0x1000
-#endif
+#endif /* __GIC_H__ */
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index e126436093..60e872637f 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -47,6 +47,10 @@ struct arch_global_data {
#include <asm-generic/global_data.h>
-#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9")
+#ifdef CONFIG_ARM64
+#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("x18")
+#else
+#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r9")
+#endif
#endif /* __ASM_GBL_DATA_H */
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 1fbc531a08..6a1f05ac3e 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -75,42 +75,45 @@ static inline phys_addr_t virt_to_phys(void * vaddr)
#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 int addr, const void *data, int bytelen)
+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 int addr, const void *data, int wordlen)
+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 int addr, const void *data, int longlen)
+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 int addr, void *data, int bytelen)
+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 int addr, void *data, int wordlen)
+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 int addr, void *data, int longlen)
+extern inline void __raw_readsl(unsigned long addr, void *data, int longlen)
{
uint32_t *buf = (uint32_t *)data;
while(longlen--)
diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h
index ff13f36ba0..f77e4b880e 100644
--- a/arch/arm/include/asm/macro.h
+++ b/arch/arm/include/asm/macro.h
@@ -54,5 +54,58 @@
bcs 1b
.endm
+#ifdef CONFIG_ARM64
+/*
+ * Register aliases.
+ */
+lr .req x30
+
+/*
+ * Branch according to exception level
+ */
+.macro switch_el, xreg, el3_label, el2_label, el1_label
+ mrs \xreg, CurrentEL
+ cmp \xreg, 0xc
+ b.eq \el3_label
+ cmp \xreg, 0x8
+ b.eq \el2_label
+ cmp \xreg, 0x4
+ b.eq \el1_label
+.endm
+
+/*
+ * Branch if current processor is a slave,
+ * choose processor with all zero affinity value as the master.
+ */
+.macro branch_if_slave, xreg, slave_label
+ mrs \xreg, mpidr_el1
+ tst \xreg, #0xff /* Test Affinity 0 */
+ b.ne \slave_label
+ lsr \xreg, \xreg, #8
+ tst \xreg, #0xff /* Test Affinity 1 */
+ b.ne \slave_label
+ lsr \xreg, \xreg, #8
+ tst \xreg, #0xff /* Test Affinity 2 */
+ b.ne \slave_label
+ lsr \xreg, \xreg, #16
+ tst \xreg, #0xff /* Test Affinity 3 */
+ b.ne \slave_label
+.endm
+
+/*
+ * Branch if current processor is a master,
+ * choose processor with all zero affinity value as the master.
+ */
+.macro branch_if_master, xreg1, xreg2, master_label
+ mrs \xreg1, mpidr_el1
+ lsr \xreg2, \xreg1, #32
+ lsl \xreg1, \xreg1, #40
+ lsr \xreg1, \xreg1, #40
+ orr \xreg1, \xreg1, \xreg2
+ cbz \xreg1, \master_label
+.endm
+
+#endif /* CONFIG_ARM64 */
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_ARM_MACRO_H__ */
diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/asm/posix_types.h
index c412486db5..d254b95b2a 100644
--- a/arch/arm/include/asm/posix_types.h
+++ b/arch/arm/include/asm/posix_types.h
@@ -28,9 +28,17 @@ typedef int __kernel_pid_t;
typedef unsigned short __kernel_ipc_pid_t;
typedef unsigned short __kernel_uid_t;
typedef unsigned short __kernel_gid_t;
+
+#ifdef __aarch64__
+typedef unsigned long __kernel_size_t;
+typedef long __kernel_ssize_t;
+typedef long __kernel_ptrdiff_t;
+#else
typedef unsigned int __kernel_size_t;
typedef int __kernel_ssize_t;
typedef int __kernel_ptrdiff_t;
+#endif
+
typedef long __kernel_time_t;
typedef long __kernel_suseconds_t;
typedef long __kernel_clock_t;
diff --git a/arch/arm/include/asm/proc-armv/ptrace.h b/arch/arm/include/asm/proc-armv/ptrace.h
index a060ee67e3..21aef58b7b 100644
--- a/arch/arm/include/asm/proc-armv/ptrace.h
+++ b/arch/arm/include/asm/proc-armv/ptrace.h
@@ -10,6 +10,25 @@
#ifndef __ASM_PROC_PTRACE_H
#define __ASM_PROC_PTRACE_H
+#ifdef CONFIG_ARM64
+
+#define PCMASK 0
+
+#ifndef __ASSEMBLY__
+
+/*
+ * This struct defines the way the registers are stored
+ * on the stack during an exception.
+ */
+struct pt_regs {
+ unsigned long elr;
+ unsigned long regs[31];
+};
+
+#endif /* __ASSEMBLY__ */
+
+#else /* CONFIG_ARM64 */
+
#define USR26_MODE 0x00
#define FIQ26_MODE 0x01
#define IRQ26_MODE 0x02
@@ -104,4 +123,6 @@ static inline int valid_user_regs(struct pt_regs *regs)
#endif /* __ASSEMBLY__ */
+#endif /* CONFIG_ARM64 */
+
#endif
diff --git a/arch/arm/include/asm/proc-armv/system.h b/arch/arm/include/asm/proc-armv/system.h
index cda8976b6a..693d1f4921 100644
--- a/arch/arm/include/asm/proc-armv/system.h
+++ b/arch/arm/include/asm/proc-armv/system.h
@@ -13,6 +13,60 @@
/*
* Save the current interrupt enable state & disable IRQs
*/
+#ifdef CONFIG_ARM64
+
+/*
+ * 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"); \
+ })
+
+#else /* CONFIG_ARM64 */
+
#define local_irq_save(x) \
({ \
unsigned long temp; \
@@ -107,7 +161,10 @@
: "r" (x) \
: "memory")
-#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
+#endif /* CONFIG_ARM64 */
+
+#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) || \
+ defined(CONFIG_ARM64)
/*
* On the StrongARM, "swp" is terminally broken since it bypasses the
* cache totally. This means that the cache becomes inconsistent, and,
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 760345f847..4178f8cf7e 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -1,6 +1,86 @@
#ifndef __ASM_ARM_SYSTEM_H
#define __ASM_ARM_SYSTEM_H
+#ifdef CONFIG_ARM64
+
+/*
+ * SCTLR_EL1/SCTLR_EL2/SCTLR_EL3 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 */
+
+#define PGTABLE_SIZE (0x10000)
+
+#ifndef __ASSEMBLY__
+
+#define isb() \
+ ({asm volatile( \
+ "isb" : : : "memory"); \
+ })
+
+#define wfi() \
+ ({asm volatile( \
+ "wfi" : : : "memory"); \
+ })
+
+static inline unsigned int current_el(void)
+{
+ unsigned int el;
+ asm volatile("mrs %0, CurrentEL" : "=r" (el) : : "cc");
+ return el >> 2;
+}
+
+static inline unsigned int get_sctlr(void)
+{
+ unsigned int el, val;
+
+ el = current_el();
+ if (el == 1)
+ asm volatile("mrs %0, sctlr_el1" : "=r" (val) : : "cc");
+ else if (el == 2)
+ asm volatile("mrs %0, sctlr_el2" : "=r" (val) : : "cc");
+ else
+ asm volatile("mrs %0, sctlr_el3" : "=r" (val) : : "cc");
+
+ return val;
+}
+
+static inline void set_sctlr(unsigned int val)
+{
+ unsigned int el;
+
+ el = current_el();
+ if (el == 1)
+ asm volatile("msr sctlr_el1, %0" : : "r" (val) : "cc");
+ else if (el == 2)
+ asm volatile("msr sctlr_el2, %0" : : "r" (val) : "cc");
+ else
+ asm volatile("msr sctlr_el3, %0" : : "r" (val) : "cc");
+
+ asm volatile("isb");
+}
+
+void __asm_flush_dcache_all(void);
+void __asm_flush_dcache_range(u64 start, u64 end);
+void __asm_invalidate_tlb_all(void);
+void __asm_invalidate_icache_all(void);
+
+void armv8_switch_to_el2(void);
+void armv8_switch_to_el1(void);
+void gic_init(void);
+void gic_send_sgi(unsigned long sgino);
+void wait_for_wakeup(void);
+void smp_kick_all_cpus(void);
+
+#endif /* __ASSEMBLY__ */
+
+#else /* CONFIG_ARM64 */
+
#ifdef __KERNEL__
#define CPU_ARCH_UNKNOWN 0
@@ -45,6 +125,8 @@
#define CR_AFE (1 << 29) /* Access flag enable */
#define CR_TE (1 << 30) /* Thumb exception enable */
+#define PGTABLE_SIZE (4096 * 4)
+
/*
* This is used to ensure the compiler did actually allocate the register we
* asked it for some inline assembly sequences. Apparently we can't trust
@@ -132,4 +214,6 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop);
#endif /* __KERNEL__ */
+#endif /* CONFIG_ARM64 */
+
#endif
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h
index 71dc049da6..2326420a7f 100644
--- a/arch/arm/include/asm/types.h
+++ b/arch/arm/include/asm/types.h
@@ -39,7 +39,11 @@ typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
+#ifdef CONFIG_ARM64
+#define BITS_PER_LONG 64
+#else /* CONFIG_ARM64 */
#define BITS_PER_LONG 32
+#endif /* CONFIG_ARM64 */
/* Dma addresses are 32-bits wide. */
diff --git a/arch/arm/include/asm/u-boot.h b/arch/arm/include/asm/u-boot.h
index 2b5fce86ab..cb81232b83 100644
--- a/arch/arm/include/asm/u-boot.h
+++ b/arch/arm/include/asm/u-boot.h
@@ -44,6 +44,10 @@ typedef struct bd_info {
#endif /* !CONFIG_SYS_GENERIC_BOARD */
/* For image.h:image_check_target_arch() */
+#ifndef CONFIG_ARM64
#define IH_ARCH_DEFAULT IH_ARCH_ARM
+#else
+#define IH_ARCH_DEFAULT IH_ARCH_ARM64
+#endif
#endif /* _U_BOOT_H_ */
diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h
index 44593a8949..0a228fb8ee 100644
--- a/arch/arm/include/asm/unaligned.h
+++ b/arch/arm/include/asm/unaligned.h
@@ -8,7 +8,7 @@
/*
* Select endianness
*/
-#ifndef __ARMEB__
+#if __BYTE_ORDER == __LITTLE_ENDIAN
#define get_unaligned __get_unaligned_le
#define put_unaligned __put_unaligned_le
#else
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 679f19a233..321997c332 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -17,14 +17,22 @@ lib-y += _umodsi3.o
lib-y += div0.o
endif
-obj-y += crt0.o
+ifdef CONFIG_ARM64
+obj-y += crt0_64.o
+else
+obj-y += crt0.o
+endif
ifndef CONFIG_SPL_BUILD
-obj-y += relocate.o
+ifdef CONFIG_ARM64
+obj-y += relocate_64.o
+else
+obj-y += relocate.o
+endif
ifndef CONFIG_SYS_GENERIC_BOARD
obj-y += board.o
endif
-obj-y += sections.o
+obj-y += sections.o
obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
@@ -35,11 +43,17 @@ else
obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
endif
+ifdef CONFIG_ARM64
+obj-y += interrupts_64.o
+else
obj-y += interrupts.o
+endif
obj-y += reset.o
obj-y += cache.o
+ifndef CONFIG_ARM64
obj-y += cache-cp15.o
+endif
# For EABI conformant tool chains, provide eabi_compat()
ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS)))
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 9c72a5353f..b770e25d87 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -344,7 +344,7 @@ void board_init_f(ulong bootflag)
#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
/* reserve TLB table */
- gd->arch.tlb_size = 4096 * 4;
+ gd->arch.tlb_size = PGTABLE_SIZE;
addr -= gd->arch.tlb_size;
/* round down to next 64 kB limit */
@@ -419,6 +419,7 @@ void board_init_f(ulong bootflag)
}
#endif
+#ifndef CONFIG_ARM64
/* setup stackpointer for exeptions */
gd->irq_sp = addr_sp;
#ifdef CONFIG_USE_IRQ
@@ -431,6 +432,10 @@ void board_init_f(ulong bootflag)
/* 8-byte alignment for ABI compliance */
addr_sp &= ~0x07;
+#else /* CONFIG_ARM64 */
+ /* 16-byte alignment for ABI compliance */
+ addr_sp &= ~0x0f;
+#endif /* CONFIG_ARM64 */
#else
addr_sp += 128; /* leave 32 words for abort-stack */
gd->irq_sp = addr_sp;
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index f476a89702..a8295bf1f1 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -196,6 +196,14 @@ static void do_nonsec_virt_switch(void)
debug("entered non-secure state\n");
#endif
#endif
+
+#ifdef CONFIG_ARM64
+ smp_kick_all_cpus();
+ armv8_switch_to_el2();
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+ armv8_switch_to_el1();
+#endif
+#endif
}
/* Subcommand: PREP */
@@ -240,6 +248,21 @@ static void boot_prep_linux(bootm_headers_t *images)
/* Subcommand: GO */
static void boot_jump_linux(bootm_headers_t *images, int flag)
{
+#ifdef CONFIG_ARM64
+ 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);
+#else
unsigned long machid = gd->bd->bi_arch_number;
char *s;
void (*kernel_entry)(int zero, int arch, uint params);
@@ -266,6 +289,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
if (!fake)
kernel_entry(0, machid, r2);
+#endif
}
/* Main Entry point for arm bootm implementation
@@ -326,3 +350,26 @@ int bootz_setup(ulong image, ulong *start, ulong *end)
}
#endif /* CONFIG_CMD_BOOTZ */
+
+#if defined(CONFIG_BOOTM_VXWORKS)
+void boot_prep_vxworks(bootm_headers_t *images)
+{
+#if defined(CONFIG_OF_LIBFDT)
+ int off;
+
+ if (images->ft_addr) {
+ off = fdt_path_offset(images->ft_addr, "/memory");
+ if (off < 0) {
+ if (arch_fixup_memory_node(images->ft_addr))
+ puts("## WARNING: fixup memory failed!\n");
+ }
+ }
+#endif
+ cleanup_before_linux();
+}
+void boot_jump_vxworks(bootm_headers_t *images)
+{
+ /* ARM VxWorks requires device tree physical address to be passed */
+ ((void (*)(void *))images->ep)(images->ft_addr);
+}
+#endif
diff --git a/arch/arm/lib/crt0.S b/arch/arm/lib/crt0.S
index ac54b9359a..dfc2de9a61 100644
--- a/arch/arm/lib/crt0.S
+++ b/arch/arm/lib/crt0.S
@@ -67,7 +67,7 @@ ENTRY(_main)
ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
#endif
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
- sub sp, #GD_SIZE /* allocate one GD above SP */
+ sub sp, sp, #GD_SIZE /* allocate one GD above SP */
bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
mov r9, sp /* GD is above SP */
mov r0, #0
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
new file mode 100644
index 0000000000..77563967e5
--- /dev/null
+++ b/arch/arm/lib/crt0_64.S
@@ -0,0 +1,113 @@
+/*
+ * crt0 - C-runtime startup Code for AArch64 U-Boot
+ *
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * (C) Copyright 2012
+ * Albert ARIBAUD <albert.u.boot@aribaud.net>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <asm-offsets.h>
+#include <asm/macro.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] /* x9 <- 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 /* still call old routine */
+
+/*
+ * Clear BSS section
+ */
+ ldr x0, =__bss_start /* this is auto-relocated! */
+ ldr x1, =__bss_end /* this is auto-relocated! */
+ 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/arm/lib/interrupts_64.c b/arch/arm/lib/interrupts_64.c
new file mode 100644
index 0000000000..b476722556
--- /dev/null
+++ b/arch/arm/lib/interrupts_64.c
@@ -0,0 +1,120 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/compiler.h>
+
+
+int interrupt_init(void)
+{
+ return 0;
+}
+
+void enable_interrupts(void)
+{
+ return;
+}
+
+int disable_interrupts(void)
+{
+ return 0;
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ int i;
+
+ printf("ELR: %lx\n", regs->elr);
+ printf("LR: %lx\n", regs->regs[30]);
+ for (i = 0; i < 29; i += 2)
+ printf("x%-2d: %016lx x%-2d: %016lx\n",
+ i, regs->regs[i], i+1, regs->regs[i+1]);
+ printf("\n");
+}
+
+/*
+ * do_bad_sync handles the impossible case in the Synchronous Abort vector.
+ */
+void do_bad_sync(struct pt_regs *pt_regs, unsigned int esr)
+{
+ printf("Bad mode in \"Synchronous Abort\" handler, esr 0x%08x\n", esr);
+ show_regs(pt_regs);
+ panic("Resetting CPU ...\n");
+}
+
+/*
+ * do_bad_irq handles the impossible case in the Irq vector.
+ */
+void do_bad_irq(struct pt_regs *pt_regs, unsigned int esr)
+{
+ printf("Bad mode in \"Irq\" handler, esr 0x%08x\n", esr);
+ show_regs(pt_regs);
+ panic("Resetting CPU ...\n");
+}
+
+/*
+ * do_bad_fiq handles the impossible case in the Fiq vector.
+ */
+void do_bad_fiq(struct pt_regs *pt_regs, unsigned int esr)
+{
+ printf("Bad mode in \"Fiq\" handler, esr 0x%08x\n", esr);
+ show_regs(pt_regs);
+ panic("Resetting CPU ...\n");
+}
+
+/*
+ * do_bad_error handles the impossible case in the Error vector.
+ */
+void do_bad_error(struct pt_regs *pt_regs, unsigned int esr)
+{
+ printf("Bad mode in \"Error\" handler, esr 0x%08x\n", esr);
+ show_regs(pt_regs);
+ panic("Resetting CPU ...\n");
+}
+
+/*
+ * do_sync handles the Synchronous Abort exception.
+ */
+void do_sync(struct pt_regs *pt_regs, unsigned int esr)
+{
+ printf("\"Synchronous Abort\" handler, esr 0x%08x\n", esr);
+ show_regs(pt_regs);
+ panic("Resetting CPU ...\n");
+}
+
+/*
+ * do_irq handles the Irq exception.
+ */
+void do_irq(struct pt_regs *pt_regs, unsigned int esr)
+{
+ printf("\"Irq\" handler, esr 0x%08x\n", esr);
+ show_regs(pt_regs);
+ panic("Resetting CPU ...\n");
+}
+
+/*
+ * do_fiq handles the Fiq exception.
+ */
+void do_fiq(struct pt_regs *pt_regs, unsigned int esr)
+{
+ printf("\"Fiq\" handler, esr 0x%08x\n", esr);
+ show_regs(pt_regs);
+ panic("Resetting CPU ...\n");
+}
+
+/*
+ * do_error handles the Error exception.
+ * Errors are more likely to be processor specific,
+ * it is defined with weak attribute and can be redefined
+ * in processor specific code.
+ */
+void __weak do_error(struct pt_regs *pt_regs, unsigned int esr)
+{
+ printf("\"Error\" handler, esr 0x%08x\n", esr);
+ show_regs(pt_regs);
+ panic("Resetting CPU ...\n");
+}
diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S
new file mode 100644
index 0000000000..7fba9e2780
--- /dev/null
+++ b/arch/arm/lib/relocate_64.S
@@ -0,0 +1,58 @@
+/*
+ * relocate - common relocation function for AArch64 U-Boot
+ *
+ * (C) Copyright 2013
+ * Albert ARIBAUD <albert.u.boot@aribaud.net>
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+/*
+ * void relocate_code (addr_moni)
+ *
+ * This function relocates the monitor code.
+ * x0 holds the destination address.
+ */
+ENTRY(relocate_code)
+ /*
+ * Copy u-boot from flash to RAM
+ */
+ ldr x1, =__image_copy_start /* x1 <- SRC &__image_copy_start */
+ subs x9, x0, x1 /* x9 <- relocation offset */
+ b.eq relocate_done /* skip relocation */
+ ldr x2, =__image_copy_end /* x2 <- SRC &__image_copy_end */
+
+copy_loop:
+ ldp x10, x11, [x1], #16 /* copy from source address [x1] */
+ stp x10, x11, [x0], #16 /* copy to target address [x0] */
+ cmp x1, x2 /* until source end address [x2] */
+ b.lo copy_loop
+
+ /*
+ * Fix .rela.dyn relocations
+ */
+ ldr x2, =__rel_dyn_start /* x2 <- SRC &__rel_dyn_start */
+ ldr x3, =__rel_dyn_end /* x3 <- SRC &__rel_dyn_end */
+fixloop:
+ ldp x0, x1, [x2], #16 /* (x0,x1) <- (SRC location, fixup) */
+ ldr x4, [x2], #8 /* x4 <- addend */
+ and x1, x1, #0xffffffff
+ cmp x1, #1027 /* relative fixup? */
+ bne fixnext
+
+ /* relative fix: store addend plus offset at dest location */
+ add x0, x0, x9
+ add x4, x4, x9
+ str x4, [x0]
+fixnext:
+ cmp x2, x3
+ b.lo fixloop
+
+relocate_done:
+ ret
+ENDPROC(relocate_code)
diff --git a/arch/blackfin/config.mk b/arch/blackfin/config.mk
index 35f871662d..73fa79855f 100644
--- a/arch/blackfin/config.mk
+++ b/arch/blackfin/config.mk
@@ -14,9 +14,9 @@ CONFIG_BFIN_CPU := \
$(shell awk '$$2 == "CONFIG_BFIN_CPU" { print $$3 }' \
$(src)include/configs/$(BOARD).h)
else
-CONFIG_BFIN_CPU := $(strip $(subst ",,$(CONFIG_BFIN_CPU)))
+CONFIG_BFIN_CPU := $(strip $(CONFIG_BFIN_CPU:"%"=%))
endif
-CONFIG_BFIN_BOOT_MODE := $(strip $(subst ",,$(CONFIG_BFIN_BOOT_MODE)))
+CONFIG_BFIN_BOOT_MODE := $(strip $(CONFIG_BFIN_BOOT_MODE:"%"=%))
PLATFORM_RELFLAGS += -ffixed-P3 -fomit-frame-pointer -mno-fdpic
PLATFORM_CPPFLAGS += -DCONFIG_BLACKFIN
diff --git a/arch/blackfin/cpu/initcode.c b/arch/blackfin/cpu/initcode.c
index ffaf1017d7..2e640afc45 100644
--- a/arch/blackfin/cpu/initcode.c
+++ b/arch/blackfin/cpu/initcode.c
@@ -18,8 +18,6 @@
#include <asm/mach-common/bits/core.h>
#include <asm/serial.h>
-#define BUG() while (1) asm volatile("emuexcpt;");
-
#ifndef __ADSPBF60x__
#include <asm/mach-common/bits/ebiu.h>
#include <asm/mach-common/bits/pll.h>
@@ -147,8 +145,6 @@ static struct ddr_config ddr_config_table[] = {
__attribute__((always_inline))
static inline void serial_init(void)
{
- uint32_t uart_base = UART_BASE;
-
#if defined(__ADSPBF54x__) || defined(__ADSPBF60x__)
# ifdef BFIN_BOOT_UART_USE_RTS
# define BFIN_UART_USE_RTS 1
@@ -156,6 +152,7 @@ static inline void serial_init(void)
# define BFIN_UART_USE_RTS 0
# endif
if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
+ uint32_t uart_base = UART_BASE;
size_t i;
/* force RTS rather than relying on auto RTS */
@@ -195,8 +192,8 @@ static inline void serial_init(void)
#if CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS
if (BFIN_DEBUG_EARLY_SERIAL) {
- serial_early_init(uart_base);
- serial_early_set_baud(uart_base, CONFIG_BAUDRATE);
+ serial_early_init(UART_BASE);
+ serial_early_set_baud(UART_BASE, CONFIG_BAUDRATE);
}
#endif
}
@@ -547,7 +544,7 @@ maybe_self_refresh(ADI_BOOT_DATA *bs)
__attribute__((always_inline)) static inline u16
program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs)
{
- u16 vr_ctl;
+ u16 vr_ctl = 0;
serial_putc('a');
@@ -731,6 +728,8 @@ update_serial_clocks(ADI_BOOT_DATA *bs, uint sdivB, uint divB, uint vcoB)
serial_putc('a');
+ if (BFIN_DEBUG_EARLY_SERIAL ||
+ CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
#ifdef __ADSPBF60x__
sdivR = bfin_read_CGU_DIV();
sdivR = ((sdivR >> 8) & 0x1f) * ((sdivR >> 5) & 0x7);
@@ -744,6 +743,8 @@ update_serial_clocks(ADI_BOOT_DATA *bs, uint sdivB, uint divB, uint vcoB)
divisor = vcoB * sdivR;
quotient = early_division(dividend, divisor);
serial_early_put_div(quotient - ANOMALY_05000230);
+ }
+
serial_putc('c');
}
@@ -913,7 +914,8 @@ check_hibernation(ADI_BOOT_DATA *bs, u16 vr_ctl, bool put_into_srfs)
continue;
serial_putc('z');
- uint32_t *hibernate_magic = bfin_read32(DPM0_RESTORE4);
+ uint32_t *hibernate_magic =
+ (uint32_t *)bfin_read32(DPM0_RESTORE4);
SSYNC(); /* make sure memory controller is done */
if (hibernate_magic[0] == 0xDEADBEEF) {
serial_putc('c');
diff --git a/arch/blackfin/include/asm/blackfin_local.h b/arch/blackfin/include/asm/blackfin_local.h
index 8ea8cde691..4d6eeab0ec 100644
--- a/arch/blackfin/include/asm/blackfin_local.h
+++ b/arch/blackfin/include/asm/blackfin_local.h
@@ -81,6 +81,8 @@ extern void blackfin_dcache_flush_invalidate_range(const void *, const void *);
# define NOP_PAD_ANOMALY_05000198
#endif
+#define BFIN_BUG() while (1) asm volatile("emuexcpt;");
+
#define _bfin_readX(addr, size, asm_size, asm_ext) ({ \
u32 __v; \
__asm__ __volatile__( \
@@ -111,7 +113,7 @@ extern void blackfin_dcache_flush_invalidate_range(const void *, const void *);
sizeof(*(addr)) == 1 ? bfin_read8(addr) : \
sizeof(*(addr)) == 2 ? bfin_read16(addr) : \
sizeof(*(addr)) == 4 ? bfin_read32(addr) : \
- ({ BUG(); 0; }); \
+ ({ BFIN_BUG(); 0; }); \
})
#define bfin_write(addr, val) \
do { \
@@ -119,7 +121,8 @@ do { \
case 1: bfin_write8(addr, val); break; \
case 2: bfin_write16(addr, val); break; \
case 4: bfin_write32(addr, val); break; \
- default: BUG(); \
+ default: \
+ BFIN_BUG(); \
} \
} while (0)
diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
index 17d1f468dd..392d72d232 100644
--- a/arch/blackfin/lib/board.c
+++ b/arch/blackfin/lib/board.c
@@ -19,6 +19,7 @@
#include <net.h>
#include <status_led.h>
#include <version.h>
+#include <watchdog.h>
#include <asm/cplb.h>
#include <asm/mach-common/bits/mpu.h>
diff --git a/arch/blackfin/lib/clocks.c b/arch/blackfin/lib/clocks.c
index 97795e11ac..7ed56a7274 100644
--- a/arch/blackfin/lib/clocks.c
+++ b/arch/blackfin/lib/clocks.c
@@ -36,7 +36,10 @@ u_long get_vco(void)
u_long get_cclk(void)
{
static u_long cached_cclk_pll_div, cached_cclk;
- u_long div, csel, ssel;
+ u_long div, csel;
+#ifndef CGU_DIV
+ u_long ssel;
+#endif
if (pll_is_bypassed())
return CONFIG_CLKIN_HZ;
diff --git a/arch/powerpc/config.mk b/arch/powerpc/config.mk
index e6bb935729..f75c3bf187 100644
--- a/arch/powerpc/config.mk
+++ b/arch/powerpc/config.mk
@@ -9,8 +9,9 @@ CROSS_COMPILE ?= ppc_8xx-
CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000
LDFLAGS_FINAL += --gc-sections
-PLATFORM_RELFLAGS += -fpic -mrelocatable -ffunction-sections -fdata-sections
-PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__
+PLATFORM_RELFLAGS += -fpic -mrelocatable -ffunction-sections -fdata-sections \
+ -meabi
+PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__ -ffixed-r2
PLATFORM_LDFLAGS += -n
# Support generic board on PPC
diff --git a/arch/powerpc/cpu/74xx_7xx/config.mk b/arch/powerpc/cpu/74xx_7xx/config.mk
index 9053191602..96812a02d8 100644
--- a/arch/powerpc/cpu/74xx_7xx/config.mk
+++ b/arch/powerpc/cpu/74xx_7xx/config.mk
@@ -5,6 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-
-PLATFORM_CPPFLAGS += -DCONFIG_74xx_7xx -ffixed-r2 -mstring
+PLATFORM_CPPFLAGS += -DCONFIG_74xx_7xx -mstring
diff --git a/arch/powerpc/cpu/Makefile b/arch/powerpc/cpu/Makefile
index d630abe1da..88b5298be0 100644
--- a/arch/powerpc/cpu/Makefile
+++ b/arch/powerpc/cpu/Makefile
@@ -1,3 +1,3 @@
-ifneq ($(filter mpc83xx mpc85xx mpc86xx,$(CPU)),)
-obj-y += mpc8xxx/
-endif
+obj-$(CONFIG_MPC83xx) += mpc8xxx/
+obj-$(CONFIG_MPC85xx) += mpc8xxx/
+obj-$(CONFIG_MPC86xx) += mpc8xxx/
diff --git a/arch/powerpc/cpu/mpc512x/config.mk b/arch/powerpc/cpu/mpc512x/config.mk
index 04717a485e..03759e6625 100644
--- a/arch/powerpc/cpu/mpc512x/config.mk
+++ b/arch/powerpc/cpu/mpc512x/config.mk
@@ -4,7 +4,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-
-PLATFORM_CPPFLAGS += -DCONFIG_MPC512X -DCONFIG_E300 \
- -ffixed-r2 -msoft-float -mcpu=603e
+PLATFORM_CPPFLAGS += -DCONFIG_MPC512X -DCONFIG_E300 -msoft-float -mcpu=603e
diff --git a/arch/powerpc/cpu/mpc5xx/config.mk b/arch/powerpc/cpu/mpc5xx/config.mk
index b33f17a1ba..31e2dc9873 100644
--- a/arch/powerpc/cpu/mpc5xx/config.mk
+++ b/arch/powerpc/cpu/mpc5xx/config.mk
@@ -5,6 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-
-PLATFORM_CPPFLAGS += -DCONFIG_5xx -ffixed-r2 -mpowerpc -msoft-float
+PLATFORM_CPPFLAGS += -DCONFIG_5xx -mpowerpc -msoft-float
diff --git a/arch/powerpc/cpu/mpc5xxx/config.mk b/arch/powerpc/cpu/mpc5xxx/config.mk
index 57bdd2d252..3384f6ffcc 100644
--- a/arch/powerpc/cpu/mpc5xxx/config.mk
+++ b/arch/powerpc/cpu/mpc5xxx/config.mk
@@ -5,7 +5,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-
-PLATFORM_CPPFLAGS += -DCONFIG_MPC5xxx -ffixed-r2 \
+PLATFORM_CPPFLAGS += -DCONFIG_MPC5xxx \
-mstring -mcpu=603e -mmultiple
diff --git a/arch/powerpc/cpu/mpc824x/config.mk b/arch/powerpc/cpu/mpc824x/config.mk
index ef605f0797..a224bc8e73 100644
--- a/arch/powerpc/cpu/mpc824x/config.mk
+++ b/arch/powerpc/cpu/mpc824x/config.mk
@@ -5,6 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-
-PLATFORM_CPPFLAGS += -DCONFIG_MPC824X -ffixed-r2 -mstring -mcpu=603e -msoft-float
+PLATFORM_CPPFLAGS += -DCONFIG_MPC824X -mstring -mcpu=603e -msoft-float
diff --git a/arch/powerpc/cpu/mpc8260/config.mk b/arch/powerpc/cpu/mpc8260/config.mk
index 91b0497ccb..dfac710e63 100644
--- a/arch/powerpc/cpu/mpc8260/config.mk
+++ b/arch/powerpc/cpu/mpc8260/config.mk
@@ -5,7 +5,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-
-PLATFORM_CPPFLAGS += -DCONFIG_8260 -DCONFIG_CPM2 -ffixed-r2 \
+PLATFORM_CPPFLAGS += -DCONFIG_8260 -DCONFIG_CPM2 \
-mstring -mcpu=603e -mmultiple
diff --git a/arch/powerpc/cpu/mpc83xx/config.mk b/arch/powerpc/cpu/mpc83xx/config.mk
index c16a00376f..dfce4d53b4 100644
--- a/arch/powerpc/cpu/mpc83xx/config.mk
+++ b/arch/powerpc/cpu/mpc83xx/config.mk
@@ -4,7 +4,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-
-PLATFORM_CPPFLAGS += -DCONFIG_MPC83xx -DCONFIG_E300 \
- -ffixed-r2 -msoft-float
+PLATFORM_CPPFLAGS += -DCONFIG_MPC83xx -DCONFIG_E300 -msoft-float
diff --git a/arch/powerpc/cpu/mpc85xx/config.mk b/arch/powerpc/cpu/mpc85xx/config.mk
index 9eef539e5e..72c964cd15 100644
--- a/arch/powerpc/cpu/mpc85xx/config.mk
+++ b/arch/powerpc/cpu/mpc85xx/config.mk
@@ -5,13 +5,10 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-
-PLATFORM_CPPFLAGS += -ffixed-r2 -Wa,-me500 -msoft-float -mno-string
+PLATFORM_CPPFLAGS += -Wa,-me500 -msoft-float -mno-string
# -mspe=yes is needed to have -mno-spe accepted by a buggy GCC;
# see "[PATCH,rs6000] make -mno-spe work as expected" on
# http://gcc.gnu.org/ml/gcc-patches/2008-04/msg00311.html
-PF_CPPFLAGS_SPE := $(call cc-option,-mspe=yes) \
+PLATFORM_CPPFLAGS += $(call cc-option,-mspe=yes) \
$(call cc-option,-mno-spe)
-PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_SPE)
diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c
index 46ae80c4d8..35867dffdd 100644
--- a/arch/powerpc/cpu/mpc85xx/speed.c
+++ b/arch/powerpc/cpu/mpc85xx/speed.c
@@ -74,12 +74,33 @@ void get_sys_info(sys_info_t *sys_info)
uint ratio[CONFIG_SYS_FSL_NUM_CC_PLLS];
unsigned long sysclk = CONFIG_SYS_CLK_FREQ;
uint mem_pll_rat;
+#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
+ uint single_src;
+#endif
sys_info->freq_systembus = sysclk;
+#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
+ /*
+ * DDR_REFCLK_SEL rcw bit is used to determine if DDR PLLS
+ * are driven by separate DDR Refclock or single source
+ * differential clock.
+ */
+ single_src = (in_be32(&gur->rcwsr[5]) >>
+ FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_SHIFT) &
+ FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_MASK;
+ /*
+ * For single source clocking, both ddrclock and syclock
+ * are driven by differential sysclock.
+ */
+ if (single_src == FSL_CORENET2_RCWSR5_DDR_REFCLK_SINGLE_CLK) {
+ printf("Single Source Clock Configuration\n");
+ sys_info->freq_ddrbus = CONFIG_SYS_CLK_FREQ;
+ } else
+#endif
#ifdef CONFIG_DDR_CLK_FREQ
- sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
+ sys_info->freq_ddrbus = CONFIG_DDR_CLK_FREQ;
#else
- sys_info->freq_ddrbus = sysclk;
+ sys_info->freq_ddrbus = sysclk;
#endif
sys_info->freq_systembus *= (in_be32(&gur->rcwsr[0]) >> 25) & 0x1f;
@@ -229,6 +250,9 @@ void get_sys_info(sys_info_t *sys_info)
case 4:
sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK + 1] / 4;
break;
+ case 5:
+ sys_info->freq_fman[1] = sys_info->freq_systembus;
+ break;
case 6:
sys_info->freq_fman[1] = freq_c_pll[CONFIG_SYS_FM2_CLK] / 2;
break;
diff --git a/arch/powerpc/cpu/mpc86xx/config.mk b/arch/powerpc/cpu/mpc86xx/config.mk
index 5dbf6a8472..69a0b96ead 100644
--- a/arch/powerpc/cpu/mpc86xx/config.mk
+++ b/arch/powerpc/cpu/mpc86xx/config.mk
@@ -5,7 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-
-PLATFORM_CPPFLAGS += -ffixed-r2 -mstring
-PLATFORM_CPPFLAGS += -maltivec -mabi=altivec -msoft-float
+PLATFORM_CPPFLAGS += -mstring -maltivec -mabi=altivec -msoft-float
diff --git a/arch/powerpc/cpu/mpc8xx/config.mk b/arch/powerpc/cpu/mpc8xx/config.mk
index c04e7338c8..ee2c883665 100644
--- a/arch/powerpc/cpu/mpc8xx/config.mk
+++ b/arch/powerpc/cpu/mpc8xx/config.mk
@@ -5,6 +5,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-
-PLATFORM_CPPFLAGS += -DCONFIG_8xx -ffixed-r2 -mstring -mcpu=860 -msoft-float
+PLATFORM_CPPFLAGS += -DCONFIG_8xx -mstring -mcpu=860 -msoft-float
diff --git a/arch/powerpc/cpu/mpc8xxx/Makefile b/arch/powerpc/cpu/mpc8xxx/Makefile
index f66ee2e423..e95539e0a3 100644
--- a/arch/powerpc/cpu/mpc8xxx/Makefile
+++ b/arch/powerpc/cpu/mpc8xxx/Makefile
@@ -19,10 +19,8 @@ ifdef MINIMAL
obj-$(CONFIG_FSL_LAW) += law.o
else
-
-ifneq ($(CPU),mpc83xx)
-obj-y += cpu.o
-endif
+obj-$(CONFIG_MPC85xx) += cpu.o
+obj-$(CONFIG_MPC86xx) += cpu.o
obj-$(CONFIG_OF_LIBFDT) += fdt.o
obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
diff --git a/arch/powerpc/cpu/ppc4xx/config.mk b/arch/powerpc/cpu/ppc4xx/config.mk
index c2b0f9aab6..71c2a6c729 100644
--- a/arch/powerpc/cpu/ppc4xx/config.mk
+++ b/arch/powerpc/cpu/ppc4xx/config.mk
@@ -5,8 +5,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
-PLATFORM_RELFLAGS += -meabi
-PLATFORM_CPPFLAGS += -DCONFIG_4xx -ffixed-r2 -mstring -msoft-float
+PLATFORM_CPPFLAGS += -DCONFIG_4xx -mstring -msoft-float
cfg=$(shell grep configs $(OBJTREE)/include/config.h | sed 's/.*<\(configs.*\)>/\1/')
is440:=$(shell grep CONFIG_440 $(TOPDIR)/include/$(cfg))
diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h
index 99e16bdf63..54ce2f053c 100644
--- a/arch/powerpc/include/asm/config_mpc85xx.h
+++ b/arch/powerpc/include/asm/config_mpc85xx.h
@@ -711,7 +711,8 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
#define CONFIG_FM_PLAT_CLK_DIV 1
#define CONFIG_SYS_FM1_CLK CONFIG_FM_PLAT_CLK_DIV
#define CONFIG_SYS_FM_MURAM_SIZE 0x30000
-#define CONFIG_SYS_FSL_TBCLK_DIV 32
+#define CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
+#define CONFIG_SYS_FSL_TBCLK_DIV 16
#define CONFIG_SYS_FSL_PCIE_COMPAT "fsl,qoriq-pcie-v2.4"
#define CONFIG_SYS_FSL_USB1_PHY_ENABLE
#define CONFIG_SYS_FSL_USB2_PHY_ENABLE
@@ -745,7 +746,7 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
#define CONFIG_SYS_NUM_FM1_DTSEC 6
#define CONFIG_SYS_NUM_FM1_10GEC 2
#endif
-#define CONFIG_SYS_FSL_NUM_USB_CTRLS 2
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_NUM_DDR_CONTROLLERS 1
#define CONFIG_PME_PLAT_CLK_DIV 1
#define CONFIG_SYS_PME_CLK CONFIG_PME_PLAT_CLK_DIV
diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h
index 672e8c6650..68c3c82453 100644
--- a/arch/powerpc/include/asm/immap_85xx.h
+++ b/arch/powerpc/include/asm/immap_85xx.h
@@ -1774,6 +1774,9 @@ defined(CONFIG_PPC_T1020) || defined(CONFIG_PPC_T1022)
#define FSL_CORENET2_RCWSR5_SRDS_PLL_PD_S3_PLL2 0x00040000
#define FSL_CORENET2_RCWSR5_SRDS_PLL_PD_S4_PLL1 0x00020000
#define FSL_CORENET2_RCWSR5_SRDS_PLL_PD_S4_PLL2 0x00010000
+#define FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_SHIFT 4
+#define FSL_CORENET2_RCWSR5_DDR_REFCLK_SEL_MASK 0x00000011
+#define FSL_CORENET2_RCWSR5_DDR_REFCLK_SINGLE_CLK 1
#else /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
#define FSL_CORENET_RCWSR0_MEM_PLL_RAT_SHIFT 17
diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c
index e7153b0480..41fc8f7ff7 100644
--- a/arch/powerpc/lib/bootm.c
+++ b/arch/powerpc/lib/bootm.c
@@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR;
extern ulong get_effective_memsize(void);
static ulong get_sp (void);
+extern void ft_fixup_num_cores(void *blob);
static void set_clocks_in_mhz (bd_t *kbd);
#ifndef CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE
@@ -277,3 +278,58 @@ static void set_clocks_in_mhz (bd_t *kbd)
#endif /* CONFIG_MPC5xxx */
}
}
+
+#if defined(CONFIG_BOOTM_VXWORKS)
+void boot_prep_vxworks(bootm_headers_t *images)
+{
+#if defined(CONFIG_OF_LIBFDT)
+ int off;
+ u64 base, size;
+
+ if (!images->ft_addr)
+ return;
+
+ base = (u64)gd->bd->bi_memstart;
+ size = (u64)gd->bd->bi_memsize;
+
+ off = fdt_path_offset(images->ft_addr, "/memory");
+ if (off < 0)
+ fdt_fixup_memory(images->ft_addr, base, size);
+
+#if defined(CONFIG_MP)
+#if defined(CONFIG_MPC85xx)
+ ft_fixup_cpu(images->ft_addr, base + size);
+ ft_fixup_num_cores(images->ft_addr);
+#elif defined(CONFIG_MPC86xx)
+ off = fdt_add_mem_rsv(images->ft_addr,
+ determine_mp_bootpg(NULL), (u64)4096);
+ if (off < 0)
+ printf("## WARNING %s: %s\n", __func__, fdt_strerror(off));
+ ft_fixup_num_cores(images->ft_addr);
+#endif
+ flush_cache((unsigned long)images->ft_addr, images->ft_len);
+#endif
+#endif
+}
+
+void boot_jump_vxworks(bootm_headers_t *images)
+{
+ /* PowerPC VxWorks boot interface conforms to the ePAPR standard
+ * general purpuse registers:
+ *
+ * r3: Effective address of the device tree image
+ * r4: 0
+ * r5: 0
+ * r6: ePAPR magic value
+ * r7: shall be the size of the boot IMA in bytes
+ * r8: 0
+ * r9: 0
+ * TCR: WRC = 0, no watchdog timer reset will occur
+ */
+ WATCHDOG_RESET();
+
+ ((void (*)(void *, ulong, ulong, ulong,
+ ulong, ulong, ulong))images->ep)(images->ft_addr,
+ 0, 0, EPAPR_MAGIC, getenv_bootm_mapsize(), 0, 0);
+}
+#endif
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index cfc1fda1e1..38019e0b48 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -5,13 +5,23 @@
#include <common.h>
#include <os.h>
+#include <asm/state.h>
DECLARE_GLOBAL_DATA_PTR;
-int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+void reset_cpu(ulong ignored)
{
+ if (state_uninit())
+ os_exit(2);
+
/* This is considered normal termination for now */
os_exit(0);
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ reset_cpu(0);
+
return 0;
}
@@ -28,7 +38,14 @@ unsigned long __attribute__((no_instrument_function)) timer_get_us(void)
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
- return -1;
+ if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+ printf("## Transferring control to Linux (at address %08lx)...\n",
+ images->ep);
+ reset_cpu(0);
+ }
+
+ return 0;
}
int cleanup_before_linux(void)
diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c
index 26f44cb597..725b505177 100644
--- a/arch/sandbox/cpu/os.c
+++ b/arch/sandbox/cpu/os.c
@@ -27,6 +27,10 @@
/* Operating System Interface */
+struct os_mem_hdr {
+ size_t length; /* number of bytes in the block */
+};
+
ssize_t os_read(int fd, void *buf, size_t count)
{
return read(fd, buf, count);
@@ -128,8 +132,45 @@ void os_tty_raw(int fd)
void *os_malloc(size_t length)
{
- return mmap(NULL, length, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ struct os_mem_hdr *hdr;
+
+ hdr = mmap(NULL, length + sizeof(*hdr), PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (hdr == MAP_FAILED)
+ return NULL;
+ hdr->length = length;
+
+ return hdr + 1;
+}
+
+void *os_free(void *ptr)
+{
+ struct os_mem_hdr *hdr = ptr;
+
+ hdr--;
+ if (ptr)
+ munmap(hdr, hdr->length + sizeof(*hdr));
+}
+
+void *os_realloc(void *ptr, size_t length)
+{
+ struct os_mem_hdr *hdr = ptr;
+ void *buf = NULL;
+
+ hdr--;
+ if (length != 0) {
+ buf = os_malloc(length);
+ if (!buf)
+ return buf;
+ if (ptr) {
+ if (length > hdr->length)
+ length = hdr->length;
+ memcpy(buf, ptr, length);
+ }
+ }
+ os_free(ptr);
+
+ return buf;
}
void os_usleep(unsigned long usec)
@@ -347,3 +388,53 @@ ssize_t os_get_filesize(const char *fname)
return ret;
return buf.st_size;
}
+
+void os_putc(int ch)
+{
+ putchar(ch);
+}
+
+void os_puts(const char *str)
+{
+ while (*str)
+ os_putc(*str++);
+}
+
+int os_write_ram_buf(const char *fname)
+{
+ struct sandbox_state *state = state_get_current();
+ int fd, ret;
+
+ fd = open(fname, O_CREAT | O_WRONLY, 0777);
+ if (fd < 0)
+ return -ENOENT;
+ ret = write(fd, state->ram_buf, state->ram_size);
+ close(fd);
+ if (ret != state->ram_size)
+ return -EIO;
+
+ return 0;
+}
+
+int os_read_ram_buf(const char *fname)
+{
+ struct sandbox_state *state = state_get_current();
+ int fd, ret;
+ int size;
+
+ size = os_get_filesize(fname);
+ if (size < 0)
+ return -ENOENT;
+ if (size != state->ram_size)
+ return -ENOSPC;
+ fd = open(fname, O_RDONLY);
+ if (fd < 0)
+ return -ENOENT;
+
+ ret = read(fd, state->ram_buf, state->ram_size);
+ close(fd);
+ if (ret != state->ram_size)
+ return -EIO;
+
+ return 0;
+}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 1b15454784..1df21d49fa 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -4,11 +4,12 @@
*/
#include <common.h>
+#include <os.h>
#include <asm/getopt.h>
#include <asm/sections.h>
#include <asm/state.h>
-#include <os.h>
+DECLARE_GLOBAL_DATA_PTR;
int sandbox_early_getopt_check(void)
{
@@ -50,9 +51,9 @@ int sandbox_early_getopt_check(void)
/* then the long flag */
if (opt->has_arg)
- printf("--%-*s", max_noarg_len, opt->flag);
- else
printf("--%-*s <arg> ", max_arg_len, opt->flag);
+ else
+ printf("--%-*s", max_noarg_len, opt->flag);
/* finally the help text */
printf(" %s\n", opt->help);
@@ -75,7 +76,8 @@ int sandbox_main_loop_init(void)
/* Execute command if required */
if (state->cmd) {
run_command_list(state->cmd, -1, 0);
- os_exit(state->exit_type);
+ if (!state->interactive)
+ os_exit(state->exit_type);
}
return 0;
@@ -96,25 +98,93 @@ static int sandbox_cmdline_cb_fdt(struct sandbox_state *state, const char *arg)
}
SANDBOX_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT");
-int main(int argc, char *argv[])
+static int sandbox_cmdline_cb_interactive(struct sandbox_state *state,
+ const char *arg)
+{
+ state->interactive = true;
+ return 0;
+}
+
+SANDBOX_CMDLINE_OPT_SHORT(interactive, 'i', 0, "Enter interactive mode");
+
+static int sandbox_cmdline_cb_memory(struct sandbox_state *state,
+ const char *arg)
{
- struct sandbox_state *state;
int err;
- err = state_init();
- if (err)
+ /* For now assume we always want to write it */
+ state->write_ram_buf = true;
+ state->ram_buf_fname = arg;
+
+ if (os_read_ram_buf(arg)) {
+ printf("Failed to read RAM buffer\n");
return err;
+ }
+
+ return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(memory, 'm', 1,
+ "Read/write ram_buf memory contents from file");
+
+static int sandbox_cmdline_cb_state(struct sandbox_state *state,
+ const char *arg)
+{
+ state->state_fname = arg;
+ return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(state, 's', 1, "Specify the sandbox state FDT");
+
+static int sandbox_cmdline_cb_read(struct sandbox_state *state,
+ const char *arg)
+{
+ state->read_state = true;
+ return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(read, 'r', 0, "Read the state FDT on startup");
+
+static int sandbox_cmdline_cb_write(struct sandbox_state *state,
+ const char *arg)
+{
+ state->write_state = true;
+ return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(write, 'w', 0, "Write state FDT on exit");
+
+static int sandbox_cmdline_cb_ignore_missing(struct sandbox_state *state,
+ const char *arg)
+{
+ state->ignore_missing_state_on_read = true;
+ return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(ignore_missing, 'n', 0,
+ "Ignore missing state on read");
+
+int main(int argc, char *argv[])
+{
+ struct sandbox_state *state;
+ int ret;
+
+ ret = state_init();
+ if (ret)
+ goto err;
state = state_get_current();
if (os_parse_args(state, argc, argv))
return 1;
- /*
- * Do pre- and post-relocation init, then start up U-Boot. This will
- * never return.
- */
+ ret = sandbox_read_state(state, state->state_fname);
+ if (ret)
+ goto err;
+
+ /* Do pre- and post-relocation init */
board_init_f(0);
- /* NOTREACHED - board_init_f() does not return */
+ board_init_r(gd->new_gd, 0);
+
+ /* NOTREACHED - board_init_r() does not return */
return 0;
+
+err:
+ printf("Error %d\n", ret);
+ return 1;
}
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index 56d5041411..a145808a52 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -4,6 +4,9 @@
*/
#include <common.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <os.h>
#include <asm/state.h>
/* Main state record for the sandbox */
@@ -15,6 +18,324 @@ void state_record_exit(enum exit_type_id exit_type)
state->exit_type = exit_type;
}
+static int state_ensure_space(int extra_size)
+{
+ void *blob = state->state_fdt;
+ int used, size, free;
+ void *buf;
+ int ret;
+
+ used = fdt_off_dt_strings(blob) + fdt_size_dt_strings(blob);
+ size = fdt_totalsize(blob);
+ free = size - used;
+ if (free > extra_size)
+ return 0;
+
+ size = used + extra_size;
+ buf = os_malloc(size);
+ if (!buf)
+ return -ENOMEM;
+
+ ret = fdt_open_into(blob, buf, size);
+ if (ret) {
+ os_free(buf);
+ return -EIO;
+ }
+
+ os_free(blob);
+ state->state_fdt = buf;
+ return 0;
+}
+
+static int state_read_file(struct sandbox_state *state, const char *fname)
+{
+ int size;
+ int ret;
+ int fd;
+
+ size = os_get_filesize(fname);
+ if (size < 0) {
+ printf("Cannot find sandbox state file '%s'\n", fname);
+ return -ENOENT;
+ }
+ state->state_fdt = os_malloc(size);
+ if (!state->state_fdt) {
+ puts("No memory to read sandbox state\n");
+ return -ENOMEM;
+ }
+ fd = os_open(fname, OS_O_RDONLY);
+ if (fd < 0) {
+ printf("Cannot open sandbox state file '%s'\n", fname);
+ ret = -EPERM;
+ goto err_open;
+ }
+ if (os_read(fd, state->state_fdt, size) != size) {
+ printf("Cannot read sandbox state file '%s'\n", fname);
+ ret = -EIO;
+ goto err_read;
+ }
+ os_close(fd);
+
+ return 0;
+err_read:
+ os_close(fd);
+err_open:
+ os_free(state->state_fdt);
+ state->state_fdt = NULL;
+
+ return ret;
+}
+
+/***
+ * sandbox_read_state_nodes() - Read state associated with a driver
+ *
+ * This looks through all compatible nodes and calls the read function on
+ * each one, to read in the state.
+ *
+ * If nothing is found, it still calls the read function once, to set up a
+ * single global state for that driver.
+ *
+ * @state: Sandbox state
+ * @io: Method to use for reading state
+ * @blob: FDT containing state
+ * @return 0 if OK, -EINVAL if the read function returned failure
+ */
+int sandbox_read_state_nodes(struct sandbox_state *state,
+ struct sandbox_state_io *io, const void *blob)
+{
+ int count;
+ int node;
+ int ret;
+
+ debug(" - read %s\n", io->name);
+ if (!io->read)
+ return 0;
+
+ node = -1;
+ count = 0;
+ while (blob) {
+ node = fdt_node_offset_by_compatible(blob, node, io->compat);
+ if (node < 0)
+ return 0; /* No more */
+ debug(" - read node '%s'\n", fdt_get_name(blob, node, NULL));
+ ret = io->read(blob, node);
+ if (ret) {
+ printf("Unable to read state for '%s'\n", io->compat);
+ return -EINVAL;
+ }
+ count++;
+ }
+
+ /*
+ * If we got no saved state, call the read function once without a
+ * node, to set up the global state.
+ */
+ if (count == 0) {
+ debug(" - read global\n");
+ ret = io->read(NULL, -1);
+ if (ret) {
+ printf("Unable to read global state for '%s'\n",
+ io->name);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+int sandbox_read_state(struct sandbox_state *state, const char *fname)
+{
+ struct sandbox_state_io *io;
+ const void *blob;
+ bool got_err;
+ int ret;
+
+ if (state->read_state && fname) {
+ ret = state_read_file(state, fname);
+ if (ret == -ENOENT && state->ignore_missing_state_on_read)
+ ret = 0;
+ if (ret)
+ return ret;
+ }
+
+ /* Call all the state read funtcions */
+ got_err = false;
+ blob = state->state_fdt;
+ io = ll_entry_start(struct sandbox_state_io, state_io);
+ for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) {
+ ret = sandbox_read_state_nodes(state, io, blob);
+ if (ret < 0)
+ got_err = true;
+ }
+
+ if (state->read_state && fname) {
+ debug("Read sandbox state from '%s'%s\n", fname,
+ got_err ? " (with errors)" : "");
+ }
+
+ return got_err ? -1 : 0;
+}
+
+/***
+ * sandbox_write_state_node() - Write state associated with a driver
+ *
+ * This calls the write function to write out global state for that driver.
+ *
+ * TODO(sjg@chromium.org): Support writing out state from multiple drivers
+ * of the same time. We don't need this yet,and it will be much easier to
+ * do when driver model is available.
+ *
+ * @state: Sandbox state
+ * @io: Method to use for writing state
+ * @return 0 if OK, -EIO if there is a fatal error (such as out of space
+ * for adding the data), -EINVAL if the write function failed.
+ */
+int sandbox_write_state_node(struct sandbox_state *state,
+ struct sandbox_state_io *io)
+{
+ void *blob;
+ int node;
+ int ret;
+
+ if (!io->write)
+ return 0;
+
+ ret = state_ensure_space(SANDBOX_STATE_MIN_SPACE);
+ if (ret) {
+ printf("Failed to add more space for state\n");
+ return -EIO;
+ }
+
+ /* The blob location can change when the size increases */
+ blob = state->state_fdt;
+ node = fdt_node_offset_by_compatible(blob, -1, io->compat);
+ if (node == -FDT_ERR_NOTFOUND) {
+ node = fdt_add_subnode(blob, 0, io->name);
+ if (node < 0) {
+ printf("Cannot create node '%s': %s\n", io->name,
+ fdt_strerror(node));
+ return -EIO;
+ }
+
+ if (fdt_setprop_string(blob, node, "compatible", io->compat)) {
+ puts("Cannot set compatible\n");
+ return -EIO;
+ }
+ } else if (node < 0) {
+ printf("Cannot access node '%s': %s\n", io->name,
+ fdt_strerror(node));
+ return -EIO;
+ }
+ debug("Write state for '%s' to node %d\n", io->compat, node);
+ ret = io->write(blob, node);
+ if (ret) {
+ printf("Unable to write state for '%s'\n", io->compat);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int sandbox_write_state(struct sandbox_state *state, const char *fname)
+{
+ struct sandbox_state_io *io;
+ bool got_err;
+ int size;
+ int ret;
+ int fd;
+
+ /* Create a state FDT if we don't have one */
+ if (!state->state_fdt) {
+ size = 0x4000;
+ state->state_fdt = os_malloc(size);
+ if (!state->state_fdt) {
+ puts("No memory to create FDT\n");
+ return -ENOMEM;
+ }
+ ret = fdt_create_empty_tree(state->state_fdt, size);
+ if (ret < 0) {
+ printf("Cannot create empty state FDT: %s\n",
+ fdt_strerror(ret));
+ ret = -EIO;
+ goto err_create;
+ }
+ }
+
+ /* Call all the state write funtcions */
+ got_err = false;
+ io = ll_entry_start(struct sandbox_state_io, state_io);
+ ret = 0;
+ for (; io < ll_entry_end(struct sandbox_state_io, state_io); io++) {
+ ret = sandbox_write_state_node(state, io);
+ if (ret == -EIO)
+ break;
+ else if (ret)
+ got_err = true;
+ }
+
+ if (ret == -EIO) {
+ printf("Could not write sandbox state\n");
+ goto err_create;
+ }
+
+ ret = fdt_pack(state->state_fdt);
+ if (ret < 0) {
+ printf("Cannot pack state FDT: %s\n", fdt_strerror(ret));
+ ret = -EINVAL;
+ goto err_create;
+ }
+ size = fdt_totalsize(state->state_fdt);
+ fd = os_open(fname, OS_O_WRONLY | OS_O_CREAT);
+ if (fd < 0) {
+ printf("Cannot open sandbox state file '%s'\n", fname);
+ ret = -EIO;
+ goto err_create;
+ }
+ if (os_write(fd, state->state_fdt, size) != size) {
+ printf("Cannot write sandbox state file '%s'\n", fname);
+ ret = -EIO;
+ goto err_write;
+ }
+ os_close(fd);
+
+ debug("Wrote sandbox state to '%s'%s\n", fname,
+ got_err ? " (with errors)" : "");
+
+ return 0;
+err_write:
+ os_close(fd);
+err_create:
+ os_free(state->state_fdt);
+
+ return ret;
+}
+
+int state_setprop(int node, const char *prop_name, const void *data, int size)
+{
+ void *blob;
+ int len;
+ int ret;
+
+ fdt_getprop(state->state_fdt, node, prop_name, &len);
+
+ /* Add space for the new property, its name and some overhead */
+ ret = state_ensure_space(size - len + strlen(prop_name) + 32);
+ if (ret)
+ return ret;
+
+ /* This should succeed, barring a mutiny */
+ blob = state->state_fdt;
+ ret = fdt_setprop(blob, node, prop_name, data, size);
+ if (ret) {
+ printf("%s: Unable to set property '%s' in node '%s': %s\n",
+ __func__, prop_name, fdt_get_name(blob, node, NULL),
+ fdt_strerror(ret));
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
struct sandbox_state *state_get_current(void)
{
assert(state);
@@ -25,6 +346,10 @@ int state_init(void)
{
state = &main_state;
+ state->ram_size = CONFIG_SYS_SDRAM_SIZE;
+ state->ram_buf = os_malloc(state->ram_size);
+ assert(state->ram_buf);
+
/*
* Example of how to use GPIOs:
*
@@ -33,3 +358,31 @@ int state_init(void)
*/
return 0;
}
+
+int state_uninit(void)
+{
+ int err;
+
+ state = &main_state;
+
+ if (state->write_ram_buf) {
+ err = os_write_ram_buf(state->ram_buf_fname);
+ if (err) {
+ printf("Failed to write RAM buffer\n");
+ return err;
+ }
+ }
+
+ if (state->write_state) {
+ if (sandbox_write_state(state, state->state_fname)) {
+ printf("Failed to write sandbox state\n");
+ return -1;
+ }
+ }
+
+ if (state->state_fdt)
+ os_free(state->state_fdt);
+ memset(state, '\0', sizeof(*state));
+
+ return 0;
+}
diff --git a/arch/sandbox/include/asm/global_data.h b/arch/sandbox/include/asm/global_data.h
index d70532aa4d..b2e9b488f1 100644
--- a/arch/sandbox/include/asm/global_data.h
+++ b/arch/sandbox/include/asm/global_data.h
@@ -12,7 +12,7 @@
/* Architecture-specific global data */
struct arch_global_data {
- u8 *ram_buf; /* emulated RAM buffer */
+ uint8_t *ram_buf; /* emulated RAM buffer */
};
#include <asm-generic/global_data.h>
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index a38820bdee..e8e4fea1b5 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -7,6 +7,8 @@
#define __SANDBOX_STATE_H
#include <config.h>
+#include <stdbool.h>
+#include <linux/stringify.h>
/* How we exited U-Boot */
enum exit_type_id {
@@ -23,17 +25,92 @@ struct sandbox_spi_info {
/* The complete state of the test system */
struct sandbox_state {
const char *cmd; /* Command to execute */
+ bool interactive; /* Enable cmdline after execute */
const char *fdt_fname; /* Filename of FDT binary */
enum exit_type_id exit_type; /* How we exited U-Boot */
const char *parse_err; /* Error to report from parsing */
int argc; /* Program arguments */
char **argv;
+ uint8_t *ram_buf; /* Emulated RAM buffer */
+ unsigned int ram_size; /* Size of RAM buffer */
+ const char *ram_buf_fname; /* Filename to use for RAM buffer */
+ bool write_ram_buf; /* Write RAM buffer on exit */
+ const char *state_fname; /* File containing sandbox state */
+ void *state_fdt; /* Holds saved state for sandbox */
+ bool read_state; /* Read sandbox state on startup */
+ bool write_state; /* Write sandbox state on exit */
+ bool ignore_missing_state_on_read; /* No error if state missing */
/* Pointer to information for each SPI bus/cs */
struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
[CONFIG_SANDBOX_SPI_MAX_CS];
};
+/* Minimum space we guarantee in the state FDT when calling read/write*/
+#define SANDBOX_STATE_MIN_SPACE 0x1000
+
+/**
+ * struct sandbox_state_io - methods to saved/restore sandbox state
+ * @name: Name of of the device tree node, also the name of the variable
+ * holding this data so it should be an identifier (use underscore
+ * instead of minus)
+ * @compat: Compatible string for the node containing this state
+ *
+ * @read: Function to read state from FDT
+ * If data is available, then blob and node will provide access to it. If
+ * not (blob == NULL and node == -1) this function should set up an empty
+ * data set for start-of-day.
+ * @param blob: Pointer to device tree blob, or NULL if no data to read
+ * @param node: Node offset to read from
+ * @return 0 if OK, -ve on error
+ *
+ * @write: Function to write state to FDT
+ * The caller will ensure that there is a node ready for the state. The
+ * node may already contain the old state, in which case it should be
+ * overridden. There is guaranteed to be SANDBOX_STATE_MIN_SPACE bytes
+ * of free space, so error checking is not required for fdt_setprop...()
+ * calls which add up to less than this much space.
+ *
+ * For adding larger properties, use state_setprop().
+ *
+ * @param blob: Device tree blob holding state
+ * @param node: Node to write our state into
+ *
+ * Note that it is possible to save data as large blobs or as individual
+ * hierarchical properties. However, unless you intend to keep state files
+ * around for a long time and be able to run an old state file on a new
+ * sandbox, it might not be worth using individual properties for everything.
+ * This is certainly supported, it is just a matter of the effort you wish
+ * to put into the state read/write feature.
+ */
+struct sandbox_state_io {
+ const char *name;
+ const char *compat;
+ int (*write)(void *blob, int node);
+ int (*read)(const void *blob, int node);
+};
+
+/**
+ * SANDBOX_STATE_IO - Declare sandbox state to read/write
+ *
+ * Sandbox permits saving state from one run and restoring it in another. This
+ * allows the test system to retain state between runs and thus better
+ * emulate a real system. Examples of state that might be useful to save are
+ * the emulated GPIOs pin settings, flash memory contents and TPM private
+ * data. U-Boot memory contents is dealth with separately since it is large
+ * and it is not normally useful to save it (since a normal system does not
+ * preserve DRAM between runs). See the '-m' option for this.
+ *
+ * See struct sandbox_state_io above for member documentation.
+ */
+#define SANDBOX_STATE_IO(_name, _compat, _read, _write) \
+ ll_entry_declare(struct sandbox_state_io, _name, state_io) = { \
+ .name = __stringify(_name), \
+ .read = _read, \
+ .write = _write, \
+ .compat = _compat, \
+ }
+
/**
* Record the exit type to be reported by the test program.
*
@@ -49,8 +126,59 @@ void state_record_exit(enum exit_type_id exit_type);
struct sandbox_state *state_get_current(void);
/**
+ * Read the sandbox state from the supplied device tree file
+ *
+ * This calls all registered state handlers to read in the sandbox state
+ * from a previous test run.
+ *
+ * @param state Sandbox state to update
+ * @param fname Filename of device tree file to read from
+ * @return 0 if OK, -ve on error
+ */
+int sandbox_read_state(struct sandbox_state *state, const char *fname);
+
+/**
+ * Write the sandbox state to the supplied device tree file
+ *
+ * This calls all registered state handlers to write out the sandbox state
+ * so that it can be preserved for a future test run.
+ *
+ * If the file exists it is overwritten.
+ *
+ * @param state Sandbox state to update
+ * @param fname Filename of device tree file to write to
+ * @return 0 if OK, -ve on error
+ */
+int sandbox_write_state(struct sandbox_state *state, const char *fname);
+
+/**
+ * Add a property to a sandbox state node
+ *
+ * This is equivalent to fdt_setprop except that it automatically enlarges
+ * the device tree if necessary. That means it is safe to write any amount
+ * of data here.
+ *
+ * This function can only be called from within struct sandbox_state_io's
+ * ->write method, i.e. within state I/O drivers.
+ *
+ * @param node Device tree node to write to
+ * @param prop_name Property to write
+ * @param data Data to write into property
+ * @param size Size of data to write into property
+ */
+int state_setprop(int node, const char *prop_name, const void *data, int size);
+
+/**
* Initialize the test system state
*/
int state_init(void);
+/**
+ * Uninitialize the test system state, writing out state if configured to
+ * do so.
+ *
+ * @return 0 if OK, -ve on error
+ */
+int state_uninit(void);
+
#endif
diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h
index bed720cf81..5707c2710d 100644
--- a/arch/sandbox/include/asm/u-boot-sandbox.h
+++ b/arch/sandbox/include/asm/u-boot-sandbox.h
@@ -23,4 +23,6 @@ int dram_init(void);
int sandbox_early_getopt_check(void);
int sandbox_main_loop_init(void);
+int cleanup_before_linux(void);
+
#endif /* _U_BOOT_SANDBOX_H_ */
diff --git a/arch/sh/cpu/sh2/config.mk b/arch/sh/cpu/sh2/config.mk
index 8a0de96714..69273b4f38 100644
--- a/arch/sh/cpu/sh2/config.mk
+++ b/arch/sh/cpu/sh2/config.mk
@@ -12,7 +12,7 @@ PLATFORM_CPPFLAGS += -m2a -m2a-nofpu -mb -ffreestanding
else # SH2
PLATFORM_CPPFLAGS += -m3e -mb
endif
-PLATFORM_CPPFLAGS += $(call cc-option,-mno-fdpic)
+PLATFORM_CPPFLAGS += -DCONFIG_SH2 $(call cc-option,-mno-fdpic)
PLATFORM_RELFLAGS += -ffixed-r13
PLATFORM_LDFLAGS += $(ENDIANNESS)
diff --git a/arch/sh/cpu/sh2/cpu.c b/arch/sh/cpu/sh2/cpu.c
index 18479a4c40..a2f856f459 100644
--- a/arch/sh/cpu/sh2/cpu.c
+++ b/arch/sh/cpu/sh2/cpu.c
@@ -23,11 +23,7 @@
int checkcpu(void)
{
-#if defined(CONFIG_SH2A)
- puts("CPU: SH2A\n");
-#else
puts("CPU: SH2\n");
-#endif
return 0;
}
diff --git a/arch/sh/cpu/sh3/config.mk b/arch/sh/cpu/sh3/config.mk
index 5c77e5c32d..abd4b8d2bd 100644
--- a/arch/sh/cpu/sh3/config.mk
+++ b/arch/sh/cpu/sh3/config.mk
@@ -11,5 +11,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
#
-PLATFORM_CPPFLAGS += -m3
+PLATFORM_CPPFLAGS += -DCONFIG_SH3 -m3
PLATFORM_RELFLAGS += -ffixed-r13
diff --git a/arch/sh/cpu/sh4/config.mk b/arch/sh/cpu/sh4/config.mk
index c3575570e7..753580beb1 100644
--- a/arch/sh/cpu/sh4/config.mk
+++ b/arch/sh/cpu/sh4/config.mk
@@ -8,5 +8,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
#
-PLATFORM_CPPFLAGS += -m4-nofpu
+PLATFORM_CPPFLAGS += -DCONFIG_SH4 -m4-nofpu
PLATFORM_RELFLAGS += -ffixed-r13
diff --git a/arch/sh/cpu/sh4/cpu.c b/arch/sh/cpu/sh4/cpu.c
index 91133a38ae..e8ee0a45ab 100644
--- a/arch/sh/cpu/sh4/cpu.c
+++ b/arch/sh/cpu/sh4/cpu.c
@@ -13,11 +13,7 @@
int checkcpu(void)
{
-#ifdef CONFIG_SH4A
- puts("CPU: SH-4A\n");
-#else
puts("CPU: SH4\n");
-#endif
return 0;
}
diff --git a/arch/sh/include/asm/cache.h b/arch/sh/include/asm/cache.h
index b21dc4422e..0698a37759 100644
--- a/arch/sh/include/asm/cache.h
+++ b/arch/sh/include/asm/cache.h
@@ -1,7 +1,7 @@
#ifndef __ASM_SH_CACHE_H
#define __ASM_SH_CACHE_H
-#if defined(CONFIG_SH4) || defined(CONFIG_SH4A)
+#if defined(CONFIG_SH4)
int cache_control(unsigned int cmd);
@@ -18,7 +18,7 @@ struct __large_struct { unsigned long buf[100]; };
*/
#define ARCH_DMA_MINALIGN 32
-#endif /* CONFIG_SH4 || CONFIG_SH4A */
+#endif /* CONFIG_SH4 */
/*
* Use the L1 data cache line size value for the minimum DMA buffer alignment
diff --git a/arch/sh/include/asm/cpu_sh4.h b/arch/sh/include/asm/cpu_sh4.h
index 9181d59a94..9f48e4fe04 100644
--- a/arch/sh/include/asm/cpu_sh4.h
+++ b/arch/sh/include/asm/cpu_sh4.h
@@ -37,6 +37,8 @@
# include <asm/cpu_sh7734.h>
#elif defined (CONFIG_CPU_SH7752)
# include <asm/cpu_sh7752.h>
+#elif defined (CONFIG_CPU_SH7753)
+# include <asm/cpu_sh7753.h>
#elif defined (CONFIG_CPU_SH7757)
# include <asm/cpu_sh7757.h>
#elif defined (CONFIG_CPU_SH7763)
diff --git a/arch/sh/include/asm/cpu_sh7753.h b/arch/sh/include/asm/cpu_sh7753.h
new file mode 100644
index 0000000000..cd0e0bba6c
--- /dev/null
+++ b/arch/sh/include/asm/cpu_sh7753.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_CPU_SH7753_H_
+#define _ASM_CPU_SH7753_H_
+
+#define CCR 0xFF00001C
+#define WTCNT 0xFFCC0000
+#define CCR_CACHE_INIT 0x0000090b
+#define CACHE_OC_NUM_WAYS 1
+
+#ifndef __ASSEMBLY__ /* put C only stuff in this section */
+/* MMU */
+struct mmu_regs {
+ unsigned int reserved[4];
+ unsigned int mmucr;
+};
+#define MMU_BASE ((struct mmu_regs *)0xff000000)
+
+/* Watchdog */
+#define WTCSR0 0xffcc0002
+#define WRSTCSR_R 0xffcc0003
+#define WRSTCSR_W 0xffcc0002
+#define WTCSR_PREFIX 0xa500
+#define WRSTCSR_PREFIX 0x6900
+#define WRSTCSR_WOVF_PREFIX 0x9600
+
+/* SCIF */
+#define SCIF0_BASE 0xfe4b0000 /* The real name is SCIF2 */
+#define SCIF1_BASE 0xfe4c0000 /* The real name is SCIF3 */
+#define SCIF2_BASE 0xfe4d0000 /* The real name is SCIF4 */
+
+/* TMU0 */
+#define TMU_BASE 0xFE430000
+
+/* ETHER, GETHER MAC address */
+struct ether_mac_regs {
+ unsigned int reserved[114];
+ unsigned int mahr;
+ unsigned int reserved2;
+ unsigned int malr;
+};
+#define GETHER0_MAC_BASE ((struct ether_mac_regs *)0xfee0400)
+#define GETHER1_MAC_BASE ((struct ether_mac_regs *)0xfee0c00)
+#define ETHER0_MAC_BASE ((struct ether_mac_regs *)0xfef0000)
+#define ETHER1_MAC_BASE ((struct ether_mac_regs *)0xfef0800)
+
+/* GETHER */
+struct gether_control_regs {
+ unsigned int gbecont;
+};
+#define GETHER_CONTROL_BASE ((struct gether_control_regs *)0xffc10100)
+#define GBECONT_RMII1 0x00020000
+#define GBECONT_RMII0 0x00010000
+
+/* SerMux */
+struct sermux_regs {
+ unsigned char smr0;
+ unsigned char smr1;
+ unsigned char smr2;
+ unsigned char smr3;
+ unsigned char smr4;
+ unsigned char smr5;
+};
+#define SERMUX_BASE ((struct sermux_regs *)0xfe470000)
+
+
+/* USB0/1 */
+struct usb_common_regs {
+ unsigned short reserved[129];
+ unsigned short suspmode;
+};
+#define USB0_COMMON_BASE ((struct usb_common_regs *)0xfe450000)
+#define USB1_COMMON_BASE ((struct usb_common_regs *)0xfe4f0000)
+
+struct usb0_phy_regs {
+ unsigned short reset;
+ unsigned short reserved[4];
+ unsigned short portsel;
+};
+#define USB0_PHY_BASE ((struct usb0_phy_regs *)0xfe5f0000)
+
+struct usb1_port_regs {
+ unsigned int port1sel;
+ unsigned int reserved;
+ unsigned int usb1intsts;
+};
+#define USB1_PORT_BASE ((struct usb1_port_regs *)0xfe4f2000)
+
+struct usb1_alignment_regs {
+ unsigned int ehcidatac; /* 0xfe4fe018 */
+ unsigned int reserved[63];
+ unsigned int ohcidatac;
+};
+#define USB1_ALIGNMENT_BASE ((struct usb1_alignment_regs *)0xfe4fe018)
+
+/* GPIO */
+struct gpio_regs {
+ unsigned short pacr;
+ unsigned short pbcr;
+ unsigned short pccr;
+ unsigned short pdcr;
+ unsigned short pecr;
+ unsigned short pfcr;
+ unsigned short pgcr;
+ unsigned short phcr;
+ unsigned short picr;
+ unsigned short pjcr;
+ unsigned short pkcr;
+ unsigned short plcr;
+ unsigned short pmcr;
+ unsigned short pncr;
+ unsigned short pocr;
+ unsigned short reserved;
+ unsigned short pqcr;
+ unsigned short prcr;
+ unsigned short pscr;
+ unsigned short ptcr;
+ unsigned short pucr;
+ unsigned short pvcr;
+ unsigned short pwcr;
+ unsigned short pxcr;
+ unsigned short pycr;
+ unsigned short pzcr;
+ unsigned char padr;
+ unsigned char reserved_a;
+ unsigned char pbdr;
+ unsigned char reserved_b;
+ unsigned char pcdr;
+ unsigned char reserved_c;
+ unsigned char pddr;
+ unsigned char reserved_d;
+ unsigned char pedr;
+ unsigned char reserved_e;
+ unsigned char pfdr;
+ unsigned char reserved_f;
+ unsigned char pgdr;
+ unsigned char reserved_g;
+ unsigned char phdr;
+ unsigned char reserved_h;
+ unsigned char pidr;
+ unsigned char reserved_i;
+ unsigned char pjdr;
+ unsigned char reserved_j;
+ unsigned char pkdr;
+ unsigned char reserved_k;
+ unsigned char pldr;
+ unsigned char reserved_l;
+ unsigned char pmdr;
+ unsigned char reserved_m;
+ unsigned char pndr;
+ unsigned char reserved_n;
+ unsigned char podr;
+ unsigned char reserved_o;
+ unsigned char ppdr;
+ unsigned char reserved_p;
+ unsigned char pqdr;
+ unsigned char reserved_q;
+ unsigned char prdr;
+ unsigned char reserved_r;
+ unsigned char psdr;
+ unsigned char reserved_s;
+ unsigned char ptdr;
+ unsigned char reserved_t;
+ unsigned char pudr;
+ unsigned char reserved_u;
+ unsigned char pvdr;
+ unsigned char reserved_v;
+ unsigned char pwdr;
+ unsigned char reserved_w;
+ unsigned char pxdr;
+ unsigned char reserved_x;
+ unsigned char pydr;
+ unsigned char reserved_y;
+ unsigned char pzdr;
+ unsigned char reserved_z;
+ unsigned short ncer;
+ unsigned short ncmcr;
+ unsigned short nccsr;
+ unsigned char reserved2[2];
+ unsigned short psel0; /* +0x70 */
+ unsigned short psel1;
+ unsigned short psel2;
+ unsigned short psel3;
+ unsigned short psel4;
+ unsigned short psel5;
+ unsigned short psel6;
+ unsigned short reserved3[2];
+ unsigned short psel7;
+};
+#define GPIO_BASE ((struct gpio_regs *)0xffec0000)
+
+#endif /* ifndef __ASSEMBLY__ */
+#endif /* _ASM_CPU_SH7753_H_ */
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 938a89cff5..b8677da959 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -1,12 +1,10 @@
#ifndef _ASM_SH_PROCESSOR_H_
#define _ASM_SH_PROCESSOR_H_
-#if defined(CONFIG_SH2) || \
- defined (CONFIG_SH2A)
+#if defined(CONFIG_SH2)
# include <asm/cpu_sh2.h>
-#elif defined (CONFIG_SH3)
+#elif defined(CONFIG_SH3)
# include <asm/cpu_sh3.h>
-#elif defined (CONFIG_SH4) || \
- defined (CONFIG_SH4A)
+#elif defined(CONFIG_SH4)
# include <asm/cpu_sh4.h>
#endif
#endif
diff --git a/arch/sh/lib/time_sh2.c b/arch/sh/lib/time_sh2.c
index be3896c3ed..4b1f47b6ad 100644
--- a/arch/sh/lib/time_sh2.c
+++ b/arch/sh/lib/time_sh2.c
@@ -84,5 +84,5 @@ void __udelay(unsigned long usec)
unsigned long get_tbclk(void)
{
- return CONFIG_SYS_HZ;
+ return CONFIG_SH_CMT_CLK_FREQ;
}
OpenPOWER on IntegriCloud