xlat_tables_v2_helpers.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. /*
  7. * This header file contains internal definitions that are not supposed to be
  8. * used outside of this library code.
  9. */
  10. #ifndef XLAT_TABLES_V2_HELPERS_H
  11. #define XLAT_TABLES_V2_HELPERS_H
  12. #ifndef XLAT_TABLES_V2_H
  13. #error "Do not include this header file directly. Include xlat_tables_v2.h instead."
  14. #endif
  15. #ifndef __ASSEMBLER__
  16. #include <stdbool.h>
  17. #include <stddef.h>
  18. #include <platform_def.h>
  19. #include <lib/cassert.h>
  20. #include <lib/utils_def.h>
  21. #include <lib/xlat_tables/xlat_tables_arch.h>
  22. #include <lib/xlat_tables/xlat_tables_defs.h>
  23. /* Forward declaration */
  24. struct mmap_region;
  25. /*
  26. * Helper macro to define an mmap_region_t. This macro allows to specify all
  27. * the fields of the structure but its parameter list is not guaranteed to
  28. * remain stable as we add members to mmap_region_t.
  29. */
  30. #define MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr) \
  31. { \
  32. .base_pa = (_pa), \
  33. .base_va = (_va), \
  34. .size = (_sz), \
  35. .attr = (_attr), \
  36. .granularity = (_gr), \
  37. }
  38. /* Struct that holds all information about the translation tables. */
  39. struct xlat_ctx {
  40. /*
  41. * Max allowed Virtual and Physical Addresses.
  42. */
  43. unsigned long long pa_max_address;
  44. uintptr_t va_max_address;
  45. /*
  46. * Array of all memory regions stored in order of ascending end address
  47. * and ascending size to simplify the code that allows overlapping
  48. * regions. The list is terminated by the first entry with size == 0.
  49. * The max size of the list is stored in `mmap_num`. `mmap` points to an
  50. * array of mmap_num + 1 elements, so that there is space for the final
  51. * null entry.
  52. */
  53. struct mmap_region *mmap;
  54. int mmap_num;
  55. /*
  56. * Array of finer-grain translation tables.
  57. * For example, if the initial lookup level is 1 then this array would
  58. * contain both level-2 and level-3 entries.
  59. */
  60. uint64_t (*tables)[XLAT_TABLE_ENTRIES];
  61. int tables_num;
  62. #if PLAT_RO_XLAT_TABLES
  63. bool readonly_tables;
  64. #endif
  65. /*
  66. * Keep track of how many regions are mapped in each table. The base
  67. * table can't be unmapped so it isn't needed to keep track of it.
  68. */
  69. #if PLAT_XLAT_TABLES_DYNAMIC
  70. int *tables_mapped_regions;
  71. #endif /* PLAT_XLAT_TABLES_DYNAMIC */
  72. int next_table;
  73. /*
  74. * Base translation table. It doesn't need to have the same amount of
  75. * entries as the ones used for other levels.
  76. */
  77. uint64_t *base_table;
  78. unsigned int base_table_entries;
  79. /*
  80. * Max Physical and Virtual addresses currently in use by the
  81. * translation tables. These might get updated as we map/unmap memory
  82. * regions but they will never go beyond pa/va_max_address.
  83. */
  84. unsigned long long max_pa;
  85. uintptr_t max_va;
  86. /* Level of the base translation table. */
  87. unsigned int base_level;
  88. /* Set to true when the translation tables are initialized. */
  89. bool initialized;
  90. /*
  91. * Translation regime managed by this xlat_ctx_t. It should be one of
  92. * the EL*_REGIME defines.
  93. */
  94. int xlat_regime;
  95. };
  96. #if PLAT_XLAT_TABLES_DYNAMIC
  97. #define XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
  98. static int _ctx_name##_mapped_regions[_xlat_tables_count];
  99. #define XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
  100. .tables_mapped_regions = _ctx_name##_mapped_regions,
  101. #else
  102. #define XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
  103. /* do nothing */
  104. #define XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
  105. /* do nothing */
  106. #endif /* PLAT_XLAT_TABLES_DYNAMIC */
  107. #if PLAT_RO_XLAT_TABLES
  108. #define XLAT_CTX_INIT_TABLE_ATTR() \
  109. .readonly_tables = false,
  110. #else
  111. #define XLAT_CTX_INIT_TABLE_ATTR()
  112. /* do nothing */
  113. #endif
  114. #define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \
  115. _xlat_tables_count, _virt_addr_space_size, \
  116. _phy_addr_space_size, _xlat_regime, \
  117. _table_section, _base_table_section) \
  118. CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \
  119. assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
  120. \
  121. static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \
  122. \
  123. static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \
  124. [XLAT_TABLE_ENTRIES] \
  125. __aligned(XLAT_TABLE_SIZE) __section(_table_section); \
  126. \
  127. static uint64_t _ctx_name##_base_xlat_table \
  128. [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \
  129. __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\
  130. * sizeof(uint64_t)) \
  131. __section(_base_table_section); \
  132. \
  133. XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
  134. \
  135. static xlat_ctx_t _ctx_name##_xlat_ctx = { \
  136. .pa_max_address = (_phy_addr_space_size) - 1ULL, \
  137. .va_max_address = (_virt_addr_space_size) - 1UL, \
  138. .mmap = _ctx_name##_mmap, \
  139. .mmap_num = (_mmap_count), \
  140. .tables = _ctx_name##_xlat_tables, \
  141. .tables_num = ARRAY_SIZE(_ctx_name##_xlat_tables), \
  142. XLAT_CTX_INIT_TABLE_ATTR() \
  143. XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
  144. .next_table = 0, \
  145. .base_table = _ctx_name##_base_xlat_table, \
  146. .base_table_entries = \
  147. ARRAY_SIZE(_ctx_name##_base_xlat_table), \
  148. .max_pa = 0U, \
  149. .max_va = 0U, \
  150. .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
  151. .initialized = false, \
  152. .xlat_regime = (_xlat_regime) \
  153. }
  154. #endif /*__ASSEMBLER__*/
  155. #endif /* XLAT_TABLES_V2_HELPERS_H */