All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] stm32mp: Enable OP-TEE and TZC support in SPL
@ 2021-03-15 15:47 Alexandru Gagniuc
  2021-03-15 15:47 ` [PATCH v2 1/5] spl: mmc: Support OP-TEE payloads in Falcon mode Alexandru Gagniuc
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Alexandru Gagniuc @ 2021-03-15 15:47 UTC (permalink / raw)
  To: u-boot

The purpose of this series is to allow booting an OP-TEE image from
SPL, by corectly configuring the TrustZone (TZC) memory regions.

Although TZC400 is a generic silicon logic that could apply to other
mach- families, support is currently restricted to stm32mp. I have
neither a feasible way nor interest in validating this for other
chips. It's fairly trivial to move the code from mach- to arch/,
should another use case arise.

The configuration of the memory regions is devicetree-driven, so there
isn't much to hardcode, However the delineation between OP-TEE secure
memory and shared memory is not given in the devicetree. This is the
one thing that has to be hardcoded.

Although a variable CONFIG_OPTEE_TZDRAM_SIZE exists which advertises
to do exactly the above, it is not suitable. This variable is used in
u-boot proper, and is dependent on lib/optee being enabled.
CONFIG_SPL_OPTEE, used herein, is independent of lib/optee. Thus,
CONFIG_OPTEE_TZDRAM_SIZE is not guaranteed to exist

Changes since v1:
  - Removed "Weak functions are stupid" comment
  - Addressed blank line complaints from checkpatch

Alexandru Gagniuc (5):
  spl: mmc: Support OP-TEE payloads in Falcon mode
  spl: Introduce spl_board_prepare_for_optee() hook
  arm: stm32mp: Implement support for TZC 400 controller
  stm32mp1: spl: Configure TrustZone controller for OP-TEE
  ARM: dts: stm32mp: Add OP-TEE reserved memory to SPL dtb

 arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi |   3 +
 arch/arm/mach-stm32mp/Makefile           |   1 +
 arch/arm/mach-stm32mp/include/mach/tzc.h |  33 ++++++
 arch/arm/mach-stm32mp/spl.c              |  84 ++++++++++++++
 arch/arm/mach-stm32mp/tzc400.c           | 133 +++++++++++++++++++++++
 common/spl/spl.c                         |   5 +
 common/spl/spl_mmc.c                     |   6 +-
 include/spl.h                            |  14 +++
 8 files changed, 277 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mach-stm32mp/include/mach/tzc.h
 create mode 100644 arch/arm/mach-stm32mp/tzc400.c

-- 
2.26.2

q

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/5] spl: mmc: Support OP-TEE payloads in Falcon mode
  2021-03-15 15:47 [PATCH v2 0/5] stm32mp: Enable OP-TEE and TZC support in SPL Alexandru Gagniuc
@ 2021-03-15 15:47 ` Alexandru Gagniuc
  2021-04-07  7:53   ` Patrick DELAUNAY
  2021-03-15 15:47 ` [PATCH v2 2/5] spl: Introduce spl_board_prepare_for_optee() hook Alexandru Gagniuc
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Alexandru Gagniuc @ 2021-03-15 15:47 UTC (permalink / raw)
  To: u-boot

In general, Falcon mode means we're booting a linux kernel directly.
With FIT images, however, an OP-TEE secure kernel can be booted before
linux. Thus, if the next stage is an IH_OS_TEE, this isn't necessarily
a problem.

Of course, a general solution would involve mmc_load_image_raw_os()
only loading the binary, and leaving the decision of suitability to
someone else. However, a rework of the boot flow is beyond the scope
of this patch. Accept IH_OS_TEE as a valid OS value.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
---
 common/spl/spl_mmc.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index add2785b4e..bab558d055 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -230,8 +230,10 @@ static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
 	if (ret)
 		return ret;
 
-	if (spl_image->os != IH_OS_LINUX) {
-		puts("Expected Linux image is not found. Trying to start U-boot\n");
+	if (spl_image->os != IH_OS_LINUX && spl_image->os != IH_OS_TEE) {
+		puts("Expected OS image is not found. Instead found ");
+		puts(genimg_get_os_name(spl_image->os));
+		puts(". Trying to start U-boot\n");
 		return -ENOENT;
 	}
 
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 2/5] spl: Introduce spl_board_prepare_for_optee() hook
  2021-03-15 15:47 [PATCH v2 0/5] stm32mp: Enable OP-TEE and TZC support in SPL Alexandru Gagniuc
  2021-03-15 15:47 ` [PATCH v2 1/5] spl: mmc: Support OP-TEE payloads in Falcon mode Alexandru Gagniuc
@ 2021-03-15 15:47 ` Alexandru Gagniuc
  2021-04-07  8:02   ` Patrick DELAUNAY
  2021-03-15 15:47 ` [PATCH v2 3/5] arm: stm32mp: Implement support for TZC 400 controller Alexandru Gagniuc
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Alexandru Gagniuc @ 2021-03-15 15:47 UTC (permalink / raw)
  To: u-boot

OP-TEE requires some particular setup, which is not needed for linux
or other payloads. Add a hook for platform-specific code to perform
any OP-TEE related configuration and initialization.

A weak function is used because it is symmetrical to other
spl_board_prepare_for_*() implementations. A solution to avoid the use
of weak functions would trivially apply to all these implementations.
However, re-designing this is beyond the scope of this patch.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Reviewed-by: Tom Rini <trini@konsulko.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
 common/spl/spl.c |  5 +++++
 include/spl.h    | 14 ++++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/common/spl/spl.c b/common/spl/spl.c
index e3d84082f4..bf4629588e 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -161,6 +161,10 @@ __weak void spl_board_prepare_for_linux(void)
 	/* Nothing to do! */
 }
 
+__weak void spl_board_prepare_for_optee(void *fdt)
+{
+}
+
 __weak void spl_board_prepare_for_boot(void)
 {
 	/* Nothing to do! */
@@ -706,6 +710,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 #if CONFIG_IS_ENABLED(OPTEE)
 	case IH_OS_TEE:
 		debug("Jumping to U-Boot via OP-TEE\n");
+		spl_board_prepare_for_optee(spl_image.fdt_addr);
 		spl_optee_entry(NULL, NULL, spl_image.fdt_addr,
 				(void *)spl_image.entry_point);
 		break;
diff --git a/include/spl.h b/include/spl.h
index 0d134587de..939b77972a 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -387,6 +387,20 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
 			   const struct image_header *header);
 
 void spl_board_prepare_for_linux(void);
+
+/**
+ * spl_board_prepare_for_optee() - Prepare board for an OPTEE payload
+ *
+ * Prepares the board for booting an OP-TEE payload. Initialization is platform
+ * specific, and may include configuring the TrustZone memory, and other
+ * initialization steps required by OP-TEE.
+ * Note that @fdt is not used directly by OP-TEE. OP-TEE passes this @fdt to
+ * its normal world target. This target is not guaranteed to be u-boot, so @fdt
+ * changes that would normally be done by u-boot should be done in this step.
+ *
+ * @fdt: Devicetree that will be passed on, or NULL
+ */
+void spl_board_prepare_for_optee(void *fdt);
 void spl_board_prepare_for_boot(void);
 int spl_board_ubi_load_image(u32 boot_device);
 int spl_board_boot_device(u32 boot_device);
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 3/5] arm: stm32mp: Implement support for TZC 400 controller
  2021-03-15 15:47 [PATCH v2 0/5] stm32mp: Enable OP-TEE and TZC support in SPL Alexandru Gagniuc
  2021-03-15 15:47 ` [PATCH v2 1/5] spl: mmc: Support OP-TEE payloads in Falcon mode Alexandru Gagniuc
  2021-03-15 15:47 ` [PATCH v2 2/5] spl: Introduce spl_board_prepare_for_optee() hook Alexandru Gagniuc
@ 2021-03-15 15:47 ` Alexandru Gagniuc
  2021-04-07  8:10   ` Patrick DELAUNAY
  2021-03-15 15:47 ` [PATCH v2 4/5] stm32mp1: spl: Configure TrustZone controller for OP-TEE Alexandru Gagniuc
  2021-03-15 15:47 ` [PATCH v2 5/5] ARM: dts: stm32mp: Add OP-TEE reserved memory to SPL dtb Alexandru Gagniuc
  4 siblings, 1 reply; 11+ messages in thread
From: Alexandru Gagniuc @ 2021-03-15 15:47 UTC (permalink / raw)
  To: u-boot

The purpose of this change is to allow configuring TrustZone (TZC)
memory permissions. For example, OP-TEE expects TZC regions to be
configured in a very particular way. The API presented here is
intended to allow exactly that.

UCLASS support is not implemented, because it would not be too useful.
Changing TZC permissions needs to be done with care, so as not to cut
off access to memory we are currently using. One place where we can
use this is at the end of SPL, right before jumping to OP-TEE.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
 arch/arm/mach-stm32mp/Makefile           |   1 +
 arch/arm/mach-stm32mp/include/mach/tzc.h |  33 ++++++
 arch/arm/mach-stm32mp/tzc400.c           | 133 +++++++++++++++++++++++
 3 files changed, 167 insertions(+)
 create mode 100644 arch/arm/mach-stm32mp/include/mach/tzc.h
 create mode 100644 arch/arm/mach-stm32mp/tzc400.c

diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile
index c8aa24d489..1b878c5a85 100644
--- a/arch/arm/mach-stm32mp/Makefile
+++ b/arch/arm/mach-stm32mp/Makefile
@@ -10,6 +10,7 @@ obj-y += bsec.o
 
 ifdef CONFIG_SPL_BUILD
 obj-y += spl.o
+obj-y += tzc400.o
 else
 obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/
 obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o
diff --git a/arch/arm/mach-stm32mp/include/mach/tzc.h b/arch/arm/mach-stm32mp/include/mach/tzc.h
new file mode 100644
index 0000000000..16db55c464
--- /dev/null
+++ b/arch/arm/mach-stm32mp/include/mach/tzc.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Simple API for configuring TrustZone memory regions
+ *
+ * The premise is that the desired TZC layout is known beforehand, and it can
+ * be configured in one step. tzc_configure() provides this functionality.
+ */
+#ifndef MACH_TZC_H
+#define MACH_TZC_H
+
+#include <linux/types.h>
+
+enum tzc_sec_mode {
+	TZC_ATTR_SEC_NONE = 0,
+	TZC_ATTR_SEC_R = 1,
+	TZC_ATTR_SEC_W = 2,
+	TZC_ATTR_SEC_RW	 = 3
+};
+
+struct tzc_region {
+	uintptr_t base;
+	uintptr_t top;
+	enum tzc_sec_mode sec_mode;
+	uint16_t nsec_id;
+	uint16_t filters_mask;
+};
+
+int tzc_configure(uintptr_t tzc, const struct tzc_region *cfg);
+int tzc_disable_filters(uintptr_t tzc, uint16_t filters_mask);
+int tzc_enable_filters(uintptr_t tzc, uint16_t filters_mask);
+void tzc_dump_config(uintptr_t tzc);
+
+#endif /* MACH_TZC_H */
diff --git a/arch/arm/mach-stm32mp/tzc400.c b/arch/arm/mach-stm32mp/tzc400.c
new file mode 100644
index 0000000000..87b2fd1984
--- /dev/null
+++ b/arch/arm/mach-stm32mp/tzc400.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Simple API for configuring TrustZone memory restrictions for TZC400
+ */
+#include <linux/iopoll.h>
+#include <mach/tzc.h>
+
+#define TZC_TIMEOUT_US		100
+
+#define TZC_BUILD_CONFIG	0x00
+#define TZC_ACTION		0x04
+#define TZC_ACTION_NONE		0
+#define TZC_ACTION_ERR		1
+#define TZC_ACTION_INT		2
+#define TZC_ACTION_INT_ERR	3
+#define TZC_GATE_KEEPER		0x08
+
+#define TZC_REGION0_OFFSET	0x100
+#define TZC_REGION_CFG_SIZE	0x20
+#define TZC_REGION1_OFFSET	0x120
+#define TZC_REGION_BASE		0x00
+#define TZC_REGION_TOP		0x08
+#define TZC_REGION_ATTRIBUTE	0x10
+#define TZC_REGION_ACCESS	0x14
+
+static uint32_t tzc_read(uintptr_t tzc, size_t reg)
+{
+	return readl(tzc + reg);
+}
+
+static void tzc_write(uintptr_t tzc, size_t reg, uint32_t val)
+{
+	writel(val, tzc + reg);
+}
+
+static uint16_t tzc_config_get_active_filters(const struct tzc_region *cfg)
+{
+	uint16_t active_filters = 0;
+
+	for ( ; cfg->top != 0; cfg++)
+		active_filters |= cfg->filters_mask;
+
+	return active_filters;
+}
+
+int tzc_configure(uintptr_t tzc, const struct tzc_region *cfg)
+{
+	uintptr_t region = tzc + TZC_REGION1_OFFSET;
+	uint32_t nsid, attr_reg, active_filters;
+	int ret;
+
+	active_filters = tzc_config_get_active_filters(cfg);
+	if (active_filters == 0)
+		return -EINVAL;
+
+	ret = tzc_disable_filters(tzc, active_filters);
+	if (ret < 0)
+		return ret;
+
+	for ( ; cfg->top != 0; cfg++, region += TZC_REGION_CFG_SIZE) {
+		attr_reg = (cfg->sec_mode & 0x03) << 30;
+		attr_reg |= (cfg->filters_mask & 0x03) << 0;
+		nsid = cfg->nsec_id & 0xffff;
+		nsid |= nsid << 16;
+
+		tzc_write(region, TZC_REGION_BASE, cfg->base);
+		tzc_write(region, TZC_REGION_TOP, cfg->top);
+		tzc_write(region, TZC_REGION_ACCESS, nsid);
+		tzc_write(region, TZC_REGION_ATTRIBUTE, attr_reg);
+	}
+
+	tzc_write(tzc, TZC_ACTION, TZC_ACTION_ERR);
+	return tzc_enable_filters(tzc, active_filters);
+}
+
+int tzc_disable_filters(uintptr_t tzc, uint16_t filters_mask)
+{
+	uint32_t gate = tzc_read(tzc, TZC_GATE_KEEPER);
+	uint32_t filter_status = filters_mask << 16;
+
+	gate &= ~filters_mask;
+	tzc_write(tzc, TZC_GATE_KEEPER, gate);
+
+	return readl_poll_timeout(tzc + TZC_GATE_KEEPER, gate,
+				 (gate & filter_status) == 0, TZC_TIMEOUT_US);
+}
+
+int tzc_enable_filters(uintptr_t tzc, uint16_t filters_mask)
+{
+	uint32_t gate = tzc_read(tzc, TZC_GATE_KEEPER);
+	uint32_t filter_status = filters_mask << 16;
+
+	gate |= filters_mask;
+	tzc_write(tzc, TZC_GATE_KEEPER, gate);
+
+	return readl_poll_timeout(tzc + TZC_GATE_KEEPER, gate,
+				 (gate & filter_status) == filter_status,
+				 TZC_TIMEOUT_US);
+}
+
+static const char *sec_access_str_from_attr(uint32_t attr)
+{
+	const char *const sec_mode[] = { "none", "RO  ", "WO  ", "RW  " };
+
+	return sec_mode[(attr >> 30) & 0x03];
+}
+
+void tzc_dump_config(uintptr_t tzc)
+{
+	uint32_t build_config, base, top, attr, nsaid;
+	int num_regions, i;
+	uintptr_t region;
+
+	build_config = tzc_read(tzc, TZC_BUILD_CONFIG);
+	num_regions = ((build_config >> 0) & 0x1f) + 1;
+
+	for (i = 0; i < num_regions; i++) {
+		region = tzc + TZC_REGION0_OFFSET + i * TZC_REGION_CFG_SIZE;
+
+		base = tzc_read(region, TZC_REGION_BASE);
+		top = tzc_read(region, TZC_REGION_TOP);
+		attr = tzc_read(region, TZC_REGION_ATTRIBUTE);
+		nsaid = tzc_read(region, TZC_REGION_ACCESS);
+
+		if (attr == 0 && nsaid == 0)
+			continue;
+
+		pr_info("TZC region %u: %08x->%08x - filters 0x%x\n",
+			i, base, top, (attr >> 0) & 0xf);
+		pr_info("\t Secure access %s NSAID %08x\n",
+			sec_access_str_from_attr(attr), nsaid);
+	}
+}
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 4/5] stm32mp1: spl: Configure TrustZone controller for OP-TEE
  2021-03-15 15:47 [PATCH v2 0/5] stm32mp: Enable OP-TEE and TZC support in SPL Alexandru Gagniuc
                   ` (2 preceding siblings ...)
  2021-03-15 15:47 ` [PATCH v2 3/5] arm: stm32mp: Implement support for TZC 400 controller Alexandru Gagniuc
@ 2021-03-15 15:47 ` Alexandru Gagniuc
  2021-04-07  8:48   ` Patrick DELAUNAY
  2021-03-15 15:47 ` [PATCH v2 5/5] ARM: dts: stm32mp: Add OP-TEE reserved memory to SPL dtb Alexandru Gagniuc
  4 siblings, 1 reply; 11+ messages in thread
From: Alexandru Gagniuc @ 2021-03-15 15:47 UTC (permalink / raw)
  To: u-boot

OP-TEE is very particular about how the TZC should be configured.
When booting an OP-TEE payload, an incorrect TZC configuration will
result in a panic.

Most information can be derived from the SPL devicetree. The only
information we don't have is the split between TZDRAM and shared
memory. This has to be hardcoded. The rest of the configuration is
fairly easy, and only requires 3 TZC regions. Configure them.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
 arch/arm/mach-stm32mp/spl.c | 84 +++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c
index b53659a698..64882c67e3 100644
--- a/arch/arm/mach-stm32mp/spl.c
+++ b/arch/arm/mach-stm32mp/spl.c
@@ -16,6 +16,7 @@
 #include <asm/global_data.h>
 #include <asm/io.h>
 #include <asm/arch/sys_proto.h>
+#include <mach/tzc.h>
 #include <linux/libfdt.h>
 
 u32 spl_boot_device(void)
@@ -92,6 +93,89 @@ __weak int board_early_init_f(void)
 	return 0;
 }
 
+uint32_t stm32mp_get_dram_size(void)
+{
+	uint32_t ram_size = 0;
+	struct udevice *dev;
+	ofnode node;
+
+	if (uclass_get_device(UCLASS_RAM, 0, &dev))
+		return 0;
+
+	dev_for_each_subnode(node, dev) {
+		ram_size = ofnode_read_u32_default(node, "st,mem-size", 0);
+		if (ram_size)
+			break;
+	}
+
+	return ram_size;
+}
+
+uint32_t optee_get_reserved_memory_base(void)
+{
+	ofnode node;
+	fdt_addr_t start;
+
+	node = ofnode_path("/reserved-memory/optee");
+	if (!ofnode_valid(node))
+		return 0;
+
+	start = ofnode_get_addr(node);
+	return (start < 0) ? 0 : (uintptr_t)start;
+}
+
+#define CFG_TZDRAM_SIZE		0x01e00000
+#define STM32_TZC_NSID_ALL		0xffff
+#define STM32_TZC_FILTER_ALL		3
+
+void stm32_init_tzc_for_optee(void)
+{
+	const uint32_t dram_size = stm32mp_get_dram_size();
+	const uintptr_t dram_top = STM32_DDR_BASE + (dram_size - 1);
+	uint32_t optee_base = optee_get_reserved_memory_base();
+	uint32_t tee_shmem_base = optee_base + CFG_TZDRAM_SIZE;
+	const uintptr_t tzc = STM32_TZC_BASE;
+
+	if (dram_size == 0)
+		panic("Cannot determine DRAM size from devicetree\n");
+
+	const struct tzc_region optee_config[] = {
+		{
+			.base = STM32_DDR_BASE,
+			.top = optee_base - 1,
+			.sec_mode = TZC_ATTR_SEC_NONE,
+			.nsec_id = STM32_TZC_NSID_ALL,
+			.filters_mask = STM32_TZC_FILTER_ALL,
+		}, {
+			.base = optee_base,
+			.top = tee_shmem_base - 1,
+			.sec_mode = TZC_ATTR_SEC_RW,
+			.nsec_id = 0,
+			.filters_mask = STM32_TZC_FILTER_ALL,
+		}, {
+			.base = tee_shmem_base,
+			.top = dram_top,
+			.sec_mode = TZC_ATTR_SEC_NONE,
+			.nsec_id = STM32_TZC_NSID_ALL,
+			.filters_mask = STM32_TZC_FILTER_ALL,
+		}, {
+			.top = 0,
+		}
+	};
+
+	flush_dcache_all();
+
+	tzc_configure(tzc, optee_config);
+	tzc_dump_config(tzc);
+
+	dcache_disable();
+}
+
+void spl_board_prepare_for_optee(void *fdt)
+{
+	stm32_init_tzc_for_optee();
+}
+
 void board_init_f(ulong dummy)
 {
 	struct udevice *dev;
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 5/5] ARM: dts: stm32mp: Add OP-TEE reserved memory to SPL dtb
  2021-03-15 15:47 [PATCH v2 0/5] stm32mp: Enable OP-TEE and TZC support in SPL Alexandru Gagniuc
                   ` (3 preceding siblings ...)
  2021-03-15 15:47 ` [PATCH v2 4/5] stm32mp1: spl: Configure TrustZone controller for OP-TEE Alexandru Gagniuc
@ 2021-03-15 15:47 ` Alexandru Gagniuc
  2021-03-29  7:43   ` Simon Glass
  4 siblings, 1 reply; 11+ messages in thread
From: Alexandru Gagniuc @ 2021-03-15 15:47 UTC (permalink / raw)
  To: u-boot

Add the "/reserved-memory/optee" node to the SPL devicetree. The
purpose is to allow configuring TZC regions when booting OP-TEE.

Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
 arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
index 6787619290..9c4100c39c 100644
--- a/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
+++ b/arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi
@@ -30,9 +30,12 @@
 	};
 
 	reserved-memory {
+		u-boot,dm-pre-reloc;
+
 		optee at de000000 {
 			reg = <0xde000000 0x02000000>;
 			no-map;
+			u-boot,dm-pre-reloc;
 		};
 	};
 
-- 
2.26.2

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v2 5/5] ARM: dts: stm32mp: Add OP-TEE reserved memory to SPL dtb
  2021-03-15 15:47 ` [PATCH v2 5/5] ARM: dts: stm32mp: Add OP-TEE reserved memory to SPL dtb Alexandru Gagniuc
@ 2021-03-29  7:43   ` Simon Glass
  0 siblings, 0 replies; 11+ messages in thread
From: Simon Glass @ 2021-03-29  7:43 UTC (permalink / raw)
  To: u-boot

On Tue, 16 Mar 2021 at 04:47, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>
> Add the "/reserved-memory/optee" node to the SPL devicetree. The
> purpose is to allow configuring TZC regions when booting OP-TEE.
>
> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> ---
>  arch/arm/dts/stm32mp157a-dk1-u-boot.dtsi | 3 +++
>  1 file changed, 3 insertions(+)
>

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

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 1/5] spl: mmc: Support OP-TEE payloads in Falcon mode
  2021-03-15 15:47 ` [PATCH v2 1/5] spl: mmc: Support OP-TEE payloads in Falcon mode Alexandru Gagniuc
@ 2021-04-07  7:53   ` Patrick DELAUNAY
  0 siblings, 0 replies; 11+ messages in thread
From: Patrick DELAUNAY @ 2021-04-07  7:53 UTC (permalink / raw)
  To: u-boot

Hi,

On 3/15/21 4:47 PM, Alexandru Gagniuc wrote:
> In general, Falcon mode means we're booting a linux kernel directly.
> With FIT images, however, an OP-TEE secure kernel can be booted before
> linux. Thus, if the next stage is an IH_OS_TEE, this isn't necessarily
> a problem.
>
> Of course, a general solution would involve mmc_load_image_raw_os()
> only loading the binary, and leaving the decision of suitability to
> someone else. However, a rework of the boot flow is beyond the scope
> of this patch. Accept IH_OS_TEE as a valid OS value.
>
> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> Reviewed-by: Tom Rini <trini@konsulko.com>
> ---
>   common/spl/spl_mmc.c | 6 ++++--
>   1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
> index add2785b4e..bab558d055 100644
> --- a/common/spl/spl_mmc.c
> +++ b/common/spl/spl_mmc.c
> @@ -230,8 +230,10 @@ static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
>   	if (ret)
>   		return ret;
>   
> -	if (spl_image->os != IH_OS_LINUX) {
> -		puts("Expected Linux image is not found. Trying to start U-boot\n");
> +	if (spl_image->os != IH_OS_LINUX && spl_image->os != IH_OS_TEE) {
> +		puts("Expected OS image is not found. Instead found ");
> +		puts(genimg_get_os_name(spl_image->os));
> +		puts(". Trying to start U-boot\n");
>   		return -ENOENT;
>   	}
>   


Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Thanks
Patrick

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 2/5] spl: Introduce spl_board_prepare_for_optee() hook
  2021-03-15 15:47 ` [PATCH v2 2/5] spl: Introduce spl_board_prepare_for_optee() hook Alexandru Gagniuc
@ 2021-04-07  8:02   ` Patrick DELAUNAY
  0 siblings, 0 replies; 11+ messages in thread
From: Patrick DELAUNAY @ 2021-04-07  8:02 UTC (permalink / raw)
  To: u-boot

Hi,

On 3/15/21 4:47 PM, Alexandru Gagniuc wrote:
> OP-TEE requires some particular setup, which is not needed for linux
> or other payloads. Add a hook for platform-specific code to perform
> any OP-TEE related configuration and initialization.
>
> A weak function is used because it is symmetrical to other
> spl_board_prepare_for_*() implementations. A solution to avoid the use
> of weak functions would trivially apply to all these implementations.
> However, re-designing this is beyond the scope of this patch.
>
> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> Reviewed-by: Tom Rini <trini@konsulko.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> ---
>   common/spl/spl.c |  5 +++++
>   include/spl.h    | 14 ++++++++++++++
>   2 files changed, 19 insertions(+)
>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Thanks
Patrick

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 3/5] arm: stm32mp: Implement support for TZC 400 controller
  2021-03-15 15:47 ` [PATCH v2 3/5] arm: stm32mp: Implement support for TZC 400 controller Alexandru Gagniuc
@ 2021-04-07  8:10   ` Patrick DELAUNAY
  0 siblings, 0 replies; 11+ messages in thread
From: Patrick DELAUNAY @ 2021-04-07  8:10 UTC (permalink / raw)
  To: u-boot

Hi

On 3/15/21 4:47 PM, Alexandru Gagniuc wrote:
> The purpose of this change is to allow configuring TrustZone (TZC)
> memory permissions. For example, OP-TEE expects TZC regions to be
> configured in a very particular way. The API presented here is
> intended to allow exactly that.
>
> UCLASS support is not implemented, because it would not be too useful.
> Changing TZC permissions needs to be done with care, so as not to cut
> off access to memory we are currently using. One place where we can
> use this is at the end of SPL, right before jumping to OP-TEE.
>
> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> ---
>   arch/arm/mach-stm32mp/Makefile           |   1 +
>   arch/arm/mach-stm32mp/include/mach/tzc.h |  33 ++++++
>   arch/arm/mach-stm32mp/tzc400.c           | 133 +++++++++++++++++++++++
>   3 files changed, 167 insertions(+)
>   create mode 100644 arch/arm/mach-stm32mp/include/mach/tzc.h
>   create mode 100644 arch/arm/mach-stm32mp/tzc400.c
>
> diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile
> index c8aa24d489..1b878c5a85 100644
> --- a/arch/arm/mach-stm32mp/Makefile
> +++ b/arch/arm/mach-stm32mp/Makefile
> @@ -10,6 +10,7 @@ obj-y += bsec.o
>   
>   ifdef CONFIG_SPL_BUILD
>   obj-y += spl.o
> +obj-y += tzc400.o
>   else
>   obj-$(CONFIG_CMD_STM32PROG) += cmd_stm32prog/
>   obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o
> diff --git a/arch/arm/mach-stm32mp/include/mach/tzc.h b/arch/arm/mach-stm32mp/include/mach/tzc.h
> new file mode 100644
> index 0000000000..16db55c464
> --- /dev/null
> +++ b/arch/arm/mach-stm32mp/include/mach/tzc.h
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Simple API for configuring TrustZone memory regions
> + *
> + * The premise is that the desired TZC layout is known beforehand, and it can
> + * be configured in one step. tzc_configure() provides this functionality.
> + */

As we activate LOG feature, can you add the define:

#define LOG_CATEGORY LOGC_ARCH

> +#ifndef MACH_TZC_H
> +#define MACH_TZC_H
> +
> +#include <linux/types.h>
> +
> +enum tzc_sec_mode {
> +	TZC_ATTR_SEC_NONE = 0,
> +	TZC_ATTR_SEC_R = 1,
> +	TZC_ATTR_SEC_W = 2,
> +	TZC_ATTR_SEC_RW	 = 3
> +};
> +
> +struct tzc_region {
> +	uintptr_t base;
> +	uintptr_t top;
> +	enum tzc_sec_mode sec_mode;
> +	uint16_t nsec_id;
> +	uint16_t filters_mask;
> +};
> +
> +int tzc_configure(uintptr_t tzc, const struct tzc_region *cfg);
> +int tzc_disable_filters(uintptr_t tzc, uint16_t filters_mask);
> +int tzc_enable_filters(uintptr_t tzc, uint16_t filters_mask);
> +void tzc_dump_config(uintptr_t tzc);

(...)


> +
> +void tzc_dump_config(uintptr_t tzc)
> +{
> +	uint32_t build_config, base, top, attr, nsaid;
> +	int num_regions, i;
> +	uintptr_t region;
> +
> +	build_config = tzc_read(tzc, TZC_BUILD_CONFIG);
> +	num_regions = ((build_config >> 0) & 0x1f) + 1;
> +
> +	for (i = 0; i < num_regions; i++) {
> +		region = tzc + TZC_REGION0_OFFSET + i * TZC_REGION_CFG_SIZE;
> +
> +		base = tzc_read(region, TZC_REGION_BASE);
> +		top = tzc_read(region, TZC_REGION_TOP);
> +		attr = tzc_read(region, TZC_REGION_ATTRIBUTE);
> +		nsaid = tzc_read(region, TZC_REGION_ACCESS);
> +
> +		if (attr == 0 && nsaid == 0)
> +			continue;
> +
> +		pr_info("TZC region %u: %08x->%08x - filters 0x%x\n",
> +			i, base, top, (attr >> 0) & 0xf);
> +		pr_info("\t Secure access %s NSAID %08x\n",
> +			sec_access_str_from_attr(attr), nsaid);
Can you use "log_info" instead of "pr_info" here....
> +	}
> +}

except this 2 minors comment, Ok with the path

Patrick

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v2 4/5] stm32mp1: spl: Configure TrustZone controller for OP-TEE
  2021-03-15 15:47 ` [PATCH v2 4/5] stm32mp1: spl: Configure TrustZone controller for OP-TEE Alexandru Gagniuc
@ 2021-04-07  8:48   ` Patrick DELAUNAY
  0 siblings, 0 replies; 11+ messages in thread
From: Patrick DELAUNAY @ 2021-04-07  8:48 UTC (permalink / raw)
  To: u-boot

Hi,

On 3/15/21 4:47 PM, Alexandru Gagniuc wrote:
> OP-TEE is very particular about how the TZC should be configured.
> When booting an OP-TEE payload, an incorrect TZC configuration will
> result in a panic.
>
> Most information can be derived from the SPL devicetree. The only
> information we don't have is the split between TZDRAM and shared
> memory. This has to be hardcoded. The rest of the configuration is
> fairly easy, and only requires 3 TZC regions. Configure them.
>
> Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
> ---
>   arch/arm/mach-stm32mp/spl.c | 84 +++++++++++++++++++++++++++++++++++++
>   1 file changed, 84 insertions(+)
>
> diff --git a/arch/arm/mach-stm32mp/spl.c b/arch/arm/mach-stm32mp/spl.c
> index b53659a698..64882c67e3 100644
> --- a/arch/arm/mach-stm32mp/spl.c
> +++ b/arch/arm/mach-stm32mp/spl.c
> @@ -16,6 +16,7 @@
>   #include <asm/global_data.h>
>   #include <asm/io.h>
>   #include <asm/arch/sys_proto.h>
> +#include <mach/tzc.h>
>   #include <linux/libfdt.h>
>   
>   u32 spl_boot_device(void)
> @@ -92,6 +93,89 @@ __weak int board_early_init_f(void)
>   	return 0;
>   }
>   
> +uint32_t stm32mp_get_dram_size(void)
> +{
> +	uint32_t ram_size = 0;
> +	struct udevice *dev;
> +	ofnode node;
> +
> +	if (uclass_get_device(UCLASS_RAM, 0, &dev))
> +		return 0;
> +
> +	dev_for_each_subnode(node, dev) {
> +		ram_size = ofnode_read_u32_default(node, "st,mem-size", 0);
> +		if (ram_size)
> +			break;
> +	}
> +
> +	return ram_size;
> +}

no need to parse the device tree here, information is available in uclas API

see dram_init() in dram_init.c


uint32_t stm32mp_get_dram_size(void)
{

 ??? struct ram_info ram;

    if (uclass_get_device(UCLASS_RAM, 0, &dev))
	return 0;

 ??? ret = ram_get_info(dev, &ram);

 ??? if (ret)

 ??? ??? return 0;

 ??? return ram.size;
}


> +uint32_t optee_get_reserved_memory_base(void)
> +{
> +	ofnode node;
> +	fdt_addr_t start;
> +
> +	node = ofnode_path("/reserved-memory/optee");
> +	if (!ofnode_valid(node))
> +		return 0;
> +
> +	start = ofnode_get_addr(node);
> +	return (start < 0) ? 0 : (uintptr_t)start;
> +}
> +
> +#define CFG_TZDRAM_SIZE		0x01e00000

=> TEE reserved size should be get from device

 ??? reserved-memory {
 ??? ??? optee at de000000 {
 ??? ??? ??? reg = <0xde000000 0x02000000>;
 ??? ??? ??? no-map;
 ??? ??? };
 ??? };

 ??? start = ofnode_get_addr_size(node, "reg", &size)

Then only the size of the shared memory is hardcoded

#define CFG_SHMEM_SIZE 		0x200000


> +#define STM32_TZC_NSID_ALL		0xffff
> +#define STM32_TZC_FILTER_ALL		3
> +
> +void stm32_init_tzc_for_optee(void)
> +{
> +	const uint32_t dram_size = stm32mp_get_dram_size();
> +	const uintptr_t dram_top = STM32_DDR_BASE + (dram_size - 1);
> +	uint32_t optee_base = optee_get_reserved_memory_base();
> +	uint32_t tee_shmem_base = optee_base + CFG_TZDRAM_SIZE;


uint32_t tee_shmem_base = optee_base + optee_size + CFG_SHMEM_SIZE;

> +	const uintptr_t tzc = STM32_TZC_BASE;
> +
> +	if (dram_size == 0)
> +		panic("Cannot determine DRAM size from devicetree\n");
> +
> +	const struct tzc_region optee_config[] = {
> +		{
> +			.base = STM32_DDR_BASE,
> +			.top = optee_base - 1,
> +			.sec_mode = TZC_ATTR_SEC_NONE,
> +			.nsec_id = STM32_TZC_NSID_ALL,
> +			.filters_mask = STM32_TZC_FILTER_ALL,
> +		}, {
> +			.base = optee_base,
> +			.top = tee_shmem_base - 1,
> +			.sec_mode = TZC_ATTR_SEC_RW,
> +			.nsec_id = 0,
> +			.filters_mask = STM32_TZC_FILTER_ALL,
> +		}, {
> +			.base = tee_shmem_base,
> +			.top = dram_top,
> +			.sec_mode = TZC_ATTR_SEC_NONE,
> +			.nsec_id = STM32_TZC_NSID_ALL,
> +			.filters_mask = STM32_TZC_FILTER_ALL,
> +		}, {
> +			.top = 0,
> +		}
> +	};
> +
> +	flush_dcache_all();
> +
> +	tzc_configure(tzc, optee_config);
> +	tzc_dump_config(tzc);
> +
> +	dcache_disable();
> +}
> +
> +void spl_board_prepare_for_optee(void *fdt)
> +{
> +	stm32_init_tzc_for_optee();
> +}
> +
>   void board_init_f(ulong dummy)
>   {
>   	struct udevice *dev;


Regards,

Patrick

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2021-04-07  8:48 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-15 15:47 [PATCH v2 0/5] stm32mp: Enable OP-TEE and TZC support in SPL Alexandru Gagniuc
2021-03-15 15:47 ` [PATCH v2 1/5] spl: mmc: Support OP-TEE payloads in Falcon mode Alexandru Gagniuc
2021-04-07  7:53   ` Patrick DELAUNAY
2021-03-15 15:47 ` [PATCH v2 2/5] spl: Introduce spl_board_prepare_for_optee() hook Alexandru Gagniuc
2021-04-07  8:02   ` Patrick DELAUNAY
2021-03-15 15:47 ` [PATCH v2 3/5] arm: stm32mp: Implement support for TZC 400 controller Alexandru Gagniuc
2021-04-07  8:10   ` Patrick DELAUNAY
2021-03-15 15:47 ` [PATCH v2 4/5] stm32mp1: spl: Configure TrustZone controller for OP-TEE Alexandru Gagniuc
2021-04-07  8:48   ` Patrick DELAUNAY
2021-03-15 15:47 ` [PATCH v2 5/5] ARM: dts: stm32mp: Add OP-TEE reserved memory to SPL dtb Alexandru Gagniuc
2021-03-29  7:43   ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.