[PATCH v2 2/4] arm: meson: add Amlogic T7 SoC family support

Lucas Tanure <[email protected]>
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <20260821084603.25974-3-tanure__13960.203870532$1787318273$gmane$org@linux.com>
Add initial support for the Amlogic T7 family (A311D2). U-Boot runs
as BL33, loaded at address 0x0 and entered from the vendor BL31 at
EL2, either uncompressed or LZ4-compressed inside the boot image (the
BL31 decompresses it).

The secure firmware writes the SCS device keys into the first page of
the loaded BL33 image (2 KiB for the BL33 key followed by 2 KiB for
the kernel key). Reserve that page with a boot0 hook, as the vendor
U-Boot does, so the keys do not overwrite U-Boot's entry code.

The firmware also enters BL33 with the non-secure watchdog running:
disable it in board_init(), otherwise the board is reset about a
minute after boot.

The memory map leaves 0x05100000 - 0x09000000 unmapped: the secure
world owns this span (the BL31 and BL32 runtime zones described in
the upstream devicetree, plus further firmware-protected pages), and
this matches the vendor bootloader's own map. The whole span is also
added to the devicetree and EFI reserved memory at boot time so no
allocation is placed in memory U-Boot cannot access.

get_effective_memsize() is capped at 0xdf800000 because the top 8 MiB
of the first DRAM bank contain pages the secure world protects at
runtime; U-Boot and its heap must stay below them.

Assisted-by: Claude:claude-fable-5
Signed-off-by: Lucas Tanure <[email protected]>
---
 arch/arm/include/asm/arch-meson/boot0.h | 18 ++++++
 arch/arm/include/asm/arch-meson/t7.h    | 25 ++++++++
 arch/arm/mach-meson/Kconfig             |  9 +++
 arch/arm/mach-meson/Makefile            |  1 +
 arch/arm/mach-meson/board-t7.c          | 82 +++++++++++++++++++++++++
 5 files changed, 135 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-meson/boot0.h
 create mode 100644 arch/arm/include/asm/arch-meson/t7.h
 create mode 100644 arch/arm/mach-meson/board-t7.c

diff --git a/arch/arm/include/asm/arch-meson/boot0.h b/arch/arm/include/asm/arch-meson/boot0.h
new file mode 100644
index 00000000000..3ec085ccd64
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/boot0.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2026 Lucas Tanure <[email protected]>
+ */
+
+#ifndef __MESON_BOOT0_H
+#define __MESON_BOOT0_H
+
+/*
+ * The T7-family secure firmware writes the SCS device keys into the
+ * first page of the loaded BL33 image (2048 bytes for the BL33 key
+ * followed by 2048 bytes for the kernel key). Keep that page reserved
+ * so the keys do not overwrite U-Boot's entry code.
+ */
+	b	reset
+	.space	4096
+
+#endif /* __MESON_BOOT0_H */
diff --git a/arch/arm/include/asm/arch-meson/t7.h b/arch/arm/include/asm/arch-meson/t7.h
new file mode 100644
index 00000000000..e0a90329082
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/t7.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2026 Lucas Tanure <[email protected]>
+ */
+
+#ifndef __T7_H__
+#define __T7_H__
+
+#include <linux/bitops.h>
+
+#define T7_WDT_CTRL		0xfe002100
+#define T7_WDT_CTRL_EN		BIT(18)
+
+/*
+ * The secure world owns 0x05000000 - 0x09000000: it contains the BL31
+ * and BL32 runtime zones (also described as reserved-memory in the
+ * upstream devicetree) and further firmware-protected pages, and is
+ * left unmapped in the T7 memory map. Reserve the whole span so nothing
+ * (EFI allocations, boot-time relocations) is ever placed in memory
+ * U-Boot cannot access.
+ */
+#define T7_SECMON_RSVMEM_START	0x05000000UL
+#define T7_SECMON_RSVMEM_SIZE	0x04000000UL
+
+#endif /* __T7_H__ */
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index c687ef822a2..1a8bab8391f 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -67,6 +67,14 @@ config MESON_A1
 	help
 	  Select this if your SoC is an A113L
 
+config MESON_T7
+	bool "T7"
+	select MESON64_COMMON
+	select ENABLE_ARM_SOC_BOOT0_HOOK
+	imply OF_UPSTREAM
+	help
+	  Select this if your SoC is an A311D2
+
 endchoice
 
 config SYS_SOC
@@ -91,6 +99,7 @@ config SYS_BOARD
 	default "q200" if MESON_GXM
 	default "s400" if MESON_AXG
 	default "u200" if MESON_G12A
+	default "vim4" if MESON_T7
 	default ""
 	help
 	  This option contains information about board name.
diff --git a/arch/arm/mach-meson/Makefile b/arch/arm/mach-meson/Makefile
index 08a24d4b24f..dc2bc0ceecb 100644
--- a/arch/arm/mach-meson/Makefile
+++ b/arch/arm/mach-meson/Makefile
@@ -17,3 +17,4 @@ endif
 obj-$(CONFIG_MESON_AXG) += board-axg.o
 obj-$(CONFIG_MESON_G12A) += board-g12a.o
 obj-$(CONFIG_MESON_A1) += board-a1.o
+obj-$(CONFIG_MESON_T7) += board-t7.o
diff --git a/arch/arm/mach-meson/board-t7.c b/arch/arm/mach-meson/board-t7.c
new file mode 100644
index 00000000000..c2725a4304f
--- /dev/null
+++ b/arch/arm/mach-meson/board-t7.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2026 Lucas Tanure <[email protected]>
+ */
+
+#include <init.h>
+#include <asm/arch/boot.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/t7.h>
+#include <asm/armv8/mmu.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+	/*
+	 * The secure firmware boots BL33 with the watchdog running,
+	 * disable it.
+	 */
+	writel(readl(T7_WDT_CTRL) & ~T7_WDT_CTRL_EN, T7_WDT_CTRL);
+
+	return 0;
+}
+
+void meson_init_reserved_memory(void *fdt)
+{
+	meson_board_add_reserved_memory(fdt, T7_SECMON_RSVMEM_START,
+					T7_SECMON_RSVMEM_SIZE);
+}
+
+int meson_get_boot_device(void)
+{
+	return -ENOSYS;
+}
+
+phys_size_t get_effective_memsize(void)
+{
+	/*
+	 * The top 8 MiB of the first DRAM bank contain pages the secure
+	 * world protects at runtime, keep U-Boot below them.
+	 */
+	return min(gd->ram_size, (phys_size_t)0xdf800000);
+}
+
+static struct mm_region t7_mem_map[] = {
+	{
+		/* DRAM below the secure monitor reserved zone */
+		.virt = 0x00000000UL,
+		.phys = 0x00000000UL,
+		.size = 0x05100000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		/*
+		 * DRAM between the secure monitor reserved zone and the
+		 * end of the first bank. 0x05100000 - 0x09000000 is
+		 * protected by the secure world and must not be mapped.
+		 */
+		.virt = 0x09000000UL,
+		.phys = 0x09000000UL,
+		.size = 0xd7000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+			 PTE_BLOCK_INNER_SHARE
+	}, {
+		/* Peripherals, GIC, ... */
+		.virt = 0xe0000000UL,
+		.phys = 0xe0000000UL,
+		.size = 0x20000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+			 PTE_BLOCK_NON_SHARE |
+			 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+	}, {
+		/* List terminator */
+		0,
+	}
+};
+
+struct mm_region *mem_map = t7_mem_map;
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.