Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
859cf9ea
Unverified
Commit
859cf9ea
authored
Mar 19, 2019
by
Soby Mathew
Committed by
GitHub
Mar 19, 2019
Browse files
Merge pull request #1900 from soby-mathew/sm/revert_xlat_changes
xlat_tables_v2: Revert recent changes to remove recursion
parents
75044d8b
f253645d
Changes
2
Hide whitespace changes
Inline
Side-by-side
lib/xlat_tables_v2/xlat_tables_core.c
View file @
859cf9ea
...
@@ -325,9 +325,8 @@ static action_t xlat_tables_unmap_region_action(const mmap_region_t *mm,
...
@@ -325,9 +325,8 @@ static action_t xlat_tables_unmap_region_action(const mmap_region_t *mm,
return
action
;
return
action
;
}
}
/*
/*
*
F
unction that writes to the translation tables and unmaps the
*
Recursive f
unction that writes to the translation tables and unmaps the
* specified region.
* specified region.
*/
*/
static
void
xlat_tables_unmap_region
(
xlat_ctx_t
*
ctx
,
mmap_region_t
*
mm
,
static
void
xlat_tables_unmap_region
(
xlat_ctx_t
*
ctx
,
mmap_region_t
*
mm
,
...
@@ -338,137 +337,70 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
...
@@ -338,137 +337,70 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
{
{
assert
((
level
>=
ctx
->
base_level
)
&&
(
level
<=
XLAT_TABLE_LEVEL_MAX
));
assert
((
level
>=
ctx
->
base_level
)
&&
(
level
<=
XLAT_TABLE_LEVEL_MAX
));
/*
uint64_t
*
subtable
;
* data structure to track DESC_TABLE entry before iterate into subtable
uint64_t
desc
;
* of next translation level. it will be used to restore previous level
* after finish subtable iteration.
*/
struct
desc_table_unmap
{
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
;
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
;
uintptr_t
table_idx_va
;
uintptr_t
table_idx_va
;
uintptr_t
table_idx_end_va
;
/* End VA of this entry */
uintptr_t
region_end_va
=
mm
->
base_va
+
mm
->
size
-
1U
;
uintptr_t
region_end_va
=
mm
->
base_va
+
mm
->
size
-
1U
;
unsigned
int
table_idx
;
table_idx_va
=
xlat_tables_find_start_va
(
mm
,
table_base_va
,
level
);
table_idx_va
=
xlat_tables_find_start_va
(
mm
,
table_base_va
,
level
);
table_idx
=
xlat_tables_va_to_index
(
table_base_va
,
table_idx_va
,
level
);
table_idx
=
xlat_tables_va_to_index
(
table_base_va
,
table_idx_va
,
level
);
while
(
this_base
!=
NULL
)
{
while
(
table_idx
<
table_entries
)
{
uint64_t
desc
;
uint64_t
desc_type
;
uintptr_t
table_idx_end_va
;
/* End VA of this entry */
action_t
action
;
/* finish current xlat level iteration. */
if
(
table_idx
>=
max_entries
)
{
if
(
this_level
>
ctx
->
base_level
)
{
xlat_table_dec_regions_count
(
ctx
,
this_base
);
}
if
(
this_level
>
level
)
{
uint64_t
*
subtable
;
/* back from subtable iteration, restore
* previous DESC_TABLE entry.
*/
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
;
level_size
=
XLAT_BLOCK_SIZE
(
this_level
);
if
(
this_level
==
level
)
{
max_entries
=
table_entries
;
}
else
{
max_entries
=
XLAT_TABLE_ENTRIES
;
}
desc
=
this_base
[
table_idx
];
subtable
=
(
uint64_t
*
)(
uintptr_t
)(
desc
&
TABLE_ADDR_MASK
);
/*
* If the subtable is now empty, remove its reference.
*/
if
(
xlat_table_is_empty
(
ctx
,
subtable
))
{
this_base
[
table_idx
]
=
INVALID_DESC
;
xlat_arch_tlbi_va
(
table_idx_va
,
ctx
->
xlat_regime
);
}
table_idx
++
;
table_idx_va
+=
level_size
;
}
else
{
/* reached end of top level, exit.*/
this_base
=
NULL
;
break
;
}
}
/* If reached the end of the region, stop iterating entries in
* current xlat level.
*/
if
(
region_end_va
<=
table_idx_va
)
{
table_idx
=
max_entries
;
continue
;
}
table_idx_end_va
=
table_idx_va
+
XLAT_BLOCK_SIZE
(
level
)
-
1U
;
table_idx_end_va
=
table_idx_va
+
XLAT_BLOCK_SIZE
(
this_level
)
-
1U
;
desc
=
table_base
[
table_idx
];
uint64_t
desc_type
=
desc
&
DESC_MASK
;
desc
=
this_base
[
table_idx
];
action_t
action
=
xlat_tables_unmap_region_action
(
mm
,
desc_type
=
desc
&
DESC_MASK
;
table_idx_va
,
table_idx_end_va
,
level
,
desc_type
);
action
=
xlat_tables_unmap_region_action
(
mm
,
table_idx_va
,
table_idx_end_va
,
this_level
,
desc_type
);
if
(
action
==
ACTION_WRITE_BLOCK_ENTRY
)
{
if
(
action
==
ACTION_WRITE_BLOCK_ENTRY
)
{
this_base
[
table_idx
]
=
INVALID_DESC
;
table_base
[
table_idx
]
=
INVALID_DESC
;
xlat_arch_tlbi_va
(
table_idx_va
,
ctx
->
xlat_regime
);
xlat_arch_tlbi_va
(
table_idx_va
,
ctx
->
xlat_regime
);
table_idx
++
;
table_idx_va
+=
level_size
;
}
else
if
(
action
==
ACTION_RECURSE_INTO_TABLE
)
{
}
else
if
(
action
==
ACTION_RECURSE_INTO_TABLE
)
{
uint64_t
*
subtable
;
uintptr_t
base_va
;
subtable
=
(
uint64_t
*
)(
uintptr_t
)(
desc
&
TABLE_ADDR_MASK
);
subtable
=
(
uint64_t
*
)(
uintptr_t
)(
desc
&
TABLE_ADDR_MASK
);
desc_tables
[
this_level
].
table_base
=
this_base
;
/* Recurse to write into subtable */
desc_tables
[
this_level
].
table_idx_va
=
table_idx_va
;
xlat_tables_unmap_region
(
ctx
,
mm
,
table_idx_va
,
base_va
=
table_idx_va
;
subtable
,
XLAT_TABLE_ENTRIES
,
desc_tables
[
this_level
].
idx
=
table_idx
;
level
+
1U
);
#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
this_base
=
subtable
;
xlat_clean_dcache_range
((
uintptr_t
)
subtable
,
this_level
++
;
XLAT_TABLE_ENTRIES
*
sizeof
(
uint64_t
));
#endif
max_entries
=
XLAT_TABLE_ENTRIES
;
/*
level_size
=
XLAT_BLOCK_SIZE
(
this_level
);
* If the subtable is now empty, remove its reference.
*/
if
(
xlat_table_is_empty
(
ctx
,
subtable
))
{
table_base
[
table_idx
]
=
INVALID_DESC
;
xlat_arch_tlbi_va
(
table_idx_va
,
ctx
->
xlat_regime
);
}
table_idx_va
=
xlat_tables_find_start_va
(
mm
,
base_va
,
this_level
);
table_idx
=
xlat_tables_va_to_index
(
base_va
,
table_idx_va
,
this_level
);
}
else
{
}
else
{
assert
(
action
==
ACTION_NONE
);
assert
(
action
==
ACTION_NONE
);
table_idx
++
;
table_idx_va
+=
level_size
;
}
}
table_idx
++
;
table_idx_va
+=
XLAT_BLOCK_SIZE
(
level
);
/* If reached the end of the region, exit */
if
(
region_end_va
<=
table_idx_va
)
break
;
}
}
if
(
level
>
ctx
->
base_level
)
xlat_table_dec_regions_count
(
ctx
,
table_base
);
}
}
#endif
/* PLAT_XLAT_TABLES_DYNAMIC */
#endif
/* PLAT_XLAT_TABLES_DYNAMIC */
...
@@ -605,169 +537,105 @@ static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
...
@@ -605,169 +537,105 @@ static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
}
}
/*
/*
*
F
unction that writes to the translation tables and maps the
*
Recursive f
unction that writes to the translation tables and maps the
* specified region. On success, it returns the VA of the last byte that was
* specified region. On success, it returns the VA of the last byte that was
* successfully mapped. On error, it returns the VA of the next entry that
* successfully mapped. On error, it returns the VA of the next entry that
* should have been mapped.
* should have been mapped.
*/
*/
static
uintptr_t
xlat_tables_map_region
(
xlat_ctx_t
*
ctx
,
mmap_region_t
*
mm
,
static
uintptr_t
xlat_tables_map_region
(
xlat_ctx_t
*
ctx
,
mmap_region_t
*
mm
,
const
uintptr_t
table_base_va
,
uintptr_t
table_base_va
,
uint64_t
*
const
table_base
,
uint64_t
*
const
table_base
,
unsigned
int
table_entries
,
unsigned
int
table_entries
,
unsigned
int
level
)
unsigned
int
level
)
{
{
assert
((
level
>=
ctx
->
base_level
)
&&
(
level
<=
XLAT_TABLE_LEVEL_MAX
));
assert
((
level
>=
ctx
->
base_level
)
&&
(
level
<=
XLAT_TABLE_LEVEL_MAX
));
/*
* data structure to track DESC_TABLE entry before iterate into subtable
* of next translation level. it will be used to restore previous level
* after finish subtable iteration.
*/
struct
desc_table_map
{
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
;
uint64_t
*
this_base
=
table_base
;
unsigned
int
max_entries
=
table_entries
;
size_t
level_size
=
XLAT_BLOCK_SIZE
(
this_level
);
uintptr_t
mm_end_va
=
mm
->
base_va
+
mm
->
size
-
1U
;
uintptr_t
mm_end_va
=
mm
->
base_va
+
mm
->
size
-
1U
;
uintptr_t
table_idx_va
;
uintptr_t
table_idx_va
;
unsigned
long
long
table_idx_pa
;
uint64_t
*
subtable
;
uint64_t
desc
;
unsigned
int
table_idx
;
unsigned
int
table_idx
;
table_idx_va
=
xlat_tables_find_start_va
(
mm
,
table_base_va
,
level
);
table_idx_va
=
xlat_tables_find_start_va
(
mm
,
table_base_va
,
level
);
table_idx
=
xlat_tables_va_to_index
(
table_base_va
,
table_idx_va
,
level
);
table_idx
=
xlat_tables_va_to_index
(
table_base_va
,
table_idx_va
,
level
);
while
(
this_base
!=
NULL
)
{
#if PLAT_XLAT_TABLES_DYNAMIC
if
(
level
>
ctx
->
base_level
)
uint64_t
desc
;
xlat_table_inc_regions_count
(
ctx
,
table_base
);
uint64_t
desc_type
;
unsigned
long
long
table_idx_pa
;
action_t
action
;
/* finish current xlat level iteration. */
if
(
table_idx
>=
max_entries
)
{
if
(
this_level
<=
level
)
{
this_base
=
NULL
;
break
;
}
else
{
/* back from subtable iteration, restore
* previous DESC_TABLE entry.
*/
this_level
--
;
level_size
=
XLAT_BLOCK_SIZE
(
this_level
);
this_base
=
desc_tables
[
this_level
].
table_base
;
table_idx
=
desc_tables
[
this_level
].
idx
;
if
(
this_level
==
level
)
{
max_entries
=
table_entries
;
}
else
{
max_entries
=
XLAT_TABLE_ENTRIES
;
}
#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
uintptr_t
subtable
;
desc
=
this_base
[
table_idx
];
subtable
=
(
uintptr_t
)(
desc
&
TABLE_ADDR_MASK
);
xlat_clean_dcache_range
(
subtable
,
XLAT_TABLE_ENTRIES
*
sizeof
(
uint64_t
));
#endif
#endif
table_idx
++
;
while
(
table_idx
<
table_entries
)
{
table_idx_va
=
desc_tables
[
this_level
].
table_idx_va
+
level_size
;
}
}
desc
=
this_base
[
table_idx
];
desc
=
table_base
[
table_idx
];
desc_type
=
desc
&
DESC_MASK
;
table_idx_pa
=
mm
->
base_pa
+
table_idx_va
-
mm
->
base_va
;
table_idx_pa
=
mm
->
base_pa
+
table_idx_va
-
mm
->
base_va
;
/* If reached the end of the region, simply exit since we
action_t
action
=
xlat_tables_map_region_action
(
mm
,
* already write all BLOCK entries and create all required
(
uint32_t
)(
desc
&
DESC_MASK
),
table_idx_pa
,
* subtables.
table_idx_va
,
level
);
*/
if
(
mm_end_va
<=
table_idx_va
)
{
this_base
=
NULL
;
break
;
}
action
=
xlat_tables_map_region_action
(
mm
,
desc_type
,
table_idx_pa
,
table_idx_va
,
this_level
);
if
(
action
==
ACTION_WRITE_BLOCK_ENTRY
)
{
if
(
action
==
ACTION_WRITE_BLOCK_ENTRY
)
{
this_base
[
table_idx
]
=
xlat_desc
(
ctx
,
mm
->
attr
,
table_idx_pa
,
this_level
);
table_idx
++
;
table_idx_va
+=
level_size
;
}
else
if
(
action
==
ACTION_CREATE_NEW_TABLE
)
{
uintptr_t
base_va
;
table_base
[
table_idx
]
=
xlat_desc
(
ctx
,
(
uint32_t
)
mm
->
attr
,
table_idx_pa
,
level
);
}
else
if
(
action
==
ACTION_CREATE_NEW_TABLE
)
{
uintptr_t
end_va
;
uint64_t
*
subtable
=
xlat_table_get_empty
(
ctx
);
subtable
=
xlat_table_get_empty
(
ctx
);
if
(
subtable
==
NULL
)
{
if
(
subtable
==
NULL
)
{
/* Not enough free tables to map this region
.
*/
/* Not enough free tables to map this region */
return
table_idx_va
;
return
table_idx_va
;
}
}
/* Point to new subtable from this one. */
/* Point to new subtable from this one. */
this_base
[
table_idx
]
=
TABLE_DESC
|
(
unsigned
long
)
subtable
;
table_base
[
table_idx
]
=
TABLE_DESC
|
(
unsigned
long
)
subtable
;
desc_tables
[
this_level
].
table_base
=
this_base
;
desc_tables
[
this_level
].
table_idx_va
=
table_idx_va
;
desc_tables
[
this_level
].
idx
=
table_idx
;
base_va
=
table_idx_va
;
this_level
++
;
this_base
=
subtable
;
level_size
=
XLAT_BLOCK_SIZE
(
this_level
);
table_idx_va
=
xlat_tables_find_start_va
(
mm
,
base_va
,
this_level
);
table_idx
=
xlat_tables_va_to_index
(
base_va
,
table_idx_va
,
this_level
);
max_entries
=
XLAT_TABLE_ENTRIES
;
#if PLAT_XLAT_TABLES_DYNAMIC
/* Recurse to write into subtable */
if
(
this_level
>
ctx
->
base_level
)
{
end_va
=
xlat_tables_map_region
(
ctx
,
mm
,
table_idx_va
,
xlat_table_inc_regions_count
(
ctx
,
subtable
);
subtable
,
XLAT_TABLE_ENTRIES
,
}
level
+
1U
);
#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
xlat_clean_dcache_range
((
uintptr_t
)
subtable
,
XLAT_TABLE_ENTRIES
*
sizeof
(
uint64_t
));
#endif
#endif
if
(
end_va
!=
(
table_idx_va
+
XLAT_BLOCK_SIZE
(
level
)
-
1U
))
return
end_va
;
}
else
if
(
action
==
ACTION_RECURSE_INTO_TABLE
)
{
}
else
if
(
action
==
ACTION_RECURSE_INTO_TABLE
)
{
uintptr_t
end_va
;
uintptr_t
base_va
;
subtable
=
(
uint64_t
*
)(
uintptr_t
)(
desc
&
TABLE_ADDR_MASK
);
uint64_t
*
subtable
=
(
uint64_t
*
)(
uintptr_t
)(
desc
&
TABLE_ADDR_MASK
);
/* Recurse to write into subtable */
end_va
=
xlat_tables_map_region
(
ctx
,
mm
,
table_idx_va
,
desc_tables
[
this_level
].
table_base
=
this_base
;
subtable
,
XLAT_TABLE_ENTRIES
,
desc_tables
[
this_level
].
table_idx_va
=
table_idx_va
;
level
+
1U
);
desc_tables
[
this_level
].
idx
=
table_idx
;
#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
base_va
=
table_idx_va
;
xlat_clean_dcache_range
((
uintptr_t
)
subtable
,
XLAT_TABLE_ENTRIES
*
sizeof
(
uint64_t
));
this_level
++
;
level_size
=
XLAT_BLOCK_SIZE
(
this_level
);
table_idx_va
=
xlat_tables_find_start_va
(
mm
,
base_va
,
this_level
);
table_idx
=
xlat_tables_va_to_index
(
base_va
,
table_idx_va
,
this_level
);
this_base
=
subtable
;
max_entries
=
XLAT_TABLE_ENTRIES
;
#if PLAT_XLAT_TABLES_DYNAMIC
if
(
this_level
>
ctx
->
base_level
)
{
xlat_table_inc_regions_count
(
ctx
,
subtable
);
}
#endif
#endif
if
(
end_va
!=
(
table_idx_va
+
XLAT_BLOCK_SIZE
(
level
)
-
1U
))
return
end_va
;
}
else
{
}
else
{
assert
(
action
==
ACTION_NONE
);
assert
(
action
==
ACTION_NONE
);
table_idx
++
;
table_idx_va
+=
level_size
;
}
}
table_idx
++
;
table_idx_va
+=
XLAT_BLOCK_SIZE
(
level
);
/* If reached the end of the region, exit */
if
(
mm_end_va
<=
table_idx_va
)
break
;
}
}
return
table_idx_va
-
1U
;
return
table_idx_va
-
1U
;
...
...
lib/xlat_tables_v2/xlat_tables_utils.c
View file @
859cf9ea
...
@@ -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
"
;
/*
/*
*
F
unction that reads the translation tables passed as an argument
*
Recursive f
unction 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,23 +118,10 @@ static void xlat_tables_print_internal(xlat_ctx_t *ctx, uintptr_t table_base_va,
...
@@ -118,23 +118,10 @@ 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
;
* 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
;
uintptr_t
table_idx_va
=
table_base_va
;
uintptr_t
table_idx_va
=
table_base_va
;
unsigned
int
table_idx
=
0U
;
size_t
level_size
=
XLAT_BLOCK_SIZE
(
level
);
/*
/*
* Keep track of how many invalid descriptors are counted in a row.
* Keep track of how many invalid descriptors are counted in a row.
...
@@ -144,110 +131,67 @@ static void xlat_tables_print_internal(xlat_ctx_t *ctx, uintptr_t table_base_va,
...
@@ -144,110 +131,67 @@ 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
(
this_base
!=
NULL
)
{
while
(
table_idx
<
table_entries
)
{
/* finish current xlat level */
if
(
table_idx
>=
max_entries
)
{
desc
=
table_base
[
table_idx
];
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
[
this_
level
],
level_spacers
[
level
],
invalid_row_count
-
1
);
invalid_row_count
-
1
);
}
}
invalid_row_count
=
0
;
invalid_row_count
=
0
;
/* no parent level to iterate. */
/*
if
(
this_level
<=
level
)
{
* Check if this is a table or a block. Tables are only
this_base
=
NULL
;
* allowed in levels other than 3, but DESC_PAGE has the
table_idx
=
max_entries
+
1
;
* same value as DESC_TABLE, so we need to check.
}
else
{
*/
/* retore previous DESC_TABLE entry and start
if
(((
desc
&
DESC_MASK
)
==
TABLE_DESC
)
&&
* to iterate.
(
level
<
XLAT_TABLE_LEVEL_MAX
))
{
*/
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
;
/*
/*
*
Check if this is a table or a block. Tables
*
Do not print any PA for a table descriptor,
* a
re only allowed in levels other than 3, but
* a
s it doesn't directly map physical memory
*
DESC_PAGE has the same value as DESC_TABLE,
*
but instead points to the next translation
*
so we need to chec
k.
*
table in the translation table wal
k.
*/
*/
printf
(
"%sVA:0x%lx size:0x%zx
\n
"
,
level_spacers
[
level
],
table_idx_va
,
level_size
);
uintptr_t
addr_inner
=
desc
&
TABLE_ADDR_MASK
;
if
(((
desc
&
DESC_MASK
)
==
TABLE_DESC
)
&&
xlat_tables_print_internal
(
ctx
,
table_idx_va
,
(
this_level
<
XLAT_TABLE_LEVEL_MAX
))
{
(
uint64_t
*
)
addr_inner
,
uintptr_t
addr_inner
;
XLAT_TABLE_ENTRIES
,
level
+
1U
);
}
else
{
/*
printf
(
"%sVA:0x%lx PA:0x%llx size:0x%zx "
,
* Do not print any PA for a table
level_spacers
[
level
],
table_idx_va
,
* descriptor, as it doesn't directly
(
uint64_t
)(
desc
&
TABLE_ADDR_MASK
),
* map physical memory but instead
level_size
);
* points to the next translation
xlat_desc_print
(
ctx
,
desc
);
* table in the translation table walk.
printf
(
"
\n
"
);
*/
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
);
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment