From 05018de5c0fb30b6c8cfb4f7c458bc8dc9c19bf8 Mon Sep 17 00:00:00 2001 From: egukim Date: Mon, 4 Sep 2017 14:25:30 +0900 Subject: [PATCH] spl: implement spl-atf on raspberry 3 b add implementation of spl-atf on raspberry 3 b board to support atf optee secure world. To execute u-boot-spl.bin, it should append built binary from head.S to u-boot-spl.bin as binary header. Change-Id: I74883a9e7d7476f9f814660b74a5e68d953aff1b Signed-off-by: egukim --- arch/arm/mach-bcm283x/Makefile | 1 + arch/arm/mach-bcm283x/bcm283x-board-spl.c | 68 ++++++++++++++++++++++++ board/raspberrypi/rpi/fit_spl_atf.its | 51 ++++++++++++++++++ board/raspberrypi/rpi/head.S | 87 +++++++++++++++++++++++++++++++ common/spl/spl_atf.c | 21 ++++++++ drivers/serial/serial_bcm283x_mu.c | 56 ++++++++++++++++++++ 6 files changed, 284 insertions(+) create mode 100644 arch/arm/mach-bcm283x/bcm283x-board-spl.c create mode 100644 board/raspberrypi/rpi/fit_spl_atf.its create mode 100644 board/raspberrypi/rpi/head.S diff --git a/arch/arm/mach-bcm283x/Makefile b/arch/arm/mach-bcm283x/Makefile index 7cd0688..931e7aa 100644 --- a/arch/arm/mach-bcm283x/Makefile +++ b/arch/arm/mach-bcm283x/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_BCM2835) += lowlevel_init.o obj-y += init.o reset.o mbox.o msg.o phys2bus.o +obj-$(CONFIG_SPL_BUILD) += bcm283x-board-spl.o diff --git a/arch/arm/mach-bcm283x/bcm283x-board-spl.c b/arch/arm/mach-bcm283x/bcm283x-board-spl.c new file mode 100644 index 0000000..a4423f7 --- /dev/null +++ b/arch/arm/mach-bcm283x/bcm283x-board-spl.c @@ -0,0 +1,68 @@ +/* + * (C) Copyright 2017 + * Dignsys inc, + * + * eunggu kim + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_ARM64 +#include +#endif + +DECLARE_GLOBAL_DATA_PTR; + +void board_init_f(ulong dummy) +{ + debug_uart_init(); + printascii("init debug uart\n\0"); +} + +void spl_board_init(void) +{ + preloader_console_init(); + + /* Save the pre-reloc driver model and start a new one */ + gd->dm_root_f = gd->dm_root; + gd->dm_root = NULL; + dm_init_and_scan(false); + + printascii("spl board init\n\0"); +} + +void board_boot_order(u32 *spl_boot_list) +{ + spl_boot_list[0] = BOOT_DEVICE_MMC1; +} + +u32 spl_boot_mode(const u32 boot_device) +{ + return MMCSD_MODE_FS; +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + return 0; +} +#endif diff --git a/board/raspberrypi/rpi/fit_spl_atf.its b/board/raspberrypi/rpi/fit_spl_atf.its new file mode 100644 index 0000000..4a970c7 --- /dev/null +++ b/board/raspberrypi/rpi/fit_spl_atf.its @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2017 Theobroma Systems Design und Consulting GmbH + * + * Minimal dts for a SPL FIT image payload. + * + * SPDX-License-Identifier: GPL-2.0+ X11 + */ + +/dts-v1/; + +/ { + description = "FIT image with U-Boot proper, ATF bl31/OPTEE, DTB"; + #address-cells = <1>; + + images { + uboot@1 { + description = "U-Boot (64-bit)"; + data = /incbin/("./u-boot-nodtb.bin"); + type = "standalone"; + arch = "arm64"; + compression = "none"; + load = <0x00080000>; + entry = <0x00080000>; + }; + atf@1 { + description = "ARM Trusted Firmware"; + data = /incbin/("./optee.bin"); + type = "firmware"; + arch = "arm64"; + compression = "none"; + load = <0x08400000>; + entry = <0x08400000>; + }; + fdt@1 { + description = "Raspberrypi 3b flat device-tree"; + data = /incbin/("./bcm2837-rpi-3-b.dtb"); + type = "flat_dt"; + compression = "none"; + }; + }; + + configurations { + default = "conf@1"; + conf@1 { + description = "Raspberrypi 3b Soc"; + firmware = "uboot@1"; + loadables = "atf@1"; + fdt = "fdt@1"; + }; + }; +}; diff --git a/board/raspberrypi/rpi/head.S b/board/raspberrypi/rpi/head.S new file mode 100644 index 0000000..075d41b --- /dev/null +++ b/board/raspberrypi/rpi/head.S @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, Linaro Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Reverse-engineered from head.bin previously committed in the Git repository. + * Build with: + * aarch64-linux-gnu-as head.S -o head.o + * aarch64-linux-gnu-objcopy -O binary head.o head.bin + */ + mov x0, #0x40000000 + str wzr, [x0] + mov w1, #0x80000000 + str w1, [x0, #8] + + ldr x0, _19_2_MHz + msr cntfrq_el0, x0 + + msr cntvoff_el2, xzr + + mov x0, #0x33ff + msr cptr_el3, x0 + + mov x0, #0x5b0 + msr scr_el3, x0 + + mov x0, #0x40 + msr s3_1_c15_c2_1, x0 + + mrs x6, mpidr_el1 + and x6, x6, #0x3 + cbz x6, core0 + + adr x5, spin_table +spin: + wfe + ldr x4, [x5, x6, lsl #3] + cbz x4, spin + mov x0, #0x0 + b 1f +core0: + ldr x4, core0_init + ldr x0, core0_init_parm +1: + mov x1, #0x0 + mov x2, #0x0 + mov x3, #0x0 + br x4 + +_19_2_MHz: + .word 0x0124f800 + .rept 23 + .word 0x0 + .endr + .balign 8, 0 +core0_init: + .word 0x8000 + .balign 8, 0 +spin_table: + .rept 8 + .word 0x0 + .endr +core0_init_parm: + .word 0x100 + .p2align 15, 0 diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c index b54b4f0..345f161 100644 --- a/common/spl/spl_atf.c +++ b/common/spl/spl_atf.c @@ -97,6 +97,27 @@ static void bl31_entry(uintptr_t bl31_entry, uintptr_t bl32_entry, raw_write_daif(SPSR_EXCEPTION_MASK); dcache_disable(); +#ifdef CONFIG_ARCH_BCM283X + { + unsigned long long spin_addr; + unsigned long long *core_1 = (unsigned long long *)(0xe0); + unsigned long long *core_2 = (unsigned long long *)(0xe8); + unsigned long long *core_3 = (unsigned long long *)(0xf0); + unsigned long long (*bl31_getspin)(void); + + bl31_getspin = (unsigned long long (*)(void)) + (CONFIG_SPL_ATF_TEXT_BASE + 4); + + spin_addr = (*bl31_getspin)(); + + /* + Release spinning cores + */ + *core_1 = spin_addr; + *core_2 = spin_addr; + *core_3 = spin_addr; + } +#endif atf_entry((void *)bl31_params, (void *)fdt_addr); } diff --git a/drivers/serial/serial_bcm283x_mu.c b/drivers/serial/serial_bcm283x_mu.c index 8a4af87..20d9eb9 100644 --- a/drivers/serial/serial_bcm283x_mu.c +++ b/drivers/serial/serial_bcm283x_mu.c @@ -202,3 +202,59 @@ U_BOOT_DRIVER(serial_bcm283x_mu) = { #endif .priv_auto_alloc_size = sizeof(struct bcm283x_mu_priv), }; + +#ifdef CONFIG_SPL_BUILD +#include + +#define IO_BASE 0x3f000000 +#define GP_BASE (IO_BASE + 0x200000) +#define MU_BASE (IO_BASE + 0x215000) + +#define AUX_ENB (*(volatile unsigned *)(MU_BASE + 0x04)) +#define MU_IO (*(volatile unsigned *)(MU_BASE + 0x40)) +#define MU_IIR (*(volatile unsigned *)(MU_BASE + 0x44)) +#define MU_IER (*(volatile unsigned *)(MU_BASE + 0x48)) +#define MU_LCR (*(volatile unsigned *)(MU_BASE + 0x4c)) +#define MU_MCR (*(volatile unsigned *)(MU_BASE + 0x50)) +#define MU_LSR (*(volatile unsigned *)(MU_BASE + 0x54)) +#define MU_CNTL (*(volatile unsigned *)(MU_BASE + 0x60)) +#define MU_STAT (*(volatile unsigned *)(MU_BASE + 0x64)) +#define MU_BAUD (*(volatile unsigned *)(MU_BASE + 0x68)) + +#define GPFSEL1 (*(volatile unsigned *)(GP_BASE + 0x04)) +#define GPPUD (*(volatile unsigned *)(GP_BASE + 0x94)) +#define GPPUDCLK0 (*(volatile unsigned *)(GP_BASE + 0x98)) + +static inline void _debug_uart_init(void) +{ + int i; + + AUX_ENB |= 1; /* Enable mini-uart */ + MU_LCR = 3; /* 8 bit. */ + MU_BAUD = 270; /* 115200 baud.(0x10e) */ + + GPFSEL1 &= ~((7<<12) | (7 << 15)); /* GPIO14 & 15 : alt5 */ + GPFSEL1 |= (2 << 12) | (2 << 15); + + /* Disable pull-up/down */ + GPPUD = 0; + for (i = 0; i < 150; i++) + __asm__ __volatile__("nop"); + GPPUDCLK0 = (2 << 14) | (2 << 15); + for (i = 0; i < 150; i++) + __asm__ __volatile__("nop"); + + GPPUDCLK0 = 0; + + MU_CNTL = 3; /* Enable Tx & Rx */ +} + +static inline void _debug_uart_putc(int ch) +{ + while (!(MU_LSR & 0x20)) + ; + MU_IO = ch; +} + +DEBUG_UART_FUNCS +#endif -- 2.7.4