mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: BAREBOX <barebox@lists.infradead.org>
Subject: [PATCH 1/3] ARM: rockchip: move to the load address with the MMU enabled
Date: Thu, 01 Oct 2026 09:42:51 +0200	[thread overview]
Message-ID: <20261001-rockchip-early-boottime-v1-1-dd891bcdb74f@pengutronix.de> (raw)
In-Reply-To: <20261001-rockchip-early-boottime-v1-0-dd891bcdb74f@pengutronix.de>

The BootROM starts barebox at the beginning of DRAM, where TF-A and
OP-TEE are loaded to later. The board entry functions therefore copy
the whole image to the load address with relocate_to_adr_full() first
thing. At that point the MMU is off, so every access is uncached and
strictly ordered. On an RK3588 moving the 1.4 MB image takes 674 ms.

Add rockchip_move_to_load_address() and call it from the SoC entry
functions instead: it enables the MMU, maps the rest of the image
cacheable and copies it to the load address, then restarts the image
from there. On the second pass the image already runs at the load
address and the function returns right away. The move itself now takes
a few milliseconds, and loading TF-A and preparing its device tree
also profit from the MMU being on early.

The SoC lowlevel init clears SCTLR_EL3.M and C, so only call it while
the MMU is still off, i.e. on the first pass.

Boards still calling relocate_to_adr_full() already run at the load
address and are unaffected. They are converted in the next commit.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-rockchip/atf.c | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-rockchip/atf.c b/arch/arm/mach-rockchip/atf.c
index 0b4566f8ae..e1ca197430 100644
--- a/arch/arm/mach-rockchip/atf.c
+++ b/arch/arm/mach-rockchip/atf.c
@@ -8,6 +8,7 @@
 #include <asm/atf_common.h>
 #include <asm/barebox-arm.h>
 #include <asm/mmu.h>
+#include <asm/cache.h>
 #include <asm-generic/memory_layout.h>
 #include <asm-generic/sections.h>
 #include <mach/rockchip/dmc.h>
@@ -131,6 +132,27 @@ static uintptr_t rk_load_optee(uintptr_t bl32, struct fwobj *bl32_fw)
 static phys_addr_t membase[ROCKCHIP_MAX_DRAM_RESOURCES];
 static resource_size_t memsize[ROCKCHIP_MAX_DRAM_RESOURCES];
 static int n_mem_resources;
+
+/*
+ * The BootROM starts us at the beginning of DRAM, where TF-A and OP-TEE go.
+ * Copy ourselves to @load_address with the MMU enabled and restart there.
+ * The SoC lowlevel init clears SCTLR_EL3.M, so it must run before this.
+ */
+static void rockchip_move_to_load_address(ulong load_address)
+{
+	void (*restart)(void) = (void *)load_address;
+
+	if ((ulong)__image_start == load_address)
+		return;
+
+	mmu_early_enable(membase[0], memsize[0]);
+	memcpy((void *)load_address, __image_start, barebox_image_size);
+	sync_caches_for_execution();
+
+	restart();
+	__builtin_unreachable();
+}
+
 static uintptr_t barebox_load_address; /* where barebox is loaded and started */
 static uintptr_t optee_load_address; /* standard SoC specific OP-TEE load address */
 static struct fwobj bl31; /* TF-A in barebox image */
@@ -202,7 +224,9 @@ void __noreturn rk3562_barebox_entry(void *fdt)
 	rk_scratch = (void *)arm_mem_scratch(memend);
 
 	if (current_el() == 3) {
-		rk3562_lowlevel_init();
+		if (!(get_cr() & CR_M))
+			rk3562_lowlevel_init();
+		rockchip_move_to_load_address(RK3562_BAREBOX_LOAD_ADDRESS);
 		rockchip_store_bootrom_iram(IOMEM(RK3562_IRAM_BASE));
 		ROCKCHIP_GET_ADDRESSES(RK3562, rk3562_bl31_bin, rk3562_bl32_bin);
 
@@ -236,7 +260,9 @@ void __noreturn rk3568_barebox_entry(void *fdt)
 	rk_scratch = (void *)arm_mem_scratch(memend);
 
 	if (current_el() == 3) {
-		rk3568_lowlevel_init();
+		if (!(get_cr() & CR_M))
+			rk3568_lowlevel_init();
+		rockchip_move_to_load_address(RK3568_BAREBOX_LOAD_ADDRESS);
 		rockchip_store_bootrom_iram(IOMEM(RK3568_IRAM_BASE));
 		ROCKCHIP_GET_ADDRESSES(RK3568, rk3568_bl31_bin, rk3568_bl32_bin);
 
@@ -273,7 +299,9 @@ void __noreturn rk3588_barebox_entry(void *fdt)
 	if (current_el() == 3) {
 		void *fdt_bl31 = NULL;
 
-		rk3588_lowlevel_init();
+		if (!(get_cr() & CR_M))
+			rk3588_lowlevel_init();
+		rockchip_move_to_load_address(RK3588_BAREBOX_LOAD_ADDRESS);
 		rockchip_store_bootrom_iram(IOMEM(RK3588_IRAM_BASE));
 		ROCKCHIP_GET_ADDRESSES(RK3588, rk3588_bl31_bin, rk3588_bl32_bin);
 
@@ -308,7 +336,9 @@ void __noreturn rk3576_barebox_entry(void *fdt)
 	if (current_el() == 3) {
 		void *fdt_scratch = NULL;
 
-		rk3576_lowlevel_init();
+		if (!(get_cr() & CR_M))
+			rk3576_lowlevel_init();
+		rockchip_move_to_load_address(RK3576_BAREBOX_LOAD_ADDRESS);
 		rockchip_store_bootrom_iram(IOMEM(RK3576_IRAM_BASE));
 		ROCKCHIP_GET_ADDRESSES(RK3576, rk3576_bl31_bin, rk3576_bl32_bin);
 

-- 
2.47.3




  reply	other threads:[~2026-10-01  7:43 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-01  7:42 [PATCH 0/3] Rockchip: early boot time optimization Sascha Hauer
2026-10-01  7:42 ` Sascha Hauer [this message]
2026-10-01  7:42 ` [PATCH 2/3] ARM: rockchip: boards: leave moving to the load address to atf.c Sascha Hauer
2026-10-01  8:30   ` Ahmad Fatoum
2026-10-01 10:19     ` Sascha Hauer
2026-10-01  7:42 ` [PATCH 3/3] ARM: rockchip: pack the device tree passed to TF-A and OP-TEE Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261001-rockchip-early-boottime-v1-1-dd891bcdb74f@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox