162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * arch/arm/include/asm/memory.h 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2000-2002 Russell King 662306a36Sopenharmony_ci * modification for nommu, Hyok S. Choi, 2004 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Note: this file should not be included explicitly, include <asm/page.h> 962306a36Sopenharmony_ci * to get access to these definitions. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci#ifndef __ASM_ARM_MEMORY_H 1262306a36Sopenharmony_ci#define __ASM_ARM_MEMORY_H 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#ifndef _ASMARM_PAGE_H 1562306a36Sopenharmony_ci#error "Do not include <asm/memory.h> directly" 1662306a36Sopenharmony_ci#endif 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include <linux/compiler.h> 1962306a36Sopenharmony_ci#include <linux/const.h> 2062306a36Sopenharmony_ci#include <linux/types.h> 2162306a36Sopenharmony_ci#include <linux/sizes.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#ifdef CONFIG_NEED_MACH_MEMORY_H 2462306a36Sopenharmony_ci#include <mach/memory.h> 2562306a36Sopenharmony_ci#endif 2662306a36Sopenharmony_ci#include <asm/kasan_def.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* 2962306a36Sopenharmony_ci * PAGE_OFFSET: the virtual address of the start of lowmem, memory above 3062306a36Sopenharmony_ci * the virtual address range for userspace. 3162306a36Sopenharmony_ci * KERNEL_OFFSET: the virtual address of the start of the kernel image. 3262306a36Sopenharmony_ci * we may further offset this with TEXT_OFFSET in practice. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci#define PAGE_OFFSET UL(CONFIG_PAGE_OFFSET) 3562306a36Sopenharmony_ci#define KERNEL_OFFSET (PAGE_OFFSET) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#ifdef CONFIG_MMU 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci/* 4062306a36Sopenharmony_ci * TASK_SIZE - the maximum size of a user space task. 4162306a36Sopenharmony_ci * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_ci#ifndef CONFIG_KASAN 4462306a36Sopenharmony_ci#define TASK_SIZE (UL(CONFIG_PAGE_OFFSET) - UL(SZ_16M)) 4562306a36Sopenharmony_ci#else 4662306a36Sopenharmony_ci#define TASK_SIZE (KASAN_SHADOW_START) 4762306a36Sopenharmony_ci#endif 4862306a36Sopenharmony_ci#define TASK_UNMAPPED_BASE ALIGN(TASK_SIZE / 3, SZ_16M) 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci/* 5162306a36Sopenharmony_ci * The maximum size of a 26-bit user space task. 5262306a36Sopenharmony_ci */ 5362306a36Sopenharmony_ci#define TASK_SIZE_26 (UL(1) << 26) 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci/* 5662306a36Sopenharmony_ci * The module space lives between the addresses given by TASK_SIZE 5762306a36Sopenharmony_ci * and PAGE_OFFSET - it must be within 32MB of the kernel text. 5862306a36Sopenharmony_ci */ 5962306a36Sopenharmony_ci#ifndef CONFIG_THUMB2_KERNEL 6062306a36Sopenharmony_ci#define MODULES_VADDR (PAGE_OFFSET - SZ_16M) 6162306a36Sopenharmony_ci#else 6262306a36Sopenharmony_ci/* smaller range for Thumb-2 symbols relocation (2^24)*/ 6362306a36Sopenharmony_ci#define MODULES_VADDR (PAGE_OFFSET - SZ_8M) 6462306a36Sopenharmony_ci#endif 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#if TASK_SIZE > MODULES_VADDR 6762306a36Sopenharmony_ci#error Top of user space clashes with start of module space 6862306a36Sopenharmony_ci#endif 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* 7162306a36Sopenharmony_ci * The highmem pkmap virtual space shares the end of the module area. 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ci#ifdef CONFIG_HIGHMEM 7462306a36Sopenharmony_ci#define MODULES_END (PAGE_OFFSET - PMD_SIZE) 7562306a36Sopenharmony_ci#else 7662306a36Sopenharmony_ci#define MODULES_END (PAGE_OFFSET) 7762306a36Sopenharmony_ci#endif 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/* 8062306a36Sopenharmony_ci * The XIP kernel gets mapped at the bottom of the module vm area. 8162306a36Sopenharmony_ci * Since we use sections to map it, this macro replaces the physical address 8262306a36Sopenharmony_ci * with its virtual address while keeping offset from the base section. 8362306a36Sopenharmony_ci */ 8462306a36Sopenharmony_ci#define XIP_VIRT_ADDR(physaddr) (MODULES_VADDR + ((physaddr) & 0x000fffff)) 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci#define FDT_FIXED_BASE UL(0xff800000) 8762306a36Sopenharmony_ci#define FDT_FIXED_SIZE (2 * SECTION_SIZE) 8862306a36Sopenharmony_ci#define FDT_VIRT_BASE(physbase) ((void *)(FDT_FIXED_BASE | (physbase) % SECTION_SIZE)) 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE) 9162306a36Sopenharmony_ci/* 9262306a36Sopenharmony_ci * Allow 16MB-aligned ioremap pages 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_ci#define IOREMAP_MAX_ORDER 24 9562306a36Sopenharmony_ci#endif 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci#define VECTORS_BASE UL(0xffff0000) 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci#else /* CONFIG_MMU */ 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 10262306a36Sopenharmony_ciextern unsigned long setup_vectors_base(void); 10362306a36Sopenharmony_ciextern unsigned long vectors_base; 10462306a36Sopenharmony_ci#define VECTORS_BASE vectors_base 10562306a36Sopenharmony_ci#endif 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci/* 10862306a36Sopenharmony_ci * The limitation of user task size can grow up to the end of free ram region. 10962306a36Sopenharmony_ci * It is difficult to define and perhaps will never meet the original meaning 11062306a36Sopenharmony_ci * of this define that was meant to. 11162306a36Sopenharmony_ci * Fortunately, there is no reference for this in noMMU mode, for now. 11262306a36Sopenharmony_ci */ 11362306a36Sopenharmony_ci#define TASK_SIZE UL(0xffffffff) 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci#ifndef TASK_UNMAPPED_BASE 11662306a36Sopenharmony_ci#define TASK_UNMAPPED_BASE UL(0x00000000) 11762306a36Sopenharmony_ci#endif 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci#ifndef END_MEM 12062306a36Sopenharmony_ci#define END_MEM (UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE) 12162306a36Sopenharmony_ci#endif 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci/* 12462306a36Sopenharmony_ci * The module can be at any place in ram in nommu mode. 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_ci#define MODULES_END (END_MEM) 12762306a36Sopenharmony_ci#define MODULES_VADDR PAGE_OFFSET 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#define XIP_VIRT_ADDR(physaddr) (physaddr) 13062306a36Sopenharmony_ci#define FDT_VIRT_BASE(physbase) ((void *)(physbase)) 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci#endif /* !CONFIG_MMU */ 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci#ifdef CONFIG_XIP_KERNEL 13562306a36Sopenharmony_ci#define KERNEL_START _sdata 13662306a36Sopenharmony_ci#else 13762306a36Sopenharmony_ci#define KERNEL_START _stext 13862306a36Sopenharmony_ci#endif 13962306a36Sopenharmony_ci#define KERNEL_END _end 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci/* 14262306a36Sopenharmony_ci * We fix the TCM memories max 32 KiB ITCM resp DTCM at these 14362306a36Sopenharmony_ci * locations 14462306a36Sopenharmony_ci */ 14562306a36Sopenharmony_ci#ifdef CONFIG_HAVE_TCM 14662306a36Sopenharmony_ci#define ITCM_OFFSET UL(0xfffe0000) 14762306a36Sopenharmony_ci#define DTCM_OFFSET UL(0xfffe8000) 14862306a36Sopenharmony_ci#endif 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci/* 15162306a36Sopenharmony_ci * Convert a page to/from a physical address 15262306a36Sopenharmony_ci */ 15362306a36Sopenharmony_ci#define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page))) 15462306a36Sopenharmony_ci#define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys))) 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci/* 15762306a36Sopenharmony_ci * PLAT_PHYS_OFFSET is the offset (from zero) of the start of physical 15862306a36Sopenharmony_ci * memory. This is used for XIP and NoMMU kernels, and on platforms that don't 15962306a36Sopenharmony_ci * have CONFIG_ARM_PATCH_PHYS_VIRT. Assembly code must always use 16062306a36Sopenharmony_ci * PLAT_PHYS_OFFSET and not PHYS_OFFSET. 16162306a36Sopenharmony_ci */ 16262306a36Sopenharmony_ci#define PLAT_PHYS_OFFSET UL(CONFIG_PHYS_OFFSET) 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci/* 16762306a36Sopenharmony_ci * Physical start and end address of the kernel sections. These addresses are 16862306a36Sopenharmony_ci * 2MB-aligned to match the section mappings placed over the kernel. We use 16962306a36Sopenharmony_ci * u64 so that LPAE mappings beyond the 32bit limit will work out as well. 17062306a36Sopenharmony_ci */ 17162306a36Sopenharmony_ciextern u64 kernel_sec_start; 17262306a36Sopenharmony_ciextern u64 kernel_sec_end; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci/* 17562306a36Sopenharmony_ci * Physical vs virtual RAM address space conversion. These are 17662306a36Sopenharmony_ci * private definitions which should NOT be used outside memory.h 17762306a36Sopenharmony_ci * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. 17862306a36Sopenharmony_ci * 17962306a36Sopenharmony_ci * PFNs are used to describe any physical page; this means 18062306a36Sopenharmony_ci * PFN 0 == physical address 0. 18162306a36Sopenharmony_ci */ 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci#if defined(CONFIG_ARM_PATCH_PHYS_VIRT) 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci/* 18662306a36Sopenharmony_ci * Constants used to force the right instruction encodings and shifts 18762306a36Sopenharmony_ci * so that all we need to do is modify the 8-bit constant field. 18862306a36Sopenharmony_ci */ 18962306a36Sopenharmony_ci#define __PV_BITS_31_24 0x81000000 19062306a36Sopenharmony_ci#define __PV_BITS_23_16 0x810000 19162306a36Sopenharmony_ci#define __PV_BITS_7_0 0x81 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ciextern unsigned long __pv_phys_pfn_offset; 19462306a36Sopenharmony_ciextern u64 __pv_offset; 19562306a36Sopenharmony_ciextern void fixup_pv_table(const void *, unsigned long); 19662306a36Sopenharmony_ciextern const void *__pv_table_begin, *__pv_table_end; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci#define PHYS_OFFSET ((phys_addr_t)__pv_phys_pfn_offset << PAGE_SHIFT) 19962306a36Sopenharmony_ci#define PHYS_PFN_OFFSET (__pv_phys_pfn_offset) 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci#ifndef CONFIG_THUMB2_KERNEL 20262306a36Sopenharmony_ci#define __pv_stub(from,to,instr) \ 20362306a36Sopenharmony_ci __asm__("@ __pv_stub\n" \ 20462306a36Sopenharmony_ci "1: " instr " %0, %1, %2\n" \ 20562306a36Sopenharmony_ci "2: " instr " %0, %0, %3\n" \ 20662306a36Sopenharmony_ci " .pushsection .pv_table,\"a\"\n" \ 20762306a36Sopenharmony_ci " .long 1b - ., 2b - .\n" \ 20862306a36Sopenharmony_ci " .popsection\n" \ 20962306a36Sopenharmony_ci : "=r" (to) \ 21062306a36Sopenharmony_ci : "r" (from), "I" (__PV_BITS_31_24), \ 21162306a36Sopenharmony_ci "I"(__PV_BITS_23_16)) 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci#define __pv_add_carry_stub(x, y) \ 21462306a36Sopenharmony_ci __asm__("@ __pv_add_carry_stub\n" \ 21562306a36Sopenharmony_ci "0: movw %R0, #0\n" \ 21662306a36Sopenharmony_ci " adds %Q0, %1, %R0, lsl #20\n" \ 21762306a36Sopenharmony_ci "1: mov %R0, %2\n" \ 21862306a36Sopenharmony_ci " adc %R0, %R0, #0\n" \ 21962306a36Sopenharmony_ci " .pushsection .pv_table,\"a\"\n" \ 22062306a36Sopenharmony_ci " .long 0b - ., 1b - .\n" \ 22162306a36Sopenharmony_ci " .popsection\n" \ 22262306a36Sopenharmony_ci : "=&r" (y) \ 22362306a36Sopenharmony_ci : "r" (x), "I" (__PV_BITS_7_0) \ 22462306a36Sopenharmony_ci : "cc") 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci#else 22762306a36Sopenharmony_ci#define __pv_stub(from,to,instr) \ 22862306a36Sopenharmony_ci __asm__("@ __pv_stub\n" \ 22962306a36Sopenharmony_ci "0: movw %0, #0\n" \ 23062306a36Sopenharmony_ci " lsl %0, #21\n" \ 23162306a36Sopenharmony_ci " " instr " %0, %1, %0\n" \ 23262306a36Sopenharmony_ci " .pushsection .pv_table,\"a\"\n" \ 23362306a36Sopenharmony_ci " .long 0b - .\n" \ 23462306a36Sopenharmony_ci " .popsection\n" \ 23562306a36Sopenharmony_ci : "=&r" (to) \ 23662306a36Sopenharmony_ci : "r" (from)) 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci#define __pv_add_carry_stub(x, y) \ 23962306a36Sopenharmony_ci __asm__("@ __pv_add_carry_stub\n" \ 24062306a36Sopenharmony_ci "0: movw %R0, #0\n" \ 24162306a36Sopenharmony_ci " lsls %R0, #21\n" \ 24262306a36Sopenharmony_ci " adds %Q0, %1, %R0\n" \ 24362306a36Sopenharmony_ci "1: mvn %R0, #0\n" \ 24462306a36Sopenharmony_ci " adc %R0, %R0, #0\n" \ 24562306a36Sopenharmony_ci " .pushsection .pv_table,\"a\"\n" \ 24662306a36Sopenharmony_ci " .long 0b - ., 1b - .\n" \ 24762306a36Sopenharmony_ci " .popsection\n" \ 24862306a36Sopenharmony_ci : "=&r" (y) \ 24962306a36Sopenharmony_ci : "r" (x) \ 25062306a36Sopenharmony_ci : "cc") 25162306a36Sopenharmony_ci#endif 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_cistatic inline phys_addr_t __virt_to_phys_nodebug(unsigned long x) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci phys_addr_t t; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci if (sizeof(phys_addr_t) == 4) { 25862306a36Sopenharmony_ci __pv_stub(x, t, "add"); 25962306a36Sopenharmony_ci } else { 26062306a36Sopenharmony_ci __pv_add_carry_stub(x, t); 26162306a36Sopenharmony_ci } 26262306a36Sopenharmony_ci return t; 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_cistatic inline unsigned long __phys_to_virt(phys_addr_t x) 26662306a36Sopenharmony_ci{ 26762306a36Sopenharmony_ci unsigned long t; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci /* 27062306a36Sopenharmony_ci * 'unsigned long' cast discard upper word when 27162306a36Sopenharmony_ci * phys_addr_t is 64 bit, and makes sure that inline 27262306a36Sopenharmony_ci * assembler expression receives 32 bit argument 27362306a36Sopenharmony_ci * in place where 'r' 32 bit operand is expected. 27462306a36Sopenharmony_ci */ 27562306a36Sopenharmony_ci __pv_stub((unsigned long) x, t, "sub"); 27662306a36Sopenharmony_ci return t; 27762306a36Sopenharmony_ci} 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci#else 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci#define PHYS_OFFSET PLAT_PHYS_OFFSET 28262306a36Sopenharmony_ci#define PHYS_PFN_OFFSET ((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT)) 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_cistatic inline phys_addr_t __virt_to_phys_nodebug(unsigned long x) 28562306a36Sopenharmony_ci{ 28662306a36Sopenharmony_ci return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET; 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cistatic inline unsigned long __phys_to_virt(phys_addr_t x) 29062306a36Sopenharmony_ci{ 29162306a36Sopenharmony_ci return x - PHYS_OFFSET + PAGE_OFFSET; 29262306a36Sopenharmony_ci} 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci#endif 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistatic inline unsigned long virt_to_pfn(const void *p) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci unsigned long kaddr = (unsigned long)p; 29962306a36Sopenharmony_ci return (((kaddr - PAGE_OFFSET) >> PAGE_SHIFT) + 30062306a36Sopenharmony_ci PHYS_PFN_OFFSET); 30162306a36Sopenharmony_ci} 30262306a36Sopenharmony_ci#define __pa_symbol_nodebug(x) __virt_to_phys_nodebug((x)) 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci#ifdef CONFIG_DEBUG_VIRTUAL 30562306a36Sopenharmony_ciextern phys_addr_t __virt_to_phys(unsigned long x); 30662306a36Sopenharmony_ciextern phys_addr_t __phys_addr_symbol(unsigned long x); 30762306a36Sopenharmony_ci#else 30862306a36Sopenharmony_ci#define __virt_to_phys(x) __virt_to_phys_nodebug(x) 30962306a36Sopenharmony_ci#define __phys_addr_symbol(x) __pa_symbol_nodebug(x) 31062306a36Sopenharmony_ci#endif 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci/* 31362306a36Sopenharmony_ci * These are *only* valid on the kernel direct mapped RAM memory. 31462306a36Sopenharmony_ci * Note: Drivers should NOT use these. They are the wrong 31562306a36Sopenharmony_ci * translation for translating DMA addresses. Use the driver 31662306a36Sopenharmony_ci * DMA support - see dma-mapping.h. 31762306a36Sopenharmony_ci */ 31862306a36Sopenharmony_ci#define virt_to_phys virt_to_phys 31962306a36Sopenharmony_cistatic inline phys_addr_t virt_to_phys(const volatile void *x) 32062306a36Sopenharmony_ci{ 32162306a36Sopenharmony_ci return __virt_to_phys((unsigned long)(x)); 32262306a36Sopenharmony_ci} 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci#define phys_to_virt phys_to_virt 32562306a36Sopenharmony_cistatic inline void *phys_to_virt(phys_addr_t x) 32662306a36Sopenharmony_ci{ 32762306a36Sopenharmony_ci return (void *)__phys_to_virt(x); 32862306a36Sopenharmony_ci} 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci/* 33162306a36Sopenharmony_ci * Drivers should NOT use these either. 33262306a36Sopenharmony_ci */ 33362306a36Sopenharmony_ci#define __pa(x) __virt_to_phys((unsigned long)(x)) 33462306a36Sopenharmony_ci#define __pa_symbol(x) __phys_addr_symbol(RELOC_HIDE((unsigned long)(x), 0)) 33562306a36Sopenharmony_ci#define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x))) 33662306a36Sopenharmony_ci#define pfn_to_kaddr(pfn) __va((phys_addr_t)(pfn) << PAGE_SHIFT) 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ciextern long long arch_phys_to_idmap_offset; 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci/* 34162306a36Sopenharmony_ci * These are for systems that have a hardware interconnect supported alias 34262306a36Sopenharmony_ci * of physical memory for idmap purposes. Most cases should leave these 34362306a36Sopenharmony_ci * untouched. Note: this can only return addresses less than 4GiB. 34462306a36Sopenharmony_ci */ 34562306a36Sopenharmony_cistatic inline bool arm_has_idmap_alias(void) 34662306a36Sopenharmony_ci{ 34762306a36Sopenharmony_ci return IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset != 0; 34862306a36Sopenharmony_ci} 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci#define IDMAP_INVALID_ADDR ((u32)~0) 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_cistatic inline unsigned long phys_to_idmap(phys_addr_t addr) 35362306a36Sopenharmony_ci{ 35462306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset) { 35562306a36Sopenharmony_ci addr += arch_phys_to_idmap_offset; 35662306a36Sopenharmony_ci if (addr > (u32)~0) 35762306a36Sopenharmony_ci addr = IDMAP_INVALID_ADDR; 35862306a36Sopenharmony_ci } 35962306a36Sopenharmony_ci return addr; 36062306a36Sopenharmony_ci} 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_cistatic inline phys_addr_t idmap_to_phys(unsigned long idmap) 36362306a36Sopenharmony_ci{ 36462306a36Sopenharmony_ci phys_addr_t addr = idmap; 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset) 36762306a36Sopenharmony_ci addr -= arch_phys_to_idmap_offset; 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci return addr; 37062306a36Sopenharmony_ci} 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_cistatic inline unsigned long __virt_to_idmap(unsigned long x) 37362306a36Sopenharmony_ci{ 37462306a36Sopenharmony_ci return phys_to_idmap(__virt_to_phys(x)); 37562306a36Sopenharmony_ci} 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci#define virt_to_idmap(x) __virt_to_idmap((unsigned long)(x)) 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci/* 38062306a36Sopenharmony_ci * Conversion between a struct page and a physical address. 38162306a36Sopenharmony_ci * 38262306a36Sopenharmony_ci * page_to_pfn(page) convert a struct page * to a PFN number 38362306a36Sopenharmony_ci * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * 38462306a36Sopenharmony_ci * 38562306a36Sopenharmony_ci * virt_to_page(k) convert a _valid_ virtual address to struct page * 38662306a36Sopenharmony_ci * virt_addr_valid(k) indicates whether a virtual address is valid 38762306a36Sopenharmony_ci */ 38862306a36Sopenharmony_ci#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr)) 39162306a36Sopenharmony_ci#define virt_addr_valid(kaddr) (((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) \ 39262306a36Sopenharmony_ci && pfn_valid(virt_to_pfn(kaddr))) 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ci#endif 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci#endif 397