18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright 2003 PathScale Inc
48c2ecf20Sopenharmony_ci * Derived from include/asm-i386/pgtable.h
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#ifndef __UM_PGTABLE_3LEVEL_H
88c2ecf20Sopenharmony_ci#define __UM_PGTABLE_3LEVEL_H
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <asm-generic/pgtable-nopud.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/* PGDIR_SHIFT determines what a third-level page table entry can map */
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT
158c2ecf20Sopenharmony_ci#define PGDIR_SHIFT	30
168c2ecf20Sopenharmony_ci#else
178c2ecf20Sopenharmony_ci#define PGDIR_SHIFT	31
188c2ecf20Sopenharmony_ci#endif
198c2ecf20Sopenharmony_ci#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
208c2ecf20Sopenharmony_ci#define PGDIR_MASK	(~(PGDIR_SIZE-1))
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci/* PMD_SHIFT determines the size of the area a second-level page table can
238c2ecf20Sopenharmony_ci * map
248c2ecf20Sopenharmony_ci */
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci#define PMD_SHIFT	21
278c2ecf20Sopenharmony_ci#define PMD_SIZE	(1UL << PMD_SHIFT)
288c2ecf20Sopenharmony_ci#define PMD_MASK	(~(PMD_SIZE-1))
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/*
318c2ecf20Sopenharmony_ci * entries per page directory level
328c2ecf20Sopenharmony_ci */
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define PTRS_PER_PTE 512
358c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT
368c2ecf20Sopenharmony_ci#define PTRS_PER_PMD 512
378c2ecf20Sopenharmony_ci#define PTRS_PER_PGD 512
388c2ecf20Sopenharmony_ci#else
398c2ecf20Sopenharmony_ci#define PTRS_PER_PMD 1024
408c2ecf20Sopenharmony_ci#define PTRS_PER_PGD 1024
418c2ecf20Sopenharmony_ci#endif
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci#define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE)
448c2ecf20Sopenharmony_ci#define FIRST_USER_ADDRESS	0UL
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#define pte_ERROR(e) \
478c2ecf20Sopenharmony_ci        printk("%s:%d: bad pte %p(%016lx).\n", __FILE__, __LINE__, &(e), \
488c2ecf20Sopenharmony_ci	       pte_val(e))
498c2ecf20Sopenharmony_ci#define pmd_ERROR(e) \
508c2ecf20Sopenharmony_ci        printk("%s:%d: bad pmd %p(%016lx).\n", __FILE__, __LINE__, &(e), \
518c2ecf20Sopenharmony_ci	       pmd_val(e))
528c2ecf20Sopenharmony_ci#define pgd_ERROR(e) \
538c2ecf20Sopenharmony_ci        printk("%s:%d: bad pgd %p(%016lx).\n", __FILE__, __LINE__, &(e), \
548c2ecf20Sopenharmony_ci	       pgd_val(e))
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci#define pud_none(x)	(!(pud_val(x) & ~_PAGE_NEWPAGE))
578c2ecf20Sopenharmony_ci#define	pud_bad(x)	((pud_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
588c2ecf20Sopenharmony_ci#define pud_present(x)	(pud_val(x) & _PAGE_PRESENT)
598c2ecf20Sopenharmony_ci#define pud_populate(mm, pud, pmd) \
608c2ecf20Sopenharmony_ci	set_pud(pud, __pud(_PAGE_TABLE + __pa(pmd)))
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT
638c2ecf20Sopenharmony_ci#define set_pud(pudptr, pudval) set_64bit((u64 *) (pudptr), pud_val(pudval))
648c2ecf20Sopenharmony_ci#else
658c2ecf20Sopenharmony_ci#define set_pud(pudptr, pudval) (*(pudptr) = (pudval))
668c2ecf20Sopenharmony_ci#endif
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistatic inline int pgd_newpage(pgd_t pgd)
698c2ecf20Sopenharmony_ci{
708c2ecf20Sopenharmony_ci	return(pgd_val(pgd) & _PAGE_NEWPAGE);
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cistatic inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEWPAGE; }
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci#ifdef CONFIG_64BIT
768c2ecf20Sopenharmony_ci#define set_pmd(pmdptr, pmdval) set_64bit((u64 *) (pmdptr), pmd_val(pmdval))
778c2ecf20Sopenharmony_ci#else
788c2ecf20Sopenharmony_ci#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
798c2ecf20Sopenharmony_ci#endif
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cistatic inline void pud_clear (pud_t *pud)
828c2ecf20Sopenharmony_ci{
838c2ecf20Sopenharmony_ci	set_pud(pud, __pud(_PAGE_NEWPAGE));
848c2ecf20Sopenharmony_ci}
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci#define pud_page(pud) phys_to_page(pud_val(pud) & PAGE_MASK)
878c2ecf20Sopenharmony_ci#define pud_pgtable(pud) ((pmd_t *) __va(pud_val(pud) & PAGE_MASK))
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistatic inline unsigned long pte_pfn(pte_t pte)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	return phys_to_pfn(pte_val(pte));
928c2ecf20Sopenharmony_ci}
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistatic inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
958c2ecf20Sopenharmony_ci{
968c2ecf20Sopenharmony_ci	pte_t pte;
978c2ecf20Sopenharmony_ci	phys_t phys = pfn_to_phys(page_nr);
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	pte_set_val(pte, phys, pgprot);
1008c2ecf20Sopenharmony_ci	return pte;
1018c2ecf20Sopenharmony_ci}
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_cistatic inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
1048c2ecf20Sopenharmony_ci{
1058c2ecf20Sopenharmony_ci	return __pmd((page_nr << PAGE_SHIFT) | pgprot_val(pgprot));
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci#endif
1098c2ecf20Sopenharmony_ci
110