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 */