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 <[email protected]>
---
 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

_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to