1#ifndef _ASM_POWERPC_MMU_HASH64_H_
2#define _ASM_POWERPC_MMU_HASH64_H_
3
4
5
6
7
8
9
10
11
12
13
14
15#include <asm/asm-compat.h>
16#include <asm/page.h>
17
18
19
20
21
22#define STE_ESID_V 0x80
23#define STE_ESID_KS 0x20
24#define STE_ESID_KP 0x10
25#define STE_ESID_N 0x08
26
27#define STE_VSID_SHIFT 12
28
29
30#define STAB0_PAGE 0x6
31#define STAB0_OFFSET (STAB0_PAGE << 12)
32#define STAB0_PHYS_ADDR (STAB0_OFFSET + PHYSICAL_START)
33
34#ifndef __ASSEMBLY__
35extern char initial_stab[];
36#endif
37
38
39
40
41
42#define SLB_NUM_BOLTED 3
43#define SLB_CACHE_ENTRIES 8
44
45
46#define SLB_ESID_V ASM_CONST(0x0000000008000000)
47
48
49#define SLB_VSID_SHIFT 12
50#define SLB_VSID_SHIFT_1T 24
51#define SLB_VSID_SSIZE_SHIFT 62
52#define SLB_VSID_B ASM_CONST(0xc000000000000000)
53#define SLB_VSID_B_256M ASM_CONST(0x0000000000000000)
54#define SLB_VSID_B_1T ASM_CONST(0x4000000000000000)
55#define SLB_VSID_KS ASM_CONST(0x0000000000000800)
56#define SLB_VSID_KP ASM_CONST(0x0000000000000400)
57#define SLB_VSID_N ASM_CONST(0x0000000000000200)
58#define SLB_VSID_L ASM_CONST(0x0000000000000100)
59#define SLB_VSID_C ASM_CONST(0x0000000000000080)
60#define SLB_VSID_LP ASM_CONST(0x0000000000000030)
61#define SLB_VSID_LP_00 ASM_CONST(0x0000000000000000)
62#define SLB_VSID_LP_01 ASM_CONST(0x0000000000000010)
63#define SLB_VSID_LP_10 ASM_CONST(0x0000000000000020)
64#define SLB_VSID_LP_11 ASM_CONST(0x0000000000000030)
65#define SLB_VSID_LLP (SLB_VSID_L|SLB_VSID_LP)
66
67#define SLB_VSID_KERNEL (SLB_VSID_KP)
68#define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS|SLB_VSID_C)
69
70#define SLBIE_C (0x08000000)
71#define SLBIE_SSIZE_SHIFT 25
72
73
74
75
76
77#define HPTES_PER_GROUP 8
78
79#define HPTE_V_SSIZE_SHIFT 62
80#define HPTE_V_AVPN_SHIFT 7
81#define HPTE_V_AVPN ASM_CONST(0x3fffffffffffff80)
82#define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)
83#define HPTE_V_COMPARE(x,y) (!(((x) ^ (y)) & 0xffffffffffffff80UL))
84#define HPTE_V_BOLTED ASM_CONST(0x0000000000000010)
85#define HPTE_V_LOCK ASM_CONST(0x0000000000000008)
86#define HPTE_V_LARGE ASM_CONST(0x0000000000000004)
87#define HPTE_V_SECONDARY ASM_CONST(0x0000000000000002)
88#define HPTE_V_VALID ASM_CONST(0x0000000000000001)
89
90#define HPTE_R_PP0 ASM_CONST(0x8000000000000000)
91#define HPTE_R_TS ASM_CONST(0x4000000000000000)
92#define HPTE_R_RPN_SHIFT 12
93#define HPTE_R_RPN ASM_CONST(0x3ffffffffffff000)
94#define HPTE_R_FLAGS ASM_CONST(0x00000000000003ff)
95#define HPTE_R_PP ASM_CONST(0x0000000000000003)
96#define HPTE_R_N ASM_CONST(0x0000000000000004)
97#define HPTE_R_C ASM_CONST(0x0000000000000080)
98#define HPTE_R_R ASM_CONST(0x0000000000000100)
99
100#define HPTE_V_1TB_SEG ASM_CONST(0x4000000000000000)
101#define HPTE_V_VRMA_MASK ASM_CONST(0x4001ffffff000000)
102
103
104
105#define PP_RWXX 0
106#define PP_RWRX 1
107#define PP_RWRW 2
108#define PP_RXRX 3
109
110#ifndef __ASSEMBLY__
111
112struct hash_pte {
113 unsigned long v;
114 unsigned long r;
115};
116
117extern struct hash_pte *htab_address;
118extern unsigned long htab_size_bytes;
119extern unsigned long htab_hash_mask;
120
121
122
123
124
125
126
127
128
129
130struct mmu_psize_def
131{
132 unsigned int shift;
133 unsigned int penc;
134 unsigned int tlbiel;
135 unsigned long avpnm;
136 unsigned long sllp;
137};
138
139#endif
140
141
142
143
144
145
146
147
148
149
150
151
152
153#define MMU_PAGE_4K 0
154#define MMU_PAGE_64K 1
155#define MMU_PAGE_64K_AP 2
156#define MMU_PAGE_1M 3
157#define MMU_PAGE_16M 4
158#define MMU_PAGE_16G 5
159#define MMU_PAGE_COUNT 6
160
161
162
163
164
165
166
167#define MMU_SEGSIZE_256M 0
168#define MMU_SEGSIZE_1T 1
169
170
171#ifndef __ASSEMBLY__
172
173
174
175
176extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT];
177extern int mmu_linear_psize;
178extern int mmu_virtual_psize;
179extern int mmu_vmalloc_psize;
180extern int mmu_vmemmap_psize;
181extern int mmu_io_psize;
182extern int mmu_kernel_ssize;
183extern int mmu_highuser_ssize;
184extern u16 mmu_slb_size;
185extern unsigned long tce_alloc_start, tce_alloc_end;
186
187
188
189
190
191
192
193extern int mmu_ci_restrictions;
194
195#ifdef CONFIG_HUGETLB_PAGE
196
197
198
199extern unsigned int mmu_huge_psizes[MMU_PAGE_COUNT];
200
201#endif
202
203
204
205
206
207static inline unsigned long hpte_encode_v(unsigned long va, int psize,
208 int ssize)
209{
210 unsigned long v;
211 v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm);
212 v <<= HPTE_V_AVPN_SHIFT;
213 if (psize != MMU_PAGE_4K)
214 v |= HPTE_V_LARGE;
215 v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
216 return v;
217}
218
219
220
221
222
223
224static inline unsigned long hpte_encode_r(unsigned long pa, int psize)
225{
226 unsigned long r;
227
228
229 if (psize == MMU_PAGE_4K)
230 return pa & HPTE_R_RPN;
231 else {
232 unsigned int penc = mmu_psize_defs[psize].penc;
233 unsigned int shift = mmu_psize_defs[psize].shift;
234 return (pa & ~((1ul << shift) - 1)) | (penc << 12);
235 }
236 return r;
237}
238
239
240
241
242static inline unsigned long hpt_va(unsigned long ea, unsigned long vsid,
243 int ssize)
244{
245 if (ssize == MMU_SEGSIZE_256M)
246 return (vsid << 28) | (ea & 0xfffffffUL);
247 return (vsid << 40) | (ea & 0xffffffffffUL);
248}
249
250
251
252
253
254static inline unsigned long hpt_hash(unsigned long va, unsigned int shift,
255 int ssize)
256{
257 unsigned long hash, vsid;
258
259 if (ssize == MMU_SEGSIZE_256M) {
260 hash = (va >> 28) ^ ((va & 0x0fffffffUL) >> shift);
261 } else {
262 vsid = va >> 40;
263 hash = vsid ^ (vsid << 25) ^ ((va & 0xffffffffffUL) >> shift);
264 }
265 return hash & 0x7fffffffffUL;
266}
267
268extern int __hash_page_4K(unsigned long ea, unsigned long access,
269 unsigned long vsid, pte_t *ptep, unsigned long trap,
270 unsigned int local, int ssize, int subpage_prot);
271extern int __hash_page_64K(unsigned long ea, unsigned long access,
272 unsigned long vsid, pte_t *ptep, unsigned long trap,
273 unsigned int local, int ssize);
274struct mm_struct;
275extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap);
276extern int hash_huge_page(struct mm_struct *mm, unsigned long access,
277 unsigned long ea, unsigned long vsid, int local,
278 unsigned long trap);
279
280extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
281 unsigned long pstart, unsigned long prot,
282 int psize, int ssize);
283extern void add_gpage(unsigned long addr, unsigned long page_size,
284 unsigned long number_of_pages);
285extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr);
286
287extern void htab_initialize(void);
288extern void htab_initialize_secondary(void);
289extern void hpte_init_native(void);
290extern void hpte_init_lpar(void);
291extern void hpte_init_iSeries(void);
292extern void hpte_init_beat(void);
293extern void hpte_init_beat_v3(void);
294
295extern void stabs_alloc(void);
296extern void slb_initialize(void);
297extern void slb_flush_and_rebolt(void);
298extern void stab_initialize(unsigned long stab);
299
300extern void slb_vmalloc_update(void);
301#endif
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354#define VSID_MULTIPLIER_256M ASM_CONST(200730139)
355#define VSID_BITS_256M 36
356#define VSID_MODULUS_256M ((1UL<<VSID_BITS_256M)-1)
357
358#define VSID_MULTIPLIER_1T ASM_CONST(12538073)
359#define VSID_BITS_1T 24
360#define VSID_MODULUS_1T ((1UL<<VSID_BITS_1T)-1)
361
362#define CONTEXT_BITS 19
363#define USER_ESID_BITS 16
364#define USER_ESID_BITS_1T 4
365
366#define USER_VSID_RANGE (1UL << (USER_ESID_BITS + SID_SHIFT))
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382#define ASM_VSID_SCRAMBLE(rt, rx, size) \
383 lis rx,VSID_MULTIPLIER_##size@h; \
384 ori rx,rx,VSID_MULTIPLIER_##size@l; \
385 mulld rt,rt,rx; \
386 \
387 srdi rx,rt,VSID_BITS_##size; \
388 clrldi rt,rt,(64-VSID_BITS_##size); \
389 add rt,rt,rx; \
390
391
392
393
394
395\
396 addi rx,rt,1; \
397 srdi rx,rx,VSID_BITS_##size; \
398 add rt,rt,rx
399
400
401#ifndef __ASSEMBLY__
402
403typedef unsigned long mm_context_id_t;
404
405typedef struct {
406 mm_context_id_t id;
407 u16 user_psize;
408
409#ifdef CONFIG_PPC_MM_SLICES
410 u64 low_slices_psize;
411 u64 high_slices_psize;
412#else
413 u16 sllp;
414#endif
415 unsigned long vdso_base;
416} mm_context_t;
417
418
419#if 0
420
421
422
423
424
425
426#define vsid_scrample(protovsid, size) \
427 ((((protovsid) * VSID_MULTIPLIER_##size) % VSID_MODULUS_##size))
428
429#else
430#define vsid_scramble(protovsid, size) \
431 ({ \
432 unsigned long x; \
433 x = (protovsid) * VSID_MULTIPLIER_##size; \
434 x = (x >> VSID_BITS_##size) + (x & VSID_MODULUS_##size); \
435 (x + ((x+1) >> VSID_BITS_##size)) & VSID_MODULUS_##size; \
436 })
437#endif
438
439
440static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize)
441{
442 if (ssize == MMU_SEGSIZE_256M)
443 return vsid_scramble(ea >> SID_SHIFT, 256M);
444 return vsid_scramble(ea >> SID_SHIFT_1T, 1T);
445}
446
447
448static inline int user_segment_size(unsigned long addr)
449{
450
451 if (addr >= (1UL << SID_SHIFT_1T))
452 return mmu_highuser_ssize;
453 return MMU_SEGSIZE_256M;
454}
455
456
457static inline unsigned long get_vsid(unsigned long context, unsigned long ea,
458 int ssize)
459{
460 if (ssize == MMU_SEGSIZE_256M)
461 return vsid_scramble((context << USER_ESID_BITS)
462 | (ea >> SID_SHIFT), 256M);
463 return vsid_scramble((context << USER_ESID_BITS_1T)
464 | (ea >> SID_SHIFT_1T), 1T);
465}
466
467
468
469
470
471#define VSID_SCRAMBLE(pvsid) (((pvsid) * VSID_MULTIPLIER_256M) % \
472 VSID_MODULUS_256M)
473#define KERNEL_VSID(ea) VSID_SCRAMBLE(GET_ESID(ea))
474
475#endif
476
477#endif
478