* [PATCH 01/23] pbl: compressed-dtb: add missing includes
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 02/23] pbl: fdt: fix fdt_fixup_mem error handling Marco Felsch
` (21 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Add missing includes else compressed-dtb.h depends on the include order.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
include/compressed-dtb.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/compressed-dtb.h b/include/compressed-dtb.h
index cc5fbb2769847c0338a6e462e2d4bdd0d77f0174..ff7c932f5b01145cdad39e9d59f222b724b9f9d1 100644
--- a/include/compressed-dtb.h
+++ b/include/compressed-dtb.h
@@ -2,9 +2,11 @@
#ifndef COMPRESSED_DTB_H_
#define COMPRESSED_DTB_H_
+#include <linux/align.h>
#include <linux/types.h>
#include <linux/sizes.h>
#include <asm/unaligned.h>
+#include <fdt.h>
struct barebox_boarddata_compressed_dtb {
#define BAREBOX_BOARDDATA_COMPRESSED_DTB_MAGIC 0x7b66bcbd
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 02/23] pbl: fdt: fix fdt_fixup_mem error handling
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
2025-11-10 20:34 ` [PATCH 01/23] pbl: compressed-dtb: add missing includes Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 03/23] ARM: atf: add missing includes in atf_common.h Marco Felsch
` (20 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
fdt_find_or_add_memory() returns >= 0 on success, so the return must be
checked to be < 0. Also fix the following pr_warn() which used the wrong
variable.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
pbl/fdt.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pbl/fdt.c b/pbl/fdt.c
index c9820112c6442b65d4f462c93b6847442097c5ab..ac377446caeafb1beaeb211aa8bdec8767ae21fe 100644
--- a/pbl/fdt.c
+++ b/pbl/fdt.c
@@ -128,9 +128,9 @@ int fdt_fixup_mem(void *fdt, unsigned long membase[], unsigned long memsize[],
snprintf(name, sizeof(name), "memory@%lx", base);
node = fdt_find_or_add_memory(fdt, root, name);
- if (!node) {
+ if (node < 0) {
pr_warn("%s: Failed to get node: %s\n",
- name, fdt_strerror(err));
+ name, fdt_strerror(node));
continue;
}
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 03/23] ARM: atf: add missing includes in atf_common.h
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
2025-11-10 20:34 ` [PATCH 01/23] pbl: compressed-dtb: add missing includes Marco Felsch
2025-11-10 20:34 ` [PATCH 02/23] pbl: fdt: fix fdt_fixup_mem error handling Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 04/23] ARM: i.MX8M: add support to pass DT via imx8m{m,n,q,p}_load_and_start_image_via_tfa() Marco Felsch
` (19 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Add missing includes else atf_common.h depends on the include order.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/include/asm/atf_common.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/include/asm/atf_common.h b/arch/arm/include/asm/atf_common.h
index ab99cd3ac1428c0dda0b9d6841a721119d45e301..11d3801da1cc171cf1601163712203b3c7089c6f 100644
--- a/arch/arm/include/asm/atf_common.h
+++ b/arch/arm/include/asm/atf_common.h
@@ -11,6 +11,9 @@
#ifndef __BL_COMMON_H__
#define __BL_COMMON_H__
+#include <linux/sizes.h>
+#include <linux/types.h>
+
#define ATF_PARAM_EP 0x01
#define ATF_PARAM_IMAGE_BINARY 0x02
#define ATF_PARAM_BL31 0x03
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 04/23] ARM: i.MX8M: add support to pass DT via imx8m{m,n,q,p}_load_and_start_image_via_tfa()
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (2 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 03/23] ARM: atf: add missing includes in atf_common.h Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 05/23] ARM: i.MX8M: cosmetic cleanup Marco Felsch
` (18 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
The internal barebox DTB isn't passed to other BL3x stages albeit it can
be very useful, e.g. OP-TEE (as BL32) could parse the memory
configuration from the DTB.
Extending the common TF-A (ATF) loader helpers is the first step to be
able to pass the board DTB to other BL3x firmware images.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/boards/congatec-qmx8p/lowlevel.c | 6 +++---
arch/arm/boards/innocomm-imx8mm-wb15/lowlevel.c | 2 +-
arch/arm/boards/karo-qsxp-ml81/lowlevel.c | 2 +-
arch/arm/boards/mnt-reform/lowlevel.c | 2 +-
arch/arm/boards/nxp-imx8mm-evk/lowlevel.c | 15 +++++++++-----
arch/arm/boards/nxp-imx8mn-evk/lowlevel.c | 11 ++++++----
arch/arm/boards/nxp-imx8mp-evk/lowlevel.c | 2 +-
arch/arm/boards/nxp-imx8mq-evk/lowlevel.c | 2 +-
arch/arm/boards/phytec-som-imx8mm/lowlevel.c | 2 +-
arch/arm/boards/phytec-som-imx8mq/lowlevel.c | 2 +-
arch/arm/boards/polyhex-debix/lowlevel.c | 6 +++---
arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c | 2 +-
arch/arm/boards/skov-imx8mp/lowlevel.c | 6 +++---
arch/arm/boards/tqma8mpxl/lowlevel.c | 2 +-
.../variscite-dt8mcustomboard-imx8mp/lowlevel.c | 2 +-
arch/arm/boards/zii-imx8mq-dev/lowlevel.c | 21 ++++++++++---------
arch/arm/mach-imx/atf.c | 24 +++++++++++-----------
include/mach/imx/xload.h | 16 +++++++--------
18 files changed, 67 insertions(+), 58 deletions(-)
diff --git a/arch/arm/boards/congatec-qmx8p/lowlevel.c b/arch/arm/boards/congatec-qmx8p/lowlevel.c
index 1889b9bb3318a2cfc4d31cabbe0476060cfeae22..fb969bcf9c0330c22134a20f21893041174316a7 100644
--- a/arch/arm/boards/congatec-qmx8p/lowlevel.c
+++ b/arch/arm/boards/congatec-qmx8p/lowlevel.c
@@ -87,7 +87,7 @@ static void power_init_board(void)
extern struct dram_timing_info dram_timing_4g;
-static void start_tfa(void)
+static void start_tfa(char dtb[])
{
/*
* If we are in EL3 we are running for the first time and need to
@@ -102,14 +102,14 @@ static void start_tfa(void)
imx8mp_ddr_init(&dram_timing_4g, DRAM_TYPE_LPDDR4);
- imx8mp_load_and_start_image_via_tfa();
+ imx8mp_load_and_start_image_via_tfa(dtb);
}
static __noreturn noinline void congatec_qmx8p_start(char dtb[])
{
setup_uart();
- start_tfa();
+ start_tfa(dtb);
/*
* Standard entry we hit once we initialized both DDR and ATF
diff --git a/arch/arm/boards/innocomm-imx8mm-wb15/lowlevel.c b/arch/arm/boards/innocomm-imx8mm-wb15/lowlevel.c
index a779c1f0ac1919cf024c8a5bd7f692b6caee6e38..fe25d74cd423235af399dd62c71255852f71b167 100644
--- a/arch/arm/boards/innocomm-imx8mm-wb15/lowlevel.c
+++ b/arch/arm/boards/innocomm-imx8mm-wb15/lowlevel.c
@@ -92,7 +92,7 @@ ENTRY_FUNCTION(start_innocomm_wb15_evk, r0, r1, r2)
imx8mm_ddr_init(&innocomm_wb15_dram_timing, DRAM_TYPE_LPDDR4);
- imx8mm_load_and_start_image_via_tfa();
+ imx8mm_load_and_start_image_via_tfa(__dtb_z_imx8mm_innocomm_wb15_evk_start);
}
/* Standard entry we hit once we initialized both DDR and ATF */
diff --git a/arch/arm/boards/karo-qsxp-ml81/lowlevel.c b/arch/arm/boards/karo-qsxp-ml81/lowlevel.c
index 506a9c9930e5b27c4de40504f5e9dbb59805c7ed..fba57446173257222a61c5cb8fd7cd9f2a13779a 100644
--- a/arch/arm/boards/karo-qsxp-ml81/lowlevel.c
+++ b/arch/arm/boards/karo-qsxp-ml81/lowlevel.c
@@ -94,7 +94,7 @@ ENTRY_FUNCTION(start_karo_qsxp_ml81, r0, r1, r2)
imx8mp_ddr_init(&karo_qsxp_ml81_dram_timing, DRAM_TYPE_LPDDR4);
- imx8mp_load_and_start_image_via_tfa();
+ imx8mp_load_and_start_image_via_tfa(__dtb_z_imx8mp_karo_qsxp_ml81_qsbase4_start);
}
/* Standard entry we hit once we initialized both DDR and ATF */
diff --git a/arch/arm/boards/mnt-reform/lowlevel.c b/arch/arm/boards/mnt-reform/lowlevel.c
index 9f951508dfdd5fba5d980a7ebd5538731a2f58fa..de54f3cd7212f9d6f2fae1f7cd3bc2b6b41b2ecb 100644
--- a/arch/arm/boards/mnt-reform/lowlevel.c
+++ b/arch/arm/boards/mnt-reform/lowlevel.c
@@ -123,7 +123,7 @@ static __noreturn noinline void mnt_reform_start(void)
imx8mq_ddr_init(&mnt_reform_dram_timing, DRAM_TYPE_LPDDR4);
- imx8mq_load_and_start_image_via_tfa();
+ imx8mq_load_and_start_image_via_tfa(__dtb_z_imx8mq_mnt_reform2_start);
}
/*
diff --git a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
index 881d8285b60ef0d2e0ca408f6847a18d17dbe5d4..7dbcfdc878eb855d6d54b35c8e9fefd3689e565a 100644
--- a/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mm-evk/lowlevel.c
@@ -21,6 +21,10 @@
#include <mach/imx/xload.h>
#include <soc/imx8m/ddr.h>
+extern char __dtb_z_imx8mm_evk_start[];
+extern char __dtb_z_imx8mm_evkb_start[];
+static void *fdt;
+
#define UART_PAD_CTRL MUX_PAD_CTRL(PAD_CTL_DSE_3P3V_45_OHM)
static void setup_uart(void)
@@ -87,10 +91,13 @@ static void power_init_board(void)
i2c = imx8m_i2c_early_init(IOMEM(MX8MQ_I2C1_BASE_ADDR));
- if (i2c_dev_probe(i2c, 0x25, true) == 0)
+ if (i2c_dev_probe(i2c, 0x25, true) == 0) {
pmic_configure(i2c, 0x25, pca9450_cfg, ARRAY_SIZE(pca9450_cfg));
- else
+ fdt = __dtb_z_imx8mm_evkb_start;
+ } else {
pmic_configure(i2c, 0x4b, bd71837_cfg, ARRAY_SIZE(bd71837_cfg));
+ fdt = __dtb_z_imx8mm_evk_start;
+ }
}
extern struct dram_timing_info imx8mm_evk_dram_timing;
@@ -109,7 +116,7 @@ static void start_atf(void)
power_init_board();
imx8mm_ddr_init(&imx8mm_evk_dram_timing, DRAM_TYPE_LPDDR4);
- imx8mm_load_and_start_image_via_tfa();
+ imx8mm_load_and_start_image_via_tfa(fdt);
}
/*
@@ -130,9 +137,7 @@ static void start_atf(void)
*/
static __noreturn noinline void nxp_imx8mm_evk_start(void)
{
- extern char __dtb_z_imx8mm_evk_start[], __dtb_z_imx8mm_evkb_start[];
struct pbl_i2c *i2c;
- void *fdt;
setup_uart();
diff --git a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
index a1a501b1d962c202be5bb06bb20a2743728eb642..032c2421693614aa0e0eaabccf9482c8cd22bca8 100644
--- a/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mn-evk/lowlevel.c
@@ -25,6 +25,10 @@
#include <mfd/bd71837.h>
#include <soc/imx8m/ddr.h>
+extern char __dtb_z_imx8mn_evk_start[];
+extern char __dtb_z_imx8mn_ddr4_evk_start[];
+static void *fdt;
+
static void setup_uart(void)
{
void __iomem *uart = IOMEM(MX8M_UART2_BASE_ADDR);
@@ -104,12 +108,14 @@ static void start_atf(void)
if (i2c_dev_probe(i2c, 0x25, true) == 0) {
pmic_configure(i2c, 0x25, pca9450_cfg, ARRAY_SIZE(pca9450_cfg));
imx8mn_ddr_init(&imx8mn_evk_lpddr4_timing, DRAM_TYPE_LPDDR4);
+ fdt = __dtb_z_imx8mn_evk_start;
} else {
pmic_configure(i2c, 0x4b, bd71837_cfg, ARRAY_SIZE(bd71837_cfg));
imx8mn_ddr_init(&imx8mn_evk_ddr4_timing, DRAM_TYPE_DDR4);
+ fdt = __dtb_z_imx8mn_ddr4_evk_start;
}
- imx8mn_load_and_start_image_via_tfa();
+ imx8mn_load_and_start_image_via_tfa(fdt);
}
/*
@@ -130,9 +136,6 @@ static void start_atf(void)
*/
static __noreturn noinline void nxp_imx8mn_evk_start(void)
{
- extern char __dtb_z_imx8mn_evk_start[], __dtb_z_imx8mn_ddr4_evk_start[];
- void *fdt;
-
setup_uart();
start_atf();
diff --git a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
index 969947d2ec4ec23a092c58de6c683a5d655640b9..5e0cab38235966503e402f519d251e9cb6c96fe7 100644
--- a/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mp-evk/lowlevel.c
@@ -103,7 +103,7 @@ static void start_atf(void)
imx8mp_ddr_init(&imx8mp_evk_dram_timing, DRAM_TYPE_LPDDR4);
- imx8mp_load_and_start_image_via_tfa();
+ imx8mp_load_and_start_image_via_tfa(__dtb_z_imx8mp_evk_start);
}
/*
diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
index d1a517dddbd93aee33e27b012d3287cfde1ea017..861664f94fd52c7f4e3ea27538d6d7f2600b8cc4 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
@@ -67,7 +67,7 @@ static __noreturn noinline void nxp_imx8mq_evk_start(void)
if (current_el() == 3) {
ddr_init();
- imx8mq_load_and_start_image_via_tfa();
+ imx8mq_load_and_start_image_via_tfa(__dtb_z_imx8mq_evk_start);
}
/*
diff --git a/arch/arm/boards/phytec-som-imx8mm/lowlevel.c b/arch/arm/boards/phytec-som-imx8mm/lowlevel.c
index 26f0f4d3e12e3c467c86deb5b9a1f921fcc43eb5..835bb66d659ab60c0e0c449c0d1b6ece9650a522 100644
--- a/arch/arm/boards/phytec-som-imx8mm/lowlevel.c
+++ b/arch/arm/boards/phytec-som-imx8mm/lowlevel.c
@@ -110,7 +110,7 @@ static void start_phyboard_polis_rdk_common(enum phytec_imx8m_ddr_size size)
phyboard_polis_rdk_ddr_init(size);
- imx8mm_load_and_start_image_via_tfa();
+ imx8mm_load_and_start_image_via_tfa(__dtb_z_imx8mm_phyboard_polis_rdk_start);
}
/* Standard entry we hit once we initialized both DDR and ATF */
diff --git a/arch/arm/boards/phytec-som-imx8mq/lowlevel.c b/arch/arm/boards/phytec-som-imx8mq/lowlevel.c
index 362b3ed823c1337a84fc653e0334f3fb859ad723..7ec05c3d01e9fa4c86f4b70bdea6f09b53caf441 100644
--- a/arch/arm/boards/phytec-som-imx8mq/lowlevel.c
+++ b/arch/arm/boards/phytec-som-imx8mq/lowlevel.c
@@ -65,7 +65,7 @@ static __noreturn noinline void phytec_phycore_imx8mq_start(void)
* loadting ATF blob again
*/
if (current_el() == 3)
- imx8mq_load_and_start_image_via_tfa();
+ imx8mq_load_and_start_image_via_tfa(__dtb_z_imx8mq_phytec_phycore_som_start);
/*
* Standard entry we hit once we initialized both DDR and ATF
diff --git a/arch/arm/boards/polyhex-debix/lowlevel.c b/arch/arm/boards/polyhex-debix/lowlevel.c
index fa49fcb5c1430617d8b2cce5c5d3024e5ff95452..707287100e30a6d6a2f75afcd93f2e56a2c126cb 100644
--- a/arch/arm/boards/polyhex-debix/lowlevel.c
+++ b/arch/arm/boards/polyhex-debix/lowlevel.c
@@ -84,7 +84,7 @@ static void power_init_board(void)
extern struct dram_timing_info imx8mp_debix_dram_timing;
extern struct dram_timing_info imx8mp_debix_8g_dram_timing;
-static void start_atf(struct dram_timing_info *dram_timing)
+static void start_atf(struct dram_timing_info *dram_timing, void *dtb)
{
/*
* If we are in EL3 we are running for the first time and need to
@@ -100,7 +100,7 @@ static void start_atf(struct dram_timing_info *dram_timing)
imx8mp_ddr_init(dram_timing, DRAM_TYPE_LPDDR4);
- imx8mp_load_and_start_image_via_tfa();
+ imx8mp_load_and_start_image_via_tfa(dtb);
}
/*
@@ -124,7 +124,7 @@ imx8mp_debix_start(struct dram_timing_info *dram_timing, void *dtb)
{
setup_uart();
- start_atf(dram_timing);
+ start_atf(dram_timing, dtb);
/*
* Standard entry we hit once we initialized both DDR and ATF
diff --git a/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c b/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c
index 711316ae4be71134e45537019fc8cdc61cec8969..f040509a0f7c1f4fcd70dc9296e4709b565bc8a6 100644
--- a/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c
+++ b/arch/arm/boards/protonic-imx8m/lowlevel-prt8mm.c
@@ -49,7 +49,7 @@ static void start_atf(void)
imx8mm_ddr_init(&prt8mm_dram_timing, DRAM_TYPE_LPDDR4);
- imx8mm_load_and_start_image_via_tfa();
+ imx8mm_load_and_start_image_via_tfa(__dtb_z_imx8mm_prt8mm_start);
}
/*
diff --git a/arch/arm/boards/skov-imx8mp/lowlevel.c b/arch/arm/boards/skov-imx8mp/lowlevel.c
index 1fd665d676753ed1210dc82b98e40adf24f0e5a0..7859240eec10b2d3f8d351c04966fc68045d8b55 100644
--- a/arch/arm/boards/skov-imx8mp/lowlevel.c
+++ b/arch/arm/boards/skov-imx8mp/lowlevel.c
@@ -149,7 +149,7 @@ static void power_init_board(void)
extern struct dram_timing_info imx8mp_skov_dram_timing;
-static void start_atf(struct dram_timing_info *dram_timing)
+static void start_atf(struct dram_timing_info *dram_timing, void *dtb)
{
/*
* If we are in EL3 we are running for the first time and need to
@@ -165,7 +165,7 @@ static void start_atf(struct dram_timing_info *dram_timing)
imx8mp_ddr_init(dram_timing, DRAM_TYPE_LPDDR4);
- imx8mp_load_and_start_image_via_tfa();
+ imx8mp_load_and_start_image_via_tfa(dtb);
}
/*
@@ -189,7 +189,7 @@ imx8mp_skov_start(struct dram_timing_info *dram_timing, void *dtb)
{
setup_uart();
- start_atf(dram_timing);
+ start_atf(dram_timing, dtb);
/*
* Standard entry we hit once we initialized both DDR and ATF
diff --git a/arch/arm/boards/tqma8mpxl/lowlevel.c b/arch/arm/boards/tqma8mpxl/lowlevel.c
index e0a0f17d3aa43435ba46c55f5609aabd1abf4300..4ab3bd934aab30b925f4496ae6883a71348053f0 100644
--- a/arch/arm/boards/tqma8mpxl/lowlevel.c
+++ b/arch/arm/boards/tqma8mpxl/lowlevel.c
@@ -96,7 +96,7 @@ static __noreturn noinline void tqma8mpxl_start(void)
imx8mp_ddr_init(&dram_timing_2gb_no_ecc, DRAM_TYPE_LPDDR4);
- imx8mp_load_and_start_image_via_tfa();
+ imx8mp_load_and_start_image_via_tfa(__dtb_z_imx8mp_tqma8mpql_mba8mpxl_start);
}
imx8mp_barebox_entry(__dtb_z_imx8mp_tqma8mpql_mba8mpxl_start);
diff --git a/arch/arm/boards/variscite-dt8mcustomboard-imx8mp/lowlevel.c b/arch/arm/boards/variscite-dt8mcustomboard-imx8mp/lowlevel.c
index c9907ebf0a35597798a3b5d073e750ae2d6d8fdf..96869e86ed8f48de821eafe0882c2a78cb0aae3d 100644
--- a/arch/arm/boards/variscite-dt8mcustomboard-imx8mp/lowlevel.c
+++ b/arch/arm/boards/variscite-dt8mcustomboard-imx8mp/lowlevel.c
@@ -95,7 +95,7 @@ static void start_atf(void)
imx8mp_ddr_init(&var_dart_imx8mp_dram_timing, DRAM_TYPE_LPDDR4);
- imx8mp_load_and_start_image_via_tfa();
+ imx8mp_load_and_start_image_via_tfa(__dtb_z_imx8mp_var_dart_dt8mcustomboard_start);
}
static __noreturn noinline void variscite_imx8mp_dart_cb_start(void)
diff --git a/arch/arm/boards/zii-imx8mq-dev/lowlevel.c b/arch/arm/boards/zii-imx8mq-dev/lowlevel.c
index 4184748cd858848df3d47a2e01f2bbaa86934202..53cdf52562991932656015a8ebf9f0a311e9ef5d 100644
--- a/arch/arm/boards/zii-imx8mq-dev/lowlevel.c
+++ b/arch/arm/boards/zii-imx8mq-dev/lowlevel.c
@@ -122,16 +122,6 @@ static __noreturn noinline void zii_imx8mq_dev_start(void)
*/
zii_imx8mq_dev_sram_setup();
}
- /*
- * Straight from the power-on we are at EL3, so the following
- * code _will_ load and jump to ATF.
- *
- * However when we are re-executed upon exit from ATF's
- * initialization routine, it is EL2 which means we'll skip
- * loadting ATF blob again
- */
- if (current_el() == 3)
- imx8mq_load_and_start_image_via_tfa();
system_type = get_system_type();
@@ -153,6 +143,17 @@ static __noreturn noinline void zii_imx8mq_dev_start(void)
break;
}
+ /*
+ * Straight from the power-on we are at EL3, so the following
+ * code _will_ load and jump to ATF.
+ *
+ * However when we are re-executed upon exit from ATF's
+ * initialization routine, it is EL2 which means we'll skip
+ * loadting ATF blob again
+ */
+ if (current_el() == 3)
+ imx8mq_load_and_start_image_via_tfa(fdt);
+
/*
* Standard entry we hit once we initialized both DDR and ATF
*/
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index 11fe0334059d104a003ee084c618ff6f0d66ea3c..42ab9e9a23e433c50a1df1739d0163049174e6a6 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -141,12 +141,12 @@ static void imx_adjust_optee_memory(void **bl32, void **bl32_image, size_t *bl32
*bl32_image += sizeof(*hdr);
}
-__noreturn void imx8mm_load_and_start_image_via_tfa(void)
+__noreturn void imx8mm_load_and_start_image_via_tfa(void *fdt)
{
- __imx8mm_load_and_start_image_via_tfa((void *)MX8M_ATF_BL33_BASE_ADDR);
+ __imx8mm_load_and_start_image_via_tfa(fdt, (void *)MX8M_ATF_BL33_BASE_ADDR);
}
-__noreturn void __imx8mm_load_and_start_image_via_tfa(void *bl33)
+__noreturn void __imx8mm_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
@@ -215,12 +215,12 @@ void imx8mp_load_bl33(void *bl33)
memcpy(bl33, __image_start, barebox_pbl_size);
}
-__noreturn void imx8mp_load_and_start_image_via_tfa(void)
+__noreturn void imx8mp_load_and_start_image_via_tfa(void *fdt)
{
- __imx8mp_load_and_start_image_via_tfa((void *)MX8M_ATF_BL33_BASE_ADDR);
+ __imx8mp_load_and_start_image_via_tfa(fdt, (void *)MX8M_ATF_BL33_BASE_ADDR);
}
-__noreturn void __imx8mp_load_and_start_image_via_tfa(void *bl33)
+__noreturn void __imx8mp_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
@@ -290,12 +290,12 @@ void imx8mn_load_bl33(void *bl33)
memcpy(bl33, __image_start, barebox_pbl_size);
}
-__noreturn void imx8mn_load_and_start_image_via_tfa(void)
+__noreturn void imx8mn_load_and_start_image_via_tfa(void *fdt)
{
- __imx8mn_load_and_start_image_via_tfa((void *)MX8M_ATF_BL33_BASE_ADDR);
+ __imx8mn_load_and_start_image_via_tfa(fdt, (void *)MX8M_ATF_BL33_BASE_ADDR);
}
-__noreturn void __imx8mn_load_and_start_image_via_tfa(void *bl33)
+__noreturn void __imx8mn_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
@@ -358,12 +358,12 @@ void imx8mq_load_bl33(void *bl33)
memcpy(bl33, __image_start, barebox_pbl_size);
}
-__noreturn void imx8mq_load_and_start_image_via_tfa(void)
+__noreturn void imx8mq_load_and_start_image_via_tfa(void *fdt)
{
- __imx8mq_load_and_start_image_via_tfa((void *)MX8M_ATF_BL33_BASE_ADDR);
+ __imx8mq_load_and_start_image_via_tfa(fdt, (void *)MX8M_ATF_BL33_BASE_ADDR);
}
-__noreturn void __imx8mq_load_and_start_image_via_tfa(void *bl33)
+__noreturn void __imx8mq_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
diff --git a/include/mach/imx/xload.h b/include/mach/imx/xload.h
index 396c728547614091fc710de50dc1583c6b6e2a68..749b936cb840373d1a3905620ee8dabdf84e8d32 100644
--- a/include/mach/imx/xload.h
+++ b/include/mach/imx/xload.h
@@ -29,14 +29,14 @@ void imx8mn_load_bl33(void *bl33);
void imx8mp_load_bl33(void *bl33);
void imx8mq_load_bl33(void *bl33);
-void __noreturn imx8mm_load_and_start_image_via_tfa(void);
-void __noreturn imx8mn_load_and_start_image_via_tfa(void);
-void __noreturn imx8mp_load_and_start_image_via_tfa(void);
-void __noreturn imx8mq_load_and_start_image_via_tfa(void);
-void __noreturn __imx8mm_load_and_start_image_via_tfa(void *bl33);
-void __noreturn __imx8mn_load_and_start_image_via_tfa(void *bl33);
-void __noreturn __imx8mp_load_and_start_image_via_tfa(void *bl33);
-void __noreturn __imx8mq_load_and_start_image_via_tfa(void *bl33);
+void __noreturn imx8mm_load_and_start_image_via_tfa(void *fdt);
+void __noreturn imx8mn_load_and_start_image_via_tfa(void *fdt);
+void __noreturn imx8mp_load_and_start_image_via_tfa(void *fdt);
+void __noreturn imx8mq_load_and_start_image_via_tfa(void *fdt);
+void __noreturn __imx8mm_load_and_start_image_via_tfa(void *fdt, void *bl33);
+void __noreturn __imx8mn_load_and_start_image_via_tfa(void *fdt, void *bl33);
+void __noreturn __imx8mp_load_and_start_image_via_tfa(void *fdt, void *bl33);
+void __noreturn __imx8mq_load_and_start_image_via_tfa(void *fdt, void *bl33);
void __noreturn imx93_load_and_start_image_via_tfa(void);
void __noreturn __imx93_load_and_start_image_via_tfa(void *bl33);
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 05/23] ARM: i.MX8M: cosmetic cleanup
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (3 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 04/23] ARM: i.MX8M: add support to pass DT via imx8m{m,n,q,p}_load_and_start_image_via_tfa() Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 06/23] ARM: i.MX8M: move BL32 setup into imx8m_tfa_start_bl31() Marco Felsch
` (17 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Rename the local imx8m_atf_start_bl31() to imx8m_tfa_start_bl31() since
the official naming is Trusted-Firmware A (TF-A) and not ARM Trusted
Firmware which was the former name.
While on it rename the parameters to make it clear what firmware
component is passed and align the function documentation with the
reality.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/atf.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index 42ab9e9a23e433c50a1df1739d0163049174e6a6..dd861f1ad87c98c8baffa2986aeef40eacedc88c 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -19,11 +19,11 @@
#include <mach/imx/xload.h>
/**
- * imx8m_atf_load_bl31 - Load ATF BL31 blob and transfer control to it
+ * imx8m_tfa_start_bl31 - Load TF-A BL31 blob and transfer control to it
*
- * @fw: Pointer to the BL31 blob
- * @fw_size: Size of the BL31 blob
- * @atf_dest: Place where the BL31 is copied to and executed
+ * @tfa: Pointer to the BL31 blob
+ * @tfa_size: Size of the BL31 blob
+ * @tfa_dest: Place where the BL31 is copied to and executed
*
* This function:
*
@@ -37,12 +37,12 @@
* 3. Transfers control to BL31
*/
-static __noreturn void imx8m_atf_start_bl31(const void *fw, size_t fw_size, void *atf_dest)
+static __noreturn void imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size, void *tfa_dest)
{
- void __noreturn (*bl31)(void) = atf_dest;
+ void __noreturn (*bl31)(void) = tfa_dest;
int ret;
- BUG_ON(fw_size > MX8M_ATF_BL31_SIZE_LIMIT);
+ BUG_ON(tfa_size > MX8M_ATF_BL31_SIZE_LIMIT);
if (IS_ENABLED(CONFIG_FSL_CAAM_RNG_PBL_INIT)) {
ret = imx_early_caam_init(MX8M_CAAM_BASE_ADDR);
@@ -52,10 +52,10 @@ static __noreturn void imx8m_atf_start_bl31(const void *fw, size_t fw_size, void
pr_debug("CAAM early init successful\n");
}
- memcpy(bl31, fw, fw_size);
+ memcpy(bl31, tfa_bin, tfa_size);
asm volatile("msr sp_el2, %0" : :
- "r" (atf_dest - 16) :
+ "r" (tfa_dest - 16) :
"cc");
bl31();
__builtin_unreachable();
@@ -176,7 +176,7 @@ __noreturn void __imx8mm_load_and_start_image_via_tfa(void *fdt, void *bl33)
get_builtin_firmware(imx8mm_bl31_bin, &bl31, &bl31_size);
}
- imx8m_atf_start_bl31(bl31, bl31_size, (void *)MX8MM_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MM_ATF_BL31_BASE_ADDR);
}
void imx8mp_load_bl33(void *bl33)
@@ -250,10 +250,9 @@ __noreturn void __imx8mp_load_and_start_image_via_tfa(void *fdt, void *bl33)
get_builtin_firmware(imx8mp_bl31_bin, &bl31, &bl31_size);
}
- imx8m_atf_start_bl31(bl31, bl31_size, (void *)MX8MP_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MP_ATF_BL31_BASE_ADDR);
}
-
void imx8mn_load_bl33(void *bl33)
{
enum bootsource src;
@@ -325,7 +324,7 @@ __noreturn void __imx8mn_load_and_start_image_via_tfa(void *fdt, void *bl33)
get_builtin_firmware(imx8mn_bl31_bin, &bl31, &bl31_size);
}
- imx8m_atf_start_bl31(bl31, bl31_size, (void *)MX8MN_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MN_ATF_BL31_BASE_ADDR);
}
void imx8mq_load_bl33(void *bl33)
@@ -393,7 +392,7 @@ __noreturn void __imx8mq_load_and_start_image_via_tfa(void *fdt, void *bl33)
get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size);
}
- imx8m_atf_start_bl31(bl31, bl31_size, (void *)MX8MQ_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MQ_ATF_BL31_BASE_ADDR);
}
void __noreturn imx93_load_and_start_image_via_tfa(void)
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 06/23] ARM: i.MX8M: move BL32 setup into imx8m_tfa_start_bl31()
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (4 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 05/23] ARM: i.MX8M: cosmetic cleanup Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 07/23] ARM: i.MX8M: imx8m_tfa_start_bl31() add support for bl33 and fdt Marco Felsch
` (16 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Each i.MX8M platform repeated the same pattern for loading the optional
BL32 image because of the firmware name handling and the BL32 location
(end of memory).
The firmware name handling can't be generalized without change the logic
to function-like macros but the rest can be handled within the common
imx8m_tfa_start_bl31() function. While on it the commit adds a sanity
check that the BL32 image size is > 0.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/atf.c | 154 ++++++++++++++++++++++--------------------------
1 file changed, 72 insertions(+), 82 deletions(-)
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index dd861f1ad87c98c8baffa2986aeef40eacedc88c..531ded2c57b1f194a2f209161ea086f41fccf58f 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -18,30 +18,77 @@
#include <mach/imx/ele.h>
#include <mach/imx/xload.h>
+static void imx_adjust_optee_memory(void **bl32, void **bl32_image, size_t *bl32_size)
+{
+ struct optee_header *hdr = *bl32_image;
+ u64 membase;
+
+ if (optee_verify_header(hdr))
+ return;
+
+ imx_scratch_save_optee_hdr(hdr);
+
+ membase = (u64)hdr->init_load_addr_hi << 32;
+ membase |= hdr->init_load_addr_lo;
+
+ *bl32 = (void *)membase;
+ *bl32_size -= sizeof(*hdr);
+ *bl32_image += sizeof(*hdr);
+}
+
/**
* imx8m_tfa_start_bl31 - Load TF-A BL31 blob and transfer control to it
*
* @tfa: Pointer to the BL31 blob
* @tfa_size: Size of the BL31 blob
* @tfa_dest: Place where the BL31 is copied to and executed
+ * @tee: Pointer to the optional BL32 blob
+ * @tee_size: Size of the optional BL32 blob
*
* This function:
*
- * 1. Copies built-in BL31 blob to an address i.MX8M's BL31
+ * 1. Copies built-in BL32 blob (if any) to the well-known OP-TEE address
+ * (end of RAM) or the address specified via the OP-TEE v2 header if
+ * found.
+ *
+ * 2. Copies built-in BL31 blob to an address i.MX8M's BL31
* expects to be placed (TF-A v2.8+ is position-independent)
*
- * 2. Sets up temporary stack pointer for EL2, which is execution
+ * 3. Sets up temporary stack pointer for EL2, which is execution
* level that BL31 will drop us off at after it completes its
* initialization routine
*
- * 3. Transfers control to BL31
+ * 4. Transfers control to BL31
*/
-static __noreturn void imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size, void *tfa_dest)
+static __noreturn void
+imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size, void *tfa_dest,
+ void *tee_bin, size_t tee_size)
{
void __noreturn (*bl31)(void) = tfa_dest;
+ unsigned long endmem;
+ void *bl32 = NULL;
int ret;
+ endmem = MX8M_DDR_CSD1_BASE_ADDR;
+ if (cpu_is_mx8mn())
+ endmem += imx8m_barebox_earlymem_size(16);
+ else
+ endmem += imx8m_barebox_earlymem_size(32);
+
+ /* TEE (BL32) handling */
+ if (tee_bin) {
+ BUG_ON(tee_size <= 0);
+
+ imx8m_tzc380_init();
+
+ bl32 = (void *)arm_mem_optee(endmem);
+ imx_adjust_optee_memory(&bl32, &tee_bin, &tee_size);
+
+ memcpy(bl32, tee_bin, tee_size);
+ }
+
+ /* TF-A (BL31) handling */
BUG_ON(tfa_size > MX8M_ATF_BL31_SIZE_LIMIT);
if (IS_ENABLED(CONFIG_FSL_CAAM_RNG_PBL_INIT)) {
@@ -54,6 +101,7 @@ static __noreturn void imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size
memcpy(bl31, tfa_bin, tfa_size);
+ /* Stack setup and BL31 jump */
asm volatile("msr sp_el2, %0" : :
"r" (tfa_dest - 16) :
"cc");
@@ -123,24 +171,6 @@ void imx8mm_load_bl33(void *bl33)
memcpy(bl33, __image_start, barebox_pbl_size);
}
-static void imx_adjust_optee_memory(void **bl32, void **bl32_image, size_t *bl32_size)
-{
- struct optee_header *hdr = *bl32_image;
- u64 membase;
-
- if (optee_verify_header(hdr))
- return;
-
- imx_scratch_save_optee_hdr(hdr);
-
- membase = (u64)hdr->init_load_addr_hi << 32;
- membase |= hdr->init_load_addr_lo;
-
- *bl32 = (void *)membase;
- *bl32_size -= sizeof(*hdr);
- *bl32_image += sizeof(*hdr);
-}
-
__noreturn void imx8mm_load_and_start_image_via_tfa(void *fdt)
{
__imx8mm_load_and_start_image_via_tfa(fdt, (void *)MX8M_ATF_BL33_BASE_ADDR);
@@ -150,7 +180,8 @@ __noreturn void __imx8mm_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
- unsigned long endmem = MX8M_DDR_CSD1_BASE_ADDR + imx8m_barebox_earlymem_size(32);
+ void *bl32 = NULL;
+ size_t bl32_size = 0;
imx_set_cpu_type(IMX_CPU_IMX8MM);
imx8mm_init_scratch_space();
@@ -158,25 +189,14 @@ __noreturn void __imx8mm_load_and_start_image_via_tfa(void *fdt, void *bl33)
imx8mm_load_bl33(bl33);
if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MM_OPTEE)) {
- void *bl32 = (void *)arm_mem_optee(endmem);
- size_t bl32_size;
- void *bl32_image;
-
- imx8m_tzc380_init();
- get_builtin_firmware_ext(imx8mm_bl32_bin,
- bl33, &bl32_image,
- &bl32_size);
-
- imx_adjust_optee_memory(&bl32, &bl32_image, &bl32_size);
-
- memcpy(bl32, bl32_image, bl32_size);
-
+ get_builtin_firmware_ext(imx8mm_bl32_bin, bl33, &bl32, &bl32_size);
get_builtin_firmware(imx8mm_bl31_bin_optee, &bl31, &bl31_size);
} else {
get_builtin_firmware(imx8mm_bl31_bin, &bl31, &bl31_size);
}
- imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MM_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MM_ATF_BL31_BASE_ADDR,
+ bl32, bl32_size);
}
void imx8mp_load_bl33(void *bl33)
@@ -224,7 +244,8 @@ __noreturn void __imx8mp_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
- unsigned long endmem = MX8M_DDR_CSD1_BASE_ADDR + imx8m_barebox_earlymem_size(32);
+ void *bl32 = NULL;
+ size_t bl32_size = 0;
imx_set_cpu_type(IMX_CPU_IMX8MP);
imx8mp_init_scratch_space();
@@ -232,25 +253,14 @@ __noreturn void __imx8mp_load_and_start_image_via_tfa(void *fdt, void *bl33)
imx8mp_load_bl33(bl33);
if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MP_OPTEE)) {
- void *bl32 = (void *)arm_mem_optee(endmem);
- size_t bl32_size;
- void *bl32_image;
-
- imx8m_tzc380_init();
- get_builtin_firmware_ext(imx8mp_bl32_bin,
- bl33, &bl32_image,
- &bl32_size);
-
- imx_adjust_optee_memory(&bl32, &bl32_image, &bl32_size);
-
- memcpy(bl32, bl32_image, bl32_size);
-
+ get_builtin_firmware_ext(imx8mp_bl32_bin, bl33, &bl32, &bl32_size);
get_builtin_firmware(imx8mp_bl31_bin_optee, &bl31, &bl31_size);
} else {
get_builtin_firmware(imx8mp_bl31_bin, &bl31, &bl31_size);
}
- imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MP_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MP_ATF_BL31_BASE_ADDR,
+ bl32, bl32_size);
}
void imx8mn_load_bl33(void *bl33)
@@ -298,7 +308,8 @@ __noreturn void __imx8mn_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
- unsigned long endmem = MX8M_DDR_CSD1_BASE_ADDR + imx8m_barebox_earlymem_size(16);
+ void *bl32 = NULL;
+ size_t bl32_size = 0;
imx_set_cpu_type(IMX_CPU_IMX8MN);
imx8mn_init_scratch_space();
@@ -306,25 +317,14 @@ __noreturn void __imx8mn_load_and_start_image_via_tfa(void *fdt, void *bl33)
imx8mn_load_bl33(bl33);
if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MN_OPTEE)) {
- void *bl32 = (void *)arm_mem_optee(endmem);
- size_t bl32_size;
- void *bl32_image;
-
- imx8m_tzc380_init();
- get_builtin_firmware_ext(imx8mn_bl32_bin,
- bl33, &bl32_image,
- &bl32_size);
-
- imx_adjust_optee_memory(&bl32, &bl32_image, &bl32_size);
-
- memcpy(bl32, bl32_image, bl32_size);
-
+ get_builtin_firmware_ext(imx8mn_bl32_bin, bl33, &bl32, &bl32_size);
get_builtin_firmware(imx8mn_bl31_bin_optee, &bl31, &bl31_size);
} else {
get_builtin_firmware(imx8mn_bl31_bin, &bl31, &bl31_size);
}
- imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MN_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MN_ATF_BL31_BASE_ADDR,
+ bl32, bl32_size);
}
void imx8mq_load_bl33(void *bl33)
@@ -366,7 +366,8 @@ __noreturn void __imx8mq_load_and_start_image_via_tfa(void *fdt, void *bl33)
{
const void *bl31;
size_t bl31_size;
- unsigned long endmem = MX8M_DDR_CSD1_BASE_ADDR + imx8m_barebox_earlymem_size(32);
+ void *bl32 = NULL;
+ size_t bl32_size = 0;
imx_set_cpu_type(IMX_CPU_IMX8MQ);
imx8mq_init_scratch_space();
@@ -374,25 +375,14 @@ __noreturn void __imx8mq_load_and_start_image_via_tfa(void *fdt, void *bl33)
imx8mq_load_bl33(bl33);
if (IS_ENABLED(CONFIG_FIRMWARE_IMX8MQ_OPTEE)) {
- void *bl32 = (void *)arm_mem_optee(endmem);
- size_t bl32_size;
- void *bl32_image;
-
- imx8m_tzc380_init();
- get_builtin_firmware_ext(imx8mq_bl32_bin,
- bl33, &bl32_image,
- &bl32_size);
-
- imx_adjust_optee_memory(&bl32, &bl32_image, &bl32_size);
-
- memcpy(bl32, bl32_image, bl32_size);
-
+ get_builtin_firmware_ext(imx8mq_bl32_bin, bl33, &bl32, &bl32_size);
get_builtin_firmware(imx8mq_bl31_bin_optee, &bl31, &bl31_size);
} else {
get_builtin_firmware(imx8mq_bl31_bin, &bl31, &bl31_size);
}
- imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MQ_ATF_BL31_BASE_ADDR);
+ imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MQ_ATF_BL31_BASE_ADDR,
+ bl32, bl32_size);
}
void __noreturn imx93_load_and_start_image_via_tfa(void)
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 07/23] ARM: i.MX8M: imx8m_tfa_start_bl31() add support for bl33 and fdt
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (5 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 06/23] ARM: i.MX8M: move BL32 setup into imx8m_tfa_start_bl31() Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 08/23] pbl: decomp: add pbl_dtbz_uncompress helper Marco Felsch
` (15 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
This adds the support to pass the bl33 entry and the fdt to
imx8m_tfa_start_bl31() which is required to pass it later on the the
bl31 via the bl_params.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/atf.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index 531ded2c57b1f194a2f209161ea086f41fccf58f..f4d4774b9eec798dd69042560d83f7313c0cb74f 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -44,6 +44,9 @@ static void imx_adjust_optee_memory(void **bl32, void **bl32_image, size_t *bl32
* @tfa_dest: Place where the BL31 is copied to and executed
* @tee: Pointer to the optional BL32 blob
* @tee_size: Size of the optional BL32 blob
+ * @bl33: Pointer to the already loaded BL33 blob
+ * @fdt: Pointer to the barebox internal DT (either compressed or not
+ * compressed)
*
* This function:
*
@@ -63,7 +66,7 @@ static void imx_adjust_optee_memory(void **bl32, void **bl32_image, size_t *bl32
static __noreturn void
imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size, void *tfa_dest,
- void *tee_bin, size_t tee_size)
+ void *tee_bin, size_t tee_size, void *bl33, void *fdt)
{
void __noreturn (*bl31)(void) = tfa_dest;
unsigned long endmem;
@@ -196,7 +199,7 @@ __noreturn void __imx8mm_load_and_start_image_via_tfa(void *fdt, void *bl33)
}
imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MM_ATF_BL31_BASE_ADDR,
- bl32, bl32_size);
+ bl32, bl32_size, bl33, fdt);
}
void imx8mp_load_bl33(void *bl33)
@@ -260,7 +263,7 @@ __noreturn void __imx8mp_load_and_start_image_via_tfa(void *fdt, void *bl33)
}
imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MP_ATF_BL31_BASE_ADDR,
- bl32, bl32_size);
+ bl32, bl32_size, bl33, fdt);
}
void imx8mn_load_bl33(void *bl33)
@@ -324,7 +327,7 @@ __noreturn void __imx8mn_load_and_start_image_via_tfa(void *fdt, void *bl33)
}
imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MN_ATF_BL31_BASE_ADDR,
- bl32, bl32_size);
+ bl32, bl32_size, bl33, fdt);
}
void imx8mq_load_bl33(void *bl33)
@@ -382,7 +385,7 @@ __noreturn void __imx8mq_load_and_start_image_via_tfa(void *fdt, void *bl33)
}
imx8m_tfa_start_bl31(bl31, bl31_size, (void *)MX8MQ_ATF_BL31_BASE_ADDR,
- bl32, bl32_size);
+ bl32, bl32_size, bl33, fdt);
}
void __noreturn imx93_load_and_start_image_via_tfa(void)
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 08/23] pbl: decomp: add pbl_dtbz_uncompress helper
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (6 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 07/23] ARM: i.MX8M: imx8m_tfa_start_bl31() add support for bl33 and fdt Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 09/23] pbl: fdt: add pbl_load_fdt helper Marco Felsch
` (14 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Add a pbl uncompress helper since uncompress() can't be used directly
within pbl.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
include/pbl.h | 1 +
pbl/decomp.c | 12 ++++++++++++
2 files changed, 13 insertions(+)
diff --git a/include/pbl.h b/include/pbl.h
index b330010562c4aba5fccbb4c421bb95291fa0bea1..9db4652e833bf5e82fd42a1cae19e94c4f2f868f 100644
--- a/include/pbl.h
+++ b/include/pbl.h
@@ -15,6 +15,7 @@ extern unsigned long free_mem_ptr;
extern unsigned long free_mem_end_ptr;
void pbl_barebox_uncompress(void *dest, void *compressed_start, unsigned int len);
+int pbl_dtbz_uncompress(void *dest, void *compressed_start, unsigned long len);
void fdt_find_mem(const void *fdt, unsigned long *membase, unsigned long *memsize);
int fdt_fixup_mem(void *fdt, unsigned long membase[], unsigned long memsize[], size_t num);
diff --git a/pbl/decomp.c b/pbl/decomp.c
index ebdf81ddfbe5af65a382b7221c7102dcc791e5b9..4d50ea15555ba96bdc2fcac4c48708c6e1261d4d 100644
--- a/pbl/decomp.c
+++ b/pbl/decomp.c
@@ -51,6 +51,12 @@ static void noinline errorfn(char *error)
while (1);
}
+static noinline void errorfn_nohang(char *error)
+{
+ puts_ll("ERROR: ");
+ puts_ll(error);
+}
+
extern unsigned char sha_sum[];
extern unsigned char sha_sum_end[];
@@ -110,3 +116,9 @@ void pbl_barebox_uncompress(void *dest, void *compressed_start, unsigned int len
NULL, NULL,
dest, NULL, errorfn);
}
+
+int pbl_dtbz_uncompress(void *dest, void *compressed_start, unsigned long len)
+{
+ return decompress(compressed_start, len, NULL, NULL, dest, NULL,
+ errorfn_nohang);
+}
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 09/23] pbl: fdt: add pbl_load_fdt helper
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (7 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 08/23] pbl: decomp: add pbl_dtbz_uncompress helper Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 10/23] ARM: i.MX: scratch: add FDT support Marco Felsch
` (13 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
The helper provides a common FDT load mechanism to load the (compressed)
DTB to the provided destination address. Early FDTs may required by
other BL3x binaries like BL31 (TF-A) and BL32 (OP-TEE).
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/Kconfig | 3 +++
include/pbl.h | 2 ++
pbl/Kconfig | 11 +++++++++
pbl/fdt.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 91 insertions(+)
diff --git a/arch/Kconfig b/arch/Kconfig
index 55618bf896c25f2afa2786706e27fce6ab4b3a39..edd574879b244d3843f1b5a06e1e25c5d4acbc8d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -62,6 +62,9 @@ config ARCH_DMA_DEFAULT_COHERENT
config ARCH_HAS_DMA_WRITE_COMBINE
bool
+config ARCH_HAS_EARLY_FDT_SUPPORT
+ bool
+
config ARCH_HAS_ASAN_FIBER_API
bool
diff --git a/include/pbl.h b/include/pbl.h
index 9db4652e833bf5e82fd42a1cae19e94c4f2f868f..bf0c9e2ba29428361cb16a572295e66f20acdd82 100644
--- a/include/pbl.h
+++ b/include/pbl.h
@@ -31,6 +31,8 @@ fdt_device_get_match_data(const void *fdt, const char *nodepath,
int pbl_barebox_verify(const void *compressed_start, unsigned int len,
const void *hash, unsigned int hash_len);
+int pbl_load_fdt(const void *fdt, void *dest, int destsize);
+
#endif
void __noreturn barebox_pbl_entry(ulong, ulong, void *);
diff --git a/pbl/Kconfig b/pbl/Kconfig
index cab9325d16e8625bcca10125b3281062abffedbc..ea2086f33ea405ecd7b00065eaf9874218152b3a 100644
--- a/pbl/Kconfig
+++ b/pbl/Kconfig
@@ -65,6 +65,17 @@ config PBL_VERIFY_PIGGY
depends on ARM || MIPS || RISCV
bool "Verify barebox proper hash before decompression" if COMPILE_TEST
+config PBL_EARLY_FDT_LOAD
+ bool "Enable early FDT loading"
+ depends on ARCH_HAS_EARLY_FDT_SUPPORT
+ select LIBFDT
+ help
+ This enables the support to decompress and load the barebox builtin DTB
+ during the pbl (BL2) phase.
+
+ This is useful for BL31 and BL32 firmwares which may use the DTB for
+ device configuration.
+
config PBL_CLOCKSOURCE
bool
diff --git a/pbl/fdt.c b/pbl/fdt.c
index ac377446caeafb1beaeb211aa8bdec8767ae21fe..0cd9f5a0f11723e9f9b6848e8553da481b92f2be 100644
--- a/pbl/fdt.c
+++ b/pbl/fdt.c
@@ -1,8 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
+#include <compressed-dtb.h>
#include <linux/libfdt.h>
#include <pbl.h>
#include <linux/printk.h>
#include <stdio.h>
+#include <uncompress.h>
static const __be32 *fdt_parse_reg(const __be32 *reg, uint32_t n,
uint64_t *val)
@@ -185,3 +187,76 @@ const void *fdt_device_get_match_data(const void *fdt, const char *nodepath,
return NULL;
}
+
+static int pbl_open_dtbz_into(const void *fdt, void *buf, int bufsize)
+{
+ const struct barebox_boarddata_compressed_dtb *compressed_dtb;
+ int ret;
+
+ if (!fdt_blob_can_be_decompressed(fdt)) {
+ pr_warn("DTB can't be decompressed\n");
+ return -EINVAL;
+ }
+
+ compressed_dtb = fdt;
+
+ if (IS_ENABLED(CONFIG_IMAGE_COMPRESSION_NONE)) {
+ ret = fdt_open_into(compressed_dtb->data, buf, bufsize);
+ if (ret)
+ pr_warn("Failed to open uncompressed DTB with %s\n",
+ fdt_strerror(ret));
+ return ret ? -EINVAL : 0;
+ }
+
+ if (bufsize < compressed_dtb->datalen_uncompressed) {
+ pr_warn("FDT buffer to small, min. %u bytes required\n",
+ compressed_dtb->datalen_uncompressed);
+ return -EINVAL;
+ }
+
+ ret = pbl_dtbz_uncompress(buf, (void *)compressed_dtb->data,
+ compressed_dtb->datalen);
+ if (ret) {
+ pr_warn("Failed to uncompress DTB err=%d\n", ret);
+ return ret;
+ }
+
+ if (!blob_is_fdt(buf)) {
+ pr_warn("Failed to determine FDT type for uncompressed DTB\n");
+ return -EINVAL;
+ }
+
+ /* Required to setup size data structures to allow runtime adaptions */
+ ret = fdt_open_into(buf, buf, bufsize);
+ if (ret)
+ pr_warn("Failed to open decompressed DTB with %s\n", fdt_strerror(ret));
+
+ return ret ? -EINVAL : 0;
+}
+
+int pbl_load_fdt(const void *fdt, void *dest, int destsize)
+{
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_PBL_EARLY_FDT_LOAD))
+ return -ENOTSUPP;
+
+ if (destsize == 0) {
+ pr_warn("Skip early FDT load due to dest buffer size of 0-bytes\n");
+ return -EINVAL;
+ }
+
+ if (blob_is_fdt(fdt)) {
+ ret = fdt_open_into(fdt, dest, destsize);
+ if (ret)
+ pr_warn("Failed to uncompressed DTB with %s\n",
+ fdt_strerror(ret));
+ return ret ? -EINVAL : 0;
+ } else if (blob_is_compressed_fdt(fdt)) {
+ return pbl_open_dtbz_into(fdt, dest, destsize);
+ }
+
+ pr_warn("FDT detection failed\n");
+
+ return -EINVAL;
+}
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 10/23] ARM: i.MX: scratch: add FDT support
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (8 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 09/23] pbl: fdt: add pbl_load_fdt helper Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-11 14:14 ` Sascha Hauer
2025-11-10 20:34 ` [PATCH 11/23] ARM: i.MX8M: esdctl: drop ddrc base from imx8m_ddrc_sdram_size Marco Felsch
` (12 subsequent siblings)
22 siblings, 1 reply; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Add support to store a FDT within the scratch area. The user needs to
query the location and size via imx_scratch_get_fdt() which can be used
afterwards to write the actual FDT into it.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/scratch.c | 16 ++++++++++++++++
common/Kconfig | 14 ++++++++++++++
include/mach/imx/scratch.h | 2 ++
3 files changed, 32 insertions(+)
diff --git a/arch/arm/mach-imx/scratch.c b/arch/arm/mach-imx/scratch.c
index e4e2d25969f061c9fcdfd7c3d87701b715eb2805..9c0f1c09c4e0b863d8c95888db7cf0518f698d53 100644
--- a/arch/arm/mach-imx/scratch.c
+++ b/arch/arm/mach-imx/scratch.c
@@ -16,7 +16,10 @@ struct imx_scratch_space {
u32 bootrom_log[128];
u32 reserved[128]; /* reserve for bootrom log */
struct optee_header optee_hdr;
+ /* FDT needs an 8 byte alignment */
+ u8 fdt[CONFIG_SCRATCH_FDT_SIZE] __aligned(8);
};
+static_assert(sizeof(struct imx_scratch_space) <= CONFIG_SCRATCH_SIZE);
static struct imx_scratch_space *scratch;
@@ -92,3 +95,16 @@ const struct optee_header *imx_scratch_get_optee_hdr(void)
return &scratch->optee_hdr;
}
+
+void imx_scratch_get_fdt(void **fdt, unsigned int *fdt_sz)
+{
+ if (!scratch) {
+ if (IN_PBL)
+ return;
+ else
+ scratch = (void *)arm_mem_scratch_get();
+ }
+
+ *fdt = scratch->fdt;
+ *fdt_sz = sizeof(scratch->fdt);
+}
diff --git a/common/Kconfig b/common/Kconfig
index eb2fb1da1e0919b6e7d5e868c48ad2e195cd8aa8..3f394416c3c376d1cf842472803a47462bb012ed 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -302,8 +302,22 @@ config MALLOC_SIZE
config SCRATCH_SIZE
hex
default 0x8000
+ default 0x48000 if PBL_EARLY_FDT_LOAD
prompt "Scratch size"
+config SCRATCH_FDT_SIZE
+ hex
+ default 0x0
+ default 0x40000 if PBL_EARLY_FDT_LOAD
+ prompt "Scratch FDT size"
+ help
+ The size of the scratch area used as destination to load and optional
+ decompress the barebox builtin DTB into it. Can be 0x0 if early FDT
+ support is not requied e.g. during BL31 and BL32 stage else
+ SCRATCH_FDT_SIZE <= SCRATCH_SIZE must be ensured.
+ This option should match the OP-TEE's CFG_DTB_MAX_SIZE configuration
+ if used by OP-TEE.
+
config MALLOC_ALIGNMENT
hex
default 8
diff --git a/include/mach/imx/scratch.h b/include/mach/imx/scratch.h
index 6c2cecabcd80f71aa754736322151d63f2711745..43bf55de48099f1662cd4331620a93303d4dd710 100644
--- a/include/mach/imx/scratch.h
+++ b/include/mach/imx/scratch.h
@@ -14,6 +14,8 @@ struct optee_header;
const struct optee_header *imx_scratch_get_optee_hdr(void);
void imx_scratch_save_optee_hdr(const struct optee_header *hdr);
+void imx_scratch_get_fdt(void **fdt, unsigned int *fdt_sz);
+
#define imx8mq_init_scratch_space() imx8m_init_scratch_space(32, true)
#define imx8mm_init_scratch_space() imx8m_init_scratch_space(32, true)
#define imx8mn_init_scratch_space() imx8m_init_scratch_space(16, true)
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 10/23] ARM: i.MX: scratch: add FDT support
2025-11-10 20:34 ` [PATCH 10/23] ARM: i.MX: scratch: add FDT support Marco Felsch
@ 2025-11-11 14:14 ` Sascha Hauer
2025-11-11 14:30 ` Ahmad Fatoum
0 siblings, 1 reply; 27+ messages in thread
From: Sascha Hauer @ 2025-11-11 14:14 UTC (permalink / raw)
To: Marco Felsch; +Cc: BAREBOX
On Mon, Nov 10, 2025 at 09:34:50PM +0100, Marco Felsch wrote:
> Add support to store a FDT within the scratch area. The user needs to
> query the location and size via imx_scratch_get_fdt() which can be used
> afterwards to write the actual FDT into it.
>
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
> arch/arm/mach-imx/scratch.c | 16 ++++++++++++++++
> common/Kconfig | 14 ++++++++++++++
> include/mach/imx/scratch.h | 2 ++
> 3 files changed, 32 insertions(+)
>
> diff --git a/arch/arm/mach-imx/scratch.c b/arch/arm/mach-imx/scratch.c
> index e4e2d25969f061c9fcdfd7c3d87701b715eb2805..9c0f1c09c4e0b863d8c95888db7cf0518f698d53 100644
> --- a/arch/arm/mach-imx/scratch.c
> +++ b/arch/arm/mach-imx/scratch.c
> @@ -16,7 +16,10 @@ struct imx_scratch_space {
> u32 bootrom_log[128];
> u32 reserved[128]; /* reserve for bootrom log */
> struct optee_header optee_hdr;
> + /* FDT needs an 8 byte alignment */
> + u8 fdt[CONFIG_SCRATCH_FDT_SIZE] __aligned(8);
> };
> +static_assert(sizeof(struct imx_scratch_space) <= CONFIG_SCRATCH_SIZE);
>
> static struct imx_scratch_space *scratch;
>
> @@ -92,3 +95,16 @@ const struct optee_header *imx_scratch_get_optee_hdr(void)
>
> return &scratch->optee_hdr;
> }
> +
> +void imx_scratch_get_fdt(void **fdt, unsigned int *fdt_sz)
> +{
> + if (!scratch) {
> + if (IN_PBL)
> + return;
> + else
> + scratch = (void *)arm_mem_scratch_get();
> + }
> +
> + *fdt = scratch->fdt;
> + *fdt_sz = sizeof(scratch->fdt);
> +}
> diff --git a/common/Kconfig b/common/Kconfig
> index eb2fb1da1e0919b6e7d5e868c48ad2e195cd8aa8..3f394416c3c376d1cf842472803a47462bb012ed 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -302,8 +302,22 @@ config MALLOC_SIZE
> config SCRATCH_SIZE
> hex
> default 0x8000
> + default 0x48000 if PBL_EARLY_FDT_LOAD
> prompt "Scratch size"
Do I get this right that the scratch space now includes the space for
the early FDT? If yes then this can lead to inconsistencies when the
scratch space is to small. Why not add an extra space?
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 10/23] ARM: i.MX: scratch: add FDT support
2025-11-11 14:14 ` Sascha Hauer
@ 2025-11-11 14:30 ` Ahmad Fatoum
2025-11-11 15:06 ` Marco Felsch
0 siblings, 1 reply; 27+ messages in thread
From: Ahmad Fatoum @ 2025-11-11 14:30 UTC (permalink / raw)
To: Sascha Hauer, Marco Felsch; +Cc: BAREBOX
Hi,
On 11/11/25 3:14 PM, Sascha Hauer wrote:
> On Mon, Nov 10, 2025 at 09:34:50PM +0100, Marco Felsch wrote:
>> Add support to store a FDT within the scratch area. The user needs to
>> query the location and size via imx_scratch_get_fdt() which can be used
>> afterwards to write the actual FDT into it.
>>
>> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
>> ---
>> arch/arm/mach-imx/scratch.c | 16 ++++++++++++++++
>> common/Kconfig | 14 ++++++++++++++
>> include/mach/imx/scratch.h | 2 ++
>> 3 files changed, 32 insertions(+)
>>
>> diff --git a/arch/arm/mach-imx/scratch.c b/arch/arm/mach-imx/scratch.c
>> index e4e2d25969f061c9fcdfd7c3d87701b715eb2805..9c0f1c09c4e0b863d8c95888db7cf0518f698d53 100644
>> --- a/arch/arm/mach-imx/scratch.c
>> +++ b/arch/arm/mach-imx/scratch.c
>> @@ -16,7 +16,10 @@ struct imx_scratch_space {
>> u32 bootrom_log[128];
>> u32 reserved[128]; /* reserve for bootrom log */
>> struct optee_header optee_hdr;
>> + /* FDT needs an 8 byte alignment */
>> + u8 fdt[CONFIG_SCRATCH_FDT_SIZE] __aligned(8);
>> };
>> +static_assert(sizeof(struct imx_scratch_space) <= CONFIG_SCRATCH_SIZE);
>>
>> static struct imx_scratch_space *scratch;
>>
>> @@ -92,3 +95,16 @@ const struct optee_header *imx_scratch_get_optee_hdr(void)
>>
>> return &scratch->optee_hdr;
>> }
>> +
>> +void imx_scratch_get_fdt(void **fdt, unsigned int *fdt_sz)
>> +{
>> + if (!scratch) {
>> + if (IN_PBL)
>> + return;
>> + else
>> + scratch = (void *)arm_mem_scratch_get();
>> + }
>> +
>> + *fdt = scratch->fdt;
>> + *fdt_sz = sizeof(scratch->fdt);
>> +}
>> diff --git a/common/Kconfig b/common/Kconfig
>> index eb2fb1da1e0919b6e7d5e868c48ad2e195cd8aa8..3f394416c3c376d1cf842472803a47462bb012ed 100644
>> --- a/common/Kconfig
>> +++ b/common/Kconfig
>> @@ -302,8 +302,22 @@ config MALLOC_SIZE
>> config SCRATCH_SIZE
>> hex
>> default 0x8000
>> + default 0x48000 if PBL_EARLY_FDT_LOAD
Easy to misconfigure. How about an additional:
range 0x48000 <some big size> if PBL_EARLY_FDT_LOAD
>> prompt "Scratch size"
>
> Do I get this right that the scratch space now includes the space for
> the early FDT? If yes then this can lead to inconsistencies when the
> scratch space is to small. Why not add an extra space?
I would prefer we do not complicate the "endmem" layout more than we
have currently.
What I think we want in future is an API to allocate from the scratch
mem a handoff block and there would be no hardcoded offsets and struct
imx_scratch_space could go away. To save handoff when switching from PBL
to proper, we would then also allocate to the scratch space.
This will probably happen separately, so I am in favor of not creating a
new section that's removed afterwards.
Cheers,
Ahmad
>
> Sascha
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 27+ messages in thread* Re: [PATCH 10/23] ARM: i.MX: scratch: add FDT support
2025-11-11 14:30 ` Ahmad Fatoum
@ 2025-11-11 15:06 ` Marco Felsch
0 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-11 15:06 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: BAREBOX
On 25-11-11, Ahmad Fatoum wrote:
> Hi,
>
> On 11/11/25 3:14 PM, Sascha Hauer wrote:
> > On Mon, Nov 10, 2025 at 09:34:50PM +0100, Marco Felsch wrote:
> >> Add support to store a FDT within the scratch area. The user needs to
> >> query the location and size via imx_scratch_get_fdt() which can be used
> >> afterwards to write the actual FDT into it.
> >>
> >> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> >> ---
> >> arch/arm/mach-imx/scratch.c | 16 ++++++++++++++++
> >> common/Kconfig | 14 ++++++++++++++
> >> include/mach/imx/scratch.h | 2 ++
> >> 3 files changed, 32 insertions(+)
> >>
> >> diff --git a/arch/arm/mach-imx/scratch.c b/arch/arm/mach-imx/scratch.c
> >> index e4e2d25969f061c9fcdfd7c3d87701b715eb2805..9c0f1c09c4e0b863d8c95888db7cf0518f698d53 100644
> >> --- a/arch/arm/mach-imx/scratch.c
> >> +++ b/arch/arm/mach-imx/scratch.c
> >> @@ -16,7 +16,10 @@ struct imx_scratch_space {
> >> u32 bootrom_log[128];
> >> u32 reserved[128]; /* reserve for bootrom log */
> >> struct optee_header optee_hdr;
> >> + /* FDT needs an 8 byte alignment */
> >> + u8 fdt[CONFIG_SCRATCH_FDT_SIZE] __aligned(8);
> >> };
> >> +static_assert(sizeof(struct imx_scratch_space) <= CONFIG_SCRATCH_SIZE);
> >>
> >> static struct imx_scratch_space *scratch;
> >>
> >> @@ -92,3 +95,16 @@ const struct optee_header *imx_scratch_get_optee_hdr(void)
> >>
> >> return &scratch->optee_hdr;
> >> }
> >> +
> >> +void imx_scratch_get_fdt(void **fdt, unsigned int *fdt_sz)
> >> +{
> >> + if (!scratch) {
> >> + if (IN_PBL)
> >> + return;
> >> + else
> >> + scratch = (void *)arm_mem_scratch_get();
> >> + }
> >> +
> >> + *fdt = scratch->fdt;
> >> + *fdt_sz = sizeof(scratch->fdt);
> >> +}
> >> diff --git a/common/Kconfig b/common/Kconfig
> >> index eb2fb1da1e0919b6e7d5e868c48ad2e195cd8aa8..3f394416c3c376d1cf842472803a47462bb012ed 100644
> >> --- a/common/Kconfig
> >> +++ b/common/Kconfig
> >> @@ -302,8 +302,22 @@ config MALLOC_SIZE
> >> config SCRATCH_SIZE
> >> hex
> >> default 0x8000
> >> + default 0x48000 if PBL_EARLY_FDT_LOAD
>
> Easy to misconfigure. How about an additional:
>
> range 0x48000 <some big size> if PBL_EARLY_FDT_LOAD
I wasn't aware of the 'range' property. I just simply followed the
Rockchip implementation, with the exception that I wanted to provide a
sane default for the SCRATCH_SIZE too.
> >> prompt "Scratch size"
> >
> > Do I get this right that the scratch space now includes the space for
> > the early FDT? If yes then this can lead to inconsistencies when the
> > scratch space is to small. Why not add an extra space?
There is a static size check for the i.MX and Rockchip case to ensure
that the overall SCRATCH_SIZE fits all members.
> I would prefer we do not complicate the "endmem" layout more than we
> have currently.
>
> What I think we want in future is an API to allocate from the scratch
> mem a handoff block and there would be no hardcoded offsets and struct
> imx_scratch_space could go away. To save handoff when switching from PBL
> to proper, we would then also allocate to the scratch space.
>
> This will probably happen separately, so I am in favor of not creating a
> new section that's removed afterwards.
I'm with Ahmad, the scratch/handoff handling could be generalized for
all platforms. IMHO the current implementation requires to much user
input (Kconfig setup), but this should be part of another patchset.
My idea is basically the same as Ahmad explained:
- Scratch pool size configured via Kconfig
- Handoff-data allocates bytes from the scratch-pool (eliminates the
moving the handoff-data)
This way barebox could check the actual FDT size (incl. adding some
space like 4K for additions).
Regards,
Marco
>
> Cheers,
> Ahmad
>
> >
> > Sascha
> >
>
> --
> Pengutronix e.K. | |
> Steuerwalder Str. 21 | http://www.pengutronix.de/ |
> 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
>
>
--
#gernperDu
#CallMeByMyFirstName
Pengutronix e.K. | |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 11/23] ARM: i.MX8M: esdctl: drop ddrc base from imx8m_ddrc_sdram_size
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (9 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 10/23] ARM: i.MX: scratch: add FDT support Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 12/23] ARM: i.MX8M: esdctl: export imx8m_ddrc_sdram_size() Marco Felsch
` (11 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
All i.MX8M use the same DDRC MMIO address. Therefore drop the ddrc param
from imx8m_ddrc_sdram_size() and set it locally.
While on it drop the param from _imx8m_ddrc_add_mem() as well since it
is no longer needed to be passed to imx8m_ddrc_sdram_size().
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/esdctl.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index 4c4c3528e1a6e68c508edc48ad38c9e2e6324c1c..0a1e042792bd90b40ffc8084efbdc5a25ba0dd02 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -467,8 +467,9 @@ static void imx_ddrc_set_mstr_device_config(u32 *mstr, unsigned bits)
*mstr |= FIELD_PREP(DDRC_MSTR_DEVICE_CONFIG, fls(bits / 8));
}
-static resource_size_t imx8m_ddrc_sdram_size(void __iomem *ddrc, unsigned buswidth)
+static resource_size_t imx8m_ddrc_sdram_size(unsigned buswidth)
{
+ void __iomem *ddrc = IOMEM(MX8M_DDRC_CTL_BASE_ADDR);
const u32 addrmap[DDRC_ADDRMAP_LENGTH] = {
readl(ddrc + DDRC_ADDRMAP(0)),
readl(ddrc + DDRC_ADDRMAP(1)),
@@ -518,10 +519,10 @@ static resource_size_t imx8m_ddrc_sdram_size(void __iomem *ddrc, unsigned buswid
reduced_adress_space, mstr);
}
-static int _imx8m_ddrc_add_mem(void *mmdcbase, const struct imx_esdctl_data *data,
+static int _imx8m_ddrc_add_mem(const struct imx_esdctl_data *data,
unsigned int buswidth)
{
- resource_size_t size = imx8m_ddrc_sdram_size(mmdcbase, buswidth);
+ resource_size_t size = imx8m_ddrc_sdram_size(buswidth);
resource_size_t size0, size1;
int ret;
@@ -555,12 +556,12 @@ static int _imx8m_ddrc_add_mem(void *mmdcbase, const struct imx_esdctl_data *dat
static int imx8m_ddrc_add_mem(void *mmdcbase, const struct imx_esdctl_data *data)
{
- return _imx8m_ddrc_add_mem(mmdcbase, data, 32);
+ return _imx8m_ddrc_add_mem(data, 32);
}
static int imx8mn_ddrc_add_mem(void *mmdcbase, const struct imx_esdctl_data *data)
{
- return _imx8m_ddrc_add_mem(mmdcbase, data, 16);
+ return _imx8m_ddrc_add_mem(data, 16);
}
#define IMX9_DDRC_CS_CONFIG(n) (0x80 + (n) * 4)
@@ -1001,7 +1002,7 @@ resource_size_t imx8m_barebox_earlymem_size(unsigned buswidth)
{
resource_size_t size;
- size = imx8m_ddrc_sdram_size(IOMEM(MX8M_DDRC_CTL_BASE_ADDR), buswidth);
+ size = imx8m_ddrc_sdram_size(buswidth);
/*
* We artificially limit detected memory size to force malloc
* pool placement to be within 4GiB address space, so as to
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 12/23] ARM: i.MX8M: esdctl: export imx8m_ddrc_sdram_size()
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (10 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 11/23] ARM: i.MX8M: esdctl: drop ddrc base from imx8m_ddrc_sdram_size Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 13/23] ARM: i.MX8M: add support to pass BL3x bl_params Marco Felsch
` (10 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
imx8m_ddrc_sdram_size() returns the full memory size whereas
imx8m_barebox_earlymem_size() limits the size to 4GiB.
This can be useful in cases like fixing up the FDT memory size for
OP-TEE which uses the information to configure the TZASC accordingly.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/esdctl.c | 2 +-
include/mach/imx/esdctl.h | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index 0a1e042792bd90b40ffc8084efbdc5a25ba0dd02..964d438e3f3433332e351d9a70f91857ee33e0b4 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -467,7 +467,7 @@ static void imx_ddrc_set_mstr_device_config(u32 *mstr, unsigned bits)
*mstr |= FIELD_PREP(DDRC_MSTR_DEVICE_CONFIG, fls(bits / 8));
}
-static resource_size_t imx8m_ddrc_sdram_size(unsigned buswidth)
+resource_size_t imx8m_ddrc_sdram_size(unsigned buswidth)
{
void __iomem *ddrc = IOMEM(MX8M_DDRC_CTL_BASE_ADDR);
const u32 addrmap[DDRC_ADDRMAP_LENGTH] = {
diff --git a/include/mach/imx/esdctl.h b/include/mach/imx/esdctl.h
index 97bd444b1a4ca2defdeb9f82180c0366296a32a0..47fb665a861bf2105b4d606ea1672caf27d8e285 100644
--- a/include/mach/imx/esdctl.h
+++ b/include/mach/imx/esdctl.h
@@ -153,6 +153,7 @@ void __noreturn imx93_barebox_entry(void *boarddata);
void imx_esdctl_disable(void);
resource_size_t imx6_get_mmdc_sdram_size(void);
resource_size_t imx8m_barebox_earlymem_size(unsigned buswidth);
+resource_size_t imx8m_ddrc_sdram_size(unsigned buswidth);
resource_size_t imx9_ddrc_sdram_size(void);
#endif
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 13/23] ARM: i.MX8M: add support to pass BL3x bl_params
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (11 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 12/23] ARM: i.MX8M: esdctl: export imx8m_ddrc_sdram_size() Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 14/23] ARM: i.MX: scratch: add OP-TEE FDTO support Marco Felsch
` (9 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Add support to handover the BL32 and BL33 entrypoints via the TF-A
struct::bl_params in arg0. This eliminates the requirement to share the
different load addresses between multiple binaries to lower the BSP
integration effort.
In addition to the entriespoints, this commit also adds the support to
pass the builtin barebox DTB to OP-TEE if enabled.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/Kconfig | 13 +++++++++++
arch/arm/mach-imx/atf.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 0d745ce2315834ec5d0c366d227b40f2adff5e83..4e2c82c4bdda712931371a7cb122470fe3441650 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -38,6 +38,19 @@ config ARCH_IMX_ATF
def_bool y
depends on ARCH_IMX8M || ARCH_IMX9
+config ARCH_IMX_ATF_PASS_BL_PARAMS
+ bool "Pass BL3x bl_params as arg0 to TF-A"
+ depends on ARCH_IMX_ATF
+ select ARM_ATF
+ select ARCH_HAS_EARLY_FDT_SUPPORT
+ help
+ Enable this option if you are using an upstream TF-A that uses
+ the struct::bl_params to handover all required BL32 and BL33
+ information required to start the BL32 and BL33 image.
+
+ Since upstream TF-A v2.12 all i.MX8M support this feature except for
+ the i.MX8MQ.
+
config ARCH_IMX_ROMAPI
def_bool y
depends on ARCH_IMX8M || ARCH_IMX9
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index f4d4774b9eec798dd69042560d83f7313c0cb74f..baaf0bcc843a72021f97591348e9d165a34d0640 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
+#include <asm/atf_common.h>
#include <asm/sections.h>
#include <common.h>
#include <firmware.h>
@@ -108,7 +109,60 @@ imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size, void *tfa_dest,
asm volatile("msr sp_el2, %0" : :
"r" (tfa_dest - 16) :
"cc");
- bl31();
+
+ /*
+ * All upstream TF-A versions should be able to handle params passed via
+ * x0-x3. However, if not explicit enabled don't pass any params to the
+ * TF-A since downstream TF-A versions may have problems. Also don't
+ * pass params for i.MX8MQ SoCs since this platform has no upstream
+ * support yet.
+ */
+ if (!IS_ENABLED(CONFIG_ARCH_IMX_ATF_PASS_BL_PARAMS) || cpu_is_mx8mq()) {
+ pr_debug("Jump to BL31 without bl-params\n");
+ bl31();
+ } else {
+ struct bl2_to_bl31_params_mem_v2 *params;
+ unsigned int bufsz = 0;
+ void *buf;
+
+ imx_scratch_get_fdt(&buf, &bufsz);
+ ret = pbl_load_fdt(fdt, buf, bufsz);
+ if (!ret) {
+ unsigned long mem_base = MX8M_DDR_CSD1_BASE_ADDR;
+ unsigned long mem_sz;
+
+ if (cpu_is_mx8mn())
+ mem_sz = imx8m_ddrc_sdram_size(16);
+ else
+ mem_sz = imx8m_ddrc_sdram_size(32);
+
+ fdt = buf;
+ ret = fdt_fixup_mem(fdt, &mem_base, &mem_sz, 1);
+ if (ret) {
+ pr_warn("Failed to fixup FDT memory node, continue without\n");
+ fdt = NULL;
+ }
+ } else {
+ if (ret == -ENOTSUPP)
+ pr_debug("PBL_EARLY_FDT_LOAD disabled, continue without\n");
+ else
+ pr_warn("Failed to load FDT, continue without\n");
+ fdt = NULL;
+ }
+
+ /* Prepare bl_params for BL32 */
+ params = bl2_plat_get_bl31_params_v2((uintptr_t)bl32,
+ (uintptr_t)bl33, (uintptr_t)fdt);
+
+ /*
+ * Start BL31 without passing the FDT via x1 since the mainline
+ * TF-A doesn't support it yet.
+ */
+ pr_debug("Jump to BL31 with bl-params (%s BL32-FDT)\n",
+ fdt ? "including" : "excluding");
+ bl31_entry_v2((uintptr_t)bl31, ¶ms->bl_params, NULL);
+ }
+
__builtin_unreachable();
}
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 14/23] ARM: i.MX: scratch: add OP-TEE FDTO support
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (12 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 13/23] ARM: i.MX8M: add support to pass BL3x bl_params Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 15/23] pbl: string: add strncmp Marco Felsch
` (8 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
OP-TEE has the support to write DTB overlay fragments if enabled via
OP-TEE config switch CFG_EXTERNAL_DTB_OVERLAY.
The overlay fragments are added to the exisiting DTB if OP-TEE was
started with a DTB provided via arg2 or written to a stand-alone DTB
overlay.
This adds a dedicated storage slot which can be passed to OP-TEE or be
used by barebox to extract the added overlay fragment into it.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/scratch.c | 14 ++++++++++++++
common/Kconfig | 10 ++++++++++
include/mach/imx/scratch.h | 1 +
3 files changed, 25 insertions(+)
diff --git a/arch/arm/mach-imx/scratch.c b/arch/arm/mach-imx/scratch.c
index 9c0f1c09c4e0b863d8c95888db7cf0518f698d53..393d3a976fec28a94e4515c82d309eb7338cdd4c 100644
--- a/arch/arm/mach-imx/scratch.c
+++ b/arch/arm/mach-imx/scratch.c
@@ -18,6 +18,7 @@ struct imx_scratch_space {
struct optee_header optee_hdr;
/* FDT needs an 8 byte alignment */
u8 fdt[CONFIG_SCRATCH_FDT_SIZE] __aligned(8);
+ u8 optee_fdto[CONFIG_SCRATCH_FDTO_SIZE] __aligned(8);
};
static_assert(sizeof(struct imx_scratch_space) <= CONFIG_SCRATCH_SIZE);
@@ -108,3 +109,16 @@ void imx_scratch_get_fdt(void **fdt, unsigned int *fdt_sz)
*fdt = scratch->fdt;
*fdt_sz = sizeof(scratch->fdt);
}
+
+void imx_scratch_get_optee_fdto(void **fdto, unsigned int *fdto_sz)
+{
+ if (!scratch) {
+ if (IN_PBL)
+ return;
+ else
+ scratch = (void *)arm_mem_scratch_get();
+ }
+
+ *fdto = scratch->optee_fdto;
+ *fdto_sz = sizeof(scratch->optee_fdto);
+}
diff --git a/common/Kconfig b/common/Kconfig
index 3f394416c3c376d1cf842472803a47462bb012ed..2e4f4d6713575dbdabf24da8953978b40ddf5604 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -318,6 +318,16 @@ config SCRATCH_FDT_SIZE
This option should match the OP-TEE's CFG_DTB_MAX_SIZE configuration
if used by OP-TEE.
+config SCRATCH_FDTO_SIZE
+ hex
+ default 0x0
+ default 0x4000 if PBL_EARLY_FDT_LOAD
+ prompt "Scratch FDTO size"
+ help
+ The size of possible FDT overlay areas used by BL3x binaries to store
+ runtime generated overlays. Can be 0x0 if early FDT support is not
+ requied e.g. during BL31 and BL32 stage.
+
config MALLOC_ALIGNMENT
hex
default 8
diff --git a/include/mach/imx/scratch.h b/include/mach/imx/scratch.h
index 43bf55de48099f1662cd4331620a93303d4dd710..a9745a95732dd961dcae83ec46c3eaa078d62a16 100644
--- a/include/mach/imx/scratch.h
+++ b/include/mach/imx/scratch.h
@@ -15,6 +15,7 @@ const struct optee_header *imx_scratch_get_optee_hdr(void);
void imx_scratch_save_optee_hdr(const struct optee_header *hdr);
void imx_scratch_get_fdt(void **fdt, unsigned int *fdt_sz);
+void imx_scratch_get_optee_fdto(void **fdto, unsigned int *fdto_sz);
#define imx8mq_init_scratch_space() imx8m_init_scratch_space(32, true)
#define imx8mm_init_scratch_space() imx8m_init_scratch_space(32, true)
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 15/23] pbl: string: add strncmp
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (13 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 14/23] ARM: i.MX: scratch: add OP-TEE FDTO support Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 16/23] pbl: fdt: add fdt_copy_node helper Marco Felsch
` (7 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
pbl/string.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/pbl/string.c b/pbl/string.c
index 528f62ef2055aa59643e7a882b2ac1358813386d..89663fef3d6a5b0bdcbda2f3c6bc686f1ee4da71 100644
--- a/pbl/string.c
+++ b/pbl/string.c
@@ -102,6 +102,21 @@ int strcmp(const char *cs, const char *ct)
return res;
}
+int strncmp(const char *cs, const char *ct, size_t count)
+{
+ register signed char __res = 0;
+
+ BUG_ON(!cs || !ct);
+
+ while (count) {
+ if ((__res = *cs - *ct++) != 0 || !*cs++)
+ break;
+ count--;
+ }
+
+ return __res;
+}
+
int strcasecmp(const char *s1, const char *s2)
{
int c1, c2;
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 16/23] pbl: fdt: add fdt_copy_node helper
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (14 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 15/23] pbl: string: add strncmp Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 17/23] handoff-data: Add BL32_DT_OVL entry Marco Felsch
` (6 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Add a helper to copy a node from a src FDT into a dest FDT. The helper
is used later on by OP-TEE because OP-TEE appends FTD overlay fragements
into the provided FTD.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
include/pbl.h | 2 ++
pbl/fdt.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 84 insertions(+)
diff --git a/include/pbl.h b/include/pbl.h
index bf0c9e2ba29428361cb16a572295e66f20acdd82..0961b6b91e585a59a3e8facb1af261857cb6f57e 100644
--- a/include/pbl.h
+++ b/include/pbl.h
@@ -28,6 +28,8 @@ struct fdt_device_id {
const void *
fdt_device_get_match_data(const void *fdt, const char *nodepath,
const struct fdt_device_id ids[]);
+int fdt_copy_node(const void *src_fdt, void *dest_fdt, const char *path,
+ const char *nodename);
int pbl_barebox_verify(const void *compressed_start, unsigned int len,
const void *hash, unsigned int hash_len);
diff --git a/pbl/fdt.c b/pbl/fdt.c
index 0cd9f5a0f11723e9f9b6848e8553da481b92f2be..fa61c3c71298a2e036e0d324c09d452d8f0f7bbe 100644
--- a/pbl/fdt.c
+++ b/pbl/fdt.c
@@ -260,3 +260,85 @@ int pbl_load_fdt(const void *fdt, void *dest, int destsize)
return -EINVAL;
}
+
+static int _fdt_copy_node(const void *src_fdt, const int src_node,
+ void *dest_fdt, int dest_node)
+{
+ int property;
+ int subnode;
+
+ fdt_for_each_property_offset(property, src_fdt, src_node) {
+ const char *name;
+ const void *prop;
+ int prop_len;
+ int ret;
+
+ prop = fdt_getprop_by_offset(src_fdt, property, &name,
+ &prop_len);
+ if (prop_len == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_INTERNAL;
+ if (prop_len < 0)
+ return prop_len;
+
+ ret = fdt_setprop(dest_fdt, dest_node, name, prop, prop_len);
+ if (ret)
+ return ret;
+ }
+
+ fdt_for_each_subnode(subnode, src_fdt, src_node) {
+ const char *name = fdt_get_name(src_fdt, subnode, NULL);
+ int node;
+ int ret;
+
+ node = fdt_add_subnode(dest_fdt, dest_node, name);
+ if (node == -FDT_ERR_EXISTS) {
+ node = fdt_subnode_offset(dest_fdt, dest_node, name);
+ if (node == -FDT_ERR_NOTFOUND)
+ return -FDT_ERR_INTERNAL;
+ }
+
+ if (node < 0)
+ return node;
+
+ ret = _fdt_copy_node(src_fdt, subnode, dest_fdt, node);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+int fdt_copy_node(const void *src_fdt, void *dest_fdt, const char *path,
+ const char *nodename)
+{
+ int src_parent, src_node;
+ int dest_parent, dest_node;
+
+ pr_debug("Copy node %s%s\n", path, nodename);
+
+ src_parent = fdt_path_offset(src_fdt, path);
+ if (src_parent < 0) {
+ pr_err("Cannot find path: %s\n", fdt_strerror(src_parent));
+ return src_parent;
+ }
+
+ src_node = fdt_subnode_offset(src_fdt, src_parent, nodename);
+ if (src_node < 0) {
+ pr_err("Cannot find node: %s\n", fdt_strerror(src_node));
+ return src_node;
+ }
+
+ dest_parent = fdt_path_offset(dest_fdt, path);
+ if (dest_parent < 0) {
+ pr_err("Cannot find path: %s\n", fdt_strerror(dest_parent));
+ return dest_parent;
+ }
+
+ dest_node = fdt_add_subnode(dest_fdt, dest_parent, nodename);
+ if (dest_node < 0) {
+ pr_err("Failed to add node:%s with: %s\n", nodename, fdt_strerror(dest_node));
+ return dest_node;
+ }
+
+ return _fdt_copy_node(src_fdt, src_node, dest_fdt, dest_node);
+}
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 17/23] handoff-data: Add BL32_DT_OVL entry
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (15 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 16/23] pbl: fdt: add fdt_copy_node helper Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 18/23] security: optee: add optee_extract_fdto helper Marco Felsch
` (5 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Add support to pass a BL32 provided FDT_OVL from pbl to barebox.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
include/pbl/handoff-data.h | 1 +
pbl/handoff-data.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/include/pbl/handoff-data.h b/include/pbl/handoff-data.h
index 7552ed5fc35f351f71822d309095980eaa764f63..88b1e9c80331a279564c338e758bd4928861ed56 100644
--- a/include/pbl/handoff-data.h
+++ b/include/pbl/handoff-data.h
@@ -13,6 +13,7 @@ struct handoff_data {
#define HANDOFF_DATA_EXTERNAL_DT HANDOFF_DATA_BAREBOX(2)
#define HANDOFF_DATA_ARM_MACHINE HANDOFF_DATA_BAREBOX(3)
#define HANDOFF_DATA_EFI HANDOFF_DATA_BAREBOX(4)
+#define HANDOFF_DATA_BL32_DT_OVL HANDOFF_DATA_BAREBOX(5)
#define HANDOFF_DATA_BOARD(n) (0x951726fb + (n))
diff --git a/pbl/handoff-data.c b/pbl/handoff-data.c
index 42e53f986bf14408f25cdf4434a5c284f8361401..2e1287cd69232d09b13384db3f1813737d67656e 100644
--- a/pbl/handoff-data.c
+++ b/pbl/handoff-data.c
@@ -189,6 +189,8 @@ static const char *handoff_data_entry_name(struct handoff_data_entry *hde)
return "handoff FDT (external)";
case HANDOFF_DATA_ARM_MACHINE:
return "ARM machine number";
+ case HANDOFF_DATA_BL32_DT_OVL:
+ return "handoff BL32 FDT overlay";
default:
sprintf(name, "handoff %08x", hde->cookie);
return name;
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 18/23] security: optee: add optee_extract_fdto helper
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (16 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 17/23] handoff-data: Add BL32_DT_OVL entry Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:34 ` [PATCH 19/23] security: optee: add helpers to apply OP-TEE FDTO Marco Felsch
` (4 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Add a helper to extract the added OP-TEE FDT overlay fragments from the
FDT provided via arg2 during the boot phase into a dedicated buffer.
The dedicated overlay buffer can be used later on by the PBL code to
apply the overlay to the barebox runtime DTB and to the kernel DTB.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
include/tee/optee.h | 6 ++++++
security/optee.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/include/tee/optee.h b/include/tee/optee.h
index 10e829c04f8832c4c04771800f1963e25f425482..679662a6e6944da59d24d6268ebcf5dff19d0980 100644
--- a/include/tee/optee.h
+++ b/include/tee/optee.h
@@ -37,6 +37,7 @@ int optee_verify_header (const struct optee_header *hdr);
void optee_set_membase(const struct optee_header *hdr);
int optee_get_membase(u64 *membase);
+int optee_extract_fdto(const void *fdt, void *fdto, unsigned int fdto_sz);
#else
@@ -49,6 +50,11 @@ static inline int optee_get_membase(u64 *membase)
return -ENOSYS;
}
+static inline int optee_extract_fdto(const void *fdt, void *fdto, unsigned int fdto_sz)
+{
+ return 0;
+}
+
#endif /* CONFIG_HAVE_OPTEE */
#ifdef __PBL__
diff --git a/security/optee.c b/security/optee.c
index 422bc1c90924ba8ab266b1aa8d06e52c819d2010..3750bb6f496af990d77f3629b470b174dd7a7c7a 100644
--- a/security/optee.c
+++ b/security/optee.c
@@ -5,7 +5,9 @@
#include <tee/optee.h>
#include <linux/printk.h>
#include <linux/errno.h>
+#include <linux/libfdt.h>
#include <linux/limits.h>
+#include <pbl.h>
static u64 optee_membase = U64_MAX;
@@ -60,3 +62,45 @@ void optee_set_membase(const struct optee_header *hdr)
optee_membase = (u64)hdr->init_load_addr_hi << 32;
optee_membase |= hdr->init_load_addr_lo;
}
+
+int optee_extract_fdto(const void *fdt, void *fdto, unsigned int fdto_sz)
+{
+ int err;
+ int subnode;
+
+ err = fdt_check_header(fdt);
+ if (err) {
+ pr_err("Invalid device tree blob: %s\n", fdt_strerror(err));
+ return err;
+ }
+
+ err = fdt_create_empty_tree(fdto, fdto_sz);
+ if (err) {
+ pr_err("Failed to initialize OP-TEE FDTO space: %s\n", fdt_strerror(err));
+ return err;
+ }
+
+ fdt_for_each_subnode(subnode, fdt, 0) {
+ const char *name;
+ int len;
+
+ name = fdt_get_name(fdt, subnode, &len);
+ if (!name) {
+ pr_warn("Failed to query FDT node name: %s\n", fdt_strerror(len));
+ continue;
+ }
+
+ if (strncmp(name, "fragment@", 9) != 0) {
+ pr_debug("Skip node %s\n", name);
+ continue;
+ }
+
+ err |= fdt_copy_node(fdt, fdto, "/", name);
+ }
+
+ /* Clear the FDTO memory to not supply incomplete overlays */
+ if (err)
+ memset(fdto, 0, fdto_sz);
+
+ return err;
+}
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 19/23] security: optee: add helpers to apply OP-TEE FDTO
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (17 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 18/23] security: optee: add optee_extract_fdto helper Marco Felsch
@ 2025-11-10 20:34 ` Marco Felsch
2025-11-10 20:35 ` [PATCH 20/23] ARM: i.MX8M: Add support to extract OP-TEE provided informations Marco Felsch
` (3 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:34 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Add helpers which can be used later on by barebox core to apply an
overlay provided by OP-TEE.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
drivers/tee/optee/Kconfig | 1 +
drivers/tee/optee/of_fixup.c | 46 ++++++++++++++++++++++++++++++++++++++++++++
include/tee/optee.h | 11 +++++++++++
3 files changed, 58 insertions(+)
diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig
index 805aba65edb72e04341db34a1ada6ff94ab30add..ebfc895203287261cd86fc77d15cc9922403e5c0 100644
--- a/drivers/tee/optee/Kconfig
+++ b/drivers/tee/optee/Kconfig
@@ -45,3 +45,4 @@ endif
config OF_FIXUP_OPTEE
def_bool y
depends on HAVE_OPTEE && ARM
+ select LIBFDT
diff --git a/drivers/tee/optee/of_fixup.c b/drivers/tee/optee/of_fixup.c
index 152322901a7e6af9c83da4c6a2d43f6e2c9af329..9df663d970671b658e38073496720033066106b2 100644
--- a/drivers/tee/optee/of_fixup.c
+++ b/drivers/tee/optee/of_fixup.c
@@ -1,10 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-only */
+#include <linux/libfdt.h>
#include <of.h>
#include <linux/ioport.h>
+#include <linux/printk.h>
#include <asm/barebox-arm.h>
#include <tee/optee.h>
+static bool optee_ovl_applied;
+
int of_optee_fixup(struct device_node *root, void *_data)
{
struct of_optee_fixup_data *fixup_data = _data;
@@ -64,3 +68,45 @@ int of_optee_fixup(struct device_node *root, void *_data)
return of_fixup_reserved_memory(root, &res_shm);
}
+
+void optee_register_overlay(void)
+{
+ struct device_node *overlay;
+ size_t size = 0;
+ void *fdto;
+ int err;
+
+ if (optee_ovl_applied) {
+ pr_warn("OP-TEE overlay already applied, skip\n");
+ return;
+ }
+
+ fdto = handoff_data_get_entry(HANDOFF_DATA_BL32_DT_OVL, &size);
+ if (!fdto || size == 0)
+ return;
+
+ err = fdt_check_header(fdto);
+ if (err) {
+ pr_warn("Invalid OP-TEE overlay found: %s\n", fdt_strerror(err));
+ return;
+ }
+
+ overlay = of_unflatten_dtb(fdto, size);
+ if (IS_ERR(overlay)) {
+ pr_warn("Failed to unflatten OP-TEE: %pe\n", overlay);
+ return;
+ }
+
+ err = of_register_overlay(overlay);
+ if (err) {
+ pr_warn("Failed to register OP-TEE overlay: %pe\n", ERR_PTR(err));
+ return;
+ }
+
+ optee_ovl_applied = true;
+}
+
+bool optee_overlay_applied(void)
+{
+ return optee_ovl_applied;
+}
diff --git a/include/tee/optee.h b/include/tee/optee.h
index 679662a6e6944da59d24d6268ebcf5dff19d0980..a3f1917f63957e9cf3193150604cf7c93876e9ce 100644
--- a/include/tee/optee.h
+++ b/include/tee/optee.h
@@ -38,6 +38,8 @@ int optee_verify_header (const struct optee_header *hdr);
void optee_set_membase(const struct optee_header *hdr);
int optee_get_membase(u64 *membase);
int optee_extract_fdto(const void *fdt, void *fdto, unsigned int fdto_sz);
+void optee_register_overlay(void);
+bool optee_overlay_applied(void);
#else
@@ -55,6 +57,15 @@ static inline int optee_extract_fdto(const void *fdt, void *fdto, unsigned int f
return 0;
}
+static inline void optee_register_overlay(void)
+{
+}
+
+static inline bool optee_overlay_applied(void)
+{
+ return false;
+}
+
#endif /* CONFIG_HAVE_OPTEE */
#ifdef __PBL__
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 20/23] ARM: i.MX8M: Add support to extract OP-TEE provided informations
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (18 preceding siblings ...)
2025-11-10 20:34 ` [PATCH 19/23] security: optee: add helpers to apply OP-TEE FDTO Marco Felsch
@ 2025-11-10 20:35 ` Marco Felsch
2025-11-10 20:35 ` [PATCH 21/23] of: base: register optional OP-TEE overlay Marco Felsch
` (2 subsequent siblings)
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:35 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Extract the OP-TEE overlay fragements information into a dedicated
overlay buffer and add the handoff data on success. The handoff data is
used by next commit.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/esdctl.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index 964d438e3f3433332e351d9a70f91857ee33e0b4..b9393fba4ab0f14992d2fec32b0e1b7f1d4bbdfd 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -1015,10 +1015,50 @@ resource_size_t imx8m_barebox_earlymem_size(unsigned buswidth)
return min_t(resource_size_t, SZ_4G - MX8M_DDR_CSD1_BASE_ADDR, size);
}
+static void imx8m_extract_optee_fdto(void)
+{
+ unsigned int early_fdt_sz, fdto_size;
+ void *early_fdt, *fdto_dst;
+
+ imx_scratch_get_fdt(&early_fdt, &early_fdt_sz);
+ /* SCRATCH_FDT_SIZE == 0, e.g. if OP-TEE w/o CFG_DT support is used */
+ if (early_fdt_sz == 0)
+ return;
+
+ imx_scratch_get_optee_fdto(&fdto_dst, &fdto_size);
+ /* SCRATCH_FDTO_SIZE == 0 if feature (back-channel) is not required */
+ if (fdto_size == 0) {
+ pr_debug("OP-TEE dest DTBO size == 0, skip extracting\n");
+ return;
+ }
+
+ /*
+ * OP-TEE DT handling is really cumbersome. In case an external DT was
+ * supplied, OP-TEE re-use this DT and appends overlays.
+ *
+ * Extract the overlays into a single overlay file to make it easier
+ * to apply these onto the barebox and kernel DT.
+ *
+ * It will become easier once barebox supports the transfer-list
+ * protocol and the protocol itself has overlay-entry support.
+ */
+ if (optee_extract_fdto(early_fdt, fdto_dst, fdto_size)) {
+ pr_warn("Failed to extract OP-TEE FDTO, continue without FDTO\n");
+ /*
+ * Don't BUG() because the system may have compile-time config
+ * support
+ */
+ return;
+ }
+
+ handoff_data_add(HANDOFF_DATA_BL32_DT_OVL, fdto_dst, fdto_size);
+}
+
static void __noreturn imx8m_barebox_entry(void *boarddata, unsigned buswidth)
{
imx8m_init_scratch_space(buswidth, false);
optee_set_membase(imx_scratch_get_optee_hdr());
+ imx8m_extract_optee_fdto();
barebox_arm_entry(MX8M_DDR_CSD1_BASE_ADDR,
imx8m_barebox_earlymem_size(buswidth), boarddata);
}
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 21/23] of: base: register optional OP-TEE overlay
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (19 preceding siblings ...)
2025-11-10 20:35 ` [PATCH 20/23] ARM: i.MX8M: Add support to extract OP-TEE provided informations Marco Felsch
@ 2025-11-10 20:35 ` Marco Felsch
2025-11-10 20:35 ` [PATCH 22/23] pbl: add support to disable/remove the /secure-chosen/stdout-path Marco Felsch
2025-11-10 20:35 ` [PATCH 23/23] ARM: i.MX8M: remove /secure-chosen/stdout-path if requested Marco Felsch
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:35 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
The BL32 OP-TEE binary can provide an overlay which contains all
required configurations made by the secure-os, e.g. reserved-memory
nodes, the firmware-interface (smc) and so on.
This overlay can be used to uniform the OP-TEE configuration handling
for all OF platforms. While this patch is platform agnostic, the OP-TEE
overlay supply handling still depends on platform specific integrations.
Therefore only i.MX8MM/N/P platforms support this new feature yet.
However, prepare all ARMv8 platforms for the new loading mechanism.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/imx9.c | 2 +-
arch/arm/mach-rockchip/rockchip.c | 3 ++-
drivers/of/base.c | 3 +++
drivers/soc/imx/soc-imx8m.c | 3 ++-
4 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-imx/imx9.c b/arch/arm/mach-imx/imx9.c
index dd4fbf099e601dda3c01a4e2d64a9552d2f616e5..7eccba4ed630c73b6b4fe266f742fe3d4ed63dd5 100644
--- a/arch/arm/mach-imx/imx9.c
+++ b/arch/arm/mach-imx/imx9.c
@@ -173,7 +173,7 @@ int imx93_init(void)
imx93_set_arm_clock();
imx93_bootsource();
- if (IS_ENABLED(CONFIG_PBL_OPTEE)) {
+ if (IS_ENABLED(CONFIG_PBL_OPTEE) && !optee_overlay_applied()) {
static struct of_optee_fixup_data optee_fixup_data = {
.shm_size = OPTEE_SHM_SIZE,
.method = "smc",
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index 0828f0fa72a9ad2495e012a42918c4b5431652e7..30cec0f0fe7cb651a1b157d5bb257fc67302422a 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -33,7 +33,8 @@ static int rockchip_init(void)
{
const struct optee_header *hdr = rk_scratch_get_optee_hdr();
- if (IS_ENABLED(CONFIG_PBL_OPTEE) && optee_verify_header(hdr) == 0) {
+ if (IS_ENABLED(CONFIG_PBL_OPTEE) && !optee_overlay_applied() &&
+ optee_verify_header(hdr) == 0) {
static struct of_optee_fixup_data optee_fixup_data = {
.shm_size = OPTEE_SHM_SIZE,
.method = "smc",
diff --git a/drivers/of/base.c b/drivers/of/base.c
index c20fffb899a9c87910f424f5e4fd116f11cea546..203ebca1bf30cda5ce817a5d6b6eb437fc3befc6 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -22,6 +22,7 @@
#include <linux/clk.h>
#include <linux/ctype.h>
#include <linux/err.h>
+#include <tee/optee.h>
static struct device_node *root_node;
@@ -2129,6 +2130,8 @@ int barebox_register_fdt(const void *dtb)
return PTR_ERR(root);
}
+ optee_register_overlay();
+
return barebox_register_of(root);
}
diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c
index 3b83284fcbfd56d543cc300b8d42771202aa0bbb..ecc5f30df35dfd89a485a3f6883ab33fbafb897e 100644
--- a/drivers/soc/imx/soc-imx8m.c
+++ b/drivers/soc/imx/soc-imx8m.c
@@ -207,7 +207,8 @@ static int imx8_soc_imx8m_init(struct soc_device_attribute *soc_dev_attr)
imx_set_reset_reason(src + IMX7_SRC_SRSR, imx7_reset_reasons);
pr_info("%s unique ID: %s\n", cputypestr, uid);
- if (IS_ENABLED(CONFIG_PBL_OPTEE) && imx8m_tzc380_is_enabled()) {
+ if (IS_ENABLED(CONFIG_PBL_OPTEE) && imx8m_tzc380_is_enabled() &&
+ !optee_overlay_applied()) {
static struct of_optee_fixup_data optee_fixup_data = {
.shm_size = OPTEE_SHM_SIZE,
.method = "smc",
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 22/23] pbl: add support to disable/remove the /secure-chosen/stdout-path
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (20 preceding siblings ...)
2025-11-10 20:35 ` [PATCH 21/23] of: base: register optional OP-TEE overlay Marco Felsch
@ 2025-11-10 20:35 ` Marco Felsch
2025-11-10 20:35 ` [PATCH 23/23] ARM: i.MX8M: remove /secure-chosen/stdout-path if requested Marco Felsch
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:35 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Add helpers to disable the /secure-chosen/stdout-path property from a
FDT to keep the secure-OS silent. This is useful to keep the console on
for development purpose and off for the release case. For the later
case, the board code also needs to ensure that no /chosen/stdout-path
exsits, else the secure-OS may fallback to this node.
The API is very specific to make clear that only the
/secure-chosen/stdout-path is patched on demand.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
include/pbl.h | 4 ++++
pbl/console.c | 18 ++++++++++++++++++
pbl/fdt.c | 26 ++++++++++++++++++++++++++
3 files changed, 48 insertions(+)
diff --git a/include/pbl.h b/include/pbl.h
index 0961b6b91e585a59a3e8facb1af261857cb6f57e..7e64a9d200ade522ebeb6394c730b608abc6d2bf 100644
--- a/include/pbl.h
+++ b/include/pbl.h
@@ -17,6 +17,9 @@ extern unsigned long free_mem_end_ptr;
void pbl_barebox_uncompress(void *dest, void *compressed_start, unsigned int len);
int pbl_dtbz_uncompress(void *dest, void *compressed_start, unsigned long len);
+void pbl_set_disable_secure_chosen_stdout(void);
+int pbl_disable_secure_chosen_stdout(void);
+
void fdt_find_mem(const void *fdt, unsigned long *membase, unsigned long *memsize);
int fdt_fixup_mem(void *fdt, unsigned long membase[], unsigned long memsize[], size_t num);
@@ -34,6 +37,7 @@ int fdt_copy_node(const void *src_fdt, void *dest_fdt, const char *path,
int pbl_barebox_verify(const void *compressed_start, unsigned int len,
const void *hash, unsigned int hash_len);
int pbl_load_fdt(const void *fdt, void *dest, int destsize);
+int fdt_remove_secure_chosen_stdout(void *fdt);
#endif
diff --git a/pbl/console.c b/pbl/console.c
index 66652320149db5cdb9d365c5b05a9ac0903935d2..b3f2ac60b5e23b487c0d098d5c2ac5c3f2c8acdc 100644
--- a/pbl/console.c
+++ b/pbl/console.c
@@ -4,6 +4,7 @@
#include <debug_ll.h>
#include <asm/sections.h>
#include <linux/err.h>
+#include <pbl.h>
/*
* Put these in the data section so that they survive the clearing of the
@@ -12,6 +13,23 @@
static __attribute__ ((section(".data"))) ulong putc_offset;
static __attribute__ ((section(".data"))) void *putc_ctx;
+/*
+ * No special segment handling required, since the value doesn't need to survive.
+ * The secure-os is loaded only once very early. Therefore this variable is
+ * checked only once too.
+ */
+static int disable_secure_chosen_stdout;
+
+void pbl_set_disable_secure_chosen_stdout(void)
+{
+ disable_secure_chosen_stdout = 1;
+}
+
+int pbl_disable_secure_chosen_stdout(void)
+{
+ return disable_secure_chosen_stdout;
+}
+
/**
* pbl_set_putc() - setup UART used for PBL console
* @putc: The putc function.
diff --git a/pbl/fdt.c b/pbl/fdt.c
index fa61c3c71298a2e036e0d324c09d452d8f0f7bbe..d8160e4a09867aab91dc89de5dc7b00dd08a4155 100644
--- a/pbl/fdt.c
+++ b/pbl/fdt.c
@@ -342,3 +342,29 @@ int fdt_copy_node(const void *src_fdt, void *dest_fdt, const char *path,
return _fdt_copy_node(src_fdt, src_node, dest_fdt, dest_node);
}
+
+int fdt_remove_secure_chosen_stdout(void *fdt)
+{
+ int sec_chosen;
+ int ret;
+
+ if (!fdt)
+ return 0;
+
+ sec_chosen = fdt_path_offset(fdt, "/secure-chosen");
+ /* No secure-chosen node found, nothing to do */
+ if (sec_chosen < 0)
+ return 0;
+
+ ret = fdt_delprop(fdt, sec_chosen, "stdout-path");
+ if (ret) {
+ if (ret == -FDT_ERR_NOTFOUND)
+ return 0;
+
+ pr_warn("Failed to delete /secure-chosen/stdout-path with:%s\n",
+ fdt_strerror(ret));
+ return -EINVAL;
+ }
+
+ return 0;
+}
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread* [PATCH 23/23] ARM: i.MX8M: remove /secure-chosen/stdout-path if requested
2025-11-10 20:34 [PATCH 00/23] Improve OP-TEE handling Marco Felsch
` (21 preceding siblings ...)
2025-11-10 20:35 ` [PATCH 22/23] pbl: add support to disable/remove the /secure-chosen/stdout-path Marco Felsch
@ 2025-11-10 20:35 ` Marco Felsch
22 siblings, 0 replies; 27+ messages in thread
From: Marco Felsch @ 2025-11-10 20:35 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
Remove the /secure-chosen/stdout-path property if requested by the board
code.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
arch/arm/mach-imx/atf.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index baaf0bcc843a72021f97591348e9d165a34d0640..e56aecb9fd814a9324c086b39be3b8790929ba3a 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -142,6 +142,14 @@ imx8m_tfa_start_bl31(const void *tfa_bin, size_t tfa_size, void *tfa_dest,
pr_warn("Failed to fixup FDT memory node, continue without\n");
fdt = NULL;
}
+
+ if (pbl_disable_secure_chosen_stdout()) {
+ ret = fdt_remove_secure_chosen_stdout(fdt);
+ if (ret) {
+ pr_warn("Failed to disable secure-chosen, continue without FDT\n");
+ fdt = NULL;
+ }
+ }
} else {
if (ret == -ENOTSUPP)
pr_debug("PBL_EARLY_FDT_LOAD disabled, continue without\n");
--
2.47.3
^ permalink raw reply [flat|nested] 27+ messages in thread