Merge "feat(handoff): fix register convention r1/x1 value on transfer list" into integration
diff --git a/include/lib/transfer_list.h b/include/lib/transfer_list.h
index 5bea270..1b5ec2d 100644
--- a/include/lib/transfer_list.h
+++ b/include/lib/transfer_list.h
@@ -29,7 +29,22 @@
  * Version of the register convention used.
  * Set to 1 for both AArch64 and AArch32 according to fw handoff spec v0.9
  */
-#define REGISTER_CONVENTION_VERSION_MASK (1 << 24)
+#define REGISTER_CONVENTION_VERSION_SHIFT_64	UL(32)
+#define REGISTER_CONVENTION_VERSION_SHIFT_32	UL(24)
+#define REGISTER_CONVENTION_VERSION_MASK	UL(0xff)
+#define REGISTER_CONVENTION_VERSION 	UL(1)
+
+#define TRANSFER_LIST_HANDOFF_X1_VALUE(__version) 	\
+	((TRANSFER_LIST_SIGNATURE &	\
+	((1UL << REGISTER_CONVENTION_VERSION_SHIFT_64) - 1)) | 	\
+	(((__version) & REGISTER_CONVENTION_VERSION_MASK) <<	\
+	 REGISTER_CONVENTION_VERSION_SHIFT_64))
+
+#define TRANSFER_LIST_HANDOFF_R1_VALUE(__version) 	\
+	((TRANSFER_LIST_SIGNATURE &	\
+	((1UL << REGISTER_CONVENTION_VERSION_SHIFT_32) - 1)) | 	\
+	(((__version) & REGISTER_CONVENTION_VERSION_MASK) <<	\
+	 REGISTER_CONVENTION_VERSION_SHIFT_32))
 
 #ifndef __ASSEMBLER__
 
diff --git a/lib/transfer_list/transfer_list.c b/lib/transfer_list/transfer_list.c
index b7fedfa..8d82d25 100644
--- a/lib/transfer_list/transfer_list.c
+++ b/lib/transfer_list/transfer_list.c
@@ -63,20 +63,21 @@
 	te = transfer_list_find(tl, TL_TAG_FDT);
 	dt = transfer_list_entry_data(te);
 
-	ep_info->args.arg1 = TRANSFER_LIST_SIGNATURE |
-			     REGISTER_CONVENTION_VERSION_MASK;
-	ep_info->args.arg3 = (uintptr_t)tl;
-
-	if (GET_RW(ep_info->spsr) == MODE_RW_32) {
-		/* aarch32 */
-		ep_info->args.arg0 = 0;
-		ep_info->args.arg2 = (uintptr_t)dt;
-	} else {
-		/* aarch64 */
+#ifdef __aarch64__
+	if (GET_RW(ep_info->spsr) == MODE_RW_64) {
 		ep_info->args.arg0 = (uintptr_t)dt;
+		ep_info->args.arg1 = TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
 		ep_info->args.arg2 = 0;
+	} else
+#endif
+	{
+		ep_info->args.arg0 = 0;
+		ep_info->args.arg1 = TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+		ep_info->args.arg2 = (uintptr_t)dt;
 	}
 
+	ep_info->args.arg3 = (uintptr_t)tl;
+
 	return ep_info;
 }
 
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index d752b6c..c96e4b9 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -357,12 +357,20 @@
 	case BL31_IMAGE_ID:
 		/*
 		 * arg0 is a bl_params_t reserved for bl31_early_platform_setup2
-		 * we just need arg1 and arg3 for BL31 to update th TL from S
+		 * we just need arg1 and arg3 for BL31 to update the TL from S
 		 * to NS memory before it exits
 		 */
-		bl_mem_params->ep_info.args.arg1 =
-			TRANSFER_LIST_SIGNATURE |
-			REGISTER_CONVENTION_VERSION_MASK;
+#ifdef __aarch64__
+		if (GET_RW(bl_mem_params->ep_info.spsr) == MODE_RW_64) {
+			bl_mem_params->ep_info.args.arg1 =
+				TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
+		} else
+#endif
+		{
+			bl_mem_params->ep_info.args.arg1 =
+				TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+		}
+
 		bl_mem_params->ep_info.args.arg3 = (uintptr_t)bl2_tl;
 		break;
 #endif
diff --git a/services/spd/opteed/opteed_main.c b/services/spd/opteed/opteed_main.c
index d6c0040..9e83848 100644
--- a/services/spd/opteed/opteed_main.c
+++ b/services/spd/opteed/opteed_main.c
@@ -552,13 +552,14 @@
 
 		if (opteed_rw == OPTEE_AARCH64) {
 			arg0 = (uint64_t)dt;
+			arg1 = TRANSFER_LIST_HANDOFF_X1_VALUE(REGISTER_CONVENTION_VERSION);
 			arg2 = 0;
 		} else {
-			arg2 = (uint64_t)dt;
 			arg0 = 0;
+			arg1 = TRANSFER_LIST_HANDOFF_R1_VALUE(REGISTER_CONVENTION_VERSION);
+			arg2 = (uint64_t)dt;
 		}
-		arg1 = TRANSFER_LIST_SIGNATURE |
-			REGISTER_CONVENTION_VERSION_MASK;
+
 		arg3 = (uint64_t)bl31_tl;
 	} else {
 		/* Default handoff arguments */