Commit c54c7fc3 authored by David Pu's avatar David Pu
Browse files

xlat_tables_v2: print xlat tables without recursion



This patch uses an array on stack to save parent xlat table information when
traversing the xlat tables. It keeps exactly same xlat table traversal
order compared to recursive version.

fixes arm-software/tf-issues#664
Signed-off-by: default avatarDavid Pu <dpu@nvidia.com>
parent db8cac2d
...@@ -109,7 +109,7 @@ static const char *invalid_descriptors_ommited = ...@@ -109,7 +109,7 @@ static const char *invalid_descriptors_ommited =
"%s(%d invalid descriptors omitted)\n"; "%s(%d invalid descriptors omitted)\n";
/* /*
* Recursive function that reads the translation tables passed as an argument * Function that reads the translation tables passed as an argument
* and prints their status. * and prints their status.
*/ */
static void xlat_tables_print_internal(xlat_ctx_t *ctx, uintptr_t table_base_va, static void xlat_tables_print_internal(xlat_ctx_t *ctx, uintptr_t table_base_va,
...@@ -118,10 +118,23 @@ static void xlat_tables_print_internal(xlat_ctx_t *ctx, uintptr_t table_base_va, ...@@ -118,10 +118,23 @@ static void xlat_tables_print_internal(xlat_ctx_t *ctx, uintptr_t table_base_va,
{ {
assert(level <= XLAT_TABLE_LEVEL_MAX); assert(level <= XLAT_TABLE_LEVEL_MAX);
uint64_t desc; /*
uintptr_t table_idx_va = table_base_va; * data structure to track DESC_TABLE entry before iterate into subtable
* of next translation level. it will be restored after return from
* subtable iteration.
*/
struct desc_table {
const uint64_t *table_base;
uintptr_t table_idx_va;
unsigned int idx;
} desc_tables[XLAT_TABLE_LEVEL_MAX + 1] = {
{NULL, 0U, XLAT_TABLE_ENTRIES}, };
unsigned int this_level = level;
const uint64_t *this_base = table_base;
unsigned int max_entries = table_entries;
size_t level_size = XLAT_BLOCK_SIZE(this_level);
unsigned int table_idx = 0U; unsigned int table_idx = 0U;
size_t level_size = XLAT_BLOCK_SIZE(level); uintptr_t table_idx_va = table_base_va;
/* /*
* Keep track of how many invalid descriptors are counted in a row. * Keep track of how many invalid descriptors are counted in a row.
...@@ -131,67 +144,110 @@ static void xlat_tables_print_internal(xlat_ctx_t *ctx, uintptr_t table_base_va, ...@@ -131,67 +144,110 @@ static void xlat_tables_print_internal(xlat_ctx_t *ctx, uintptr_t table_base_va,
*/ */
int invalid_row_count = 0; int invalid_row_count = 0;
while (table_idx < table_entries) { while (this_base != NULL) {
/* finish current xlat level */
desc = table_base[table_idx]; if (table_idx >= max_entries) {
if ((desc & DESC_MASK) == INVALID_DESC) {
if (invalid_row_count == 0) {
printf("%sVA:0x%lx size:0x%zx\n",
level_spacers[level],
table_idx_va, level_size);
}
invalid_row_count++;
} else {
if (invalid_row_count > 1) { if (invalid_row_count > 1) {
printf(invalid_descriptors_ommited, printf(invalid_descriptors_ommited,
level_spacers[level], level_spacers[this_level],
invalid_row_count - 1); invalid_row_count - 1);
} }
invalid_row_count = 0; invalid_row_count = 0;
/* /* no parent level to iterate. */
* Check if this is a table or a block. Tables are only if (this_level <= level) {
* allowed in levels other than 3, but DESC_PAGE has the this_base = NULL;
* same value as DESC_TABLE, so we need to check. table_idx = max_entries + 1;
*/ } else {
if (((desc & DESC_MASK) == TABLE_DESC) && /* retore previous DESC_TABLE entry and start
(level < XLAT_TABLE_LEVEL_MAX)) { * to iterate.
*/
this_level--;
level_size = XLAT_BLOCK_SIZE(this_level);
this_base = desc_tables[this_level].table_base;
table_idx = desc_tables[this_level].idx;
table_idx_va =
desc_tables[this_level].table_idx_va;
if (this_level == level) {
max_entries = table_entries;
} else {
max_entries = XLAT_TABLE_ENTRIES;
}
assert(this_base != NULL);
}
} else {
uint64_t desc = this_base[table_idx];
if ((desc & DESC_MASK) == INVALID_DESC) {
if (invalid_row_count == 0) {
printf("%sVA:0x%lx size:0x%zx\n",
level_spacers[this_level],
table_idx_va, level_size);
}
invalid_row_count++;
table_idx++;
table_idx_va += level_size;
} else {
if (invalid_row_count > 1) {
printf(invalid_descriptors_ommited,
level_spacers[this_level],
invalid_row_count - 1);
}
invalid_row_count = 0;
/* /*
* Do not print any PA for a table descriptor, * Check if this is a table or a block. Tables
* as it doesn't directly map physical memory * are only allowed in levels other than 3, but
* but instead points to the next translation * DESC_PAGE has the same value as DESC_TABLE,
* table in the translation table walk. * so we need to check.
*/ */
printf("%sVA:0x%lx size:0x%zx\n",
level_spacers[level],
table_idx_va, level_size);
uintptr_t addr_inner = desc & TABLE_ADDR_MASK;
xlat_tables_print_internal(ctx, table_idx_va, if (((desc & DESC_MASK) == TABLE_DESC) &&
(uint64_t *)addr_inner, (this_level < XLAT_TABLE_LEVEL_MAX)) {
XLAT_TABLE_ENTRIES, level + 1U); uintptr_t addr_inner;
} else {
printf("%sVA:0x%lx PA:0x%llx size:0x%zx ", /*
level_spacers[level], table_idx_va, * Do not print any PA for a table
(uint64_t)(desc & TABLE_ADDR_MASK), * descriptor, as it doesn't directly
level_size); * map physical memory but instead
xlat_desc_print(ctx, desc); * points to the next translation
printf("\n"); * table in the translation table walk.
*/
printf("%sVA:0x%lx size:0x%zx\n",
level_spacers[this_level],
table_idx_va, level_size);
addr_inner = desc & TABLE_ADDR_MASK;
/* save current xlat level */
desc_tables[this_level].table_base =
this_base;
desc_tables[this_level].idx =
table_idx + 1;
desc_tables[this_level].table_idx_va =
table_idx_va + level_size;
/* start iterating next level entries */
this_base = (uint64_t *)addr_inner;
max_entries = XLAT_TABLE_ENTRIES;
this_level++;
level_size =
XLAT_BLOCK_SIZE(this_level);
table_idx = 0U;
} else {
printf("%sVA:0x%lx PA:0x%llx size:0x%zx ",
level_spacers[this_level],
table_idx_va,
(uint64_t)(desc & TABLE_ADDR_MASK),
level_size);
xlat_desc_print(ctx, desc);
printf("\n");
table_idx++;
table_idx_va += level_size;
}
} }
} }
table_idx++;
table_idx_va += level_size;
}
if (invalid_row_count > 1) {
printf(invalid_descriptors_ommited,
level_spacers[level], invalid_row_count - 1);
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment