aboutsummaryrefslogtreecommitdiff
path: root/inc/hf/manifest.h
blob: 88f3b6e8ff3612d618cc0a4c524e7f0584a63a8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
 * Copyright 2019 The Hafnium Authors.
 *
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file or at
 * https://opensource.org/licenses/BSD-3-Clause.
 */

#pragma once

#include "hf/addr.h"
#include "hf/ffa.h"
#include "hf/memiter.h"
#include "hf/string.h"
#include "hf/vm.h"

#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 */
	struct ffa_uuid uuid;
	/** 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.
 */
struct manifest_vm {
	/* Properties defined for both primary and secondary VMs. */
	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. */
		struct {
			uint64_t boot_address;
			struct string ramdisk_filename;
		} primary;
		/* Properties specific to secondary VMs. */
		struct {
			uint64_t mem_size;
			ffa_vcpu_count_t vcpu_count;
			struct string fdt_filename;
		} secondary;
	};
};

/**
 * Hafnium manifest parsed from FDT.
 */
struct manifest {
	bool ffa_tee_enabled;
	ffa_vm_count_t vm_count;
	struct manifest_vm vm[MAX_VMS];
};

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,
	MANIFEST_ERROR_RESERVED_VM_ID,
	MANIFEST_ERROR_NO_PRIMARY_VM,
	MANIFEST_ERROR_TOO_MANY_VMS,
	MANIFEST_ERROR_PROPERTY_NOT_FOUND,
	MANIFEST_ERROR_MALFORMED_STRING,
	MANIFEST_ERROR_STRING_TOO_LONG,
	MANIFEST_ERROR_MALFORMED_INTEGER,
	MANIFEST_ERROR_INTEGER_OVERFLOW,
	MANIFEST_ERROR_MALFORMED_INTEGER_LIST,
	MANIFEST_ERROR_MALFORMED_BOOLEAN,
};

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