As discussed here[1], the go command causes undefined behavior when used
for running custom OSes since the icache might hold outdated data. OSes
usually also expect the MMU to be disabled upon execution.

Therefore this patch adds a call to cleanup_before_linux before we jump
to the loaded program/os which disables both the caches and the MMU.
This makes the go command's behavior consistent with riscv platforms.

NOTE: This might cause regressions with users expecting a configured MMU
but I'm unsure if it's a supported use case for the go command anyway.

[1]: https://lore.kernel.org/u-boot/d9dxl95mtq8i.3euy0c6m2l...@ti.com/

Signed-off-by: Anshul Dalal <ansh...@ti.com>
---
 arch/arm/lib/Makefile |  1 +
 arch/arm/lib/boot.c   | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)
 create mode 100644 arch/arm/lib/boot.c

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 74cd5051552..e4cb50a7f71 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -24,6 +24,7 @@ endif
 ifndef CONFIG_XPL_BUILD
 ifdef CONFIG_ARM64
 obj-y  += relocate_64.o
+obj-y  += boot.o
 else
 obj-y  += relocate.o
 endif
diff --git a/arch/arm/lib/boot.c b/arch/arm/lib/boot.c
new file mode 100644
index 00000000000..eafdb0f9e5a
--- /dev/null
+++ b/arch/arm/lib/boot.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2025 Texas Instruments Incorporated - https://www.ti.com/
+ * Anshul Dalal, <ansh...@ti.com>
+ */
+
+#include <command.h>
+#include <asm/u-boot-arm.h>
+
+unsigned long do_go_exec(ulong (*entry)(int, char *const[]), int argc,
+                        char *const argv[])
+{
+       cleanup_before_linux();
+
+       return entry(argc, argv);
+}
-- 
2.49.0

Reply via email to