blob: 1beb2f9c5705405a544a1eed5a8b5418ee04029c [file] [log] [blame]
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +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 <arch_helpers.h>
11#include <debug.h>
12#include <host_utils.h>
13#include <stdlib.h>
14#include <string.h>
15#include <test_helpers.h>
16#include <utils_def.h>
17#include <xlat_contexts.h> /* API to test */
18#include <xlat_defs.h>
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +010019#include <xlat_defs_private.h>
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +010020#include <xlat_tables.h> /* API to test */
21#include <xlat_test_defs.h>
22#include <xlat_test_helpers.h>
23}
24
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +010025/*
26 * Generate VA space parameters given a walk start level and a region.
27 * The VA returned will fit in a single table of level `level`, so that
28 * there translation can start at that given level.
29 */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +010030static uint64_t gen_va_space_params_by_lvl(int level,
31 xlat_addr_region_id_t region,
32 size_t *va_size)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +010033{
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +010034 assert(level >= XLAT_TEST_MIN_LVL());
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +010035 assert(level <= XLAT_TABLE_LEVEL_MAX);
36 assert(va_size != NULL);
37
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +010038 *va_size = (1ULL << XLAT_ADDR_SHIFT(level)) *
39 XLAT_GET_TABLE_ENTRIES(level);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +010040
41 return xlat_test_helpers_get_start_va(region, *va_size);
42}
43
44/*
45 * Generate a mmap array containing a set of mmap regions defined by
46 * 'start_va', 'last_lvl' and 'offset'. The mmap array will have
47 * three regions:
48 *
49 * - First region mapped at the beginning of a table whose final
50 * lookup level is 'last_lvl'. This region will be descendant of
51 * an entry at the beginning of a table at level 'first_lvl'.
52 * - Second region mapped at a random index of a table whose final
53 * lookup level is 'last_lvl'. This region will be descendant of
54 * an entry at a random index of a table at level 'first_lvl'.
55 * - Third region mapped at the end of a table whose final
56 * lookup level is 'last_lvl'. This region will be descendant of
57 * an entry at the final entry of a table at level 'first_lvl'.
58 *
59 * ┌──────────┐
60 * ┌───────────────┤ First │
61 * │ │ Region │
62 * │ ├──────────┤
63 * │ │ │
64 * │ │ │
65 * │ │ │
66 * │ │ │
67 * │ │ │
68 * │ │ │
69 * │ │ │
70 * ┌──────────────┐ │ │ │
71 * │ │ │ │ │
72 * │ First entry ├───────┘ │ │
73 * ├──────────────┤ │ │
74 * │ Second entry │ │ │
75 * │ (Reserved) │ └──────────┘
76 * │ │
77 * ├──────────────┤
78 * │ │ ┌──────────┐
79 * │ │ │ │
80 * │ │ │ │
81 * │ │ │ │
82 * ├──────────────┤ ├──────────┤
83 * │ Second │ │ Second │
84 * │ Region ├────────────────────────┤ Region │
85 * ├──────────────┤ ├──────────┤
86 * │ │ │ │
87 * │ │ │ │
88 * │ │ │ │
89 * │ │ │ │
90 * │ │ │ │
91 * │ │ │ │
92 * ├──────────────┤ └──────────┘
93 * │ │
94 * │ Third Region ├───────┐
95 * └──────────────┘ │ ┌─────────┐
96 * First Level │ │ │
97 * │ │ │
98 * │ │ │
99 * │ │ │
100 * │ │ │
101 * │ │ │
102 * │ │ │
103 * │ │ │
104 * │ │ │
105 * │ │ │
106 * │ │ │
107 * │ │ │
108 * │ │ │
109 * │ ├─────────┤
110 * └─────────────────┤ Third |
111 * | region │
112 * └─────────┘
113 * Last level
114 *
115 * For all the mmap regions, the granularity (returned in *granularity) is
116 * setup to the minimum granularity needed to map a block at level 'last_lvl'.
117 * The size of the mmap region is setup to the same as the granularity.
118 *
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100119 * This function caters for the reduced number of entries on the
120 * tables at level -1.
121 *
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100122 * This function also returns :
123 * - An array ('tbl_idxs') with the expected indexes mapping
124 * the regions at the last level table.
125 */
126static int gen_mmap_array_by_level(xlat_mmap_region *mmap,
127 unsigned int *tbl_idxs,
128 unsigned int mmap_size,
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100129 int first_lvl,
130 int last_lvl,
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100131 size_t *granularity,
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100132 uint64_t start_va,
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100133 bool allow_transient)
134{
135 uint64_t attrs;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100136 uint64_t mmap_start_va = start_va;
137 unsigned int max_table_entries = XLAT_GET_TABLE_ENTRIES(first_lvl);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100138
139 assert(mmap_size >= 3U);
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100140 assert(last_lvl > XLAT_TEST_MIN_LVL());
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100141 assert(last_lvl <= XLAT_TABLE_LEVEL_MAX);
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100142 assert(first_lvl >= XLAT_TEST_MIN_LVL());
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100143 assert(first_lvl <= last_lvl);
144 assert(mmap != NULL);
145 assert(tbl_idxs != NULL);
146 assert(granularity != NULL);
147
148 /* Generate a mapping at the beginning of the table */
149 tbl_idxs[0U] = 0U;
150
151 /*
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100152 * Generate a mapping in a random position of the table.
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100153 * The entry after the first one will always be left intentionally
154 * unused.
155 */
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +0100156 tbl_idxs[1U] = (unsigned int)test_helpers_get_rand_in_range(2UL,
157 max_table_entries - 2);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100158
159 /* Generate a mapping at the end of the table */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100160 tbl_idxs[2U] = max_table_entries - 1U;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100161
162 do {
Mate Toth-Pal3f0a8ae2024-08-01 11:09:56 +0200163 attrs = xlat_test_helpers_rand_mmap_attrs(true);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100164 } while ((attrs == MT_TRANSIENT) && (allow_transient == false));
165
166 *granularity = XLAT_BLOCK_SIZE(last_lvl);
167
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100168 for (unsigned int i = 0U; i < 3U; i++) {
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100169 mmap[i].base_va = mmap_start_va;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100170 if (first_lvl < last_lvl) {
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100171 /*
172 * Add an offset to the mmap region base VA so that
173 * this region will be mapped to a TTE in the
174 * `first_lvl` table at the same index as specified
175 * in tbl_idxs[].
176 */
177 mmap[i].base_va += tbl_idxs[i] *
178 XLAT_BLOCK_SIZE(first_lvl);
179 }
180
181 mmap[i].base_va += (tbl_idxs[i] * (*granularity));
182
183 /*
184 * PA can be any address (as long as there are not overlaps,
185 * for which there is a specific test). For simplicity,
186 * create an identity mapping using the base_va for the PA.
187 */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100188 mmap[i].base_pa = mmap[i].base_va & XLAT_TEST_GET_PA_MASK();
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100189 mmap[i].size = *granularity;
190 mmap[i].attr = attrs;
191 mmap[i].granularity = *granularity;
192 }
193
194 return 0;
195}
196
197/*
198 * Given a context and a set of expected indexes and levels for the last walk,
199 * validate that the translation tables in the context are valid.
200 * Note that this function expects a valid and initialized context.
201 */
202static void validate_xlat_tables(xlat_ctx *ctx, unsigned int *expected_idxs,
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100203 int expected_level)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100204{
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100205 uint64_t tte, tte_oa, attrs, upper_attrs, lower_attrs, type;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100206 uint64_t exp_upper_attrs, exp_lower_attrs;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100207 unsigned int index, granularity, addr_offset;
208 uint64_t test_va, pa, pa_mask;
209 int level, retval;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100210
211 assert(ctx != NULL);
212 assert(expected_idxs != NULL);
213
214 for (unsigned int i = 0U; i < ctx->cfg->mmap_regions; i++) {
215 granularity = ctx->cfg->mmap[i].granularity;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +0100216 addr_offset = (unsigned int)test_helpers_get_rand_in_range(0UL,
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100217 granularity - 1U);
218 test_va = ctx->cfg->base_va + ctx->cfg->mmap[i].base_va +
219 addr_offset;
220 pa = ctx->cfg->mmap[i].base_pa + addr_offset;
221
222 /* Perform a table walk */
223 retval = xlat_test_helpers_table_walk(ctx, test_va,
224 &tte, NULL, &level,
225 &index);
226
227 /* Return value */
228 CHECK_VERBOSE((retval == 0),
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100229 "Perform table walk for addr 0x%lx", test_va);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100230
231 /* Last table level */
232 CHECK_EQUAL(expected_level, level);
233
234 /* tte index on the page */
235 CHECK_EQUAL(expected_idxs[i], index);
236
237 /* Expected tte attributes */
238 retval = xlat_test_helpers_get_attrs_for_va(ctx, test_va,
239 &attrs);
240
241 /* Return value */
242 CHECK_EQUAL(0, retval);
243
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100244 exp_upper_attrs = EXTRACT(UPPER_ATTRS, attrs);
245 upper_attrs = EXTRACT(UPPER_ATTRS, tte);
246 exp_lower_attrs = EXTRACT(LOWER_ATTRS, attrs);
247 if (is_feat_lpa2_4k_present() == true) {
248 lower_attrs = EXTRACT(LOWER_ATTRS,
249 (tte & ~TTE_OA_BITS_50_51_MASK));
250 } else {
251 lower_attrs = EXTRACT(LOWER_ATTRS, tte);
252 }
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100253
254 /* Validate that the attributes are as expected */
255 CHECK_VERBOSE((exp_upper_attrs == upper_attrs),
256 "Validate Upper Attrs: Read 0x%lx - Expected 0x%lx",
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100257 upper_attrs, exp_upper_attrs);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100258
259 CHECK_VERBOSE((exp_lower_attrs == lower_attrs),
260 "Validate Lower Attrs: Read 0x%lx - Expected 0x%lx",
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100261 lower_attrs, exp_lower_attrs);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100262
263 /* Validate the PA */
264 pa_mask = (1ULL << XLAT_ADDR_SHIFT(level)) - 1ULL;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100265 tte_oa = xlat_get_oa_from_tte(tte);
266
267 CHECK_EQUAL(tte_oa, (pa & ~pa_mask));
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100268
269 /* Validate the descriptor type */
270 type = (level == XLAT_TABLE_LEVEL_MAX) ? PAGE_DESC :
271 BLOCK_DESC;
272 CHECK_EQUAL(type, (tte & DESC_MASK));
273 }
274}
275
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +0200276void xlat_ctx_init_tc5(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100277{
278 struct xlat_ctx ctx;
279 struct xlat_ctx_cfg cfg;
280 struct xlat_ctx_tbls tbls;
281 uint64_t start_va;
282 size_t va_size, granularity;
283 unsigned int mmap_count;
284 xlat_addr_region_id_t va_region;
285 int retval;
286 struct xlat_mmap_region init_mmap[3U];
287 unsigned int tbl_idx[3U];
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100288 int base_lvl, end_lvl;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100289
290 /**********************************************************************
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +0200291 * TEST CASE 5:
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100292 *
293 * For each possible base level, create a set of mmap regions
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100294 * ranging from level 1 or 0 (lowest level at which a valid walk can
295 * finish depending on whether FEAT_LPA2 is available) to
296 * XLAT_TABLE_LEVEL_MAX.
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100297 *
298 * For each possible (va_region, base_lvl, end_lvl) triplet for a
299 * base table there will be three mmap regions created:
300 *
301 * - First region mapped at the beginning of a table whose final
302 * lookup level is 'last_lvl'. This region will be descendant of
303 * an entry at the beginning of a 'base_lvl' table.
304 * - Second region mapped at a random index of a table whose final
305 * lookup level is 'last_lvl'. This region will be descendant of
306 * an entry at a random index of a 'base_lvl' table.
307 * - Third region mapped at the end of a table whose final
308 * lookup level is 'last_lvl'. This region will be descendant of
309 * an entry at the end of a 'base_lvl'.
310 *
311 * Then verify that the tables can be walked and that the levels,
312 * offsets and attributes on the ttes are as expected.
313 *
314 * This test validates that the xlat library is able to create
315 * tables starting on any valid initial lookup level and
316 * finishing on any valid level as well.
317 *********************************************************************/
318
319 mmap_count = 3U;
320
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100321 end_lvl = XLAT_MIN_BLOCK_LVL();
322 for (; end_lvl <= XLAT_TABLE_LEVEL_MAX; end_lvl++) {
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100323 for (int i = 0U; i < VA_REGIONS; i++) {
324 va_region = (xlat_addr_region_id_t)i;
325
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100326 for (base_lvl = XLAT_TEST_MIN_LVL();
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100327 base_lvl <= end_lvl;
328 base_lvl++) {
329
330 start_va = gen_va_space_params_by_lvl(base_lvl,
331 va_region,
332 &va_size);
333
334 retval = gen_mmap_array_by_level(&init_mmap[0U],
335 &tbl_idx[0U],
336 mmap_count,
337 base_lvl,
338 end_lvl,
339 &granularity,
340 start_va,
341 false);
342 /*
343 * verify that the test setup is correct so far
344 */
345 CHECK_TRUE(retval == 0);
346
347 /* Clean the data structures */
348 memset((void *)&ctx, 0,
349 sizeof(struct xlat_ctx));
350 memset((void *)&cfg, 0,
351 sizeof(struct xlat_ctx_cfg));
352 memset((void *)&tbls, 0,
353 sizeof(struct xlat_ctx_tbls));
354
355 /* Initialize the test structure */
356 retval = xlat_ctx_cfg_init(&cfg, va_region,
357 &init_mmap[0U],
358 mmap_count, va_size);
359
360 /*
361 * verify that the test setup is correct so far
362 */
363 CHECK_TRUE(retval == 0);
364
365 /* Test xlat_ctx_init() */
366 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
367 xlat_test_helpers_tbls(),
368 XLAT_TESTS_MAX_TABLES);
369
370 /*
371 * verify that the test setup is correct so far
372 */
373 CHECK_TRUE(retval == 0);
374
375 validate_xlat_tables(&ctx, &tbl_idx[0U],
376 end_lvl);
377 }
378 }
379 }
380}
381
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100382void xlat_get_llt_from_va_tc1(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100383{
384 struct xlat_ctx ctx;
385 struct xlat_ctx_cfg cfg;
386 struct xlat_ctx_tbls tbls;
387 struct xlat_llt_info tbl_info, tbl_val;
388 struct xlat_mmap_region init_mmap[3U];
389 uint64_t start_va;
390 size_t va_size, granularity;
391 unsigned int mmap_count, index;
392 xlat_addr_region_id_t va_region;
393 int retval;
394 unsigned int tbl_idx[3U];
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100395 int base_lvl, end_lvl;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100396 unsigned int mmap_idx;
397 uint64_t tte;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100398 uint64_t test_va;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100399
400 /***************************************************************
401 * TEST CASE 1:
402 *
403 * For each possible base level, create a set of mmap regions
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100404 * ranging from level 1 or 0 (lowest level at which a valid walk
405 * can finish depending on whether FEAT_LPA2 is available) to
406 * XLAT_TABLE_LEVEL_MAX.
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100407 *
408 * For each possible (va_region, base_lvl, end_lvl) triplet,
409 * create 3 mappings that will correspond to a tte in the Last
410 * level Table. Then verify that the call to
411 * xlat_get_llt_from_va() is able to return the right
412 * xlat_tbl_info structure with the expected values.
413 ***************************************************************/
414
415 mmap_count = 3U;
416 va_region = (xlat_addr_region_id_t)test_helpers_get_rand_in_range(
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +0100417 0UL, VA_REGIONS - 1);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100418
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100419 end_lvl = XLAT_MIN_BLOCK_LVL();
420 for (; end_lvl <= XLAT_TABLE_LEVEL_MAX; end_lvl++) {
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100421
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100422 for (base_lvl = XLAT_TEST_MIN_LVL();
423 base_lvl <= end_lvl;
424 base_lvl++) {
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100425
426 /* Clean the data structures */
427 memset((void *)&ctx, 0,
428 sizeof(struct xlat_ctx));
429 memset((void *)&cfg, 0,
430 sizeof(struct xlat_ctx_cfg));
431 memset((void *)&tbls, 0,
432 sizeof(struct xlat_ctx_tbls));
433 memset((void *)&tbl_info, 0,
434 sizeof(struct xlat_llt_info));
435 memset((void *)&tbl_val, 0,
436 sizeof(struct xlat_llt_info));
437
438 start_va = gen_va_space_params_by_lvl(base_lvl,
439 va_region,
440 &va_size);
441
442 /*
443 * Use gen_mmap_array_by_level() to generate
444 * the mmap array.
445 */
446 retval = gen_mmap_array_by_level(&init_mmap[0U],
447 &tbl_idx[0U],
448 mmap_count,
449 base_lvl,
450 end_lvl,
451 &granularity,
452 start_va,
453 true);
454
455 /* Ensure that so far the test setup is OK */
456 CHECK_TRUE(retval == 0);
457
458 retval = xlat_ctx_cfg_init(&cfg, va_region,
459 &init_mmap[0U],
460 mmap_count, va_size);
461
462 /* Ensure that so far the test setup is OK */
463 CHECK_TRUE(retval == 0);
464
465 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
466 xlat_test_helpers_tbls(),
467 XLAT_TESTS_MAX_TABLES);
468
469 /* Ensure that so far the test setup is OK */
470 CHECK_TRUE(retval == 0);
471
472 for (mmap_idx = 0U; mmap_idx < mmap_count; mmap_idx++) {
473 /*
474 * For each mmap region, pick up a
475 * random address for the test.
476 */
477 test_va = init_mmap[mmap_idx].base_va
478 + ctx.cfg->base_va;
479 test_va +=
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +0100480 test_helpers_get_rand_in_range(0UL,
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100481 init_mmap[mmap_idx].size - 1);
482
483 /*
484 * Perform a table walk to retrieve
485 * table info. Store the expected values
486 * inside the validation xlat_llt_info
487 * structure.
488 */
489 retval = xlat_test_helpers_table_walk(&ctx,
490 test_va,
491 &tte,
492 &(tbl_val.table),
493 &(tbl_val.level),
494 &index);
495
496 /*
497 * Calculate the expected base VA for the llt.
498 */
499 tbl_val.llt_base_va = start_va;
500 tbl_val.llt_base_va += (base_lvl < end_lvl) ?
501 (XLAT_BLOCK_SIZE(base_lvl) *
502 tbl_idx[mmap_idx]) : 0;
503
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100504 /* Ensure that so far the test setup is OK */
505 CHECK_TRUE(retval == 0);
506
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100507 VERBOSE("\nTesting VA 0x%lx", test_va);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100508
509 /* Test xlat_get_llt_from_va */
510 retval = xlat_get_llt_from_va(&tbl_info, &ctx,
511 test_va);
512
513 /* Check the return value */
514 CHECK_TRUE(retval == 0);
515
516 /*
517 * Validate the structure returned by
518 * xlat_get_llt_from_va
519 */
520 MEMCMP_EQUAL((void *)&tbl_val,
521 (void *)&tbl_info,
522 sizeof(struct xlat_llt_info));
523 VERBOSE(" : PASS\n\n");
524 }
525 }
526 }
527}
528
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100529void xlat_get_llt_from_va_tc2(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100530{
531 struct xlat_ctx ctx;
532 struct xlat_ctx_cfg cfg;
533 struct xlat_ctx_tbls tbls;
534 struct xlat_llt_info tbl_info;
535 struct xlat_mmap_region init_mmap[3U];
536 unsigned int tbl_idx[3U];
537 size_t va_size, granularity;
538 uint64_t start_va, test_va;
539 xlat_addr_region_id_t va_region;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100540 int base_lvl, end_lvl;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100541 int retval;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100542 uint64_t max_va_size = XLAT_TEST_MAX_VA_SIZE();
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100543
544 /***************************************************************
545 * TEST CASE 2:
546 *
547 * Test xlat_get_llt_from_va() with a VAs ouside
548 * of the context VA space.
549 ***************************************************************/
550
551 /*
552 * Pick up a base and end levels for the translation tables.
553 * The leves are arbitrary. Just to have a VA space enough
554 * for the tests.
555 */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100556 base_lvl = 2;
557 end_lvl = 3;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100558
559 for (int i = 0U; i < VA_REGIONS; i++) {
560 va_region = (xlat_addr_region_id_t)i;
561
562 /*
563 * For the low region, the test will be executed
564 * only once, for a VA above the VA space limits.
565 *
566 * For the high region, the test will be executed twice:
567 * - Once for VA below the VA space.
568 * - Once of a VA above the VA space.
569 */
570 for (unsigned int j = 0; j < (i + 1U); j++) {
571
572 /* Clean the data structures */
573 memset((void *)&ctx, 0, sizeof(struct xlat_ctx));
574 memset((void *)&cfg, 0, sizeof(struct xlat_ctx_cfg));
575 memset((void *)&tbls, 0, sizeof(struct xlat_ctx_tbls));
576 memset((void *)&tbl_info, 0,
577 sizeof(struct xlat_llt_info));
578
579 /* Get VA space limits for Level 2 */
580 start_va = gen_va_space_params_by_lvl(base_lvl, va_region,
581 &va_size);
582
583 /*
584 * use gen_mmap_array_by_level() to generate
585 * the mmap for convenience.
586 */
587 retval = gen_mmap_array_by_level(&init_mmap[0U],
588 &tbl_idx[0U],
589 3U, base_lvl, end_lvl,
590 &granularity,
591 start_va,
592 true);
593
594 /* Ensure that so far the test setup is OK */
595 CHECK_TRUE(retval == 0);
596
597 retval = xlat_ctx_cfg_init(&cfg, va_region,
598 &init_mmap[0U], 3U,
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100599 max_va_size);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100600 CHECK_TRUE(retval == 0);
601
602 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
603 xlat_test_helpers_tbls(),
604 XLAT_TESTS_MAX_TABLES);
605 CHECK_TRUE(retval == 0);
606
607 VERBOSE("\n");
608
609 if (j == 0U) {
610 /*
611 * VA above the VA space.
612 * The upper range of the address is arbitrary.
613 */
614 test_va = (ctx.cfg->max_va_size) +
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +0100615 test_helpers_get_rand_in_range(0UL,
616 XLAT_BLOCK_SIZE(base_lvl) - 1);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100617 } else {
618 /*
619 * VA below the VA space.
620 * The upper range of the address is arbitrary.
621 */
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +0100622 test_va = test_helpers_get_rand_in_range(0UL,
623 XLAT_BLOCK_SIZE(base_lvl) - 1);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100624 }
625
626 /* Test xlat_get_llt_from_va */
627 retval = xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
628
629 /* Check the return value */
630 CHECK_VERBOSE((retval == -EFAULT),
631 "Testing VA 0x%lx", test_va);
632 VERBOSE("\n");
633 }
634 }
635}
636
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100637void xlat_get_llt_from_va_tc3(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100638{
639 struct xlat_ctx ctx;
640 struct xlat_ctx_cfg cfg;
641 struct xlat_ctx_tbls tbls;
642 struct xlat_llt_info tbl_info;
643 struct xlat_mmap_region init_mmap[3U];
644 unsigned int tbl_idx[3U];
645 size_t va_size, granularity;
646 uint64_t start_va, test_va;
647 xlat_addr_region_id_t va_region;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100648 int base_lvl, end_lvl;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100649 int retval;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100650 uint64_t max_va_size = XLAT_TEST_MAX_VA_SIZE();
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100651
652 /***************************************************************
653 * TEST CASE 3:
654 *
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100655 * Test xlat_get_llt_from_va() with an unmapped VA belonging to
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100656 * the context VA space.
657 ***************************************************************/
658
659 /*
660 * Pick up a base and end levels for the translation tables.
661 * The leves are arbitrary. Just to have a VA space enough
662 * for the tests.
663 */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100664 base_lvl = XLAT_TEST_MIN_LVL();
665 end_lvl = 3;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100666
667 for (int i = 0U; i < VA_REGIONS; i++) {
668 va_region = (xlat_addr_region_id_t)i;
669
670 /* Clean the data structures */
671 memset((void *)&ctx, 0, sizeof(struct xlat_ctx));
672 memset((void *)&cfg, 0, sizeof(struct xlat_ctx_cfg));
673 memset((void *)&tbls, 0, sizeof(struct xlat_ctx_tbls));
674 memset((void *)&tbl_info, 0, sizeof(struct xlat_llt_info));
675
676 /* VA space boundaries */
677 start_va = gen_va_space_params_by_lvl(base_lvl, va_region,
678 &va_size);
679
680 /*
681 * use gen_mmap_array_by_level() to generate
682 * the mmap for convenience, although we will
683 * only use one of the mmap regions (init_mmap[0]).
684 */
685 retval = gen_mmap_array_by_level(&init_mmap[0U],
686 &tbl_idx[0U],
687 3U, base_lvl, end_lvl,
688 &granularity,
689 start_va,
690 true);
691
692 /* Ensure that so far the test setup is OK */
693 CHECK_TRUE(retval == 0);
694
695 retval = xlat_ctx_cfg_init(&cfg, va_region,
696 &init_mmap[0U], 3U,
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100697 max_va_size);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100698 CHECK_TRUE(retval == 0);
699
700 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
701 xlat_test_helpers_tbls(),
702 XLAT_TESTS_MAX_TABLES);
703 CHECK_TRUE(retval == 0);
704
705 VERBOSE("\n");
706
707 test_va = ctx.cfg->base_va;
708 test_va += (init_mmap[0U].base_va + init_mmap[0U].size);
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +0100709 test_va += test_helpers_get_rand_in_range(1UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100710
711 /* Test xlat_get_llt_from_va */
712 retval = xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
713
714 /* Check the return value */
715 CHECK_VERBOSE((retval == 0),
716 "Testing VA 0x%lx", test_va);
717 VERBOSE("\n");
718 }
719}
720
721void xlat_get_llt_from_va_prepare_assertion(struct xlat_ctx *ctx,
722 struct xlat_ctx_cfg *cfg,
723 struct xlat_ctx_tbls *tbls,
724 struct xlat_mmap_region *init_mmap)
725{
726 uint64_t start_va, end_va;
727 xlat_addr_region_id_t va_region;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100728 uint64_t max_va_size = XLAT_TEST_MAX_VA_SIZE();
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100729
730 assert(ctx != NULL);
731 assert(cfg != NULL);
732 assert(tbls != NULL);
733 assert(init_mmap != NULL);
734
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +0100735 va_region = (xlat_addr_region_id_t)test_helpers_get_rand_in_range(0UL,
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100736 VA_REGIONS - 1U);
737
738 /* Clean the data structures */
739 memset((void *)ctx, 0, sizeof(struct xlat_ctx));
740 memset((void *)cfg, 0, sizeof(struct xlat_ctx_cfg));
741 memset((void *)tbls, 0, sizeof(struct xlat_ctx_tbls));
742
743 /* VA space boundaries */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100744 start_va = xlat_test_helpers_get_start_va(va_region, max_va_size);
745 end_va = start_va + max_va_size - 1ULL;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100746
747 /* Generate a random mmap area */
Mate Toth-Pal3f0a8ae2024-08-01 11:09:56 +0200748 xlat_test_helpers_rand_mmap_array(init_mmap, 1U, start_va, end_va, true);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100749
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100750 (void)xlat_ctx_cfg_init(cfg, va_region, init_mmap, 1U, max_va_size);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100751
752 (void)xlat_ctx_init(ctx, cfg, tbls,
753 xlat_test_helpers_tbls(),
754 XLAT_TESTS_MAX_TABLES);
755}
756
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100757void xlat_get_llt_from_va_tc4(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100758{
759
760 struct xlat_ctx ctx;
761 struct xlat_ctx_cfg cfg;
762 struct xlat_ctx_tbls tbls;
763 struct xlat_mmap_region init_mmap;
764 uint64_t test_va;
765
766 /***************************************************************
767 * TEST CASE 4:
768 *
769 * Try calling xlat_get_llt_from_va() with a NULL
770 * xlat_llt_info structure
771 ***************************************************************/
772
773 xlat_get_llt_from_va_prepare_assertion(&ctx, &cfg, &tbls, &init_mmap);
774
775 test_va = ctx.cfg->base_va + init_mmap.base_va;
776
777 /* Test xlat_get_llt_from_va */
778 test_helpers_expect_assert_fail(true);
779 (void)xlat_get_llt_from_va(NULL, &ctx, test_va);
780 test_helpers_fail_if_no_assert_failed();
781}
782
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100783void xlat_get_llt_from_va_tc5(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100784{
785 struct xlat_llt_info tbl_info;
786
787 /***************************************************************
788 * TEST CASE 5:
789 *
790 * Try calling xlat_get_llt_from_va() with a NULL
791 * xlat_ctx structure.
792 ***************************************************************/
793
794 /* Clean the data structures */
795 memset((void *)&tbl_info, 0, sizeof(struct xlat_llt_info));
796
797 /* Test xlat_get_llt_from_va: NULL xlat_ctx */
798 test_helpers_expect_assert_fail(true);
799 (void)xlat_get_llt_from_va(&tbl_info, NULL, 0ULL);
800 test_helpers_fail_if_no_assert_failed();
801}
802
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100803void xlat_get_llt_from_va_tc6(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100804{
805 struct xlat_ctx ctx;
806 struct xlat_ctx_cfg cfg;
807 struct xlat_ctx_tbls tbls;
808 struct xlat_llt_info tbl_info;
809 struct xlat_mmap_region init_mmap;
810 uint64_t test_va;
811
812 /***************************************************************
813 * TEST CASE 6:
814 *
815 * Try calling xlat_get_llt_from_va() with a NULL
816 * xlat_ctx_cfg structure.
817 ***************************************************************/
818
819 xlat_get_llt_from_va_prepare_assertion(&ctx, &cfg, &tbls, &init_mmap);
820 memset((void *)&tbl_info, 0, sizeof(struct xlat_llt_info));
821
822 test_va = ctx.cfg->base_va + init_mmap.base_va;
823
824 /* Test xlat_get_llt_from_va: NULL xlat_ctx.cfg */
825 ctx.cfg = NULL;
826 test_helpers_expect_assert_fail(true);
827 (void)xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
828 test_helpers_fail_if_no_assert_failed();
829}
830
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100831void xlat_get_llt_from_va_tc7(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100832{
833 struct xlat_ctx ctx;
834 struct xlat_ctx_cfg cfg;
835 struct xlat_ctx_tbls tbls;
836 struct xlat_llt_info tbl_info;
837 struct xlat_mmap_region init_mmap;
838 uint64_t test_va;
839
840 /***************************************************************
841 * TEST CASE 7:
842 *
843 * Try calling xlat_get_llt_from_va() with a NULL
844 * xlat_ctx_tbls structure.
845 ***************************************************************/
846
847 xlat_get_llt_from_va_prepare_assertion(&ctx, &cfg, &tbls, &init_mmap);
848 memset((void *)&tbl_info, 0, sizeof(struct xlat_llt_info));
849
850 test_va = ctx.cfg->base_va + init_mmap.base_va;
851
852 /* Test xlat_get_llt_from_va: NULL xlat_ctx.tbls */
853 ctx.tbls = NULL;
854 test_helpers_expect_assert_fail(true);
855 (void)xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
856 test_helpers_fail_if_no_assert_failed();
857}
858
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100859void xlat_get_llt_from_va_tc8(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100860{
861 struct xlat_ctx ctx;
862 struct xlat_ctx_cfg cfg;
863 struct xlat_ctx_tbls tbls;
864 struct xlat_llt_info tbl_info;
865 struct xlat_mmap_region init_mmap;
866 uint64_t test_va;
867
868 /***************************************************************
869 * TEST CASE 8:
870 *
871 * Try calling xlat_get_llt_from_va() with an uninitialized
872 * xlat_ctx_cfg structure.
873 * Perform a full initialization of the context and then force
874 * 'ctx.cfg->initialized' to 'false' so we can ensure that
875 * this is what it is actually tested.
876 ***************************************************************/
877
878 xlat_get_llt_from_va_prepare_assertion(&ctx, &cfg, &tbls, &init_mmap);
879 memset((void *)&tbl_info, 0, sizeof(struct xlat_llt_info));
880
881 test_va = ctx.cfg->base_va + init_mmap.base_va;
882
883 /* Mark the cfg structure as not initialized */
Aliyha Ajmal7f9ee6e2024-10-10 10:44:17 +0100884 cfg.init = false;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100885
886 test_helpers_expect_assert_fail(true);
887 (void)xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
888 test_helpers_fail_if_no_assert_failed();
889}
890
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100891void xlat_get_llt_from_va_tc9(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100892{
893 struct xlat_ctx ctx;
894 struct xlat_ctx_cfg cfg;
895 struct xlat_ctx_tbls tbls;
896 struct xlat_llt_info tbl_info;
897 struct xlat_mmap_region init_mmap;
898 uint64_t test_va;
899
900 /***************************************************************
901 * TEST CASE 9:
902 *
903 * Try calling xlat_get_llt_from_va() with an uninitialized
904 * xlat_ctx_tbls structure.
905 * Perform a full initialization of the context and then force
906 * 'ctx.tbls->initialized' to 'false' so we can ensure that
907 * this is what it is actually tested.
908 ***************************************************************/
909
910 xlat_get_llt_from_va_prepare_assertion(&ctx, &cfg, &tbls, &init_mmap);
911 memset((void *)&tbl_info, 0, sizeof(struct xlat_llt_info));
912
913 test_va = ctx.cfg->base_va + init_mmap.base_va;
914
915 /* Mark the tbls structure as not initialized */
Aliyha Ajmal7f9ee6e2024-10-10 10:44:17 +0100916 tbls.init = false;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100917
918 test_helpers_expect_assert_fail(true);
919 (void)xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
920 test_helpers_fail_if_no_assert_failed();
921}
922
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +0100923void xlat_get_tte_ptr_tc1(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100924{
925 struct xlat_ctx ctx;
926 struct xlat_ctx_cfg cfg;
927 struct xlat_ctx_tbls tbls;
928 struct xlat_llt_info tbl_info;
929 struct xlat_mmap_region init_mmap[3U];
930 unsigned int tbl_idx[3U];
931 uint64_t start_va, test_va;
932 xlat_addr_region_id_t va_region;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100933 unsigned int index;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100934 uint64_t *tte_ptr, *val_tte, *table;
935 uint64_t tte;
936 size_t granularity;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100937 int base_lvl, end_lvl;
938 int level, retval;
939 uint64_t max_va_size = XLAT_TEST_MAX_VA_SIZE();
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100940
941 /***************************************************************
942 * TEST CASE 1:
943 *
944 * Initialize a translation context with a given VA space and
945 * 3 mmap regions at level 3. Then get a tte using
946 * xlat_get_tte_ptr() and verify that it is the correct entry.
947 *
948 * This test tries three different mmap areas per VA region:
949 *
Soby Mathewbddaba12023-04-22 03:34:00 +0000950 * - An address corresponding to the first entry at a
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100951 * last level table.
952 * - An address corresponding to the last entry at a
953 * last level table.
954 * - An address corresponding to an intermediate entry
955 * at a last level table.
956 *
Soby Mathewbddaba12023-04-22 03:34:00 +0000957 * The test also tests 2 negative cases :
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100958 * 1. It tries to get the TTE via xlat_get_tte() for a lower
959 * VA than the base VA.
960 * 2. It tries to get the TTE for a higher VA than is mapped
961 * by the last level table.
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100962 ***************************************************************/
963
964 /*
965 * Pick up a base and end levels for the translation tables.
966 * The leves are arbitrary. Just to have a VA space enough
967 * for the tests.
968 */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100969 base_lvl = XLAT_TEST_MIN_LVL();
970 end_lvl = 3;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100971
972 for (int i = 0U; i < VA_REGIONS; i++) {
973 va_region = (xlat_addr_region_id_t)i;
974
975 /* Clean the data structures */
976 memset((void *)&ctx, 0, sizeof(struct xlat_ctx));
977 memset((void *)&cfg, 0, sizeof(struct xlat_ctx_cfg));
978 memset((void *)&tbls, 0, sizeof(struct xlat_ctx_tbls));
979 memset((void *)&tbl_info, 0, sizeof(struct xlat_llt_info));
980
981 /* VA space boundaries */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100982 start_va = xlat_test_helpers_get_start_va(va_region, max_va_size);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100983
984 /* Generate the mmap regions */
985 retval = gen_mmap_array_by_level(&init_mmap[0U],
986 &tbl_idx[0U],
987 3U, base_lvl, end_lvl,
988 &granularity,
989 start_va, true);
990
991 /* Ensure that so far the test setup is OK */
992 CHECK_TRUE(retval == 0);
993
994 retval = xlat_ctx_cfg_init(&cfg, va_region, &init_mmap[0U], 3U,
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +0100995 max_va_size);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +0100996
997 /* Ensure that so far the test setup is OK */
998 CHECK_TRUE(retval == 0);
999
1000 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
1001 xlat_test_helpers_tbls(),
1002 XLAT_TESTS_MAX_TABLES);
1003
1004 /* Ensure that so far the test setup is OK */
1005 CHECK_TRUE(retval == 0);
1006
1007 /* Get the xlat_llt_info structure used to look for TTEs */
1008 test_va = ctx.cfg->base_va + init_mmap[0].base_va;
1009 retval = xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
1010
1011 /* Ensure that so far the test setup is OK */
1012 CHECK_TRUE(retval == 0);
1013
1014 /*
1015 * Iterate over test VAs of all 3 mmap regions to
1016 * test xlat_get_tte_ptr().
1017 */
1018 VERBOSE("\n");
1019 for (unsigned int i = 0U; i < 3U; i++) {
1020 /*
1021 * Get the xlat_llt_info structure used
1022 * to look for TTEs.
1023 */
1024 test_va = ctx.cfg->base_va + init_mmap[i].base_va;
1025 retval = xlat_get_llt_from_va(&tbl_info,
1026 &ctx, test_va);
1027
1028 /* Ensure that so far the test setup is OK */
1029 CHECK_TRUE(retval == 0);
1030
1031 /*
1032 * Add a random offset to the current 'test_va'
1033 * to be used for the tests.
1034 */
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001035 test_va += test_helpers_get_rand_in_range(0UL,
1036 PAGE_SIZE - 1);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001037
1038 /*
1039 * Perform a table walk to get the table containing
1040 * the tte we are insterested in as well as the
1041 * index of that tte in the table.
1042 */
1043 retval = xlat_test_helpers_table_walk(&ctx, test_va,
1044 &tte, &table,
1045 &level, &index);
1046 /* Ensure that so far the test setup is OK */
1047 CHECK_TRUE(retval == 0);
1048
1049 /* Get a pointer to the expected tte */
1050 val_tte = &table[index];
1051
1052 /* Test xlat_get_tte_ptr() */
1053 tte_ptr = xlat_get_tte_ptr(&tbl_info, test_va);
1054
1055 /* Validate the output */
1056 CHECK_VERBOSE((val_tte == tte_ptr),
1057 "Testing VA 0x%lx", test_va);
1058 }
1059
1060 /*
1061 * test xlat_get_tte_ptr() agains a VA below the minimum
1062 * VA mapped by 'tbl_info'. Use init_mmap[1] for this test.
1063 */
1064 test_va = ctx.cfg->base_va + init_mmap[1U].base_va;
1065 retval = xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
1066
1067 /* Ensure that so far the test setup is OK */
1068 CHECK_TRUE(retval == 0);
1069
1070 test_va = tbl_info.llt_base_va;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001071 test_va -= test_helpers_get_rand_in_range(1UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001072
1073 tte_ptr = xlat_get_tte_ptr(&tbl_info, test_va);
1074
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001075 /* Validate the output */
1076 CHECK_VERBOSE((tte_ptr == NULL),
1077 "Check address 0x%lx against TT at VA 0x%lx",
1078 test_va, tbl_info.llt_base_va);
1079
Soby Mathewbddaba12023-04-22 03:34:00 +00001080 /*
1081 * test xlat_get_tte_ptr() against a VA above the max
1082 * VA mapped by 'tbl_info'. Use init_mmap[0] for this test.
1083 */
1084 test_va = ctx.cfg->base_va + init_mmap[0U].base_va;
1085 retval = xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
1086
1087 /* Ensure that so far the test setup is OK */
1088 CHECK_TRUE(retval == 0);
1089
1090 test_va = tbl_info.llt_base_va + XLAT_BLOCK_SIZE(tbl_info.level - 1);
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001091 test_va += test_helpers_get_rand_in_range(1UL, PAGE_SIZE - 1UL);
Soby Mathewbddaba12023-04-22 03:34:00 +00001092
1093 tte_ptr = xlat_get_tte_ptr(&tbl_info, test_va);
1094
1095 /* Validate the output */
1096 CHECK_VERBOSE((tte_ptr == NULL),
1097 "Check address 0x%lx against TT at VA 0x%lx",
1098 test_va, tbl_info.llt_base_va);
1099
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001100 VERBOSE("\n");
1101 }
1102}
1103
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01001104void xlat_get_tte_ptr_tc2(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001105{
1106 /***************************************************************
1107 * TEST CASE 2:
1108 *
1109 * Try to get a tte using xlat_get_tte() with a NULL
1110 * xlat_llt_info structure.
1111 ***************************************************************/
1112
1113 test_helpers_expect_assert_fail(true);
1114 (void)xlat_get_tte_ptr(NULL, 0ULL);
1115 test_helpers_fail_if_no_assert_failed();
1116}
1117
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01001118void xlat_get_tte_ptr_tc3(void)
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001119{
1120 struct xlat_ctx ctx;
1121 struct xlat_ctx_cfg cfg;
1122 struct xlat_ctx_tbls tbls;
1123 struct xlat_llt_info tbl_info;
1124 struct xlat_mmap_region init_mmap;
1125 uint64_t test_va;
1126
1127 /***************************************************************
1128 * TEST CASE 3:
1129 *
1130 * Try to get a tte using xlat_get_tte() in which 'level' is
1131 * below the minimum for the current architecture implementation.
1132 ***************************************************************/
1133
1134 xlat_get_llt_from_va_prepare_assertion(&ctx, &cfg, &tbls, &init_mmap);
1135 memset((void *)&tbl_info, 0, sizeof(struct xlat_llt_info));
1136
1137 test_va = ctx.cfg->base_va + init_mmap.base_va;
1138
1139 /* Override the xlat_llt_info structure's level field */
1140 tbl_info.level = XLAT_TABLE_LEVEL_MIN - 1;
1141
1142 test_helpers_expect_assert_fail(true);
1143 (void)xlat_get_tte_ptr(&tbl_info, test_va);
1144 test_helpers_fail_if_no_assert_failed();
1145}
1146
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01001147void xlat_get_tte_ptr_tc4(void)
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001148{
1149 struct xlat_ctx ctx;
1150 struct xlat_ctx_cfg cfg;
1151 struct xlat_ctx_tbls tbls;
1152 struct xlat_llt_info tbl_info;
1153 struct xlat_mmap_region init_mmap;
1154 uint64_t test_va;
1155
1156 /***************************************************************
1157 * TEST CASE 4:
1158 *
1159 * Try to get a tte using xlat_get_tte() in which 'level' is
1160 * above the maximum for the current architecture implementation.
1161 ***************************************************************/
1162
1163 xlat_get_llt_from_va_prepare_assertion(&ctx, &cfg, &tbls, &init_mmap);
1164 memset((void *)&tbl_info, 0, sizeof(struct xlat_llt_info));
1165
1166 test_va = ctx.cfg->base_va + init_mmap.base_va;
1167
1168 /* Override the xlat_llt_info structure's level field */
1169 tbl_info.level = XLAT_TABLE_LEVEL_MAX + 1;
1170
1171 test_helpers_expect_assert_fail(true);
1172 (void)xlat_get_tte_ptr(&tbl_info, test_va);
1173 test_helpers_fail_if_no_assert_failed();
1174}
1175
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01001176void xlat_unmap_memory_page_tc1(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001177{
1178 struct xlat_ctx ctx;
1179 struct xlat_ctx_cfg cfg;
1180 struct xlat_ctx_tbls tbls;
1181 uint64_t start_va;
1182 size_t va_size, granularity;
1183 unsigned int mmap_count;
1184 xlat_addr_region_id_t va_region;
1185 int retval;
1186 struct xlat_mmap_region init_mmap[3U];
1187 unsigned int tbl_idx[3U];
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001188 int base_lvl, end_lvl;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001189
1190 /***************************************************************
1191 * TEST CASE 1:
1192 *
1193 * For each possible end lookup level, create a set transient
1194 * valid random mappings.
1195 *
1196 * For each possible (va_region, end_lvl) tuple, there will be
1197 * three mmap regions created:
1198 *
1199 * - First region mapped at the beginning of a table whose
1200 * final lookup level is 'end_lvl'
1201 * - Second region mapped at a random tte of a table whose
1202 * final lookup level is 'end_lvl'
1203 * - Third region mapped at the end of a table whose
1204 * final lookup level is 'end_lvl'
1205 *
1206 * Then verify that the tables can be unmapped and that the
1207 * resulting tte will contain a transient invalid entry.
1208 ***************************************************************/
1209
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001210 mmap_count = 3;
1211 base_lvl = XLAT_TEST_MIN_LVL();
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001212
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01001213 end_lvl = XLAT_MIN_BLOCK_LVL();
1214 for (; end_lvl <= XLAT_TABLE_LEVEL_MAX; end_lvl++) {
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001215 for (int i = 0U; i < VA_REGIONS; i++) {
1216 va_region = (xlat_addr_region_id_t)i;
1217
1218 start_va = gen_va_space_params_by_lvl(base_lvl,
1219 va_region,
1220 &va_size);
1221
1222 retval = gen_mmap_array_by_level(&init_mmap[0U],
1223 &tbl_idx[0U],
1224 mmap_count,
1225 base_lvl,
1226 end_lvl,
1227 &granularity,
1228 start_va,
1229 false);
1230
1231 /* Verify that the test setup is correct so far */
1232 CHECK_TRUE(retval == 0);
1233
1234 /* Clean the data structures */
1235 memset((void *)&ctx, 0, sizeof(struct xlat_ctx));
1236 memset((void *)&cfg, 0, sizeof(struct xlat_ctx_cfg));
1237 memset((void *)&tbls, 0, sizeof(struct xlat_ctx_tbls));
1238
1239 /* Initialize the test structure */
1240 retval = xlat_ctx_cfg_init(&cfg, va_region,
1241 &init_mmap[0U],
1242 mmap_count, va_size);
1243
1244 /* Verify that the test setup is correct so far */
1245 CHECK_TRUE(retval == 0);
1246
1247 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
1248 xlat_test_helpers_tbls(),
1249 XLAT_TESTS_MAX_TABLES);
1250
1251 /* Verify that the test setup is correct so far */
1252 CHECK_TRUE(retval == 0);
1253
1254 /*
1255 * For each one of the mmap regions:
1256 * - get the TTE of a random VA and make it transient
1257 * - call xlat_unmap_memory_page() over the same VA
1258 * - verify that the TTE is now transient invalid.
1259 */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001260 for (unsigned int j = 0U; j < mmap_count; j++) {
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001261 uint64_t tte;
1262 uint64_t *tbl_ptr;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001263 unsigned int tte_idx;
1264 int tte_lvl;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001265 struct xlat_llt_info tbl_info;
1266 uint64_t offset =
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001267 test_helpers_get_rand_in_range(0UL,
1268 PAGE_SIZE - 1);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001269 uint64_t test_va = init_mmap[j].base_va +
1270 ctx.cfg->base_va + offset;
1271
1272 /*
1273 * Perform a table walk to retrieve the table
1274 * where the VA is mapped along with the index
1275 * of the TTE within the table.
1276 */
1277 retval = xlat_test_helpers_table_walk(&ctx,
1278 test_va, &tte,
1279 &tbl_ptr, &tte_lvl,
1280 &tte_idx);
1281
1282 /*
1283 * Verify that the test setup is correct so far
1284 */
1285 CHECK_TRUE(retval == 0);
1286
1287 /*
1288 * The TTE is expected to be valid. Make it
1289 * transient valid within the table.
1290 */
1291 tbl_ptr[tte_idx] |=
1292 (1ULL << TRANSIENT_FLAG_SHIFT);
1293
1294 /*
1295 * Retrieve the xlat_llt_info structure needed
1296 * to feed xlat_unmap_memory_page()
1297 */
1298 retval = xlat_get_llt_from_va(&tbl_info, &ctx,
1299 test_va);
1300
1301 /*
1302 * Verify that the test setup is correct so far
1303 */
1304 CHECK_TRUE(retval == 0);
1305
1306 /*
1307 * Try to unmap the page/block
1308 * containing `test_va`
1309 */
1310 retval = xlat_unmap_memory_page(&tbl_info,
1311 test_va);
1312
1313 /* Verify that the return is as expected */
1314 CHECK_TRUE(retval == 0);
1315
1316 /*
1317 * Verify that the TTE is marked as transient
1318 * invalid.
1319 */
1320 CHECK_VERBOSE((tbl_ptr[tte_idx] ==
1321 TRANSIENT_DESC),
1322 "Verifying TTE for VA 0x%lx is marked as Transient Invalid",
1323 test_va);
1324 }
1325 VERBOSE("\n");
1326 }
1327 }
1328}
1329
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01001330void xlat_unmap_memory_page_tc2(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001331{
1332 struct xlat_ctx ctx;
1333 struct xlat_ctx_cfg cfg;
1334 struct xlat_ctx_tbls tbls;
1335 uint64_t start_va, test_va;
1336 size_t va_size, granularity;
1337 unsigned int mmap_count;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001338 unsigned int tte_idx;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001339 xlat_addr_region_id_t va_region;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001340 int retval, tte_lvl;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001341 struct xlat_mmap_region init_mmap[3U];
1342 unsigned int tbl_idx[3U];
1343 struct xlat_llt_info tbl_info;
1344 uint64_t tte, val_tte;
1345 uint64_t *tbl_ptr;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001346 int base_lvl, end_lvl;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001347
1348 /***************************************************************
1349 * TEST CASE 2:
1350 *
1351 * Generate a mmap region with a set of transient valid
1352 * mappings. Then run a set of negative tests:
1353 *
1354 * - Try addresses below and above the range mapped by the
1355 * xlat_llt_info structure on a transient-valid entry.
1356 * - Try unmapping from a valid non-transient entry.
1357 * - Try unmapping from an invalid entry.
1358 ***************************************************************/
1359
1360 /*
1361 * Pick up a base and end levels for the translation tables.
1362 * The leves are arbitrary. Just to have a VA space enough
1363 * for the tests.
1364 */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001365 base_lvl = XLAT_TEST_MIN_LVL();
1366 end_lvl = 3;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001367
1368 mmap_count = 3U;
1369
1370 for (int i = 0U; i < VA_REGIONS; i++) {
1371 va_region = (xlat_addr_region_id_t)i;
1372
1373 start_va = gen_va_space_params_by_lvl(base_lvl,
1374 va_region, &va_size);
1375
1376 /*
1377 * We generate the mmap regions to use. We will be interested
1378 * in init_mmap[1].
1379 */
1380 retval = gen_mmap_array_by_level(&init_mmap[0U], &tbl_idx[0U],
1381 mmap_count, base_lvl, end_lvl,
1382 &granularity,
1383 start_va, false);
1384
1385 /* Verify that the test setup is correct so far */
1386 CHECK_TRUE(retval == 0);
1387
1388 /* Clean the data structures */
1389 memset((void *)&ctx, 0, sizeof(struct xlat_ctx));
1390 memset((void *)&cfg, 0, sizeof(struct xlat_ctx_cfg));
1391 memset((void *)&tbls, 0, sizeof(struct xlat_ctx_tbls));
1392
1393 /* Initialize the test structure */
1394 retval = xlat_ctx_cfg_init(&cfg, va_region, &init_mmap[0U],
1395 mmap_count, va_size);
1396
1397 /* Verify that the test setup is correct so far */
1398 CHECK_TRUE(retval == 0);
1399
1400 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
1401 xlat_test_helpers_tbls(),
1402 XLAT_TESTS_MAX_TABLES);
1403
1404 /* Verify that the test setup is correct so far */
1405 CHECK_TRUE(retval == 0);
1406
1407 /*
1408 * Make the TTEs of the mapped region, which is expected
1409 * to be valid, transient valid.
1410 */
1411 test_va = init_mmap[1U].base_va + ctx.cfg->base_va;
1412
1413 /*
1414 * Perform a table walk to retrieve the table where the VA
1415 * is mapped along with the index of the TTE within the table.
1416 */
1417 retval = xlat_test_helpers_table_walk(&ctx, test_va, &tte,
1418 &tbl_ptr, &tte_lvl,
1419 &tte_idx);
1420
1421 /* Verify that the test setup is correct so far */
1422 CHECK_TRUE(retval == 0);
1423
1424 /*
1425 * The TTE is expected to be valid. Make it
1426 * transient valid within the table.
1427 */
1428 tbl_ptr[tte_idx] |= (1ULL << TRANSIENT_FLAG_SHIFT);
1429 val_tte = tbl_ptr[tte_idx];
1430
1431 /*
1432 * Retrieve the xlat_llt_info structure needed to feed
1433 * xlat_unmap_memory_page().
1434 */
1435 retval = xlat_get_llt_from_va(&tbl_info, &ctx,
1436 init_mmap[1U].base_pa + ctx.cfg->base_va);
1437
1438 /* Verify that the test setup is correct so far */
1439 CHECK_TRUE(retval == 0);
1440
1441 /*
1442 * Test xlat_unmmap_memory_page() with a valid address
1443 * below the start of init_mmap[0U]. This gives us an address
1444 * below the range mapped by table we retrieved.
1445 */
1446 test_va = init_mmap[0U].base_va + ctx.cfg->base_va;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001447 test_va -= test_helpers_get_rand_in_range(1UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001448
1449 /* Try to unmap the page/block containing `test_va` */
1450 retval = xlat_unmap_memory_page(&tbl_info, test_va);
1451
1452 /* Verify that the return is as expected */
1453 CHECK_VERBOSE((retval == -EFAULT),
1454 "Testing VA 0x%lx on TTE for VA 0x%lx",
1455 test_va,
1456 init_mmap[1U].base_va + ctx.cfg->base_va);
1457
1458 /* Verify that the TTE remains unchanged */
1459 CHECK_EQUAL(val_tte, tbl_ptr[tte_idx]);
1460
1461 /*
1462 * Repeat the process, this time with an address on a page
1463 * after the one mapped by init_mmap[2U]. This gives us an
1464 * address over the range mapped by table we retrieved.
1465 */
1466 test_va = init_mmap[2U].base_va + ctx.cfg->base_va;
1467 test_va += PAGE_SIZE;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001468 test_va += test_helpers_get_rand_in_range(0UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001469
1470 /* Try to unmap the page/block containing `test_va` */
1471 retval = xlat_unmap_memory_page(&tbl_info, test_va);
1472
1473 /* Verify that the return is as expected */
1474 CHECK_VERBOSE((retval == -EFAULT),
1475 "Testing VA 0x%lx on TTE for VA 0x%lx",
1476 test_va,
1477 init_mmap[2U].base_va + ctx.cfg->base_va);
1478
1479 /* Verify that the TTE remains unchanged */
1480 CHECK_EQUAL(val_tte, tbl_ptr[tte_idx]);
1481
1482 /*
1483 * Try to unmap an address marked as non-transient
1484 */
1485 tbl_ptr[tte_idx] &= ~(MASK(TRANSIENT_FLAG));
1486 val_tte = tbl_ptr[tte_idx];
1487
1488 test_va = init_mmap[1U].base_va + ctx.cfg->base_va;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001489 test_va += test_helpers_get_rand_in_range(0UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001490
1491 /* Try to unmap the page/block containing `test_va` */
1492 retval = xlat_unmap_memory_page(&tbl_info, test_va);
1493
1494 /* Verify that the return is as expected */
1495 CHECK_VERBOSE((retval == -EFAULT),
1496 "Testing VA 0x%lx on a non-transient valid TTE",
1497 test_va);
1498
1499 /* Verify that the TTE remains unchanged */
1500 CHECK_EQUAL(val_tte, tbl_ptr[tte_idx]);
1501
1502 /*
1503 * Try to unmap an address marked as invalid.
1504 */
1505 tbl_ptr[tte_idx] = INVALID_DESC;
1506 val_tte = tbl_ptr[tte_idx];
1507
1508 test_va = init_mmap[1U].base_va + ctx.cfg->base_va;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001509 test_va += test_helpers_get_rand_in_range(0UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001510
1511 /* Try to unmap the page/block containing `test_va` */
1512 retval = xlat_unmap_memory_page(&tbl_info, test_va);
1513
1514 /* Verify that the return is as expected */
1515 CHECK_VERBOSE((retval == -EFAULT),
1516 "Testing VA 0x%lx on a ninvalid TTE",
1517 test_va);
1518
1519 /* Verify that the TTE remains unchanged */
1520 CHECK_EQUAL(val_tte, tbl_ptr[tte_idx]);
1521 VERBOSE("\n");
1522 }
1523}
1524
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01001525void xlat_unmap_memory_page_tc3(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001526{
1527 /***************************************************************
1528 * TEST CASE 3:
1529 *
1530 * Try calling xlat_unmap_memory_page with a NULL
1531 * xlat_llt_info structure.
1532 ***************************************************************/
1533
1534 test_helpers_expect_assert_fail(true);
1535 (void)xlat_unmap_memory_page(NULL, 0ULL);
1536 test_helpers_fail_if_no_assert_failed();
1537}
1538
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01001539void xlat_map_memory_page_with_attrs_tc1(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001540{
1541 struct xlat_ctx ctx;
1542 struct xlat_ctx_cfg cfg;
1543 struct xlat_ctx_tbls tbls;
1544 uint64_t start_va;
1545 size_t va_size, granularity;
1546 unsigned int mmap_count;
1547 xlat_addr_region_id_t va_region;
1548 int retval;
1549 struct xlat_mmap_region init_mmap[3U];
1550 unsigned int tbl_idx[3U];
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001551 int base_lvl, end_lvl;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001552
1553 /***************************************************************
1554 * TEST CASE 1:
1555 *
1556 * For each possible end lookup level, create a set transient
1557 * random mappings.
1558 *
1559 * For each possible (va_region, end_lvl) tuple, there will be three
1560 * mmap regions created:
1561 *
1562 * - First region mapped at the beginning of a table whose
1563 * final lookup level is 'end_lvl'
1564 * - Second region mapped at a random index of a table whose
1565 * final lookup level is 'end_lvl'
1566 * - Third region mapped at the end of a table whose
1567 * final lookup level is 'end_lvl'
1568 *
1569 * Then verify that we can map PA areas into the transient
1570 * entries using random attributes and that the generated
1571 * entry is valid.
1572 ***************************************************************/
1573
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001574 mmap_count = 3;
1575 base_lvl = XLAT_TEST_MIN_LVL();
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001576
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01001577 end_lvl = XLAT_MIN_BLOCK_LVL();
1578 for (; end_lvl <= XLAT_TABLE_LEVEL_MAX; end_lvl++) {
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001579 for (int i = 0U; i < VA_REGIONS; i++) {
1580 va_region = (xlat_addr_region_id_t)i;
1581
1582 start_va = gen_va_space_params_by_lvl(base_lvl,
1583 va_region,
1584 &va_size);
1585
1586 retval = gen_mmap_array_by_level(&init_mmap[0U],
1587 &tbl_idx[0U],
1588 mmap_count,
1589 base_lvl,
1590 end_lvl,
1591 &granularity,
1592 start_va,
1593 false);
1594
1595 /* Verify that the test setup is correct so far */
1596 CHECK_TRUE(retval == 0);
1597
1598 /* Force all the mmap regions to be TRANSIENT */
1599 for (unsigned int j = 0U; j < mmap_count; j++) {
1600 init_mmap[j].attr = MT_TRANSIENT;
1601 }
1602
1603 /* Clean the data structures */
1604 memset((void *)&ctx, 0, sizeof(struct xlat_ctx));
1605 memset((void *)&cfg, 0, sizeof(struct xlat_ctx_cfg));
1606 memset((void *)&tbls, 0, sizeof(struct xlat_ctx_tbls));
1607
1608 /* Initialize the test structure */
1609 retval = xlat_ctx_cfg_init(&cfg, va_region,
1610 &init_mmap[0U],
1611 mmap_count, va_size);
1612
1613 /* Verify that the test setup is correct so far */
1614 CHECK_TRUE(retval == 0);
1615
1616 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
1617 xlat_test_helpers_tbls(),
1618 XLAT_TESTS_MAX_TABLES);
1619
1620 /* Verify that the test setup is correct so far */
1621 CHECK_TRUE(retval == 0);
1622
1623 /*
1624 * For each one of the mmap regions:
1625 * - Generate a random VA within the mmap VA space.
1626 * - generate a set of random attributes.
1627 * - Map a random PA to the generated VA and with
1628 * the generated attributes.
1629 * - call xlat_unmap_memory_page_map_with_attrs() to
1630 * create the mapping.
1631 * - verify that the new entry is valid.
1632 */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001633 for (unsigned int j = 0U; j < mmap_count; j++) {
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001634 uint64_t tte, val_tte, attrs, pa, type;
1635 uint64_t *tbl_ptr;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001636 unsigned int tte_idx;
1637 int tte_lvl;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001638 struct xlat_llt_info tbl_info;
1639 uint64_t offset =
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001640 test_helpers_get_rand_in_range(0UL,
1641 init_mmap[i].size - 1);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001642 uint64_t test_va = init_mmap[j].base_va +
1643 ctx.cfg->base_va + offset;
1644
1645 /*
1646 * Perform a table walk to retrieve the table
1647 * where the VA is mapped along with the index
1648 * of the TTE within the table.
1649 */
1650 retval = xlat_test_helpers_table_walk(&ctx,
1651 test_va, &tte,
1652 &tbl_ptr, &tte_lvl,
1653 &tte_idx);
1654
1655 /*
1656 * Verify that the test setup is correct so far
1657 */
1658 CHECK_TRUE(retval == 0);
1659
1660 /* Generate a random set of attributes. */
1661 do {
Mate Toth-Pal3f0a8ae2024-08-01 11:09:56 +02001662 attrs = xlat_test_helpers_rand_mmap_attrs(true);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001663 } while (attrs == MT_TRANSIENT);
1664
1665 /*
1666 * Generate the validation TTE. For convenience,
1667 * create an identity mapping.
1668 */
1669 retval = xlat_test_helpers_gen_attrs(&val_tte,
1670 attrs);
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001671 pa = init_mmap[j].base_va & XLAT_TEST_GET_PA_MASK();
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001672
1673 /*
1674 * Add an arbitrary offset to PA to be passed to
1675 * xlat_map_memory_page_with_attrs()
1676 */
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001677 pa += test_helpers_get_rand_in_range(1UL,
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001678 XLAT_BLOCK_SIZE(end_lvl) - 1);
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001679 val_tte |= set_oa_to_tte(pa &
1680 XLAT_ADDR_MASK(end_lvl));
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001681
1682 /* The TTE will be a transient one */
1683 val_tte |= (1ULL <<
1684 TRANSIENT_FLAG_SHIFT);
1685
1686 /* TTE type */
1687 type = (end_lvl == XLAT_TABLE_LEVEL_MAX) ?
1688 PAGE_DESC :
1689 BLOCK_DESC;
1690 val_tte |= type;
1691
1692 /* Verify the test setup */
1693 CHECK_TRUE(retval == 0);
1694
1695 /*
1696 * Retrieve the xlat_llt_info structure needed
1697 * to feed xlat_map_memory_page_with_attrs()
1698 */
1699 retval = xlat_get_llt_from_va(&tbl_info, &ctx,
1700 test_va);
1701
1702 /*
1703 * Verify that the test setup is correct so far
1704 */
1705 CHECK_TRUE(retval == 0);
1706
1707 /*
1708 * Try to map the PA with the attributes to the
1709 * `test_va`
1710 */
1711 retval = xlat_map_memory_page_with_attrs(
1712 &tbl_info,
1713 test_va, pa, attrs);
1714
1715 /* Verify that the return is as expected */
1716 CHECK_VERBOSE((retval == 0),
1717 "Mapping PA 0x%.16lx to VA 0x%.16lx with attrs 0x%lx",
1718 pa, test_va, attrs);
1719 CHECK_TRUE(retval == 0);
1720
1721 /*
1722 * Verify that the generated TTE matches
1723 * the validation one.
1724 */
1725 CHECK_VERBOSE((val_tte == tbl_ptr[tte_idx]),
1726 "Verifying TTE 0x%.16lx against 0x%.16lx",
1727 tbl_ptr[tte_idx], val_tte);
1728 }
1729 VERBOSE("\n");
1730 }
1731 }
1732}
1733
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01001734void xlat_map_memory_page_with_attrs_tc2(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001735{
1736 struct xlat_ctx ctx;
1737 struct xlat_ctx_cfg cfg;
1738 struct xlat_ctx_tbls tbls;
1739 uint64_t start_va, test_va, test_pa;
1740 size_t va_size, granularity;
1741 unsigned int mmap_count;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001742 unsigned int tte_idx;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001743 xlat_addr_region_id_t va_region;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001744 int tte_lvl, retval;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001745 struct xlat_mmap_region init_mmap[3U];
1746 unsigned int tbl_idx[3U];
1747 struct xlat_llt_info tbl_info;
1748 uint64_t tte, val_tte;
1749 uint64_t *tbl_ptr;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001750 int base_lvl, end_lvl;
Soby Mathew1eccd462024-10-21 13:36:34 +01001751 const unsigned int pa_range_bits_arr[] = {
1752 [0x0] = PARANGE_WIDTH_32BITS,
1753 [0x1] = PARANGE_WIDTH_36BITS,
1754 [0x2] = PARANGE_WIDTH_40BITS,
1755 [0x3] = PARANGE_WIDTH_42BITS,
1756 [0x4] = PARANGE_WIDTH_44BITS,
1757 [0x5] = PARANGE_WIDTH_48BITS,
1758 [0x6] = PARANGE_WIDTH_52BITS
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001759 };
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001760 unsigned int parange_index =
1761 (unsigned int)test_helpers_get_rand_in_range(0UL,
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001762 ARRAY_SIZE(pa_range_bits_arr) - 1U);
1763 uint64_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001764
1765 /***************************************************************
1766 * TEST CASE 2:
1767 *
1768 * Generate a mmap region with a set of transient invalid
1769 * mappings. Then run a set of negative tests:
1770 *
1771 * - Try addresses below and above the range mapped by the
1772 * xlat_llt_info structure on a transient-invalid entry.
1773 * - Try mapping a PA lager than the maximum supported PA
1774 * to a transient-invalid entry.
1775 * - Try mapping to a transient-valid entry.
1776 * - Try mapping to a valid entry.
1777 * - Try mapping to an invalid entry.
1778 ***************************************************************/
1779
1780 /*
1781 * Pick up a base and end levels for the translation tables.
1782 * The leves are arbitrary. Just to have a VA space enough
1783 * for the tests.
1784 */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001785 base_lvl = XLAT_TEST_MIN_LVL();
1786 end_lvl = 3;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001787
1788 mmap_count = 3U;
1789
1790 for (int i = 0U; i < VA_REGIONS; i++) {
1791 va_region = (xlat_addr_region_id_t)i;
1792
1793 start_va = gen_va_space_params_by_lvl(base_lvl,
1794 va_region, &va_size);
1795
1796 /*
1797 * We generate the mmap regions to use. We will be interested
1798 * in init_mmap[1] for the transient-invalid tests and in
1799 * init_mmap[2] for the rest of tests.
1800 */
1801 retval = gen_mmap_array_by_level(&init_mmap[0U], &tbl_idx[0U],
1802 mmap_count, base_lvl, end_lvl,
1803 &granularity,
1804 start_va, false);
1805
1806 /* Verify that the test setup is correct so far */
1807 CHECK_TRUE(retval == 0);
1808
1809 /* Force init_mmap[1] to be TRANSIENT */
1810 init_mmap[1U].attr = MT_TRANSIENT;
1811
1812 /* Clean the data structures */
1813 memset((void *)&ctx, 0, sizeof(struct xlat_ctx));
1814 memset((void *)&cfg, 0, sizeof(struct xlat_ctx_cfg));
1815 memset((void *)&tbls, 0, sizeof(struct xlat_ctx_tbls));
1816
1817 /* Initialize the test structure */
1818 retval = xlat_ctx_cfg_init(&cfg, va_region, &init_mmap[0U],
1819 mmap_count, va_size);
1820
1821 /* Verify that the test setup is correct so far */
1822 CHECK_TRUE(retval == 0);
1823
1824 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
1825 xlat_test_helpers_tbls(),
1826 XLAT_TESTS_MAX_TABLES);
1827
1828 /* Verify that the test setup is correct so far */
1829 CHECK_TRUE(retval == 0);
1830
1831 test_va = init_mmap[1U].base_va + ctx.cfg->base_va;
1832
1833 /*
1834 * Retrieve the xlat_llt_info structure needed to feed
1835 * xlat_map_memory_page_with_attrs().
1836 */
1837 retval = xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
1838
1839 /* Verify that the test setup is correct so far */
1840 CHECK_TRUE(retval == 0);
1841
1842 /*
1843 * Test xlat_map_memory_page_with_attrs() with a valid address
1844 * within init_mmap[0]. This gives us an address
1845 * below the range mapped by table we retrieved (which belongs
1846 * to init_mmap[1]). For simplicity, set the attributes and
1847 * the PA both to 0x0.
1848 */
1849 test_va = init_mmap[0U].base_va + ctx.cfg->base_va;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001850 test_va += test_helpers_get_rand_in_range(0UL,
1851 init_mmap[0U].size - 1);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001852
1853 /* Try to map to the page/block containing `test_va` */
1854 retval = xlat_map_memory_page_with_attrs(&tbl_info, test_va,
1855 0ULL, 0ULL);
1856
1857 /* Verify that the return is as expected */
1858 CHECK_VERBOSE((retval == -EFAULT),
1859 "Testing VA 0x%.16lx on TTE for VA 0x%.16lx",
1860 test_va,
1861 init_mmap[1U].base_va + ctx.cfg->base_va);
1862
1863 /*
1864 * Repeat the process, this time with an address on a page
1865 * mapped by init_mmap[2]. This gives us an
1866 * address over the range mapped by table we retrieved.
1867 */
1868 test_va = init_mmap[2U].base_va + ctx.cfg->base_va;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001869 test_va += test_helpers_get_rand_in_range(0UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001870
1871 /* Try to map to the page/block containing `test_va` */
1872 retval = xlat_map_memory_page_with_attrs(&tbl_info, test_va,
1873 0ULL, 0ULL);
1874
1875 /* Verify that the return is as expected */
1876 CHECK_VERBOSE((retval == -EFAULT),
1877 "Testing VA 0x%.16lx on TTE for VA 0x%.16lx",
1878 test_va,
1879 init_mmap[2U].base_va + ctx.cfg->base_va);
1880
1881 /*
1882 * Test with a PA larger than the maximum PA supported.
1883 */
1884
1885 /* Configure a random maximum PA supported */
Javier Almansa Sobrino2fa8abe2023-06-06 13:18:17 +01001886 xlat_test_helpers_set_parange(parange_index);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001887 test_pa =
1888 (1ULL << pa_range_bits_arr[parange_index]) + PAGE_SIZE;
1889
1890 test_va = init_mmap[1U].base_va + ctx.cfg->base_va;
1891
1892 /*
1893 * Perform a table walk to retrieve the table where the VA
1894 * is mapped along with the index of the TTE within the table.
1895 */
1896 retval = xlat_test_helpers_table_walk(&ctx, test_va, &tte,
1897 &tbl_ptr, &tte_lvl,
1898 &tte_idx);
1899
1900 /* Verify that the test setup is correct so far */
1901 CHECK_TRUE(retval == 0);
1902
1903 /*
1904 * Take a snapshot of the TTE. This will be used to verify
1905 * that the TTE hasn't been altered.
1906 */
1907 val_tte = tbl_ptr[tte_idx];
1908
1909 /* Get a random address to test */
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001910 test_va += test_helpers_get_rand_in_range(0UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001911
1912 /* Try to map the PA to the page/block containing `test_va` */
1913 retval = xlat_map_memory_page_with_attrs(&tbl_info, test_va,
1914 test_pa, 0ULL);
1915
1916 /* Verify that the return is as expected */
1917 CHECK_VERBOSE((retval == -EFAULT),
1918 "Testing PA 0x%.16lx on with a max supported PA of 0x%.16llx",
1919 test_pa,
1920 (1ULL << pa_range_bits_arr[parange_index]) - 1ULL);
1921
1922 /* Verify that the TTE remains unchanged */
1923 CHECK_EQUAL(val_tte, tbl_ptr[tte_idx]);
1924
1925 /* Restore the maximum supported PA size for next tests */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01001926 host_write_sysreg("id_aa64mmfr0_el1", id_aa64mmfr0_el1);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001927
1928 /* The rest of the tests will be based on init_mmap[2] */
1929 test_va = init_mmap[2U].base_va + ctx.cfg->base_va;
1930
1931 /*
1932 * Perform a table walk to retrieve the table where the VA
1933 * is mapped along with the index of the TTE within the table.
1934 */
1935 retval = xlat_test_helpers_table_walk(&ctx, test_va, &tte,
1936 &tbl_ptr, &tte_lvl,
1937 &tte_idx);
1938
1939 /* Verify that the test setup is correct so far */
1940 CHECK_TRUE(retval == 0);
1941
1942 /*
Soby Mathewbddaba12023-04-22 03:34:00 +00001943 * Retrieve the xlat_llt_info structure needed to feed
1944 * xlat_map_memory_page_with_attrs().
1945 */
1946 retval = xlat_get_llt_from_va(&tbl_info, &ctx, test_va);
1947
1948 /* Verify that the test setup is correct so far */
1949 CHECK_TRUE(retval == 0);
1950
1951 /*
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001952 * Make the TTEs of the mapped region, which is expected
1953 * to be valid, transient valid.
1954 */
1955 tbl_ptr[tte_idx] |= (1ULL << TRANSIENT_FLAG_SHIFT);
1956
1957 /*
1958 * Take a snapshot of the TTE. This will be used to verify
1959 * that the TTE hasn't been altered.
1960 */
1961 val_tte = tbl_ptr[tte_idx];
1962
1963 /*
Soby Mathewbddaba12023-04-22 03:34:00 +00001964 * Now try to map a valid VA. In this case the associated
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001965 * TTE will contain a transient valid mapping.
1966 */
1967 test_va = init_mmap[2U].base_va + ctx.cfg->base_va;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001968 test_va += test_helpers_get_rand_in_range(0UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001969
1970 /* Try to map to the page/block containing `test_va` */
1971 retval = xlat_map_memory_page_with_attrs(&tbl_info, test_va,
1972 0ULL, 0ULL);
1973
1974 /* Verify that the return is as expected */
1975 CHECK_VERBOSE((retval == -EFAULT),
1976 "Testing VA 0x%.16lx on a transient valid TTE",
1977 test_va);
1978
1979 /* Verify that the TTE remains unchanged */
1980 CHECK_EQUAL(val_tte, tbl_ptr[tte_idx]);
1981
1982 /*
1983 * Repeat the last test but after clearing the TRANSIENT
1984 * flag from the TTE. This will test the behaviour with
1985 * a non transient TTE.
1986 */
1987 tbl_ptr[tte_idx] &= ~(1ULL << TRANSIENT_FLAG_SHIFT);
1988 val_tte = tbl_ptr[tte_idx];
1989
1990 test_va = init_mmap[2U].base_va + ctx.cfg->base_va;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01001991 test_va += test_helpers_get_rand_in_range(0UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01001992
1993 /* Try to map to the page/block containing `test_va` */
1994 retval = xlat_map_memory_page_with_attrs(&tbl_info, test_va,
1995 0ULL, 0ULL);
1996
1997 /* Verify that the return is as expected */
1998 CHECK_VERBOSE((retval == -EFAULT),
1999 "Testing VA 0x%.16lx on a valid TTE",
2000 test_va);
2001
2002 /* Verify that the TTE remains unchanged */
2003 CHECK_EQUAL(val_tte, tbl_ptr[tte_idx]);
2004
2005 /*
2006 * Repeat the last test on an INVALID TTE.
2007 */
2008 tbl_ptr[tte_idx] = 0ULL;
2009 val_tte = 0ULL;
2010
2011 test_va = init_mmap[2U].base_va + ctx.cfg->base_va;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01002012 test_va += test_helpers_get_rand_in_range(0UL, PAGE_SIZE - 1UL);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002013
2014 /* Try to map to the page/block containing `test_va` */
2015 retval = xlat_map_memory_page_with_attrs(&tbl_info, test_va,
2016 0ULL, 0ULL);
2017
2018 /* Verify that the return is as expected */
2019 CHECK_VERBOSE((retval == -EFAULT),
2020 "Testing VA 0x%.16lx on an invalid TTE",
2021 test_va);
2022
2023 /* Verify that the TTE remains unchanged */
2024 CHECK_EQUAL(val_tte, tbl_ptr[tte_idx]);
2025
2026 VERBOSE("\n");
2027 }
2028}
2029
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01002030void xlat_map_memory_page_with_attrs_tc3(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002031{
2032 /***************************************************************
2033 * TEST CASE 3:
2034 *
2035 * Try calling xlat_map_memory_page_with_attrs with a NULL
2036 * xlat_llt_info structure.
2037 ***************************************************************/
2038
2039 test_helpers_expect_assert_fail(true);
2040 (void)xlat_map_memory_page_with_attrs(NULL, 0ULL, 0ULL, 0ULL);
2041 test_helpers_fail_if_no_assert_failed();
2042}
2043
2044/* Helper function to validate ttbrx_el2 registers */
2045static void validate_ttbrx_el2(struct xlat_ctx *ctx)
2046{
2047 uint64_t expected_ttbrx, ttbrx;
2048 xlat_addr_region_id_t va_region;
2049
2050 assert(ctx != NULL);
2051
2052 va_region = ctx->cfg->region;
2053
2054 /* BADDR */
2055 expected_ttbrx = ((uint64_t)&ctx->tbls->tables[0U]) &
2056 MASK(TTBRx_EL2_BADDR);
2057
2058 ttbrx = read_ttbr1_el2();
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002059 if (va_region == VA_LOW_REGION) {
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002060 ttbrx = read_ttbr0_el2();
2061
2062 /*
2063 * CnP bit. It is expected that the xlat library will
2064 * automatically set this bit for the low region.
2065 */
2066 expected_ttbrx |= (1ULL << TTBRx_EL2_CnP_SHIFT);
2067 }
2068
2069 CHECK_VERBOSE((expected_ttbrx == ttbrx),
2070 "Expected TTBR%c_EL2: 0x%lx - Received: 0x%lx",
2071 (unsigned int)va_region + '0',
2072 expected_ttbrx, ttbrx);
2073}
2074
2075/* Helper function to validate TCR_EL2 register */
2076static void validate_tcr_el2(struct xlat_ctx *low_ctx,
2077 struct xlat_ctx *high_ctx)
2078{
2079 uint64_t exp_tcr, tcr;
2080 size_t t0sz, t1sz;
2081 unsigned int parange;
2082
2083 tcr = read_tcr_el2();
2084
2085 /*
2086 * Calculate the VA space size for both contexts based on
2087 * the TCR_EL2 register.
2088 */
2089 t0sz = ((size_t)1) << (64U - EXTRACT(TCR_EL2_T0SZ, tcr));
2090 t1sz = ((size_t)1) << (64U - EXTRACT(TCR_EL2_T1SZ, tcr));
2091
2092 /* Validate the VA space size of the contexts */
2093 CHECK_VERBOSE((t0sz == low_ctx->cfg->max_va_size),
2094 "Check VA space size for Low Region: 0x%lx == 0x%lx",
2095 t0sz, low_ctx->cfg->max_va_size);
2096 CHECK_VERBOSE((t1sz == high_ctx->cfg->max_va_size),
2097 "Check VA space size for High Region: 0x%lx == 0x%lx",
2098 t1sz, high_ctx->cfg->max_va_size);
2099
2100 /* Mask out TxSZ fields. We have already validated them */
2101 tcr &= ~(MASK(TCR_EL2_T0SZ) | MASK(TCR_EL2_T1SZ));
2102
2103 /*
2104 * Inner and outher cacheability attributes as expected by RMM
2105 * for all the contexts.
2106 */
2107 exp_tcr = TCR_EL2_IRGN0_WBWA | TCR_EL2_ORGN0_WBWA;
2108 exp_tcr |= TCR_EL2_IRGN1_WBWA | TCR_EL2_ORGN1_WBWA;
2109
2110 /* Shareability as expected by RMM for all the contexts */
2111 exp_tcr |= TCR_EL2_SH0_IS | TCR_EL2_SH1_IS;
2112
2113 /* Granule size for all the contexts. Only 4KB supported */
2114 exp_tcr |= TCR_EL2_TG0_4K | TCR_EL2_TG1_4K;
2115
2116 /* Hierarchical permissions */
2117 exp_tcr |= TCR_EL2_AS | TCR_EL2_HPD0 | TCR_EL2_HPD1;
2118
2119 /*
2120 * Xlat library configures TCR_EL2.IPS to the max
2121 * supported by the PE.
2122 */
2123 parange = EXTRACT(ID_AA64MMFR0_EL1_PARANGE, read_id_aa64mmfr0_el1());
2124 exp_tcr |= INPLACE(TCR_EL2_IPS, parange);
2125
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002126 if (is_feat_lpa2_4k_present() == true) {
2127 exp_tcr |= (TCR_EL2_DS_LPA2_EN
2128 | TCR_EL2_SH0_IS
2129 | TCR_EL2_SH1_IS);
2130 }
2131
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002132 /* Validate tcr_el2*/
2133 CHECK_VERBOSE((exp_tcr == tcr),
2134 "Validate TCR_EL2 against expected value: Read 0x%.16lx - Expected 0x%.16lx",
2135 tcr, exp_tcr);
2136}
2137
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01002138void xlat_arch_setup_mmu_cfg_tc1(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002139{
2140 struct xlat_ctx ctx[2U];
2141 struct xlat_ctx_cfg cfg[2U];
2142 struct xlat_ctx_tbls tbls[2U];
2143 uint64_t *base_tbl[2U], *xlat_tables;
2144 uint64_t start_va, end_va;
2145 xlat_addr_region_id_t va_region;
2146 int retval;
2147 struct xlat_mmap_region init_mmap[2U];
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002148 unsigned int pa_index, max_pa_index;
2149 bool lpa2 = is_feat_lpa2_4k_present();
Soby Mathew1eccd462024-10-21 13:36:34 +01002150 const unsigned int pa_range_bits_arr[] = {
2151 [0x0] = PARANGE_WIDTH_32BITS,
2152 [0x1] = PARANGE_WIDTH_36BITS,
2153 [0x2] = PARANGE_WIDTH_40BITS,
2154 [0x3] = PARANGE_WIDTH_42BITS,
2155 [0x4] = PARANGE_WIDTH_44BITS,
2156 [0x5] = PARANGE_WIDTH_48BITS,
2157 [0x6] = PARANGE_WIDTH_52BITS
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002158 };
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002159 uint64_t max_va_size = XLAT_TEST_MAX_VA_SIZE();
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002160 struct xlat_mmu_cfg mmu_config;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002161
2162 /***************************************************************
2163 * TEST CASE 1:
2164 *
2165 * Generate a translation context for each region and configure
2166 * the MMU registers based on both contexts. Verify that the
2167 * right parameters have been configured.
2168 ***************************************************************/
2169
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002170 max_pa_index = ARRAY_SIZE(pa_range_bits_arr);
2171 max_pa_index = (lpa2 == true) ? max_pa_index : max_pa_index - 1U;
Javier Almansa Sobrinoe627b4d2023-10-12 11:25:08 +01002172 pa_index = (unsigned int)test_helpers_get_rand_in_range(0UL,
2173 max_pa_index - 1U);
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002174
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002175 /* Clean the data structures */
2176 memset((void *)&ctx, 0, sizeof(struct xlat_ctx) * 2U);
2177 memset((void *)&cfg, 0, sizeof(struct xlat_ctx_cfg) * 2U);
2178 memset((void *)&tbls, 0, sizeof(struct xlat_ctx_tbls) * 2U);
2179
2180 /* Configure a random maximum PA supported */
Javier Almansa Sobrino2fa8abe2023-06-06 13:18:17 +01002181 xlat_test_helpers_set_parange(pa_index);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002182
2183 for (int i = 0U; i < VA_REGIONS; i++) {
2184 va_region = (xlat_addr_region_id_t)i;
2185
2186 xlat_tables = xlat_test_helpers_tbls();
2187 /* Use half of the available tables for each region */
2188 base_tbl[i] = &xlat_tables[(i * XLAT_TESTS_MAX_TABLES *
2189 XLAT_TABLE_ENTRIES) >> 1U];
2190 /* VA space boundaries */
2191 start_va = xlat_test_helpers_get_start_va(va_region,
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002192 max_va_size);
2193 end_va = start_va + max_va_size - 1ULL;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002194
2195 /* Generate only a single mmap region for each region */
Mate Toth-Pal3f0a8ae2024-08-01 11:09:56 +02002196 xlat_test_helpers_rand_mmap_array(&init_mmap[i], 1U, start_va, end_va, true);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002197
2198 retval = xlat_ctx_cfg_init(&cfg[i], va_region, &init_mmap[i],
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002199 1U, max_va_size);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002200 CHECK_TRUE(retval == 0);
2201
2202 retval = xlat_ctx_init(&ctx[i], &cfg[i], &tbls[i],
2203 base_tbl[i], XLAT_TESTS_MAX_TABLES >> 1U);
2204 CHECK_TRUE(retval == 0);
2205
2206 /* Initialize MMU for the given context */
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002207 retval = xlat_arch_setup_mmu_cfg(&ctx[i], &mmu_config);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002208
2209 /* Verify that the MMU has been configured */
2210 CHECK_TRUE(retval == 0);
2211
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002212 /* Write the MMU config for the given context */
2213 xlat_arch_write_mmu_cfg(&mmu_config);
2214
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002215 /* Validate TTBR_EL2 for each context */
2216 validate_ttbrx_el2(&ctx[i]);
2217 }
2218
2219 /* Validate TCR_EL2 for both contexts at the same time */
2220 validate_tcr_el2(&ctx[0U], &ctx[1U]);
2221}
2222
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01002223void xlat_arch_setup_mmu_cfg_tc2(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002224{
2225 struct xlat_ctx ctx;
2226 struct xlat_ctx_cfg cfg;
2227 struct xlat_ctx_tbls tbls;
2228 uint64_t start_va, end_va;
2229 int retval;
2230 struct xlat_mmap_region init_mmap;
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002231 uint64_t max_va_size = XLAT_TEST_MAX_VA_SIZE();
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002232 struct xlat_mmu_cfg mmu_config;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002233
2234 /***************************************************************
Javier Almansa Sobrino2fa8abe2023-06-06 13:18:17 +01002235 * TEST CASE 2:
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002236 *
2237 * Generate a valid translation context for one of the regions
2238 * and overwrite it to test different failure conditions on
2239 * xlat_arch_setup_mmu_cfg():
2240 *
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002241 * - Call xlat_arch_setup_mmu_cfg() with an uninitialized
2242 * context configuration.
Javier Almansa Sobrino2fa8abe2023-06-06 13:18:17 +01002243 * - Call xlat_arch_setup_mmu_cfg() for a CPU which
2244 * does not have support for 4KB granularity.
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002245 * - Call xlat_arch_setup_mmu_cfg() for a CPU which
2246 * does not support FEAT_LPA2 but reports a PA
2247 * size larger than 48 bits.
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002248 ***************************************************************/
2249
2250 /* Clean the data structures */
2251 memset((void *)&ctx, 0, sizeof(struct xlat_ctx));
2252 memset((void *)&cfg, 0, sizeof(struct xlat_ctx_cfg));
2253 memset((void *)&tbls, 0, sizeof(struct xlat_ctx_tbls));
2254
2255 /* VA space boundaries */
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002256 start_va = xlat_test_helpers_get_start_va(VA_LOW_REGION, max_va_size);
2257 end_va = start_va + max_va_size - 1ULL;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002258
2259 /* Generate only a single mmap region for each region */
Mate Toth-Pal3f0a8ae2024-08-01 11:09:56 +02002260 xlat_test_helpers_rand_mmap_array(&init_mmap, 1U, start_va, end_va, true);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002261
2262 retval = xlat_ctx_cfg_init(&cfg, VA_LOW_REGION, &init_mmap,
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002263 1U, max_va_size);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002264 CHECK_TRUE(retval == 0);
2265
2266 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
2267 xlat_test_helpers_tbls(),
2268 XLAT_TESTS_MAX_TABLES);
2269 CHECK_TRUE(retval == 0);
2270
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002271 /* Force the context to be uninitialized */
Aliyha Ajmal7f9ee6e2024-10-10 10:44:17 +01002272 ctx.cfg->init = false;
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002273
2274 /* Try to initialize MMU for the given context */
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002275 retval = xlat_arch_setup_mmu_cfg(&ctx, &mmu_config);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002276
2277 /* Verify that the MMU has failed to be initialized */
2278 CHECK_TRUE(retval == -EINVAL);
Javier Almansa Sobrino2fa8abe2023-06-06 13:18:17 +01002279
2280 /* Restore the context initialized flag */
Aliyha Ajmal7f9ee6e2024-10-10 10:44:17 +01002281 ctx.cfg->init = true;
Javier Almansa Sobrino2fa8abe2023-06-06 13:18:17 +01002282
2283 /* Force the architecture to report 4K granularity as not available */
2284 host_write_sysreg("id_aa64mmfr0_el1",
2285 INPLACE(ID_AA64MMFR0_EL1_PARANGE, 5U) |
2286 INPLACE(ID_AA64MMFR0_EL1_TGRAN4,
2287 ID_AA64MMFR0_EL1_TGRAN4_NOT_SUPPORTED));
2288
2289 /* Try to initialize MMU for the given context */
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002290 retval = xlat_arch_setup_mmu_cfg(&ctx, &mmu_config);
Javier Almansa Sobrino2fa8abe2023-06-06 13:18:17 +01002291
2292 /* Verify that the MMU has failed to be initialized */
2293 CHECK_TRUE(retval == -EPERM);
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002294
2295 /*
2296 * Force the architecture to report 4K granularity available without
2297 * support for LPA2 but with an PA size of more than 48 bits.
2298 * Note that this scenario should never happen on the architecture
2299 * however, the library still checks for this.
2300 */
2301 host_write_sysreg("id_aa64mmfr0_el1",
2302 INPLACE(ID_AA64MMFR0_EL1_PARANGE, 6U) |
2303 INPLACE(ID_AA64MMFR0_EL1_TGRAN4,
2304 ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED));
2305
2306 /* Try to initialize MMU for the given context */
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002307 retval = xlat_arch_setup_mmu_cfg(&ctx, &mmu_config);
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002308
2309 /* Verify that the MMU has failed to be initialized */
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002310 CHECK_TRUE(retval == -EPERM);
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002311
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002312}
2313
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01002314void xlat_arch_setup_mmu_cfg_tc3(void)
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002315{
2316 /***************************************************************
2317 * TEST CASE 3:
2318 *
2319 * Test xlat_arch_setup_mmu_cfg() with a NULL context.
2320 ***************************************************************/
2321
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002322 struct xlat_mmu_cfg mmu_config;
2323
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002324 test_helpers_expect_assert_fail(true);
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002325 (void)xlat_arch_setup_mmu_cfg(NULL, &mmu_config);
Javier Almansa Sobrino6cf9d8a2023-03-29 17:42:22 +01002326 test_helpers_fail_if_no_assert_failed();
2327}
2328
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01002329void xlat_arch_setup_mmu_cfg_tc4(void)
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002330{
2331 struct xlat_ctx ctx;
2332 struct xlat_ctx_cfg cfg;
2333 struct xlat_ctx_tbls tbls;
2334 struct xlat_mmap_region init_mmap;
2335
2336 /***************************************************************
2337 * TEST CASE 4:
2338 *
2339 * Test xlat_arch_setup_mmu_cfg() with a context in which the
2340 * configuration is NULL.
2341 *
2342 * This test reuses xlat_get_llt_from_va_prepare_assertion()
2343 * in order to generate an initial valid context.
2344 ***************************************************************/
2345
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002346 struct xlat_mmu_cfg mmu_config;
2347
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002348 xlat_get_llt_from_va_prepare_assertion(&ctx, &cfg, &tbls, &init_mmap);
2349
2350 /* Force the context configuration to NULL */
2351 ctx.cfg = NULL;
2352
2353 test_helpers_expect_assert_fail(true);
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002354 (void)xlat_arch_setup_mmu_cfg(&ctx, &mmu_config);
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002355 test_helpers_fail_if_no_assert_failed();
2356}
2357
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01002358void xlat_arch_setup_mmu_cfg_tc5(void)
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002359{
2360 struct xlat_ctx ctx;
2361 struct xlat_ctx_cfg cfg;
2362 struct xlat_ctx_tbls tbls;
2363 struct xlat_mmap_region init_mmap;
2364
2365 /***************************************************************
2366 * TEST CASE 5:
2367 *
2368 * Test xlat_arch_setup_mmu_cfg() with a context in which the
2369 * 'tbls' structure is NULL.
2370 *
2371 * This test reuses xlat_get_llt_from_va_prepare_assertion()
2372 * in order to generate an initial valid context.
2373 ***************************************************************/
2374
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002375 struct xlat_mmu_cfg mmu_config;
2376
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002377 xlat_get_llt_from_va_prepare_assertion(&ctx, &cfg, &tbls, &init_mmap);
2378
2379 /* Force the context tables structure to NULL */
2380 ctx.tbls = NULL;
2381
2382 test_helpers_expect_assert_fail(true);
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002383 (void)xlat_arch_setup_mmu_cfg(&ctx, &mmu_config);
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002384 test_helpers_fail_if_no_assert_failed();
2385}
2386
Soby Mathew4714e232023-10-04 07:03:08 +01002387void xlat_arch_setup_mmu_cfg_tc6(void)
2388{
2389 struct xlat_ctx ctx;
2390 struct xlat_ctx_cfg cfg;
2391 struct xlat_ctx_tbls tbls;
2392 uintptr_t start_va, end_va;
2393 int retval;
2394 struct xlat_mmap_region init_mmap;
2395 uint64_t max_va_size = XLAT_TEST_MAX_VA_SIZE();
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002396 struct xlat_mmu_cfg mmu_config;
Soby Mathew4714e232023-10-04 07:03:08 +01002397
2398 /***************************************************************
2399 * TEST CASE 6:
2400 * Generate a valid translation context for one of the regions
2401 * and call xlat_arch_setup_mmu_cfg() with the MMU enabled.
2402 *
2403 ***************************************************************/
2404
2405 /* Clean the data structures */
2406 memset((void *)&ctx, 0, sizeof(struct xlat_ctx));
2407 memset((void *)&cfg, 0, sizeof(struct xlat_ctx_cfg));
2408 memset((void *)&tbls, 0, sizeof(struct xlat_ctx_tbls));
2409
2410 /* VA space boundaries */
2411 start_va = xlat_test_helpers_get_start_va(VA_LOW_REGION, max_va_size);
2412 end_va = start_va + max_va_size - 1UL;
2413
2414 /* Generate only a single mmap region for each region */
Mate Toth-Pal3f0a8ae2024-08-01 11:09:56 +02002415 xlat_test_helpers_rand_mmap_array(&init_mmap, 1U, start_va, end_va, true);
Soby Mathew4714e232023-10-04 07:03:08 +01002416
2417 retval = xlat_ctx_cfg_init(&cfg, VA_LOW_REGION, &init_mmap,
2418 1U, max_va_size);
2419 CHECK_TRUE(retval == 0);
2420
2421 retval = xlat_ctx_init(&ctx, &cfg, &tbls,
2422 xlat_test_helpers_tbls(),
2423 XLAT_TESTS_MAX_TABLES);
2424 CHECK_TRUE(retval == 0);
2425
2426 /* Force the MMU enablement */
2427 xlat_enable_mmu_el2();
2428
2429 test_helpers_expect_assert_fail(true);
2430
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002431 /* Initialize MMU config for the given context */
2432 retval = xlat_arch_setup_mmu_cfg(&ctx, &mmu_config);
2433 CHECK_TRUE(retval == 0);
Soby Mathew4714e232023-10-04 07:03:08 +01002434
Mate Toth-Paldb9c5e82024-08-01 11:05:58 +02002435 /* Try to write the MMU config for the given context */
2436 xlat_arch_write_mmu_cfg(&mmu_config);
2437
2438 test_helpers_fail_if_no_assert_failed();
2439}
2440
2441void xlat_arch_setup_mmu_cfg_tc7(void)
2442{
2443 /***************************************************************
2444 * TEST CASE 7:
2445 *
2446 * Test xlat_arch_setup_mmu_cfg() with a NULL config.
2447 ***************************************************************/
2448
2449 struct xlat_ctx ctx;
2450
2451 test_helpers_expect_assert_fail(true);
2452 (void)xlat_arch_setup_mmu_cfg(&ctx, NULL);
Soby Mathew4714e232023-10-04 07:03:08 +01002453 test_helpers_fail_if_no_assert_failed();
2454}
2455
Javier Almansa Sobrinocd599e22023-06-28 12:28:00 +01002456void xlat_get_oa_from_tte_tc1(void)
Javier Almansa Sobrino59f0ef62023-05-17 12:21:02 +01002457{
2458 uint64_t test_tte, val_addr, output_addr;
2459
2460 /***************************************************************
2461 * TEST CASE 1:
2462 *
2463 * Test xlat_get_oa_from_tte() with 4K granularity and with and
2464 * without LPA2 support.
2465 ***************************************************************/
2466
2467 /*
2468 * Generate a random TTE to test. We are not concerned about the
2469 * validity of the TTE or about any bitfield that is not part of
2470 * the output address, as xlat_get_oa_from_tte() is expected to
2471 * just ignore those.
2472 */
2473 test_tte = ~0ULL;
2474
2475 /* Test with FEAT_LPA2 available */
2476 host_write_sysreg("id_aa64mmfr0_el1",
2477 INPLACE(ID_AA64MMFR0_EL1_PARANGE, 6UL) |
2478 INPLACE(ID_AA64MMFR0_EL1_TGRAN4,
2479 ID_AA64MMFR0_EL1_TGRAN4_LPA2));
2480
2481 /* Generate the validation address from the test TTE */
2482 val_addr = test_tte & BIT_MASK_ULL(TTE_OA_BIT_49_LPA2, OA_SHIFT);
2483 val_addr |= INPLACE(OA_BITS_50_51, EXTRACT(TTE_OA_BITS_50_51, test_tte));
2484
2485 output_addr = xlat_get_oa_from_tte(test_tte);
2486
2487 CHECK_VERBOSE((val_addr == output_addr),
2488 "Test xlat_get_oa_from_tte, LPA2 supported: OA = %p - Expected = %p",
2489 (void *)output_addr, (void *)val_addr);
2490
2491 /* Repeat the test, by disabling support for FEAT_LPA2 this time */
2492 host_write_sysreg("id_aa64mmfr0_el1",
2493 INPLACE(ID_AA64MMFR0_EL1_PARANGE, 5U) |
2494 INPLACE(ID_AA64MMFR0_EL1_TGRAN4,
2495 ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED));
2496
2497 /* Generate the validation address */
2498 val_addr = test_tte & BIT_MASK_ULL(TTE_OA_MSB, OA_SHIFT);
2499
2500 output_addr = xlat_get_oa_from_tte(test_tte);
2501
2502 CHECK_VERBOSE((val_addr == output_addr),
2503 "Test xlat_get_oa_from_tte, LPA2 not supported: OA = %p - Expected = %p",
2504 (void *)output_addr, (void *)val_addr);
2505}