powerpc/mm/hash64: Add a variable to track the end of IO mapping
[linux-2.6-block.git] / arch / powerpc / include / asm / book3s / 64 / hash-4k.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
ab537dca
AK
2#ifndef _ASM_POWERPC_BOOK3S_64_HASH_4K_H
3#define _ASM_POWERPC_BOOK3S_64_HASH_4K_H
423e2f94 4
eea86aa4
ME
5#define H_PTE_INDEX_SIZE 9 // size: 8B << 9 = 4KB, maps: 2^9 x 4KB = 2MB
6#define H_PMD_INDEX_SIZE 7 // size: 8B << 7 = 1KB, maps: 2^7 x 2MB = 256MB
7#define H_PUD_INDEX_SIZE 9 // size: 8B << 9 = 4KB, maps: 2^9 x 256MB = 128GB
8#define H_PGD_INDEX_SIZE 9 // size: 8B << 9 = 4KB, maps: 2^9 x 128GB = 64TB
ab537dca 9
f384796c
AK
10/*
11 * Each context is 512TB. But on 4k we restrict our max TASK size to 64TB
12 * Hence also limit max EA bits to 64TB.
13 */
14#define MAX_EA_BITS_PER_CONTEXT 46
15
ab537dca 16#ifndef __ASSEMBLY__
dd1842a2
AK
17#define H_PTE_TABLE_SIZE (sizeof(pte_t) << H_PTE_INDEX_SIZE)
18#define H_PMD_TABLE_SIZE (sizeof(pmd_t) << H_PMD_INDEX_SIZE)
19#define H_PUD_TABLE_SIZE (sizeof(pud_t) << H_PUD_INDEX_SIZE)
20#define H_PGD_TABLE_SIZE (sizeof(pgd_t) << H_PGD_INDEX_SIZE)
ab537dca 21
273b4936
RP
22#define H_PAGE_F_GIX_SHIFT 53
23#define H_PAGE_F_SECOND _RPAGE_RPN44 /* HPTE is in 2ndary HPTEG */
24#define H_PAGE_F_GIX (_RPAGE_RPN43 | _RPAGE_RPN42 | _RPAGE_RPN41)
9d2edb18 25#define H_PAGE_BUSY _RPAGE_RSV1 /* software: PTE & hash are busy */
273b4936 26#define H_PAGE_HASHPTE _RPAGE_RSV2 /* software: PTE & hash are busy */
9d2edb18 27
c605782b 28/* PTE flags to conserve for HPTE identification */
945537df
AK
29#define _PAGE_HPTEFLAGS (H_PAGE_BUSY | H_PAGE_HASHPTE | \
30 H_PAGE_F_SECOND | H_PAGE_F_GIX)
31/*
32 * Not supported by 4k linux page size
33 */
34#define H_PAGE_4K_PFN 0x0
35#define H_PAGE_THP_HUGE 0x0
36#define H_PAGE_COMBO 0x0
1c7ec8a4
AK
37
38/* 8 bytes per each pte entry */
39#define H_PTE_FRAG_SIZE_SHIFT (H_PTE_INDEX_SIZE + 3)
40#define H_PTE_FRAG_NR (PAGE_SIZE >> H_PTE_FRAG_SIZE_SHIFT)
8a6c697b
AK
41#define H_PMD_FRAG_SIZE_SHIFT (H_PMD_INDEX_SIZE + 3)
42#define H_PMD_FRAG_NR (PAGE_SIZE >> H_PMD_FRAG_SIZE_SHIFT)
1a2f7789
AK
43
44/* memory key bits, only 8 keys supported */
45#define H_PTE_PKEY_BIT0 0
46#define H_PTE_PKEY_BIT1 0
47#define H_PTE_PKEY_BIT2 _RPAGE_RSV3
48#define H_PTE_PKEY_BIT3 _RPAGE_RSV4
49#define H_PTE_PKEY_BIT4 _RPAGE_RSV5
50
ab537dca 51/*
368ced78 52 * On all 4K setups, remap_4k_pfn() equates to remap_pfn_range()
ab537dca 53 */
ab537dca
AK
54#define remap_4k_pfn(vma, addr, pfn, prot) \
55 remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, (prot))
56
26a344ae 57#ifdef CONFIG_HUGETLB_PAGE
c0a6c719 58static inline int hash__hugepd_ok(hugepd_t hpd)
26a344ae 59{
20717e1f 60 unsigned long hpdval = hpd_val(hpd);
26a344ae 61 /*
6a119eae
AK
62 * if it is not a pte and have hugepd shift mask
63 * set, then it is a hugepd directory pointer
26a344ae 64 */
f1981b5b 65 if (!(hpdval & _PAGE_PTE) && (hpdval & _PAGE_PRESENT) &&
20717e1f 66 ((hpdval & HUGEPD_SHIFT_MASK) != 0))
6a119eae
AK
67 return true;
68 return false;
26a344ae 69}
26a344ae
AK
70#endif
71
59aa31fd
RP
72/*
73 * 4K PTE format is different from 64K PTE format. Saving the hash_slot is just
74 * a matter of returning the PTE bits that need to be modified. On 64K PTE,
75 * things are a little more involved and hence needs many more parameters to
76 * accomplish the same. However we want to abstract this out from the caller by
77 * keeping the prototype consistent across the two formats.
78 */
79static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
ff31e105
AK
80 unsigned int subpg_index, unsigned long hidx,
81 int offset)
59aa31fd
RP
82{
83 return (hidx << H_PAGE_F_GIX_SHIFT) &
84 (H_PAGE_F_SECOND | H_PAGE_F_GIX);
85}
86
ab624762
AK
87#ifdef CONFIG_TRANSPARENT_HUGEPAGE
88
89static inline char *get_hpte_slot_array(pmd_t *pmdp)
90{
91 BUG();
92 return NULL;
93}
94
95static inline unsigned int hpte_valid(unsigned char *hpte_slot_array, int index)
96{
97 BUG();
98 return 0;
99}
100
101static inline unsigned int hpte_hash_index(unsigned char *hpte_slot_array,
102 int index)
103{
104 BUG();
105 return 0;
106}
107
108static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array,
109 unsigned int index, unsigned int hidx)
110{
111 BUG();
112}
113
114static inline int hash__pmd_trans_huge(pmd_t pmd)
115{
116 return 0;
117}
118
119static inline int hash__pmd_same(pmd_t pmd_a, pmd_t pmd_b)
120{
121 BUG();
122 return 0;
123}
124
125static inline pmd_t hash__pmd_mkhuge(pmd_t pmd)
126{
127 BUG();
128 return pmd;
129}
130
131extern unsigned long hash__pmd_hugepage_update(struct mm_struct *mm,
132 unsigned long addr, pmd_t *pmdp,
133 unsigned long clr, unsigned long set);
134extern pmd_t hash__pmdp_collapse_flush(struct vm_area_struct *vma,
135 unsigned long address, pmd_t *pmdp);
136extern void hash__pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp,
137 pgtable_t pgtable);
138extern pgtable_t hash__pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp);
ab624762
AK
139extern pmd_t hash__pmdp_huge_get_and_clear(struct mm_struct *mm,
140 unsigned long addr, pmd_t *pmdp);
141extern int hash__has_transparent_hugepage(void);
142#endif
143
ab537dca
AK
144#endif /* !__ASSEMBLY__ */
145
146#endif /* _ASM_POWERPC_BOOK3S_64_HASH_4K_H */