blob: 1d62005806c55e7d14665bce33544b48902e890c [file] [log] [blame]
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6#include <CppUTest/CommandLineTestRunner.h>
7#include <CppUTest/TestHarness.h>
8
9extern "C" {
10#include <cpuid.h>
11#include <granule.h>
12#include <granule_types.h>
13#include <host_harness.h>
14#include <host_utils.h>
15#include <status.h>
16#include <stdlib.h>
17#include <string.h>
18#include <s2tt_pvt_defs.h>
19#include <s2tt_test_helpers.h>
20#include <ripas.h>
21#include <s2tt.h> /* Interface to exercise */
22#include <test_helpers.h>
23#include <unistd.h>
24#include <utils_def.h>
25}
26
27void s2tte_is_addr_lvl_aligned_tc1(void)
28{
29 /***************************************************************
30 * TEST CASE 1:
31 *
32 * For every valid level, generate an aligned valid PA and
33 * validate that add_is_level_aligned() returns the right
34 * result.
35 ***************************************************************/
Soby Mathewb1228bb2024-12-31 17:42:46 +000036 struct s2tt_context s2tt_ctx;
37
38 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +010039
40 /*
41 * Generate an s2tt context to be used for the test. Only
42 * enable_lpa2 field is needed for the current test.
43 */
44 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
45
46 for (long level = s2tt_test_helpers_min_table_lvl();
47 level <= S2TT_TEST_HELPERS_MAX_LVL; level++) {
48 unsigned long pa = s2tt_test_helpers_gen_addr(level, true);
49
50 CHECK_TRUE(s2tte_is_addr_lvl_aligned(
51 (const struct s2tt_context *)&s2tt_ctx,
52 pa, level));
53 }
54}
55
56void s2tte_is_addr_lvl_aligned_tc2(void)
57{
58 /***************************************************************
59 * TEST CASE 2:
60 *
61 * Negative tests: for every valid level, generate an unaligned
62 * PA and validate that add_is_level_aligned() returns the
63 * right result.
64 ***************************************************************/
Soby Mathewb1228bb2024-12-31 17:42:46 +000065 struct s2tt_context s2tt_ctx;
66
67 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +010068
69 /*
70 * Generate an s2tt context to be used for the test. Only
71 * enable_lpa2 field is needed for the current test.
72 */
73 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
74
75 for (long level = s2tt_test_helpers_min_table_lvl();
76 level <= S2TT_TEST_HELPERS_MAX_LVL; level++) {
77 unsigned long pa = s2tt_test_helpers_gen_addr(level, true);
78
79 pa += test_helpers_get_rand_in_range(1UL, (unsigned long)GRANULE_SIZE - 1UL);
80
81 CHECK_TRUE(s2tte_is_addr_lvl_aligned(
82 (const struct s2tt_context *)&s2tt_ctx,
83 pa, level) == false);
84 }
85}
86
87void s2tte_is_addr_lvl_aligned_tc3(void)
88{
89 /***************************************************************
90 * TEST CASE 3:
91 *
92 * Given a valid PA, call s2tte_is_addr_lvl_aligned() with a level
93 * above the maximum permitted one.
94 ***************************************************************/
95
96 long level = S2TT_TEST_HELPERS_MAX_LVL + 1L;
97 unsigned long pa = 0UL; /* Aligned to any level */
Soby Mathewb1228bb2024-12-31 17:42:46 +000098 struct s2tt_context s2tt_ctx;
99
100 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100101
102 /*
103 * Generate an s2tt context to be used for the test. Only
104 * enable_lpa2 field is needed for the current test.
105 */
106 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
107
108 test_helpers_expect_assert_fail(true);
109 (void)s2tte_is_addr_lvl_aligned((const struct s2tt_context *)&s2tt_ctx,
110 pa, level);
111 test_helpers_fail_if_no_assert_failed();
112}
113
114void s2tte_is_addr_lvl_aligned_tc4(void)
115{
116 /***************************************************************
117 * TEST CASE 4:
118 *
119 * Given a valid PA, call s2tte_is_addr_lvl_aligned() with a level
120 * below the minimum permitted one.
121 ***************************************************************/
122
123 long level = s2tt_test_helpers_min_table_lvl() - 1L;
124 unsigned long pa = 0UL; /* Aligned to any level */
Soby Mathewb1228bb2024-12-31 17:42:46 +0000125 struct s2tt_context s2tt_ctx;
126
127 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100128
129 /*
130 * Generate an s2tt context to be used for the test. Only
131 * enable_lpa2 field is needed for the current test.
132 */
133 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
134
135 test_helpers_expect_assert_fail(true);
136 (void)s2tte_is_addr_lvl_aligned((const struct s2tt_context *)&s2tt_ctx,
137 pa, level);
138 test_helpers_fail_if_no_assert_failed();
139}
140
141void s2tte_is_addr_lvl_aligned_tc5(void)
142{
143 /***************************************************************
144 * TEST CASE 5:
145 *
146 * Test s2tte_is_addr_lvl_aligned() with a NULL
147 * s2tt_context pointer.
148 ***************************************************************/
149
150 long level = s2tt_test_helpers_min_table_lvl();
151 unsigned long pa = 0UL; /* Aligned to any level */
152
153 test_helpers_expect_assert_fail(true);
154 (void)s2tte_is_addr_lvl_aligned((const struct s2tt_context *)NULL,
155 pa, level);
156 test_helpers_fail_if_no_assert_failed();
157}
158
159void s2tte_map_size_tc1(void)
160{
161 /***************************************************************
162 * TEST CASE 1:
163 *
164 * For each valid level, invoke s2tte_map_size() and validate
165 * its output.
166 ***************************************************************/
167
168 for (long level = s2tt_test_helpers_min_table_lvl();
169 level <= S2TT_TEST_HELPERS_MAX_LVL; level++) {
170 unsigned long expected_size =
171 s2tt_test_helpers_get_entry_va_space_size(level);
172
173 UNSIGNED_LONGS_EQUAL(expected_size, s2tte_map_size(level));
174 }
175}
176
177void s2tt_invalidate_page_tc1(void)
178{
179 /***************************************************************
180 * TEST CASE 1:
181 *
182 * Invoke s2tt_invalidate_page() with valid parameters.
183 * Note that this test can only validate the fake_host platform
184 * implementation.
185 **************************************************************/
186
Soby Mathewb1228bb2024-12-31 17:42:46 +0000187 struct s2tt_context s2tt_ctx;
188
189 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
190
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100191 unsigned long ipa = s2tt_test_helpers_gen_addr(S2TT_TEST_HELPERS_MAX_LVL, true);
192
193 s2tt_ctx.vmid = (unsigned int)test_helpers_get_rand_in_range(
194 0UL, (1UL << VTTBR_EL2_VMID_WIDTH) - 1UL);
195
196 s2tt_invalidate_page((const struct s2tt_context *)&s2tt_ctx, ipa);
197
198 TEST_EXIT;
199}
200
201void s2tt_invalidate_page_tc2(void)
202{
203 /***************************************************************
204 * TEST CASE 2:
205 *
206 * Invoke s2tt_invalidate_page() with a valid address and a NULL
207 * s2tt_context.
208 ***************************************************************/
209
210 test_helpers_expect_assert_fail(true);
211 s2tt_invalidate_page(NULL, 0UL);
212 test_helpers_fail_if_no_assert_failed();
213
214}
215
216void s2tt_invalidate_block_tc1(void)
217{
218 /***************************************************************
219 * TEST CASE 1:
220 *
221 * Invoke s2tt_invalidate_block() with valid parameters.
222 * Note that this test can only validate the fake_host platform
223 * implementation.
224 ***************************************************************/
225
Soby Mathewb1228bb2024-12-31 17:42:46 +0000226 struct s2tt_context s2tt_ctx;
227
228 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
229
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100230 unsigned long ipa;
231
232 for (unsigned int level = S2TT_MIN_BLOCK_LEVEL;
233 level < S2TT_PAGE_LEVEL; level++) {
234 ipa = s2tt_test_helpers_gen_addr(level, true);
235
236 s2tt_ctx.vmid = (unsigned int)test_helpers_get_rand_in_range(
237 2UL, (1UL << VTTBR_EL2_VMID_WIDTH) - 1UL);
238
239 s2tt_invalidate_block((const struct s2tt_context *)&s2tt_ctx, ipa);
240 }
241
242 TEST_EXIT;
243}
244
245void s2tt_invalidate_block_tc2(void)
246{
247 /***************************************************************
248 * TEST CASE 2:
249 *
250 * Invoke s2tt_invalidate_block() with a valid address and a NULL
251 * s2tt_context.
252 ***************************************************************/
253
254 test_helpers_expect_assert_fail(true);
255 s2tt_invalidate_block(NULL, 0UL);
256 test_helpers_fail_if_no_assert_failed();
257
258}
259
260void s2tt_invalidate_pages_in_block_tc1(void)
261{
262 /***************************************************************
263 * TEST CASE 1:
264 *
265 * Invoke s2tt_invalidate_pages_in_block() with valid parameters.
266 * Note that this test can only validate the fake_host platform
267 * implementation.
268 ***************************************************************/
269
Soby Mathewb1228bb2024-12-31 17:42:46 +0000270 struct s2tt_context s2tt_ctx;
271
272 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
273
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100274 unsigned long ipa = s2tt_test_helpers_gen_addr(S2TT_TEST_HELPERS_MAX_LVL, true);
275
276 s2tt_ctx.vmid = (unsigned int)test_helpers_get_rand_in_range(
277 2UL, (1UL << VTTBR_EL2_VMID_WIDTH) - 1UL);
278
279 s2tt_invalidate_pages_in_block((const struct s2tt_context *)&s2tt_ctx, ipa);
280
281 TEST_EXIT;
282}
283
284void s2tt_invalidate_pages_in_block_tc2(void)
285{
286 /***************************************************************
287 * TEST CASE 2:
288 *
289 * Invoke s2tt_invalidate_pages_in_block() with a valid address
290 * and a NULL s2tt_context.
291 ***************************************************************/
292
293 test_helpers_expect_assert_fail(true);
294 s2tt_invalidate_pages_in_block(NULL, 0UL);
295 test_helpers_fail_if_no_assert_failed();
296
297}
298
299void s2tt_is_unassigned_empty_block_tc1(void)
300{
301 /***************************************************************
302 * TEST CASE 1:
303 *
304 * Create an unassigned empty block and validate that
305 * s2tt_is_unassigned_empty_block() returns the expected
306 * value
307 ***************************************************************/
308
309 unsigned long s2tt[S2TTES_PER_S2TT];
310
311 s2tt_init_unassigned_empty((const struct s2tt_context *)NULL, &s2tt[0]);
312
313 CHECK_TRUE(s2tt_is_unassigned_empty_block(
314 (const struct s2tt_context *)NULL, &s2tt[0U]));
315}
316
317typedef void(*init_unassigned_cb)(const struct s2tt_context *s2tt_ctx,
318 unsigned long *s2tt);
319typedef bool(*s2tt_is_unassigned_x_block_cb)(const struct s2tt_context *s2tt_ctx,
320 unsigned long *s2tt);
321/* Use as array index for unassigned NS test case */
322#define S2TTE_INVALID_NS_INDEX (3U)
323
324/*
325 * Helper to implement a set of negative tests for
326 * s2tte_is_unassigned_{x}_block() APIS where x belongs to
327 * [RMI_EMPTY, RMI_RAM, RMI_DESTROYED, NS]:
328 *
329 * - Validate s2tt_is_unassigned_{x}_block() with a corresponding
330 * unassigned block in which a random TTE is of a different
331 * unassigned type.
332 * - Validate s2tt_is_unassigned_{x}_block() with an
333 * unassigned matching block in which a random TTE is of
334 * a different unassigned type.
335 */
336static void test_is_unassigned_x_block(unsigned int type)
337{
338 unsigned long ripas_arr[] = {S2TTE_INVALID_RIPAS_EMPTY,
339 S2TTE_INVALID_RIPAS_RAM,
340 S2TTE_INVALID_RIPAS_DESTROYED,
341 S2TTE_NS};
342 init_unassigned_cb init_unassigned_cbs[] = {
343 s2tt_init_unassigned_empty,
344 s2tt_init_unassigned_ram,
345 s2tt_init_unassigned_destroyed,
346 s2tt_init_unassigned_ns
347 };
348 s2tt_is_unassigned_x_block_cb s2tt_is_unassigned_x_block_cbs[] = {
349 s2tt_is_unassigned_empty_block,
350 s2tt_is_unassigned_ram_block,
351 s2tt_is_unassigned_destroyed_block,
352 s2tt_is_unassigned_ns_block,
353 };
354 long level = test_helpers_get_rand_in_range(
355 s2tt_test_helpers_min_block_lvl(),
356 S2TT_TEST_HELPERS_MAX_LVL);
357 unsigned long pa = s2tt_test_helpers_gen_addr(level, true);
358 unsigned long s2tt[S2TTES_PER_S2TT];
359 unsigned int tte_idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
360 S2TTES_PER_S2TT - 1UL);
Soby Mathewb1228bb2024-12-31 17:42:46 +0000361 struct s2tt_context s2tt_ctx;
362
363 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
364
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100365 unsigned int idx;
366
367 assert(type <= S2TTE_INVALID_NS_INDEX);
368
369 /*
370 * pick a random type of unassigned S2TTE to test with other than
371 * the type passed.
372 */
373 do {
374 idx = (unsigned int)test_helpers_get_rand_in_range(
375 0UL, ARRAY_SIZE(ripas_arr) - 1UL);
376 } while (idx == type);
377
378 /*
379 * Initialize an s2tt_context structure for the test.
380 * Only 'enable_lpa2' is used by the API, so the rest of fields
381 * can be left untouched.
382 */
383 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
384
385 /* Initialize a translation table with the required unassigned type */
386 init_unassigned_cbs[type](
387 (const struct s2tt_context *)&s2tt_ctx, &s2tt[0]);
388
389 /*
390 * Modify the random entry on the S2TT with a different
391 * unassigned S2TTE
392 */
393 s2tt[tte_idx] = s2tt_test_create_unassigned(
394 (const struct s2tt_context *)&s2tt_ctx,
395 ripas_arr[idx]);
396 CHECK_FALSE(s2tt_is_unassigned_x_block_cbs[type](
397 (const struct s2tt_context *)&s2tt_ctx,
398 &s2tt[0U]));
399
400 /* pickup a random type of assigned S2TTE to test with */
401 idx = (unsigned int)test_helpers_get_rand_in_range(
402 0UL, ARRAY_SIZE(ripas_arr) - 1UL);
403
404 /* Modify the random entry on the S2TT with an assigned S2TTE */
405 s2tt[tte_idx] = s2tt_test_create_assigned(
406 (const struct s2tt_context *)&s2tt_ctx,
407 pa, level, ripas_arr[idx]);
408 CHECK_FALSE(s2tt_is_unassigned_x_block_cbs[type](
409 (const struct s2tt_context *)&s2tt_ctx,
410 &s2tt[0U]));
411}
412
413void s2tt_is_unassigned_empty_block_tc2(void)
414{
415 /***************************************************************
416 * TEST CASE 2:
417 *
418 * Set of negative tests:
419 * - Validate s2tt_is_unassigned_empty_block() with an
420 * unassigned empty block in which a random TTE is of
421 * a different unassigned type.
422 * - Validate s2tt_is_unassigned_empty_block() with an
423 * unassigned empty block in which a random TTE is of
424 * a different assigned type.
425 ***************************************************************/
426
427 test_is_unassigned_x_block(RMI_EMPTY);
428}
429
430void s2tt_is_unassigned_empty_block_tc3(void)
431{
432 /***************************************************************
433 * TEST CASE 3:
434 *
435 * Invoke s2tt_is_unassigned_empty_block() with a NULL table.
436 ***************************************************************/
437
438 test_helpers_expect_assert_fail(true);
439 (void)s2tt_is_unassigned_empty_block(
440 (const struct s2tt_context *)NULL, NULL);
441 test_helpers_fail_if_no_assert_failed();
442}
443
444void s2tt_is_unassigned_ram_block_tc1(void)
445{
446 /***************************************************************
447 * TEST CASE 1:
448 *
449 * Create an unassigned ram block and validate that
450 * s2tt_is_unassigned_ram_block() returns the expected value
451 ***************************************************************/
452
453 unsigned long s2tt[S2TTES_PER_S2TT];
454
455 s2tt_init_unassigned_ram((const struct s2tt_context *)NULL, &s2tt[0]);
456
457 CHECK_TRUE(s2tt_is_unassigned_ram_block(
458 (const struct s2tt_context *)NULL, &s2tt[0U]));
459}
460
461void s2tt_is_unassigned_ram_block_tc2(void)
462{
463 /***************************************************************
464 * TEST CASE 2:
465 *
466 * Set of negative tests:
467 * - Validate s2tt_is_unassigned_ram_block() with an
468 * unassigned ram block in which a random TTE is of
469 * a different unassigned type.
470 * - Validate s2tt_is_unassigned_ram_block() with an
471 * unassigned ram block in which a random TTE is of
472 * a different assigned type.
473 ***************************************************************/
474
475 test_is_unassigned_x_block(RMI_RAM);
476}
477
478void s2tt_is_unassigned_ram_block_tc3(void)
479{
480 /***************************************************************
481 * TEST CASE 3:
482 *
483 * Invoke s2tt_is_unassigned_ram_block() with a NULL table.
484 ***************************************************************/
485
486 test_helpers_expect_assert_fail(true);
487 (void)s2tt_is_unassigned_ram_block(
488 (const struct s2tt_context *)NULL, NULL);
489 test_helpers_fail_if_no_assert_failed();
490}
491
492void s2tt_is_unassigned_ns_block_tc1(void)
493{
494 /***************************************************************
495 * TEST CASE 1:
496 *
497 * Create an unassigned ns block and validate that
498 * s2tt_is_unassigned_ns_block() returns the expected value
499 ***************************************************************/
500
501 unsigned long s2tt[S2TTES_PER_S2TT];
502
503 s2tt_init_unassigned_ns((const struct s2tt_context *)NULL, &s2tt[0]);
504
505 CHECK_TRUE(s2tt_is_unassigned_ns_block((const struct s2tt_context *)NULL,
506 &s2tt[0U]));
507}
508
509void s2tt_is_unassigned_ns_block_tc2(void)
510{
511 /***************************************************************
512 * TEST CASE 2:
513 *
514 * Set of negative tests:
515 * - Validate s2tt_is_unassigned_ns_block() with an
516 * unassigned ns block in which a random TTE is of
517 * a different unassigned type.
518 * - Validate s2tt_is_unassigned_ns_block() with an
519 * unassigned ns block in which a random TTE is of
520 * a different assigned type.
521 ***************************************************************/
522
523 test_is_unassigned_x_block(S2TTE_INVALID_NS_INDEX);
524}
525
526void s2tt_is_unassigned_ns_block_tc3(void)
527{
528 /***************************************************************
529 * TEST CASE 3:
530 *
531 * Invoke s2tt_is_unassigned_ns_block() with a NULL table.
532 ***************************************************************/
533
534 test_helpers_expect_assert_fail(true);
535 (void)s2tt_is_unassigned_ns_block((const struct s2tt_context *)NULL, NULL);
536 test_helpers_fail_if_no_assert_failed();
537}
538
539void s2tt_is_unassigned_destroyed_block_tc1(void)
540{
541 /***************************************************************
542 * TEST CASE 1:
543 *
544 * Create an unassigned destroyed block and validate that
545 * s2tt_is_unassigned_destroyed_block() returns the
546 * expected value
547 ***************************************************************/
548
549 unsigned long s2tt[S2TTES_PER_S2TT];
550
551 s2tt_init_unassigned_destroyed((const struct s2tt_context *)NULL, &s2tt[0]);
552
553 CHECK_TRUE(s2tt_is_unassigned_destroyed_block(
554 (const struct s2tt_context *)NULL, &s2tt[0U]));
555}
556
557void s2tt_is_unassigned_destroyed_block_tc2(void)
558{
559 /***************************************************************
560 * TEST CASE 2:
561 *
562 * Set of negative tests:
563 * - Validate s2tt_is_unassigned_destroyed_block() with
564 * an unassigned ns block in which a random TTE is of
565 * a different unassigned type.
566 * - Validate s2tt_is_unassigned_destroyed_block() with
567 * an unassigned ns block in which a random TTE is of
568 * a different assigned type.
569 ***************************************************************/
570
571 test_is_unassigned_x_block(RMI_DESTROYED);
572}
573
574void s2tt_is_unassigned_destroyed_block_tc3(void)
575{
576 /***************************************************************
577 * TEST CASE 3:
578 *
579 * Invoke s2tt_is_unassigned_destroyed_block() with a NULL table.
580 ***************************************************************/
581
582 test_helpers_expect_assert_fail(true);
583 (void)s2tt_is_unassigned_destroyed_block(
584 (const struct s2tt_context *)NULL, NULL);
585 test_helpers_fail_if_no_assert_failed();
586}
587
588void s2tt_maps_assigned_empty_block_tc1(void)
589{
590 /***************************************************************
591 * TEST CASE 1:
592 *
593 * For each valid level, create an assigned empty block and
594 * validate that s2tt_maps_assigned_empty_block() returns
595 * the expected value
596 ***************************************************************/
597
Soby Mathewb1228bb2024-12-31 17:42:46 +0000598 s2tt_context s2tt_ctx;
599
600 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100601
602 /*
603 * Generate an s2tt context to be used for the test.
604 * only s2tt_ctx.enable_lpa2 is of use on this API, so
605 * the rest of them can be uninitialized.
606 */
607 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
608
609 for (long level = s2tt_test_helpers_min_block_lvl();
610 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
611
612 unsigned long s2tt[S2TTES_PER_S2TT];
613 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
614
615 /* Generate the table */
616 s2tt_init_assigned_empty((const struct s2tt_context *)&s2tt_ctx,
617 &s2tt[0U], pa, level);
618
619 CHECK_TRUE(s2tt_maps_assigned_empty_block(
620 (const struct s2tt_context *)&s2tt_ctx,
621 &s2tt[0U], level));
622 }
623}
624
625void s2tt_maps_assigned_empty_block_tc2(void)
626{
627 /***************************************************************
628 * TEST CASE 2:
629 *
630 * For each valid level, create an assigned empty block and
631 * then change a random TTE to a different type to validate
632 * that s2tt_maps_assigned_empty_block() returns the expected
633 * value
634 ***************************************************************/
635
636 unsigned long unassigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
637 S2TTE_INVALID_RIPAS_RAM,
638 S2TTE_NS,
639 S2TTE_INVALID_RIPAS_DESTROYED};
640 unsigned long assigned_ripas[] = {S2TTE_INVALID_RIPAS_RAM,
641 S2TTE_NS,
642 S2TTE_INVALID_RIPAS_DESTROYED};
Soby Mathewb1228bb2024-12-31 17:42:46 +0000643 s2tt_context s2tt_ctx;
644
645 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100646
647 /*
648 * Generate an s2tt context to be used for the test.
649 * only s2tt_ctx.enable_lpa2 is of use on this API, so
650 * the rest of them can be uninitialized.
651 */
652 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
653
654 for (long level = s2tt_test_helpers_min_block_lvl();
655 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
656
657 unsigned int tte_idx =
658 (unsigned int)test_helpers_get_rand_in_range(0UL,
659 S2TTES_PER_S2TT - 1UL);
660 /* pickup a random type of unassigned S2TTE to test with */
661 unsigned int idx =
662 (unsigned int)test_helpers_get_rand_in_range(0UL,
663 ARRAY_SIZE(unassigned_ripas) - 1UL);
664 unsigned long s2tt[S2TTES_PER_S2TT];
665 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
666
667 /* Generate the table */
668 s2tt_init_assigned_empty((const struct s2tt_context *)&s2tt_ctx,
669 &s2tt[0U], pa, level);
670
671 /* Alter a random S2TTE on the table */
672 s2tt[tte_idx] = s2tt_test_create_unassigned(
673 (const struct s2tt_context *)&s2tt_ctx,
674 unassigned_ripas[idx]);
675 CHECK_FALSE(s2tt_maps_assigned_empty_block(
676 (const struct s2tt_context *)&s2tt_ctx,
677 &s2tt[0U], level));
678
679 /* pickup a random type of assigned S2TTE to test with */
680 idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
681 ARRAY_SIZE(assigned_ripas) - 1UL);
682
683 /* Alter a random S2TTE on the table */
684 s2tt[tte_idx] = s2tt_test_create_assigned(
685 (const struct s2tt_context *)&s2tt_ctx, pa, level,
686 assigned_ripas[idx]);
687 CHECK_FALSE(s2tt_maps_assigned_empty_block(
688 (const struct s2tt_context *)&s2tt_ctx,
689 &s2tt[0U], level));
690 }
691}
692
693void s2tt_maps_assigned_empty_block_tc3(void)
694{
695 /***************************************************************
696 * TEST CASE 3:
697 *
698 * Invoke s2tt_maps_assigned_empty_block() with the incorrect
699 * level.
700 ***************************************************************/
701
702 long level = s2tt_test_helpers_min_block_lvl();
703 unsigned long s2tt[S2TTES_PER_S2TT];
704 unsigned long pa;
Soby Mathewb1228bb2024-12-31 17:42:46 +0000705 s2tt_context s2tt_ctx;
706
707 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100708
709 /*
710 * Generate an s2tt context to be used for the test.
711 * only s2tt_ctx.enable_lpa2 is of use on this API, so
712 * the rest of them can be uninitialized.
713 */
714 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
715
716 /*
717 * Get a PA aligned @level - 1 so we can create a table
718 * @level starting at such PA.
719 */
720 pa = s2tt_test_helpers_gen_addr(level - 1L, true);
721
722 /* Generate a valid table */
723 s2tt_init_assigned_empty((const struct s2tt_context *)&s2tt_ctx,
724 &s2tt[0U], pa, level);
725
726 CHECK_FALSE(s2tt_maps_assigned_empty_block(
727 (const struct s2tt_context *)&s2tt_ctx,
728 &s2tt[0U], level + 1L));
729}
730
731void s2tt_maps_assigned_empty_block_tc4(void)
732{
733 /***************************************************************
734 * TEST CASE 4:
735 *
736 * Invoke s2tt_maps_assigned_empty_block() with a valid level
737 * and a NULL table pointer.
738 ***************************************************************/
739
740 long level = s2tt_test_helpers_min_block_lvl();
Soby Mathewb1228bb2024-12-31 17:42:46 +0000741 s2tt_context s2tt_ctx;
742
743 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100744
745 /*
746 * Generate an s2tt context to be used for the test.
747 * only s2tt_ctx.enable_lpa2 is of use on this API, so
748 * the rest of them can be uninitialized.
749 */
750 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
751
752
753 test_helpers_expect_assert_fail(true);
754 (void)s2tt_maps_assigned_empty_block(
755 (const struct s2tt_context *)&s2tt_ctx, NULL, level);
756 test_helpers_fail_if_no_assert_failed();
757}
758
759void s2tt_maps_assigned_empty_block_tc5(void)
760{
761 /***************************************************************
762 * TEST CASE 5:
763 *
764 * Invoke s2tt_maps_assigned_empty_block() with a level above
765 * the maximum allowed.
766 ***************************************************************/
767
768 long level = S2TT_TEST_HELPERS_MAX_LVL;
769 unsigned long s2tt[S2TTES_PER_S2TT];
770 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
Soby Mathewb1228bb2024-12-31 17:42:46 +0000771 s2tt_context s2tt_ctx;
772
773 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100774
775 /*
776 * Generate an s2tt context to be used for the test.
777 * only s2tt_ctx.enable_lpa2 is of use on this API, so
778 * the rest of them can be uninitialized.
779 */
780 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
781
782 /* Generate a valid table */
783 s2tt_init_assigned_empty((const struct s2tt_context *)&s2tt_ctx,
784 &s2tt[0U], pa, level);
785
786 test_helpers_expect_assert_fail(true);
787 (void)s2tt_maps_assigned_empty_block(
788 (const struct s2tt_context *)&s2tt_ctx,
789 &s2tt[0U], level + 1UL);
790 test_helpers_fail_if_no_assert_failed();
791}
792
793void s2tt_maps_assigned_empty_block_tc6(void)
794{
795 /***************************************************************
796 * TEST CASE 6:
797 *
798 * Invoke s2tt_maps_assigned_empty_block() with a level below
799 * the minimum allowed.
800 ***************************************************************/
801
802 long level = s2tt_test_helpers_min_block_lvl();
803 unsigned long s2tt[S2TTES_PER_S2TT];
804 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
Soby Mathewb1228bb2024-12-31 17:42:46 +0000805 s2tt_context s2tt_ctx;
806
807 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100808
809 /*
810 * Generate an s2tt context to be used for the test.
811 * only s2tt_ctx.enable_lpa2 is of use on this API, so
812 * the rest of them can be uninitialized.
813 */
814 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
815
816 /* Generate a valid table */
817 s2tt_init_assigned_empty((const struct s2tt_context *)&s2tt_ctx,
818 &s2tt[0U], pa, level);
819
820 level = s2tt_test_helpers_min_table_lvl() - 1L;
821 test_helpers_expect_assert_fail(true);
822 (void)s2tt_maps_assigned_empty_block(
823 (const struct s2tt_context *)&s2tt_ctx,
824 &s2tt[0U], level - 1UL);
825 test_helpers_fail_if_no_assert_failed();
826}
827
828void s2tt_maps_assigned_empty_block_tc7(void)
829{
830 /***************************************************************
831 * TEST CASE 7:
832 *
833 * Invoke s2tt_maps_assigned_empty_block() with a NULL pointer
834 * to a s2tt_context structure.
835 ***************************************************************/
836
837 long level = s2tt_test_helpers_min_block_lvl();
838 unsigned long s2tt[S2TTES_PER_S2TT];
839 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
Soby Mathewb1228bb2024-12-31 17:42:46 +0000840 s2tt_context s2tt_ctx;
841
842 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100843
844 /*
845 * Generate an s2tt context to be used for the test.
846 * only s2tt_ctx.enable_lpa2 is of use on this API, so
847 * the rest of them can be uninitialized.
848 */
849 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
850
851 /* Generate a valid table */
852 s2tt_init_assigned_empty((const struct s2tt_context *)&s2tt_ctx,
853 &s2tt[0U], pa, level);
854
855 test_helpers_expect_assert_fail(true);
856 (void)s2tt_maps_assigned_empty_block(
857 (const struct s2tt_context *)NULL,
858 &s2tt[0U], level);
859 test_helpers_fail_if_no_assert_failed();
860}
861
862void s2tt_maps_assigned_ram_block_tc1(void)
863{
864 /***************************************************************
865 * TEST CASE 1:
866 *
867 * For each valid level, create an assigned ram block and
868 * validate that s2tt_maps_assigned_ram_block() returns
869 * the expected value
870 ***************************************************************/
871
Soby Mathewb1228bb2024-12-31 17:42:46 +0000872 s2tt_context s2tt_ctx;
873
874 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100875
876 /*
877 * Generate an s2tt context to be used for the test.
878 * only s2tt_ctx.enable_lpa2 is of use on this API, so
879 * the rest of them can be uninitialized.
880 */
881 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
882
883 for (long level = s2tt_test_helpers_min_block_lvl();
884 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
885
886 unsigned long s2tt[S2TTES_PER_S2TT];
887 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
888
889 /* Generate the table */
890 s2tt_init_assigned_ram((const struct s2tt_context *)&s2tt_ctx,
891 &s2tt[0U], pa, level);
892
893 CHECK_TRUE(s2tt_maps_assigned_ram_block(
894 (const struct s2tt_context *)&s2tt_ctx,
895 &s2tt[0U], level));
896 }
897}
898
899void s2tt_maps_assigned_ram_block_tc2(void)
900{
901 /***************************************************************
902 * TEST CASE 2:
903 *
904 * For each valid level, create an assigned ram block and
905 * then change a random TTE to a different type to validate
906 * that s2tt_maps_assigned_ram_block() returns the expected
907 * value
908 ***************************************************************/
909
910 unsigned long unassigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
911 S2TTE_INVALID_RIPAS_RAM,
912 S2TTE_NS,
913 S2TTE_INVALID_RIPAS_DESTROYED};
914 unsigned long assigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
915 S2TTE_NS,
916 S2TTE_INVALID_RIPAS_DESTROYED};
Soby Mathewb1228bb2024-12-31 17:42:46 +0000917 s2tt_context s2tt_ctx;
918
919 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100920
921 /*
922 * Generate an s2tt context to be used for the test.
923 * only s2tt_ctx.enable_lpa2 is of use on this API, so
924 * the rest of them can be uninitialized.
925 */
926 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
927
928 for (long level = s2tt_test_helpers_min_block_lvl();
929 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
930
931 unsigned int tte_idx =
932 (unsigned int)test_helpers_get_rand_in_range(0UL,
933 S2TTES_PER_S2TT - 1UL);
934 /* pickup a random type of unassigned S2TTE to test with */
935 unsigned int idx =
936 (unsigned int)test_helpers_get_rand_in_range(0UL,
937 ARRAY_SIZE(unassigned_ripas) - 1UL);
938 unsigned long s2tt[S2TTES_PER_S2TT];
939 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
940
941 /* Generate the table */
942 s2tt_init_assigned_ram((const struct s2tt_context *)&s2tt_ctx,
943 &s2tt[0U], pa, level);
944
945 /* Alter a random S2TTE on the table */
946 s2tt[tte_idx] = s2tt_test_create_unassigned(
947 (const struct s2tt_context *)&s2tt_ctx,
948 unassigned_ripas[idx]);
949 CHECK_FALSE(s2tt_maps_assigned_ram_block(
950 (const struct s2tt_context *)&s2tt_ctx,
951 &s2tt[0U], level));
952
953 /* pickup a random type of assigned S2TTE to test with */
954 idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
955 ARRAY_SIZE(assigned_ripas) - 1UL);
956
957 /* Alter a random S2TTE on the table */
958 s2tt[tte_idx] = s2tt_test_create_assigned(
959 (const struct s2tt_context *)&s2tt_ctx,
960 pa, level, assigned_ripas[idx]);
961 CHECK_FALSE(s2tt_maps_assigned_ram_block(
962 (const struct s2tt_context *)&s2tt_ctx,
963 &s2tt[0U], level));
964 }
965}
966
967void s2tt_maps_assigned_ram_block_tc3(void)
968{
969 /***************************************************************
970 * TEST CASE 3:
971 *
972 * Invoke s2tt_maps_assigned_ram_block() with the incorrect
973 * level.
974 ***************************************************************/
975
976 long level = s2tt_test_helpers_min_block_lvl();
977 unsigned long s2tt[S2TTES_PER_S2TT];
978 unsigned long pa;
Soby Mathewb1228bb2024-12-31 17:42:46 +0000979 s2tt_context s2tt_ctx;
980
981 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +0100982
983 /*
984 * Generate an s2tt context to be used for the test.
985 * only s2tt_ctx.enable_lpa2 is of use on this API, so
986 * the rest of them can be uninitialized.
987 */
988 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
989
990 /*
991 * Get a PA aligned @level - 1 so we can create a table
992 * @level starting at such PA.
993 */
994 pa = s2tt_test_helpers_gen_addr(level - 1L, true);
995
996 /* Generate a valid table */
997 s2tt_init_assigned_ram((const struct s2tt_context *)&s2tt_ctx,
998 &s2tt[0U], pa, level);
999
1000 CHECK_FALSE(s2tt_maps_assigned_ram_block(
1001 (const struct s2tt_context *)&s2tt_ctx,
1002 &s2tt[0U], level + 1L));
1003}
1004
1005void s2tt_maps_assigned_ram_block_tc4(void)
1006{
1007 /***************************************************************
1008 * TEST CASE 4:
1009 *
1010 * Invoke s2tt_maps_assigned_ram_block() with a valid level
1011 * and a NULL table pointer.
1012 ***************************************************************/
1013
1014 long level = s2tt_test_helpers_min_block_lvl();
Soby Mathewb1228bb2024-12-31 17:42:46 +00001015 s2tt_context s2tt_ctx;
1016
1017 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001018
1019 /*
1020 * Generate an s2tt context to be used for the test.
1021 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1022 * the rest of them can be uninitialized.
1023 */
1024 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1025
1026 test_helpers_expect_assert_fail(true);
1027 (void)s2tt_maps_assigned_ram_block(
1028 (const struct s2tt_context *)&s2tt_ctx, NULL, level);
1029 test_helpers_fail_if_no_assert_failed();
1030}
1031
1032void s2tt_maps_assigned_ram_block_tc5(void)
1033{
1034 /***************************************************************
1035 * TEST CASE 5:
1036 *
1037 * Invoke s2tt_maps_assigned_ram_block() with a level above
1038 * the maximum allowed.
1039 ***************************************************************/
1040
1041 long level = S2TT_TEST_HELPERS_MAX_LVL;
1042 unsigned long s2tt[S2TTES_PER_S2TT];
1043 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
Soby Mathewb1228bb2024-12-31 17:42:46 +00001044 s2tt_context s2tt_ctx;
1045
1046 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001047
1048 /*
1049 * Generate an s2tt context to be used for the test.
1050 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1051 * the rest of them can be uninitialized.
1052 */
1053 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1054
1055 /* Generate a valid table */
1056 s2tt_init_assigned_ram((const struct s2tt_context *)&s2tt_ctx,
1057 &s2tt[0U], pa, level);
1058
1059 test_helpers_expect_assert_fail(true);
1060 (void)s2tt_maps_assigned_ram_block(
1061 (const struct s2tt_context *)&s2tt_ctx,
1062 &s2tt[0U], level + 1UL);
1063 test_helpers_fail_if_no_assert_failed();
1064}
1065
1066void s2tt_maps_assigned_ram_block_tc6(void)
1067{
1068 /***************************************************************
1069 * TEST CASE 6:
1070 *
1071 * Invoke s2tt_maps_assigned_ram_block() with a level below
1072 * the minimum allowed.
1073 ***************************************************************/
1074
1075 long level = s2tt_test_helpers_min_block_lvl();
1076 unsigned long s2tt[S2TTES_PER_S2TT];
1077 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
Soby Mathewb1228bb2024-12-31 17:42:46 +00001078 s2tt_context s2tt_ctx;
1079
1080 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001081
1082 /*
1083 * Generate an s2tt context to be used for the test.
1084 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1085 * the rest of them can be uninitialized.
1086 */
1087 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1088
1089 /* Generate a valid table */
1090 s2tt_init_assigned_ram((const struct s2tt_context *)&s2tt_ctx,
1091 &s2tt[0U], pa, level);
1092
1093 level = s2tt_test_helpers_min_table_lvl() - 1L;
1094 test_helpers_expect_assert_fail(true);
1095 (void)s2tt_maps_assigned_ram_block((const struct s2tt_context *)&s2tt_ctx,
1096 &s2tt[0U], level);
1097 test_helpers_fail_if_no_assert_failed();
1098}
1099
1100void s2tt_maps_assigned_ram_block_tc7(void)
1101{
1102 /***************************************************************
1103 * TEST CASE 7:
1104 *
1105 * Invoke s2tt_maps_assigned_ram_block() with a NULL pointer to
1106 * s2tt_context structure.
1107 ***************************************************************/
1108
1109 long level = s2tt_test_helpers_min_block_lvl();
1110 unsigned long s2tt[S2TTES_PER_S2TT];
1111 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
Soby Mathewb1228bb2024-12-31 17:42:46 +00001112 s2tt_context s2tt_ctx;
1113
1114 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001115
1116 /*
1117 * Generate an s2tt context to be used for the test.
1118 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1119 * the rest of them can be uninitialized.
1120 */
1121 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1122
1123 /* Generate a valid table */
1124 s2tt_init_assigned_ram((const struct s2tt_context *)&s2tt_ctx,
1125 &s2tt[0U], pa, level);
1126
1127 test_helpers_expect_assert_fail(true);
1128 (void)s2tt_maps_assigned_ram_block((const struct s2tt_context *)NULL,
1129 &s2tt[0U], level);
1130 test_helpers_fail_if_no_assert_failed();
1131}
1132
1133void s2tt_maps_assigned_ns_block_tc1(void)
1134{
1135 /***************************************************************
1136 * TEST CASE 1:
1137 *
1138 * For each valid level, create an assigned ns block and
1139 * validate that s2tt_maps_assigned_ns_block() returns
1140 * the expected value
1141 ***************************************************************/
1142
Soby Mathewb1228bb2024-12-31 17:42:46 +00001143 s2tt_context s2tt_ctx;
1144
1145 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001146
1147 /*
1148 * Generate an s2tt context to be used for the test.
1149 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1150 * the rest of them can be uninitialized.
1151 */
1152 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1153
1154 for (long level = s2tt_test_helpers_min_block_lvl();
1155 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
1156
1157 unsigned long s2tt[S2TTES_PER_S2TT];
1158 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1159 unsigned long attrs =
1160 s2tt_test_helpers_gen_ns_attrs(true, false);
1161
1162 /* Generate the table */
1163 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1164 &s2tt[0U], attrs, pa, level);
1165
1166 CHECK_TRUE(s2tt_maps_assigned_ns_block(
1167 (const struct s2tt_context *)&s2tt_ctx,
1168 &s2tt[0U], level));
1169 }
1170}
1171
1172void s2tt_maps_assigned_ns_block_tc2(void)
1173{
1174 /***************************************************************
1175 * TEST CASE 2:
1176 *
1177 * For each valid level, create an assigned ns block and
1178 * alter the NS attributes of a random TTE with a random value.
1179 * Then verify that s2tt_maps_assigned_ns_block() returns
1180 * the expected value.
1181 ***************************************************************/
1182
Soby Mathewb1228bb2024-12-31 17:42:46 +00001183 s2tt_context s2tt_ctx;
1184
1185 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001186
1187 /*
1188 * Generate an s2tt context to be used for the test.
1189 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1190 * the rest of them can be uninitialized.
1191 */
1192 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1193
1194 for (long level = s2tt_test_helpers_min_block_lvl();
1195 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
1196
1197 unsigned long s2tt[S2TTES_PER_S2TT];
1198 unsigned int index = test_helpers_get_rand_in_range(0UL,
1199 S2TTES_PER_S2TT - 1UL);
1200 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1201 unsigned long new_attrs, attrs =
1202 s2tt_test_helpers_gen_ns_attrs(true, false);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001203
1204 /* Generate the table */
1205 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1206 &s2tt[0U], attrs, pa, level);
1207
1208 /* Generate the offending set of NS attrs */
1209 do {
Soby Mathew217748d2024-10-02 11:02:19 +01001210 new_attrs = test_helpers_get_rand_in_range(0UL, ULONG_MAX)
1211 & S2TTE_NS_ATTR_MASK;
1212 } while (new_attrs == (s2tt[0U] & S2TTE_NS_ATTR_MASK));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001213
1214 /* Alter the NS attributes on a random TTE */
Soby Mathew217748d2024-10-02 11:02:19 +01001215 s2tt[index] &= ~S2TTE_NS_ATTR_MASK;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001216 s2tt[index] |= new_attrs;
1217
1218 CHECK_FALSE(s2tt_maps_assigned_ns_block(
1219 (const struct s2tt_context *)&s2tt_ctx,
1220 &s2tt[0U], level));
1221 }
1222}
1223
1224void s2tt_maps_assigned_ns_block_tc3(void)
1225{
1226 /***************************************************************
1227 * TEST CASE 3:
1228 *
1229 * For each valid level, create an assigned ns block and
1230 * then change a random TTE to a different type to validate
1231 * that s2tt_maps_assigned_ns_block() returns the expected
1232 * value
1233 ***************************************************************/
1234
1235 unsigned long unassigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
1236 S2TTE_INVALID_RIPAS_RAM,
1237 S2TTE_NS,
1238 S2TTE_INVALID_RIPAS_DESTROYED};
1239 unsigned long assigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
1240 S2TTE_INVALID_RIPAS_RAM,
1241 S2TTE_INVALID_RIPAS_DESTROYED};
1242
1243 unsigned long attrs = s2tt_test_helpers_gen_ns_attrs(true, false);
Soby Mathewb1228bb2024-12-31 17:42:46 +00001244 s2tt_context s2tt_ctx;
1245
1246 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001247
1248 /*
1249 * Generate an s2tt context to be used for the test.
1250 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1251 * the rest of them can be uninitialized.
1252 */
1253 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1254
1255 for (long level = s2tt_test_helpers_min_block_lvl();
1256 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
1257
1258 unsigned int tte_idx =
1259 (unsigned int)test_helpers_get_rand_in_range(0UL,
1260 S2TTES_PER_S2TT - 1UL);
1261 /* pickup a random type of unassigned S2TTE to test with */
1262 unsigned int idx =
1263 (unsigned int)test_helpers_get_rand_in_range(0UL,
1264 ARRAY_SIZE(unassigned_ripas) - 1UL);
1265 unsigned long s2tt[S2TTES_PER_S2TT];
1266 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1267
1268 /* Generate the table */
1269 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1270 &s2tt[0U], attrs, pa, level);
1271
1272 /* Alter a random S2TTE on the table */
1273 s2tt[tte_idx] = s2tt_test_create_unassigned(
1274 (const struct s2tt_context *)&s2tt_ctx,
1275 unassigned_ripas[idx]);
1276 CHECK_FALSE(s2tt_maps_assigned_ns_block(
1277 (const struct s2tt_context *)&s2tt_ctx,
1278 &s2tt[0U], level));
1279
1280 /* pickup a random type of assigned S2TTE to test with */
1281 idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
1282 ARRAY_SIZE(assigned_ripas) - 1UL);
1283
1284 /* Alter a random S2TTE on the table */
1285 s2tt[tte_idx] = s2tt_test_create_assigned(
1286 (const struct s2tt_context *)&s2tt_ctx,
1287 pa, level, assigned_ripas[idx]);
1288 CHECK_FALSE(s2tt_maps_assigned_ns_block(
1289 (const struct s2tt_context *)&s2tt_ctx,
1290 &s2tt[0U], level));
1291 }
1292}
1293
1294void s2tt_maps_assigned_ns_block_tc4(void)
1295{
1296 /***************************************************************
1297 * TEST CASE 4:
1298 *
1299 * Invoke s2tt_maps_assigned_ns_block() with the incorrect
1300 * level.
1301 ***************************************************************/
1302
1303 long level = s2tt_test_helpers_min_block_lvl();
1304 unsigned long s2tt[S2TTES_PER_S2TT];
1305 unsigned long attrs = s2tt_test_helpers_gen_ns_attrs(true, false);
1306 unsigned long pa;
Soby Mathewb1228bb2024-12-31 17:42:46 +00001307 s2tt_context s2tt_ctx;
1308
1309 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001310
1311 /*
1312 * Generate an s2tt context to be used for the test.
1313 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1314 * the rest of them can be uninitialized.
1315 */
1316 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1317
1318 /* Get a PA aligned only to 'level' */
1319 do {
1320 pa = s2tt_test_helpers_gen_addr(level, true);
1321
1322 } while (s2tte_is_addr_lvl_aligned((const struct s2tt_context *)&s2tt_ctx,
1323 pa, level - 1L));
1324
1325 /* Generate a valid table */
1326 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1327 &s2tt[0U], attrs, pa, level);
1328
1329 CHECK_FALSE(s2tt_maps_assigned_ns_block(
1330 (const struct s2tt_context *)&s2tt_ctx,
1331 &s2tt[0U], level));
1332}
1333
1334void s2tt_maps_assigned_ns_block_tc5(void)
1335{
1336 /***************************************************************
1337 * TEST CASE 5:
1338 *
1339 * Invoke s2tt_maps_assigned_ns_block() with a valid level
1340 * and a NULL table pointer.
1341 ***************************************************************/
1342
1343 long level = s2tt_test_helpers_min_block_lvl();
Soby Mathewb1228bb2024-12-31 17:42:46 +00001344 s2tt_context s2tt_ctx;
1345
1346 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001347
1348 /*
1349 * Generate an s2tt context to be used for the test.
1350 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1351 * the rest of them can be uninitialized.
1352 */
1353 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1354
1355 test_helpers_expect_assert_fail(true);
1356 (void)s2tt_maps_assigned_ns_block(
1357 (const struct s2tt_context *)&s2tt_ctx, NULL, level);
1358 test_helpers_fail_if_no_assert_failed();
1359}
1360
1361void s2tt_maps_assigned_ns_block_tc6(void)
1362{
1363 /***************************************************************
1364 * TEST CASE 6:
1365 *
1366 * Invoke s2tt_maps_assigned_ns_block() with a level above
1367 * the maximum allowed.
1368 ***************************************************************/
1369
1370 long level = S2TT_TEST_HELPERS_MAX_LVL;
1371 unsigned long s2tt[S2TTES_PER_S2TT];
1372 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1373 unsigned long attrs = s2tt_test_helpers_gen_ns_attrs(true, false);
Soby Mathewb1228bb2024-12-31 17:42:46 +00001374 s2tt_context s2tt_ctx;
1375
1376 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001377
1378 /*
1379 * Generate an s2tt context to be used for the test.
1380 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1381 * the rest of them can be uninitialized.
1382 */
1383 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1384
1385 /* Generate a valid table */
1386 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1387 &s2tt[0U], attrs, pa, level);
1388
1389 test_helpers_expect_assert_fail(true);
1390 (void)s2tt_maps_assigned_ram_block((const struct s2tt_context *)&s2tt_ctx,
1391 &s2tt[0U], level + 1UL);
1392 test_helpers_fail_if_no_assert_failed();
1393}
1394
1395void s2tt_maps_assigned_ns_block_tc7(void)
1396{
1397 /***************************************************************
1398 * TEST CASE 7:
1399 *
1400 * Invoke s2tt_maps_assigned_ram_block() with a level below
1401 * the minimum allowed.
1402 ***************************************************************/
1403
1404 long level = s2tt_test_helpers_min_block_lvl();
1405 unsigned long s2tt[S2TTES_PER_S2TT];
1406 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1407 unsigned long attrs = s2tt_test_helpers_gen_ns_attrs(true, false);
Soby Mathewb1228bb2024-12-31 17:42:46 +00001408 s2tt_context s2tt_ctx;
1409
1410 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001411
1412 /*
1413 * Generate an s2tt context to be used for the test.
1414 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1415 * the rest of them can be uninitialized.
1416 */
1417 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1418
1419 /* Generate a valid table */
1420 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1421 &s2tt[0U], attrs, pa, level);
1422
1423 level = s2tt_test_helpers_min_table_lvl() - 1L;
1424 test_helpers_expect_assert_fail(true);
1425 (void)s2tt_maps_assigned_ns_block((const struct s2tt_context *)&s2tt_ctx,
1426 &s2tt[0U], level);
1427 test_helpers_fail_if_no_assert_failed();
1428}
1429
1430void s2tt_maps_assigned_ns_block_tc8(void)
1431{
1432 /***************************************************************
1433 * TEST CASE 8:
1434 *
1435 * Invoke s2tt_maps_assigned_ram_block() with a NULL pointer to
1436 * s2tt_context structure.
1437 ***************************************************************/
1438
1439 long level = s2tt_test_helpers_min_block_lvl();
1440 unsigned long s2tt[S2TTES_PER_S2TT];
1441 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1442 unsigned long attrs = s2tt_test_helpers_gen_ns_attrs(true, false);
Soby Mathewb1228bb2024-12-31 17:42:46 +00001443 s2tt_context s2tt_ctx;
1444
1445 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001446
1447 /*
1448 * Generate an s2tt context to be used for the test.
1449 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1450 * the rest of them can be uninitialized.
1451 */
1452 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1453
1454 /* Generate a valid table */
1455 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1456 &s2tt[0U], attrs, pa, level);
1457
1458 test_helpers_expect_assert_fail(true);
1459 (void)s2tt_maps_assigned_ns_block((const struct s2tt_context *)NULL,
1460 &s2tt[0U], level);
1461 test_helpers_fail_if_no_assert_failed();
1462}
1463
1464void s2tt_maps_assigned_destroyed_block_tc1(void)
1465{
1466 /***************************************************************
1467 * TEST CASE 1:
1468 *
1469 * For each valid level, create an assigned destroyed block and
1470 * validate that s2tt_maps_assigned_destroyed_block() returns
1471 * the expected value
1472 ***************************************************************/
1473
Soby Mathewb1228bb2024-12-31 17:42:46 +00001474 s2tt_context s2tt_ctx;
1475
1476 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001477
1478 /*
1479 * Generate an s2tt context to be used for the test.
1480 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1481 * the rest of them can be uninitialized.
1482 */
1483 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1484
1485 for (long level = s2tt_test_helpers_min_block_lvl();
1486 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
1487
1488 unsigned long s2tt[S2TTES_PER_S2TT];
1489 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1490
1491 /* Generate the table */
1492 s2tt_init_assigned_destroyed(
1493 (const struct s2tt_context *)&s2tt_ctx,
1494 &s2tt[0U], pa, level);
1495
1496 CHECK_TRUE(s2tt_maps_assigned_destroyed_block(
1497 (const struct s2tt_context *)&s2tt_ctx,
1498 &s2tt[0U], level));
1499 }
1500}
1501
1502void s2tt_maps_assigned_destroyed_block_tc2(void)
1503{
1504 /***************************************************************
1505 * TEST CASE 2:
1506 *
1507 * For each valid level, create an assigned destroyed block and
1508 * then change a random TTE to a different type to validate
1509 * that s2tt_maps_assigned_destroyed_block() returns the
1510 * expected value
1511 ***************************************************************/
1512
1513 unsigned long unassigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
1514 S2TTE_INVALID_RIPAS_RAM,
1515 S2TTE_NS,
1516 S2TTE_INVALID_RIPAS_DESTROYED};
1517 unsigned long assigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
1518 S2TTE_NS,
1519 S2TTE_INVALID_RIPAS_RAM};
Soby Mathewb1228bb2024-12-31 17:42:46 +00001520 s2tt_context s2tt_ctx;
1521
1522 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001523
1524 /*
1525 * Generate an s2tt context to be used for the test.
1526 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1527 * the rest of them can be uninitialized.
1528 */
1529 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1530
1531 for (long level = s2tt_test_helpers_min_block_lvl();
1532 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
1533
1534 unsigned int tte_idx =
1535 (unsigned int)test_helpers_get_rand_in_range(0UL,
1536 S2TTES_PER_S2TT - 1UL);
1537 /* pickup a random type of unassigned S2TTE to test with */
1538 unsigned int idx =
1539 (unsigned int)test_helpers_get_rand_in_range(0UL,
1540 ARRAY_SIZE(unassigned_ripas) - 1UL);
1541 unsigned long s2tt[S2TTES_PER_S2TT];
1542 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1543
1544 /* Generate the table */
1545 s2tt_init_assigned_destroyed(
1546 (const struct s2tt_context *)&s2tt_ctx,
1547 &s2tt[0U], pa, level);
1548
1549 /* Alter a random S2TTE on the table */
1550 s2tt[tte_idx] = s2tt_test_create_unassigned(
1551 (const struct s2tt_context *)&s2tt_ctx,
1552 unassigned_ripas[idx]);
1553 CHECK_FALSE(s2tt_maps_assigned_destroyed_block(
1554 (const struct s2tt_context *)&s2tt_ctx,
1555 &s2tt[0U], level));
1556
1557 /* pickup a random type of assigned S2TTE to test with */
1558 idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
1559 ARRAY_SIZE(assigned_ripas) - 1UL);
1560
1561 /* Alter a random S2TTE on the table */
1562 s2tt[tte_idx] = s2tt_test_create_assigned(
1563 (const struct s2tt_context *)&s2tt_ctx,
1564 pa, level, assigned_ripas[idx]);
1565 CHECK_FALSE(s2tt_maps_assigned_destroyed_block(
1566 (const struct s2tt_context *)&s2tt_ctx,
1567 &s2tt[0U], level));
1568 }
1569}
1570
1571void s2tt_maps_assigned_destroyed_block_tc3(void)
1572{
1573 /***************************************************************
1574 * TEST CASE 3:
1575 *
1576 * Invoke s2tt_maps_assigned_destroyed_block() with the
1577 * incorrect level.
1578 ***************************************************************/
1579
1580 long level = s2tt_test_helpers_min_block_lvl();
1581 unsigned long s2tt[S2TTES_PER_S2TT];
1582 unsigned long pa;
Soby Mathewb1228bb2024-12-31 17:42:46 +00001583 s2tt_context s2tt_ctx;
1584
1585 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001586
1587 /*
1588 * Generate an s2tt context to be used for the test.
1589 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1590 * the rest of them can be uninitialized.
1591 */
1592 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1593
1594 /*
1595 * Get a PA aligned only to 'level' - 1 so we can spawn a table
1596 * at level 'level' starting on that PA.
1597 */
1598 pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1599
1600 /* Generate a valid table */
1601 s2tt_init_assigned_destroyed((const struct s2tt_context *)&s2tt_ctx,
1602 &s2tt[0U], pa, level);
1603
1604 CHECK_FALSE(s2tt_maps_assigned_destroyed_block(
1605 (const struct s2tt_context *)&s2tt_ctx,
1606 &s2tt[0U], level + 1L));
1607}
1608
1609void s2tt_maps_assigned_destroyed_block_tc4(void)
1610{
1611 /***************************************************************
1612 * TEST CASE 4:
1613 *
1614 * Invoke s2tt_maps_assigned_destroyed_block() with a valid
1615 * level and a NULL table pointer.
1616 ***************************************************************/
1617
1618 long level = s2tt_test_helpers_min_block_lvl();
Soby Mathewb1228bb2024-12-31 17:42:46 +00001619 s2tt_context s2tt_ctx;
1620
1621 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001622
1623 /*
1624 * Generate an s2tt context to be used for the test.
1625 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1626 * the rest of them can be uninitialized.
1627 */
1628 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1629
1630 test_helpers_expect_assert_fail(true);
1631 (void)s2tt_maps_assigned_destroyed_block((
1632 const struct s2tt_context *)&s2tt_ctx,
1633 NULL, level);
1634 test_helpers_fail_if_no_assert_failed();
1635}
1636
1637void s2tt_maps_assigned_destroyed_block_tc5(void)
1638{
1639 /***************************************************************
1640 * TEST CASE 5:
1641 *
1642 * Invoke s2tt_maps_assigned_destroyed_block() with a level
1643 * above the maximum allowed.
1644 ***************************************************************/
1645
1646 long level = S2TT_TEST_HELPERS_MAX_LVL;
1647 unsigned long s2tt[S2TTES_PER_S2TT];
1648 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
Soby Mathewb1228bb2024-12-31 17:42:46 +00001649 s2tt_context s2tt_ctx;
1650
1651 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001652
1653 /*
1654 * Generate an s2tt context to be used for the test.
1655 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1656 * the rest of them can be uninitialized.
1657 */
1658 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1659
1660 /* Generate a valid table */
1661 s2tt_init_assigned_destroyed((const struct s2tt_context *)&s2tt_ctx,
1662 &s2tt[0U], pa, level);
1663
1664 test_helpers_expect_assert_fail(true);
1665 (void)s2tt_maps_assigned_destroyed_block(
1666 (const struct s2tt_context *)&s2tt_ctx,
1667 &s2tt[0U], level + 1L);
1668 test_helpers_fail_if_no_assert_failed();
1669}
1670
1671void s2tt_maps_assigned_destroyed_block_tc6(void)
1672{
1673 /***************************************************************
1674 * TEST CASE 6:
1675 *
1676 * Invoke s2tt_maps_assigned_destroyed_block() with a level
1677 * below the minimum allowed.
1678 ***************************************************************/
1679
1680 long level = s2tt_test_helpers_min_block_lvl();
1681 unsigned long s2tt[S2TTES_PER_S2TT];
1682 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
Soby Mathewb1228bb2024-12-31 17:42:46 +00001683 s2tt_context s2tt_ctx;
1684
1685 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001686
1687 /*
1688 * Generate an s2tt context to be used for the test.
1689 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1690 * the rest of them can be uninitialized.
1691 */
1692 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1693
1694 /* Generate a valid table */
1695 s2tt_init_assigned_destroyed((const struct s2tt_context *)&s2tt_ctx,
1696 &s2tt[0U], pa, level);
1697
1698 test_helpers_expect_assert_fail(true);
1699 level = s2tt_test_helpers_min_table_lvl() - 1L;
1700 (void)s2tt_maps_assigned_destroyed_block(
1701 (const struct s2tt_context *)&s2tt_ctx,
1702 &s2tt[0U], level);
1703 test_helpers_fail_if_no_assert_failed();
1704}
1705
1706void s2tt_maps_assigned_destroyed_block_tc7(void)
1707{
1708 /***************************************************************
1709 * TEST CASE 7:
1710 *
1711 * Invoke s2tt_maps_assigned_destroyed_block() with a NULL
1712 * pointer to a s2tt_context structure.
1713 ***************************************************************/
1714
1715 long level = s2tt_test_helpers_min_block_lvl();
1716 unsigned long s2tt[S2TTES_PER_S2TT];
1717 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
Soby Mathewb1228bb2024-12-31 17:42:46 +00001718 s2tt_context s2tt_ctx;
1719
1720 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001721
1722 /*
1723 * Generate an s2tt context to be used for the test.
1724 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1725 * the rest of them can be uninitialized.
1726 */
1727 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1728
1729 /* Generate a valid table */
1730 s2tt_init_assigned_destroyed((const struct s2tt_context *)&s2tt_ctx,
1731 &s2tt[0U], pa, level);
1732
1733 test_helpers_expect_assert_fail(true);
1734 (void)s2tt_maps_assigned_destroyed_block(
1735 (const struct s2tt_context *)NULL,
1736 &s2tt[0U], level);
1737 test_helpers_fail_if_no_assert_failed();
1738}
1739
1740/*
1741 * Ancillary function to generate a test input to test
1742 * s2tt_skip_non_live_entries(). The only input required to this function
1743 * is @wi.index. The rest are output values.
1744 *
1745 * - Arguments:
1746 * iter: Iteration number.
1747 * 0: generate a live S2TTE at index > wi.index,
1748 * 1: generate a live S2TTE at index at wi.index,
1749 * 2: generate a live S2TTE at index < wi.index.
1750 * wi: The s2tt_walk structure to pass to
1751 * s2tt_skip_non_live_entries(). Other than wi.level, all
1752 * other fieds are setup by this helper.
1753 * tte_idx: tte index where the live entry is generated.
1754 * entry_ipa: the aligned IPA corresponding to the entry
1755 * at `table_ipa[tte_idx]`
1756 * ipa: An unaligned IPA belonging to the block/page
1757 * pointed by the entry at `table_ipa[wi.index]`.
1758 *
1759 * - Returns: The expected ipa that should be returned by
1760 * s2tt_skip_non_live_entries() as per the test input.
1761 */
1762static unsigned long skip_non_live_entries_gen_ipas(unsigned int iter,
1763 struct s2tt_walk *wi,
1764 unsigned int *tte_idx,
1765 unsigned long *entry_ipa,
1766 unsigned long *ipa)
1767{
1768 long level = wi->last_level;
1769 unsigned long table_ipa, next_stt_ipa;
1770
1771 /*
1772 * Initialize wi.index somewhere in the middle of the table.
1773 * Note that level -1 has only 16 entries.
1774 */
1775 if (level == S2TT_TEST_HELPERS_MIN_LVL_LPA2) {
1776 wi->index = test_helpers_get_rand_in_range(5UL, 10UL);
1777 } else {
1778 wi->index = test_helpers_get_rand_in_range(100UL, 200UL);
1779 }
1780
1781 switch (iter) {
1782 case 0U:
1783 /* Get a random index > wi.index */
1784 *tte_idx =
1785 (unsigned int)test_helpers_get_rand_in_range(
1786 wi->index + 1UL, S2TTES_PER_S2TT - 1UL);
1787 break;
1788 case 1U:
1789 /* Test index will be wi.index */
1790 *tte_idx = wi->index;
1791 break;
1792 case 2U:
1793 /* Get a random index < wi.index */
1794 *tte_idx = (unsigned int)test_helpers_get_rand_in_range(
1795 0UL, wi->index - 1UL);
1796 break;
1797 default:
1798 /* Not allowed */
1799 assert(false);
1800 }
1801
1802 /*
1803 * Get an IPA aligned @level - 1, so we would have a table
1804 * @level starting at such IPA.
1805 */
1806 table_ipa = s2tt_test_helpers_gen_addr(level - 1L, true);
1807
1808 /*
1809 * Calculate the IPA of the entry on the table
1810 * indexed by tte_idx.
1811 */
1812 *entry_ipa = table_ipa + (s2tte_map_size(level) * (*tte_idx));
1813
1814 /* Calculate the IPA for the next table */
1815 next_stt_ipa = table_ipa + (s2tte_map_size(level) * S2TTES_PER_S2TT);
1816
1817 /* Calculate a non-aligned valid IPA at wi.index used to test */
1818
1819 *ipa = table_ipa + (s2tte_map_size(level) * wi->index) +
1820 test_helpers_get_rand_in_range(1UL,
1821 s2tte_map_size(level) - 1UL);
1822
1823 /*
1824 * Depending on `iter`, the expected address returned by
1825 * s2tt_skip_non_live_entries() will be:
1826 *
1827 * - When 'iter' == 0: *entry_ipa
1828 * - When 'iter' == 1: *ipa
1829 * - When 'iter' == 2: The IPA of the next s2tt (next_stt_ipa)
1830 */
1831 return ((iter == 0U) ? *entry_ipa :
1832 ((iter == 1U) ? *ipa : next_stt_ipa));
1833}
1834
1835void s2tt_skip_non_live_entries_tc1(void)
1836{
1837 /***************************************************************
1838 * TEST CASE 1:
1839 *
1840 * For every valid level, generate a set of tests for
1841 * s2tt_skip_non_live_entries():
1842 * - Test with an unassigned entry/table with a live
1843 * entry > wi.index.
1844 * - Test with an unassigned entry/table with the entry
1845 * at wi.index being live.
1846 * - Test with an unassigned entry/table with a random
1847 * live entry at a random index < wi.index.
1848 * - Test with an unassigned entry/table with no live
1849 * entries.
1850 ***************************************************************/
1851
1852 unsigned long ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
1853 S2TTE_NS,
1854 S2TTE_INVALID_RIPAS_RAM,
1855 S2TTE_INVALID_RIPAS_DESTROYED};
1856
1857 init_unassigned_cb init_unassigned_cbs[] = {
1858 s2tt_init_unassigned_empty,
1859 s2tt_init_unassigned_ns,
1860 s2tt_init_unassigned_ram,
1861 s2tt_init_unassigned_destroyed
1862 };
Soby Mathewb1228bb2024-12-31 17:42:46 +00001863 s2tt_context s2tt_ctx;
1864
1865 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001866
1867 /*
1868 * Generate an s2tt context to be used for the test.
1869 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1870 * the rest of them can be uninitialized.
1871 */
1872 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1873
1874 for (long level = s2tt_test_helpers_min_table_lvl();
1875 level <= S2TT_TEST_HELPERS_MAX_LVL; level++) {
1876
1877 unsigned long entry_ipa, ret_ipa, expected_ipa, ipa;
1878 unsigned long s2tt[S2TTES_PER_S2TT];
1879 unsigned int tte_idx, cb_idx = 0U;
1880 struct s2tt_walk wi = {
1881 NULL, /* Not needed */
1882 0UL,
1883 level};
1884
1885 for (unsigned int i = 0U; i < 3U; i++) {
1886
1887 expected_ipa = skip_non_live_entries_gen_ipas(
1888 i, &wi, &tte_idx, &entry_ipa, &ipa);
1889
1890 if (level < s2tt_test_helpers_min_block_lvl()) {
1891 /* Table */
1892
1893 /*
1894 * Clear the s2tt so there are no valid
1895 * table entries
1896 */
1897 (void)memset((void *)&s2tt[0], 0, sizeof(s2tt));
1898
1899 /* Generate a live entry at the random index */
1900 s2tt[tte_idx] =
1901 s2tte_create_table(
1902 (const struct s2tt_context *)&s2tt_ctx,
1903 entry_ipa, level);
1904 } else {
1905 /* Block or page */
1906
1907 /*
1908 * Generate an unassigned table of a random
1909 * RIPAS type and add an assigned entry of a
1910 * random RIPAS type at the random index.
1911 */
1912 cb_idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
1913 ARRAY_SIZE(init_unassigned_cbs) - 1UL);
1914 init_unassigned_cbs[cb_idx](
1915 (const struct s2tt_context *)&s2tt_ctx,
1916 &s2tt[0U]);
1917
1918 cb_idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
1919 ARRAY_SIZE(ripas) - 1UL);
1920 s2tt[tte_idx] =
1921 s2tt_test_create_assigned(
1922 (const struct s2tt_context *)&s2tt_ctx,
1923 entry_ipa, level, ripas[cb_idx]);
1924 }
1925
1926 /* Validate s2tt_skip_non_live_entries() with current params */
1927 ret_ipa = s2tt_skip_non_live_entries(
1928 (const struct s2tt_context *)&s2tt_ctx,
1929 ipa, &s2tt[0U], &wi);
1930 CHECK_TRUE(expected_ipa == ret_ipa);
1931 } /* TEST ID */
1932
1933 /*
1934 * Test with a table without live entries. By recycling the
1935 * arguments from the last test when `iter` == 2, we should
1936 * also get the same results.
1937 */
1938 if (level < s2tt_test_helpers_min_block_lvl()) {
1939 /* Table */
1940 (void)memset((void *)&s2tt[0], 0, sizeof(s2tt));
1941 } else {
1942 /* Block or Page */
1943 init_unassigned_cbs[cb_idx](
1944 (const struct s2tt_context *)&s2tt_ctx, &s2tt[0U]);
1945 }
1946
1947 /* Validate s2tt_skip_non_live_entries() with current params */
1948 ret_ipa = s2tt_skip_non_live_entries(
1949 (const struct s2tt_context *)&s2tt_ctx,
1950 ipa, &s2tt[0U], &wi);
1951 UNSIGNED_LONGS_EQUAL(expected_ipa, ret_ipa);
1952 } /* LEVEL */
1953}
1954
1955void s2tt_skip_non_live_entries_tc2(void)
1956{
1957 /***************************************************************
1958 * TEST CASE 2:
1959 *
1960 * Call s2tt_skip_non_live_entries() with a NULL s2tt pointer.
1961 ***************************************************************/
1962
Soby Mathewb1228bb2024-12-31 17:42:46 +00001963 struct s2tt_context s2tt_ctx;
1964
1965 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
1966
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001967 struct s2tt_walk wi = {
1968 NULL, /* Not needed */
1969 0UL,
1970 0UL};
1971
1972 /*
1973 * Generate an s2tt context to be used for the test. Only
1974 * enable_lpa2 field is needed for the current test.
1975 */
1976 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1977
1978 test_helpers_expect_assert_fail(true);
1979 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)&s2tt_ctx,
1980 0UL, NULL, &wi);
1981 test_helpers_fail_if_no_assert_failed();
1982}
1983
1984void s2tt_skip_non_live_entries_tc3(void)
1985{
1986 /***************************************************************
1987 * TEST CASE 3:
1988 *
1989 * Call s2tt_skip_non_live_entries() with a NULL s2tt_walk struct
1990 * pointer.
1991 ***************************************************************/
1992
1993 unsigned long s2tt[S2TTES_PER_S2TT];
Soby Mathewb1228bb2024-12-31 17:42:46 +00001994 struct s2tt_context s2tt_ctx;
1995
1996 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01001997
1998 /*
1999 * Generate an s2tt context to be used for the test. Only
2000 * enable_lpa2 field is needed for the current test.
2001 */
2002 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2003
2004 test_helpers_expect_assert_fail(true);
2005 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)&s2tt_ctx,
2006 0UL, &s2tt[0U], NULL);
2007 test_helpers_fail_if_no_assert_failed();
2008}
2009
2010void s2tt_skip_non_live_entries_tc4(void)
2011{
2012 /***************************************************************
2013 * TEST CASE 4:
2014 *
2015 * Call s2tt_skip_non_live_entries() with a s2tt_walk struct in
2016 * which the level is below the minimum allowed.
2017 ***************************************************************/
2018
2019 unsigned long s2tt[S2TTES_PER_S2TT];
Soby Mathewb1228bb2024-12-31 17:42:46 +00002020 struct s2tt_context s2tt_ctx;
2021
2022 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
2023
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002024 struct s2tt_walk wi = {
2025 NULL, /* Not needed */
2026 0UL,
2027 s2tt_test_helpers_min_table_lvl() - 1U};
2028
2029 /*
2030 * Generate an s2tt context to be used for the test. Only
2031 * enable_lpa2 field is needed for the current test.
2032 */
2033 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2034 test_helpers_expect_assert_fail(true);
2035 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)&s2tt_ctx,
2036 0UL, &s2tt[0U], &wi);
2037 test_helpers_fail_if_no_assert_failed();
2038}
2039
2040void s2tt_skip_non_live_entries_tc5(void)
2041{
2042 /***************************************************************
2043 * TEST CASE 5:
2044 *
2045 * Call s2tt_skip_non_live_entries() with a s2tt_walk struct in
2046 * which the level is above the maximum allowed.
2047 ***************************************************************/
2048
2049 unsigned long s2tt[S2TTES_PER_S2TT];
Soby Mathewb1228bb2024-12-31 17:42:46 +00002050 struct s2tt_context s2tt_ctx;
2051
2052 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
2053
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002054 struct s2tt_walk wi = {
2055 NULL, /* Not needed */
2056 0UL,
2057 S2TT_TEST_HELPERS_MAX_LVL + 1U};
2058
2059 /*
2060 * Generate an s2tt context to be used for the test. Only
2061 * enable_lpa2 field is needed for the current test.
2062 */
2063 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2064 test_helpers_expect_assert_fail(true);
2065 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)&s2tt_ctx,
2066 0UL, &s2tt[0U], &wi);
2067 test_helpers_fail_if_no_assert_failed();
2068}
2069
2070void s2tt_skip_non_live_entries_tc6(void)
2071{
2072 /***************************************************************
2073 * TEST CASE 6:
2074 *
2075 * Call s2tt_skip_non_live_entries() with a s2tt_walk struct in
2076 * which the index is above the maximum permitted
2077 ***************************************************************/
2078
2079 unsigned long s2tt[S2TTES_PER_S2TT];
Soby Mathewb1228bb2024-12-31 17:42:46 +00002080 struct s2tt_context s2tt_ctx;
2081
2082 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
2083
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002084 struct s2tt_walk wi = {
2085 NULL, /* Not needed */
2086 S2TTES_PER_S2TT + 1UL,
2087 s2tt_test_helpers_min_table_lvl()};
2088
2089 /*
2090 * Generate an s2tt context to be used for the test. Only
2091 * enable_lpa2 field is needed for the current test.
2092 */
2093 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2094 test_helpers_expect_assert_fail(true);
2095 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)&s2tt_ctx,
2096 0UL, &s2tt[0U], &wi);
2097 test_helpers_fail_if_no_assert_failed();
2098}
2099
2100void s2tt_skip_non_live_entries_tc7(void)
2101{
2102 /***************************************************************
2103 * TEST CASE 7:
2104 *
2105 * Call s2tt_skip_non_live_entries() with a NULL pointer to
2106 * s2tt_context structure.
2107 ***************************************************************/
2108
2109 unsigned long s2tt[S2TTES_PER_S2TT];
2110 struct s2tt_walk wi = {
2111 NULL, /* Not needed */
2112 0UL,
2113 s2tt_test_helpers_min_table_lvl()};
2114
2115 test_helpers_expect_assert_fail(true);
2116 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)NULL,
2117 0UL, &s2tt[0U], &wi);
2118 test_helpers_fail_if_no_assert_failed();
2119}
2120
2121/*
2122 * Ancillary function to populate a set of S2 translation tables given an IPA.
2123 * It generates a set of concatenated tables starting at SL + 1.
2124 *
2125 * Arguments:
2126 * - ipa: IPA mapped to the translation table. It is the caller
2127 * responsibility to ensure that the index at SL of the
2128 * table walk does not exceed S2TTE_MAX_CONCAT_TABLES.
2129 * - tt_walk_idx: An array of indexes to the tables in tt_walk[] used
2130 * to walk the tables.
2131 * - tt_walk: An array of tt base addresses for each level which will be
2132 * used to walk the tables.
2133 * - end_lvl: Level at which the walk would finish.
2134 * - tt_granules: Array to store the struct granule pointers corresponding
2135 * to tt_walk[] entries.
2136 * - val_tt_granule: The expected struct granule* of the S2TT at the end of
2137 * test function.
2138 *
2139 * This function creates a set of S2TTE_MAX_CONCAT_TABLES at the level after
2140 * the starting one (sl), which is sl+1. The `ipa` argument is such that the
2141 * translation table hierarchy at sl+1 level will be within the
2142 * S2TTE_MAX_CONCAT_TABLES. This allows the caller to test concatenated tables
2143 * by using thranslaton tables hierarchy at sl+1 level as the start level to
2144 * the test function. As an example, the layout of an array of adjacent granules
2145 * which will be used to create a translation table hierarchy starting from
2146 * level 0 to level 3 would be as follows:
2147 *
2148 * --------------------------
2149 * granule_base | Level -1 S2TT | (Unused in this example)
2150 * --------------------------
2151 * | Level 0 S2TT |
2152 * -------------------------- ---
2153 * | 1st Level 1 S2TT | \
2154 * -------------------------- \
2155 * | 2nd Level 1 S2TT | \
2156 * -------------------------- \
2157 * | (...) | | Concatenated tables
2158 * -------------------------- /
2159 * | 15th Level 1 S2TT | /
2160 * -------------------------- /
2161 * | 16th Level 1 S2T | /
2162 * -------------------------- ---
2163 * | Level 2 S2TT |
2164 * --------------------------
2165 * | Level 3 S2TT |
2166 * --------------------------
2167 *
2168 * It is the caller responsibility to ensure that all the arrays passed to this
2169 * function are sized correctly.
2170 *
2171 * Also note that when FEAT_LPA2 is available, the architectural minimum start
2172 * level supported by stage 2 lookup will be '-1', therefore an offset of one
2173 * will be added to all the indexes used to index the tt_walk* arrays to offset
2174 * the negative value. For simplicity, the offset will be applied even when
2175 * FEAT_LPA2 is not available (SL == 0).
2176 */
2177static void populate_s2tts(struct s2tt_context *s2tt_ctx,
2178 unsigned long ipa, unsigned long *tt_walk_idx,
2179 unsigned long *tt_walk, long end_lvl,
2180 struct granule **tt_granules,
2181 struct granule **val_tt_granule)
2182{
2183 long sl = s2tt_test_helpers_min_table_lvl();
2184 unsigned int next_granule;
2185 unsigned long current_table;
2186 unsigned long *table;
2187 unsigned long *parent_table;
2188 long level;
2189 unsigned long granule_base = host_util_get_granule_base();
2190 struct granule *str_granule_base = test_helpers_granule_struct_base();
2191 unsigned int n_granules = S2TTE_MAX_CONCAT_TABLES +
2192 (S2TT_TEST_HELPERS_MAX_LVL -
2193 S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2194
2195 /* Initialize the granules for the translaton tables */
2196 for (unsigned int i = 0U; i < n_granules; i++) {
2197 tt_granules[i] = str_granule_base + i;
2198 s2tt_test_granule_set_state(tt_granules[i], GRANULE_STATE_RTT);
2199 s2tt_test_granule_set_lock(tt_granules[i], false);
2200 };
2201
2202 /* Root granule must be locked. */
2203 s2tt_test_granule_set_lock(tt_granules[sl + 1L], true);
2204
2205 /*
2206 * Initialize the index for the root granule. Note that SL can be -1
2207 */
2208 next_granule = sl + 1L;
2209
2210 /* Iterate over all the levels and generate the translatation tables */
2211 for (level = sl; level <= end_lvl; level++) {
2212 tt_walk_idx[level + 1L] =
2213 s2tt_test_helpers_get_idx_from_addr(ipa, level);
2214
2215 if (level == sl) {
2216 /*
2217 * Start Level. Get and initialize a table
2218 * for this level.
2219 */
2220 tt_walk[level + 1L] = (granule_base +
2221 (GRANULE_SIZE * next_granule++));
2222 table = (unsigned long *)tt_walk[level + 1L];
2223 (void)memset((void *)table, 0, GRANULE_SIZE);
2224 } else if (level == sl + 1L) {
2225 /*
2226 * Level after the SL. This level will include the
2227 * set of concatenated tables.
2228 */
2229 parent_table = (unsigned long *)tt_walk[level];
2230
2231 /*
2232 * Create the set of S2TTE_MAX_CONCAT_TABLES
2233 * concatenated tables and populate each entry of the
2234 * parent table (at level SL) to point to them.
2235 */
2236 for (unsigned int i = 0U;
2237 i < S2TTE_MAX_CONCAT_TABLES; i++) {
2238 unsigned long concat_table = (granule_base +
2239 (GRANULE_SIZE * next_granule++));
2240 parent_table[i] =
2241 s2tte_create_table(
2242 (const struct s2tt_context *)s2tt_ctx,
2243 concat_table, level);
2244
2245 /* Clean this level tables */
2246 (void)memset((void *)concat_table, 0, GRANULE_SIZE);
2247 }
2248
2249 /*
2250 * Now there are S2TTE_MAX_CONCAT_TABLES concatenated
2251 * tables on this level, of which only one will be used
2252 * during the table walk. Find that table and assign it
2253 * to the current level of tt_walk[].
2254 */
2255 tt_walk[level + 1L] = (granule_base +
2256 ((sl + 2 + tt_walk_idx[level]) * GRANULE_SIZE));
2257 } else if (level < S2TT_TEST_HELPERS_MAX_LVL) {
2258 /*
2259 * Tables between the start level + 1 and the
2260 * page level.
2261 */
2262 parent_table = (unsigned long *)tt_walk[level];
2263
2264 /* Get, store and initialize the table on this level */
2265 current_table = (granule_base +
2266 (GRANULE_SIZE * next_granule++));
2267 tt_walk[level + 1L] = current_table;
2268 (void)memset((void *)current_table, 0, GRANULE_SIZE);
2269
2270 /* And assign the table to the current level of tt_walk[] */
2271 parent_table[tt_walk_idx[level]] =
2272 s2tte_create_table(
2273 (const struct s2tt_context *)s2tt_ctx,
2274 current_table, level - 1L);
2275 } else {
2276 /* Page Level */
2277 parent_table = (unsigned long *)tt_walk[level];
2278
2279 /* Get, store and initialize the table on this level */
2280 current_table = (granule_base +
2281 (GRANULE_SIZE * next_granule++));
2282 tt_walk[level + 1L] = current_table;
2283
2284 /*
2285 * Initialize the table as a L3 table.
2286 * We initialize as assigned-ram for no particular
2287 * reason using the IPA as PA.
2288 */
2289 table = (unsigned long *)current_table;
2290 s2tt_init_assigned_ram((const struct s2tt_context *)s2tt_ctx,
2291 table, (ipa & s2tt_test_helpers_lvl_mask(level)), level);
2292
2293 /* And assign the table to the current level of tt_walk[] */
2294 parent_table[tt_walk_idx[level]] =
2295 s2tte_create_table(
2296 (const struct s2tt_context *)s2tt_ctx,
2297 current_table, level - 1L);
2298 }
2299 }
2300
2301 /* Generate the expected validation granule */
2302 *val_tt_granule = addr_to_granule(tt_walk[end_lvl + 1]);
2303}
2304
2305void s2tt_walk_lock_unlock_tc1(void)
2306{
2307 /***************************************************************
2308 * TEST CASE 1:
2309 *
2310 * Several positive tests:
2311 * - 1a) Generate a random mapping starting at the minimum
2312 * possible level up to the maximum one and use
2313 * s2tt_walk_lock_unlock() to walk the translation
2314 * table and validate its output.
2315 * - 1b) Repeat the test above, but starting the walk at
2316 * (SL + 1) so as to test the concatenated tables support.
2317 * - 2a & 2b) Repeat the two tests above, but finalising the
2318 * walk at a level below the maximum one.
2319 * - 3a & 3b) Repeat the first two tests, but completing the
2320 * tables up to a level below the maximum one and calling
2321 * s2tt_walk_lock_unlock() with a level above the last
2322 * one mapped on the translation tables.
2323 *
2324 * The level after the starting one will have
2325 * S2TTE_MAX_CONCAT_TABLES concatenated granules so to test the
2326 * concatenated starting levels.
2327 ***************************************************************/
2328
2329 long sl = s2tt_test_helpers_min_table_lvl();
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002330 const long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2331 long end_level_x;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002332 unsigned long pa, sl_index;
2333 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2334 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2335 struct s2tt_walk wi;
2336 struct granule *val_tt_granule;
Soby Mathewb1228bb2024-12-31 17:42:46 +00002337 struct s2tt_context s2tt_ctx;
2338
2339 (void)memset(&s2tt_ctx, 0, sizeof(s2tt_ctx));
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002340
2341 /* Total number of granules, included the concatenated ones */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002342 const unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002343 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2344
2345 /*
2346 * Granules to hold the translation tables,
2347 * including concatenated ones.
2348 */
2349 struct granule *g_tables[granules];
2350
2351 /*
2352 * Generate a random address that spans across the whole IPA size
2353 * but whose walk index at SL + 1 is within
2354 * S2TTE_MAX_CONCAT_TABLES range so the address can also be used to
2355 * test concatenated root table support.
2356 *
2357 * The address doesn't need to have any alignment.
2358 */
2359 do {
2360 pa = test_helpers_get_rand_in_range(1UL,
2361 (1UL << arch_feat_get_pa_width()) - 1UL);
2362 sl_index = s2tt_test_helpers_get_idx_from_addr(pa, sl);
2363 } while (sl_index >= S2TTE_MAX_CONCAT_TABLES);
2364
2365 /* Generate an s2tt context to be used for the test */
2366 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2367
2368 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2369 end_level, &g_tables[0U], &val_tt_granule);
2370
2371 /* Finish the creation of the s2tt_context */
2372 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2373 s2tt_ctx.s2_starting_level = sl;
2374 s2tt_ctx.g_rtt = g_tables[sl + 1UL];
2375 s2tt_ctx.num_root_rtts = 1U;
2376
2377 /*
2378 * Invoke s2tt_walk_lock_unlock() with the generated translation tables
2379 *
2380 * (Test 1a)
2381 */
2382 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2383 pa, end_level, &wi);
2384
2385 LONGS_EQUAL(end_level, wi.last_level);
2386 CHECK_TRUE(val_tt_granule == wi.g_llt);
2387 UNSIGNED_LONGS_EQUAL(tt_walk_idx[end_level + 1U], wi.index);
2388
2389 for (unsigned int i = sl + 1U; i < granules; i++) {
2390 if (g_tables[i] == wi.g_llt) {
2391 /* Granule must be locked */
2392 CHECK_TRUE(LOCKED(wi.g_llt));
2393 } else {
2394 /* Granule must be unlocked */
2395 CHECK_FALSE(LOCKED(g_tables[i]));
2396 }
2397 }
2398
2399 /*
2400 * Repeat the test, but this time starting from the next level after
2401 * the starting one, so we can test the concatenated tables.
2402 *
2403 * (Test 1b)
2404 */
2405 (void)memset(&wi, 0, sizeof(wi));
2406
2407 /* Initialize the granules for the translaton tables */
2408 for (unsigned int i = 0U; i < granules; i++) {
2409 s2tt_test_granule_set_lock(g_tables[i], false);
2410 };
2411
2412 /*
2413 * Root granule must be locked. In this case, the root granule is
2414 * the granule after the minimum level plus one.
2415 */
2416 s2tt_test_granule_set_lock(g_tables[sl + 2], true);
2417
2418 /*
2419 * Invoke s2tt_walk_lock_unlock() with the generated translation tables
2420 * starting on the next starting level.
2421 */
2422 s2tt_ctx.s2_starting_level = sl + 1L;
2423 s2tt_ctx.g_rtt = g_tables[sl + 2UL];
2424 s2tt_ctx.num_root_rtts = S2TTE_MAX_CONCAT_TABLES;
2425
2426 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2427 pa, end_level, &wi);
2428
2429 LONGS_EQUAL(end_level, wi.last_level);
2430 CHECK_TRUE(val_tt_granule == wi.g_llt);
2431 LONGS_EQUAL(tt_walk_idx[end_level + 1U], wi.index);
2432
2433 for (unsigned int i = sl + 1U; i < granules; i++) {
2434 if (g_tables[i] == wi.g_llt) {
2435 /* Granule must be locked */
2436 CHECK_TRUE(LOCKED(wi.g_llt));
2437 } else {
2438 /* Granule must be unlocked */
2439 CHECK_FALSE(LOCKED(g_tables[i]));
2440 }
2441 }
2442
2443 /*
2444 * Repeat both the tests above, but this time finalizing the walk
2445 * a level below the maximum one. Reuse the structures initialized
2446 * on the test before.
2447 *
2448 * (Test 2a & 2b)
2449 */
2450 (void)memset(&wi, 0, sizeof(wi));
2451
2452 /* Initialize the granules for the translaton tables */
2453 for (unsigned int i = 0U; i < granules; i++) {
2454 s2tt_test_granule_set_lock(g_tables[i], false);
2455 };
2456
2457 /* Root granule must be locked */
2458 s2tt_test_granule_set_lock(g_tables[sl + 1], true);
2459
2460 s2tt_ctx.s2_starting_level = sl;
2461 s2tt_ctx.g_rtt = g_tables[sl + 1UL];
2462 s2tt_ctx.num_root_rtts = 1U;
2463
2464 /*
2465 * Update the expected end_level and validation granule
2466 *
2467 * (Test 2a)
2468 */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002469 end_level_x = S2TT_TEST_HELPERS_MAX_LVL - 1U;
2470 val_tt_granule = addr_to_granule(tt_walk[end_level_x + 1U]);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002471
2472 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002473 pa, end_level_x, &wi);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002474
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002475 LONGS_EQUAL(end_level_x, wi.last_level);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002476 CHECK_TRUE(val_tt_granule == wi.g_llt);
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002477 LONGS_EQUAL(tt_walk_idx[end_level_x + 1U], wi.index);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002478
2479 for (unsigned int i = sl + 1U; i < granules; i++) {
2480 if (g_tables[i] == wi.g_llt) {
2481 /* Granule must be locked */
2482 CHECK_TRUE(LOCKED(wi.g_llt));
2483 } else {
2484 /* Granule must be unlocked */
2485 CHECK_FALSE(LOCKED(g_tables[i]));
2486 }
2487 }
2488
2489 /*
2490 * Repeat the test, but this time starting from the next level after
2491 * the starting one, so we can test the concatenated tables.
2492 *
2493 * (Test 2b)
2494 */
2495 (void)memset(&wi, 0, sizeof(wi));
2496
2497 /* Initialize the granules for the translaton tables */
2498 for (unsigned int i = 0U; i < granules; i++) {
2499 s2tt_test_granule_set_lock(g_tables[i], false);
2500 };
2501
2502 /* Root granule must be locked */
2503 s2tt_test_granule_set_lock(g_tables[sl + 2], true);
2504
2505 /*
2506 * Invoke s2tt_walk_lock_unlock() with the generated translation tables
2507 * starting on the next starting level.
2508 */
2509 s2tt_ctx.s2_starting_level = sl + 1L;
2510 s2tt_ctx.g_rtt = g_tables[sl + 2UL];
2511 s2tt_ctx.num_root_rtts = S2TTE_MAX_CONCAT_TABLES;
2512
2513 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002514 pa, end_level_x, &wi);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002515
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002516 LONGS_EQUAL(end_level_x, wi.last_level);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002517 CHECK_TRUE(val_tt_granule == wi.g_llt);
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002518 LONGS_EQUAL(tt_walk_idx[end_level_x + 1U], wi.index);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002519
2520 for (unsigned int i = sl + 1U; i < granules; i++) {
2521 if (g_tables[i] == wi.g_llt) {
2522 /* Granule must be locked */
2523 CHECK_TRUE(LOCKED(wi.g_llt));
2524 } else {
2525 /* Granule must be unlocked */
2526 CHECK_FALSE(LOCKED(g_tables[i]));
2527 }
2528 }
2529
2530 /*
2531 * Repeat the two first tests, but this time the mapping will
2532 * be finalizing a level below the maximum one and
2533 * s2tt_walk_lock_unlock() will be called to walk up to the
2534 * maximum level.
2535 *
2536 * (Tests 3a & 3b)
2537 */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002538 end_level_x = S2TT_TEST_HELPERS_MAX_LVL;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002539 (void)memset(&wi, 0, sizeof(wi));
2540
2541 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002542 end_level_x - 1L, &g_tables[0U], &val_tt_granule);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002543
2544 s2tt_ctx.s2_starting_level = sl;
2545 s2tt_ctx.g_rtt = g_tables[sl + 1UL];
2546 s2tt_ctx.num_root_rtts = 1;
2547
2548 /* Test 3a */
2549 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002550 pa, end_level_x, &wi);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002551
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002552 LONGS_EQUAL((end_level_x - 1L), wi.last_level);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002553 CHECK_TRUE(val_tt_granule == wi.g_llt);
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002554 LONGS_EQUAL(tt_walk_idx[end_level_x], wi.index);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002555
2556 for (unsigned int i = sl + 1U; i < granules; i++) {
2557 if (g_tables[i] == wi.g_llt) {
2558 /* Granule must be locked */
2559 CHECK_TRUE(LOCKED(wi.g_llt));
2560 } else {
2561 /* Granule must be unlocked */
2562 CHECK_FALSE(LOCKED(g_tables[i]));
2563 }
2564 }
2565
2566 /*
2567 * Repeat the test, but this time starting from the next level after
2568 * the starting one, so we can test the concatenated tables.
2569 *
2570 * (Test 3b)
2571 */
2572 (void)memset(&wi, 0, sizeof(wi));
2573
2574 /* Initialize the granules for the translaton tables */
2575 for (unsigned int i = 0U; i < granules; i++) {
2576 s2tt_test_granule_set_lock(g_tables[i], false);
2577 };
2578
2579 /* Root granule must be locked */
2580 s2tt_test_granule_set_lock(g_tables[sl + 2], true);
2581
2582 /*
2583 * Invoke s2tt_walk_lock_unlock() with the generated translation tables
2584 * starting on the next starting level.
2585 */
2586 s2tt_ctx.s2_starting_level = sl + 1L;
2587 s2tt_ctx.g_rtt = g_tables[sl + 2UL];
2588 s2tt_ctx.num_root_rtts = S2TTE_MAX_CONCAT_TABLES;
2589
2590 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002591 pa, end_level_x, &wi);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002592
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002593 LONGS_EQUAL((end_level_x - 1L), wi.last_level);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002594 CHECK_TRUE(val_tt_granule == wi.g_llt);
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002595 LONGS_EQUAL(tt_walk_idx[end_level_x], wi.index);
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002596
2597 for (unsigned int i = sl + 1U; i < granules; i++) {
2598 if (g_tables[i] == wi.g_llt) {
2599 /* Granule must be locked */
2600 CHECK_TRUE(LOCKED(wi.g_llt));
2601 } else {
2602 /* Granule must be unlocked */
2603 CHECK_FALSE(LOCKED(g_tables[i]));
2604 }
2605 }
2606}
2607
2608void s2tt_walk_lock_unlock_tc2(void)
2609{
2610 /***************************************************************
2611 * TEST CASE 2:
2612 *
2613 * Test s2tt_walk_lock_unlock() with a set of tables in wich
2614 * the granule of one of them is not set to 'GRANULE_STATE_RTT'
2615 ***************************************************************/
2616
2617 long sl = s2tt_test_helpers_min_table_lvl();
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002618 const long end_level = S2TT_TEST_HELPERS_MAX_LVL;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002619 unsigned long pa;
2620 unsigned long sl_index;
2621 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2622 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2623 struct s2tt_walk wi;
2624 struct granule *val_tt_granule;
2625 struct s2tt_context s2tt_ctx;
2626
2627 /* Total number of granules, included the concatenated ones */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002628 const unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002629 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2630
2631 /*
2632 * Granules to hold the translation tables,
2633 * including concatenated ones.
2634 */
2635 struct granule *g_tables[granules];
2636
2637 /*
2638 * Generate a random address that spans across the whole IPA size
2639 * but whose walk index at SL + 1 is within
2640 * S2TTE_MAX_CONCAT_TABLES range so the address can also be used to
2641 * test concatenated root table support.
2642 *
2643 * The address doesn't need to have any alignment.
2644 */
2645 do {
2646 pa = test_helpers_get_rand_in_range(1UL,
2647 (1UL << arch_feat_get_pa_width()) - 1UL);
2648 sl_index = s2tt_test_helpers_get_idx_from_addr(pa, sl);
2649 } while (sl_index >= S2TTE_MAX_CONCAT_TABLES);
2650
2651 /* Generate an s2tt context to be used for the test */
2652 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2653 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2654 end_level, &g_tables[0U], &val_tt_granule);
2655
2656 /* Finish the creation of the s2tt_context */
2657 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2658 s2tt_ctx.s2_starting_level = sl;
2659 s2tt_ctx.g_rtt = g_tables[sl + 1UL];
2660 s2tt_ctx.num_root_rtts = 1U;
2661
2662 /*
2663 * Change the granule state for an arbitrary level. In this case, we
2664 * choose Level 2 for simplicity and convenience. The new granule
2665 * state is also chosen arbitrarily.
2666 *
2667 * Note that index '0' corresponds to level '-1' and one of the
2668 * intermediate levels (the level after the starting one) has
2669 * 'S2TTE_MAX_CONCAT_TABLES' tables.
2670 */
2671 s2tt_test_granule_set_state(g_tables[3 + S2TTE_MAX_CONCAT_TABLES],
2672 GRANULE_STATE_RD);
2673
2674 /* The call should cause an assertion failure */
2675 test_helpers_expect_assert_fail(true);
2676 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2677 pa, end_level, &wi);
2678 test_helpers_fail_if_no_assert_failed();
2679}
2680
2681void s2tt_walk_lock_unlock_tc3(void)
2682{
2683 /***************************************************************
2684 * TEST CASE 3:
2685 *
2686 * Test s2tt_walk_lock_unlock() with a set of tables in which
2687 * one of the granules is already locked.
2688 ***************************************************************/
2689
2690 long sl = s2tt_test_helpers_min_table_lvl();
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002691 const long end_level = S2TT_TEST_HELPERS_MAX_LVL;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002692 unsigned long pa;
2693 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2694 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2695 struct s2tt_walk wi;
2696 struct granule *val_tt_granule;
2697 struct s2tt_context s2tt_ctx;
2698
2699 /* Total number of granules, included the concatenated ones */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002700 const unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002701 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2702
2703 /*
2704 * Granules to hold the translation tables,
2705 * including concatenated ones.
2706 */
2707 struct granule *g_tables[granules];
2708
2709 /* Generate an s2tt context to be used for the test */
2710 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2711
2712 pa = 0UL; /* Valid on any level */
2713 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2714 end_level, &g_tables[0U], &val_tt_granule);
2715
2716 /* Finish the creation of the s2tt_context */
2717 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2718 s2tt_ctx.s2_starting_level = sl;
2719 s2tt_ctx.g_rtt = g_tables[sl + 1UL];
2720 s2tt_ctx.num_root_rtts = 1U;
2721
2722 /*
2723 * Lock the granule of an arbitrary level. In this case, we
2724 * choose Level 2 for simplicity and convenience.
2725 *
2726 * Note that index '0' corresponds to level '-1' and one of the
2727 * intermediate levels (the level after the starting one) has
2728 * 'S2TTE_MAX_CONCAT_TABLES' tables.
2729 */
2730 s2tt_test_granule_set_lock(g_tables[3 + S2TTE_MAX_CONCAT_TABLES], true);
2731
2732 /* The call should cause an assertion failure */
2733 test_helpers_expect_assert_fail(true);
2734 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2735 pa, end_level, &wi);
2736 test_helpers_fail_if_no_assert_failed();
2737}
2738
2739void s2tt_walk_lock_unlock_tc4(void)
2740{
2741 /***************************************************************
2742 * TEST CASE 4:
2743 *
2744 * Test s2tt_walk_lock_unlock() with a null array of granules.
2745 ***************************************************************/
2746
2747 long sl = s2tt_test_helpers_min_table_lvl();
2748 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2749 unsigned long pa;
2750 struct s2tt_walk wi;
2751 struct s2tt_context s2tt_ctx;
2752
2753 pa = 0UL;
2754
2755 /* Generate an s2tt context to be used for the test */
2756 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2757 s2tt_ctx.s2_starting_level = sl;
2758 s2tt_ctx.g_rtt = NULL;
2759 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2760 s2tt_ctx.num_root_rtts = 1U;
2761
2762 /* The call should cause an assertion failure */
2763 test_helpers_expect_assert_fail(true);
2764 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2765 pa, end_level, &wi);
2766 test_helpers_fail_if_no_assert_failed();
2767}
2768
2769void s2tt_walk_lock_unlock_tc5(void)
2770{
2771 /***************************************************************
2772 * TEST CASE 5:
2773 *
2774 * Test s2tt_walk_lock_unlock() with a null s2tt_walk structure.
2775 ***************************************************************/
2776
2777 long sl = s2tt_test_helpers_min_table_lvl();
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002778 const long end_level = S2TT_TEST_HELPERS_MAX_LVL;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002779 unsigned long pa;
2780 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2781 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2782 struct granule *val_tt_granule;
2783 struct s2tt_context s2tt_ctx;
2784
2785 /* Total number of granules, included the concatenated ones */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002786 const unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002787 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2788
2789 /*
2790 * Granules to hold the translation tables,
2791 * including concatenated ones.
2792 */
2793 struct granule *g_tables[granules];
2794
2795 /* Generate an s2tt context to be used for the test */
2796 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2797
2798 pa = 0UL; /* Valid on any level */
2799 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2800 end_level, &g_tables[0U], &val_tt_granule);
2801
2802 /* Finish the creation of the s2tt_context */
2803 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2804 s2tt_ctx.s2_starting_level = sl;
2805 s2tt_ctx.g_rtt = NULL;
2806 s2tt_ctx.num_root_rtts = 1U;
2807
2808 /* The call should cause an assertion failure */
2809 test_helpers_expect_assert_fail(true);
2810 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2811 pa, end_level, NULL);
2812 test_helpers_fail_if_no_assert_failed();
2813}
2814
2815void s2tt_walk_lock_unlock_tc6(void)
2816{
2817 /***************************************************************
2818 * TEST CASE 6:
2819 *
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002820 * Test s2tt_walk_lock_unlock() with a start level above the
2821 * maximum permitted.
2822 ***************************************************************/
2823
2824 long sl = s2tt_test_helpers_min_table_lvl();
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002825 const long end_level = S2TT_TEST_HELPERS_MAX_LVL;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002826 unsigned long pa;
2827 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2828 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2829 struct s2tt_walk wi;
2830 struct granule *val_tt_granule;
2831 struct s2tt_context s2tt_ctx;
2832
2833 /* Total number of granules, included the concatenated ones */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002834 const unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002835 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2);
2836
2837 /*
2838 * Granules to hold the translation tables,
2839 * including concatenated ones.
2840 */
2841 struct granule *g_tables[granules];
2842
2843 /* Generate an s2tt context to be used for the test */
2844 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2845
2846 pa = 0UL; /* Valid on any level */
2847 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2848 end_level, &g_tables[0U], &val_tt_granule);
2849
2850 /* Finish the creation of the s2tt_context */
2851 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2852 s2tt_ctx.s2_starting_level = end_level + 1L;
2853 s2tt_ctx.g_rtt = g_tables[sl + 1U];
2854 s2tt_ctx.num_root_rtts = 1U;
2855
2856 /* The call should cause an assertion failure */
2857 test_helpers_expect_assert_fail(true);
2858 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2859 pa, end_level, &wi);
2860 test_helpers_fail_if_no_assert_failed();
2861}
2862
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01002863void s2tt_walk_lock_unlock_tc7(void)
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002864{
2865 /***************************************************************
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01002866 * TEST CASE 7:
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002867 *
2868 * Test s2tt_walk_lock_unlock() with a walk end level below the
2869 * start level.
2870 ***************************************************************/
2871
2872 long sl = s2tt_test_helpers_min_table_lvl();
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002873 const long end_level = S2TT_TEST_HELPERS_MAX_LVL;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002874 unsigned long pa;
2875 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2876 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2877 struct s2tt_walk wi;
2878 struct granule *val_tt_granule;
2879 struct s2tt_context s2tt_ctx;
2880
2881 /* Total number of granules, included the concatenated ones */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002882 const unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002883 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2884
2885 /*
2886 * Granules to hold the translation tables,
2887 * including concatenated ones.
2888 */
2889 struct granule *g_tables[granules];
2890
2891 /* Generate an s2tt context to be used for the test */
2892 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2893
2894 pa = 0UL; /* Valid on any level */
2895 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2896 end_level, &g_tables[0U], &val_tt_granule);
2897
2898 /* Finish the creation of the s2tt_context */
2899 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2900 s2tt_ctx.s2_starting_level = sl;
2901 s2tt_ctx.g_rtt = g_tables[sl + 1U];
2902 s2tt_ctx.num_root_rtts = 1U;
2903
2904 /* The call should cause an assertion failure */
2905 test_helpers_expect_assert_fail(true);
2906 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2907 pa, sl - 1U, &wi);
2908 test_helpers_fail_if_no_assert_failed();
2909}
2910
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01002911void s2tt_walk_lock_unlock_tc8(void)
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002912{
2913 /***************************************************************
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01002914 * TEST CASE 8:
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002915 *
2916 * Test s2tt_walk_lock_unlock() with an end walk level above the
2917 * maximum permitted.
2918 ***************************************************************/
2919
2920 long sl = s2tt_test_helpers_min_table_lvl();
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002921 const long end_level = S2TT_TEST_HELPERS_MAX_LVL;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002922 unsigned long pa;
2923 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2924 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2925 struct s2tt_walk wi;
2926 struct granule *val_tt_granule;
2927 struct s2tt_context s2tt_ctx;
2928
2929 /* Total number of granules, included the concatenated ones */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002930 const unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002931 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2932
2933 /*
2934 * Granules to hold the translation tables,
2935 * including concatenated ones.
2936 */
2937 struct granule *g_tables[granules];
2938
2939 /* Generate an s2tt context to be used for the test */
2940 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2941
2942 pa = 0UL; /* Valid on any level */
2943 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2944 end_level, &g_tables[0U], &val_tt_granule);
2945
2946 /* Finish the creation of the s2tt_context */
2947 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2948 s2tt_ctx.s2_starting_level = sl;
2949 s2tt_ctx.g_rtt = g_tables[sl + 1U];
2950 s2tt_ctx.num_root_rtts = 1U;
2951
2952 /* The call should cause an assertion failure */
2953 test_helpers_expect_assert_fail(true);
2954 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2955 pa, end_level + 1, &wi);
2956 test_helpers_fail_if_no_assert_failed();
2957}
2958
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01002959void s2tt_walk_lock_unlock_tc9(void)
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002960{
2961 /***************************************************************
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01002962 * TEST CASE 9:
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002963 *
2964 * Test s2tt_walk_lock_unlock() with a PA above the maximum
2965 * supported IPA size.
2966 ***************************************************************/
2967
2968 long sl = s2tt_test_helpers_min_table_lvl();
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002969 const long end_level = S2TT_TEST_HELPERS_MAX_LVL;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002970 unsigned long pa;
2971 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2972 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2973 struct s2tt_walk wi;
2974 struct granule *val_tt_granule;
2975 s2tt_context s2tt_ctx;
2976
2977 /* Total number of granules, included the concatenated ones */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00002978 const unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01002979 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2980
2981 /*
2982 * Granules to hold the translation tables,
2983 * including concatenated ones.
2984 */
2985 struct granule *g_tables[granules];
2986
2987 /* Generate an s2tt context to be used for the test */
2988 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2989
2990 pa = 0UL; /* Valid on any level */
2991
2992 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2993 end_level, &g_tables[0U], &val_tt_granule);
2994
2995 /* Finish the creation of the s2tt_context */
2996 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2997 s2tt_ctx.s2_starting_level = sl;
2998 s2tt_ctx.g_rtt = g_tables[sl + 1U];
2999 s2tt_ctx.num_root_rtts = 1U;
3000
3001 /* Generate an address larger than the maximum allowable size */
3002 pa = 1UL << s2tt_ctx.ipa_bits;
3003
3004 /* The call should cause an assertion failure */
3005 test_helpers_expect_assert_fail(true);
3006 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
3007 pa, end_level, &wi);
3008 test_helpers_fail_if_no_assert_failed();
3009}
3010
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01003011void s2tt_walk_lock_unlock_tc10(void)
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01003012{
3013 /***************************************************************
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01003014 * TEST CASE 10:
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01003015 *
3016 * Test s2tt_walk_lock_unlock() with an invalid max ipa size.
3017 ***************************************************************/
3018
3019 long sl = s2tt_test_helpers_min_table_lvl();
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00003020 const long end_level = S2TT_TEST_HELPERS_MAX_LVL;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01003021 unsigned long pa;
3022 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
3023 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
3024 struct s2tt_walk wi;
3025 struct granule *val_tt_granule;
3026 struct s2tt_context s2tt_ctx;
3027
3028 /* Total number of granules, included the concatenated ones */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00003029 const unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01003030 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
3031
3032 /*
3033 * Granules to hold the translation tables,
3034 * including concatenated ones.
3035 */
3036 struct granule *g_tables[granules];
3037
3038 /* Generate an s2tt context to be used for the test */
3039 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
3040
3041 pa = 0UL; /* Valid on any level */
3042
3043 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
3044 end_level, &g_tables[0U], &val_tt_granule);
3045
3046 /* Finish the creation of the s2tt_context */
3047 s2tt_ctx.ipa_bits = arch_feat_get_pa_width() + 1UL;
3048 s2tt_ctx.s2_starting_level = sl;
3049 s2tt_ctx.g_rtt = g_tables[sl + 1U];
3050 s2tt_ctx.num_root_rtts = 1U;
3051
3052 /* The call should cause an assertion failure */
3053 test_helpers_expect_assert_fail(true);
3054 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
3055 pa, end_level, &wi);
3056 test_helpers_fail_if_no_assert_failed();
3057}
3058
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01003059void s2tt_walk_lock_unlock_tc11(void)
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01003060{
3061 /***************************************************************
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01003062 * TEST CASE 11:
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01003063 *
3064 * Test s2tt_walk_lock_unlock() with a combination of first
3065 * look-up level and root tables in which the number of
3066 * concatenated tables would result larger than the maximum
3067 * permitted.
3068 ***************************************************************/
3069
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00003070 const long end_level = S2TT_TEST_HELPERS_MAX_LVL;
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01003071 unsigned long pa;
3072 unsigned long sl_index;
3073 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
3074 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
3075 struct s2tt_walk wi;
3076 struct granule *val_tt_granule;
3077 struct s2tt_context s2tt_ctx;
3078
3079 /* Total number of granules, included the concatenated ones */
Javier Almansa Sobrinoe7d1f032024-11-21 11:21:31 +00003080 const unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01003081 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
3082
3083 /*
3084 * Granules to hold the translation tables,
3085 * including concatenated ones.
3086 */
3087 struct granule *g_tables[granules];
3088
3089 /*
3090 * We need to generate a concatenated table at SL + 1 with a number
3091 * of tables > S2TTE_MAX_CONCAT_TABLES. In order to avoid an
3092 * overflowing IPA when FEAT_LPA2 is enabled, we set SL to be
3093 * the architectural minimum plus 1.
3094 */
3095 long sl = s2tt_test_helpers_min_table_lvl() + 1L;
3096
3097 /*
3098 * Generate a random address that spans across the whole IPA size but
3099 * whose walk table index at SL is larger than S2TTE_MAX_CONCAT_TABLES.
3100 *
3101 * The address doesn't need to have any alignment.
3102 */
3103 do {
3104 pa = test_helpers_get_rand_in_range(1UL,
3105 (1UL << arch_feat_get_pa_width()) - 1UL);
3106 sl_index = s2tt_test_helpers_get_idx_from_addr(pa, sl);
3107 } while (sl_index <= S2TTE_MAX_CONCAT_TABLES);
3108
3109 /* Generate an s2tt context to be used for the test */
3110 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
3111
3112 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
3113 end_level, &g_tables[0U], &val_tt_granule);
3114
3115 /* Finish the creation of the s2tt_context */
3116 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
3117 s2tt_ctx.s2_starting_level = sl + 1L;
3118 s2tt_ctx.g_rtt = g_tables[sl + 2U];
3119 s2tt_ctx.num_root_rtts = S2TTE_MAX_CONCAT_TABLES;
3120
3121 /* The call should cause an assertion failure */
3122 test_helpers_expect_assert_fail(true);
3123 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
3124 pa, end_level, &wi);
3125 test_helpers_fail_if_no_assert_failed();
3126}
3127
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01003128void s2tt_walk_lock_unlock_tc12(void)
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01003129{
3130 /***************************************************************
Javier Almansa Sobrinob7a9d902024-08-06 15:32:57 +01003131 * TEST CASE 12:
Javier Almansa Sobrino9810a8e2024-06-03 15:17:25 +01003132 *
3133 * Test s2tt_walk_lock_unlock() with a null s2tt_context.
3134 ***************************************************************/
3135
3136 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
3137 unsigned long pa;
3138 struct s2tt_walk wi;
3139
3140 pa = 0UL;
3141
3142 /* The call should cause an assertion failure */
3143 test_helpers_expect_assert_fail(true);
3144 s2tt_walk_lock_unlock((const struct s2tt_context *)NULL,
3145 pa, end_level, &wi);
3146 test_helpers_fail_if_no_assert_failed();
3147}