PSA FF-A: add partition manifest parsing

Add PSA FF-A partition manifest structure to VM manifest. Add FF-A
partition package structure (comprises header + image dtb + image
payload). Parse FF-A partition manifest DT if requested by the
is_ffa_partition DTS boolean.

This assumes Hafnium entry point is directly fed with the hypervisor
manifest pointer address (rather than the initrd image).

For a regular VM, the entry point is the start address of the VM
workspace allocated by Hafnium from the mem ranges provided in
hypervisor manifest. If the VM is an FF-A compliant partition,
the VM entry point is extrapolated from the FF-A partition manifest
(start of the workspace as SP header load address plus entry point
offset from partition DTS).

Change-Id: I6947646d0cd6eb3c4d97a31aa589244b365c8486
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Signed-off-by: Louis Mayencourt <louis.mayencourt@arm.com>
diff --git a/inc/hf/manifest.h b/inc/hf/manifest.h
index ab3a92f..9286202 100644
--- a/inc/hf/manifest.h
+++ b/inc/hf/manifest.h
@@ -16,6 +16,7 @@
 
 #pragma once
 
+#include "hf/addr.h"
 #include "hf/ffa.h"
 #include "hf/memiter.h"
 #include "hf/string.h"
@@ -23,6 +24,103 @@
 
 #define MANIFEST_INVALID_ADDRESS UINT64_MAX
 
+#define SP_PKG_HEADER_MAGIC (0x474b5053)
+#define SP_PKG_HEADER_VERSION (0x1)
+
+#define SP_RTX_BUF_NAME_SIZE 10
+
+enum run_time_el {
+	EL1 = 0,
+	S_EL0,
+	S_EL1,
+	SUPERVISOR_MODE,
+	SECURE_USER_MODE,
+	SECURE_SUPERVISOR_MODE
+};
+
+enum execution_state { AARCH64 = 0, AARCH32 };
+
+enum xlat_granule { PAGE_4KB = 0, PAGE_16KB, PAGE_64KB };
+
+enum messaging_method {
+	DIRECT_MESSAGING = 0,
+	INDIRECT_MESSAGING,
+	BOTH_MESSAGING
+};
+
+/**
+ * Partition manifest as described in PSA FF-A v1.0 spec section 3.1
+ */
+struct sp_manifest {
+	/** PSA-FF-A expected version - mandatory */
+	uint32_t ffa_version;
+	/** UUID - mandatory */
+	uint32_t uuid[4];
+	/** Partition id - optional */
+	ffa_vm_id_t id;
+	/** Aux ids for mem transactions - optional */
+	ffa_vm_id_t aux_id;
+
+	/* NOTE: optional name field maps to VM debug_name field */
+
+	/** mandatory */
+	ffa_vcpu_count_t execution_ctx_count;
+	/** EL1 or secure EL1, secure EL0 - mandatory */
+	enum run_time_el run_time_el;
+	/** AArch32 / AArch64 - mandatory */
+	enum execution_state execution_state;
+	/** optional */
+	uintpaddr_t load_addr;
+	/** optional */
+	size_t ep_offset;
+	/**  4/16/64KB - mandatory */
+	enum xlat_granule xlat_granule;
+	/** optional */
+	uint16_t boot_order;
+
+	/** Optional RX/TX buffers */
+	struct {
+		bool rxtx_found;
+		/** optional */
+		uint64_t base_address;
+		/** optional */
+		uint16_t pages_count;
+		/** mandatory */
+		uint16_t attributes;
+		/** Optional */
+		char name[SP_RTX_BUF_NAME_SIZE];
+	} rxtx;
+
+	/** mandatory - direct/indirect msg or both */
+	enum messaging_method messaging_method;
+	/** optional */
+	bool has_primary_scheduler;
+	/** optional - preemptible / run to completion */
+	uint8_t runtime_model;
+	/** optional */
+	bool time_slice_mem;
+	/** optional - tuples SEPID/SMMUID/streamId */
+	uint32_t stream_ep_ids[1];
+};
+
+/**
+ *  Header for a PSA FF-A partition package.
+ */
+struct sp_pkg_header {
+	/** Magic used to identify a SP package. Value is "SPKG" */
+	uint32_t magic;
+	/** Version number of the header */
+	uint32_t version;
+	/** Offset in bytes to the partition manifest */
+	uint32_t pm_offset;
+	/** Size in bytes of the partition manifest */
+	uint32_t pm_size;
+	/** Offset in bytes to the base address of the partition binary */
+	uint32_t img_offset;
+	/** Size in bytes of the partition binary */
+	uint32_t img_size;
+};
+
 /**
  * Holds information about one of the VMs described in the manifest.
  */
@@ -31,6 +129,8 @@
 	struct string debug_name;
 	struct string kernel_filename;
 	struct smc_whitelist smc_whitelist;
+	bool is_ffa_partition;
+	struct sp_manifest sp;
 
 	union {
 		/* Properties specific to the primary VM. */
@@ -58,6 +158,7 @@
 enum manifest_return_code {
 	MANIFEST_SUCCESS = 0,
 	MANIFEST_ERROR_FILE_SIZE,
+	MANIFEST_ERROR_MALFORMED_DTB,
 	MANIFEST_ERROR_NO_ROOT_NODE,
 	MANIFEST_ERROR_NO_HYPERVISOR_FDT_NODE,
 	MANIFEST_ERROR_NOT_COMPATIBLE,
@@ -73,7 +174,11 @@
 	MANIFEST_ERROR_MALFORMED_BOOLEAN,
 };
 
-enum manifest_return_code manifest_init(struct manifest *manifest,
-					struct memiter *manifest_fdt);
+enum manifest_return_code manifest_init(struct mm_stage1_locked stage1_locked,
+					struct manifest *manifest,
+					struct memiter *manifest_fdt,
+					struct mpool *ppool);
+
+void manifest_dump(struct manifest_vm *vm);
 
 const char *manifest_strerror(enum manifest_return_code ret_code);