blob: 97148ad9a9fbbab7bd94de251ab56966275f91e1 [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" })
Olivier Deprez035fa152022-03-14 11:19:10 +01001714 .StartChild("test-memory-ns")
1715 .Description("test-memory")
1716 .Property("base-address", "<0x7200000>")
1717 .Property("pages-count", "<1>")
1718 .Property("attributes", "<0xb>")
1719 .EndChild()
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001720 .Label("rx")
1721 .StartChild("rx")
1722 .Description("rx-buffer")
1723 .Property("base-address", "<0x7300000>")
1724 .Property("pages-count", "<1>")
1725 .Property("attributes", "<1>")
1726 .EndChild()
1727 .Label("tx")
1728 .StartChild("tx")
1729 .Description("tx-buffer")
Daniel Boulby9279b552022-06-28 17:04:01 +01001730 .Property("base-address", "<0x7301000>")
Manish Pandeyfa1f2912020-05-05 12:57:01 +01001731 .Property("pages-count", "<1>")
1732 .Property("attributes", "<3>")
1733 .EndChild()
Manish Pandey6542f5c2020-04-27 14:37:46 +01001734 .EndChild()
Manish Pandeye68e7932020-04-23 15:29:28 +01001735 .StartChild("device-regions")
1736 .Compatible({ "arm,ffa-manifest-device-regions" })
1737 .StartChild("test-device")
1738 .Description("test-device")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001739 .Property("base-address", "<0x24000000>")
Manish Pandeye68e7932020-04-23 15:29:28 +01001740 .Property("pages-count", "<16>")
1741 .Property("attributes", "<3>")
1742 .Property("smmu-id", "<1>")
1743 .Property("stream-ids", "<0 1>")
1744 .Property("interrupts", "<2 3>, <4 5>")
1745 .EndChild()
Olivier Deprez035fa152022-03-14 11:19:10 +01001746 .StartChild("test-device-ns")
1747 .Description("test-device")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001748 .Property("base-address", "<0x20000000>")
Olivier Deprez035fa152022-03-14 11:19:10 +01001749 .Property("pages-count", "<1>")
1750 .Property("attributes", "<0x9>")
1751 .EndChild()
Manish Pandeye68e7932020-04-23 15:29:28 +01001752 .EndChild()
Olivier Deprez62d99e32020-01-09 15:58:07 +01001753 .Build();
Daniel Boulby4339edc2024-02-21 14:59:00 +00001754
Olivier Deprez62d99e32020-01-09 15:58:07 +01001755 /* clang-format on */
Olivier Deprez62d99e32020-01-09 15:58:07 +01001756 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1757
Olivier Deprez93644652022-09-09 11:01:12 +02001758 vm = &m->vm[0];
1759 ASSERT_EQ(vm->partition.ffa_version, 0x10000);
Olivier Deprez62d99e32020-01-09 15:58:07 +01001760 ASSERT_THAT(
Kathleen Capella422b10b2023-06-30 18:28:27 -04001761 std::span(vm->partition.uuids[0].uuid, 4),
Olivier Deprez62d99e32020-01-09 15:58:07 +01001762 ElementsAre(0xb4b5671e, 0x4a904fe1, 0xb81ffb13, 0xdae1dacb));
Olivier Deprez93644652022-09-09 11:01:12 +02001763 ASSERT_EQ(vm->partition.execution_ctx_count, 1);
1764 ASSERT_EQ(vm->partition.run_time_el, S_EL1);
1765 ASSERT_EQ(vm->partition.execution_state, AARCH64);
1766 ASSERT_EQ(vm->partition.ep_offset, 0x00002000);
1767 ASSERT_EQ(vm->partition.xlat_granule, PAGE_4KB);
1768 ASSERT_EQ(vm->partition.boot_order, 0);
1769 ASSERT_EQ(vm->partition.messaging_method, FFA_PARTITION_INDIRECT_MSG);
1770 ASSERT_EQ(vm->partition.ns_interrupts_action, NS_ACTION_ME);
Davidson K5d5f2792024-08-19 19:09:12 +05301771 ASSERT_EQ(vm->partition.mem_regions[0].attributes, (8 | 3));
Raghu Krishnamurthy8c250a92021-07-02 12:16:42 -07001772
Olivier Deprez93644652022-09-09 11:01:12 +02001773 ASSERT_EQ(vm->partition.rxtx.available, true);
1774 ASSERT_EQ(vm->partition.rxtx.rx_buffer->base_address, 0x7300000);
1775 ASSERT_EQ(vm->partition.rxtx.rx_buffer->page_count, 1);
1776 ASSERT_EQ(vm->partition.rxtx.rx_buffer->attributes, 1);
1777 ASSERT_EQ(vm->partition.rxtx.tx_buffer->base_address, 0x7301000);
1778 ASSERT_EQ(vm->partition.rxtx.tx_buffer->page_count, 1);
1779 ASSERT_EQ(vm->partition.rxtx.tx_buffer->attributes, 3);
1780
Daniel Boulby4339edc2024-02-21 14:59:00 +00001781 ASSERT_EQ(vm->partition.dev_regions[0].base_address, 0x24000000);
Olivier Deprez93644652022-09-09 11:01:12 +02001782 ASSERT_EQ(vm->partition.dev_regions[0].page_count, 16);
Olivier Deprez058ddee2024-08-27 09:22:11 +02001783 ASSERT_EQ(vm->partition.dev_regions[0].attributes, 3);
Madhukar Pappireddy9c764b32024-06-20 14:36:55 -05001784 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.smmu_id, 1);
1785 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.stream_ids[0], 0);
1786 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.stream_ids[1], 1);
Olivier Deprez93644652022-09-09 11:01:12 +02001787 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].id, 2);
1788 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].attributes, 3);
1789 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].id, 4);
1790 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].attributes, 5);
Daniel Boulby4339edc2024-02-21 14:59:00 +00001791 ASSERT_EQ(vm->partition.dev_regions[1].base_address, 0x20000000);
Olivier Deprez058ddee2024-08-27 09:22:11 +02001792 ASSERT_EQ(vm->partition.dev_regions[1].attributes, (8 | 1));
Olivier Deprez62d99e32020-01-09 15:58:07 +01001793}
1794
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001795TEST_F(manifest, ffa_valid_interrupt_target_manifest)
1796{
1797 struct manifest_vm *vm;
1798 struct_manifest *m;
1799
1800 /* clang-format off */
1801 std::vector<char> dtb = ManifestDtBuilder()
1802 .FfaValidManifest()
1803 .StartChild("device-regions")
1804 .Compatible({ "arm,ffa-manifest-device-regions" })
1805 .StartChild("test-device")
1806 .Description("test-device")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001807 .Property("base-address", "<0x24000000>")
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001808 .Property("pages-count", "<16>")
1809 .Property("attributes", "<3>")
1810 .Property("smmu-id", "<1>")
1811 .Property("stream-ids", "<0 1>")
1812 .Property("interrupts", "<2 3>, <4 5>")
1813 .Property("interrupts-target", "<2 0x1234 0x5678>, <4 0x12345678 0x87654321>")
1814 .EndChild()
1815 .EndChild()
1816 .Build();
1817 /* clang-format on */
1818
1819 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1820
1821 vm = &m->vm[0];
1822
Daniel Boulby4339edc2024-02-21 14:59:00 +00001823 ASSERT_EQ(vm->partition.dev_regions[0].base_address, 0x24000000);
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001824 ASSERT_EQ(vm->partition.dev_regions[0].page_count, 16);
Olivier Deprez058ddee2024-08-27 09:22:11 +02001825 ASSERT_EQ(vm->partition.dev_regions[0].attributes, 3);
Madhukar Pappireddy9c764b32024-06-20 14:36:55 -05001826 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.smmu_id, 1);
1827 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.stream_ids[0], 0);
1828 ASSERT_EQ(vm->partition.dev_regions[0].dma_prop.stream_ids[1], 1);
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001829 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].id, 2);
1830 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].attributes, 3);
1831 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].mpidr_valid, true);
1832 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[0].mpidr,
1833 0x123400005678);
1834 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].id, 4);
1835 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].attributes, 5);
1836 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].mpidr_valid, true);
1837 ASSERT_EQ(vm->partition.dev_regions[0].interrupts[1].mpidr,
1838 0x1234567887654321);
1839}
1840
1841TEST_F(manifest, ffa_invalid_interrupt_target_manifest)
1842{
1843 struct_manifest *m;
1844
1845 /* clang-format off */
1846 std::vector<char> dtb = ManifestDtBuilder()
1847 .FfaValidManifest()
1848 .StartChild("device-regions")
1849 .Compatible({ "arm,ffa-manifest-device-regions" })
1850 .StartChild("test-device")
1851 .Description("test-device")
Daniel Boulby4339edc2024-02-21 14:59:00 +00001852 .Property("base-address", "<0x24000000>")
Raghu Krishnamurthy98da1ca2022-10-04 08:59:01 -07001853 .Property("pages-count", "<16>")
1854 .Property("attributes", "<3>")
1855 .Property("smmu-id", "<1>")
1856 .Property("stream-ids", "<0 1>")
1857 .Property("interrupts", "<2 3>, <4 5>")
1858 .Property("interrupts-target", "<20 0x1234 0x5678>")
1859 .EndChild()
1860 .EndChild()
1861 .Build();
1862 /* clang-format on */
1863
1864 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
1865 MANIFEST_ERROR_INTERRUPT_ID_NOT_IN_LIST);
1866}
1867
Kathleen Capella4a2a6e72023-04-21 14:43:26 -04001868TEST_F(manifest, ffa_boot_order_not_unique)
1869{
1870 struct_manifest *m;
1871 struct memiter it;
1872 struct mm_stage1_locked mm_stage1_locked;
1873 struct boot_params params;
1874 Partition_package spkg_1;
1875 Partition_package spkg_2;
1876
1877 /* clang-format off */
1878 std::vector<char> dtb1 = ManifestDtBuilder()
1879 .Compatible({ "arm,ffa-manifest-1.0" })
1880 .Property("ffa-version", "<0x10001>")
1881 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
1882 .FfaLoadAddress((uint64_t)&spkg_1)
1883 .Property("execution-ctx-count", "<1>")
1884 .Property("exception-level", "<1>")
1885 .Property("execution-state", "<0>")
1886 .Property("entrypoint-offset", "<0x00002000>")
1887 .Property("xlat-granule", "<0>")
1888 .Property("boot-order", "<1>")
1889 .Property("messaging-method", "<1>")
1890 .Property("ns-interrupts-action", "<0>")
1891 .Build();
1892
1893 std::vector<char> dtb2 = ManifestDtBuilder()
1894 .Compatible({ "arm,ffa-manifest-1.0" })
1895 .Property("ffa-version", "<0x10001>")
1896 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
1897 .FfaLoadAddress((uint64_t)&spkg_2)
1898 .Property("execution-ctx-count", "<1>")
1899 .Property("exception-level", "<1>")
1900 .Property("execution-state", "<0>")
1901 .Property("entrypoint-offset", "<0x00002000>")
1902 .Property("xlat-granule", "<0>")
1903 .Property("boot-order", "<1>")
1904 .Property("messaging-method", "<1>")
1905 .Property("ns-interrupts-action", "<0>")
1906 .Build();
1907
1908 /* clang-format on */
1909 spkg_1.init(dtb1);
1910 spkg_2.init(dtb2);
1911
1912 /* clang-format off */
1913 std::vector<char> core_dtb = ManifestDtBuilder()
1914 .StartChild("hypervisor")
1915 .Compatible()
1916 .StartChild("vm1")
1917 .DebugName("ffa_partition_1")
1918 .FfaPartition()
1919 .LoadAddress((uint64_t)&spkg_1)
1920 .VcpuCount(1)
1921 .MemSize(0x10000000)
1922 .EndChild()
1923 .StartChild("vm2")
1924 .DebugName("ffa_partition_2")
1925 .FfaPartition()
1926 .LoadAddress((uint64_t)&spkg_2)
1927 .VcpuCount(1)
1928 .MemSize(0x10000000)
1929 .EndChild()
1930 .EndChild()
1931 .Build();
1932 /* clang-format on */
1933
1934 boot_params_init(&params, nullptr);
1935 memiter_init(&it, core_dtb.data(), core_dtb.size());
1936 ASSERT_EQ(manifest_init(mm_stage1_locked, &m, &it, &params, &ppool),
1937 MANIFEST_ERROR_INVALID_BOOT_ORDER);
1938}
Daniel Boulby941ef342023-11-21 13:47:15 +00001939
Kathleen Capella422b10b2023-06-30 18:28:27 -04001940TEST_F(manifest, ffa_valid_multiple_uuids)
1941{
1942 struct manifest_vm *vm;
1943 struct_manifest *m;
1944
1945 /* clang-format off */
1946 std::vector<char> dtb = ManifestDtBuilder()
1947 .Compatible({ "arm,ffa-manifest-1.0" })
1948 .Property("ffa-version", "<0x10002>")
1949 .Property("uuid",
1950 "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>,\
1951 <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
1952 .Property("execution-ctx-count", "<1>")
1953 .Property("exception-level", "<2>")
1954 .Property("execution-state", "<0>")
1955 .Property("entrypoint-offset", "<0x00002000>")
1956 .Property("xlat-granule", "<0>")
1957 .Property("boot-order", "<0>")
1958 .Property("messaging-method", "<4>")
1959 .Property("ns-interrupts-action", "<1>")
1960 .Build();
1961 /* clang-format on */
1962 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb), MANIFEST_SUCCESS);
1963
1964 vm = &m->vm[0];
1965 ASSERT_EQ(vm->partition.ffa_version, 0x10002);
1966 ASSERT_THAT(
1967 std::span(vm->partition.uuids[0].uuid, 4),
1968 ElementsAre(0xb4b5671e, 0x4a904fe1, 0xb81ffb13, 0xdae1dacb));
1969 ASSERT_THAT(
1970 std::span(vm->partition.uuids[1].uuid, 4),
1971 ElementsAre(0xb4b5671e, 0x4a904fe1, 0xb81ffb13, 0xdae1daaa));
1972 ASSERT_EQ(vm->partition.uuid_count, 2);
1973 ASSERT_EQ(vm->partition.execution_ctx_count, 1);
1974 ASSERT_EQ(vm->partition.run_time_el, S_EL1);
1975 ASSERT_EQ(vm->partition.execution_state, AARCH64);
1976 ASSERT_EQ(vm->partition.ep_offset, 0x00002000);
1977 ASSERT_EQ(vm->partition.xlat_granule, PAGE_4KB);
1978 ASSERT_EQ(vm->partition.boot_order, 0);
1979 ASSERT_EQ(vm->partition.messaging_method, FFA_PARTITION_INDIRECT_MSG);
1980 ASSERT_EQ(vm->partition.ns_interrupts_action, NS_ACTION_ME);
1981}
Karl Meakin45abeeb2024-08-02 16:55:44 +01001982
1983TEST_F(manifest, ffa_too_many_uuids)
1984{
1985 struct_manifest *m;
1986
1987 /* clang-format off */
1988 std::vector<char> dtb = ManifestDtBuilder()
1989 .Compatible({ "arm,ffa-manifest-1.0" })
1990 .Property("ffa-version", "<0x10002>")
1991 .Property("uuid",
1992 "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>,"
1993 "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>,"
1994 "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>,"
1995 "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>,"
1996 "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
1997 .Property("execution-ctx-count", "<1>")
1998 .Property("exception-level", "<2>")
1999 .Property("execution-state", "<0>")
2000 .Property("entrypoint-offset", "<0x00002000>")
2001 .Property("xlat-granule", "<0>")
2002 .Property("boot-order", "<0>")
2003 .Property("messaging-method", "<4>")
2004 .Property("ns-interrupts-action", "<1>")
2005 .Build();
2006 /* clang-format on */
2007 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2008 MANIFEST_ERROR_TOO_MANY_UUIDS);
2009}
2010
Kathleen Capella422b10b2023-06-30 18:28:27 -04002011TEST_F(manifest, ffa_uuid_all_zeros)
2012{
2013 struct_manifest *m;
2014
2015 /* clang-format off */
2016 std::vector<char> dtb = ManifestDtBuilder()
2017 .Compatible({ "arm,ffa-manifest-1.0" })
2018 .Property("ffa-version", "<0x10002>")
2019 .Property("uuid",
2020 "<0x0 0x0 0x0 0x0>, <0x0 0x0 0x0 0x0>")
2021 .Property("execution-ctx-count", "<1>")
2022 .Property("exception-level", "<2>")
2023 .Property("execution-state", "<0>")
2024 .Property("entrypoint-offset", "<0x00002000>")
2025 .Property("xlat-granule", "<0>")
2026 .Property("boot-order", "<0>")
2027 .Property("messaging-method", "<4>")
2028 .Property("ns-interrupts-action", "<1>")
2029 .Build();
2030 /* clang-format on */
2031 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2032 MANIFEST_ERROR_UUID_ALL_ZEROS);
2033}
Daniel Boulby941ef342023-11-21 13:47:15 +00002034
2035/*
2036 * Test that the address space of two device region nodes specified across
2037 * different SPs cannot overlap.
2038 */
2039TEST_F(manifest, ffa_device_region_multi_sps)
2040{
2041 struct_manifest *m;
2042 struct memiter it;
2043 struct mm_stage1_locked mm_stage1_locked;
2044 struct boot_params params;
2045 Partition_package spkg_1;
2046 Partition_package spkg_2;
2047
2048 /* clang-format off */
2049 std::vector<char> dtb1 = ManifestDtBuilder()
2050 .Compatible({ "arm,ffa-manifest-1.0" })
2051 .Property("ffa-version", "<0x10001>")
2052 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
2053 .FfaLoadAddress((uint64_t)&spkg_1)
2054 .Property("execution-ctx-count", "<1>")
2055 .Property("exception-level", "<0>")
2056 .Property("execution-state", "<0>")
2057 .Property("entrypoint-offset", "<0x0>")
2058 .Property("xlat-granule", "<0>")
2059 .Property("messaging-method", "<0x7>")
2060 .StartChild("device-regions")
2061 .Compatible({ "arm,ffa-manifest-device-regions" })
2062 .StartChild("test-device-0")
2063 .Description("test-device-0")
Daniel Boulby4339edc2024-02-21 14:59:00 +00002064 .Property("base-address", "<0x24000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00002065 .Property("pages-count", "<16>")
2066 .Property("attributes", "<3>")
2067 .EndChild()
2068 .EndChild()
2069 .Build();
2070
2071 std::vector<char> dtb2 = ManifestDtBuilder()
2072 .Compatible({ "arm,ffa-manifest-1.0" })
2073 .Property("ffa-version", "<0x10001>")
2074 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
2075 .FfaLoadAddress((uint64_t)&spkg_2)
2076 .Property("execution-ctx-count", "<1>")
2077 .Property("exception-level", "<0>")
2078 .Property("execution-state", "<0>")
2079 .Property("entrypoint-offset", "<0x0>")
2080 .Property("xlat-granule", "<0>")
2081 .Property("messaging-method", "<0x7>")
2082 .StartChild("device-regions")
2083 .Compatible({ "arm,ffa-manifest-device-regions" })
2084 .StartChild("test-device-0")
2085 .Description("test-device-1")
Daniel Boulby4339edc2024-02-21 14:59:00 +00002086 .Property("base-address", "<0x24000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00002087 .Property("pages-count", "<16>")
2088 .Property("attributes", "<3>")
2089 .EndChild()
2090 .EndChild()
2091 .Build();
2092
2093 /* clang-format on */
2094 spkg_1.init(dtb1);
2095 spkg_2.init(dtb2);
2096
2097 /* clang-format off */
2098 std::vector<char> core_dtb = ManifestDtBuilder()
2099 .StartChild("hypervisor")
2100 .Compatible()
2101 .StartChild("vm1")
2102 .DebugName("ffa_partition_1")
2103 .FfaPartition()
2104 .LoadAddress((uint64_t)&spkg_1)
2105 .VcpuCount(1)
2106 .MemSize(0x4000)
2107 .EndChild()
2108 .StartChild("vm2")
2109 .DebugName("ffa_partition_2")
2110 .FfaPartition()
2111 .LoadAddress((uint64_t)&spkg_2)
2112 .VcpuCount(1)
2113 .MemSize(0x4000)
2114 .EndChild()
2115 .EndChild()
2116 .Build();
2117 /* clang-format on */
2118 boot_params_init(&params, &spkg_1);
2119 memiter_init(&it, core_dtb.data(), core_dtb.size());
2120 ASSERT_EQ(manifest_init(mm_stage1_locked, &m, &it, &params, &ppool),
2121 MANIFEST_ERROR_MEM_REGION_OVERLAP);
2122
2123 manifest_dealloc();
2124
2125 /* clang-format off */
2126 dtb1 = ManifestDtBuilder()
2127 .Compatible({ "arm,ffa-manifest-1.0" })
2128 .Property("ffa-version", "<0x10001>")
2129 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>")
2130 .FfaLoadAddress((uint64_t)&spkg_1)
2131 .Property("execution-ctx-count", "<1>")
2132 .Property("exception-level", "<0>")
2133 .Property("execution-state", "<0>")
2134 .Property("entrypoint-offset", "<0x0>")
2135 .Property("xlat-granule", "<0>")
2136 .Property("messaging-method", "<0x7>")
2137 .StartChild("device-regions")
2138 .Compatible({ "arm,ffa-manifest-device-regions" })
2139 .StartChild("test-device-0")
2140 .Description("test-device-0")
Daniel Boulby4339edc2024-02-21 14:59:00 +00002141 .Property("base-address", "<0x24000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00002142 .Property("pages-count", "<16>")
2143 .Property("attributes", "<3>")
2144 .EndChild()
2145 .EndChild()
2146 .Build();
2147
2148 dtb2 = ManifestDtBuilder()
2149 .Compatible({ "arm,ffa-manifest-1.0" })
2150 .Property("ffa-version", "<0x10001>")
2151 .Property("uuid", "<0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1daaa>")
2152 .FfaLoadAddress((uint64_t)&spkg_2)
2153 .Property("execution-ctx-count", "<1>")
2154 .Property("exception-level", "<0>")
2155 .Property("execution-state", "<0>")
2156 .Property("entrypoint-offset", "<0x0>")
2157 .Property("xlat-granule", "<0>")
2158 .Property("messaging-method", "<0x7>")
2159 .StartChild("device-regions")
2160 .Compatible({ "arm,ffa-manifest-device-regions" })
2161 .StartChild("test-device-0")
2162 .Description("test-device-1")
Daniel Boulby4339edc2024-02-21 14:59:00 +00002163 .Property("base-address", "<0x25000000>")
Daniel Boulby941ef342023-11-21 13:47:15 +00002164 .Property("pages-count", "<16>")
2165 .Property("attributes", "<3>")
2166 .EndChild()
2167 .EndChild()
2168 .Build();
2169
2170 /* clang-format on */
2171 spkg_1.init(dtb1);
2172 spkg_2.init(dtb2);
2173
2174 /* clang-format off */
2175 core_dtb = ManifestDtBuilder()
2176 .StartChild("hypervisor")
2177 .Compatible()
2178 .StartChild("vm1")
2179 .DebugName("ffa_partition_1")
2180 .FfaPartition()
2181 .LoadAddress((uint64_t)&spkg_1)
2182 .VcpuCount(1)
2183 .MemSize(0x4000)
2184 .EndChild()
2185 .StartChild("vm2")
2186 .DebugName("ffa_partition_2")
2187 .FfaPartition()
2188 .LoadAddress((uint64_t)&spkg_2)
2189 .VcpuCount(1)
2190 .MemSize(0x4000)
2191 .EndChild()
2192 .EndChild()
2193 .Build();
2194 /* clang-format on */
2195 boot_params_init(&params, &spkg_1);
2196 memiter_init(&it, core_dtb.data(), core_dtb.size());
2197 ASSERT_EQ(manifest_init(mm_stage1_locked, &m, &it, &params, &ppool),
2198 MANIFEST_SUCCESS);
2199}
Madhukar Pappireddy99c5eff2024-07-08 15:07:41 -05002200
2201/*
2202 * Tests to trigger various error conditions while parsing dma related
2203 * properties of memory region nodes.
2204 */
2205TEST_F(manifest, ffa_memory_region_invalid_dma_properties)
2206{
2207 struct_manifest *m;
2208
2209 /*
2210 * SMMU ID must be specified if the partition specifies Stream IDs for
2211 * any device upstream of SMMU.
2212 */
2213 /* clang-format off */
2214 std::vector<char> dtb = ManifestDtBuilder()
2215 .FfaValidManifest()
2216 .StartChild("memory-regions")
2217 .Compatible({ "arm,ffa-manifest-memory-regions" })
2218 .StartChild("test-memory")
2219 .Description("test-memory")
2220 .Property("base-address", "<0x7100000>")
2221 .Property("pages-count", "<16>")
2222 .Property("attributes", "<3>")
2223 .Property("stream-ids", "<0 1>")
2224 .Property("interrupts", "<2 3>, <4 5>")
2225 .EndChild()
2226 .EndChild()
2227 .Build();
2228 /* clang-format on */
2229
2230 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2231 MANIFEST_ERROR_MISSING_SMMU_ID);
2232 manifest_dealloc();
2233
2234 /*
2235 * All stream ids belonging to a dma device must specify the same access
2236 * permissions.
2237 */
2238 /* clang-format off */
2239 dtb = ManifestDtBuilder()
2240 .FfaValidManifest()
2241 .StartChild("memory-regions")
2242 .Compatible({ "arm,ffa-manifest-memory-regions" })
2243 .StartChild("test-memory")
2244 .Description("test-memory")
2245 .Property("base-address", "<0x7100000>")
2246 .Property("pages-count", "<16>")
2247 .Property("attributes", "<3>")
2248 .Property("smmu-id", "<1>")
2249 .Property("stream-ids", "<0 1>")
2250 .Property("stream-ids-access-permissions", "<0x3 0xb>")
2251 .Property("interrupts", "<2 3>, <4 5>")
2252 .EndChild()
2253 .EndChild()
2254 .Build();
2255 /* clang-format on */
2256
2257 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2258 MANIFEST_ERROR_MISMATCH_DMA_ACCESS_PERMISSIONS);
2259 manifest_dealloc();
2260
2261 /*
2262 * DMA device stream ID count exceeds predefined limit.
2263 */
2264 /* clang-format off */
2265 dtb = ManifestDtBuilder()
2266 .FfaValidManifest()
2267 .StartChild("memory-regions")
2268 .Compatible({ "arm,ffa-manifest-memory-regions" })
2269 .StartChild("test-memory")
2270 .Description("test-memory")
2271 .Property("base-address", "<0x7100000>")
2272 .Property("pages-count", "<16>")
2273 .Property("attributes", "<3>")
2274 .Property("smmu-id", "<1>")
2275 .Property("stream-ids", "<0 1 4 9 12 >")
2276 .Property("stream-ids-access-permissions", "<0x3 0x3 0x3>")
2277 .EndChild()
2278 .EndChild()
2279 .Build();
2280 /* clang-format on */
2281
2282 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2283 MANIFEST_ERROR_STREAM_IDS_OVERFLOW);
2284 manifest_dealloc();
2285
2286 /*
2287 * DMA access permissions count exceeds predefined limit
2288 */
2289 /* clang-format off */
2290 dtb = ManifestDtBuilder()
2291 .FfaValidManifest()
2292 .StartChild("memory-regions")
2293 .Compatible({ "arm,ffa-manifest-memory-regions" })
2294 .StartChild("test-memory")
2295 .Description("test-memory")
2296 .Property("base-address", "<0x7100000>")
2297 .Property("pages-count", "<16>")
2298 .Property("attributes", "<3>")
2299 .Property("smmu-id", "<1>")
2300 .Property("stream-ids", "<0 1>")
2301 .Property("stream-ids-access-permissions", "<0x3 0x3 0x3 0x3 0x3>")
2302 .EndChild()
2303 .EndChild()
2304 .Build();
2305 /* clang-format on */
2306
2307 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2308 MANIFEST_ERROR_DMA_ACCESS_PERMISSIONS_OVERFLOW);
2309}
2310
2311/*
2312 * Tests to trigger various error conditions while parsing dma related
2313 * properties of device region nodes.
2314 */
2315TEST_F(manifest, ffa_device_region_invalid_dma_properties)
2316{
2317 struct_manifest *m;
2318
2319 /*
2320 * SMMU ID must be specified if the partition specifies Stream IDs for
2321 * any device upstream of SMMU.
2322 */
2323 /* clang-format off */
2324 std::vector<char> dtb = ManifestDtBuilder()
2325 .FfaValidManifest()
2326 .StartChild("device-regions")
2327 .Compatible({ "arm,ffa-manifest-device-regions" })
2328 .StartChild("test-device")
2329 .Description("test-device")
2330 .Property("base-address", "<0x24000000>")
2331 .Property("pages-count", "<16>")
2332 .Property("attributes", "<3>")
2333 .Property("stream-ids", "<0 1>")
2334 .Property("interrupts", "<2 3>, <4 5>")
2335 .EndChild()
2336 .EndChild()
2337 .Build();
2338 /* clang-format on */
2339
2340 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2341 MANIFEST_ERROR_MISSING_SMMU_ID);
2342 manifest_dealloc();
2343
2344 /*
2345 * Dma devices defined through device region nodes exceed predefined
2346 * limit.
2347 */
2348 /* clang-format off */
2349 dtb = ManifestDtBuilder()
2350 .FfaValidManifest()
2351 .StartChild("device-regions")
2352 .Compatible({ "arm,ffa-manifest-device-regions" })
2353 .StartChild("test-device-0")
2354 .Description("test-device-0")
2355 .Property("base-address", "<0x27000000>")
2356 .Property("pages-count", "<16>")
2357 .Property("attributes", "<3>")
2358 .Property("smmu-id", "<1>")
2359 .Property("stream-ids", "<0 1>")
2360 .EndChild()
2361 .StartChild("test-device-1")
2362 .Description("test-device-1")
2363 .Property("base-address", "<0x25000000>")
2364 .Property("pages-count", "<16>")
2365 .Property("attributes", "<3>")
2366 .Property("smmu-id", "<1>")
2367 .Property("stream-ids", "<2 3>")
2368 .EndChild()
2369 .StartChild("test-device-2")
2370 .Description("test-device-2")
2371 .Property("base-address", "<0x26000000>")
2372 .Property("pages-count", "<16>")
2373 .Property("attributes", "<3>")
2374 .Property("smmu-id", "<1>")
2375 .Property("stream-ids", "<4 5>")
2376 .EndChild()
2377 .EndChild()
2378 .Build();
2379 /* clang-format on */
2380
2381 ASSERT_EQ(ffa_manifest_from_vec(&m, dtb),
2382 MANIFEST_ERROR_DMA_DEVICE_OVERFLOW);
2383}
David Brazdil7a462ec2019-08-15 12:27:47 +01002384} /* namespace */