* [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers
@ 2025-06-27 14:07 Sascha Hauer
2025-06-27 14:07 ` [PATCH 01/14] pbl: add panic_no_stacktrace() Sascha Hauer
` (13 more replies)
0 siblings, 14 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX; +Cc: Ahmad Fatoum, Marco Felsch
This series combines Marcos "i.MX6Q TZASC and OP-TEE early helpers" [1]
and my series fixing chainloading barebox on OP-TEE enabled i.MX6ul
platforms [2] into one.
Changes to Marcos series are:
- rename imx6q_tzc380_is_enabled() to imx6q_tzc380_is_bypassed() as the
function really only detects if the bypass bits are set correctly and
not if the tzc380 is enabled.
- Add i.MX6UL variants of the functions Marco created for i.MX6DQ
- Marco created a mx6_start_optee_early() function that has a
switch/case for the actual SoC type. I have split that into SoC
specific functions so that we don't have to carry the binary weight
when only one specific SoC is needed
Changes to my series:
- Ahmad mentioned in [3] that detecting if we are chainloaded based on a
register passed from the 1st stage not robust and might have security
issues. I am therefore now checking if the TZASC is accessible or not.
As a special bonus this series brings us exception handling support in
PBL for ARMv7/ARMv8. This done to implement data_abort_mask() which we
need for the TZASC-is-accessible check, but will also be useful for
debugging issues in the PBL.
[1] https://lore.kernel.org/20250626144527.416697-1-m.felsch@pengutronix.de
[2] https://lore.kernel.org/20250626140329.418033-1-s.hauer@pengutronix.de
[3] https://lore.kernel.org/70b41f3b-4329-48f7-827f-1924e002ab04@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Marco Felsch (6):
ARM: i.MX6QDL: add imxcfg helper to configure the TZASC1/2
ARM: i.MX6Q: add imx6_get_mmdc_sdram_size
ARM: mach-imx: tzasc: add region configure helpers
ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_early_ns_region1()
ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_is_bypassed()
ARM: optee-early: add mx6_start_optee_early helper
Sascha Hauer (8):
pbl: add panic_no_stacktrace()
arch: Allow data_abort_mask() in PBL
ARM: add exception handling support for PBL
ARM: i.MX: add imx6_can_access_tzasc()
ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled
ARM: i.MX: Webasto ccbv2: fix barebox chainloading with OP-TEE enabled
ARM: optee-early: drop start_optee_early()
ARM: i.MX: tqma6ulx: use ENTRY_FUNCTION_WITHSTACK
Documentation/user/optee.rst | 18 +-
arch/Kconfig | 3 +
arch/arm/Kconfig | 10 +
arch/arm/boards/tqma6ulx/lowlevel.c | 27 +--
arch/arm/boards/webasto-ccbv2/lowlevel.c | 24 +--
arch/arm/cpu/Makefile | 1 +
arch/arm/cpu/interrupts_32.c | 14 +-
arch/arm/cpu/interrupts_64.c | 10 +-
arch/arm/cpu/uncompress.c | 2 +
arch/arm/include/asm/barebox-arm.h | 8 +
arch/arm/lib/pbl.lds.S | 4 +
arch/arm/lib32/optee-early.c | 40 +++-
arch/arm/mach-imx/Kconfig | 2 +
arch/arm/mach-imx/Makefile | 2 +-
arch/arm/mach-imx/esdctl.c | 5 +
arch/arm/mach-imx/tzasc.c | 331 +++++++++++++++++++++++++++++++
include/abort.h | 3 +-
include/mach/imx/esdctl.h | 1 +
include/mach/imx/imx6q-tzasc.h | 8 +
include/mach/imx/tzasc.h | 5 +
include/tee/optee.h | 5 +-
pbl/misc.c | 3 +
22 files changed, 481 insertions(+), 45 deletions(-)
---
base-commit: 7e5ea8eb09a1ca3b13e89586411f5a60ae8fd5b3
change-id: 20250627-arm-optee-early-helper-6d894df2201c
Best regards,
--
Sascha Hauer <s.hauer@pengutronix.de>
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 01/14] pbl: add panic_no_stacktrace()
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 14:07 ` [PATCH 02/14] arch: Allow data_abort_mask() in PBL Sascha Hauer
` (12 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX
ARM code calls panic_no_stacktrace() when exceptions are enabled.
In order to to add exception handling support for PBL introduce
panic_no_stacktrace() for PBL as an alias to panic().
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
pbl/misc.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/pbl/misc.c b/pbl/misc.c
index 1f0d992ce08b5c45e8416885de7395f065ab7666..075c6a854bc8c0e01000087bd2a957a7abe92d0d 100644
--- a/pbl/misc.c
+++ b/pbl/misc.c
@@ -20,3 +20,6 @@ void __noreturn panic(const char *fmt, ...)
va_end(args);
while(1);
}
+
+void __noreturn panic_no_stacktrace(const char *fmt, ...)
+ __alias(panic);
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 02/14] arch: Allow data_abort_mask() in PBL
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
2025-06-27 14:07 ` [PATCH 01/14] pbl: add panic_no_stacktrace() Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 14:07 ` [PATCH 03/14] ARM: add exception handling support for PBL Sascha Hauer
` (11 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX
With this architecures which want to support data_abort_mask() in
PBL can select ARCH_HAS_DATA_ABORT_MASK_PBL.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/Kconfig | 3 +++
include/abort.h | 3 ++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index dc5d1e454df5f8f3576e4aba3dd33b7907a75953..5edfd6f7e8d4c7e576d7061f797a917223f8b031 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -68,6 +68,9 @@ config ARCH_HAS_STACK_DUMP
config ARCH_HAS_DATA_ABORT_MASK
bool
+config ARCH_HAS_DATA_ABORT_MASK_PBL
+ bool
+
config ARCH_HAS_ZERO_PAGE
bool
diff --git a/include/abort.h b/include/abort.h
index 95db1b54d6d9f361c9607c6a8ea1f96b4c5f18d0..c623a4c510414c9e92f21e911473bbe8565cace5 100644
--- a/include/abort.h
+++ b/include/abort.h
@@ -2,7 +2,8 @@
#ifndef __ABORT_H
#define __ABORT_H
-#if defined CONFIG_ARCH_HAS_DATA_ABORT_MASK && IN_PROPER
+#if (defined CONFIG_ARCH_HAS_DATA_ABORT_MASK && IN_PROPER) || \
+ (defined CONFIG_ARCH_HAS_DATA_ABORT_MASK_PBL && IN_PBL)
/*
* data_abort_mask - ignore data aborts
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 03/14] ARM: add exception handling support for PBL
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
2025-06-27 14:07 ` [PATCH 01/14] pbl: add panic_no_stacktrace() Sascha Hauer
2025-06-27 14:07 ` [PATCH 02/14] arch: Allow data_abort_mask() in PBL Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 15:30 ` Ahmad Fatoum
2025-06-27 15:45 ` Marco Felsch
2025-06-27 14:07 ` [PATCH 04/14] ARM: i.MX6QDL: add imxcfg helper to configure the TZASC1/2 Sascha Hauer
` (10 subsequent siblings)
13 siblings, 2 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX
Exception handling in PBL can be very useful for debugging PBL code.
This patch adds support for it.
This is currently only implemented for ARMv7 and ARMv8. Only on these
architectures we can tell the CPU where the exception table is. On ARMv6
and older we would have to copy the exception table either to 0x0 or
0xffff0000. Not all SoCs have writable memory at these locations, so we
would have to utilize the MMU to map writable memory there. We are not
there yet, so for now skip exception handling support on these older
architectures.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/Kconfig | 10 ++++++++++
arch/arm/cpu/Makefile | 1 +
arch/arm/cpu/interrupts_32.c | 14 +++++++++++++-
arch/arm/cpu/interrupts_64.c | 10 +++++++++-
arch/arm/cpu/uncompress.c | 2 ++
arch/arm/include/asm/barebox-arm.h | 8 ++++++++
arch/arm/lib/pbl.lds.S | 4 ++++
7 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0800b15d784ca0ab975cf7ceb2f7b47ed10643b1..eaccee9f2f7a128a820e1c55fba816ec5ac4c02d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -378,6 +378,16 @@ config ARM_EXCEPTIONS
bool "enable arm exception handling support"
default y
+config ARM_EXCEPTIONS_PBL
+ select ARCH_HAS_DATA_ABORT_MASK_PBL
+ depends on CPU_V7 || CPU_V8
+ bool "enable arm exception handling support in PBL"
+ help
+ Say yes here to enable exception handling in PBL. Note that the exception
+ table has to be initialized by calling arm_pbl_init_exceptions(). This is
+ done in barebox_pbl_start(). If you need exception handling earlier then
+ you have to call arm_pbl_init_exceptions() earlier from your board code.
+
config ARM_UNWIND
bool "enable stack unwinding support"
depends on AEABI
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index 39e59c2a2f733d668d57a2f28bdd99f69a016229..9550592796702759f950a3bc4de385100ef2b2e8 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -3,6 +3,7 @@
obj-pbl-y += cpu.o
obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions_$(S64_32).o interrupts_$(S64_32).o
+pbl-$(CONFIG_ARM_EXCEPTIONS_PBL) += exceptions_$(S64_32).o interrupts_$(S64_32).o
obj-$(CONFIG_MMU) += mmu-common.o
obj-pbl-$(CONFIG_MMU) += mmu_$(S64_32).o
obj-$(CONFIG_MMU) += dma_$(S64_32).o
diff --git a/arch/arm/cpu/interrupts_32.c b/arch/arm/cpu/interrupts_32.c
index 623efb3966f0c34632e678d9e1edf2b6affcb4c5..cd503b38eeea551f27bbab0663bbfabdda7ffeea 100644
--- a/arch/arm/cpu/interrupts_32.c
+++ b/arch/arm/cpu/interrupts_32.c
@@ -12,6 +12,7 @@
#include <asm/ptrace.h>
#include <asm/barebox-arm.h>
#include <asm/unwind.h>
+#include <asm/system_info.h>
#include <init.h>
/* Avoid missing prototype warning, called from assembly */
@@ -61,7 +62,7 @@ void show_regs (struct pt_regs *regs)
fast_interrupts_enabled (regs) ? "on" : "off",
processor_modes[processor_mode (regs)],
thumb_mode (regs) ? " (T)" : "");
-#ifdef CONFIG_ARM_UNWIND
+#if defined CONFIG_ARM_UNWIND && IN_PROPER
unwind_backtrace(regs);
#endif
}
@@ -181,3 +182,14 @@ int data_abort_unmask(void)
return arm_data_abort_occurred != 0;
}
+
+#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
+void arm_pbl_init_exceptions(void)
+{
+ if (cpu_architecture() < CPU_ARCH_ARMv7)
+ return;
+
+ set_vbar((unsigned long)__exceptions_start);
+ arm_fixup_vectors();
+}
+#endif
diff --git a/arch/arm/cpu/interrupts_64.c b/arch/arm/cpu/interrupts_64.c
index 4d4ef2bab88ef46a7be1cd4add8f3e51423a283b..574ab6a7ec220d2239b6e27c05426e2d4c67d426 100644
--- a/arch/arm/cpu/interrupts_64.c
+++ b/arch/arm/cpu/interrupts_64.c
@@ -88,7 +88,8 @@ static void __noreturn do_exception(struct pt_regs *pt_regs)
{
show_regs(pt_regs);
- unwind_backtrace(pt_regs);
+ if (IN_PROPER)
+ unwind_backtrace(pt_regs);
panic_no_stacktrace("panic: unhandled exception");
}
@@ -226,3 +227,10 @@ static int aarch64_init_vectors(void)
return 0;
}
core_initcall(aarch64_init_vectors);
+
+#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
+void arm_pbl_init_exceptions(void)
+{
+ aarch64_init_vectors();
+}
+#endif
diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
index 4657a4828e67e1b0acfa9dec3aef33bc4c525468..4529ef5e3821e5b31a3673de6285d2f37e0ecba2 100644
--- a/arch/arm/cpu/uncompress.c
+++ b/arch/arm/cpu/uncompress.c
@@ -63,6 +63,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
+ arm_pbl_init_exceptions();
+
if (IS_ENABLED(CONFIG_MMU))
mmu_early_enable(membase, memsize);
else if (IS_ENABLED(CONFIG_ARMV7R_MPU))
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index 7d35e88c812393d45e331f238baecfa91cbbe299..3ab442bd373e50a84b26145395e42879fc96757f 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -52,6 +52,14 @@ static inline void arm_fixup_vectors(void)
}
#endif
+#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
+void arm_pbl_init_exceptions(void);
+#else
+static inline void arm_pbl_init_exceptions(void)
+{
+}
+#endif
+
void *barebox_arm_boot_dtb(void);
/*
diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
index dad37c9e9bca98beb4f34360fa53a0421662f03c..9c51f5eb3a3d8256752a78e03fed851c84d92edb 100644
--- a/arch/arm/lib/pbl.lds.S
+++ b/arch/arm/lib/pbl.lds.S
@@ -52,6 +52,10 @@ SECTIONS
__bare_init_start = .;
*(.text_bare_init*)
__bare_init_end = .;
+ . = ALIGN(0x20);
+ __exceptions_start = .;
+ KEEP(*(.text_exceptions*))
+ __exceptions_stop = .;
*(.text*)
}
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 04/14] ARM: i.MX6QDL: add imxcfg helper to configure the TZASC1/2
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (2 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 03/14] ARM: add exception handling support for PBL Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 14:07 ` [PATCH 05/14] ARM: i.MX6Q: add imx6_get_mmdc_sdram_size Sascha Hauer
` (9 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX; +Cc: Ahmad Fatoum, Marco Felsch
From: Marco Felsch <m.felsch@pengutronix.de>
On i.MX6 platforms we need to set the bypass mode within the DCD unlike
the i.MX8M platforms which uses the PBL lowlevel code
(imx8m_tzc380_init()).
Add a helper for this to make the integration easier.
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
include/mach/imx/imx6q-tzasc.h | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/include/mach/imx/imx6q-tzasc.h b/include/mach/imx/imx6q-tzasc.h
new file mode 100644
index 0000000000000000000000000000000000000000..968b17d5ec3f74674d3a2049423d71a978e675e9
--- /dev/null
+++ b/include/mach/imx/imx6q-tzasc.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Per default all clocks are on, except for TZASC1/2 CG11/2, so enable them
+ * before activate the modules (disable the bypass mode).
+ */
+wm 32 0x020c4070 0xffffffff
+/* Disable TZASC1/2 bypass */
+wm 32 0x020E0024 0x00000003
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 05/14] ARM: i.MX6Q: add imx6_get_mmdc_sdram_size
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (3 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 04/14] ARM: i.MX6QDL: add imxcfg helper to configure the TZASC1/2 Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 14:07 ` [PATCH 06/14] ARM: mach-imx: tzasc: add region configure helpers Sascha Hauer
` (8 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX; +Cc: Ahmad Fatoum, Marco Felsch
From: Marco Felsch <m.felsch@pengutronix.de>
Add a helper to query the MMDC configured SDRAM size.
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/esdctl.c | 5 +++++
include/mach/imx/esdctl.h | 1 +
2 files changed, 6 insertions(+)
diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index 4b67b52ca45eea178889dfc5554a8a9a8ddf51b7..4c4c3528e1a6e68c508edc48ad38c9e2e6324c1c 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -286,6 +286,11 @@ static inline resource_size_t imx6_mmdc_sdram_size(void __iomem *mmdcbase)
return size;
}
+resource_size_t imx6_get_mmdc_sdram_size(void)
+{
+ return imx6_mmdc_sdram_size(IOMEM(MX6_MMDC_P0_BASE_ADDR));
+}
+
static int imx6_mmdc_add_mem(void *mmdcbase, const struct imx_esdctl_data *data)
{
return arm_add_mem_device("ram0", data->base0,
diff --git a/include/mach/imx/esdctl.h b/include/mach/imx/esdctl.h
index d79bf17959e6d46d19af35be8c10003007d21223..97bd444b1a4ca2defdeb9f82180c0366296a32a0 100644
--- a/include/mach/imx/esdctl.h
+++ b/include/mach/imx/esdctl.h
@@ -151,6 +151,7 @@ void __noreturn imx7d_barebox_entry(void *boarddata);
void __noreturn imx93_barebox_entry(void *boarddata);
#define imx6sx_barebox_entry(boarddata) imx6ul_barebox_entry(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 imx9_ddrc_sdram_size(void);
#endif
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 06/14] ARM: mach-imx: tzasc: add region configure helpers
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (4 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 05/14] ARM: i.MX6Q: add imx6_get_mmdc_sdram_size Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 14:07 ` [PATCH 07/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_early_ns_region1() Sascha Hauer
` (7 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX; +Cc: Ahmad Fatoum, Marco Felsch
From: Marco Felsch <m.felsch@pengutronix.de>
At the moment the TZC380 driver is very limited and focused on minimal
platform setup unlike the TZC400 driver.
This commit adds helper functions to setup any number of TZASC regions
of any size which is required by later commits to setup an early
non-secure TZASC region1.
The code is based on the TZC400 barebox driver and the TZC380 OP-TEE
driver.
Acked-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/tzasc.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 236 insertions(+)
diff --git a/arch/arm/mach-imx/tzasc.c b/arch/arm/mach-imx/tzasc.c
index 4cb4d7c5cffc17dc56e77124df2b2df0ed67251c..2a48f841af49d3f14bc017950d2553f7f52b7416 100644
--- a/arch/arm/mach-imx/tzasc.c
+++ b/arch/arm/mach-imx/tzasc.c
@@ -1,11 +1,76 @@
// SPDX-License-Identifier: GPL-2.0-only
+#define pr_fmt(fmt) "tzc380: " fmt
+
+#include <common.h>
#include <mach/imx/generic.h>
#include <mach/imx/tzasc.h>
+#include <linux/bitfield.h>
#include <linux/bitops.h>
+#include <linux/log2.h>
+#include <linux/sizes.h>
#include <mach/imx/imx8m-regs.h>
#include <io.h>
+/*******************************************************************************
+ * TZC380 defines
+ ******************************************************************************/
+
+#define TZC380_BUILD_CONFIG 0x000
+#define TZC380_BUILD_CONFIG_AW GENMASK(13, 8)
+#define TZC380_BUILD_CONFIG_NR GENMASK(4, 0)
+
+/*
+ * All TZC region configuration registers are placed one after another. It
+ * depicts size of block of registers for programming each region.
+ */
+#define TZC380_REGION_REG_SIZE 0x10
+
+#define TZC380_REGION_SETUP_LOW_0 0x100
+#define TZC380_REGION_SETUP_HIGH_0 0x104
+#define TZC380_REGION_ATTR_0 0x108
+#define TZC380_REGION_SP GENMASK(31, 28)
+#define TZC380_SUBREGION_DIS_MASK GENMASK(15, 8)
+#define TZC380_REGION_SIZE GENMASK(6, 1)
+#define TZC380_REGION_EN BIT(0)
+
+/* ID Registers */
+#define TZC380_PID0_OFF 0xfe0
+#define TZC380_PID1_OFF 0xfe4
+#define TZC380_PERIPHERAL_ID 0x380
+#define TZC380_PID2_OFF 0xfe8
+#define TZC380_PID3_OFF 0xfec
+#define TZC380_PID4_OFF 0xfd0
+#define TZC380_CID0_OFF 0xff0
+#define TZC380_CID1_OFF 0xff4
+#define TZC380_CID2_OFF 0xff8
+
+#define TZC380_REGION_OFFSET(region_no) \
+ (TZC380_REGION_REG_SIZE * (region_no))
+#define TZC380_REGION_SETUP_LOW(region_no) \
+ (TZC380_REGION_OFFSET(region_no) + TZC380_REGION_SETUP_LOW_0)
+#define TZC380_REGION_SETUP_HIGH(region_no) \
+ (TZC380_REGION_OFFSET(region_no) + TZC380_REGION_SETUP_HIGH_0)
+#define TZC380_REGION_ATTR(region_no) \
+ (TZC380_REGION_OFFSET(region_no) + TZC380_REGION_ATTR_0)
+
+#define TZC380_REGION_SP_NS_W FIELD_PREP(TZC380_REGION_SP, BIT(0))
+#define TZC380_REGION_SP_NS_R FIELD_PREP(TZC380_REGION_SP, BIT(1))
+#define TZC380_REGION_SP_S_W FIELD_PREP(TZC380_REGION_SP, BIT(2))
+#define TZC380_REGION_SP_S_R FIELD_PREP(TZC380_REGION_SP, BIT(3))
+
+#define TZC380_REGION_SP_ALL \
+ (TZC380_REGION_SP_NS_W | TZC380_REGION_SP_NS_R | \
+ TZC380_REGION_SP_S_W | TZC380_REGION_SP_S_R)
+#define TZC380_REGION_SP_S_RW \
+ (TZC380_REGION_SP_S_W | TZC380_REGION_SP_S_R)
+#define TZC380_REGION_SP_NS_RW \
+ (TZC380_REGION_SP_NS_W | TZC380_REGION_SP_NS_R)
+
+/*******************************************************************************
+ * SoC specific defines
+ ******************************************************************************/
+
#define GPR_TZASC_EN BIT(0)
#define GPR_TZASC_ID_SWAP_BYPASS BIT(1)
#define GPR_TZASC_EN_LOCK BIT(16)
@@ -14,6 +79,177 @@
#define MX8M_TZASC_REGION_ATTRIBUTES_0 (MX8M_TZASC_BASE_ADDR + 0x108)
#define MX8M_TZASC_REGION_ATTRIBUTES_0_SP GENMASK(31, 28)
+/*
+ * Implementation defined values used to validate inputs later.
+ * Filters : max of 4 ; 0 to 3
+ * Regions : max of 9 ; 0 to 8
+ * Address width : Values between 32 to 64
+ */
+struct tzc380_instance {
+ void __iomem *base;
+ uint8_t addr_width;
+ uint8_t num_regions;
+};
+
+/* Some platforms like i.MX6 does have two tzc380 controllers */
+static struct tzc380_instance tzc380_inst[2];
+
+static inline unsigned int tzc_read_peripheral_id(void __iomem *base)
+{
+ unsigned int id;
+
+ id = in_le32(base + TZC380_PID0_OFF);
+ /* Masks DESC part in PID1 */
+ id |= ((in_le32(base + TZC380_PID1_OFF) & 0xFU) << 8U);
+
+ return id;
+}
+
+static struct tzc380_instance *tzc380_init(void __iomem *base)
+{
+ struct tzc380_instance *tzc380 = &tzc380_inst[0];
+ unsigned int tzc380_id;
+ unsigned int tzc380_build;
+
+ if (tzc380->base)
+ tzc380 = &tzc380_inst[1];
+
+ if (tzc380->base)
+ panic("TZC-380: No free memory\n");
+
+ tzc380->base = base;
+
+ tzc380_id = tzc_read_peripheral_id(base);
+ if (tzc380_id != TZC380_PERIPHERAL_ID)
+ panic("TZC-380 : Wrong device ID (0x%x).\n", tzc380_id);
+
+ /* Save values we will use later. */
+ tzc380_build = in_le32(base + TZC380_BUILD_CONFIG);
+ tzc380->addr_width = FIELD_GET(TZC380_BUILD_CONFIG_AW, tzc380_build) + 1;
+ tzc380->num_regions = FIELD_GET(TZC380_BUILD_CONFIG_NR, tzc380_build) + 1;
+
+ return tzc380;
+}
+
+static void
+tzc380_configure_region(struct tzc380_instance *tzc380, unsigned int region,
+ uint64_t region_base, unsigned int region_attr)
+{
+ void __iomem *base = tzc380->base;
+
+ /* Do range checks on regions */
+ ASSERT((region < tzc380->num_regions));
+
+ pr_debug("Configuring region %u\n", region);
+ pr_debug("... base = %#llx\n", region_base);
+ pr_debug("... sp = %#x\n",
+ (unsigned int)FIELD_GET(TZC380_REGION_SP, region_attr));
+ pr_debug("... subregion dis-mask = %#x\n",
+ (unsigned int)FIELD_GET(TZC380_SUBREGION_DIS_MASK, region_attr));
+ pr_debug("... size = %#x\n",
+ (unsigned int)FIELD_GET(TZC380_REGION_SIZE, region_attr));
+ pr_debug("... enable = %#x\n",
+ (unsigned int)FIELD_GET(TZC380_REGION_EN, region_attr));
+
+ /***************************************************/
+ /* Inputs look ok, start programming registers. */
+ /* The address registers are 32 bits wide and */
+ /* have a LOW and HIGH */
+ /* component used to construct an address up to a */
+ /* 64bit. */
+ /***************************************************/
+ out_le32(base + TZC380_REGION_SETUP_LOW(region), (uint32_t)region_base);
+ out_le32(base + TZC380_REGION_SETUP_HIGH(region), (uint32_t)(region_base >> 32));
+
+ /* Set region attributes */
+ out_le32(base + TZC380_REGION_ATTR(region), region_attr);
+}
+
+static int
+tzc380_auto_configure(struct tzc380_instance *tzc380, unsigned int region,
+ uint64_t base, uint64_t size,
+ unsigned int attr)
+{
+ uint64_t sub_region_size = 0;
+ uint64_t area = 0;
+ uint8_t lregion = region;
+ uint64_t region_size = 0;
+ uint64_t sub_address = 0;
+ uint64_t address = base;
+ uint64_t lsize = size;
+ unsigned int lattr;
+ uint32_t mask = 0;
+ uint64_t reminder;
+ int i = 0;
+ uint8_t pow = 0;
+
+ ASSERT(tzc380->base);
+
+ /*
+ * TZC380 RM
+ * For region_attributes_<n> registers, region_size:
+ * Note: The AXI address width, that is AXI_ADDRESS_MSB+1, controls the
+ * upper limit value of the field.
+ */
+ pow = tzc380->addr_width;
+
+ while (lsize != 0 && pow >= 15) {
+ region_size = 1ULL << pow;
+
+ /* Case region fits alignment and covers requested area */
+ if ((address % region_size == 0) &&
+ ((address + lsize) % region_size == 0)) {
+ lattr = attr;
+ lattr |= FIELD_PREP(TZC380_REGION_SIZE, (pow - 1));
+ lattr |= TZC380_REGION_EN;
+
+ tzc380_configure_region(tzc380, lregion, address, lattr);
+
+ lregion++;
+ address += region_size;
+ lsize -= region_size;
+ pow = tzc380->addr_width;
+ continue;
+ }
+
+ /* Cover area using several subregions */
+ sub_region_size = div_u64(region_size, 8);
+ div64_u64_rem(address, sub_region_size, &reminder);
+ if (reminder == 0 && lsize > 2 * sub_region_size) {
+ sub_address = div64_u64(address, region_size) * region_size;
+ mask = 0;
+ for (i = 0; i < 8; i++) {
+ area = (i + 1) * sub_region_size;
+ if (sub_address + area <= address ||
+ sub_address + area > address + lsize) {
+ mask |= FIELD_PREP(TZC380_SUBREGION_DIS_MASK, BIT(i));
+ } else {
+ address += sub_region_size;
+ lsize -= sub_region_size;
+ }
+ }
+
+ lattr = mask | attr;
+ lattr |= FIELD_PREP(TZC380_REGION_SIZE, (pow - 1));
+ lattr |= TZC380_REGION_EN;
+
+ tzc380_configure_region(tzc380, lregion, sub_address, lattr);
+
+ lregion++;
+ pow = tzc380->addr_width;
+ continue;
+ }
+ pow--;
+ }
+ ASSERT(lsize == 0);
+ ASSERT(address == base + size);
+ return lregion;
+}
+
+/******************************************************************************
+ * SoC specific helpers
+ ******************************************************************************/
+
void imx8m_tzc380_init(void)
{
u32 __iomem *gpr = IOMEM(MX8M_IOMUXC_GPR_BASE_ADDR);
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 07/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_early_ns_region1()
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (5 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 06/14] ARM: mach-imx: tzasc: add region configure helpers Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 14:07 ` [PATCH 08/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_is_bypassed() Sascha Hauer
` (6 subsequent siblings)
13 siblings, 0 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX; +Cc: Ahmad Fatoum, Marco Felsch
From: Marco Felsch <m.felsch@pengutronix.de>
Add a helper function which can be used by the board code to setup an
early non-secure TZASC region1 which covers the whole SDRAM size.
This eliminates the current workaround of configuring region0 as
non-secure/secure region.
Acked-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/Makefile | 2 +-
arch/arm/mach-imx/tzasc.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++
include/mach/imx/tzasc.h | 2 ++
3 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 23f51fc660197c2da923697e0c303eec8c85e2b4..07e14b392d6c6872aeed382c1e67899184304cf6 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -21,7 +21,7 @@ obj-pbl-$(CONFIG_ARCH_IMX8M) += imx8m.o
obj-pbl-$(CONFIG_ARCH_IMX_SCRATCHMEM) += scratch.o
obj-$(CONFIG_ARCH_IMX9) += imx9.o imx-v3-image.o
lwl-$(CONFIG_ARCH_IMX_ATF) += atf.o
-obj-pbl-$(CONFIG_ARCH_IMX8M) += tzasc.o
+obj-pbl-y += tzasc.o
obj-pbl-$(CONFIG_ARCH_IMX_ROMAPI) += romapi.o
obj-$(CONFIG_IMX_IIM) += iim.o
obj-$(CONFIG_NAND_IMX) += nand.o
diff --git a/arch/arm/mach-imx/tzasc.c b/arch/arm/mach-imx/tzasc.c
index 2a48f841af49d3f14bc017950d2553f7f52b7416..169c4b9801e5fdd01edd3c5661418a945cf21c55 100644
--- a/arch/arm/mach-imx/tzasc.c
+++ b/arch/arm/mach-imx/tzasc.c
@@ -3,8 +3,10 @@
#define pr_fmt(fmt) "tzc380: " fmt
#include <common.h>
+#include <mach/imx/esdctl.h>
#include <mach/imx/generic.h>
#include <mach/imx/tzasc.h>
+#include <mach/imx/imx6-regs.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/log2.h>
@@ -71,6 +73,9 @@
* SoC specific defines
******************************************************************************/
+#define MX6_TZASC1_BASE 0x21d0000
+#define MX6_TZASC2_BASE 0x21d4000
+
#define GPR_TZASC_EN BIT(0)
#define GPR_TZASC_ID_SWAP_BYPASS BIT(1)
#define GPR_TZASC_EN_LOCK BIT(16)
@@ -250,6 +255,54 @@ tzc380_auto_configure(struct tzc380_instance *tzc380, unsigned int region,
* SoC specific helpers
******************************************************************************/
+static void imx_tzc380_init_and_setup(void __iomem *base, unsigned int region,
+ resource_size_t region_base,
+ resource_size_t region_size,
+ unsigned int region_attr)
+{
+ struct tzc380_instance *tzasc = tzc380_init(base);
+
+ tzc380_auto_configure(tzasc, region, region_base, region_size,
+ region_attr);
+}
+
+/*
+ * imx6q_tzc380_early_ns_region1 - configure the whole DRAM as non-secure
+ * region1
+ *
+ * Passing data between TEE and barebox need to follow some requirements:
+ * - the location can be accessed by the normal and secure world
+ * - the mapping in the normal and secure world must be the same to avoid
+ * manual cache maintenance.
+ *
+ * Therefore this function reads the DRAM size out of the MMDC controller and
+ * configures the whole size as non-secure TZC380 region1. This allows the
+ * early TEE code to map the location as non-secure to while writing the data
+ * e.g. device-tee-overlays. Later on the TEE may reconfigure and lock the
+ * TZC380 regions. The reconfiguration needs to ensure that the exchange data
+ * location is still accessible by the normal world.
+ */
+void imx6q_tzc380_early_ns_region1(void)
+{
+ resource_size_t ram_sz = imx6_get_mmdc_sdram_size();
+
+ imx_tzc380_init_and_setup(IOMEM(MX6_TZASC1_BASE), 1,
+ MX6_MMDC_PORT01_BASE_ADDR, ram_sz,
+ TZC380_REGION_SP_NS_RW);
+ imx_tzc380_init_and_setup(IOMEM(MX6_TZASC2_BASE), 1,
+ MX6_MMDC_PORT01_BASE_ADDR, ram_sz,
+ TZC380_REGION_SP_NS_RW);
+}
+
+void imx6ul_tzc380_early_ns_region1(void)
+{
+ resource_size_t ram_sz = imx6_get_mmdc_sdram_size();
+
+ imx_tzc380_init_and_setup(IOMEM(MX6_TZASC1_BASE), 1,
+ MX6_MMDC_PORT0_BASE_ADDR, ram_sz,
+ TZC380_REGION_SP_NS_RW);
+}
+
void imx8m_tzc380_init(void)
{
u32 __iomem *gpr = IOMEM(MX8M_IOMUXC_GPR_BASE_ADDR);
diff --git a/include/mach/imx/tzasc.h b/include/mach/imx/tzasc.h
index 51c86f168ee41db8659c0ad5f48ca1f102cb76d3..eb479ad55c9c101a5fb47fc4a7178b3669b9e44f 100644
--- a/include/mach/imx/tzasc.h
+++ b/include/mach/imx/tzasc.h
@@ -6,6 +6,8 @@
#include <linux/types.h>
#include <asm/system.h>
+void imx6q_tzc380_early_ns_region1(void);
+void imx6ul_tzc380_early_ns_region1(void);
void imx8m_tzc380_init(void);
bool imx8m_tzc380_is_enabled(void);
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 08/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_is_bypassed()
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (6 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 07/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_early_ns_region1() Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 15:57 ` Marco Felsch
2025-06-27 14:07 ` [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc() Sascha Hauer
` (5 subsequent siblings)
13 siblings, 1 reply; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX; +Cc: Ahmad Fatoum, Marco Felsch
From: Marco Felsch <m.felsch@pengutronix.de>
The TZASC_BYP bits in the IOMUX GPR offer a great way to shoot yourself
in the foot. These bits are cleared by default and with these bits
cleared the TZASC will never check DDR transactions. The TZASC can be
configured normally with the bits cleared, it just doesn't work and all
secure regions can be accessed by the normal worls. These
bits can only be set in the DCD table, trying to set them in code will
make the system hang. As the DCD tables are board specific it's easy to
forget setting them. This patch adds a function that checks if the bits
are set as desired which will be called by the optee-early helper later.
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/tzasc.c | 26 ++++++++++++++++++++++++++
include/mach/imx/tzasc.h | 2 ++
2 files changed, 28 insertions(+)
diff --git a/arch/arm/mach-imx/tzasc.c b/arch/arm/mach-imx/tzasc.c
index 169c4b9801e5fdd01edd3c5661418a945cf21c55..ed20ad8803a2e91b67b5d8c3ab1a4265c4228ec7 100644
--- a/arch/arm/mach-imx/tzasc.c
+++ b/arch/arm/mach-imx/tzasc.c
@@ -76,6 +76,9 @@
#define MX6_TZASC1_BASE 0x21d0000
#define MX6_TZASC2_BASE 0x21d4000
+#define MX6_GPR_TZASC1_EN BIT(0)
+#define MX6_GPR_TZASC2_EN BIT(1)
+
#define GPR_TZASC_EN BIT(0)
#define GPR_TZASC_ID_SWAP_BYPASS BIT(1)
#define GPR_TZASC_EN_LOCK BIT(16)
@@ -303,6 +306,29 @@ void imx6ul_tzc380_early_ns_region1(void)
TZC380_REGION_SP_NS_RW);
}
+bool imx6q_tzc380_is_bypassed(void)
+{
+ u32 __iomem *gpr = IOMEM(MX6_IOMUXC_BASE_ADDR);
+
+ /*
+ * MX6_GPR_TZASC1_EN and MX6_GPR_TZASC2_EN are sticky bits which
+ * preserve their values once set until the next power-up cycle.
+ */
+ return (readl(&gpr[9]) & (MX6_GPR_TZASC1_EN | MX6_GPR_TZASC2_EN)) !=
+ (MX6_GPR_TZASC1_EN | MX6_GPR_TZASC2_EN);
+}
+
+bool imx6ul_tzc380_is_bypassed(void)
+{
+ u32 __iomem *gpr = IOMEM(MX6_IOMUXC_BASE_ADDR + 0x4000);
+
+ /*
+ * MX6_GPR_TZASC1_EN is a sticky bit which preserves its value
+ * once set until the next power-up cycle.
+ */
+ return !(readl(&gpr[9]) & MX6_GPR_TZASC1_EN);
+}
+
void imx8m_tzc380_init(void)
{
u32 __iomem *gpr = IOMEM(MX8M_IOMUXC_GPR_BASE_ADDR);
diff --git a/include/mach/imx/tzasc.h b/include/mach/imx/tzasc.h
index eb479ad55c9c101a5fb47fc4a7178b3669b9e44f..0fbcdc2150e63864366a8dddeed2d1b97685903d 100644
--- a/include/mach/imx/tzasc.h
+++ b/include/mach/imx/tzasc.h
@@ -8,6 +8,8 @@
void imx6q_tzc380_early_ns_region1(void);
void imx6ul_tzc380_early_ns_region1(void);
+bool imx6q_tzc380_is_bypassed(void);
+bool imx6ul_tzc380_is_bypassed(void);
void imx8m_tzc380_init(void);
bool imx8m_tzc380_is_enabled(void);
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc()
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (7 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 08/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_is_bypassed() Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 15:33 ` Ahmad Fatoum
2025-06-27 16:04 ` Marco Felsch
2025-06-27 14:07 ` [PATCH 10/14] ARM: optee-early: add mx6_start_optee_early helper Sascha Hauer
` (4 subsequent siblings)
13 siblings, 2 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX
On ARMv7 there is no direct way to detect if we are in the secure or non
secure world. Add a imx6_can_access_tzasc() for this purpose. When
accessing the TZASC triggers a data abort then we are in the non secure
world. This function can be used later to detect if we have to load
OP-TEE or not.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/mach-imx/tzasc.c | 16 ++++++++++++++++
include/mach/imx/tzasc.h | 1 +
2 files changed, 17 insertions(+)
diff --git a/arch/arm/mach-imx/tzasc.c b/arch/arm/mach-imx/tzasc.c
index ed20ad8803a2e91b67b5d8c3ab1a4265c4228ec7..63f01cbaa6d4a8fbf47b9683ca840ee64f908cfc 100644
--- a/arch/arm/mach-imx/tzasc.c
+++ b/arch/arm/mach-imx/tzasc.c
@@ -13,6 +13,8 @@
#include <linux/sizes.h>
#include <mach/imx/imx8m-regs.h>
#include <io.h>
+#include <abort.h>
+#include <asm/barebox-arm.h>
/*******************************************************************************
* TZC380 defines
@@ -329,6 +331,20 @@ bool imx6ul_tzc380_is_bypassed(void)
return !(readl(&gpr[9]) & MX6_GPR_TZASC1_EN);
}
+bool imx6_can_access_tzasc(void)
+{
+ if (!IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL))
+ panic("%s only works with CONFIG_ARM_EXCEPTIONS_PBL\n", __func__);
+
+ arm_pbl_init_exceptions();
+
+ data_abort_mask();
+
+ readl(IOMEM(MX6_TZASC1_BASE));
+
+ return !data_abort_unmask();
+}
+
void imx8m_tzc380_init(void)
{
u32 __iomem *gpr = IOMEM(MX8M_IOMUXC_GPR_BASE_ADDR);
diff --git a/include/mach/imx/tzasc.h b/include/mach/imx/tzasc.h
index 0fbcdc2150e63864366a8dddeed2d1b97685903d..ca85704a8f459ab6e0cdc975940d855929f3d6f7 100644
--- a/include/mach/imx/tzasc.h
+++ b/include/mach/imx/tzasc.h
@@ -10,6 +10,7 @@ void imx6q_tzc380_early_ns_region1(void);
void imx6ul_tzc380_early_ns_region1(void);
bool imx6q_tzc380_is_bypassed(void);
bool imx6ul_tzc380_is_bypassed(void);
+bool imx6_can_access_tzasc(void);
void imx8m_tzc380_init(void);
bool imx8m_tzc380_is_enabled(void);
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 10/14] ARM: optee-early: add mx6_start_optee_early helper
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (8 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc() Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 15:38 ` Ahmad Fatoum
2025-06-27 14:07 ` [PATCH 11/14] ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled Sascha Hauer
` (3 subsequent siblings)
13 siblings, 1 reply; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX; +Cc: Marco Felsch
From: Marco Felsch <m.felsch@pengutronix.de>
Add a i.MX6 specific helper function which covers most of the steps
usually done within the board lowlevel code. All new i.MX6 boards are
encouraged to use this helper to load OP-TEE since the helper validates
that the TZC380 is enabled and setup the TZC380 region properly.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Documentation/user/optee.rst | 18 +++++++++++-------
arch/arm/lib32/optee-early.c | 42 ++++++++++++++++++++++++++++++++++++++++++
include/tee/optee.h | 4 ++++
3 files changed, 57 insertions(+), 7 deletions(-)
diff --git a/Documentation/user/optee.rst b/Documentation/user/optee.rst
index 2729d21d2e441c8c9ba8171544ace8f516ceefdf..70db754bc4c5ca892c57383ec33097c700806d88 100644
--- a/Documentation/user/optee.rst
+++ b/Documentation/user/optee.rst
@@ -19,14 +19,18 @@ During the PBL
^^^^^^^^^^^^^^
To start OP-TEE during the lowlevel initialization of your board in the ``PBL``,
-enable the ``CONFIG_PBL_OPTEE`` configuration variable. your board should then
+enable the ``CONFIG_PBL_OPTEE`` configuration variable. Your board should then
call the function ``start_optee_early(void* tee, void* fdt)`` with a valid tee
-and FDT. Ensure that your OP-TEE is compiled with ``CFG_NS_ENTRY_ADDR`` unset,
-otherwise OP-TEE will not correctly return to barebox after startup.
-Since OP-TEE in the default configuration also modifies the device tree, don't
-pass the barebox internal device tree, instead copy it into a different memory
-location and pass it to OP-TEE afterwards.
-The modified device tree can then be passed to the main barebox start function.
+and FDT. If you're running on an i.MX6 platform your board code should call
+``imx6q_start_optee_early()`` or ``imx6ul_start_optee_early()`` instead since it
+validates that the TZASC not bypassed and configured as expected by OP-TEE.
+
+Ensure that your OP-TEE is compiled with ``CFG_NS_ENTRY_ADDR`` unset, otherwise
+OP-TEE will not correctly return to barebox after startup. Since OP-TEE in the
+default configuration also modifies the device tree, don't pass the barebox
+internal device tree, instead copy it into a different memory location and pass
+it to OP-TEE afterwards. The modified device tree can then be passed to the
+main barebox start function.
Before Linux start
^^^^^^^^^^^^^^^^^^
diff --git a/arch/arm/lib32/optee-early.c b/arch/arm/lib32/optee-early.c
index 735d829c99fb533ccc9e865430ea167bfd2f0cc2..6f842bdd2010582c61a8e88c9f644e6ae93bcbf4 100644
--- a/arch/arm/lib32/optee-early.c
+++ b/arch/arm/lib32/optee-early.c
@@ -10,6 +10,8 @@
#include <tee/optee.h>
#include <debug_ll.h>
#include <string.h>
+#include <mach/imx/imx6.h>
+#include <mach/imx/tzasc.h>
static jmp_buf tee_buf;
@@ -37,3 +39,43 @@ int start_optee_early(void *fdt, void *tee)
return 0;
}
+
+int imx6q_start_optee_early(void *fdt, void *tee, void *data_location,
+ unsigned int data_location_size)
+{
+ if (imx6q_tzc380_is_bypassed())
+ panic("TZC380 is bypassed, abort OP-TEE loading\n");
+
+ /* Add early non-secure TZASC region1 to pass DTO */
+ imx6q_tzc380_early_ns_region1();
+
+ /*
+ * Set the OP-TEE <-> barebox exchange data location to zero.
+ * This is optional since recent OP-TEE versions perform the
+ * memset too.
+ */
+ if (data_location)
+ memset(data_location, 0, data_location_size);
+
+ return start_optee_early(fdt, tee);
+}
+
+int imx6ul_start_optee_early(void *fdt, void *tee, void *data_location,
+ unsigned int data_location_size)
+{
+ if (imx6ul_tzc380_is_bypassed())
+ panic("TZC380 is bypassed, abort OP-TEE loading\n");
+
+ /* Add early non-secure TZASC region1 to pass DTO */
+ imx6ul_tzc380_early_ns_region1();
+
+ /*
+ * Set the OP-TEE <-> barebox exchange data location to zero.
+ * This is optional since recent OP-TEE versions perform the
+ * memset too.
+ */
+ if (data_location)
+ memset(data_location, 0, data_location_size);
+
+ return start_optee_early(fdt, tee);
+}
diff --git a/include/tee/optee.h b/include/tee/optee.h
index f52775dab5b40f306075bc2d302938c584a6f5ec..943dbb8fdab6a11e25fb27e3487fe6fdec59a182 100644
--- a/include/tee/optee.h
+++ b/include/tee/optee.h
@@ -54,6 +54,10 @@ static inline int optee_get_membase(u64 *membase)
#ifdef __PBL__
int start_optee_early(void* fdt, void* tee);
+int imx6q_start_optee_early(void *fdt, void *tee, void *data_location,
+ unsigned int data_location_size);
+int imx6ul_start_optee_early(void *fdt, void *tee, void *data_location,
+ unsigned int data_location_size);
#endif /* __PBL__ */
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 11/14] ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (9 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 10/14] ARM: optee-early: add mx6_start_optee_early helper Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 15:39 ` Ahmad Fatoum
` (2 more replies)
2025-06-27 14:07 ` [PATCH 12/14] ARM: i.MX: Webasto ccbv2: " Sascha Hauer
` (2 subsequent siblings)
13 siblings, 3 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX
When barebox starts we have to guess if we have to start OP-TEE or not.
The current detection works by checking if the first stage passed us a
device tree pointer. This is not robust and might have security issues
[1], so replace that with the check with imx6_can_access_tzasc(). If we
can access the TZASC then we are the first stage and configure it and
start OP-TEE, otherwise assume that we are chainloaded and continue
without starting OP-TEE.
Chainloading barebox with OP-TEE enabled contained several bugs, so it
never actually worked. This patch fixes them.
[1] https://lore.kernel.org/70b41f3b-4329-48f7-827f-1924e002ab04@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/boards/tqma6ulx/lowlevel.c | 22 +++++++++-------------
arch/arm/mach-imx/Kconfig | 1 +
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/arch/arm/boards/tqma6ulx/lowlevel.c b/arch/arm/boards/tqma6ulx/lowlevel.c
index 5fd997d2ec7e79c7319237a4ae52216e584ba5cd..da67e67537167096477de2b905ee5c42c653c3af 100644
--- a/arch/arm/boards/tqma6ulx/lowlevel.c
+++ b/arch/arm/boards/tqma6ulx/lowlevel.c
@@ -16,6 +16,8 @@
#include <pbl/i2c.h>
#include <boards/tq/tq_eeprom.h>
#include <tee/optee.h>
+#include <mach/imx/tzasc.h>
+#include <tee/optee.h>
#include "tqma6ulx.h"
@@ -66,7 +68,7 @@ static void *read_eeprom(void)
return fdt;
}
-static void noinline start_mba6ulx(u32 r0)
+static void noinline start_mba6ulx(void)
{
void *fdt;
int tee_size;
@@ -76,21 +78,15 @@ static void noinline start_mba6ulx(u32 r0)
fdt = read_eeprom();
- /* Enable normal/secure r/w for TZC380 region0 */
- writel(0xf0000000, 0x021D0108);
-
/*
- * Chainloading barebox will pass a device tree within the RAM in r0,
- * skip OP-TEE early loading in this case
+ * Skip loading barebox when we are chainloaded. We can detect that by detecting
+ * if we can access the TZASC.
*/
- if (IS_ENABLED(CONFIG_FIRMWARE_TQMA6UL_OPTEE) &&
- !(r0 > MX6_MMDC_P0_BASE_ADDR &&
- r0 < MX6_MMDC_P0_BASE_ADDR + SZ_256M)) {
- get_builtin_firmware(mba6ul_optee_bin, &tee, &tee_size);
+ if (IS_ENABLED(CONFIG_FIRMWARE_TQMA6UL_OPTEE) && imx6_can_access_tzasc()) {
- memset((void *)OPTEE_OVERLAY_LOCATION, 0, 0x1000);
+ get_builtin_firmware(mba6ul_optee_bin, &tee, &tee_size);
- start_optee_early(NULL, tee);
+ imx6ul_start_optee_early(NULL, tee, (void *)OPTEE_OVERLAY_LOCATION, 0x1000);
}
imx6ul_barebox_entry(fdt);
@@ -112,5 +108,5 @@ ENTRY_FUNCTION(start_imx6ul_mba6ulx, r0, r1, r2)
setup_c();
barrier();
- start_mba6ulx(r0);
+ start_mba6ulx();
}
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 552e7227a0221fee8232dfba5dcdd60de923ff0c..1bf28b473af2b517a784c11d33f745ad74750583 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -490,6 +490,7 @@ config MACH_TQMA6X
config MACH_TQMA6UL
bool "TQ tqma6ul on mba6ulx"
+ select CONFIG_ARM_EXCEPTIONS_PBL if FIRMWARE_TQMA6UL_OPTEE
select ARCH_IMX6UL
select BOARD_TQ
select I2C_IMX_EARLY
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 12/14] ARM: i.MX: Webasto ccbv2: fix barebox chainloading with OP-TEE enabled
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (10 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 11/14] ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 15:17 ` Ahmad Fatoum
2025-06-27 14:07 ` [PATCH 13/14] ARM: optee-early: drop start_optee_early() Sascha Hauer
2025-06-27 14:08 ` [PATCH 14/14] ARM: i.MX: tqma6ulx: use ENTRY_FUNCTION_WITHSTACK Sascha Hauer
13 siblings, 1 reply; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX
When barebox starts we have to guess if we have to start OP-TEE or not.
The current detection works by checking if the first stage passed us a
device tree pointer. This is not robust and might have security issues
[1], so replace that with the check with imx6_can_access_tzasc(). If we
can access the TZASC then we are the first stage and configure it and
start OP-TEE, otherwise assume that we are chainloaded and continue
without starting OP-TEE.
Chainloading barebox with OP-TEE enabled contained several bugs, so it
never actually worked. This patch fixes them.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/boards/webasto-ccbv2/lowlevel.c | 24 +++++++++---------------
arch/arm/mach-imx/Kconfig | 1 +
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/arch/arm/boards/webasto-ccbv2/lowlevel.c b/arch/arm/boards/webasto-ccbv2/lowlevel.c
index 7a198bd801d41e61e6ab4b3c284948154b61d1ca..c25f8a9cb3ce58742576aa05193f1cf730e2e2c7 100644
--- a/arch/arm/boards/webasto-ccbv2/lowlevel.c
+++ b/arch/arm/boards/webasto-ccbv2/lowlevel.c
@@ -13,6 +13,7 @@
#include <mach/imx/iomux-mx6ul.h>
#include <asm/cache.h>
#include <tee/optee.h>
+#include <mach/imx/tzasc.h>
#include "ccbv2.h"
@@ -31,28 +32,21 @@ static void configure_uart(void)
}
-static void noinline start_ccbv2(u32 r0, unsigned long mem_size, char *fdt)
+static void noinline start_ccbv2(unsigned long mem_size, char *fdt)
{
int tee_size;
void *tee;
- /* Enable normal/secure r/w for TZC380 region0 */
- writel(0xf0000000, 0x021D0108);
-
configure_uart();
/*
- * Chainloading barebox will pass a device tree within the RAM in r0,
- * skip OP-TEE early loading in this case
+ * Skip loading barebox when we are chainloaded. We can detect that by detecting
+ * if we can access the TZASC.
*/
- if(IS_ENABLED(CONFIG_FIRMWARE_CCBV2_OPTEE)
- && !(r0 > MX6_MMDC_P0_BASE_ADDR
- && r0 < MX6_MMDC_P0_BASE_ADDR + mem_size)) {
+ if (IS_ENABLED(CONFIG_FIRMWARE_TQMA6UL_OPTEE) && imx6_can_access_tzasc()) {
get_builtin_firmware(ccbv2_optee_bin, &tee, &tee_size);
- memset((void *)OPTEE_OVERLAY_LOCATION, 0, 0x1000);
-
- start_optee_early(NULL, tee);
+ imx6ul_start_optee_early(NULL, tee, (void *)OPTEE_OVERLAY_LOCATION, 0x1000);
}
imx6ul_barebox_entry(fdt);
@@ -70,7 +64,7 @@ ENTRY_FUNCTION(start_imx6ul_ccbv2_256m, r0, r1, r2)
setup_c();
barrier();
- start_ccbv2(r0, SZ_256M, __dtb_z_imx6ul_webasto_ccbv2_start);
+ start_ccbv2(SZ_256M, __dtb_z_imx6ul_webasto_ccbv2_start);
}
ENTRY_FUNCTION(start_imx6ul_ccbv2_512m, r0, r1, r2)
@@ -83,7 +77,7 @@ ENTRY_FUNCTION(start_imx6ul_ccbv2_512m, r0, r1, r2)
setup_c();
barrier();
- start_ccbv2(r0, SZ_512M, __dtb_z_imx6ul_webasto_ccbv2_start);
+ start_ccbv2(SZ_512M, __dtb_z_imx6ul_webasto_ccbv2_start);
}
extern char __dtb_z_imx6ul_webasto_marvel_start[];
@@ -97,5 +91,5 @@ ENTRY_FUNCTION(start_imx6ul_marvel, r0, r1, r2)
setup_c();
barrier();
- start_ccbv2(r0, SZ_512M, __dtb_z_imx6ul_webasto_marvel_start);
+ start_ccbv2(SZ_512M, __dtb_z_imx6ul_webasto_marvel_start);
}
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 1bf28b473af2b517a784c11d33f745ad74750583..b8486b1fa18944dbb91aab02fc717dd1d228ee09 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -504,6 +504,7 @@ config MACH_VARISCITE_MX6
config MACH_WEBASTO_CCBV2
bool "Webasto Common Communication Board V2"
select ARCH_IMX6UL
+ select CONFIG_ARM_EXCEPTIONS_PBL if FIRMWARE_CCBV2_OPTEE
config MACH_GK802
bool "Zealz GK802 Mini PC"
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 13/14] ARM: optee-early: drop start_optee_early()
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (11 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 12/14] ARM: i.MX: Webasto ccbv2: " Sascha Hauer
@ 2025-06-27 14:07 ` Sascha Hauer
2025-06-27 15:21 ` Ahmad Fatoum
2025-06-27 14:08 ` [PATCH 14/14] ARM: i.MX: tqma6ulx: use ENTRY_FUNCTION_WITHSTACK Sascha Hauer
13 siblings, 1 reply; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:07 UTC (permalink / raw)
To: BAREBOX
Now that all users of start_optee_early() use the SoC variants
make start_optee_early() a static function. While at it move the zeroing
of the data_location which was duplicated in the SoC specific functions
to start_optee_early().
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/lib32/optee-early.c | 34 +++++++++++++++-------------------
include/tee/optee.h | 1 -
2 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/arch/arm/lib32/optee-early.c b/arch/arm/lib32/optee-early.c
index 6f842bdd2010582c61a8e88c9f644e6ae93bcbf4..7ef3f3e9c6f3b934aba9d4d3db2df3fd7a0aa642 100644
--- a/arch/arm/lib32/optee-early.c
+++ b/arch/arm/lib32/optee-early.c
@@ -15,12 +15,24 @@
static jmp_buf tee_buf;
-int start_optee_early(void *fdt, void *tee)
+static int start_optee_early(void *fdt, void *tee, void *data_location,
+ unsigned int data_location_size)
{
void (*tee_start)(void *r0, void *r1, void *r2);
struct optee_header *hdr;
int ret;
+ /* We expect this function to be called with data caches disabled */
+ BUG_ON(get_cr() & CR_C);
+
+ /*
+ * Set the OP-TEE <-> barebox exchange data location to zero.
+ * This is optional since recent OP-TEE versions perform the
+ * memset too.
+ */
+ if (data_location)
+ memset(data_location, 0, data_location_size);
+
hdr = tee;
ret = optee_verify_header(hdr);
if (ret < 0)
@@ -49,15 +61,7 @@ int imx6q_start_optee_early(void *fdt, void *tee, void *data_location,
/* Add early non-secure TZASC region1 to pass DTO */
imx6q_tzc380_early_ns_region1();
- /*
- * Set the OP-TEE <-> barebox exchange data location to zero.
- * This is optional since recent OP-TEE versions perform the
- * memset too.
- */
- if (data_location)
- memset(data_location, 0, data_location_size);
-
- return start_optee_early(fdt, tee);
+ return start_optee_early(fdt, tee, data_location, data_location_size);
}
int imx6ul_start_optee_early(void *fdt, void *tee, void *data_location,
@@ -69,13 +73,5 @@ int imx6ul_start_optee_early(void *fdt, void *tee, void *data_location,
/* Add early non-secure TZASC region1 to pass DTO */
imx6ul_tzc380_early_ns_region1();
- /*
- * Set the OP-TEE <-> barebox exchange data location to zero.
- * This is optional since recent OP-TEE versions perform the
- * memset too.
- */
- if (data_location)
- memset(data_location, 0, data_location_size);
-
- return start_optee_early(fdt, tee);
+ return start_optee_early(fdt, tee, data_location, data_location_size);
}
diff --git a/include/tee/optee.h b/include/tee/optee.h
index 943dbb8fdab6a11e25fb27e3487fe6fdec59a182..77f7924aa4793c001aa6fb15440729e6c77bd483 100644
--- a/include/tee/optee.h
+++ b/include/tee/optee.h
@@ -53,7 +53,6 @@ static inline int optee_get_membase(u64 *membase)
#ifdef __PBL__
-int start_optee_early(void* fdt, void* tee);
int imx6q_start_optee_early(void *fdt, void *tee, void *data_location,
unsigned int data_location_size);
int imx6ul_start_optee_early(void *fdt, void *tee, void *data_location,
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* [PATCH 14/14] ARM: i.MX: tqma6ulx: use ENTRY_FUNCTION_WITHSTACK
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
` (12 preceding siblings ...)
2025-06-27 14:07 ` [PATCH 13/14] ARM: optee-early: drop start_optee_early() Sascha Hauer
@ 2025-06-27 14:08 ` Sascha Hauer
2025-06-27 15:21 ` Ahmad Fatoum
13 siblings, 1 reply; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 14:08 UTC (permalink / raw)
To: BAREBOX
The first thing the tqma6ulx lowlevel code does is setting up the stack.
Use ENTRY_FUNCTION_WITHSTACK() which is specifically for this purpose.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm/boards/tqma6ulx/lowlevel.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/arch/arm/boards/tqma6ulx/lowlevel.c b/arch/arm/boards/tqma6ulx/lowlevel.c
index da67e67537167096477de2b905ee5c42c653c3af..57639f8a84e7680c4ee0608abf31ae8b6f1cfd28 100644
--- a/arch/arm/boards/tqma6ulx/lowlevel.c
+++ b/arch/arm/boards/tqma6ulx/lowlevel.c
@@ -92,13 +92,10 @@ static void noinline start_mba6ulx(void)
imx6ul_barebox_entry(fdt);
}
-ENTRY_FUNCTION(start_imx6ul_mba6ulx, r0, r1, r2)
+ENTRY_FUNCTION_WITHSTACK(start_imx6ul_mba6ulx, 0x00910000, r0, r1, r2)
{
-
imx6ul_cpu_lowlevel_init();
- arm_setup_stack(0x00910000);
-
if (IS_ENABLED(CONFIG_DEBUG_LL)) {
imx6_uart_setup_ll();
putc_ll('>');
--
2.39.5
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 12/14] ARM: i.MX: Webasto ccbv2: fix barebox chainloading with OP-TEE enabled
2025-06-27 14:07 ` [PATCH 12/14] ARM: i.MX: Webasto ccbv2: " Sascha Hauer
@ 2025-06-27 15:17 ` Ahmad Fatoum
0 siblings, 0 replies; 35+ messages in thread
From: Ahmad Fatoum @ 2025-06-27 15:17 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX
On 6/27/25 16:07, Sascha Hauer wrote:
> When barebox starts we have to guess if we have to start OP-TEE or not.
> The current detection works by checking if the first stage passed us a
> device tree pointer. This is not robust and might have security issues
> [1], so replace that with the check with imx6_can_access_tzasc(). If we
> can access the TZASC then we are the first stage and configure it and
> start OP-TEE, otherwise assume that we are chainloaded and continue
> without starting OP-TEE.
>
> Chainloading barebox with OP-TEE enabled contained several bugs, so it
> never actually worked. This patch fixes them.
[1]:
https://lore.barebox.org/barebox/aF6R-RbRmCgcp9AE@pengutronix.de/T/#mc4bcae71ee7622eda46d1f6a3de52fdf40f4c65e
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
With the bug below fixed:
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 1bf28b473af2b517a784c11d33f745ad74750583..b8486b1fa18944dbb91aab02fc717dd1d228ee09 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -504,6 +504,7 @@ config MACH_VARISCITE_MX6
> config MACH_WEBASTO_CCBV2
> bool "Webasto Common Communication Board V2"
> select ARCH_IMX6UL
> + select CONFIG_ARM_EXCEPTIONS_PBL if FIRMWARE_CCBV2_OPTEE
Drop the CONFIG_
>
> config MACH_GK802
> bool "Zealz GK802 Mini PC"
>
--
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] 35+ messages in thread
* Re: [PATCH 13/14] ARM: optee-early: drop start_optee_early()
2025-06-27 14:07 ` [PATCH 13/14] ARM: optee-early: drop start_optee_early() Sascha Hauer
@ 2025-06-27 15:21 ` Ahmad Fatoum
2025-06-27 17:59 ` Sascha Hauer
0 siblings, 1 reply; 35+ messages in thread
From: Ahmad Fatoum @ 2025-06-27 15:21 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX
Hi,
On 6/27/25 16:07, Sascha Hauer wrote:
> Now that all users of start_optee_early() use the SoC variants
> make start_optee_early() a static function. While at it move the zeroing
> of the data_location which was duplicated in the SoC specific functions
> to start_optee_early().
start_optee_early() is documented in Documentation/user/optee.rst and
would need to be updated.
> + /* We expect this function to be called with data caches disabled */
> + BUG_ON(get_cr() & CR_C);
Did you mean to drop the BUG_ON() in start_optee_early().
Cheers,
Ahmad
--
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] 35+ messages in thread
* Re: [PATCH 14/14] ARM: i.MX: tqma6ulx: use ENTRY_FUNCTION_WITHSTACK
2025-06-27 14:08 ` [PATCH 14/14] ARM: i.MX: tqma6ulx: use ENTRY_FUNCTION_WITHSTACK Sascha Hauer
@ 2025-06-27 15:21 ` Ahmad Fatoum
0 siblings, 0 replies; 35+ messages in thread
From: Ahmad Fatoum @ 2025-06-27 15:21 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX
On 6/27/25 16:08, Sascha Hauer wrote:
> The first thing the tqma6ulx lowlevel code does is setting up the stack.
> Use ENTRY_FUNCTION_WITHSTACK() which is specifically for this purpose.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> arch/arm/boards/tqma6ulx/lowlevel.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/arch/arm/boards/tqma6ulx/lowlevel.c b/arch/arm/boards/tqma6ulx/lowlevel.c
> index da67e67537167096477de2b905ee5c42c653c3af..57639f8a84e7680c4ee0608abf31ae8b6f1cfd28 100644
> --- a/arch/arm/boards/tqma6ulx/lowlevel.c
> +++ b/arch/arm/boards/tqma6ulx/lowlevel.c
> @@ -92,13 +92,10 @@ static void noinline start_mba6ulx(void)
> imx6ul_barebox_entry(fdt);
> }
>
> -ENTRY_FUNCTION(start_imx6ul_mba6ulx, r0, r1, r2)
> +ENTRY_FUNCTION_WITHSTACK(start_imx6ul_mba6ulx, 0x00910000, r0, r1, r2)
> {
> -
> imx6ul_cpu_lowlevel_init();
>
> - arm_setup_stack(0x00910000);
> -
> if (IS_ENABLED(CONFIG_DEBUG_LL)) {
> imx6_uart_setup_ll();
> putc_ll('>');
>
--
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] 35+ messages in thread
* Re: [PATCH 03/14] ARM: add exception handling support for PBL
2025-06-27 14:07 ` [PATCH 03/14] ARM: add exception handling support for PBL Sascha Hauer
@ 2025-06-27 15:30 ` Ahmad Fatoum
2025-06-27 15:45 ` Marco Felsch
1 sibling, 0 replies; 35+ messages in thread
From: Ahmad Fatoum @ 2025-06-27 15:30 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX
On 6/27/25 16:07, Sascha Hauer wrote:
> Exception handling in PBL can be very useful for debugging PBL code.
> This patch adds support for it.
\o/
>
> This is currently only implemented for ARMv7 and ARMv8. Only on these
> architectures we can tell the CPU where the exception table is. On ARMv6
> and older we would have to copy the exception table either to 0x0 or
> 0xffff0000. Not all SoCs have writable memory at these locations, so we
> would have to utilize the MMU to map writable memory there. We are not
> there yet, so for now skip exception handling support on these older
> architectures.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> arch/arm/Kconfig | 10 ++++++++++
> arch/arm/cpu/Makefile | 1 +
> arch/arm/cpu/interrupts_32.c | 14 +++++++++++++-
> arch/arm/cpu/interrupts_64.c | 10 +++++++++-
> arch/arm/cpu/uncompress.c | 2 ++
> arch/arm/include/asm/barebox-arm.h | 8 ++++++++
> arch/arm/lib/pbl.lds.S | 4 ++++
> 7 files changed, 47 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 0800b15d784ca0ab975cf7ceb2f7b47ed10643b1..eaccee9f2f7a128a820e1c55fba816ec5ac4c02d 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -378,6 +378,16 @@ config ARM_EXCEPTIONS
> bool "enable arm exception handling support"
> default y
>
> +config ARM_EXCEPTIONS_PBL
> + select ARCH_HAS_DATA_ABORT_MASK_PBL
> + depends on CPU_V7 || CPU_V8
> + bool "enable arm exception handling support in PBL"
> + help
> + Say yes here to enable exception handling in PBL. Note that the exception
> + table has to be initialized by calling arm_pbl_init_exceptions(). This is
> + done in barebox_pbl_start(). If you need exception handling earlier then
> + you have to call arm_pbl_init_exceptions() earlier from your board code.
> +
> config ARM_UNWIND
> bool "enable stack unwinding support"
> depends on AEABI
> diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
> index 39e59c2a2f733d668d57a2f28bdd99f69a016229..9550592796702759f950a3bc4de385100ef2b2e8 100644
> --- a/arch/arm/cpu/Makefile
> +++ b/arch/arm/cpu/Makefile
> @@ -3,6 +3,7 @@
> obj-pbl-y += cpu.o
>
> obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions_$(S64_32).o interrupts_$(S64_32).o
> +pbl-$(CONFIG_ARM_EXCEPTIONS_PBL) += exceptions_$(S64_32).o interrupts_$(S64_32).o
> obj-$(CONFIG_MMU) += mmu-common.o
> obj-pbl-$(CONFIG_MMU) += mmu_$(S64_32).o
> obj-$(CONFIG_MMU) += dma_$(S64_32).o
> diff --git a/arch/arm/cpu/interrupts_32.c b/arch/arm/cpu/interrupts_32.c
> index 623efb3966f0c34632e678d9e1edf2b6affcb4c5..cd503b38eeea551f27bbab0663bbfabdda7ffeea 100644
> --- a/arch/arm/cpu/interrupts_32.c
> +++ b/arch/arm/cpu/interrupts_32.c
> @@ -12,6 +12,7 @@
> #include <asm/ptrace.h>
> #include <asm/barebox-arm.h>
> #include <asm/unwind.h>
> +#include <asm/system_info.h>
> #include <init.h>
>
> /* Avoid missing prototype warning, called from assembly */
> @@ -61,7 +62,7 @@ void show_regs (struct pt_regs *regs)
> fast_interrupts_enabled (regs) ? "on" : "off",
> processor_modes[processor_mode (regs)],
> thumb_mode (regs) ? " (T)" : "");
> -#ifdef CONFIG_ARM_UNWIND
> +#if defined CONFIG_ARM_UNWIND && IN_PROPER
> unwind_backtrace(regs);
> #endif
> }
> @@ -181,3 +182,14 @@ int data_abort_unmask(void)
>
> return arm_data_abort_occurred != 0;
> }
> +
> +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> +void arm_pbl_init_exceptions(void)
> +{
> + if (cpu_architecture() < CPU_ARCH_ARMv7)
> + return;
> +
> + set_vbar((unsigned long)__exceptions_start);
> + arm_fixup_vectors();
> +}
> +#endif
> diff --git a/arch/arm/cpu/interrupts_64.c b/arch/arm/cpu/interrupts_64.c
> index 4d4ef2bab88ef46a7be1cd4add8f3e51423a283b..574ab6a7ec220d2239b6e27c05426e2d4c67d426 100644
> --- a/arch/arm/cpu/interrupts_64.c
> +++ b/arch/arm/cpu/interrupts_64.c
> @@ -88,7 +88,8 @@ static void __noreturn do_exception(struct pt_regs *pt_regs)
> {
> show_regs(pt_regs);
>
> - unwind_backtrace(pt_regs);
> + if (IN_PROPER)
> + unwind_backtrace(pt_regs);
>
> panic_no_stacktrace("panic: unhandled exception");
> }
> @@ -226,3 +227,10 @@ static int aarch64_init_vectors(void)
> return 0;
> }
> core_initcall(aarch64_init_vectors);
> +
> +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> +void arm_pbl_init_exceptions(void)
> +{
> + aarch64_init_vectors();
> +}
> +#endif
> diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
> index 4657a4828e67e1b0acfa9dec3aef33bc4c525468..4529ef5e3821e5b31a3673de6285d2f37e0ecba2 100644
> --- a/arch/arm/cpu/uncompress.c
> +++ b/arch/arm/cpu/uncompress.c
> @@ -63,6 +63,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
>
> pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
>
> + arm_pbl_init_exceptions();
> +
> if (IS_ENABLED(CONFIG_MMU))
> mmu_early_enable(membase, memsize);
> else if (IS_ENABLED(CONFIG_ARMV7R_MPU))
> diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
> index 7d35e88c812393d45e331f238baecfa91cbbe299..3ab442bd373e50a84b26145395e42879fc96757f 100644
> --- a/arch/arm/include/asm/barebox-arm.h
> +++ b/arch/arm/include/asm/barebox-arm.h
> @@ -52,6 +52,14 @@ static inline void arm_fixup_vectors(void)
> }
> #endif
>
> +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> +void arm_pbl_init_exceptions(void);
> +#else
> +static inline void arm_pbl_init_exceptions(void)
> +{
> +}
> +#endif
> +
> void *barebox_arm_boot_dtb(void);
>
> /*
> diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
> index dad37c9e9bca98beb4f34360fa53a0421662f03c..9c51f5eb3a3d8256752a78e03fed851c84d92edb 100644
> --- a/arch/arm/lib/pbl.lds.S
> +++ b/arch/arm/lib/pbl.lds.S
> @@ -52,6 +52,10 @@ SECTIONS
> __bare_init_start = .;
> *(.text_bare_init*)
> __bare_init_end = .;
> + . = ALIGN(0x20);
> + __exceptions_start = .;
> + KEEP(*(.text_exceptions*))
> + __exceptions_stop = .;
> *(.text*)
> }
>
>
--
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] 35+ messages in thread
* Re: [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc()
2025-06-27 14:07 ` [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc() Sascha Hauer
@ 2025-06-27 15:33 ` Ahmad Fatoum
2025-06-27 17:39 ` Sascha Hauer
2025-06-27 16:04 ` Marco Felsch
1 sibling, 1 reply; 35+ messages in thread
From: Ahmad Fatoum @ 2025-06-27 15:33 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX
On 6/27/25 16:07, Sascha Hauer wrote:
> On ARMv7 there is no direct way to detect if we are in the secure or non
> secure world. Add a imx6_can_access_tzasc() for this purpose. When
> accessing the TZASC triggers a data abort then we are in the non secure
> world. This function can be used later to detect if we have to load
> OP-TEE or not.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> arch/arm/mach-imx/tzasc.c | 16 ++++++++++++++++
> include/mach/imx/tzasc.h | 1 +
> 2 files changed, 17 insertions(+)
>
> diff --git a/arch/arm/mach-imx/tzasc.c b/arch/arm/mach-imx/tzasc.c
> index ed20ad8803a2e91b67b5d8c3ab1a4265c4228ec7..63f01cbaa6d4a8fbf47b9683ca840ee64f908cfc 100644
> --- a/arch/arm/mach-imx/tzasc.c
> +++ b/arch/arm/mach-imx/tzasc.c
> @@ -13,6 +13,8 @@
> #include <linux/sizes.h>
> #include <mach/imx/imx8m-regs.h>
> #include <io.h>
> +#include <abort.h>
> +#include <asm/barebox-arm.h>
>
> /*******************************************************************************
> * TZC380 defines
> @@ -329,6 +331,20 @@ bool imx6ul_tzc380_is_bypassed(void)
> return !(readl(&gpr[9]) & MX6_GPR_TZASC1_EN);
> }
>
How about dropping the panic and just failing the build:
#ifdef CONFIG_ARM_EXCEPTIONS_PBL
> +bool imx6_can_access_tzasc(void)
> +{
> + if (!IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL))
> + panic("%s only works with CONFIG_ARM_EXCEPTIONS_PBL\n", __func__);
> +
> + arm_pbl_init_exceptions();
> +
> + data_abort_mask();
> +
> + readl(IOMEM(MX6_TZASC1_BASE));
> +
> + return !data_abort_unmask();
> +}
#else
bool imx6_can_access_tzasc(void)
__compiletime_error("function called without CONFIG_ARM_EXCEPTIONS_PBL ");
#endif
> +
> void imx8m_tzc380_init(void)
> {
> u32 __iomem *gpr = IOMEM(MX8M_IOMUXC_GPR_BASE_ADDR);
> diff --git a/include/mach/imx/tzasc.h b/include/mach/imx/tzasc.h
> index 0fbcdc2150e63864366a8dddeed2d1b97685903d..ca85704a8f459ab6e0cdc975940d855929f3d6f7 100644
> --- a/include/mach/imx/tzasc.h
> +++ b/include/mach/imx/tzasc.h
> @@ -10,6 +10,7 @@ void imx6q_tzc380_early_ns_region1(void);
> void imx6ul_tzc380_early_ns_region1(void);
> bool imx6q_tzc380_is_bypassed(void);
> bool imx6ul_tzc380_is_bypassed(void);
> +bool imx6_can_access_tzasc(void);
> void imx8m_tzc380_init(void);
> bool imx8m_tzc380_is_enabled(void);
>
>
--
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] 35+ messages in thread
* Re: [PATCH 10/14] ARM: optee-early: add mx6_start_optee_early helper
2025-06-27 14:07 ` [PATCH 10/14] ARM: optee-early: add mx6_start_optee_early helper Sascha Hauer
@ 2025-06-27 15:38 ` Ahmad Fatoum
0 siblings, 0 replies; 35+ messages in thread
From: Ahmad Fatoum @ 2025-06-27 15:38 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX; +Cc: Marco Felsch
On 6/27/25 16:07, Sascha Hauer wrote:
> From: Marco Felsch <m.felsch@pengutronix.de>
> To start OP-TEE during the lowlevel initialization of your board in the ``PBL``,
> -enable the ``CONFIG_PBL_OPTEE`` configuration variable. your board should then
> +enable the ``CONFIG_PBL_OPTEE`` configuration variable. Your board should then
> call the function ``start_optee_early(void* tee, void* fdt)`` with a valid tee
> -and FDT. Ensure that your OP-TEE is compiled with ``CFG_NS_ENTRY_ADDR`` unset,
> -otherwise OP-TEE will not correctly return to barebox after startup.
> -Since OP-TEE in the default configuration also modifies the device tree, don't
> -pass the barebox internal device tree, instead copy it into a different memory
> -location and pass it to OP-TEE afterwards.
> -The modified device tree can then be passed to the main barebox start function.
> +and FDT. If you're running on an i.MX6 platform your board code should call
> +``imx6q_start_optee_early()`` or ``imx6ul_start_optee_early()`` instead since it
> +validates that the TZASC not bypassed and configured as expected by OP-TEE.
validates that the TZASC is not bypassed and is configured as expected
by OP-TEE.
> +Ensure that your OP-TEE is compiled with ``CFG_NS_ENTRY_ADDR`` unset, otherwise
> +OP-TEE will not correctly return to barebox after startup. Since OP-TEE in the
> +default configuration also modifies the device tree, don't pass the barebox
> +internal device tree, instead copy it into a different memory location and pass
> +it to OP-TEE afterwards. The modified device tree can then be passed to the
> +main barebox start function.
.. note:: Modification of the device tree usually makes it bigger.
Some spare space must be left after the end of the device tree to
accommodate this.
Cheers,
Ahmad
--
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] 35+ messages in thread
* Re: [PATCH 11/14] ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled
2025-06-27 14:07 ` [PATCH 11/14] ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled Sascha Hauer
@ 2025-06-27 15:39 ` Ahmad Fatoum
2025-06-27 16:08 ` Marco Felsch
2025-06-27 16:10 ` Marco Felsch
2 siblings, 0 replies; 35+ messages in thread
From: Ahmad Fatoum @ 2025-06-27 15:39 UTC (permalink / raw)
To: Sascha Hauer, BAREBOX
On 6/27/25 16:07, Sascha Hauer wrote:
> When barebox starts we have to guess if we have to start OP-TEE or not.
> The current detection works by checking if the first stage passed us a
> device tree pointer. This is not robust and might have security issues
> [1], so replace that with the check with imx6_can_access_tzasc(). If we
> can access the TZASC then we are the first stage and configure it and
> start OP-TEE, otherwise assume that we are chainloaded and continue
> without starting OP-TEE.
>
> Chainloading barebox with OP-TEE enabled contained several bugs, so it
> never actually worked. This patch fixes them.
>
> [1] https://lore.kernel.org/70b41f3b-4329-48f7-827f-1924e002ab04@pengutronix.de
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
With below bug fixed:
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> config MACH_TQMA6UL
> bool "TQ tqma6ul on mba6ulx"
> + select CONFIG_ARM_EXCEPTIONS_PBL if FIRMWARE_TQMA6UL_OPTEE
Drop the CONFIG_
Cheers,
Ahmad
--
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] 35+ messages in thread
* Re: [PATCH 03/14] ARM: add exception handling support for PBL
2025-06-27 14:07 ` [PATCH 03/14] ARM: add exception handling support for PBL Sascha Hauer
2025-06-27 15:30 ` Ahmad Fatoum
@ 2025-06-27 15:45 ` Marco Felsch
2025-06-27 17:22 ` Sascha Hauer
1 sibling, 1 reply; 35+ messages in thread
From: Marco Felsch @ 2025-06-27 15:45 UTC (permalink / raw)
To: Sascha Hauer; +Cc: BAREBOX
Hi Sascha,
On 25-06-27, Sascha Hauer wrote:
> Exception handling in PBL can be very useful for debugging PBL code.
> This patch adds support for it.
>
> This is currently only implemented for ARMv7 and ARMv8. Only on these
> architectures we can tell the CPU where the exception table is. On ARMv6
> and older we would have to copy the exception table either to 0x0 or
> 0xffff0000. Not all SoCs have writable memory at these locations, so we
> would have to utilize the MMU to map writable memory there. We are not
> there yet, so for now skip exception handling support on these older
> architectures.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> arch/arm/Kconfig | 10 ++++++++++
> arch/arm/cpu/Makefile | 1 +
> arch/arm/cpu/interrupts_32.c | 14 +++++++++++++-
> arch/arm/cpu/interrupts_64.c | 10 +++++++++-
> arch/arm/cpu/uncompress.c | 2 ++
> arch/arm/include/asm/barebox-arm.h | 8 ++++++++
> arch/arm/lib/pbl.lds.S | 4 ++++
> 7 files changed, 47 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 0800b15d784ca0ab975cf7ceb2f7b47ed10643b1..eaccee9f2f7a128a820e1c55fba816ec5ac4c02d 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -378,6 +378,16 @@ config ARM_EXCEPTIONS
> bool "enable arm exception handling support"
> default y
>
> +config ARM_EXCEPTIONS_PBL
> + select ARCH_HAS_DATA_ABORT_MASK_PBL
> + depends on CPU_V7 || CPU_V8
> + bool "enable arm exception handling support in PBL"
> + help
> + Say yes here to enable exception handling in PBL. Note that the exception
> + table has to be initialized by calling arm_pbl_init_exceptions(). This is
> + done in barebox_pbl_start(). If you need exception handling earlier then
> + you have to call arm_pbl_init_exceptions() earlier from your board code.
> +
> config ARM_UNWIND
> bool "enable stack unwinding support"
> depends on AEABI
> diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
> index 39e59c2a2f733d668d57a2f28bdd99f69a016229..9550592796702759f950a3bc4de385100ef2b2e8 100644
> --- a/arch/arm/cpu/Makefile
> +++ b/arch/arm/cpu/Makefile
> @@ -3,6 +3,7 @@
> obj-pbl-y += cpu.o
>
> obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions_$(S64_32).o interrupts_$(S64_32).o
> +pbl-$(CONFIG_ARM_EXCEPTIONS_PBL) += exceptions_$(S64_32).o interrupts_$(S64_32).o
> obj-$(CONFIG_MMU) += mmu-common.o
> obj-pbl-$(CONFIG_MMU) += mmu_$(S64_32).o
> obj-$(CONFIG_MMU) += dma_$(S64_32).o
> diff --git a/arch/arm/cpu/interrupts_32.c b/arch/arm/cpu/interrupts_32.c
> index 623efb3966f0c34632e678d9e1edf2b6affcb4c5..cd503b38eeea551f27bbab0663bbfabdda7ffeea 100644
> --- a/arch/arm/cpu/interrupts_32.c
> +++ b/arch/arm/cpu/interrupts_32.c
> @@ -12,6 +12,7 @@
> #include <asm/ptrace.h>
> #include <asm/barebox-arm.h>
> #include <asm/unwind.h>
> +#include <asm/system_info.h>
> #include <init.h>
>
> /* Avoid missing prototype warning, called from assembly */
> @@ -61,7 +62,7 @@ void show_regs (struct pt_regs *regs)
> fast_interrupts_enabled (regs) ? "on" : "off",
> processor_modes[processor_mode (regs)],
> thumb_mode (regs) ? " (T)" : "");
> -#ifdef CONFIG_ARM_UNWIND
> +#if defined CONFIG_ARM_UNWIND && IN_PROPER
> unwind_backtrace(regs);
> #endif
> }
> @@ -181,3 +182,14 @@ int data_abort_unmask(void)
>
> return arm_data_abort_occurred != 0;
> }
> +
> +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> +void arm_pbl_init_exceptions(void)
> +{
> + if (cpu_architecture() < CPU_ARCH_ARMv7)
> + return;
> +
> + set_vbar((unsigned long)__exceptions_start);
> + arm_fixup_vectors();
> +}
> +#endif
> diff --git a/arch/arm/cpu/interrupts_64.c b/arch/arm/cpu/interrupts_64.c
> index 4d4ef2bab88ef46a7be1cd4add8f3e51423a283b..574ab6a7ec220d2239b6e27c05426e2d4c67d426 100644
> --- a/arch/arm/cpu/interrupts_64.c
> +++ b/arch/arm/cpu/interrupts_64.c
> @@ -88,7 +88,8 @@ static void __noreturn do_exception(struct pt_regs *pt_regs)
> {
> show_regs(pt_regs);
>
> - unwind_backtrace(pt_regs);
> + if (IN_PROPER)
> + unwind_backtrace(pt_regs);
>
> panic_no_stacktrace("panic: unhandled exception");
> }
> @@ -226,3 +227,10 @@ static int aarch64_init_vectors(void)
> return 0;
> }
> core_initcall(aarch64_init_vectors);
> +
> +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> +void arm_pbl_init_exceptions(void)
> +{
> + aarch64_init_vectors();
> +}
> +#endif
> diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
> index 4657a4828e67e1b0acfa9dec3aef33bc4c525468..4529ef5e3821e5b31a3673de6285d2f37e0ecba2 100644
> --- a/arch/arm/cpu/uncompress.c
> +++ b/arch/arm/cpu/uncompress.c
> @@ -63,6 +63,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
>
> pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
>
> + arm_pbl_init_exceptions();
> +
> if (IS_ENABLED(CONFIG_MMU))
> mmu_early_enable(membase, memsize);
> else if (IS_ENABLED(CONFIG_ARMV7R_MPU))
> diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
> index 7d35e88c812393d45e331f238baecfa91cbbe299..3ab442bd373e50a84b26145395e42879fc96757f 100644
> --- a/arch/arm/include/asm/barebox-arm.h
> +++ b/arch/arm/include/asm/barebox-arm.h
> @@ -52,6 +52,14 @@ static inline void arm_fixup_vectors(void)
> }
> #endif
>
> +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> +void arm_pbl_init_exceptions(void);
> +#else
> +static inline void arm_pbl_init_exceptions(void)
> +{
> +}
> +#endif
> +
> void *barebox_arm_boot_dtb(void);
>
> /*
> diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
> index dad37c9e9bca98beb4f34360fa53a0421662f03c..9c51f5eb3a3d8256752a78e03fed851c84d92edb 100644
> --- a/arch/arm/lib/pbl.lds.S
> +++ b/arch/arm/lib/pbl.lds.S
> @@ -52,6 +52,10 @@ SECTIONS
> __bare_init_start = .;
> *(.text_bare_init*)
> __bare_init_end = .;
> + . = ALIGN(0x20);
> + __exceptions_start = .;
> + KEEP(*(.text_exceptions*))
> + __exceptions_stop = .;
Nit: We only need this in case of CONFIG_CPU_64, right? Maybe I
overlooked it but the only user of this section is
arch/arm/cpu/exceptions_32.S. Not sure why arch/arm/lib64/barebox.lds.S
has this section too.
Regards,
Marco
> *(.text*)
> }
>
>
> --
> 2.39.5
>
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 08/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_is_bypassed()
2025-06-27 14:07 ` [PATCH 08/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_is_bypassed() Sascha Hauer
@ 2025-06-27 15:57 ` Marco Felsch
2025-06-27 17:26 ` Sascha Hauer
0 siblings, 1 reply; 35+ messages in thread
From: Marco Felsch @ 2025-06-27 15:57 UTC (permalink / raw)
To: Sascha Hauer; +Cc: BAREBOX, Ahmad Fatoum
On 25-06-27, Sascha Hauer wrote:
> From: Marco Felsch <m.felsch@pengutronix.de>
>
> The TZASC_BYP bits in the IOMUX GPR offer a great way to shoot yourself
> in the foot. These bits are cleared by default and with these bits
> cleared the TZASC will never check DDR transactions. The TZASC can be
> configured normally with the bits cleared, it just doesn't work and all
> secure regions can be accessed by the normal worls. These
> bits can only be set in the DCD table, trying to set them in code will
> make the system hang. As the DCD tables are board specific it's easy to
I think this is not entirely true. At least the i.MX6 TRM says, that any
DDR access must be done before the TZASC is turned on.
Since most i.MX6/7 boards do use the DCD RAM setup and tell the BootROM
to load the barebox(-pbl) directly into RAM, we can enable it only from
DCD. But it should still be possible to enable it within the code, like
we do for i.MX8M. This only requires that the barebox-pbl is loaded into
internal OCRAM which is the rare case for i.MX6/7 boards.
Keep in mind, I did not test the later case.
> forget setting them. This patch adds a function that checks if the bits
> are set as desired which will be called by the optee-early helper later.
>
> Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> arch/arm/mach-imx/tzasc.c | 26 ++++++++++++++++++++++++++
> include/mach/imx/tzasc.h | 2 ++
> 2 files changed, 28 insertions(+)
>
> diff --git a/arch/arm/mach-imx/tzasc.c b/arch/arm/mach-imx/tzasc.c
> index 169c4b9801e5fdd01edd3c5661418a945cf21c55..ed20ad8803a2e91b67b5d8c3ab1a4265c4228ec7 100644
> --- a/arch/arm/mach-imx/tzasc.c
> +++ b/arch/arm/mach-imx/tzasc.c
> @@ -76,6 +76,9 @@
> #define MX6_TZASC1_BASE 0x21d0000
> #define MX6_TZASC2_BASE 0x21d4000
>
> +#define MX6_GPR_TZASC1_EN BIT(0)
> +#define MX6_GPR_TZASC2_EN BIT(1)
> +
> #define GPR_TZASC_EN BIT(0)
> #define GPR_TZASC_ID_SWAP_BYPASS BIT(1)
> #define GPR_TZASC_EN_LOCK BIT(16)
> @@ -303,6 +306,29 @@ void imx6ul_tzc380_early_ns_region1(void)
> TZC380_REGION_SP_NS_RW);
> }
>
> +bool imx6q_tzc380_is_bypassed(void)
> +{
> + u32 __iomem *gpr = IOMEM(MX6_IOMUXC_BASE_ADDR);
> +
> + /*
> + * MX6_GPR_TZASC1_EN and MX6_GPR_TZASC2_EN are sticky bits which
> + * preserve their values once set until the next power-up cycle.
> + */
> + return (readl(&gpr[9]) & (MX6_GPR_TZASC1_EN | MX6_GPR_TZASC2_EN)) !=
> + (MX6_GPR_TZASC1_EN | MX6_GPR_TZASC2_EN);
> +}
> +
> +bool imx6ul_tzc380_is_bypassed(void)
> +{
> + u32 __iomem *gpr = IOMEM(MX6_IOMUXC_BASE_ADDR + 0x4000);
> +
> + /*
> + * MX6_GPR_TZASC1_EN is a sticky bit which preserves its value
> + * once set until the next power-up cycle.
> + */
> + return !(readl(&gpr[9]) & MX6_GPR_TZASC1_EN);
> +}
> +
> void imx8m_tzc380_init(void)
> {
> u32 __iomem *gpr = IOMEM(MX8M_IOMUXC_GPR_BASE_ADDR);
> diff --git a/include/mach/imx/tzasc.h b/include/mach/imx/tzasc.h
> index eb479ad55c9c101a5fb47fc4a7178b3669b9e44f..0fbcdc2150e63864366a8dddeed2d1b97685903d 100644
> --- a/include/mach/imx/tzasc.h
> +++ b/include/mach/imx/tzasc.h
> @@ -8,6 +8,8 @@
>
> void imx6q_tzc380_early_ns_region1(void);
> void imx6ul_tzc380_early_ns_region1(void);
> +bool imx6q_tzc380_is_bypassed(void);
> +bool imx6ul_tzc380_is_bypassed(void);
> void imx8m_tzc380_init(void);
> bool imx8m_tzc380_is_enabled(void);
>
>
> --
> 2.39.5
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc()
2025-06-27 14:07 ` [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc() Sascha Hauer
2025-06-27 15:33 ` Ahmad Fatoum
@ 2025-06-27 16:04 ` Marco Felsch
2025-06-27 17:48 ` Sascha Hauer
1 sibling, 1 reply; 35+ messages in thread
From: Marco Felsch @ 2025-06-27 16:04 UTC (permalink / raw)
To: Sascha Hauer; +Cc: BAREBOX
On 25-06-27, Sascha Hauer wrote:
> On ARMv7 there is no direct way to detect if we are in the secure or non
> secure world. Add a imx6_can_access_tzasc() for this purpose. When
> accessing the TZASC triggers a data abort then we are in the non secure
> world. This function can be used later to detect if we have to load
^
because OP-TEE configures the TZASC access policy to secure-world R/W. ?
Keep in mind that this test will fail if a downstream/buggy OP-TEE
doesn't configure the CSU correctly. Fingers crossed that this never
will never happen.
> OP-TEE or not.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> arch/arm/mach-imx/tzasc.c | 16 ++++++++++++++++
> include/mach/imx/tzasc.h | 1 +
> 2 files changed, 17 insertions(+)
>
> diff --git a/arch/arm/mach-imx/tzasc.c b/arch/arm/mach-imx/tzasc.c
> index ed20ad8803a2e91b67b5d8c3ab1a4265c4228ec7..63f01cbaa6d4a8fbf47b9683ca840ee64f908cfc 100644
> --- a/arch/arm/mach-imx/tzasc.c
> +++ b/arch/arm/mach-imx/tzasc.c
> @@ -13,6 +13,8 @@
> #include <linux/sizes.h>
> #include <mach/imx/imx8m-regs.h>
> #include <io.h>
> +#include <abort.h>
> +#include <asm/barebox-arm.h>
>
> /*******************************************************************************
> * TZC380 defines
> @@ -329,6 +331,20 @@ bool imx6ul_tzc380_is_bypassed(void)
> return !(readl(&gpr[9]) & MX6_GPR_TZASC1_EN);
> }
>
> +bool imx6_can_access_tzasc(void)
> +{
> + if (!IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL))
> + panic("%s only works with CONFIG_ARM_EXCEPTIONS_PBL\n", __func__);
> +
> + arm_pbl_init_exceptions();
Can't we do that within the imx*_cpu_lowlevel_init?
Regards,
Marco
> +
> + data_abort_mask();
> +
> + readl(IOMEM(MX6_TZASC1_BASE));
> +
> + return !data_abort_unmask();
> +}
> +
> void imx8m_tzc380_init(void)
> {
> u32 __iomem *gpr = IOMEM(MX8M_IOMUXC_GPR_BASE_ADDR);
> diff --git a/include/mach/imx/tzasc.h b/include/mach/imx/tzasc.h
> index 0fbcdc2150e63864366a8dddeed2d1b97685903d..ca85704a8f459ab6e0cdc975940d855929f3d6f7 100644
> --- a/include/mach/imx/tzasc.h
> +++ b/include/mach/imx/tzasc.h
> @@ -10,6 +10,7 @@ void imx6q_tzc380_early_ns_region1(void);
> void imx6ul_tzc380_early_ns_region1(void);
> bool imx6q_tzc380_is_bypassed(void);
> bool imx6ul_tzc380_is_bypassed(void);
> +bool imx6_can_access_tzasc(void);
> void imx8m_tzc380_init(void);
> bool imx8m_tzc380_is_enabled(void);
>
>
> --
> 2.39.5
>
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 11/14] ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled
2025-06-27 14:07 ` [PATCH 11/14] ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled Sascha Hauer
2025-06-27 15:39 ` Ahmad Fatoum
@ 2025-06-27 16:08 ` Marco Felsch
2025-06-27 16:10 ` Marco Felsch
2 siblings, 0 replies; 35+ messages in thread
From: Marco Felsch @ 2025-06-27 16:08 UTC (permalink / raw)
To: Sascha Hauer; +Cc: BAREBOX
On 25-06-27, Sascha Hauer wrote:
> When barebox starts we have to guess if we have to start OP-TEE or not.
> The current detection works by checking if the first stage passed us a
> device tree pointer. This is not robust and might have security issues
> [1], so replace that with the check with imx6_can_access_tzasc(). If we
> can access the TZASC then we are the first stage and configure it and
> start OP-TEE, otherwise assume that we are chainloaded and continue
> without starting OP-TEE.
>
> Chainloading barebox with OP-TEE enabled contained several bugs, so it
> never actually worked. This patch fixes them.
>
> [1] https://lore.kernel.org/70b41f3b-4329-48f7-827f-1924e002ab04@pengutronix.de
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
> ---
> arch/arm/boards/tqma6ulx/lowlevel.c | 22 +++++++++-------------
> arch/arm/mach-imx/Kconfig | 1 +
> 2 files changed, 10 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm/boards/tqma6ulx/lowlevel.c b/arch/arm/boards/tqma6ulx/lowlevel.c
> index 5fd997d2ec7e79c7319237a4ae52216e584ba5cd..da67e67537167096477de2b905ee5c42c653c3af 100644
> --- a/arch/arm/boards/tqma6ulx/lowlevel.c
> +++ b/arch/arm/boards/tqma6ulx/lowlevel.c
> @@ -16,6 +16,8 @@
> #include <pbl/i2c.h>
> #include <boards/tq/tq_eeprom.h>
> #include <tee/optee.h>
> +#include <mach/imx/tzasc.h>
> +#include <tee/optee.h>
>
> #include "tqma6ulx.h"
>
> @@ -66,7 +68,7 @@ static void *read_eeprom(void)
> return fdt;
> }
>
> -static void noinline start_mba6ulx(u32 r0)
> +static void noinline start_mba6ulx(void)
> {
> void *fdt;
> int tee_size;
> @@ -76,21 +78,15 @@ static void noinline start_mba6ulx(u32 r0)
>
> fdt = read_eeprom();
>
> - /* Enable normal/secure r/w for TZC380 region0 */
> - writel(0xf0000000, 0x021D0108);
> -
> /*
> - * Chainloading barebox will pass a device tree within the RAM in r0,
> - * skip OP-TEE early loading in this case
> + * Skip loading barebox when we are chainloaded. We can detect that by detecting
> + * if we can access the TZASC.
> */
> - if (IS_ENABLED(CONFIG_FIRMWARE_TQMA6UL_OPTEE) &&
> - !(r0 > MX6_MMDC_P0_BASE_ADDR &&
> - r0 < MX6_MMDC_P0_BASE_ADDR + SZ_256M)) {
> - get_builtin_firmware(mba6ul_optee_bin, &tee, &tee_size);
> + if (IS_ENABLED(CONFIG_FIRMWARE_TQMA6UL_OPTEE) && imx6_can_access_tzasc()) {
>
> - memset((void *)OPTEE_OVERLAY_LOCATION, 0, 0x1000);
> + get_builtin_firmware(mba6ul_optee_bin, &tee, &tee_size);
>
> - start_optee_early(NULL, tee);
> + imx6ul_start_optee_early(NULL, tee, (void *)OPTEE_OVERLAY_LOCATION, 0x1000);
> }
>
> imx6ul_barebox_entry(fdt);
> @@ -112,5 +108,5 @@ ENTRY_FUNCTION(start_imx6ul_mba6ulx, r0, r1, r2)
> setup_c();
> barrier();
>
> - start_mba6ulx(r0);
> + start_mba6ulx();
> }
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 552e7227a0221fee8232dfba5dcdd60de923ff0c..1bf28b473af2b517a784c11d33f745ad74750583 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -490,6 +490,7 @@ config MACH_TQMA6X
>
> config MACH_TQMA6UL
> bool "TQ tqma6ul on mba6ulx"
> + select CONFIG_ARM_EXCEPTIONS_PBL if FIRMWARE_TQMA6UL_OPTEE
> select ARCH_IMX6UL
> select BOARD_TQ
> select I2C_IMX_EARLY
>
> --
> 2.39.5
>
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 11/14] ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled
2025-06-27 14:07 ` [PATCH 11/14] ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled Sascha Hauer
2025-06-27 15:39 ` Ahmad Fatoum
2025-06-27 16:08 ` Marco Felsch
@ 2025-06-27 16:10 ` Marco Felsch
2 siblings, 0 replies; 35+ messages in thread
From: Marco Felsch @ 2025-06-27 16:10 UTC (permalink / raw)
To: Sascha Hauer; +Cc: BAREBOX
On 25-06-27, Sascha Hauer wrote:
> When barebox starts we have to guess if we have to start OP-TEE or not.
> The current detection works by checking if the first stage passed us a
> device tree pointer. This is not robust and might have security issues
> [1], so replace that with the check with imx6_can_access_tzasc(). If we
> can access the TZASC then we are the first stage and configure it and
> start OP-TEE, otherwise assume that we are chainloaded and continue
> without starting OP-TEE.
>
> Chainloading barebox with OP-TEE enabled contained several bugs, so it
> never actually worked. This patch fixes them.
>
> [1] https://lore.kernel.org/70b41f3b-4329-48f7-827f-1924e002ab04@pengutronix.de
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
> arch/arm/boards/tqma6ulx/lowlevel.c | 22 +++++++++-------------
> arch/arm/mach-imx/Kconfig | 1 +
> 2 files changed, 10 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm/boards/tqma6ulx/lowlevel.c b/arch/arm/boards/tqma6ulx/lowlevel.c
> index 5fd997d2ec7e79c7319237a4ae52216e584ba5cd..da67e67537167096477de2b905ee5c42c653c3af 100644
> --- a/arch/arm/boards/tqma6ulx/lowlevel.c
> +++ b/arch/arm/boards/tqma6ulx/lowlevel.c
> @@ -16,6 +16,8 @@
> #include <pbl/i2c.h>
> #include <boards/tq/tq_eeprom.h>
> #include <tee/optee.h>
> +#include <mach/imx/tzasc.h>
> +#include <tee/optee.h>
>
> #include "tqma6ulx.h"
>
> @@ -66,7 +68,7 @@ static void *read_eeprom(void)
> return fdt;
> }
>
> -static void noinline start_mba6ulx(u32 r0)
> +static void noinline start_mba6ulx(void)
> {
> void *fdt;
> int tee_size;
> @@ -76,21 +78,15 @@ static void noinline start_mba6ulx(u32 r0)
>
> fdt = read_eeprom();
>
> - /* Enable normal/secure r/w for TZC380 region0 */
> - writel(0xf0000000, 0x021D0108);
> -
> /*
> - * Chainloading barebox will pass a device tree within the RAM in r0,
> - * skip OP-TEE early loading in this case
> + * Skip loading barebox when we are chainloaded. We can detect that by detecting
> + * if we can access the TZASC.
> */
> - if (IS_ENABLED(CONFIG_FIRMWARE_TQMA6UL_OPTEE) &&
> - !(r0 > MX6_MMDC_P0_BASE_ADDR &&
> - r0 < MX6_MMDC_P0_BASE_ADDR + SZ_256M)) {
> - get_builtin_firmware(mba6ul_optee_bin, &tee, &tee_size);
> + if (IS_ENABLED(CONFIG_FIRMWARE_TQMA6UL_OPTEE) && imx6_can_access_tzasc()) {
>
> - memset((void *)OPTEE_OVERLAY_LOCATION, 0, 0x1000);
> + get_builtin_firmware(mba6ul_optee_bin, &tee, &tee_size);
>
> - start_optee_early(NULL, tee);
> + imx6ul_start_optee_early(NULL, tee, (void *)OPTEE_OVERLAY_LOCATION, 0x1000);
> }
>
> imx6ul_barebox_entry(fdt);
> @@ -112,5 +108,5 @@ ENTRY_FUNCTION(start_imx6ul_mba6ulx, r0, r1, r2)
> setup_c();
> barrier();
>
> - start_mba6ulx(r0);
> + start_mba6ulx();
> }
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index 552e7227a0221fee8232dfba5dcdd60de923ff0c..1bf28b473af2b517a784c11d33f745ad74750583 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -490,6 +490,7 @@ config MACH_TQMA6X
>
> config MACH_TQMA6UL
> bool "TQ tqma6ul on mba6ulx"
> + select CONFIG_ARM_EXCEPTIONS_PBL if FIRMWARE_TQMA6UL_OPTEE
^
Please drop the CONFIG_ as Ahmad already mentioned this for patch12.
> select ARCH_IMX6UL
> select BOARD_TQ
> select I2C_IMX_EARLY
>
> --
> 2.39.5
>
>
>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 03/14] ARM: add exception handling support for PBL
2025-06-27 15:45 ` Marco Felsch
@ 2025-06-27 17:22 ` Sascha Hauer
2025-06-27 17:46 ` Marco Felsch
0 siblings, 1 reply; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 17:22 UTC (permalink / raw)
To: Marco Felsch; +Cc: BAREBOX
On Fri, Jun 27, 2025 at 05:45:09PM +0200, Marco Felsch wrote:
> Hi Sascha,
>
> On 25-06-27, Sascha Hauer wrote:
> > Exception handling in PBL can be very useful for debugging PBL code.
> > This patch adds support for it.
> >
> > This is currently only implemented for ARMv7 and ARMv8. Only on these
> > architectures we can tell the CPU where the exception table is. On ARMv6
> > and older we would have to copy the exception table either to 0x0 or
> > 0xffff0000. Not all SoCs have writable memory at these locations, so we
> > would have to utilize the MMU to map writable memory there. We are not
> > there yet, so for now skip exception handling support on these older
> > architectures.
> >
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > arch/arm/Kconfig | 10 ++++++++++
> > arch/arm/cpu/Makefile | 1 +
> > arch/arm/cpu/interrupts_32.c | 14 +++++++++++++-
> > arch/arm/cpu/interrupts_64.c | 10 +++++++++-
> > arch/arm/cpu/uncompress.c | 2 ++
> > arch/arm/include/asm/barebox-arm.h | 8 ++++++++
> > arch/arm/lib/pbl.lds.S | 4 ++++
> > 7 files changed, 47 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > index 0800b15d784ca0ab975cf7ceb2f7b47ed10643b1..eaccee9f2f7a128a820e1c55fba816ec5ac4c02d 100644
> > --- a/arch/arm/Kconfig
> > +++ b/arch/arm/Kconfig
> > @@ -378,6 +378,16 @@ config ARM_EXCEPTIONS
> > bool "enable arm exception handling support"
> > default y
> >
> > +config ARM_EXCEPTIONS_PBL
> > + select ARCH_HAS_DATA_ABORT_MASK_PBL
> > + depends on CPU_V7 || CPU_V8
> > + bool "enable arm exception handling support in PBL"
> > + help
> > + Say yes here to enable exception handling in PBL. Note that the exception
> > + table has to be initialized by calling arm_pbl_init_exceptions(). This is
> > + done in barebox_pbl_start(). If you need exception handling earlier then
> > + you have to call arm_pbl_init_exceptions() earlier from your board code.
> > +
> > config ARM_UNWIND
> > bool "enable stack unwinding support"
> > depends on AEABI
> > diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
> > index 39e59c2a2f733d668d57a2f28bdd99f69a016229..9550592796702759f950a3bc4de385100ef2b2e8 100644
> > --- a/arch/arm/cpu/Makefile
> > +++ b/arch/arm/cpu/Makefile
> > @@ -3,6 +3,7 @@
> > obj-pbl-y += cpu.o
> >
> > obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions_$(S64_32).o interrupts_$(S64_32).o
> > +pbl-$(CONFIG_ARM_EXCEPTIONS_PBL) += exceptions_$(S64_32).o interrupts_$(S64_32).o
> > obj-$(CONFIG_MMU) += mmu-common.o
> > obj-pbl-$(CONFIG_MMU) += mmu_$(S64_32).o
> > obj-$(CONFIG_MMU) += dma_$(S64_32).o
> > diff --git a/arch/arm/cpu/interrupts_32.c b/arch/arm/cpu/interrupts_32.c
> > index 623efb3966f0c34632e678d9e1edf2b6affcb4c5..cd503b38eeea551f27bbab0663bbfabdda7ffeea 100644
> > --- a/arch/arm/cpu/interrupts_32.c
> > +++ b/arch/arm/cpu/interrupts_32.c
> > @@ -12,6 +12,7 @@
> > #include <asm/ptrace.h>
> > #include <asm/barebox-arm.h>
> > #include <asm/unwind.h>
> > +#include <asm/system_info.h>
> > #include <init.h>
> >
> > /* Avoid missing prototype warning, called from assembly */
> > @@ -61,7 +62,7 @@ void show_regs (struct pt_regs *regs)
> > fast_interrupts_enabled (regs) ? "on" : "off",
> > processor_modes[processor_mode (regs)],
> > thumb_mode (regs) ? " (T)" : "");
> > -#ifdef CONFIG_ARM_UNWIND
> > +#if defined CONFIG_ARM_UNWIND && IN_PROPER
> > unwind_backtrace(regs);
> > #endif
> > }
> > @@ -181,3 +182,14 @@ int data_abort_unmask(void)
> >
> > return arm_data_abort_occurred != 0;
> > }
> > +
> > +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> > +void arm_pbl_init_exceptions(void)
> > +{
> > + if (cpu_architecture() < CPU_ARCH_ARMv7)
> > + return;
> > +
> > + set_vbar((unsigned long)__exceptions_start);
> > + arm_fixup_vectors();
> > +}
> > +#endif
> > diff --git a/arch/arm/cpu/interrupts_64.c b/arch/arm/cpu/interrupts_64.c
> > index 4d4ef2bab88ef46a7be1cd4add8f3e51423a283b..574ab6a7ec220d2239b6e27c05426e2d4c67d426 100644
> > --- a/arch/arm/cpu/interrupts_64.c
> > +++ b/arch/arm/cpu/interrupts_64.c
> > @@ -88,7 +88,8 @@ static void __noreturn do_exception(struct pt_regs *pt_regs)
> > {
> > show_regs(pt_regs);
> >
> > - unwind_backtrace(pt_regs);
> > + if (IN_PROPER)
> > + unwind_backtrace(pt_regs);
> >
> > panic_no_stacktrace("panic: unhandled exception");
> > }
> > @@ -226,3 +227,10 @@ static int aarch64_init_vectors(void)
> > return 0;
> > }
> > core_initcall(aarch64_init_vectors);
> > +
> > +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> > +void arm_pbl_init_exceptions(void)
> > +{
> > + aarch64_init_vectors();
> > +}
> > +#endif
> > diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
> > index 4657a4828e67e1b0acfa9dec3aef33bc4c525468..4529ef5e3821e5b31a3673de6285d2f37e0ecba2 100644
> > --- a/arch/arm/cpu/uncompress.c
> > +++ b/arch/arm/cpu/uncompress.c
> > @@ -63,6 +63,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
> >
> > pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
> >
> > + arm_pbl_init_exceptions();
> > +
> > if (IS_ENABLED(CONFIG_MMU))
> > mmu_early_enable(membase, memsize);
> > else if (IS_ENABLED(CONFIG_ARMV7R_MPU))
> > diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
> > index 7d35e88c812393d45e331f238baecfa91cbbe299..3ab442bd373e50a84b26145395e42879fc96757f 100644
> > --- a/arch/arm/include/asm/barebox-arm.h
> > +++ b/arch/arm/include/asm/barebox-arm.h
> > @@ -52,6 +52,14 @@ static inline void arm_fixup_vectors(void)
> > }
> > #endif
> >
> > +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> > +void arm_pbl_init_exceptions(void);
> > +#else
> > +static inline void arm_pbl_init_exceptions(void)
> > +{
> > +}
> > +#endif
> > +
> > void *barebox_arm_boot_dtb(void);
> >
> > /*
> > diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
> > index dad37c9e9bca98beb4f34360fa53a0421662f03c..9c51f5eb3a3d8256752a78e03fed851c84d92edb 100644
> > --- a/arch/arm/lib/pbl.lds.S
> > +++ b/arch/arm/lib/pbl.lds.S
> > @@ -52,6 +52,10 @@ SECTIONS
> > __bare_init_start = .;
> > *(.text_bare_init*)
> > __bare_init_end = .;
> > + . = ALIGN(0x20);
> > + __exceptions_start = .;
> > + KEEP(*(.text_exceptions*))
> > + __exceptions_stop = .;
>
> Nit: We only need this in case of CONFIG_CPU_64, right?
s/CONFIG_CPU_64/CONFIG_CPU_32/
Yes, right.
> Maybe I
> overlooked it but the only user of this section is
> arch/arm/cpu/exceptions_32.S. Not sure why arch/arm/lib64/barebox.lds.S
> has this section too.
Likely because the initial arm64 linker script started as a copy from
the arm32 linker script.
I'll prepare a patch to remove the section from arch/arm/lib64/barebox.lds.S
because it's indeed unused.
In arch/arm/lib/pbl.lds.S we could add an #ifdef CONFIG_CPU_64 around the
section, but it doesn't make a difference, the section will be empty
anyway.
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] 35+ messages in thread
* Re: [PATCH 08/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_is_bypassed()
2025-06-27 15:57 ` Marco Felsch
@ 2025-06-27 17:26 ` Sascha Hauer
2025-06-27 17:42 ` Marco Felsch
0 siblings, 1 reply; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 17:26 UTC (permalink / raw)
To: Marco Felsch; +Cc: BAREBOX, Ahmad Fatoum
On Fri, Jun 27, 2025 at 05:57:23PM +0200, Marco Felsch wrote:
> On 25-06-27, Sascha Hauer wrote:
> > From: Marco Felsch <m.felsch@pengutronix.de>
> >
> > The TZASC_BYP bits in the IOMUX GPR offer a great way to shoot yourself
> > in the foot. These bits are cleared by default and with these bits
> > cleared the TZASC will never check DDR transactions. The TZASC can be
> > configured normally with the bits cleared, it just doesn't work and all
> > secure regions can be accessed by the normal worls. These
> > bits can only be set in the DCD table, trying to set them in code will
> > make the system hang. As the DCD tables are board specific it's easy to
>
> I think this is not entirely true. At least the i.MX6 TRM says, that any
> DDR access must be done before the TZASC is turned on.
>
> Since most i.MX6/7 boards do use the DCD RAM setup and tell the BootROM
> to load the barebox(-pbl) directly into RAM, we can enable it only from
> DCD. But it should still be possible to enable it within the code, like
> we do for i.MX8M. This only requires that the barebox-pbl is loaded into
> internal OCRAM which is the rare case for i.MX6/7 boards.
So you mean that the bypass bit has to be set before the DDR controller
is initialized which requires us to put it into the DCD table when we
initialize the DDR controller in DCD?
Well, that makes more sense to me. I'll adjust the commit message
accordingly.
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] 35+ messages in thread
* Re: [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc()
2025-06-27 15:33 ` Ahmad Fatoum
@ 2025-06-27 17:39 ` Sascha Hauer
0 siblings, 0 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 17:39 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: BAREBOX
On Fri, Jun 27, 2025 at 05:33:19PM +0200, Ahmad Fatoum wrote:
> On 6/27/25 16:07, Sascha Hauer wrote:
> > On ARMv7 there is no direct way to detect if we are in the secure or non
> > secure world. Add a imx6_can_access_tzasc() for this purpose. When
> > accessing the TZASC triggers a data abort then we are in the non secure
> > world. This function can be used later to detect if we have to load
> > OP-TEE or not.
> >
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > arch/arm/mach-imx/tzasc.c | 16 ++++++++++++++++
> > include/mach/imx/tzasc.h | 1 +
> > 2 files changed, 17 insertions(+)
> >
> > diff --git a/arch/arm/mach-imx/tzasc.c b/arch/arm/mach-imx/tzasc.c
> > index ed20ad8803a2e91b67b5d8c3ab1a4265c4228ec7..63f01cbaa6d4a8fbf47b9683ca840ee64f908cfc 100644
> > --- a/arch/arm/mach-imx/tzasc.c
> > +++ b/arch/arm/mach-imx/tzasc.c
> > @@ -13,6 +13,8 @@
> > #include <linux/sizes.h>
> > #include <mach/imx/imx8m-regs.h>
> > #include <io.h>
> > +#include <abort.h>
> > +#include <asm/barebox-arm.h>
> >
> > /*******************************************************************************
> > * TZC380 defines
> > @@ -329,6 +331,20 @@ bool imx6ul_tzc380_is_bypassed(void)
> > return !(readl(&gpr[9]) & MX6_GPR_TZASC1_EN);
> > }
> >
>
> How about dropping the panic and just failing the build:
>
> #ifdef CONFIG_ARM_EXCEPTIONS_PBL
>
> > +bool imx6_can_access_tzasc(void)
> > +{
> > + if (!IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL))
> > + panic("%s only works with CONFIG_ARM_EXCEPTIONS_PBL\n", __func__);
> > +
> > + arm_pbl_init_exceptions();
> > +
> > + data_abort_mask();
> > +
> > + readl(IOMEM(MX6_TZASC1_BASE));
> > +
> > + return !data_abort_unmask();
> > +}
>
> #else
>
> bool imx6_can_access_tzasc(void)
> __compiletime_error("function called without CONFIG_ARM_EXCEPTIONS_PBL ");
>
> #endif
At the moment tzasc.c is obj-y, so failing the build would make
CONFIG_ARM_EXCEPTIONS_PBL mandatory for i.MX.
We could introduce a config symbol for the TZASC code and select
CONFIG_ARM_EXCEPTIONS_PBL from there.
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] 35+ messages in thread
* Re: [PATCH 08/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_is_bypassed()
2025-06-27 17:26 ` Sascha Hauer
@ 2025-06-27 17:42 ` Marco Felsch
0 siblings, 0 replies; 35+ messages in thread
From: Marco Felsch @ 2025-06-27 17:42 UTC (permalink / raw)
To: Sascha Hauer; +Cc: BAREBOX, Ahmad Fatoum
On 25-06-27, Sascha Hauer wrote:
> On Fri, Jun 27, 2025 at 05:57:23PM +0200, Marco Felsch wrote:
> > On 25-06-27, Sascha Hauer wrote:
> > > From: Marco Felsch <m.felsch@pengutronix.de>
> > >
> > > The TZASC_BYP bits in the IOMUX GPR offer a great way to shoot yourself
> > > in the foot. These bits are cleared by default and with these bits
> > > cleared the TZASC will never check DDR transactions. The TZASC can be
> > > configured normally with the bits cleared, it just doesn't work and all
> > > secure regions can be accessed by the normal worls. These
> > > bits can only be set in the DCD table, trying to set them in code will
> > > make the system hang. As the DCD tables are board specific it's easy to
> >
> > I think this is not entirely true. At least the i.MX6 TRM says, that any
> > DDR access must be done before the TZASC is turned on.
> >
> > Since most i.MX6/7 boards do use the DCD RAM setup and tell the BootROM
> > to load the barebox(-pbl) directly into RAM, we can enable it only from
> > DCD. But it should still be possible to enable it within the code, like
> > we do for i.MX8M. This only requires that the barebox-pbl is loaded into
> > internal OCRAM which is the rare case for i.MX6/7 boards.
>
> So you mean that the bypass bit has to be set before the DDR controller
> is initialized which requires us to put it into the DCD table when we
> initialize the DDR controller in DCD?
I think that the DRAM controller can be initialized before the TZASC is
enabled, e.g. the DCD DRAM initialization can happen before the DCD
TZASC enable. At least the Webasto and the TQMA6ULX is doing it that
way.
What needs to be ensured is, that no DRAM access is in process once we
enable the TZASC. Best solution to do that is using the SoC eFuse, the
DCD or the barebox-pbl if executed from OCRAM.
> Well, that makes more sense to me. I'll adjust the commit message
> accordingly.
Thanks, with that adapted:
Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
^ permalink raw reply [flat|nested] 35+ messages in thread
* Re: [PATCH 03/14] ARM: add exception handling support for PBL
2025-06-27 17:22 ` Sascha Hauer
@ 2025-06-27 17:46 ` Marco Felsch
0 siblings, 0 replies; 35+ messages in thread
From: Marco Felsch @ 2025-06-27 17:46 UTC (permalink / raw)
To: Sascha Hauer; +Cc: BAREBOX
On 25-06-27, Sascha Hauer wrote:
> On Fri, Jun 27, 2025 at 05:45:09PM +0200, Marco Felsch wrote:
> > Hi Sascha,
> >
> > On 25-06-27, Sascha Hauer wrote:
> > > Exception handling in PBL can be very useful for debugging PBL code.
> > > This patch adds support for it.
> > >
> > > This is currently only implemented for ARMv7 and ARMv8. Only on these
> > > architectures we can tell the CPU where the exception table is. On ARMv6
> > > and older we would have to copy the exception table either to 0x0 or
> > > 0xffff0000. Not all SoCs have writable memory at these locations, so we
> > > would have to utilize the MMU to map writable memory there. We are not
> > > there yet, so for now skip exception handling support on these older
> > > architectures.
> > >
> > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > > ---
> > > arch/arm/Kconfig | 10 ++++++++++
> > > arch/arm/cpu/Makefile | 1 +
> > > arch/arm/cpu/interrupts_32.c | 14 +++++++++++++-
> > > arch/arm/cpu/interrupts_64.c | 10 +++++++++-
> > > arch/arm/cpu/uncompress.c | 2 ++
> > > arch/arm/include/asm/barebox-arm.h | 8 ++++++++
> > > arch/arm/lib/pbl.lds.S | 4 ++++
> > > 7 files changed, 47 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> > > index 0800b15d784ca0ab975cf7ceb2f7b47ed10643b1..eaccee9f2f7a128a820e1c55fba816ec5ac4c02d 100644
> > > --- a/arch/arm/Kconfig
> > > +++ b/arch/arm/Kconfig
> > > @@ -378,6 +378,16 @@ config ARM_EXCEPTIONS
> > > bool "enable arm exception handling support"
> > > default y
> > >
> > > +config ARM_EXCEPTIONS_PBL
> > > + select ARCH_HAS_DATA_ABORT_MASK_PBL
> > > + depends on CPU_V7 || CPU_V8
> > > + bool "enable arm exception handling support in PBL"
> > > + help
> > > + Say yes here to enable exception handling in PBL. Note that the exception
> > > + table has to be initialized by calling arm_pbl_init_exceptions(). This is
> > > + done in barebox_pbl_start(). If you need exception handling earlier then
> > > + you have to call arm_pbl_init_exceptions() earlier from your board code.
> > > +
> > > config ARM_UNWIND
> > > bool "enable stack unwinding support"
> > > depends on AEABI
> > > diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
> > > index 39e59c2a2f733d668d57a2f28bdd99f69a016229..9550592796702759f950a3bc4de385100ef2b2e8 100644
> > > --- a/arch/arm/cpu/Makefile
> > > +++ b/arch/arm/cpu/Makefile
> > > @@ -3,6 +3,7 @@
> > > obj-pbl-y += cpu.o
> > >
> > > obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions_$(S64_32).o interrupts_$(S64_32).o
> > > +pbl-$(CONFIG_ARM_EXCEPTIONS_PBL) += exceptions_$(S64_32).o interrupts_$(S64_32).o
> > > obj-$(CONFIG_MMU) += mmu-common.o
> > > obj-pbl-$(CONFIG_MMU) += mmu_$(S64_32).o
> > > obj-$(CONFIG_MMU) += dma_$(S64_32).o
> > > diff --git a/arch/arm/cpu/interrupts_32.c b/arch/arm/cpu/interrupts_32.c
> > > index 623efb3966f0c34632e678d9e1edf2b6affcb4c5..cd503b38eeea551f27bbab0663bbfabdda7ffeea 100644
> > > --- a/arch/arm/cpu/interrupts_32.c
> > > +++ b/arch/arm/cpu/interrupts_32.c
> > > @@ -12,6 +12,7 @@
> > > #include <asm/ptrace.h>
> > > #include <asm/barebox-arm.h>
> > > #include <asm/unwind.h>
> > > +#include <asm/system_info.h>
> > > #include <init.h>
> > >
> > > /* Avoid missing prototype warning, called from assembly */
> > > @@ -61,7 +62,7 @@ void show_regs (struct pt_regs *regs)
> > > fast_interrupts_enabled (regs) ? "on" : "off",
> > > processor_modes[processor_mode (regs)],
> > > thumb_mode (regs) ? " (T)" : "");
> > > -#ifdef CONFIG_ARM_UNWIND
> > > +#if defined CONFIG_ARM_UNWIND && IN_PROPER
> > > unwind_backtrace(regs);
> > > #endif
> > > }
> > > @@ -181,3 +182,14 @@ int data_abort_unmask(void)
> > >
> > > return arm_data_abort_occurred != 0;
> > > }
> > > +
> > > +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> > > +void arm_pbl_init_exceptions(void)
> > > +{
> > > + if (cpu_architecture() < CPU_ARCH_ARMv7)
> > > + return;
> > > +
> > > + set_vbar((unsigned long)__exceptions_start);
> > > + arm_fixup_vectors();
> > > +}
> > > +#endif
> > > diff --git a/arch/arm/cpu/interrupts_64.c b/arch/arm/cpu/interrupts_64.c
> > > index 4d4ef2bab88ef46a7be1cd4add8f3e51423a283b..574ab6a7ec220d2239b6e27c05426e2d4c67d426 100644
> > > --- a/arch/arm/cpu/interrupts_64.c
> > > +++ b/arch/arm/cpu/interrupts_64.c
> > > @@ -88,7 +88,8 @@ static void __noreturn do_exception(struct pt_regs *pt_regs)
> > > {
> > > show_regs(pt_regs);
> > >
> > > - unwind_backtrace(pt_regs);
> > > + if (IN_PROPER)
> > > + unwind_backtrace(pt_regs);
> > >
> > > panic_no_stacktrace("panic: unhandled exception");
> > > }
> > > @@ -226,3 +227,10 @@ static int aarch64_init_vectors(void)
> > > return 0;
> > > }
> > > core_initcall(aarch64_init_vectors);
> > > +
> > > +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> > > +void arm_pbl_init_exceptions(void)
> > > +{
> > > + aarch64_init_vectors();
> > > +}
> > > +#endif
> > > diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c
> > > index 4657a4828e67e1b0acfa9dec3aef33bc4c525468..4529ef5e3821e5b31a3673de6285d2f37e0ecba2 100644
> > > --- a/arch/arm/cpu/uncompress.c
> > > +++ b/arch/arm/cpu/uncompress.c
> > > @@ -63,6 +63,8 @@ void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
> > >
> > > pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
> > >
> > > + arm_pbl_init_exceptions();
> > > +
> > > if (IS_ENABLED(CONFIG_MMU))
> > > mmu_early_enable(membase, memsize);
> > > else if (IS_ENABLED(CONFIG_ARMV7R_MPU))
> > > diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
> > > index 7d35e88c812393d45e331f238baecfa91cbbe299..3ab442bd373e50a84b26145395e42879fc96757f 100644
> > > --- a/arch/arm/include/asm/barebox-arm.h
> > > +++ b/arch/arm/include/asm/barebox-arm.h
> > > @@ -52,6 +52,14 @@ static inline void arm_fixup_vectors(void)
> > > }
> > > #endif
> > >
> > > +#if IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL)
> > > +void arm_pbl_init_exceptions(void);
> > > +#else
> > > +static inline void arm_pbl_init_exceptions(void)
> > > +{
> > > +}
> > > +#endif
> > > +
> > > void *barebox_arm_boot_dtb(void);
> > >
> > > /*
> > > diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
> > > index dad37c9e9bca98beb4f34360fa53a0421662f03c..9c51f5eb3a3d8256752a78e03fed851c84d92edb 100644
> > > --- a/arch/arm/lib/pbl.lds.S
> > > +++ b/arch/arm/lib/pbl.lds.S
> > > @@ -52,6 +52,10 @@ SECTIONS
> > > __bare_init_start = .;
> > > *(.text_bare_init*)
> > > __bare_init_end = .;
> > > + . = ALIGN(0x20);
> > > + __exceptions_start = .;
> > > + KEEP(*(.text_exceptions*))
> > > + __exceptions_stop = .;
> >
> > Nit: We only need this in case of CONFIG_CPU_64, right?
>
> s/CONFIG_CPU_64/CONFIG_CPU_32/
>
> Yes, right.
right /o\
> > Maybe I
> > overlooked it but the only user of this section is
> > arch/arm/cpu/exceptions_32.S. Not sure why arch/arm/lib64/barebox.lds.S
> > has this section too.
>
> Likely because the initial arm64 linker script started as a copy from
> the arm32 linker script.
Yes, I guess so too.
> I'll prepare a patch to remove the section from arch/arm/lib64/barebox.lds.S
> because it's indeed unused.
>
> In arch/arm/lib/pbl.lds.S we could add an #ifdef CONFIG_CPU_64 around the
#ifdef CONFIG_CPU_32. yes.
> section, but it doesn't make a difference, the section will be empty
> anyway.
Sure, just the ALIGN() may add some more bytes but this can be ignored.
At least a comment would be nice :)
Regards,
Marco
>
> 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] 35+ messages in thread
* Re: [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc()
2025-06-27 16:04 ` Marco Felsch
@ 2025-06-27 17:48 ` Sascha Hauer
2025-06-27 17:54 ` Marco Felsch
0 siblings, 1 reply; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 17:48 UTC (permalink / raw)
To: Marco Felsch; +Cc: BAREBOX
On Fri, Jun 27, 2025 at 06:04:04PM +0200, Marco Felsch wrote:
> On 25-06-27, Sascha Hauer wrote:
> > On ARMv7 there is no direct way to detect if we are in the secure or non
> > secure world. Add a imx6_can_access_tzasc() for this purpose. When
> > accessing the TZASC triggers a data abort then we are in the non secure
> > world. This function can be used later to detect if we have to load
> ^
> because OP-TEE configures the TZASC access policy to secure-world R/W. ?
Will add.
>
> Keep in mind that this test will fail if a downstream/buggy OP-TEE
> doesn't configure the CSU correctly. Fingers crossed that this never
> will never happen.
When you are using this buggy OP-TEE for security relevant stuff you're
screwed anyway.
When in this case barebox tries to start OP-TEE again and your board
crashes because of this then you are lucky as this could give you a hint
that there's really something wrong.
> > +bool imx6_can_access_tzasc(void)
> > +{
> > + if (!IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL))
> > + panic("%s only works with CONFIG_ARM_EXCEPTIONS_PBL\n", __func__);
> > +
> > + arm_pbl_init_exceptions();
>
> Can't we do that within the imx*_cpu_lowlevel_init?
No, we need a proper C environment for this which is not guaranteed in
these functions.
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] 35+ messages in thread
* Re: [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc()
2025-06-27 17:48 ` Sascha Hauer
@ 2025-06-27 17:54 ` Marco Felsch
0 siblings, 0 replies; 35+ messages in thread
From: Marco Felsch @ 2025-06-27 17:54 UTC (permalink / raw)
To: Sascha Hauer; +Cc: BAREBOX
On 25-06-27, Sascha Hauer wrote:
> On Fri, Jun 27, 2025 at 06:04:04PM +0200, Marco Felsch wrote:
> > On 25-06-27, Sascha Hauer wrote:
> > > On ARMv7 there is no direct way to detect if we are in the secure or non
> > > secure world. Add a imx6_can_access_tzasc() for this purpose. When
> > > accessing the TZASC triggers a data abort then we are in the non secure
> > > world. This function can be used later to detect if we have to load
> > ^
> > because OP-TEE configures the TZASC access policy to secure-world R/W. ?
>
> Will add.
>
> >
> > Keep in mind that this test will fail if a downstream/buggy OP-TEE
> > doesn't configure the CSU correctly. Fingers crossed that this never
> > will never happen.
>
> When you are using this buggy OP-TEE for security relevant stuff you're
> screwed anyway.
>
> When in this case barebox tries to start OP-TEE again and your board
> crashes because of this then you are lucky as this could give you a hint
> that there's really something wrong.
Yes, you're right.
> > > +bool imx6_can_access_tzasc(void)
> > > +{
> > > + if (!IS_ENABLED(CONFIG_ARM_EXCEPTIONS_PBL))
> > > + panic("%s only works with CONFIG_ARM_EXCEPTIONS_PBL\n", __func__);
> > > +
> > > + arm_pbl_init_exceptions();
> >
> > Can't we do that within the imx*_cpu_lowlevel_init?
>
> No, we need a proper C environment for this which is not guaranteed in
> these functions.
Ah, right.
Regards,
Marco
>
> 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] 35+ messages in thread
* Re: [PATCH 13/14] ARM: optee-early: drop start_optee_early()
2025-06-27 15:21 ` Ahmad Fatoum
@ 2025-06-27 17:59 ` Sascha Hauer
0 siblings, 0 replies; 35+ messages in thread
From: Sascha Hauer @ 2025-06-27 17:59 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: BAREBOX
On Fri, Jun 27, 2025 at 05:21:03PM +0200, Ahmad Fatoum wrote:
> Hi,
>
> On 6/27/25 16:07, Sascha Hauer wrote:
> > Now that all users of start_optee_early() use the SoC variants
> > make start_optee_early() a static function. While at it move the zeroing
> > of the data_location which was duplicated in the SoC specific functions
> > to start_optee_early().
>
> start_optee_early() is documented in Documentation/user/optee.rst and
> would need to be updated.
I adjusted the documentation in "ARM: optee-early: add mx6_start_optee_early helper".
Apparently I failed to catch all occurences.
>
>
> > + /* We expect this function to be called with data caches disabled */
> > + BUG_ON(get_cr() & CR_C);
>
> Did you mean to drop the BUG_ON() in start_optee_early().
My series was originally based on master and at some point I rebased on
v2025.06.1 which gave me this artifact which doesn't belong into this
patch. I'll rebase on master again next time.
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] 35+ messages in thread
end of thread, other threads:[~2025-06-27 19:05 UTC | newest]
Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-27 14:07 [PATCH 00/14] i.MX6 TZASC and OP-TEE early helpers Sascha Hauer
2025-06-27 14:07 ` [PATCH 01/14] pbl: add panic_no_stacktrace() Sascha Hauer
2025-06-27 14:07 ` [PATCH 02/14] arch: Allow data_abort_mask() in PBL Sascha Hauer
2025-06-27 14:07 ` [PATCH 03/14] ARM: add exception handling support for PBL Sascha Hauer
2025-06-27 15:30 ` Ahmad Fatoum
2025-06-27 15:45 ` Marco Felsch
2025-06-27 17:22 ` Sascha Hauer
2025-06-27 17:46 ` Marco Felsch
2025-06-27 14:07 ` [PATCH 04/14] ARM: i.MX6QDL: add imxcfg helper to configure the TZASC1/2 Sascha Hauer
2025-06-27 14:07 ` [PATCH 05/14] ARM: i.MX6Q: add imx6_get_mmdc_sdram_size Sascha Hauer
2025-06-27 14:07 ` [PATCH 06/14] ARM: mach-imx: tzasc: add region configure helpers Sascha Hauer
2025-06-27 14:07 ` [PATCH 07/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_early_ns_region1() Sascha Hauer
2025-06-27 14:07 ` [PATCH 08/14] ARM: mach-imx: tzasc: add imx6[q|ul]_tzc380_is_bypassed() Sascha Hauer
2025-06-27 15:57 ` Marco Felsch
2025-06-27 17:26 ` Sascha Hauer
2025-06-27 17:42 ` Marco Felsch
2025-06-27 14:07 ` [PATCH 09/14] ARM: i.MX: add imx6_can_access_tzasc() Sascha Hauer
2025-06-27 15:33 ` Ahmad Fatoum
2025-06-27 17:39 ` Sascha Hauer
2025-06-27 16:04 ` Marco Felsch
2025-06-27 17:48 ` Sascha Hauer
2025-06-27 17:54 ` Marco Felsch
2025-06-27 14:07 ` [PATCH 10/14] ARM: optee-early: add mx6_start_optee_early helper Sascha Hauer
2025-06-27 15:38 ` Ahmad Fatoum
2025-06-27 14:07 ` [PATCH 11/14] ARM: i.MX: tqma6ulx: fix barebox chainloading with OP-TEE enabled Sascha Hauer
2025-06-27 15:39 ` Ahmad Fatoum
2025-06-27 16:08 ` Marco Felsch
2025-06-27 16:10 ` Marco Felsch
2025-06-27 14:07 ` [PATCH 12/14] ARM: i.MX: Webasto ccbv2: " Sascha Hauer
2025-06-27 15:17 ` Ahmad Fatoum
2025-06-27 14:07 ` [PATCH 13/14] ARM: optee-early: drop start_optee_early() Sascha Hauer
2025-06-27 15:21 ` Ahmad Fatoum
2025-06-27 17:59 ` Sascha Hauer
2025-06-27 14:08 ` [PATCH 14/14] ARM: i.MX: tqma6ulx: use ENTRY_FUNCTION_WITHSTACK Sascha Hauer
2025-06-27 15:21 ` Ahmad Fatoum
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox