Line data Source code
1 0 : /* 2 : * Copyright 2019 Broadcom 3 : * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries. 4 : * 5 : * SPDX-License-Identifier: Apache-2.0 6 : */ 7 : #ifndef ZEPHYR_INCLUDE_ARCH_ARM64_ARM_MMU_H_ 8 : #define ZEPHYR_INCLUDE_ARCH_ARM64_ARM_MMU_H_ 9 : 10 : #ifndef _ASMLANGUAGE 11 : #include <stdint.h> 12 : #include <stdlib.h> 13 : #endif 14 : 15 : /* Following Memory types supported through MAIR encodings can be passed 16 : * by user through "attrs"(attributes) field of specified memory region. 17 : * As MAIR supports such 8 encodings, we will reserve attrs[2:0]; 18 : * so that we can provide encodings upto 7 if needed in future. 19 : */ 20 0 : #define MT_TYPE_MASK 0x7U 21 0 : #define MT_TYPE(attr) (attr & MT_TYPE_MASK) 22 0 : #define MT_DEVICE_nGnRnE 0U 23 0 : #define MT_DEVICE_nGnRE 1U 24 0 : #define MT_DEVICE_GRE 2U 25 0 : #define MT_NORMAL_NC 3U 26 0 : #define MT_NORMAL 4U 27 0 : #define MT_NORMAL_WT 5U 28 : 29 0 : #define MEMORY_ATTRIBUTES ((0x00 << (MT_DEVICE_nGnRnE * 8)) | \ 30 : (0x04 << (MT_DEVICE_nGnRE * 8)) | \ 31 : (0x0c << (MT_DEVICE_GRE * 8)) | \ 32 : (0x44 << (MT_NORMAL_NC * 8)) | \ 33 : (0xffUL << (MT_NORMAL * 8)) | \ 34 : (0xbbUL << (MT_NORMAL_WT * 8))) 35 : 36 : /* More flags from user's perspective are supported using remaining bits 37 : * of "attrs" field, i.e. attrs[31:3], underlying code will take care 38 : * of setting PTE fields correctly. 39 : * 40 : * current usage of attrs[31:3] is: 41 : * attrs[3] : Access Permissions 42 : * attrs[4] : Memory access from secure/ns state 43 : * attrs[5] : Execute Permissions privileged mode (PXN) 44 : * attrs[6] : Execute Permissions unprivileged mode (UXN) 45 : * attrs[7] : Mirror RO/RW permissions to EL0 46 : * attrs[8] : Overwrite existing mapping if any 47 : * attrs[9] : non-Global mapping (nG) 48 : * attrs[10]: Paged-out mapping 49 : * 50 : */ 51 0 : #define MT_PERM_SHIFT 3U 52 0 : #define MT_SEC_SHIFT 4U 53 0 : #define MT_P_EXECUTE_SHIFT 5U 54 0 : #define MT_U_EXECUTE_SHIFT 6U 55 0 : #define MT_RW_AP_SHIFT 7U 56 0 : #define MT_NO_OVERWRITE_SHIFT 8U 57 0 : #define MT_NON_GLOBAL_SHIFT 9U 58 0 : #define MT_PAGED_OUT_SHIFT 10U 59 : 60 0 : #define MT_RO (0U << MT_PERM_SHIFT) 61 0 : #define MT_RW (1U << MT_PERM_SHIFT) 62 : 63 0 : #define MT_RW_AP_ELx (1U << MT_RW_AP_SHIFT) 64 0 : #define MT_RW_AP_EL_HIGHER (0U << MT_RW_AP_SHIFT) 65 : 66 0 : #define MT_SECURE (0U << MT_SEC_SHIFT) 67 0 : #define MT_NS (1U << MT_SEC_SHIFT) 68 : 69 0 : #define MT_P_EXECUTE (0U << MT_P_EXECUTE_SHIFT) 70 0 : #define MT_P_EXECUTE_NEVER (1U << MT_P_EXECUTE_SHIFT) 71 : 72 0 : #define MT_U_EXECUTE (0U << MT_U_EXECUTE_SHIFT) 73 0 : #define MT_U_EXECUTE_NEVER (1U << MT_U_EXECUTE_SHIFT) 74 : 75 0 : #define MT_NO_OVERWRITE (1U << MT_NO_OVERWRITE_SHIFT) 76 : 77 0 : #define MT_G (0U << MT_NON_GLOBAL_SHIFT) 78 0 : #define MT_NG (1U << MT_NON_GLOBAL_SHIFT) 79 : 80 0 : #define MT_PAGED_OUT (1U << MT_PAGED_OUT_SHIFT) 81 : 82 0 : #define MT_P_RW_U_RW (MT_RW | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER) 83 0 : #define MT_P_RW_U_NA (MT_RW | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER) 84 0 : #define MT_P_RO_U_RO (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER) 85 0 : #define MT_P_RO_U_NA (MT_RO | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE_NEVER | MT_U_EXECUTE_NEVER) 86 0 : #define MT_P_RO_U_RX (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE_NEVER | MT_U_EXECUTE) 87 0 : #define MT_P_RX_U_RX (MT_RO | MT_RW_AP_ELx | MT_P_EXECUTE | MT_U_EXECUTE) 88 0 : #define MT_P_RX_U_NA (MT_RO | MT_RW_AP_EL_HIGHER | MT_P_EXECUTE | MT_U_EXECUTE_NEVER) 89 : 90 : #ifdef CONFIG_ARMV8_A_NS 91 : #define MT_DEFAULT_SECURE_STATE MT_NS 92 : #else 93 0 : #define MT_DEFAULT_SECURE_STATE MT_SECURE 94 : #endif 95 : 96 : /* Definitions used by arch_page_info_get() */ 97 0 : #define ARCH_DATA_PAGE_LOADED BIT(0) 98 0 : #define ARCH_DATA_PAGE_ACCESSED BIT(1) 99 0 : #define ARCH_DATA_PAGE_DIRTY BIT(2) 100 0 : #define ARCH_DATA_PAGE_NOT_MAPPED BIT(3) 101 : 102 : /* 103 : * Special unpaged "location" tags (highest possible descriptor physical 104 : * address values unlikely to conflict with backing store locations) 105 : */ 106 0 : #define ARCH_UNPAGED_ANON_ZERO 0x0000fffffffff000 107 0 : #define ARCH_UNPAGED_ANON_UNINIT 0x0000ffffffffe000 108 : 109 : #ifndef _ASMLANGUAGE 110 : 111 : /* Region definition data structure */ 112 : struct arm_mmu_region { 113 : /* Region Base Physical Address */ 114 : uintptr_t base_pa; 115 : /* Region Base Virtual Address */ 116 : uintptr_t base_va; 117 : /* Region size */ 118 : size_t size; 119 : /* Region Name */ 120 : const char *name; 121 : /* Region Attributes */ 122 : uint32_t attrs; 123 : }; 124 : 125 : /* MMU configuration data structure */ 126 : struct arm_mmu_config { 127 : /* Number of regions */ 128 0 : unsigned int num_regions; 129 : /* Regions */ 130 : const struct arm_mmu_region *mmu_regions; 131 : }; 132 : 133 0 : struct arm_mmu_ptables { 134 0 : uint64_t *base_xlat_table; 135 0 : uint64_t ttbr0; 136 : }; 137 : 138 : /* Convenience macros to represent the ARMv8-A-specific 139 : * configuration for memory access permission and 140 : * cache-ability attribution. 141 : */ 142 : 143 0 : #define MMU_REGION_ENTRY(_name, _base_pa, _base_va, _size, _attrs) \ 144 : {\ 145 : .name = _name, \ 146 : .base_pa = _base_pa, \ 147 : .base_va = _base_va, \ 148 : .size = _size, \ 149 : .attrs = _attrs, \ 150 : } 151 : 152 0 : #define MMU_REGION_FLAT_ENTRY(name, adr, sz, attrs) \ 153 : MMU_REGION_ENTRY(name, adr, adr, sz, attrs) 154 : 155 : /* 156 : * @brief Auto generate mmu region entry for node_id 157 : * 158 : * Example usage: 159 : * 160 : * @code{.c} 161 : * DT_FOREACH_STATUS_OKAY_VARGS(nxp_imx_gpio, 162 : * MMU_REGION_DT_FLAT_ENTRY, 163 : * (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS)) 164 : * @endcode 165 : * 166 : * @note Since devicetree_generated.h does not include 167 : * node_id##_P_reg_FOREACH_PROP_ELEM* definitions, 168 : * we can't automate dts node with multiple reg 169 : * entries. 170 : */ 171 0 : #define MMU_REGION_DT_FLAT_ENTRY(node_id, attrs) \ 172 : MMU_REGION_FLAT_ENTRY(DT_NODE_FULL_NAME(node_id), \ 173 : DT_REG_ADDR(node_id), \ 174 : DT_REG_SIZE(node_id), \ 175 : attrs), 176 : 177 : /* 178 : * @brief Auto generate mmu region entry for status = "okay" 179 : * nodes compatible to a driver 180 : * 181 : * Example usage: 182 : * 183 : * @code{.c} 184 : * MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(nxp_imx_gpio, 185 : * (MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_NS)) 186 : * @endcode 187 : * 188 : * @note This is a wrapper of @ref MMU_REGION_DT_FLAT_ENTRY 189 : */ 190 0 : #define MMU_REGION_DT_COMPAT_FOREACH_FLAT_ENTRY(compat, attr) \ 191 : DT_FOREACH_STATUS_OKAY_VARGS(compat, \ 192 : MMU_REGION_DT_FLAT_ENTRY, attr) 193 : 194 : /* Kernel macros for memory attribution 195 : * (access permissions and cache-ability). 196 : * 197 : * The macros are to be stored in k_mem_partition_attr_t 198 : * objects. The format of a k_mem_partition_attr_t object 199 : * is an uint32_t composed by permission and attribute flags 200 : * located in include/arch/arm64/arm_mmu.h 201 : */ 202 : 203 : /* Read-Write access permission attributes */ 204 0 : #define K_MEM_PARTITION_P_RW_U_RW ((k_mem_partition_attr_t) \ 205 : {MT_P_RW_U_RW}) 206 0 : #define K_MEM_PARTITION_P_RW_U_NA ((k_mem_partition_attr_t) \ 207 : {MT_P_RW_U_NA}) 208 0 : #define K_MEM_PARTITION_P_RO_U_RO ((k_mem_partition_attr_t) \ 209 : {MT_P_RO_U_RO}) 210 0 : #define K_MEM_PARTITION_P_RO_U_NA ((k_mem_partition_attr_t) \ 211 : {MT_P_RO_U_NA}) 212 : /* Execution-allowed attributes */ 213 0 : #define K_MEM_PARTITION_P_RX_U_RX ((k_mem_partition_attr_t) \ 214 : {MT_P_RX_U_RX}) 215 : /* Typedef for the k_mem_partition attribute */ 216 0 : typedef struct { uint32_t attrs; } k_mem_partition_attr_t; 217 : 218 : /* Reference to the MMU configuration. 219 : * 220 : * This struct is defined and populated for each SoC (in the SoC definition), 221 : * and holds the build-time configuration information for the fixed MMU 222 : * regions enabled during kernel initialization. 223 : */ 224 0 : extern const struct arm_mmu_config mmu_config; 225 : 226 : #endif /* _ASMLANGUAGE */ 227 : 228 : #endif /* ZEPHYR_INCLUDE_ARCH_ARM64_ARM_MMU_H_ */