Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
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
5c04fc78
Unverified
Commit
5c04fc78
authored
6 years ago
by
Antonio Niño Díaz
Committed by
GitHub
6 years ago
Browse files
Options
Download
Plain Diff
Merge pull request #1689 from antonio-nino-diaz-arm/an/alloc-va
xlat v2: Support mapping regions with allocated VA
parents
0668e5a8
9056f108
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
include/lib/xlat_tables/xlat_tables_v2.h
+36
-0
include/lib/xlat_tables/xlat_tables_v2.h
lib/xlat_tables_v2/xlat_tables_context.c
+33
-0
lib/xlat_tables_v2/xlat_tables_context.c
lib/xlat_tables_v2/xlat_tables_core.c
+91
-0
lib/xlat_tables_v2/xlat_tables_core.c
with
160 additions
and
0 deletions
+160
-0
include/lib/xlat_tables/xlat_tables_v2.h
View file @
5c04fc78
...
...
@@ -33,6 +33,12 @@
#define MAP_REGION_FLAT(_adr, _sz, _attr) \
MAP_REGION(_adr, _adr, _sz, _attr)
/*
* Helper macro to define entries for mmap_region_t. It allows to define 'pa'
* and sets 'va' to 0 for each region. To be used with mmap_add_alloc_va().
*/
#define MAP_REGION_ALLOC_VA(pa, sz, attr) MAP_REGION(pa, 0, sz, attr)
/*
* Helper macro to define an mmap_region_t to map with the desired granularity
* of translation tables.
...
...
@@ -219,6 +225,21 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm);
void
mmap_add
(
const
mmap_region_t
*
mm
);
void
mmap_add_ctx
(
xlat_ctx_t
*
ctx
,
const
mmap_region_t
*
mm
);
/*
* Add a region with defined base PA. Returns base VA calculated using the
* highest existing region in the mmap array even if it fails to allocate the
* region.
*/
void
mmap_add_region_alloc_va
(
unsigned
long
long
base_pa
,
uintptr_t
*
base_va
,
size_t
size
,
unsigned
int
attr
);
void
mmap_add_region_alloc_va_ctx
(
xlat_ctx_t
*
ctx
,
mmap_region_t
*
mm
);
/*
* Add an array of static regions with defined base PA, and fill the base VA
* field on the array of structs. This function can only be used before
* initializing the translation tables. The regions cannot be removed afterwards.
*/
void
mmap_add_alloc_va
(
mmap_region_t
*
mm
);
#if PLAT_XLAT_TABLES_DYNAMIC
/*
...
...
@@ -236,6 +257,21 @@ int mmap_add_dynamic_region(unsigned long long base_pa, uintptr_t base_va,
size_t
size
,
unsigned
int
attr
);
int
mmap_add_dynamic_region_ctx
(
xlat_ctx_t
*
ctx
,
mmap_region_t
*
mm
);
/*
* Add a dynamic region with defined base PA. Returns base VA calculated using
* the highest existing region in the mmap array even if it fails to allocate
* the region.
*
* mmap_add_dynamic_region_alloc_va() returns the allocated VA in 'base_va'.
* mmap_add_dynamic_region_alloc_va_ctx() returns it in 'mm->base_va'.
*
* It returns the same error values as mmap_add_dynamic_region().
*/
int
mmap_add_dynamic_region_alloc_va
(
unsigned
long
long
base_pa
,
uintptr_t
*
base_va
,
size_t
size
,
unsigned
int
attr
);
int
mmap_add_dynamic_region_alloc_va_ctx
(
xlat_ctx_t
*
ctx
,
mmap_region_t
*
mm
);
/*
* Remove a region with the specified base VA and size. Only dynamic regions can
* be removed, and they can be removed even if the translation tables are
...
...
This diff is collapsed.
Click to expand it.
lib/xlat_tables_v2/xlat_tables_context.c
View file @
5c04fc78
...
...
@@ -38,6 +38,25 @@ void mmap_add(const mmap_region_t *mm)
mmap_add_ctx
(
&
tf_xlat_ctx
,
mm
);
}
void
mmap_add_region_alloc_va
(
unsigned
long
long
base_pa
,
uintptr_t
*
base_va
,
size_t
size
,
unsigned
int
attr
)
{
mmap_region_t
mm
=
MAP_REGION_ALLOC_VA
(
base_pa
,
size
,
attr
);
mmap_add_region_alloc_va_ctx
(
&
tf_xlat_ctx
,
&
mm
);
*
base_va
=
mm
.
base_va
;
}
void
mmap_add_alloc_va
(
mmap_region_t
*
mm
)
{
while
(
mm
->
granularity
!=
0U
)
{
assert
(
mm
->
base_va
==
0U
);
mmap_add_region_alloc_va_ctx
(
&
tf_xlat_ctx
,
mm
);
mm
++
;
}
}
#if PLAT_XLAT_TABLES_DYNAMIC
int
mmap_add_dynamic_region
(
unsigned
long
long
base_pa
,
uintptr_t
base_va
,
...
...
@@ -48,6 +67,20 @@ int mmap_add_dynamic_region(unsigned long long base_pa, uintptr_t base_va,
return
mmap_add_dynamic_region_ctx
(
&
tf_xlat_ctx
,
&
mm
);
}
int
mmap_add_dynamic_region_alloc_va
(
unsigned
long
long
base_pa
,
uintptr_t
*
base_va
,
size_t
size
,
unsigned
int
attr
)
{
mmap_region_t
mm
=
MAP_REGION_ALLOC_VA
(
base_pa
,
size
,
attr
);
int
rc
=
mmap_add_dynamic_region_alloc_va_ctx
(
&
tf_xlat_ctx
,
&
mm
);
*
base_va
=
mm
.
base_va
;
return
rc
;
}
int
mmap_remove_dynamic_region
(
uintptr_t
base_va
,
size_t
size
)
{
return
mmap_remove_dynamic_region_ctx
(
&
tf_xlat_ctx
,
...
...
This diff is collapsed.
Click to expand it.
lib/xlat_tables_v2/xlat_tables_core.c
View file @
5c04fc78
...
...
@@ -811,6 +811,80 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
ctx
->
max_va
=
end_va
;
}
/*
* Determine the table level closest to the initial lookup level that
* can describe this translation. Then, align base VA to the next block
* at the determined level.
*/
static
void
mmap_alloc_va_align_ctx
(
xlat_ctx_t
*
ctx
,
mmap_region_t
*
mm
)
{
/*
* By or'ing the size and base PA the alignment will be the one
* corresponding to the smallest boundary of the two of them.
*
* There are three different cases. For example (for 4 KiB page size):
*
* +--------------+------------------++--------------+
* | PA alignment | Size multiple of || VA alignment |
* +--------------+------------------++--------------+
* | 2 MiB | 2 MiB || 2 MiB | (1)
* | 2 MiB | 4 KiB || 4 KiB | (2)
* | 4 KiB | 2 MiB || 4 KiB | (3)
* +--------------+------------------++--------------+
*
* - In (1), it is possible to take advantage of the alignment of the PA
* and the size of the region to use a level 2 translation table
* instead of a level 3 one.
*
* - In (2), the size is smaller than a block entry of level 2, so it is
* needed to use a level 3 table to describe the region or the library
* will map more memory than the desired one.
*
* - In (3), even though the region has the size of one level 2 block
* entry, it isn't possible to describe the translation with a level 2
* block entry because of the alignment of the base PA.
*
* Only bits 47:21 of a level 2 block descriptor are used by the MMU,
* bits 20:0 of the resulting address are 0 in this case. Because of
* this, the PA generated as result of this translation is aligned to
* 2 MiB. The PA that was requested to be mapped is aligned to 4 KiB,
* though, which means that the resulting translation is incorrect.
* The only way to prevent this is by using a finer granularity.
*/
unsigned
long
long
align_check
;
align_check
=
mm
->
base_pa
|
(
unsigned
long
long
)
mm
->
size
;
/*
* Assume it is always aligned to level 3. There's no need to check that
* level because its block size is PAGE_SIZE. The checks to verify that
* the addresses and size are aligned to PAGE_SIZE are inside
* mmap_add_region.
*/
for
(
unsigned
int
level
=
ctx
->
base_level
;
level
<=
2U
;
++
level
)
{
if
((
align_check
&
XLAT_BLOCK_MASK
(
level
))
!=
0U
)
continue
;
mm
->
base_va
=
round_up
(
mm
->
base_va
,
XLAT_BLOCK_SIZE
(
level
));
return
;
}
}
void
mmap_add_region_alloc_va_ctx
(
xlat_ctx_t
*
ctx
,
mmap_region_t
*
mm
)
{
mm
->
base_va
=
ctx
->
max_va
+
1UL
;
assert
(
mm
->
size
>
0U
);
mmap_alloc_va_align_ctx
(
ctx
,
mm
);
/* Detect overflows. More checks are done in mmap_add_region_check(). */
assert
(
mm
->
base_va
>
ctx
->
max_va
);
mmap_add_region_ctx
(
ctx
,
mm
);
}
void
mmap_add_ctx
(
xlat_ctx_t
*
ctx
,
const
mmap_region_t
*
mm
)
{
const
mmap_region_t
*
mm_cursor
=
mm
;
...
...
@@ -931,6 +1005,23 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
return
0
;
}
int
mmap_add_dynamic_region_alloc_va_ctx
(
xlat_ctx_t
*
ctx
,
mmap_region_t
*
mm
)
{
mm
->
base_va
=
ctx
->
max_va
+
1UL
;
if
(
mm
->
size
==
0U
)
return
0
;
mmap_alloc_va_align_ctx
(
ctx
,
mm
);
/* Detect overflows. More checks are done in mmap_add_region_check(). */
if
(
mm
->
base_va
<
ctx
->
max_va
)
{
return
-
ENOMEM
;
}
return
mmap_add_dynamic_region_ctx
(
ctx
,
mm
);
}
/*
* Removes the region with given base Virtual Address and size from the given
* context.
...
...
This diff is collapsed.
Click to expand it.
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
Menu
Projects
Groups
Snippets
Help