xlat-tables-lib-v2-design.rst 20 KB

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