U-Boot Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] arm: mvebu: armada8k: do not offer the ATF/TEE region as free memory
@ 2026-08-27 19:36 Bruno Banelli
  2026-09-07 18:06 ` Tom Rini
  0 siblings, 1 reply; 2+ messages in thread
From: Bruno Banelli @ 2026-08-27 19:36 UTC (permalink / raw)
  To: u-boot
  Cc: Stefan Roese, Tom Rini, Ilias Apalodimas, Marek Vasut,
	Vincent Jardin, Sughosh Ganu, Heinrich Schuchardt, Bruno Banelli

mvebu_mem_map[] deliberately leaves the ATF and TEE region unmapped:

	{
		/* RAM 0-64MB */
		.phys = 0x0UL,
		.size = ATF_REGION_START,
		...
	},
	/* ATF and TEE region 0x4000000-0x5400000 not mapped */
	{
		/* RAM 66MB-2GB */
		.phys = ATF_REGION_END,
		...
	},

Nothing tells LMB about the hole, so the whole of DRAM bank 0 is added
as available memory (sizes elided from the dumps below for width):

 lmb_dump_all:
  memory.count = 0x2
  memory[0] [0x0-0xbfffffff], flags: none
  memory[1] [0x100000000-0x43fffffff], flags: none
  reserved.count = 0x4
  reserved[0] [0x4000000-0x41fffff], flags: no-map
  reserved[1] [0x7eb1d000-0x7eb1ffff], flags: no-notify, no-overwrite
  reserved[2] [0x7eb20f40-0xbfffffff], flags: no-overwrite
  reserved[3] [0x100000000-0x43fffffff], flags: no-overwrite

The only part of the hole that is reserved is the 2 MiB psci-area from
armada-ap80x.dtsi.  The remaining 18 MiB is allocatable, and since
lmb_add() notifies the EFI allocator, it is also published to EFI
payloads as EFI_CONVENTIONAL_MEMORY.  Any access to it faults:

  => md 0x4200000 4
  "Synchronous Abort" handler, esr 0x96000006, far 0x4200000
  Resetting CPU ...

ESR 0x96000006 is a data abort at the current exception level with
DFSC 0x06, a level 2 translation fault - there is no mapping, which is
exactly what mvebu_mem_map[] intends.  The same abort with WnR set
(esr 0x96000046) is what MemTest86 v11 for ARM64 hits on its first
write, because the EFI memory map it is handed says:

  0x000004000000 - 0x0000041FFFFF (2MB)  {Reserved Memory}
  0x000004200000 - 0x000006FFFFFF (46MB) {Free Memory}

Add an lmb_arch_add_memory() for Armada 8k that adds each DRAM bank
around the ATF and TEE region instead of over it, and select
LMB_ARCH_MEM_MAP for ARMADA_8K.  The hook replaces the generic
lmb_add_memory() rather than extending it, so it also has to reproduce
the LMB_LIMIT_DMA_BELOW_RAM_TOP reservation above gd->ram_top; both are
needed on this SoC, which maps only the first 2 GiB of DRAM.

After the change:

 lmb_dump_all:
  memory.count = 0x3
  memory[0] [0x0-0x3ffffff], flags: none
  memory[1] [0x5400000-0xbfffffff], flags: none
  memory[2] [0x100000000-0x43fffffff], flags: none
  reserved.count = 0x3
  reserved[0] [0x7eb1d000-0x7eb1ffff], flags: no-notify, no-overwrite
  reserved[1] [0x7eb20f40-0xbfffffff], flags: no-overwrite
  reserved[2] [0x100000000-0x43fffffff], flags: no-overwrite

  => md 0x4200000 4
  "Synchronous Abort" handler, esr 0x96000006, far 0x4200000
  => md 0x5400000 4
  05400000: 00000000 ffffffff 00000000 ffdfffff  ................

and MemTest86 completes passes instead of aborting.

Note the psci-area reservation disappears from the dump: the region is
no longer part of the LMB memory map, so boot_fdt_reserve_region() gets
-EINVAL back from lmb_alloc_mem() and skips it.  That is harmless - the
memory is not allocatable either way - but it is a visible change in
"bdinfo" output.

board_get_usable_ram_top() already clamps gd->ram_top to the 2 GiB that
mvebu_mem_map[] maps, for the same underlying reason.  A ram_top limit
cannot express a hole in the middle of a bank, hence this patch.

Tested on a SolidRun MACCHIATObin (Armada 8040) with 16 GiB of DRAM.

Signed-off-by: Bruno Banelli <bbanelli@gmail.com>
---
 arch/arm/mach-mvebu/armada8k/cpu.c | 89 ++++++++++++++++++++++++++++++
 lib/Kconfig                        |  2 +-
 2 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mvebu/armada8k/cpu.c b/arch/arm/mach-mvebu/armada8k/cpu.c
index 220b32dd02..666be973a7 100644
--- a/arch/arm/mach-mvebu/armada8k/cpu.c
+++ b/arch/arm/mach-mvebu/armada8k/cpu.c
@@ -6,8 +6,11 @@
 #include <cpu_func.h>
 #include <dm.h>
 #include <fdtdec.h>
+#include <lmb.h>
+#include <log.h>
 #include <linux/libfdt.h>
 #include <linux/sizes.h>
+#include <asm/global_data.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/arch/cpu.h>
@@ -17,6 +20,8 @@
 
 #include "soc_info.h"
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /* Armada 7k/8k */
 #define MVEBU_RFU_BASE			(MVEBU_REGISTER(0x6f0000))
 #define RFU_GLOBAL_SW_RST		(MVEBU_RFU_BASE + 0x84)
@@ -61,6 +66,90 @@ static struct mm_region mvebu_mem_map[] = {
 
 struct mm_region *mem_map = mvebu_mem_map;
 
+#if CONFIG_IS_ENABLED(LMB_ARCH_MEM_MAP)
+/**
+ * mvebu_lmb_reserve() - mark a region as present but not allocatable
+ * @base:	start of the region
+ * @size:	size of the region
+ */
+static void mvebu_lmb_reserve(phys_addr_t base, phys_size_t size)
+{
+	phys_addr_t addr = base;
+
+	if (lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &addr, size, LMB_NOOVERWRITE))
+		log_err("Failed to reserve 0x%llx bytes at 0x%llx\n",
+			(unsigned long long)size, (unsigned long long)base);
+}
+
+/**
+ * mvebu_lmb_add_bank() - add one memory range, honouring ram_top
+ * @base:	start of the range
+ * @size:	size of the range
+ * @ram_top:	highest address U-Boot may allocate from
+ *
+ * The reservation above @ram_top mirrors the generic lmb_add_memory(), which
+ * this hook replaces.
+ */
+static void mvebu_lmb_add_bank(phys_addr_t base, phys_size_t size, u64 ram_top)
+{
+	phys_addr_t bank_end = base + size;
+
+	lmb_add(base, size);
+
+	if (!IS_ENABLED(CONFIG_LMB_LIMIT_DMA_BELOW_RAM_TOP))
+		return;
+
+	if (base >= ram_top)
+		mvebu_lmb_reserve(base, size);
+	else if (bank_end > ram_top)
+		mvebu_lmb_reserve(ram_top, bank_end - ram_top);
+}
+
+/**
+ * lmb_arch_add_memory() - add DRAM to LMB, minus the ATF and TEE region
+ *
+ * mvebu_mem_map[] above deliberately has no entry for ATF_REGION_START to
+ * ATF_REGION_END, so U-Boot has no translation for that range and any access
+ * to it takes a translation fault. It must not be handed to LMB either:
+ * everything LMB holds as available is published to EFI payloads as
+ * EFI_CONVENTIONAL_MEMORY, and the first payload to use it aborts.
+ */
+void lmb_arch_add_memory(void)
+{
+	phys_addr_t bank_start, bank_end;
+	u64 ram_top = gd->ram_top;
+	int i;
+
+	/* Assume a 4GB ram_top if not defined */
+	if (!ram_top)
+		ram_top = 0x100000000ULL;
+
+	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (!gd->dram[i].size)
+			continue;
+
+		bank_start = gd->dram[i].start;
+		bank_end = bank_start + gd->dram[i].size;
+
+		if (bank_end <= ATF_REGION_START ||
+		    bank_start >= ATF_REGION_END) {
+			mvebu_lmb_add_bank(bank_start, gd->dram[i].size,
+					   ram_top);
+			continue;
+		}
+
+		if (bank_start < ATF_REGION_START)
+			mvebu_lmb_add_bank(bank_start,
+					   ATF_REGION_START - bank_start,
+					   ram_top);
+		if (bank_end > ATF_REGION_END)
+			mvebu_lmb_add_bank(ATF_REGION_END,
+					   bank_end - ATF_REGION_END,
+					   ram_top);
+	}
+}
+#endif
+
 void enable_caches(void)
 {
 	icache_enable();
diff --git a/lib/Kconfig b/lib/Kconfig
index 24e55ade4d..6b6b90bc91 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -1295,7 +1295,7 @@ config SPL_LMB
 config LMB_ARCH_MEM_MAP
 	bool
 	depends on LMB
-	default y if FSL_LAYERSCAPE || X86
+	default y if ARMADA_8K || FSL_LAYERSCAPE || X86
 	help
 	  Some architectures have special or unique aspects which need
 	  consideration when adding memory ranges to the list of available
-- 
2.43.0


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

* Re: [PATCH] arm: mvebu: armada8k: do not offer the ATF/TEE region as free memory
  2026-08-27 19:36 [PATCH] arm: mvebu: armada8k: do not offer the ATF/TEE region as free memory Bruno Banelli
@ 2026-09-07 18:06 ` Tom Rini
  0 siblings, 0 replies; 2+ messages in thread
From: Tom Rini @ 2026-09-07 18:06 UTC (permalink / raw)
  To: u-boot, Bruno Banelli
  Cc: Stefan Roese, Ilias Apalodimas, Marek Vasut, Vincent Jardin,
	Sughosh Ganu, Heinrich Schuchardt

On Thu, 27 Aug 2026 21:36:03 +0200, Bruno Banelli wrote:

> mvebu_mem_map[] deliberately leaves the ATF and TEE region unmapped:
> 
> 	{
> 		/* RAM 0-64MB */
> 		.phys = 0x0UL,
> 		.size = ATF_REGION_START,
> 		...
> 	},
> 	/* ATF and TEE region 0x4000000-0x5400000 not mapped */
> 	{
> 		/* RAM 66MB-2GB */
> 		.phys = ATF_REGION_END,
> 		...
> 	},
> 
> [...]

Applied to u-boot/main, thanks!

[1/1] arm: mvebu: armada8k: do not offer the ATF/TEE region as free memory
      commit: 835ac41ca69a5aa9171b6c8dbbb54ddb5520c161
-- 
Tom



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

end of thread, other threads:[~2026-09-07 18:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-27 19:36 [PATCH] arm: mvebu: armada8k: do not offer the ATF/TEE region as free memory Bruno Banelli
2026-09-07 18:06 ` Tom Rini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox