1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <asm/reg.h>
18 #include <asm/page.h>
19 #include <asm/pgtable.h>
20 #include <asm/cputable.h>
21 #include <asm/ppc_asm.h>
22 #include <asm/thread_info.h>
23 #include <asm/asm-offsets.h>
24 #include <asm/export.h>
25 #include <asm/feature-fixups.h>
26 #include <asm/code-patching-asm.h>
27
28 #ifdef CONFIG_SMP
29 .section .bss
30 .align 2
31 mmu_hash_lock:
32 .space 4
33 #endif
34
35
36
37
38
39
40
41
42
43
44
45
46
47 .text
48 _GLOBAL(hash_page)
49 #ifdef CONFIG_SMP
50 lis r8, (mmu_hash_lock - PAGE_OFFSET)@h
51 ori r8, r8, (mmu_hash_lock - PAGE_OFFSET)@l
52 lis r0,0x0fff
53 b 10f
54 11: lwz r6,0(r8)
55 cmpwi 0,r6,0
56 bne 11b
57 10: lwarx r6,0,r8
58 cmpwi 0,r6,0
59 bne- 11b
60 stwcx. r0,0,r8
61 bne- 10b
62 isync
63 #endif
64
65 lis r0,KERNELBASE@h
66 cmplw 0,r4,r0
67 ori r3,r3,_PAGE_USER|_PAGE_PRESENT
68 mfspr r5, SPRN_SPRG_PGDIR
69 blt+ 112f
70 lis r5, (swapper_pg_dir - PAGE_OFFSET)@ha
71 addi r5 ,r5 ,(swapper_pg_dir - PAGE_OFFSET)@l
72 rlwimi r3,r9,32-12,29,29
73 112:
74 #ifndef CONFIG_PTE_64BIT
75 rlwimi r5,r4,12,20,29
76 lwz r8,0(r5)
77 rlwinm. r8,r8,0,0,19
78 #else
79 rlwinm r8,r4,13,19,29
80 lwzx r8,r8,r5
81 rlwinm. r8,r8,0,0,20
82 #endif
83 #ifdef CONFIG_SMP
84 beq- hash_page_out
85 #else
86
87
88
89
90 beqlr-
91 #endif
92 #ifndef CONFIG_PTE_64BIT
93 rlwimi r8,r4,22,20,29
94 #else
95 rlwimi r8,r4,23,20,28
96 #endif
97 rlwinm r0,r3,32-3,24,24
98 ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE
99
100
101
102
103
104
105
106
107
108
109 #if (PTE_FLAGS_OFFSET != 0)
110 addi r8,r8,PTE_FLAGS_OFFSET
111 #endif
112 retry:
113 lwarx r6,0,r8
114 andc. r5,r3,r6
115 #ifdef CONFIG_SMP
116 bne- hash_page_out
117 #else
118 bnelr-
119 #endif
120 or r5,r0,r6
121 #ifdef CONFIG_PTE_64BIT
122 #ifdef CONFIG_SMP
123 subf r10,r6,r8
124 subi r10,r10,PTE_FLAGS_OFFSET
125 lwzx r10,r6,r10
126 #else
127 lwz r10,-PTE_FLAGS_OFFSET(r8)
128 #endif
129 #endif
130 stwcx. r5,0,r8
131 bne- retry
132
133 mfsrin r3,r4
134 mfctr r0
135 stw r0,_CTR(r11)
136 bl create_hpte
137
138 #ifdef CONFIG_SMP
139 eieio
140 lis r8, (mmu_hash_lock - PAGE_OFFSET)@ha
141 li r0,0
142 stw r0, (mmu_hash_lock - PAGE_OFFSET)@l(r8)
143 #endif
144
145
146 lwz r5,_CTR(r11)
147 mtctr r5
148 lwz r0,GPR0(r11)
149 lwz r8,GPR8(r11)
150 b fast_exception_return
151
152 #ifdef CONFIG_SMP
153 hash_page_out:
154 eieio
155 lis r8, (mmu_hash_lock - PAGE_OFFSET)@ha
156 li r0,0
157 stw r0, (mmu_hash_lock - PAGE_OFFSET)@l(r8)
158 blr
159 #endif
160
161
162
163
164
165
166
167
168
169
170 _GLOBAL(add_hash_page)
171 mflr r0
172 stw r0,4(r1)
173
174
175 mulli r3,r3,897*16
176 rlwinm r0,r4,4,28,31
177 mulli r0,r0,0x111
178 add r3,r3,r0
179
180 #ifdef CONFIG_SMP
181 lwz r8,TASK_CPU(r2)
182 oris r8,r8,12
183 #endif
184
185
186
187
188
189
190
191
192
193
194 mfmsr r9
195 SYNC
196 rlwinm r0,r9,0,17,15
197 rlwinm r0,r0,0,28,26
198 mtmsr r0
199 SYNC_601
200 isync
201
202 #ifdef CONFIG_SMP
203 lis r6, (mmu_hash_lock - PAGE_OFFSET)@ha
204 addi r6, r6, (mmu_hash_lock - PAGE_OFFSET)@l
205 10: lwarx r0,0,r6
206 cmpi 0,r0,0
207 bne- 11f
208 stwcx. r8,0,r6
209 beq+ 12f
210 11: lwz r0,0(r6)
211 cmpi 0,r0,0
212 beq 10b
213 b 11b
214 12: isync
215 #endif
216
217
218
219
220
221
222 mr r8,r5
223 #ifndef CONFIG_PTE_64BIT
224 rlwimi r8,r4,22,20,29
225 #else
226 rlwimi r8,r4,23,20,28
227 addi r8,r8,PTE_FLAGS_OFFSET
228 #endif
229 1: lwarx r6,0,r8
230 andi. r0,r6,_PAGE_HASHPTE
231 bne 9f
232 #ifdef CONFIG_PTE_64BIT
233 #ifdef CONFIG_SMP
234 subf r10,r6,r8
235 subi r10,r10,PTE_FLAGS_OFFSET
236 lwzx r10,r6,r10
237 #else
238 lwz r10,-PTE_FLAGS_OFFSET(r8)
239 #endif
240 #endif
241 ori r5,r6,_PAGE_HASHPTE
242 stwcx. r5,0,r8
243 bne- 1b
244
245 bl create_hpte
246
247 9:
248 #ifdef CONFIG_SMP
249 lis r6, (mmu_hash_lock - PAGE_OFFSET)@ha
250 addi r6, r6, (mmu_hash_lock - PAGE_OFFSET)@l
251 eieio
252 li r0,0
253 stw r0,0(r6)
254 #endif
255
256
257 mtmsr r9
258 SYNC_601
259 isync
260
261 lwz r0,4(r1)
262 mtlr r0
263 blr
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284 Hash_base = 0xc0180000
285 Hash_bits = 12
286 Hash_msk = (((1 << Hash_bits) - 1) * 64)
287
288
289 #define HPTE_SIZE 8
290 #define PTEG_SIZE 64
291 #define LG_PTEG_SIZE 6
292 #define LDPTEu lwzu
293 #define LDPTE lwz
294 #define STPTE stw
295 #define CMPPTE cmpw
296 #define PTE_H 0x40
297 #define PTE_V 0x80000000
298 #define TST_V(r) rlwinm. r,r,0,0,0
299 #define SET_V(r) oris r,r,PTE_V@h
300 #define CLR_V(r,t) rlwinm r,r,0,1,31
301
302 #define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1)
303 #define HASH_RIGHT 31-LG_PTEG_SIZE
304
305 _GLOBAL(create_hpte)
306
307 rlwinm r8,r5,32-9,30,30
308 rlwinm r0,r5,32-6,30,30
309 and r8,r8,r0
310 rlwimi r5,r5,32-1,30,30
311 rlwimi r5,r5,32-2,31,31
312 ori r8,r8,0xe04
313 andc r8,r5,r8
314 BEGIN_FTR_SECTION
315 rlwinm r8,r8,0,~_PAGE_COHERENT
316 END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
317 #ifdef CONFIG_PTE_64BIT
318
319 rlwimi r8,r10,8,20,22
320 rlwimi r8,r10,2,29,29
321 #endif
322
323
324 rlwinm r5,r3,7,1,24
325 rlwimi r5,r4,10,26,31
326 SET_V(r5)
327
328 patch_site 0f, patch__hash_page_A0
329 patch_site 1f, patch__hash_page_A1
330 patch_site 2f, patch__hash_page_A2
331
332 0: lis r0, (Hash_base - PAGE_OFFSET)@h
333 1: rlwimi r0,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT
334 2: rlwinm r3,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT
335 xor r3,r3,r0
336 li r0,8
337
338
339
340
341
342 andi. r6,r6,_PAGE_HASHPTE
343 beq+ 10f
344 tlbie r4
345
346 lis r4, (htab_hash_searches - PAGE_OFFSET)@ha
347 lwz r6, (htab_hash_searches - PAGE_OFFSET)@l(r4)
348 addi r6,r6,1
349 stw r6, (htab_hash_searches - PAGE_OFFSET)@l(r4)
350
351
352 mtctr r0
353 addi r4,r3,-HPTE_SIZE
354 1: LDPTEu r6,HPTE_SIZE(r4)
355 CMPPTE 0,r6,r5
356 bdnzf 2,1b
357 beq+ found_slot
358
359 patch_site 0f, patch__hash_page_B
360
361 ori r5,r5,PTE_H
362 0: xoris r4,r3,Hash_msk>>16
363 xori r4,r4,(-PTEG_SIZE & 0xffff)
364 addi r4,r4,-HPTE_SIZE
365 mtctr r0
366 2: LDPTEu r6,HPTE_SIZE(r4)
367 CMPPTE 0,r6,r5
368 bdnzf 2,2b
369 beq+ found_slot
370 xori r5,r5,PTE_H
371
372
373 10: mtctr r0
374 addi r4,r3,-HPTE_SIZE
375 1: LDPTEu r6,HPTE_SIZE(r4)
376 TST_V(r6)
377 bdnzf 2,1b
378 beq+ found_empty
379
380
381 lis r4, (primary_pteg_full - PAGE_OFFSET)@ha
382 lwz r6, (primary_pteg_full - PAGE_OFFSET)@l(r4)
383 addi r6,r6,1
384 stw r6, (primary_pteg_full - PAGE_OFFSET)@l(r4)
385
386 patch_site 0f, patch__hash_page_C
387
388 ori r5,r5,PTE_H
389 0: xoris r4,r3,Hash_msk>>16
390 xori r4,r4,(-PTEG_SIZE & 0xffff)
391 addi r4,r4,-HPTE_SIZE
392 mtctr r0
393 2: LDPTEu r6,HPTE_SIZE(r4)
394 TST_V(r6)
395 bdnzf 2,2b
396 beq+ found_empty
397 xori r5,r5,PTE_H
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418 1: lis r4, (next_slot - PAGE_OFFSET)@ha
419 lwz r6, (next_slot - PAGE_OFFSET)@l(r4)
420 addi r6,r6,HPTE_SIZE
421 andi. r6,r6,7*HPTE_SIZE
422 stw r6,next_slot@l(r4)
423 add r4,r3,r6
424 LDPTE r0,HPTE_SIZE/2(r4)
425 clrrwi r0,r0,12
426 lis r6,etext@h
427 ori r6,r6,etext@l
428 tophys(r6,r6)
429 cmpl cr0,r0,r6
430 blt 1b
431
432 #ifndef CONFIG_SMP
433
434 found_empty:
435 STPTE r5,0(r4)
436 found_slot:
437 STPTE r8,HPTE_SIZE/2(r4)
438
439 #else
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457 found_empty:
458 found_slot:
459 CLR_V(r5,r0)
460 STPTE r5,0(r4)
461 sync
462 TLBSYNC
463 STPTE r8,HPTE_SIZE/2(r4)
464 sync
465 SET_V(r5)
466 STPTE r5,0(r4)
467 #endif
468
469 sync
470 blr
471
472 .section .bss
473 .align 2
474 next_slot:
475 .space 4
476 primary_pteg_full:
477 .space 4
478 htab_hash_searches:
479 .space 4
480 .previous
481
482
483
484
485
486
487
488
489
490 _GLOBAL(flush_hash_pages)
491
492
493
494
495
496
497
498
499 mfmsr r10
500 SYNC
501 rlwinm r0,r10,0,17,15
502 rlwinm r0,r0,0,28,26
503 mtmsr r0
504 SYNC_601
505 isync
506
507
508 #ifndef CONFIG_PTE_64BIT
509 rlwimi r5,r4,22,20,29
510 #else
511 rlwimi r5,r4,23,20,28
512 #endif
513 1: lwz r0,PTE_FLAGS_OFFSET(r5)
514 cmpwi cr1,r6,1
515 andi. r0,r0,_PAGE_HASHPTE
516 bne 2f
517 ble cr1,19f
518 addi r4,r4,0x1000
519 addi r5,r5,PTE_SIZE
520 addi r6,r6,-1
521 b 1b
522
523
524 2: mulli r3,r3,897*16
525 rlwinm r0,r4,4,28,31
526 mulli r0,r0,0x111
527 add r3,r3,r0
528
529
530 rlwinm r11,r3,7,1,24
531 rlwimi r11,r4,10,26,31
532 SET_V(r11)
533
534 #ifdef CONFIG_SMP
535 lis r9, (mmu_hash_lock - PAGE_OFFSET)@ha
536 addi r9, r9, (mmu_hash_lock - PAGE_OFFSET)@l
537 tophys (r8, r2)
538 lwz r8, TASK_CPU(r8)
539 oris r8,r8,9
540 10: lwarx r0,0,r9
541 cmpi 0,r0,0
542 bne- 11f
543 stwcx. r8,0,r9
544 beq+ 12f
545 11: lwz r0,0(r9)
546 cmpi 0,r0,0
547 beq 10b
548 b 11b
549 12: isync
550 #endif
551
552
553
554
555
556
557 #if (PTE_FLAGS_OFFSET != 0)
558 addi r5,r5,PTE_FLAGS_OFFSET
559 #endif
560 33: lwarx r8,0,r5
561 andi. r0,r8,_PAGE_HASHPTE
562 beq 8f
563 rlwinm r8,r8,0,31,29
564 stwcx. r8,0,r5
565 bne- 33b
566
567 patch_site 0f, patch__flush_hash_A0
568 patch_site 1f, patch__flush_hash_A1
569 patch_site 2f, patch__flush_hash_A2
570
571 0: lis r8, (Hash_base - PAGE_OFFSET)@h
572 1: rlwimi r8,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT
573 2: rlwinm r0,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT
574 xor r8,r0,r8
575
576
577 li r0,8
578 mtctr r0
579 addi r12,r8,-HPTE_SIZE
580 1: LDPTEu r0,HPTE_SIZE(r12)
581 CMPPTE 0,r0,r11
582 bdnzf 2,1b
583 beq+ 3f
584
585 patch_site 0f, patch__flush_hash_B
586
587 ori r11,r11,PTE_H
588 li r0,8
589 0: xoris r12,r8,Hash_msk>>16
590 xori r12,r12,(-PTEG_SIZE & 0xffff)
591 addi r12,r12,-HPTE_SIZE
592 mtctr r0
593 2: LDPTEu r0,HPTE_SIZE(r12)
594 CMPPTE 0,r0,r11
595 bdnzf 2,2b
596 xori r11,r11,PTE_H
597 bne- 4f
598
599 3: li r0,0
600 STPTE r0,0(r12)
601 4: sync
602 tlbie r4
603 sync
604
605 8: ble cr1,9f
606 81: addi r6,r6,-1
607 addi r5,r5,PTE_SIZE
608 addi r4,r4,0x1000
609 lwz r0,0(r5)
610 cmpwi cr1,r6,1
611 andi. r0,r0,_PAGE_HASHPTE
612 bne 33b
613 bgt cr1,81b
614
615 9:
616 #ifdef CONFIG_SMP
617 TLBSYNC
618 li r0,0
619 stw r0,0(r9)
620 #endif
621
622 19: mtmsr r10
623 SYNC_601
624 isync
625 blr
626 EXPORT_SYMBOL(flush_hash_pages)
627
628
629
630
631 _GLOBAL(_tlbie)
632 #ifdef CONFIG_SMP
633 lwz r8,TASK_CPU(r2)
634 oris r8,r8,11
635 mfmsr r10
636 SYNC
637 rlwinm r0,r10,0,17,15
638 rlwinm r0,r0,0,28,26
639 mtmsr r0
640 SYNC_601
641 isync
642 lis r9,mmu_hash_lock@h
643 ori r9,r9,mmu_hash_lock@l
644 tophys(r9,r9)
645 10: lwarx r7,0,r9
646 cmpwi 0,r7,0
647 bne- 10b
648 stwcx. r8,0,r9
649 bne- 10b
650 eieio
651 tlbie r3
652 sync
653 TLBSYNC
654 li r0,0
655 stw r0,0(r9)
656 mtmsr r10
657 SYNC_601
658 isync
659 #else
660 tlbie r3
661 sync
662 #endif
663 blr
664
665
666
667
668 _GLOBAL(_tlbia)
669 #if defined(CONFIG_SMP)
670 lwz r8,TASK_CPU(r2)
671 oris r8,r8,10
672 mfmsr r10
673 SYNC
674 rlwinm r0,r10,0,17,15
675 rlwinm r0,r0,0,28,26
676 mtmsr r0
677 SYNC_601
678 isync
679 lis r9,mmu_hash_lock@h
680 ori r9,r9,mmu_hash_lock@l
681 tophys(r9,r9)
682 10: lwarx r7,0,r9
683 cmpwi 0,r7,0
684 bne- 10b
685 stwcx. r8,0,r9
686 bne- 10b
687 sync
688 tlbia
689 sync
690 TLBSYNC
691 li r0,0
692 stw r0,0(r9)
693 mtmsr r10
694 SYNC_601
695 isync
696 #else
697 sync
698 tlbia
699 sync
700 #endif
701 blr