18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci// Copyright (C) 2005-2017 Andes Technology Corporation 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#ifndef _ASMNDS32_PGTABLE_H 58c2ecf20Sopenharmony_ci#define _ASMNDS32_PGTABLE_H 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <asm-generic/pgtable-nopmd.h> 88c2ecf20Sopenharmony_ci#include <linux/sizes.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <asm/memory.h> 118c2ecf20Sopenharmony_ci#include <asm/nds32.h> 128c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 138c2ecf20Sopenharmony_ci#include <asm/fixmap.h> 148c2ecf20Sopenharmony_ci#include <nds32_intrinsic.h> 158c2ecf20Sopenharmony_ci#endif 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#ifdef CONFIG_ANDES_PAGE_SIZE_4KB 188c2ecf20Sopenharmony_ci#define PGDIR_SHIFT 22 198c2ecf20Sopenharmony_ci#define PTRS_PER_PGD 1024 208c2ecf20Sopenharmony_ci#define PTRS_PER_PTE 1024 218c2ecf20Sopenharmony_ci#endif 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#ifdef CONFIG_ANDES_PAGE_SIZE_8KB 248c2ecf20Sopenharmony_ci#define PGDIR_SHIFT 24 258c2ecf20Sopenharmony_ci#define PTRS_PER_PGD 256 268c2ecf20Sopenharmony_ci#define PTRS_PER_PTE 2048 278c2ecf20Sopenharmony_ci#endif 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 308c2ecf20Sopenharmony_ciextern void __pte_error(const char *file, int line, unsigned long val); 318c2ecf20Sopenharmony_ciextern void __pgd_error(const char *file, int line, unsigned long val); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) 348c2ecf20Sopenharmony_ci#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) 358c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#define PMD_SIZE (1UL << PMD_SHIFT) 388c2ecf20Sopenharmony_ci#define PMD_MASK (~(PMD_SIZE-1)) 398c2ecf20Sopenharmony_ci#define PGDIR_SIZE (1UL << PGDIR_SHIFT) 408c2ecf20Sopenharmony_ci#define PGDIR_MASK (~(PGDIR_SIZE-1)) 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* 438c2ecf20Sopenharmony_ci * This is the lowest virtual address we can permit any user space 448c2ecf20Sopenharmony_ci * mapping to be mapped at. This is particularly important for 458c2ecf20Sopenharmony_ci * non-high vector CPUs. 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_ci#define FIRST_USER_ADDRESS 0x8000 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM 508c2ecf20Sopenharmony_ci#define CONSISTENT_BASE ((PKMAP_BASE) - (SZ_2M)) 518c2ecf20Sopenharmony_ci#define CONSISTENT_END (PKMAP_BASE) 528c2ecf20Sopenharmony_ci#else 538c2ecf20Sopenharmony_ci#define CONSISTENT_BASE (FIXADDR_START - SZ_2M) 548c2ecf20Sopenharmony_ci#define CONSISTENT_END (FIXADDR_START) 558c2ecf20Sopenharmony_ci#endif 568c2ecf20Sopenharmony_ci#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM 598c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 608c2ecf20Sopenharmony_ci#include <asm/highmem.h> 618c2ecf20Sopenharmony_ci#endif 628c2ecf20Sopenharmony_ci#endif 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci#define VMALLOC_RESERVE SZ_128M 658c2ecf20Sopenharmony_ci#define VMALLOC_END (CONSISTENT_BASE - PAGE_SIZE) 668c2ecf20Sopenharmony_ci#define VMALLOC_START ((VMALLOC_END) - VMALLOC_RESERVE) 678c2ecf20Sopenharmony_ci#define VMALLOC_VMADDR(x) ((unsigned long)(x)) 688c2ecf20Sopenharmony_ci#define MAXMEM __pa(VMALLOC_START) 698c2ecf20Sopenharmony_ci#define MAXMEM_PFN PFN_DOWN(MAXMEM) 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci#define FIRST_USER_PGD_NR 0 728c2ecf20Sopenharmony_ci#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) + FIRST_USER_PGD_NR) 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci/* L2 PTE */ 758c2ecf20Sopenharmony_ci#define _PAGE_V (1UL << 0) 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci#define _PAGE_M_XKRW (0UL << 1) 788c2ecf20Sopenharmony_ci#define _PAGE_M_UR_KR (1UL << 1) 798c2ecf20Sopenharmony_ci#define _PAGE_M_UR_KRW (2UL << 1) 808c2ecf20Sopenharmony_ci#define _PAGE_M_URW_KRW (3UL << 1) 818c2ecf20Sopenharmony_ci#define _PAGE_M_KR (5UL << 1) 828c2ecf20Sopenharmony_ci#define _PAGE_M_KRW (7UL << 1) 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci#define _PAGE_D (1UL << 4) 858c2ecf20Sopenharmony_ci#define _PAGE_E (1UL << 5) 868c2ecf20Sopenharmony_ci#define _PAGE_A (1UL << 6) 878c2ecf20Sopenharmony_ci#define _PAGE_G (1UL << 7) 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci#define _PAGE_C_DEV (0UL << 8) 908c2ecf20Sopenharmony_ci#define _PAGE_C_DEV_WB (1UL << 8) 918c2ecf20Sopenharmony_ci#define _PAGE_C_MEM (2UL << 8) 928c2ecf20Sopenharmony_ci#define _PAGE_C_MEM_SHRD_WB (4UL << 8) 938c2ecf20Sopenharmony_ci#define _PAGE_C_MEM_SHRD_WT (5UL << 8) 948c2ecf20Sopenharmony_ci#define _PAGE_C_MEM_WB (6UL << 8) 958c2ecf20Sopenharmony_ci#define _PAGE_C_MEM_WT (7UL << 8) 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci#define _PAGE_L (1UL << 11) 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci#define _HAVE_PAGE_L (_PAGE_L) 1008c2ecf20Sopenharmony_ci#define _PAGE_FILE (1UL << 1) 1018c2ecf20Sopenharmony_ci#define _PAGE_YOUNG 0 1028c2ecf20Sopenharmony_ci#define _PAGE_M_MASK _PAGE_M_KRW 1038c2ecf20Sopenharmony_ci#define _PAGE_C_MASK _PAGE_C_MEM_WT 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 1068c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 1078c2ecf20Sopenharmony_ci#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WT 1088c2ecf20Sopenharmony_ci#else 1098c2ecf20Sopenharmony_ci#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WB 1108c2ecf20Sopenharmony_ci#endif 1118c2ecf20Sopenharmony_ci#else 1128c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 1138c2ecf20Sopenharmony_ci#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WT 1148c2ecf20Sopenharmony_ci#else 1158c2ecf20Sopenharmony_ci#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WB 1168c2ecf20Sopenharmony_ci#endif 1178c2ecf20Sopenharmony_ci#endif 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH 1208c2ecf20Sopenharmony_ci#define _PAGE_CACHE _PAGE_C_MEM_WT 1218c2ecf20Sopenharmony_ci#else 1228c2ecf20Sopenharmony_ci#define _PAGE_CACHE _PAGE_C_MEM_WB 1238c2ecf20Sopenharmony_ci#endif 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci#define _PAGE_IOREMAP \ 1268c2ecf20Sopenharmony_ci (_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_G | _PAGE_C_DEV) 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci/* 1298c2ecf20Sopenharmony_ci * + Level 1 descriptor (PMD) 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_ci#define PMD_TYPE_TABLE 0 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci#define _PAGE_USER_TABLE PMD_TYPE_TABLE 1368c2ecf20Sopenharmony_ci#define _PAGE_KERNEL_TABLE PMD_TYPE_TABLE 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci#define PAGE_EXEC __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_E) 1398c2ecf20Sopenharmony_ci#define PAGE_NONE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_A) 1408c2ecf20Sopenharmony_ci#define PAGE_READ __pgprot(_PAGE_V | _PAGE_M_UR_KR) 1418c2ecf20Sopenharmony_ci#define PAGE_RDWR __pgprot(_PAGE_V | _PAGE_M_URW_KRW | _PAGE_D) 1428c2ecf20Sopenharmony_ci#define PAGE_COPY __pgprot(_PAGE_V | _PAGE_M_UR_KR) 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci#define PAGE_UXKRWX_V1 __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) 1458c2ecf20Sopenharmony_ci#define PAGE_UXKRWX_V2 __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) 1468c2ecf20Sopenharmony_ci#define PAGE_URXKRWX_V2 __pgprot(_PAGE_V | _PAGE_M_UR_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) 1478c2ecf20Sopenharmony_ci#define PAGE_CACHE_L1 __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE) 1488c2ecf20Sopenharmony_ci#define PAGE_MEMORY __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) 1498c2ecf20Sopenharmony_ci#define PAGE_KERNEL __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) 1508c2ecf20Sopenharmony_ci#define PAGE_SHARED __pgprot(_PAGE_V | _PAGE_M_URW_KRW | _PAGE_D | _PAGE_CACHE_SHRD) 1518c2ecf20Sopenharmony_ci#define PAGE_DEVICE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_G | _PAGE_C_DEV) 1528c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */ 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci/* xwr */ 1558c2ecf20Sopenharmony_ci#define __P000 (PAGE_NONE | _PAGE_CACHE_SHRD) 1568c2ecf20Sopenharmony_ci#define __P001 (PAGE_READ | _PAGE_CACHE_SHRD) 1578c2ecf20Sopenharmony_ci#define __P010 (PAGE_COPY | _PAGE_CACHE_SHRD) 1588c2ecf20Sopenharmony_ci#define __P011 (PAGE_COPY | _PAGE_CACHE_SHRD) 1598c2ecf20Sopenharmony_ci#define __P100 (PAGE_EXEC | _PAGE_CACHE_SHRD) 1608c2ecf20Sopenharmony_ci#define __P101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD) 1618c2ecf20Sopenharmony_ci#define __P110 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD) 1628c2ecf20Sopenharmony_ci#define __P111 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD) 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci#define __S000 (PAGE_NONE | _PAGE_CACHE_SHRD) 1658c2ecf20Sopenharmony_ci#define __S001 (PAGE_READ | _PAGE_CACHE_SHRD) 1668c2ecf20Sopenharmony_ci#define __S010 (PAGE_RDWR | _PAGE_CACHE_SHRD) 1678c2ecf20Sopenharmony_ci#define __S011 (PAGE_RDWR | _PAGE_CACHE_SHRD) 1688c2ecf20Sopenharmony_ci#define __S100 (PAGE_EXEC | _PAGE_CACHE_SHRD) 1698c2ecf20Sopenharmony_ci#define __S101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD) 1708c2ecf20Sopenharmony_ci#define __S110 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD) 1718c2ecf20Sopenharmony_ci#define __S111 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD) 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 1748c2ecf20Sopenharmony_ci/* 1758c2ecf20Sopenharmony_ci * ZERO_PAGE is a global shared page that is always zero: used 1768c2ecf20Sopenharmony_ci * for zero-mapped memory areas etc.. 1778c2ecf20Sopenharmony_ci */ 1788c2ecf20Sopenharmony_ciextern struct page *empty_zero_page; 1798c2ecf20Sopenharmony_ciextern void paging_init(void); 1808c2ecf20Sopenharmony_ci#define ZERO_PAGE(vaddr) (empty_zero_page) 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) 1838c2ecf20Sopenharmony_ci#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))) 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci#define pte_none(pte) !(pte_val(pte)) 1868c2ecf20Sopenharmony_ci#define pte_clear(mm,addr,ptep) set_pte_at((mm),(addr),(ptep), __pte(0)) 1878c2ecf20Sopenharmony_ci#define pte_page(pte) (pfn_to_page(pte_pfn(pte))) 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_cistatic unsigned long pmd_page_vaddr(pmd_t pmd) 1908c2ecf20Sopenharmony_ci{ 1918c2ecf20Sopenharmony_ci return ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)); 1928c2ecf20Sopenharmony_ci} 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) 1958c2ecf20Sopenharmony_ci/* 1968c2ecf20Sopenharmony_ci * Set a level 1 translation table entry, and clean it out of 1978c2ecf20Sopenharmony_ci * any caches such that the MMUs can load it correctly. 1988c2ecf20Sopenharmony_ci */ 1998c2ecf20Sopenharmony_cistatic inline void set_pmd(pmd_t * pmdp, pmd_t pmd) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci *pmdp = pmd; 2038c2ecf20Sopenharmony_ci#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) 2048c2ecf20Sopenharmony_ci __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (pmdp):"memory"); 2058c2ecf20Sopenharmony_ci __nds32__msync_all(); 2068c2ecf20Sopenharmony_ci __nds32__dsb(); 2078c2ecf20Sopenharmony_ci#endif 2088c2ecf20Sopenharmony_ci} 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci/* 2118c2ecf20Sopenharmony_ci * Set a PTE and flush it out 2128c2ecf20Sopenharmony_ci */ 2138c2ecf20Sopenharmony_cistatic inline void set_pte(pte_t * ptep, pte_t pte) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci *ptep = pte; 2178c2ecf20Sopenharmony_ci#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) 2188c2ecf20Sopenharmony_ci __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (ptep):"memory"); 2198c2ecf20Sopenharmony_ci __nds32__msync_all(); 2208c2ecf20Sopenharmony_ci __nds32__dsb(); 2218c2ecf20Sopenharmony_ci#endif 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci/* 2258c2ecf20Sopenharmony_ci * The following only work if pte_present() is true. 2268c2ecf20Sopenharmony_ci * Undefined behaviour if not.. 2278c2ecf20Sopenharmony_ci */ 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci/* 2308c2ecf20Sopenharmony_ci * pte_write: this page is writeable for user mode 2318c2ecf20Sopenharmony_ci * pte_read: this page is readable for user mode 2328c2ecf20Sopenharmony_ci * pte_kernel_write: this page is writeable for kernel mode 2338c2ecf20Sopenharmony_ci * 2348c2ecf20Sopenharmony_ci * We don't have pte_kernel_read because kernel always can read. 2358c2ecf20Sopenharmony_ci * 2368c2ecf20Sopenharmony_ci * */ 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci#define pte_present(pte) (pte_val(pte) & _PAGE_V) 2398c2ecf20Sopenharmony_ci#define pte_write(pte) ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW) 2408c2ecf20Sopenharmony_ci#define pte_read(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KR) || \ 2418c2ecf20Sopenharmony_ci ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \ 2428c2ecf20Sopenharmony_ci ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW)) 2438c2ecf20Sopenharmony_ci#define pte_kernel_write(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW) || \ 2448c2ecf20Sopenharmony_ci ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \ 2458c2ecf20Sopenharmony_ci ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_KRW) || \ 2468c2ecf20Sopenharmony_ci (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_XKRW) && pte_exec(pte))) 2478c2ecf20Sopenharmony_ci#define pte_exec(pte) (pte_val(pte) & _PAGE_E) 2488c2ecf20Sopenharmony_ci#define pte_dirty(pte) (pte_val(pte) & _PAGE_D) 2498c2ecf20Sopenharmony_ci#define pte_young(pte) (pte_val(pte) & _PAGE_YOUNG) 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci/* 2528c2ecf20Sopenharmony_ci * The following only works if pte_present() is not true. 2538c2ecf20Sopenharmony_ci */ 2548c2ecf20Sopenharmony_ci#define pte_file(pte) (pte_val(pte) & _PAGE_FILE) 2558c2ecf20Sopenharmony_ci#define pte_to_pgoff(x) (pte_val(x) >> 2) 2568c2ecf20Sopenharmony_ci#define pgoff_to_pte(x) __pte(((x) << 2) | _PAGE_FILE) 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci#define PTE_FILE_MAX_BITS 29 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci#define PTE_BIT_FUNC(fn,op) \ 2618c2ecf20Sopenharmony_cistatic inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_cistatic inline pte_t pte_wrprotect(pte_t pte) 2648c2ecf20Sopenharmony_ci{ 2658c2ecf20Sopenharmony_ci pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK; 2668c2ecf20Sopenharmony_ci pte_val(pte) = pte_val(pte) | _PAGE_M_UR_KR; 2678c2ecf20Sopenharmony_ci return pte; 2688c2ecf20Sopenharmony_ci} 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_cistatic inline pte_t pte_mkwrite(pte_t pte) 2718c2ecf20Sopenharmony_ci{ 2728c2ecf20Sopenharmony_ci pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK; 2738c2ecf20Sopenharmony_ci pte_val(pte) = pte_val(pte) | _PAGE_M_URW_KRW; 2748c2ecf20Sopenharmony_ci return pte; 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ciPTE_BIT_FUNC(exprotect, &=~_PAGE_E); 2788c2ecf20Sopenharmony_ciPTE_BIT_FUNC(mkexec, |=_PAGE_E); 2798c2ecf20Sopenharmony_ciPTE_BIT_FUNC(mkclean, &=~_PAGE_D); 2808c2ecf20Sopenharmony_ciPTE_BIT_FUNC(mkdirty, |=_PAGE_D); 2818c2ecf20Sopenharmony_ciPTE_BIT_FUNC(mkold, &=~_PAGE_YOUNG); 2828c2ecf20Sopenharmony_ciPTE_BIT_FUNC(mkyoung, |=_PAGE_YOUNG); 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci/* 2858c2ecf20Sopenharmony_ci * Mark the prot value as uncacheable and unbufferable. 2868c2ecf20Sopenharmony_ci */ 2878c2ecf20Sopenharmony_ci#define pgprot_noncached(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV) 2888c2ecf20Sopenharmony_ci#define pgprot_writecombine(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV_WB) 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci#define pmd_none(pmd) (pmd_val(pmd)&0x1) 2918c2ecf20Sopenharmony_ci#define pmd_present(pmd) (!pmd_none(pmd)) 2928c2ecf20Sopenharmony_ci#define pmd_bad(pmd) pmd_none(pmd) 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci#define copy_pmd(pmdpd,pmdps) set_pmd((pmdpd), *(pmdps)) 2958c2ecf20Sopenharmony_ci#define pmd_clear(pmdp) set_pmd((pmdp), __pmd(1)) 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_cistatic inline pmd_t __mk_pmd(pte_t * ptep, unsigned long prot) 2988c2ecf20Sopenharmony_ci{ 2998c2ecf20Sopenharmony_ci unsigned long ptr = (unsigned long)ptep; 3008c2ecf20Sopenharmony_ci pmd_t pmd; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci /* 3038c2ecf20Sopenharmony_ci * The pmd must be loaded with the physical 3048c2ecf20Sopenharmony_ci * address of the PTE table 3058c2ecf20Sopenharmony_ci */ 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci pmd_val(pmd) = __virt_to_phys(ptr) | prot; 3088c2ecf20Sopenharmony_ci return pmd; 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci/* 3148c2ecf20Sopenharmony_ci * Permanent address of a page. We never have highmem, so this is trivial. 3158c2ecf20Sopenharmony_ci */ 3168c2ecf20Sopenharmony_ci#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT)) 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci/* 3198c2ecf20Sopenharmony_ci * Conversion functions: convert a page and protection to a page entry, 3208c2ecf20Sopenharmony_ci * and a page entry and page directory to the page they refer to. 3218c2ecf20Sopenharmony_ci */ 3228c2ecf20Sopenharmony_ci#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot) 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci/* 3258c2ecf20Sopenharmony_ci * The "pgd_xxx()" functions here are trivial for a folded two-level 3268c2ecf20Sopenharmony_ci * setup: the pgd is never bad, and a pmd always exists (as it's folded 3278c2ecf20Sopenharmony_ci * into the pgd entry) 3288c2ecf20Sopenharmony_ci */ 3298c2ecf20Sopenharmony_ci#define pgd_none(pgd) (0) 3308c2ecf20Sopenharmony_ci#define pgd_bad(pgd) (0) 3318c2ecf20Sopenharmony_ci#define pgd_present(pgd) (1) 3328c2ecf20Sopenharmony_ci#define pgd_clear(pgdp) do { } while (0) 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci#define page_pte_prot(page,prot) mk_pte(page, prot) 3358c2ecf20Sopenharmony_ci#define page_pte(page) mk_pte(page, __pgprot(0)) 3368c2ecf20Sopenharmony_ci/* 3378c2ecf20Sopenharmony_ci * L1PTE = $mr1 + ((virt >> PMD_SHIFT) << 2); 3388c2ecf20Sopenharmony_ci * L2PTE = (((virt >> PAGE_SHIFT) & (PTRS_PER_PTE -1 )) << 2); 3398c2ecf20Sopenharmony_ci * PPN = (phys & 0xfffff000); 3408c2ecf20Sopenharmony_ci * 3418c2ecf20Sopenharmony_ci*/ 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_cistatic inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 3448c2ecf20Sopenharmony_ci{ 3458c2ecf20Sopenharmony_ci const unsigned long mask = 0xfff; 3468c2ecf20Sopenharmony_ci pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); 3478c2ecf20Sopenharmony_ci return pte; 3488c2ecf20Sopenharmony_ci} 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ciextern pgd_t swapper_pg_dir[PTRS_PER_PGD]; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci/* Encode and decode a swap entry. 3538c2ecf20Sopenharmony_ci * 3548c2ecf20Sopenharmony_ci * We support up to 32GB of swap on 4k machines 3558c2ecf20Sopenharmony_ci */ 3568c2ecf20Sopenharmony_ci#define __swp_type(x) (((x).val >> 2) & 0x7f) 3578c2ecf20Sopenharmony_ci#define __swp_offset(x) ((x).val >> 9) 3588c2ecf20Sopenharmony_ci#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) }) 3598c2ecf20Sopenharmony_ci#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) 3608c2ecf20Sopenharmony_ci#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ 3638c2ecf20Sopenharmony_ci#define kern_addr_valid(addr) (1) 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci/* 3668c2ecf20Sopenharmony_ci * We provide our own arch_get_unmapped_area to cope with VIPT caches. 3678c2ecf20Sopenharmony_ci */ 3688c2ecf20Sopenharmony_ci#define HAVE_ARCH_UNMAPPED_AREA 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci/* 3718c2ecf20Sopenharmony_ci * remap a physical address `phys' of size `size' with page protection `prot' 3728c2ecf20Sopenharmony_ci * into virtual address `from' 3738c2ecf20Sopenharmony_ci */ 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci#endif /* _ASMNDS32_PGTABLE_H */ 378