[U-Boot] [PATCH 2/8] spl: atf: add arm32 variant
Heiko Stuebner
heiko at sntech.de
Fri Apr 5 08:30:07 UTC 2019
ATF can also support arm32 socs with being a bl32 payload either
including optee or the minimal sp_min payload included in ATF itself.
So add the necessary infrasturcture to jump into ATF as bl32 from spl
which then will jump into the real u-boot.
We keep using the arm64 datastructures because, while they are named
bl31_*, the only difference is not populating the bl31-related fields
and making the bl32 ones mandatory, so there really is no need to
redefine all of them simply to drop the empty bl31 parts.
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
---
common/spl/Kconfig | 2 +-
common/spl/spl_atf.c | 86 ++++++++++++++++++++++++++++++++++++++++++--
include/atf_common.h | 52 +++++++++++++++++++++++++++
3 files changed, 137 insertions(+), 3 deletions(-)
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 206c24076d..ba39c17cf2 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -886,7 +886,7 @@ config SPL_YMODEM_SUPPORT
config SPL_ATF
bool "Support ARM Trusted Firmware"
- depends on ARM64
+ depends on ARM || ARM64
help
ATF(ARM Trusted Firmware) is a component for ARM AArch64 which
is loaded by SPL (which is considered as BL2 in ATF terminology).
diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c
index cddab6a735..2fbec29b73 100644
--- a/common/spl/spl_atf.c
+++ b/common/spl/spl_atf.c
@@ -17,6 +17,9 @@
static struct bl2_to_bl31_params_mem bl31_params_mem;
static struct bl31_params *bl2_to_bl31_params;
+typedef void (*atf_entry_t)(struct bl31_params *params, void *plat_params);
+
+#ifdef CONFIG_ARM64
/**
* bl2_plat_get_bl31_params() - prepare params for bl31.
*
@@ -83,8 +86,6 @@ static inline void raw_write_daif(unsigned int daif)
__asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory");
}
-typedef void (*atf_entry_t)(struct bl31_params *params, void *plat_params);
-
static void bl31_entry(uintptr_t bl31_entry, uintptr_t bl33_entry,
uintptr_t fdt_addr)
{
@@ -98,6 +99,83 @@ static void bl31_entry(uintptr_t bl31_entry, uintptr_t bl33_entry,
atf_entry((void *)bl31_params, (void *)fdt_addr);
}
+#else /* CONFIG_ARM64 */
+static struct bl31_params *bl2_plat_get_bl32_params(uintptr_t bl33_entry)
+{
+ 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 */
+ 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);
+
+ /* 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 r0) */
+ bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
+ bl33_ep_info->pc = bl33_entry;
+ bl33_ep_info->spsr = SPSR_MODE32(MODE32_hyp,
+ SPSR_T_ARM,
+#ifdef __ARMEB__
+ SPSR_E_BIG,
+#else
+ SPSR_E_LITTLE,
+#endif
+ 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;
+}
+
+static inline void raw_write_aif(unsigned int aif)
+{
+ unsigned int val;
+
+ val = get_cpsr();
+ val &= ~SPSR_EXCEPTION_MASK;
+ val |= aif;
+
+ __asm__ __volatile__("msr cpsr_c, %0\n\t" : : "r" (val) );
+}
+
+static void bl32_entry(uintptr_t bl32_entry, uintptr_t bl33_entry,
+ uintptr_t fdt_addr)
+{
+ struct bl31_params *bl31_params;
+ atf_entry_t atf_entry = (atf_entry_t)bl32_entry;
+
+ bl31_params = bl2_plat_get_bl32_params(bl33_entry);
+
+ raw_write_aif(SPSR_EXCEPTION_MASK);
+ dcache_disable();
+
+ atf_entry((void *)bl31_params, (void *)fdt_addr);
+}
+#endif /* CONFIG_ARM64 */
static int spl_fit_images_find_uboot(void *blob)
{
@@ -171,5 +249,9 @@ void spl_invoke_atf(struct spl_image_info *spl_image)
* We don't provide a BL3-2 entry yet, but this will be possible
* using similar logic.
*/
+#ifdef CONFIG_ARM64
bl31_entry(spl_image->entry_point, bl33_entry, platform_param);
+#else
+ bl32_entry(spl_image->entry_point, bl33_entry, platform_param);
+#endif
}
diff --git a/include/atf_common.h b/include/atf_common.h
index 3a7d40e5f0..9fdb190375 100644
--- a/include/atf_common.h
+++ b/include/atf_common.h
@@ -32,6 +32,8 @@
#define MODE_RW_64 0x0
#define MODE_RW_32 0x1
+#ifdef CONFIG_ARM64
+
#define MODE_EL_SHIFT 0x2
#define MODE_EL_MASK 0x3
#define MODE_EL3 0x3
@@ -66,6 +68,53 @@
#define DISABLE_ALL_EXECPTIONS \
(DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
+#else /* CONFIG_ARM64 */
+
+#define SPSR_E_SHIFT 9
+#define SPSR_E_MASK 0x1
+#define SPSR_E_LITTLE 0
+#define SPSR_E_BIG 1
+
+#define SPSR_T_SHIFT 5
+#define SPSR_T_MASK 0x1
+#define SPSR_T_ARM 0
+#define SPSR_T_THUMB 1
+
+#define MODE32_SHIFT 0
+#define MODE32_MASK 0xf
+#define MODE32_usr 0x0
+#define MODE32_fiq 0x1
+#define MODE32_irq 0x2
+#define MODE32_svc 0x3
+#define MODE32_mon 0x6
+#define MODE32_abt 0x7
+#define MODE32_hyp 0xa
+#define MODE32_und 0xb
+#define MODE32_sys 0xf
+
+#define SPSR_AIF_SHIFT 6
+#define SPSR_AIF_MASK 0x07
+
+#define SPSR_MODE32(mode, isa, endian, aif) \
+ (MODE_RW_32 << MODE_RW_SHIFT | \
+ ((mode) & MODE32_MASK) << MODE32_SHIFT | \
+ ((isa) & SPSR_T_MASK) << SPSR_T_SHIFT | \
+ ((endian) & SPSR_E_MASK) << SPSR_E_SHIFT | \
+ ((aif) & SPSR_AIF_MASK) << SPSR_AIF_SHIFT)
+
+#define SPSR_FIQ (1 << 6)
+#define SPSR_IRQ (1 << 7)
+#define SPSR_SERROR (1 << 8)
+#define SPSR_EXCEPTION_MASK (SPSR_FIQ | SPSR_IRQ | SPSR_SERROR)
+
+#define AIF_FIQ_BIT (1 << 0)
+#define AIF_IRQ_BIT (1 << 1)
+#define AIF_ABT_BIT (1 << 2)
+#define DISABLE_ALL_EXECPTIONS \
+ (AIF_FIQ_BIT | AIF_IRQ_BIT | AIF_ABT_BIT)
+
+#endif /* CONFIG_ARM64 */
+
#ifndef __ASSEMBLY__
/*******************************************************************************
@@ -152,6 +201,9 @@ struct image_desc {
* BL31 image information is mandatory if this structure is used. If either of
* the optional BL32 and BL33 image information is not provided, this is
* indicated by the respective image_info pointers being zero.
+ *
+ * In ARM32 mode BL31 image information is to be left empty and BL32
+ * information becomes mandatory.
******************************************************************************/
struct bl31_params {
struct param_header h;
--
2.20.1
More information about the U-Boot
mailing list