aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/kernel/head_fsl_booke.S168
-rw-r--r--include/asm-powerpc/pgtable-ppc32.h15
2 files changed, 48 insertions, 135 deletions
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S
index c4268500e856..7d554968b635 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -483,90 +483,16 @@ interrupt_base:
483 483
484 /* Data Storage Interrupt */ 484 /* Data Storage Interrupt */
485 START_EXCEPTION(DataStorage) 485 START_EXCEPTION(DataStorage)
486 mtspr SPRN_SPRG0, r10 /* Save some working registers */ 486 NORMAL_EXCEPTION_PROLOG
487 mtspr SPRN_SPRG1, r11 487 mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
488 mtspr SPRN_SPRG4W, r12 488 stw r5,_ESR(r11)
489 mtspr SPRN_SPRG5W, r13 489 mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
490 mfcr r11 490 andis. r10,r5,(ESR_ILK|ESR_DLK)@h
491 mtspr SPRN_SPRG7W, r11 491 bne 1f
492 492 EXC_XFER_EE_LITE(0x0300, handle_page_fault)
493 /* 4931:
494 * Check if it was a store fault, if not then bail 494 addi r3,r1,STACK_FRAME_OVERHEAD
495 * because a user tried to access a kernel or 495 EXC_XFER_EE_LITE(0x0300, CacheLockingException)
496 * read-protected page. Otherwise, get the
497 * offending address and handle it.
498 */
499 mfspr r10, SPRN_ESR
500 andis. r10, r10, ESR_ST@h
501 beq 2f
502
503 mfspr r10, SPRN_DEAR /* Get faulting address */
504
505 /* If we are faulting a kernel address, we have to use the
506 * kernel page tables.
507 */
508 lis r11, PAGE_OFFSET@h
509 cmplw 0, r10, r11
510 bge 2f
511
512 /* Get the PGD for the current thread */
5133:
514 mfspr r11,SPRN_SPRG3
515 lwz r11,PGDIR(r11)
5164:
517 FIND_PTE
518
519 /* Are _PAGE_USER & _PAGE_RW set & _PAGE_HWWRITE not? */
520 andi. r13, r11, _PAGE_RW|_PAGE_USER|_PAGE_HWWRITE
521 cmpwi 0, r13, _PAGE_RW|_PAGE_USER
522 bne 2f /* Bail if not */
523
524 /* Update 'changed'. */
525 ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
526 stw r11, PTE_FLAGS_OFFSET(r12) /* Update Linux page table */
527
528 /* MAS2 not updated as the entry does exist in the tlb, this
529 fault taken to detect state transition (eg: COW -> DIRTY)
530 */
531 andi. r11, r11, _PAGE_HWEXEC
532 rlwimi r11, r11, 31, 27, 27 /* SX <- _PAGE_HWEXEC */
533 ori r11, r11, (MAS3_UW|MAS3_SW|MAS3_UR|MAS3_SR)@l /* set static perms */
534
535 /* update search PID in MAS6, AS = 0 */
536 mfspr r12, SPRN_PID0
537 slwi r12, r12, 16
538 mtspr SPRN_MAS6, r12
539
540 /* find the TLB index that caused the fault. It has to be here. */
541 tlbsx 0, r10
542
543 /* only update the perm bits, assume the RPN is fine */
544 mfspr r12, SPRN_MAS3
545 rlwimi r12, r11, 0, 20, 31
546 mtspr SPRN_MAS3,r12
547 tlbwe
548
549 /* Done...restore registers and get out of here. */
550 mfspr r11, SPRN_SPRG7R
551 mtcr r11
552 mfspr r13, SPRN_SPRG5R
553 mfspr r12, SPRN_SPRG4R
554 mfspr r11, SPRN_SPRG1
555 mfspr r10, SPRN_SPRG0
556 rfi /* Force context change */
557
5582:
559 /*
560 * The bailout. Restore registers to pre-exception conditions
561 * and call the heavyweights to help us out.
562 */
563 mfspr r11, SPRN_SPRG7R
564 mtcr r11
565 mfspr r13, SPRN_SPRG5R
566 mfspr r12, SPRN_SPRG4R
567 mfspr r11, SPRN_SPRG1
568 mfspr r10, SPRN_SPRG0
569 b data_access
570 496
571 /* Instruction Storage Interrupt */ 497 /* Instruction Storage Interrupt */
572 INSTRUCTION_STORAGE_EXCEPTION 498 INSTRUCTION_STORAGE_EXCEPTION
@@ -645,15 +571,30 @@ interrupt_base:
645 lwz r11,PGDIR(r11) 571 lwz r11,PGDIR(r11)
646 572
6474: 5734:
574 /* Mask of required permission bits. Note that while we
575 * do copy ESR:ST to _PAGE_RW position as trying to write
576 * to an RO page is pretty common, we don't do it with
577 * _PAGE_DIRTY. We could do it, but it's a fairly rare
578 * event so I'd rather take the overhead when it happens
579 * rather than adding an instruction here. We should measure
580 * whether the whole thing is worth it in the first place
581 * as we could avoid loading SPRN_ESR completely in the first
582 * place...
583 *
584 * TODO: Is it worth doing that mfspr & rlwimi in the first
585 * place or can we save a couple of instructions here ?
586 */
587 mfspr r12,SPRN_ESR
588 li r13,_PAGE_PRESENT|_PAGE_ACCESSED
589 rlwimi r13,r12,11,29,29
590
648 FIND_PTE 591 FIND_PTE
649 andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ 592 andc. r13,r13,r11 /* Check permission */
650 beq 2f /* Bail if not present */ 593 bne 2f /* Bail if permission mismach */
651 594
652#ifdef CONFIG_PTE_64BIT 595#ifdef CONFIG_PTE_64BIT
653 lwz r13, 0(r12) 596 lwz r13, 0(r12)
654#endif 597#endif
655 ori r11, r11, _PAGE_ACCESSED
656 stw r11, PTE_FLAGS_OFFSET(r12)
657 598
658 /* Jump to common tlb load */ 599 /* Jump to common tlb load */
659 b finish_tlb_load 600 b finish_tlb_load
@@ -667,7 +608,7 @@ interrupt_base:
667 mfspr r12, SPRN_SPRG4R 608 mfspr r12, SPRN_SPRG4R
668 mfspr r11, SPRN_SPRG1 609 mfspr r11, SPRN_SPRG1
669 mfspr r10, SPRN_SPRG0 610 mfspr r10, SPRN_SPRG0
670 b data_access 611 b DataStorage
671 612
672 /* Instruction TLB Error Interrupt */ 613 /* Instruction TLB Error Interrupt */
673 /* 614 /*
@@ -705,15 +646,16 @@ interrupt_base:
705 lwz r11,PGDIR(r11) 646 lwz r11,PGDIR(r11)
706 647
7074: 6484:
649 /* Make up the required permissions */
650 li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
651
708 FIND_PTE 652 FIND_PTE
709 andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ 653 andc. r13,r13,r11 /* Check permission */
710 beq 2f /* Bail if not present */ 654 bne 2f /* Bail if permission mismach */
711 655
712#ifdef CONFIG_PTE_64BIT 656#ifdef CONFIG_PTE_64BIT
713 lwz r13, 0(r12) 657 lwz r13, 0(r12)
714#endif 658#endif
715 ori r11, r11, _PAGE_ACCESSED
716 stw r11, PTE_FLAGS_OFFSET(r12)
717 659
718 /* Jump to common TLB load point */ 660 /* Jump to common TLB load point */
719 b finish_tlb_load 661 b finish_tlb_load
@@ -768,29 +710,13 @@ interrupt_base:
768 * Local functions 710 * Local functions
769 */ 711 */
770 712
771 /*
772 * Data TLB exceptions will bail out to this point
773 * if they can't resolve the lightweight TLB fault.
774 */
775data_access:
776 NORMAL_EXCEPTION_PROLOG
777 mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
778 stw r5,_ESR(r11)
779 mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
780 andis. r10,r5,(ESR_ILK|ESR_DLK)@h
781 bne 1f
782 EXC_XFER_EE_LITE(0x0300, handle_page_fault)
7831:
784 addi r3,r1,STACK_FRAME_OVERHEAD
785 EXC_XFER_EE_LITE(0x0300, CacheLockingException)
786
787/* 713/*
788
789 * Both the instruction and data TLB miss get to this 714 * Both the instruction and data TLB miss get to this
790 * point to load the TLB. 715 * point to load the TLB.
791 * r10 - EA of fault 716 * r10 - EA of fault
792 * r11 - TLB (info from Linux PTE) 717 * r11 - TLB (info from Linux PTE)
793 * r12, r13 - available to use 718 * r12 - available to use
719 * r13 - upper bits of PTE (if PTE_64BIT) or available to use
794 * CR5 - results of addr >= PAGE_OFFSET 720 * CR5 - results of addr >= PAGE_OFFSET
795 * MAS0, MAS1 - loaded with proper value when we get here 721 * MAS0, MAS1 - loaded with proper value when we get here
796 * MAS2, MAS3 - will need additional info from Linux PTE 722 * MAS2, MAS3 - will need additional info from Linux PTE
@@ -812,20 +738,14 @@ finish_tlb_load:
812#endif 738#endif
813 mtspr SPRN_MAS2, r12 739 mtspr SPRN_MAS2, r12
814 740
815 bge 5, 1f 741 li r10, (_PAGE_HWEXEC | _PAGE_PRESENT)
816 742 rlwimi r10, r11, 31, 29, 29 /* extract _PAGE_DIRTY into SW */
817 /* is user addr */ 743 and r12, r11, r10
818 andi. r12, r11, (_PAGE_USER | _PAGE_HWWRITE | _PAGE_HWEXEC)
819 andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */ 744 andi. r10, r11, _PAGE_USER /* Test for _PAGE_USER */
820 srwi r10, r12, 1 745 slwi r10, r12, 1
821 or r12, r12, r10 /* Copy user perms into supervisor */ 746 or r10, r10, r12
822 iseleq r12, 0, r12 747 iseleq r12, r12, r10
823 b 2f 748
824
825 /* is kernel addr */
8261: rlwinm r12, r11, 31, 29, 29 /* Extract _PAGE_HWWRITE into SW */
827 ori r12, r12, (MAS3_SX | MAS3_SR)
828
829#ifdef CONFIG_PTE_64BIT 749#ifdef CONFIG_PTE_64BIT
8302: rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */ 7502: rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */
831 rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */ 751 rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */
diff --git a/include/asm-powerpc/pgtable-ppc32.h b/include/asm-powerpc/pgtable-ppc32.h
index 73015f0139de..3a96d001cb75 100644
--- a/include/asm-powerpc/pgtable-ppc32.h
+++ b/include/asm-powerpc/pgtable-ppc32.h
@@ -295,10 +295,10 @@ extern int icache_44x_need_flush;
295#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */ 295#define _PAGE_PRESENT 0x00001 /* S: PTE contains a translation */
296#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */ 296#define _PAGE_USER 0x00002 /* S: User page (maps to UR) */
297#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */ 297#define _PAGE_FILE 0x00002 /* S: when !present: nonlinear file mapping */
298#define _PAGE_ACCESSED 0x00004 /* S: Page referenced */ 298#define _PAGE_RW 0x00004 /* S: Write permission (SW) */
299#define _PAGE_HWWRITE 0x00008 /* H: Dirty & RW, set in exception */ 299#define _PAGE_DIRTY 0x00008 /* S: Page dirty */
300#define _PAGE_RW 0x00010 /* S: Write permission */ 300#define _PAGE_HWEXEC 0x00010 /* H: SX permission */
301#define _PAGE_HWEXEC 0x00020 /* H: UX permission */ 301#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */
302 302
303#define _PAGE_ENDIAN 0x00040 /* H: E bit */ 303#define _PAGE_ENDIAN 0x00040 /* H: E bit */
304#define _PAGE_GUARDED 0x00080 /* H: G bit */ 304#define _PAGE_GUARDED 0x00080 /* H: G bit */
@@ -307,21 +307,14 @@ extern int icache_44x_need_flush;
307#define _PAGE_WRITETHRU 0x00400 /* H: W bit */ 307#define _PAGE_WRITETHRU 0x00400 /* H: W bit */
308 308
309#ifdef CONFIG_PTE_64BIT 309#ifdef CONFIG_PTE_64BIT
310#define _PAGE_DIRTY 0x08000 /* S: Page dirty */
311
312/* ERPN in a PTE never gets cleared, ignore it */ 310/* ERPN in a PTE never gets cleared, ignore it */
313#define _PTE_NONE_MASK 0xffffffffffff0000ULL 311#define _PTE_NONE_MASK 0xffffffffffff0000ULL
314#else
315#define _PAGE_DIRTY 0x00800 /* S: Page dirty */
316#endif 312#endif
317 313
318#define _PMD_PRESENT 0 314#define _PMD_PRESENT 0
319#define _PMD_PRESENT_MASK (PAGE_MASK) 315#define _PMD_PRESENT_MASK (PAGE_MASK)
320#define _PMD_BAD (~PAGE_MASK) 316#define _PMD_BAD (~PAGE_MASK)
321 317
322/* Until my rework is finished, FSL BookE still needs atomic PTE updates */
323#define PTE_ATOMIC_UPDATES 1
324
325#elif defined(CONFIG_8xx) 318#elif defined(CONFIG_8xx)
326/* Definitions for 8xx embedded chips. */ 319/* Definitions for 8xx embedded chips. */
327#define _PAGE_PRESENT 0x0001 /* Page is valid */ 320#define _PAGE_PRESENT 0x0001 /* Page is valid */