diff options
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r-- | arch/arm/cpu/Makefile | 7 | ||||
-rw-r--r-- | arch/arm/cpu/cache-armv7.S | 3 | ||||
-rw-r--r-- | arch/arm/cpu/cpuinfo.c | 9 | ||||
-rw-r--r-- | arch/arm/cpu/dtb.c | 6 | ||||
-rw-r--r-- | arch/arm/cpu/entry.c | 23 | ||||
-rw-r--r-- | arch/arm/cpu/entry.h | 10 | ||||
-rw-r--r-- | arch/arm/cpu/entry_ll.S | 25 | ||||
-rw-r--r-- | arch/arm/cpu/entry_ll_64.S | 23 | ||||
-rw-r--r-- | arch/arm/cpu/mmu-early.c | 7 | ||||
-rw-r--r-- | arch/arm/cpu/mmu.c | 23 | ||||
-rw-r--r-- | arch/arm/cpu/mmu.h | 1 | ||||
-rw-r--r-- | arch/arm/cpu/start-pbl.c | 109 | ||||
-rw-r--r-- | arch/arm/cpu/start.c | 14 | ||||
-rw-r--r-- | arch/arm/cpu/uncompress.c | 17 |
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 *); |