diff options
| author | Ingo Molnar <mingo@elte.hu> | 2010-06-18 04:53:12 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-06-18 04:53:19 -0400 |
| commit | 646b1db4956ba8bf748b835b5eba211133d91c2e (patch) | |
| tree | 061166d873d9da9cf83044a7593ad111787076c5 /arch/powerpc/kernel | |
| parent | 0f2c3de2ba110626515234d5d584fb1b0c0749a2 (diff) | |
| parent | 7e27d6e778cd87b6f2415515d7127eba53fe5d02 (diff) | |
Merge commit 'v2.6.35-rc3' into perf/core
Merge reason: Go from -rc1 base to -rc3 base, merge in fixes.
Diffstat (limited to 'arch/powerpc/kernel')
| -rw-r--r-- | arch/powerpc/kernel/Makefile | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/cputable.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/crash.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/kernel/fsl_booke_entry_mapping.S | 237 | ||||
| -rw-r--r-- | arch/powerpc/kernel/head_fsl_booke.S | 200 | ||||
| -rw-r--r-- | arch/powerpc/kernel/kprobes.c | 14 | ||||
| -rw-r--r-- | arch/powerpc/kernel/misc_32.S | 17 | ||||
| -rw-r--r-- | arch/powerpc/kernel/pci-common.c | 1 | ||||
| -rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/swsusp_booke.S | 193 | ||||
| -rw-r--r-- | arch/powerpc/kernel/traps.c | 88 | ||||
| -rw-r--r-- | arch/powerpc/kernel/vmlinux.lds.S | 10 |
12 files changed, 556 insertions, 220 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 877326320e74..58d0572de6f9 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
| @@ -57,8 +57,12 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | |||
| 57 | obj-$(CONFIG_E500) += idle_e500.o | 57 | obj-$(CONFIG_E500) += idle_e500.o |
| 58 | obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o | 58 | obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o |
| 59 | obj-$(CONFIG_TAU) += tau_6xx.o | 59 | obj-$(CONFIG_TAU) += tau_6xx.o |
| 60 | obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o \ | 60 | obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o |
| 61 | swsusp_$(CONFIG_WORD_SIZE).o | 61 | ifeq ($(CONFIG_FSL_BOOKE),y) |
| 62 | obj-$(CONFIG_HIBERNATION) += swsusp_booke.o | ||
| 63 | else | ||
| 64 | obj-$(CONFIG_HIBERNATION) += swsusp_$(CONFIG_WORD_SIZE).o | ||
| 65 | endif | ||
| 62 | obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o | 66 | obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o |
| 63 | obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o | 67 | obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o |
| 64 | obj-$(CONFIG_44x) += cpu_setup_44x.o | 68 | obj-$(CONFIG_44x) += cpu_setup_44x.o |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 9556be903e96..87aa0f3c6047 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
| @@ -1840,7 +1840,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
| 1840 | .oprofile_cpu_type = "ppc/e500mc", | 1840 | .oprofile_cpu_type = "ppc/e500mc", |
| 1841 | .oprofile_type = PPC_OPROFILE_FSL_EMB, | 1841 | .oprofile_type = PPC_OPROFILE_FSL_EMB, |
| 1842 | .cpu_setup = __setup_cpu_e500mc, | 1842 | .cpu_setup = __setup_cpu_e500mc, |
| 1843 | .machine_check = machine_check_e500, | 1843 | .machine_check = machine_check_e500mc, |
| 1844 | .platform = "ppce500mc", | 1844 | .platform = "ppce500mc", |
| 1845 | }, | 1845 | }, |
| 1846 | { /* default match */ | 1846 | { /* default match */ |
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 8c066d6a8e4b..b46f2e09bd81 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c | |||
| @@ -163,6 +163,7 @@ static void crash_kexec_prepare_cpus(int cpu) | |||
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | /* wait for all the CPUs to hit real mode but timeout if they don't come in */ | 165 | /* wait for all the CPUs to hit real mode but timeout if they don't come in */ |
| 166 | #ifdef CONFIG_PPC_STD_MMU_64 | ||
| 166 | static void crash_kexec_wait_realmode(int cpu) | 167 | static void crash_kexec_wait_realmode(int cpu) |
| 167 | { | 168 | { |
| 168 | unsigned int msecs; | 169 | unsigned int msecs; |
| @@ -187,6 +188,7 @@ static void crash_kexec_wait_realmode(int cpu) | |||
| 187 | } | 188 | } |
| 188 | mb(); | 189 | mb(); |
| 189 | } | 190 | } |
| 191 | #endif | ||
| 190 | 192 | ||
| 191 | /* | 193 | /* |
| 192 | * This function will be called by secondary cpus or by kexec cpu | 194 | * This function will be called by secondary cpus or by kexec cpu |
| @@ -445,7 +447,9 @@ void default_machine_crash_shutdown(struct pt_regs *regs) | |||
| 445 | crash_kexec_prepare_cpus(crashing_cpu); | 447 | crash_kexec_prepare_cpus(crashing_cpu); |
| 446 | cpu_set(crashing_cpu, cpus_in_crash); | 448 | cpu_set(crashing_cpu, cpus_in_crash); |
| 447 | crash_kexec_stop_spus(); | 449 | crash_kexec_stop_spus(); |
| 450 | #ifdef CONFIG_PPC_STD_MMU_64 | ||
| 448 | crash_kexec_wait_realmode(crashing_cpu); | 451 | crash_kexec_wait_realmode(crashing_cpu); |
| 452 | #endif | ||
| 449 | if (ppc_md.kexec_cpu_down) | 453 | if (ppc_md.kexec_cpu_down) |
| 450 | ppc_md.kexec_cpu_down(1, 0); | 454 | ppc_md.kexec_cpu_down(1, 0); |
| 451 | } | 455 | } |
diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S new file mode 100644 index 000000000000..beb4d78a2304 --- /dev/null +++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S | |||
| @@ -0,0 +1,237 @@ | |||
| 1 | |||
| 2 | /* 1. Find the index of the entry we're executing in */ | ||
| 3 | bl invstr /* Find our address */ | ||
| 4 | invstr: mflr r6 /* Make it accessible */ | ||
| 5 | mfmsr r7 | ||
| 6 | rlwinm r4,r7,27,31,31 /* extract MSR[IS] */ | ||
| 7 | mfspr r7, SPRN_PID0 | ||
| 8 | slwi r7,r7,16 | ||
| 9 | or r7,r7,r4 | ||
| 10 | mtspr SPRN_MAS6,r7 | ||
| 11 | tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ | ||
| 12 | mfspr r7,SPRN_MAS1 | ||
| 13 | andis. r7,r7,MAS1_VALID@h | ||
| 14 | bne match_TLB | ||
| 15 | |||
| 16 | mfspr r7,SPRN_MMUCFG | ||
| 17 | rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ | ||
| 18 | cmpwi r7,3 | ||
| 19 | bne match_TLB /* skip if NPIDS != 3 */ | ||
| 20 | |||
| 21 | mfspr r7,SPRN_PID1 | ||
| 22 | slwi r7,r7,16 | ||
| 23 | or r7,r7,r4 | ||
| 24 | mtspr SPRN_MAS6,r7 | ||
| 25 | tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */ | ||
| 26 | mfspr r7,SPRN_MAS1 | ||
| 27 | andis. r7,r7,MAS1_VALID@h | ||
| 28 | bne match_TLB | ||
| 29 | mfspr r7, SPRN_PID2 | ||
| 30 | slwi r7,r7,16 | ||
| 31 | or r7,r7,r4 | ||
| 32 | mtspr SPRN_MAS6,r7 | ||
| 33 | tlbsx 0,r6 /* Fall through, we had to match */ | ||
| 34 | |||
| 35 | match_TLB: | ||
| 36 | mfspr r7,SPRN_MAS0 | ||
| 37 | rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ | ||
| 38 | |||
| 39 | mfspr r7,SPRN_MAS1 /* Insure IPROT set */ | ||
| 40 | oris r7,r7,MAS1_IPROT@h | ||
| 41 | mtspr SPRN_MAS1,r7 | ||
| 42 | tlbwe | ||
| 43 | |||
| 44 | /* 2. Invalidate all entries except the entry we're executing in */ | ||
| 45 | mfspr r9,SPRN_TLB1CFG | ||
| 46 | andi. r9,r9,0xfff | ||
| 47 | li r6,0 /* Set Entry counter to 0 */ | ||
| 48 | 1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
| 49 | rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ | ||
| 50 | mtspr SPRN_MAS0,r7 | ||
| 51 | tlbre | ||
| 52 | mfspr r7,SPRN_MAS1 | ||
| 53 | rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */ | ||
| 54 | cmpw r3,r6 | ||
| 55 | beq skpinv /* Dont update the current execution TLB */ | ||
| 56 | mtspr SPRN_MAS1,r7 | ||
| 57 | tlbwe | ||
| 58 | isync | ||
| 59 | skpinv: addi r6,r6,1 /* Increment */ | ||
| 60 | cmpw r6,r9 /* Are we done? */ | ||
| 61 | bne 1b /* If not, repeat */ | ||
| 62 | |||
| 63 | /* Invalidate TLB0 */ | ||
| 64 | li r6,0x04 | ||
| 65 | tlbivax 0,r6 | ||
| 66 | TLBSYNC | ||
| 67 | /* Invalidate TLB1 */ | ||
| 68 | li r6,0x0c | ||
| 69 | tlbivax 0,r6 | ||
| 70 | TLBSYNC | ||
| 71 | |||
| 72 | /* 3. Setup a temp mapping and jump to it */ | ||
| 73 | andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */ | ||
| 74 | addi r5, r5, 0x1 | ||
| 75 | lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
| 76 | rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ | ||
| 77 | mtspr SPRN_MAS0,r7 | ||
| 78 | tlbre | ||
| 79 | |||
| 80 | /* grab and fixup the RPN */ | ||
| 81 | mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */ | ||
| 82 | rlwinm r6,r6,25,27,31 | ||
| 83 | li r8,-1 | ||
| 84 | addi r6,r6,10 | ||
| 85 | slw r6,r8,r6 /* convert to mask */ | ||
| 86 | |||
| 87 | bl 1f /* Find our address */ | ||
| 88 | 1: mflr r7 | ||
| 89 | |||
| 90 | mfspr r8,SPRN_MAS3 | ||
| 91 | #ifdef CONFIG_PHYS_64BIT | ||
| 92 | mfspr r23,SPRN_MAS7 | ||
| 93 | #endif | ||
| 94 | and r8,r6,r8 | ||
| 95 | subfic r9,r6,-4096 | ||
| 96 | and r9,r9,r7 | ||
| 97 | |||
| 98 | or r25,r8,r9 | ||
| 99 | ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR) | ||
| 100 | |||
| 101 | /* Just modify the entry ID and EPN for the temp mapping */ | ||
| 102 | lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
| 103 | rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | ||
| 104 | mtspr SPRN_MAS0,r7 | ||
| 105 | xori r6,r4,1 /* Setup TMP mapping in the other Address space */ | ||
| 106 | slwi r6,r6,12 | ||
| 107 | oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h | ||
| 108 | ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l | ||
| 109 | mtspr SPRN_MAS1,r6 | ||
| 110 | mfspr r6,SPRN_MAS2 | ||
| 111 | li r7,0 /* temp EPN = 0 */ | ||
| 112 | rlwimi r7,r6,0,20,31 | ||
| 113 | mtspr SPRN_MAS2,r7 | ||
| 114 | mtspr SPRN_MAS3,r8 | ||
| 115 | tlbwe | ||
| 116 | |||
| 117 | xori r6,r4,1 | ||
| 118 | slwi r6,r6,5 /* setup new context with other address space */ | ||
| 119 | bl 1f /* Find our address */ | ||
| 120 | 1: mflr r9 | ||
| 121 | rlwimi r7,r9,0,20,31 | ||
| 122 | addi r7,r7,(2f - 1b) | ||
| 123 | mtspr SPRN_SRR0,r7 | ||
| 124 | mtspr SPRN_SRR1,r6 | ||
| 125 | rfi | ||
| 126 | 2: | ||
| 127 | /* 4. Clear out PIDs & Search info */ | ||
| 128 | li r6,0 | ||
| 129 | mtspr SPRN_MAS6,r6 | ||
| 130 | mtspr SPRN_PID0,r6 | ||
| 131 | |||
| 132 | mfspr r7,SPRN_MMUCFG | ||
| 133 | rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ | ||
| 134 | cmpwi r7,3 | ||
| 135 | bne 2f /* skip if NPIDS != 3 */ | ||
| 136 | |||
| 137 | mtspr SPRN_PID1,r6 | ||
| 138 | mtspr SPRN_PID2,r6 | ||
| 139 | |||
| 140 | /* 5. Invalidate mapping we started in */ | ||
| 141 | 2: | ||
| 142 | lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
| 143 | rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ | ||
| 144 | mtspr SPRN_MAS0,r7 | ||
| 145 | tlbre | ||
| 146 | mfspr r6,SPRN_MAS1 | ||
| 147 | rlwinm r6,r6,0,2,0 /* clear IPROT */ | ||
| 148 | mtspr SPRN_MAS1,r6 | ||
| 149 | tlbwe | ||
| 150 | /* Invalidate TLB1 */ | ||
| 151 | li r9,0x0c | ||
| 152 | tlbivax 0,r9 | ||
| 153 | TLBSYNC | ||
| 154 | |||
| 155 | /* The mapping only needs to be cache-coherent on SMP */ | ||
| 156 | #ifdef CONFIG_SMP | ||
| 157 | #define M_IF_SMP MAS2_M | ||
| 158 | #else | ||
| 159 | #define M_IF_SMP 0 | ||
| 160 | #endif | ||
| 161 | |||
| 162 | #if defined(ENTRY_MAPPING_BOOT_SETUP) | ||
| 163 | |||
| 164 | /* 6. Setup KERNELBASE mapping in TLB1[0] */ | ||
| 165 | lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ | ||
| 166 | mtspr SPRN_MAS0,r6 | ||
| 167 | lis r6,(MAS1_VALID|MAS1_IPROT)@h | ||
| 168 | ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l | ||
| 169 | mtspr SPRN_MAS1,r6 | ||
| 170 | lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h | ||
| 171 | ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l | ||
| 172 | mtspr SPRN_MAS2,r6 | ||
| 173 | mtspr SPRN_MAS3,r8 | ||
| 174 | tlbwe | ||
| 175 | |||
| 176 | /* 7. Jump to KERNELBASE mapping */ | ||
| 177 | lis r6,(KERNELBASE & ~0xfff)@h | ||
| 178 | ori r6,r6,(KERNELBASE & ~0xfff)@l | ||
| 179 | |||
| 180 | #elif defined(ENTRY_MAPPING_KEXEC_SETUP) | ||
| 181 | /* | ||
| 182 | * 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp | ||
| 183 | * mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This | ||
| 184 | * will cover the first 2GiB of memory. | ||
| 185 | */ | ||
| 186 | |||
| 187 | lis r10, (MAS1_VALID|MAS1_IPROT)@h | ||
| 188 | ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l | ||
| 189 | li r11, 0 | ||
| 190 | li r0, 8 | ||
| 191 | mtctr r0 | ||
| 192 | |||
| 193 | next_tlb_setup: | ||
| 194 | addi r0, r11, 3 | ||
| 195 | rlwinm r0, r0, 16, 4, 15 // Compute esel | ||
| 196 | rlwinm r9, r11, 28, 0, 3 // Compute [ER]PN | ||
| 197 | oris r0, r0, (MAS0_TLBSEL(1))@h | ||
| 198 | mtspr SPRN_MAS0,r0 | ||
| 199 | mtspr SPRN_MAS1,r10 | ||
| 200 | mtspr SPRN_MAS2,r9 | ||
| 201 | ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR) | ||
| 202 | mtspr SPRN_MAS3,r9 | ||
| 203 | tlbwe | ||
| 204 | addi r11, r11, 1 | ||
| 205 | bdnz+ next_tlb_setup | ||
| 206 | |||
| 207 | /* 7. Jump to our 1:1 mapping */ | ||
| 208 | li r6, 0 | ||
| 209 | |||
| 210 | #else | ||
| 211 | #error You need to specify the mapping or not use this at all. | ||
| 212 | #endif | ||
| 213 | |||
| 214 | lis r7,MSR_KERNEL@h | ||
| 215 | ori r7,r7,MSR_KERNEL@l | ||
| 216 | bl 1f /* Find our address */ | ||
| 217 | 1: mflr r9 | ||
| 218 | rlwimi r6,r9,0,20,31 | ||
| 219 | addi r6,r6,(2f - 1b) | ||
| 220 | add r6, r6, r25 | ||
| 221 | mtspr SPRN_SRR0,r6 | ||
| 222 | mtspr SPRN_SRR1,r7 | ||
| 223 | rfi /* start execution out of TLB1[0] entry */ | ||
| 224 | |||
| 225 | /* 8. Clear out the temp mapping */ | ||
| 226 | 2: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
| 227 | rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | ||
| 228 | mtspr SPRN_MAS0,r7 | ||
| 229 | tlbre | ||
| 230 | mfspr r8,SPRN_MAS1 | ||
| 231 | rlwinm r8,r8,0,2,0 /* clear IPROT */ | ||
| 232 | mtspr SPRN_MAS1,r8 | ||
| 233 | tlbwe | ||
| 234 | /* Invalidate TLB1 */ | ||
| 235 | li r9,0x0c | ||
| 236 | tlbivax 0,r9 | ||
| 237 | TLBSYNC | ||
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index edd4a57fd29e..4faeba247854 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
| @@ -94,204 +94,10 @@ _ENTRY(_start); | |||
| 94 | */ | 94 | */ |
| 95 | 95 | ||
| 96 | _ENTRY(__early_start) | 96 | _ENTRY(__early_start) |
| 97 | /* 1. Find the index of the entry we're executing in */ | ||
| 98 | bl invstr /* Find our address */ | ||
| 99 | invstr: mflr r6 /* Make it accessible */ | ||
| 100 | mfmsr r7 | ||
| 101 | rlwinm r4,r7,27,31,31 /* extract MSR[IS] */ | ||
| 102 | mfspr r7, SPRN_PID0 | ||
| 103 | slwi r7,r7,16 | ||
| 104 | or r7,r7,r4 | ||
| 105 | mtspr SPRN_MAS6,r7 | ||
| 106 | tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */ | ||
| 107 | mfspr r7,SPRN_MAS1 | ||
| 108 | andis. r7,r7,MAS1_VALID@h | ||
| 109 | bne match_TLB | ||
| 110 | |||
| 111 | mfspr r7,SPRN_MMUCFG | ||
| 112 | rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ | ||
| 113 | cmpwi r7,3 | ||
| 114 | bne match_TLB /* skip if NPIDS != 3 */ | ||
| 115 | |||
| 116 | mfspr r7,SPRN_PID1 | ||
| 117 | slwi r7,r7,16 | ||
| 118 | or r7,r7,r4 | ||
| 119 | mtspr SPRN_MAS6,r7 | ||
| 120 | tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */ | ||
| 121 | mfspr r7,SPRN_MAS1 | ||
| 122 | andis. r7,r7,MAS1_VALID@h | ||
| 123 | bne match_TLB | ||
| 124 | mfspr r7, SPRN_PID2 | ||
| 125 | slwi r7,r7,16 | ||
| 126 | or r7,r7,r4 | ||
| 127 | mtspr SPRN_MAS6,r7 | ||
| 128 | tlbsx 0,r6 /* Fall through, we had to match */ | ||
| 129 | |||
| 130 | match_TLB: | ||
| 131 | mfspr r7,SPRN_MAS0 | ||
| 132 | rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */ | ||
| 133 | |||
| 134 | mfspr r7,SPRN_MAS1 /* Insure IPROT set */ | ||
| 135 | oris r7,r7,MAS1_IPROT@h | ||
| 136 | mtspr SPRN_MAS1,r7 | ||
| 137 | tlbwe | ||
| 138 | |||
| 139 | /* 2. Invalidate all entries except the entry we're executing in */ | ||
| 140 | mfspr r9,SPRN_TLB1CFG | ||
| 141 | andi. r9,r9,0xfff | ||
| 142 | li r6,0 /* Set Entry counter to 0 */ | ||
| 143 | 1: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
| 144 | rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ | ||
| 145 | mtspr SPRN_MAS0,r7 | ||
| 146 | tlbre | ||
| 147 | mfspr r7,SPRN_MAS1 | ||
| 148 | rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */ | ||
| 149 | cmpw r3,r6 | ||
| 150 | beq skpinv /* Dont update the current execution TLB */ | ||
| 151 | mtspr SPRN_MAS1,r7 | ||
| 152 | tlbwe | ||
| 153 | isync | ||
| 154 | skpinv: addi r6,r6,1 /* Increment */ | ||
| 155 | cmpw r6,r9 /* Are we done? */ | ||
| 156 | bne 1b /* If not, repeat */ | ||
| 157 | |||
| 158 | /* Invalidate TLB0 */ | ||
| 159 | li r6,0x04 | ||
| 160 | tlbivax 0,r6 | ||
| 161 | TLBSYNC | ||
| 162 | /* Invalidate TLB1 */ | ||
| 163 | li r6,0x0c | ||
| 164 | tlbivax 0,r6 | ||
| 165 | TLBSYNC | ||
| 166 | |||
| 167 | /* 3. Setup a temp mapping and jump to it */ | ||
| 168 | andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */ | ||
| 169 | addi r5, r5, 0x1 | ||
| 170 | lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
| 171 | rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ | ||
| 172 | mtspr SPRN_MAS0,r7 | ||
| 173 | tlbre | ||
| 174 | |||
| 175 | /* grab and fixup the RPN */ | ||
| 176 | mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */ | ||
| 177 | rlwinm r6,r6,25,27,31 | ||
| 178 | li r8,-1 | ||
| 179 | addi r6,r6,10 | ||
| 180 | slw r6,r8,r6 /* convert to mask */ | ||
| 181 | |||
| 182 | bl 1f /* Find our address */ | ||
| 183 | 1: mflr r7 | ||
| 184 | |||
| 185 | mfspr r8,SPRN_MAS3 | ||
| 186 | #ifdef CONFIG_PHYS_64BIT | ||
| 187 | mfspr r23,SPRN_MAS7 | ||
| 188 | #endif | ||
| 189 | and r8,r6,r8 | ||
| 190 | subfic r9,r6,-4096 | ||
| 191 | and r9,r9,r7 | ||
| 192 | |||
| 193 | or r25,r8,r9 | ||
| 194 | ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR) | ||
| 195 | |||
| 196 | /* Just modify the entry ID and EPN for the temp mapping */ | ||
| 197 | lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
| 198 | rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | ||
| 199 | mtspr SPRN_MAS0,r7 | ||
| 200 | xori r6,r4,1 /* Setup TMP mapping in the other Address space */ | ||
| 201 | slwi r6,r6,12 | ||
| 202 | oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h | ||
| 203 | ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l | ||
| 204 | mtspr SPRN_MAS1,r6 | ||
| 205 | mfspr r6,SPRN_MAS2 | ||
| 206 | li r7,0 /* temp EPN = 0 */ | ||
| 207 | rlwimi r7,r6,0,20,31 | ||
| 208 | mtspr SPRN_MAS2,r7 | ||
| 209 | mtspr SPRN_MAS3,r8 | ||
| 210 | tlbwe | ||
| 211 | |||
| 212 | xori r6,r4,1 | ||
| 213 | slwi r6,r6,5 /* setup new context with other address space */ | ||
| 214 | bl 1f /* Find our address */ | ||
| 215 | 1: mflr r9 | ||
| 216 | rlwimi r7,r9,0,20,31 | ||
| 217 | addi r7,r7,(2f - 1b) | ||
| 218 | mtspr SPRN_SRR0,r7 | ||
| 219 | mtspr SPRN_SRR1,r6 | ||
| 220 | rfi | ||
| 221 | 2: | ||
| 222 | /* 4. Clear out PIDs & Search info */ | ||
| 223 | li r6,0 | ||
| 224 | mtspr SPRN_MAS6,r6 | ||
| 225 | mtspr SPRN_PID0,r6 | ||
| 226 | |||
| 227 | mfspr r7,SPRN_MMUCFG | ||
| 228 | rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */ | ||
| 229 | cmpwi r7,3 | ||
| 230 | bne 2f /* skip if NPIDS != 3 */ | ||
| 231 | 97 | ||
| 232 | mtspr SPRN_PID1,r6 | 98 | #define ENTRY_MAPPING_BOOT_SETUP |
| 233 | mtspr SPRN_PID2,r6 | 99 | #include "fsl_booke_entry_mapping.S" |
| 234 | 100 | #undef ENTRY_MAPPING_BOOT_SETUP | |
| 235 | /* 5. Invalidate mapping we started in */ | ||
| 236 | 2: | ||
| 237 | lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
| 238 | rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */ | ||
| 239 | mtspr SPRN_MAS0,r7 | ||
| 240 | tlbre | ||
| 241 | mfspr r6,SPRN_MAS1 | ||
| 242 | rlwinm r6,r6,0,2,0 /* clear IPROT */ | ||
| 243 | mtspr SPRN_MAS1,r6 | ||
| 244 | tlbwe | ||
| 245 | /* Invalidate TLB1 */ | ||
| 246 | li r9,0x0c | ||
| 247 | tlbivax 0,r9 | ||
| 248 | TLBSYNC | ||
| 249 | |||
| 250 | /* The mapping only needs to be cache-coherent on SMP */ | ||
| 251 | #ifdef CONFIG_SMP | ||
| 252 | #define M_IF_SMP MAS2_M | ||
| 253 | #else | ||
| 254 | #define M_IF_SMP 0 | ||
| 255 | #endif | ||
| 256 | |||
| 257 | /* 6. Setup KERNELBASE mapping in TLB1[0] */ | ||
| 258 | lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ | ||
| 259 | mtspr SPRN_MAS0,r6 | ||
| 260 | lis r6,(MAS1_VALID|MAS1_IPROT)@h | ||
| 261 | ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l | ||
| 262 | mtspr SPRN_MAS1,r6 | ||
| 263 | lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h | ||
| 264 | ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l | ||
| 265 | mtspr SPRN_MAS2,r6 | ||
| 266 | mtspr SPRN_MAS3,r8 | ||
| 267 | tlbwe | ||
| 268 | |||
| 269 | /* 7. Jump to KERNELBASE mapping */ | ||
| 270 | lis r6,(KERNELBASE & ~0xfff)@h | ||
| 271 | ori r6,r6,(KERNELBASE & ~0xfff)@l | ||
| 272 | lis r7,MSR_KERNEL@h | ||
| 273 | ori r7,r7,MSR_KERNEL@l | ||
| 274 | bl 1f /* Find our address */ | ||
| 275 | 1: mflr r9 | ||
| 276 | rlwimi r6,r9,0,20,31 | ||
| 277 | addi r6,r6,(2f - 1b) | ||
| 278 | mtspr SPRN_SRR0,r6 | ||
| 279 | mtspr SPRN_SRR1,r7 | ||
| 280 | rfi /* start execution out of TLB1[0] entry */ | ||
| 281 | |||
| 282 | /* 8. Clear out the temp mapping */ | ||
| 283 | 2: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | ||
| 284 | rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | ||
| 285 | mtspr SPRN_MAS0,r7 | ||
| 286 | tlbre | ||
| 287 | mfspr r8,SPRN_MAS1 | ||
| 288 | rlwinm r8,r8,0,2,0 /* clear IPROT */ | ||
| 289 | mtspr SPRN_MAS1,r8 | ||
| 290 | tlbwe | ||
| 291 | /* Invalidate TLB1 */ | ||
| 292 | li r9,0x0c | ||
| 293 | tlbivax 0,r9 | ||
| 294 | TLBSYNC | ||
| 295 | 101 | ||
| 296 | /* Establish the interrupt vector offsets */ | 102 | /* Establish the interrupt vector offsets */ |
| 297 | SET_IVOR(0, CriticalInput); | 103 | SET_IVOR(0, CriticalInput); |
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index c533525ca56a..bc47352deb1f 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c | |||
| @@ -378,17 +378,6 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p, | |||
| 378 | * single-stepped a copy of the instruction. The address of this | 378 | * single-stepped a copy of the instruction. The address of this |
| 379 | * copy is p->ainsn.insn. | 379 | * copy is p->ainsn.insn. |
| 380 | */ | 380 | */ |
| 381 | static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) | ||
| 382 | { | ||
| 383 | int ret; | ||
| 384 | unsigned int insn = *p->ainsn.insn; | ||
| 385 | |||
| 386 | regs->nip = (unsigned long)p->addr; | ||
| 387 | ret = emulate_step(regs, insn); | ||
| 388 | if (ret == 0) | ||
| 389 | regs->nip = (unsigned long)p->addr + 4; | ||
| 390 | } | ||
| 391 | |||
| 392 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) | 381 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) |
| 393 | { | 382 | { |
| 394 | struct kprobe *cur = kprobe_running(); | 383 | struct kprobe *cur = kprobe_running(); |
| @@ -406,7 +395,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs) | |||
| 406 | cur->post_handler(cur, regs, 0); | 395 | cur->post_handler(cur, regs, 0); |
| 407 | } | 396 | } |
| 408 | 397 | ||
| 409 | resume_execution(cur, regs); | 398 | /* Adjust nip to after the single-stepped instruction */ |
| 399 | regs->nip = (unsigned long)cur->addr + 4; | ||
| 410 | regs->msr |= kcb->kprobe_saved_msr; | 400 | regs->msr |= kcb->kprobe_saved_msr; |
| 411 | 401 | ||
| 412 | /*Restore back the original saved kprobes variables and continue. */ | 402 | /*Restore back the original saved kprobes variables and continue. */ |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 8043d1b73cf0..dc66d52dcff5 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
| @@ -711,6 +711,22 @@ relocate_new_kernel: | |||
| 711 | /* r4 = reboot_code_buffer */ | 711 | /* r4 = reboot_code_buffer */ |
| 712 | /* r5 = start_address */ | 712 | /* r5 = start_address */ |
| 713 | 713 | ||
| 714 | #ifdef CONFIG_FSL_BOOKE | ||
| 715 | |||
| 716 | mr r29, r3 | ||
| 717 | mr r30, r4 | ||
| 718 | mr r31, r5 | ||
| 719 | |||
| 720 | #define ENTRY_MAPPING_KEXEC_SETUP | ||
| 721 | #include "fsl_booke_entry_mapping.S" | ||
| 722 | #undef ENTRY_MAPPING_KEXEC_SETUP | ||
| 723 | |||
| 724 | mr r3, r29 | ||
| 725 | mr r4, r30 | ||
| 726 | mr r5, r31 | ||
| 727 | |||
| 728 | li r0, 0 | ||
| 729 | #else | ||
| 714 | li r0, 0 | 730 | li r0, 0 |
| 715 | 731 | ||
| 716 | /* | 732 | /* |
| @@ -727,6 +743,7 @@ relocate_new_kernel: | |||
| 727 | rfi | 743 | rfi |
| 728 | 744 | ||
| 729 | 1: | 745 | 1: |
| 746 | #endif | ||
| 730 | /* from this point address translation is turned off */ | 747 | /* from this point address translation is turned off */ |
| 731 | /* and interrupts are disabled */ | 748 | /* and interrupts are disabled */ |
| 732 | 749 | ||
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 6646005dffb1..5b38f6ae2b29 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
| @@ -1309,6 +1309,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
| 1309 | printk(KERN_WARNING "PCI: Cannot allocate resource region " | 1309 | printk(KERN_WARNING "PCI: Cannot allocate resource region " |
| 1310 | "%d of PCI bridge %d, will remap\n", i, bus->number); | 1310 | "%d of PCI bridge %d, will remap\n", i, bus->number); |
| 1311 | clear_resource: | 1311 | clear_resource: |
| 1312 | res->start = res->end = 0; | ||
| 1312 | res->flags = 0; | 1313 | res->flags = 0; |
| 1313 | } | 1314 | } |
| 1314 | 1315 | ||
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index bc9f39d2598b..3b4dcc82a4c1 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
| @@ -101,7 +101,7 @@ EXPORT_SYMBOL(pci_dram_offset); | |||
| 101 | EXPORT_SYMBOL(start_thread); | 101 | EXPORT_SYMBOL(start_thread); |
| 102 | EXPORT_SYMBOL(kernel_thread); | 102 | EXPORT_SYMBOL(kernel_thread); |
| 103 | 103 | ||
| 104 | #ifndef CONFIG_BOOKE | 104 | #ifdef CONFIG_PPC_FPU |
| 105 | EXPORT_SYMBOL_GPL(cvt_df); | 105 | EXPORT_SYMBOL_GPL(cvt_df); |
| 106 | EXPORT_SYMBOL_GPL(cvt_fd); | 106 | EXPORT_SYMBOL_GPL(cvt_fd); |
| 107 | #endif | 107 | #endif |
diff --git a/arch/powerpc/kernel/swsusp_booke.S b/arch/powerpc/kernel/swsusp_booke.S new file mode 100644 index 000000000000..11a39307dd71 --- /dev/null +++ b/arch/powerpc/kernel/swsusp_booke.S | |||
| @@ -0,0 +1,193 @@ | |||
| 1 | /* | ||
| 2 | * Based on swsusp_32.S, modified for FSL BookE by | ||
| 3 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
| 4 | * Copyright (c) 2009-2010 MontaVista Software, LLC. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <linux/threads.h> | ||
| 8 | #include <asm/processor.h> | ||
| 9 | #include <asm/page.h> | ||
| 10 | #include <asm/cputable.h> | ||
| 11 | #include <asm/thread_info.h> | ||
| 12 | #include <asm/ppc_asm.h> | ||
| 13 | #include <asm/asm-offsets.h> | ||
| 14 | #include <asm/mmu.h> | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Structure for storing CPU registers on the save area. | ||
| 18 | */ | ||
| 19 | #define SL_SP 0 | ||
| 20 | #define SL_PC 4 | ||
| 21 | #define SL_MSR 8 | ||
| 22 | #define SL_TCR 0xc | ||
| 23 | #define SL_SPRG0 0x10 | ||
| 24 | #define SL_SPRG1 0x14 | ||
| 25 | #define SL_SPRG2 0x18 | ||
| 26 | #define SL_SPRG3 0x1c | ||
| 27 | #define SL_SPRG4 0x20 | ||
| 28 | #define SL_SPRG5 0x24 | ||
| 29 | #define SL_SPRG6 0x28 | ||
| 30 | #define SL_SPRG7 0x2c | ||
| 31 | #define SL_TBU 0x30 | ||
| 32 | #define SL_TBL 0x34 | ||
| 33 | #define SL_R2 0x38 | ||
| 34 | #define SL_CR 0x3c | ||
| 35 | #define SL_LR 0x40 | ||
| 36 | #define SL_R12 0x44 /* r12 to r31 */ | ||
| 37 | #define SL_SIZE (SL_R12 + 80) | ||
| 38 | |||
| 39 | .section .data | ||
| 40 | .align 5 | ||
| 41 | |||
| 42 | _GLOBAL(swsusp_save_area) | ||
| 43 | .space SL_SIZE | ||
| 44 | |||
| 45 | |||
| 46 | .section .text | ||
| 47 | .align 5 | ||
| 48 | |||
| 49 | _GLOBAL(swsusp_arch_suspend) | ||
| 50 | lis r11,swsusp_save_area@h | ||
| 51 | ori r11,r11,swsusp_save_area@l | ||
| 52 | |||
| 53 | mflr r0 | ||
| 54 | stw r0,SL_LR(r11) | ||
| 55 | mfcr r0 | ||
| 56 | stw r0,SL_CR(r11) | ||
| 57 | stw r1,SL_SP(r11) | ||
| 58 | stw r2,SL_R2(r11) | ||
| 59 | stmw r12,SL_R12(r11) | ||
| 60 | |||
| 61 | /* Save MSR & TCR */ | ||
| 62 | mfmsr r4 | ||
| 63 | stw r4,SL_MSR(r11) | ||
| 64 | mfspr r4,SPRN_TCR | ||
| 65 | stw r4,SL_TCR(r11) | ||
| 66 | |||
| 67 | /* Get a stable timebase and save it */ | ||
| 68 | 1: mfspr r4,SPRN_TBRU | ||
| 69 | stw r4,SL_TBU(r11) | ||
| 70 | mfspr r5,SPRN_TBRL | ||
| 71 | stw r5,SL_TBL(r11) | ||
| 72 | mfspr r3,SPRN_TBRU | ||
| 73 | cmpw r3,r4 | ||
| 74 | bne 1b | ||
| 75 | |||
| 76 | /* Save SPRGs */ | ||
| 77 | mfsprg r4,0 | ||
| 78 | stw r4,SL_SPRG0(r11) | ||
| 79 | mfsprg r4,1 | ||
| 80 | stw r4,SL_SPRG1(r11) | ||
| 81 | mfsprg r4,2 | ||
| 82 | stw r4,SL_SPRG2(r11) | ||
| 83 | mfsprg r4,3 | ||
| 84 | stw r4,SL_SPRG3(r11) | ||
| 85 | mfsprg r4,4 | ||
| 86 | stw r4,SL_SPRG4(r11) | ||
| 87 | mfsprg r4,5 | ||
| 88 | stw r4,SL_SPRG5(r11) | ||
| 89 | mfsprg r4,6 | ||
| 90 | stw r4,SL_SPRG6(r11) | ||
| 91 | mfsprg r4,7 | ||
| 92 | stw r4,SL_SPRG7(r11) | ||
| 93 | |||
| 94 | /* Call the low level suspend stuff (we should probably have made | ||
| 95 | * a stackframe... | ||
| 96 | */ | ||
| 97 | bl swsusp_save | ||
| 98 | |||
| 99 | /* Restore LR from the save area */ | ||
| 100 | lis r11,swsusp_save_area@h | ||
| 101 | ori r11,r11,swsusp_save_area@l | ||
| 102 | lwz r0,SL_LR(r11) | ||
| 103 | mtlr r0 | ||
| 104 | |||
| 105 | blr | ||
| 106 | |||
| 107 | _GLOBAL(swsusp_arch_resume) | ||
| 108 | sync | ||
| 109 | |||
| 110 | /* Load ptr the list of pages to copy in r3 */ | ||
| 111 | lis r11,(restore_pblist)@h | ||
| 112 | ori r11,r11,restore_pblist@l | ||
| 113 | lwz r3,0(r11) | ||
| 114 | |||
| 115 | /* Copy the pages. This is a very basic implementation, to | ||
| 116 | * be replaced by something more cache efficient */ | ||
| 117 | 1: | ||
| 118 | li r0,256 | ||
| 119 | mtctr r0 | ||
| 120 | lwz r5,pbe_address(r3) /* source */ | ||
| 121 | lwz r6,pbe_orig_address(r3) /* destination */ | ||
| 122 | 2: | ||
| 123 | lwz r8,0(r5) | ||
| 124 | lwz r9,4(r5) | ||
| 125 | lwz r10,8(r5) | ||
| 126 | lwz r11,12(r5) | ||
| 127 | addi r5,r5,16 | ||
| 128 | stw r8,0(r6) | ||
| 129 | stw r9,4(r6) | ||
| 130 | stw r10,8(r6) | ||
| 131 | stw r11,12(r6) | ||
| 132 | addi r6,r6,16 | ||
| 133 | bdnz 2b | ||
| 134 | lwz r3,pbe_next(r3) | ||
| 135 | cmpwi 0,r3,0 | ||
| 136 | bne 1b | ||
| 137 | |||
| 138 | bl flush_dcache_L1 | ||
| 139 | bl flush_instruction_cache | ||
| 140 | |||
| 141 | lis r11,swsusp_save_area@h | ||
| 142 | ori r11,r11,swsusp_save_area@l | ||
| 143 | |||
| 144 | lwz r4,SL_SPRG0(r11) | ||
| 145 | mtsprg 0,r4 | ||
| 146 | lwz r4,SL_SPRG1(r11) | ||
| 147 | mtsprg 1,r4 | ||
| 148 | lwz r4,SL_SPRG2(r11) | ||
| 149 | mtsprg 2,r4 | ||
| 150 | lwz r4,SL_SPRG3(r11) | ||
| 151 | mtsprg 3,r4 | ||
| 152 | lwz r4,SL_SPRG4(r11) | ||
| 153 | mtsprg 4,r4 | ||
| 154 | lwz r4,SL_SPRG5(r11) | ||
| 155 | mtsprg 5,r4 | ||
| 156 | lwz r4,SL_SPRG6(r11) | ||
| 157 | mtsprg 6,r4 | ||
| 158 | lwz r4,SL_SPRG7(r11) | ||
| 159 | mtsprg 7,r4 | ||
| 160 | |||
| 161 | /* restore the MSR */ | ||
| 162 | lwz r3,SL_MSR(r11) | ||
| 163 | mtmsr r3 | ||
| 164 | |||
| 165 | /* Restore TB */ | ||
| 166 | li r3,0 | ||
| 167 | mtspr SPRN_TBWL,r3 | ||
| 168 | lwz r3,SL_TBU(r11) | ||
| 169 | lwz r4,SL_TBL(r11) | ||
| 170 | mtspr SPRN_TBWU,r3 | ||
| 171 | mtspr SPRN_TBWL,r4 | ||
| 172 | |||
| 173 | /* Restore TCR and clear any pending bits in TSR. */ | ||
| 174 | lwz r4,SL_TCR(r11) | ||
| 175 | mtspr SPRN_TCR,r4 | ||
| 176 | lis r4, (TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS)@h | ||
| 177 | mtspr SPRN_TSR,r4 | ||
| 178 | |||
| 179 | /* Kick decrementer */ | ||
| 180 | li r0,1 | ||
| 181 | mtdec r0 | ||
| 182 | |||
| 183 | /* Restore the callee-saved registers and return */ | ||
| 184 | lwz r0,SL_CR(r11) | ||
| 185 | mtcr r0 | ||
| 186 | lwz r2,SL_R2(r11) | ||
| 187 | lmw r12,SL_R12(r11) | ||
| 188 | lwz r1,SL_SP(r11) | ||
| 189 | lwz r0,SL_LR(r11) | ||
| 190 | mtlr r0 | ||
| 191 | |||
| 192 | li r3,0 | ||
| 193 | blr | ||
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 3031fc712ad0..25fc33984c2b 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | 2 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) |
| 3 | * Copyright 2007-2010 Freescale Semiconductor, Inc. | ||
| 3 | * | 4 | * |
| 4 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
| 5 | * modify it under the terms of the GNU General Public License | 6 | * modify it under the terms of the GNU General Public License |
| @@ -305,7 +306,7 @@ static inline int check_io_access(struct pt_regs *regs) | |||
| 305 | #ifndef CONFIG_FSL_BOOKE | 306 | #ifndef CONFIG_FSL_BOOKE |
| 306 | #define get_mc_reason(regs) ((regs)->dsisr) | 307 | #define get_mc_reason(regs) ((regs)->dsisr) |
| 307 | #else | 308 | #else |
| 308 | #define get_mc_reason(regs) (mfspr(SPRN_MCSR) & MCSR_MASK) | 309 | #define get_mc_reason(regs) (mfspr(SPRN_MCSR)) |
| 309 | #endif | 310 | #endif |
| 310 | #define REASON_FP ESR_FP | 311 | #define REASON_FP ESR_FP |
| 311 | #define REASON_ILLEGAL (ESR_PIL | ESR_PUO) | 312 | #define REASON_ILLEGAL (ESR_PIL | ESR_PUO) |
| @@ -421,6 +422,91 @@ int machine_check_47x(struct pt_regs *regs) | |||
| 421 | return 0; | 422 | return 0; |
| 422 | } | 423 | } |
| 423 | #elif defined(CONFIG_E500) | 424 | #elif defined(CONFIG_E500) |
| 425 | int machine_check_e500mc(struct pt_regs *regs) | ||
| 426 | { | ||
| 427 | unsigned long mcsr = mfspr(SPRN_MCSR); | ||
| 428 | unsigned long reason = mcsr; | ||
| 429 | int recoverable = 1; | ||
| 430 | |||
| 431 | printk("Machine check in kernel mode.\n"); | ||
| 432 | printk("Caused by (from MCSR=%lx): ", reason); | ||
| 433 | |||
| 434 | if (reason & MCSR_MCP) | ||
| 435 | printk("Machine Check Signal\n"); | ||
| 436 | |||
| 437 | if (reason & MCSR_ICPERR) { | ||
| 438 | printk("Instruction Cache Parity Error\n"); | ||
| 439 | |||
| 440 | /* | ||
| 441 | * This is recoverable by invalidating the i-cache. | ||
| 442 | */ | ||
| 443 | mtspr(SPRN_L1CSR1, mfspr(SPRN_L1CSR1) | L1CSR1_ICFI); | ||
| 444 | while (mfspr(SPRN_L1CSR1) & L1CSR1_ICFI) | ||
| 445 | ; | ||
| 446 | |||
| 447 | /* | ||
| 448 | * This will generally be accompanied by an instruction | ||
| 449 | * fetch error report -- only treat MCSR_IF as fatal | ||
| 450 | * if it wasn't due to an L1 parity error. | ||
| 451 | */ | ||
| 452 | reason &= ~MCSR_IF; | ||
| 453 | } | ||
| 454 | |||
| 455 | if (reason & MCSR_DCPERR_MC) { | ||
| 456 | printk("Data Cache Parity Error\n"); | ||
| 457 | recoverable = 0; | ||
| 458 | } | ||
| 459 | |||
| 460 | if (reason & MCSR_L2MMU_MHIT) { | ||
| 461 | printk("Hit on multiple TLB entries\n"); | ||
| 462 | recoverable = 0; | ||
| 463 | } | ||
| 464 | |||
| 465 | if (reason & MCSR_NMI) | ||
| 466 | printk("Non-maskable interrupt\n"); | ||
| 467 | |||
| 468 | if (reason & MCSR_IF) { | ||
| 469 | printk("Instruction Fetch Error Report\n"); | ||
| 470 | recoverable = 0; | ||
| 471 | } | ||
| 472 | |||
| 473 | if (reason & MCSR_LD) { | ||
| 474 | printk("Load Error Report\n"); | ||
| 475 | recoverable = 0; | ||
| 476 | } | ||
| 477 | |||
| 478 | if (reason & MCSR_ST) { | ||
| 479 | printk("Store Error Report\n"); | ||
| 480 | recoverable = 0; | ||
| 481 | } | ||
| 482 | |||
| 483 | if (reason & MCSR_LDG) { | ||
| 484 | printk("Guarded Load Error Report\n"); | ||
| 485 | recoverable = 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | if (reason & MCSR_TLBSYNC) | ||
| 489 | printk("Simultaneous tlbsync operations\n"); | ||
| 490 | |||
| 491 | if (reason & MCSR_BSL2_ERR) { | ||
| 492 | printk("Level 2 Cache Error\n"); | ||
| 493 | recoverable = 0; | ||
| 494 | } | ||
| 495 | |||
| 496 | if (reason & MCSR_MAV) { | ||
| 497 | u64 addr; | ||
| 498 | |||
| 499 | addr = mfspr(SPRN_MCAR); | ||
| 500 | addr |= (u64)mfspr(SPRN_MCARU) << 32; | ||
| 501 | |||
| 502 | printk("Machine Check %s Address: %#llx\n", | ||
| 503 | reason & MCSR_MEA ? "Effective" : "Physical", addr); | ||
| 504 | } | ||
| 505 | |||
| 506 | mtspr(SPRN_MCSR, mcsr); | ||
| 507 | return mfspr(SPRN_MCSR) == 0 && recoverable; | ||
| 508 | } | ||
| 509 | |||
| 424 | int machine_check_e500(struct pt_regs *regs) | 510 | int machine_check_e500(struct pt_regs *regs) |
| 425 | { | 511 | { |
| 426 | unsigned long reason = get_mc_reason(regs); | 512 | unsigned long reason = get_mc_reason(regs); |
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index dcd01c82e701..8a0deefac08d 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S | |||
| @@ -223,19 +223,17 @@ SECTIONS | |||
| 223 | #endif | 223 | #endif |
| 224 | 224 | ||
| 225 | /* The initial task and kernel stack */ | 225 | /* The initial task and kernel stack */ |
| 226 | .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { | 226 | INIT_TASK_DATA_SECTION(THREAD_SIZE) |
| 227 | INIT_TASK_DATA(THREAD_SIZE) | ||
| 228 | } | ||
| 229 | 227 | ||
| 230 | .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { | 228 | .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) { |
| 231 | PAGE_ALIGNED_DATA(PAGE_SIZE) | 229 | PAGE_ALIGNED_DATA(PAGE_SIZE) |
| 232 | } | 230 | } |
| 233 | 231 | ||
| 234 | .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { | 232 | .data..cacheline_aligned : AT(ADDR(.data..cacheline_aligned) - LOAD_OFFSET) { |
| 235 | CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) | 233 | CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) |
| 236 | } | 234 | } |
| 237 | 235 | ||
| 238 | .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { | 236 | .data..read_mostly : AT(ADDR(.data..read_mostly) - LOAD_OFFSET) { |
| 239 | READ_MOSTLY_DATA(L1_CACHE_BYTES) | 237 | READ_MOSTLY_DATA(L1_CACHE_BYTES) |
| 240 | } | 238 | } |
| 241 | 239 | ||
