18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * arch/arm/include/asm/memory.h 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2000-2002 Russell King 68c2ecf20Sopenharmony_ci * modification for nommu, Hyok S. Choi, 2004 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Note: this file should not be included by non-asm/.h files 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci#ifndef __ASM_ARM_MEMORY_H 118c2ecf20Sopenharmony_ci#define __ASM_ARM_MEMORY_H 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/compiler.h> 148c2ecf20Sopenharmony_ci#include <linux/const.h> 158c2ecf20Sopenharmony_ci#include <linux/types.h> 168c2ecf20Sopenharmony_ci#include <linux/sizes.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#ifdef CONFIG_NEED_MACH_MEMORY_H 198c2ecf20Sopenharmony_ci#include <mach/memory.h> 208c2ecf20Sopenharmony_ci#endif 218c2ecf20Sopenharmony_ci#include <asm/kasan_def.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci/* PAGE_OFFSET - the virtual address of the start of the kernel image */ 248c2ecf20Sopenharmony_ci#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#ifdef CONFIG_MMU 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci/* 298c2ecf20Sopenharmony_ci * TASK_SIZE - the maximum size of a user space task. 308c2ecf20Sopenharmony_ci * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ci#ifndef CONFIG_KASAN 338c2ecf20Sopenharmony_ci#define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(SZ_16M)) 348c2ecf20Sopenharmony_ci#else 358c2ecf20Sopenharmony_ci#define TASK_SIZE (KASAN_SHADOW_START) 368c2ecf20Sopenharmony_ci#endif 378c2ecf20Sopenharmony_ci#define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_16M) 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/* 408c2ecf20Sopenharmony_ci * The maximum size of a 26-bit user space task. 418c2ecf20Sopenharmony_ci */ 428c2ecf20Sopenharmony_ci#define TASK_SIZE_26 (UL(1) << 26) 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* 458c2ecf20Sopenharmony_ci * The module space lives between the addresses given by TASK_SIZE 468c2ecf20Sopenharmony_ci * and PAGE_OFFSET - it must be within 32MB of the kernel text. 478c2ecf20Sopenharmony_ci */ 488c2ecf20Sopenharmony_ci#ifndef CONFIG_THUMB2_KERNEL 498c2ecf20Sopenharmony_ci#define MODULES_VADDR (PAGE_OFFSET - SZ_16M) 508c2ecf20Sopenharmony_ci#else 518c2ecf20Sopenharmony_ci/* smaller range for Thumb-2 symbols relocation (2^24)*/ 528c2ecf20Sopenharmony_ci#define MODULES_VADDR (PAGE_OFFSET - SZ_8M) 538c2ecf20Sopenharmony_ci#endif 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#if TASK_SIZE > MODULES_VADDR 568c2ecf20Sopenharmony_ci#error Top of user space clashes with start of module space 578c2ecf20Sopenharmony_ci#endif 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci/* 608c2ecf20Sopenharmony_ci * The highmem pkmap virtual space shares the end of the module area. 618c2ecf20Sopenharmony_ci */ 628c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM 638c2ecf20Sopenharmony_ci#define MODULES_END (PAGE_OFFSET - PMD_SIZE) 648c2ecf20Sopenharmony_ci#else 658c2ecf20Sopenharmony_ci#define MODULES_END (PAGE_OFFSET) 668c2ecf20Sopenharmony_ci#endif 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* 698c2ecf20Sopenharmony_ci * The XIP kernel gets mapped at the bottom of the module vm area. 708c2ecf20Sopenharmony_ci * Since we use sections to map it, this macro replaces the physical address 718c2ecf20Sopenharmony_ci * with its virtual address while keeping offset from the base section. 728c2ecf20Sopenharmony_ci */ 738c2ecf20Sopenharmony_ci#define XIP_VIRT_ADDR(physaddr) (MODULES_VADDR + ((physaddr) & 0x000fffff)) 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci#define FDT_FIXED_BASE UL(0xff800000) 768c2ecf20Sopenharmony_ci#define FDT_FIXED_SIZE (2 * SECTION_SIZE) 778c2ecf20Sopenharmony_ci#define FDT_VIRT_BASE(physbase) ((void *)(FDT_FIXED_BASE | (physbase) % SECTION_SIZE)) 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE) 808c2ecf20Sopenharmony_ci/* 818c2ecf20Sopenharmony_ci * Allow 16MB-aligned ioremap pages 828c2ecf20Sopenharmony_ci */ 838c2ecf20Sopenharmony_ci#define IOREMAP_MAX_ORDER 24 848c2ecf20Sopenharmony_ci#endif 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci#define VECTORS_BASE UL(0xffff0000) 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci#else /* CONFIG_MMU */ 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 918c2ecf20Sopenharmony_ciextern unsigned long setup_vectors_base(void); 928c2ecf20Sopenharmony_ciextern unsigned long vectors_base; 938c2ecf20Sopenharmony_ci#define VECTORS_BASE vectors_base 948c2ecf20Sopenharmony_ci#endif 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci/* 978c2ecf20Sopenharmony_ci * The limitation of user task size can grow up to the end of free ram region. 988c2ecf20Sopenharmony_ci * It is difficult to define and perhaps will never meet the original meaning 998c2ecf20Sopenharmony_ci * of this define that was meant to. 1008c2ecf20Sopenharmony_ci * Fortunately, there is no reference for this in noMMU mode, for now. 1018c2ecf20Sopenharmony_ci */ 1028c2ecf20Sopenharmony_ci#define TASK_SIZE UL(0xffffffff) 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci#ifndef TASK_UNMAPPED_BASE 1058c2ecf20Sopenharmony_ci#define TASK_UNMAPPED_BASE UL(0x00000000) 1068c2ecf20Sopenharmony_ci#endif 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci#ifndef END_MEM 1098c2ecf20Sopenharmony_ci#define END_MEM (UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE) 1108c2ecf20Sopenharmony_ci#endif 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci/* 1138c2ecf20Sopenharmony_ci * The module can be at any place in ram in nommu mode. 1148c2ecf20Sopenharmony_ci */ 1158c2ecf20Sopenharmony_ci#define MODULES_END (END_MEM) 1168c2ecf20Sopenharmony_ci#define MODULES_VADDR PAGE_OFFSET 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci#define XIP_VIRT_ADDR(physaddr) (physaddr) 1198c2ecf20Sopenharmony_ci#define FDT_VIRT_BASE(physbase) ((void *)(physbase)) 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci#endif /* !CONFIG_MMU */ 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci#ifdef CONFIG_XIP_KERNEL 1248c2ecf20Sopenharmony_ci#define KERNEL_START _sdata 1258c2ecf20Sopenharmony_ci#else 1268c2ecf20Sopenharmony_ci#define KERNEL_START _stext 1278c2ecf20Sopenharmony_ci#endif 1288c2ecf20Sopenharmony_ci#define KERNEL_END _end 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci/* 1318c2ecf20Sopenharmony_ci * We fix the TCM memories max 32 KiB ITCM resp DTCM at these 1328c2ecf20Sopenharmony_ci * locations 1338c2ecf20Sopenharmony_ci */ 1348c2ecf20Sopenharmony_ci#ifdef CONFIG_HAVE_TCM 1358c2ecf20Sopenharmony_ci#define ITCM_OFFSET UL(0xfffe0000) 1368c2ecf20Sopenharmony_ci#define DTCM_OFFSET UL(0xfffe8000) 1378c2ecf20Sopenharmony_ci#endif 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci/* 1408c2ecf20Sopenharmony_ci * Convert a page to/from a physical address 1418c2ecf20Sopenharmony_ci */ 1428c2ecf20Sopenharmony_ci#define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page))) 1438c2ecf20Sopenharmony_ci#define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys))) 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci/* 1468c2ecf20Sopenharmony_ci * PLAT_PHYS_OFFSET is the offset (from zero) of the start of physical 1478c2ecf20Sopenharmony_ci * memory. This is used for XIP and NoMMU kernels, and on platforms that don't 1488c2ecf20Sopenharmony_ci * have CONFIG_ARM_PATCH_PHYS_VIRT. Assembly code must always use 1498c2ecf20Sopenharmony_ci * PLAT_PHYS_OFFSET and not PHYS_OFFSET. 1508c2ecf20Sopenharmony_ci */ 1518c2ecf20Sopenharmony_ci#define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET) 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci#ifdef CONFIG_XIP_KERNEL 1548c2ecf20Sopenharmony_ci/* 1558c2ecf20Sopenharmony_ci * When referencing data in RAM from the XIP region in a relative manner 1568c2ecf20Sopenharmony_ci * with the MMU off, we need the relative offset between the two physical 1578c2ecf20Sopenharmony_ci * addresses. The macro below achieves this, which is: 1588c2ecf20Sopenharmony_ci * __pa(v_data) - __xip_pa(v_text) 1598c2ecf20Sopenharmony_ci */ 1608c2ecf20Sopenharmony_ci#define PHYS_RELATIVE(v_data, v_text) \ 1618c2ecf20Sopenharmony_ci (((v_data) - PAGE_OFFSET + PLAT_PHYS_OFFSET) - \ 1628c2ecf20Sopenharmony_ci ((v_text) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) + \ 1638c2ecf20Sopenharmony_ci CONFIG_XIP_PHYS_ADDR)) 1648c2ecf20Sopenharmony_ci#else 1658c2ecf20Sopenharmony_ci#define PHYS_RELATIVE(v_data, v_text) ((v_data) - (v_text)) 1668c2ecf20Sopenharmony_ci#endif 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci#ifdef CONFIG_RANDOMIZE_BASE 1718c2ecf20Sopenharmony_ciextern unsigned long __kaslr_offset; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_cistatic inline unsigned long kaslr_offset(void) 1748c2ecf20Sopenharmony_ci{ 1758c2ecf20Sopenharmony_ci return __kaslr_offset; 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci#else 1788c2ecf20Sopenharmony_cistatic inline unsigned long kaslr_offset(void) 1798c2ecf20Sopenharmony_ci{ 1808c2ecf20Sopenharmony_ci return 0; 1818c2ecf20Sopenharmony_ci} 1828c2ecf20Sopenharmony_ci#endif 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci/* 1858c2ecf20Sopenharmony_ci * Physical vs virtual RAM address space conversion. These are 1868c2ecf20Sopenharmony_ci * private definitions which should NOT be used outside memory.h 1878c2ecf20Sopenharmony_ci * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. 1888c2ecf20Sopenharmony_ci * 1898c2ecf20Sopenharmony_ci * PFNs are used to describe any physical page; this means 1908c2ecf20Sopenharmony_ci * PFN 0 == physical address 0. 1918c2ecf20Sopenharmony_ci */ 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci#if defined(CONFIG_ARM_PATCH_PHYS_VIRT) 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci/* 1968c2ecf20Sopenharmony_ci * Constants used to force the right instruction encodings and shifts 1978c2ecf20Sopenharmony_ci * so that all we need to do is modify the 8-bit constant field. 1988c2ecf20Sopenharmony_ci */ 1998c2ecf20Sopenharmony_ci#define __PV_BITS_31_24 0x81000000 2008c2ecf20Sopenharmony_ci#define __PV_BITS_23_16 0x810000 2018c2ecf20Sopenharmony_ci#define __PV_BITS_7_0 0x81 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ciextern unsigned long __pv_phys_pfn_offset; 2048c2ecf20Sopenharmony_ciextern u64 __pv_offset; 2058c2ecf20Sopenharmony_ciextern void fixup_pv_table(const void *, unsigned long); 2068c2ecf20Sopenharmony_ciextern const void *__pv_table_begin, *__pv_table_end; 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci#define PHYS_OFFSET ((phys_addr_t)__pv_phys_pfn_offset << PAGE_SHIFT) 2098c2ecf20Sopenharmony_ci#define PHYS_PFN_OFFSET (__pv_phys_pfn_offset) 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci#ifndef CONFIG_THUMB2_KERNEL 2128c2ecf20Sopenharmony_ci#define __pv_stub(from,to,instr) \ 2138c2ecf20Sopenharmony_ci __asm__("@ __pv_stub\n" \ 2148c2ecf20Sopenharmony_ci "1: " instr " %0, %1, %2\n" \ 2158c2ecf20Sopenharmony_ci "2: " instr " %0, %0, %3\n" \ 2168c2ecf20Sopenharmony_ci " .pushsection .pv_table,\"a\"\n" \ 2178c2ecf20Sopenharmony_ci " .long 1b - ., 2b - .\n" \ 2188c2ecf20Sopenharmony_ci " .popsection\n" \ 2198c2ecf20Sopenharmony_ci : "=r" (to) \ 2208c2ecf20Sopenharmony_ci : "r" (from), "I" (__PV_BITS_31_24), \ 2218c2ecf20Sopenharmony_ci "I"(__PV_BITS_23_16)) 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci#define __pv_add_carry_stub(x, y) \ 2248c2ecf20Sopenharmony_ci __asm__("@ __pv_add_carry_stub\n" \ 2258c2ecf20Sopenharmony_ci "0: movw %R0, #0\n" \ 2268c2ecf20Sopenharmony_ci " adds %Q0, %1, %R0, lsl #20\n" \ 2278c2ecf20Sopenharmony_ci "1: mov %R0, %2\n" \ 2288c2ecf20Sopenharmony_ci " adc %R0, %R0, #0\n" \ 2298c2ecf20Sopenharmony_ci " .pushsection .pv_table,\"a\"\n" \ 2308c2ecf20Sopenharmony_ci " .long 0b - ., 1b - .\n" \ 2318c2ecf20Sopenharmony_ci " .popsection\n" \ 2328c2ecf20Sopenharmony_ci : "=&r" (y) \ 2338c2ecf20Sopenharmony_ci : "r" (x), "I" (__PV_BITS_7_0) \ 2348c2ecf20Sopenharmony_ci : "cc") 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci#else 2378c2ecf20Sopenharmony_ci#define __pv_stub(from,to,instr) \ 2388c2ecf20Sopenharmony_ci __asm__("@ __pv_stub\n" \ 2398c2ecf20Sopenharmony_ci "0: movw %0, #0\n" \ 2408c2ecf20Sopenharmony_ci " lsl %0, #21\n" \ 2418c2ecf20Sopenharmony_ci " " instr " %0, %1, %0\n" \ 2428c2ecf20Sopenharmony_ci " .pushsection .pv_table,\"a\"\n" \ 2438c2ecf20Sopenharmony_ci " .long 0b - .\n" \ 2448c2ecf20Sopenharmony_ci " .popsection\n" \ 2458c2ecf20Sopenharmony_ci : "=&r" (to) \ 2468c2ecf20Sopenharmony_ci : "r" (from)) 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci#define __pv_add_carry_stub(x, y) \ 2498c2ecf20Sopenharmony_ci __asm__("@ __pv_add_carry_stub\n" \ 2508c2ecf20Sopenharmony_ci "0: movw %R0, #0\n" \ 2518c2ecf20Sopenharmony_ci " lsls %R0, #21\n" \ 2528c2ecf20Sopenharmony_ci " adds %Q0, %1, %R0\n" \ 2538c2ecf20Sopenharmony_ci "1: mvn %R0, #0\n" \ 2548c2ecf20Sopenharmony_ci " adc %R0, %R0, #0\n" \ 2558c2ecf20Sopenharmony_ci " .pushsection .pv_table,\"a\"\n" \ 2568c2ecf20Sopenharmony_ci " .long 0b - ., 1b - .\n" \ 2578c2ecf20Sopenharmony_ci " .popsection\n" \ 2588c2ecf20Sopenharmony_ci : "=&r" (y) \ 2598c2ecf20Sopenharmony_ci : "r" (x) \ 2608c2ecf20Sopenharmony_ci : "cc") 2618c2ecf20Sopenharmony_ci#endif 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_cistatic inline phys_addr_t __virt_to_phys_nodebug(unsigned long x) 2648c2ecf20Sopenharmony_ci{ 2658c2ecf20Sopenharmony_ci phys_addr_t t; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci if (sizeof(phys_addr_t) == 4) { 2688c2ecf20Sopenharmony_ci __pv_stub(x, t, "add"); 2698c2ecf20Sopenharmony_ci } else { 2708c2ecf20Sopenharmony_ci __pv_add_carry_stub(x, t); 2718c2ecf20Sopenharmony_ci } 2728c2ecf20Sopenharmony_ci return t; 2738c2ecf20Sopenharmony_ci} 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cistatic inline unsigned long __phys_to_virt(phys_addr_t x) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci unsigned long t; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci /* 2808c2ecf20Sopenharmony_ci * 'unsigned long' cast discard upper word when 2818c2ecf20Sopenharmony_ci * phys_addr_t is 64 bit, and makes sure that inline 2828c2ecf20Sopenharmony_ci * assembler expression receives 32 bit argument 2838c2ecf20Sopenharmony_ci * in place where 'r' 32 bit operand is expected. 2848c2ecf20Sopenharmony_ci */ 2858c2ecf20Sopenharmony_ci __pv_stub((unsigned long) x, t, "sub"); 2868c2ecf20Sopenharmony_ci return t; 2878c2ecf20Sopenharmony_ci} 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci#else 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci#define PHYS_OFFSET PLAT_PHYS_OFFSET 2928c2ecf20Sopenharmony_ci#define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT)) 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_cistatic inline phys_addr_t __virt_to_phys_nodebug(unsigned long x) 2958c2ecf20Sopenharmony_ci{ 2968c2ecf20Sopenharmony_ci return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET; 2978c2ecf20Sopenharmony_ci} 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_cistatic inline unsigned long __phys_to_virt(phys_addr_t x) 3008c2ecf20Sopenharmony_ci{ 3018c2ecf20Sopenharmony_ci return x - PHYS_OFFSET + PAGE_OFFSET; 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci#endif 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci#define virt_to_pfn(kaddr) \ 3078c2ecf20Sopenharmony_ci ((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \ 3088c2ecf20Sopenharmony_ci PHYS_PFN_OFFSET) 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci#define __pa_symbol_nodebug(x) __virt_to_phys_nodebug((x)) 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_VIRTUAL 3138c2ecf20Sopenharmony_ciextern phys_addr_t __virt_to_phys(unsigned long x); 3148c2ecf20Sopenharmony_ciextern phys_addr_t __phys_addr_symbol(unsigned long x); 3158c2ecf20Sopenharmony_ci#else 3168c2ecf20Sopenharmony_ci#define __virt_to_phys(x) __virt_to_phys_nodebug(x) 3178c2ecf20Sopenharmony_ci#define __phys_addr_symbol(x) __pa_symbol_nodebug(x) 3188c2ecf20Sopenharmony_ci#endif 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci/* 3218c2ecf20Sopenharmony_ci * These are *only* valid on the kernel direct mapped RAM memory. 3228c2ecf20Sopenharmony_ci * Note: Drivers should NOT use these. They are the wrong 3238c2ecf20Sopenharmony_ci * translation for translating DMA addresses. Use the driver 3248c2ecf20Sopenharmony_ci * DMA support - see dma-mapping.h. 3258c2ecf20Sopenharmony_ci */ 3268c2ecf20Sopenharmony_ci#define virt_to_phys virt_to_phys 3278c2ecf20Sopenharmony_cistatic inline phys_addr_t virt_to_phys(const volatile void *x) 3288c2ecf20Sopenharmony_ci{ 3298c2ecf20Sopenharmony_ci return __virt_to_phys((unsigned long)(x)); 3308c2ecf20Sopenharmony_ci} 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci#define phys_to_virt phys_to_virt 3338c2ecf20Sopenharmony_cistatic inline void *phys_to_virt(phys_addr_t x) 3348c2ecf20Sopenharmony_ci{ 3358c2ecf20Sopenharmony_ci return (void *)__phys_to_virt(x); 3368c2ecf20Sopenharmony_ci} 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci/* 3398c2ecf20Sopenharmony_ci * Drivers should NOT use these either. 3408c2ecf20Sopenharmony_ci */ 3418c2ecf20Sopenharmony_ci#define __pa(x) __virt_to_phys((unsigned long)(x)) 3428c2ecf20Sopenharmony_ci#define __pa_symbol(x) __phys_addr_symbol(RELOC_HIDE((unsigned long)(x), 0)) 3438c2ecf20Sopenharmony_ci#define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) 3448c2ecf20Sopenharmony_ci#define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT) 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ciextern long long arch_phys_to_idmap_offset; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci/* 3498c2ecf20Sopenharmony_ci * These are for systems that have a hardware interconnect supported alias 3508c2ecf20Sopenharmony_ci * of physical memory for idmap purposes. Most cases should leave these 3518c2ecf20Sopenharmony_ci * untouched. Note: this can only return addresses less than 4GiB. 3528c2ecf20Sopenharmony_ci */ 3538c2ecf20Sopenharmony_cistatic inline bool arm_has_idmap_alias(void) 3548c2ecf20Sopenharmony_ci{ 3558c2ecf20Sopenharmony_ci return IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset != 0; 3568c2ecf20Sopenharmony_ci} 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci#define IDMAP_INVALID_ADDR ((u32)~0) 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_cistatic inline unsigned long phys_to_idmap(phys_addr_t addr) 3618c2ecf20Sopenharmony_ci{ 3628c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset) { 3638c2ecf20Sopenharmony_ci addr += arch_phys_to_idmap_offset; 3648c2ecf20Sopenharmony_ci if (addr > (u32)~0) 3658c2ecf20Sopenharmony_ci addr = IDMAP_INVALID_ADDR; 3668c2ecf20Sopenharmony_ci } 3678c2ecf20Sopenharmony_ci return addr; 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_cistatic inline phys_addr_t idmap_to_phys(unsigned long idmap) 3718c2ecf20Sopenharmony_ci{ 3728c2ecf20Sopenharmony_ci phys_addr_t addr = idmap; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset) 3758c2ecf20Sopenharmony_ci addr -= arch_phys_to_idmap_offset; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci return addr; 3788c2ecf20Sopenharmony_ci} 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_cistatic inline unsigned long __virt_to_idmap(unsigned long x) 3818c2ecf20Sopenharmony_ci{ 3828c2ecf20Sopenharmony_ci return phys_to_idmap(__virt_to_phys(x)); 3838c2ecf20Sopenharmony_ci} 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci#define virt_to_idmap(x) __virt_to_idmap((unsigned long)(x)) 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci/* 3888c2ecf20Sopenharmony_ci * Virtual <-> DMA view memory address translations 3898c2ecf20Sopenharmony_ci * Again, these are *only* valid on the kernel direct mapped RAM 3908c2ecf20Sopenharmony_ci * memory. Use of these is *deprecated* (and that doesn't mean 3918c2ecf20Sopenharmony_ci * use the __ prefixed forms instead.) See dma-mapping.h. 3928c2ecf20Sopenharmony_ci */ 3938c2ecf20Sopenharmony_ci#ifndef __virt_to_bus 3948c2ecf20Sopenharmony_ci#define __virt_to_bus __virt_to_phys 3958c2ecf20Sopenharmony_ci#define __bus_to_virt __phys_to_virt 3968c2ecf20Sopenharmony_ci#define __pfn_to_bus(x) __pfn_to_phys(x) 3978c2ecf20Sopenharmony_ci#define __bus_to_pfn(x) __phys_to_pfn(x) 3988c2ecf20Sopenharmony_ci#endif 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_ci/* 4018c2ecf20Sopenharmony_ci * Conversion between a struct page and a physical address. 4028c2ecf20Sopenharmony_ci * 4038c2ecf20Sopenharmony_ci * page_to_pfn(page) convert a struct page * to a PFN number 4048c2ecf20Sopenharmony_ci * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * 4058c2ecf20Sopenharmony_ci * 4068c2ecf20Sopenharmony_ci * virt_to_page(k) convert a _valid_ virtual address to struct page * 4078c2ecf20Sopenharmony_ci * virt_addr_valid(k) indicates whether a virtual address is valid 4088c2ecf20Sopenharmony_ci */ 4098c2ecf20Sopenharmony_ci#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) 4128c2ecf20Sopenharmony_ci#define virt_addr_valid(kaddr) (((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) \ 4138c2ecf20Sopenharmony_ci && pfn_valid(virt_to_pfn(kaddr))) 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci#endif 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci#include <asm-generic/memory_model.h> 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_ci#endif 420