summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorKever Yang <kever.yang@rock-chips.com>2017-05-05 11:47:45 +0800
committerTom Rini <trini@konsulko.com>2017-05-15 10:38:09 -0400
commitbcc1726a7bdd910b482528fde2faef21bff3b361 (patch)
tree9fca97762d722f45e3575a79accd79090f106b87 /common
parent9ad7147b8d38f00df1d81e237f5cfad0a0e3a39b (diff)
downloadu-boot-bcc1726a7bdd910b482528fde2faef21bff3b361.tar.gz
u-boot-bcc1726a7bdd910b482528fde2faef21bff3b361.tar.bz2
u-boot-bcc1726a7bdd910b482528fde2faef21bff3b361.zip
spl: add support to booting with ATF
ATF(ARM Trusted Firmware) is used by ARM arch64 SoCs, find more infomation about ATF at: https://github.com/ARM-software/arm-trusted-firmware SPL is considered as BL2 in ATF terminology, it needs to load other parts of ATF binary like BL31, BL32, SCP-BL30, and BL33(U-Boot). And needs to prepare the parameter for BL31 which including entry and image information for all other images. Then the SPL handle PC to BL31 with the parameter, the BL31 will do the rest of work and at last get into U-Boot(BL33). This patch needs work with patches from Andre for SPL support multi binary in FIT. The entry point of bl31 and bl33 are still using hard code because we still can not get them from the FIT image information. Signed-off-by: Kever Yang <kever.yang@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Acked-by: Simon Glass <sjg@chromium.org> Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'common')
-rw-r--r--common/spl/Kconfig14
-rw-r--r--common/spl/Makefile1
-rw-r--r--common/spl/spl.c5
-rw-r--r--common/spl/spl_atf.c97
4 files changed, 117 insertions, 0 deletions
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index f51ae2c484..e324e24b4f 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -693,6 +693,20 @@ config SPL_YMODEM_SUPPORT
means of transmitting U-Boot over a serial line for using in SPL,
with a checksum to ensure correctness.
+config SPL_ATF_SUPPORT
+ bool "Support ARM Trusted Firmware"
+ depends on SPL && ARM64
+ help
+ ATF(ARM Trusted Firmware) is a component for ARM arch64 which which
+ is loaded by SPL(which is considered as BL2 in ATF terminology).
+ More detail at: https://github.com/ARM-software/arm-trusted-firmware
+
+config SPL_ATF_TEXT_BASE
+ depends on SPL_ATF_SUPPORT
+ hex "ATF BL31 base address"
+ help
+ This is the base address in memory for ATF BL31 text and entry point.
+
config TPL_ENV_SUPPORT
bool "Support an environment"
depends on TPL
diff --git a/common/spl/Makefile b/common/spl/Makefile
index 1933cbdfed..b3b34d6277 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -20,6 +20,7 @@ endif
obj-$(CONFIG_SPL_UBI) += spl_ubi.o
obj-$(CONFIG_SPL_NET_SUPPORT) += spl_net.o
obj-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o
+obj-$(CONFIG_SPL_ATF_SUPPORT) += spl_atf.o
obj-$(CONFIG_SPL_USB_SUPPORT) += spl_usb.o
obj-$(CONFIG_SPL_FAT_SUPPORT) += spl_fat.o
obj-$(CONFIG_SPL_EXT_SUPPORT) += spl_ext.o
diff --git a/common/spl/spl.c b/common/spl/spl.c
index df984b8efd..0a49766f21 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -415,6 +415,11 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
gd->malloc_ptr / 1024);
#endif
+ if (IS_ENABLED(CONFIG_SPL_ATF_SUPPORT)) {
+ debug("loaded - jumping to U-Boot via ATF BL31.\n");
+ bl31_entry();
+ }
+
debug("loaded - jumping to U-Boot...\n");
spl_board_prepare_for_boot();
jump_to_image_no_args(&spl_image);
diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c
new file mode 100644
index 0000000000..6e8f928044
--- /dev/null
+++ b/common/spl/spl_atf.c
@@ -0,0 +1,97 @@
+/*
+ * Reference to the ARM TF Project,
+ * plat/arm/common/arm_bl2_setup.c
+ * Portions copyright (c) 2013-2016, ARM Limited and Contributors. All rights
+ * reserved.
+ * Copyright (C) 2016 Rockchip Electronic Co.,Ltd
+ * Written by Kever Yang <kever.yang@rock-chips.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common.h>
+#include <atf_common.h>
+#include <errno.h>
+#include <spl.h>
+
+static struct bl2_to_bl31_params_mem bl31_params_mem;
+static struct bl31_params *bl2_to_bl31_params;
+
+/**
+ * bl2_plat_get_bl31_params() - prepare params for bl31.
+ *
+ * This function assigns a pointer to the memory that the platform has kept
+ * aside to pass platform specific and trusted firmware related information
+ * to BL31. This memory is allocated by allocating memory to
+ * bl2_to_bl31_params_mem structure which is a superset of all the
+ * structure whose information is passed to BL31
+ * NOTE: This function should be called only once and should be done
+ * before generating params to BL31
+ *
+ * @return bl31 params structure pointer
+ */
+struct bl31_params *bl2_plat_get_bl31_params(void)
+{
+ struct entry_point_info *bl33_ep_info;
+
+ /*
+ * Initialise the memory for all the arguments that needs to
+ * be passed to BL31
+ */
+ memset(&bl31_params_mem, 0, sizeof(struct bl2_to_bl31_params_mem));
+
+ /* Assign memory for TF related information */
+ bl2_to_bl31_params = &bl31_params_mem.bl31_params;
+ SET_PARAM_HEAD(bl2_to_bl31_params, ATF_PARAM_BL31, ATF_VERSION_1, 0);
+
+ /* Fill BL31 related information */
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
+ ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
+
+ /* Fill BL32 related information if it exists */
+#ifdef BL32_BASE
+ bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, ATF_PARAM_EP,
+ ATF_VERSION_1, 0);
+ bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info,
+ ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
+#endif /* BL32_BASE */
+
+ /* Fill BL33 related information */
+ bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
+ bl33_ep_info = &bl31_params_mem.bl33_ep_info;
+ SET_PARAM_HEAD(bl33_ep_info, ATF_PARAM_EP, ATF_VERSION_1,
+ ATF_EP_NON_SECURE);
+
+ /* BL33 expects to receive the primary CPU MPID (through x0) */
+ bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
+ bl33_ep_info->pc = CONFIG_SYS_TEXT_BASE;
+ bl33_ep_info->spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
+ DISABLE_ALL_EXECPTIONS);
+
+ bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
+ ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
+
+ return bl2_to_bl31_params;
+}
+
+void raw_write_daif(unsigned int daif)
+{
+ __asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory");
+}
+
+void bl31_entry(void)
+{
+ struct bl31_params *bl31_params;
+ void (*entry)(struct bl31_params *params, void *plat_params) = NULL;
+
+ bl31_params = bl2_plat_get_bl31_params();
+ entry = (void *)CONFIG_SPL_ATF_TEXT_BASE;
+
+ raw_write_daif(SPSR_EXCEPTION_MASK);
+ dcache_disable();
+
+ entry(bl31_params, NULL);
+}