summaryrefslogtreecommitdiffstats
path: root/arch/arm/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r--arch/arm/cpu/Makefile7
-rw-r--r--arch/arm/cpu/cache-armv7.S3
-rw-r--r--arch/arm/cpu/cpuinfo.c9
-rw-r--r--arch/arm/cpu/dtb.c6
-rw-r--r--arch/arm/cpu/entry.c23
-rw-r--r--arch/arm/cpu/entry.h10
-rw-r--r--arch/arm/cpu/entry_ll.S25
-rw-r--r--arch/arm/cpu/entry_ll_64.S23
-rw-r--r--arch/arm/cpu/mmu-early.c7
-rw-r--r--arch/arm/cpu/mmu.c23
-rw-r--r--arch/arm/cpu/mmu.h1
-rw-r--r--arch/arm/cpu/start-pbl.c109
-rw-r--r--arch/arm/cpu/start.c14
-rw-r--r--arch/arm/cpu/uncompress.c17
14 files changed, 115 insertions, 162 deletions
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index 97e4eb52e3..e0b16747ad 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -8,7 +8,7 @@ obj-pbl-$(CONFIG_CPU_32v7) += hyp.o
AFLAGS_hyp.o :=-Wa,-march=armv7-a -Wa,-mcpu=all
AFLAGS_pbl-hyp.o :=-Wa,-march=armv7-a -Wa,-mcpu=all
-obj-y += start.o entry.o
+obj-y += start.o entry.o entry_ll$(S64).o
pbl-$(CONFIG_BOARD_ARM_GENERIC_DT) += board-dt-2nd.o
pbl-$(CONFIG_BOARD_ARM_GENERIC_DT_AARCH64) += board-dt-2nd-aarch64.o
@@ -47,8 +47,7 @@ AFLAGS_cache-armv8.o :=-Wa,-march=armv8-a
obj-pbl-$(CONFIG_CPU_64v8) += cache-armv8.o
AFLAGS_pbl-cache-armv8.o :=-Wa,-march=armv8-a
-pbl-y += entry.o
-pbl-$(CONFIG_PBL_SINGLE_IMAGE) += start-pbl.o
-pbl-$(CONFIG_PBL_MULTI_IMAGES) += uncompress.o
+pbl-y += entry.o entry_ll$(S64).o
+pbl-y += uncompress.o
obj-pbl-y += common.o sections.o
diff --git a/arch/arm/cpu/cache-armv7.S b/arch/arm/cpu/cache-armv7.S
index 6a8aff8bb1..0f6108426c 100644
--- a/arch/arm/cpu/cache-armv7.S
+++ b/arch/arm/cpu/cache-armv7.S
@@ -7,7 +7,6 @@ ENTRY(v7_mmu_cache_on)
mov r12, lr
#ifdef CONFIG_MMU
mrc p15, 0, r11, c0, c1, 4 @ read ID_MMFR0
- tst r11, #0xf @ VMSA
mov r0, #0
dsb @ drain write buffer
tst r11, #0xf @ VMSA
@@ -21,8 +20,6 @@ ENTRY(v7_mmu_cache_on)
orr r0, r0, #1 << 25 @ big-endian page tables
#endif
orrne r0, r0, #1 @ MMU enabled
- movne r1, #-1
- mcrne p15, 0, r1, c3, c0, 0 @ load domain access control
#endif
isb
mcr p15, 0, r0, c1, c0, 0 @ load control register
diff --git a/arch/arm/cpu/cpuinfo.c b/arch/arm/cpu/cpuinfo.c
index 1ba3b4379c..ff6e1eb87b 100644
--- a/arch/arm/cpu/cpuinfo.c
+++ b/arch/arm/cpu/cpuinfo.c
@@ -76,8 +76,6 @@ static int do_cpuinfo(int argc, char *argv[])
: "=r" (cache)
:
: "memory");
-
- cr = get_cr();
#else
__asm__ __volatile__(
"mrc p15, 0, %0, c0, c0, 0 @ read control reg\n"
@@ -90,13 +88,8 @@ static int do_cpuinfo(int argc, char *argv[])
: "=r" (cache)
:
: "memory");
-
- __asm__ __volatile__(
- "mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
- : "=r" (cr)
- :
- : "memory");
#endif
+ cr = get_cr();
switch (mainid >> 24) {
case 0x41:
diff --git a/arch/arm/cpu/dtb.c b/arch/arm/cpu/dtb.c
index b9390b46e6..1ba5aa415e 100644
--- a/arch/arm/cpu/dtb.c
+++ b/arch/arm/cpu/dtb.c
@@ -36,12 +36,6 @@ static int of_arm_init(void)
if (fdt)
pr_debug("using boarddata provided DTB\n");
- /* Next see if we have a builtin dtb */
- if (!fdt && IS_ENABLED(CONFIG_BUILTIN_DTB)) {
- fdt = __dtb_start;
- pr_debug("using internal DTB\n");
- }
-
if (!fdt) {
pr_debug("No DTB found\n");
return 0;
diff --git a/arch/arm/cpu/entry.c b/arch/arm/cpu/entry.c
index 30df95f078..0b447de801 100644
--- a/arch/arm/cpu/entry.c
+++ b/arch/arm/cpu/entry.c
@@ -24,16 +24,19 @@
* be fine.
*/
+/*
+ * It can be hard to convince GCC to not use old stack pointer after
+ * we modify it with arm_setup_stack() on ARM64, so we implement the
+ * low level details in assembly
+ */
+void __noreturn __barebox_arm_entry(unsigned long membase,
+ unsigned long memsize,
+ void *boarddata,
+ unsigned long sp);
+
void NAKED __noreturn barebox_arm_entry(unsigned long membase,
- unsigned long memsize, void *boarddata)
+ unsigned long memsize, void *boarddata)
{
- arm_setup_stack(arm_mem_stack_top(membase, membase + memsize));
- arm_early_mmu_cache_invalidate();
-
- if (IS_ENABLED(CONFIG_PBL_MULTI_IMAGES))
- barebox_multi_pbl_start(membase, memsize, boarddata);
- else if (IS_ENABLED(CONFIG_PBL_SINGLE_IMAGE))
- barebox_single_pbl_start(membase, memsize, boarddata);
- else
- barebox_non_pbl_start(membase, memsize, boarddata);
+ __barebox_arm_entry(membase, memsize, boarddata,
+ arm_mem_stack_top(membase, membase + memsize));
}
diff --git a/arch/arm/cpu/entry.h b/arch/arm/cpu/entry.h
index f0163a34f7..18110eadf3 100644
--- a/arch/arm/cpu/entry.h
+++ b/arch/arm/cpu/entry.h
@@ -7,12 +7,8 @@ void __noreturn barebox_non_pbl_start(unsigned long membase,
unsigned long memsize,
void *boarddata);
-void __noreturn barebox_multi_pbl_start(unsigned long membase,
- unsigned long memsize,
- void *boarddata);
-
-void __noreturn barebox_single_pbl_start(unsigned long membase,
- unsigned long memsize,
- void *boarddata);
+void __noreturn barebox_pbl_start(unsigned long membase,
+ unsigned long memsize,
+ void *boarddata);
#endif
diff --git a/arch/arm/cpu/entry_ll.S b/arch/arm/cpu/entry_ll.S
new file mode 100644
index 0000000000..8cc7a84f10
--- /dev/null
+++ b/arch/arm/cpu/entry_ll.S
@@ -0,0 +1,25 @@
+#include <linux/linkage.h>
+#include <asm/sections.h>
+
+/*
+ * r0: memory base
+ * r1: memory size
+ * r2: board data
+ * r3: new value for SP
+ */
+.section .text.__barebox_arm_entry
+ENTRY(__barebox_arm_entry)
+ mov sp, r3
+ mov r4, r0
+ mov r5, r1
+ mov r6, r2
+ bl arm_early_mmu_cache_invalidate
+ mov r0, r4
+ mov r1, r5
+ mov r2, r6
+#if IS_ENABLED(CONFIG_PBL_IMAGE)
+ b barebox_pbl_start
+#else
+ b barebox_non_pbl_start
+#endif
+ENDPROC(__barebox_arm_entry)
diff --git a/arch/arm/cpu/entry_ll_64.S b/arch/arm/cpu/entry_ll_64.S
new file mode 100644
index 0000000000..37e0cb66b5
--- /dev/null
+++ b/arch/arm/cpu/entry_ll_64.S
@@ -0,0 +1,23 @@
+#include <linux/linkage.h>
+#include <asm/sections.h>
+
+/*
+ * x0: memory base
+ * x1: memory size
+ * x2: board data
+ * x3: new value for SP
+ */
+.section .text.__barebox_arm_entry
+ENTRY(__barebox_arm_entry)
+ mov sp, x3
+ /*
+ * arm_early_mmu_cache_invalidate is jsut a call to
+ * v8_invalidate_icache_all() which doesn't clobber x0, x1 or x2
+ */
+ bl arm_early_mmu_cache_invalidate
+#if IS_ENABLED(CONFIG_PBL_IMAGE)
+ b barebox_pbl_start
+#else
+ b barebox_non_pbl_start
+#endif
+ENDPROC(__barebox_arm_entry) \ No newline at end of file
diff --git a/arch/arm/cpu/mmu-early.c b/arch/arm/cpu/mmu-early.c
index 2f5876fc46..7c30526b94 100644
--- a/arch/arm/cpu/mmu-early.c
+++ b/arch/arm/cpu/mmu-early.c
@@ -29,7 +29,12 @@ void mmu_early_enable(unsigned long membase, unsigned long memsize,
arm_set_cache_functions();
set_ttbr(ttb);
- set_domain(DOMAIN_MANAGER);
+
+ /* For the XN bit to take effect, we can't be using DOMAIN_MANAGER. */
+ if (cpu_architecture() >= CPU_ARCH_ARMv7)
+ set_domain(DOMAIN_CLIENT);
+ else
+ set_domain(DOMAIN_MANAGER);
/*
* This marks the whole address space as uncachable as well as
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 123e19e9e5..158b130b57 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -56,13 +56,14 @@ static inline void tlb_invalidate(void)
);
}
-#define PTE_FLAGS_CACHED_V7 (PTE_EXT_TEX(1) | PTE_BUFFERABLE | PTE_CACHEABLE)
-#define PTE_FLAGS_WC_V7 (PTE_EXT_TEX(1) | PTE_EXT_XN)
-#define PTE_FLAGS_UNCACHED_V7 PTE_EXT_XN
+#define PTE_FLAGS_CACHED_V7 (PTE_EXT_TEX(1) | PTE_BUFFERABLE | PTE_CACHEABLE | \
+ PTE_EXT_AP_URW_SRW)
+#define PTE_FLAGS_WC_V7 (PTE_EXT_TEX(1) | PTE_EXT_AP_URW_SRW | PTE_EXT_XN)
+#define PTE_FLAGS_UNCACHED_V7 (PTE_EXT_AP_URW_SRW | PTE_EXT_XN)
#define PTE_FLAGS_CACHED_V4 (PTE_SMALL_AP_UNO_SRW | PTE_BUFFERABLE | PTE_CACHEABLE)
#define PTE_FLAGS_UNCACHED_V4 PTE_SMALL_AP_UNO_SRW
-#define PGD_FLAGS_WC_V7 (PMD_SECT_TEX(1) | PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \
- PMD_SECT_XN)
+#define PGD_FLAGS_WC_V7 (PMD_SECT_TEX(1) | PMD_SECT_DEF_UNCACHED | \
+ PMD_SECT_BUFFERABLE | PMD_SECT_XN)
#define PGD_FLAGS_UNCACHED_V7 (PMD_SECT_DEF_UNCACHED | PMD_SECT_XN)
/*
@@ -445,7 +446,12 @@ void __mmu_init(bool mmu_on)
ttb = xmemalign(ARM_TTB_SIZE, ARM_TTB_SIZE);
set_ttbr(ttb);
- set_domain(DOMAIN_MANAGER);
+
+ /* For the XN bit to take effect, we can't be using DOMAIN_MANAGER. */
+ if (cpu_architecture() >= CPU_ARCH_ARMv7)
+ set_domain(DOMAIN_CLIENT);
+ else
+ set_domain(DOMAIN_MANAGER);
create_flat_mapping(ttb);
__mmu_cache_flush();
@@ -455,11 +461,6 @@ void __mmu_init(bool mmu_on)
vectors_init();
- /*
- * First remap sdram cached using sections.
- * This is to speed up the generation of 2nd level page tables
- * below
- */
for_each_memory_bank(bank) {
create_sections(ttb, bank->start, bank->start + bank->size - 1,
PMD_SECT_DEF_CACHED);
diff --git a/arch/arm/cpu/mmu.h b/arch/arm/cpu/mmu.h
index c911ee209f..6e7a4c0350 100644
--- a/arch/arm/cpu/mmu.h
+++ b/arch/arm/cpu/mmu.h
@@ -36,6 +36,7 @@ static inline void set_ttbr(void *ttb)
asm volatile ("mcr p15,0,%0,c2,c0,0" : : "r"(ttb) /*:*/);
}
+#define DOMAIN_CLIENT 1
#define DOMAIN_MANAGER 3
static inline void set_domain(unsigned val)
diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c
deleted file mode 100644
index 796239d902..0000000000
--- a/arch/arm/cpu/start-pbl.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * start-pbl.c
- *
- * Copyright (c) 2010-2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- * Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <common.h>
-#include <init.h>
-#include <linux/sizes.h>
-#include <pbl.h>
-#include <asm/barebox-arm.h>
-#include <asm/barebox-arm-head.h>
-#include <asm-generic/memory_layout.h>
-#include <asm/sections.h>
-#include <asm/secure.h>
-#include <asm/cache.h>
-#include <asm/mmu.h>
-#include <asm/unaligned.h>
-
-#include "entry.h"
-
-unsigned long free_mem_ptr;
-unsigned long free_mem_end_ptr;
-
-void pbl_start(void);
-
-/*
- * First instructions in the pbl image
- */
-void __naked __section(.text_head_entry) pbl_start(void)
-{
- barebox_arm_head();
-}
-
-extern void *input_data;
-extern void *input_data_end;
-
-__noreturn void barebox_single_pbl_start(unsigned long membase,
- unsigned long memsize, void *boarddata)
-{
- unsigned long offset;
- unsigned long pg_start, pg_end, pg_len, uncompressed_len;
- void __noreturn (*barebox)(unsigned long, unsigned long, void *);
- unsigned long endmem = membase + memsize;
- unsigned long barebox_base;
-
- if (IS_ENABLED(CONFIG_PBL_RELOCATABLE))
- relocate_to_current_adr();
-
- /* Get offset between linked address and runtime address */
- offset = get_runtime_offset();
-
- pg_start = (unsigned long)&input_data + global_variable_offset();
- pg_end = (unsigned long)&input_data_end + global_variable_offset();
- pg_len = pg_end - pg_start;
- uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4));
-
- if (IS_ENABLED(CONFIG_RELOCATABLE))
- barebox_base = arm_mem_barebox_image(membase, endmem, uncompressed_len + MAX_BSS_SIZE);
- else
- barebox_base = TEXT_BASE;
-
- if (offset && (IS_ENABLED(CONFIG_PBL_FORCE_PIGGYDATA_COPY) ||
- region_overlap(pg_start, pg_len, barebox_base, pg_len * 4))) {
- /*
- * copy piggydata binary to its link address
- */
- memcpy(&input_data, (void *)pg_start, pg_len);
- pg_start = (uint32_t)&input_data;
- }
-
- setup_c();
-
- if (IS_ENABLED(CONFIG_MMU_EARLY)) {
- unsigned long ttb = arm_mem_ttb(membase, endmem);
- mmu_early_enable(membase, memsize, ttb);
- }
-
- free_mem_ptr = arm_mem_early_malloc(membase, endmem);
- free_mem_end_ptr = arm_mem_early_malloc_end(membase, endmem);
-
- pbl_barebox_uncompress((void*)barebox_base, (void *)pg_start, pg_len);
-
- sync_caches_for_execution();
-
- if (IS_ENABLED(CONFIG_THUMB2_BAREBOX))
- barebox = (void *)(barebox_base + 1);
- else
- barebox = (void *)barebox_base;
-
- if (IS_ENABLED(CONFIG_CPU_V7) && boot_cpu_mode() == HYP_MODE)
- armv7_switch_to_hyp();
-
- barebox(membase, memsize, boarddata);
-}
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index c97b2770c4..44d974e40e 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -193,7 +193,19 @@ __noreturn void barebox_non_pbl_start(unsigned long membase,
uint32_t totalsize = 0;
const char *name;
- if (blob_is_fdt(boarddata)) {
+ if ((unsigned long)boarddata < 8192) {
+ struct barebox_arm_boarddata *bd;
+ uint32_t machine_type = (unsigned long)boarddata;
+ unsigned long mem = arm_mem_boarddata(membase, endmem,
+ sizeof(*bd));
+ pr_debug("found machine type %d in boarddata\n",
+ machine_type);
+ bd = barebox_boarddata = (void *)mem;
+ barebox_boarddata_size = sizeof(*bd);
+ bd->magic = BAREBOX_ARM_BOARDDATA_MAGIC;
+ bd->machine = machine_type;
+ malloc_end = mem;
+ } else if (blob_is_fdt(boarddata)) {
totalsize = get_unaligned_be32(boarddata + 4);
name = "DTB";
} else if (blob_is_compressed_fdt(boarddata)) {
diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
index 4f16af22f8..88d073ebdd 100644
--- a/arch/arm/cpu/uncompress.c
+++ b/arch/arm/cpu/uncompress.c
@@ -36,14 +36,27 @@
#include "entry.h"
+#ifndef CONFIG_HAVE_PBL_MULTI_IMAGES
+
+void start_pbl(void);
+
+/*
+ * First instructions in the pbl image
+ */
+void __naked __section(.text_head_entry_start_single_pbl) start_pbl(void)
+{
+ barebox_arm_head();
+}
+#endif
+
unsigned long free_mem_ptr;
unsigned long free_mem_end_ptr;
extern unsigned char input_data[];
extern unsigned char input_data_end[];
-void __noreturn barebox_multi_pbl_start(unsigned long membase,
- unsigned long memsize, void *boarddata)
+void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
+ void *boarddata)
{
uint32_t pg_len, uncompressed_len;
void __noreturn (*barebox)(unsigned long, unsigned long, void *);