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