aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/head_64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/head_64.S')
-rw-r--r--arch/powerpc/kernel/head_64.S69
1 files changed, 49 insertions, 20 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index d3aee08e6814..215973a2c8d5 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -36,8 +36,7 @@
36#include <asm/firmware.h> 36#include <asm/firmware.h>
37#include <asm/page_64.h> 37#include <asm/page_64.h>
38#include <asm/exception.h> 38#include <asm/exception.h>
39 39#include <asm/irqflags.h>
40#define DO_SOFT_DISABLE
41 40
42/* 41/*
43 * We layout physical memory as follows: 42 * We layout physical memory as follows:
@@ -450,8 +449,8 @@ bad_stack:
450 */ 449 */
451fast_exc_return_irq: /* restores irq state too */ 450fast_exc_return_irq: /* restores irq state too */
452 ld r3,SOFTE(r1) 451 ld r3,SOFTE(r1)
452 TRACE_AND_RESTORE_IRQ(r3);
453 ld r12,_MSR(r1) 453 ld r12,_MSR(r1)
454 stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
455 rldicl r4,r12,49,63 /* get MSR_EE to LSB */ 454 rldicl r4,r12,49,63 /* get MSR_EE to LSB */
456 stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */ 455 stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */
457 b 1f 456 b 1f
@@ -621,7 +620,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
621 mtlr r10 620 mtlr r10
622 621
623 andi. r10,r12,MSR_RI /* check for unrecoverable exception */ 622 andi. r10,r12,MSR_RI /* check for unrecoverable exception */
624 beq- unrecov_slb 623 beq- 2f
625 624
626.machine push 625.machine push
627.machine "power4" 626.machine "power4"
@@ -643,6 +642,22 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
643 rfid 642 rfid
644 b . /* prevent speculative execution */ 643 b . /* prevent speculative execution */
645 644
6452:
646#ifdef CONFIG_PPC_ISERIES
647BEGIN_FW_FTR_SECTION
648 b unrecov_slb
649END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
650#endif /* CONFIG_PPC_ISERIES */
651 mfspr r11,SPRN_SRR0
652 clrrdi r10,r13,32
653 LOAD_HANDLER(r10,unrecov_slb)
654 mtspr SPRN_SRR0,r10
655 mfmsr r10
656 ori r10,r10,MSR_IR|MSR_DR|MSR_RI
657 mtspr SPRN_SRR1,r10
658 rfid
659 b .
660
646unrecov_slb: 661unrecov_slb:
647 EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) 662 EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
648 DISABLE_INTS 663 DISABLE_INTS
@@ -808,7 +823,7 @@ _STATIC(load_up_altivec)
808 * Hash table stuff 823 * Hash table stuff
809 */ 824 */
810 .align 7 825 .align 7
811_GLOBAL(do_hash_page) 826_STATIC(do_hash_page)
812 std r3,_DAR(r1) 827 std r3,_DAR(r1)
813 std r4,_DSISR(r1) 828 std r4,_DSISR(r1)
814 829
@@ -820,6 +835,27 @@ BEGIN_FTR_SECTION
820END_FTR_SECTION_IFCLR(CPU_FTR_SLB) 835END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
821 836
822 /* 837 /*
838 * On iSeries, we soft-disable interrupts here, then
839 * hard-enable interrupts so that the hash_page code can spin on
840 * the hash_table_lock without problems on a shared processor.
841 */
842 DISABLE_INTS
843
844 /*
845 * Currently, trace_hardirqs_off() will be called by DISABLE_INTS
846 * and will clobber volatile registers when irq tracing is enabled
847 * so we need to reload them. It may be possible to be smarter here
848 * and move the irq tracing elsewhere but let's keep it simple for
849 * now
850 */
851#ifdef CONFIG_TRACE_IRQFLAGS
852 ld r3,_DAR(r1)
853 ld r4,_DSISR(r1)
854 ld r5,_TRAP(r1)
855 ld r12,_MSR(r1)
856 clrrdi r5,r5,4
857#endif /* CONFIG_TRACE_IRQFLAGS */
858 /*
823 * We need to set the _PAGE_USER bit if MSR_PR is set or if we are 859 * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
824 * accessing a userspace segment (even from the kernel). We assume 860 * accessing a userspace segment (even from the kernel). We assume
825 * kernel addresses always have the high bit set. 861 * kernel addresses always have the high bit set.
@@ -832,13 +868,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
832 rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */ 868 rlwimi r4,r5,22+2,31-2,31-2 /* Set _PAGE_EXEC if trap is 0x400 */
833 869
834 /* 870 /*
835 * On iSeries, we soft-disable interrupts here, then
836 * hard-enable interrupts so that the hash_page code can spin on
837 * the hash_table_lock without problems on a shared processor.
838 */
839 DISABLE_INTS
840
841 /*
842 * r3 contains the faulting address 871 * r3 contains the faulting address
843 * r4 contains the required access permissions 872 * r4 contains the required access permissions
844 * r5 contains the trap number 873 * r5 contains the trap number
@@ -848,7 +877,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
848 bl .hash_page /* build HPTE if possible */ 877 bl .hash_page /* build HPTE if possible */
849 cmpdi r3,0 /* see if hash_page succeeded */ 878 cmpdi r3,0 /* see if hash_page succeeded */
850 879
851#ifdef DO_SOFT_DISABLE
852BEGIN_FW_FTR_SECTION 880BEGIN_FW_FTR_SECTION
853 /* 881 /*
854 * If we had interrupts soft-enabled at the point where the 882 * If we had interrupts soft-enabled at the point where the
@@ -860,7 +888,7 @@ BEGIN_FW_FTR_SECTION
860 */ 888 */
861 beq 13f 889 beq 13f
862END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 890END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
863#endif 891
864BEGIN_FW_FTR_SECTION 892BEGIN_FW_FTR_SECTION
865 /* 893 /*
866 * Here we have interrupts hard-disabled, so it is sufficient 894 * Here we have interrupts hard-disabled, so it is sufficient
@@ -874,11 +902,12 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
874 902
875 /* 903 /*
876 * hash_page couldn't handle it, set soft interrupt enable back 904 * hash_page couldn't handle it, set soft interrupt enable back
877 * to what it was before the trap. Note that .local_irq_restore 905 * to what it was before the trap. Note that .raw_local_irq_restore
878 * handles any interrupts pending at this point. 906 * handles any interrupts pending at this point.
879 */ 907 */
880 ld r3,SOFTE(r1) 908 ld r3,SOFTE(r1)
881 bl .local_irq_restore 909 TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f)
910 bl .raw_local_irq_restore
882 b 11f 911 b 11f
883 912
884/* Here we have a page fault that hash_page can't handle. */ 913/* Here we have a page fault that hash_page can't handle. */
@@ -1477,6 +1506,10 @@ _INIT_STATIC(start_here_multiplatform)
1477 addi r2,r2,0x4000 1506 addi r2,r2,0x4000
1478 add r2,r2,r26 1507 add r2,r2,r26
1479 1508
1509 /* Set initial ptr to current */
1510 LOAD_REG_IMMEDIATE(r4, init_task)
1511 std r4,PACACURRENT(r13)
1512
1480 /* Do very early kernel initializations, including initial hash table, 1513 /* Do very early kernel initializations, including initial hash table,
1481 * stab and slb setup before we turn on relocation. */ 1514 * stab and slb setup before we turn on relocation. */
1482 1515
@@ -1505,10 +1538,6 @@ _INIT_GLOBAL(start_here_common)
1505 li r0,0 1538 li r0,0
1506 stdu r0,-STACK_FRAME_OVERHEAD(r1) 1539 stdu r0,-STACK_FRAME_OVERHEAD(r1)
1507 1540
1508 /* ptr to current */
1509 LOAD_REG_IMMEDIATE(r4, init_task)
1510 std r4,PACACURRENT(r13)
1511
1512 /* Load the TOC */ 1541 /* Load the TOC */
1513 ld r2,PACATOC(r13) 1542 ld r2,PACATOC(r13)
1514 std r1,PACAKSAVE(r13) 1543 std r1,PACAKSAVE(r13)