1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (C) 2012 Regents of the University of California
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #ifndef _ASM_RISCV_PGTABLE_64_H
7*4882a593Smuzhiyun #define _ASM_RISCV_PGTABLE_64_H
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <linux/const.h>
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun #define PGDIR_SHIFT 30
12*4882a593Smuzhiyun /* Size of region mapped by a page global directory */
13*4882a593Smuzhiyun #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
14*4882a593Smuzhiyun #define PGDIR_MASK (~(PGDIR_SIZE - 1))
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define PMD_SHIFT 21
17*4882a593Smuzhiyun /* Size of region mapped by a page middle directory */
18*4882a593Smuzhiyun #define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
19*4882a593Smuzhiyun #define PMD_MASK (~(PMD_SIZE - 1))
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun /* Page Middle Directory entry */
22*4882a593Smuzhiyun typedef struct {
23*4882a593Smuzhiyun unsigned long pmd;
24*4882a593Smuzhiyun } pmd_t;
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #define pmd_val(x) ((x).pmd)
27*4882a593Smuzhiyun #define __pmd(x) ((pmd_t) { (x) })
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #define PTRS_PER_PMD (PAGE_SIZE / sizeof(pmd_t))
30*4882a593Smuzhiyun
pud_present(pud_t pud)31*4882a593Smuzhiyun static inline int pud_present(pud_t pud)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun return (pud_val(pud) & _PAGE_PRESENT);
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun
pud_none(pud_t pud)36*4882a593Smuzhiyun static inline int pud_none(pud_t pud)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun return (pud_val(pud) == 0);
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun
pud_bad(pud_t pud)41*4882a593Smuzhiyun static inline int pud_bad(pud_t pud)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun return !pud_present(pud);
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun #define pud_leaf pud_leaf
pud_leaf(pud_t pud)47*4882a593Smuzhiyun static inline int pud_leaf(pud_t pud)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun return pud_present(pud) &&
50*4882a593Smuzhiyun (pud_val(pud) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun
set_pud(pud_t * pudp,pud_t pud)53*4882a593Smuzhiyun static inline void set_pud(pud_t *pudp, pud_t pud)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun *pudp = pud;
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun
pud_clear(pud_t * pudp)58*4882a593Smuzhiyun static inline void pud_clear(pud_t *pudp)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun set_pud(pudp, __pud(0));
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun
pud_page_vaddr(pud_t pud)63*4882a593Smuzhiyun static inline unsigned long pud_page_vaddr(pud_t pud)
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun return (unsigned long)pfn_to_virt(pud_val(pud) >> _PAGE_PFN_SHIFT);
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
pud_page(pud_t pud)68*4882a593Smuzhiyun static inline struct page *pud_page(pud_t pud)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun return pfn_to_page(pud_val(pud) >> _PAGE_PFN_SHIFT);
71*4882a593Smuzhiyun }
72*4882a593Smuzhiyun
pfn_pmd(unsigned long pfn,pgprot_t prot)73*4882a593Smuzhiyun static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t prot)
74*4882a593Smuzhiyun {
75*4882a593Smuzhiyun return __pmd((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun
_pmd_pfn(pmd_t pmd)78*4882a593Smuzhiyun static inline unsigned long _pmd_pfn(pmd_t pmd)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun return pmd_val(pmd) >> _PAGE_PFN_SHIFT;
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun #define pmd_ERROR(e) \
84*4882a593Smuzhiyun pr_err("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun #endif /* _ASM_RISCV_PGTABLE_64_H */
87