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