blob: b6ef2c527afa84e3181e0fbe801487986d5e82d5 [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);
1151 unsigned long ns_mask = (s2tt_ctx.enable_lpa2 == true) ?
1152 S2TTE_NS_ATTR_LPA2_MASK : S2TTE_NS_ATTR_MASK;
1153
1154 /* Generate the table */
1155 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1156 &s2tt[0U], attrs, pa, level);
1157
1158 /* Generate the offending set of NS attrs */
1159 do {
1160 new_attrs = test_helpers_get_rand_in_range(0UL, ULONG_MAX);
1161 new_attrs &= ns_mask;
1162 } while (new_attrs == (s2tt[0U] & ns_mask));
1163
1164 /* Alter the NS attributes on a random TTE */
1165 s2tt[index] &= ~ns_mask;
1166 s2tt[index] |= new_attrs;
1167
1168 CHECK_FALSE(s2tt_maps_assigned_ns_block(
1169 (const struct s2tt_context *)&s2tt_ctx,
1170 &s2tt[0U], level));
1171 }
1172}
1173
1174void s2tt_maps_assigned_ns_block_tc3(void)
1175{
1176 /***************************************************************
1177 * TEST CASE 3:
1178 *
1179 * For each valid level, create an assigned ns block and
1180 * then change a random TTE to a different type to validate
1181 * that s2tt_maps_assigned_ns_block() returns the expected
1182 * value
1183 ***************************************************************/
1184
1185 unsigned long unassigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
1186 S2TTE_INVALID_RIPAS_RAM,
1187 S2TTE_NS,
1188 S2TTE_INVALID_RIPAS_DESTROYED};
1189 unsigned long assigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
1190 S2TTE_INVALID_RIPAS_RAM,
1191 S2TTE_INVALID_RIPAS_DESTROYED};
1192
1193 unsigned long attrs = s2tt_test_helpers_gen_ns_attrs(true, false);
1194 s2tt_context s2tt_ctx = { 0UL };
1195
1196 /*
1197 * Generate an s2tt context to be used for the test.
1198 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1199 * the rest of them can be uninitialized.
1200 */
1201 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1202
1203 for (long level = s2tt_test_helpers_min_block_lvl();
1204 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
1205
1206 unsigned int tte_idx =
1207 (unsigned int)test_helpers_get_rand_in_range(0UL,
1208 S2TTES_PER_S2TT - 1UL);
1209 /* pickup a random type of unassigned S2TTE to test with */
1210 unsigned int idx =
1211 (unsigned int)test_helpers_get_rand_in_range(0UL,
1212 ARRAY_SIZE(unassigned_ripas) - 1UL);
1213 unsigned long s2tt[S2TTES_PER_S2TT];
1214 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1215
1216 /* Generate the table */
1217 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1218 &s2tt[0U], attrs, pa, level);
1219
1220 /* Alter a random S2TTE on the table */
1221 s2tt[tte_idx] = s2tt_test_create_unassigned(
1222 (const struct s2tt_context *)&s2tt_ctx,
1223 unassigned_ripas[idx]);
1224 CHECK_FALSE(s2tt_maps_assigned_ns_block(
1225 (const struct s2tt_context *)&s2tt_ctx,
1226 &s2tt[0U], level));
1227
1228 /* pickup a random type of assigned S2TTE to test with */
1229 idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
1230 ARRAY_SIZE(assigned_ripas) - 1UL);
1231
1232 /* Alter a random S2TTE on the table */
1233 s2tt[tte_idx] = s2tt_test_create_assigned(
1234 (const struct s2tt_context *)&s2tt_ctx,
1235 pa, level, assigned_ripas[idx]);
1236 CHECK_FALSE(s2tt_maps_assigned_ns_block(
1237 (const struct s2tt_context *)&s2tt_ctx,
1238 &s2tt[0U], level));
1239 }
1240}
1241
1242void s2tt_maps_assigned_ns_block_tc4(void)
1243{
1244 /***************************************************************
1245 * TEST CASE 4:
1246 *
1247 * Invoke s2tt_maps_assigned_ns_block() with the incorrect
1248 * level.
1249 ***************************************************************/
1250
1251 long level = s2tt_test_helpers_min_block_lvl();
1252 unsigned long s2tt[S2TTES_PER_S2TT];
1253 unsigned long attrs = s2tt_test_helpers_gen_ns_attrs(true, false);
1254 unsigned long pa;
1255 s2tt_context s2tt_ctx = { 0UL };
1256
1257 /*
1258 * Generate an s2tt context to be used for the test.
1259 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1260 * the rest of them can be uninitialized.
1261 */
1262 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1263
1264 /* Get a PA aligned only to 'level' */
1265 do {
1266 pa = s2tt_test_helpers_gen_addr(level, true);
1267
1268 } while (s2tte_is_addr_lvl_aligned((const struct s2tt_context *)&s2tt_ctx,
1269 pa, level - 1L));
1270
1271 /* Generate a valid table */
1272 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1273 &s2tt[0U], attrs, pa, level);
1274
1275 CHECK_FALSE(s2tt_maps_assigned_ns_block(
1276 (const struct s2tt_context *)&s2tt_ctx,
1277 &s2tt[0U], level));
1278}
1279
1280void s2tt_maps_assigned_ns_block_tc5(void)
1281{
1282 /***************************************************************
1283 * TEST CASE 5:
1284 *
1285 * Invoke s2tt_maps_assigned_ns_block() with a valid level
1286 * and a NULL table pointer.
1287 ***************************************************************/
1288
1289 long level = s2tt_test_helpers_min_block_lvl();
1290 s2tt_context s2tt_ctx = { 0UL };
1291
1292 /*
1293 * Generate an s2tt context to be used for the test.
1294 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1295 * the rest of them can be uninitialized.
1296 */
1297 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1298
1299 test_helpers_expect_assert_fail(true);
1300 (void)s2tt_maps_assigned_ns_block(
1301 (const struct s2tt_context *)&s2tt_ctx, NULL, level);
1302 test_helpers_fail_if_no_assert_failed();
1303}
1304
1305void s2tt_maps_assigned_ns_block_tc6(void)
1306{
1307 /***************************************************************
1308 * TEST CASE 6:
1309 *
1310 * Invoke s2tt_maps_assigned_ns_block() with a level above
1311 * the maximum allowed.
1312 ***************************************************************/
1313
1314 long level = S2TT_TEST_HELPERS_MAX_LVL;
1315 unsigned long s2tt[S2TTES_PER_S2TT];
1316 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1317 unsigned long attrs = s2tt_test_helpers_gen_ns_attrs(true, false);
1318 s2tt_context s2tt_ctx = { 0UL };
1319
1320 /*
1321 * Generate an s2tt context to be used for the test.
1322 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1323 * the rest of them can be uninitialized.
1324 */
1325 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1326
1327 /* Generate a valid table */
1328 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1329 &s2tt[0U], attrs, pa, level);
1330
1331 test_helpers_expect_assert_fail(true);
1332 (void)s2tt_maps_assigned_ram_block((const struct s2tt_context *)&s2tt_ctx,
1333 &s2tt[0U], level + 1UL);
1334 test_helpers_fail_if_no_assert_failed();
1335}
1336
1337void s2tt_maps_assigned_ns_block_tc7(void)
1338{
1339 /***************************************************************
1340 * TEST CASE 7:
1341 *
1342 * Invoke s2tt_maps_assigned_ram_block() with a level below
1343 * the minimum allowed.
1344 ***************************************************************/
1345
1346 long level = s2tt_test_helpers_min_block_lvl();
1347 unsigned long s2tt[S2TTES_PER_S2TT];
1348 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1349 unsigned long attrs = s2tt_test_helpers_gen_ns_attrs(true, false);
1350 s2tt_context s2tt_ctx = { 0UL };
1351
1352 /*
1353 * Generate an s2tt context to be used for the test.
1354 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1355 * the rest of them can be uninitialized.
1356 */
1357 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1358
1359 /* Generate a valid table */
1360 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1361 &s2tt[0U], attrs, pa, level);
1362
1363 level = s2tt_test_helpers_min_table_lvl() - 1L;
1364 test_helpers_expect_assert_fail(true);
1365 (void)s2tt_maps_assigned_ns_block((const struct s2tt_context *)&s2tt_ctx,
1366 &s2tt[0U], level);
1367 test_helpers_fail_if_no_assert_failed();
1368}
1369
1370void s2tt_maps_assigned_ns_block_tc8(void)
1371{
1372 /***************************************************************
1373 * TEST CASE 8:
1374 *
1375 * Invoke s2tt_maps_assigned_ram_block() with a NULL pointer to
1376 * s2tt_context structure.
1377 ***************************************************************/
1378
1379 long level = s2tt_test_helpers_min_block_lvl();
1380 unsigned long s2tt[S2TTES_PER_S2TT];
1381 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1382 unsigned long attrs = s2tt_test_helpers_gen_ns_attrs(true, false);
1383 s2tt_context s2tt_ctx = { 0UL };
1384
1385 /*
1386 * Generate an s2tt context to be used for the test.
1387 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1388 * the rest of them can be uninitialized.
1389 */
1390 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1391
1392 /* Generate a valid table */
1393 s2tt_init_assigned_ns((const struct s2tt_context *)&s2tt_ctx,
1394 &s2tt[0U], attrs, pa, level);
1395
1396 test_helpers_expect_assert_fail(true);
1397 (void)s2tt_maps_assigned_ns_block((const struct s2tt_context *)NULL,
1398 &s2tt[0U], level);
1399 test_helpers_fail_if_no_assert_failed();
1400}
1401
1402void s2tt_maps_assigned_destroyed_block_tc1(void)
1403{
1404 /***************************************************************
1405 * TEST CASE 1:
1406 *
1407 * For each valid level, create an assigned destroyed block and
1408 * validate that s2tt_maps_assigned_destroyed_block() returns
1409 * the expected value
1410 ***************************************************************/
1411
1412 s2tt_context s2tt_ctx = { 0UL };
1413
1414 /*
1415 * Generate an s2tt context to be used for the test.
1416 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1417 * the rest of them can be uninitialized.
1418 */
1419 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1420
1421 for (long level = s2tt_test_helpers_min_block_lvl();
1422 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
1423
1424 unsigned long s2tt[S2TTES_PER_S2TT];
1425 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1426
1427 /* Generate the table */
1428 s2tt_init_assigned_destroyed(
1429 (const struct s2tt_context *)&s2tt_ctx,
1430 &s2tt[0U], pa, level);
1431
1432 CHECK_TRUE(s2tt_maps_assigned_destroyed_block(
1433 (const struct s2tt_context *)&s2tt_ctx,
1434 &s2tt[0U], level));
1435 }
1436}
1437
1438void s2tt_maps_assigned_destroyed_block_tc2(void)
1439{
1440 /***************************************************************
1441 * TEST CASE 2:
1442 *
1443 * For each valid level, create an assigned destroyed block and
1444 * then change a random TTE to a different type to validate
1445 * that s2tt_maps_assigned_destroyed_block() returns the
1446 * expected value
1447 ***************************************************************/
1448
1449 unsigned long unassigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
1450 S2TTE_INVALID_RIPAS_RAM,
1451 S2TTE_NS,
1452 S2TTE_INVALID_RIPAS_DESTROYED};
1453 unsigned long assigned_ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
1454 S2TTE_NS,
1455 S2TTE_INVALID_RIPAS_RAM};
1456 s2tt_context s2tt_ctx = { 0UL };
1457
1458 /*
1459 * Generate an s2tt context to be used for the test.
1460 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1461 * the rest of them can be uninitialized.
1462 */
1463 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1464
1465 for (long level = s2tt_test_helpers_min_block_lvl();
1466 level <= S2TT_TEST_HELPERS_MAX_TABLE_LVL; level++) {
1467
1468 unsigned int tte_idx =
1469 (unsigned int)test_helpers_get_rand_in_range(0UL,
1470 S2TTES_PER_S2TT - 1UL);
1471 /* pickup a random type of unassigned S2TTE to test with */
1472 unsigned int idx =
1473 (unsigned int)test_helpers_get_rand_in_range(0UL,
1474 ARRAY_SIZE(unassigned_ripas) - 1UL);
1475 unsigned long s2tt[S2TTES_PER_S2TT];
1476 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1477
1478 /* Generate the table */
1479 s2tt_init_assigned_destroyed(
1480 (const struct s2tt_context *)&s2tt_ctx,
1481 &s2tt[0U], pa, level);
1482
1483 /* Alter a random S2TTE on the table */
1484 s2tt[tte_idx] = s2tt_test_create_unassigned(
1485 (const struct s2tt_context *)&s2tt_ctx,
1486 unassigned_ripas[idx]);
1487 CHECK_FALSE(s2tt_maps_assigned_destroyed_block(
1488 (const struct s2tt_context *)&s2tt_ctx,
1489 &s2tt[0U], level));
1490
1491 /* pickup a random type of assigned S2TTE to test with */
1492 idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
1493 ARRAY_SIZE(assigned_ripas) - 1UL);
1494
1495 /* Alter a random S2TTE on the table */
1496 s2tt[tte_idx] = s2tt_test_create_assigned(
1497 (const struct s2tt_context *)&s2tt_ctx,
1498 pa, level, assigned_ripas[idx]);
1499 CHECK_FALSE(s2tt_maps_assigned_destroyed_block(
1500 (const struct s2tt_context *)&s2tt_ctx,
1501 &s2tt[0U], level));
1502 }
1503}
1504
1505void s2tt_maps_assigned_destroyed_block_tc3(void)
1506{
1507 /***************************************************************
1508 * TEST CASE 3:
1509 *
1510 * Invoke s2tt_maps_assigned_destroyed_block() with the
1511 * incorrect level.
1512 ***************************************************************/
1513
1514 long level = s2tt_test_helpers_min_block_lvl();
1515 unsigned long s2tt[S2TTES_PER_S2TT];
1516 unsigned long pa;
1517 s2tt_context s2tt_ctx = { 0UL };
1518
1519 /*
1520 * Generate an s2tt context to be used for the test.
1521 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1522 * the rest of them can be uninitialized.
1523 */
1524 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1525
1526 /*
1527 * Get a PA aligned only to 'level' - 1 so we can spawn a table
1528 * at level 'level' starting on that PA.
1529 */
1530 pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1531
1532 /* Generate a valid table */
1533 s2tt_init_assigned_destroyed((const struct s2tt_context *)&s2tt_ctx,
1534 &s2tt[0U], pa, level);
1535
1536 CHECK_FALSE(s2tt_maps_assigned_destroyed_block(
1537 (const struct s2tt_context *)&s2tt_ctx,
1538 &s2tt[0U], level + 1L));
1539}
1540
1541void s2tt_maps_assigned_destroyed_block_tc4(void)
1542{
1543 /***************************************************************
1544 * TEST CASE 4:
1545 *
1546 * Invoke s2tt_maps_assigned_destroyed_block() with a valid
1547 * level and a NULL table pointer.
1548 ***************************************************************/
1549
1550 long level = s2tt_test_helpers_min_block_lvl();
1551 s2tt_context s2tt_ctx = { 0UL };
1552
1553 /*
1554 * Generate an s2tt context to be used for the test.
1555 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1556 * the rest of them can be uninitialized.
1557 */
1558 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1559
1560 test_helpers_expect_assert_fail(true);
1561 (void)s2tt_maps_assigned_destroyed_block((
1562 const struct s2tt_context *)&s2tt_ctx,
1563 NULL, level);
1564 test_helpers_fail_if_no_assert_failed();
1565}
1566
1567void s2tt_maps_assigned_destroyed_block_tc5(void)
1568{
1569 /***************************************************************
1570 * TEST CASE 5:
1571 *
1572 * Invoke s2tt_maps_assigned_destroyed_block() with a level
1573 * above the maximum allowed.
1574 ***************************************************************/
1575
1576 long level = S2TT_TEST_HELPERS_MAX_LVL;
1577 unsigned long s2tt[S2TTES_PER_S2TT];
1578 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1579 s2tt_context s2tt_ctx = { 0UL };
1580
1581 /*
1582 * Generate an s2tt context to be used for the test.
1583 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1584 * the rest of them can be uninitialized.
1585 */
1586 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1587
1588 /* Generate a valid table */
1589 s2tt_init_assigned_destroyed((const struct s2tt_context *)&s2tt_ctx,
1590 &s2tt[0U], pa, level);
1591
1592 test_helpers_expect_assert_fail(true);
1593 (void)s2tt_maps_assigned_destroyed_block(
1594 (const struct s2tt_context *)&s2tt_ctx,
1595 &s2tt[0U], level + 1L);
1596 test_helpers_fail_if_no_assert_failed();
1597}
1598
1599void s2tt_maps_assigned_destroyed_block_tc6(void)
1600{
1601 /***************************************************************
1602 * TEST CASE 6:
1603 *
1604 * Invoke s2tt_maps_assigned_destroyed_block() with a level
1605 * below the minimum allowed.
1606 ***************************************************************/
1607
1608 long level = s2tt_test_helpers_min_block_lvl();
1609 unsigned long s2tt[S2TTES_PER_S2TT];
1610 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1611 s2tt_context s2tt_ctx = { 0UL };
1612
1613 /*
1614 * Generate an s2tt context to be used for the test.
1615 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1616 * the rest of them can be uninitialized.
1617 */
1618 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1619
1620 /* Generate a valid table */
1621 s2tt_init_assigned_destroyed((const struct s2tt_context *)&s2tt_ctx,
1622 &s2tt[0U], pa, level);
1623
1624 test_helpers_expect_assert_fail(true);
1625 level = s2tt_test_helpers_min_table_lvl() - 1L;
1626 (void)s2tt_maps_assigned_destroyed_block(
1627 (const struct s2tt_context *)&s2tt_ctx,
1628 &s2tt[0U], level);
1629 test_helpers_fail_if_no_assert_failed();
1630}
1631
1632void s2tt_maps_assigned_destroyed_block_tc7(void)
1633{
1634 /***************************************************************
1635 * TEST CASE 7:
1636 *
1637 * Invoke s2tt_maps_assigned_destroyed_block() with a NULL
1638 * pointer to a s2tt_context structure.
1639 ***************************************************************/
1640
1641 long level = s2tt_test_helpers_min_block_lvl();
1642 unsigned long s2tt[S2TTES_PER_S2TT];
1643 unsigned long pa = s2tt_test_helpers_gen_addr(level - 1L, true);
1644 s2tt_context s2tt_ctx = { 0UL };
1645
1646 /*
1647 * Generate an s2tt context to be used for the test.
1648 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1649 * the rest of them can be uninitialized.
1650 */
1651 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1652
1653 /* Generate a valid table */
1654 s2tt_init_assigned_destroyed((const struct s2tt_context *)&s2tt_ctx,
1655 &s2tt[0U], pa, level);
1656
1657 test_helpers_expect_assert_fail(true);
1658 (void)s2tt_maps_assigned_destroyed_block(
1659 (const struct s2tt_context *)NULL,
1660 &s2tt[0U], level);
1661 test_helpers_fail_if_no_assert_failed();
1662}
1663
1664/*
1665 * Ancillary function to generate a test input to test
1666 * s2tt_skip_non_live_entries(). The only input required to this function
1667 * is @wi.index. The rest are output values.
1668 *
1669 * - Arguments:
1670 * iter: Iteration number.
1671 * 0: generate a live S2TTE at index > wi.index,
1672 * 1: generate a live S2TTE at index at wi.index,
1673 * 2: generate a live S2TTE at index < wi.index.
1674 * wi: The s2tt_walk structure to pass to
1675 * s2tt_skip_non_live_entries(). Other than wi.level, all
1676 * other fieds are setup by this helper.
1677 * tte_idx: tte index where the live entry is generated.
1678 * entry_ipa: the aligned IPA corresponding to the entry
1679 * at `table_ipa[tte_idx]`
1680 * ipa: An unaligned IPA belonging to the block/page
1681 * pointed by the entry at `table_ipa[wi.index]`.
1682 *
1683 * - Returns: The expected ipa that should be returned by
1684 * s2tt_skip_non_live_entries() as per the test input.
1685 */
1686static unsigned long skip_non_live_entries_gen_ipas(unsigned int iter,
1687 struct s2tt_walk *wi,
1688 unsigned int *tte_idx,
1689 unsigned long *entry_ipa,
1690 unsigned long *ipa)
1691{
1692 long level = wi->last_level;
1693 unsigned long table_ipa, next_stt_ipa;
1694
1695 /*
1696 * Initialize wi.index somewhere in the middle of the table.
1697 * Note that level -1 has only 16 entries.
1698 */
1699 if (level == S2TT_TEST_HELPERS_MIN_LVL_LPA2) {
1700 wi->index = test_helpers_get_rand_in_range(5UL, 10UL);
1701 } else {
1702 wi->index = test_helpers_get_rand_in_range(100UL, 200UL);
1703 }
1704
1705 switch (iter) {
1706 case 0U:
1707 /* Get a random index > wi.index */
1708 *tte_idx =
1709 (unsigned int)test_helpers_get_rand_in_range(
1710 wi->index + 1UL, S2TTES_PER_S2TT - 1UL);
1711 break;
1712 case 1U:
1713 /* Test index will be wi.index */
1714 *tte_idx = wi->index;
1715 break;
1716 case 2U:
1717 /* Get a random index < wi.index */
1718 *tte_idx = (unsigned int)test_helpers_get_rand_in_range(
1719 0UL, wi->index - 1UL);
1720 break;
1721 default:
1722 /* Not allowed */
1723 assert(false);
1724 }
1725
1726 /*
1727 * Get an IPA aligned @level - 1, so we would have a table
1728 * @level starting at such IPA.
1729 */
1730 table_ipa = s2tt_test_helpers_gen_addr(level - 1L, true);
1731
1732 /*
1733 * Calculate the IPA of the entry on the table
1734 * indexed by tte_idx.
1735 */
1736 *entry_ipa = table_ipa + (s2tte_map_size(level) * (*tte_idx));
1737
1738 /* Calculate the IPA for the next table */
1739 next_stt_ipa = table_ipa + (s2tte_map_size(level) * S2TTES_PER_S2TT);
1740
1741 /* Calculate a non-aligned valid IPA at wi.index used to test */
1742
1743 *ipa = table_ipa + (s2tte_map_size(level) * wi->index) +
1744 test_helpers_get_rand_in_range(1UL,
1745 s2tte_map_size(level) - 1UL);
1746
1747 /*
1748 * Depending on `iter`, the expected address returned by
1749 * s2tt_skip_non_live_entries() will be:
1750 *
1751 * - When 'iter' == 0: *entry_ipa
1752 * - When 'iter' == 1: *ipa
1753 * - When 'iter' == 2: The IPA of the next s2tt (next_stt_ipa)
1754 */
1755 return ((iter == 0U) ? *entry_ipa :
1756 ((iter == 1U) ? *ipa : next_stt_ipa));
1757}
1758
1759void s2tt_skip_non_live_entries_tc1(void)
1760{
1761 /***************************************************************
1762 * TEST CASE 1:
1763 *
1764 * For every valid level, generate a set of tests for
1765 * s2tt_skip_non_live_entries():
1766 * - Test with an unassigned entry/table with a live
1767 * entry > wi.index.
1768 * - Test with an unassigned entry/table with the entry
1769 * at wi.index being live.
1770 * - Test with an unassigned entry/table with a random
1771 * live entry at a random index < wi.index.
1772 * - Test with an unassigned entry/table with no live
1773 * entries.
1774 ***************************************************************/
1775
1776 unsigned long ripas[] = {S2TTE_INVALID_RIPAS_EMPTY,
1777 S2TTE_NS,
1778 S2TTE_INVALID_RIPAS_RAM,
1779 S2TTE_INVALID_RIPAS_DESTROYED};
1780
1781 init_unassigned_cb init_unassigned_cbs[] = {
1782 s2tt_init_unassigned_empty,
1783 s2tt_init_unassigned_ns,
1784 s2tt_init_unassigned_ram,
1785 s2tt_init_unassigned_destroyed
1786 };
1787 s2tt_context s2tt_ctx = { 0UL };
1788
1789 /*
1790 * Generate an s2tt context to be used for the test.
1791 * only s2tt_ctx.enable_lpa2 is of use on this API, so
1792 * the rest of them can be uninitialized.
1793 */
1794 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1795
1796 for (long level = s2tt_test_helpers_min_table_lvl();
1797 level <= S2TT_TEST_HELPERS_MAX_LVL; level++) {
1798
1799 unsigned long entry_ipa, ret_ipa, expected_ipa, ipa;
1800 unsigned long s2tt[S2TTES_PER_S2TT];
1801 unsigned int tte_idx, cb_idx = 0U;
1802 struct s2tt_walk wi = {
1803 NULL, /* Not needed */
1804 0UL,
1805 level};
1806
1807 for (unsigned int i = 0U; i < 3U; i++) {
1808
1809 expected_ipa = skip_non_live_entries_gen_ipas(
1810 i, &wi, &tte_idx, &entry_ipa, &ipa);
1811
1812 if (level < s2tt_test_helpers_min_block_lvl()) {
1813 /* Table */
1814
1815 /*
1816 * Clear the s2tt so there are no valid
1817 * table entries
1818 */
1819 (void)memset((void *)&s2tt[0], 0, sizeof(s2tt));
1820
1821 /* Generate a live entry at the random index */
1822 s2tt[tte_idx] =
1823 s2tte_create_table(
1824 (const struct s2tt_context *)&s2tt_ctx,
1825 entry_ipa, level);
1826 } else {
1827 /* Block or page */
1828
1829 /*
1830 * Generate an unassigned table of a random
1831 * RIPAS type and add an assigned entry of a
1832 * random RIPAS type at the random index.
1833 */
1834 cb_idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
1835 ARRAY_SIZE(init_unassigned_cbs) - 1UL);
1836 init_unassigned_cbs[cb_idx](
1837 (const struct s2tt_context *)&s2tt_ctx,
1838 &s2tt[0U]);
1839
1840 cb_idx = (unsigned int)test_helpers_get_rand_in_range(0UL,
1841 ARRAY_SIZE(ripas) - 1UL);
1842 s2tt[tte_idx] =
1843 s2tt_test_create_assigned(
1844 (const struct s2tt_context *)&s2tt_ctx,
1845 entry_ipa, level, ripas[cb_idx]);
1846 }
1847
1848 /* Validate s2tt_skip_non_live_entries() with current params */
1849 ret_ipa = s2tt_skip_non_live_entries(
1850 (const struct s2tt_context *)&s2tt_ctx,
1851 ipa, &s2tt[0U], &wi);
1852 CHECK_TRUE(expected_ipa == ret_ipa);
1853 } /* TEST ID */
1854
1855 /*
1856 * Test with a table without live entries. By recycling the
1857 * arguments from the last test when `iter` == 2, we should
1858 * also get the same results.
1859 */
1860 if (level < s2tt_test_helpers_min_block_lvl()) {
1861 /* Table */
1862 (void)memset((void *)&s2tt[0], 0, sizeof(s2tt));
1863 } else {
1864 /* Block or Page */
1865 init_unassigned_cbs[cb_idx](
1866 (const struct s2tt_context *)&s2tt_ctx, &s2tt[0U]);
1867 }
1868
1869 /* Validate s2tt_skip_non_live_entries() with current params */
1870 ret_ipa = s2tt_skip_non_live_entries(
1871 (const struct s2tt_context *)&s2tt_ctx,
1872 ipa, &s2tt[0U], &wi);
1873 UNSIGNED_LONGS_EQUAL(expected_ipa, ret_ipa);
1874 } /* LEVEL */
1875}
1876
1877void s2tt_skip_non_live_entries_tc2(void)
1878{
1879 /***************************************************************
1880 * TEST CASE 2:
1881 *
1882 * Call s2tt_skip_non_live_entries() with a NULL s2tt pointer.
1883 ***************************************************************/
1884
1885 struct s2tt_context s2tt_ctx = { 0UL };
1886 struct s2tt_walk wi = {
1887 NULL, /* Not needed */
1888 0UL,
1889 0UL};
1890
1891 /*
1892 * Generate an s2tt context to be used for the test. Only
1893 * enable_lpa2 field is needed for the current test.
1894 */
1895 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1896
1897 test_helpers_expect_assert_fail(true);
1898 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)&s2tt_ctx,
1899 0UL, NULL, &wi);
1900 test_helpers_fail_if_no_assert_failed();
1901}
1902
1903void s2tt_skip_non_live_entries_tc3(void)
1904{
1905 /***************************************************************
1906 * TEST CASE 3:
1907 *
1908 * Call s2tt_skip_non_live_entries() with a NULL s2tt_walk struct
1909 * pointer.
1910 ***************************************************************/
1911
1912 unsigned long s2tt[S2TTES_PER_S2TT];
1913 struct s2tt_context s2tt_ctx = { 0UL };
1914
1915 /*
1916 * Generate an s2tt context to be used for the test. Only
1917 * enable_lpa2 field is needed for the current test.
1918 */
1919 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1920
1921 test_helpers_expect_assert_fail(true);
1922 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)&s2tt_ctx,
1923 0UL, &s2tt[0U], NULL);
1924 test_helpers_fail_if_no_assert_failed();
1925}
1926
1927void s2tt_skip_non_live_entries_tc4(void)
1928{
1929 /***************************************************************
1930 * TEST CASE 4:
1931 *
1932 * Call s2tt_skip_non_live_entries() with a s2tt_walk struct in
1933 * which the level is below the minimum allowed.
1934 ***************************************************************/
1935
1936 unsigned long s2tt[S2TTES_PER_S2TT];
1937 struct s2tt_context s2tt_ctx = { 0UL };
1938 struct s2tt_walk wi = {
1939 NULL, /* Not needed */
1940 0UL,
1941 s2tt_test_helpers_min_table_lvl() - 1U};
1942
1943 /*
1944 * Generate an s2tt context to be used for the test. Only
1945 * enable_lpa2 field is needed for the current test.
1946 */
1947 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1948 test_helpers_expect_assert_fail(true);
1949 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)&s2tt_ctx,
1950 0UL, &s2tt[0U], &wi);
1951 test_helpers_fail_if_no_assert_failed();
1952}
1953
1954void s2tt_skip_non_live_entries_tc5(void)
1955{
1956 /***************************************************************
1957 * TEST CASE 5:
1958 *
1959 * Call s2tt_skip_non_live_entries() with a s2tt_walk struct in
1960 * which the level is above the maximum allowed.
1961 ***************************************************************/
1962
1963 unsigned long s2tt[S2TTES_PER_S2TT];
1964 struct s2tt_context s2tt_ctx = { 0UL };
1965 struct s2tt_walk wi = {
1966 NULL, /* Not needed */
1967 0UL,
1968 S2TT_TEST_HELPERS_MAX_LVL + 1U};
1969
1970 /*
1971 * Generate an s2tt context to be used for the test. Only
1972 * enable_lpa2 field is needed for the current test.
1973 */
1974 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
1975 test_helpers_expect_assert_fail(true);
1976 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)&s2tt_ctx,
1977 0UL, &s2tt[0U], &wi);
1978 test_helpers_fail_if_no_assert_failed();
1979}
1980
1981void s2tt_skip_non_live_entries_tc6(void)
1982{
1983 /***************************************************************
1984 * TEST CASE 6:
1985 *
1986 * Call s2tt_skip_non_live_entries() with a s2tt_walk struct in
1987 * which the index is above the maximum permitted
1988 ***************************************************************/
1989
1990 unsigned long s2tt[S2TTES_PER_S2TT];
1991 struct s2tt_context s2tt_ctx = { 0UL };
1992 struct s2tt_walk wi = {
1993 NULL, /* Not needed */
1994 S2TTES_PER_S2TT + 1UL,
1995 s2tt_test_helpers_min_table_lvl()};
1996
1997 /*
1998 * Generate an s2tt context to be used for the test. Only
1999 * enable_lpa2 field is needed for the current test.
2000 */
2001 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2002 test_helpers_expect_assert_fail(true);
2003 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)&s2tt_ctx,
2004 0UL, &s2tt[0U], &wi);
2005 test_helpers_fail_if_no_assert_failed();
2006}
2007
2008void s2tt_skip_non_live_entries_tc7(void)
2009{
2010 /***************************************************************
2011 * TEST CASE 7:
2012 *
2013 * Call s2tt_skip_non_live_entries() with a NULL pointer to
2014 * s2tt_context structure.
2015 ***************************************************************/
2016
2017 unsigned long s2tt[S2TTES_PER_S2TT];
2018 struct s2tt_walk wi = {
2019 NULL, /* Not needed */
2020 0UL,
2021 s2tt_test_helpers_min_table_lvl()};
2022
2023 test_helpers_expect_assert_fail(true);
2024 (void)s2tt_skip_non_live_entries((const struct s2tt_context *)NULL,
2025 0UL, &s2tt[0U], &wi);
2026 test_helpers_fail_if_no_assert_failed();
2027}
2028
2029/*
2030 * Ancillary function to populate a set of S2 translation tables given an IPA.
2031 * It generates a set of concatenated tables starting at SL + 1.
2032 *
2033 * Arguments:
2034 * - ipa: IPA mapped to the translation table. It is the caller
2035 * responsibility to ensure that the index at SL of the
2036 * table walk does not exceed S2TTE_MAX_CONCAT_TABLES.
2037 * - tt_walk_idx: An array of indexes to the tables in tt_walk[] used
2038 * to walk the tables.
2039 * - tt_walk: An array of tt base addresses for each level which will be
2040 * used to walk the tables.
2041 * - end_lvl: Level at which the walk would finish.
2042 * - tt_granules: Array to store the struct granule pointers corresponding
2043 * to tt_walk[] entries.
2044 * - val_tt_granule: The expected struct granule* of the S2TT at the end of
2045 * test function.
2046 *
2047 * This function creates a set of S2TTE_MAX_CONCAT_TABLES at the level after
2048 * the starting one (sl), which is sl+1. The `ipa` argument is such that the
2049 * translation table hierarchy at sl+1 level will be within the
2050 * S2TTE_MAX_CONCAT_TABLES. This allows the caller to test concatenated tables
2051 * by using thranslaton tables hierarchy at sl+1 level as the start level to
2052 * the test function. As an example, the layout of an array of adjacent granules
2053 * which will be used to create a translation table hierarchy starting from
2054 * level 0 to level 3 would be as follows:
2055 *
2056 * --------------------------
2057 * granule_base | Level -1 S2TT | (Unused in this example)
2058 * --------------------------
2059 * | Level 0 S2TT |
2060 * -------------------------- ---
2061 * | 1st Level 1 S2TT | \
2062 * -------------------------- \
2063 * | 2nd Level 1 S2TT | \
2064 * -------------------------- \
2065 * | (...) | | Concatenated tables
2066 * -------------------------- /
2067 * | 15th Level 1 S2TT | /
2068 * -------------------------- /
2069 * | 16th Level 1 S2T | /
2070 * -------------------------- ---
2071 * | Level 2 S2TT |
2072 * --------------------------
2073 * | Level 3 S2TT |
2074 * --------------------------
2075 *
2076 * It is the caller responsibility to ensure that all the arrays passed to this
2077 * function are sized correctly.
2078 *
2079 * Also note that when FEAT_LPA2 is available, the architectural minimum start
2080 * level supported by stage 2 lookup will be '-1', therefore an offset of one
2081 * will be added to all the indexes used to index the tt_walk* arrays to offset
2082 * the negative value. For simplicity, the offset will be applied even when
2083 * FEAT_LPA2 is not available (SL == 0).
2084 */
2085static void populate_s2tts(struct s2tt_context *s2tt_ctx,
2086 unsigned long ipa, unsigned long *tt_walk_idx,
2087 unsigned long *tt_walk, long end_lvl,
2088 struct granule **tt_granules,
2089 struct granule **val_tt_granule)
2090{
2091 long sl = s2tt_test_helpers_min_table_lvl();
2092 unsigned int next_granule;
2093 unsigned long current_table;
2094 unsigned long *table;
2095 unsigned long *parent_table;
2096 long level;
2097 unsigned long granule_base = host_util_get_granule_base();
2098 struct granule *str_granule_base = test_helpers_granule_struct_base();
2099 unsigned int n_granules = S2TTE_MAX_CONCAT_TABLES +
2100 (S2TT_TEST_HELPERS_MAX_LVL -
2101 S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2102
2103 /* Initialize the granules for the translaton tables */
2104 for (unsigned int i = 0U; i < n_granules; i++) {
2105 tt_granules[i] = str_granule_base + i;
2106 s2tt_test_granule_set_state(tt_granules[i], GRANULE_STATE_RTT);
2107 s2tt_test_granule_set_lock(tt_granules[i], false);
2108 };
2109
2110 /* Root granule must be locked. */
2111 s2tt_test_granule_set_lock(tt_granules[sl + 1L], true);
2112
2113 /*
2114 * Initialize the index for the root granule. Note that SL can be -1
2115 */
2116 next_granule = sl + 1L;
2117
2118 /* Iterate over all the levels and generate the translatation tables */
2119 for (level = sl; level <= end_lvl; level++) {
2120 tt_walk_idx[level + 1L] =
2121 s2tt_test_helpers_get_idx_from_addr(ipa, level);
2122
2123 if (level == sl) {
2124 /*
2125 * Start Level. Get and initialize a table
2126 * for this level.
2127 */
2128 tt_walk[level + 1L] = (granule_base +
2129 (GRANULE_SIZE * next_granule++));
2130 table = (unsigned long *)tt_walk[level + 1L];
2131 (void)memset((void *)table, 0, GRANULE_SIZE);
2132 } else if (level == sl + 1L) {
2133 /*
2134 * Level after the SL. This level will include the
2135 * set of concatenated tables.
2136 */
2137 parent_table = (unsigned long *)tt_walk[level];
2138
2139 /*
2140 * Create the set of S2TTE_MAX_CONCAT_TABLES
2141 * concatenated tables and populate each entry of the
2142 * parent table (at level SL) to point to them.
2143 */
2144 for (unsigned int i = 0U;
2145 i < S2TTE_MAX_CONCAT_TABLES; i++) {
2146 unsigned long concat_table = (granule_base +
2147 (GRANULE_SIZE * next_granule++));
2148 parent_table[i] =
2149 s2tte_create_table(
2150 (const struct s2tt_context *)s2tt_ctx,
2151 concat_table, level);
2152
2153 /* Clean this level tables */
2154 (void)memset((void *)concat_table, 0, GRANULE_SIZE);
2155 }
2156
2157 /*
2158 * Now there are S2TTE_MAX_CONCAT_TABLES concatenated
2159 * tables on this level, of which only one will be used
2160 * during the table walk. Find that table and assign it
2161 * to the current level of tt_walk[].
2162 */
2163 tt_walk[level + 1L] = (granule_base +
2164 ((sl + 2 + tt_walk_idx[level]) * GRANULE_SIZE));
2165 } else if (level < S2TT_TEST_HELPERS_MAX_LVL) {
2166 /*
2167 * Tables between the start level + 1 and the
2168 * page level.
2169 */
2170 parent_table = (unsigned long *)tt_walk[level];
2171
2172 /* Get, store and initialize the table on this level */
2173 current_table = (granule_base +
2174 (GRANULE_SIZE * next_granule++));
2175 tt_walk[level + 1L] = current_table;
2176 (void)memset((void *)current_table, 0, GRANULE_SIZE);
2177
2178 /* And assign the table to the current level of tt_walk[] */
2179 parent_table[tt_walk_idx[level]] =
2180 s2tte_create_table(
2181 (const struct s2tt_context *)s2tt_ctx,
2182 current_table, level - 1L);
2183 } else {
2184 /* Page Level */
2185 parent_table = (unsigned long *)tt_walk[level];
2186
2187 /* Get, store and initialize the table on this level */
2188 current_table = (granule_base +
2189 (GRANULE_SIZE * next_granule++));
2190 tt_walk[level + 1L] = current_table;
2191
2192 /*
2193 * Initialize the table as a L3 table.
2194 * We initialize as assigned-ram for no particular
2195 * reason using the IPA as PA.
2196 */
2197 table = (unsigned long *)current_table;
2198 s2tt_init_assigned_ram((const struct s2tt_context *)s2tt_ctx,
2199 table, (ipa & s2tt_test_helpers_lvl_mask(level)), level);
2200
2201 /* And assign the table to the current level of tt_walk[] */
2202 parent_table[tt_walk_idx[level]] =
2203 s2tte_create_table(
2204 (const struct s2tt_context *)s2tt_ctx,
2205 current_table, level - 1L);
2206 }
2207 }
2208
2209 /* Generate the expected validation granule */
2210 *val_tt_granule = addr_to_granule(tt_walk[end_lvl + 1]);
2211}
2212
2213void s2tt_walk_lock_unlock_tc1(void)
2214{
2215 /***************************************************************
2216 * TEST CASE 1:
2217 *
2218 * Several positive tests:
2219 * - 1a) Generate a random mapping starting at the minimum
2220 * possible level up to the maximum one and use
2221 * s2tt_walk_lock_unlock() to walk the translation
2222 * table and validate its output.
2223 * - 1b) Repeat the test above, but starting the walk at
2224 * (SL + 1) so as to test the concatenated tables support.
2225 * - 2a & 2b) Repeat the two tests above, but finalising the
2226 * walk at a level below the maximum one.
2227 * - 3a & 3b) Repeat the first two tests, but completing the
2228 * tables up to a level below the maximum one and calling
2229 * s2tt_walk_lock_unlock() with a level above the last
2230 * one mapped on the translation tables.
2231 *
2232 * The level after the starting one will have
2233 * S2TTE_MAX_CONCAT_TABLES concatenated granules so to test the
2234 * concatenated starting levels.
2235 ***************************************************************/
2236
2237 long sl = s2tt_test_helpers_min_table_lvl();
2238 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2239 unsigned long pa, sl_index;
2240 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2241 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2242 struct s2tt_walk wi;
2243 struct granule *val_tt_granule;
2244 struct s2tt_context s2tt_ctx = { 0UL };
2245
2246 /* Total number of granules, included the concatenated ones */
2247 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
2248 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2249
2250 /*
2251 * Granules to hold the translation tables,
2252 * including concatenated ones.
2253 */
2254 struct granule *g_tables[granules];
2255
2256 /*
2257 * Generate a random address that spans across the whole IPA size
2258 * but whose walk index at SL + 1 is within
2259 * S2TTE_MAX_CONCAT_TABLES range so the address can also be used to
2260 * test concatenated root table support.
2261 *
2262 * The address doesn't need to have any alignment.
2263 */
2264 do {
2265 pa = test_helpers_get_rand_in_range(1UL,
2266 (1UL << arch_feat_get_pa_width()) - 1UL);
2267 sl_index = s2tt_test_helpers_get_idx_from_addr(pa, sl);
2268 } while (sl_index >= S2TTE_MAX_CONCAT_TABLES);
2269
2270 /* Generate an s2tt context to be used for the test */
2271 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2272
2273 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2274 end_level, &g_tables[0U], &val_tt_granule);
2275
2276 /* Finish the creation of the s2tt_context */
2277 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2278 s2tt_ctx.s2_starting_level = sl;
2279 s2tt_ctx.g_rtt = g_tables[sl + 1UL];
2280 s2tt_ctx.num_root_rtts = 1U;
2281
2282 /*
2283 * Invoke s2tt_walk_lock_unlock() with the generated translation tables
2284 *
2285 * (Test 1a)
2286 */
2287 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2288 pa, end_level, &wi);
2289
2290 LONGS_EQUAL(end_level, wi.last_level);
2291 CHECK_TRUE(val_tt_granule == wi.g_llt);
2292 UNSIGNED_LONGS_EQUAL(tt_walk_idx[end_level + 1U], wi.index);
2293
2294 for (unsigned int i = sl + 1U; i < granules; i++) {
2295 if (g_tables[i] == wi.g_llt) {
2296 /* Granule must be locked */
2297 CHECK_TRUE(LOCKED(wi.g_llt));
2298 } else {
2299 /* Granule must be unlocked */
2300 CHECK_FALSE(LOCKED(g_tables[i]));
2301 }
2302 }
2303
2304 /*
2305 * Repeat the test, but this time starting from the next level after
2306 * the starting one, so we can test the concatenated tables.
2307 *
2308 * (Test 1b)
2309 */
2310 (void)memset(&wi, 0, sizeof(wi));
2311
2312 /* Initialize the granules for the translaton tables */
2313 for (unsigned int i = 0U; i < granules; i++) {
2314 s2tt_test_granule_set_lock(g_tables[i], false);
2315 };
2316
2317 /*
2318 * Root granule must be locked. In this case, the root granule is
2319 * the granule after the minimum level plus one.
2320 */
2321 s2tt_test_granule_set_lock(g_tables[sl + 2], true);
2322
2323 /*
2324 * Invoke s2tt_walk_lock_unlock() with the generated translation tables
2325 * starting on the next starting level.
2326 */
2327 s2tt_ctx.s2_starting_level = sl + 1L;
2328 s2tt_ctx.g_rtt = g_tables[sl + 2UL];
2329 s2tt_ctx.num_root_rtts = S2TTE_MAX_CONCAT_TABLES;
2330
2331 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2332 pa, end_level, &wi);
2333
2334 LONGS_EQUAL(end_level, wi.last_level);
2335 CHECK_TRUE(val_tt_granule == wi.g_llt);
2336 LONGS_EQUAL(tt_walk_idx[end_level + 1U], wi.index);
2337
2338 for (unsigned int i = sl + 1U; i < granules; i++) {
2339 if (g_tables[i] == wi.g_llt) {
2340 /* Granule must be locked */
2341 CHECK_TRUE(LOCKED(wi.g_llt));
2342 } else {
2343 /* Granule must be unlocked */
2344 CHECK_FALSE(LOCKED(g_tables[i]));
2345 }
2346 }
2347
2348 /*
2349 * Repeat both the tests above, but this time finalizing the walk
2350 * a level below the maximum one. Reuse the structures initialized
2351 * on the test before.
2352 *
2353 * (Test 2a & 2b)
2354 */
2355 (void)memset(&wi, 0, sizeof(wi));
2356
2357 /* Initialize the granules for the translaton tables */
2358 for (unsigned int i = 0U; i < granules; i++) {
2359 s2tt_test_granule_set_lock(g_tables[i], false);
2360 };
2361
2362 /* Root granule must be locked */
2363 s2tt_test_granule_set_lock(g_tables[sl + 1], true);
2364
2365 s2tt_ctx.s2_starting_level = sl;
2366 s2tt_ctx.g_rtt = g_tables[sl + 1UL];
2367 s2tt_ctx.num_root_rtts = 1U;
2368
2369 /*
2370 * Update the expected end_level and validation granule
2371 *
2372 * (Test 2a)
2373 */
2374 end_level = S2TT_TEST_HELPERS_MAX_LVL - 1U;
2375 val_tt_granule = addr_to_granule(tt_walk[end_level + 1U]);
2376
2377 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2378 pa, end_level, &wi);
2379
2380 LONGS_EQUAL(end_level, wi.last_level);
2381 CHECK_TRUE(val_tt_granule == wi.g_llt);
2382 LONGS_EQUAL(tt_walk_idx[end_level + 1U], wi.index);
2383
2384 for (unsigned int i = sl + 1U; i < granules; i++) {
2385 if (g_tables[i] == wi.g_llt) {
2386 /* Granule must be locked */
2387 CHECK_TRUE(LOCKED(wi.g_llt));
2388 } else {
2389 /* Granule must be unlocked */
2390 CHECK_FALSE(LOCKED(g_tables[i]));
2391 }
2392 }
2393
2394 /*
2395 * Repeat the test, but this time starting from the next level after
2396 * the starting one, so we can test the concatenated tables.
2397 *
2398 * (Test 2b)
2399 */
2400 (void)memset(&wi, 0, sizeof(wi));
2401
2402 /* Initialize the granules for the translaton tables */
2403 for (unsigned int i = 0U; i < granules; i++) {
2404 s2tt_test_granule_set_lock(g_tables[i], false);
2405 };
2406
2407 /* Root granule must be locked */
2408 s2tt_test_granule_set_lock(g_tables[sl + 2], true);
2409
2410 /*
2411 * Invoke s2tt_walk_lock_unlock() with the generated translation tables
2412 * starting on the next starting level.
2413 */
2414 s2tt_ctx.s2_starting_level = sl + 1L;
2415 s2tt_ctx.g_rtt = g_tables[sl + 2UL];
2416 s2tt_ctx.num_root_rtts = S2TTE_MAX_CONCAT_TABLES;
2417
2418 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2419 pa, end_level, &wi);
2420
2421 LONGS_EQUAL(end_level, wi.last_level);
2422 CHECK_TRUE(val_tt_granule == wi.g_llt);
2423 LONGS_EQUAL(tt_walk_idx[end_level + 1U], wi.index);
2424
2425 for (unsigned int i = sl + 1U; i < granules; i++) {
2426 if (g_tables[i] == wi.g_llt) {
2427 /* Granule must be locked */
2428 CHECK_TRUE(LOCKED(wi.g_llt));
2429 } else {
2430 /* Granule must be unlocked */
2431 CHECK_FALSE(LOCKED(g_tables[i]));
2432 }
2433 }
2434
2435 /*
2436 * Repeat the two first tests, but this time the mapping will
2437 * be finalizing a level below the maximum one and
2438 * s2tt_walk_lock_unlock() will be called to walk up to the
2439 * maximum level.
2440 *
2441 * (Tests 3a & 3b)
2442 */
2443 end_level = S2TT_TEST_HELPERS_MAX_LVL;
2444 (void)memset(&wi, 0, sizeof(wi));
2445
2446 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2447 end_level - 1L, &g_tables[0U], &val_tt_granule);
2448
2449 s2tt_ctx.s2_starting_level = sl;
2450 s2tt_ctx.g_rtt = g_tables[sl + 1UL];
2451 s2tt_ctx.num_root_rtts = 1;
2452
2453 /* Test 3a */
2454 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2455 pa, end_level, &wi);
2456
2457 LONGS_EQUAL((end_level - 1L), wi.last_level);
2458 CHECK_TRUE(val_tt_granule == wi.g_llt);
2459 LONGS_EQUAL(tt_walk_idx[end_level], wi.index);
2460
2461 for (unsigned int i = sl + 1U; i < granules; i++) {
2462 if (g_tables[i] == wi.g_llt) {
2463 /* Granule must be locked */
2464 CHECK_TRUE(LOCKED(wi.g_llt));
2465 } else {
2466 /* Granule must be unlocked */
2467 CHECK_FALSE(LOCKED(g_tables[i]));
2468 }
2469 }
2470
2471 /*
2472 * Repeat the test, but this time starting from the next level after
2473 * the starting one, so we can test the concatenated tables.
2474 *
2475 * (Test 3b)
2476 */
2477 (void)memset(&wi, 0, sizeof(wi));
2478
2479 /* Initialize the granules for the translaton tables */
2480 for (unsigned int i = 0U; i < granules; i++) {
2481 s2tt_test_granule_set_lock(g_tables[i], false);
2482 };
2483
2484 /* Root granule must be locked */
2485 s2tt_test_granule_set_lock(g_tables[sl + 2], true);
2486
2487 /*
2488 * Invoke s2tt_walk_lock_unlock() with the generated translation tables
2489 * starting on the next starting level.
2490 */
2491 s2tt_ctx.s2_starting_level = sl + 1L;
2492 s2tt_ctx.g_rtt = g_tables[sl + 2UL];
2493 s2tt_ctx.num_root_rtts = S2TTE_MAX_CONCAT_TABLES;
2494
2495 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2496 pa, end_level, &wi);
2497
2498 LONGS_EQUAL((end_level - 1L), wi.last_level);
2499 CHECK_TRUE(val_tt_granule == wi.g_llt);
2500 LONGS_EQUAL(tt_walk_idx[end_level], wi.index);
2501
2502 for (unsigned int i = sl + 1U; i < granules; i++) {
2503 if (g_tables[i] == wi.g_llt) {
2504 /* Granule must be locked */
2505 CHECK_TRUE(LOCKED(wi.g_llt));
2506 } else {
2507 /* Granule must be unlocked */
2508 CHECK_FALSE(LOCKED(g_tables[i]));
2509 }
2510 }
2511}
2512
2513void s2tt_walk_lock_unlock_tc2(void)
2514{
2515 /***************************************************************
2516 * TEST CASE 2:
2517 *
2518 * Test s2tt_walk_lock_unlock() with a set of tables in wich
2519 * the granule of one of them is not set to 'GRANULE_STATE_RTT'
2520 ***************************************************************/
2521
2522 long sl = s2tt_test_helpers_min_table_lvl();
2523 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2524 unsigned long pa;
2525 unsigned long sl_index;
2526 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2527 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2528 struct s2tt_walk wi;
2529 struct granule *val_tt_granule;
2530 struct s2tt_context s2tt_ctx;
2531
2532 /* Total number of granules, included the concatenated ones */
2533 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
2534 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2535
2536 /*
2537 * Granules to hold the translation tables,
2538 * including concatenated ones.
2539 */
2540 struct granule *g_tables[granules];
2541
2542 /*
2543 * Generate a random address that spans across the whole IPA size
2544 * but whose walk index at SL + 1 is within
2545 * S2TTE_MAX_CONCAT_TABLES range so the address can also be used to
2546 * test concatenated root table support.
2547 *
2548 * The address doesn't need to have any alignment.
2549 */
2550 do {
2551 pa = test_helpers_get_rand_in_range(1UL,
2552 (1UL << arch_feat_get_pa_width()) - 1UL);
2553 sl_index = s2tt_test_helpers_get_idx_from_addr(pa, sl);
2554 } while (sl_index >= S2TTE_MAX_CONCAT_TABLES);
2555
2556 /* Generate an s2tt context to be used for the test */
2557 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2558 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2559 end_level, &g_tables[0U], &val_tt_granule);
2560
2561 /* Finish the creation of the s2tt_context */
2562 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2563 s2tt_ctx.s2_starting_level = sl;
2564 s2tt_ctx.g_rtt = g_tables[sl + 1UL];
2565 s2tt_ctx.num_root_rtts = 1U;
2566
2567 /*
2568 * Change the granule state for an arbitrary level. In this case, we
2569 * choose Level 2 for simplicity and convenience. The new granule
2570 * state is also chosen arbitrarily.
2571 *
2572 * Note that index '0' corresponds to level '-1' and one of the
2573 * intermediate levels (the level after the starting one) has
2574 * 'S2TTE_MAX_CONCAT_TABLES' tables.
2575 */
2576 s2tt_test_granule_set_state(g_tables[3 + S2TTE_MAX_CONCAT_TABLES],
2577 GRANULE_STATE_RD);
2578
2579 /* The call should cause an assertion failure */
2580 test_helpers_expect_assert_fail(true);
2581 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2582 pa, end_level, &wi);
2583 test_helpers_fail_if_no_assert_failed();
2584}
2585
2586void s2tt_walk_lock_unlock_tc3(void)
2587{
2588 /***************************************************************
2589 * TEST CASE 3:
2590 *
2591 * Test s2tt_walk_lock_unlock() with a set of tables in which
2592 * one of the granules is already locked.
2593 ***************************************************************/
2594
2595 long sl = s2tt_test_helpers_min_table_lvl();
2596 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2597 unsigned long pa;
2598 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2599 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2600 struct s2tt_walk wi;
2601 struct granule *val_tt_granule;
2602 struct s2tt_context s2tt_ctx;
2603
2604 /* Total number of granules, included the concatenated ones */
2605 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
2606 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2607
2608 /*
2609 * Granules to hold the translation tables,
2610 * including concatenated ones.
2611 */
2612 struct granule *g_tables[granules];
2613
2614 /* Generate an s2tt context to be used for the test */
2615 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2616
2617 pa = 0UL; /* Valid on any level */
2618 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2619 end_level, &g_tables[0U], &val_tt_granule);
2620
2621 /* Finish the creation of the s2tt_context */
2622 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2623 s2tt_ctx.s2_starting_level = sl;
2624 s2tt_ctx.g_rtt = g_tables[sl + 1UL];
2625 s2tt_ctx.num_root_rtts = 1U;
2626
2627 /*
2628 * Lock the granule of an arbitrary level. In this case, we
2629 * choose Level 2 for simplicity and convenience.
2630 *
2631 * Note that index '0' corresponds to level '-1' and one of the
2632 * intermediate levels (the level after the starting one) has
2633 * 'S2TTE_MAX_CONCAT_TABLES' tables.
2634 */
2635 s2tt_test_granule_set_lock(g_tables[3 + S2TTE_MAX_CONCAT_TABLES], true);
2636
2637 /* The call should cause an assertion failure */
2638 test_helpers_expect_assert_fail(true);
2639 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2640 pa, end_level, &wi);
2641 test_helpers_fail_if_no_assert_failed();
2642}
2643
2644void s2tt_walk_lock_unlock_tc4(void)
2645{
2646 /***************************************************************
2647 * TEST CASE 4:
2648 *
2649 * Test s2tt_walk_lock_unlock() with a null array of granules.
2650 ***************************************************************/
2651
2652 long sl = s2tt_test_helpers_min_table_lvl();
2653 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2654 unsigned long pa;
2655 struct s2tt_walk wi;
2656 struct s2tt_context s2tt_ctx;
2657
2658 pa = 0UL;
2659
2660 /* Generate an s2tt context to be used for the test */
2661 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2662 s2tt_ctx.s2_starting_level = sl;
2663 s2tt_ctx.g_rtt = NULL;
2664 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2665 s2tt_ctx.num_root_rtts = 1U;
2666
2667 /* The call should cause an assertion failure */
2668 test_helpers_expect_assert_fail(true);
2669 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2670 pa, end_level, &wi);
2671 test_helpers_fail_if_no_assert_failed();
2672}
2673
2674void s2tt_walk_lock_unlock_tc5(void)
2675{
2676 /***************************************************************
2677 * TEST CASE 5:
2678 *
2679 * Test s2tt_walk_lock_unlock() with a null s2tt_walk structure.
2680 ***************************************************************/
2681
2682 long sl = s2tt_test_helpers_min_table_lvl();
2683 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2684 unsigned long pa;
2685 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2686 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2687 struct granule *val_tt_granule;
2688 struct s2tt_context s2tt_ctx;
2689
2690 /* Total number of granules, included the concatenated ones */
2691 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
2692 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2693
2694 /*
2695 * Granules to hold the translation tables,
2696 * including concatenated ones.
2697 */
2698 struct granule *g_tables[granules];
2699
2700 /* Generate an s2tt context to be used for the test */
2701 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2702
2703 pa = 0UL; /* Valid on any level */
2704 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2705 end_level, &g_tables[0U], &val_tt_granule);
2706
2707 /* Finish the creation of the s2tt_context */
2708 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2709 s2tt_ctx.s2_starting_level = sl;
2710 s2tt_ctx.g_rtt = NULL;
2711 s2tt_ctx.num_root_rtts = 1U;
2712
2713 /* The call should cause an assertion failure */
2714 test_helpers_expect_assert_fail(true);
2715 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2716 pa, end_level, NULL);
2717 test_helpers_fail_if_no_assert_failed();
2718}
2719
2720void s2tt_walk_lock_unlock_tc6(void)
2721{
2722 /***************************************************************
2723 * TEST CASE 6:
2724 *
2725 * Test s2tt_walk_lock_unlock() with a start level below the
2726 * minimum permitted.
2727 ***************************************************************/
2728
2729 long sl = s2tt_test_helpers_min_table_lvl();
2730 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2731 unsigned long pa;
2732 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2733 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2734 struct s2tt_walk wi;
2735 struct granule *val_tt_granule;
2736 struct s2tt_context s2tt_ctx;
2737
2738 /* Total number of granules, included the concatenated ones */
2739 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
2740 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2741
2742 /*
2743 * Granules to hold the translation tables,
2744 * including concatenated ones.
2745 */
2746 struct granule *g_tables[granules];
2747
2748 /* Generate an s2tt context to be used for the test */
2749 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2750
2751 pa = 0UL; /* Valid on any level */
2752 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2753 end_level, &g_tables[0U], &val_tt_granule);
2754
2755 /* Finish the creation of the s2tt_context */
2756 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2757 s2tt_ctx.s2_starting_level = sl - 1L;
2758 s2tt_ctx.g_rtt = g_tables[sl + 1U];
2759 s2tt_ctx.num_root_rtts = 1U;
2760
2761 /* The call should cause an assertion failure */
2762 test_helpers_expect_assert_fail(true);
2763 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2764 pa, end_level, &wi);
2765 test_helpers_fail_if_no_assert_failed();
2766}
2767
2768void s2tt_walk_lock_unlock_tc7(void)
2769{
2770 /***************************************************************
2771 * TEST CASE 7:
2772 *
2773 * Test s2tt_walk_lock_unlock() with a start level above the
2774 * maximum permitted.
2775 ***************************************************************/
2776
2777 long sl = s2tt_test_helpers_min_table_lvl();
2778 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2779 unsigned long pa;
2780 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2781 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2782 struct s2tt_walk wi;
2783 struct granule *val_tt_granule;
2784 struct s2tt_context s2tt_ctx;
2785
2786 /* Total number of granules, included the concatenated ones */
2787 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
2788 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2);
2789
2790 /*
2791 * Granules to hold the translation tables,
2792 * including concatenated ones.
2793 */
2794 struct granule *g_tables[granules];
2795
2796 /* Generate an s2tt context to be used for the test */
2797 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2798
2799 pa = 0UL; /* Valid on any level */
2800 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2801 end_level, &g_tables[0U], &val_tt_granule);
2802
2803 /* Finish the creation of the s2tt_context */
2804 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2805 s2tt_ctx.s2_starting_level = end_level + 1L;
2806 s2tt_ctx.g_rtt = g_tables[sl + 1U];
2807 s2tt_ctx.num_root_rtts = 1U;
2808
2809 /* The call should cause an assertion failure */
2810 test_helpers_expect_assert_fail(true);
2811 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2812 pa, end_level, &wi);
2813 test_helpers_fail_if_no_assert_failed();
2814}
2815
2816void s2tt_walk_lock_unlock_tc8(void)
2817{
2818 /***************************************************************
2819 * TEST CASE 8:
2820 *
2821 * Test s2tt_walk_lock_unlock() with a walk end level below the
2822 * start level.
2823 ***************************************************************/
2824
2825 long sl = s2tt_test_helpers_min_table_lvl();
2826 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2827 unsigned long pa;
2828 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2829 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2830 struct s2tt_walk wi;
2831 struct granule *val_tt_granule;
2832 struct s2tt_context s2tt_ctx;
2833
2834 /* Total number of granules, included the concatenated ones */
2835 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
2836 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2837
2838 /*
2839 * Granules to hold the translation tables,
2840 * including concatenated ones.
2841 */
2842 struct granule *g_tables[granules];
2843
2844 /* Generate an s2tt context to be used for the test */
2845 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2846
2847 pa = 0UL; /* Valid on any level */
2848 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2849 end_level, &g_tables[0U], &val_tt_granule);
2850
2851 /* Finish the creation of the s2tt_context */
2852 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2853 s2tt_ctx.s2_starting_level = sl;
2854 s2tt_ctx.g_rtt = g_tables[sl + 1U];
2855 s2tt_ctx.num_root_rtts = 1U;
2856
2857 /* The call should cause an assertion failure */
2858 test_helpers_expect_assert_fail(true);
2859 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2860 pa, sl - 1U, &wi);
2861 test_helpers_fail_if_no_assert_failed();
2862}
2863
2864void s2tt_walk_lock_unlock_tc9(void)
2865{
2866 /***************************************************************
2867 * TEST CASE 9:
2868 *
2869 * Test s2tt_walk_lock_unlock() with an end walk level above the
2870 * maximum permitted.
2871 ***************************************************************/
2872
2873 long sl = s2tt_test_helpers_min_table_lvl();
2874 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2875 unsigned long pa;
2876 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2877 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2878 struct s2tt_walk wi;
2879 struct granule *val_tt_granule;
2880 struct s2tt_context s2tt_ctx;
2881
2882 /* Total number of granules, included the concatenated ones */
2883 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
2884 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2885
2886 /*
2887 * Granules to hold the translation tables,
2888 * including concatenated ones.
2889 */
2890 struct granule *g_tables[granules];
2891
2892 /* Generate an s2tt context to be used for the test */
2893 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2894
2895 pa = 0UL; /* Valid on any level */
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 /* The call should cause an assertion failure */
2906 test_helpers_expect_assert_fail(true);
2907 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2908 pa, end_level + 1, &wi);
2909 test_helpers_fail_if_no_assert_failed();
2910}
2911
2912void s2tt_walk_lock_unlock_tc10(void)
2913{
2914 /***************************************************************
2915 * TEST CASE 10:
2916 *
2917 * Test s2tt_walk_lock_unlock() with a PA above the maximum
2918 * supported IPA size.
2919 ***************************************************************/
2920
2921 long sl = s2tt_test_helpers_min_table_lvl();
2922 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2923 unsigned long pa;
2924 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2925 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2926 struct s2tt_walk wi;
2927 struct granule *val_tt_granule;
2928 s2tt_context s2tt_ctx;
2929
2930 /* Total number of granules, included the concatenated ones */
2931 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
2932 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2933
2934 /*
2935 * Granules to hold the translation tables,
2936 * including concatenated ones.
2937 */
2938 struct granule *g_tables[granules];
2939
2940 /* Generate an s2tt context to be used for the test */
2941 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2942
2943 pa = 0UL; /* Valid on any level */
2944
2945 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2946 end_level, &g_tables[0U], &val_tt_granule);
2947
2948 /* Finish the creation of the s2tt_context */
2949 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
2950 s2tt_ctx.s2_starting_level = sl;
2951 s2tt_ctx.g_rtt = g_tables[sl + 1U];
2952 s2tt_ctx.num_root_rtts = 1U;
2953
2954 /* Generate an address larger than the maximum allowable size */
2955 pa = 1UL << s2tt_ctx.ipa_bits;
2956
2957 /* The call should cause an assertion failure */
2958 test_helpers_expect_assert_fail(true);
2959 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
2960 pa, end_level, &wi);
2961 test_helpers_fail_if_no_assert_failed();
2962}
2963
2964void s2tt_walk_lock_unlock_tc11(void)
2965{
2966 /***************************************************************
2967 * TEST CASE 11:
2968 *
2969 * Test s2tt_walk_lock_unlock() with an invalid max ipa size.
2970 ***************************************************************/
2971
2972 long sl = s2tt_test_helpers_min_table_lvl();
2973 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
2974 unsigned long pa;
2975 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2976 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
2977 struct s2tt_walk wi;
2978 struct granule *val_tt_granule;
2979 struct s2tt_context s2tt_ctx;
2980
2981 /* Total number of granules, included the concatenated ones */
2982 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
2983 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
2984
2985 /*
2986 * Granules to hold the translation tables,
2987 * including concatenated ones.
2988 */
2989 struct granule *g_tables[granules];
2990
2991 /* Generate an s2tt context to be used for the test */
2992 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
2993
2994 pa = 0UL; /* Valid on any level */
2995
2996 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
2997 end_level, &g_tables[0U], &val_tt_granule);
2998
2999 /* Finish the creation of the s2tt_context */
3000 s2tt_ctx.ipa_bits = arch_feat_get_pa_width() + 1UL;
3001 s2tt_ctx.s2_starting_level = sl;
3002 s2tt_ctx.g_rtt = g_tables[sl + 1U];
3003 s2tt_ctx.num_root_rtts = 1U;
3004
3005 /* The call should cause an assertion failure */
3006 test_helpers_expect_assert_fail(true);
3007 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
3008 pa, end_level, &wi);
3009 test_helpers_fail_if_no_assert_failed();
3010}
3011
3012void s2tt_walk_lock_unlock_tc12(void)
3013{
3014 /***************************************************************
3015 * TEST CASE 12:
3016 *
3017 * Test s2tt_walk_lock_unlock() with a combination of first
3018 * look-up level and root tables in which the number of
3019 * concatenated tables would result larger than the maximum
3020 * permitted.
3021 ***************************************************************/
3022
3023 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
3024 unsigned long pa;
3025 unsigned long sl_index;
3026 unsigned long tt_walk_idx[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
3027 unsigned long tt_walk[end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U];
3028 struct s2tt_walk wi;
3029 struct granule *val_tt_granule;
3030 struct s2tt_context s2tt_ctx;
3031
3032 /* Total number of granules, included the concatenated ones */
3033 unsigned int granules = S2TTE_MAX_CONCAT_TABLES +
3034 (end_level - S2TT_TEST_HELPERS_MIN_LVL_LPA2 + 1U);
3035
3036 /*
3037 * Granules to hold the translation tables,
3038 * including concatenated ones.
3039 */
3040 struct granule *g_tables[granules];
3041
3042 /*
3043 * We need to generate a concatenated table at SL + 1 with a number
3044 * of tables > S2TTE_MAX_CONCAT_TABLES. In order to avoid an
3045 * overflowing IPA when FEAT_LPA2 is enabled, we set SL to be
3046 * the architectural minimum plus 1.
3047 */
3048 long sl = s2tt_test_helpers_min_table_lvl() + 1L;
3049
3050 /*
3051 * Generate a random address that spans across the whole IPA size but
3052 * whose walk table index at SL is larger than S2TTE_MAX_CONCAT_TABLES.
3053 *
3054 * The address doesn't need to have any alignment.
3055 */
3056 do {
3057 pa = test_helpers_get_rand_in_range(1UL,
3058 (1UL << arch_feat_get_pa_width()) - 1UL);
3059 sl_index = s2tt_test_helpers_get_idx_from_addr(pa, sl);
3060 } while (sl_index <= S2TTE_MAX_CONCAT_TABLES);
3061
3062 /* Generate an s2tt context to be used for the test */
3063 s2tt_ctx.enable_lpa2 = s2tt_test_helpers_lpa2_enabled();
3064
3065 populate_s2tts(&s2tt_ctx, pa, &tt_walk_idx[0U], &tt_walk[0U],
3066 end_level, &g_tables[0U], &val_tt_granule);
3067
3068 /* Finish the creation of the s2tt_context */
3069 s2tt_ctx.ipa_bits = arch_feat_get_pa_width();
3070 s2tt_ctx.s2_starting_level = sl + 1L;
3071 s2tt_ctx.g_rtt = g_tables[sl + 2U];
3072 s2tt_ctx.num_root_rtts = S2TTE_MAX_CONCAT_TABLES;
3073
3074 /* The call should cause an assertion failure */
3075 test_helpers_expect_assert_fail(true);
3076 s2tt_walk_lock_unlock((const struct s2tt_context *)&s2tt_ctx,
3077 pa, end_level, &wi);
3078 test_helpers_fail_if_no_assert_failed();
3079}
3080
3081void s2tt_walk_lock_unlock_tc13(void)
3082{
3083 /***************************************************************
3084 * TEST CASE 13:
3085 *
3086 * Test s2tt_walk_lock_unlock() with a null s2tt_context.
3087 ***************************************************************/
3088
3089 long end_level = S2TT_TEST_HELPERS_MAX_LVL;
3090 unsigned long pa;
3091 struct s2tt_walk wi;
3092
3093 pa = 0UL;
3094
3095 /* The call should cause an assertion failure */
3096 test_helpers_expect_assert_fail(true);
3097 s2tt_walk_lock_unlock((const struct s2tt_context *)NULL,
3098 pa, end_level, &wi);
3099 test_helpers_fail_if_no_assert_failed();
3100}