diff mbox series

[U-Boot,07/15] spl: atf: introduce spl_invoke_atf and make bl31_entry private

Message ID 1505330989-25602-8-git-send-email-philipp.tomsich@theobroma-systems.com
State Accepted
Delegated to: Philipp Tomsich
Headers show
Series [U-Boot,01/15] image: add IH_OS_ARM_TRUSTED_FIRMWARE for ARM Trusted Firmware | expand

Commit Message

Philipp Tomsich Sept. 13, 2017, 7:29 p.m. UTC
This adds a new interface spl_invoke_atf() that takes a spl_image_info
argument and then derives the necessary parameters for the ATF entry.
Based on the additional information recorded (into /fit-images) from
the FIT loadables, we can now easily locate the next boot stage.

We now pass a pointer to a FDT as the platform-specific parameter
pointer to ATF (so we don't run into the future headache of every
board/platform defining their own proprietary tag-structure), as
FDT access is already available in ATF.

With the necessary infrastructure in place, we can now update the
support for the ARM Trusted Firmware to dispatch into the
spl_invoke_atf function only if a IH_OS_ARM_TRUSTED_FIRMWARE image is
loaded.

Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
---

 common/spl/spl.c     | 11 +++----
 common/spl/spl_atf.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 82 insertions(+), 13 deletions(-)

Comments

Simon Glass Sept. 17, 2017, 5:53 p.m. UTC | #1
Hi Philipp,

On 13 September 2017 at 13:29, Philipp Tomsich
<philipp.tomsich@theobroma-systems.com> wrote:
> This adds a new interface spl_invoke_atf() that takes a spl_image_info
> argument and then derives the necessary parameters for the ATF entry.
> Based on the additional information recorded (into /fit-images) from
> the FIT loadables, we can now easily locate the next boot stage.
>
> We now pass a pointer to a FDT as the platform-specific parameter
> pointer to ATF (so we don't run into the future headache of every
> board/platform defining their own proprietary tag-structure), as
> FDT access is already available in ATF.
>
> With the necessary infrastructure in place, we can now update the
> support for the ARM Trusted Firmware to dispatch into the
> spl_invoke_atf function only if a IH_OS_ARM_TRUSTED_FIRMWARE image is
> loaded.
>
> Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
> ---
>
>  common/spl/spl.c     | 11 +++----
>  common/spl/spl_atf.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++-----
>  2 files changed, 82 insertions(+), 13 deletions(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

Please see question below

[..]

> index 6e8f928..63557c0 100644
> --- a/common/spl/spl_atf.c
> +++ b/common/spl/spl_atf.c
> @@ -5,6 +5,7 @@
>   * reserved.
>   * Copyright (C) 2016 Rockchip Electronic Co.,Ltd
>   * Written by Kever Yang <kever.yang@rock-chips.com>
> + * Copyright (C) 2017 Theobroma Systems Design und Consulting GmbH
>   *
>   * SPDX-License-Identifier:     BSD-3-Clause
>   */
> @@ -30,7 +31,7 @@ static struct bl31_params *bl2_to_bl31_params;
>   *
>   * @return bl31 params structure pointer
>   */
> -struct bl31_params *bl2_plat_get_bl31_params(void)
> +static struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl33_entry)
>  {
>         struct entry_point_info *bl33_ep_info;
>
> @@ -66,7 +67,7 @@ struct bl31_params *bl2_plat_get_bl31_params(void)
>
>         /* 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->pc = bl33_entry;
>         bl33_ep_info->spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
>                                      DISABLE_ALL_EXECPTIONS);
>
> @@ -77,21 +78,88 @@ struct bl31_params *bl2_plat_get_bl31_params(void)
>         return bl2_to_bl31_params;
>  }
>
> -void raw_write_daif(unsigned int daif)
> +static inline void raw_write_daif(unsigned int daif)
>  {
>         __asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory");
>  }
>
> -void bl31_entry(void)
> +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)
>  {
>         struct bl31_params *bl31_params;
> -       void (*entry)(struct bl31_params *params, void *plat_params) = NULL;
> +       atf_entry_t  atf_entry = (atf_entry_t)bl31_entry;
>
> -       bl31_params = bl2_plat_get_bl31_params();
> -       entry = (void *)CONFIG_SPL_ATF_TEXT_BASE;
> +       bl31_params = bl2_plat_get_bl31_params(bl33_entry);
>
>         raw_write_daif(SPSR_EXCEPTION_MASK);
>         dcache_disable();
>
> -       entry(bl31_params, NULL);
> +       atf_entry((void *)bl31_params, (void *)fdt_addr);
> +}
> +
> +static int spl_fit_images_find_uboot(void *blob)
> +{
> +       int parent, node, ndepth;
> +       const void *data;
> +
> +       if (!blob)
> +               return -FDT_ERR_BADMAGIC;
> +
> +       parent = fdt_path_offset(blob, "/fit-images");
> +       if (parent < 0)
> +               return -FDT_ERR_NOTFOUND;
> +
> +       for (node = fdt_next_node(blob, parent, &ndepth);
> +            (node >= 0) && (ndepth > 0);
> +            node = fdt_next_node(blob, node, &ndepth)) {
> +               if (ndepth != 1)
> +                       continue;
> +
> +               data = fdt_getprop(blob, node, FIT_OS_PROP, NULL);
> +               if (!data)
> +                       continue;
> +
> +               if (genimg_get_os_id(data) == IH_OS_U_BOOT)
> +                       return node;

How come this is in 'data' instead of the 'type' property?

Regards,
Simon
Philipp Tomsich Nov. 7, 2017, 9:30 a.m. UTC | #2
> On 17 Sep 2017, at 19:53, Simon Glass <sjg@chromium.org> wrote:
> 
> Hi Philipp,
> 
> On 13 September 2017 at 13:29, Philipp Tomsich
> <philipp.tomsich@theobroma-systems.com <mailto:philipp.tomsich@theobroma-systems.com>> wrote:
>> This adds a new interface spl_invoke_atf() that takes a spl_image_info
>> argument and then derives the necessary parameters for the ATF entry.
>> Based on the additional information recorded (into /fit-images) from
>> the FIT loadables, we can now easily locate the next boot stage.
>> 
>> We now pass a pointer to a FDT as the platform-specific parameter
>> pointer to ATF (so we don't run into the future headache of every
>> board/platform defining their own proprietary tag-structure), as
>> FDT access is already available in ATF.
>> 
>> With the necessary infrastructure in place, we can now update the
>> support for the ARM Trusted Firmware to dispatch into the
>> spl_invoke_atf function only if a IH_OS_ARM_TRUSTED_FIRMWARE image is
>> loaded.
>> 
>> Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
>> ---
>> 
>> common/spl/spl.c     | 11 +++----
>> common/spl/spl_atf.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++-----
>> 2 files changed, 82 insertions(+), 13 deletions(-)
> 
> Reviewed-by: Simon Glass <sjg@chromium.org <mailto:sjg@chromium.org>>
> 
> Please see question below
> 
> [..]
> 
>> index 6e8f928..63557c0 100644
>> --- a/common/spl/spl_atf.c
>> +++ b/common/spl/spl_atf.c
>> @@ -5,6 +5,7 @@
>>  * reserved.
>>  * Copyright (C) 2016 Rockchip Electronic Co.,Ltd
>>  * Written by Kever Yang <kever.yang@rock-chips.com <mailto:kever.yang@rock-chips.com>>
>> + * Copyright (C) 2017 Theobroma Systems Design und Consulting GmbH
>>  *
>>  * SPDX-License-Identifier:     BSD-3-Clause
>>  */
>> @@ -30,7 +31,7 @@ static struct bl31_params *bl2_to_bl31_params;
>>  *
>>  * @return bl31 params structure pointer
>>  */
>> -struct bl31_params *bl2_plat_get_bl31_params(void)
>> +static struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl33_entry)
>> {
>>        struct entry_point_info *bl33_ep_info;
>> 
>> @@ -66,7 +67,7 @@ struct bl31_params *bl2_plat_get_bl31_params(void)
>> 
>>        /* 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->pc = bl33_entry;
>>        bl33_ep_info->spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
>>                                     DISABLE_ALL_EXECPTIONS);
>> 
>> @@ -77,21 +78,88 @@ struct bl31_params *bl2_plat_get_bl31_params(void)
>>        return bl2_to_bl31_params;
>> }
>> 
>> -void raw_write_daif(unsigned int daif)
>> +static inline void raw_write_daif(unsigned int daif)
>> {
>>        __asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory");
>> }
>> 
>> -void bl31_entry(void)
>> +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)
>> {
>>        struct bl31_params *bl31_params;
>> -       void (*entry)(struct bl31_params *params, void *plat_params) = NULL;
>> +       atf_entry_t  atf_entry = (atf_entry_t)bl31_entry;
>> 
>> -       bl31_params = bl2_plat_get_bl31_params();
>> -       entry = (void *)CONFIG_SPL_ATF_TEXT_BASE;
>> +       bl31_params = bl2_plat_get_bl31_params(bl33_entry);
>> 
>>        raw_write_daif(SPSR_EXCEPTION_MASK);
>>        dcache_disable();
>> 
>> -       entry(bl31_params, NULL);
>> +       atf_entry((void *)bl31_params, (void *)fdt_addr);
>> +}
>> +
>> +static int spl_fit_images_find_uboot(void *blob)
>> +{
>> +       int parent, node, ndepth;
>> +       const void *data;
>> +
>> +       if (!blob)
>> +               return -FDT_ERR_BADMAGIC;
>> +
>> +       parent = fdt_path_offset(blob, "/fit-images");
>> +       if (parent < 0)
>> +               return -FDT_ERR_NOTFOUND;
>> +
>> +       for (node = fdt_next_node(blob, parent, &ndepth);
>> +            (node >= 0) && (ndepth > 0);
>> +            node = fdt_next_node(blob, node, &ndepth)) {
>> +               if (ndepth != 1)
>> +                       continue;
>> +
>> +               data = fdt_getprop(blob, node, FIT_OS_PROP, NULL);
>> +               if (!data)
>> +                       continue;
>> +
>> +               if (genimg_get_os_id(data) == IH_OS_U_BOOT)
>> +                       return node;
> 
> How come this is in 'data' instead of the 'type' property?

In fact it’s in FIT_OS_PROP (which expands to “os”).
Naming this variable ‘data' may have not been the best choice, but ‘prop’ didn’t
seem much better…

Regards,
Philipp.
Philipp Tomsich Nov. 23, 2017, 2:51 p.m. UTC | #3
> This adds a new interface spl_invoke_atf() that takes a spl_image_info
> argument and then derives the necessary parameters for the ATF entry.
> Based on the additional information recorded (into /fit-images) from
> the FIT loadables, we can now easily locate the next boot stage.
> 
> We now pass a pointer to a FDT as the platform-specific parameter
> pointer to ATF (so we don't run into the future headache of every
> board/platform defining their own proprietary tag-structure), as
> FDT access is already available in ATF.
> 
> With the necessary infrastructure in place, we can now update the
> support for the ARM Trusted Firmware to dispatch into the
> spl_invoke_atf function only if a IH_OS_ARM_TRUSTED_FIRMWARE image is
> loaded.
> 
> Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
> 
>  common/spl/spl.c     | 11 +++----
>  common/spl/spl_atf.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++-----
>  2 files changed, 82 insertions(+), 13 deletions(-)
> 

Applied to u-boot-rockchip, thanks!
Kever Yang Dec. 15, 2017, 3:14 a.m. UTC | #4
Hi Philipp,

     This patch use fdt_addr as plat_params, break the compatible with 
upstream

ATF, and get error:

"ERROR:   not expected type found 6410029648624618960"

The ATF do have a requirement for plat_params structure, and fdt_addr 
does not match this:

/* common header for all plat parameter type */
struct bl31_plat_param {
 >-------uint64_t type;
 >-------void *next;
};


Thanks,
- Kever

On 11/23/2017 10:51 PM, Philipp Tomsich wrote:
>> This adds a new interface spl_invoke_atf() that takes a spl_image_info
>> argument and then derives the necessary parameters for the ATF entry.
>> Based on the additional information recorded (into /fit-images) from
>> the FIT loadables, we can now easily locate the next boot stage.
>>
>> We now pass a pointer to a FDT as the platform-specific parameter
>> pointer to ATF (so we don't run into the future headache of every
>> board/platform defining their own proprietary tag-structure), as
>> FDT access is already available in ATF.
>>
>> With the necessary infrastructure in place, we can now update the
>> support for the ARM Trusted Firmware to dispatch into the
>> spl_invoke_atf function only if a IH_OS_ARM_TRUSTED_FIRMWARE image is
>> loaded.
>>
>> Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
>> Reviewed-by: Simon Glass <sjg@chromium.org>
>> ---
>>
>>   common/spl/spl.c     | 11 +++----
>>   common/spl/spl_atf.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++-----
>>   2 files changed, 82 insertions(+), 13 deletions(-)
>>
> Applied to u-boot-rockchip, thanks!
> _______________________________________________
> U-Boot mailing list
> U-Boot@lists.denx.de
> https://lists.denx.de/listinfo/u-boot
diff mbox series

Patch

diff --git a/common/spl/spl.c b/common/spl/spl.c
index 8b219ba..32198ef 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -410,6 +410,12 @@  void board_init_r(gd_t *dummy1, ulong dummy2)
 	case IH_OS_U_BOOT:
 		debug("Jumping to U-Boot\n");
 		break;
+#if CONFIG_IS_ENABLED(ATF)
+	case IH_OS_ARM_TRUSTED_FIRMWARE:
+		debug("Jumping to U-Boot via ARM Trusted Firmware\n");
+		spl_invoke_atf(&spl_image);
+		break;
+#endif
 #ifdef CONFIG_SPL_OS_BOOT
 	case IH_OS_LINUX:
 		debug("Jumping to Linux\n");
@@ -425,11 +431,6 @@  void board_init_r(gd_t *dummy1, ulong dummy2)
 	      gd->malloc_ptr / 1024);
 #endif
 
-	if (CONFIG_IS_ENABLED(ATF_SUPPORT)) {
-		debug("loaded - jumping to U-Boot via ATF BL31.\n");
-		bl31_entry();
-	}
-
 	debug("loaded - jumping to U-Boot...\n");
 #ifdef CONFIG_BOOTSTAGE_STASH
 	int ret;
diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c
index 6e8f928..63557c0 100644
--- a/common/spl/spl_atf.c
+++ b/common/spl/spl_atf.c
@@ -5,6 +5,7 @@ 
  * reserved.
  * Copyright (C) 2016 Rockchip Electronic Co.,Ltd
  * Written by Kever Yang <kever.yang@rock-chips.com>
+ * Copyright (C) 2017 Theobroma Systems Design und Consulting GmbH
  *
  * SPDX-License-Identifier:     BSD-3-Clause
  */
@@ -30,7 +31,7 @@  static struct bl31_params *bl2_to_bl31_params;
  *
  * @return bl31 params structure pointer
  */
-struct bl31_params *bl2_plat_get_bl31_params(void)
+static struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl33_entry)
 {
 	struct entry_point_info *bl33_ep_info;
 
@@ -66,7 +67,7 @@  struct bl31_params *bl2_plat_get_bl31_params(void)
 
 	/* 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->pc = bl33_entry;
 	bl33_ep_info->spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
 				     DISABLE_ALL_EXECPTIONS);
 
@@ -77,21 +78,88 @@  struct bl31_params *bl2_plat_get_bl31_params(void)
 	return bl2_to_bl31_params;
 }
 
-void raw_write_daif(unsigned int daif)
+static inline void raw_write_daif(unsigned int daif)
 {
 	__asm__ __volatile__("msr DAIF, %0\n\t" : : "r" (daif) : "memory");
 }
 
-void bl31_entry(void)
+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)
 {
 	struct bl31_params *bl31_params;
-	void (*entry)(struct bl31_params *params, void *plat_params) = NULL;
+	atf_entry_t  atf_entry = (atf_entry_t)bl31_entry;
 
-	bl31_params = bl2_plat_get_bl31_params();
-	entry = (void *)CONFIG_SPL_ATF_TEXT_BASE;
+	bl31_params = bl2_plat_get_bl31_params(bl33_entry);
 
 	raw_write_daif(SPSR_EXCEPTION_MASK);
 	dcache_disable();
 
-	entry(bl31_params, NULL);
+	atf_entry((void *)bl31_params, (void *)fdt_addr);
+}
+
+static int spl_fit_images_find_uboot(void *blob)
+{
+	int parent, node, ndepth;
+	const void *data;
+
+	if (!blob)
+		return -FDT_ERR_BADMAGIC;
+
+	parent = fdt_path_offset(blob, "/fit-images");
+	if (parent < 0)
+		return -FDT_ERR_NOTFOUND;
+
+	for (node = fdt_next_node(blob, parent, &ndepth);
+	     (node >= 0) && (ndepth > 0);
+	     node = fdt_next_node(blob, node, &ndepth)) {
+		if (ndepth != 1)
+			continue;
+
+		data = fdt_getprop(blob, node, FIT_OS_PROP, NULL);
+		if (!data)
+			continue;
+
+		if (genimg_get_os_id(data) == IH_OS_U_BOOT)
+			return node;
+	};
+
+	return -FDT_ERR_NOTFOUND;
+}
+
+uintptr_t spl_fit_images_get_entry(void *blob, int node)
+{
+	ulong  val;
+
+	val = fdt_getprop_u32(blob, node, "entry-point");
+	if (val == FDT_ERROR)
+		val = fdt_getprop_u32(blob, node, "load-addr");
+
+	debug("%s: entry point 0x%lx\n", __func__, val);
+	return val;
+}
+
+void spl_invoke_atf(struct spl_image_info *spl_image)
+{
+	uintptr_t  bl33_entry = CONFIG_SYS_TEXT_BASE;
+	void *blob = spl_image->fdt_addr;
+	int node;
+
+	/*
+	 * Find the U-Boot binary (in /fit-images) load addreess or
+	 * entry point (if different) and pass it as the BL3-3 entry
+	 * point.
+	 * This will need to be extended to support Falcon mode.
+	 */
+
+	node = spl_fit_images_find_uboot(blob);
+	if (node >= 0)
+		bl33_entry = spl_fit_images_get_entry(blob, node);
+
+	/*
+	 * We don't provide a BL3-2 entry yet, but this will be possible
+	 * using similar logic.
+	 */
+	bl31_entry(spl_image->entry_point, bl33_entry, (uintptr_t)blob);
 }