18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef __ASM_SH_PGTABLE_32_H
38c2ecf20Sopenharmony_ci#define __ASM_SH_PGTABLE_32_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci/*
68c2ecf20Sopenharmony_ci * Linux PTEL encoding.
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Hardware and software bit definitions for the PTEL value (see below for
98c2ecf20Sopenharmony_ci * notes on SH-X2 MMUs and 64-bit PTEs):
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * - Bits 0 and 7 are reserved on SH-3 (_PAGE_WT and _PAGE_SZ1 on SH-4).
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci * - Bit 1 is the SH-bit, but is unused on SH-3 due to an MMU bug (the
148c2ecf20Sopenharmony_ci *   hardware PTEL value can't have the SH-bit set when MMUCR.IX is set,
158c2ecf20Sopenharmony_ci *   which is the default in cpu-sh3/mmu_context.h:MMU_CONTROL_INIT).
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci *   In order to keep this relatively clean, do not use these for defining
188c2ecf20Sopenharmony_ci *   SH-3 specific flags until all of the other unused bits have been
198c2ecf20Sopenharmony_ci *   exhausted.
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci * - Bit 9 is reserved by everyone and used by _PAGE_PROTNONE.
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * - Bits 10 and 11 are low bits of the PPN that are reserved on >= 4K pages.
248c2ecf20Sopenharmony_ci *   Bit 10 is used for _PAGE_ACCESSED, and bit 11 is used for _PAGE_SPECIAL.
258c2ecf20Sopenharmony_ci *
268c2ecf20Sopenharmony_ci * - On 29 bit platforms, bits 31 to 29 are used for the space attributes
278c2ecf20Sopenharmony_ci *   and timing control which (together with bit 0) are moved into the
288c2ecf20Sopenharmony_ci *   old-style PTEA on the parts that support it.
298c2ecf20Sopenharmony_ci *
308c2ecf20Sopenharmony_ci * SH-X2 MMUs and extended PTEs
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci * SH-X2 supports an extended mode TLB with split data arrays due to the
338c2ecf20Sopenharmony_ci * number of bits needed for PR and SZ (now EPR and ESZ) encodings. The PR and
348c2ecf20Sopenharmony_ci * SZ bit placeholders still exist in data array 1, but are implemented as
358c2ecf20Sopenharmony_ci * reserved bits, with the real logic existing in data array 2.
368c2ecf20Sopenharmony_ci *
378c2ecf20Sopenharmony_ci * The downside to this is that we can no longer fit everything in to a 32-bit
388c2ecf20Sopenharmony_ci * PTE encoding, so a 64-bit pte_t is necessary for these parts. On the plus
398c2ecf20Sopenharmony_ci * side, this gives us quite a few spare bits to play with for future usage.
408c2ecf20Sopenharmony_ci */
418c2ecf20Sopenharmony_ci/* Legacy and compat mode bits */
428c2ecf20Sopenharmony_ci#define	_PAGE_WT	0x001		/* WT-bit on SH-4, 0 on SH-3 */
438c2ecf20Sopenharmony_ci#define _PAGE_HW_SHARED	0x002		/* SH-bit  : shared among processes */
448c2ecf20Sopenharmony_ci#define _PAGE_DIRTY	0x004		/* D-bit   : page changed */
458c2ecf20Sopenharmony_ci#define _PAGE_CACHABLE	0x008		/* C-bit   : cachable */
468c2ecf20Sopenharmony_ci#define _PAGE_SZ0	0x010		/* SZ0-bit : Size of page */
478c2ecf20Sopenharmony_ci#define _PAGE_RW	0x020		/* PR0-bit : write access allowed */
488c2ecf20Sopenharmony_ci#define _PAGE_USER	0x040		/* PR1-bit : user space access allowed*/
498c2ecf20Sopenharmony_ci#define _PAGE_SZ1	0x080		/* SZ1-bit : Size of page (on SH-4) */
508c2ecf20Sopenharmony_ci#define _PAGE_PRESENT	0x100		/* V-bit   : page is valid */
518c2ecf20Sopenharmony_ci#define _PAGE_PROTNONE	0x200		/* software: if not present  */
528c2ecf20Sopenharmony_ci#define _PAGE_ACCESSED	0x400		/* software: page referenced */
538c2ecf20Sopenharmony_ci#define _PAGE_SPECIAL	0x800		/* software: special page */
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci#define _PAGE_SZ_MASK	(_PAGE_SZ0 | _PAGE_SZ1)
568c2ecf20Sopenharmony_ci#define _PAGE_PR_MASK	(_PAGE_RW | _PAGE_USER)
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci/* Extended mode bits */
598c2ecf20Sopenharmony_ci#define _PAGE_EXT_ESZ0		0x0010	/* ESZ0-bit: Size of page */
608c2ecf20Sopenharmony_ci#define _PAGE_EXT_ESZ1		0x0020	/* ESZ1-bit: Size of page */
618c2ecf20Sopenharmony_ci#define _PAGE_EXT_ESZ2		0x0040	/* ESZ2-bit: Size of page */
628c2ecf20Sopenharmony_ci#define _PAGE_EXT_ESZ3		0x0080	/* ESZ3-bit: Size of page */
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci#define _PAGE_EXT_USER_EXEC	0x0100	/* EPR0-bit: User space executable */
658c2ecf20Sopenharmony_ci#define _PAGE_EXT_USER_WRITE	0x0200	/* EPR1-bit: User space writable */
668c2ecf20Sopenharmony_ci#define _PAGE_EXT_USER_READ	0x0400	/* EPR2-bit: User space readable */
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci#define _PAGE_EXT_KERN_EXEC	0x0800	/* EPR3-bit: Kernel space executable */
698c2ecf20Sopenharmony_ci#define _PAGE_EXT_KERN_WRITE	0x1000	/* EPR4-bit: Kernel space writable */
708c2ecf20Sopenharmony_ci#define _PAGE_EXT_KERN_READ	0x2000	/* EPR5-bit: Kernel space readable */
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci#define _PAGE_EXT_WIRED		0x4000	/* software: Wire TLB entry */
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci/* Wrapper for extended mode pgprot twiddling */
758c2ecf20Sopenharmony_ci#define _PAGE_EXT(x)		((unsigned long long)(x) << 32)
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci#ifdef CONFIG_X2TLB
788c2ecf20Sopenharmony_ci#define _PAGE_PCC_MASK	0x00000000	/* No legacy PTEA support */
798c2ecf20Sopenharmony_ci#else
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci/* software: moves to PTEA.TC (Timing Control) */
828c2ecf20Sopenharmony_ci#define _PAGE_PCC_AREA5	0x00000000	/* use BSC registers for area5 */
838c2ecf20Sopenharmony_ci#define _PAGE_PCC_AREA6	0x80000000	/* use BSC registers for area6 */
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci/* software: moves to PTEA.SA[2:0] (Space Attributes) */
868c2ecf20Sopenharmony_ci#define _PAGE_PCC_IODYN 0x00000001	/* IO space, dynamically sized bus */
878c2ecf20Sopenharmony_ci#define _PAGE_PCC_IO8	0x20000000	/* IO space, 8 bit bus */
888c2ecf20Sopenharmony_ci#define _PAGE_PCC_IO16	0x20000001	/* IO space, 16 bit bus */
898c2ecf20Sopenharmony_ci#define _PAGE_PCC_COM8	0x40000000	/* Common Memory space, 8 bit bus */
908c2ecf20Sopenharmony_ci#define _PAGE_PCC_COM16	0x40000001	/* Common Memory space, 16 bit bus */
918c2ecf20Sopenharmony_ci#define _PAGE_PCC_ATR8	0x60000000	/* Attribute Memory space, 8 bit bus */
928c2ecf20Sopenharmony_ci#define _PAGE_PCC_ATR16	0x60000001	/* Attribute Memory space, 6 bit bus */
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci#define _PAGE_PCC_MASK	0xe0000001
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci/* copy the ptea attributes */
978c2ecf20Sopenharmony_cistatic inline unsigned long copy_ptea_attributes(unsigned long x)
988c2ecf20Sopenharmony_ci{
998c2ecf20Sopenharmony_ci	return	((x >> 28) & 0xe) | (x & 0x1);
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci#endif
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci/* Mask which drops unused bits from the PTEL value */
1048c2ecf20Sopenharmony_ci#if defined(CONFIG_CPU_SH3)
1058c2ecf20Sopenharmony_ci#define _PAGE_CLEAR_FLAGS	(_PAGE_PROTNONE | _PAGE_ACCESSED| \
1068c2ecf20Sopenharmony_ci				  _PAGE_SZ1	| _PAGE_HW_SHARED)
1078c2ecf20Sopenharmony_ci#elif defined(CONFIG_X2TLB)
1088c2ecf20Sopenharmony_ci/* Get rid of the legacy PR/SZ bits when using extended mode */
1098c2ecf20Sopenharmony_ci#define _PAGE_CLEAR_FLAGS	(_PAGE_PROTNONE | _PAGE_ACCESSED | \
1108c2ecf20Sopenharmony_ci				 _PAGE_PR_MASK | _PAGE_SZ_MASK)
1118c2ecf20Sopenharmony_ci#else
1128c2ecf20Sopenharmony_ci#define _PAGE_CLEAR_FLAGS	(_PAGE_PROTNONE | _PAGE_ACCESSED)
1138c2ecf20Sopenharmony_ci#endif
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci#define _PAGE_FLAGS_HARDWARE_MASK	(phys_addr_mask() & ~(_PAGE_CLEAR_FLAGS))
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci/* Hardware flags, page size encoding */
1188c2ecf20Sopenharmony_ci#if !defined(CONFIG_MMU)
1198c2ecf20Sopenharmony_ci# define _PAGE_FLAGS_HARD	0ULL
1208c2ecf20Sopenharmony_ci#elif defined(CONFIG_X2TLB)
1218c2ecf20Sopenharmony_ci# if defined(CONFIG_PAGE_SIZE_4KB)
1228c2ecf20Sopenharmony_ci#  define _PAGE_FLAGS_HARD	_PAGE_EXT(_PAGE_EXT_ESZ0)
1238c2ecf20Sopenharmony_ci# elif defined(CONFIG_PAGE_SIZE_8KB)
1248c2ecf20Sopenharmony_ci#  define _PAGE_FLAGS_HARD	_PAGE_EXT(_PAGE_EXT_ESZ1)
1258c2ecf20Sopenharmony_ci# elif defined(CONFIG_PAGE_SIZE_64KB)
1268c2ecf20Sopenharmony_ci#  define _PAGE_FLAGS_HARD	_PAGE_EXT(_PAGE_EXT_ESZ2)
1278c2ecf20Sopenharmony_ci# endif
1288c2ecf20Sopenharmony_ci#else
1298c2ecf20Sopenharmony_ci# if defined(CONFIG_PAGE_SIZE_4KB)
1308c2ecf20Sopenharmony_ci#  define _PAGE_FLAGS_HARD	_PAGE_SZ0
1318c2ecf20Sopenharmony_ci# elif defined(CONFIG_PAGE_SIZE_64KB)
1328c2ecf20Sopenharmony_ci#  define _PAGE_FLAGS_HARD	_PAGE_SZ1
1338c2ecf20Sopenharmony_ci# endif
1348c2ecf20Sopenharmony_ci#endif
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci#if defined(CONFIG_X2TLB)
1378c2ecf20Sopenharmony_ci# if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
1388c2ecf20Sopenharmony_ci#  define _PAGE_SZHUGE	(_PAGE_EXT_ESZ2)
1398c2ecf20Sopenharmony_ci# elif defined(CONFIG_HUGETLB_PAGE_SIZE_256K)
1408c2ecf20Sopenharmony_ci#  define _PAGE_SZHUGE	(_PAGE_EXT_ESZ0 | _PAGE_EXT_ESZ2)
1418c2ecf20Sopenharmony_ci# elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB)
1428c2ecf20Sopenharmony_ci#  define _PAGE_SZHUGE	(_PAGE_EXT_ESZ0 | _PAGE_EXT_ESZ1 | _PAGE_EXT_ESZ2)
1438c2ecf20Sopenharmony_ci# elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
1448c2ecf20Sopenharmony_ci#  define _PAGE_SZHUGE	(_PAGE_EXT_ESZ3)
1458c2ecf20Sopenharmony_ci# elif defined(CONFIG_HUGETLB_PAGE_SIZE_64MB)
1468c2ecf20Sopenharmony_ci#  define _PAGE_SZHUGE	(_PAGE_EXT_ESZ2 | _PAGE_EXT_ESZ3)
1478c2ecf20Sopenharmony_ci# endif
1488c2ecf20Sopenharmony_ci# define _PAGE_WIRED	(_PAGE_EXT(_PAGE_EXT_WIRED))
1498c2ecf20Sopenharmony_ci#else
1508c2ecf20Sopenharmony_ci# if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
1518c2ecf20Sopenharmony_ci#  define _PAGE_SZHUGE	(_PAGE_SZ1)
1528c2ecf20Sopenharmony_ci# elif defined(CONFIG_HUGETLB_PAGE_SIZE_1MB)
1538c2ecf20Sopenharmony_ci#  define _PAGE_SZHUGE	(_PAGE_SZ0 | _PAGE_SZ1)
1548c2ecf20Sopenharmony_ci# endif
1558c2ecf20Sopenharmony_ci# define _PAGE_WIRED	(0)
1568c2ecf20Sopenharmony_ci#endif
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci/*
1598c2ecf20Sopenharmony_ci * Stub out _PAGE_SZHUGE if we don't have a good definition for it,
1608c2ecf20Sopenharmony_ci * to make pte_mkhuge() happy.
1618c2ecf20Sopenharmony_ci */
1628c2ecf20Sopenharmony_ci#ifndef _PAGE_SZHUGE
1638c2ecf20Sopenharmony_ci# define _PAGE_SZHUGE	(_PAGE_FLAGS_HARD)
1648c2ecf20Sopenharmony_ci#endif
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci/*
1678c2ecf20Sopenharmony_ci * Mask of bits that are to be preserved across pgprot changes.
1688c2ecf20Sopenharmony_ci */
1698c2ecf20Sopenharmony_ci#define _PAGE_CHG_MASK \
1708c2ecf20Sopenharmony_ci	(PTE_MASK | _PAGE_ACCESSED | _PAGE_CACHABLE | \
1718c2ecf20Sopenharmony_ci	 _PAGE_DIRTY | _PAGE_SPECIAL)
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci#if defined(CONFIG_X2TLB) /* SH-X2 TLB */
1768c2ecf20Sopenharmony_ci#define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE | \
1778c2ecf20Sopenharmony_ci				 _PAGE_ACCESSED | _PAGE_FLAGS_HARD)
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
1808c2ecf20Sopenharmony_ci				 _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \
1818c2ecf20Sopenharmony_ci				 _PAGE_EXT(_PAGE_EXT_KERN_READ  | \
1828c2ecf20Sopenharmony_ci					   _PAGE_EXT_KERN_WRITE | \
1838c2ecf20Sopenharmony_ci					   _PAGE_EXT_USER_READ  | \
1848c2ecf20Sopenharmony_ci					   _PAGE_EXT_USER_WRITE))
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci#define PAGE_EXECREAD	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
1878c2ecf20Sopenharmony_ci				 _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \
1888c2ecf20Sopenharmony_ci				 _PAGE_EXT(_PAGE_EXT_KERN_EXEC | \
1898c2ecf20Sopenharmony_ci					   _PAGE_EXT_KERN_READ | \
1908c2ecf20Sopenharmony_ci					   _PAGE_EXT_USER_EXEC | \
1918c2ecf20Sopenharmony_ci					   _PAGE_EXT_USER_READ))
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci#define PAGE_COPY	PAGE_EXECREAD
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
1968c2ecf20Sopenharmony_ci				 _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \
1978c2ecf20Sopenharmony_ci				 _PAGE_EXT(_PAGE_EXT_KERN_READ | \
1988c2ecf20Sopenharmony_ci					   _PAGE_EXT_USER_READ))
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci#define PAGE_WRITEONLY	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
2018c2ecf20Sopenharmony_ci				 _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \
2028c2ecf20Sopenharmony_ci				 _PAGE_EXT(_PAGE_EXT_KERN_WRITE | \
2038c2ecf20Sopenharmony_ci					   _PAGE_EXT_USER_WRITE))
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci#define PAGE_RWX	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | \
2068c2ecf20Sopenharmony_ci				 _PAGE_CACHABLE | _PAGE_FLAGS_HARD | \
2078c2ecf20Sopenharmony_ci				 _PAGE_EXT(_PAGE_EXT_KERN_WRITE | \
2088c2ecf20Sopenharmony_ci					   _PAGE_EXT_KERN_READ  | \
2098c2ecf20Sopenharmony_ci					   _PAGE_EXT_KERN_EXEC  | \
2108c2ecf20Sopenharmony_ci					   _PAGE_EXT_USER_WRITE | \
2118c2ecf20Sopenharmony_ci					   _PAGE_EXT_USER_READ  | \
2128c2ecf20Sopenharmony_ci					   _PAGE_EXT_USER_EXEC))
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \
2158c2ecf20Sopenharmony_ci				 _PAGE_DIRTY | _PAGE_ACCESSED | \
2168c2ecf20Sopenharmony_ci				 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | \
2178c2ecf20Sopenharmony_ci				 _PAGE_EXT(_PAGE_EXT_KERN_READ | \
2188c2ecf20Sopenharmony_ci					   _PAGE_EXT_KERN_WRITE | \
2198c2ecf20Sopenharmony_ci					   _PAGE_EXT_KERN_EXEC))
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci#define PAGE_KERNEL_NOCACHE \
2228c2ecf20Sopenharmony_ci			__pgprot(_PAGE_PRESENT | _PAGE_DIRTY | \
2238c2ecf20Sopenharmony_ci				 _PAGE_ACCESSED | _PAGE_HW_SHARED | \
2248c2ecf20Sopenharmony_ci				 _PAGE_FLAGS_HARD | \
2258c2ecf20Sopenharmony_ci				 _PAGE_EXT(_PAGE_EXT_KERN_READ | \
2268c2ecf20Sopenharmony_ci					   _PAGE_EXT_KERN_WRITE | \
2278c2ecf20Sopenharmony_ci					   _PAGE_EXT_KERN_EXEC))
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci#define PAGE_KERNEL_RO	__pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \
2308c2ecf20Sopenharmony_ci				 _PAGE_DIRTY | _PAGE_ACCESSED | \
2318c2ecf20Sopenharmony_ci				 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD | \
2328c2ecf20Sopenharmony_ci				 _PAGE_EXT(_PAGE_EXT_KERN_READ | \
2338c2ecf20Sopenharmony_ci					   _PAGE_EXT_KERN_EXEC))
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci#define PAGE_KERNEL_PCC(slot, type) \
2368c2ecf20Sopenharmony_ci			__pgprot(0)
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci#elif defined(CONFIG_MMU) /* SH-X TLB */
2398c2ecf20Sopenharmony_ci#define PAGE_NONE	__pgprot(_PAGE_PROTNONE | _PAGE_CACHABLE | \
2408c2ecf20Sopenharmony_ci				 _PAGE_ACCESSED | _PAGE_FLAGS_HARD)
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | \
2438c2ecf20Sopenharmony_ci				 _PAGE_CACHABLE | _PAGE_ACCESSED | \
2448c2ecf20Sopenharmony_ci				 _PAGE_FLAGS_HARD)
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | \
2478c2ecf20Sopenharmony_ci				 _PAGE_ACCESSED | _PAGE_FLAGS_HARD)
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_CACHABLE | \
2508c2ecf20Sopenharmony_ci				 _PAGE_ACCESSED | _PAGE_FLAGS_HARD)
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci#define PAGE_EXECREAD	PAGE_READONLY
2538c2ecf20Sopenharmony_ci#define PAGE_RWX	PAGE_SHARED
2548c2ecf20Sopenharmony_ci#define PAGE_WRITEONLY	PAGE_SHARED
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_CACHABLE | \
2578c2ecf20Sopenharmony_ci				 _PAGE_DIRTY | _PAGE_ACCESSED | \
2588c2ecf20Sopenharmony_ci				 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD)
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci#define PAGE_KERNEL_NOCACHE \
2618c2ecf20Sopenharmony_ci			__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \
2628c2ecf20Sopenharmony_ci				 _PAGE_ACCESSED | _PAGE_HW_SHARED | \
2638c2ecf20Sopenharmony_ci				 _PAGE_FLAGS_HARD)
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci#define PAGE_KERNEL_RO	__pgprot(_PAGE_PRESENT | _PAGE_CACHABLE | \
2668c2ecf20Sopenharmony_ci				 _PAGE_DIRTY | _PAGE_ACCESSED | \
2678c2ecf20Sopenharmony_ci				 _PAGE_HW_SHARED | _PAGE_FLAGS_HARD)
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci#define PAGE_KERNEL_PCC(slot, type) \
2708c2ecf20Sopenharmony_ci			__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \
2718c2ecf20Sopenharmony_ci				 _PAGE_ACCESSED | _PAGE_FLAGS_HARD | \
2728c2ecf20Sopenharmony_ci				 (slot ? _PAGE_PCC_AREA5 : _PAGE_PCC_AREA6) | \
2738c2ecf20Sopenharmony_ci				 (type))
2748c2ecf20Sopenharmony_ci#else /* no mmu */
2758c2ecf20Sopenharmony_ci#define PAGE_NONE		__pgprot(0)
2768c2ecf20Sopenharmony_ci#define PAGE_SHARED		__pgprot(0)
2778c2ecf20Sopenharmony_ci#define PAGE_COPY		__pgprot(0)
2788c2ecf20Sopenharmony_ci#define PAGE_EXECREAD		__pgprot(0)
2798c2ecf20Sopenharmony_ci#define PAGE_RWX		__pgprot(0)
2808c2ecf20Sopenharmony_ci#define PAGE_READONLY		__pgprot(0)
2818c2ecf20Sopenharmony_ci#define PAGE_WRITEONLY		__pgprot(0)
2828c2ecf20Sopenharmony_ci#define PAGE_KERNEL		__pgprot(0)
2838c2ecf20Sopenharmony_ci#define PAGE_KERNEL_NOCACHE	__pgprot(0)
2848c2ecf20Sopenharmony_ci#define PAGE_KERNEL_RO		__pgprot(0)
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci#define PAGE_KERNEL_PCC(slot, type) \
2878c2ecf20Sopenharmony_ci				__pgprot(0)
2888c2ecf20Sopenharmony_ci#endif
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci/*
2958c2ecf20Sopenharmony_ci * Certain architectures need to do special things when PTEs
2968c2ecf20Sopenharmony_ci * within a page table are directly modified.  Thus, the following
2978c2ecf20Sopenharmony_ci * hook is made available.
2988c2ecf20Sopenharmony_ci */
2998c2ecf20Sopenharmony_ci#ifdef CONFIG_X2TLB
3008c2ecf20Sopenharmony_cistatic inline void set_pte(pte_t *ptep, pte_t pte)
3018c2ecf20Sopenharmony_ci{
3028c2ecf20Sopenharmony_ci	ptep->pte_high = pte.pte_high;
3038c2ecf20Sopenharmony_ci	smp_wmb();
3048c2ecf20Sopenharmony_ci	ptep->pte_low = pte.pte_low;
3058c2ecf20Sopenharmony_ci}
3068c2ecf20Sopenharmony_ci#else
3078c2ecf20Sopenharmony_ci#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
3088c2ecf20Sopenharmony_ci#endif
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci/*
3138c2ecf20Sopenharmony_ci * (pmds are folded into pgds so this doesn't get actually called,
3148c2ecf20Sopenharmony_ci * but the define is needed for a generic inline function.)
3158c2ecf20Sopenharmony_ci */
3168c2ecf20Sopenharmony_ci#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci#define pfn_pte(pfn, prot) \
3198c2ecf20Sopenharmony_ci	__pte(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
3208c2ecf20Sopenharmony_ci#define pfn_pmd(pfn, prot) \
3218c2ecf20Sopenharmony_ci	__pmd(((unsigned long long)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci#define pte_none(x)		(!pte_val(x))
3248c2ecf20Sopenharmony_ci#define pte_present(x)		((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci#define pte_clear(mm,addr,xp) do { set_pte_at(mm, addr, xp, __pte(0)); } while (0)
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci#define pmd_none(x)	(!pmd_val(x))
3298c2ecf20Sopenharmony_ci#define pmd_present(x)	(pmd_val(x))
3308c2ecf20Sopenharmony_ci#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
3318c2ecf20Sopenharmony_ci#define	pmd_bad(x)	(pmd_val(x) & ~PAGE_MASK)
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci#define pages_to_mb(x)	((x) >> (20-PAGE_SHIFT))
3348c2ecf20Sopenharmony_ci#define pte_page(x)	pfn_to_page(pte_pfn(x))
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci/*
3378c2ecf20Sopenharmony_ci * The following only work if pte_present() is true.
3388c2ecf20Sopenharmony_ci * Undefined behaviour if not..
3398c2ecf20Sopenharmony_ci */
3408c2ecf20Sopenharmony_ci#define pte_not_present(pte)	(!((pte).pte_low & _PAGE_PRESENT))
3418c2ecf20Sopenharmony_ci#define pte_dirty(pte)		((pte).pte_low & _PAGE_DIRTY)
3428c2ecf20Sopenharmony_ci#define pte_young(pte)		((pte).pte_low & _PAGE_ACCESSED)
3438c2ecf20Sopenharmony_ci#define pte_special(pte)	((pte).pte_low & _PAGE_SPECIAL)
3448c2ecf20Sopenharmony_ci
3458c2ecf20Sopenharmony_ci#ifdef CONFIG_X2TLB
3468c2ecf20Sopenharmony_ci#define pte_write(pte) \
3478c2ecf20Sopenharmony_ci	((pte).pte_high & (_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE))
3488c2ecf20Sopenharmony_ci#else
3498c2ecf20Sopenharmony_ci#define pte_write(pte)		((pte).pte_low & _PAGE_RW)
3508c2ecf20Sopenharmony_ci#endif
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci#define PTE_BIT_FUNC(h,fn,op) \
3538c2ecf20Sopenharmony_cistatic inline pte_t pte_##fn(pte_t pte) { pte.pte_##h op; return pte; }
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci#ifdef CONFIG_X2TLB
3568c2ecf20Sopenharmony_ci/*
3578c2ecf20Sopenharmony_ci * We cheat a bit in the SH-X2 TLB case. As the permission bits are
3588c2ecf20Sopenharmony_ci * individually toggled (and user permissions are entirely decoupled from
3598c2ecf20Sopenharmony_ci * kernel permissions), we attempt to couple them a bit more sanely here.
3608c2ecf20Sopenharmony_ci */
3618c2ecf20Sopenharmony_ciPTE_BIT_FUNC(high, wrprotect, &= ~(_PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE));
3628c2ecf20Sopenharmony_ciPTE_BIT_FUNC(high, mkwrite, |= _PAGE_EXT_USER_WRITE | _PAGE_EXT_KERN_WRITE);
3638c2ecf20Sopenharmony_ciPTE_BIT_FUNC(high, mkhuge, |= _PAGE_SZHUGE);
3648c2ecf20Sopenharmony_ci#else
3658c2ecf20Sopenharmony_ciPTE_BIT_FUNC(low, wrprotect, &= ~_PAGE_RW);
3668c2ecf20Sopenharmony_ciPTE_BIT_FUNC(low, mkwrite, |= _PAGE_RW);
3678c2ecf20Sopenharmony_ciPTE_BIT_FUNC(low, mkhuge, |= _PAGE_SZHUGE);
3688c2ecf20Sopenharmony_ci#endif
3698c2ecf20Sopenharmony_ci
3708c2ecf20Sopenharmony_ciPTE_BIT_FUNC(low, mkclean, &= ~_PAGE_DIRTY);
3718c2ecf20Sopenharmony_ciPTE_BIT_FUNC(low, mkdirty, |= _PAGE_DIRTY);
3728c2ecf20Sopenharmony_ciPTE_BIT_FUNC(low, mkold, &= ~_PAGE_ACCESSED);
3738c2ecf20Sopenharmony_ciPTE_BIT_FUNC(low, mkyoung, |= _PAGE_ACCESSED);
3748c2ecf20Sopenharmony_ciPTE_BIT_FUNC(low, mkspecial, |= _PAGE_SPECIAL);
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci/*
3778c2ecf20Sopenharmony_ci * Macro and implementation to make a page protection as uncachable.
3788c2ecf20Sopenharmony_ci */
3798c2ecf20Sopenharmony_ci#define pgprot_writecombine(prot) \
3808c2ecf20Sopenharmony_ci	__pgprot(pgprot_val(prot) & ~_PAGE_CACHABLE)
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci#define pgprot_noncached	 pgprot_writecombine
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci/*
3858c2ecf20Sopenharmony_ci * Conversion functions: convert a page and protection to a page entry,
3868c2ecf20Sopenharmony_ci * and a page entry and page directory to the page they refer to.
3878c2ecf20Sopenharmony_ci *
3888c2ecf20Sopenharmony_ci * extern pte_t mk_pte(struct page *page, pgprot_t pgprot)
3898c2ecf20Sopenharmony_ci */
3908c2ecf20Sopenharmony_ci#define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_cistatic inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
3938c2ecf20Sopenharmony_ci{
3948c2ecf20Sopenharmony_ci	pte.pte_low &= _PAGE_CHG_MASK;
3958c2ecf20Sopenharmony_ci	pte.pte_low |= pgprot_val(newprot);
3968c2ecf20Sopenharmony_ci
3978c2ecf20Sopenharmony_ci#ifdef CONFIG_X2TLB
3988c2ecf20Sopenharmony_ci	pte.pte_high |= pgprot_val(newprot) >> 32;
3998c2ecf20Sopenharmony_ci#endif
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_ci	return pte;
4028c2ecf20Sopenharmony_ci}
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_cistatic inline unsigned long pmd_page_vaddr(pmd_t pmd)
4058c2ecf20Sopenharmony_ci{
4068c2ecf20Sopenharmony_ci	return (unsigned long)pmd_val(pmd);
4078c2ecf20Sopenharmony_ci}
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci#define pmd_page(pmd)		(virt_to_page(pmd_val(pmd)))
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci#ifdef CONFIG_X2TLB
4128c2ecf20Sopenharmony_ci#define pte_ERROR(e) \
4138c2ecf20Sopenharmony_ci	printk("%s:%d: bad pte %p(%08lx%08lx).\n", __FILE__, __LINE__, \
4148c2ecf20Sopenharmony_ci	       &(e), (e).pte_high, (e).pte_low)
4158c2ecf20Sopenharmony_ci#define pgd_ERROR(e) \
4168c2ecf20Sopenharmony_ci	printk("%s:%d: bad pgd %016llx.\n", __FILE__, __LINE__, pgd_val(e))
4178c2ecf20Sopenharmony_ci#else
4188c2ecf20Sopenharmony_ci#define pte_ERROR(e) \
4198c2ecf20Sopenharmony_ci	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
4208c2ecf20Sopenharmony_ci#define pgd_ERROR(e) \
4218c2ecf20Sopenharmony_ci	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
4228c2ecf20Sopenharmony_ci#endif
4238c2ecf20Sopenharmony_ci
4248c2ecf20Sopenharmony_ci/*
4258c2ecf20Sopenharmony_ci * Encode and de-code a swap entry
4268c2ecf20Sopenharmony_ci *
4278c2ecf20Sopenharmony_ci * Constraints:
4288c2ecf20Sopenharmony_ci *	_PAGE_PRESENT at bit 8
4298c2ecf20Sopenharmony_ci *	_PAGE_PROTNONE at bit 9
4308c2ecf20Sopenharmony_ci *
4318c2ecf20Sopenharmony_ci * For the normal case, we encode the swap type into bits 0:7 and the
4328c2ecf20Sopenharmony_ci * swap offset into bits 10:30. For the 64-bit PTE case, we keep the
4338c2ecf20Sopenharmony_ci * preserved bits in the low 32-bits and use the upper 32 as the swap
4348c2ecf20Sopenharmony_ci * offset (along with a 5-bit type), following the same approach as x86
4358c2ecf20Sopenharmony_ci * PAE. This keeps the logic quite simple.
4368c2ecf20Sopenharmony_ci *
4378c2ecf20Sopenharmony_ci * As is evident by the Alpha code, if we ever get a 64-bit unsigned
4388c2ecf20Sopenharmony_ci * long (swp_entry_t) to match up with the 64-bit PTEs, this all becomes
4398c2ecf20Sopenharmony_ci * much cleaner..
4408c2ecf20Sopenharmony_ci *
4418c2ecf20Sopenharmony_ci * NOTE: We should set ZEROs at the position of _PAGE_PRESENT
4428c2ecf20Sopenharmony_ci *       and _PAGE_PROTNONE bits
4438c2ecf20Sopenharmony_ci */
4448c2ecf20Sopenharmony_ci#ifdef CONFIG_X2TLB
4458c2ecf20Sopenharmony_ci#define __swp_type(x)			((x).val & 0x1f)
4468c2ecf20Sopenharmony_ci#define __swp_offset(x)			((x).val >> 5)
4478c2ecf20Sopenharmony_ci#define __swp_entry(type, offset)	((swp_entry_t){ (type) | (offset) << 5})
4488c2ecf20Sopenharmony_ci#define __pte_to_swp_entry(pte)		((swp_entry_t){ (pte).pte_high })
4498c2ecf20Sopenharmony_ci#define __swp_entry_to_pte(x)		((pte_t){ 0, (x).val })
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_ci#else
4528c2ecf20Sopenharmony_ci#define __swp_type(x)			((x).val & 0xff)
4538c2ecf20Sopenharmony_ci#define __swp_offset(x)			((x).val >> 10)
4548c2ecf20Sopenharmony_ci#define __swp_entry(type, offset)	((swp_entry_t){(type) | (offset) <<10})
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci#define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) >> 1 })
4578c2ecf20Sopenharmony_ci#define __swp_entry_to_pte(x)		((pte_t) { (x).val << 1 })
4588c2ecf20Sopenharmony_ci#endif
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */
4618c2ecf20Sopenharmony_ci#endif /* __ASM_SH_PGTABLE_32_H */
462