[PATCH] bloblist: Fix bloblist convention checking.

Levi Yun yeoreum.yun at arm.com
Tue Jul 9 15:25:16 CEST 2024


According to recently firmware handsoff spec [1]'s
"Register usage at handoff boundary",
Transfer List's signature value was changed from 0x40_b10b
(3 bytes) to 4a0f_b10b (4 bytes).

As updating of TL's signature, register value of x1/r1 should be:

In aarch32's r1 value should be
    R1[23:0]: TL signature (4a0f_b10b->masked range value: 0f_b10b)
    R1[31:24]: version of the register convention ==  1

and

In aarch64's x1 value should be
    X1[31:0]: TL signature (4a0f_b10b)
    X1[39:32]: version of the register convention ==  1
    X1[63:40]: MBZ
(See the [2] and [3]).

Also, according to architecture, the convention is slight different:

In aarch32:
    R0: MBZ
    R1: see above
    R2: Compatibility location for passing a platform description devicetree
    R3: tl_base_pa

In aarch64:
    X0: Compatibility location for passing a platform description devicetree
    X1: see above
    X2: MBZ
    X3: tl_base_pa

This patch fix problems:
   1. breaking X1 value with updated specification in aarch64
        - change of length of signature field.

   2. previous error value set in R1 in arm32.
        - length of signature should be 24, but it uses 32bit signature.

   3. according to architecture, check register convetion differently.

[1] https://github.com/FirmwareHandoff/firmware_handoff
[2] https://github.com/FirmwareHandoff/firmware_handoff/issues/32
[3] https://github.com/FirmwareHandoff/firmware_handoff/commit/5aa7aa1d3a1db75213e458d392b751f0707de027

Signed-off-by: Levi Yun <yeoreum.yun at arm.com>
---
 arch/arm/lib/xferlist.c |  8 +++++---
 common/bloblist.c       | 11 ++++++++++-
 include/bloblist.h      |  5 ++++-
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arm/lib/xferlist.c b/arch/arm/lib/xferlist.c
index f9c5d88bd4..a6349293bd 100644
--- a/arch/arm/lib/xferlist.c
+++ b/arch/arm/lib/xferlist.c
@@ -12,12 +12,14 @@ int xferlist_from_boot_arg(ulong addr, ulong size)
 {
 	int ret;

-	ret = bloblist_check(saved_args[3], size);
+	if (IS_ENABLED(CONFIG_64BIT))
+		ret = bloblist_check_reg_conv(saved_args[0], saved_args[2], saved_args[1]);
+	else
+		ret = bloblist_check_reg_conv(saved_args[2], saved_args[0], saved_args[1]);
 	if (ret)
 		return ret;

-	ret = bloblist_check_reg_conv(saved_args[0], saved_args[2],
-				      saved_args[1]);
+	ret = bloblist_check(saved_args[3], size);
 	if (ret)
 		return ret;

diff --git a/common/bloblist.c b/common/bloblist.c
index 11d6422b69..2008ab4d25 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -576,7 +576,16 @@ int bloblist_maybe_init(void)

 int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig)
 {
-	if (rzero || rsig != (BLOBLIST_MAGIC | BLOBLIST_REGCONV_VER) ||
+	ulong version = BLOBLIST_REGCONV_VER;
+	ulong sigval;
+
+	sigval = (IS_ENABLED(CONFIG_64BIT)) ?
+			((BLOBLIST_MAGIC & ((1UL << BLOBLIST_REGCONV_SHIFT_64) - 1)) |
+			 ((version  & BLOBLIST_REGCONV_MASK) << BLOBLIST_REGCONV_SHIFT_64)) :
+			((BLOBLIST_MAGIC & ((1UL << BLOBLIST_REGCONV_SHIFT_32) - 1)) |
+			 ((version  & BLOBLIST_REGCONV_MASK) << BLOBLIST_REGCONV_SHIFT_32));
+
+	if (rzero || rsig != sigval ||
 	    rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) {
 		gd->bloblist = NULL;  /* Reset the gd bloblist pointer */
 		return -EIO;
diff --git a/include/bloblist.h b/include/bloblist.h
index 7fbdd622bc..f4849f22a0 100644
--- a/include/bloblist.h
+++ b/include/bloblist.h
@@ -83,7 +83,10 @@ enum {
 	 * Register convention version should be placed into a higher byte
 	 * https://github.com/FirmwareHandoff/firmware_handoff/issues/32
 	 */
-	BLOBLIST_REGCONV_VER	= 1 << 24,
+	BLOBLIST_REGCONV_SHIFT_64 = 32,
+	BLOBLIST_REGCONV_SHIFT_32 = 24,
+	BLOBLIST_REGCONV_MASK = 0xff,
+	BLOBLIST_REGCONV_VER = 1,

 	BLOBLIST_BLOB_ALIGN_LOG2 = 3,
 	BLOBLIST_BLOB_ALIGN	 = 1 << BLOBLIST_BLOB_ALIGN_LOG2,
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}



More information about the U-Boot mailing list