aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2007-11-07 22:28:14 -0500
committerPaul Mackerras <paulus@samba.org>2007-11-07 22:28:14 -0500
commit688016f4e2028e3c2c27e959ad001536e10ee2c5 (patch)
treef45baa7b2c115f1297b4ad8d30b306204ef5e537 /arch
parent2c84b4076c0cbbc44ffea2ae1da2a801fb23f081 (diff)
parent29273158f82020241d9a6539d6cef9cf926654c9 (diff)
Merge branch 'for-2.6.24' of master.kernel.org:/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx into merge
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/boot/dts/walnut.dts4
-rwxr-xr-xarch/powerpc/boot/wrapper32
-rw-r--r--arch/powerpc/kernel/cputable.c36
-rw-r--r--arch/powerpc/kernel/entry_32.S23
-rw-r--r--arch/powerpc/kernel/misc_32.S32
-rw-r--r--arch/powerpc/kernel/prom.c12
-rw-r--r--arch/powerpc/mm/40x_mmu.c17
-rw-r--r--arch/powerpc/mm/44x_mmu.c1
-rw-r--r--arch/powerpc/mm/fault.c2
-rw-r--r--arch/powerpc/mm/mmu_decl.h4
-rw-r--r--arch/ppc/kernel/entry.S23
-rw-r--r--arch/ppc/kernel/misc.S31
-rw-r--r--arch/ppc/mm/44x_mmu.c1
-rw-r--r--arch/ppc/mm/4xx_mmu.c17
-rw-r--r--arch/ppc/mm/fault.c2
-rw-r--r--arch/ppc/mm/mmu_decl.h4
-rw-r--r--arch/ppc/platforms/4xx/ebony.c2
-rw-r--r--arch/ppc/platforms/4xx/luan.c7
-rw-r--r--arch/ppc/platforms/4xx/ocotea.c2
-rw-r--r--arch/ppc/platforms/4xx/taishan.c2
20 files changed, 186 insertions, 68 deletions
diff --git a/arch/powerpc/boot/dts/walnut.dts b/arch/powerpc/boot/dts/walnut.dts
index fa681f5343fe..754fa3960f83 100644
--- a/arch/powerpc/boot/dts/walnut.dts
+++ b/arch/powerpc/boot/dts/walnut.dts
@@ -122,7 +122,9 @@
122 device_type = "network"; 122 device_type = "network";
123 compatible = "ibm,emac-405gp", "ibm,emac"; 123 compatible = "ibm,emac-405gp", "ibm,emac";
124 interrupt-parent = <&UIC0>; 124 interrupt-parent = <&UIC0>;
125 interrupts = <9 4 f 4>; 125 interrupts = <
126 f 4 /* Ethernet */
127 9 4 /* Ethernet Wake Up */>;
126 local-mac-address = [000000000000]; /* Filled in by zImage */ 128 local-mac-address = [000000000000]; /* Filled in by zImage */
127 reg = <ef600800 70>; 129 reg = <ef600800 70>;
128 mal-device = <&MAL>; 130 mal-device = <&MAL>;
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index ece6f49638da..31147a037728 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -21,6 +21,14 @@
21# (default ./arch/powerpc/boot) 21# (default ./arch/powerpc/boot)
22# -W dir specify working directory for temporary files (default .) 22# -W dir specify working directory for temporary files (default .)
23 23
24# Stop execution if any command fails
25set -e
26
27# Allow for verbose output
28if [ "$V" = 1 ]; then
29 set -x
30fi
31
24# defaults 32# defaults
25kernel= 33kernel=
26ofile=zImage 34ofile=zImage
@@ -111,7 +119,7 @@ if [ -n "$dts" ]; then
111 if [ -z "$dtb" ]; then 119 if [ -z "$dtb" ]; then
112 dtb="$platform.dtb" 120 dtb="$platform.dtb"
113 fi 121 fi
114 dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" || exit 1 122 dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts"
115fi 123fi
116 124
117if [ -z "$kernel" ]; then 125if [ -z "$kernel" ]; then
@@ -283,23 +291,13 @@ ps3)
283 291
284 ${CROSS}objcopy -O binary "$ofile" "$ofile.bin" 292 ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
285 293
286 msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \ 294 dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
287 skip=$overlay_dest seek=$system_reset_kernel \ 295 skip=$overlay_dest seek=$system_reset_kernel \
288 count=$overlay_size bs=1 2>&1) 296 count=$overlay_size bs=1
289 297
290 if [ $? -ne "0" ]; then 298 dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
291 echo $msg 299 skip=$system_reset_overlay seek=$overlay_dest \
292 exit 1 300 count=$overlay_size bs=1
293 fi
294
295 msg=$(dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
296 skip=$system_reset_overlay seek=$overlay_dest \
297 count=$overlay_size bs=1 2>&1)
298
299 if [ $? -ne "0" ]; then
300 echo $msg
301 exit 2
302 fi
303 301
304 gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld" 302 gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld"
305 ;; 303 ;;
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index d3fb7d0c6c1c..9ed351f3c966 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -1104,6 +1104,16 @@ static struct cpu_spec __initdata cpu_specs[] = {
1104 { 1104 {
1105 .pvr_mask = 0xf0000fff, 1105 .pvr_mask = 0xf0000fff,
1106 .pvr_value = 0x40000850, 1106 .pvr_value = 0x40000850,
1107 .cpu_name = "440GR Rev. A",
1108 .cpu_features = CPU_FTRS_44X,
1109 .cpu_user_features = COMMON_USER_BOOKE,
1110 .icache_bsize = 32,
1111 .dcache_bsize = 32,
1112 .platform = "ppc440",
1113 },
1114 { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
1115 .pvr_mask = 0xf0000fff,
1116 .pvr_value = 0x40000858,
1107 .cpu_name = "440EP Rev. A", 1117 .cpu_name = "440EP Rev. A",
1108 .cpu_features = CPU_FTRS_44X, 1118 .cpu_features = CPU_FTRS_44X,
1109 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, 1119 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
@@ -1115,28 +1125,27 @@ static struct cpu_spec __initdata cpu_specs[] = {
1115 { 1125 {
1116 .pvr_mask = 0xf0000fff, 1126 .pvr_mask = 0xf0000fff,
1117 .pvr_value = 0x400008d3, 1127 .pvr_value = 0x400008d3,
1118 .cpu_name = "440EP Rev. B", 1128 .cpu_name = "440GR Rev. B",
1119 .cpu_features = CPU_FTRS_44X, 1129 .cpu_features = CPU_FTRS_44X,
1120 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, 1130 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
1121 .icache_bsize = 32, 1131 .icache_bsize = 32,
1122 .dcache_bsize = 32, 1132 .dcache_bsize = 32,
1123 .cpu_setup = __setup_cpu_440ep,
1124 .platform = "ppc440", 1133 .platform = "ppc440",
1125 }, 1134 },
1126 { /* 440EPX */ 1135 { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */
1127 .pvr_mask = 0xf0000ffb, 1136 .pvr_mask = 0xf0000fff,
1128 .pvr_value = 0x200008D0, 1137 .pvr_value = 0x400008db,
1129 .cpu_name = "440EPX", 1138 .cpu_name = "440EP Rev. B",
1130 .cpu_features = CPU_FTRS_44X, 1139 .cpu_features = CPU_FTRS_44X,
1131 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, 1140 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
1132 .icache_bsize = 32, 1141 .icache_bsize = 32,
1133 .dcache_bsize = 32, 1142 .dcache_bsize = 32,
1134 .cpu_setup = __setup_cpu_440epx, 1143 .cpu_setup = __setup_cpu_440ep,
1135 .platform = "ppc440", 1144 .platform = "ppc440",
1136 }, 1145 },
1137 { /* 440GRX */ 1146 { /* 440GRX */
1138 .pvr_mask = 0xf0000ffb, 1147 .pvr_mask = 0xf0000ffb,
1139 .pvr_value = 0x200008D8, 1148 .pvr_value = 0x200008D0,
1140 .cpu_name = "440GRX", 1149 .cpu_name = "440GRX",
1141 .cpu_features = CPU_FTRS_44X, 1150 .cpu_features = CPU_FTRS_44X,
1142 .cpu_user_features = COMMON_USER_BOOKE, 1151 .cpu_user_features = COMMON_USER_BOOKE,
@@ -1145,6 +1154,17 @@ static struct cpu_spec __initdata cpu_specs[] = {
1145 .cpu_setup = __setup_cpu_440grx, 1154 .cpu_setup = __setup_cpu_440grx,
1146 .platform = "ppc440", 1155 .platform = "ppc440",
1147 }, 1156 },
1157 { /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */
1158 .pvr_mask = 0xf0000ffb,
1159 .pvr_value = 0x200008D8,
1160 .cpu_name = "440EPX",
1161 .cpu_features = CPU_FTRS_44X,
1162 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
1163 .icache_bsize = 32,
1164 .dcache_bsize = 32,
1165 .cpu_setup = __setup_cpu_440epx,
1166 .platform = "ppc440",
1167 },
1148 { /* 440GP Rev. B */ 1168 { /* 440GP Rev. B */
1149 .pvr_mask = 0xf0000fff, 1169 .pvr_mask = 0xf0000fff,
1150 .pvr_value = 0x40000440, 1170 .pvr_value = 0x40000440,
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 21d889e63e87..a7572cf464bd 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -244,6 +244,13 @@ syscall_exit_cont:
244 andis. r10,r0,DBCR0_IC@h 244 andis. r10,r0,DBCR0_IC@h
245 bnel- load_dbcr0 245 bnel- load_dbcr0
246#endif 246#endif
247#ifdef CONFIG_44x
248 lis r4,icache_44x_need_flush@ha
249 lwz r5,icache_44x_need_flush@l(r4)
250 cmplwi cr0,r5,0
251 bne- 2f
2521:
253#endif /* CONFIG_44x */
247 stwcx. r0,0,r1 /* to clear the reservation */ 254 stwcx. r0,0,r1 /* to clear the reservation */
248 lwz r4,_LINK(r1) 255 lwz r4,_LINK(r1)
249 lwz r5,_CCR(r1) 256 lwz r5,_CCR(r1)
@@ -258,6 +265,12 @@ syscall_exit_cont:
258 mtspr SPRN_SRR1,r8 265 mtspr SPRN_SRR1,r8
259 SYNC 266 SYNC
260 RFI 267 RFI
268#ifdef CONFIG_44x
2692: li r7,0
270 iccci r0,r0
271 stw r7,icache_44x_need_flush@l(r4)
272 b 1b
273#endif /* CONFIG_44x */
261 274
26266: li r3,-ENOSYS 27566: li r3,-ENOSYS
263 b ret_from_syscall 276 b ret_from_syscall
@@ -683,6 +696,16 @@ resume_kernel:
683 696
684 /* interrupts are hard-disabled at this point */ 697 /* interrupts are hard-disabled at this point */
685restore: 698restore:
699#ifdef CONFIG_44x
700 lis r4,icache_44x_need_flush@ha
701 lwz r5,icache_44x_need_flush@l(r4)
702 cmplwi cr0,r5,0
703 beq+ 1f
704 li r6,0
705 iccci r0,r0
706 stw r6,icache_44x_need_flush@l(r4)
7071:
708#endif /* CONFIG_44x */
686 lwz r0,GPR0(r1) 709 lwz r0,GPR0(r1)
687 lwz r2,GPR2(r1) 710 lwz r2,GPR2(r1)
688 REST_4GPRS(3, r1) 711 REST_4GPRS(3, r1)
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 8533de50347d..8b642ab26d37 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -288,7 +288,16 @@ _GLOBAL(_tlbia)
288 */ 288 */
289_GLOBAL(_tlbie) 289_GLOBAL(_tlbie)
290#if defined(CONFIG_40x) 290#if defined(CONFIG_40x)
291 /* We run the search with interrupts disabled because we have to change
292 * the PID and I don't want to preempt when that happens.
293 */
294 mfmsr r5
295 mfspr r6,SPRN_PID
296 wrteei 0
297 mtspr SPRN_PID,r4
291 tlbsx. r3, 0, r3 298 tlbsx. r3, 0, r3
299 mtspr SPRN_PID,r6
300 wrtee r5
292 bne 10f 301 bne 10f
293 sync 302 sync
294 /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear. 303 /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
@@ -297,23 +306,23 @@ _GLOBAL(_tlbie)
297 tlbwe r3, r3, TLB_TAG 306 tlbwe r3, r3, TLB_TAG
298 isync 307 isync
29910: 30810:
309
300#elif defined(CONFIG_44x) 310#elif defined(CONFIG_44x)
301 mfspr r4,SPRN_MMUCR 311 mfspr r5,SPRN_MMUCR
302 mfspr r5,SPRN_PID /* Get PID */ 312 rlwimi r5,r4,0,24,31 /* Set TID */
303 rlwimi r4,r5,0,24,31 /* Set TID */
304 313
305 /* We have to run the search with interrupts disabled, even critical 314 /* We have to run the search with interrupts disabled, even critical
306 * and debug interrupts (in fact the only critical exceptions we have 315 * and debug interrupts (in fact the only critical exceptions we have
307 * are debug and machine check). Otherwise an interrupt which causes 316 * are debug and machine check). Otherwise an interrupt which causes
308 * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */ 317 * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
309 mfmsr r5 318 mfmsr r4
310 lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha 319 lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
311 addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l 320 addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
312 andc r6,r5,r6 321 andc r6,r4,r6
313 mtmsr r6 322 mtmsr r6
314 mtspr SPRN_MMUCR,r4 323 mtspr SPRN_MMUCR,r5
315 tlbsx. r3, 0, r3 324 tlbsx. r3, 0, r3
316 mtmsr r5 325 mtmsr r4
317 bne 10f 326 bne 10f
318 sync 327 sync
319 /* There are only 64 TLB entries, so r3 < 64, 328 /* There are only 64 TLB entries, so r3 < 64,
@@ -534,12 +543,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
534 addi r3,r3,L1_CACHE_BYTES 543 addi r3,r3,L1_CACHE_BYTES
535 bdnz 0b 544 bdnz 0b
536 sync 545 sync
546#ifndef CONFIG_44x
547 /* We don't flush the icache on 44x. Those have a virtual icache
548 * and we don't have access to the virtual address here (it's
549 * not the page vaddr but where it's mapped in user space). The
550 * flushing of the icache on these is handled elsewhere, when
551 * a change in the address space occurs, before returning to
552 * user space
553 */
537 mtctr r4 554 mtctr r4
5381: icbi 0,r6 5551: icbi 0,r6
539 addi r6,r6,L1_CACHE_BYTES 556 addi r6,r6,L1_CACHE_BYTES
540 bdnz 1b 557 bdnz 1b
541 sync 558 sync
542 isync 559 isync
560#endif /* CONFIG_44x */
543 blr 561 blr
544 562
545/* 563/*
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 9f329a8928ea..acc0d247d3c3 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -697,6 +697,18 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
697 prop = of_get_flat_dt_prop(node, "cpu-version", NULL); 697 prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
698 if (prop && (*prop & 0xff000000) == 0x0f000000) 698 if (prop && (*prop & 0xff000000) == 0x0f000000)
699 identify_cpu(0, *prop); 699 identify_cpu(0, *prop);
700#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU)
701 /*
702 * Since 440GR(x)/440EP(x) processors have the same pvr,
703 * we check the node path and set bit 28 in the cur_cpu_spec
704 * pvr for EP(x) processor version. This bit is always 0 in
705 * the "real" pvr. Then we call identify_cpu again with
706 * the new logical pvr to enable FPU support.
707 */
708 if (strstr(uname, "440EP")) {
709 identify_cpu(0, cur_cpu_spec->pvr_value | 0x8);
710 }
711#endif
700 } 712 }
701 713
702 check_cpu_feature_properties(node); 714 check_cpu_feature_properties(node);
diff --git a/arch/powerpc/mm/40x_mmu.c b/arch/powerpc/mm/40x_mmu.c
index e067df836be2..3899ea97fbdf 100644
--- a/arch/powerpc/mm/40x_mmu.c
+++ b/arch/powerpc/mm/40x_mmu.c
@@ -98,13 +98,12 @@ unsigned long __init mmu_mapin_ram(void)
98 98
99 v = KERNELBASE; 99 v = KERNELBASE;
100 p = PPC_MEMSTART; 100 p = PPC_MEMSTART;
101 s = 0; 101 s = total_lowmem;
102 102
103 if (__map_without_ltlbs) { 103 if (__map_without_ltlbs)
104 return s; 104 return 0;
105 }
106 105
107 while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) { 106 while (s >= LARGE_PAGE_SIZE_16M) {
108 pmd_t *pmdp; 107 pmd_t *pmdp;
109 unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE; 108 unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
110 109
@@ -116,10 +115,10 @@ unsigned long __init mmu_mapin_ram(void)
116 115
117 v += LARGE_PAGE_SIZE_16M; 116 v += LARGE_PAGE_SIZE_16M;
118 p += LARGE_PAGE_SIZE_16M; 117 p += LARGE_PAGE_SIZE_16M;
119 s += LARGE_PAGE_SIZE_16M; 118 s -= LARGE_PAGE_SIZE_16M;
120 } 119 }
121 120
122 while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) { 121 while (s >= LARGE_PAGE_SIZE_4M) {
123 pmd_t *pmdp; 122 pmd_t *pmdp;
124 unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE; 123 unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
125 124
@@ -128,8 +127,8 @@ unsigned long __init mmu_mapin_ram(void)
128 127
129 v += LARGE_PAGE_SIZE_4M; 128 v += LARGE_PAGE_SIZE_4M;
130 p += LARGE_PAGE_SIZE_4M; 129 p += LARGE_PAGE_SIZE_4M;
131 s += LARGE_PAGE_SIZE_4M; 130 s -= LARGE_PAGE_SIZE_4M;
132 } 131 }
133 132
134 return s; 133 return total_lowmem - s;
135} 134}
diff --git a/arch/powerpc/mm/44x_mmu.c b/arch/powerpc/mm/44x_mmu.c
index c3df50476539..04dc08798d3d 100644
--- a/arch/powerpc/mm/44x_mmu.c
+++ b/arch/powerpc/mm/44x_mmu.c
@@ -35,6 +35,7 @@
35 */ 35 */
36unsigned int tlb_44x_index; /* = 0 */ 36unsigned int tlb_44x_index; /* = 0 */
37unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS; 37unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
38int icache_44x_need_flush;
38 39
39/* 40/*
40 * "Pins" a 256MB TLB entry in AS0 for kernel lowmem 41 * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index a18fda361cc0..8135da06e0a4 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -309,7 +309,7 @@ good_area:
309 set_bit(PG_arch_1, &page->flags); 309 set_bit(PG_arch_1, &page->flags);
310 } 310 }
311 pte_update(ptep, 0, _PAGE_HWEXEC); 311 pte_update(ptep, 0, _PAGE_HWEXEC);
312 _tlbie(address); 312 _tlbie(address, mm->context.id);
313 pte_unmap_unlock(ptep, ptl); 313 pte_unmap_unlock(ptep, ptl);
314 up_read(&mm->mmap_sem); 314 up_read(&mm->mmap_sem);
315 return 0; 315 return 0;
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index c94a64fd3c01..eb3a732e91db 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -61,12 +61,12 @@ extern unsigned long total_lowmem;
61#define mmu_mapin_ram() (0UL) 61#define mmu_mapin_ram() (0UL)
62 62
63#elif defined(CONFIG_4xx) 63#elif defined(CONFIG_4xx)
64#define flush_HPTE(X, va, pg) _tlbie(va) 64#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
65extern void MMU_init_hw(void); 65extern void MMU_init_hw(void);
66extern unsigned long mmu_mapin_ram(void); 66extern unsigned long mmu_mapin_ram(void);
67 67
68#elif defined(CONFIG_FSL_BOOKE) 68#elif defined(CONFIG_FSL_BOOKE)
69#define flush_HPTE(X, va, pg) _tlbie(va) 69#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
70extern void MMU_init_hw(void); 70extern void MMU_init_hw(void);
71extern unsigned long mmu_mapin_ram(void); 71extern unsigned long mmu_mapin_ram(void);
72extern void adjust_total_lowmem(void); 72extern void adjust_total_lowmem(void);
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index fba7ca17a67e..b19bfef2034d 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -244,6 +244,13 @@ syscall_exit_cont:
244 andis. r10,r0,DBCR0_IC@h 244 andis. r10,r0,DBCR0_IC@h
245 bnel- load_dbcr0 245 bnel- load_dbcr0
246#endif 246#endif
247#ifdef CONFIG_44x
248 lis r4,icache_44x_need_flush@ha
249 lwz r5,icache_44x_need_flush@l(r4)
250 cmplwi cr0,r5,0
251 bne- 2f
2521:
253#endif /* CONFIG_44x */
247 stwcx. r0,0,r1 /* to clear the reservation */ 254 stwcx. r0,0,r1 /* to clear the reservation */
248 lwz r4,_LINK(r1) 255 lwz r4,_LINK(r1)
249 lwz r5,_CCR(r1) 256 lwz r5,_CCR(r1)
@@ -258,6 +265,12 @@ syscall_exit_cont:
258 mtspr SPRN_SRR1,r8 265 mtspr SPRN_SRR1,r8
259 SYNC 266 SYNC
260 RFI 267 RFI
268#ifdef CONFIG_44x
2692: li r7,0
270 iccci r0,r0
271 stw r7,icache_44x_need_flush@l(r4)
272 b 1b
273#endif /* CONFIG_44x */
261 274
26266: li r3,-ENOSYS 27566: li r3,-ENOSYS
263 b ret_from_syscall 276 b ret_from_syscall
@@ -679,6 +692,16 @@ resume_kernel:
679 692
680 /* interrupts are hard-disabled at this point */ 693 /* interrupts are hard-disabled at this point */
681restore: 694restore:
695#ifdef CONFIG_44x
696 lis r4,icache_44x_need_flush@ha
697 lwz r5,icache_44x_need_flush@l(r4)
698 cmplwi cr0,r5,0
699 beq+ 1f
700 li r6,0
701 iccci r0,r0
702 stw r6,icache_44x_need_flush@l(r4)
7031:
704#endif /* CONFIG_44x */
682 lwz r0,GPR0(r1) 705 lwz r0,GPR0(r1)
683 lwz r2,GPR2(r1) 706 lwz r2,GPR2(r1)
684 REST_4GPRS(3, r1) 707 REST_4GPRS(3, r1)
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index a22e1f4d94c8..e0c850d85c53 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -224,7 +224,16 @@ _GLOBAL(_tlbia)
224 */ 224 */
225_GLOBAL(_tlbie) 225_GLOBAL(_tlbie)
226#if defined(CONFIG_40x) 226#if defined(CONFIG_40x)
227 /* We run the search with interrupts disabled because we have to change
228 * the PID and I don't want to preempt when that happens.
229 */
230 mfmsr r5
231 mfspr r6,SPRN_PID
232 wrteei 0
233 mtspr SPRN_PID,r4
227 tlbsx. r3, 0, r3 234 tlbsx. r3, 0, r3
235 mtspr SPRN_PID,r6
236 wrtee r5
228 bne 10f 237 bne 10f
229 sync 238 sync
230 /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear. 239 /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear.
@@ -234,22 +243,21 @@ _GLOBAL(_tlbie)
234 isync 243 isync
23510: 24410:
236#elif defined(CONFIG_44x) 245#elif defined(CONFIG_44x)
237 mfspr r4,SPRN_MMUCR 246 mfspr r5,SPRN_MMUCR
238 mfspr r5,SPRN_PID /* Get PID */ 247 rlwimi r5,r4,0,24,31 /* Set TID */
239 rlwimi r4,r5,0,24,31 /* Set TID */
240 248
241 /* We have to run the search with interrupts disabled, even critical 249 /* We have to run the search with interrupts disabled, even critical
242 * and debug interrupts (in fact the only critical exceptions we have 250 * and debug interrupts (in fact the only critical exceptions we have
243 * are debug and machine check). Otherwise an interrupt which causes 251 * are debug and machine check). Otherwise an interrupt which causes
244 * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */ 252 * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */
245 mfmsr r5 253 mfmsr r4
246 lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha 254 lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha
247 addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l 255 addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
248 andc r6,r5,r6 256 andc r6,r4,r6
249 mtmsr r6 257 mtmsr r6
250 mtspr SPRN_MMUCR,r4 258 mtspr SPRN_MMUCR,r5
251 tlbsx. r3, 0, r3 259 tlbsx. r3, 0, r3
252 mtmsr r5 260 mtmsr r4
253 bne 10f 261 bne 10f
254 sync 262 sync
255 /* There are only 64 TLB entries, so r3 < 64, 263 /* There are only 64 TLB entries, so r3 < 64,
@@ -491,12 +499,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
491 addi r3,r3,L1_CACHE_BYTES 499 addi r3,r3,L1_CACHE_BYTES
492 bdnz 0b 500 bdnz 0b
493 sync 501 sync
502#ifndef CONFIG_44x
503 /* We don't flush the icache on 44x. Those have a virtual icache
504 * and we don't have access to the virtual address here (it's
505 * not the page vaddr but where it's mapped in user space). The
506 * flushing of the icache on these is handled elsewhere, when
507 * a change in the address space occurs, before returning to
508 * user space
509 */
494 mtctr r4 510 mtctr r4
4951: icbi 0,r6 5111: icbi 0,r6
496 addi r6,r6,L1_CACHE_BYTES 512 addi r6,r6,L1_CACHE_BYTES
497 bdnz 1b 513 bdnz 1b
498 sync 514 sync
499 isync 515 isync
516#endif /* CONFIG_44x */
500 blr 517 blr
501 518
502/* 519/*
diff --git a/arch/ppc/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c
index 0a0a0487b334..6536a25cfcb8 100644
--- a/arch/ppc/mm/44x_mmu.c
+++ b/arch/ppc/mm/44x_mmu.c
@@ -61,6 +61,7 @@ extern char etext[], _stext[];
61 */ 61 */
62unsigned int tlb_44x_index = 0; 62unsigned int tlb_44x_index = 0;
63unsigned int tlb_44x_hwater = 62; 63unsigned int tlb_44x_hwater = 62;
64int icache_44x_need_flush;
64 65
65/* 66/*
66 * "Pins" a 256MB TLB entry in AS0 for kernel lowmem 67 * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
diff --git a/arch/ppc/mm/4xx_mmu.c b/arch/ppc/mm/4xx_mmu.c
index 838e09db71d9..ea785dbaac7c 100644
--- a/arch/ppc/mm/4xx_mmu.c
+++ b/arch/ppc/mm/4xx_mmu.c
@@ -99,13 +99,12 @@ unsigned long __init mmu_mapin_ram(void)
99 99
100 v = KERNELBASE; 100 v = KERNELBASE;
101 p = PPC_MEMSTART; 101 p = PPC_MEMSTART;
102 s = 0; 102 s = total_lowmem;
103 103
104 if (__map_without_ltlbs) { 104 if (__map_without_ltlbs)
105 return s; 105 return 0;
106 }
107 106
108 while (s <= (total_lowmem - LARGE_PAGE_SIZE_16M)) { 107 while (s >= LARGE_PAGE_SIZE_16M) {
109 pmd_t *pmdp; 108 pmd_t *pmdp;
110 unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE; 109 unsigned long val = p | _PMD_SIZE_16M | _PAGE_HWEXEC | _PAGE_HWWRITE;
111 110
@@ -117,10 +116,10 @@ unsigned long __init mmu_mapin_ram(void)
117 116
118 v += LARGE_PAGE_SIZE_16M; 117 v += LARGE_PAGE_SIZE_16M;
119 p += LARGE_PAGE_SIZE_16M; 118 p += LARGE_PAGE_SIZE_16M;
120 s += LARGE_PAGE_SIZE_16M; 119 s -= LARGE_PAGE_SIZE_16M;
121 } 120 }
122 121
123 while (s <= (total_lowmem - LARGE_PAGE_SIZE_4M)) { 122 while (s >= LARGE_PAGE_SIZE_4M) {
124 pmd_t *pmdp; 123 pmd_t *pmdp;
125 unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE; 124 unsigned long val = p | _PMD_SIZE_4M | _PAGE_HWEXEC | _PAGE_HWWRITE;
126 125
@@ -129,8 +128,8 @@ unsigned long __init mmu_mapin_ram(void)
129 128
130 v += LARGE_PAGE_SIZE_4M; 129 v += LARGE_PAGE_SIZE_4M;
131 p += LARGE_PAGE_SIZE_4M; 130 p += LARGE_PAGE_SIZE_4M;
132 s += LARGE_PAGE_SIZE_4M; 131 s -= LARGE_PAGE_SIZE_4M;
133 } 132 }
134 133
135 return s; 134 return total_lowmem - s;
136} 135}
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 254c23b755e6..36c0e7529edb 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -227,7 +227,7 @@ good_area:
227 set_bit(PG_arch_1, &page->flags); 227 set_bit(PG_arch_1, &page->flags);
228 } 228 }
229 pte_update(ptep, 0, _PAGE_HWEXEC); 229 pte_update(ptep, 0, _PAGE_HWEXEC);
230 _tlbie(address); 230 _tlbie(address, mm->context.id);
231 pte_unmap_unlock(ptep, ptl); 231 pte_unmap_unlock(ptep, ptl);
232 up_read(&mm->mmap_sem); 232 up_read(&mm->mmap_sem);
233 return 0; 233 return 0;
diff --git a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h
index 540f3292b229..f1d4f2109a99 100644
--- a/arch/ppc/mm/mmu_decl.h
+++ b/arch/ppc/mm/mmu_decl.h
@@ -54,12 +54,12 @@ extern unsigned int num_tlbcam_entries;
54#define mmu_mapin_ram() (0UL) 54#define mmu_mapin_ram() (0UL)
55 55
56#elif defined(CONFIG_4xx) 56#elif defined(CONFIG_4xx)
57#define flush_HPTE(X, va, pg) _tlbie(va) 57#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
58extern void MMU_init_hw(void); 58extern void MMU_init_hw(void);
59extern unsigned long mmu_mapin_ram(void); 59extern unsigned long mmu_mapin_ram(void);
60 60
61#elif defined(CONFIG_FSL_BOOKE) 61#elif defined(CONFIG_FSL_BOOKE)
62#define flush_HPTE(X, va, pg) _tlbie(va) 62#define flush_HPTE(pid, va, pg) _tlbie(va, pid)
63extern void MMU_init_hw(void); 63extern void MMU_init_hw(void);
64extern unsigned long mmu_mapin_ram(void); 64extern unsigned long mmu_mapin_ram(void);
65extern void adjust_total_lowmem(void); 65extern void adjust_total_lowmem(void);
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c
index 05d7184d7e14..453643a0eeea 100644
--- a/arch/ppc/platforms/4xx/ebony.c
+++ b/arch/ppc/platforms/4xx/ebony.c
@@ -236,7 +236,7 @@ ebony_early_serial_map(void)
236 gen550_init(0, &port); 236 gen550_init(0, &port);
237 237
238 /* Purge TLB entry added in head_44x.S for early serial access */ 238 /* Purge TLB entry added in head_44x.S for early serial access */
239 _tlbie(UART0_IO_BASE); 239 _tlbie(UART0_IO_BASE, 0);
240#endif 240#endif
241 241
242 port.membase = ioremap64(PPC440GP_UART1_ADDR, 8); 242 port.membase = ioremap64(PPC440GP_UART1_ADDR, 8);
diff --git a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c
index 4b169610f154..b79ebb8a3e6c 100644
--- a/arch/ppc/platforms/4xx/luan.c
+++ b/arch/ppc/platforms/4xx/luan.c
@@ -230,9 +230,14 @@ luan_setup_hoses(void)
230 230
231 /* Allocate hoses for PCIX1 and PCIX2 */ 231 /* Allocate hoses for PCIX1 and PCIX2 */
232 hose1 = pcibios_alloc_controller(); 232 hose1 = pcibios_alloc_controller();
233 if (!hose1)
234 return;
235
233 hose2 = pcibios_alloc_controller(); 236 hose2 = pcibios_alloc_controller();
234 if (!hose1 || !hose2) 237 if (!hose2) {
238 pcibios_free_controller(hose1);
235 return; 239 return;
240 }
236 241
237 /* Setup PCIX1 */ 242 /* Setup PCIX1 */
238 hose1->first_busno = 0; 243 hose1->first_busno = 0;
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
index fd0f971881d6..28a712cd4800 100644
--- a/arch/ppc/platforms/4xx/ocotea.c
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -259,7 +259,7 @@ ocotea_early_serial_map(void)
259 gen550_init(0, &port); 259 gen550_init(0, &port);
260 260
261 /* Purge TLB entry added in head_44x.S for early serial access */ 261 /* Purge TLB entry added in head_44x.S for early serial access */
262 _tlbie(UART0_IO_BASE); 262 _tlbie(UART0_IO_BASE, 0);
263#endif 263#endif
264 264
265 port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); 265 port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);
diff --git a/arch/ppc/platforms/4xx/taishan.c b/arch/ppc/platforms/4xx/taishan.c
index 888c492b4a45..f6a0c6650f33 100644
--- a/arch/ppc/platforms/4xx/taishan.c
+++ b/arch/ppc/platforms/4xx/taishan.c
@@ -316,7 +316,7 @@ taishan_early_serial_map(void)
316 gen550_init(0, &port); 316 gen550_init(0, &port);
317 317
318 /* Purge TLB entry added in head_44x.S for early serial access */ 318 /* Purge TLB entry added in head_44x.S for early serial access */
319 _tlbie(UART0_IO_BASE); 319 _tlbie(UART0_IO_BASE, 0);
320#endif 320#endif
321 321
322 port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); 322 port.membase = ioremap64(PPC440GX_UART1_ADDR, 8);