Extend gpt block store configurator to provide GPT access

To allow block_store clients to base their own configuration on
information in the GPT, this change adds an additional storage
partition to the configuration of the partitioned_block_store
to expose the GPT contained at the head of a UEFI disk image.
This will be exploited for FWU configuration.

Signed-off-by: Julian Hall <julian.hall@arm.com>
Change-Id: I59efc1d091ffa5a050b632c7382ac97320b91d93
diff --git a/components/media/disk/guid.h b/components/media/disk/guid.h
index 10bf916..cf7f836 100644
--- a/components/media/disk/guid.h
+++ b/components/media/disk/guid.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -33,4 +33,7 @@
 #define DISK_GUID_UNIQUE_PARTITION_PSA_PS \
 	"701456da-9b50-49b2-9722-47510f851ccd"
 
+#define DISK_GUID_UNIQUE_PARTITION_DISK_HEADER \
+	"5cb130b7-a138-4d08-b0be-c2d4eff57870"
+
 #endif /* MEDIA_DISK_GUID_H */
diff --git a/components/service/block_storage/block_store/partitioned/partitioned_block_store.c b/components/service/block_storage/block_store/partitioned/partitioned_block_store.c
index 735dead..6b26465 100644
--- a/components/service/block_storage/block_store/partitioned/partitioned_block_store.c
+++ b/components/service/block_storage/block_store/partitioned/partitioned_block_store.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -399,3 +399,9 @@
 
 	return true;
 }
+
+const struct storage_partition_info *partitioned_block_store_get_back_store_info(
+	const struct partitioned_block_store *partitioned_block_store)
+{
+	return &partitioned_block_store->back_store_info;
+}
diff --git a/components/service/block_storage/block_store/partitioned/partitioned_block_store.h b/components/service/block_storage/block_store/partitioned/partitioned_block_store.h
index 091b5fc..35c223c 100644
--- a/components/service/block_storage/block_store/partitioned/partitioned_block_store.h
+++ b/components/service/block_storage/block_store/partitioned/partitioned_block_store.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -132,6 +132,18 @@
 	uint64_t attributes,
 	const char *owner);
 
+/**
+ * \brief Get information about back store
+ *
+ *  Returns information about the underlying block device that is being partitioned
+ *
+ * \param[in]  partitioned_block_store  The subject partitioned_block_store
+ *
+ * \return Pointer to storage_partition_info structure.
+ */
+const struct storage_partition_info *partitioned_block_store_get_back_store_info(
+	const struct partitioned_block_store *partitioned_block_store);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/service/block_storage/config/gpt/gpt_partition_configurator.c b/components/service/block_storage/config/gpt/gpt_partition_configurator.c
index 076c65f..d47cb7e 100644
--- a/components/service/block_storage/config/gpt/gpt_partition_configurator.c
+++ b/components/service/block_storage/config/gpt/gpt_partition_configurator.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -7,6 +7,7 @@
 
 #include <stddef.h>
 #include <common/uuid/uuid.h>
+#include <media/disk/guid.h>
 #include <media/disk/partition_table.h>
 #include "gpt_partition_configurator.h"
 
@@ -47,18 +48,55 @@
 	return is_configured;
 }
 
+static bool add_disk_header_partition(
+	struct partitioned_block_store *subject)
+{
+	/* Adds a partition to make the MBR/GPT readable via a separate partition. This
+	 * enables clients to retrieve information from the GPT for their own configuration
+	 * purposes.
+	 */
+	const struct storage_partition_info *disk_info =
+		partitioned_block_store_get_back_store_info(subject);
+
+	size_t entry_table_size = PLAT_PARTITION_MAX_ENTRIES * sizeof(gpt_entry_t);
+	size_t disk_header_size = GPT_ENTRY_OFFSET + entry_table_size;
+	size_t num_header_blocks =
+		(disk_header_size + disk_info->block_size - 1) / disk_info->block_size;
+
+	if (num_header_blocks > 0 && num_header_blocks <= disk_info->num_blocks) {
+
+		struct uuid_octets partition_guid;
+
+		uuid_guid_octets_from_canonical(&partition_guid,
+			DISK_GUID_UNIQUE_PARTITION_DISK_HEADER);
+
+		uint32_t starting_lba = 0;
+		uint32_t ending_lba = starting_lba + num_header_blocks - 1;
+
+		return partitioned_block_store_add_partition(
+			subject, &partition_guid,
+			starting_lba, ending_lba,
+			0, NULL);
+	}
+
+	return false;
+}
+
 bool gpt_partition_configure(
 	struct partitioned_block_store *subject,
 	unsigned int volume_id)
 {
+	bool success = false;
 	int result = load_partition_table(volume_id);
 
-	if (result == 0) {
+	if ((result == 0) && add_disk_header_partition(subject)) {
 
 		partitioned_block_store_attach_config_listener(
 			subject,
 			gpt_partition_config_listener);
+
+		success = true;
 	}
 
-	return result == 0;
+	return success;
 }