diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2018-11-09 10:55:05 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2018-11-09 10:55:05 +0100 |
commit | c9a2ebb18e59ea3be369b97cb0a00ba71230b90c (patch) | |
tree | 684533fe720119fbd5437d721248982e7b11a736 | |
parent | 227426f16163d3721fee82650980aae0eef01375 (diff) | |
parent | c60aa1f01393807660fbe7b67d49b48c3c37eae2 (diff) | |
download | barebox-c9a2ebb18e59ea3be369b97cb0a00ba71230b90c.tar.gz barebox-c9a2ebb18e59ea3be369b97cb0a00ba71230b90c.tar.xz |
Merge branch 'for-next/rpi3'
-rw-r--r-- | arch/arm/boards/raspberry-pi/lowlevel.c | 14 | ||||
-rw-r--r-- | arch/arm/boards/raspberry-pi/rpi-common.c | 2 | ||||
-rw-r--r-- | arch/arm/configs/rpi_defconfig | 3 | ||||
-rw-r--r-- | arch/arm/cpu/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/cpu/hyp.S | 116 | ||||
-rw-r--r-- | arch/arm/cpu/lowlevel.S | 23 | ||||
-rw-r--r-- | arch/arm/cpu/sm.c | 6 | ||||
-rw-r--r-- | arch/arm/cpu/sm_as.S | 15 | ||||
-rw-r--r-- | arch/arm/cpu/start-pbl.c | 4 | ||||
-rw-r--r-- | arch/arm/cpu/start.c | 5 | ||||
-rw-r--r-- | arch/arm/cpu/uncompress.c | 4 | ||||
-rw-r--r-- | arch/arm/dts/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/dts/bcm2837-rpi-3.dts | 16 | ||||
-rw-r--r-- | arch/arm/include/asm/opcodes-virt.h | 39 | ||||
-rw-r--r-- | arch/arm/include/asm/opcodes.h | 231 | ||||
-rw-r--r-- | arch/arm/include/asm/secure.h | 3 | ||||
-rw-r--r-- | arch/arm/include/asm/system.h | 26 | ||||
-rw-r--r-- | arch/arm/mach-bcm283x/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm/mach-bcm283x/core.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-bcm283x/include/mach/mbox.h | 4 | ||||
-rw-r--r-- | images/Makefile.bcm283x | 4 |
21 files changed, 511 insertions, 16 deletions
diff --git a/arch/arm/boards/raspberry-pi/lowlevel.c b/arch/arm/boards/raspberry-pi/lowlevel.c index cbc6caa4b9..34c9350920 100644 --- a/arch/arm/boards/raspberry-pi/lowlevel.c +++ b/arch/arm/boards/raspberry-pi/lowlevel.c @@ -1,7 +1,7 @@ +#include <asm/barebox-arm.h> +#include <asm/cache.h> #include <common.h> #include <linux/sizes.h> -#include <asm/barebox-arm.h> -#include <asm/barebox-arm-head.h> #include <mach/platform.h> extern char __dtb_bcm2835_rpi_start[]; @@ -23,3 +23,13 @@ ENTRY_FUNCTION(start_raspberry_pi2, r0, r1, r2) barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_512M, fdt); } + +extern char __dtb_bcm2837_rpi_3_start[]; +ENTRY_FUNCTION(start_raspberry_pi3, r0, r1, r2) +{ + void *fdt = __dtb_bcm2837_rpi_3_start + get_runtime_offset(); + + arm_cpu_lowlevel_init(); + + barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_512M, fdt); +} diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c index 6e375bc984..3baed65255 100644 --- a/arch/arm/boards/raspberry-pi/rpi-common.c +++ b/arch/arm/boards/raspberry-pi/rpi-common.c @@ -174,6 +174,8 @@ const struct rpi_model rpi_models_old_scheme[] = { const struct rpi_model rpi_models_new_scheme[] = { RPI_MODEL(0, "Unknown model", NULL), RPI_MODEL(BCM2836_BOARD_REV_2_B, "2 Model B", rpi_b_plus_init), + RPI_MODEL(BCM2837_BOARD_REV_3_B, "3 Model B", rpi_b_plus_init), + RPI_MODEL(BCM2835_BOARD_REV_ZERO, "Zero", rpi_b_plus_init), }; static int rpi_board_rev = 0; diff --git a/arch/arm/configs/rpi_defconfig b/arch/arm/configs/rpi_defconfig index f3aef42904..2bb6158493 100644 --- a/arch/arm/configs/rpi_defconfig +++ b/arch/arm/configs/rpi_defconfig @@ -1,10 +1,13 @@ CONFIG_ARCH_BCM283X=y CONFIG_MACH_RPI=y CONFIG_MACH_RPI2=y +CONFIG_MACH_RPI3=y CONFIG_AEABI=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_ARM_UNWIND=y +CONFIG_IMAGE_COMPRESSION_NONE=y CONFIG_MMU=y +CONFIG_MALLOC_SIZE=0x0 CONFIG_MALLOC_TLSF=y CONFIG_KALLSYMS=y CONFIG_PROMPT="R-Pi> " diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index 874d723e2c..a35db435c1 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -4,6 +4,9 @@ obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions$(S64).o interrupts$(S64).o obj-$(CONFIG_MMU) += mmu$(S64).o lwl-y += lowlevel$(S64).o obj-pbl-$(CONFIG_MMU) += mmu-early$(S64).o +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 @@ -23,6 +26,7 @@ endif obj-$(CONFIG_ARM_PSCI) += psci.o obj-pbl-$(CONFIG_ARM_SMCCC) += smccc-call$(S64).o AFLAGS_smccc-call$(S64).o :=-Wa,-march=armv$(if $(S64),8,7)-a +AFLAGS_pbl-smccc-call$(S64).o :=-Wa,-march=armv$(if $(S64),8,7)-a obj-$(CONFIG_ARM_SECURE_MONITOR) += sm.o sm_as.o AFLAGS_sm_as.o :=-Wa,-march=armv7-a diff --git a/arch/arm/cpu/hyp.S b/arch/arm/cpu/hyp.S new file mode 100644 index 0000000000..1314b56eab --- /dev/null +++ b/arch/arm/cpu/hyp.S @@ -0,0 +1,116 @@ +#include <linux/linkage.h> +#include <asm/system.h> +#include <asm/opcodes-virt.h> +#include <init.h> + +.arch_extension sec +.arch_extension virt + +__BARE_INIT + +.data + .align 2 +ENTRY(__boot_cpu_mode) + .long 0 +.text + +ENTRY(__hyp_install) + mrs r12, cpsr + and r12, r12, #MODE_MASK + + @ Save the initial CPU state + adr r0, .L__boot_cpu_mode_offset + ldr r1, [r0] + str r12, [r0, r1] + + cmp r12, #HYP_MODE + movne pc, lr @ give up if the CPU is not in HYP mode + + @ Now install the hypervisor stub: + adr r12, __hyp_vectors + mcr p15, 4, r12, c12, c0, 0 @ set hypervisor vector base (HVBAR) + + @ Disable all traps, so we don't get any nasty surprise + mov r12, #0 + mcr p15, 4, r12, c1, c1, 0 @ HCR + mcr p15, 4, r12, c1, c1, 2 @ HCPTR + mcr p15, 4, r12, c1, c1, 3 @ HSTR + +THUMB( orr r12, #(1 << 30) ) @ HSCTLR.TE + mcr p15, 4, r12, c1, c0, 0 @ HSCTLR + + mrc p15, 4, r12, c1, c1, 1 @ HDCR + and r12, #0x1f @ Preserve HPMN + mcr p15, 4, r12, c1, c1, 1 @ HDCR + + @ Make sure NS-SVC is initialised appropriately + mrc p15, 0, r12, c1, c0, 0 @ SCTLR + orr r12, #(1 << 5) @ CP15 barriers enabled + bic r12, #(3 << 7) @ Clear SED/ITD for v8 (RES0 for v7) + bic r12, #(3 << 19) @ WXN and UWXN disabled + mcr p15, 0, r12, c1, c0, 0 @ SCTLR + + mrc p15, 0, r12, c0, c0, 0 @ MIDR + mcr p15, 4, r12, c0, c0, 0 @ VPIDR + + mrc p15, 0, r12, c0, c0, 5 @ MPIDR + mcr p15, 4, r12, c0, c0, 5 @ VMPIDR + bx lr +ENDPROC(__hyp_install) + +ENTRY(armv7_hyp_install) + mov r2, lr + + bl __hyp_install + + /* set the cpu to SVC32 mode, mask irq and fiq */ + mrs r12, cpsr + eor r12, r12, #HYP_MODE + tst r12, #MODE_MASK + bic r12, r12, #MODE_MASK + orr r12, r12, #(PSR_I_BIT | PSR_F_BIT | SVC_MODE) +THUMB( orr r12, r12, #PSR_T_BIT ) + bne 1f + orr r12, r12, #PSR_A_BIT + adr lr, 2f + msr spsr_cxsf, r12 + __MSR_ELR_HYP(14) + __ERET +1: msr cpsr_c, r12 +2: + mov pc, r2 +ENDPROC(armv7_hyp_install) + +ENTRY(armv7_switch_to_hyp) + mov r0, lr + mov r1, sp @ save SVC copy of LR and SP + isb + hvc #0 @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1 + mov sp, r1 + mov lr, r0 @ restore SVC copy of LR and SP + + bx lr +ENDPROC(armv7_switch_to_hyp) + +.align 2 +.L__boot_cpu_mode_offset: + .long __boot_cpu_mode - . + +/* The HYP trap is crafted to match armv7_switch_to_hyp() */ +__hyp_do_trap: + mov lr, r0 + mov sp, r1 + bx lr +ENDPROC(__hyp_do_trap) + +.align 5 +__hyp_vectors: +__hyp_reset: W(b) . +__hyp_und: W(b) . +__hyp_svc: W(b) . +__hyp_pabort: W(b) . +__hyp_dabort: W(b) . +__hyp_trap: W(b) __hyp_do_trap +__hyp_irq: W(b) . +__hyp_fiq: W(b) . +ENDPROC(__hyp_vectors) diff --git a/arch/arm/cpu/lowlevel.S b/arch/arm/cpu/lowlevel.S index 7696a198e7..3b52644e43 100644 --- a/arch/arm/cpu/lowlevel.S +++ b/arch/arm/cpu/lowlevel.S @@ -1,16 +1,33 @@ #include <linux/linkage.h> #include <init.h> #include <asm/system.h> +#include <asm/opcodes-virt.h> .section ".text_bare_init_","ax" ENTRY(arm_cpu_lowlevel_init) /* save lr, since it may be banked away with a processor mode change */ mov r2, lr + +#ifdef CONFIG_CPU_32v7 + /* careful: the hyp install corrupts r0 and r1 */ + bl __hyp_install +#endif + /* set the cpu to SVC32 mode, mask irq and fiq */ mrs r12, cpsr - bic r12, r12, #0x1f - orr r12, r12, #0xd3 - msr cpsr, r12 + eor r12, r12, #HYP_MODE + tst r12, #MODE_MASK + bic r12, r12, #MODE_MASK + orr r12, r12, #(PSR_I_BIT | PSR_F_BIT | SVC_MODE) +THUMB( orr r12, r12, #PSR_T_BIT ) + bne 1f + orr r12, r12, #PSR_A_BIT + adr lr, 2f + msr spsr_cxsf, r12 + __MSR_ELR_HYP(14) + __ERET +1: msr cpsr_c, r12 +2: #if __LINUX_ARM_ARCH__ >= 6 /* diff --git a/arch/arm/cpu/sm.c b/arch/arm/cpu/sm.c index cb0bac106b..6fad30adab 100644 --- a/arch/arm/cpu/sm.c +++ b/arch/arm/cpu/sm.c @@ -184,6 +184,9 @@ int armv7_secure_monitor_install(void) return -EINVAL; } + if (__boot_cpu_mode == HYP_MODE) + return 0; + mmuon = get_cr() & CR_M; vbar = get_vbar(); @@ -259,6 +262,9 @@ static int sm_init(void) bootm_secure_state_names, ARRAY_SIZE(bootm_secure_state_names)); + if (__boot_cpu_mode == HYP_MODE) + bootm_secure_state = ARM_STATE_HYP; + return 0; } device_initcall(sm_init);
\ No newline at end of file diff --git a/arch/arm/cpu/sm_as.S b/arch/arm/cpu/sm_as.S index 09580e75de..de6cd0406f 100644 --- a/arch/arm/cpu/sm_as.S +++ b/arch/arm/cpu/sm_as.S @@ -129,7 +129,9 @@ secure_monitor: sub sp, sp, #4*4 @ allocate result structure on stack mov r12, sp push {r4-r6, r12} +#ifdef CONFIG_ARM_PSCI bl psci_entry +#endif pop {r4-r6, r12} ldm r12, {r0-r3} add sp, sp, #4*4 @@ -146,23 +148,14 @@ hyp_trap: mov pc, lr @ do no switch modes, but @ return to caller -ENTRY(armv7_switch_to_hyp) - mov r0, lr - mov r1, sp @ save SVC copy of LR and SP - isb - hvc #0 @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1 - mov sp, r1 - mov lr, r0 @ restore SVC copy of LR and SP - - bx lr -ENDPROC(armv7_switch_to_hyp) - ENTRY(psci_cpu_entry) mrc p15, 0, r0, c1, c0, 1 @ ACTLR orr r0, r0, #(1 << 6) @ Set SMP bit mcr p15, 0, r0, c1, c0, 1 @ ACTLR bl secure_monitor_stack_setup +#ifdef CONFIG_ARM_PSCI bl psci_cpu_entry_c +#endif ENDPROC(psci_cpu_entry) diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c index 16159d7f9d..48a8086456 100644 --- a/arch/arm/cpu/start-pbl.c +++ b/arch/arm/cpu/start-pbl.c @@ -26,6 +26,7 @@ #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> @@ -98,5 +99,8 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, 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 64bd942ad7..a79d64eaa6 100644 --- a/arch/arm/cpu/start.c +++ b/arch/arm/cpu/start.c @@ -24,6 +24,7 @@ #include <asm/barebox-arm-head.h> #include <asm-generic/memory_layout.h> #include <asm/sections.h> +#include <asm/secure.h> #include <asm/unaligned.h> #include <asm/cache.h> #include <asm/mmu.h> @@ -147,6 +148,10 @@ __noreturn void barebox_non_pbl_start(unsigned long membase, unsigned long barebox_base = arm_mem_barebox_image(membase, endmem, barebox_size); + + if (IS_ENABLED(CONFIG_CPU_V7)) + armv7_hyp_install(); + if (IS_ENABLED(CONFIG_RELOCATABLE)) relocate_to_adr(barebox_base); diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c index 43b49b4212..048bca0c95 100644 --- a/arch/arm/cpu/uncompress.c +++ b/arch/arm/cpu/uncompress.c @@ -27,6 +27,7 @@ #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> @@ -105,5 +106,8 @@ void __noreturn barebox_multi_pbl_start(unsigned long membase, pr_debug("jumping to uncompressed image at 0x%p\n", barebox); + if (IS_ENABLED(CONFIG_CPU_V7) && __boot_cpu_mode == HYP_MODE) + armv7_switch_to_hyp(); + barebox(membase, memsize, boarddata); } diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 4ecb3c2a0a..503d9b18f9 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -72,6 +72,7 @@ pbl-dtb-$(CONFIG_MACH_PHYTEC_SOM_RK3288) += rk3288-phycore-som.dtb.o pbl-dtb-$(CONFIG_MACH_REALQ7) += imx6q-dmo-edmqmx6.dtb.o pbl-dtb-$(CONFIG_MACH_RPI) += bcm2835-rpi.dtb.o pbl-dtb-$(CONFIG_MACH_RPI2) += bcm2836-rpi-2.dtb.o +pbl-dtb-$(CONFIG_MACH_RPI3) += bcm2837-rpi-3.dtb.o pbl-dtb-$(CONFIG_MACH_SABRELITE) += imx6q-sabrelite.dtb.o imx6dl-sabrelite.dtb.o pbl-dtb-$(CONFIG_MACH_SABRESD) += imx6q-sabresd.dtb.o pbl-dtb-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += imx6sx-sdb.dtb.o diff --git a/arch/arm/dts/bcm2837-rpi-3.dts b/arch/arm/dts/bcm2837-rpi-3.dts new file mode 100644 index 0000000000..d6ffc36912 --- /dev/null +++ b/arch/arm/dts/bcm2837-rpi-3.dts @@ -0,0 +1,16 @@ +#include <arm64/broadcom/bcm2837-rpi-3-b.dts> + +/ { + chosen { + stdout-path = &uart0; + }; + + memory { + reg = <0x0 0x0>; + }; +}; + +&uart0 { + status = "okay"; + /delete-node/ bluetooth; +}; diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h new file mode 100644 index 0000000000..efcfdf92d9 --- /dev/null +++ b/arch/arm/include/asm/opcodes-virt.h @@ -0,0 +1,39 @@ +/* + * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions + * Copyright (C) 2012 Linaro Limited + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef __ASM_ARM_OPCODES_VIRT_H +#define __ASM_ARM_OPCODES_VIRT_H + +#include <asm/opcodes.h> + +#define __HVC(imm16) __inst_arm_thumb32( \ + 0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F), \ + 0xF7E08000 | (((imm16) & 0xF000) << 4) | ((imm16) & 0x0FFF) \ +) + +#define __ERET __inst_arm_thumb32( \ + 0xE160006E, \ + 0xF3DE8F00 \ +) + +#define __MSR_ELR_HYP(regnum) __inst_arm_thumb32( \ + 0xE12EF300 | regnum, \ + 0xF3808E30 | (regnum << 16) \ +) + +#endif /* ! __ASM_ARM_OPCODES_VIRT_H */ diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h new file mode 100644 index 0000000000..a78bf5d2c5 --- /dev/null +++ b/arch/arm/include/asm/opcodes.h @@ -0,0 +1,231 @@ +/* + * arch/arm/include/asm/opcodes.h + * + * 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. + */ + +#ifndef __ASM_ARM_OPCODES_H +#define __ASM_ARM_OPCODES_H + +#ifndef __ASSEMBLY__ +#include <linux/linkage.h> +extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); +#endif + +#define ARM_OPCODE_CONDTEST_FAIL 0 +#define ARM_OPCODE_CONDTEST_PASS 1 +#define ARM_OPCODE_CONDTEST_UNCOND 2 + + +/* + * Assembler opcode byteswap helpers. + * These are only intended for use by this header: don't use them directly, + * because they will be suboptimal in most cases. + */ +#define ___asm_opcode_swab32(x) ( \ + (((x) << 24) & 0xFF000000) \ + | (((x) << 8) & 0x00FF0000) \ + | (((x) >> 8) & 0x0000FF00) \ + | (((x) >> 24) & 0x000000FF) \ +) +#define ___asm_opcode_swab16(x) ( \ + (((x) << 8) & 0xFF00) \ + | (((x) >> 8) & 0x00FF) \ +) +#define ___asm_opcode_swahb32(x) ( \ + (((x) << 8) & 0xFF00FF00) \ + | (((x) >> 8) & 0x00FF00FF) \ +) +#define ___asm_opcode_swahw32(x) ( \ + (((x) << 16) & 0xFFFF0000) \ + | (((x) >> 16) & 0x0000FFFF) \ +) +#define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF) +#define ___asm_opcode_identity16(x) ((x) & 0xFFFF) + + +/* + * Opcode byteswap helpers + * + * These macros help with converting instructions between a canonical integer + * format and in-memory representation, in an endianness-agnostic manner. + * + * __mem_to_opcode_*() convert from in-memory representation to canonical form. + * __opcode_to_mem_*() convert from canonical form to in-memory representation. + * + * + * Canonical instruction representation: + * + * ARM: 0xKKLLMMNN + * Thumb 16-bit: 0x0000KKLL, where KK < 0xE8 + * Thumb 32-bit: 0xKKLLMMNN, where KK >= 0xE8 + * + * There is no way to distinguish an ARM instruction in canonical representation + * from a Thumb instruction (just as these cannot be distinguished in memory). + * Where this distinction is important, it needs to be tracked separately. + * + * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not + * represent any valid Thumb-2 instruction. For this range, + * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false. + * + * The ___asm variants are intended only for use by this header, in situations + * involving inline assembler. For .S files, the normal __opcode_*() macros + * should do the right thing. + */ +#ifdef __ASSEMBLY__ + +#define ___opcode_swab32(x) ___asm_opcode_swab32(x) +#define ___opcode_swab16(x) ___asm_opcode_swab16(x) +#define ___opcode_swahb32(x) ___asm_opcode_swahb32(x) +#define ___opcode_swahw32(x) ___asm_opcode_swahw32(x) +#define ___opcode_identity32(x) ___asm_opcode_identity32(x) +#define ___opcode_identity16(x) ___asm_opcode_identity16(x) + +#else /* ! __ASSEMBLY__ */ + +#include <linux/types.h> +#include <linux/swab.h> + +#define ___opcode_swab32(x) swab32(x) +#define ___opcode_swab16(x) swab16(x) +#define ___opcode_swahb32(x) swahb32(x) +#define ___opcode_swahw32(x) swahw32(x) +#define ___opcode_identity32(x) ((u32)(x)) +#define ___opcode_identity16(x) ((u16)(x)) + +#endif /* ! __ASSEMBLY__ */ + + +#ifdef CONFIG_CPU_ENDIAN_BE8 + +#define __opcode_to_mem_arm(x) ___opcode_swab32(x) +#define __opcode_to_mem_thumb16(x) ___opcode_swab16(x) +#define __opcode_to_mem_thumb32(x) ___opcode_swahb32(x) +#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_swab32(x) +#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_swab16(x) +#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahb32(x) + +#else /* ! CONFIG_CPU_ENDIAN_BE8 */ + +#define __opcode_to_mem_arm(x) ___opcode_identity32(x) +#define __opcode_to_mem_thumb16(x) ___opcode_identity16(x) +#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x) +#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x) +#ifndef CONFIG_CPU_ENDIAN_BE32 +/* + * On BE32 systems, using 32-bit accesses to store Thumb instructions will not + * work in all cases, due to alignment constraints. For now, a correct + * version is not provided for BE32. + */ +#define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x) +#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x) +#endif + +#endif /* ! CONFIG_CPU_ENDIAN_BE8 */ + +#define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x) +#define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x) +#ifndef CONFIG_CPU_ENDIAN_BE32 +#define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x) +#endif + +/* Operations specific to Thumb opcodes */ + +/* Instruction size checks: */ +#define __opcode_is_thumb32(x) ( \ + ((x) & 0xF8000000) == 0xE8000000 \ + || ((x) & 0xF0000000) == 0xF0000000 \ +) +#define __opcode_is_thumb16(x) ( \ + ((x) & 0xFFFF0000) == 0 \ + && !(((x) & 0xF800) == 0xE800 || ((x) & 0xF000) == 0xF000) \ +) + +/* Operations to construct or split 32-bit Thumb instructions: */ +#define __opcode_thumb32_first(x) (___opcode_identity16((x) >> 16)) +#define __opcode_thumb32_second(x) (___opcode_identity16(x)) +#define __opcode_thumb32_compose(first, second) ( \ + (___opcode_identity32(___opcode_identity16(first)) << 16) \ + | ___opcode_identity32(___opcode_identity16(second)) \ +) +#define ___asm_opcode_thumb32_first(x) (___asm_opcode_identity16((x) >> 16)) +#define ___asm_opcode_thumb32_second(x) (___asm_opcode_identity16(x)) +#define ___asm_opcode_thumb32_compose(first, second) ( \ + (___asm_opcode_identity32(___asm_opcode_identity16(first)) << 16) \ + | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \ +) + +/* + * Opcode injection helpers + * + * In rare cases it is necessary to assemble an opcode which the + * assembler does not support directly, or which would normally be + * rejected because of the CFLAGS or AFLAGS used to build the affected + * file. + * + * Before using these macros, consider carefully whether it is feasible + * instead to change the build flags for your file, or whether it really + * makes sense to support old assembler versions when building that + * particular kernel feature. + * + * The macros defined here should only be used where there is no viable + * alternative. + * + * + * __inst_arm(x): emit the specified ARM opcode + * __inst_thumb16(x): emit the specified 16-bit Thumb opcode + * __inst_thumb32(x): emit the specified 32-bit Thumb opcode + * + * __inst_arm_thumb16(arm, thumb): emit either the specified arm or + * 16-bit Thumb opcode, depending on whether an ARM or Thumb-2 + * kernel is being built + * + * __inst_arm_thumb32(arm, thumb): emit either the specified arm or + * 32-bit Thumb opcode, depending on whether an ARM or Thumb-2 + * kernel is being built + * + * + * Note that using these macros directly is poor practice. Instead, you + * should use them to define human-readable wrapper macros to encode the + * instructions that you care about. In code which might run on ARMv7 or + * above, you can usually use the __inst_arm_thumb{16,32} macros to + * specify the ARM and Thumb alternatives at the same time. This ensures + * that the correct opcode gets emitted depending on the instruction set + * used for the kernel build. + * + * Look at opcodes-virt.h for an example of how to use these macros. + */ +#include <linux/stringify.h> + +#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x)) +#define __inst_thumb32(x) ___inst_thumb32( \ + ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)), \ + ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x)) \ +) +#define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x)) + +#ifdef CONFIG_THUMB2_BAREBOX +#define __inst_arm_thumb16(arm_opcode, thumb_opcode) \ + __inst_thumb16(thumb_opcode) +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) \ + __inst_thumb32(thumb_opcode) +#else +#define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) +#endif + +/* Helpers for the helpers. Don't use these directly. */ +#ifdef __ASSEMBLY__ +#define ___inst_arm(x) .long x +#define ___inst_thumb16(x) .short x +#define ___inst_thumb32(first, second) .short first, second +#else +#define ___inst_arm(x) ".long " __stringify(x) "\n\t" +#define ___inst_thumb16(x) ".short " __stringify(x) "\n\t" +#define ___inst_thumb32(first, second) \ + ".short " __stringify(first) ", " __stringify(second) "\n\t" +#endif + +#endif /* __ASM_ARM_OPCODES_H */ diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h index a4cb1f6c1c..663d81ea27 100644 --- a/arch/arm/include/asm/secure.h +++ b/arch/arm/include/asm/secure.h @@ -5,9 +5,12 @@ int armv7_secure_monitor_install(void); int __armv7_secure_monitor_install(void); + void armv7_switch_to_hyp(void); +void armv7_hyp_install(void); extern unsigned char secure_monitor_init_vectors[]; +extern int __boot_cpu_mode; enum arm_security_state { ARM_STATE_SECURE, diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 2f13e2b98d..45eeb6e62c 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -60,6 +60,32 @@ #define CR_AFE (1 << 29) /* Access flag enable */ #define CR_TE (1 << 30) /* Thumb exception enable */ +/* + * PSR bits + */ +#define USR_MODE 0x00000010 +#define FIQ_MODE 0x00000011 +#define IRQ_MODE 0x00000012 +#define SVC_MODE 0x00000013 +#define ABT_MODE 0x00000017 +#define HYP_MODE 0x0000001a +#define UND_MODE 0x0000001b +#define SYSTEM_MODE 0x0000001f +#define MODE32_BIT 0x00000010 +#define MODE_MASK 0x0000001f + +#define PSR_T_BIT 0x00000020 +#define PSR_F_BIT 0x00000040 +#define PSR_I_BIT 0x00000080 +#define PSR_A_BIT 0x00000100 +#define PSR_E_BIT 0x00000200 +#define PSR_J_BIT 0x01000000 +#define PSR_Q_BIT 0x08000000 +#define PSR_V_BIT 0x10000000 +#define PSR_C_BIT 0x20000000 +#define PSR_Z_BIT 0x40000000 +#define PSR_N_BIT 0x80000000 + #ifndef __ASSEMBLY__ #if __LINUX_ARM_ARCH__ > 7 static inline unsigned int current_el(void) diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig index 1457f114cc..af2f88c47a 100644 --- a/arch/arm/mach-bcm283x/Kconfig +++ b/arch/arm/mach-bcm283x/Kconfig @@ -19,6 +19,12 @@ config MACH_RPI2 select CPU_V7 select MACH_RPI_COMMON +config MACH_RPI3 + bool "RaspberryPi 3 (BCM2837/CORTEX-A53)" + select CPU_V7 + select MACH_RPI_COMMON + select ARM_SECURE_MONITOR + endmenu config MACH_RPI_DEBUG_UART_BASE diff --git a/arch/arm/mach-bcm283x/core.c b/arch/arm/mach-bcm283x/core.c index fddcb0d1a1..26f0996b1c 100644 --- a/arch/arm/mach-bcm283x/core.c +++ b/arch/arm/mach-bcm283x/core.c @@ -41,6 +41,7 @@ static int bcm2835_clk_init(void) clk = clk_fixed("uart0-pl0110", 3 * 1000 * 1000); clk_register_clkdev(clk, NULL, "uart0-pl0110"); clk_register_clkdev(clk, NULL, "20201000.serial"); + clk_register_clkdev(clk, NULL, "3f201000.serial"); clk = clk_fixed("bcm2835-cs", 1 * 1000 * 1000); clk_register_clkdev(clk, NULL, "bcm2835-cs"); diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h index 2b5aea88ee..0d1ac074e3 100644 --- a/arch/arm/mach-bcm283x/include/mach/mbox.h +++ b/arch/arm/mach-bcm283x/include/mach/mbox.h @@ -129,6 +129,10 @@ struct bcm2835_mbox_tag_hdr { /* RPi 2 */ #define BCM2836_BOARD_REV_2_B 0x4 +/* RPi 3 */ +#define BCM2837_BOARD_REV_3_B 0x8 +/* Zero */ +#define BCM2835_BOARD_REV_ZERO 0x9 /* * 0x2..0xf from: diff --git a/images/Makefile.bcm283x b/images/Makefile.bcm283x index d59ef043f0..d14e648926 100644 --- a/images/Makefile.bcm283x +++ b/images/Makefile.bcm283x @@ -9,3 +9,7 @@ image-$(CONFIG_MACH_RPI) += barebox-raspberry-pi-1.img pblx-$(CONFIG_MACH_RPI2) += start_raspberry_pi2 FILE_barebox-raspberry-pi-2.img = start_raspberry_pi2.pblx image-$(CONFIG_MACH_RPI2) += barebox-raspberry-pi-2.img + +pblx-$(CONFIG_MACH_RPI3) += start_raspberry_pi3 +FILE_barebox-raspberry-pi-3.img = start_raspberry_pi3.pblx +image-$(CONFIG_MACH_RPI3) += barebox-raspberry-pi-3.img
\ No newline at end of file |