Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0-only */ 2 : : /* 3 : : * arch/arm/include/asm/memory.h 4 : : * 5 : : * Copyright (C) 2000-2002 Russell King 6 : : * modification for nommu, Hyok S. Choi, 2004 7 : : * 8 : : * Note: this file should not be included by non-asm/.h files 9 : : */ 10 : : #ifndef __ASM_ARM_MEMORY_H 11 : : #define __ASM_ARM_MEMORY_H 12 : : 13 : : #include <linux/compiler.h> 14 : : #include <linux/const.h> 15 : : #include <linux/types.h> 16 : : #include <linux/sizes.h> 17 : : 18 : : #ifdef CONFIG_NEED_MACH_MEMORY_H 19 : : #include <mach/memory.h> 20 : : #endif 21 : : 22 : : /* PAGE_OFFSET - the virtual address of the start of the kernel image */ 23 : : #define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) 24 : : 25 : : #ifdef CONFIG_MMU 26 : : 27 : : /* 28 : : * TASK_SIZE - the maximum size of a user space task. 29 : : * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area 30 : : */ 31 : : #define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(SZ_16M)) 32 : : #define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_16M) 33 : : 34 : : /* 35 : : * The maximum size of a 26-bit user space task. 36 : : */ 37 : : #define TASK_SIZE_26 (UL(1) << 26) 38 : : 39 : : /* 40 : : * The module space lives between the addresses given by TASK_SIZE 41 : : * and PAGE_OFFSET - it must be within 32MB of the kernel text. 42 : : */ 43 : : #ifndef CONFIG_THUMB2_KERNEL 44 : : #define MODULES_VADDR (PAGE_OFFSET - SZ_16M) 45 : : #else 46 : : /* smaller range for Thumb-2 symbols relocation (2^24)*/ 47 : : #define MODULES_VADDR (PAGE_OFFSET - SZ_8M) 48 : : #endif 49 : : 50 : : #if TASK_SIZE > MODULES_VADDR 51 : : #error Top of user space clashes with start of module space 52 : : #endif 53 : : 54 : : /* 55 : : * The highmem pkmap virtual space shares the end of the module area. 56 : : */ 57 : : #ifdef CONFIG_HIGHMEM 58 : : #define MODULES_END (PAGE_OFFSET - PMD_SIZE) 59 : : #else 60 : : #define MODULES_END (PAGE_OFFSET) 61 : : #endif 62 : : 63 : : /* 64 : : * The XIP kernel gets mapped at the bottom of the module vm area. 65 : : * Since we use sections to map it, this macro replaces the physical address 66 : : * with its virtual address while keeping offset from the base section. 67 : : */ 68 : : #define XIP_VIRT_ADDR(physaddr) (MODULES_VADDR + ((physaddr) & 0x000fffff)) 69 : : 70 : : #if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE) 71 : : /* 72 : : * Allow 16MB-aligned ioremap pages 73 : : */ 74 : : #define IOREMAP_MAX_ORDER 24 75 : : #endif 76 : : 77 : : #define VECTORS_BASE UL(0xffff0000) 78 : : 79 : : #else /* CONFIG_MMU */ 80 : : 81 : : #ifndef __ASSEMBLY__ 82 : : extern unsigned long setup_vectors_base(void); 83 : : extern unsigned long vectors_base; 84 : : #define VECTORS_BASE vectors_base 85 : : #endif 86 : : 87 : : /* 88 : : * The limitation of user task size can grow up to the end of free ram region. 89 : : * It is difficult to define and perhaps will never meet the original meaning 90 : : * of this define that was meant to. 91 : : * Fortunately, there is no reference for this in noMMU mode, for now. 92 : : */ 93 : : #define TASK_SIZE UL(0xffffffff) 94 : : 95 : : #ifndef TASK_UNMAPPED_BASE 96 : : #define TASK_UNMAPPED_BASE UL(0x00000000) 97 : : #endif 98 : : 99 : : #ifndef END_MEM 100 : : #define END_MEM (UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE) 101 : : #endif 102 : : 103 : : /* 104 : : * The module can be at any place in ram in nommu mode. 105 : : */ 106 : : #define MODULES_END (END_MEM) 107 : : #define MODULES_VADDR PAGE_OFFSET 108 : : 109 : : #define XIP_VIRT_ADDR(physaddr) (physaddr) 110 : : 111 : : #endif /* !CONFIG_MMU */ 112 : : 113 : : #ifdef CONFIG_XIP_KERNEL 114 : : #define KERNEL_START _sdata 115 : : #else 116 : : #define KERNEL_START _stext 117 : : #endif 118 : : #define KERNEL_END _end 119 : : 120 : : /* 121 : : * We fix the TCM memories max 32 KiB ITCM resp DTCM at these 122 : : * locations 123 : : */ 124 : : #ifdef CONFIG_HAVE_TCM 125 : : #define ITCM_OFFSET UL(0xfffe0000) 126 : : #define DTCM_OFFSET UL(0xfffe8000) 127 : : #endif 128 : : 129 : : /* 130 : : * Convert a page to/from a physical address 131 : : */ 132 : : #define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page))) 133 : : #define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys))) 134 : : 135 : : /* 136 : : * PLAT_PHYS_OFFSET is the offset (from zero) of the start of physical 137 : : * memory. This is used for XIP and NoMMU kernels, and on platforms that don't 138 : : * have CONFIG_ARM_PATCH_PHYS_VIRT. Assembly code must always use 139 : : * PLAT_PHYS_OFFSET and not PHYS_OFFSET. 140 : : */ 141 : : #define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET) 142 : : 143 : : #ifdef CONFIG_XIP_KERNEL 144 : : /* 145 : : * When referencing data in RAM from the XIP region in a relative manner 146 : : * with the MMU off, we need the relative offset between the two physical 147 : : * addresses. The macro below achieves this, which is: 148 : : * __pa(v_data) - __xip_pa(v_text) 149 : : */ 150 : : #define PHYS_RELATIVE(v_data, v_text) \ 151 : : (((v_data) - PAGE_OFFSET + PLAT_PHYS_OFFSET) - \ 152 : : ((v_text) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) + \ 153 : : CONFIG_XIP_PHYS_ADDR)) 154 : : #else 155 : : #define PHYS_RELATIVE(v_data, v_text) ((v_data) - (v_text)) 156 : : #endif 157 : : 158 : : #ifndef __ASSEMBLY__ 159 : : 160 : : /* 161 : : * Physical vs virtual RAM address space conversion. These are 162 : : * private definitions which should NOT be used outside memory.h 163 : : * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. 164 : : * 165 : : * PFNs are used to describe any physical page; this means 166 : : * PFN 0 == physical address 0. 167 : : */ 168 : : 169 : : #if defined(CONFIG_ARM_PATCH_PHYS_VIRT) 170 : : 171 : : /* 172 : : * Constants used to force the right instruction encodings and shifts 173 : : * so that all we need to do is modify the 8-bit constant field. 174 : : */ 175 : : #define __PV_BITS_31_24 0x81000000 176 : : #define __PV_BITS_7_0 0x81 177 : : 178 : : extern unsigned long __pv_phys_pfn_offset; 179 : : extern u64 __pv_offset; 180 : : extern void fixup_pv_table(const void *, unsigned long); 181 : : extern const void *__pv_table_begin, *__pv_table_end; 182 : : 183 : : #define PHYS_OFFSET ((phys_addr_t)__pv_phys_pfn_offset << PAGE_SHIFT) 184 : : #define PHYS_PFN_OFFSET (__pv_phys_pfn_offset) 185 : : 186 : : #define __pv_stub(from,to,instr,type) \ 187 : : __asm__("@ __pv_stub\n" \ 188 : : "1: " instr " %0, %1, %2\n" \ 189 : : " .pushsection .pv_table,\"a\"\n" \ 190 : : " .long 1b\n" \ 191 : : " .popsection\n" \ 192 : : : "=r" (to) \ 193 : : : "r" (from), "I" (type)) 194 : : 195 : : #define __pv_stub_mov_hi(t) \ 196 : : __asm__ volatile("@ __pv_stub_mov\n" \ 197 : : "1: mov %R0, %1\n" \ 198 : : " .pushsection .pv_table,\"a\"\n" \ 199 : : " .long 1b\n" \ 200 : : " .popsection\n" \ 201 : : : "=r" (t) \ 202 : : : "I" (__PV_BITS_7_0)) 203 : : 204 : : #define __pv_add_carry_stub(x, y) \ 205 : : __asm__ volatile("@ __pv_add_carry_stub\n" \ 206 : : "1: adds %Q0, %1, %2\n" \ 207 : : " adc %R0, %R0, #0\n" \ 208 : : " .pushsection .pv_table,\"a\"\n" \ 209 : : " .long 1b\n" \ 210 : : " .popsection\n" \ 211 : : : "+r" (y) \ 212 : : : "r" (x), "I" (__PV_BITS_31_24) \ 213 : : : "cc") 214 : : 215 : : static inline phys_addr_t __virt_to_phys_nodebug(unsigned long x) 216 : : { 217 : : phys_addr_t t; 218 : : 219 : : if (sizeof(phys_addr_t) == 4) { 220 : 10536420 : __pv_stub(x, t, "add", __PV_BITS_31_24); 221 : : } else { 222 : : __pv_stub_mov_hi(t); 223 : : __pv_add_carry_stub(x, t); 224 : : } 225 : : return t; 226 : : } 227 : : 228 : 212627484 : static inline unsigned long __phys_to_virt(phys_addr_t x) 229 : : { 230 : : unsigned long t; 231 : : 232 : : /* 233 : : * 'unsigned long' cast discard upper word when 234 : : * phys_addr_t is 64 bit, and makes sure that inline 235 : : * assembler expression receives 32 bit argument 236 : : * in place where 'r' 32 bit operand is expected. 237 : : */ 238 : 547703226 : __pv_stub((unsigned long) x, t, "sub", __PV_BITS_31_24); 239 : 212627484 : return t; 240 : : } 241 : : 242 : : #else 243 : : 244 : : #define PHYS_OFFSET PLAT_PHYS_OFFSET 245 : : #define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT)) 246 : : 247 : : static inline phys_addr_t __virt_to_phys_nodebug(unsigned long x) 248 : : { 249 : : return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET; 250 : : } 251 : : 252 : : static inline unsigned long __phys_to_virt(phys_addr_t x) 253 : : { 254 : : return x - PHYS_OFFSET + PAGE_OFFSET; 255 : : } 256 : : 257 : : #endif 258 : : 259 : : #define virt_to_pfn(kaddr) \ 260 : : ((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \ 261 : : PHYS_PFN_OFFSET) 262 : : 263 : : #define __pa_symbol_nodebug(x) __virt_to_phys_nodebug((x)) 264 : : 265 : : #ifdef CONFIG_DEBUG_VIRTUAL 266 : : extern phys_addr_t __virt_to_phys(unsigned long x); 267 : : extern phys_addr_t __phys_addr_symbol(unsigned long x); 268 : : #else 269 : : #define __virt_to_phys(x) __virt_to_phys_nodebug(x) 270 : : #define __phys_addr_symbol(x) __pa_symbol_nodebug(x) 271 : : #endif 272 : : 273 : : /* 274 : : * These are *only* valid on the kernel direct mapped RAM memory. 275 : : * Note: Drivers should NOT use these. They are the wrong 276 : : * translation for translating DMA addresses. Use the driver 277 : : * DMA support - see dma-mapping.h. 278 : : */ 279 : : #define virt_to_phys virt_to_phys 280 : : static inline phys_addr_t virt_to_phys(const volatile void *x) 281 : : { 282 : 10455208 : return __virt_to_phys((unsigned long)(x)); 283 : : } 284 : : 285 : : #define phys_to_virt phys_to_virt 286 : : static inline void *phys_to_virt(phys_addr_t x) 287 : : { 288 : 53576 : return (void *)__phys_to_virt(x); 289 : : } 290 : : 291 : : /* 292 : : * Drivers should NOT use these either. 293 : : */ 294 : : #define __pa(x) __virt_to_phys((unsigned long)(x)) 295 : : #define __pa_symbol(x) __phys_addr_symbol(RELOC_HIDE((unsigned long)(x), 0)) 296 : : #define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) 297 : : #define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT) 298 : : 299 : : extern long long arch_phys_to_idmap_offset; 300 : : 301 : : /* 302 : : * These are for systems that have a hardware interconnect supported alias 303 : : * of physical memory for idmap purposes. Most cases should leave these 304 : : * untouched. Note: this can only return addresses less than 4GiB. 305 : : */ 306 : : static inline bool arm_has_idmap_alias(void) 307 : : { 308 : : return IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset != 0; 309 : : } 310 : : 311 : : #define IDMAP_INVALID_ADDR ((u32)~0) 312 : : 313 : : static inline unsigned long phys_to_idmap(phys_addr_t addr) 314 : : { 315 [ - + - + ]: 1616 : if (IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset) { 316 : 0 : addr += arch_phys_to_idmap_offset; 317 : : if (addr > (u32)~0) 318 : : addr = IDMAP_INVALID_ADDR; 319 : : } 320 : : return addr; 321 : : } 322 : : 323 : : static inline phys_addr_t idmap_to_phys(unsigned long idmap) 324 : : { 325 : : phys_addr_t addr = idmap; 326 : : 327 : : if (IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset) 328 : : addr -= arch_phys_to_idmap_offset; 329 : : 330 : : return addr; 331 : : } 332 : : 333 : : static inline unsigned long __virt_to_idmap(unsigned long x) 334 : : { 335 : : return phys_to_idmap(__virt_to_phys(x)); 336 : : } 337 : : 338 : : #define virt_to_idmap(x) __virt_to_idmap((unsigned long)(x)) 339 : : 340 : : /* 341 : : * Virtual <-> DMA view memory address translations 342 : : * Again, these are *only* valid on the kernel direct mapped RAM 343 : : * memory. Use of these is *deprecated* (and that doesn't mean 344 : : * use the __ prefixed forms instead.) See dma-mapping.h. 345 : : */ 346 : : #ifndef __virt_to_bus 347 : : #define __virt_to_bus __virt_to_phys 348 : : #define __bus_to_virt __phys_to_virt 349 : : #define __pfn_to_bus(x) __pfn_to_phys(x) 350 : : #define __bus_to_pfn(x) __phys_to_pfn(x) 351 : : #endif 352 : : 353 : : /* 354 : : * Conversion between a struct page and a physical address. 355 : : * 356 : : * page_to_pfn(page) convert a struct page * to a PFN number 357 : : * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * 358 : : * 359 : : * virt_to_page(k) convert a _valid_ virtual address to struct page * 360 : : * virt_addr_valid(k) indicates whether a virtual address is valid 361 : : */ 362 : : #define ARCH_PFN_OFFSET PHYS_PFN_OFFSET 363 : : 364 : : #define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) 365 : : #define virt_addr_valid(kaddr) (((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) \ 366 : : && pfn_valid(virt_to_pfn(kaddr))) 367 : : 368 : : #endif 369 : : 370 : : #include <asm-generic/memory_model.h> 371 : : 372 : : #endif