mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: Barebox List <barebox@lists.infradead.org>
Subject: [PATCH 7/7] ARM: i.MX93: Add OP-TEE support
Date: Fri, 19 Jan 2024 15:24:13 +0100	[thread overview]
Message-ID: <20240119142413.3206832-8-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20240119142413.3206832-1-s.hauer@pengutronix.de>

This enables OP-TEE support for i.MX93. This is done in a way very
similar to how it's done on i.MX8M.
One major difference is that the i.MX93 needs a RAM firmware for the
EdgeLock secure enclave. Without it OP-TEE doesn't work properly.
The firmware can be integrated into the i.MX93 image where the ROM
picks it up automatically. The firmware image is SoC revision specific
though, so we load the firmware during runtime to avoid having to
create a barebox image for each SoC revision.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/atf.c    | 23 ++++++++++++-
 arch/arm/mach-imx/ele.c    | 67 ++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/esdctl.c |  1 +
 arch/arm/mach-imx/imx9.c   | 15 +++++++++
 firmware/Kconfig           | 12 +++++++
 firmware/Makefile          |  5 ++-
 include/mach/imx/ele.h     |  5 +++
 7 files changed, 126 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-imx/atf.c b/arch/arm/mach-imx/atf.c
index 148de8f448..fad9b7954f 100644
--- a/arch/arm/mach-imx/atf.c
+++ b/arch/arm/mach-imx/atf.c
@@ -14,6 +14,7 @@
 #include <soc/fsl/fsl_udc.h>
 #include <soc/fsl/caam.h>
 #include <tee/optee.h>
+#include <mach/imx/ele.h>
 
 /**
  * imx8m_atf_load_bl31 - Load ATF BL31 blob and transfer control to it
@@ -383,6 +384,8 @@ void __noreturn imx93_load_and_start_image_via_tfa(void)
 	void __noreturn (*bl31)(void) = (void *)atf_dest;
 	const void *tfa;
 	size_t tfa_size;
+	void *bl33 = (void *)MX93_ATF_BL33_BASE_ADDR;
+	unsigned long endmem = MX9_DDR_CSD1_BASE_ADDR + imx9_ddrc_sdram_size();
 
 	imx93_init_scratch_space(true);
 
@@ -402,7 +405,25 @@ void __noreturn imx93_load_and_start_image_via_tfa(void)
 	 */
 	memcpy((void *)MX93_ATF_BL33_BASE_ADDR, __image_start, ALIGN(barebox_pbl_size, 1024));
 
-	get_builtin_firmware(imx93_bl31_bin, &tfa, &tfa_size);
+	if (IS_ENABLED(CONFIG_FIRMWARE_IMX93_OPTEE)) {
+		void *bl32 = (void *)arm_mem_optee(endmem);
+		size_t bl32_size;
+		void *bl32_image;
+
+		imx93_ele_load_fw(bl33);
+
+		get_builtin_firmware_ext(imx93_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(imx93_bl31_bin_optee, &tfa, &tfa_size);
+	} else {
+		get_builtin_firmware(imx93_bl31_bin, &tfa, &tfa_size);
+	}
 
 	memcpy(bl31, tfa, tfa_size);
 
diff --git a/arch/arm/mach-imx/ele.c b/arch/arm/mach-imx/ele.c
index 70cfc9ba81..eaae784c94 100644
--- a/arch/arm/mach-imx/ele.c
+++ b/arch/arm/mach-imx/ele.c
@@ -9,6 +9,8 @@
 #include <mach/imx/ele.h>
 #include <mach/imx/imx9-regs.h>
 #include <linux/iopoll.h>
+#include <firmware.h>
+#include <linux/bitfield.h>
 
 #define MU_SR_TE0_MASK		BIT(0)
 #define MU_SR_RF0_MASK		BIT(0)
@@ -142,6 +144,71 @@ int ele_call(struct ele_msg *msg, bool get_response)
 	return imx9_s3mua_call(msg, get_response);
 }
 
+int ele_get_info(struct ele_get_info_data *info)
+{
+        struct ele_msg msg = {
+		.version = ELE_VERSION,
+		.tag = ELE_CMD_TAG,
+		.size = 4,
+		.command = ELE_GET_INFO_REQ,
+		.data = {
+			upper_32_bits((unsigned long)info),
+			lower_32_bits((unsigned long)info),
+			sizeof(struct ele_get_info_data),
+		},
+	};
+	int ret;
+
+	ret = ele_call(&msg, true);
+	if (ret)
+		pr_err("Could not get ELE info: ret %d, response 0x%x\n",
+			ret, msg.data[0]);
+
+	return ret;
+}
+
+int imx93_ele_load_fw(void *bl33)
+{
+	struct ele_get_info_data info = {};
+	struct ele_msg msg = {
+		.version = ELE_VERSION,
+		.tag = ELE_CMD_TAG,
+		.size = 4,
+		.command = ELE_FW_AUTH_REQ,
+	};
+	void *firmware;
+	int size, ret;
+	int rev = 0;
+
+	ele_get_info(&info);
+
+	rev = FIELD_GET(ELE_INFO_SOC_REV, info.soc);
+
+	switch (rev) {
+	case 0xa0:
+		get_builtin_firmware_ext(mx93a0_ahab_container_img, bl33, &firmware, &size);
+		break;
+	case 0xa1:
+		get_builtin_firmware_ext(mx93a1_ahab_container_img, bl33, &firmware, &size);
+		break;
+	default:
+		pr_err("Unknown unhandled SoC revision %2x\n", rev);
+		return -EINVAL;
+	}
+
+	/* Address of the container header */
+	msg.data[0] = lower_32_bits((unsigned long)firmware);
+	/* Actual address of the container header */
+	msg.data[2] = lower_32_bits((unsigned long)firmware);
+
+	ret = ele_call(&msg, true);
+	if (ret)
+		pr_err("Could not start ELE firmware: ret %d, response 0x%x\n",
+			ret, msg.data[0]);
+
+	return 0;
+}
+
 int ele_read_common_fuse(u16 fuse_id, u32 *fuse_word, u32 *response)
 {
 	struct ele_msg msg;
diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index 0dbf0f7242..19b630c7e8 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -1048,6 +1048,7 @@ void __noreturn imx7d_barebox_entry(void *boarddata)
 void __noreturn imx93_barebox_entry(void *boarddata)
 {
 	imx93_init_scratch_space(false);
+	optee_set_membase(imx_scratch_get_optee_hdr());
 
 	barebox_arm_entry(MX9_DDR_CSD1_BASE_ADDR,
 			  imx9_ddrc_sdram_size(), boarddata);
diff --git a/arch/arm/mach-imx/imx9.c b/arch/arm/mach-imx/imx9.c
index 0df4824afd..bfc248aadf 100644
--- a/arch/arm/mach-imx/imx9.c
+++ b/arch/arm/mach-imx/imx9.c
@@ -7,6 +7,10 @@
 #include <mach/imx/ele.h>
 #include <linux/bitfield.h>
 #include <mach/imx/imx9-regs.h>
+#include <tee/optee.h>
+#include <asm-generic/memory_layout.h>
+#include <asm/optee.h>
+#include <mach/imx/scratch.h>
 
 #define SPEED_GRADING_MASK GENMASK(11, 6)
 #define MARKETING_GRADING_MASK     GENMASK(5, 4)
@@ -169,5 +173,16 @@ int imx93_init(void)
 	imx93_type();
 	imx93_set_arm_clock();
 
+	if (IS_ENABLED(CONFIG_PBL_OPTEE)) {
+		static struct of_optee_fixup_data optee_fixup_data = {
+			.shm_size = OPTEE_SHM_SIZE,
+			.method = "smc",
+		};
+
+		optee_set_membase(imx_scratch_get_optee_hdr());
+		of_optee_fixup(of_get_root_node(), &optee_fixup_data);
+		of_register_fixup(of_optee_fixup, &optee_fixup_data);
+	}
+
 	return 0;
 }
diff --git a/firmware/Kconfig b/firmware/Kconfig
index c1731366c6..86a40a9dd1 100644
--- a/firmware/Kconfig
+++ b/firmware/Kconfig
@@ -73,6 +73,18 @@ config FIRMWARE_IMX8MQ_OPTEE
 	  in CONFIG_EXTRA_FIRMWARE_DIR/imx8mq-bl32.bin. When this option is enabled then
 	  the TF-A binary will be used from CONFIG_EXTRA_FIRMWARE_DIR/imx8mq-bl31.bin-optee.
 
+config FIRMWARE_IMX93_OPTEE
+	bool "install OP-TEE on i.MX93 boards"
+	depends on FIRMWARE_IMX93_ATF && PBL_OPTEE
+	help
+	  This enables OP-TEE loading and starting on i.MX8MQ. Place the OP-TEE binary
+	  in CONFIG_EXTRA_FIRMWARE_DIR/imx93-bl32.bin. When this option is enabled then
+	  the TF-A binary will be used from CONFIG_EXTRA_FIRMWARE_DIR/imx93-bl31.bin-optee.
+	  Additionally OP-TEE requires a RAM firmware loaded into the ELE. This is expected
+	  in CONFIG_EXTRA_FIRMWARE_DIR/mx93a0-ahab-container.img and
+	  CONFIG_EXTRA_FIRMWARE_DIR/mx93a1-ahab-container.img. You can obtain it from
+	  https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-ele-imx-0.1.0.bin
+
 config FIRMWARE_CCBV2_OPTEE
 	bool
 	depends on MACH_WEBASTO_CCBV2 && PBL_OPTEE
diff --git a/firmware/Makefile b/firmware/Makefile
index 51d98d54bf..31dd68664e 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -16,10 +16,13 @@ pbl-firmware-$(CONFIG_FIRMWARE_IMX8MM_ATF) += imx8mm-bl31.bin$(if $(CONFIG_FIRMW
 pbl-firmware-$(CONFIG_FIRMWARE_IMX8MN_ATF) += imx8mn-bl31.bin$(if $(CONFIG_FIRMWARE_IMX8MN_OPTEE),-optee,)
 pbl-firmware-$(CONFIG_FIRMWARE_IMX8MP_ATF) += imx8mp-bl31.bin$(if $(CONFIG_FIRMWARE_IMX8MP_OPTEE),-optee,)
 pbl-firmware-$(CONFIG_FIRMWARE_IMX8MQ_ATF) += imx8mq-bl31.bin
-pbl-firmware-$(CONFIG_FIRMWARE_IMX93_ATF) += imx93-bl31.bin
+pbl-firmware-$(CONFIG_FIRMWARE_IMX93_ATF) += imx93-bl31.bin$(if $(CONFIG_FIRMWARE_IMX93_OPTEE),-optee,)
 fw-external-$(CONFIG_FIRMWARE_IMX8MM_OPTEE) += imx8mm-bl32.bin
 fw-external-$(CONFIG_FIRMWARE_IMX8MN_OPTEE) += imx8mn-bl32.bin
 fw-external-$(CONFIG_FIRMWARE_IMX8MP_OPTEE) += imx8mp-bl32.bin
+fw-external-$(CONFIG_FIRMWARE_IMX93_OPTEE) += imx93-bl32.bin \
+					      mx93a0-ahab-container.img \
+					      mx93a1-ahab-container.img
 pbl-firmware-$(CONFIG_ARCH_RK3568) += rk3568-bl31.bin
 pbl-firmware-$(CONFIG_ARCH_RK3568_OPTEE) += rk3568-op-tee.bin
 pbl-firmware-$(CONFIG_ARCH_RK3588) += rk3588-bl31.bin
diff --git a/include/mach/imx/ele.h b/include/mach/imx/ele.h
index 5770878d7d..7e6896be3c 100644
--- a/include/mach/imx/ele.h
+++ b/include/mach/imx/ele.h
@@ -132,10 +132,15 @@ struct ele_get_info_data {
 	u32 state;
 };
 
+#define ELE_INFO_SOC_REV	GENMASK(31, 24)
+
 int ele_call(struct ele_msg *msg, bool get_response);
 
 int ele_read_common_fuse(u16 fuse_id, u32 *fuse_word, u32 *response);
 int ele_release_rdc(u8 core_id, u8 xrdc, u32 *response);
 int ele_read_shadow_fuse(u16 fuse_id, u32 *fuse_word, u32 *response);
+int ele_get_info(struct ele_get_info_data *info);
+
+int imx93_ele_load_fw(void *bl33);
 
 #endif
-- 
2.39.2




  parent reply	other threads:[~2024-01-19 14:25 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-19 14:24 [PATCH 0/7] ARM: Add i.MX93 " Sascha Hauer
2024-01-19 14:24 ` [PATCH 1/7] firmware: add missing FIRMWARE_IMX8MQ_OPTEE symbol Sascha Hauer
2024-01-19 15:10   ` Marco Felsch
2024-01-19 14:24 ` [PATCH 2/7] firmware: add missing include Sascha Hauer
2024-01-19 15:11   ` Marco Felsch
2024-01-19 14:24 ` [PATCH 3/7] firmware: i.MX OP-TEE: Add some Kconfig help Sascha Hauer
2024-01-19 15:12   ` Marco Felsch
2024-01-19 14:24 ` [PATCH 4/7] ARM: i.MX93: add imx93_barebox_entry() Sascha Hauer
2024-01-19 15:21   ` Marco Felsch
2024-01-22 10:20     ` Sascha Hauer
2024-01-19 14:24 ` [PATCH 5/7] ARM: i.MX: export imx9_ddrc_sdram_size() Sascha Hauer
2024-01-19 15:21   ` Marco Felsch
2024-01-19 14:24 ` [PATCH 6/7] ARM: i.MX93: add scratch space support Sascha Hauer
2024-01-19 15:23   ` Marco Felsch
2024-01-19 14:24 ` Sascha Hauer [this message]
2024-01-22 10:15 ` [PATCH 0/7] ARM: Add i.MX93 OP-TEE support Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240119142413.3206832-8-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox