1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_POWERPC_NOHASH_PTE_E500_H
3 #define _ASM_POWERPC_NOHASH_PTE_E500_H
4 #ifdef __KERNEL__
5 
6 /* PTE bit definitions for processors compliant to the Book3E
7  * architecture 2.06 or later. The position of the PTE bits
8  * matches the HW definition of the optional Embedded Page Table
9  * category.
10  */
11 
12 /* Architected bits */
13 #define _PAGE_PRESENT	0x000001 /* software: pte contains a translation */
14 #define _PAGE_SW1	0x000002
15 #define _PAGE_BAP_SR	0x000004
16 #define _PAGE_BAP_UR	0x000008
17 #define _PAGE_BAP_SW	0x000010
18 #define _PAGE_BAP_UW	0x000020
19 #define _PAGE_BAP_SX	0x000040
20 #define _PAGE_BAP_UX	0x000080
21 #define _PAGE_PSIZE_MSK	0x000f00
22 #define _PAGE_TSIZE_4K	0x000100
23 #define _PAGE_DIRTY	0x001000 /* C: page changed */
24 #define _PAGE_SW0	0x002000
25 #define _PAGE_U3	0x004000
26 #define _PAGE_U2	0x008000
27 #define _PAGE_U1	0x010000
28 #define _PAGE_U0	0x020000
29 #define _PAGE_ACCESSED	0x040000
30 #define _PAGE_ENDIAN	0x080000
31 #define _PAGE_GUARDED	0x100000
32 #define _PAGE_COHERENT	0x200000 /* M: enforce memory coherence */
33 #define _PAGE_NO_CACHE	0x400000 /* I: cache inhibit */
34 #define _PAGE_WRITETHRU	0x800000 /* W: cache write-through */
35 
36 #define _PAGE_PSIZE_SHIFT		7
37 #define _PAGE_PSIZE_SHIFT_OFFSET	10
38 
39 /* "Higher level" linux bit combinations */
40 #define _PAGE_EXEC		(_PAGE_BAP_SX | _PAGE_BAP_UX) /* .. and was cache cleaned */
41 #define _PAGE_READ		(_PAGE_BAP_SR | _PAGE_BAP_UR) /* User read permission */
42 #define _PAGE_WRITE		(_PAGE_BAP_SW | _PAGE_BAP_UW) /* User write permission */
43 
44 #define _PAGE_KERNEL_RW		(_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY)
45 #define _PAGE_KERNEL_RO		(_PAGE_BAP_SR)
46 #define _PAGE_KERNEL_RWX	(_PAGE_BAP_SW | _PAGE_BAP_SR | _PAGE_DIRTY | _PAGE_BAP_SX)
47 #define _PAGE_KERNEL_ROX	(_PAGE_BAP_SR | _PAGE_BAP_SX)
48 
49 #define _PAGE_NA	0
50 #define _PAGE_NAX	_PAGE_BAP_UX
51 #define _PAGE_RO	_PAGE_READ
52 #define _PAGE_ROX	(_PAGE_READ | _PAGE_BAP_UX)
53 #define _PAGE_RW	(_PAGE_READ | _PAGE_WRITE)
54 #define _PAGE_RWX	(_PAGE_READ | _PAGE_WRITE | _PAGE_BAP_UX)
55 
56 #define _PAGE_SPECIAL	_PAGE_SW0
57 
58 #define	PTE_RPN_SHIFT	(24)
59 
60 #define PTE_WIMGE_SHIFT (19)
61 #define PTE_BAP_SHIFT	(2)
62 
63 /* On 32-bit, we never clear the top part of the PTE */
64 #ifdef CONFIG_PPC32
65 #define _PTE_NONE_MASK	0xffffffff00000000ULL
66 #define _PMD_PRESENT	0
67 #define _PMD_PRESENT_MASK (PAGE_MASK)
68 #define _PMD_BAD	(~PAGE_MASK)
69 #define _PMD_USER	0
70 #else
71 #define _PTE_NONE_MASK	0
72 #endif
73 
74 /*
75  * We define 2 sets of base prot bits, one for basic pages (ie,
76  * cacheable kernel and user pages) and one for non cacheable
77  * pages. We always set _PAGE_COHERENT when SMP is enabled or
78  * the processor might need it for DMA coherency.
79  */
80 #define _PAGE_BASE_NC	(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_TSIZE_4K)
81 #if defined(CONFIG_SMP)
82 #define _PAGE_BASE	(_PAGE_BASE_NC | _PAGE_COHERENT)
83 #else
84 #define _PAGE_BASE	(_PAGE_BASE_NC)
85 #endif
86 
87 #include <asm/pgtable-masks.h>
88 
89 #ifndef __ASSEMBLY__
pte_mkexec(pte_t pte)90 static inline pte_t pte_mkexec(pte_t pte)
91 {
92 	return __pte((pte_val(pte) & ~_PAGE_BAP_SX) | _PAGE_BAP_UX);
93 }
94 #define pte_mkexec pte_mkexec
95 
pte_huge_size(pte_t pte)96 static inline unsigned long pte_huge_size(pte_t pte)
97 {
98 	pte_basic_t val = pte_val(pte);
99 
100 	return 1UL << (((val & _PAGE_PSIZE_MSK) >> _PAGE_PSIZE_SHIFT) + _PAGE_PSIZE_SHIFT_OFFSET);
101 }
102 #define pte_huge_size pte_huge_size
103 
pmd_leaf(pmd_t pmd)104 static inline int pmd_leaf(pmd_t pmd)
105 {
106 	if (IS_ENABLED(CONFIG_PPC64))
107 		return (long)pmd_val(pmd) > 0;
108 	else
109 		return pmd_val(pmd) & _PAGE_PSIZE_MSK;
110 }
111 #define pmd_leaf pmd_leaf
112 
pmd_leaf_size(pmd_t pmd)113 static inline unsigned long pmd_leaf_size(pmd_t pmd)
114 {
115 	return pte_huge_size(__pte(pmd_val(pmd)));
116 }
117 #define pmd_leaf_size pmd_leaf_size
118 
119 #ifdef CONFIG_PPC64
pud_leaf(pud_t pud)120 static inline int pud_leaf(pud_t pud)
121 {
122 	if (IS_ENABLED(CONFIG_PPC64))
123 		return (long)pud_val(pud) > 0;
124 	else
125 		return pud_val(pud) & _PAGE_PSIZE_MSK;
126 }
127 #define pud_leaf pud_leaf
128 
pud_leaf_size(pud_t pud)129 static inline unsigned long pud_leaf_size(pud_t pud)
130 {
131 	return pte_huge_size(__pte(pud_val(pud)));
132 }
133 #define pud_leaf_size pud_leaf_size
134 
135 #endif
136 
137 #endif /* __ASSEMBLY__ */
138 
139 #endif /* __KERNEL__ */
140 #endif /*  _ASM_POWERPC_NOHASH_PTE_E500_H */
141