From 2e0f3ac758da99fb6d1b4c651643999d83cd0a7f Mon Sep 17 00:00:00 2001
From: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Date: Mon, 12 Aug 2019 23:50:42 +0200
Subject: firmware: do not use relocated _boot_status before it is valid

When OpenSBI is started from an address not equal to the link address,
it is first relocated to the link address. Hart 0 performs the
relocation and notifies the other harts of its completion with the
_boot_status variable. It uses the copy of the variable relative to the
link address. This copy contains valid data only after relocation has
finished. The waiting harts will therefore read invalid data until
relocation has finished. This can cause them to continue execution too
early.

Fix this by using the _boot_status variable relative to the load address
while OpenSBI has not finished relocation.

Signed-off-by: Lukas Auer <lukas.auer@aisec.fraunhofer.de>
Reviewed-by: Anup Patel <anup.patel@wdc.com>
---
 firmware/fw_base.S | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

(limited to 'firmware')

diff --git a/firmware/fw_base.S b/firmware/fw_base.S
index f2b1ee0..f596638 100644
--- a/firmware/fw_base.S
+++ b/firmware/fw_base.S
@@ -111,8 +111,6 @@ _wait_relocate_copy_done:
 	REG_L	t1, 0(t1)
 	beq	t0, t1, _wait_for_boot_hart
 	la	t2, _boot_status
-	sub	t2, t2, t0
-	add	t2, t2, t1
 	la	t3, _wait_for_boot_hart
 	sub	t3, t3, t0
 	add	t3, t3, t1
@@ -128,8 +126,17 @@ _wait_relocate_copy_done:
 	jr	t3
 _relocate_done:
 
-	/* mark relocate copy done */
+	/*
+	 * Mark relocate copy done
+	 * Use _boot_status copy relative to the load address
+	 */
 	la	t0, _boot_status
+	la	t1, _link_start
+	REG_L	t1, 0(t1)
+	la	t2, _load_start
+	REG_L	t2, 0(t2)
+	sub	t0, t0, t1
+	add	t0, t0, t2
 	li	t1, BOOT_STATUS_RELOCATE_DONE
 	REG_S	t1, 0(t0)
 	fence	rw, rw
-- 
cgit v1.2.3