150acfb2bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
207037db5SPalmer Dabbelt /*
307037db5SPalmer Dabbelt * Copyright (C) 2012 Regents of the University of California
407037db5SPalmer Dabbelt */
507037db5SPalmer Dabbelt
607037db5SPalmer Dabbelt #ifndef _ASM_RISCV_PGTABLE_64_H
707037db5SPalmer Dabbelt #define _ASM_RISCV_PGTABLE_64_H
807037db5SPalmer Dabbelt
9100631b4SHeiko Stuebner #include <linux/bits.h>
1007037db5SPalmer Dabbelt #include <linux/const.h>
11ff689fd2SHeiko Stuebner #include <asm/errata_list.h>
1207037db5SPalmer Dabbelt
13e8a62cc2SAlexandre Ghiti extern bool pgtable_l4_enabled;
14d10efa21SQinglin Pan extern bool pgtable_l5_enabled;
15e8a62cc2SAlexandre Ghiti
16e8a62cc2SAlexandre Ghiti #define PGDIR_SHIFT_L3 30
17e8a62cc2SAlexandre Ghiti #define PGDIR_SHIFT_L4 39
18d10efa21SQinglin Pan #define PGDIR_SHIFT_L5 48
19e8a62cc2SAlexandre Ghiti #define PGDIR_SIZE_L3 (_AC(1, UL) << PGDIR_SHIFT_L3)
20e8a62cc2SAlexandre Ghiti
21d10efa21SQinglin Pan #define PGDIR_SHIFT (pgtable_l5_enabled ? PGDIR_SHIFT_L5 : \
22d10efa21SQinglin Pan (pgtable_l4_enabled ? PGDIR_SHIFT_L4 : PGDIR_SHIFT_L3))
2307037db5SPalmer Dabbelt /* Size of region mapped by a page global directory */
2407037db5SPalmer Dabbelt #define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
2507037db5SPalmer Dabbelt #define PGDIR_MASK (~(PGDIR_SIZE - 1))
2607037db5SPalmer Dabbelt
27d10efa21SQinglin Pan /* p4d is folded into pgd in case of 4-level page table */
2871fc3621SAlexandre Ghiti #define P4D_SHIFT_L3 30
2971fc3621SAlexandre Ghiti #define P4D_SHIFT_L4 39
3071fc3621SAlexandre Ghiti #define P4D_SHIFT_L5 39
3171fc3621SAlexandre Ghiti #define P4D_SHIFT (pgtable_l5_enabled ? P4D_SHIFT_L5 : \
3271fc3621SAlexandre Ghiti (pgtable_l4_enabled ? P4D_SHIFT_L4 : P4D_SHIFT_L3))
33d10efa21SQinglin Pan #define P4D_SIZE (_AC(1, UL) << P4D_SHIFT)
34d10efa21SQinglin Pan #define P4D_MASK (~(P4D_SIZE - 1))
35d10efa21SQinglin Pan
36e8a62cc2SAlexandre Ghiti /* pud is folded into pgd in case of 3-level page table */
37e8a62cc2SAlexandre Ghiti #define PUD_SHIFT 30
38e8a62cc2SAlexandre Ghiti #define PUD_SIZE (_AC(1, UL) << PUD_SHIFT)
39e8a62cc2SAlexandre Ghiti #define PUD_MASK (~(PUD_SIZE - 1))
40e8a62cc2SAlexandre Ghiti
4107037db5SPalmer Dabbelt #define PMD_SHIFT 21
4207037db5SPalmer Dabbelt /* Size of region mapped by a page middle directory */
4307037db5SPalmer Dabbelt #define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
4407037db5SPalmer Dabbelt #define PMD_MASK (~(PMD_SIZE - 1))
4507037db5SPalmer Dabbelt
46d10efa21SQinglin Pan /* Page 4th Directory entry */
47d10efa21SQinglin Pan typedef struct {
48d10efa21SQinglin Pan unsigned long p4d;
49d10efa21SQinglin Pan } p4d_t;
50d10efa21SQinglin Pan
51d10efa21SQinglin Pan #define p4d_val(x) ((x).p4d)
52d10efa21SQinglin Pan #define __p4d(x) ((p4d_t) { (x) })
53d10efa21SQinglin Pan #define PTRS_PER_P4D (PAGE_SIZE / sizeof(p4d_t))
54d10efa21SQinglin Pan
55e8a62cc2SAlexandre Ghiti /* Page Upper Directory entry */
56e8a62cc2SAlexandre Ghiti typedef struct {
57e8a62cc2SAlexandre Ghiti unsigned long pud;
58e8a62cc2SAlexandre Ghiti } pud_t;
59e8a62cc2SAlexandre Ghiti
60e8a62cc2SAlexandre Ghiti #define pud_val(x) ((x).pud)
61e8a62cc2SAlexandre Ghiti #define __pud(x) ((pud_t) { (x) })
62e8a62cc2SAlexandre Ghiti #define PTRS_PER_PUD (PAGE_SIZE / sizeof(pud_t))
63e8a62cc2SAlexandre Ghiti
6407037db5SPalmer Dabbelt /* Page Middle Directory entry */
6507037db5SPalmer Dabbelt typedef struct {
6607037db5SPalmer Dabbelt unsigned long pmd;
6707037db5SPalmer Dabbelt } pmd_t;
6807037db5SPalmer Dabbelt
6907037db5SPalmer Dabbelt #define pmd_val(x) ((x).pmd)
7007037db5SPalmer Dabbelt #define __pmd(x) ((pmd_t) { (x) })
7107037db5SPalmer Dabbelt
7207037db5SPalmer Dabbelt #define PTRS_PER_PMD (PAGE_SIZE / sizeof(pmd_t))
7307037db5SPalmer Dabbelt
74100631b4SHeiko Stuebner /*
75100631b4SHeiko Stuebner * rv64 PTE format:
76100631b4SHeiko Stuebner * | 63 | 62 61 | 60 54 | 53 10 | 9 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
77100631b4SHeiko Stuebner * N MT RSV PFN reserved for SW D A G U X W R V
78100631b4SHeiko Stuebner */
79100631b4SHeiko Stuebner #define _PAGE_PFN_MASK GENMASK(53, 10)
80100631b4SHeiko Stuebner
81ff689fd2SHeiko Stuebner /*
8223ad288aSQinglin Pan * [63] Svnapot definitions:
8323ad288aSQinglin Pan * 0 Svnapot disabled
8423ad288aSQinglin Pan * 1 Svnapot enabled
8523ad288aSQinglin Pan */
8623ad288aSQinglin Pan #define _PAGE_NAPOT_SHIFT 63
8723ad288aSQinglin Pan #define _PAGE_NAPOT BIT(_PAGE_NAPOT_SHIFT)
8823ad288aSQinglin Pan /*
8923ad288aSQinglin Pan * Only 64KB (order 4) napot ptes supported.
9023ad288aSQinglin Pan */
9123ad288aSQinglin Pan #define NAPOT_CONT_ORDER_BASE 4
9223ad288aSQinglin Pan enum napot_cont_order {
9323ad288aSQinglin Pan NAPOT_CONT64KB_ORDER = NAPOT_CONT_ORDER_BASE,
9423ad288aSQinglin Pan NAPOT_ORDER_MAX,
9523ad288aSQinglin Pan };
9623ad288aSQinglin Pan
9723ad288aSQinglin Pan #define for_each_napot_order(order) \
9823ad288aSQinglin Pan for (order = NAPOT_CONT_ORDER_BASE; order < NAPOT_ORDER_MAX; order++)
9923ad288aSQinglin Pan #define for_each_napot_order_rev(order) \
10023ad288aSQinglin Pan for (order = NAPOT_ORDER_MAX - 1; \
10123ad288aSQinglin Pan order >= NAPOT_CONT_ORDER_BASE; order--)
10223ad288aSQinglin Pan #define napot_cont_order(val) (__builtin_ctzl((val.pte >> _PAGE_PFN_SHIFT) << 1))
10323ad288aSQinglin Pan
10423ad288aSQinglin Pan #define napot_cont_shift(order) ((order) + PAGE_SHIFT)
10523ad288aSQinglin Pan #define napot_cont_size(order) BIT(napot_cont_shift(order))
10623ad288aSQinglin Pan #define napot_cont_mask(order) (~(napot_cont_size(order) - 1UL))
10723ad288aSQinglin Pan #define napot_pte_num(order) BIT(order)
10823ad288aSQinglin Pan
10923ad288aSQinglin Pan #ifdef CONFIG_RISCV_ISA_SVNAPOT
11023ad288aSQinglin Pan #define HUGE_MAX_HSTATE (2 + (NAPOT_ORDER_MAX - NAPOT_CONT_ORDER_BASE))
11123ad288aSQinglin Pan #else
11223ad288aSQinglin Pan #define HUGE_MAX_HSTATE 2
11323ad288aSQinglin Pan #endif
11423ad288aSQinglin Pan
11523ad288aSQinglin Pan /*
116ff689fd2SHeiko Stuebner * [62:61] Svpbmt Memory Type definitions:
117ff689fd2SHeiko Stuebner *
118ff689fd2SHeiko Stuebner * 00 - PMA Normal Cacheable, No change to implied PMA memory type
119ff689fd2SHeiko Stuebner * 01 - NC Non-cacheable, idempotent, weakly-ordered Main Memory
120ff689fd2SHeiko Stuebner * 10 - IO Non-cacheable, non-idempotent, strongly-ordered I/O memory
121ff689fd2SHeiko Stuebner * 11 - Rsvd Reserved for future standard use
122ff689fd2SHeiko Stuebner */
123ff689fd2SHeiko Stuebner #define _PAGE_NOCACHE_SVPBMT (1UL << 61)
124ff689fd2SHeiko Stuebner #define _PAGE_IO_SVPBMT (1UL << 62)
125ff689fd2SHeiko Stuebner #define _PAGE_MTMASK_SVPBMT (_PAGE_NOCACHE_SVPBMT | _PAGE_IO_SVPBMT)
126ff689fd2SHeiko Stuebner
127a35707c3SHeiko Stuebner /*
128a35707c3SHeiko Stuebner * [63:59] T-Head Memory Type definitions:
129a35707c3SHeiko Stuebner *
130a35707c3SHeiko Stuebner * 00000 - NC Weakly-ordered, Non-cacheable, Non-bufferable, Non-shareable, Non-trustable
131a35707c3SHeiko Stuebner * 01110 - PMA Weakly-ordered, Cacheable, Bufferable, Shareable, Non-trustable
132a35707c3SHeiko Stuebner * 10000 - IO Strongly-ordered, Non-cacheable, Non-bufferable, Non-shareable, Non-trustable
133a35707c3SHeiko Stuebner */
134a35707c3SHeiko Stuebner #define _PAGE_PMA_THEAD ((1UL << 62) | (1UL << 61) | (1UL << 60))
135a35707c3SHeiko Stuebner #define _PAGE_NOCACHE_THEAD 0UL
136a35707c3SHeiko Stuebner #define _PAGE_IO_THEAD (1UL << 63)
137a35707c3SHeiko Stuebner #define _PAGE_MTMASK_THEAD (_PAGE_PMA_THEAD | _PAGE_IO_THEAD | (1UL << 59))
138a35707c3SHeiko Stuebner
riscv_page_mtmask(void)139ff689fd2SHeiko Stuebner static inline u64 riscv_page_mtmask(void)
140ff689fd2SHeiko Stuebner {
141ff689fd2SHeiko Stuebner u64 val;
142ff689fd2SHeiko Stuebner
143ff689fd2SHeiko Stuebner ALT_SVPBMT(val, _PAGE_MTMASK);
144ff689fd2SHeiko Stuebner return val;
145ff689fd2SHeiko Stuebner }
146ff689fd2SHeiko Stuebner
riscv_page_nocache(void)147ff689fd2SHeiko Stuebner static inline u64 riscv_page_nocache(void)
148ff689fd2SHeiko Stuebner {
149ff689fd2SHeiko Stuebner u64 val;
150ff689fd2SHeiko Stuebner
151ff689fd2SHeiko Stuebner ALT_SVPBMT(val, _PAGE_NOCACHE);
152ff689fd2SHeiko Stuebner return val;
153ff689fd2SHeiko Stuebner }
154ff689fd2SHeiko Stuebner
riscv_page_io(void)155ff689fd2SHeiko Stuebner static inline u64 riscv_page_io(void)
156ff689fd2SHeiko Stuebner {
157ff689fd2SHeiko Stuebner u64 val;
158ff689fd2SHeiko Stuebner
159ff689fd2SHeiko Stuebner ALT_SVPBMT(val, _PAGE_IO);
160ff689fd2SHeiko Stuebner return val;
161ff689fd2SHeiko Stuebner }
162ff689fd2SHeiko Stuebner
163ff689fd2SHeiko Stuebner #define _PAGE_NOCACHE riscv_page_nocache()
164ff689fd2SHeiko Stuebner #define _PAGE_IO riscv_page_io()
165ff689fd2SHeiko Stuebner #define _PAGE_MTMASK riscv_page_mtmask()
166ff689fd2SHeiko Stuebner
167ff689fd2SHeiko Stuebner /* Set of bits to preserve across pte_modify() */
168ff689fd2SHeiko Stuebner #define _PAGE_CHG_MASK (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ | \
169ff689fd2SHeiko Stuebner _PAGE_WRITE | _PAGE_EXEC | \
170ff689fd2SHeiko Stuebner _PAGE_USER | _PAGE_GLOBAL | \
171ff689fd2SHeiko Stuebner _PAGE_MTMASK))
172ff689fd2SHeiko Stuebner
pud_present(pud_t pud)17307037db5SPalmer Dabbelt static inline int pud_present(pud_t pud)
17407037db5SPalmer Dabbelt {
17507037db5SPalmer Dabbelt return (pud_val(pud) & _PAGE_PRESENT);
17607037db5SPalmer Dabbelt }
17707037db5SPalmer Dabbelt
pud_none(pud_t pud)17807037db5SPalmer Dabbelt static inline int pud_none(pud_t pud)
17907037db5SPalmer Dabbelt {
18007037db5SPalmer Dabbelt return (pud_val(pud) == 0);
18107037db5SPalmer Dabbelt }
18207037db5SPalmer Dabbelt
pud_bad(pud_t pud)18307037db5SPalmer Dabbelt static inline int pud_bad(pud_t pud)
18407037db5SPalmer Dabbelt {
18507037db5SPalmer Dabbelt return !pud_present(pud);
18607037db5SPalmer Dabbelt }
18707037db5SPalmer Dabbelt
188af6513eaSSteven Price #define pud_leaf pud_leaf
pud_leaf(pud_t pud)189af6513eaSSteven Price static inline int pud_leaf(pud_t pud)
190af6513eaSSteven Price {
191f5397c3eSNanyong Sun return pud_present(pud) && (pud_val(pud) & _PAGE_LEAF);
192af6513eaSSteven Price }
193af6513eaSSteven Price
pud_user(pud_t pud)1942c8a81dcSTong Tiangen static inline int pud_user(pud_t pud)
1952c8a81dcSTong Tiangen {
1962c8a81dcSTong Tiangen return pud_val(pud) & _PAGE_USER;
1972c8a81dcSTong Tiangen }
1982c8a81dcSTong Tiangen
set_pud(pud_t * pudp,pud_t pud)19907037db5SPalmer Dabbelt static inline void set_pud(pud_t *pudp, pud_t pud)
20007037db5SPalmer Dabbelt {
201193b1fc1SAlexandre Ghiti WRITE_ONCE(*pudp, pud);
20207037db5SPalmer Dabbelt }
20307037db5SPalmer Dabbelt
pud_clear(pud_t * pudp)20407037db5SPalmer Dabbelt static inline void pud_clear(pud_t *pudp)
20507037db5SPalmer Dabbelt {
20607037db5SPalmer Dabbelt set_pud(pudp, __pud(0));
20707037db5SPalmer Dabbelt }
20807037db5SPalmer Dabbelt
pfn_pud(unsigned long pfn,pgprot_t prot)209e8a62cc2SAlexandre Ghiti static inline pud_t pfn_pud(unsigned long pfn, pgprot_t prot)
210e8a62cc2SAlexandre Ghiti {
211e8a62cc2SAlexandre Ghiti return __pud((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
212e8a62cc2SAlexandre Ghiti }
213e8a62cc2SAlexandre Ghiti
_pud_pfn(pud_t pud)214e8a62cc2SAlexandre Ghiti static inline unsigned long _pud_pfn(pud_t pud)
215e8a62cc2SAlexandre Ghiti {
21688573389SAlexandre Ghiti return __page_val_to_pfn(pud_val(pud));
217e8a62cc2SAlexandre Ghiti }
218e8a62cc2SAlexandre Ghiti
pud_pgtable(pud_t pud)2199cf6fa24SAneesh Kumar K.V static inline pmd_t *pud_pgtable(pud_t pud)
22007037db5SPalmer Dabbelt {
221100631b4SHeiko Stuebner return (pmd_t *)pfn_to_virt(__page_val_to_pfn(pud_val(pud)));
22207037db5SPalmer Dabbelt }
22307037db5SPalmer Dabbelt
pud_page(pud_t pud)2248ad8b727SNick Hu static inline struct page *pud_page(pud_t pud)
2258ad8b727SNick Hu {
226100631b4SHeiko Stuebner return pfn_to_page(__page_val_to_pfn(pud_val(pud)));
2278ad8b727SNick Hu }
2288ad8b727SNick Hu
229d10efa21SQinglin Pan #define mm_p4d_folded mm_p4d_folded
mm_p4d_folded(struct mm_struct * mm)230d10efa21SQinglin Pan static inline bool mm_p4d_folded(struct mm_struct *mm)
231d10efa21SQinglin Pan {
232d10efa21SQinglin Pan if (pgtable_l5_enabled)
233d10efa21SQinglin Pan return false;
234d10efa21SQinglin Pan
235d10efa21SQinglin Pan return true;
236d10efa21SQinglin Pan }
237d10efa21SQinglin Pan
238e8a62cc2SAlexandre Ghiti #define mm_pud_folded mm_pud_folded
mm_pud_folded(struct mm_struct * mm)239e8a62cc2SAlexandre Ghiti static inline bool mm_pud_folded(struct mm_struct *mm)
240e8a62cc2SAlexandre Ghiti {
241e8a62cc2SAlexandre Ghiti if (pgtable_l4_enabled)
242e8a62cc2SAlexandre Ghiti return false;
243e8a62cc2SAlexandre Ghiti
244e8a62cc2SAlexandre Ghiti return true;
245e8a62cc2SAlexandre Ghiti }
246e8a62cc2SAlexandre Ghiti
247e8a62cc2SAlexandre Ghiti #define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
248e8a62cc2SAlexandre Ghiti
pfn_pmd(unsigned long pfn,pgprot_t prot)24907037db5SPalmer Dabbelt static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t prot)
25007037db5SPalmer Dabbelt {
251a35707c3SHeiko Stuebner unsigned long prot_val = pgprot_val(prot);
252a35707c3SHeiko Stuebner
253a35707c3SHeiko Stuebner ALT_THEAD_PMA(prot_val);
254a35707c3SHeiko Stuebner
255a35707c3SHeiko Stuebner return __pmd((pfn << _PAGE_PFN_SHIFT) | prot_val);
25607037db5SPalmer Dabbelt }
25707037db5SPalmer Dabbelt
_pmd_pfn(pmd_t pmd)258671f9a3eSAnup Patel static inline unsigned long _pmd_pfn(pmd_t pmd)
259671f9a3eSAnup Patel {
260100631b4SHeiko Stuebner return __page_val_to_pfn(pmd_val(pmd));
261671f9a3eSAnup Patel }
262671f9a3eSAnup Patel
2639eb4fcffSNanyong Sun #define mk_pmd(page, prot) pfn_pmd(page_to_pfn(page), prot)
2649eb4fcffSNanyong Sun
26507037db5SPalmer Dabbelt #define pmd_ERROR(e) \
26607037db5SPalmer Dabbelt pr_err("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
26707037db5SPalmer Dabbelt
268e8a62cc2SAlexandre Ghiti #define pud_ERROR(e) \
269e8a62cc2SAlexandre Ghiti pr_err("%s:%d: bad pud %016lx.\n", __FILE__, __LINE__, pud_val(e))
270e8a62cc2SAlexandre Ghiti
271d10efa21SQinglin Pan #define p4d_ERROR(e) \
272d10efa21SQinglin Pan pr_err("%s:%d: bad p4d %016lx.\n", __FILE__, __LINE__, p4d_val(e))
273d10efa21SQinglin Pan
set_p4d(p4d_t * p4dp,p4d_t p4d)274e8a62cc2SAlexandre Ghiti static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
275e8a62cc2SAlexandre Ghiti {
276e8a62cc2SAlexandre Ghiti if (pgtable_l4_enabled)
277193b1fc1SAlexandre Ghiti WRITE_ONCE(*p4dp, p4d);
278e8a62cc2SAlexandre Ghiti else
279e8a62cc2SAlexandre Ghiti set_pud((pud_t *)p4dp, (pud_t){ p4d_val(p4d) });
280e8a62cc2SAlexandre Ghiti }
281e8a62cc2SAlexandre Ghiti
p4d_none(p4d_t p4d)282e8a62cc2SAlexandre Ghiti static inline int p4d_none(p4d_t p4d)
283e8a62cc2SAlexandre Ghiti {
284e8a62cc2SAlexandre Ghiti if (pgtable_l4_enabled)
285e8a62cc2SAlexandre Ghiti return (p4d_val(p4d) == 0);
286e8a62cc2SAlexandre Ghiti
287e8a62cc2SAlexandre Ghiti return 0;
288e8a62cc2SAlexandre Ghiti }
289e8a62cc2SAlexandre Ghiti
p4d_present(p4d_t p4d)290e8a62cc2SAlexandre Ghiti static inline int p4d_present(p4d_t p4d)
291e8a62cc2SAlexandre Ghiti {
292e8a62cc2SAlexandre Ghiti if (pgtable_l4_enabled)
293e8a62cc2SAlexandre Ghiti return (p4d_val(p4d) & _PAGE_PRESENT);
294e8a62cc2SAlexandre Ghiti
295e8a62cc2SAlexandre Ghiti return 1;
296e8a62cc2SAlexandre Ghiti }
297e8a62cc2SAlexandre Ghiti
p4d_bad(p4d_t p4d)298e8a62cc2SAlexandre Ghiti static inline int p4d_bad(p4d_t p4d)
299e8a62cc2SAlexandre Ghiti {
300e8a62cc2SAlexandre Ghiti if (pgtable_l4_enabled)
301e8a62cc2SAlexandre Ghiti return !p4d_present(p4d);
302e8a62cc2SAlexandre Ghiti
303e8a62cc2SAlexandre Ghiti return 0;
304e8a62cc2SAlexandre Ghiti }
305e8a62cc2SAlexandre Ghiti
p4d_clear(p4d_t * p4d)306e8a62cc2SAlexandre Ghiti static inline void p4d_clear(p4d_t *p4d)
307e8a62cc2SAlexandre Ghiti {
308e8a62cc2SAlexandre Ghiti if (pgtable_l4_enabled)
309e8a62cc2SAlexandre Ghiti set_p4d(p4d, __p4d(0));
310e8a62cc2SAlexandre Ghiti }
311e8a62cc2SAlexandre Ghiti
pfn_p4d(unsigned long pfn,pgprot_t prot)312d10efa21SQinglin Pan static inline p4d_t pfn_p4d(unsigned long pfn, pgprot_t prot)
313d10efa21SQinglin Pan {
314d10efa21SQinglin Pan return __p4d((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
315d10efa21SQinglin Pan }
316d10efa21SQinglin Pan
_p4d_pfn(p4d_t p4d)317d10efa21SQinglin Pan static inline unsigned long _p4d_pfn(p4d_t p4d)
318d10efa21SQinglin Pan {
31988573389SAlexandre Ghiti return __page_val_to_pfn(p4d_val(p4d));
320d10efa21SQinglin Pan }
321d10efa21SQinglin Pan
p4d_pgtable(p4d_t p4d)322e8a62cc2SAlexandre Ghiti static inline pud_t *p4d_pgtable(p4d_t p4d)
323e8a62cc2SAlexandre Ghiti {
324e8a62cc2SAlexandre Ghiti if (pgtable_l4_enabled)
32588573389SAlexandre Ghiti return (pud_t *)pfn_to_virt(__page_val_to_pfn(p4d_val(p4d)));
326e8a62cc2SAlexandre Ghiti
327e8a62cc2SAlexandre Ghiti return (pud_t *)pud_pgtable((pud_t) { p4d_val(p4d) });
328e8a62cc2SAlexandre Ghiti }
329d10efa21SQinglin Pan #define p4d_page_vaddr(p4d) ((unsigned long)p4d_pgtable(p4d))
330e8a62cc2SAlexandre Ghiti
p4d_page(p4d_t p4d)331e8a62cc2SAlexandre Ghiti static inline struct page *p4d_page(p4d_t p4d)
332e8a62cc2SAlexandre Ghiti {
33388573389SAlexandre Ghiti return pfn_to_page(__page_val_to_pfn(p4d_val(p4d)));
334e8a62cc2SAlexandre Ghiti }
335e8a62cc2SAlexandre Ghiti
336e8a62cc2SAlexandre Ghiti #define pud_index(addr) (((addr) >> PUD_SHIFT) & (PTRS_PER_PUD - 1))
337e8a62cc2SAlexandre Ghiti
338e8a62cc2SAlexandre Ghiti #define pud_offset pud_offset
339*e0316069SAlexandre Ghiti pud_t *pud_offset(p4d_t *p4d, unsigned long address);
340e8a62cc2SAlexandre Ghiti
set_pgd(pgd_t * pgdp,pgd_t pgd)341d10efa21SQinglin Pan static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)
342d10efa21SQinglin Pan {
343d10efa21SQinglin Pan if (pgtable_l5_enabled)
344193b1fc1SAlexandre Ghiti WRITE_ONCE(*pgdp, pgd);
345d10efa21SQinglin Pan else
346d10efa21SQinglin Pan set_p4d((p4d_t *)pgdp, (p4d_t){ pgd_val(pgd) });
347d10efa21SQinglin Pan }
348d10efa21SQinglin Pan
pgd_none(pgd_t pgd)349d10efa21SQinglin Pan static inline int pgd_none(pgd_t pgd)
350d10efa21SQinglin Pan {
351d10efa21SQinglin Pan if (pgtable_l5_enabled)
352d10efa21SQinglin Pan return (pgd_val(pgd) == 0);
353d10efa21SQinglin Pan
354d10efa21SQinglin Pan return 0;
355d10efa21SQinglin Pan }
356d10efa21SQinglin Pan
pgd_present(pgd_t pgd)357d10efa21SQinglin Pan static inline int pgd_present(pgd_t pgd)
358d10efa21SQinglin Pan {
359d10efa21SQinglin Pan if (pgtable_l5_enabled)
360d10efa21SQinglin Pan return (pgd_val(pgd) & _PAGE_PRESENT);
361d10efa21SQinglin Pan
362d10efa21SQinglin Pan return 1;
363d10efa21SQinglin Pan }
364d10efa21SQinglin Pan
pgd_bad(pgd_t pgd)365d10efa21SQinglin Pan static inline int pgd_bad(pgd_t pgd)
366d10efa21SQinglin Pan {
367d10efa21SQinglin Pan if (pgtable_l5_enabled)
368d10efa21SQinglin Pan return !pgd_present(pgd);
369d10efa21SQinglin Pan
370d10efa21SQinglin Pan return 0;
371d10efa21SQinglin Pan }
372d10efa21SQinglin Pan
pgd_clear(pgd_t * pgd)373d10efa21SQinglin Pan static inline void pgd_clear(pgd_t *pgd)
374d10efa21SQinglin Pan {
375d10efa21SQinglin Pan if (pgtable_l5_enabled)
376d10efa21SQinglin Pan set_pgd(pgd, __pgd(0));
377d10efa21SQinglin Pan }
378d10efa21SQinglin Pan
pgd_pgtable(pgd_t pgd)379d10efa21SQinglin Pan static inline p4d_t *pgd_pgtable(pgd_t pgd)
380d10efa21SQinglin Pan {
381d10efa21SQinglin Pan if (pgtable_l5_enabled)
38288573389SAlexandre Ghiti return (p4d_t *)pfn_to_virt(__page_val_to_pfn(pgd_val(pgd)));
383d10efa21SQinglin Pan
384d10efa21SQinglin Pan return (p4d_t *)p4d_pgtable((p4d_t) { pgd_val(pgd) });
385d10efa21SQinglin Pan }
386d10efa21SQinglin Pan #define pgd_page_vaddr(pgd) ((unsigned long)pgd_pgtable(pgd))
387d10efa21SQinglin Pan
pgd_page(pgd_t pgd)388d10efa21SQinglin Pan static inline struct page *pgd_page(pgd_t pgd)
389d10efa21SQinglin Pan {
39088573389SAlexandre Ghiti return pfn_to_page(__page_val_to_pfn(pgd_val(pgd)));
391d10efa21SQinglin Pan }
392d10efa21SQinglin Pan #define pgd_page(pgd) pgd_page(pgd)
393d10efa21SQinglin Pan
394d10efa21SQinglin Pan #define p4d_index(addr) (((addr) >> P4D_SHIFT) & (PTRS_PER_P4D - 1))
395d10efa21SQinglin Pan
396d10efa21SQinglin Pan #define p4d_offset p4d_offset
397*e0316069SAlexandre Ghiti p4d_t *p4d_offset(pgd_t *pgd, unsigned long address);
398d10efa21SQinglin Pan
39907037db5SPalmer Dabbelt #endif /* _ASM_RISCV_PGTABLE_64_H */
400