1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2009 Chen Liqin <liqin.chen@sunplusct.com> 4*4882a593Smuzhiyun * Copyright (C) 2012 Regents of the University of California 5*4882a593Smuzhiyun * Copyright (C) 2017 SiFive 6*4882a593Smuzhiyun * Copyright (C) 2017 XiaojingZhu <zhuxiaoj@ict.ac.cn> 7*4882a593Smuzhiyun */ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #ifndef _ASM_RISCV_PAGE_H 10*4882a593Smuzhiyun #define _ASM_RISCV_PAGE_H 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #include <linux/pfn.h> 13*4882a593Smuzhiyun #include <linux/const.h> 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #define PAGE_SHIFT (12) 16*4882a593Smuzhiyun #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) 17*4882a593Smuzhiyun #define PAGE_MASK (~(PAGE_SIZE - 1)) 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun #ifdef CONFIG_64BIT 20*4882a593Smuzhiyun #define HUGE_MAX_HSTATE 2 21*4882a593Smuzhiyun #else 22*4882a593Smuzhiyun #define HUGE_MAX_HSTATE 1 23*4882a593Smuzhiyun #endif 24*4882a593Smuzhiyun #define HPAGE_SHIFT PMD_SHIFT 25*4882a593Smuzhiyun #define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) 26*4882a593Smuzhiyun #define HPAGE_MASK (~(HPAGE_SIZE - 1)) 27*4882a593Smuzhiyun #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun /* 30*4882a593Smuzhiyun * PAGE_OFFSET -- the first address of the first page of memory. 31*4882a593Smuzhiyun * When not using MMU this corresponds to the first free page in 32*4882a593Smuzhiyun * physical memory (aligned on a page boundary). 33*4882a593Smuzhiyun */ 34*4882a593Smuzhiyun #define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun #define KERN_VIRT_SIZE (-PAGE_OFFSET) 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun #ifndef __ASSEMBLY__ 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun #define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) 41*4882a593Smuzhiyun #define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun /* align addr on a size boundary - adjust address up/down if needed */ 44*4882a593Smuzhiyun #define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) 45*4882a593Smuzhiyun #define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1))) 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun /* align addr on a size boundary - adjust address up if needed */ 48*4882a593Smuzhiyun #define _ALIGN(addr, size) _ALIGN_UP(addr, size) 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun #define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE) 51*4882a593Smuzhiyun #define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun #define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE) 54*4882a593Smuzhiyun #define copy_user_page(vto, vfrom, vaddr, topg) \ 55*4882a593Smuzhiyun memcpy((vto), (vfrom), PAGE_SIZE) 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun /* 58*4882a593Smuzhiyun * Use struct definitions to apply C type checking 59*4882a593Smuzhiyun */ 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun /* Page Global Directory entry */ 62*4882a593Smuzhiyun typedef struct { 63*4882a593Smuzhiyun unsigned long pgd; 64*4882a593Smuzhiyun } pgd_t; 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun /* Page Table entry */ 67*4882a593Smuzhiyun typedef struct { 68*4882a593Smuzhiyun unsigned long pte; 69*4882a593Smuzhiyun } pte_t; 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun typedef struct { 72*4882a593Smuzhiyun unsigned long pgprot; 73*4882a593Smuzhiyun } pgprot_t; 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun typedef struct page *pgtable_t; 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun #define pte_val(x) ((x).pte) 78*4882a593Smuzhiyun #define pgd_val(x) ((x).pgd) 79*4882a593Smuzhiyun #define pgprot_val(x) ((x).pgprot) 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun #define __pte(x) ((pte_t) { (x) }) 82*4882a593Smuzhiyun #define __pgd(x) ((pgd_t) { (x) }) 83*4882a593Smuzhiyun #define __pgprot(x) ((pgprot_t) { (x) }) 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun #ifdef CONFIG_64BIT 86*4882a593Smuzhiyun #define PTE_FMT "%016lx" 87*4882a593Smuzhiyun #else 88*4882a593Smuzhiyun #define PTE_FMT "%08lx" 89*4882a593Smuzhiyun #endif 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun #ifdef CONFIG_MMU 92*4882a593Smuzhiyun extern unsigned long va_pa_offset; 93*4882a593Smuzhiyun extern unsigned long pfn_base; 94*4882a593Smuzhiyun #define ARCH_PFN_OFFSET (pfn_base) 95*4882a593Smuzhiyun #else 96*4882a593Smuzhiyun #define va_pa_offset 0 97*4882a593Smuzhiyun #define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) 98*4882a593Smuzhiyun #endif /* CONFIG_MMU */ 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun extern unsigned long max_low_pfn; 101*4882a593Smuzhiyun extern unsigned long min_low_pfn; 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun #define __pa_to_va_nodebug(x) ((void *)((unsigned long) (x) + va_pa_offset)) 104*4882a593Smuzhiyun #define __va_to_pa_nodebug(x) ((unsigned long)(x) - va_pa_offset) 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_VIRTUAL 107*4882a593Smuzhiyun extern phys_addr_t __virt_to_phys(unsigned long x); 108*4882a593Smuzhiyun extern phys_addr_t __phys_addr_symbol(unsigned long x); 109*4882a593Smuzhiyun #else 110*4882a593Smuzhiyun #define __virt_to_phys(x) __va_to_pa_nodebug(x) 111*4882a593Smuzhiyun #define __phys_addr_symbol(x) __va_to_pa_nodebug(x) 112*4882a593Smuzhiyun #endif /* CONFIG_DEBUG_VIRTUAL */ 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun #define __pa_symbol(x) __phys_addr_symbol(RELOC_HIDE((unsigned long)(x), 0)) 115*4882a593Smuzhiyun #define __pa(x) __virt_to_phys((unsigned long)(x)) 116*4882a593Smuzhiyun #define __va(x) ((void *)__pa_to_va_nodebug((phys_addr_t)(x))) 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun #define phys_to_pfn(phys) (PFN_DOWN(phys)) 119*4882a593Smuzhiyun #define pfn_to_phys(pfn) (PFN_PHYS(pfn)) 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun #define virt_to_pfn(vaddr) (phys_to_pfn(__pa(vaddr))) 122*4882a593Smuzhiyun #define pfn_to_virt(pfn) (__va(pfn_to_phys(pfn))) 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun #define virt_to_page(vaddr) (pfn_to_page(virt_to_pfn(vaddr))) 125*4882a593Smuzhiyun #define page_to_virt(page) (pfn_to_virt(page_to_pfn(page))) 126*4882a593Smuzhiyun 127*4882a593Smuzhiyun #define page_to_phys(page) (pfn_to_phys(page_to_pfn(page))) 128*4882a593Smuzhiyun #define page_to_bus(page) (page_to_phys(page)) 129*4882a593Smuzhiyun #define phys_to_page(paddr) (pfn_to_page(phys_to_pfn(paddr))) 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun #ifdef CONFIG_FLATMEM 132*4882a593Smuzhiyun #define pfn_valid(pfn) \ 133*4882a593Smuzhiyun (((pfn) >= ARCH_PFN_OFFSET) && (((pfn) - ARCH_PFN_OFFSET) < max_mapnr)) 134*4882a593Smuzhiyun #endif 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun #endif /* __ASSEMBLY__ */ 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun #define virt_addr_valid(vaddr) ({ \ 139*4882a593Smuzhiyun unsigned long _addr = (unsigned long)vaddr; \ 140*4882a593Smuzhiyun (unsigned long)(_addr) >= PAGE_OFFSET && pfn_valid(virt_to_pfn(_addr)); \ 141*4882a593Smuzhiyun }) 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun #define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun #include <asm-generic/memory_model.h> 146*4882a593Smuzhiyun #include <asm-generic/getorder.h> 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun #endif /* _ASM_RISCV_PAGE_H */ 149