18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
38c2ecf20Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
48c2ecf20Sopenharmony_ci * for more details.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 2003 Ralf Baechle
78c2ecf20Sopenharmony_ci * Copyright (C) 1999, 2000, 2001 Silicon Graphics, Inc.
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci#ifndef _ASM_PGTABLE_64_H
108c2ecf20Sopenharmony_ci#define _ASM_PGTABLE_64_H
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/compiler.h>
138c2ecf20Sopenharmony_ci#include <linux/linkage.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <asm/addrspace.h>
168c2ecf20Sopenharmony_ci#include <asm/page.h>
178c2ecf20Sopenharmony_ci#include <asm/cachectl.h>
188c2ecf20Sopenharmony_ci#include <asm/fixmap.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#if CONFIG_PGTABLE_LEVELS == 2
218c2ecf20Sopenharmony_ci#include <asm-generic/pgtable-nopmd.h>
228c2ecf20Sopenharmony_ci#elif CONFIG_PGTABLE_LEVELS == 3
238c2ecf20Sopenharmony_ci#include <asm-generic/pgtable-nopud.h>
248c2ecf20Sopenharmony_ci#else
258c2ecf20Sopenharmony_ci#include <asm-generic/pgtable-nop4d.h>
268c2ecf20Sopenharmony_ci#endif
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci/*
298c2ecf20Sopenharmony_ci * Each address space has 2 4K pages as its page directory, giving 1024
308c2ecf20Sopenharmony_ci * (== PTRS_PER_PGD) 8 byte pointers to pmd tables. Each pmd table is a
318c2ecf20Sopenharmony_ci * single 4K page, giving 512 (== PTRS_PER_PMD) 8 byte pointers to page
328c2ecf20Sopenharmony_ci * tables. Each page table is also a single 4K page, giving 512 (==
338c2ecf20Sopenharmony_ci * PTRS_PER_PTE) 8 byte ptes. Each pud entry is initialized to point to
348c2ecf20Sopenharmony_ci * invalid_pmd_table, each pmd entry is initialized to point to
358c2ecf20Sopenharmony_ci * invalid_pte_table, each pte is initialized to 0.
368c2ecf20Sopenharmony_ci *
378c2ecf20Sopenharmony_ci * Kernel mappings: kernel mappings are held in the swapper_pg_table.
388c2ecf20Sopenharmony_ci * The layout is identical to userspace except it's indexed with the
398c2ecf20Sopenharmony_ci * fault address - VMALLOC_START.
408c2ecf20Sopenharmony_ci */
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci/* PGDIR_SHIFT determines what a third-level page table entry can map */
448c2ecf20Sopenharmony_ci#ifdef __PAGETABLE_PMD_FOLDED
458c2ecf20Sopenharmony_ci#define PGDIR_SHIFT	(PAGE_SHIFT + PAGE_SHIFT + PTE_ORDER - 3)
468c2ecf20Sopenharmony_ci#else
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci/* PMD_SHIFT determines the size of the area a second-level page table can map */
498c2ecf20Sopenharmony_ci#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT + PTE_ORDER - 3))
508c2ecf20Sopenharmony_ci#define PMD_SIZE	(1UL << PMD_SHIFT)
518c2ecf20Sopenharmony_ci#define PMD_MASK	(~(PMD_SIZE-1))
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci# ifdef __PAGETABLE_PUD_FOLDED
548c2ecf20Sopenharmony_ci# define PGDIR_SHIFT	(PMD_SHIFT + (PAGE_SHIFT + PMD_ORDER - 3))
558c2ecf20Sopenharmony_ci# endif
568c2ecf20Sopenharmony_ci#endif
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci#ifndef __PAGETABLE_PUD_FOLDED
598c2ecf20Sopenharmony_ci#define PUD_SHIFT	(PMD_SHIFT + (PAGE_SHIFT + PMD_ORDER - 3))
608c2ecf20Sopenharmony_ci#define PUD_SIZE	(1UL << PUD_SHIFT)
618c2ecf20Sopenharmony_ci#define PUD_MASK	(~(PUD_SIZE-1))
628c2ecf20Sopenharmony_ci#define PGDIR_SHIFT	(PUD_SHIFT + (PAGE_SHIFT + PUD_ORDER - 3))
638c2ecf20Sopenharmony_ci#endif
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
668c2ecf20Sopenharmony_ci#define PGDIR_MASK	(~(PGDIR_SIZE-1))
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci/*
698c2ecf20Sopenharmony_ci * For 4kB page size we use a 3 level page tree and an 8kB pud, which
708c2ecf20Sopenharmony_ci * permits us mapping 40 bits of virtual address space.
718c2ecf20Sopenharmony_ci *
728c2ecf20Sopenharmony_ci * We used to implement 41 bits by having an order 1 pmd level but that seemed
738c2ecf20Sopenharmony_ci * rather pointless.
748c2ecf20Sopenharmony_ci *
758c2ecf20Sopenharmony_ci * For 8kB page size we use a 3 level page tree which permits a total of
768c2ecf20Sopenharmony_ci * 8TB of address space.  Alternatively a 33-bit / 8GB organization using
778c2ecf20Sopenharmony_ci * two levels would be easy to implement.
788c2ecf20Sopenharmony_ci *
798c2ecf20Sopenharmony_ci * For 16kB page size we use a 2 level page tree which permits a total of
808c2ecf20Sopenharmony_ci * 36 bits of virtual address space.  We could add a third level but it seems
818c2ecf20Sopenharmony_ci * like at the moment there's no need for this.
828c2ecf20Sopenharmony_ci *
838c2ecf20Sopenharmony_ci * For 64kB page size we use a 2 level page table tree for a total of 42 bits
848c2ecf20Sopenharmony_ci * of virtual address space.
858c2ecf20Sopenharmony_ci */
868c2ecf20Sopenharmony_ci#ifdef CONFIG_PAGE_SIZE_4KB
878c2ecf20Sopenharmony_ci# ifdef CONFIG_MIPS_VA_BITS_48
888c2ecf20Sopenharmony_ci#  define PGD_ORDER		0
898c2ecf20Sopenharmony_ci#  define PUD_ORDER		0
908c2ecf20Sopenharmony_ci# else
918c2ecf20Sopenharmony_ci#  define PGD_ORDER		1
928c2ecf20Sopenharmony_ci#  define PUD_ORDER		aieeee_attempt_to_allocate_pud
938c2ecf20Sopenharmony_ci# endif
948c2ecf20Sopenharmony_ci#define PMD_ORDER		0
958c2ecf20Sopenharmony_ci#define PTE_ORDER		0
968c2ecf20Sopenharmony_ci#endif
978c2ecf20Sopenharmony_ci#ifdef CONFIG_PAGE_SIZE_8KB
988c2ecf20Sopenharmony_ci#define PGD_ORDER		0
998c2ecf20Sopenharmony_ci#define PUD_ORDER		aieeee_attempt_to_allocate_pud
1008c2ecf20Sopenharmony_ci#define PMD_ORDER		0
1018c2ecf20Sopenharmony_ci#define PTE_ORDER		0
1028c2ecf20Sopenharmony_ci#endif
1038c2ecf20Sopenharmony_ci#ifdef CONFIG_PAGE_SIZE_16KB
1048c2ecf20Sopenharmony_ci#ifdef CONFIG_MIPS_VA_BITS_48
1058c2ecf20Sopenharmony_ci#define PGD_ORDER               1
1068c2ecf20Sopenharmony_ci#else
1078c2ecf20Sopenharmony_ci#define PGD_ORDER               0
1088c2ecf20Sopenharmony_ci#endif
1098c2ecf20Sopenharmony_ci#define PUD_ORDER		aieeee_attempt_to_allocate_pud
1108c2ecf20Sopenharmony_ci#define PMD_ORDER		0
1118c2ecf20Sopenharmony_ci#define PTE_ORDER		0
1128c2ecf20Sopenharmony_ci#endif
1138c2ecf20Sopenharmony_ci#ifdef CONFIG_PAGE_SIZE_32KB
1148c2ecf20Sopenharmony_ci#define PGD_ORDER		0
1158c2ecf20Sopenharmony_ci#define PUD_ORDER		aieeee_attempt_to_allocate_pud
1168c2ecf20Sopenharmony_ci#define PMD_ORDER		0
1178c2ecf20Sopenharmony_ci#define PTE_ORDER		0
1188c2ecf20Sopenharmony_ci#endif
1198c2ecf20Sopenharmony_ci#ifdef CONFIG_PAGE_SIZE_64KB
1208c2ecf20Sopenharmony_ci#define PGD_ORDER		0
1218c2ecf20Sopenharmony_ci#define PUD_ORDER		aieeee_attempt_to_allocate_pud
1228c2ecf20Sopenharmony_ci#ifdef CONFIG_MIPS_VA_BITS_48
1238c2ecf20Sopenharmony_ci#define PMD_ORDER		0
1248c2ecf20Sopenharmony_ci#else
1258c2ecf20Sopenharmony_ci#define PMD_ORDER		aieeee_attempt_to_allocate_pmd
1268c2ecf20Sopenharmony_ci#endif
1278c2ecf20Sopenharmony_ci#define PTE_ORDER		0
1288c2ecf20Sopenharmony_ci#endif
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci#define PTRS_PER_PGD	((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
1318c2ecf20Sopenharmony_ci#ifndef __PAGETABLE_PUD_FOLDED
1328c2ecf20Sopenharmony_ci#define PTRS_PER_PUD	((PAGE_SIZE << PUD_ORDER) / sizeof(pud_t))
1338c2ecf20Sopenharmony_ci#endif
1348c2ecf20Sopenharmony_ci#ifndef __PAGETABLE_PMD_FOLDED
1358c2ecf20Sopenharmony_ci#define PTRS_PER_PMD	((PAGE_SIZE << PMD_ORDER) / sizeof(pmd_t))
1368c2ecf20Sopenharmony_ci#endif
1378c2ecf20Sopenharmony_ci#define PTRS_PER_PTE	((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci#define USER_PTRS_PER_PGD       ((TASK_SIZE64 / PGDIR_SIZE)?(TASK_SIZE64 / PGDIR_SIZE):1)
1408c2ecf20Sopenharmony_ci#define FIRST_USER_ADDRESS	0UL
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci/*
1438c2ecf20Sopenharmony_ci * TLB refill handlers also map the vmalloc area into xuseg.  Avoid
1448c2ecf20Sopenharmony_ci * the first couple of pages so NULL pointer dereferences will still
1458c2ecf20Sopenharmony_ci * reliably trap.
1468c2ecf20Sopenharmony_ci */
1478c2ecf20Sopenharmony_ci#define VMALLOC_START		(MAP_BASE + (2 * PAGE_SIZE))
1488c2ecf20Sopenharmony_ci#define VMALLOC_END	\
1498c2ecf20Sopenharmony_ci	(MAP_BASE + \
1508c2ecf20Sopenharmony_ci	 min(PTRS_PER_PGD * PTRS_PER_PUD * PTRS_PER_PMD * PTRS_PER_PTE * PAGE_SIZE, \
1518c2ecf20Sopenharmony_ci	     (1UL << cpu_vmbits)) - (1UL << 32))
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ci#if defined(CONFIG_MODULES) && defined(KBUILD_64BIT_SYM32) && \
1548c2ecf20Sopenharmony_ci	VMALLOC_START != CKSSEG
1558c2ecf20Sopenharmony_ci/* Load modules into 32bit-compatible segment. */
1568c2ecf20Sopenharmony_ci#define MODULE_START	CKSSEG
1578c2ecf20Sopenharmony_ci#define MODULE_END	(FIXADDR_START-2*PAGE_SIZE)
1588c2ecf20Sopenharmony_ci#endif
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci#define pte_ERROR(e) \
1618c2ecf20Sopenharmony_ci	printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
1628c2ecf20Sopenharmony_ci#ifndef __PAGETABLE_PMD_FOLDED
1638c2ecf20Sopenharmony_ci#define pmd_ERROR(e) \
1648c2ecf20Sopenharmony_ci	printk("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
1658c2ecf20Sopenharmony_ci#endif
1668c2ecf20Sopenharmony_ci#ifndef __PAGETABLE_PUD_FOLDED
1678c2ecf20Sopenharmony_ci#define pud_ERROR(e) \
1688c2ecf20Sopenharmony_ci	printk("%s:%d: bad pud %016lx.\n", __FILE__, __LINE__, pud_val(e))
1698c2ecf20Sopenharmony_ci#endif
1708c2ecf20Sopenharmony_ci#define pgd_ERROR(e) \
1718c2ecf20Sopenharmony_ci	printk("%s:%d: bad pgd %016lx.\n", __FILE__, __LINE__, pgd_val(e))
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ciextern pte_t invalid_pte_table[PTRS_PER_PTE];
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci#ifndef __PAGETABLE_PUD_FOLDED
1768c2ecf20Sopenharmony_ci/*
1778c2ecf20Sopenharmony_ci * For 4-level pagetables we defines these ourselves, for 3-level the
1788c2ecf20Sopenharmony_ci * definitions are below, for 2-level the
1798c2ecf20Sopenharmony_ci * definitions are supplied by <asm-generic/pgtable-nopmd.h>.
1808c2ecf20Sopenharmony_ci */
1818c2ecf20Sopenharmony_citypedef struct { unsigned long pud; } pud_t;
1828c2ecf20Sopenharmony_ci#define pud_val(x)	((x).pud)
1838c2ecf20Sopenharmony_ci#define __pud(x)	((pud_t) { (x) })
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ciextern pud_t invalid_pud_table[PTRS_PER_PUD];
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci/*
1888c2ecf20Sopenharmony_ci * Empty pgd entries point to the invalid_pud_table.
1898c2ecf20Sopenharmony_ci */
1908c2ecf20Sopenharmony_cistatic inline int p4d_none(p4d_t p4d)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	return p4d_val(p4d) == (unsigned long)invalid_pud_table;
1938c2ecf20Sopenharmony_ci}
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistatic inline int p4d_bad(p4d_t p4d)
1968c2ecf20Sopenharmony_ci{
1978c2ecf20Sopenharmony_ci	if (unlikely(p4d_val(p4d) & ~PAGE_MASK))
1988c2ecf20Sopenharmony_ci		return 1;
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	return 0;
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_cistatic inline int p4d_present(p4d_t p4d)
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	return p4d_val(p4d) != (unsigned long)invalid_pud_table;
2068c2ecf20Sopenharmony_ci}
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_cistatic inline void p4d_clear(p4d_t *p4dp)
2098c2ecf20Sopenharmony_ci{
2108c2ecf20Sopenharmony_ci	p4d_val(*p4dp) = (unsigned long)invalid_pud_table;
2118c2ecf20Sopenharmony_ci}
2128c2ecf20Sopenharmony_ci
2138c2ecf20Sopenharmony_cistatic inline pud_t *p4d_pgtable(p4d_t p4d)
2148c2ecf20Sopenharmony_ci{
2158c2ecf20Sopenharmony_ci	return (pud_t *)p4d_val(p4d);
2168c2ecf20Sopenharmony_ci}
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci#define p4d_phys(p4d)		virt_to_phys((void *)p4d_val(p4d))
2198c2ecf20Sopenharmony_ci#define p4d_page(p4d)		(pfn_to_page(p4d_phys(p4d) >> PAGE_SHIFT))
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci#define p4d_index(address)	(((address) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_cistatic inline void set_p4d(p4d_t *p4d, p4d_t p4dval)
2248c2ecf20Sopenharmony_ci{
2258c2ecf20Sopenharmony_ci	*p4d = p4dval;
2268c2ecf20Sopenharmony_ci}
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci#endif
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci#ifndef __PAGETABLE_PMD_FOLDED
2318c2ecf20Sopenharmony_ci/*
2328c2ecf20Sopenharmony_ci * For 3-level pagetables we defines these ourselves, for 2-level the
2338c2ecf20Sopenharmony_ci * definitions are supplied by <asm-generic/pgtable-nopmd.h>.
2348c2ecf20Sopenharmony_ci */
2358c2ecf20Sopenharmony_citypedef struct { unsigned long pmd; } pmd_t;
2368c2ecf20Sopenharmony_ci#define pmd_val(x)	((x).pmd)
2378c2ecf20Sopenharmony_ci#define __pmd(x)	((pmd_t) { (x) } )
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ciextern pmd_t invalid_pmd_table[PTRS_PER_PMD];
2418c2ecf20Sopenharmony_ci#endif
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci/*
2448c2ecf20Sopenharmony_ci * Empty pgd/pmd entries point to the invalid_pte_table.
2458c2ecf20Sopenharmony_ci */
2468c2ecf20Sopenharmony_cistatic inline int pmd_none(pmd_t pmd)
2478c2ecf20Sopenharmony_ci{
2488c2ecf20Sopenharmony_ci	return pmd_val(pmd) == (unsigned long) invalid_pte_table;
2498c2ecf20Sopenharmony_ci}
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_cistatic inline int pmd_bad(pmd_t pmd)
2528c2ecf20Sopenharmony_ci{
2538c2ecf20Sopenharmony_ci#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
2548c2ecf20Sopenharmony_ci	/* pmd_huge(pmd) but inline */
2558c2ecf20Sopenharmony_ci	if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
2568c2ecf20Sopenharmony_ci		return 0;
2578c2ecf20Sopenharmony_ci#endif
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	if (unlikely(pmd_val(pmd) & ~PAGE_MASK))
2608c2ecf20Sopenharmony_ci		return 1;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	return 0;
2638c2ecf20Sopenharmony_ci}
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_cistatic inline int pmd_present(pmd_t pmd)
2668c2ecf20Sopenharmony_ci{
2678c2ecf20Sopenharmony_ci#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
2688c2ecf20Sopenharmony_ci	if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
2698c2ecf20Sopenharmony_ci		return pmd_val(pmd) & _PAGE_PRESENT;
2708c2ecf20Sopenharmony_ci#endif
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	return pmd_val(pmd) != (unsigned long) invalid_pte_table;
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_cistatic inline void pmd_clear(pmd_t *pmdp)
2768c2ecf20Sopenharmony_ci{
2778c2ecf20Sopenharmony_ci	pmd_val(*pmdp) = ((unsigned long) invalid_pte_table);
2788c2ecf20Sopenharmony_ci}
2798c2ecf20Sopenharmony_ci#ifndef __PAGETABLE_PMD_FOLDED
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci/*
2828c2ecf20Sopenharmony_ci * Empty pud entries point to the invalid_pmd_table.
2838c2ecf20Sopenharmony_ci */
2848c2ecf20Sopenharmony_cistatic inline int pud_none(pud_t pud)
2858c2ecf20Sopenharmony_ci{
2868c2ecf20Sopenharmony_ci	return pud_val(pud) == (unsigned long) invalid_pmd_table;
2878c2ecf20Sopenharmony_ci}
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_cistatic inline int pud_bad(pud_t pud)
2908c2ecf20Sopenharmony_ci{
2918c2ecf20Sopenharmony_ci	return pud_val(pud) & ~PAGE_MASK;
2928c2ecf20Sopenharmony_ci}
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_cistatic inline int pud_present(pud_t pud)
2958c2ecf20Sopenharmony_ci{
2968c2ecf20Sopenharmony_ci	return pud_val(pud) != (unsigned long) invalid_pmd_table;
2978c2ecf20Sopenharmony_ci}
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_cistatic inline void pud_clear(pud_t *pudp)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	pud_val(*pudp) = ((unsigned long) invalid_pmd_table);
3028c2ecf20Sopenharmony_ci}
3038c2ecf20Sopenharmony_ci#endif
3048c2ecf20Sopenharmony_ci
3058c2ecf20Sopenharmony_ci#define pte_page(x)		pfn_to_page(pte_pfn(x))
3068c2ecf20Sopenharmony_ci
3078c2ecf20Sopenharmony_ci#ifdef CONFIG_CPU_VR41XX
3088c2ecf20Sopenharmony_ci#define pte_pfn(x)		((unsigned long)((x).pte >> (PAGE_SHIFT + 2)))
3098c2ecf20Sopenharmony_ci#define pfn_pte(pfn, prot)	__pte(((pfn) << (PAGE_SHIFT + 2)) | pgprot_val(prot))
3108c2ecf20Sopenharmony_ci#else
3118c2ecf20Sopenharmony_ci#define pte_pfn(x)		((unsigned long)((x).pte >> _PFN_SHIFT))
3128c2ecf20Sopenharmony_ci#define pfn_pte(pfn, prot)	__pte(((pfn) << _PFN_SHIFT) | pgprot_val(prot))
3138c2ecf20Sopenharmony_ci#define pfn_pmd(pfn, prot)	__pmd(((pfn) << _PFN_SHIFT) | pgprot_val(prot))
3148c2ecf20Sopenharmony_ci#endif
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci#ifndef __PAGETABLE_PMD_FOLDED
3178c2ecf20Sopenharmony_cistatic inline pmd_t *pud_pgtable(pud_t pud)
3188c2ecf20Sopenharmony_ci{
3198c2ecf20Sopenharmony_ci	return (pmd_t *)pud_val(pud);
3208c2ecf20Sopenharmony_ci}
3218c2ecf20Sopenharmony_ci#define pud_phys(pud)		virt_to_phys((void *)pud_val(pud))
3228c2ecf20Sopenharmony_ci#define pud_page(pud)		(pfn_to_page(pud_phys(pud) >> PAGE_SHIFT))
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci#endif
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ci/*
3278c2ecf20Sopenharmony_ci * Initialize a new pgd / pmd table with invalid pointers.
3288c2ecf20Sopenharmony_ci */
3298c2ecf20Sopenharmony_ciextern void pgd_init(unsigned long page);
3308c2ecf20Sopenharmony_ciextern void pud_init(unsigned long page, unsigned long pagetable);
3318c2ecf20Sopenharmony_ciextern void pmd_init(unsigned long page, unsigned long pagetable);
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci/*
3348c2ecf20Sopenharmony_ci * Non-present pages:  high 40 bits are offset, next 8 bits type,
3358c2ecf20Sopenharmony_ci * low 16 bits zero.
3368c2ecf20Sopenharmony_ci */
3378c2ecf20Sopenharmony_cistatic inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
3388c2ecf20Sopenharmony_ci{ pte_t pte; pte_val(pte) = (type << 16) | (offset << 24); return pte; }
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci#define __swp_type(x)		(((x).val >> 16) & 0xff)
3418c2ecf20Sopenharmony_ci#define __swp_offset(x)		((x).val >> 24)
3428c2ecf20Sopenharmony_ci#define __swp_entry(type, offset) ((swp_entry_t) { pte_val(mk_swap_pte((type), (offset))) })
3438c2ecf20Sopenharmony_ci#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
3448c2ecf20Sopenharmony_ci#define __swp_entry_to_pte(x)	((pte_t) { (x).val })
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ci#endif /* _ASM_PGTABLE_64_H */
347