Add FF-A v1.1 boot protocol

Implement parsing of the FF-A v1.1 boot protocol. The patch is backwards
compatible since the used boot protocol version can be identified by the
signature field.

Signed-off-by: Balint Dobszay <balint.dobszay@arm.com>
Change-Id: I831d69aadd6bf40f9931bf695e173f1870bf8900
diff --git a/components/config/loader/sp/sp_config_loader.c b/components/config/loader/sp/sp_config_loader.c
index 6aaff4b..5c7c552 100644
--- a/components/config/loader/sp/sp_config_loader.c
+++ b/components/config/loader/sp/sp_config_loader.c
@@ -295,6 +295,55 @@
 	return true;
 }
 
+static bool sp_config_load_v1_1(struct ffa_boot_info_header_v1_1 *boot_info_header)
+{
+	size_t desc_end = 0;
+	size_t total_desc_size = 0;
+	struct ffa_boot_info_desc_v1_1 *boot_info_desc = NULL;
+	uint32_t expected_version = SHIFT_U32(1, FFA_VERSION_MAJOR_SHIFT) |
+				    SHIFT_U32(1, FFA_VERSION_MINOR_SHIFT);
+
+	if (boot_info_header->version != expected_version) {
+		EMSG("Invalid FF-A boot info version");
+		return false;
+	}
+
+	if (boot_info_header->desc_size != sizeof(struct ffa_boot_info_desc_v1_1)) {
+		EMSG("Boot info descriptor size mismatch");
+		return false;
+	}
+
+	if (MUL_OVERFLOW(boot_info_header->desc_size, boot_info_header->desc_cnt,
+			 &total_desc_size)) {
+		EMSG("Boot info descriptor overflow");
+		return false;
+	}
+
+	if (ADD_OVERFLOW(boot_info_header->desc_offs, total_desc_size, &desc_end) ||
+	    boot_info_header->size < desc_end) {
+		EMSG("Boot info descriptor overflow");
+		return false;
+	}
+
+	boot_info_desc = (struct ffa_boot_info_desc_v1_1 *)((uintptr_t)boot_info_header +
+							    boot_info_header->desc_offs);
+
+	for (unsigned int i = 0; i < boot_info_header->desc_cnt; i++) {
+		uint16_t flags = FFA_BOOT_INFO_CONTENT_FMT_ADDR << FFA_BOOT_INFO_CONTENT_FMT_SHIFT;
+		uint16_t type = FFA_BOOT_INFO_TYPE_STD << FFA_BOOT_INFO_TYPE_SHIFT |
+				FFA_BOOT_INFO_ID_STD_FDT << FFA_BOOT_INFO_ID_SHIFT;
+
+		if (boot_info_desc[i].flags == flags && boot_info_desc[i].type == type) {
+			if (!load_fdt((void *)boot_info_desc->contents, boot_info_desc->size)) {
+				EMSG("Failed to load SP config FDT");
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
 bool sp_config_load(union ffa_boot_info *boot_info)
 {
 	if (!boot_info)
@@ -303,6 +352,9 @@
 	switch (boot_info->signature) {
 	case FFA_BOOT_INFO_SIGNATURE_V1_0:
 		return sp_config_load_v1_0((struct ffa_boot_info_v1_0 *)&boot_info->boot_info_v1_0);
+	case FFA_BOOT_INFO_SIGNATURE_V1_1:
+		return sp_config_load_v1_1((struct ffa_boot_info_header_v1_1 *)
+					   &boot_info->boot_info_v1_1);
 	default:
 		EMSG("Invalid FF-A boot info signature");
 		return false;
diff --git a/components/messaging/ffa/libsp/include/ffa_api_defines.h b/components/messaging/ffa/libsp/include/ffa_api_defines.h
index 03b1198..17a5eda 100644
--- a/components/messaging/ffa/libsp/include/ffa_api_defines.h
+++ b/components/messaging/ffa/libsp/include/ffa_api_defines.h
@@ -68,6 +68,34 @@
 
 /* Boot information signature */
 #define FFA_BOOT_INFO_SIGNATURE_V1_0	UINT32_C(0x412D4646) /* FF-A ASCII */
+#define FFA_BOOT_INFO_SIGNATURE_V1_1	UINT32_C(0x0FFA)
+
+/* Boot information type */
+#define FFA_BOOT_INFO_TYPE_SHIFT	UINT32_C(7)
+#define FFA_BOOT_INFO_TYPE_MASK		UINT32_C(1)
+
+#define FFA_BOOT_INFO_TYPE_STD		UINT32_C(0)
+#define FFA_BOOT_INFO_TYPE_IMPDEF	UINT32_C(1)
+
+/* Boot information ID */
+#define FFA_BOOT_INFO_ID_SHIFT		UINT32_C(0)
+#define FFA_BOOT_INFO_ID_MASK		GENMASK_32(6, 0)
+
+#define FFA_BOOT_INFO_ID_STD_FDT	UINT32_C(0)
+#define FFA_BOOT_INFO_ID_STD_HOB	UINT32_C(1)
+
+/* Boot information flags */
+#define FFA_BOOT_INFO_CONTENT_FMT_SHIFT	UINT32_C(2)
+#define FFA_BOOT_INFO_CONTENT_FMT_MASK	GENMASK_32(1, 0)
+
+#define FFA_BOOT_INFO_CONTENT_FMT_ADDR	UINT32_C(0)
+#define FFA_BOOT_INFO_CONTENT_FMT_VAL	UINT32_C(1)
+
+#define FFA_BOOT_INFO_NAME_FMT_SHIFT	UINT32_C(0)
+#define FFA_BOOT_INFO_NAME_FMT_MASK	GENMASK_32(1, 0)
+
+#define FFA_BOOT_INFO_NAME_FMT_STR	UINT32_C(0)
+#define FFA_BOOT_INFO_NAME_FMT_UUID	UINT32_C(1)
 
 /* FFA_VERSION */
 #define FFA_VERSION_MAJOR		UINT32_C(1)
diff --git a/components/messaging/ffa/libsp/include/ffa_api_types.h b/components/messaging/ffa/libsp/include/ffa_api_types.h
index 8333488..7156c02 100644
--- a/components/messaging/ffa/libsp/include/ffa_api_types.h
+++ b/components/messaging/ffa/libsp/include/ffa_api_types.h
@@ -32,9 +32,33 @@
 	struct ffa_name_value_pair_v1_0 nvp[]; /**< Array of name value size pairs */
 };
 
+struct ffa_boot_info_desc_v1_1 {
+	uint8_t name[16]; /**< Name of boot information passed to the consumer */
+	uint8_t type; /**< Type of boot information passed to the consumer */
+	uint8_t reserved_mbz; /**< Reserved (MBZ) */;
+	uint16_t flags; /**< Flags to describe properties of boot information in this descriptor */
+	uint32_t size; /**< Size (in bytes) of boot info identified by Name and Type fields */
+	uint64_t contents; /**< Value or address of boot info identified by Name and Type fields. */
+} __packed;
+
+/**
+ * @brief Structure for passing boot protocol data (FF-A v1.1)
+ */
+struct ffa_boot_info_header_v1_1 {
+	uint32_t signature; /**< 0x0ffa */
+	uint32_t version; /**< FF-A version: bit[31]: MBZ, bit[30:16] major version number,
+				bit[15:0]  minor version number */
+	uint32_t size; /**< Size of boot information blob spanning contiguous memory */
+	uint32_t desc_size; /**< Size of each boot information descriptor in the array */
+	uint32_t desc_cnt; /**< Count of boot information descriptors in the array */
+	uint32_t desc_offs; /**< Offset to array of boot information descriptors */
+	uint64_t reserved_mbz; /**< Reserved (MBZ) */
+} __packed;
+
 union ffa_boot_info {
 	uint32_t signature;
 	struct ffa_boot_info_v1_0 boot_info_v1_0;
+	struct ffa_boot_info_header_v1_1 boot_info_v1_1;
 };
 
 /**