Soby Mathew | b4c6df4 | 2022-11-09 11:13:29 +0000 | [diff] [blame] | 1 | /* |
| 2 | * SPDX-License-Identifier: BSD-3-Clause |
| 3 | * SPDX-FileCopyrightText: Copyright TF-RMM Contributors. |
| 4 | * SPDX-FileCopyrightText: Copyright Arm Limited and Contributors. |
| 5 | */ |
| 6 | |
| 7 | /* This file is derived from xlat_table_v2 library in TF-A project */ |
| 8 | |
| 9 | #ifndef XLAT_TABLES_H |
| 10 | #define XLAT_TABLES_H |
| 11 | |
| 12 | #ifndef __ASSEMBLER__ |
| 13 | |
| 14 | #include <memory.h> |
| 15 | #include <stddef.h> |
| 16 | #include <stdint.h> |
| 17 | |
| 18 | #endif |
| 19 | |
| 20 | #include <xlat_contexts.h> |
| 21 | #include <xlat_defs.h> |
| 22 | |
| 23 | #ifndef __ASSEMBLER__ |
| 24 | |
| 25 | /* |
| 26 | * Default granularity size for a struct xlat_mmap_region. |
| 27 | * Useful when no specific granularity is required. |
| 28 | * |
| 29 | * By default, choose the biggest possible block size allowed by the |
| 30 | * architectural state and granule size in order to minimize the number of page |
| 31 | * tables required for the mapping. |
| 32 | */ |
| 33 | #define REGION_DEFAULT_GRANULARITY XLAT_BLOCK_SIZE(MIN_LVL_BLOCK_DESC) |
| 34 | |
| 35 | /* |
| 36 | * Helper macro to define a struct xlat_mmap_region. This macro allows to |
| 37 | * specify all the fields of the structure but its parameter list is not |
| 38 | * guaranteed to remain stable as we add members to struct xlat_mmap_region. |
| 39 | */ |
| 40 | #define MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr) \ |
| 41 | { \ |
| 42 | .base_pa = (_pa), \ |
| 43 | .base_va = (_va), \ |
| 44 | .size = (_sz), \ |
| 45 | .attr = (_attr), \ |
| 46 | .granularity = (_gr), \ |
| 47 | } |
| 48 | |
| 49 | /* Helper macro to define anstruct xlat_mmap_region. */ |
| 50 | #define MAP_REGION(_pa, _va, _sz, _attr) \ |
| 51 | MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, REGION_DEFAULT_GRANULARITY) |
| 52 | |
| 53 | /* Helper macro to define anstruct xlat_mmap_region with an identity mapping. */ |
| 54 | #define MAP_REGION_FLAT(_adr, _sz, _attr) \ |
| 55 | MAP_REGION(_adr, _adr, _sz, _attr) |
| 56 | |
| 57 | /* |
| 58 | * Helper macro to define an mmap_region_t to map with the desired granularity |
| 59 | * of translation tables but with invalid page descriptors. |
| 60 | * |
| 61 | * The granularity value passed to this macro must be a valid block or page |
| 62 | * size. When using a 4KB translation granule, this might be 4KB, 2MB or 1GB. |
| 63 | * Passing REGION_DEFAULT_GRANULARITY is also allowed and means that the library |
| 64 | * is free to choose the granularity for this region. |
| 65 | * |
| 66 | * This macro can be used to define transient regions where memory used to |
| 67 | * reserve VA can be assigned to a PA dynamically. These VA will fault if it |
| 68 | * is accessed before a valid PA is assigned to it. |
| 69 | */ |
| 70 | |
| 71 | #define MAP_REGION_TRANSIENT(_va, _sz, _gr) \ |
| 72 | MAP_REGION_FULL_SPEC(ULL(0), _va, _sz, MT_TRANSIENT, _gr) |
| 73 | |
| 74 | /* Definition of an invalid descriptor */ |
| 75 | #define INVALID_DESC UL(0x0) |
| 76 | |
| 77 | /* |
| 78 | * Shifts and masks to access fields of an mmap attribute |
| 79 | */ |
| 80 | #define MT_TYPE_SHIFT UL(0) |
| 81 | #define MT_TYPE_WIDTH UL(4) |
| 82 | #define MT_TYPE_MASK MASK(MT_TYPE) |
| 83 | #define MT_TYPE(_attr) ((_attr) & MT_TYPE_MASK) |
| 84 | /* Access permissions (RO/RW) */ |
| 85 | #define MT_PERM_SHIFT (MT_TYPE_SHIFT + MT_TYPE_WIDTH) |
| 86 | /* Access permissions for instruction execution (EXECUTE/EXECUTE_NEVER) */ |
| 87 | #define MT_EXECUTE_FLAG_SHIFT (MT_PERM_SHIFT + 1UL) |
| 88 | |
| 89 | /* Contiguos descriptor flag */ |
| 90 | #define MT_CONT_SHIFT (MT_EXECUTE_FLAG_SHIFT + 1UL) |
| 91 | |
| 92 | /* NG Flag */ |
| 93 | #define MT_NG_SHIFT (MT_CONT_SHIFT + 1UL) |
| 94 | |
| 95 | /* Shareability attribute for the memory region */ |
| 96 | #define MT_SHAREABILITY_SHIFT (MT_NG_SHIFT + 1UL) |
| 97 | #define MT_SHAREABILITY_WIDTH UL(2) |
| 98 | #define MT_SHAREABILITY_MASK MASK(MT_SHAREABILITY) |
| 99 | #define MT_SHAREABILITY(_attr) ((_attr) & MT_SHAREABILITY_MASK) |
| 100 | |
| 101 | /* Physical address space (REALM/NS, as ROOT/SECURE do not apply to R-EL2) */ |
| 102 | #define MT_PAS_SHIFT (MT_SHAREABILITY_SHIFT + MT_SHAREABILITY_WIDTH) |
| 103 | #define MT_PAS_WIDTH UL(1) |
| 104 | #define MT_PAS_MASK MASK(MT_PAS) |
| 105 | #define MT_PAS(_attr) ((_attr) & MT_PAS_MASK) |
| 106 | |
| 107 | /* All other bits are reserved */ |
| 108 | |
Javier Almansa Sobrino | bb66f8a | 2023-01-05 16:43:43 +0000 | [diff] [blame^] | 109 | /* Macro to access translatio table lower attributes */ |
| 110 | #define LOWER_ATTRS(x) (((x) & UL(0xfff)) << UL(2)) |
| 111 | |
| 112 | /* Public definitions to use with the LOWER_ATTRS() macro*/ |
| 113 | #define NS (U(0x1) << UL(3)) /* Bit[5] absolutely */ |
| 114 | |
Soby Mathew | b4c6df4 | 2022-11-09 11:13:29 +0000 | [diff] [blame] | 115 | /* |
| 116 | * Memory mapping attributes |
| 117 | */ |
| 118 | |
| 119 | /* |
| 120 | * Memory types supported. |
| 121 | * These are organised so that, going down the list, the memory types are |
| 122 | * getting weaker; conversely going up the list the memory types are getting |
| 123 | * stronger. |
| 124 | */ |
| 125 | #define MT_DEVICE UL(0) |
| 126 | #define MT_NON_CACHEABLE UL(1) |
| 127 | #define MT_MEMORY UL(2) |
| 128 | #define MT_TRANSIENT UL(3) |
| 129 | /* Values up to 7 are reserved to add new memory types in the future */ |
| 130 | |
| 131 | #define MT_RO INPLACE(MT_PERM, 0UL) |
| 132 | #define MT_RW INPLACE(MT_PERM, 1UL) |
| 133 | |
| 134 | #define MT_REALM INPLACE(MT_PAS, 0UL) |
| 135 | #define MT_NS INPLACE(MT_PAS, 1UL) |
| 136 | |
| 137 | /* |
| 138 | * Access permissions for instruction execution are only relevant for normal |
| 139 | * read-only memory, i.e. MT_MEMORY | MT_RO. They are ignored (and potentially |
| 140 | * overridden) otherwise: |
| 141 | * - Device memory is always marked as execute-never. |
| 142 | * - Read-write normal memory is always marked as execute-never. |
| 143 | */ |
| 144 | #define MT_EXECUTE INPLACE(MT_EXECUTE_FLAG, 0UL) |
| 145 | #define MT_EXECUTE_NEVER INPLACE(MT_EXECUTE_FLAG, 1UL) |
| 146 | |
| 147 | /* |
| 148 | * Shareability defines the visibility of any cache changes to |
| 149 | * all masters belonging to a shareable domain. |
| 150 | * |
| 151 | * MT_SHAREABILITY_ISH: For inner shareable domain |
| 152 | * MT_SHAREABILITY_OSH: For outer shareable domain |
| 153 | * MT_SHAREABILITY_NSH: For non shareable domain |
| 154 | */ |
| 155 | #define MT_SHAREABILITY_ISH INPLACE(MT_SHAREABILITY, 1UL) |
| 156 | #define MT_SHAREABILITY_OSH INPLACE(MT_SHAREABILITY, 2UL) |
| 157 | #define MT_SHAREABILITY_NSH INPLACE(MT_SHAREABILITY, 3UL) |
| 158 | |
| 159 | #define MT_CONT INPLACE(MT_CONT, 1UL) |
| 160 | #define MT_NG INPLACE(MT_NG, 1UL) |
| 161 | |
| 162 | /* Compound attributes for most common usages */ |
| 163 | #define MT_CODE (MT_MEMORY | MT_SHAREABILITY_ISH \ |
| 164 | | MT_RO | MT_EXECUTE) |
| 165 | #define MT_RO_DATA (MT_MEMORY | MT_SHAREABILITY_ISH \ |
| 166 | | MT_RO | MT_EXECUTE_NEVER) |
| 167 | #define MT_RW_DATA (MT_MEMORY | MT_SHAREABILITY_ISH \ |
| 168 | | MT_RW | MT_EXECUTE_NEVER) |
| 169 | |
| 170 | /* |
| 171 | * Structure for specifying a single region of memory. |
| 172 | */ |
| 173 | struct xlat_mmap_region { |
| 174 | uintptr_t base_pa; /* Base PA for the current region. */ |
| 175 | uintptr_t base_va; /* Base VA for the current region. */ |
| 176 | size_t size; /* Size of the current region. */ |
| 177 | uint64_t attr; /* Attrs for the current region. */ |
| 178 | size_t granularity; /* Region granularity. */ |
| 179 | }; |
| 180 | |
| 181 | /* |
| 182 | * Structure containing a table entry and its related information. |
| 183 | */ |
| 184 | struct xlat_table_entry { |
| 185 | uint64_t *table; /* Pointer to the translation table. */ |
| 186 | uintptr_t base_va; /* Context base VA for the current entry. */ |
| 187 | unsigned int level; /* Table level of the current entry. */ |
| 188 | unsigned int entries; /* Number of entries used by this table. */ |
| 189 | }; |
| 190 | |
| 191 | /****************************************************************************** |
| 192 | * Generic translation table APIs. |
| 193 | *****************************************************************************/ |
| 194 | |
| 195 | static inline void xlat_write_descriptor(uint64_t *entry, uint64_t desc) |
| 196 | { |
| 197 | SCA_WRITE64(entry, desc); |
| 198 | } |
| 199 | |
| 200 | static inline uint64_t xlat_read_descriptor(uint64_t *entry) |
| 201 | { |
| 202 | return SCA_READ64(entry); |
| 203 | } |
| 204 | |
| 205 | /* |
| 206 | * Initialize translation tables (and mark xlat_ctx_cfg as initialized if |
| 207 | * not already initialized) associated to the current context. |
| 208 | * |
| 209 | * The struct xlat_ctx_cfg of the context might be shared with other |
| 210 | * contexts that might have already initialized it. This is expected and |
| 211 | * should not cause any problem. |
| 212 | * |
| 213 | * This function assumes that the xlat_ctx_cfg field of the context has been |
| 214 | * properly configured by previous calls to xlat_mmap_add_region_ctx(). |
| 215 | * |
| 216 | * This function returns 0 on success or an error code otherwise. |
| 217 | */ |
| 218 | int xlat_init_tables_ctx(struct xlat_ctx *ctx); |
| 219 | |
| 220 | /* |
| 221 | * Add a memory region with defined base PA and base VA. This function can only |
| 222 | * be used before marking the xlat_ctx_cfg for the current xlat_ctx as |
| 223 | * initialized. |
| 224 | * |
| 225 | * The region cannot be removed once added. |
| 226 | * |
| 227 | * This function returns 0 on success or an error code otherwise. |
| 228 | */ |
| 229 | int xlat_mmap_add_region_ctx(struct xlat_ctx *ctx, |
| 230 | struct xlat_mmap_region *mm); |
| 231 | |
| 232 | /* |
| 233 | * Add an array of memory regions with defined base PA and base VA. |
| 234 | * This function needs to be called before initialiting the xlat_ctx_cfg. |
| 235 | * Setting the `last` argument to true will initialise the xlat_ctx_cfg. |
| 236 | * |
| 237 | * The regions cannot be removed once added. |
| 238 | * |
| 239 | * Return 0 on success or a negative error code otherwise. |
| 240 | */ |
| 241 | int xlat_mmap_add_ctx(struct xlat_ctx *ctx, |
| 242 | struct xlat_mmap_region *mm, |
| 243 | bool last); |
| 244 | |
| 245 | /* |
| 246 | * Return a table entry structure given a context and a VA. |
| 247 | * The return structure is populated on the retval field. |
| 248 | * |
| 249 | * This function returns 0 on success or a negative error code otherwise. |
| 250 | */ |
| 251 | int xlat_get_table_from_va(struct xlat_table_entry * const retval, |
| 252 | const struct xlat_ctx * const ctx, |
| 253 | const uintptr_t va); |
| 254 | |
| 255 | /* |
| 256 | * Function to unmap a physical memory page from the descriptor entry and |
| 257 | * VA given. |
| 258 | * This function implements the "Break" part of the Break-Before-Make semantics |
| 259 | * mandated by the Armv8.x architecture in order to update the page descriptors. |
| 260 | * |
| 261 | * This function returns 0 on success or a negative error code otherwise. |
| 262 | */ |
| 263 | int xlat_unmap_memory_page(struct xlat_table_entry * const table, |
| 264 | const uintptr_t va); |
| 265 | |
| 266 | /* |
| 267 | * Function to map a physical memory page from the descriptor table entry |
| 268 | * and VA given. This function implements the "Make" part of the |
| 269 | * Break-Before-Make semantics mandated by the armv8.x architecture in order |
| 270 | * to update the page descriptors. |
| 271 | * |
| 272 | * This function returns 0 on success or a negative error code otherwise. |
| 273 | */ |
| 274 | int xlat_map_memory_page_with_attrs(const struct xlat_table_entry * const table, |
| 275 | const uintptr_t va, |
| 276 | const uintptr_t pa, |
| 277 | const uint64_t attrs); |
| 278 | |
| 279 | /* |
| 280 | * This function finds the descriptor entry on a table given the corresponding |
| 281 | * table entry structure and the VA for that descriptor. |
| 282 | * |
| 283 | */ |
| 284 | uint64_t *xlat_get_pte_from_table(const struct xlat_table_entry * const table, |
| 285 | const uintptr_t va); |
| 286 | |
| 287 | /* |
| 288 | * Set up the MMU configuration registers for the specified platform parameters. |
| 289 | * |
| 290 | * This function must be called for each context as it configures the |
| 291 | * appropriate TTBRx register depending on it. |
| 292 | * |
| 293 | * This function also assumes that the contexts for high and low VA halfs share |
| 294 | * the same virtual address space as well as the same physical address space, |
| 295 | * so it is safe to call it for each context initialization. |
| 296 | * |
| 297 | * Returns 0 on success or a negative error code otherwise. |
| 298 | */ |
| 299 | int xlat_arch_setup_mmu_cfg(struct xlat_ctx * const ctx); |
| 300 | |
| 301 | /* MMU control */ |
| 302 | void xlat_enable_mmu_el2(void); |
| 303 | |
| 304 | /* |
| 305 | * Returns true if the xlat_ctx_cfg field in the xlat_ctx is initialized. |
| 306 | */ |
| 307 | bool xlat_ctx_cfg_initialized(const struct xlat_ctx * const ctx); |
| 308 | |
| 309 | /* |
| 310 | * Returns true if the translation tables on the current context are already |
| 311 | * initialized or false otherwise. |
| 312 | */ |
| 313 | bool xlat_ctx_tbls_initialized(const struct xlat_ctx * const ctx); |
| 314 | |
| 315 | /* |
| 316 | * Initialize a context dynamically at runtime using the given xlat_ctx_cfg |
| 317 | * and xlat_ctx_tbls structures. |
| 318 | * |
| 319 | * Return 0 if success or a Posix erro code otherwise. |
| 320 | */ |
| 321 | int xlat_ctx_create_dynamic(struct xlat_ctx *ctx, |
| 322 | struct xlat_ctx_cfg *cfg, |
| 323 | struct xlat_ctx_tbls *tbls, |
| 324 | void *base_tables, |
| 325 | unsigned int base_level_entries, |
| 326 | void *tables_ptr, |
| 327 | unsigned int ntables); |
| 328 | |
| 329 | #endif /*__ASSEMBLER__*/ |
| 330 | #endif /* XLAT_TABLES_H */ |