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