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