Commit bcc1726a7bdd910b482528fde2faef21bff3b361

Authored by Kever Yang
Committed by Tom Rini
1 parent 9ad7147b8d

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>

Showing 6 changed files with 301 additions and 0 deletions Side-by-side Diff

... ... @@ -693,6 +693,20 @@
693 693 means of transmitting U-Boot over a serial line for using in SPL,
694 694 with a checksum to ensure correctness.
695 695  
  696 +config SPL_ATF_SUPPORT
  697 + bool "Support ARM Trusted Firmware"
  698 + depends on SPL && ARM64
  699 + help
  700 + ATF(ARM Trusted Firmware) is a component for ARM arch64 which which
  701 + is loaded by SPL(which is considered as BL2 in ATF terminology).
  702 + More detail at: https://github.com/ARM-software/arm-trusted-firmware
  703 +
  704 +config SPL_ATF_TEXT_BASE
  705 + depends on SPL_ATF_SUPPORT
  706 + hex "ATF BL31 base address"
  707 + help
  708 + This is the base address in memory for ATF BL31 text and entry point.
  709 +
696 710 config TPL_ENV_SUPPORT
697 711 bool "Support an environment"
698 712 depends on TPL
... ... @@ -20,6 +20,7 @@
20 20 obj-$(CONFIG_SPL_UBI) += spl_ubi.o
21 21 obj-$(CONFIG_SPL_NET_SUPPORT) += spl_net.o
22 22 obj-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o
  23 +obj-$(CONFIG_SPL_ATF_SUPPORT) += spl_atf.o
23 24 obj-$(CONFIG_SPL_USB_SUPPORT) += spl_usb.o
24 25 obj-$(CONFIG_SPL_FAT_SUPPORT) += spl_fat.o
25 26 obj-$(CONFIG_SPL_EXT_SUPPORT) += spl_ext.o
... ... @@ -415,6 +415,11 @@
415 415 gd->malloc_ptr / 1024);
416 416 #endif
417 417  
  418 + if (IS_ENABLED(CONFIG_SPL_ATF_SUPPORT)) {
  419 + debug("loaded - jumping to U-Boot via ATF BL31.\n");
  420 + bl31_entry();
  421 + }
  422 +
418 423 debug("loaded - jumping to U-Boot...\n");
419 424 spl_board_prepare_for_boot();
420 425 jump_to_image_no_args(&spl_image);
common/spl/spl_atf.c
  1 +/*
  2 + * Reference to the ARM TF Project,
  3 + * plat/arm/common/arm_bl2_setup.c
  4 + * Portions copyright (c) 2013-2016, ARM Limited and Contributors. All rights
  5 + * reserved.
  6 + * Copyright (C) 2016 Rockchip Electronic Co.,Ltd
  7 + * Written by Kever Yang <kever.yang@rock-chips.com>
  8 + *
  9 + * SPDX-License-Identifier: BSD-3-Clause
  10 + */
  11 +
  12 +#include <common.h>
  13 +#include <atf_common.h>
  14 +#include <errno.h>
  15 +#include <spl.h>
  16 +
  17 +static struct bl2_to_bl31_params_mem bl31_params_mem;
  18 +static struct bl31_params *bl2_to_bl31_params;
  19 +
  20 +/**
  21 + * bl2_plat_get_bl31_params() - prepare params for bl31.
  22 + *
  23 + * This function assigns a pointer to the memory that the platform has kept
  24 + * aside to pass platform specific and trusted firmware related information
  25 + * to BL31. This memory is allocated by allocating memory to
  26 + * bl2_to_bl31_params_mem structure which is a superset of all the
  27 + * structure whose information is passed to BL31
  28 + * NOTE: This function should be called only once and should be done
  29 + * before generating params to BL31
  30 + *
  31 + * @return bl31 params structure pointer
  32 + */
  33 +struct bl31_params *bl2_plat_get_bl31_params(void)
  34 +{
  35 + struct entry_point_info *bl33_ep_info;
  36 +
  37 + /*
  38 + * Initialise the memory for all the arguments that needs to
  39 + * be passed to BL31
  40 + */
  41 + memset(&bl31_params_mem, 0, sizeof(struct bl2_to_bl31_params_mem));
  42 +
  43 + /* Assign memory for TF related information */
  44 + bl2_to_bl31_params = &bl31_params_mem.bl31_params;
  45 + SET_PARAM_HEAD(bl2_to_bl31_params, ATF_PARAM_BL31, ATF_VERSION_1, 0);
  46 +
  47 + /* Fill BL31 related information */
  48 + SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
  49 + ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
  50 +
  51 + /* Fill BL32 related information if it exists */
  52 +#ifdef BL32_BASE
  53 + bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
  54 + SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, ATF_PARAM_EP,
  55 + ATF_VERSION_1, 0);
  56 + bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
  57 + SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info,
  58 + ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
  59 +#endif /* BL32_BASE */
  60 +
  61 + /* Fill BL33 related information */
  62 + bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
  63 + bl33_ep_info = &bl31_params_mem.bl33_ep_info;
  64 + SET_PARAM_HEAD(bl33_ep_info, ATF_PARAM_EP, ATF_VERSION_1,
  65 + ATF_EP_NON_SECURE);
  66 +
  67 + /* BL33 expects to receive the primary CPU MPID (through x0) */
  68 + bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
  69 + bl33_ep_info->pc = CONFIG_SYS_TEXT_BASE;
  70 + bl33_ep_info->spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
  71 + DISABLE_ALL_EXECPTIONS);
  72 +
  73 + bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
  74 + SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
  75 + ATF_PARAM_IMAGE_BINARY, ATF_VERSION_1, 0);
  76 +
  77 + return bl2_to_bl31_params;
  78 +}
  79 +
  80 +void raw_write_daif(unsigned int daif)
  81 +{
  82 + __asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory");
  83 +}
  84 +
  85 +void bl31_entry(void)
  86 +{
  87 + struct bl31_params *bl31_params;
  88 + void (*entry)(struct bl31_params *params, void *plat_params) = NULL;
  89 +
  90 + bl31_params = bl2_plat_get_bl31_params();
  91 + entry = (void *)CONFIG_SPL_ATF_TEXT_BASE;
  92 +
  93 + raw_write_daif(SPSR_EXCEPTION_MASK);
  94 + dcache_disable();
  95 +
  96 + entry(bl31_params, NULL);
  97 +}
include/atf_common.h
  1 +/*
  2 + * This is from the ARM TF Project,
  3 + * Repository: https://github.com/ARM-software/arm-trusted-firmware.git
  4 + * File: include/common/bl_common.h
  5 + * Portions copyright (c) 2013-2016, ARM Limited and Contributors. All rights
  6 + * reserved.
  7 + * Copyright (C) 2016-2017 Rockchip Electronic Co.,Ltd
  8 + *
  9 + * SPDX-License-Identifier: BSD-3-Clause
  10 + */
  11 +
  12 +#ifndef __BL_COMMON_H__
  13 +#define __BL_COMMON_H__
  14 +
  15 +#define ATF_PARAM_EP 0x01
  16 +#define ATF_PARAM_IMAGE_BINARY 0x02
  17 +#define ATF_PARAM_BL31 0x03
  18 +
  19 +#define ATF_VERSION_1 0x01
  20 +
  21 +#define ATF_EP_SECURE 0x0
  22 +#define ATF_EP_NON_SECURE 0x1
  23 +
  24 +#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \
  25 + (_p)->h.type = (uint8_t)(_type); \
  26 + (_p)->h.version = (uint8_t)(_ver); \
  27 + (_p)->h.size = (uint16_t)sizeof(*_p); \
  28 + (_p)->h.attr = (uint32_t)(_attr) ; \
  29 + } while (0)
  30 +
  31 +#define MODE_RW_SHIFT 0x4
  32 +#define MODE_RW_MASK 0x1
  33 +#define MODE_RW_64 0x0
  34 +#define MODE_RW_32 0x1
  35 +
  36 +#define MODE_EL_SHIFT 0x2
  37 +#define MODE_EL_MASK 0x3
  38 +#define MODE_EL3 0x3
  39 +#define MODE_EL2 0x2
  40 +#define MODE_EL1 0x1
  41 +#define MODE_EL0 0x0
  42 +
  43 +#define MODE_SP_SHIFT 0x0
  44 +#define MODE_SP_MASK 0x1
  45 +#define MODE_SP_EL0 0x0
  46 +#define MODE_SP_ELX 0x1
  47 +
  48 +#define SPSR_DAIF_SHIFT 6
  49 +#define SPSR_DAIF_MASK 0x0f
  50 +
  51 +#define SPSR_64(el, sp, daif) \
  52 + (MODE_RW_64 << MODE_RW_SHIFT | \
  53 + ((el) & MODE_EL_MASK) << MODE_EL_SHIFT | \
  54 + ((sp) & MODE_SP_MASK) << MODE_SP_SHIFT | \
  55 + ((daif) & SPSR_DAIF_MASK) << SPSR_DAIF_SHIFT)
  56 +
  57 +#define SPSR_FIQ (1 << 6)
  58 +#define SPSR_IRQ (1 << 7)
  59 +#define SPSR_SERROR (1 << 8)
  60 +#define SPSR_DEBUG (1 << 9)
  61 +#define SPSR_EXCEPTION_MASK (SPSR_FIQ | SPSR_IRQ | SPSR_SERROR | SPSR_DEBUG)
  62 +
  63 +#define DAIF_FIQ_BIT (1<<0)
  64 +#define DAIF_IRQ_BIT (1<<1)
  65 +#define DAIF_ABT_BIT (1<<2)
  66 +#define DAIF_DBG_BIT (1<<3)
  67 +#define DISABLE_ALL_EXECPTIONS \
  68 + (DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
  69 +
  70 +#ifndef __ASSEMBLY__
  71 +
  72 +/*******************************************************************************
  73 + * Structure used for telling the next BL how much of a particular type of
  74 + * memory is available for its use and how much is already used.
  75 + ******************************************************************************/
  76 +struct aapcs64_params {
  77 + unsigned long arg0;
  78 + unsigned long arg1;
  79 + unsigned long arg2;
  80 + unsigned long arg3;
  81 + unsigned long arg4;
  82 + unsigned long arg5;
  83 + unsigned long arg6;
  84 + unsigned long arg7;
  85 +};
  86 +
  87 +/***************************************************************************
  88 + * This structure provides version information and the size of the
  89 + * structure, attributes for the structure it represents
  90 + ***************************************************************************/
  91 +struct param_header {
  92 + uint8_t type; /* type of the structure */
  93 + uint8_t version; /* version of this structure */
  94 + uint16_t size; /* size of this structure in bytes */
  95 + uint32_t attr; /* attributes: unused bits SBZ */
  96 +};
  97 +
  98 +/*****************************************************************************
  99 + * This structure represents the superset of information needed while
  100 + * switching exception levels. The only two mechanisms to do so are
  101 + * ERET & SMC. Security state is indicated using bit zero of header
  102 + * attribute
  103 + * NOTE: BL1 expects entrypoint followed by spsr at an offset from the start
  104 + * of this structure defined by the macro `ENTRY_POINT_INFO_PC_OFFSET` while
  105 + * processing SMC to jump to BL31.
  106 + *****************************************************************************/
  107 +struct entry_point_info {
  108 + struct param_header h;
  109 + uintptr_t pc;
  110 + uint32_t spsr;
  111 + struct aapcs64_params args;
  112 +};
  113 +
  114 +/*****************************************************************************
  115 + * Image info binary provides information from the image loader that
  116 + * can be used by the firmware to manage available trusted RAM.
  117 + * More advanced firmware image formats can provide additional
  118 + * information that enables optimization or greater flexibility in the
  119 + * common firmware code
  120 + *****************************************************************************/
  121 +struct atf_image_info {
  122 + struct param_header h;
  123 + uintptr_t image_base; /* physical address of base of image */
  124 + uint32_t image_size; /* bytes read from image file */
  125 +};
  126 +
  127 +/*****************************************************************************
  128 + * The image descriptor struct definition.
  129 + *****************************************************************************/
  130 +struct image_desc {
  131 + /* Contains unique image id for the image. */
  132 + unsigned int image_id;
  133 + /*
  134 + * This member contains Image state information.
  135 + * Refer IMAGE_STATE_XXX defined above.
  136 + */
  137 + unsigned int state;
  138 + uint32_t copied_size; /* image size copied in blocks */
  139 + struct atf_image_info atf_image_info;
  140 + struct entry_point_info ep_info;
  141 +};
  142 +
  143 +/*******************************************************************************
  144 + * This structure represents the superset of information that can be passed to
  145 + * BL31 e.g. while passing control to it from BL2. The BL32 parameters will be
  146 + * populated only if BL2 detects its presence. A pointer to a structure of this
  147 + * type should be passed in X0 to BL31's cold boot entrypoint.
  148 + *
  149 + * Use of this structure and the X0 parameter is not mandatory: the BL31
  150 + * platform code can use other mechanisms to provide the necessary information
  151 + * about BL32 and BL33 to the common and SPD code.
  152 + *
  153 + * BL31 image information is mandatory if this structure is used. If either of
  154 + * the optional BL32 and BL33 image information is not provided, this is
  155 + * indicated by the respective image_info pointers being zero.
  156 + ******************************************************************************/
  157 +struct bl31_params {
  158 + struct param_header h;
  159 + struct atf_image_info *bl31_image_info;
  160 + struct entry_point_info *bl32_ep_info;
  161 + struct atf_image_info *bl32_image_info;
  162 + struct entry_point_info *bl33_ep_info;
  163 + struct atf_image_info *bl33_image_info;
  164 +};
  165 +
  166 +/*******************************************************************************
  167 + * This structure represents the superset of information that is passed to
  168 + * BL31, e.g. while passing control to it from BL2, bl31_params
  169 + * and other platform specific params
  170 + ******************************************************************************/
  171 +struct bl2_to_bl31_params_mem {
  172 + struct bl31_params bl31_params;
  173 + struct atf_image_info bl31_image_info;
  174 + struct atf_image_info bl32_image_info;
  175 + struct atf_image_info bl33_image_info;
  176 + struct entry_point_info bl33_ep_info;
  177 + struct entry_point_info bl32_ep_info;
  178 + struct entry_point_info bl31_ep_info;
  179 +};
  180 +
  181 +#endif /*__ASSEMBLY__*/
  182 +
  183 +#endif /* __BL_COMMON_H__ */
... ... @@ -267,5 +267,6 @@
267 267 int spl_mmc_load_image(struct spl_image_info *spl_image,
268 268 struct spl_boot_device *bootdev);
269 269  
  270 +void bl31_entry(void);
270 271 #endif