xref: /rk3399_ARM-atf/docs/components/xlat-tables-lib-v2-design.rst (revision 8aa050554b996406231a66a048b56fa03ba220c8)
1Translation (XLAT) Tables Library
2=================================
3
4.. contents::
5
6
7This document describes the design of the translation tables library (version 2)
8used by Trusted Firmware-A (TF-A). This library provides APIs to create page
9tables based on a description of the memory layout, as well as setting up system
10registers related to the Memory Management Unit (MMU) and performing the
11required Translation Lookaside Buffer (TLB) maintenance operations.
12
13More specifically, some use cases that this library aims to support are:
14
15#. Statically allocate translation tables and populate them (at run-time) based
16   on a description of the memory layout. The memory layout is typically
17   provided by the platform port as a list of memory regions;
18
19#. Support for generating translation tables pertaining to a different
20   translation regime than the exception level the library code is executing at;
21
22#. Support for dynamic mapping and unmapping of regions, even while the MMU is
23   on. This can be used to temporarily map some memory regions and unmap them
24   later on when no longer needed;
25
26#. Support for non-identity virtual to physical mappings to compress the virtual
27   address space;
28
29#. Support for changing memory attributes of memory regions at run-time.
30
31
32About version 1 and version 2
33-----------------------------
34
35This document focuses on version 2 of the library, whose sources are available
36in the `lib/xlat_tables_v2`_ directory. Version 1 of the library can still be
37found in `lib/xlat_tables`_ directory but it is less flexible and doesn't
38support dynamic mapping. Although potential bug fixes will be applied to both
39versions, future features enhancements will focus on version 2 and might not be
40back-ported to version 1. Therefore, it is recommended to use version 2,
41especially for new platform ports.
42
43However, please note that version 2 is still in active development and is not
44considered stable yet. Hence, compatibility breaks might be introduced.
45
46From this point onwards, this document will implicitly refer to version 2 of the
47library.
48
49
50Design concepts and interfaces
51------------------------------
52
53This section presents some of the key concepts and data structures used in the
54translation tables library.
55
56`mmap` regions
57~~~~~~~~~~~~~~
58
59An ``mmap_region`` is an abstract, concise way to represent a memory region to
60map. It is one of the key interfaces to the library. It is identified by:
61
62- its physical base address;
63- its virtual base address;
64- its size;
65- its attributes;
66- its mapping granularity (optional).
67
68See the ``struct mmap_region`` type in `xlat_tables_v2.h`_.
69
70The user usually provides a list of such mmap regions to map and lets the
71library transpose that in a set of translation tables. As a result, the library
72might create new translation tables, update or split existing ones.
73
74The region attributes specify the type of memory (for example device or cached
75normal memory) as well as the memory access permissions (read-only or
76read-write, executable or not, secure or non-secure, and so on). In the case of
77the EL1&0 translation regime, the attributes also specify whether the region is
78a User region (EL0) or Privileged region (EL1). See the ``MT_xxx`` definitions
79in `xlat_tables_v2.h`_. Note that for the EL1&0 translation regime the Execute
80Never attribute is set simultaneously for both EL1 and EL0.
81
82The granularity controls the translation table level to go down to when mapping
83the region. For example, assuming the MMU has been configured to use a 4KB
84granule size, the library might map a 2MB memory region using either of the two
85following options:
86
87- using a single level-2 translation table entry;
88- using a level-2 intermediate entry to a level-3 translation table (which
89  contains 512 entries, each mapping 4KB).
90
91The first solution potentially requires less translation tables, hence
92potentially less memory.  However, if part of this 2MB region is later remapped
93with different memory attributes, the library might need to split the existing
94page tables to refine the mappings. If a single level-2 entry has been used
95here, a level-3 table will need to be allocated on the fly and the level-2
96modified to point to this new level-3 table. This has a performance cost at
97run-time.
98
99If the user knows upfront that such a remapping operation is likely to happen
100then they might enforce a 4KB mapping granularity for this 2MB region from the
101beginning; remapping some of these 4KB pages on the fly then becomes a
102lightweight operation.
103
104The region's granularity is an optional field; if it is not specified the
105library will choose the mapping granularity for this region as it sees fit (more
106details can be found in `The memory mapping algorithm`_ section below).
107
108Translation Context
109~~~~~~~~~~~~~~~~~~~
110
111The library can create or modify translation tables pertaining to a different
112translation regime than the exception level the library code is executing at.
113For example, the library might be used by EL3 software (for instance BL31) to
114create translation tables pertaining to the S-EL1&0 translation regime.
115
116This flexibility comes from the use of *translation contexts*. A *translation
117context* constitutes the superset of information used by the library to track
118the status of a set of translation tables for a given translation regime.
119
120The library internally allocates a default translation context, which pertains
121to the translation regime of the current exception level. Additional contexts
122may be explicitly allocated and initialized using the
123``REGISTER_XLAT_CONTEXT()`` macro. Separate APIs are provided to act either on
124the default translation context or on an alternative one.
125
126To register a translation context, the user must provide the library with the
127following information:
128
129* A name.
130
131  The resulting translation context variable will be called after this name, to
132  which ``_xlat_ctx`` is appended. For example, if the macro name parameter is
133  ``foo``, the context variable name will be ``foo_xlat_ctx``.
134
135* The maximum number of `mmap` regions to map.
136
137  Should account for both static and dynamic regions, if applicable.
138
139* The number of sub-translation tables to allocate.
140
141  Number of translation tables to statically allocate for this context,
142  excluding the initial lookup level translation table, which is always
143  allocated. For example, if the initial lookup level is 1, this parameter would
144  specify the number of level-2 and level-3 translation tables to pre-allocate
145  for this context.
146
147* The size of the virtual address space.
148
149  Size in bytes of the virtual address space to map using this context. This
150  will incidentally determine the number of entries in the initial lookup level
151  translation table : the library will allocate as many entries as is required
152  to map the entire virtual address space.
153
154* The size of the physical address space.
155
156  Size in bytes of the physical address space to map using this context.
157
158The default translation context is internally initialized using information
159coming (for the most part) from platform-specific defines:
160
161- name: hard-coded to ``tf`` ; hence the name of the default context variable is
162  ``tf_xlat_ctx``;
163- number of `mmap` regions: ``MAX_MMAP_REGIONS``;
164- number of sub-translation tables: ``MAX_XLAT_TABLES``;
165- size of the virtual address space: ``PLAT_VIRT_ADDR_SPACE_SIZE``;
166- size of the physical address space: ``PLAT_PHY_ADDR_SPACE_SIZE``.
167
168Please refer to the `Porting Guide`_ for more details about these macros.
169
170
171Static and dynamic memory regions
172~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
173
174The library optionally supports dynamic memory mapping. This feature may be
175enabled using the ``PLAT_XLAT_TABLES_DYNAMIC`` platform build flag.
176
177When dynamic memory mapping is enabled, the library categorises mmap regions as
178*static* or *dynamic*.
179
180- *Static regions* are fixed for the lifetime of the system. They can only be
181  added early on, before the translation tables are created and populated. They
182  cannot be removed afterwards.
183
184- *Dynamic regions* can be added or removed any time.
185
186When the dynamic memory mapping feature is disabled, only static regions exist.
187
188The dynamic memory mapping feature may be used to map and unmap transient memory
189areas. This is useful when the user needs to access some memory for a fixed
190period of time, after which the memory may be discarded and reclaimed. For
191example, a memory region that is only required at boot time while the system is
192initializing, or to temporarily share a memory buffer between the normal world
193and trusted world. Note that it is up to the caller to ensure that these regions
194are not accessed concurrently while the regions are being added or removed.
195
196Although this feature provides some level of dynamic memory allocation, this
197does not allow dynamically allocating an arbitrary amount of memory at an
198arbitrary memory location. The user is still required to declare at compile-time
199the limits of these allocations ; the library will deny any mapping request that
200does not fit within this pre-allocated pool of memory.
201
202
203Library APIs
204------------
205
206The external APIs exposed by this library are declared and documented in the
207`xlat_tables_v2.h`_ header file. This should be the reference point for
208getting information about the usage of the different APIs this library
209provides. This section just provides some extra details and clarifications.
210
211Although the ``mmap_region`` structure is a publicly visible type, it is not
212recommended to populate these structures by hand. Instead, wherever APIs expect
213function arguments of type ``mmap_region_t``, these should be constructed using
214the ``MAP_REGION*()`` family of helper macros. This is to limit the risk of
215compatibility breaks, should the ``mmap_region`` structure type evolve in the
216future.
217
218The ``MAP_REGION()`` and ``MAP_REGION_FLAT()`` macros do not allow specifying a
219mapping granularity, which leaves the library implementation free to choose
220it. However, in cases where a specific granularity is required, the
221``MAP_REGION2()`` macro might be used instead.
222
223As explained earlier in this document, when the dynamic mapping feature is
224disabled, there is no notion of dynamic regions. Conceptually, there are only
225static regions. For this reason (and to retain backward compatibility with the
226version 1 of the library), the APIs that map static regions do not embed the
227word *static* in their functions names (for example ``mmap_add_region()``), in
228contrast with the dynamic regions APIs (for example
229``mmap_add_dynamic_region()``).
230
231Although the definition of static and dynamic regions is not based on the state
232of the MMU, the two are still related in some way. Static regions can only be
233added before ``init_xlat_tables()`` is called and ``init_xlat_tables()`` must be
234called while the MMU is still off. As a result, static regions cannot be added
235once the MMU has been enabled. Dynamic regions can be added with the MMU on or
236off. In practice, the usual call flow would look like this:
237
238#. The MMU is initially off.
239
240#. Add some static regions, add some dynamic regions.
241
242#. Initialize translation tables based on the list of mmap regions (using one of
243   the ``init_xlat_tables*()`` APIs).
244
245#. At this point, it is no longer possible to add static regions. Dynamic
246   regions can still be added or removed.
247
248#. Enable the MMU.
249
250#. Dynamic regions can continue to be added or removed.
251
252Because static regions are added early on at boot time and are all in the
253control of the platform initialization code, the ``mmap_add*()`` family of APIs
254are not expected to fail. They do not return any error code.
255
256Nonetheless, these APIs will check upfront whether the region can be
257successfully added before updating the translation context structure. If the
258library detects that there is insufficient memory to meet the request, or that
259the new region will overlap another one in an invalid way, or if any other
260unexpected error is encountered, they will print an error message on the UART.
261Additionally, when asserts are enabled (typically in debug builds), an assertion
262will be triggered. Otherwise, the function call will just return straight away,
263without adding the offending memory region.
264
265
266Library limitations
267-------------------
268
269Dynamic regions are not allowed to overlap each other. Static regions are
270allowed to overlap as long as one of them is fully contained inside the other
271one. This is allowed for backwards compatibility with the previous behaviour in
272the version 1 of the library.
273
274
275Implementation details
276----------------------
277
278Code structure
279~~~~~~~~~~~~~~
280
281The library is divided into 4 modules:
282
283- **Core module**
284
285  Provides the main functionality of the library, such as the initialization of
286  translation tables contexts and mapping/unmapping memory regions. This module
287  provides functions such as ``mmap_add_region_ctx`` that let the caller specify
288  the translation tables context affected by them.
289
290  See `xlat_tables_core.c`_.
291
292- **Active context module**
293
294  Instantiates the context that is used by the current BL image and provides
295  helpers to manipulate it, abstracting it from the rest of the code.
296  This module provides functions such as ``mmap_add_region``, that directly
297  affect the BL image using them.
298
299  See `xlat_tables_context.c`_.
300
301- **Utilities module**
302
303  Provides additional functionality like debug print of the current state of the
304  translation tables and helpers to query memory attributes and to modify them.
305
306  See `xlat_tables_utils.c`_.
307
308- **Architectural module**
309
310  Provides functions that are dependent on the current execution state
311  (AArch32/AArch64), such as the functions used for TLB invalidation, setup the
312  MMU, or calculate the Physical Address Space size. They do not need a
313  translation context to work on.
314
315  See `aarch32/xlat_tables_arch.c`_ and `aarch64/xlat_tables_arch.c`_.
316
317From mmap regions to translation tables
318~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
319
320A translation context contains a list of ``mmap_region_t``, which holds the
321information of all the regions that are mapped at any given time. Whenever there
322is a request to map (resp. unmap) a memory region, it is added to (resp. removed
323from) the ``mmap_region_t`` list.
324
325The mmap regions list is a conceptual way to represent the memory layout. At
326some point, the library has to convert this information into actual translation
327tables to program into the MMU.
328
329Before the ``init_xlat_tables()`` API is called, the library only acts on the
330mmap regions list. Adding a static or dynamic region at this point through one
331of the ``mmap_add*()`` APIs does not affect the translation tables in any way,
332they only get registered in the internal mmap region list. It is only when the
333user calls the ``init_xlat_tables()`` that the translation tables are populated
334in memory based on the list of mmap regions registered so far. This is an
335optimization that allows creation of the initial set of translation tables in
336one go, rather than having to edit them every time while the MMU is disabled.
337
338After the ``init_xlat_tables()`` API has been called, only dynamic regions can
339be added. Changes to the translation tables (as well as the mmap regions list)
340will take effect immediately.
341
342The memory mapping algorithm
343~~~~~~~~~~~~~~~~~~~~~~~~~~~~
344
345The mapping function is implemented as a recursive algorithm. It is however
346bound by the level of depth of the translation tables (the Armv8-A architecture
347allows up to 4 lookup levels).
348
349By default [#granularity-ref]_, the algorithm will attempt to minimize the
350number of translation tables created to satisfy the user's request. It will
351favour mapping a region using the biggest possible blocks, only creating a
352sub-table if it is strictly necessary. This is to reduce the memory footprint of
353the firmware.
354
355The most common reason for needing a sub-table is when a specific mapping
356requires a finer granularity. Misaligned regions also require a finer
357granularity than what the user may had originally expected, using a lot more
358memory than expected. The reason is that all levels of translation are
359restricted to address translations of the same granularity as the size of the
360blocks of that level.  For example, for a 4 KiB page size, a level 2 block entry
361can only translate up to a granularity of 2 MiB. If the Physical Address is not
362aligned to 2 MiB then additional level 3 tables are also needed.
363
364Note that not every translation level allows any type of descriptor. Depending
365on the page size, levels 0 and 1 of translation may only allow table
366descriptors. If a block entry could be able to describe a translation, but that
367level does not allow block descriptors, a table descriptor will have to be used
368instead, as well as additional tables at the next level.
369
370|Alignment Example|
371
372The mmap regions are sorted in a way that simplifies the code that maps
373them. Even though this ordering is only strictly needed for overlapping static
374regions, it must also be applied for dynamic regions to maintain a consistent
375order of all regions at all times. As each new region is mapped, existing
376entries in the translation tables are checked to ensure consistency. Please
377refer to the comments in the source code of the core module for more details
378about the sorting algorithm in use.
379
380.. [#granularity-ref] That is, when mmap regions do not enforce their mapping
381                      granularity.
382
383TLB maintenance operations
384~~~~~~~~~~~~~~~~~~~~~~~~~~
385
386The library takes care of performing TLB maintenance operations when required.
387For example, when the user requests removing a dynamic region, the library
388invalidates all TLB entries associated to that region to ensure that these
389changes are visible to subsequent execution, including speculative execution,
390that uses the changed translation table entries.
391
392A counter-example is the initialization of translation tables. In this case,
393explicit TLB maintenance is not required. The Armv8-A architecture guarantees
394that all TLBs are disabled from reset and their contents have no effect on
395address translation at reset [#tlb-reset-ref]_. Therefore, the TLBs invalidation
396is deferred to the ``enable_mmu*()`` family of functions, just before the MMU is
397turned on.
398
399TLB invalidation is not required when adding dynamic regions either. Dynamic
400regions are not allowed to overlap existing memory region. Therefore, if the
401dynamic mapping request is deemed legitimate, it automatically concerns memory
402that was not mapped in this translation regime and the library will have
403initialized its corresponding translation table entry to an invalid
404descriptor. Given that the TLBs are not architecturally permitted to hold any
405invalid translation table entry [#tlb-no-invalid-entry]_, this means that this
406mapping cannot be cached in the TLBs.
407
408.. [#tlb-reset-ref] See section D4.9 `Translation Lookaside Buffers (TLBs)`, subsection `TLB behavior at reset` in Armv8-A, rev C.a.
409.. [#tlb-no-invalid-entry] See section D4.10.1 `General TLB maintenance requirements` in Armv8-A, rev C.a.
410
411--------------
412
413*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
414
415.. _lib/xlat_tables_v2: ../../lib/xlat_tables_v2
416.. _lib/xlat_tables: ../../lib/xlat_tables
417.. _xlat_tables_v2.h: ../../include/lib/xlat_tables/xlat_tables_v2.h
418.. _xlat_tables_context.c: ../../lib/xlat_tables_v2/xlat_tables_context.c
419.. _xlat_tables_core.c: ../../lib/xlat_tables_v2/xlat_tables_core.c
420.. _xlat_tables_utils.c: ../../lib/xlat_tables_v2/xlat_tables_utils.c
421.. _aarch32/xlat_tables_arch.c: ../../lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
422.. _aarch64/xlat_tables_arch.c: ../../lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
423.. _Porting Guide: ../getting_started/porting-guide.rst
424.. |Alignment Example| image:: ../diagrams/xlat_align.png?raw=true
425