18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2009 Chen Liqin <liqin.chen@sunplusct.com> 48c2ecf20Sopenharmony_ci * Copyright (C) 2012 Regents of the University of California 58c2ecf20Sopenharmony_ci * Copyright (C) 2017 SiFive 68c2ecf20Sopenharmony_ci * Copyright (C) 2017 XiaojingZhu <zhuxiaoj@ict.ac.cn> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#ifndef _ASM_RISCV_PAGE_H 108c2ecf20Sopenharmony_ci#define _ASM_RISCV_PAGE_H 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/pfn.h> 138c2ecf20Sopenharmony_ci#include <linux/const.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define PAGE_SHIFT (12) 168c2ecf20Sopenharmony_ci#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) 178c2ecf20Sopenharmony_ci#define PAGE_MASK (~(PAGE_SIZE - 1)) 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT 208c2ecf20Sopenharmony_ci#define HUGE_MAX_HSTATE 2 218c2ecf20Sopenharmony_ci#else 228c2ecf20Sopenharmony_ci#define HUGE_MAX_HSTATE 1 238c2ecf20Sopenharmony_ci#endif 248c2ecf20Sopenharmony_ci#define HPAGE_SHIFT PMD_SHIFT 258c2ecf20Sopenharmony_ci#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT) 268c2ecf20Sopenharmony_ci#define HPAGE_MASK (~(HPAGE_SIZE - 1)) 278c2ecf20Sopenharmony_ci#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci/* 308c2ecf20Sopenharmony_ci * PAGE_OFFSET -- the first address of the first page of memory. 318c2ecf20Sopenharmony_ci * When not using MMU this corresponds to the first free page in 328c2ecf20Sopenharmony_ci * physical memory (aligned on a page boundary). 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci#define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL) 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define KERN_VIRT_SIZE (-PAGE_OFFSET) 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#define PAGE_UP(addr) (((addr)+((PAGE_SIZE)-1))&(~((PAGE_SIZE)-1))) 418c2ecf20Sopenharmony_ci#define PAGE_DOWN(addr) ((addr)&(~((PAGE_SIZE)-1))) 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* align addr on a size boundary - adjust address up/down if needed */ 448c2ecf20Sopenharmony_ci#define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1))) 458c2ecf20Sopenharmony_ci#define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1))) 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci/* align addr on a size boundary - adjust address up if needed */ 488c2ecf20Sopenharmony_ci#define _ALIGN(addr, size) _ALIGN_UP(addr, size) 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#define clear_page(pgaddr) memset((pgaddr), 0, PAGE_SIZE) 518c2ecf20Sopenharmony_ci#define copy_page(to, from) memcpy((to), (from), PAGE_SIZE) 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define clear_user_page(pgaddr, vaddr, page) memset((pgaddr), 0, PAGE_SIZE) 548c2ecf20Sopenharmony_ci#define copy_user_page(vto, vfrom, vaddr, topg) \ 558c2ecf20Sopenharmony_ci memcpy((vto), (vfrom), PAGE_SIZE) 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* 588c2ecf20Sopenharmony_ci * Use struct definitions to apply C type checking 598c2ecf20Sopenharmony_ci */ 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* Page Global Directory entry */ 628c2ecf20Sopenharmony_citypedef struct { 638c2ecf20Sopenharmony_ci unsigned long pgd; 648c2ecf20Sopenharmony_ci} pgd_t; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci/* Page Table entry */ 678c2ecf20Sopenharmony_citypedef struct { 688c2ecf20Sopenharmony_ci unsigned long pte; 698c2ecf20Sopenharmony_ci} pte_t; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_citypedef struct { 728c2ecf20Sopenharmony_ci unsigned long pgprot; 738c2ecf20Sopenharmony_ci} pgprot_t; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_citypedef struct page *pgtable_t; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci#define pte_val(x) ((x).pte) 788c2ecf20Sopenharmony_ci#define pgd_val(x) ((x).pgd) 798c2ecf20Sopenharmony_ci#define pgprot_val(x) ((x).pgprot) 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci#define __pte(x) ((pte_t) { (x) }) 828c2ecf20Sopenharmony_ci#define __pgd(x) ((pgd_t) { (x) }) 838c2ecf20Sopenharmony_ci#define __pgprot(x) ((pgprot_t) { (x) }) 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT 868c2ecf20Sopenharmony_ci#define PTE_FMT "%016lx" 878c2ecf20Sopenharmony_ci#else 888c2ecf20Sopenharmony_ci#define PTE_FMT "%08lx" 898c2ecf20Sopenharmony_ci#endif 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci#ifdef CONFIG_MMU 928c2ecf20Sopenharmony_ciextern unsigned long va_pa_offset; 938c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT 948c2ecf20Sopenharmony_ciextern unsigned long va_kernel_pa_offset; 958c2ecf20Sopenharmony_ci#endif 968c2ecf20Sopenharmony_ciextern unsigned long pfn_base; 978c2ecf20Sopenharmony_ci#define ARCH_PFN_OFFSET (pfn_base) 988c2ecf20Sopenharmony_ci#else 998c2ecf20Sopenharmony_ci#define va_pa_offset 0 1008c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT 1018c2ecf20Sopenharmony_ci#define va_kernel_pa_offset 0 1028c2ecf20Sopenharmony_ci#endif 1038c2ecf20Sopenharmony_ci#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT) 1048c2ecf20Sopenharmony_ci#endif /* CONFIG_MMU */ 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ciextern unsigned long max_low_pfn; 1078c2ecf20Sopenharmony_ciextern unsigned long min_low_pfn; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ciextern unsigned long kernel_virt_addr; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT 1128c2ecf20Sopenharmony_ci#define linear_mapping_pa_to_va(x) ((void *)((unsigned long)(x) + va_pa_offset)) 1138c2ecf20Sopenharmony_ci#define kernel_mapping_pa_to_va(x) ((void *)((unsigned long)(x) + va_kernel_pa_offset)) 1148c2ecf20Sopenharmony_ci#define __pa_to_va_nodebug(x) linear_mapping_pa_to_va(x) 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci#define linear_mapping_va_to_pa(x) ((unsigned long)(x) - va_pa_offset) 1178c2ecf20Sopenharmony_ci#define kernel_mapping_va_to_pa(x) ((unsigned long)(x) - va_kernel_pa_offset) 1188c2ecf20Sopenharmony_ci#define __va_to_pa_nodebug(x) ({ \ 1198c2ecf20Sopenharmony_ci unsigned long _x = x; \ 1208c2ecf20Sopenharmony_ci (_x < kernel_virt_addr) ? \ 1218c2ecf20Sopenharmony_ci linear_mapping_va_to_pa(_x) : kernel_mapping_va_to_pa(_x); \ 1228c2ecf20Sopenharmony_ci }) 1238c2ecf20Sopenharmony_ci#else 1248c2ecf20Sopenharmony_ci#define __pa_to_va_nodebug(x) ((void *)((unsigned long) (x) + va_pa_offset)) 1258c2ecf20Sopenharmony_ci#define __va_to_pa_nodebug(x) ((unsigned long)(x) - va_pa_offset) 1268c2ecf20Sopenharmony_ci#endif 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci#ifdef CONFIG_DEBUG_VIRTUAL 1298c2ecf20Sopenharmony_ciextern phys_addr_t __virt_to_phys(unsigned long x); 1308c2ecf20Sopenharmony_ciextern phys_addr_t __phys_addr_symbol(unsigned long x); 1318c2ecf20Sopenharmony_ci#else 1328c2ecf20Sopenharmony_ci#define __virt_to_phys(x) __va_to_pa_nodebug(x) 1338c2ecf20Sopenharmony_ci#define __phys_addr_symbol(x) __va_to_pa_nodebug(x) 1348c2ecf20Sopenharmony_ci#endif /* CONFIG_DEBUG_VIRTUAL */ 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci#define __pa_symbol(x) __phys_addr_symbol(RELOC_HIDE((unsigned long)(x), 0)) 1378c2ecf20Sopenharmony_ci#define __pa(x) __virt_to_phys((unsigned long)(x)) 1388c2ecf20Sopenharmony_ci#define __va(x) ((void *)__pa_to_va_nodebug((phys_addr_t)(x))) 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci#define phys_to_pfn(phys) (PFN_DOWN(phys)) 1418c2ecf20Sopenharmony_ci#define pfn_to_phys(pfn) (PFN_PHYS(pfn)) 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci#define virt_to_pfn(vaddr) (phys_to_pfn(__pa(vaddr))) 1448c2ecf20Sopenharmony_ci#define pfn_to_virt(pfn) (__va(pfn_to_phys(pfn))) 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci#define virt_to_page(vaddr) (pfn_to_page(virt_to_pfn(vaddr))) 1478c2ecf20Sopenharmony_ci#define page_to_virt(page) (pfn_to_virt(page_to_pfn(page))) 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci#define page_to_phys(page) (pfn_to_phys(page_to_pfn(page))) 1508c2ecf20Sopenharmony_ci#define page_to_bus(page) (page_to_phys(page)) 1518c2ecf20Sopenharmony_ci#define phys_to_page(paddr) (pfn_to_page(phys_to_pfn(paddr))) 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci#ifdef CONFIG_FLATMEM 1548c2ecf20Sopenharmony_ci#define pfn_valid(pfn) \ 1558c2ecf20Sopenharmony_ci (((pfn) >= ARCH_PFN_OFFSET) && (((pfn) - ARCH_PFN_OFFSET) < max_mapnr)) 1568c2ecf20Sopenharmony_ci#endif 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */ 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci#define virt_addr_valid(vaddr) ({ \ 1618c2ecf20Sopenharmony_ci unsigned long _addr = (unsigned long)vaddr; \ 1628c2ecf20Sopenharmony_ci (unsigned long)(_addr) >= PAGE_OFFSET && pfn_valid(virt_to_pfn(_addr)); \ 1638c2ecf20Sopenharmony_ci}) 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci#include <asm-generic/memory_model.h> 1688c2ecf20Sopenharmony_ci#include <asm-generic/getorder.h> 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci#endif /* _ASM_RISCV_PAGE_H */ 171