blob: a64d3ab0c9bf7577c379d3ca76329bce22bd24ab [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;
Daniel Boulby4339edc2024-02-21 14:59:00 +0000408
409 params->ns_device_mem_ranges[0].begin =
410 pa_init((uintpaddr_t)0x20000000);
411 params->ns_device_mem_ranges[0].end =
412 pa_init((uintpaddr_t)0x24000000);
413 params->ns_device_mem_ranges_count = 1;
414
415 params->device_mem_ranges[0].begin =
416 pa_init((uintpaddr_t)0x24000000);
417 params->device_mem_ranges[0].end =
418 pa_init((uintpaddr_t)0x28000000);
419 params->device_mem_ranges_count = 1;
J-Alves77b6f4f2023-03-15 11:34:49 +0000420 }
421
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100422 enum manifest_return_code manifest_from_vec(
Olivier Deprez93644652022-09-09 11:01:12 +0200423 struct_manifest **m, const std::vector<char> &vec)
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100424 {
425 struct memiter it;
426 struct mm_stage1_locked mm_stage1_locked;
J-Alves77b6f4f2023-03-15 11:34:49 +0000427 struct boot_params params;
428
429 boot_params_init(&params, nullptr);
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100430
431 memiter_init(&it, vec.data(), vec.size());
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100432
J-Alves77b6f4f2023-03-15 11:34:49 +0000433 return manifest_init(mm_stage1_locked, m, &it, &params, &ppool);
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100434 }
435
436 enum manifest_return_code ffa_manifest_from_vec(
Olivier Deprez93644652022-09-09 11:01:12 +0200437 struct_manifest **m, const std::vector<char> &vec)
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100438 {
439 struct memiter it;
440 struct mm_stage1_locked mm_stage1_locked;
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100441 Partition_package spkg(vec);
J-Alves77b6f4f2023-03-15 11:34:49 +0000442 struct boot_params params;
443
444 boot_params_init(&params, &spkg);
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100445
446 /* clang-format off */
447 std::vector<char> core_dtb = ManifestDtBuilder()
448 .StartChild("hypervisor")
449 .Compatible()
450 .StartChild("vm1")
451 .DebugName("primary_vm")
452 .FfaPartition()
453 .LoadAddress((uint64_t)&spkg)
454 .EndChild()
455 .EndChild()
456 .Build();
457 /* clang-format on */
458 memiter_init(&it, core_dtb.data(), core_dtb.size());
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100459
J-Alves77b6f4f2023-03-15 11:34:49 +0000460 return manifest_init(mm_stage1_locked, m, &it, &params, &ppool);
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100461 }
462};
463
464TEST_F(manifest, no_hypervisor_node)
David Brazdil7a462ec2019-08-15 12:27:47 +0100465{
Olivier Deprez93644652022-09-09 11:01:12 +0200466 struct_manifest *m;
David Brazdil52256ff2019-08-23 15:15:15 +0100467 std::vector<char> dtb = ManifestDtBuilder().Build();
David Brazdil7a462ec2019-08-15 12:27:47 +0100468
David Brazdila2358d42020-01-27 18:51:38 +0000469 ASSERT_EQ(manifest_from_vec(&m, dtb),
David Brazdil7a462ec2019-08-15 12:27:47 +0100470 MANIFEST_ERROR_NO_HYPERVISOR_FDT_NODE);
471}
472
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100473TEST_F(manifest, no_compatible_property)
David Brazdil7a462ec2019-08-15 12:27:47 +0100474{
Olivier Deprez93644652022-09-09 11:01:12 +0200475 struct_manifest *m;
David Brazdil7a462ec2019-08-15 12:27:47 +0100476
David Brazdil52256ff2019-08-23 15:15:15 +0100477 /* clang-format off */
478 std::vector<char> dtb = ManifestDtBuilder()
479 .StartChild("hypervisor")
480 .EndChild()
481 .Build();
482 /* clang-format on */
483
David Brazdilf4925382020-03-25 13:33:51 +0000484 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_ERROR_NOT_COMPATIBLE);
David Brazdil7a462ec2019-08-15 12:27:47 +0100485}
486
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100487TEST_F(manifest, not_compatible)
David Brazdil7a462ec2019-08-15 12:27:47 +0100488{
Olivier Deprez93644652022-09-09 11:01:12 +0200489 struct_manifest *m;
David Brazdil7a462ec2019-08-15 12:27:47 +0100490
David Brazdil52256ff2019-08-23 15:15:15 +0100491 /* clang-format off */
492 std::vector<char> dtb = ManifestDtBuilder()
493 .StartChild("hypervisor")
David Brazdil74e9c3b2019-08-28 11:09:08 +0100494 .Compatible({ "foo,bar" })
495 .EndChild()
496 .Build();
497 /* clang-format on */
498
David Brazdila2358d42020-01-27 18:51:38 +0000499 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_ERROR_NOT_COMPATIBLE);
David Brazdil74e9c3b2019-08-28 11:09:08 +0100500}
501
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100502TEST_F(manifest, compatible_one_of_many)
David Brazdil74e9c3b2019-08-28 11:09:08 +0100503{
Olivier Deprez93644652022-09-09 11:01:12 +0200504 struct_manifest *m;
David Brazdil74e9c3b2019-08-28 11:09:08 +0100505
506 /* clang-format off */
507 std::vector<char> dtb = ManifestDtBuilder()
508 .StartChild("hypervisor")
509 .Compatible({ "foo,bar", "hafnium,hafnium" })
510 .StartChild("vm1")
511 .DebugName("primary")
512 .EndChild()
513 .EndChild()
514 .Build();
515 /* clang-format on */
516
David Brazdila2358d42020-01-27 18:51:38 +0000517 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
David Brazdil74e9c3b2019-08-28 11:09:08 +0100518}
519
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100520TEST_F(manifest, no_vm_nodes)
David Brazdil74e9c3b2019-08-28 11:09:08 +0100521{
Olivier Deprez93644652022-09-09 11:01:12 +0200522 struct_manifest *m;
David Brazdil74e9c3b2019-08-28 11:09:08 +0100523
524 /* clang-format off */
525 std::vector<char> dtb = ManifestDtBuilder()
526 .StartChild("hypervisor")
527 .Compatible()
528 .EndChild()
529 .Build();
530 /* clang-format on */
531
David Brazdila2358d42020-01-27 18:51:38 +0000532 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_ERROR_NO_PRIMARY_VM);
David Brazdil0dbb41f2019-09-09 18:03:35 +0100533}
534
535static std::vector<char> gen_long_string_dtb(bool valid)
536{
537 const char last_valid[] = "1234567890123456789012345678901";
538 const char first_invalid[] = "12345678901234567890123456789012";
David Brazdil136f2942019-09-23 14:11:03 +0100539 static_assert(sizeof(last_valid) == STRING_MAX_SIZE);
540 static_assert(sizeof(first_invalid) == STRING_MAX_SIZE + 1);
David Brazdil0dbb41f2019-09-09 18:03:35 +0100541
542 /* clang-format off */
543 return ManifestDtBuilder()
544 .StartChild("hypervisor")
545 .Compatible()
546 .StartChild("vm1")
547 .DebugName(valid ? last_valid : first_invalid)
548 .EndChild()
549 .EndChild()
550 .Build();
551 /* clang-format on */
552}
553
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100554TEST_F(manifest, long_string)
David Brazdil0dbb41f2019-09-09 18:03:35 +0100555{
Olivier Deprez93644652022-09-09 11:01:12 +0200556 struct_manifest *m;
David Brazdil0dbb41f2019-09-09 18:03:35 +0100557 std::vector<char> dtb_last_valid = gen_long_string_dtb(true);
558 std::vector<char> dtb_first_invalid = gen_long_string_dtb(false);
559
David Brazdila2358d42020-01-27 18:51:38 +0000560 ASSERT_EQ(manifest_from_vec(&m, dtb_last_valid), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200561 manifest_dealloc();
562
David Brazdila2358d42020-01-27 18:51:38 +0000563 ASSERT_EQ(manifest_from_vec(&m, dtb_first_invalid),
564 MANIFEST_ERROR_STRING_TOO_LONG);
David Brazdil74e9c3b2019-08-28 11:09:08 +0100565}
566
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100567TEST_F(manifest, reserved_vm_id)
David Brazdil74e9c3b2019-08-28 11:09:08 +0100568{
Olivier Deprez93644652022-09-09 11:01:12 +0200569 struct_manifest *m;
David Brazdil74e9c3b2019-08-28 11:09:08 +0100570
571 /* clang-format off */
572 std::vector<char> dtb = ManifestDtBuilder()
573 .StartChild("hypervisor")
574 .Compatible()
David Brazdil52256ff2019-08-23 15:15:15 +0100575 .StartChild("vm1")
576 .DebugName("primary_vm")
577 .EndChild()
578 .StartChild("vm0")
579 .DebugName("reserved_vm")
580 .VcpuCount(1)
581 .MemSize(0x1000)
582 .KernelFilename("kernel")
583 .EndChild()
584 .EndChild()
585 .Build();
586 /* clang-format on */
587
David Brazdila2358d42020-01-27 18:51:38 +0000588 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_ERROR_RESERVED_VM_ID);
David Brazdil7a462ec2019-08-15 12:27:47 +0100589}
590
Andrew Scullae9962e2019-10-03 16:51:16 +0100591static std::vector<char> gen_vcpu_count_limit_dtb(uint32_t vcpu_count)
David Brazdil52256ff2019-08-23 15:15:15 +0100592{
593 /* clang-format off */
594 return ManifestDtBuilder()
595 .StartChild("hypervisor")
David Brazdil74e9c3b2019-08-28 11:09:08 +0100596 .Compatible()
David Brazdil52256ff2019-08-23 15:15:15 +0100597 .StartChild("vm1")
598 .DebugName("primary_vm")
599 .EndChild()
600 .StartChild("vm2")
601 .DebugName("secondary_vm")
602 .VcpuCount(vcpu_count)
603 .MemSize(0x1000)
604 .KernelFilename("kernel")
605 .EndChild()
606 .EndChild()
607 .Build();
608 /* clang-format on */
609}
David Brazdil7a462ec2019-08-15 12:27:47 +0100610
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100611TEST_F(manifest, vcpu_count_limit)
David Brazdil7a462ec2019-08-15 12:27:47 +0100612{
Olivier Deprez93644652022-09-09 11:01:12 +0200613 struct_manifest *m;
David Brazdil52256ff2019-08-23 15:15:15 +0100614 std::vector<char> dtb_last_valid = gen_vcpu_count_limit_dtb(UINT16_MAX);
615 std::vector<char> dtb_first_invalid =
616 gen_vcpu_count_limit_dtb(UINT16_MAX + 1);
David Brazdil7a462ec2019-08-15 12:27:47 +0100617
David Brazdila2358d42020-01-27 18:51:38 +0000618 ASSERT_EQ(manifest_from_vec(&m, dtb_last_valid), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200619 ASSERT_EQ(m->vm_count, 2);
620 ASSERT_EQ(m->vm[1].secondary.vcpu_count, UINT16_MAX);
621 manifest_dealloc();
David Brazdil7a462ec2019-08-15 12:27:47 +0100622
David Brazdila2358d42020-01-27 18:51:38 +0000623 ASSERT_EQ(manifest_from_vec(&m, dtb_first_invalid),
David Brazdil0dbb41f2019-09-09 18:03:35 +0100624 MANIFEST_ERROR_INTEGER_OVERFLOW);
David Brazdil7a462ec2019-08-15 12:27:47 +0100625}
626
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100627TEST_F(manifest, no_ramdisk_primary)
David Brazdile6f83222019-09-23 14:47:37 +0100628{
Olivier Deprez93644652022-09-09 11:01:12 +0200629 struct_manifest *m;
David Brazdile6f83222019-09-23 14:47:37 +0100630
631 /* clang-format off */
632 std::vector<char> dtb = ManifestDtBuilder()
633 .StartChild("hypervisor")
634 .Compatible()
635 .StartChild("vm1")
636 .DebugName("primary_vm")
637 .EndChild()
638 .EndChild()
639 .Build();
640 /* clang-format on */
641
David Brazdila2358d42020-01-27 18:51:38 +0000642 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200643 ASSERT_EQ(m->vm_count, 1);
644 ASSERT_STREQ(string_data(&m->vm[0].debug_name), "primary_vm");
645 ASSERT_STREQ(string_data(&m->vm[0].primary.ramdisk_filename), "");
David Brazdile6f83222019-09-23 14:47:37 +0100646}
647
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100648TEST_F(manifest, no_boot_address_primary)
David Brazdil080ee312020-02-25 15:30:30 -0800649{
Olivier Deprez93644652022-09-09 11:01:12 +0200650 struct_manifest *m;
David Brazdil080ee312020-02-25 15:30:30 -0800651
652 /* clang-format off */
653 std::vector<char> dtb = ManifestDtBuilder()
654 .StartChild("hypervisor")
655 .Compatible()
656 .StartChild("vm1")
657 .DebugName("primary_vm")
658 .EndChild()
659 .EndChild()
660 .Build();
661 /* clang-format on */
662
663 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200664 ASSERT_EQ(m->vm_count, 1);
665 ASSERT_STREQ(string_data(&m->vm[0].debug_name), "primary_vm");
666 ASSERT_EQ(m->vm[0].primary.boot_address, MANIFEST_INVALID_ADDRESS);
David Brazdil080ee312020-02-25 15:30:30 -0800667}
668
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100669TEST_F(manifest, boot_address_primary)
David Brazdil080ee312020-02-25 15:30:30 -0800670{
Olivier Deprez93644652022-09-09 11:01:12 +0200671 struct_manifest *m;
David Brazdil080ee312020-02-25 15:30:30 -0800672 const uint64_t addr = UINT64_C(0x12345678ABCDEFEF);
673
674 /* clang-format off */
675 std::vector<char> dtb = ManifestDtBuilder()
676 .StartChild("hypervisor")
677 .Compatible()
678 .StartChild("vm1")
679 .DebugName("primary_vm")
680 .BootAddress(addr)
681 .EndChild()
682 .EndChild()
683 .Build();
684 /* clang-format on */
685
686 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200687 ASSERT_EQ(m->vm_count, 1);
688 ASSERT_STREQ(string_data(&m->vm[0].debug_name), "primary_vm");
689 ASSERT_EQ(m->vm[0].primary.boot_address, addr);
David Brazdil080ee312020-02-25 15:30:30 -0800690}
691
Andrew Scullb2c3a242019-11-04 13:52:36 +0000692static std::vector<char> gen_malformed_boolean_dtb(
693 const std::string_view &value)
Andrew Scullae9962e2019-10-03 16:51:16 +0100694{
Andrew Scullae9962e2019-10-03 16:51:16 +0100695 /* clang-format off */
Andrew Scullb2c3a242019-11-04 13:52:36 +0000696 return ManifestDtBuilder()
Andrew Scullae9962e2019-10-03 16:51:16 +0100697 .StartChild("hypervisor")
698 .Compatible()
699 .StartChild("vm1")
700 .DebugName("primary_vm")
Andrew Scullb2c3a242019-11-04 13:52:36 +0000701 .Property("smc_whitelist_permissive", value)
Andrew Scull5dc089e2019-11-04 13:21:03 +0000702 .EndChild()
Andrew Scullae9962e2019-10-03 16:51:16 +0100703 .EndChild()
704 .Build();
705 /* clang-format on */
Andrew Scullb2c3a242019-11-04 13:52:36 +0000706}
Andrew Scullae9962e2019-10-03 16:51:16 +0100707
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100708TEST_F(manifest, malformed_booleans)
Andrew Scullb2c3a242019-11-04 13:52:36 +0000709{
Olivier Deprez93644652022-09-09 11:01:12 +0200710 struct_manifest *m;
Andrew Scullae9962e2019-10-03 16:51:16 +0100711
Andrew Scullb2c3a242019-11-04 13:52:36 +0000712 std::vector<char> dtb_false = gen_malformed_boolean_dtb("\"false\"");
713 std::vector<char> dtb_true = gen_malformed_boolean_dtb("\"true\"");
714 std::vector<char> dtb_0 = gen_malformed_boolean_dtb("\"<0>\"");
715 std::vector<char> dtb_1 = gen_malformed_boolean_dtb("\"<1>\"");
Andrew Scullae9962e2019-10-03 16:51:16 +0100716
David Brazdila2358d42020-01-27 18:51:38 +0000717 ASSERT_EQ(manifest_from_vec(&m, dtb_false),
Andrew Scullb2c3a242019-11-04 13:52:36 +0000718 MANIFEST_ERROR_MALFORMED_BOOLEAN);
Olivier Deprez93644652022-09-09 11:01:12 +0200719 manifest_dealloc();
720
David Brazdila2358d42020-01-27 18:51:38 +0000721 ASSERT_EQ(manifest_from_vec(&m, dtb_true),
Andrew Scullb2c3a242019-11-04 13:52:36 +0000722 MANIFEST_ERROR_MALFORMED_BOOLEAN);
Olivier Deprez93644652022-09-09 11:01:12 +0200723 manifest_dealloc();
724
David Brazdila2358d42020-01-27 18:51:38 +0000725 ASSERT_EQ(manifest_from_vec(&m, dtb_0),
Andrew Scullb2c3a242019-11-04 13:52:36 +0000726 MANIFEST_ERROR_MALFORMED_BOOLEAN);
Olivier Deprez93644652022-09-09 11:01:12 +0200727 manifest_dealloc();
728
David Brazdila2358d42020-01-27 18:51:38 +0000729 ASSERT_EQ(manifest_from_vec(&m, dtb_1),
Andrew Scullb2c3a242019-11-04 13:52:36 +0000730 MANIFEST_ERROR_MALFORMED_BOOLEAN);
Andrew Scullae9962e2019-10-03 16:51:16 +0100731}
732
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100733TEST_F(manifest, valid)
David Brazdil7a462ec2019-08-15 12:27:47 +0100734{
Olivier Deprez93644652022-09-09 11:01:12 +0200735 struct_manifest *m;
David Brazdil7a462ec2019-08-15 12:27:47 +0100736 struct manifest_vm *vm;
David Brazdil7a462ec2019-08-15 12:27:47 +0100737
David Brazdil52256ff2019-08-23 15:15:15 +0100738 /* clang-format off */
739 std::vector<char> dtb = ManifestDtBuilder()
740 .StartChild("hypervisor")
David Brazdil74e9c3b2019-08-28 11:09:08 +0100741 .Compatible()
David Brazdil52256ff2019-08-23 15:15:15 +0100742 .StartChild("vm1")
743 .DebugName("primary_vm")
Andrew Scull72b43c02019-09-18 13:53:45 +0100744 .KernelFilename("primary_kernel")
David Brazdile6f83222019-09-23 14:47:37 +0100745 .RamdiskFilename("primary_ramdisk")
Andrew Scullae9962e2019-10-03 16:51:16 +0100746 .SmcWhitelist({0x32000000, 0x33001111})
David Brazdil52256ff2019-08-23 15:15:15 +0100747 .EndChild()
748 .StartChild("vm3")
749 .DebugName("second_secondary_vm")
750 .VcpuCount(43)
751 .MemSize(0x12345)
Andrew Scull72b43c02019-09-18 13:53:45 +0100752 .KernelFilename("second_secondary_kernel")
David Brazdil52256ff2019-08-23 15:15:15 +0100753 .EndChild()
754 .StartChild("vm2")
755 .DebugName("first_secondary_vm")
756 .VcpuCount(42)
757 .MemSize(12345)
Andrew Scullae9962e2019-10-03 16:51:16 +0100758 .SmcWhitelist({0x04000000, 0x30002222, 0x31445566})
759 .SmcWhitelistPermissive()
David Brazdil52256ff2019-08-23 15:15:15 +0100760 .EndChild()
761 .EndChild()
762 .Build();
763 /* clang-format on */
764
David Brazdila2358d42020-01-27 18:51:38 +0000765 ASSERT_EQ(manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
Olivier Deprez93644652022-09-09 11:01:12 +0200766 ASSERT_EQ(m->vm_count, 3);
David Brazdil7a462ec2019-08-15 12:27:47 +0100767
Olivier Deprez93644652022-09-09 11:01:12 +0200768 vm = &m->vm[0];
David Brazdil136f2942019-09-23 14:11:03 +0100769 ASSERT_STREQ(string_data(&vm->debug_name), "primary_vm");
770 ASSERT_STREQ(string_data(&vm->kernel_filename), "primary_kernel");
David Brazdile6f83222019-09-23 14:47:37 +0100771 ASSERT_STREQ(string_data(&vm->primary.ramdisk_filename),
772 "primary_ramdisk");
Andrew Scullae9962e2019-10-03 16:51:16 +0100773 ASSERT_THAT(
774 std::span(vm->smc_whitelist.smcs, vm->smc_whitelist.smc_count),
775 ElementsAre(0x32000000, 0x33001111));
776 ASSERT_FALSE(vm->smc_whitelist.permissive);
David Brazdil7a462ec2019-08-15 12:27:47 +0100777
Olivier Deprez93644652022-09-09 11:01:12 +0200778 vm = &m->vm[1];
David Brazdil136f2942019-09-23 14:11:03 +0100779 ASSERT_STREQ(string_data(&vm->debug_name), "first_secondary_vm");
780 ASSERT_STREQ(string_data(&vm->kernel_filename), "");
David Brazdil7a462ec2019-08-15 12:27:47 +0100781 ASSERT_EQ(vm->secondary.vcpu_count, 42);
782 ASSERT_EQ(vm->secondary.mem_size, 12345);
Andrew Scullae9962e2019-10-03 16:51:16 +0100783 ASSERT_THAT(
784 std::span(vm->smc_whitelist.smcs, vm->smc_whitelist.smc_count),
785 ElementsAre(0x04000000, 0x30002222, 0x31445566));
786 ASSERT_TRUE(vm->smc_whitelist.permissive);
David Brazdil7a462ec2019-08-15 12:27:47 +0100787
Olivier Deprez93644652022-09-09 11:01:12 +0200788 vm = &m->vm[2];
David Brazdil136f2942019-09-23 14:11:03 +0100789 ASSERT_STREQ(string_data(&vm->debug_name), "second_secondary_vm");
790 ASSERT_STREQ(string_data(&vm->kernel_filename),
791 "second_secondary_kernel");
David Brazdil7a462ec2019-08-15 12:27:47 +0100792 ASSERT_EQ(vm->secondary.vcpu_count, 43);
793 ASSERT_EQ(vm->secondary.mem_size, 0x12345);
Andrew Scullae9962e2019-10-03 16:51:16 +0100794 ASSERT_THAT(
795 std::span(vm->smc_whitelist.smcs, vm->smc_whitelist.smc_count),
796 IsEmpty());
797 ASSERT_FALSE(vm->smc_whitelist.permissive);
David Brazdil7a462ec2019-08-15 12:27:47 +0100798}
799
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100800TEST_F(manifest, ffa_not_compatible)
Olivier Deprez62d99e32020-01-09 15:58:07 +0100801{
Olivier Deprez93644652022-09-09 11:01:12 +0200802 struct_manifest *m;
Olivier Deprez62d99e32020-01-09 15:58:07 +0100803
804 /* clang-format off */
805 std::vector<char> dtb = ManifestDtBuilder()
806 .Compatible({ "arm,ffa-manifest-2.0" })
807 .Property("ffa-version", "<0x10000>")
808 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
809 .Property("execution-ctx-count", "<1>")
810 .Property("exception-level", "<2>")
811 .Property("execution-state", "<0>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000812 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100813 .Property("xlat-granule", "<0>")
814 .Property("messaging-method", "<1>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500815 .Property("ns-interrupts-action", "<1>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100816 .Build();
817 /* clang-format on */
818
819 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
820 MANIFEST_ERROR_NOT_COMPATIBLE);
821}
822
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100823TEST_F(manifest, ffa_missing_property)
Olivier Deprez62d99e32020-01-09 15:58:07 +0100824{
Olivier Deprez93644652022-09-09 11:01:12 +0200825 struct_manifest *m;
Olivier Deprez62d99e32020-01-09 15:58:07 +0100826
827 /* clang-format off */
828 std::vector<char> dtb = ManifestDtBuilder()
829 .Compatible({ "arm,ffa-manifest-1.0" })
830 .Property("ffa-version", "<0x10000>")
831 .Build();
832 /* clang-format on */
833
834 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
835 MANIFEST_ERROR_PROPERTY_NOT_FOUND);
836}
837
Daniel Boulby801f8ef2022-06-27 14:21:01 +0100838TEST_F(manifest, ffa_validate_sanity_check)
Olivier Deprez62d99e32020-01-09 15:58:07 +0100839{
J-Alvesb37fd082020-10-22 12:29:21 +0100840 /*
841 * TODO: write test excluding all optional fields of the manifest, in
842 * accordance with specification.
843 */
Olivier Deprez93644652022-09-09 11:01:12 +0200844 struct_manifest *m;
Olivier Deprez62d99e32020-01-09 15:58:07 +0100845
846 /* Incompatible version */
847 /* clang-format off */
848 std::vector<char> dtb = ManifestDtBuilder()
849 .Compatible({ "arm,ffa-manifest-1.0" })
850 .Property("ffa-version", "<0xa1>")
851 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
852 .Property("execution-ctx-count", "<1>")
853 .Property("exception-level", "<2>")
854 .Property("execution-state", "<0>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000855 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100856 .Property("xlat-granule", "<0>")
J-Alvesb37fd082020-10-22 12:29:21 +0100857 .Property("boot-order", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100858 .Property("messaging-method", "<1>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500859 .Property("ns-interrupts-action", "<1>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100860 .Build();
861 /* clang-format on */
862 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
863 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +0200864 manifest_dealloc();
Olivier Deprez62d99e32020-01-09 15:58:07 +0100865
866 /* Incompatible translation granule */
867 /* clang-format off */
868 dtb = ManifestDtBuilder()
869 .Compatible({ "arm,ffa-manifest-1.0" })
870 .Property("ffa-version", "<0x10000>")
871 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
872 .Property("execution-ctx-count", "<1>")
873 .Property("exception-level", "<2>")
874 .Property("execution-state", "<0>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000875 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100876 .Property("xlat-granule", "<3>")
J-Alvesb37fd082020-10-22 12:29:21 +0100877 .Property("boot-order", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100878 .Property("messaging-method", "<1>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500879 .Property("ns-interrupts-action", "<1>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100880 .Build();
881 /* clang-format on */
882 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
883 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +0200884 manifest_dealloc();
Olivier Deprez62d99e32020-01-09 15:58:07 +0100885
886 /* Incompatible exeption level */
887 /* clang-format off */
888 dtb = ManifestDtBuilder()
889 .Compatible({ "arm,ffa-manifest-1.0" })
890 .Property("ffa-version", "<0x10000>")
891 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
892 .Property("execution-ctx-count", "<1>")
Daniel Boulby874d5432023-04-27 12:40:24 +0100893 .Property("exception-level", "<10>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100894 .Property("execution-state", "<0>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000895 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100896 .Property("xlat-granule", "<0>")
J-Alvesb37fd082020-10-22 12:29:21 +0100897 .Property("boot-order", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100898 .Property("messaging-method", "<1>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500899 .Property("ns-interrupts-action", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100900 .Build();
901 /* clang-format on */
902 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
903 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +0200904 manifest_dealloc();
Olivier Deprez62d99e32020-01-09 15:58:07 +0100905
906 /* Incompatible execution state */
907 /* clang-format off */
908 dtb = ManifestDtBuilder()
909 .Compatible({ "arm,ffa-manifest-1.0" })
910 .Property("ffa-version", "<0x10000>")
911 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
912 .Property("execution-ctx-count", "<1>")
913 .Property("exception-level", "<2>")
914 .Property("execution-state", "<2>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000915 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100916 .Property("xlat-granule", "<0>")
J-Alvesb37fd082020-10-22 12:29:21 +0100917 .Property("boot-order", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100918 .Property("messaging-method", "<1>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500919 .Property("ns-interrupts-action", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100920 .Build();
921 /* clang-format on */
922 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
923 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +0200924 manifest_dealloc();
Olivier Deprez62d99e32020-01-09 15:58:07 +0100925
Kathleen Capellaf71dee42023-08-08 16:24:14 -0400926 /* Incompatible messaging method - unrecognized messaging-method. */
927 /* clang-format off */
928 dtb = ManifestDtBuilder()
929 .Compatible({ "arm,ffa-manifest-1.0" })
930 .Property("ffa-version", "<0x10002>")
931 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
932 .Property("execution-ctx-count", "<1>")
933 .Property("exception-level", "<2>")
934 .Property("execution-state", "<0>")
935 .Property("entrypoint-offset", "<0x00002000>")
936 .Property("xlat-granule", "<0>")
937 .Property("boot-order", "<0>")
938 .Property("messaging-method", "<0x272>")
939 .Property("ns-interrupts-action", "<0>")
940 .Build();
941 /* clang-format on */
942 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
943 MANIFEST_ERROR_NOT_COMPATIBLE);
944 manifest_dealloc();
945
946 /* Incompatible messaging method - only endpoints using FF-A version >=
947 * FF-A v1.2 are allowed to set FFA_PARTITION_DIRECT_REQ2_RECV and
948 * FFA_PARTITION_DIRECT_REQ2_SEND. */
Olivier Deprez62d99e32020-01-09 15:58:07 +0100949 /* clang-format off */
950 dtb = ManifestDtBuilder()
951 .Compatible({ "arm,ffa-manifest-1.0" })
952 .Property("ffa-version", "<0x10000>")
953 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
954 .Property("execution-ctx-count", "<1>")
955 .Property("exception-level", "<2>")
956 .Property("execution-state", "<0>")
J-Alves2f86c1e2022-02-23 18:44:19 +0000957 .Property("entrypoint-offset", "<0x00002000>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100958 .Property("xlat-granule", "<0>")
J-Alvesb37fd082020-10-22 12:29:21 +0100959 .Property("boot-order", "<0>")
Kathleen Capellaf71dee42023-08-08 16:24:14 -0400960 .Property("messaging-method", "<0x204>")
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500961 .Property("ns-interrupts-action", "<0>")
Olivier Deprez62d99e32020-01-09 15:58:07 +0100962 .Build();
963 /* clang-format on */
964 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
965 MANIFEST_ERROR_NOT_COMPATIBLE);
Madhukar Pappireddy5c04a382022-12-28 11:29:26 -0600966
967 /*
968 * No need to invoke manifest_dealloac() since manifest TearDown calls
969 * it when the test ends.
970 */
971}
972
973TEST_F(manifest, ffa_validate_interrupt_actions)
974{
975 struct_manifest *m;
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500976
977 /* Incompatible NS interrupt action */
978 /* clang-format off */
Madhukar Pappireddy5c04a382022-12-28 11:29:26 -0600979 std::vector<char> dtb = ManifestDtBuilder()
Madhukar Pappireddy84154052022-06-21 18:30:25 -0500980 .Compatible({ "arm,ffa-manifest-1.0" })
981 .Property("ffa-version", "<0x10000>")
982 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
983 .Property("execution-ctx-count", "<1>")
984 .Property("exception-level", "<2>")
985 .Property("execution-state", "<0>")
986 .Property("entrypoint-offset", "<0x00002000>")
987 .Property("xlat-granule", "<0>")
988 .Property("boot-order", "<0>")
989 .Property("messaging-method", "<1>")
990 .Property("ns-interrupts-action", "<4>")
991 .Build();
992 /* clang-format on */
Madhukar Pappireddy5c04a382022-12-28 11:29:26 -0600993 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
994 MANIFEST_ERROR_ILLEGAL_NS_INT_ACTION);
Madhukar Pappireddyee736ad2022-12-28 11:37:09 -0600995 manifest_dealloc();
996
997 /* Incompatible other-s-interrupts-action for S-EL1 partition */
998 /* clang-format off */
999 dtb = ManifestDtBuilder()
1000 .Compatible({ "arm,ffa-manifest-1.0" })
1001 .Property("ffa-version", "<0x10000>")
1002 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1003 .Property("execution-ctx-count", "<1>")
1004 .Property("exception-level", "<2>")
1005 .Property("execution-state", "<0>")
1006 .Property("entrypoint-offset", "<0x00002000>")
1007 .Property("xlat-granule", "<0>")
1008 .Property("boot-order", "<0>")
1009 .Property("messaging-method", "<1>")
1010 .Property("ns-interrupts-action", "<1>")
1011 .Property("other-s-interrupts-action", "<0>")
1012 .Build();
1013 /* clang-format on */
1014 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1015 MANIFEST_ERROR_NOT_COMPATIBLE);
1016 manifest_dealloc();
1017
1018 /*
1019 * Incompatible choice of the fields ns-interrupts-action and
1020 * other-s-interrupts-action.
1021 */
1022 /* clang-format off */
1023 dtb = ManifestDtBuilder()
1024 .Compatible({ "arm,ffa-manifest-1.0" })
1025 .Property("ffa-version", "<0x10000>")
1026 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1027 .Property("execution-ctx-count", "<1>")
1028 .Property("exception-level", "<1>")
1029 .Property("execution-state", "<0>")
1030 .Property("entrypoint-offset", "<0x00002000>")
1031 .Property("xlat-granule", "<0>")
1032 .Property("boot-order", "<0>")
1033 .Property("messaging-method", "<1>")
1034 .Property("ns-interrupts-action", "<2>")
1035 .Property("other-s-interrupts-action", "<0>")
1036 .Build();
1037 /* clang-format on */
1038 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1039 MANIFEST_ERROR_NOT_COMPATIBLE);
1040 manifest_dealloc();
1041
1042 /* Illegal value specified for the field other-s-interrupts-action. */
1043 /* clang-format off */
1044 dtb = ManifestDtBuilder()
1045 .Compatible({ "arm,ffa-manifest-1.0" })
1046 .Property("ffa-version", "<0x10000>")
1047 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1048 .Property("execution-ctx-count", "<1>")
1049 .Property("exception-level", "<1>")
1050 .Property("execution-state", "<0>")
1051 .Property("entrypoint-offset", "<0x00002000>")
1052 .Property("xlat-granule", "<0>")
1053 .Property("boot-order", "<0>")
1054 .Property("messaging-method", "<1>")
1055 .Property("other-s-interrupts-action", "<2>")
1056 .Build();
1057 /* clang-format on */
1058 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1059 MANIFEST_ERROR_ILLEGAL_OTHER_S_INT_ACTION);
Olivier Deprez62d99e32020-01-09 15:58:07 +01001060}
1061
Olivier Depreza15f2352022-09-26 09:17:24 +02001062TEST_F(manifest, power_management)
1063{
1064 struct manifest_vm *vm;
1065 struct_manifest *m;
1066
1067 /* S-EL1 partition power management field can set bit 0. */
1068 /* clang-format off */
1069 std::vector<char> dtb = ManifestDtBuilder()
1070 .Compatible({ "arm,ffa-manifest-1.0" })
1071 .Property("ffa-version", "<0x10001>")
1072 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1073 .Property("execution-ctx-count", "<8>")
1074 .Property("exception-level", "<2>")
1075 .Property("execution-state", "<0>")
1076 .Property("entrypoint-offset", "<0x00002000>")
1077 .Property("messaging-method", "<1>")
1078 .Property("power-management-messages", "<1>")
1079 .Build();
1080 /* clang-format on */
1081 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1082 vm = &m->vm[0];
1083 ASSERT_EQ(vm->partition.power_management, 1);
1084 manifest_dealloc();
1085
1086 /* S-EL1 partition power management field can set bit 3. */
1087 /* clang-format off */
1088 dtb = ManifestDtBuilder()
1089 .Compatible({ "arm,ffa-manifest-1.0" })
1090 .Property("ffa-version", "<0x10001>")
1091 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1092 .Property("execution-ctx-count", "<8>")
1093 .Property("exception-level", "<2>")
1094 .Property("execution-state", "<0>")
1095 .Property("entrypoint-offset", "<0x00002000>")
1096 .Property("messaging-method", "<1>")
1097 .Property("power-management-messages", "<8>")
1098 .Build();
1099 /* clang-format on */
1100 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1101 vm = &m->vm[0];
1102 ASSERT_EQ(vm->partition.power_management, 8);
1103 manifest_dealloc();
1104
1105 /* S-EL1 partition power management field can only set bits 0 and 3. */
1106 /* clang-format off */
1107 dtb = ManifestDtBuilder()
1108 .Compatible({ "arm,ffa-manifest-1.0" })
1109 .Property("ffa-version", "<0x10001>")
1110 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1111 .Property("execution-ctx-count", "<8>")
1112 .Property("exception-level", "<2>")
1113 .Property("execution-state", "<0>")
1114 .Property("entrypoint-offset", "<0x00002000>")
1115 .Property("messaging-method", "<1>")
1116 .Property("power-management-messages", "<0xf>")
1117 .Build();
1118 /* clang-format on */
1119 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1120 vm = &m->vm[0];
1121 ASSERT_EQ(vm->partition.power_management, 9);
1122 manifest_dealloc();
1123
1124 /* S-EL0 partition power management field is forced to 0. */
1125 /* clang-format off */
1126 dtb = ManifestDtBuilder()
1127 .Compatible({ "arm,ffa-manifest-1.0" })
1128 .Property("ffa-version", "<0x10001>")
1129 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1130 .Property("execution-ctx-count", "<1>")
1131 .Property("exception-level", "<1>")
1132 .Property("execution-state", "<0>")
1133 .Property("entrypoint-offset", "<0x00002000>")
1134 .Property("messaging-method", "<1>")
1135 .Property("power-management-messages", "<0xff>")
1136 .Build();
1137 /* clang-format on */
1138 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1139 vm = &m->vm[0];
1140 ASSERT_EQ(vm->partition.power_management, 0);
1141}
1142
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001143TEST_F(manifest, ffa_validate_rxtx_info)
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001144{
Olivier Deprez93644652022-09-09 11:01:12 +02001145 struct_manifest *m;
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001146
1147 /* Not Compatible */
1148 /* clang-format off */
1149 std::vector<char> dtb = ManifestDtBuilder()
1150 .FfaValidManifest()
1151 .StartChild("rx_tx-info")
1152 .Compatible({ "foo,bar" })
1153 .EndChild()
1154 .Build();
1155 /* clang-format on */
1156 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1157 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +02001158 manifest_dealloc();
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001159
1160 /* Missing Properties */
1161 /* clang-format off */
1162 dtb = ManifestDtBuilder()
1163 .FfaValidManifest()
1164 .StartChild("rx_tx-info")
1165 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1166 .EndChild()
1167 .Build();
1168 /* clang-format on */
1169 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1170 MANIFEST_ERROR_PROPERTY_NOT_FOUND);
1171}
1172
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001173TEST_F(manifest, ffa_validate_mem_regions)
Manish Pandey6542f5c2020-04-27 14:37:46 +01001174{
Olivier Deprez93644652022-09-09 11:01:12 +02001175 struct_manifest *m;
Manish Pandey6542f5c2020-04-27 14:37:46 +01001176
1177 /* Not Compatible */
1178 /* clang-format off */
1179 std::vector<char> dtb = ManifestDtBuilder()
1180 .FfaValidManifest()
1181 .StartChild("memory-regions")
1182 .Compatible({ "foo,bar" })
1183 .EndChild()
1184 .Build();
1185 /* clang-format on */
1186 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1187 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +02001188 manifest_dealloc();
Manish Pandey6542f5c2020-04-27 14:37:46 +01001189
1190 /* Memory regions unavailable */
1191 /* clang-format off */
1192 dtb = ManifestDtBuilder()
1193 .FfaValidManifest()
1194 .StartChild("memory-regions")
1195 .Compatible({ "arm,ffa-manifest-memory-regions" })
1196 .EndChild()
1197 .Build();
1198 /* clang-format on */
1199 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1200 MANIFEST_ERROR_MEMORY_REGION_NODE_EMPTY);
Olivier Deprez93644652022-09-09 11:01:12 +02001201 manifest_dealloc();
Manish Pandey6542f5c2020-04-27 14:37:46 +01001202
1203 /* Missing Properties */
1204 /* clang-format off */
1205 dtb = ManifestDtBuilder()
1206 .FfaValidManifest()
1207 .StartChild("memory-regions")
1208 .Compatible({ "arm,ffa-manifest-memory-regions" })
1209 .StartChild("test-memory")
1210 .Description("test-memory")
1211 .EndChild()
1212 .EndChild()
1213 .Build();
1214 /* clang-format on */
1215 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1216 MANIFEST_ERROR_PROPERTY_NOT_FOUND);
Olivier Deprez93644652022-09-09 11:01:12 +02001217 manifest_dealloc();
Manish Pandeyf06c9072020-09-29 15:41:58 +01001218
Varun Wadekar4afbfd72022-10-13 14:30:18 +01001219 /* Empty memory region */
1220 /* clang-format off */
1221 dtb = ManifestDtBuilder()
1222 .FfaValidManifest()
1223 .StartChild("memory-regions")
1224 .Compatible({ "arm,ffa-manifest-memory-regions" })
1225 .Label("rx")
1226 .StartChild("rx")
1227 .Description("rx-buffer")
1228 .Property("base-address", "<0x7300000>")
1229 .Property("pages-count", "<0>")
1230 .Property("attributes", "<1>")
1231 .EndChild()
1232 .Label("tx")
1233 .StartChild("tx")
1234 .Description("tx-buffer")
1235 .Property("base-address", "<0x7310000>")
1236 .Property("pages-count", "<2>")
1237 .Property("attributes", "<3>")
1238 .EndChild()
1239 .EndChild()
1240 .StartChild("rx_tx-info")
1241 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1242 .Property("rx-buffer", "<&rx>")
1243 .Property("tx-buffer", "<&tx>")
1244 .EndChild()
1245 .Build();
1246 /* clang-format on */
1247 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1248 MANIFEST_ERROR_MEM_REGION_EMPTY);
1249 manifest_dealloc();
1250
Davidson K8ccd2d02024-09-03 16:10:54 +05301251 /* Mutually exclusive base-address and load-address-relative-offset
1252 * properties */
Karl Meakine92efbe2023-06-01 14:16:22 +01001253 /* clang-format off */
1254 dtb = ManifestDtBuilder()
1255 .FfaValidManifest()
1256 .StartChild("memory-regions")
1257 .Compatible({ "arm,ffa-manifest-memory-regions" })
1258 .Label("rx")
1259 .StartChild("rx")
1260 .Description("rx-buffer")
1261 .Property("base-address", "<0x7300000>")
Davidson K8ccd2d02024-09-03 16:10:54 +05301262 .Property("load-address-relative-offset", "<0x7300000>")
Karl Meakine92efbe2023-06-01 14:16:22 +01001263 .Property("pages-count", "<1>")
1264 .Property("attributes", "<1>")
1265 .EndChild()
1266 .EndChild()
1267 .Build();
1268 /* clang-format on */
1269 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1270 MANIFEST_ERROR_BASE_ADDRESS_AND_RELATIVE_ADDRESS);
1271 manifest_dealloc();
1272 /* Relative-address overflow*/
1273 /* clang-format off */
1274 dtb = ManifestDtBuilder()
1275 .FfaValidManifest()
1276 .Property("load-address", "<0xffffff00 0xffffff00>")
1277 .StartChild("memory-regions")
1278 .Compatible({ "arm,ffa-manifest-memory-regions" })
1279 .Label("rx")
1280 .StartChild("rx")
1281 .Description("rx-buffer")
Davidson K8ccd2d02024-09-03 16:10:54 +05301282 .Property("load-address-relative-offset", "<0xffffff00 0xffffff00>")
Karl Meakine92efbe2023-06-01 14:16:22 +01001283 .Property("pages-count", "<1>")
1284 .Property("attributes", "<1>")
1285 .EndChild()
1286 .EndChild()
1287 .Build();
1288 /* clang-format on */
1289 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1290 MANIFEST_ERROR_INTEGER_OVERFLOW);
1291 manifest_dealloc();
1292
Daniel Boulby9279b552022-06-28 17:04:01 +01001293 /* Overlapping memory regions */
1294 /* clang-format off */
1295 dtb = ManifestDtBuilder()
1296 .FfaValidManifest()
1297 .StartChild("memory-regions")
1298 .Compatible({ "arm,ffa-manifest-memory-regions" })
1299 .Label("rx")
1300 .StartChild("rx")
1301 .Description("rx-buffer")
1302 .Property("base-address", "<0x7300000>")
1303 .Property("pages-count", "<1>")
1304 .Property("attributes", "<1>")
1305 .EndChild()
1306 .Label("tx")
1307 .StartChild("tx")
1308 .Description("tx-buffer")
1309 .Property("base-address", "<0x7300000>")
1310 .Property("pages-count", "<2>")
1311 .Property("attributes", "<3>")
1312 .EndChild()
1313 .EndChild()
1314 .Build();
1315 /* clang-format on */
1316 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1317 MANIFEST_ERROR_MEM_REGION_OVERLAP);
Olivier Deprez93644652022-09-09 11:01:12 +02001318 manifest_dealloc();
Daniel Boulby9279b552022-06-28 17:04:01 +01001319
1320 /* clang-format off */
1321 dtb = ManifestDtBuilder()
1322 .FfaValidManifest()
1323 .StartChild("memory-regions")
1324 .Compatible({ "arm,ffa-manifest-memory-regions" })
1325 .Label("rx")
1326 .StartChild("rx")
1327 .Description("rx-buffer")
1328 .Property("base-address", "<0x7300000>")
1329 .Property("pages-count", "<2>")
1330 .Property("attributes", "<1>")
1331 .EndChild()
1332 .Label("tx")
1333 .StartChild("tx")
1334 .Description("tx-buffer")
1335 .Property("base-address", "<0x7301000>")
1336 .Property("pages-count", "<2>")
1337 .Property("attributes", "<3>")
1338 .EndChild()
1339 .EndChild()
1340 .Build();
1341 /* clang-format on */
1342 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1343 MANIFEST_ERROR_MEM_REGION_OVERLAP);
Olivier Deprez93644652022-09-09 11:01:12 +02001344 manifest_dealloc();
Daniel Boulby9279b552022-06-28 17:04:01 +01001345
1346 /* clang-format off */
1347 dtb = ManifestDtBuilder()
1348 .FfaValidManifest()
1349 .StartChild("memory-regions")
1350 .Compatible({ "arm,ffa-manifest-memory-regions" })
1351 .Label("rx")
1352 .StartChild("rx")
1353 .Description("rx-buffer")
Varun Wadekarae9aeaa2022-10-13 14:23:58 +01001354 .Property("base-address", "<0x7301000>")
1355 .Property("pages-count", "<1>")
1356 .Property("attributes", "<1>")
1357 .EndChild()
1358 .Label("tx")
1359 .StartChild("tx")
1360 .Description("tx-buffer")
1361 .Property("base-address", "<0x7300000>")
1362 .Property("pages-count", "<2>")
1363 .Property("attributes", "<3>")
1364 .EndChild()
1365 .EndChild()
1366 .Build();
1367 /* clang-format on */
1368 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1369 MANIFEST_ERROR_MEM_REGION_OVERLAP);
Daniel Boulbyc1a613d2022-10-18 11:26:17 +01001370 manifest_dealloc();
1371
1372 /* Unaligned memory region */
1373 /* clang-format off */
1374 dtb = ManifestDtBuilder()
1375 .FfaValidManifest()
1376 .StartChild("memory-regions")
1377 .Compatible({ "arm,ffa-manifest-memory-regions" })
1378 .Label("rx")
1379 .StartChild("rx")
1380 .Description("rx-buffer")
1381 .Property("base-address", "<0x7300FFF>")
1382 .Property("pages-count", "<2>")
1383 .Property("attributes", "<1>")
1384 .EndChild()
1385 .Label("tx")
1386 .StartChild("tx")
1387 .Description("tx-buffer")
1388 .Property("base-address", "<0x7303000>")
1389 .Property("pages-count", "<2>")
1390 .Property("attributes", "<3>")
1391 .EndChild()
1392 .EndChild()
1393 .Build();
1394 /* clang-format on */
1395 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1396 MANIFEST_ERROR_MEM_REGION_UNALIGNED);
1397 manifest_dealloc();
Varun Wadekarae9aeaa2022-10-13 14:23:58 +01001398
Manish Pandeyf06c9072020-09-29 15:41:58 +01001399 /* Different RXTX buffer sizes */
1400 /* clang-format off */
1401 dtb = ManifestDtBuilder()
1402 .FfaValidManifest()
1403 .StartChild("memory-regions")
1404 .Compatible({ "arm,ffa-manifest-memory-regions" })
1405 .Label("rx")
1406 .StartChild("rx")
1407 .Description("rx-buffer")
1408 .Property("base-address", "<0x7300000>")
1409 .Property("pages-count", "<1>")
1410 .Property("attributes", "<1>")
1411 .EndChild()
1412 .Label("tx")
1413 .StartChild("tx")
1414 .Description("tx-buffer")
1415 .Property("base-address", "<0x7310000>")
1416 .Property("pages-count", "<2>")
1417 .Property("attributes", "<3>")
1418 .EndChild()
1419 .EndChild()
1420 .StartChild("rx_tx-info")
1421 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1422 .Property("rx-buffer", "<&rx>")
1423 .Property("tx-buffer", "<&tx>")
1424 .EndChild()
1425 .Build();
1426 /* clang-format on */
1427 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1428 MANIFEST_ERROR_RXTX_SIZE_MISMATCH);
Manish Pandey6542f5c2020-04-27 14:37:46 +01001429}
1430
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001431TEST_F(manifest, ffa_validate_dev_regions)
Manish Pandeye68e7932020-04-23 15:29:28 +01001432{
Olivier Deprez93644652022-09-09 11:01:12 +02001433 struct_manifest *m;
Manish Pandeye68e7932020-04-23 15:29:28 +01001434
1435 /* Not Compatible */
1436 /* clang-format off */
1437 std::vector<char> dtb = ManifestDtBuilder()
1438 .FfaValidManifest()
1439 .StartChild("device-regions")
1440 .Compatible({ "foo,bar" })
1441 .EndChild()
1442 .Build();
1443 /* clang-format on */
1444 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1445 MANIFEST_ERROR_NOT_COMPATIBLE);
Olivier Deprez93644652022-09-09 11:01:12 +02001446 manifest_dealloc();
Manish Pandeye68e7932020-04-23 15:29:28 +01001447
1448 /* Memory regions unavailable */
1449 /* clang-format off */
1450 dtb = ManifestDtBuilder()
1451 .FfaValidManifest()
1452 .StartChild("device-regions")
1453 .Compatible({ "arm,ffa-manifest-device-regions" })
1454 .EndChild()
1455 .Build();
1456 /* clang-format on */
1457 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1458 MANIFEST_ERROR_DEVICE_REGION_NODE_EMPTY);
Olivier Deprez93644652022-09-09 11:01:12 +02001459 manifest_dealloc();
Manish Pandeye68e7932020-04-23 15:29:28 +01001460
1461 /* Missing Properties */
1462 /* clang-format off */
1463 dtb = ManifestDtBuilder()
1464 .FfaValidManifest()
1465 .StartChild("device-regions")
1466 .Compatible({ "arm,ffa-manifest-device-regions" })
1467 .StartChild("test-device")
1468 .Description("test-device")
1469 .EndChild()
1470 .EndChild()
1471 .Build();
1472 /* clang-format on */
1473 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1474 MANIFEST_ERROR_PROPERTY_NOT_FOUND);
Olivier Deprez93644652022-09-09 11:01:12 +02001475 manifest_dealloc();
Manish Pandeye68e7932020-04-23 15:29:28 +01001476
1477 /* Malformed interrupt list pair */
1478 /* clang-format off */
1479 dtb = ManifestDtBuilder()
1480 .FfaValidManifest()
1481 .StartChild("device-regions")
1482 .Compatible({ "arm,ffa-manifest-device-regions" })
1483 .StartChild("test-device")
1484 .Description("test-device")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001485 .Property("base-address", "<0x24000000>")
Manish Pandeye68e7932020-04-23 15:29:28 +01001486 .Property("pages-count", "<16>")
1487 .Property("attributes", "<3>")
1488 .Property("smmu-id", "<1>")
1489 .Property("stream-ids", "<0 1>")
1490 .Property("interrupts", "<2 3>, <4>")
1491 .EndChild()
1492 .EndChild()
1493 .Build();
1494 /* clang-format on */
1495 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1496 MANIFEST_ERROR_MALFORMED_INTEGER_LIST);
Olivier Deprez93644652022-09-09 11:01:12 +02001497 manifest_dealloc();
Daniel Boulby667334f2022-06-27 15:23:21 +01001498
1499 /* Non-unique interrupt IDs */
1500 /* clang-format off */
1501 dtb = ManifestDtBuilder()
1502 .FfaValidManifest()
1503 .StartChild("device-regions")
1504 .Compatible({ "arm,ffa-manifest-device-regions" })
1505 .StartChild("test-device-0")
1506 .Description("test-device-0")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001507 .Property("base-address", "<0x24000000>")
Daniel Boulby667334f2022-06-27 15:23:21 +01001508 .Property("pages-count", "<16>")
1509 .Property("attributes", "<3>")
1510 .Property("interrupts", "<2 3>")
1511 .EndChild()
1512 .StartChild("test-device-1")
1513 .Description("test-device-1")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001514 .Property("base-address", "<0x25000000>")
Daniel Boulby667334f2022-06-27 15:23:21 +01001515 .Property("pages-count", "<16>")
1516 .Property("attributes", "<3>")
1517 .Property("interrupts", "<1 3>, <2 5> ")
1518 .EndChild()
1519 .EndChild()
1520 .Build();
Daniel Boulby941ef342023-11-21 13:47:15 +00001521
Daniel Boulby667334f2022-06-27 15:23:21 +01001522 /* clang-format on */
1523 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1524 MANIFEST_ERROR_INTERRUPT_ID_REPEATED);
1525 /* Check valid interrupts were still mapped */
Olivier Deprez93644652022-09-09 11:01:12 +02001526 ASSERT_EQ(m->vm[0].partition.dev_regions[0].interrupts[0].id, 2);
1527 ASSERT_EQ(m->vm[0].partition.dev_regions[0].interrupts[0].attributes,
1528 3);
1529 ASSERT_EQ(m->vm[0].partition.dev_regions[1].interrupts[0].id, 1);
1530 ASSERT_EQ(m->vm[0].partition.dev_regions[1].interrupts[0].attributes,
1531 3);
Daniel Boulby941ef342023-11-21 13:47:15 +00001532 manifest_dealloc();
1533
1534 /* Overlapping address space between two device region nodes. */
1535 /* clang-format off */
1536 dtb = ManifestDtBuilder()
1537 .FfaValidManifest()
1538 .StartChild("device-regions")
1539 .Compatible({"arm,ffa-manifest-device-regions"})
1540 .StartChild("test-device-0")
1541 .Description("test-device-0")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001542 .Property("base-address", "<0x24000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00001543 .Property("pages-count", "<16>")
1544 .Property("attributes", "<3>")
1545 .EndChild()
1546 .StartChild("test-device-1")
1547 .Description("test-device-1")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001548 .Property("base-address", "<0x24000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00001549 .Property("pages-count", "<16>")
1550 .Property("attributes", "<3>")
1551 .EndChild()
Daniel Boulby4339edc2024-02-21 14:59:00 +00001552 .EndChild()
Daniel Boulby941ef342023-11-21 13:47:15 +00001553 .Build();
1554
1555 /* clang-format on */
1556 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1557 MANIFEST_ERROR_MEM_REGION_OVERLAP);
1558 manifest_dealloc();
1559
1560 /*
Daniel Boulby4339edc2024-02-21 14:59:00 +00001561 * Device regions cannot be defined outside of the regions specified in
1562 * the spmc.
Daniel Boulby941ef342023-11-21 13:47:15 +00001563 */
1564 /* clang-format off */
1565 dtb = ManifestDtBuilder()
1566 .FfaValidManifest()
Daniel Boulby941ef342023-11-21 13:47:15 +00001567 .StartChild("device-regions")
1568 .Compatible({"arm,ffa-manifest-device-regions"})
1569 .StartChild("test-device-0")
1570 .Description("test-device-0")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001571 .Property("base-address", "<0x50000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00001572 .Property("pages-count", "<16>")
1573 .Property("attributes", "<3>")
1574 .EndChild()
1575 .EndChild()
1576 .Build();
1577 /* clang-format on */
1578 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
Daniel Boulby4339edc2024-02-21 14:59:00 +00001579 MANIFEST_ERROR_DEVICE_MEM_REGION_INVALID);
1580 manifest_dealloc();
1581
1582 /*
1583 * Memory defined as NS in SPMC manifest given Secure attribute should
1584 * fail.
1585 */
1586 /* clang-format off */
1587 dtb = ManifestDtBuilder()
1588 .FfaValidManifest()
1589 .StartChild("device-regions")
1590 .Compatible({"arm,ffa-manifest-device-regions"})
1591 .StartChild("test-device-0")
1592 .Description("test-device-0")
1593 .Property("base-address", "<0x20000000>")
1594 .Property("pages-count", "<16>")
1595 .Property("attributes", "<3>")
1596 .EndChild()
1597 .EndChild()
1598 .Build();
1599 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1600 MANIFEST_ERROR_DEVICE_MEM_REGION_INVALID);
Manish Pandeye68e7932020-04-23 15:29:28 +01001601}
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001602
1603TEST_F(manifest, ffa_invalid_memory_region_attributes)
Raghu Krishnamurthy384693c2021-10-11 13:56:24 -07001604{
Olivier Deprez93644652022-09-09 11:01:12 +02001605 struct_manifest *m;
Raghu Krishnamurthy384693c2021-10-11 13:56:24 -07001606
1607 /* clang-format off */
1608 std::vector<char> dtb = ManifestDtBuilder()
1609 .FfaValidManifest()
1610 .StartChild("rx_tx-info")
1611 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1612 .Property("rx-buffer", "<&rx>")
1613 .Property("tx-buffer", "<&tx>")
1614 .EndChild()
1615 .StartChild("memory-regions")
1616 .Compatible({ "arm,ffa-manifest-memory-regions" })
1617 .StartChild("test-memory")
1618 .Description("test-memory")
1619 .Property("base-address", "<0x7100000>")
1620 .Property("pages-count", "<4>")
1621 .Property("attributes", "<7>")
1622 .EndChild()
1623 .Label("rx")
1624 .StartChild("rx")
1625 .Description("rx-buffer")
1626 .Property("base-address", "<0x7300000>")
1627 .Property("pages-count", "<1>")
1628 .Property("attributes", "<1>")
1629 .EndChild()
1630 .Label("tx")
1631 .StartChild("tx")
1632 .Description("tx-buffer")
1633 .Property("base-address", "<0x7310000>")
1634 .Property("pages-count", "<1>")
1635 .Property("attributes", "<3>")
1636 .EndChild()
1637 .EndChild()
1638 .Build();
1639 /* clang-format on */
1640
1641 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1642 MANIFEST_ERROR_INVALID_MEM_PERM);
1643}
1644
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001645TEST_F(manifest, ffa_invalid_device_region_attributes)
Raghu Krishnamurthy384693c2021-10-11 13:56:24 -07001646{
Olivier Deprez93644652022-09-09 11:01:12 +02001647 struct_manifest *m;
Raghu Krishnamurthy384693c2021-10-11 13:56:24 -07001648
1649 /* clang-format off */
1650 std::vector<char> dtb = ManifestDtBuilder()
1651 .FfaValidManifest()
1652 .StartChild("rx_tx-info")
1653 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1654 .Property("rx-buffer", "<&rx>")
1655 .Property("tx-buffer", "<&tx>")
1656 .EndChild()
1657 .StartChild("memory-regions")
1658 .Compatible({ "arm,ffa-manifest-memory-regions" })
1659 .StartChild("test-memory")
1660 .Description("test-memory")
1661 .Property("base-address", "<0x7100000>")
1662 .Property("pages-count", "<4>")
1663 .Property("attributes", "<3>")
1664 .EndChild()
1665 .Label("rx")
1666 .StartChild("rx")
1667 .Description("rx-buffer")
1668 .Property("base-address", "<0x7300000>")
1669 .Property("pages-count", "<1>")
1670 .Property("attributes", "<1>")
1671 .EndChild()
1672 .Label("tx")
1673 .StartChild("tx")
1674 .Description("tx-buffer")
1675 .Property("base-address", "<0x7310000>")
1676 .Property("pages-count", "<1>")
1677 .Property("attributes", "<3>")
1678 .EndChild()
1679 .EndChild()
1680 .StartChild("device-regions")
1681 .Compatible({ "arm,ffa-manifest-device-regions" })
1682 .StartChild("test-device")
1683 .Description("test-device")
1684 .Property("base-address", "<0x7200000>")
1685 .Property("pages-count", "<16>")
1686 .Property("attributes", "<5>")
1687 .Property("smmu-id", "<1>")
1688 .Property("stream-ids", "<0 1>")
1689 .Property("interrupts", "<2 3>, <4 5>")
1690 .EndChild()
1691 .EndChild()
1692 .Build();
1693 /* clang-format on */
1694
1695 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1696 MANIFEST_ERROR_INVALID_MEM_PERM);
1697}
Manish Pandeye68e7932020-04-23 15:29:28 +01001698
Daniel Boulby801f8ef2022-06-27 14:21:01 +01001699TEST_F(manifest, ffa_valid)
Olivier Deprez62d99e32020-01-09 15:58:07 +01001700{
Olivier Deprez93644652022-09-09 11:01:12 +02001701 struct manifest_vm *vm;
1702 struct_manifest *m;
Olivier Deprez62d99e32020-01-09 15:58:07 +01001703
1704 /* clang-format off */
1705 std::vector<char> dtb = ManifestDtBuilder()
Manish Pandeycb8fbb22020-08-18 00:04:43 +01001706 .FfaValidManifest()
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001707 .StartChild("rx_tx-info")
1708 .Compatible({ "arm,ffa-manifest-rx_tx-buffer" })
1709 .Property("rx-buffer", "<&rx>")
1710 .Property("tx-buffer", "<&tx>")
1711 .EndChild()
Manish Pandey6542f5c2020-04-27 14:37:46 +01001712 .StartChild("memory-regions")
1713 .Compatible({ "arm,ffa-manifest-memory-regions" })
1714 .StartChild("test-memory")
1715 .Description("test-memory")
Davidson K8ccd2d02024-09-03 16:10:54 +05301716 .Property("load-address-relative-offset", "<0x7100000>")
Manish Pandey6542f5c2020-04-27 14:37:46 +01001717 .Property("pages-count", "<4>")
Raghu Krishnamurthy384693c2021-10-11 13:56:24 -07001718 .Property("attributes", "<3>")
Madhukar Pappireddy99c5eff2024-07-08 15:07:41 -05001719 .Property("smmu-id", "<1>")
1720 .Property("stream-ids", "<0 1>")
1721 .Property("stream-ids-access-permissions", "<0x3 0x3>")
Manish Pandey6542f5c2020-04-27 14:37:46 +01001722 .EndChild()
Olivier Deprez035fa152022-03-14 11:19:10 +01001723 .StartChild("test-memory-ns")
1724 .Description("test-memory")
1725 .Property("base-address", "<0x7200000>")
1726 .Property("pages-count", "<1>")
1727 .Property("attributes", "<0xb>")
1728 .EndChild()
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001729 .Label("rx")
1730 .StartChild("rx")
1731 .Description("rx-buffer")
1732 .Property("base-address", "<0x7300000>")
1733 .Property("pages-count", "<1>")
1734 .Property("attributes", "<1>")
1735 .EndChild()
1736 .Label("tx")
1737 .StartChild("tx")
1738 .Description("tx-buffer")
Daniel Boulby9279b552022-06-28 17:04:01 +01001739 .Property("base-address", "<0x7301000>")
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001740 .Property("pages-count", "<1>")
1741 .Property("attributes", "<3>")
1742 .EndChild()
Manish Pandey6542f5c2020-04-27 14:37:46 +01001743 .EndChild()
Manish Pandeye68e7932020-04-23 15:29:28 +01001744 .StartChild("device-regions")
1745 .Compatible({ "arm,ffa-manifest-device-regions" })
1746 .StartChild("test-device")
1747 .Description("test-device")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001748 .Property("base-address", "<0x24000000>")
Manish Pandeye68e7932020-04-23 15:29:28 +01001749 .Property("pages-count", "<16>")
1750 .Property("attributes", "<3>")
1751 .Property("smmu-id", "<1>")
1752 .Property("stream-ids", "<0 1>")
1753 .Property("interrupts", "<2 3>, <4 5>")
1754 .EndChild()
Olivier Deprez035fa152022-03-14 11:19:10 +01001755 .StartChild("test-device-ns")
1756 .Description("test-device")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001757 .Property("base-address", "<0x20000000>")
Olivier Deprez035fa152022-03-14 11:19:10 +01001758 .Property("pages-count", "<1>")
1759 .Property("attributes", "<0x9>")
1760 .EndChild()
Manish Pandeye68e7932020-04-23 15:29:28 +01001761 .EndChild()
Olivier Deprez62d99e32020-01-09 15:58:07 +01001762 .Build();
Daniel Boulby4339edc2024-02-21 14:59:00 +00001763
Olivier Deprez62d99e32020-01-09 15:58:07 +01001764 /* clang-format on */
Olivier Deprez62d99e32020-01-09 15:58:07 +01001765 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1766
Olivier Deprez93644652022-09-09 11:01:12 +02001767 vm = &m->vm[0];
1768 ASSERT_EQ(vm->partition.ffa_version, 0x10000);
Olivier Deprez62d99e32020-01-09 15:58:07 +01001769 ASSERT_THAT(
Kathleen Capella422b10b2023-06-30 18:28:27 -04001770 std::span(vm->partition.uuids[0].uuid, 4),
Olivier Deprez62d99e32020-01-09 15:58:07 +01001771 ElementsAre(0xb4b5671e, 0x4a904fe1, 0xb81ffb13, 0xdae1dacb));
Olivier Deprez93644652022-09-09 11:01:12 +02001772 ASSERT_EQ(vm->partition.execution_ctx_count, 1);
1773 ASSERT_EQ(vm->partition.run_time_el, S_EL1);
1774 ASSERT_EQ(vm->partition.execution_state, AARCH64);
1775 ASSERT_EQ(vm->partition.ep_offset, 0x00002000);
1776 ASSERT_EQ(vm->partition.xlat_granule, PAGE_4KB);
1777 ASSERT_EQ(vm->partition.boot_order, 0);
1778 ASSERT_EQ(vm->partition.messaging_method, FFA_PARTITION_INDIRECT_MSG);
1779 ASSERT_EQ(vm->partition.ns_interrupts_action, NS_ACTION_ME);
1780 ASSERT_EQ(vm->partition.mem_regions[0].base_address, 0x7100000);
1781 ASSERT_EQ(vm->partition.mem_regions[0].page_count, 4);
1782 ASSERT_EQ(vm->partition.mem_regions[0].attributes, 3);
Madhukar Pappireddy99c5eff2024-07-08 15:07:41 -05001783 ASSERT_EQ(vm->partition.mem_regions[0].dma_prop.smmu_id, 1);
1784 ASSERT_EQ(vm->partition.mem_regions[0].dma_prop.stream_ids[0], 0);
1785 ASSERT_EQ(vm->partition.mem_regions[0].dma_prop.stream_ids[1], 1);
1786 ASSERT_EQ(vm->partition.mem_regions[0].dma_access_permissions, 3);
Olivier Deprez93644652022-09-09 11:01:12 +02001787 ASSERT_EQ(vm->partition.mem_regions[1].attributes, (8 | 3));
Raghu Krishnamurthy8c250a92021-07-02 12:16:42 -07001788
Olivier Deprez93644652022-09-09 11:01:12 +02001789 ASSERT_EQ(vm->partition.rxtx.available, true);
1790 ASSERT_EQ(vm->partition.rxtx.rx_buffer->base_address, 0x7300000);
1791 ASSERT_EQ(vm->partition.rxtx.rx_buffer->page_count, 1);
1792 ASSERT_EQ(vm->partition.rxtx.rx_buffer->attributes, 1);
1793 ASSERT_EQ(vm->partition.rxtx.tx_buffer->base_address, 0x7301000);
1794 ASSERT_EQ(vm->partition.rxtx.tx_buffer->page_count, 1);
1795 ASSERT_EQ(vm->partition.rxtx.tx_buffer->attributes, 3);
1796
Daniel Boulby4339edc2024-02-21 14:59:00 +00001797 ASSERT_EQ(vm->partition.dev_regions[0].base_address, 0x24000000);
Olivier Deprez93644652022-09-09 11:01:12 +02001798 ASSERT_EQ(vm->partition.dev_regions[0].page_count, 16);
Olivier Deprez058ddee2024-08-27 09:22:11 +02001799 ASSERT_EQ(vm->partition.dev_regions[0].attributes, 3);
Madhukar Pappireddy9c764b32024-06-20 14:36:55 -05001800 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.smmu_id, 1);
1801 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.stream_ids[0], 0);
1802 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.stream_ids[1], 1);
Olivier Deprez93644652022-09-09 11:01:12 +02001803 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].id, 2);
1804 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].attributes, 3);
1805 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].id, 4);
1806 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].attributes, 5);
Daniel Boulby4339edc2024-02-21 14:59:00 +00001807 ASSERT_EQ(vm->partition.dev_regions[1].base_address, 0x20000000);
Olivier Deprez058ddee2024-08-27 09:22:11 +02001808 ASSERT_EQ(vm->partition.dev_regions[1].attributes, (8 | 1));
Olivier Deprez62d99e32020-01-09 15:58:07 +01001809}
1810
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001811TEST_F(manifest, ffa_valid_interrupt_target_manifest)
1812{
1813 struct manifest_vm *vm;
1814 struct_manifest *m;
1815
1816 /* clang-format off */
1817 std::vector<char> dtb = ManifestDtBuilder()
1818 .FfaValidManifest()
1819 .StartChild("device-regions")
1820 .Compatible({ "arm,ffa-manifest-device-regions" })
1821 .StartChild("test-device")
1822 .Description("test-device")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001823 .Property("base-address", "<0x24000000>")
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001824 .Property("pages-count", "<16>")
1825 .Property("attributes", "<3>")
1826 .Property("smmu-id", "<1>")
1827 .Property("stream-ids", "<0 1>")
1828 .Property("interrupts", "<2 3>, <4 5>")
1829 .Property("interrupts-target", "<2 0x1234 0x5678>, <4 0x12345678 0x87654321>")
1830 .EndChild()
1831 .EndChild()
1832 .Build();
1833 /* clang-format on */
1834
1835 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1836
1837 vm = &m->vm[0];
1838
Daniel Boulby4339edc2024-02-21 14:59:00 +00001839 ASSERT_EQ(vm->partition.dev_regions[0].base_address, 0x24000000);
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001840 ASSERT_EQ(vm->partition.dev_regions[0].page_count, 16);
Olivier Deprez058ddee2024-08-27 09:22:11 +02001841 ASSERT_EQ(vm->partition.dev_regions[0].attributes, 3);
Madhukar Pappireddy9c764b32024-06-20 14:36:55 -05001842 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.smmu_id, 1);
1843 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.stream_ids[0], 0);
1844 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.stream_ids[1], 1);
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001845 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].id, 2);
1846 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].attributes, 3);
1847 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].mpidr_valid, true);
1848 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].mpidr,
1849 0x123400005678);
1850 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].id, 4);
1851 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].attributes, 5);
1852 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].mpidr_valid, true);
1853 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].mpidr,
1854 0x1234567887654321);
1855}
1856
1857TEST_F(manifest, ffa_invalid_interrupt_target_manifest)
1858{
1859 struct_manifest *m;
1860
1861 /* clang-format off */
1862 std::vector<char> dtb = ManifestDtBuilder()
1863 .FfaValidManifest()
1864 .StartChild("device-regions")
1865 .Compatible({ "arm,ffa-manifest-device-regions" })
1866 .StartChild("test-device")
1867 .Description("test-device")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001868 .Property("base-address", "<0x24000000>")
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001869 .Property("pages-count", "<16>")
1870 .Property("attributes", "<3>")
1871 .Property("smmu-id", "<1>")
1872 .Property("stream-ids", "<0 1>")
1873 .Property("interrupts", "<2 3>, <4 5>")
1874 .Property("interrupts-target", "<20 0x1234 0x5678>")
1875 .EndChild()
1876 .EndChild()
1877 .Build();
1878 /* clang-format on */
1879
1880 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1881 MANIFEST_ERROR_INTERRUPT_ID_NOT_IN_LIST);
1882}
1883
Kathleen Capella4a2a6e72023-04-21 14:43:26 -04001884TEST_F(manifest, ffa_boot_order_not_unique)
1885{
1886 struct_manifest *m;
1887 struct memiter it;
1888 struct mm_stage1_locked mm_stage1_locked;
1889 struct boot_params params;
1890 Partition_package spkg_1;
1891 Partition_package spkg_2;
1892
1893 /* clang-format off */
1894 std::vector<char> dtb1 = ManifestDtBuilder()
1895 .Compatible({ "arm,ffa-manifest-1.0" })
1896 .Property("ffa-version", "<0x10001>")
1897 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1898 .FfaLoadAddress((uint64_t)&spkg_1)
1899 .Property("execution-ctx-count", "<1>")
1900 .Property("exception-level", "<1>")
1901 .Property("execution-state", "<0>")
1902 .Property("entrypoint-offset", "<0x00002000>")
1903 .Property("xlat-granule", "<0>")
1904 .Property("boot-order", "<1>")
1905 .Property("messaging-method", "<1>")
1906 .Property("ns-interrupts-action", "<0>")
1907 .Build();
1908
1909 std::vector<char> dtb2 = ManifestDtBuilder()
1910 .Compatible({ "arm,ffa-manifest-1.0" })
1911 .Property("ffa-version", "<0x10001>")
1912 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
1913 .FfaLoadAddress((uint64_t)&spkg_2)
1914 .Property("execution-ctx-count", "<1>")
1915 .Property("exception-level", "<1>")
1916 .Property("execution-state", "<0>")
1917 .Property("entrypoint-offset", "<0x00002000>")
1918 .Property("xlat-granule", "<0>")
1919 .Property("boot-order", "<1>")
1920 .Property("messaging-method", "<1>")
1921 .Property("ns-interrupts-action", "<0>")
1922 .Build();
1923
1924 /* clang-format on */
1925 spkg_1.init(dtb1);
1926 spkg_2.init(dtb2);
1927
1928 /* clang-format off */
1929 std::vector<char> core_dtb = ManifestDtBuilder()
1930 .StartChild("hypervisor")
1931 .Compatible()
1932 .StartChild("vm1")
1933 .DebugName("ffa_partition_1")
1934 .FfaPartition()
1935 .LoadAddress((uint64_t)&spkg_1)
1936 .VcpuCount(1)
1937 .MemSize(0x10000000)
1938 .EndChild()
1939 .StartChild("vm2")
1940 .DebugName("ffa_partition_2")
1941 .FfaPartition()
1942 .LoadAddress((uint64_t)&spkg_2)
1943 .VcpuCount(1)
1944 .MemSize(0x10000000)
1945 .EndChild()
1946 .EndChild()
1947 .Build();
1948 /* clang-format on */
1949
1950 boot_params_init(&params, nullptr);
1951 memiter_init(&it, core_dtb.data(), core_dtb.size());
1952 ASSERT_EQ(manifest_init(mm_stage1_locked, &m, &it, &params, &ppool),
1953 MANIFEST_ERROR_INVALID_BOOT_ORDER);
1954}
Daniel Boulby941ef342023-11-21 13:47:15 +00001955
Kathleen Capella422b10b2023-06-30 18:28:27 -04001956TEST_F(manifest, ffa_valid_multiple_uuids)
1957{
1958 struct manifest_vm *vm;
1959 struct_manifest *m;
1960
1961 /* clang-format off */
1962 std::vector<char> dtb = ManifestDtBuilder()
1963 .Compatible({ "arm,ffa-manifest-1.0" })
1964 .Property("ffa-version", "<0x10002>")
1965 .Property("uuid",
1966 "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>,\
1967 <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
1968 .Property("execution-ctx-count", "<1>")
1969 .Property("exception-level", "<2>")
1970 .Property("execution-state", "<0>")
1971 .Property("entrypoint-offset", "<0x00002000>")
1972 .Property("xlat-granule", "<0>")
1973 .Property("boot-order", "<0>")
1974 .Property("messaging-method", "<4>")
1975 .Property("ns-interrupts-action", "<1>")
1976 .Build();
1977 /* clang-format on */
1978 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1979
1980 vm = &m->vm[0];
1981 ASSERT_EQ(vm->partition.ffa_version, 0x10002);
1982 ASSERT_THAT(
1983 std::span(vm->partition.uuids[0].uuid, 4),
1984 ElementsAre(0xb4b5671e, 0x4a904fe1, 0xb81ffb13, 0xdae1dacb));
1985 ASSERT_THAT(
1986 std::span(vm->partition.uuids[1].uuid, 4),
1987 ElementsAre(0xb4b5671e, 0x4a904fe1, 0xb81ffb13, 0xdae1daaa));
1988 ASSERT_EQ(vm->partition.uuid_count, 2);
1989 ASSERT_EQ(vm->partition.execution_ctx_count, 1);
1990 ASSERT_EQ(vm->partition.run_time_el, S_EL1);
1991 ASSERT_EQ(vm->partition.execution_state, AARCH64);
1992 ASSERT_EQ(vm->partition.ep_offset, 0x00002000);
1993 ASSERT_EQ(vm->partition.xlat_granule, PAGE_4KB);
1994 ASSERT_EQ(vm->partition.boot_order, 0);
1995 ASSERT_EQ(vm->partition.messaging_method, FFA_PARTITION_INDIRECT_MSG);
1996 ASSERT_EQ(vm->partition.ns_interrupts_action, NS_ACTION_ME);
1997}
1998TEST_F(manifest, ffa_uuid_all_zeros)
1999{
2000 struct_manifest *m;
2001
2002 /* clang-format off */
2003 std::vector<char> dtb = ManifestDtBuilder()
2004 .Compatible({ "arm,ffa-manifest-1.0" })
2005 .Property("ffa-version", "<0x10002>")
2006 .Property("uuid",
2007 "<0x0 0x0 0x0 0x0>, <0x0 0x0 0x0 0x0>")
2008 .Property("execution-ctx-count", "<1>")
2009 .Property("exception-level", "<2>")
2010 .Property("execution-state", "<0>")
2011 .Property("entrypoint-offset", "<0x00002000>")
2012 .Property("xlat-granule", "<0>")
2013 .Property("boot-order", "<0>")
2014 .Property("messaging-method", "<4>")
2015 .Property("ns-interrupts-action", "<1>")
2016 .Build();
2017 /* clang-format on */
2018 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2019 MANIFEST_ERROR_UUID_ALL_ZEROS);
2020}
Daniel Boulby941ef342023-11-21 13:47:15 +00002021
2022/*
2023 * Test that the address space of two device region nodes specified across
2024 * different SPs cannot overlap.
2025 */
2026TEST_F(manifest, ffa_device_region_multi_sps)
2027{
2028 struct_manifest *m;
2029 struct memiter it;
2030 struct mm_stage1_locked mm_stage1_locked;
2031 struct boot_params params;
2032 Partition_package spkg_1;
2033 Partition_package spkg_2;
2034
2035 /* clang-format off */
2036 std::vector<char> dtb1 = ManifestDtBuilder()
2037 .Compatible({ "arm,ffa-manifest-1.0" })
2038 .Property("ffa-version", "<0x10001>")
2039 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
2040 .FfaLoadAddress((uint64_t)&spkg_1)
2041 .Property("execution-ctx-count", "<1>")
2042 .Property("exception-level", "<0>")
2043 .Property("execution-state", "<0>")
2044 .Property("entrypoint-offset", "<0x0>")
2045 .Property("xlat-granule", "<0>")
2046 .Property("messaging-method", "<0x7>")
2047 .StartChild("device-regions")
2048 .Compatible({ "arm,ffa-manifest-device-regions" })
2049 .StartChild("test-device-0")
2050 .Description("test-device-0")
Daniel Boulby4339edc2024-02-21 14:59:00 +00002051 .Property("base-address", "<0x24000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00002052 .Property("pages-count", "<16>")
2053 .Property("attributes", "<3>")
2054 .EndChild()
2055 .EndChild()
2056 .Build();
2057
2058 std::vector<char> dtb2 = ManifestDtBuilder()
2059 .Compatible({ "arm,ffa-manifest-1.0" })
2060 .Property("ffa-version", "<0x10001>")
2061 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
2062 .FfaLoadAddress((uint64_t)&spkg_2)
2063 .Property("execution-ctx-count", "<1>")
2064 .Property("exception-level", "<0>")
2065 .Property("execution-state", "<0>")
2066 .Property("entrypoint-offset", "<0x0>")
2067 .Property("xlat-granule", "<0>")
2068 .Property("messaging-method", "<0x7>")
2069 .StartChild("device-regions")
2070 .Compatible({ "arm,ffa-manifest-device-regions" })
2071 .StartChild("test-device-0")
2072 .Description("test-device-1")
Daniel Boulby4339edc2024-02-21 14:59:00 +00002073 .Property("base-address", "<0x24000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00002074 .Property("pages-count", "<16>")
2075 .Property("attributes", "<3>")
2076 .EndChild()
2077 .EndChild()
2078 .Build();
2079
2080 /* clang-format on */
2081 spkg_1.init(dtb1);
2082 spkg_2.init(dtb2);
2083
2084 /* clang-format off */
2085 std::vector<char> core_dtb = ManifestDtBuilder()
2086 .StartChild("hypervisor")
2087 .Compatible()
2088 .StartChild("vm1")
2089 .DebugName("ffa_partition_1")
2090 .FfaPartition()
2091 .LoadAddress((uint64_t)&spkg_1)
2092 .VcpuCount(1)
2093 .MemSize(0x4000)
2094 .EndChild()
2095 .StartChild("vm2")
2096 .DebugName("ffa_partition_2")
2097 .FfaPartition()
2098 .LoadAddress((uint64_t)&spkg_2)
2099 .VcpuCount(1)
2100 .MemSize(0x4000)
2101 .EndChild()
2102 .EndChild()
2103 .Build();
2104 /* clang-format on */
2105 boot_params_init(&params, &spkg_1);
2106 memiter_init(&it, core_dtb.data(), core_dtb.size());
2107 ASSERT_EQ(manifest_init(mm_stage1_locked, &m, &it, &params, &ppool),
2108 MANIFEST_ERROR_MEM_REGION_OVERLAP);
2109
2110 manifest_dealloc();
2111
2112 /* clang-format off */
2113 dtb1 = ManifestDtBuilder()
2114 .Compatible({ "arm,ffa-manifest-1.0" })
2115 .Property("ffa-version", "<0x10001>")
2116 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
2117 .FfaLoadAddress((uint64_t)&spkg_1)
2118 .Property("execution-ctx-count", "<1>")
2119 .Property("exception-level", "<0>")
2120 .Property("execution-state", "<0>")
2121 .Property("entrypoint-offset", "<0x0>")
2122 .Property("xlat-granule", "<0>")
2123 .Property("messaging-method", "<0x7>")
2124 .StartChild("device-regions")
2125 .Compatible({ "arm,ffa-manifest-device-regions" })
2126 .StartChild("test-device-0")
2127 .Description("test-device-0")
Daniel Boulby4339edc2024-02-21 14:59:00 +00002128 .Property("base-address", "<0x24000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00002129 .Property("pages-count", "<16>")
2130 .Property("attributes", "<3>")
2131 .EndChild()
2132 .EndChild()
2133 .Build();
2134
2135 dtb2 = ManifestDtBuilder()
2136 .Compatible({ "arm,ffa-manifest-1.0" })
2137 .Property("ffa-version", "<0x10001>")
2138 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
2139 .FfaLoadAddress((uint64_t)&spkg_2)
2140 .Property("execution-ctx-count", "<1>")
2141 .Property("exception-level", "<0>")
2142 .Property("execution-state", "<0>")
2143 .Property("entrypoint-offset", "<0x0>")
2144 .Property("xlat-granule", "<0>")
2145 .Property("messaging-method", "<0x7>")
2146 .StartChild("device-regions")
2147 .Compatible({ "arm,ffa-manifest-device-regions" })
2148 .StartChild("test-device-0")
2149 .Description("test-device-1")
Daniel Boulby4339edc2024-02-21 14:59:00 +00002150 .Property("base-address", "<0x25000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00002151 .Property("pages-count", "<16>")
2152 .Property("attributes", "<3>")
2153 .EndChild()
2154 .EndChild()
2155 .Build();
2156
2157 /* clang-format on */
2158 spkg_1.init(dtb1);
2159 spkg_2.init(dtb2);
2160
2161 /* clang-format off */
2162 core_dtb = ManifestDtBuilder()
2163 .StartChild("hypervisor")
2164 .Compatible()
2165 .StartChild("vm1")
2166 .DebugName("ffa_partition_1")
2167 .FfaPartition()
2168 .LoadAddress((uint64_t)&spkg_1)
2169 .VcpuCount(1)
2170 .MemSize(0x4000)
2171 .EndChild()
2172 .StartChild("vm2")
2173 .DebugName("ffa_partition_2")
2174 .FfaPartition()
2175 .LoadAddress((uint64_t)&spkg_2)
2176 .VcpuCount(1)
2177 .MemSize(0x4000)
2178 .EndChild()
2179 .EndChild()
2180 .Build();
2181 /* clang-format on */
2182 boot_params_init(&params, &spkg_1);
2183 memiter_init(&it, core_dtb.data(), core_dtb.size());
2184 ASSERT_EQ(manifest_init(mm_stage1_locked, &m, &it, &params, &ppool),
2185 MANIFEST_SUCCESS);
2186}
Madhukar Pappireddy99c5eff2024-07-08 15:07:41 -05002187
2188/*
2189 * Tests to trigger various error conditions while parsing dma related
2190 * properties of memory region nodes.
2191 */
2192TEST_F(manifest, ffa_memory_region_invalid_dma_properties)
2193{
2194 struct_manifest *m;
2195
2196 /*
2197 * SMMU ID must be specified if the partition specifies Stream IDs for
2198 * any device upstream of SMMU.
2199 */
2200 /* clang-format off */
2201 std::vector<char> dtb = ManifestDtBuilder()
2202 .FfaValidManifest()
2203 .StartChild("memory-regions")
2204 .Compatible({ "arm,ffa-manifest-memory-regions" })
2205 .StartChild("test-memory")
2206 .Description("test-memory")
2207 .Property("base-address", "<0x7100000>")
2208 .Property("pages-count", "<16>")
2209 .Property("attributes", "<3>")
2210 .Property("stream-ids", "<0 1>")
2211 .Property("interrupts", "<2 3>, <4 5>")
2212 .EndChild()
2213 .EndChild()
2214 .Build();
2215 /* clang-format on */
2216
2217 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2218 MANIFEST_ERROR_MISSING_SMMU_ID);
2219 manifest_dealloc();
2220
2221 /*
2222 * All stream ids belonging to a dma device must specify the same access
2223 * permissions.
2224 */
2225 /* clang-format off */
2226 dtb = ManifestDtBuilder()
2227 .FfaValidManifest()
2228 .StartChild("memory-regions")
2229 .Compatible({ "arm,ffa-manifest-memory-regions" })
2230 .StartChild("test-memory")
2231 .Description("test-memory")
2232 .Property("base-address", "<0x7100000>")
2233 .Property("pages-count", "<16>")
2234 .Property("attributes", "<3>")
2235 .Property("smmu-id", "<1>")
2236 .Property("stream-ids", "<0 1>")
2237 .Property("stream-ids-access-permissions", "<0x3 0xb>")
2238 .Property("interrupts", "<2 3>, <4 5>")
2239 .EndChild()
2240 .EndChild()
2241 .Build();
2242 /* clang-format on */
2243
2244 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2245 MANIFEST_ERROR_MISMATCH_DMA_ACCESS_PERMISSIONS);
2246 manifest_dealloc();
2247
2248 /*
2249 * DMA device stream ID count exceeds predefined limit.
2250 */
2251 /* clang-format off */
2252 dtb = ManifestDtBuilder()
2253 .FfaValidManifest()
2254 .StartChild("memory-regions")
2255 .Compatible({ "arm,ffa-manifest-memory-regions" })
2256 .StartChild("test-memory")
2257 .Description("test-memory")
2258 .Property("base-address", "<0x7100000>")
2259 .Property("pages-count", "<16>")
2260 .Property("attributes", "<3>")
2261 .Property("smmu-id", "<1>")
2262 .Property("stream-ids", "<0 1 4 9 12 >")
2263 .Property("stream-ids-access-permissions", "<0x3 0x3 0x3>")
2264 .EndChild()
2265 .EndChild()
2266 .Build();
2267 /* clang-format on */
2268
2269 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2270 MANIFEST_ERROR_STREAM_IDS_OVERFLOW);
2271 manifest_dealloc();
2272
2273 /*
2274 * DMA access permissions count exceeds predefined limit
2275 */
2276 /* clang-format off */
2277 dtb = ManifestDtBuilder()
2278 .FfaValidManifest()
2279 .StartChild("memory-regions")
2280 .Compatible({ "arm,ffa-manifest-memory-regions" })
2281 .StartChild("test-memory")
2282 .Description("test-memory")
2283 .Property("base-address", "<0x7100000>")
2284 .Property("pages-count", "<16>")
2285 .Property("attributes", "<3>")
2286 .Property("smmu-id", "<1>")
2287 .Property("stream-ids", "<0 1>")
2288 .Property("stream-ids-access-permissions", "<0x3 0x3 0x3 0x3 0x3>")
2289 .EndChild()
2290 .EndChild()
2291 .Build();
2292 /* clang-format on */
2293
2294 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2295 MANIFEST_ERROR_DMA_ACCESS_PERMISSIONS_OVERFLOW);
2296}
2297
2298/*
2299 * Tests to trigger various error conditions while parsing dma related
2300 * properties of device region nodes.
2301 */
2302TEST_F(manifest, ffa_device_region_invalid_dma_properties)
2303{
2304 struct_manifest *m;
2305
2306 /*
2307 * SMMU ID must be specified if the partition specifies Stream IDs for
2308 * any device upstream of SMMU.
2309 */
2310 /* clang-format off */
2311 std::vector<char> dtb = ManifestDtBuilder()
2312 .FfaValidManifest()
2313 .StartChild("device-regions")
2314 .Compatible({ "arm,ffa-manifest-device-regions" })
2315 .StartChild("test-device")
2316 .Description("test-device")
2317 .Property("base-address", "<0x24000000>")
2318 .Property("pages-count", "<16>")
2319 .Property("attributes", "<3>")
2320 .Property("stream-ids", "<0 1>")
2321 .Property("interrupts", "<2 3>, <4 5>")
2322 .EndChild()
2323 .EndChild()
2324 .Build();
2325 /* clang-format on */
2326
2327 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2328 MANIFEST_ERROR_MISSING_SMMU_ID);
2329 manifest_dealloc();
2330
2331 /*
2332 * Dma devices defined through device region nodes exceed predefined
2333 * limit.
2334 */
2335 /* clang-format off */
2336 dtb = ManifestDtBuilder()
2337 .FfaValidManifest()
2338 .StartChild("device-regions")
2339 .Compatible({ "arm,ffa-manifest-device-regions" })
2340 .StartChild("test-device-0")
2341 .Description("test-device-0")
2342 .Property("base-address", "<0x27000000>")
2343 .Property("pages-count", "<16>")
2344 .Property("attributes", "<3>")
2345 .Property("smmu-id", "<1>")
2346 .Property("stream-ids", "<0 1>")
2347 .EndChild()
2348 .StartChild("test-device-1")
2349 .Description("test-device-1")
2350 .Property("base-address", "<0x25000000>")
2351 .Property("pages-count", "<16>")
2352 .Property("attributes", "<3>")
2353 .Property("smmu-id", "<1>")
2354 .Property("stream-ids", "<2 3>")
2355 .EndChild()
2356 .StartChild("test-device-2")
2357 .Description("test-device-2")
2358 .Property("base-address", "<0x26000000>")
2359 .Property("pages-count", "<16>")
2360 .Property("attributes", "<3>")
2361 .Property("smmu-id", "<1>")
2362 .Property("stream-ids", "<4 5>")
2363 .EndChild()
2364 .EndChild()
2365 .Build();
2366 /* clang-format on */
2367
2368 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2369 MANIFEST_ERROR_DMA_DEVICE_OVERFLOW);
2370}
David Brazdil7a462ec2019-08-15 12:27:47 +01002371} /* namespace */