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