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