blob: 6d07c41b0e4deb039f0a420dab8dd29a72150df6 [file] [log] [blame]
David Brazdil7a462ec2019-08-15 12:27:47 +01001/*
2 * Copyright 2019 The Hafnium Authors.
3 *
Andrew Walbrane959ec12020-06-17 15:01:09 +01004 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/BSD-3-Clause.
David Brazdil7a462ec2019-08-15 12:27:47 +01007 */
8
David Brazdil52256ff2019-08-23 15:15:15 +01009#include <array>
10#include <cstdio>
Andrew Scullae9962e2019-10-03 16:51:16 +010011#include <span>
David Brazdil52256ff2019-08-23 15:15:15 +010012#include <sstream>
13
David Brazdil7a462ec2019-08-15 12:27:47 +010014#include <gmock/gmock.h>
15
16extern "C" {
J-Alves2f86c1e2022-02-23 18:44:19 +000017#include "hf/arch/std.h"
18
J-Alves77b6f4f2023-03-15 11:34:49 +000019#include "hf/boot_params.h"
David Brazdil7a462ec2019-08-15 12:27:47 +010020#include "hf/manifest.h"
J-Alves2f86c1e2022-02-23 18:44:19 +000021#include "hf/sp_pkg.h"
David Brazdil7a462ec2019-08-15 12:27:47 +010022}
23
24namespace
25{
Andrew Scullae9962e2019-10-03 16:51:16 +010026using ::testing::ElementsAre;
David Brazdil7a462ec2019-08-15 12:27:47 +010027using ::testing::Eq;
Andrew Scullae9962e2019-10-03 16:51:16 +010028using ::testing::IsEmpty;
David Brazdil7a462ec2019-08-15 12:27:47 +010029using ::testing::NotNull;
30
Daniel Boulby801f8ef2022-06-27 14:21:01 +010031using struct_manifest = struct manifest;
32
J-Alves5c0ae6f2023-06-14 15:20:21 +010033constexpr size_t TEST_HEAP_SIZE = PAGE_SIZE * 128;
Daniel Boulby801f8ef2022-06-27 14:21:01 +010034
David Brazdil52256ff2019-08-23 15:15:15 +010035template <typename T>
David Brazdil0dbb41f2019-09-09 18:03:35 +010036void exec(const char *program, const char *args[], const T &stdin,
David Brazdil52256ff2019-08-23 15:15:15 +010037 std::vector<char> *stdout)
38{
39 /* Create two pipes, one for stdin and one for stdout. */
40 int pipes[2][2];
41 pipe(pipes[0]);
42 pipe(pipes[1]);
David Brazdil7a462ec2019-08-15 12:27:47 +010043
David Brazdil52256ff2019-08-23 15:15:15 +010044 /* Assign FDs for reading/writing by the parent/child. */
45 int parent_read_fd = pipes[1][0]; /* stdout pipe, read FD */
46 int parent_write_fd = pipes[0][1]; /* stdin pipe, write FD */
47 int child_read_fd = pipes[0][0]; /* stdin pipe, read FD */
48 int child_write_fd = pipes[1][1]; /* stdout pipe, write FD */
David Brazdil7a462ec2019-08-15 12:27:47 +010049
David Brazdil52256ff2019-08-23 15:15:15 +010050 if (fork()) {
51 /* Parent process. */
52 std::array<char, 128> buf;
53 ssize_t res;
54
55 /* Close child FDs which won't be used. */
56 close(child_read_fd);
57 close(child_write_fd);
58
59 /* Write to stdin. */
60 for (size_t count = 0; count < stdin.size();) {
61 res = write(parent_write_fd, stdin.data() + count,
62 stdin.size() - count);
63 if (res < 0) {
64 std::cerr << "IO error" << std::endl;
65 exit(1);
66 }
67 count += res;
68 }
69 close(parent_write_fd);
70
71 /* Read from stdout. */
72 while (true) {
73 res = read(parent_read_fd, buf.data(), buf.size());
74 if (res == 0) {
75 /* EOF */
76 break;
77 } else if (res < 0) {
78 std::cerr << "IO error" << std::endl;
79 exit(1);
80 }
81 stdout->insert(stdout->end(), buf.begin(),
82 buf.begin() + res);
83 }
84 close(parent_read_fd);
85 } else {
86 /* Child process. */
87
88 /* Redirect stdin/stdout to read/write FDs. */
89 dup2(child_read_fd, STDIN_FILENO);
90 dup2(child_write_fd, STDOUT_FILENO);
91
92 /* Close all FDs which are now unused. */
93 close(child_read_fd);
94 close(child_write_fd);
95 close(parent_read_fd);
96 close(parent_write_fd);
97
98 /* Execute the given program. */
David Brazdil0dbb41f2019-09-09 18:03:35 +010099 execv(program, const_cast<char *const *>(args));
David Brazdil52256ff2019-08-23 15:15:15 +0100100 }
101}
102
103/**
104 * Class for programatically building a Device Tree.
105 *
106 * Usage:
107 * std::vector<char> dtb = ManifestDtBuilder()
108 * .Command1()
109 * .Command2()
110 * ...
111 * .CommandN()
112 * .Build();
113 */
114class ManifestDtBuilder
115{
116 public:
117 ManifestDtBuilder()
118 {
119 dts_ << "/dts-v1/;" << std::endl;
120 dts_ << std::endl;
121
122 /* Start root node. */
123 StartChild("/");
124 }
125
Andrew Scullae9962e2019-10-03 16:51:16 +0100126 std::vector<char> Build(bool dump = false)
David Brazdil52256ff2019-08-23 15:15:15 +0100127 {
David Brazdil0dbb41f2019-09-09 18:03:35 +0100128 const char *program = "./build/image/dtc.py";
129 const char *dtc_args[] = {program, "compile", NULL};
David Brazdil52256ff2019-08-23 15:15:15 +0100130 std::vector<char> dtc_stdout;
131
132 /* Finish root node. */
133 EndChild();
134
Andrew Scullae9962e2019-10-03 16:51:16 +0100135 if (dump) {
136 Dump();
137 }
138
David Brazdil0dbb41f2019-09-09 18:03:35 +0100139 exec(program, dtc_args, dts_.str(), &dtc_stdout);
David Brazdil52256ff2019-08-23 15:15:15 +0100140 return dtc_stdout;
141 }
142
Andrew Scullae9962e2019-10-03 16:51:16 +0100143 void Dump()
144 {
145 std::cerr << dts_.str() << std::endl;
146 }
147
David Brazdil52256ff2019-08-23 15:15:15 +0100148 ManifestDtBuilder &StartChild(const std::string_view &name)
149 {
150 dts_ << name << " {" << std::endl;
151 return *this;
152 }
153
154 ManifestDtBuilder &EndChild()
155 {
156 dts_ << "};" << std::endl;
157 return *this;
158 }
159
David Brazdil74e9c3b2019-08-28 11:09:08 +0100160 ManifestDtBuilder &Compatible(const std::vector<std::string_view>
161 &value = {"hafnium,hafnium"})
162 {
163 return StringListProperty("compatible", value);
164 }
165
David Brazdil52256ff2019-08-23 15:15:15 +0100166 ManifestDtBuilder &DebugName(const std::string_view &value)
167 {
168 return StringProperty("debug_name", value);
169 }
170
Manish Pandey6542f5c2020-04-27 14:37:46 +0100171 ManifestDtBuilder &Description(const std::string_view &value)
172 {
173 return StringProperty("description", value);
174 }
175
David Brazdil52256ff2019-08-23 15:15:15 +0100176 ManifestDtBuilder &KernelFilename(const std::string_view &value)
177 {
178 return StringProperty("kernel_filename", value);
179 }
180
David Brazdile6f83222019-09-23 14:47:37 +0100181 ManifestDtBuilder &RamdiskFilename(const std::string_view &value)
182 {
183 return StringProperty("ramdisk_filename", value);
184 }
185
David Brazdil080ee312020-02-25 15:30:30 -0800186 ManifestDtBuilder &BootAddress(uint64_t value)
187 {
188 return Integer64Property("boot_address", value);
189 }
190
Andrew Scullae9962e2019-10-03 16:51:16 +0100191 ManifestDtBuilder &VcpuCount(uint32_t value)
David Brazdil52256ff2019-08-23 15:15:15 +0100192 {
193 return IntegerProperty("vcpu_count", value);
194 }
195
Andrew Scullae9962e2019-10-03 16:51:16 +0100196 ManifestDtBuilder &MemSize(uint32_t value)
David Brazdil52256ff2019-08-23 15:15:15 +0100197 {
198 return IntegerProperty("mem_size", value);
199 }
200
Andrew Scullae9962e2019-10-03 16:51:16 +0100201 ManifestDtBuilder &SmcWhitelist(const std::vector<uint32_t> &value)
202 {
203 return IntegerListProperty("smc_whitelist", value);
204 }
205
206 ManifestDtBuilder &SmcWhitelistPermissive()
207 {
208 return BooleanProperty("smc_whitelist_permissive");
209 }
210
Olivier Deprez62d99e32020-01-09 15:58:07 +0100211 ManifestDtBuilder &LoadAddress(uint64_t value)
212 {
213 return Integer64Property("load_address", value);
214 }
215
216 ManifestDtBuilder &FfaPartition()
217 {
218 return BooleanProperty("is_ffa_partition");
219 }
220
Andrew Scullae9962e2019-10-03 16:51:16 +0100221 ManifestDtBuilder &Property(const std::string_view &name,
222 const std::string_view &value)
223 {
224 dts_ << name << " = " << value << ";" << std::endl;
225 return *this;
226 }
227
Manish Pandeyfa1f2912020-05-05 12:57:01 +0100228 ManifestDtBuilder &Label(const std::string_view &name)
229 {
230 dts_ << name << ": ";
231 return *this;
232 }
233
Manish Pandeycb8fbb22020-08-18 00:04:43 +0100234 ManifestDtBuilder &FfaValidManifest()
235 {
236 Compatible({"arm,ffa-manifest-1.0"});
237 Property("ffa-version", "<0x10000>");
238 Property("uuid",
239 "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>");
240 Property("execution-ctx-count", "<1>");
241 Property("exception-level", "<2>");
242 Property("execution-state", "<0>");
J-Alves2f86c1e2022-02-23 18:44:19 +0000243 Property("entrypoint-offset", "<0x00002000>");
Manish Pandeycb8fbb22020-08-18 00:04:43 +0100244 Property("xlat-granule", "<0>");
J-Alvesb37fd082020-10-22 12:29:21 +0100245 Property("boot-order", "<0>");
Kathleen Capellaf71dee42023-08-08 16:24:14 -0400246 Property("messaging-method", "<0x4>");
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500247 Property("ns-interrupts-action", "<1>");
Manish Pandeycb8fbb22020-08-18 00:04:43 +0100248 return *this;
249 }
250
Kathleen Capella4a2a6e72023-04-21 14:43:26 -0400251 ManifestDtBuilder &FfaLoadAddress(uint64_t value)
252 {
253 Integer64Property("load-address", value);
254 return *this;
255 }
256
David Brazdil52256ff2019-08-23 15:15:15 +0100257 private:
258 ManifestDtBuilder &StringProperty(const std::string_view &name,
259 const std::string_view &value)
260 {
261 dts_ << name << " = \"" << value << "\";" << std::endl;
262 return *this;
263 }
264
David Brazdil74e9c3b2019-08-28 11:09:08 +0100265 ManifestDtBuilder &StringListProperty(
266 const std::string_view &name,
267 const std::vector<std::string_view> &value)
268 {
269 bool is_first = true;
270
271 dts_ << name << " = ";
272 for (const std::string_view &entry : value) {
273 if (is_first) {
274 is_first = false;
275 } else {
276 dts_ << ", ";
277 }
278 dts_ << "\"" << entry << "\"";
279 }
280 dts_ << ";" << std::endl;
281 return *this;
282 }
283
David Brazdil52256ff2019-08-23 15:15:15 +0100284 ManifestDtBuilder &IntegerProperty(const std::string_view &name,
Andrew Scullae9962e2019-10-03 16:51:16 +0100285 uint32_t value)
David Brazdil52256ff2019-08-23 15:15:15 +0100286 {
287 dts_ << name << " = <" << value << ">;" << std::endl;
288 return *this;
289 }
290
David Brazdil080ee312020-02-25 15:30:30 -0800291 ManifestDtBuilder &Integer64Property(const std::string_view &name,
292 uint64_t value)
293 {
294 uint32_t high = value >> 32;
295 uint32_t low = (uint32_t)value;
296 dts_ << name << " = <" << high << " " << low << ">;"
297 << std::endl;
298 return *this;
299 }
300
Andrew Scullae9962e2019-10-03 16:51:16 +0100301 ManifestDtBuilder &IntegerListProperty(
302 const std::string_view &name,
303 const std::vector<uint32_t> &value)
304 {
305 dts_ << name << " = < ";
306 for (const uint32_t entry : value) {
307 dts_ << entry << " ";
308 }
309 dts_ << ">;" << std::endl;
310 return *this;
311 }
312
313 ManifestDtBuilder &BooleanProperty(const std::string_view &name)
314 {
Andrew Scull5dc089e2019-11-04 13:21:03 +0000315 dts_ << name << ";" << std::endl;
316 return *this;
Andrew Scullae9962e2019-10-03 16:51:16 +0100317 }
318
David Brazdil52256ff2019-08-23 15:15:15 +0100319 std::stringstream dts_;
320};
321
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100322class manifest : public ::testing::Test
David Brazdil0dbb41f2019-09-09 18:03:35 +0100323{
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100324 void SetUp() override
325 {
326 test_heap = std::make_unique<uint8_t[]>(TEST_HEAP_SIZE);
327 mpool_init(&ppool, MM_PPOOL_ENTRY_SIZE);
328 mpool_add_chunk(&ppool, test_heap.get(), TEST_HEAP_SIZE);
329 }
330
Olivier Deprez93644652022-09-09 11:01:12 +0200331 void TearDown() override
332 {
333 manifest_dealloc();
334 }
335
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100336 std::unique_ptr<uint8_t[]> test_heap;
337
338 protected:
Olivier Deprez62d99e32020-01-09 15:58:07 +0100339 struct mpool ppool;
David Brazdil0dbb41f2019-09-09 18:03:35 +0100340
Olivier Deprez93644652022-09-09 11:01:12 +0200341 void manifest_dealloc(void)
342 {
343 manifest_deinit(&ppool);
344 }
345
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100346 public:
347 /**
348 * Class for programatically building a Partition package.
349 */
350 class Partition_package
351 {
352 public:
353 __attribute__((aligned(PAGE_SIZE))) struct sp_pkg_header spkg;
354 __attribute__((
355 aligned(PAGE_SIZE))) char manifest_dtb[PAGE_SIZE] = {};
356 __attribute__((aligned(PAGE_SIZE))) char img[PAGE_SIZE] = {};
David Brazdil0dbb41f2019-09-09 18:03:35 +0100357
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100358 Partition_package(const std::vector<char> &vec)
359 {
Kathleen Capella4a2a6e72023-04-21 14:43:26 -0400360 init(vec);
361 }
362
363 Partition_package()
364 {
365 }
366
367 void init(const std::vector<char> &vec)
368 {
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100369 // Initialise header field
370 spkg.magic = SP_PKG_HEADER_MAGIC;
371 spkg.version = SP_PKG_HEADER_VERSION_2;
372 spkg.pm_offset = PAGE_SIZE;
373 spkg.pm_size = vec.size();
374 spkg.img_offset = 2 * PAGE_SIZE;
375 spkg.img_size = ARRAY_SIZE(img);
376
377 // Copy dtb into package
378 std::copy(vec.begin(), vec.end(), manifest_dtb);
379 }
380 };
381
J-Alves77b6f4f2023-03-15 11:34:49 +0000382 static void boot_params_init(struct boot_params *params,
383 Partition_package *pkg)
384 {
385 /*
386 * For the manifest tests we only care about the memory ranges
387 * in boot_params.
388 */
389 params->mem_ranges[0].begin = pa_init((uintpaddr_t)0x7000000);
390 params->mem_ranges[0].end = pa_init((uintpaddr_t)0x8ffffff);
391 params->mem_ranges_count = 1;
392
393 if (pkg != nullptr) {
394 auto mem_base = (uintpaddr_t)pkg;
395 uintpaddr_t mem_end =
396 mem_base + sp_pkg_get_mem_size(&pkg->spkg);
397
398 params->mem_ranges_count++;
399
400 params->mem_ranges[1].begin = pa_init(mem_base);
401 params->mem_ranges[1].end = pa_init(mem_end);
402 }
403
404 params->ns_mem_ranges[0].begin =
405 pa_init((uintpaddr_t)0x7000000);
406 params->ns_mem_ranges[0].end = pa_init((uintpaddr_t)0x8ffffff);
407 params->ns_mem_ranges_count = 1;
408 }
409
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100410 enum manifest_return_code manifest_from_vec(
Olivier Deprez93644652022-09-09 11:01:12 +0200411 struct_manifest **m, const std::vector<char> &vec)
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100412 {
413 struct memiter it;
414 struct mm_stage1_locked mm_stage1_locked;
J-Alves77b6f4f2023-03-15 11:34:49 +0000415 struct boot_params params;
416
417 boot_params_init(&params, nullptr);
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100418
419 memiter_init(&it, vec.data(), vec.size());
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100420
J-Alves77b6f4f2023-03-15 11:34:49 +0000421 return manifest_init(mm_stage1_locked, m, &it, &params, &ppool);
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100422 }
423
424 enum manifest_return_code ffa_manifest_from_vec(
Olivier Deprez93644652022-09-09 11:01:12 +0200425 struct_manifest **m, const std::vector<char> &vec)
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100426 {
427 struct memiter it;
428 struct mm_stage1_locked mm_stage1_locked;
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100429 Partition_package spkg(vec);
J-Alves77b6f4f2023-03-15 11:34:49 +0000430 struct boot_params params;
431
432 boot_params_init(&params, &spkg);
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100433
434 /* clang-format off */
435 std::vector<char> core_dtb = ManifestDtBuilder()
436 .StartChild("hypervisor")
437 .Compatible()
438 .StartChild("vm1")
439 .DebugName("primary_vm")
440 .FfaPartition()
441 .LoadAddress((uint64_t)&spkg)
442 .EndChild()
443 .EndChild()
444 .Build();
445 /* clang-format on */
446 memiter_init(&it, core_dtb.data(), core_dtb.size());
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100447
J-Alves77b6f4f2023-03-15 11:34:49 +0000448 return manifest_init(mm_stage1_locked, m, &it, &params, &ppool);
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100449 }
450};
451
452TEST_F(manifest, no_hypervisor_node)
David Brazdil7a462ec2019-08-15 12:27:47 +0100453{
Olivier Deprez93644652022-09-09 11:01:12 +0200454 struct_manifest *m;
David Brazdil52256ff2019-08-23 15:15:15 +0100455 std::vector<char> dtb = ManifestDtBuilder().Build();
David Brazdil7a462ec2019-08-15 12:27:47 +0100456
David Brazdila2358d42020-01-27 18:51:38 +0000457 ASSERT_EQ(manifest_from_vec(&m, dtb),
David Brazdil7a462ec2019-08-15 12:27:47 +0100458 MANIFEST_ERROR_NO_HYPERVISOR_FDT_NODE);
459}
460
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100461TEST_F(manifest, no_compatible_property)
David Brazdil7a462ec2019-08-15 12:27:47 +0100462{
Olivier Deprez93644652022-09-09 11:01:12 +0200463 struct_manifest *m;
David Brazdil7a462ec2019-08-15 12:27:47 +0100464
David Brazdil52256ff2019-08-23 15:15:15 +0100465 /* clang-format off */
466 std::vector<char> dtb = ManifestDtBuilder()
467 .StartChild("hypervisor")
468 .EndChild()
469 .Build();
470 /* clang-format on */
471
David Brazdilf4925382020-03-25 13:33:51 +0000472 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_ERROR_NOT_COMPATIBLE);
David Brazdil7a462ec2019-08-15 12:27:47 +0100473}
474
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100475TEST_F(manifest, not_compatible)
David Brazdil7a462ec2019-08-15 12:27:47 +0100476{
Olivier Deprez93644652022-09-09 11:01:12 +0200477 struct_manifest *m;
David Brazdil7a462ec2019-08-15 12:27:47 +0100478
David Brazdil52256ff2019-08-23 15:15:15 +0100479 /* clang-format off */
480 std::vector<char> dtb = ManifestDtBuilder()
481 .StartChild("hypervisor")
David Brazdil74e9c3b2019-08-28 11:09:08 +0100482 .Compatible({ "foo,bar" })
483 .EndChild()
484 .Build();
485 /* clang-format on */
486
David Brazdila2358d42020-01-27 18:51:38 +0000487 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_ERROR_NOT_COMPATIBLE);
David Brazdil74e9c3b2019-08-28 11:09:08 +0100488}
489
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100490TEST_F(manifest, compatible_one_of_many)
David Brazdil74e9c3b2019-08-28 11:09:08 +0100491{
Olivier Deprez93644652022-09-09 11:01:12 +0200492 struct_manifest *m;
David Brazdil74e9c3b2019-08-28 11:09:08 +0100493
494 /* clang-format off */
495 std::vector<char> dtb = ManifestDtBuilder()
496 .StartChild("hypervisor")
497 .Compatible({ "foo,bar", "hafnium,hafnium" })
498 .StartChild("vm1")
499 .DebugName("primary")
500 .EndChild()
501 .EndChild()
502 .Build();
503 /* clang-format on */
504
David Brazdila2358d42020-01-27 18:51:38 +0000505 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
David Brazdil74e9c3b2019-08-28 11:09:08 +0100506}
507
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100508TEST_F(manifest, no_vm_nodes)
David Brazdil74e9c3b2019-08-28 11:09:08 +0100509{
Olivier Deprez93644652022-09-09 11:01:12 +0200510 struct_manifest *m;
David Brazdil74e9c3b2019-08-28 11:09:08 +0100511
512 /* clang-format off */
513 std::vector<char> dtb = ManifestDtBuilder()
514 .StartChild("hypervisor")
515 .Compatible()
516 .EndChild()
517 .Build();
518 /* clang-format on */
519
David Brazdila2358d42020-01-27 18:51:38 +0000520 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_ERROR_NO_PRIMARY_VM);
David Brazdil0dbb41f2019-09-09 18:03:35 +0100521}
522
523static std::vector<char> gen_long_string_dtb(bool valid)
524{
525 const char last_valid[] = "1234567890123456789012345678901";
526 const char first_invalid[] = "12345678901234567890123456789012";
David Brazdil136f2942019-09-23 14:11:03 +0100527 static_assert(sizeof(last_valid) == STRING_MAX_SIZE);
528 static_assert(sizeof(first_invalid) == STRING_MAX_SIZE + 1);
David Brazdil0dbb41f2019-09-09 18:03:35 +0100529
530 /* clang-format off */
531 return ManifestDtBuilder()
532 .StartChild("hypervisor")
533 .Compatible()
534 .StartChild("vm1")
535 .DebugName(valid ? last_valid : first_invalid)
536 .EndChild()
537 .EndChild()
538 .Build();
539 /* clang-format on */
540}
541
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100542TEST_F(manifest, long_string)
David Brazdil0dbb41f2019-09-09 18:03:35 +0100543{
Olivier Deprez93644652022-09-09 11:01:12 +0200544 struct_manifest *m;
David Brazdil0dbb41f2019-09-09 18:03:35 +0100545 std::vector<char> dtb_last_valid = gen_long_string_dtb(true);
546 std::vector<char> dtb_first_invalid = gen_long_string_dtb(false);
547
David Brazdila2358d42020-01-27 18:51:38 +0000548 ASSERT_EQ(manifest_from_vec(&m, dtb_last_valid), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200549 manifest_dealloc();
550
David Brazdila2358d42020-01-27 18:51:38 +0000551 ASSERT_EQ(manifest_from_vec(&m, dtb_first_invalid),
552 MANIFEST_ERROR_STRING_TOO_LONG);
David Brazdil74e9c3b2019-08-28 11:09:08 +0100553}
554
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100555TEST_F(manifest, reserved_vm_id)
David Brazdil74e9c3b2019-08-28 11:09:08 +0100556{
Olivier Deprez93644652022-09-09 11:01:12 +0200557 struct_manifest *m;
David Brazdil74e9c3b2019-08-28 11:09:08 +0100558
559 /* clang-format off */
560 std::vector<char> dtb = ManifestDtBuilder()
561 .StartChild("hypervisor")
562 .Compatible()
David Brazdil52256ff2019-08-23 15:15:15 +0100563 .StartChild("vm1")
564 .DebugName("primary_vm")
565 .EndChild()
566 .StartChild("vm0")
567 .DebugName("reserved_vm")
568 .VcpuCount(1)
569 .MemSize(0x1000)
570 .KernelFilename("kernel")
571 .EndChild()
572 .EndChild()
573 .Build();
574 /* clang-format on */
575
David Brazdila2358d42020-01-27 18:51:38 +0000576 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_ERROR_RESERVED_VM_ID);
David Brazdil7a462ec2019-08-15 12:27:47 +0100577}
578
Andrew Scullae9962e2019-10-03 16:51:16 +0100579static std::vector<char> gen_vcpu_count_limit_dtb(uint32_t vcpu_count)
David Brazdil52256ff2019-08-23 15:15:15 +0100580{
581 /* clang-format off */
582 return ManifestDtBuilder()
583 .StartChild("hypervisor")
David Brazdil74e9c3b2019-08-28 11:09:08 +0100584 .Compatible()
David Brazdil52256ff2019-08-23 15:15:15 +0100585 .StartChild("vm1")
586 .DebugName("primary_vm")
587 .EndChild()
588 .StartChild("vm2")
589 .DebugName("secondary_vm")
590 .VcpuCount(vcpu_count)
591 .MemSize(0x1000)
592 .KernelFilename("kernel")
593 .EndChild()
594 .EndChild()
595 .Build();
596 /* clang-format on */
597}
David Brazdil7a462ec2019-08-15 12:27:47 +0100598
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100599TEST_F(manifest, vcpu_count_limit)
David Brazdil7a462ec2019-08-15 12:27:47 +0100600{
Olivier Deprez93644652022-09-09 11:01:12 +0200601 struct_manifest *m;
David Brazdil52256ff2019-08-23 15:15:15 +0100602 std::vector<char> dtb_last_valid = gen_vcpu_count_limit_dtb(UINT16_MAX);
603 std::vector<char> dtb_first_invalid =
604 gen_vcpu_count_limit_dtb(UINT16_MAX + 1);
David Brazdil7a462ec2019-08-15 12:27:47 +0100605
David Brazdila2358d42020-01-27 18:51:38 +0000606 ASSERT_EQ(manifest_from_vec(&m, dtb_last_valid), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200607 ASSERT_EQ(m->vm_count, 2);
608 ASSERT_EQ(m->vm[1].secondary.vcpu_count, UINT16_MAX);
609 manifest_dealloc();
David Brazdil7a462ec2019-08-15 12:27:47 +0100610
David Brazdila2358d42020-01-27 18:51:38 +0000611 ASSERT_EQ(manifest_from_vec(&m, dtb_first_invalid),
David Brazdil0dbb41f2019-09-09 18:03:35 +0100612 MANIFEST_ERROR_INTEGER_OVERFLOW);
David Brazdil7a462ec2019-08-15 12:27:47 +0100613}
614
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100615TEST_F(manifest, no_ramdisk_primary)
David Brazdile6f83222019-09-23 14:47:37 +0100616{
Olivier Deprez93644652022-09-09 11:01:12 +0200617 struct_manifest *m;
David Brazdile6f83222019-09-23 14:47:37 +0100618
619 /* clang-format off */
620 std::vector<char> dtb = ManifestDtBuilder()
621 .StartChild("hypervisor")
622 .Compatible()
623 .StartChild("vm1")
624 .DebugName("primary_vm")
625 .EndChild()
626 .EndChild()
627 .Build();
628 /* clang-format on */
629
David Brazdila2358d42020-01-27 18:51:38 +0000630 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200631 ASSERT_EQ(m->vm_count, 1);
632 ASSERT_STREQ(string_data(&m->vm[0].debug_name), "primary_vm");
633 ASSERT_STREQ(string_data(&m->vm[0].primary.ramdisk_filename), "");
David Brazdile6f83222019-09-23 14:47:37 +0100634}
635
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100636TEST_F(manifest, no_boot_address_primary)
David Brazdil080ee312020-02-25 15:30:30 -0800637{
Olivier Deprez93644652022-09-09 11:01:12 +0200638 struct_manifest *m;
David Brazdil080ee312020-02-25 15:30:30 -0800639
640 /* clang-format off */
641 std::vector<char> dtb = ManifestDtBuilder()
642 .StartChild("hypervisor")
643 .Compatible()
644 .StartChild("vm1")
645 .DebugName("primary_vm")
646 .EndChild()
647 .EndChild()
648 .Build();
649 /* clang-format on */
650
651 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200652 ASSERT_EQ(m->vm_count, 1);
653 ASSERT_STREQ(string_data(&m->vm[0].debug_name), "primary_vm");
654 ASSERT_EQ(m->vm[0].primary.boot_address, MANIFEST_INVALID_ADDRESS);
David Brazdil080ee312020-02-25 15:30:30 -0800655}
656
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100657TEST_F(manifest, boot_address_primary)
David Brazdil080ee312020-02-25 15:30:30 -0800658{
Olivier Deprez93644652022-09-09 11:01:12 +0200659 struct_manifest *m;
David Brazdil080ee312020-02-25 15:30:30 -0800660 const uint64_t addr = UINT64_C(0x12345678ABCDEFEF);
661
662 /* clang-format off */
663 std::vector<char> dtb = ManifestDtBuilder()
664 .StartChild("hypervisor")
665 .Compatible()
666 .StartChild("vm1")
667 .DebugName("primary_vm")
668 .BootAddress(addr)
669 .EndChild()
670 .EndChild()
671 .Build();
672 /* clang-format on */
673
674 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200675 ASSERT_EQ(m->vm_count, 1);
676 ASSERT_STREQ(string_data(&m->vm[0].debug_name), "primary_vm");
677 ASSERT_EQ(m->vm[0].primary.boot_address, addr);
David Brazdil080ee312020-02-25 15:30:30 -0800678}
679
Andrew Scullb2c3a242019-11-04 13:52:36 +0000680static std::vector<char> gen_malformed_boolean_dtb(
681 const std::string_view &value)
Andrew Scullae9962e2019-10-03 16:51:16 +0100682{
Andrew Scullae9962e2019-10-03 16:51:16 +0100683 /* clang-format off */
Andrew Scullb2c3a242019-11-04 13:52:36 +0000684 return ManifestDtBuilder()
Andrew Scullae9962e2019-10-03 16:51:16 +0100685 .StartChild("hypervisor")
686 .Compatible()
687 .StartChild("vm1")
688 .DebugName("primary_vm")
Andrew Scullb2c3a242019-11-04 13:52:36 +0000689 .Property("smc_whitelist_permissive", value)
Andrew Scull5dc089e2019-11-04 13:21:03 +0000690 .EndChild()
Andrew Scullae9962e2019-10-03 16:51:16 +0100691 .EndChild()
692 .Build();
693 /* clang-format on */
Andrew Scullb2c3a242019-11-04 13:52:36 +0000694}
Andrew Scullae9962e2019-10-03 16:51:16 +0100695
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100696TEST_F(manifest, malformed_booleans)
Andrew Scullb2c3a242019-11-04 13:52:36 +0000697{
Olivier Deprez93644652022-09-09 11:01:12 +0200698 struct_manifest *m;
Andrew Scullae9962e2019-10-03 16:51:16 +0100699
Andrew Scullb2c3a242019-11-04 13:52:36 +0000700 std::vector<char> dtb_false = gen_malformed_boolean_dtb("\"false\"");
701 std::vector<char> dtb_true = gen_malformed_boolean_dtb("\"true\"");
702 std::vector<char> dtb_0 = gen_malformed_boolean_dtb("\"<0>\"");
703 std::vector<char> dtb_1 = gen_malformed_boolean_dtb("\"<1>\"");
Andrew Scullae9962e2019-10-03 16:51:16 +0100704
David Brazdila2358d42020-01-27 18:51:38 +0000705 ASSERT_EQ(manifest_from_vec(&m, dtb_false),
Andrew Scullb2c3a242019-11-04 13:52:36 +0000706 MANIFEST_ERROR_MALFORMED_BOOLEAN);
Olivier Deprez93644652022-09-09 11:01:12 +0200707 manifest_dealloc();
708
David Brazdila2358d42020-01-27 18:51:38 +0000709 ASSERT_EQ(manifest_from_vec(&m, dtb_true),
Andrew Scullb2c3a242019-11-04 13:52:36 +0000710 MANIFEST_ERROR_MALFORMED_BOOLEAN);
Olivier Deprez93644652022-09-09 11:01:12 +0200711 manifest_dealloc();
712
David Brazdila2358d42020-01-27 18:51:38 +0000713 ASSERT_EQ(manifest_from_vec(&m, dtb_0),
Andrew Scullb2c3a242019-11-04 13:52:36 +0000714 MANIFEST_ERROR_MALFORMED_BOOLEAN);
Olivier Deprez93644652022-09-09 11:01:12 +0200715 manifest_dealloc();
716
David Brazdila2358d42020-01-27 18:51:38 +0000717 ASSERT_EQ(manifest_from_vec(&m, dtb_1),
Andrew Scullb2c3a242019-11-04 13:52:36 +0000718 MANIFEST_ERROR_MALFORMED_BOOLEAN);
Andrew Scullae9962e2019-10-03 16:51:16 +0100719}
720
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100721TEST_F(manifest, valid)
David Brazdil7a462ec2019-08-15 12:27:47 +0100722{
Olivier Deprez93644652022-09-09 11:01:12 +0200723 struct_manifest *m;
David Brazdil7a462ec2019-08-15 12:27:47 +0100724 struct manifest_vm *vm;
David Brazdil7a462ec2019-08-15 12:27:47 +0100725
David Brazdil52256ff2019-08-23 15:15:15 +0100726 /* clang-format off */
727 std::vector<char> dtb = ManifestDtBuilder()
728 .StartChild("hypervisor")
David Brazdil74e9c3b2019-08-28 11:09:08 +0100729 .Compatible()
David Brazdil52256ff2019-08-23 15:15:15 +0100730 .StartChild("vm1")
731 .DebugName("primary_vm")
Andrew Scull72b43c02019-09-18 13:53:45 +0100732 .KernelFilename("primary_kernel")
David Brazdile6f83222019-09-23 14:47:37 +0100733 .RamdiskFilename("primary_ramdisk")
Andrew Scullae9962e2019-10-03 16:51:16 +0100734 .SmcWhitelist({0x32000000, 0x33001111})
David Brazdil52256ff2019-08-23 15:15:15 +0100735 .EndChild()
736 .StartChild("vm3")
737 .DebugName("second_secondary_vm")
738 .VcpuCount(43)
739 .MemSize(0x12345)
Andrew Scull72b43c02019-09-18 13:53:45 +0100740 .KernelFilename("second_secondary_kernel")
David Brazdil52256ff2019-08-23 15:15:15 +0100741 .EndChild()
742 .StartChild("vm2")
743 .DebugName("first_secondary_vm")
744 .VcpuCount(42)
745 .MemSize(12345)
Andrew Scullae9962e2019-10-03 16:51:16 +0100746 .SmcWhitelist({0x04000000, 0x30002222, 0x31445566})
747 .SmcWhitelistPermissive()
David Brazdil52256ff2019-08-23 15:15:15 +0100748 .EndChild()
749 .EndChild()
750 .Build();
751 /* clang-format on */
752
David Brazdila2358d42020-01-27 18:51:38 +0000753 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200754 ASSERT_EQ(m->vm_count, 3);
David Brazdil7a462ec2019-08-15 12:27:47 +0100755
Olivier Deprez93644652022-09-09 11:01:12 +0200756 vm = &m->vm[0];
David Brazdil136f2942019-09-23 14:11:03 +0100757 ASSERT_STREQ(string_data(&vm->debug_name), "primary_vm");
758 ASSERT_STREQ(string_data(&vm->kernel_filename), "primary_kernel");
David Brazdile6f83222019-09-23 14:47:37 +0100759 ASSERT_STREQ(string_data(&vm->primary.ramdisk_filename),
760 "primary_ramdisk");
Andrew Scullae9962e2019-10-03 16:51:16 +0100761 ASSERT_THAT(
762 std::span(vm->smc_whitelist.smcs, vm->smc_whitelist.smc_count),
763 ElementsAre(0x32000000, 0x33001111));
764 ASSERT_FALSE(vm->smc_whitelist.permissive);
David Brazdil7a462ec2019-08-15 12:27:47 +0100765
Olivier Deprez93644652022-09-09 11:01:12 +0200766 vm = &m->vm[1];
David Brazdil136f2942019-09-23 14:11:03 +0100767 ASSERT_STREQ(string_data(&vm->debug_name), "first_secondary_vm");
768 ASSERT_STREQ(string_data(&vm->kernel_filename), "");
David Brazdil7a462ec2019-08-15 12:27:47 +0100769 ASSERT_EQ(vm->secondary.vcpu_count, 42);
770 ASSERT_EQ(vm->secondary.mem_size, 12345);
Andrew Scullae9962e2019-10-03 16:51:16 +0100771 ASSERT_THAT(
772 std::span(vm->smc_whitelist.smcs, vm->smc_whitelist.smc_count),
773 ElementsAre(0x04000000, 0x30002222, 0x31445566));
774 ASSERT_TRUE(vm->smc_whitelist.permissive);
David Brazdil7a462ec2019-08-15 12:27:47 +0100775
Olivier Deprez93644652022-09-09 11:01:12 +0200776 vm = &m->vm[2];
David Brazdil136f2942019-09-23 14:11:03 +0100777 ASSERT_STREQ(string_data(&vm->debug_name), "second_secondary_vm");
778 ASSERT_STREQ(string_data(&vm->kernel_filename),
779 "second_secondary_kernel");
David Brazdil7a462ec2019-08-15 12:27:47 +0100780 ASSERT_EQ(vm->secondary.vcpu_count, 43);
781 ASSERT_EQ(vm->secondary.mem_size, 0x12345);
Andrew Scullae9962e2019-10-03 16:51:16 +0100782 ASSERT_THAT(
783 std::span(vm->smc_whitelist.smcs, vm->smc_whitelist.smc_count),
784 IsEmpty());
785 ASSERT_FALSE(vm->smc_whitelist.permissive);
David Brazdil7a462ec2019-08-15 12:27:47 +0100786}
787
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100788TEST_F(manifest, ffa_not_compatible)
Olivier Deprez62d99e32020-01-09 15:58:07 +0100789{
Olivier Deprez93644652022-09-09 11:01:12 +0200790 struct_manifest *m;
Olivier Deprez62d99e32020-01-09 15:58:07 +0100791
792 /* clang-format off */
793 std::vector<char> dtb = ManifestDtBuilder()
794 .Compatible({ "arm,ffa-manifest-2.0" })
795 .Property("ffa-version", "<0x10000>")
796 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
797 .Property("execution-ctx-count", "<1>")
798 .Property("exception-level", "<2>")
799 .Property("execution-state", "<0>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000800 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100801 .Property("xlat-granule", "<0>")
802 .Property("messaging-method", "<1>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500803 .Property("ns-interrupts-action", "<1>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100804 .Build();
805 /* clang-format on */
806
807 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
808 MANIFEST_ERROR_NOT_COMPATIBLE);
809}
810
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100811TEST_F(manifest, ffa_missing_property)
Olivier Deprez62d99e32020-01-09 15:58:07 +0100812{
Olivier Deprez93644652022-09-09 11:01:12 +0200813 struct_manifest *m;
Olivier Deprez62d99e32020-01-09 15:58:07 +0100814
815 /* clang-format off */
816 std::vector<char> dtb = ManifestDtBuilder()
817 .Compatible({ "arm,ffa-manifest-1.0" })
818 .Property("ffa-version", "<0x10000>")
819 .Build();
820 /* clang-format on */
821
822 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
823 MANIFEST_ERROR_PROPERTY_NOT_FOUND);
824}
825
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100826TEST_F(manifest, ffa_validate_sanity_check)
Olivier Deprez62d99e32020-01-09 15:58:07 +0100827{
J-Alvesb37fd082020-10-22 12:29:21 +0100828 /*
829 * TODO: write test excluding all optional fields of the manifest, in
830 * accordance with specification.
831 */
Olivier Deprez93644652022-09-09 11:01:12 +0200832 struct_manifest *m;
Olivier Deprez62d99e32020-01-09 15:58:07 +0100833
834 /* Incompatible version */
835 /* clang-format off */
836 std::vector<char> dtb = ManifestDtBuilder()
837 .Compatible({ "arm,ffa-manifest-1.0" })
838 .Property("ffa-version", "<0xa1>")
839 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
840 .Property("execution-ctx-count", "<1>")
841 .Property("exception-level", "<2>")
842 .Property("execution-state", "<0>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000843 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100844 .Property("xlat-granule", "<0>")
J-Alvesb37fd082020-10-22 12:29:21 +0100845 .Property("boot-order", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100846 .Property("messaging-method", "<1>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500847 .Property("ns-interrupts-action", "<1>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100848 .Build();
849 /* clang-format on */
850 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
851 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +0200852 manifest_dealloc();
Olivier Deprez62d99e32020-01-09 15:58:07 +0100853
854 /* Incompatible translation granule */
855 /* clang-format off */
856 dtb = ManifestDtBuilder()
857 .Compatible({ "arm,ffa-manifest-1.0" })
858 .Property("ffa-version", "<0x10000>")
859 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
860 .Property("execution-ctx-count", "<1>")
861 .Property("exception-level", "<2>")
862 .Property("execution-state", "<0>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000863 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100864 .Property("xlat-granule", "<3>")
J-Alvesb37fd082020-10-22 12:29:21 +0100865 .Property("boot-order", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100866 .Property("messaging-method", "<1>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500867 .Property("ns-interrupts-action", "<1>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100868 .Build();
869 /* clang-format on */
870 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
871 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +0200872 manifest_dealloc();
Olivier Deprez62d99e32020-01-09 15:58:07 +0100873
874 /* Incompatible exeption level */
875 /* clang-format off */
876 dtb = ManifestDtBuilder()
877 .Compatible({ "arm,ffa-manifest-1.0" })
878 .Property("ffa-version", "<0x10000>")
879 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
880 .Property("execution-ctx-count", "<1>")
Daniel Boulby874d5432023-04-27 12:40:24 +0100881 .Property("exception-level", "<10>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100882 .Property("execution-state", "<0>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000883 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100884 .Property("xlat-granule", "<0>")
J-Alvesb37fd082020-10-22 12:29:21 +0100885 .Property("boot-order", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100886 .Property("messaging-method", "<1>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500887 .Property("ns-interrupts-action", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100888 .Build();
889 /* clang-format on */
890 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
891 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +0200892 manifest_dealloc();
Olivier Deprez62d99e32020-01-09 15:58:07 +0100893
894 /* Incompatible execution state */
895 /* clang-format off */
896 dtb = ManifestDtBuilder()
897 .Compatible({ "arm,ffa-manifest-1.0" })
898 .Property("ffa-version", "<0x10000>")
899 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
900 .Property("execution-ctx-count", "<1>")
901 .Property("exception-level", "<2>")
902 .Property("execution-state", "<2>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000903 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100904 .Property("xlat-granule", "<0>")
J-Alvesb37fd082020-10-22 12:29:21 +0100905 .Property("boot-order", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100906 .Property("messaging-method", "<1>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500907 .Property("ns-interrupts-action", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100908 .Build();
909 /* clang-format on */
910 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
911 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +0200912 manifest_dealloc();
Olivier Deprez62d99e32020-01-09 15:58:07 +0100913
Kathleen Capellaf71dee42023-08-08 16:24:14 -0400914 /* Incompatible messaging method - unrecognized messaging-method. */
915 /* clang-format off */
916 dtb = ManifestDtBuilder()
917 .Compatible({ "arm,ffa-manifest-1.0" })
918 .Property("ffa-version", "<0x10002>")
919 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
920 .Property("execution-ctx-count", "<1>")
921 .Property("exception-level", "<2>")
922 .Property("execution-state", "<0>")
923 .Property("entrypoint-offset", "<0x00002000>")
924 .Property("xlat-granule", "<0>")
925 .Property("boot-order", "<0>")
926 .Property("messaging-method", "<0x272>")
927 .Property("ns-interrupts-action", "<0>")
928 .Build();
929 /* clang-format on */
930 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
931 MANIFEST_ERROR_NOT_COMPATIBLE);
932 manifest_dealloc();
933
934 /* Incompatible messaging method - only endpoints using FF-A version >=
935 * FF-A v1.2 are allowed to set FFA_PARTITION_DIRECT_REQ2_RECV and
936 * FFA_PARTITION_DIRECT_REQ2_SEND. */
Olivier Deprez62d99e32020-01-09 15:58:07 +0100937 /* clang-format off */
938 dtb = ManifestDtBuilder()
939 .Compatible({ "arm,ffa-manifest-1.0" })
940 .Property("ffa-version", "<0x10000>")
941 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
942 .Property("execution-ctx-count", "<1>")
943 .Property("exception-level", "<2>")
944 .Property("execution-state", "<0>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000945 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100946 .Property("xlat-granule", "<0>")
J-Alvesb37fd082020-10-22 12:29:21 +0100947 .Property("boot-order", "<0>")
Kathleen Capellaf71dee42023-08-08 16:24:14 -0400948 .Property("messaging-method", "<0x204>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500949 .Property("ns-interrupts-action", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100950 .Build();
951 /* clang-format on */
952 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
953 MANIFEST_ERROR_NOT_COMPATIBLE);
Madhukar Pappireddy5c04a382022-12-28 11:29:26 -0600954
955 /*
956 * No need to invoke manifest_dealloac() since manifest TearDown calls
957 * it when the test ends.
958 */
959}
960
961TEST_F(manifest, ffa_validate_interrupt_actions)
962{
963 struct_manifest *m;
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500964
965 /* Incompatible NS interrupt action */
966 /* clang-format off */
Madhukar Pappireddy5c04a382022-12-28 11:29:26 -0600967 std::vector<char> dtb = ManifestDtBuilder()
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500968 .Compatible({ "arm,ffa-manifest-1.0" })
969 .Property("ffa-version", "<0x10000>")
970 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
971 .Property("execution-ctx-count", "<1>")
972 .Property("exception-level", "<2>")
973 .Property("execution-state", "<0>")
974 .Property("entrypoint-offset", "<0x00002000>")
975 .Property("xlat-granule", "<0>")
976 .Property("boot-order", "<0>")
977 .Property("messaging-method", "<1>")
978 .Property("ns-interrupts-action", "<4>")
979 .Build();
980 /* clang-format on */
Madhukar Pappireddy5c04a382022-12-28 11:29:26 -0600981 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
982 MANIFEST_ERROR_ILLEGAL_NS_INT_ACTION);
Madhukar Pappireddyee736ad2022-12-28 11:37:09 -0600983 manifest_dealloc();
984
985 /* Incompatible other-s-interrupts-action for S-EL1 partition */
986 /* clang-format off */
987 dtb = ManifestDtBuilder()
988 .Compatible({ "arm,ffa-manifest-1.0" })
989 .Property("ffa-version", "<0x10000>")
990 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
991 .Property("execution-ctx-count", "<1>")
992 .Property("exception-level", "<2>")
993 .Property("execution-state", "<0>")
994 .Property("entrypoint-offset", "<0x00002000>")
995 .Property("xlat-granule", "<0>")
996 .Property("boot-order", "<0>")
997 .Property("messaging-method", "<1>")
998 .Property("ns-interrupts-action", "<1>")
999 .Property("other-s-interrupts-action", "<0>")
1000 .Build();
1001 /* clang-format on */
1002 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1003 MANIFEST_ERROR_NOT_COMPATIBLE);
1004 manifest_dealloc();
1005
1006 /*
1007 * Incompatible choice of the fields ns-interrupts-action and
1008 * other-s-interrupts-action.
1009 */
1010 /* clang-format off */
1011 dtb = ManifestDtBuilder()
1012 .Compatible({ "arm,ffa-manifest-1.0" })
1013 .Property("ffa-version", "<0x10000>")
1014 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1015 .Property("execution-ctx-count", "<1>")
1016 .Property("exception-level", "<1>")
1017 .Property("execution-state", "<0>")
1018 .Property("entrypoint-offset", "<0x00002000>")
1019 .Property("xlat-granule", "<0>")
1020 .Property("boot-order", "<0>")
1021 .Property("messaging-method", "<1>")
1022 .Property("ns-interrupts-action", "<2>")
1023 .Property("other-s-interrupts-action", "<0>")
1024 .Build();
1025 /* clang-format on */
1026 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1027 MANIFEST_ERROR_NOT_COMPATIBLE);
1028 manifest_dealloc();
1029
1030 /* Illegal value specified for the field other-s-interrupts-action. */
1031 /* clang-format off */
1032 dtb = ManifestDtBuilder()
1033 .Compatible({ "arm,ffa-manifest-1.0" })
1034 .Property("ffa-version", "<0x10000>")
1035 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1036 .Property("execution-ctx-count", "<1>")
1037 .Property("exception-level", "<1>")
1038 .Property("execution-state", "<0>")
1039 .Property("entrypoint-offset", "<0x00002000>")
1040 .Property("xlat-granule", "<0>")
1041 .Property("boot-order", "<0>")
1042 .Property("messaging-method", "<1>")
1043 .Property("other-s-interrupts-action", "<2>")
1044 .Build();
1045 /* clang-format on */
1046 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1047 MANIFEST_ERROR_ILLEGAL_OTHER_S_INT_ACTION);
Olivier Deprez62d99e32020-01-09 15:58:07 +01001048}
1049
Olivier Depreza15f2352022-09-26 09:17:24 +02001050TEST_F(manifest, power_management)
1051{
1052 struct manifest_vm *vm;
1053 struct_manifest *m;
1054
1055 /* S-EL1 partition power management field can set bit 0. */
1056 /* clang-format off */
1057 std::vector<char> dtb = ManifestDtBuilder()
1058 .Compatible({ "arm,ffa-manifest-1.0" })
1059 .Property("ffa-version", "<0x10001>")
1060 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1061 .Property("execution-ctx-count", "<8>")
1062 .Property("exception-level", "<2>")
1063 .Property("execution-state", "<0>")
1064 .Property("entrypoint-offset", "<0x00002000>")
1065 .Property("messaging-method", "<1>")
1066 .Property("power-management-messages", "<1>")
1067 .Build();
1068 /* clang-format on */
1069 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1070 vm = &m->vm[0];
1071 ASSERT_EQ(vm->partition.power_management, 1);
1072 manifest_dealloc();
1073
1074 /* S-EL1 partition power management field can set bit 3. */
1075 /* clang-format off */
1076 dtb = ManifestDtBuilder()
1077 .Compatible({ "arm,ffa-manifest-1.0" })
1078 .Property("ffa-version", "<0x10001>")
1079 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1080 .Property("execution-ctx-count", "<8>")
1081 .Property("exception-level", "<2>")
1082 .Property("execution-state", "<0>")
1083 .Property("entrypoint-offset", "<0x00002000>")
1084 .Property("messaging-method", "<1>")
1085 .Property("power-management-messages", "<8>")
1086 .Build();
1087 /* clang-format on */
1088 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1089 vm = &m->vm[0];
1090 ASSERT_EQ(vm->partition.power_management, 8);
1091 manifest_dealloc();
1092
1093 /* S-EL1 partition power management field can only set bits 0 and 3. */
1094 /* clang-format off */
1095 dtb = ManifestDtBuilder()
1096 .Compatible({ "arm,ffa-manifest-1.0" })
1097 .Property("ffa-version", "<0x10001>")
1098 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1099 .Property("execution-ctx-count", "<8>")
1100 .Property("exception-level", "<2>")
1101 .Property("execution-state", "<0>")
1102 .Property("entrypoint-offset", "<0x00002000>")
1103 .Property("messaging-method", "<1>")
1104 .Property("power-management-messages", "<0xf>")
1105 .Build();
1106 /* clang-format on */
1107 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1108 vm = &m->vm[0];
1109 ASSERT_EQ(vm->partition.power_management, 9);
1110 manifest_dealloc();
1111
1112 /* S-EL0 partition power management field is forced to 0. */
1113 /* clang-format off */
1114 dtb = ManifestDtBuilder()
1115 .Compatible({ "arm,ffa-manifest-1.0" })
1116 .Property("ffa-version", "<0x10001>")
1117 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1118 .Property("execution-ctx-count", "<1>")
1119 .Property("exception-level", "<1>")
1120 .Property("execution-state", "<0>")
1121 .Property("entrypoint-offset", "<0x00002000>")
1122 .Property("messaging-method", "<1>")
1123 .Property("power-management-messages", "<0xff>")
1124 .Build();
1125 /* clang-format on */
1126 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1127 vm = &m->vm[0];
1128 ASSERT_EQ(vm->partition.power_management, 0);
1129}
1130
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001131TEST_F(manifest, ffa_validate_rxtx_info)
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001132{
Olivier Deprez93644652022-09-09 11:01:12 +02001133 struct_manifest *m;
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001134
1135 /* Not Compatible */
1136 /* clang-format off */
1137 std::vector<char> dtb = ManifestDtBuilder()
1138 .FfaValidManifest()
1139 .StartChild("rx_tx-info")
1140 .Compatible({ "foo,bar" })
1141 .EndChild()
1142 .Build();
1143 /* clang-format on */
1144 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1145 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +02001146 manifest_dealloc();
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001147
1148 /* Missing Properties */
1149 /* clang-format off */
1150 dtb = ManifestDtBuilder()
1151 .FfaValidManifest()
1152 .StartChild("rx_tx-info")
1153 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1154 .EndChild()
1155 .Build();
1156 /* clang-format on */
1157 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1158 MANIFEST_ERROR_PROPERTY_NOT_FOUND);
1159}
1160
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001161TEST_F(manifest, ffa_validate_mem_regions)
Manish Pandey6542f5c2020-04-27 14:37:46 +01001162{
Olivier Deprez93644652022-09-09 11:01:12 +02001163 struct_manifest *m;
Manish Pandey6542f5c2020-04-27 14:37:46 +01001164
1165 /* Not Compatible */
1166 /* clang-format off */
1167 std::vector<char> dtb = ManifestDtBuilder()
1168 .FfaValidManifest()
1169 .StartChild("memory-regions")
1170 .Compatible({ "foo,bar" })
1171 .EndChild()
1172 .Build();
1173 /* clang-format on */
1174 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1175 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +02001176 manifest_dealloc();
Manish Pandey6542f5c2020-04-27 14:37:46 +01001177
1178 /* Memory regions unavailable */
1179 /* clang-format off */
1180 dtb = ManifestDtBuilder()
1181 .FfaValidManifest()
1182 .StartChild("memory-regions")
1183 .Compatible({ "arm,ffa-manifest-memory-regions" })
1184 .EndChild()
1185 .Build();
1186 /* clang-format on */
1187 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1188 MANIFEST_ERROR_MEMORY_REGION_NODE_EMPTY);
Olivier Deprez93644652022-09-09 11:01:12 +02001189 manifest_dealloc();
Manish Pandey6542f5c2020-04-27 14:37:46 +01001190
1191 /* Missing Properties */
1192 /* clang-format off */
1193 dtb = ManifestDtBuilder()
1194 .FfaValidManifest()
1195 .StartChild("memory-regions")
1196 .Compatible({ "arm,ffa-manifest-memory-regions" })
1197 .StartChild("test-memory")
1198 .Description("test-memory")
1199 .EndChild()
1200 .EndChild()
1201 .Build();
1202 /* clang-format on */
1203 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1204 MANIFEST_ERROR_PROPERTY_NOT_FOUND);
Olivier Deprez93644652022-09-09 11:01:12 +02001205 manifest_dealloc();
Manish Pandeyf06c9072020-09-29 15:41:58 +01001206
Varun Wadekar4afbfd72022-10-13 14:30:18 +01001207 /* Empty memory region */
1208 /* clang-format off */
1209 dtb = ManifestDtBuilder()
1210 .FfaValidManifest()
1211 .StartChild("memory-regions")
1212 .Compatible({ "arm,ffa-manifest-memory-regions" })
1213 .Label("rx")
1214 .StartChild("rx")
1215 .Description("rx-buffer")
1216 .Property("base-address", "<0x7300000>")
1217 .Property("pages-count", "<0>")
1218 .Property("attributes", "<1>")
1219 .EndChild()
1220 .Label("tx")
1221 .StartChild("tx")
1222 .Description("tx-buffer")
1223 .Property("base-address", "<0x7310000>")
1224 .Property("pages-count", "<2>")
1225 .Property("attributes", "<3>")
1226 .EndChild()
1227 .EndChild()
1228 .StartChild("rx_tx-info")
1229 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1230 .Property("rx-buffer", "<&rx>")
1231 .Property("tx-buffer", "<&tx>")
1232 .EndChild()
1233 .Build();
1234 /* clang-format on */
1235 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1236 MANIFEST_ERROR_MEM_REGION_EMPTY);
1237 manifest_dealloc();
1238
Karl Meakine92efbe2023-06-01 14:16:22 +01001239 /* Mutually exclusive base-address and relative-address properties */
1240 /* clang-format off */
1241 dtb = ManifestDtBuilder()
1242 .FfaValidManifest()
1243 .StartChild("memory-regions")
1244 .Compatible({ "arm,ffa-manifest-memory-regions" })
1245 .Label("rx")
1246 .StartChild("rx")
1247 .Description("rx-buffer")
1248 .Property("base-address", "<0x7300000>")
1249 .Property("relative-address", "<0x7300000>")
1250 .Property("pages-count", "<1>")
1251 .Property("attributes", "<1>")
1252 .EndChild()
1253 .EndChild()
1254 .Build();
1255 /* clang-format on */
1256 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1257 MANIFEST_ERROR_BASE_ADDRESS_AND_RELATIVE_ADDRESS);
1258 manifest_dealloc();
1259 /* Relative-address overflow*/
1260 /* clang-format off */
1261 dtb = ManifestDtBuilder()
1262 .FfaValidManifest()
1263 .Property("load-address", "<0xffffff00 0xffffff00>")
1264 .StartChild("memory-regions")
1265 .Compatible({ "arm,ffa-manifest-memory-regions" })
1266 .Label("rx")
1267 .StartChild("rx")
1268 .Description("rx-buffer")
1269 .Property("relative-address", "<0xffffff00 0xffffff00>")
1270 .Property("pages-count", "<1>")
1271 .Property("attributes", "<1>")
1272 .EndChild()
1273 .EndChild()
1274 .Build();
1275 /* clang-format on */
1276 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1277 MANIFEST_ERROR_INTEGER_OVERFLOW);
1278 manifest_dealloc();
1279
Daniel Boulby9279b552022-06-28 17:04:01 +01001280 /* Overlapping memory regions */
1281 /* clang-format off */
1282 dtb = ManifestDtBuilder()
1283 .FfaValidManifest()
1284 .StartChild("memory-regions")
1285 .Compatible({ "arm,ffa-manifest-memory-regions" })
1286 .Label("rx")
1287 .StartChild("rx")
1288 .Description("rx-buffer")
1289 .Property("base-address", "<0x7300000>")
1290 .Property("pages-count", "<1>")
1291 .Property("attributes", "<1>")
1292 .EndChild()
1293 .Label("tx")
1294 .StartChild("tx")
1295 .Description("tx-buffer")
1296 .Property("base-address", "<0x7300000>")
1297 .Property("pages-count", "<2>")
1298 .Property("attributes", "<3>")
1299 .EndChild()
1300 .EndChild()
1301 .Build();
1302 /* clang-format on */
1303 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1304 MANIFEST_ERROR_MEM_REGION_OVERLAP);
Olivier Deprez93644652022-09-09 11:01:12 +02001305 manifest_dealloc();
Daniel Boulby9279b552022-06-28 17:04:01 +01001306
1307 /* clang-format off */
1308 dtb = ManifestDtBuilder()
1309 .FfaValidManifest()
1310 .StartChild("memory-regions")
1311 .Compatible({ "arm,ffa-manifest-memory-regions" })
1312 .Label("rx")
1313 .StartChild("rx")
1314 .Description("rx-buffer")
1315 .Property("base-address", "<0x7300000>")
1316 .Property("pages-count", "<2>")
1317 .Property("attributes", "<1>")
1318 .EndChild()
1319 .Label("tx")
1320 .StartChild("tx")
1321 .Description("tx-buffer")
1322 .Property("base-address", "<0x7301000>")
1323 .Property("pages-count", "<2>")
1324 .Property("attributes", "<3>")
1325 .EndChild()
1326 .EndChild()
1327 .Build();
1328 /* clang-format on */
1329 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1330 MANIFEST_ERROR_MEM_REGION_OVERLAP);
Olivier Deprez93644652022-09-09 11:01:12 +02001331 manifest_dealloc();
Daniel Boulby9279b552022-06-28 17:04:01 +01001332
1333 /* clang-format off */
1334 dtb = ManifestDtBuilder()
1335 .FfaValidManifest()
1336 .StartChild("memory-regions")
1337 .Compatible({ "arm,ffa-manifest-memory-regions" })
1338 .Label("rx")
1339 .StartChild("rx")
1340 .Description("rx-buffer")
Varun Wadekarae9aeaa2022-10-13 14:23:58 +01001341 .Property("base-address", "<0x7301000>")
1342 .Property("pages-count", "<1>")
1343 .Property("attributes", "<1>")
1344 .EndChild()
1345 .Label("tx")
1346 .StartChild("tx")
1347 .Description("tx-buffer")
1348 .Property("base-address", "<0x7300000>")
1349 .Property("pages-count", "<2>")
1350 .Property("attributes", "<3>")
1351 .EndChild()
1352 .EndChild()
1353 .Build();
1354 /* clang-format on */
1355 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1356 MANIFEST_ERROR_MEM_REGION_OVERLAP);
Daniel Boulbyc1a613d2022-10-18 11:26:17 +01001357 manifest_dealloc();
1358
1359 /* Unaligned memory region */
1360 /* clang-format off */
1361 dtb = ManifestDtBuilder()
1362 .FfaValidManifest()
1363 .StartChild("memory-regions")
1364 .Compatible({ "arm,ffa-manifest-memory-regions" })
1365 .Label("rx")
1366 .StartChild("rx")
1367 .Description("rx-buffer")
1368 .Property("base-address", "<0x7300FFF>")
1369 .Property("pages-count", "<2>")
1370 .Property("attributes", "<1>")
1371 .EndChild()
1372 .Label("tx")
1373 .StartChild("tx")
1374 .Description("tx-buffer")
1375 .Property("base-address", "<0x7303000>")
1376 .Property("pages-count", "<2>")
1377 .Property("attributes", "<3>")
1378 .EndChild()
1379 .EndChild()
1380 .Build();
1381 /* clang-format on */
1382 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1383 MANIFEST_ERROR_MEM_REGION_UNALIGNED);
1384 manifest_dealloc();
Varun Wadekarae9aeaa2022-10-13 14:23:58 +01001385
Manish Pandeyf06c9072020-09-29 15:41:58 +01001386 /* Different RXTX buffer sizes */
1387 /* clang-format off */
1388 dtb = ManifestDtBuilder()
1389 .FfaValidManifest()
1390 .StartChild("memory-regions")
1391 .Compatible({ "arm,ffa-manifest-memory-regions" })
1392 .Label("rx")
1393 .StartChild("rx")
1394 .Description("rx-buffer")
1395 .Property("base-address", "<0x7300000>")
1396 .Property("pages-count", "<1>")
1397 .Property("attributes", "<1>")
1398 .EndChild()
1399 .Label("tx")
1400 .StartChild("tx")
1401 .Description("tx-buffer")
1402 .Property("base-address", "<0x7310000>")
1403 .Property("pages-count", "<2>")
1404 .Property("attributes", "<3>")
1405 .EndChild()
1406 .EndChild()
1407 .StartChild("rx_tx-info")
1408 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1409 .Property("rx-buffer", "<&rx>")
1410 .Property("tx-buffer", "<&tx>")
1411 .EndChild()
1412 .Build();
1413 /* clang-format on */
1414 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1415 MANIFEST_ERROR_RXTX_SIZE_MISMATCH);
Manish Pandey6542f5c2020-04-27 14:37:46 +01001416}
1417
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001418TEST_F(manifest, ffa_validate_dev_regions)
Manish Pandeye68e7932020-04-23 15:29:28 +01001419{
Olivier Deprez93644652022-09-09 11:01:12 +02001420 struct_manifest *m;
Manish Pandeye68e7932020-04-23 15:29:28 +01001421
1422 /* Not Compatible */
1423 /* clang-format off */
1424 std::vector<char> dtb = ManifestDtBuilder()
1425 .FfaValidManifest()
1426 .StartChild("device-regions")
1427 .Compatible({ "foo,bar" })
1428 .EndChild()
1429 .Build();
1430 /* clang-format on */
1431 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1432 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +02001433 manifest_dealloc();
Manish Pandeye68e7932020-04-23 15:29:28 +01001434
1435 /* Memory regions unavailable */
1436 /* clang-format off */
1437 dtb = ManifestDtBuilder()
1438 .FfaValidManifest()
1439 .StartChild("device-regions")
1440 .Compatible({ "arm,ffa-manifest-device-regions" })
1441 .EndChild()
1442 .Build();
1443 /* clang-format on */
1444 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1445 MANIFEST_ERROR_DEVICE_REGION_NODE_EMPTY);
Olivier Deprez93644652022-09-09 11:01:12 +02001446 manifest_dealloc();
Manish Pandeye68e7932020-04-23 15:29:28 +01001447
1448 /* Missing Properties */
1449 /* clang-format off */
1450 dtb = ManifestDtBuilder()
1451 .FfaValidManifest()
1452 .StartChild("device-regions")
1453 .Compatible({ "arm,ffa-manifest-device-regions" })
1454 .StartChild("test-device")
1455 .Description("test-device")
1456 .EndChild()
1457 .EndChild()
1458 .Build();
1459 /* clang-format on */
1460 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1461 MANIFEST_ERROR_PROPERTY_NOT_FOUND);
Olivier Deprez93644652022-09-09 11:01:12 +02001462 manifest_dealloc();
Manish Pandeye68e7932020-04-23 15:29:28 +01001463
1464 /* Malformed interrupt list pair */
1465 /* clang-format off */
1466 dtb = ManifestDtBuilder()
1467 .FfaValidManifest()
1468 .StartChild("device-regions")
1469 .Compatible({ "arm,ffa-manifest-device-regions" })
1470 .StartChild("test-device")
1471 .Description("test-device")
1472 .Property("base-address", "<0x7200000>")
1473 .Property("pages-count", "<16>")
1474 .Property("attributes", "<3>")
1475 .Property("smmu-id", "<1>")
1476 .Property("stream-ids", "<0 1>")
1477 .Property("interrupts", "<2 3>, <4>")
1478 .EndChild()
1479 .EndChild()
1480 .Build();
1481 /* clang-format on */
1482 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1483 MANIFEST_ERROR_MALFORMED_INTEGER_LIST);
Olivier Deprez93644652022-09-09 11:01:12 +02001484 manifest_dealloc();
Daniel Boulby667334f2022-06-27 15:23:21 +01001485
1486 /* Non-unique interrupt IDs */
1487 /* clang-format off */
1488 dtb = ManifestDtBuilder()
1489 .FfaValidManifest()
1490 .StartChild("device-regions")
1491 .Compatible({ "arm,ffa-manifest-device-regions" })
1492 .StartChild("test-device-0")
1493 .Description("test-device-0")
1494 .Property("base-address", "<0x7200000>")
1495 .Property("pages-count", "<16>")
1496 .Property("attributes", "<3>")
1497 .Property("interrupts", "<2 3>")
1498 .EndChild()
1499 .StartChild("test-device-1")
1500 .Description("test-device-1")
1501 .Property("base-address", "<0x8200000>")
1502 .Property("pages-count", "<16>")
1503 .Property("attributes", "<3>")
1504 .Property("interrupts", "<1 3>, <2 5> ")
1505 .EndChild()
1506 .EndChild()
1507 .Build();
Daniel Boulby941ef342023-11-21 13:47:15 +00001508
Daniel Boulby667334f2022-06-27 15:23:21 +01001509 /* clang-format on */
1510 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1511 MANIFEST_ERROR_INTERRUPT_ID_REPEATED);
1512 /* Check valid interrupts were still mapped */
Olivier Deprez93644652022-09-09 11:01:12 +02001513 ASSERT_EQ(m->vm[0].partition.dev_regions[0].interrupts[0].id, 2);
1514 ASSERT_EQ(m->vm[0].partition.dev_regions[0].interrupts[0].attributes,
1515 3);
1516 ASSERT_EQ(m->vm[0].partition.dev_regions[1].interrupts[0].id, 1);
1517 ASSERT_EQ(m->vm[0].partition.dev_regions[1].interrupts[0].attributes,
1518 3);
Daniel Boulby941ef342023-11-21 13:47:15 +00001519 manifest_dealloc();
1520
1521 /* Overlapping address space between two device region nodes. */
1522 /* clang-format off */
1523 dtb = ManifestDtBuilder()
1524 .FfaValidManifest()
1525 .StartChild("device-regions")
1526 .Compatible({"arm,ffa-manifest-device-regions"})
1527 .StartChild("test-device-0")
1528 .Description("test-device-0")
1529 .Property("base-address", "<0x7200000>")
1530 .Property("pages-count", "<16>")
1531 .Property("attributes", "<3>")
1532 .EndChild()
1533 .StartChild("test-device-1")
1534 .Description("test-device-1")
1535 .Property("base-address", "<0x7200000>")
1536 .Property("pages-count", "<16>")
1537 .Property("attributes", "<3>")
1538 .EndChild()
1539 .EndChild()
1540 .Build();
1541
1542 /* clang-format on */
1543 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1544 MANIFEST_ERROR_MEM_REGION_OVERLAP);
1545 manifest_dealloc();
1546
1547 /*
1548 * Check memory region node and device region node address space
1549 * cannot overlap.
1550 */
1551 /* clang-format off */
1552 dtb = ManifestDtBuilder()
1553 .FfaValidManifest()
1554 .StartChild("memory-regions")
1555 .Compatible({"arm,ffa-manifest-memory-regions" })
1556 .StartChild("test-memory")
1557 .Description("test-memory")
1558 .Property("base-address", "<0x7100000>")
1559 .Property("pages-count", "<16>")
1560 .Property("attributes", "<3>")
1561 .EndChild()
1562 .EndChild()
1563 .StartChild("device-regions")
1564 .Compatible({"arm,ffa-manifest-device-regions"})
1565 .StartChild("test-device-0")
1566 .Description("test-device-0")
1567 .Property("base-address", "<0x7100000>")
1568 .Property("pages-count", "<16>")
1569 .Property("attributes", "<3>")
1570 .EndChild()
1571 .EndChild()
1572 .Build();
1573 /* clang-format on */
1574 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1575 MANIFEST_ERROR_MEM_REGION_OVERLAP);
Manish Pandeye68e7932020-04-23 15:29:28 +01001576}
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001577
1578TEST_F(manifest, ffa_invalid_memory_region_attributes)
Raghu Krishnamurthy384693c2021-10-11 13:56:24 -07001579{
Olivier Deprez93644652022-09-09 11:01:12 +02001580 struct_manifest *m;
Raghu Krishnamurthy384693c2021-10-11 13:56:24 -07001581
1582 /* clang-format off */
1583 std::vector<char> dtb = ManifestDtBuilder()
1584 .FfaValidManifest()
1585 .StartChild("rx_tx-info")
1586 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1587 .Property("rx-buffer", "<&rx>")
1588 .Property("tx-buffer", "<&tx>")
1589 .EndChild()
1590 .StartChild("memory-regions")
1591 .Compatible({ "arm,ffa-manifest-memory-regions" })
1592 .StartChild("test-memory")
1593 .Description("test-memory")
1594 .Property("base-address", "<0x7100000>")
1595 .Property("pages-count", "<4>")
1596 .Property("attributes", "<7>")
1597 .EndChild()
1598 .Label("rx")
1599 .StartChild("rx")
1600 .Description("rx-buffer")
1601 .Property("base-address", "<0x7300000>")
1602 .Property("pages-count", "<1>")
1603 .Property("attributes", "<1>")
1604 .EndChild()
1605 .Label("tx")
1606 .StartChild("tx")
1607 .Description("tx-buffer")
1608 .Property("base-address", "<0x7310000>")
1609 .Property("pages-count", "<1>")
1610 .Property("attributes", "<3>")
1611 .EndChild()
1612 .EndChild()
1613 .Build();
1614 /* clang-format on */
1615
1616 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1617 MANIFEST_ERROR_INVALID_MEM_PERM);
1618}
1619
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001620TEST_F(manifest, ffa_invalid_device_region_attributes)
Raghu Krishnamurthy384693c2021-10-11 13:56:24 -07001621{
Olivier Deprez93644652022-09-09 11:01:12 +02001622 struct_manifest *m;
Raghu Krishnamurthy384693c2021-10-11 13:56:24 -07001623
1624 /* clang-format off */
1625 std::vector<char> dtb = ManifestDtBuilder()
1626 .FfaValidManifest()
1627 .StartChild("rx_tx-info")
1628 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1629 .Property("rx-buffer", "<&rx>")
1630 .Property("tx-buffer", "<&tx>")
1631 .EndChild()
1632 .StartChild("memory-regions")
1633 .Compatible({ "arm,ffa-manifest-memory-regions" })
1634 .StartChild("test-memory")
1635 .Description("test-memory")
1636 .Property("base-address", "<0x7100000>")
1637 .Property("pages-count", "<4>")
1638 .Property("attributes", "<3>")
1639 .EndChild()
1640 .Label("rx")
1641 .StartChild("rx")
1642 .Description("rx-buffer")
1643 .Property("base-address", "<0x7300000>")
1644 .Property("pages-count", "<1>")
1645 .Property("attributes", "<1>")
1646 .EndChild()
1647 .Label("tx")
1648 .StartChild("tx")
1649 .Description("tx-buffer")
1650 .Property("base-address", "<0x7310000>")
1651 .Property("pages-count", "<1>")
1652 .Property("attributes", "<3>")
1653 .EndChild()
1654 .EndChild()
1655 .StartChild("device-regions")
1656 .Compatible({ "arm,ffa-manifest-device-regions" })
1657 .StartChild("test-device")
1658 .Description("test-device")
1659 .Property("base-address", "<0x7200000>")
1660 .Property("pages-count", "<16>")
1661 .Property("attributes", "<5>")
1662 .Property("smmu-id", "<1>")
1663 .Property("stream-ids", "<0 1>")
1664 .Property("interrupts", "<2 3>, <4 5>")
1665 .EndChild()
1666 .EndChild()
1667 .Build();
1668 /* clang-format on */
1669
1670 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1671 MANIFEST_ERROR_INVALID_MEM_PERM);
1672}
Manish Pandeye68e7932020-04-23 15:29:28 +01001673
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001674TEST_F(manifest, ffa_valid)
Olivier Deprez62d99e32020-01-09 15:58:07 +01001675{
Olivier Deprez93644652022-09-09 11:01:12 +02001676 struct manifest_vm *vm;
1677 struct_manifest *m;
Olivier Deprez62d99e32020-01-09 15:58:07 +01001678
1679 /* clang-format off */
1680 std::vector<char> dtb = ManifestDtBuilder()
Manish Pandeycb8fbb22020-08-18 00:04:43 +01001681 .FfaValidManifest()
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001682 .StartChild("rx_tx-info")
1683 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1684 .Property("rx-buffer", "<&rx>")
1685 .Property("tx-buffer", "<&tx>")
1686 .EndChild()
Manish Pandey6542f5c2020-04-27 14:37:46 +01001687 .StartChild("memory-regions")
1688 .Compatible({ "arm,ffa-manifest-memory-regions" })
1689 .StartChild("test-memory")
1690 .Description("test-memory")
Karl Meakine92efbe2023-06-01 14:16:22 +01001691 .Property("relative-address", "<0x7100000>")
Manish Pandey6542f5c2020-04-27 14:37:46 +01001692 .Property("pages-count", "<4>")
Raghu Krishnamurthy384693c2021-10-11 13:56:24 -07001693 .Property("attributes", "<3>")
Manish Pandey6542f5c2020-04-27 14:37:46 +01001694 .EndChild()
Olivier Deprez035fa152022-03-14 11:19:10 +01001695 .StartChild("test-memory-ns")
1696 .Description("test-memory")
1697 .Property("base-address", "<0x7200000>")
1698 .Property("pages-count", "<1>")
1699 .Property("attributes", "<0xb>")
1700 .EndChild()
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001701 .Label("rx")
1702 .StartChild("rx")
1703 .Description("rx-buffer")
1704 .Property("base-address", "<0x7300000>")
1705 .Property("pages-count", "<1>")
1706 .Property("attributes", "<1>")
1707 .EndChild()
1708 .Label("tx")
1709 .StartChild("tx")
1710 .Description("tx-buffer")
Daniel Boulby9279b552022-06-28 17:04:01 +01001711 .Property("base-address", "<0x7301000>")
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001712 .Property("pages-count", "<1>")
1713 .Property("attributes", "<3>")
1714 .EndChild()
Manish Pandey6542f5c2020-04-27 14:37:46 +01001715 .EndChild()
Manish Pandeye68e7932020-04-23 15:29:28 +01001716 .StartChild("device-regions")
1717 .Compatible({ "arm,ffa-manifest-device-regions" })
1718 .StartChild("test-device")
1719 .Description("test-device")
Olivier Deprez035fa152022-03-14 11:19:10 +01001720 .Property("base-address", "<0x7400000>")
Manish Pandeye68e7932020-04-23 15:29:28 +01001721 .Property("pages-count", "<16>")
1722 .Property("attributes", "<3>")
1723 .Property("smmu-id", "<1>")
1724 .Property("stream-ids", "<0 1>")
1725 .Property("interrupts", "<2 3>, <4 5>")
1726 .EndChild()
Olivier Deprez035fa152022-03-14 11:19:10 +01001727 .StartChild("test-device-ns")
1728 .Description("test-device")
1729 .Property("base-address", "<0x7500000>")
1730 .Property("pages-count", "<1>")
1731 .Property("attributes", "<0x9>")
1732 .EndChild()
Manish Pandeye68e7932020-04-23 15:29:28 +01001733 .EndChild()
Olivier Deprez62d99e32020-01-09 15:58:07 +01001734 .Build();
1735 /* clang-format on */
Olivier Deprez62d99e32020-01-09 15:58:07 +01001736 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1737
Olivier Deprez93644652022-09-09 11:01:12 +02001738 vm = &m->vm[0];
1739 ASSERT_EQ(vm->partition.ffa_version, 0x10000);
Olivier Deprez62d99e32020-01-09 15:58:07 +01001740 ASSERT_THAT(
Kathleen Capella422b10b2023-06-30 18:28:27 -04001741 std::span(vm->partition.uuids[0].uuid, 4),
Olivier Deprez62d99e32020-01-09 15:58:07 +01001742 ElementsAre(0xb4b5671e, 0x4a904fe1, 0xb81ffb13, 0xdae1dacb));
Olivier Deprez93644652022-09-09 11:01:12 +02001743 ASSERT_EQ(vm->partition.execution_ctx_count, 1);
1744 ASSERT_EQ(vm->partition.run_time_el, S_EL1);
1745 ASSERT_EQ(vm->partition.execution_state, AARCH64);
1746 ASSERT_EQ(vm->partition.ep_offset, 0x00002000);
1747 ASSERT_EQ(vm->partition.xlat_granule, PAGE_4KB);
1748 ASSERT_EQ(vm->partition.boot_order, 0);
1749 ASSERT_EQ(vm->partition.messaging_method, FFA_PARTITION_INDIRECT_MSG);
1750 ASSERT_EQ(vm->partition.ns_interrupts_action, NS_ACTION_ME);
1751 ASSERT_EQ(vm->partition.mem_regions[0].base_address, 0x7100000);
1752 ASSERT_EQ(vm->partition.mem_regions[0].page_count, 4);
1753 ASSERT_EQ(vm->partition.mem_regions[0].attributes, 3);
1754 ASSERT_EQ(vm->partition.mem_regions[1].attributes, (8 | 3));
Raghu Krishnamurthy8c250a92021-07-02 12:16:42 -07001755
Olivier Deprez93644652022-09-09 11:01:12 +02001756 ASSERT_EQ(vm->partition.rxtx.available, true);
1757 ASSERT_EQ(vm->partition.rxtx.rx_buffer->base_address, 0x7300000);
1758 ASSERT_EQ(vm->partition.rxtx.rx_buffer->page_count, 1);
1759 ASSERT_EQ(vm->partition.rxtx.rx_buffer->attributes, 1);
1760 ASSERT_EQ(vm->partition.rxtx.tx_buffer->base_address, 0x7301000);
1761 ASSERT_EQ(vm->partition.rxtx.tx_buffer->page_count, 1);
1762 ASSERT_EQ(vm->partition.rxtx.tx_buffer->attributes, 3);
1763
1764 ASSERT_EQ(vm->partition.dev_regions[0].base_address, 0x7400000);
1765 ASSERT_EQ(vm->partition.dev_regions[0].page_count, 16);
1766 ASSERT_EQ(vm->partition.dev_regions[0].attributes, 3);
1767 ASSERT_EQ(vm->partition.dev_regions[0].smmu_id, 1);
1768 ASSERT_EQ(vm->partition.dev_regions[0].stream_ids[0], 0);
1769 ASSERT_EQ(vm->partition.dev_regions[0].stream_ids[1], 1);
1770 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].id, 2);
1771 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].attributes, 3);
1772 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].id, 4);
1773 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].attributes, 5);
1774 ASSERT_EQ(vm->partition.dev_regions[1].attributes, (8 | 1));
Olivier Deprez62d99e32020-01-09 15:58:07 +01001775}
1776
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001777TEST_F(manifest, ffa_valid_interrupt_target_manifest)
1778{
1779 struct manifest_vm *vm;
1780 struct_manifest *m;
1781
1782 /* clang-format off */
1783 std::vector<char> dtb = ManifestDtBuilder()
1784 .FfaValidManifest()
1785 .StartChild("device-regions")
1786 .Compatible({ "arm,ffa-manifest-device-regions" })
1787 .StartChild("test-device")
1788 .Description("test-device")
1789 .Property("base-address", "<0x7400000>")
1790 .Property("pages-count", "<16>")
1791 .Property("attributes", "<3>")
1792 .Property("smmu-id", "<1>")
1793 .Property("stream-ids", "<0 1>")
1794 .Property("interrupts", "<2 3>, <4 5>")
1795 .Property("interrupts-target", "<2 0x1234 0x5678>, <4 0x12345678 0x87654321>")
1796 .EndChild()
1797 .EndChild()
1798 .Build();
1799 /* clang-format on */
1800
1801 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1802
1803 vm = &m->vm[0];
1804
1805 ASSERT_EQ(vm->partition.dev_regions[0].base_address, 0x7400000);
1806 ASSERT_EQ(vm->partition.dev_regions[0].page_count, 16);
1807 ASSERT_EQ(vm->partition.dev_regions[0].attributes, 3);
1808 ASSERT_EQ(vm->partition.dev_regions[0].smmu_id, 1);
1809 ASSERT_EQ(vm->partition.dev_regions[0].stream_ids[0], 0);
1810 ASSERT_EQ(vm->partition.dev_regions[0].stream_ids[1], 1);
1811 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].id, 2);
1812 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].attributes, 3);
1813 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].mpidr_valid, true);
1814 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].mpidr,
1815 0x123400005678);
1816 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].id, 4);
1817 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].attributes, 5);
1818 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].mpidr_valid, true);
1819 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].mpidr,
1820 0x1234567887654321);
1821}
1822
1823TEST_F(manifest, ffa_invalid_interrupt_target_manifest)
1824{
1825 struct_manifest *m;
1826
1827 /* clang-format off */
1828 std::vector<char> dtb = ManifestDtBuilder()
1829 .FfaValidManifest()
1830 .StartChild("device-regions")
1831 .Compatible({ "arm,ffa-manifest-device-regions" })
1832 .StartChild("test-device")
1833 .Description("test-device")
1834 .Property("base-address", "<0x7400000>")
1835 .Property("pages-count", "<16>")
1836 .Property("attributes", "<3>")
1837 .Property("smmu-id", "<1>")
1838 .Property("stream-ids", "<0 1>")
1839 .Property("interrupts", "<2 3>, <4 5>")
1840 .Property("interrupts-target", "<20 0x1234 0x5678>")
1841 .EndChild()
1842 .EndChild()
1843 .Build();
1844 /* clang-format on */
1845
1846 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1847 MANIFEST_ERROR_INTERRUPT_ID_NOT_IN_LIST);
1848}
1849
Kathleen Capella4a2a6e72023-04-21 14:43:26 -04001850TEST_F(manifest, ffa_boot_order_not_unique)
1851{
1852 struct_manifest *m;
1853 struct memiter it;
1854 struct mm_stage1_locked mm_stage1_locked;
1855 struct boot_params params;
1856 Partition_package spkg_1;
1857 Partition_package spkg_2;
1858
1859 /* clang-format off */
1860 std::vector<char> dtb1 = ManifestDtBuilder()
1861 .Compatible({ "arm,ffa-manifest-1.0" })
1862 .Property("ffa-version", "<0x10001>")
1863 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1864 .FfaLoadAddress((uint64_t)&spkg_1)
1865 .Property("execution-ctx-count", "<1>")
1866 .Property("exception-level", "<1>")
1867 .Property("execution-state", "<0>")
1868 .Property("entrypoint-offset", "<0x00002000>")
1869 .Property("xlat-granule", "<0>")
1870 .Property("boot-order", "<1>")
1871 .Property("messaging-method", "<1>")
1872 .Property("ns-interrupts-action", "<0>")
1873 .Build();
1874
1875 std::vector<char> dtb2 = ManifestDtBuilder()
1876 .Compatible({ "arm,ffa-manifest-1.0" })
1877 .Property("ffa-version", "<0x10001>")
1878 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
1879 .FfaLoadAddress((uint64_t)&spkg_2)
1880 .Property("execution-ctx-count", "<1>")
1881 .Property("exception-level", "<1>")
1882 .Property("execution-state", "<0>")
1883 .Property("entrypoint-offset", "<0x00002000>")
1884 .Property("xlat-granule", "<0>")
1885 .Property("boot-order", "<1>")
1886 .Property("messaging-method", "<1>")
1887 .Property("ns-interrupts-action", "<0>")
1888 .Build();
1889
1890 /* clang-format on */
1891 spkg_1.init(dtb1);
1892 spkg_2.init(dtb2);
1893
1894 /* clang-format off */
1895 std::vector<char> core_dtb = ManifestDtBuilder()
1896 .StartChild("hypervisor")
1897 .Compatible()
1898 .StartChild("vm1")
1899 .DebugName("ffa_partition_1")
1900 .FfaPartition()
1901 .LoadAddress((uint64_t)&spkg_1)
1902 .VcpuCount(1)
1903 .MemSize(0x10000000)
1904 .EndChild()
1905 .StartChild("vm2")
1906 .DebugName("ffa_partition_2")
1907 .FfaPartition()
1908 .LoadAddress((uint64_t)&spkg_2)
1909 .VcpuCount(1)
1910 .MemSize(0x10000000)
1911 .EndChild()
1912 .EndChild()
1913 .Build();
1914 /* clang-format on */
1915
1916 boot_params_init(&params, nullptr);
1917 memiter_init(&it, core_dtb.data(), core_dtb.size());
1918 ASSERT_EQ(manifest_init(mm_stage1_locked, &m, &it, &params, &ppool),
1919 MANIFEST_ERROR_INVALID_BOOT_ORDER);
1920}
Daniel Boulby941ef342023-11-21 13:47:15 +00001921
Kathleen Capella422b10b2023-06-30 18:28:27 -04001922TEST_F(manifest, ffa_valid_multiple_uuids)
1923{
1924 struct manifest_vm *vm;
1925 struct_manifest *m;
1926
1927 /* clang-format off */
1928 std::vector<char> dtb = ManifestDtBuilder()
1929 .Compatible({ "arm,ffa-manifest-1.0" })
1930 .Property("ffa-version", "<0x10002>")
1931 .Property("uuid",
1932 "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>,\
1933 <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
1934 .Property("execution-ctx-count", "<1>")
1935 .Property("exception-level", "<2>")
1936 .Property("execution-state", "<0>")
1937 .Property("entrypoint-offset", "<0x00002000>")
1938 .Property("xlat-granule", "<0>")
1939 .Property("boot-order", "<0>")
1940 .Property("messaging-method", "<4>")
1941 .Property("ns-interrupts-action", "<1>")
1942 .Build();
1943 /* clang-format on */
1944 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1945
1946 vm = &m->vm[0];
1947 ASSERT_EQ(vm->partition.ffa_version, 0x10002);
1948 ASSERT_THAT(
1949 std::span(vm->partition.uuids[0].uuid, 4),
1950 ElementsAre(0xb4b5671e, 0x4a904fe1, 0xb81ffb13, 0xdae1dacb));
1951 ASSERT_THAT(
1952 std::span(vm->partition.uuids[1].uuid, 4),
1953 ElementsAre(0xb4b5671e, 0x4a904fe1, 0xb81ffb13, 0xdae1daaa));
1954 ASSERT_EQ(vm->partition.uuid_count, 2);
1955 ASSERT_EQ(vm->partition.execution_ctx_count, 1);
1956 ASSERT_EQ(vm->partition.run_time_el, S_EL1);
1957 ASSERT_EQ(vm->partition.execution_state, AARCH64);
1958 ASSERT_EQ(vm->partition.ep_offset, 0x00002000);
1959 ASSERT_EQ(vm->partition.xlat_granule, PAGE_4KB);
1960 ASSERT_EQ(vm->partition.boot_order, 0);
1961 ASSERT_EQ(vm->partition.messaging_method, FFA_PARTITION_INDIRECT_MSG);
1962 ASSERT_EQ(vm->partition.ns_interrupts_action, NS_ACTION_ME);
1963}
1964TEST_F(manifest, ffa_uuid_all_zeros)
1965{
1966 struct_manifest *m;
1967
1968 /* clang-format off */
1969 std::vector<char> dtb = ManifestDtBuilder()
1970 .Compatible({ "arm,ffa-manifest-1.0" })
1971 .Property("ffa-version", "<0x10002>")
1972 .Property("uuid",
1973 "<0x0 0x0 0x0 0x0>, <0x0 0x0 0x0 0x0>")
1974 .Property("execution-ctx-count", "<1>")
1975 .Property("exception-level", "<2>")
1976 .Property("execution-state", "<0>")
1977 .Property("entrypoint-offset", "<0x00002000>")
1978 .Property("xlat-granule", "<0>")
1979 .Property("boot-order", "<0>")
1980 .Property("messaging-method", "<4>")
1981 .Property("ns-interrupts-action", "<1>")
1982 .Build();
1983 /* clang-format on */
1984 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1985 MANIFEST_ERROR_UUID_ALL_ZEROS);
1986}
Daniel Boulby941ef342023-11-21 13:47:15 +00001987
1988/*
1989 * Test that the address space of two device region nodes specified across
1990 * different SPs cannot overlap.
1991 */
1992TEST_F(manifest, ffa_device_region_multi_sps)
1993{
1994 struct_manifest *m;
1995 struct memiter it;
1996 struct mm_stage1_locked mm_stage1_locked;
1997 struct boot_params params;
1998 Partition_package spkg_1;
1999 Partition_package spkg_2;
2000
2001 /* clang-format off */
2002 std::vector<char> dtb1 = ManifestDtBuilder()
2003 .Compatible({ "arm,ffa-manifest-1.0" })
2004 .Property("ffa-version", "<0x10001>")
2005 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
2006 .FfaLoadAddress((uint64_t)&spkg_1)
2007 .Property("execution-ctx-count", "<1>")
2008 .Property("exception-level", "<0>")
2009 .Property("execution-state", "<0>")
2010 .Property("entrypoint-offset", "<0x0>")
2011 .Property("xlat-granule", "<0>")
2012 .Property("messaging-method", "<0x7>")
2013 .StartChild("device-regions")
2014 .Compatible({ "arm,ffa-manifest-device-regions" })
2015 .StartChild("test-device-0")
2016 .Description("test-device-0")
2017 .Property("base-address", "<0x7200000>")
2018 .Property("pages-count", "<16>")
2019 .Property("attributes", "<3>")
2020 .EndChild()
2021 .EndChild()
2022 .Build();
2023
2024 std::vector<char> dtb2 = ManifestDtBuilder()
2025 .Compatible({ "arm,ffa-manifest-1.0" })
2026 .Property("ffa-version", "<0x10001>")
2027 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
2028 .FfaLoadAddress((uint64_t)&spkg_2)
2029 .Property("execution-ctx-count", "<1>")
2030 .Property("exception-level", "<0>")
2031 .Property("execution-state", "<0>")
2032 .Property("entrypoint-offset", "<0x0>")
2033 .Property("xlat-granule", "<0>")
2034 .Property("messaging-method", "<0x7>")
2035 .StartChild("device-regions")
2036 .Compatible({ "arm,ffa-manifest-device-regions" })
2037 .StartChild("test-device-0")
2038 .Description("test-device-1")
2039 .Property("base-address", "<0x7200000>")
2040 .Property("pages-count", "<16>")
2041 .Property("attributes", "<3>")
2042 .EndChild()
2043 .EndChild()
2044 .Build();
2045
2046 /* clang-format on */
2047 spkg_1.init(dtb1);
2048 spkg_2.init(dtb2);
2049
2050 /* clang-format off */
2051 std::vector<char> core_dtb = ManifestDtBuilder()
2052 .StartChild("hypervisor")
2053 .Compatible()
2054 .StartChild("vm1")
2055 .DebugName("ffa_partition_1")
2056 .FfaPartition()
2057 .LoadAddress((uint64_t)&spkg_1)
2058 .VcpuCount(1)
2059 .MemSize(0x4000)
2060 .EndChild()
2061 .StartChild("vm2")
2062 .DebugName("ffa_partition_2")
2063 .FfaPartition()
2064 .LoadAddress((uint64_t)&spkg_2)
2065 .VcpuCount(1)
2066 .MemSize(0x4000)
2067 .EndChild()
2068 .EndChild()
2069 .Build();
2070 /* clang-format on */
2071 boot_params_init(&params, &spkg_1);
2072 memiter_init(&it, core_dtb.data(), core_dtb.size());
2073 ASSERT_EQ(manifest_init(mm_stage1_locked, &m, &it, &params, &ppool),
2074 MANIFEST_ERROR_MEM_REGION_OVERLAP);
2075
2076 manifest_dealloc();
2077
2078 /* clang-format off */
2079 dtb1 = ManifestDtBuilder()
2080 .Compatible({ "arm,ffa-manifest-1.0" })
2081 .Property("ffa-version", "<0x10001>")
2082 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
2083 .FfaLoadAddress((uint64_t)&spkg_1)
2084 .Property("execution-ctx-count", "<1>")
2085 .Property("exception-level", "<0>")
2086 .Property("execution-state", "<0>")
2087 .Property("entrypoint-offset", "<0x0>")
2088 .Property("xlat-granule", "<0>")
2089 .Property("messaging-method", "<0x7>")
2090 .StartChild("device-regions")
2091 .Compatible({ "arm,ffa-manifest-device-regions" })
2092 .StartChild("test-device-0")
2093 .Description("test-device-0")
2094 .Property("base-address", "<0x7200000>")
2095 .Property("pages-count", "<16>")
2096 .Property("attributes", "<3>")
2097 .EndChild()
2098 .EndChild()
2099 .Build();
2100
2101 dtb2 = ManifestDtBuilder()
2102 .Compatible({ "arm,ffa-manifest-1.0" })
2103 .Property("ffa-version", "<0x10001>")
2104 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
2105 .FfaLoadAddress((uint64_t)&spkg_2)
2106 .Property("execution-ctx-count", "<1>")
2107 .Property("exception-level", "<0>")
2108 .Property("execution-state", "<0>")
2109 .Property("entrypoint-offset", "<0x0>")
2110 .Property("xlat-granule", "<0>")
2111 .Property("messaging-method", "<0x7>")
2112 .StartChild("device-regions")
2113 .Compatible({ "arm,ffa-manifest-device-regions" })
2114 .StartChild("test-device-0")
2115 .Description("test-device-1")
2116 .Property("base-address", "<0x7300000>")
2117 .Property("pages-count", "<16>")
2118 .Property("attributes", "<3>")
2119 .EndChild()
2120 .EndChild()
2121 .Build();
2122
2123 /* clang-format on */
2124 spkg_1.init(dtb1);
2125 spkg_2.init(dtb2);
2126
2127 /* clang-format off */
2128 core_dtb = ManifestDtBuilder()
2129 .StartChild("hypervisor")
2130 .Compatible()
2131 .StartChild("vm1")
2132 .DebugName("ffa_partition_1")
2133 .FfaPartition()
2134 .LoadAddress((uint64_t)&spkg_1)
2135 .VcpuCount(1)
2136 .MemSize(0x4000)
2137 .EndChild()
2138 .StartChild("vm2")
2139 .DebugName("ffa_partition_2")
2140 .FfaPartition()
2141 .LoadAddress((uint64_t)&spkg_2)
2142 .VcpuCount(1)
2143 .MemSize(0x4000)
2144 .EndChild()
2145 .EndChild()
2146 .Build();
2147 /* clang-format on */
2148 boot_params_init(&params, &spkg_1);
2149 memiter_init(&it, core_dtb.data(), core_dtb.size());
2150 ASSERT_EQ(manifest_init(mm_stage1_locked, &m, &it, &params, &ppool),
2151 MANIFEST_SUCCESS);
2152}
David Brazdil7a462ec2019-08-15 12:27:47 +01002153} /* namespace */