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