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);