aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc
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/ppc
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/ppc')
-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
10 files changed, 68 insertions, 23 deletions
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);