diff options
Diffstat (limited to 'arch/powerpc/kernel')
40 files changed, 1216 insertions, 898 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index d17edb4a2f9d..1308a86e9070 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -103,6 +103,10 @@ endif | |||
103 | 103 | ||
104 | obj-$(CONFIG_PPC64) += $(obj64-y) | 104 | obj-$(CONFIG_PPC64) += $(obj64-y) |
105 | 105 | ||
106 | ifneq ($(CONFIG_XMON)$(CONFIG_KEXEC),) | ||
107 | obj-y += ppc_save_regs.o | ||
108 | endif | ||
109 | |||
106 | extra-$(CONFIG_PPC_FPU) += fpu.o | 110 | extra-$(CONFIG_PPC_FPU) += fpu.o |
107 | extra-$(CONFIG_PPC64) += entry_64.o | 111 | extra-$(CONFIG_PPC64) += entry_64.o |
108 | 112 | ||
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 75c5dd0138fd..661d07d2146b 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -60,6 +60,7 @@ int main(void) | |||
60 | { | 60 | { |
61 | DEFINE(THREAD, offsetof(struct task_struct, thread)); | 61 | DEFINE(THREAD, offsetof(struct task_struct, thread)); |
62 | DEFINE(MM, offsetof(struct task_struct, mm)); | 62 | DEFINE(MM, offsetof(struct task_struct, mm)); |
63 | DEFINE(MMCONTEXTID, offsetof(struct mm_struct, context.id)); | ||
63 | #ifdef CONFIG_PPC64 | 64 | #ifdef CONFIG_PPC64 |
64 | DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); | 65 | DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context)); |
65 | #else | 66 | #else |
@@ -306,6 +307,7 @@ int main(void) | |||
306 | DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32)); | 307 | DEFINE(CFG_SYSCALL_MAP32, offsetof(struct vdso_data, syscall_map_32)); |
307 | DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec)); | 308 | DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec)); |
308 | DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); | 309 | DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec)); |
310 | DEFINE(STAMP_XTIME, offsetof(struct vdso_data, stamp_xtime)); | ||
309 | DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size)); | 311 | DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size)); |
310 | DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size)); | 312 | DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size)); |
311 | DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size)); | 313 | DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size)); |
@@ -378,6 +380,10 @@ int main(void) | |||
378 | DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); | 380 | DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); |
379 | DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); | 381 | DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); |
380 | #endif | 382 | #endif |
383 | #ifdef CONFIG_44x | ||
384 | DEFINE(PGD_T_LOG2, PGD_T_LOG2); | ||
385 | DEFINE(PTE_T_LOG2, PTE_T_LOG2); | ||
386 | #endif | ||
381 | 387 | ||
382 | return 0; | 388 | return 0; |
383 | } | 389 | } |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 7e8719504f39..923f87aff20a 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/oprofile_impl.h> | 19 | #include <asm/oprofile_impl.h> |
20 | #include <asm/cputable.h> | 20 | #include <asm/cputable.h> |
21 | #include <asm/prom.h> /* for PTRRELOC on ARCH=ppc */ | 21 | #include <asm/prom.h> /* for PTRRELOC on ARCH=ppc */ |
22 | #include <asm/mmu.h> | ||
22 | 23 | ||
23 | struct cpu_spec* cur_cpu_spec = NULL; | 24 | struct cpu_spec* cur_cpu_spec = NULL; |
24 | EXPORT_SYMBOL(cur_cpu_spec); | 25 | EXPORT_SYMBOL(cur_cpu_spec); |
@@ -94,6 +95,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
94 | .cpu_name = "POWER3 (630)", | 95 | .cpu_name = "POWER3 (630)", |
95 | .cpu_features = CPU_FTRS_POWER3, | 96 | .cpu_features = CPU_FTRS_POWER3, |
96 | .cpu_user_features = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE, | 97 | .cpu_user_features = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE, |
98 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
97 | .icache_bsize = 128, | 99 | .icache_bsize = 128, |
98 | .dcache_bsize = 128, | 100 | .dcache_bsize = 128, |
99 | .num_pmcs = 8, | 101 | .num_pmcs = 8, |
@@ -109,6 +111,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
109 | .cpu_name = "POWER3 (630+)", | 111 | .cpu_name = "POWER3 (630+)", |
110 | .cpu_features = CPU_FTRS_POWER3, | 112 | .cpu_features = CPU_FTRS_POWER3, |
111 | .cpu_user_features = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE, | 113 | .cpu_user_features = COMMON_USER_PPC64|PPC_FEATURE_PPC_LE, |
114 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
112 | .icache_bsize = 128, | 115 | .icache_bsize = 128, |
113 | .dcache_bsize = 128, | 116 | .dcache_bsize = 128, |
114 | .num_pmcs = 8, | 117 | .num_pmcs = 8, |
@@ -124,6 +127,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
124 | .cpu_name = "RS64-II (northstar)", | 127 | .cpu_name = "RS64-II (northstar)", |
125 | .cpu_features = CPU_FTRS_RS64, | 128 | .cpu_features = CPU_FTRS_RS64, |
126 | .cpu_user_features = COMMON_USER_PPC64, | 129 | .cpu_user_features = COMMON_USER_PPC64, |
130 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
127 | .icache_bsize = 128, | 131 | .icache_bsize = 128, |
128 | .dcache_bsize = 128, | 132 | .dcache_bsize = 128, |
129 | .num_pmcs = 8, | 133 | .num_pmcs = 8, |
@@ -139,6 +143,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
139 | .cpu_name = "RS64-III (pulsar)", | 143 | .cpu_name = "RS64-III (pulsar)", |
140 | .cpu_features = CPU_FTRS_RS64, | 144 | .cpu_features = CPU_FTRS_RS64, |
141 | .cpu_user_features = COMMON_USER_PPC64, | 145 | .cpu_user_features = COMMON_USER_PPC64, |
146 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
142 | .icache_bsize = 128, | 147 | .icache_bsize = 128, |
143 | .dcache_bsize = 128, | 148 | .dcache_bsize = 128, |
144 | .num_pmcs = 8, | 149 | .num_pmcs = 8, |
@@ -154,6 +159,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
154 | .cpu_name = "RS64-III (icestar)", | 159 | .cpu_name = "RS64-III (icestar)", |
155 | .cpu_features = CPU_FTRS_RS64, | 160 | .cpu_features = CPU_FTRS_RS64, |
156 | .cpu_user_features = COMMON_USER_PPC64, | 161 | .cpu_user_features = COMMON_USER_PPC64, |
162 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
157 | .icache_bsize = 128, | 163 | .icache_bsize = 128, |
158 | .dcache_bsize = 128, | 164 | .dcache_bsize = 128, |
159 | .num_pmcs = 8, | 165 | .num_pmcs = 8, |
@@ -169,6 +175,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
169 | .cpu_name = "RS64-IV (sstar)", | 175 | .cpu_name = "RS64-IV (sstar)", |
170 | .cpu_features = CPU_FTRS_RS64, | 176 | .cpu_features = CPU_FTRS_RS64, |
171 | .cpu_user_features = COMMON_USER_PPC64, | 177 | .cpu_user_features = COMMON_USER_PPC64, |
178 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
172 | .icache_bsize = 128, | 179 | .icache_bsize = 128, |
173 | .dcache_bsize = 128, | 180 | .dcache_bsize = 128, |
174 | .num_pmcs = 8, | 181 | .num_pmcs = 8, |
@@ -184,6 +191,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
184 | .cpu_name = "POWER4 (gp)", | 191 | .cpu_name = "POWER4 (gp)", |
185 | .cpu_features = CPU_FTRS_POWER4, | 192 | .cpu_features = CPU_FTRS_POWER4, |
186 | .cpu_user_features = COMMON_USER_POWER4, | 193 | .cpu_user_features = COMMON_USER_POWER4, |
194 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
187 | .icache_bsize = 128, | 195 | .icache_bsize = 128, |
188 | .dcache_bsize = 128, | 196 | .dcache_bsize = 128, |
189 | .num_pmcs = 8, | 197 | .num_pmcs = 8, |
@@ -199,6 +207,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
199 | .cpu_name = "POWER4+ (gq)", | 207 | .cpu_name = "POWER4+ (gq)", |
200 | .cpu_features = CPU_FTRS_POWER4, | 208 | .cpu_features = CPU_FTRS_POWER4, |
201 | .cpu_user_features = COMMON_USER_POWER4, | 209 | .cpu_user_features = COMMON_USER_POWER4, |
210 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
202 | .icache_bsize = 128, | 211 | .icache_bsize = 128, |
203 | .dcache_bsize = 128, | 212 | .dcache_bsize = 128, |
204 | .num_pmcs = 8, | 213 | .num_pmcs = 8, |
@@ -215,6 +224,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
215 | .cpu_features = CPU_FTRS_PPC970, | 224 | .cpu_features = CPU_FTRS_PPC970, |
216 | .cpu_user_features = COMMON_USER_POWER4 | | 225 | .cpu_user_features = COMMON_USER_POWER4 | |
217 | PPC_FEATURE_HAS_ALTIVEC_COMP, | 226 | PPC_FEATURE_HAS_ALTIVEC_COMP, |
227 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
218 | .icache_bsize = 128, | 228 | .icache_bsize = 128, |
219 | .dcache_bsize = 128, | 229 | .dcache_bsize = 128, |
220 | .num_pmcs = 8, | 230 | .num_pmcs = 8, |
@@ -233,6 +243,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
233 | .cpu_features = CPU_FTRS_PPC970, | 243 | .cpu_features = CPU_FTRS_PPC970, |
234 | .cpu_user_features = COMMON_USER_POWER4 | | 244 | .cpu_user_features = COMMON_USER_POWER4 | |
235 | PPC_FEATURE_HAS_ALTIVEC_COMP, | 245 | PPC_FEATURE_HAS_ALTIVEC_COMP, |
246 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
236 | .icache_bsize = 128, | 247 | .icache_bsize = 128, |
237 | .dcache_bsize = 128, | 248 | .dcache_bsize = 128, |
238 | .num_pmcs = 8, | 249 | .num_pmcs = 8, |
@@ -251,6 +262,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
251 | .cpu_features = CPU_FTRS_PPC970, | 262 | .cpu_features = CPU_FTRS_PPC970, |
252 | .cpu_user_features = COMMON_USER_POWER4 | | 263 | .cpu_user_features = COMMON_USER_POWER4 | |
253 | PPC_FEATURE_HAS_ALTIVEC_COMP, | 264 | PPC_FEATURE_HAS_ALTIVEC_COMP, |
265 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
254 | .icache_bsize = 128, | 266 | .icache_bsize = 128, |
255 | .dcache_bsize = 128, | 267 | .dcache_bsize = 128, |
256 | .num_pmcs = 8, | 268 | .num_pmcs = 8, |
@@ -269,6 +281,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
269 | .cpu_features = CPU_FTRS_PPC970, | 281 | .cpu_features = CPU_FTRS_PPC970, |
270 | .cpu_user_features = COMMON_USER_POWER4 | | 282 | .cpu_user_features = COMMON_USER_POWER4 | |
271 | PPC_FEATURE_HAS_ALTIVEC_COMP, | 283 | PPC_FEATURE_HAS_ALTIVEC_COMP, |
284 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
272 | .icache_bsize = 128, | 285 | .icache_bsize = 128, |
273 | .dcache_bsize = 128, | 286 | .dcache_bsize = 128, |
274 | .num_pmcs = 8, | 287 | .num_pmcs = 8, |
@@ -287,6 +300,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
287 | .cpu_features = CPU_FTRS_PPC970, | 300 | .cpu_features = CPU_FTRS_PPC970, |
288 | .cpu_user_features = COMMON_USER_POWER4 | | 301 | .cpu_user_features = COMMON_USER_POWER4 | |
289 | PPC_FEATURE_HAS_ALTIVEC_COMP, | 302 | PPC_FEATURE_HAS_ALTIVEC_COMP, |
303 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
290 | .icache_bsize = 128, | 304 | .icache_bsize = 128, |
291 | .dcache_bsize = 128, | 305 | .dcache_bsize = 128, |
292 | .num_pmcs = 8, | 306 | .num_pmcs = 8, |
@@ -303,6 +317,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
303 | .cpu_name = "POWER5 (gr)", | 317 | .cpu_name = "POWER5 (gr)", |
304 | .cpu_features = CPU_FTRS_POWER5, | 318 | .cpu_features = CPU_FTRS_POWER5, |
305 | .cpu_user_features = COMMON_USER_POWER5, | 319 | .cpu_user_features = COMMON_USER_POWER5, |
320 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
306 | .icache_bsize = 128, | 321 | .icache_bsize = 128, |
307 | .dcache_bsize = 128, | 322 | .dcache_bsize = 128, |
308 | .num_pmcs = 6, | 323 | .num_pmcs = 6, |
@@ -323,6 +338,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
323 | .cpu_name = "POWER5+ (gs)", | 338 | .cpu_name = "POWER5+ (gs)", |
324 | .cpu_features = CPU_FTRS_POWER5, | 339 | .cpu_features = CPU_FTRS_POWER5, |
325 | .cpu_user_features = COMMON_USER_POWER5_PLUS, | 340 | .cpu_user_features = COMMON_USER_POWER5_PLUS, |
341 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
326 | .icache_bsize = 128, | 342 | .icache_bsize = 128, |
327 | .dcache_bsize = 128, | 343 | .dcache_bsize = 128, |
328 | .num_pmcs = 6, | 344 | .num_pmcs = 6, |
@@ -339,6 +355,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
339 | .cpu_name = "POWER5+ (gs)", | 355 | .cpu_name = "POWER5+ (gs)", |
340 | .cpu_features = CPU_FTRS_POWER5, | 356 | .cpu_features = CPU_FTRS_POWER5, |
341 | .cpu_user_features = COMMON_USER_POWER5_PLUS, | 357 | .cpu_user_features = COMMON_USER_POWER5_PLUS, |
358 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
342 | .icache_bsize = 128, | 359 | .icache_bsize = 128, |
343 | .dcache_bsize = 128, | 360 | .dcache_bsize = 128, |
344 | .num_pmcs = 6, | 361 | .num_pmcs = 6, |
@@ -356,6 +373,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
356 | .cpu_name = "POWER5+", | 373 | .cpu_name = "POWER5+", |
357 | .cpu_features = CPU_FTRS_POWER5, | 374 | .cpu_features = CPU_FTRS_POWER5, |
358 | .cpu_user_features = COMMON_USER_POWER5_PLUS, | 375 | .cpu_user_features = COMMON_USER_POWER5_PLUS, |
376 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
359 | .icache_bsize = 128, | 377 | .icache_bsize = 128, |
360 | .dcache_bsize = 128, | 378 | .dcache_bsize = 128, |
361 | .machine_check = machine_check_generic, | 379 | .machine_check = machine_check_generic, |
@@ -369,6 +387,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
369 | .cpu_features = CPU_FTRS_POWER6, | 387 | .cpu_features = CPU_FTRS_POWER6, |
370 | .cpu_user_features = COMMON_USER_POWER6 | | 388 | .cpu_user_features = COMMON_USER_POWER6 | |
371 | PPC_FEATURE_POWER6_EXT, | 389 | PPC_FEATURE_POWER6_EXT, |
390 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
372 | .icache_bsize = 128, | 391 | .icache_bsize = 128, |
373 | .dcache_bsize = 128, | 392 | .dcache_bsize = 128, |
374 | .num_pmcs = 6, | 393 | .num_pmcs = 6, |
@@ -388,6 +407,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
388 | .cpu_name = "POWER6 (architected)", | 407 | .cpu_name = "POWER6 (architected)", |
389 | .cpu_features = CPU_FTRS_POWER6, | 408 | .cpu_features = CPU_FTRS_POWER6, |
390 | .cpu_user_features = COMMON_USER_POWER6, | 409 | .cpu_user_features = COMMON_USER_POWER6, |
410 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
391 | .icache_bsize = 128, | 411 | .icache_bsize = 128, |
392 | .dcache_bsize = 128, | 412 | .dcache_bsize = 128, |
393 | .machine_check = machine_check_generic, | 413 | .machine_check = machine_check_generic, |
@@ -400,6 +420,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
400 | .cpu_name = "POWER7 (architected)", | 420 | .cpu_name = "POWER7 (architected)", |
401 | .cpu_features = CPU_FTRS_POWER7, | 421 | .cpu_features = CPU_FTRS_POWER7, |
402 | .cpu_user_features = COMMON_USER_POWER7, | 422 | .cpu_user_features = COMMON_USER_POWER7, |
423 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
403 | .icache_bsize = 128, | 424 | .icache_bsize = 128, |
404 | .dcache_bsize = 128, | 425 | .dcache_bsize = 128, |
405 | .machine_check = machine_check_generic, | 426 | .machine_check = machine_check_generic, |
@@ -412,6 +433,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
412 | .cpu_name = "POWER7 (raw)", | 433 | .cpu_name = "POWER7 (raw)", |
413 | .cpu_features = CPU_FTRS_POWER7, | 434 | .cpu_features = CPU_FTRS_POWER7, |
414 | .cpu_user_features = COMMON_USER_POWER7, | 435 | .cpu_user_features = COMMON_USER_POWER7, |
436 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
415 | .icache_bsize = 128, | 437 | .icache_bsize = 128, |
416 | .dcache_bsize = 128, | 438 | .dcache_bsize = 128, |
417 | .num_pmcs = 6, | 439 | .num_pmcs = 6, |
@@ -434,6 +456,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
434 | .cpu_user_features = COMMON_USER_PPC64 | | 456 | .cpu_user_features = COMMON_USER_PPC64 | |
435 | PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP | | 457 | PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP | |
436 | PPC_FEATURE_SMT, | 458 | PPC_FEATURE_SMT, |
459 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
437 | .icache_bsize = 128, | 460 | .icache_bsize = 128, |
438 | .dcache_bsize = 128, | 461 | .dcache_bsize = 128, |
439 | .num_pmcs = 4, | 462 | .num_pmcs = 4, |
@@ -449,6 +472,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
449 | .cpu_name = "PA6T", | 472 | .cpu_name = "PA6T", |
450 | .cpu_features = CPU_FTRS_PA6T, | 473 | .cpu_features = CPU_FTRS_PA6T, |
451 | .cpu_user_features = COMMON_USER_PA6T, | 474 | .cpu_user_features = COMMON_USER_PA6T, |
475 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
452 | .icache_bsize = 64, | 476 | .icache_bsize = 64, |
453 | .dcache_bsize = 64, | 477 | .dcache_bsize = 64, |
454 | .num_pmcs = 6, | 478 | .num_pmcs = 6, |
@@ -466,6 +490,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
466 | .cpu_name = "POWER4 (compatible)", | 490 | .cpu_name = "POWER4 (compatible)", |
467 | .cpu_features = CPU_FTRS_COMPATIBLE, | 491 | .cpu_features = CPU_FTRS_COMPATIBLE, |
468 | .cpu_user_features = COMMON_USER_PPC64, | 492 | .cpu_user_features = COMMON_USER_PPC64, |
493 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
469 | .icache_bsize = 128, | 494 | .icache_bsize = 128, |
470 | .dcache_bsize = 128, | 495 | .dcache_bsize = 128, |
471 | .num_pmcs = 6, | 496 | .num_pmcs = 6, |
@@ -483,6 +508,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
483 | .cpu_features = CPU_FTRS_PPC601, | 508 | .cpu_features = CPU_FTRS_PPC601, |
484 | .cpu_user_features = COMMON_USER | PPC_FEATURE_601_INSTR | | 509 | .cpu_user_features = COMMON_USER | PPC_FEATURE_601_INSTR | |
485 | PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB, | 510 | PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB, |
511 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
486 | .icache_bsize = 32, | 512 | .icache_bsize = 32, |
487 | .dcache_bsize = 32, | 513 | .dcache_bsize = 32, |
488 | .machine_check = machine_check_generic, | 514 | .machine_check = machine_check_generic, |
@@ -494,6 +520,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
494 | .cpu_name = "603", | 520 | .cpu_name = "603", |
495 | .cpu_features = CPU_FTRS_603, | 521 | .cpu_features = CPU_FTRS_603, |
496 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 522 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
523 | .mmu_features = 0, | ||
497 | .icache_bsize = 32, | 524 | .icache_bsize = 32, |
498 | .dcache_bsize = 32, | 525 | .dcache_bsize = 32, |
499 | .cpu_setup = __setup_cpu_603, | 526 | .cpu_setup = __setup_cpu_603, |
@@ -506,6 +533,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
506 | .cpu_name = "603e", | 533 | .cpu_name = "603e", |
507 | .cpu_features = CPU_FTRS_603, | 534 | .cpu_features = CPU_FTRS_603, |
508 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 535 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
536 | .mmu_features = 0, | ||
509 | .icache_bsize = 32, | 537 | .icache_bsize = 32, |
510 | .dcache_bsize = 32, | 538 | .dcache_bsize = 32, |
511 | .cpu_setup = __setup_cpu_603, | 539 | .cpu_setup = __setup_cpu_603, |
@@ -518,6 +546,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
518 | .cpu_name = "603ev", | 546 | .cpu_name = "603ev", |
519 | .cpu_features = CPU_FTRS_603, | 547 | .cpu_features = CPU_FTRS_603, |
520 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 548 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
549 | .mmu_features = 0, | ||
521 | .icache_bsize = 32, | 550 | .icache_bsize = 32, |
522 | .dcache_bsize = 32, | 551 | .dcache_bsize = 32, |
523 | .cpu_setup = __setup_cpu_603, | 552 | .cpu_setup = __setup_cpu_603, |
@@ -530,6 +559,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
530 | .cpu_name = "604", | 559 | .cpu_name = "604", |
531 | .cpu_features = CPU_FTRS_604, | 560 | .cpu_features = CPU_FTRS_604, |
532 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 561 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
562 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
533 | .icache_bsize = 32, | 563 | .icache_bsize = 32, |
534 | .dcache_bsize = 32, | 564 | .dcache_bsize = 32, |
535 | .num_pmcs = 2, | 565 | .num_pmcs = 2, |
@@ -543,6 +573,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
543 | .cpu_name = "604e", | 573 | .cpu_name = "604e", |
544 | .cpu_features = CPU_FTRS_604, | 574 | .cpu_features = CPU_FTRS_604, |
545 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 575 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
576 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
546 | .icache_bsize = 32, | 577 | .icache_bsize = 32, |
547 | .dcache_bsize = 32, | 578 | .dcache_bsize = 32, |
548 | .num_pmcs = 4, | 579 | .num_pmcs = 4, |
@@ -556,6 +587,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
556 | .cpu_name = "604r", | 587 | .cpu_name = "604r", |
557 | .cpu_features = CPU_FTRS_604, | 588 | .cpu_features = CPU_FTRS_604, |
558 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 589 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
590 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
559 | .icache_bsize = 32, | 591 | .icache_bsize = 32, |
560 | .dcache_bsize = 32, | 592 | .dcache_bsize = 32, |
561 | .num_pmcs = 4, | 593 | .num_pmcs = 4, |
@@ -569,6 +601,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
569 | .cpu_name = "604ev", | 601 | .cpu_name = "604ev", |
570 | .cpu_features = CPU_FTRS_604, | 602 | .cpu_features = CPU_FTRS_604, |
571 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 603 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
604 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
572 | .icache_bsize = 32, | 605 | .icache_bsize = 32, |
573 | .dcache_bsize = 32, | 606 | .dcache_bsize = 32, |
574 | .num_pmcs = 4, | 607 | .num_pmcs = 4, |
@@ -582,6 +615,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
582 | .cpu_name = "740/750", | 615 | .cpu_name = "740/750", |
583 | .cpu_features = CPU_FTRS_740_NOTAU, | 616 | .cpu_features = CPU_FTRS_740_NOTAU, |
584 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 617 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
618 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
585 | .icache_bsize = 32, | 619 | .icache_bsize = 32, |
586 | .dcache_bsize = 32, | 620 | .dcache_bsize = 32, |
587 | .num_pmcs = 4, | 621 | .num_pmcs = 4, |
@@ -595,6 +629,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
595 | .cpu_name = "750CX", | 629 | .cpu_name = "750CX", |
596 | .cpu_features = CPU_FTRS_750, | 630 | .cpu_features = CPU_FTRS_750, |
597 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 631 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
632 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
598 | .icache_bsize = 32, | 633 | .icache_bsize = 32, |
599 | .dcache_bsize = 32, | 634 | .dcache_bsize = 32, |
600 | .num_pmcs = 4, | 635 | .num_pmcs = 4, |
@@ -608,6 +643,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
608 | .cpu_name = "750CX", | 643 | .cpu_name = "750CX", |
609 | .cpu_features = CPU_FTRS_750, | 644 | .cpu_features = CPU_FTRS_750, |
610 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 645 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
646 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
611 | .icache_bsize = 32, | 647 | .icache_bsize = 32, |
612 | .dcache_bsize = 32, | 648 | .dcache_bsize = 32, |
613 | .num_pmcs = 4, | 649 | .num_pmcs = 4, |
@@ -622,6 +658,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
622 | .cpu_name = "750CXe", | 658 | .cpu_name = "750CXe", |
623 | .cpu_features = CPU_FTRS_750, | 659 | .cpu_features = CPU_FTRS_750, |
624 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 660 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
661 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
625 | .icache_bsize = 32, | 662 | .icache_bsize = 32, |
626 | .dcache_bsize = 32, | 663 | .dcache_bsize = 32, |
627 | .num_pmcs = 4, | 664 | .num_pmcs = 4, |
@@ -636,6 +673,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
636 | .cpu_name = "750CXe", | 673 | .cpu_name = "750CXe", |
637 | .cpu_features = CPU_FTRS_750, | 674 | .cpu_features = CPU_FTRS_750, |
638 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 675 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
676 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
639 | .icache_bsize = 32, | 677 | .icache_bsize = 32, |
640 | .dcache_bsize = 32, | 678 | .dcache_bsize = 32, |
641 | .num_pmcs = 4, | 679 | .num_pmcs = 4, |
@@ -650,6 +688,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
650 | .cpu_name = "750CL", | 688 | .cpu_name = "750CL", |
651 | .cpu_features = CPU_FTRS_750CL, | 689 | .cpu_features = CPU_FTRS_750CL, |
652 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 690 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
691 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
653 | .icache_bsize = 32, | 692 | .icache_bsize = 32, |
654 | .dcache_bsize = 32, | 693 | .dcache_bsize = 32, |
655 | .num_pmcs = 4, | 694 | .num_pmcs = 4, |
@@ -664,6 +703,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
664 | .cpu_name = "745/755", | 703 | .cpu_name = "745/755", |
665 | .cpu_features = CPU_FTRS_750, | 704 | .cpu_features = CPU_FTRS_750, |
666 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 705 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
706 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
667 | .icache_bsize = 32, | 707 | .icache_bsize = 32, |
668 | .dcache_bsize = 32, | 708 | .dcache_bsize = 32, |
669 | .num_pmcs = 4, | 709 | .num_pmcs = 4, |
@@ -678,6 +718,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
678 | .cpu_name = "750FX", | 718 | .cpu_name = "750FX", |
679 | .cpu_features = CPU_FTRS_750FX1, | 719 | .cpu_features = CPU_FTRS_750FX1, |
680 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 720 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
721 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
681 | .icache_bsize = 32, | 722 | .icache_bsize = 32, |
682 | .dcache_bsize = 32, | 723 | .dcache_bsize = 32, |
683 | .num_pmcs = 4, | 724 | .num_pmcs = 4, |
@@ -692,6 +733,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
692 | .cpu_name = "750FX", | 733 | .cpu_name = "750FX", |
693 | .cpu_features = CPU_FTRS_750FX2, | 734 | .cpu_features = CPU_FTRS_750FX2, |
694 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 735 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
736 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
695 | .icache_bsize = 32, | 737 | .icache_bsize = 32, |
696 | .dcache_bsize = 32, | 738 | .dcache_bsize = 32, |
697 | .num_pmcs = 4, | 739 | .num_pmcs = 4, |
@@ -706,6 +748,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
706 | .cpu_name = "750FX", | 748 | .cpu_name = "750FX", |
707 | .cpu_features = CPU_FTRS_750FX, | 749 | .cpu_features = CPU_FTRS_750FX, |
708 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 750 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
751 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
709 | .icache_bsize = 32, | 752 | .icache_bsize = 32, |
710 | .dcache_bsize = 32, | 753 | .dcache_bsize = 32, |
711 | .num_pmcs = 4, | 754 | .num_pmcs = 4, |
@@ -720,6 +763,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
720 | .cpu_name = "750GX", | 763 | .cpu_name = "750GX", |
721 | .cpu_features = CPU_FTRS_750GX, | 764 | .cpu_features = CPU_FTRS_750GX, |
722 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 765 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
766 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
723 | .icache_bsize = 32, | 767 | .icache_bsize = 32, |
724 | .dcache_bsize = 32, | 768 | .dcache_bsize = 32, |
725 | .num_pmcs = 4, | 769 | .num_pmcs = 4, |
@@ -734,6 +778,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
734 | .cpu_name = "740/750", | 778 | .cpu_name = "740/750", |
735 | .cpu_features = CPU_FTRS_740, | 779 | .cpu_features = CPU_FTRS_740, |
736 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, | 780 | .cpu_user_features = COMMON_USER | PPC_FEATURE_PPC_LE, |
781 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
737 | .icache_bsize = 32, | 782 | .icache_bsize = 32, |
738 | .dcache_bsize = 32, | 783 | .dcache_bsize = 32, |
739 | .num_pmcs = 4, | 784 | .num_pmcs = 4, |
@@ -749,6 +794,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
749 | .cpu_features = CPU_FTRS_7400_NOTAU, | 794 | .cpu_features = CPU_FTRS_7400_NOTAU, |
750 | .cpu_user_features = COMMON_USER | | 795 | .cpu_user_features = COMMON_USER | |
751 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 796 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
797 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
752 | .icache_bsize = 32, | 798 | .icache_bsize = 32, |
753 | .dcache_bsize = 32, | 799 | .dcache_bsize = 32, |
754 | .num_pmcs = 4, | 800 | .num_pmcs = 4, |
@@ -764,6 +810,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
764 | .cpu_features = CPU_FTRS_7400, | 810 | .cpu_features = CPU_FTRS_7400, |
765 | .cpu_user_features = COMMON_USER | | 811 | .cpu_user_features = COMMON_USER | |
766 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 812 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
813 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
767 | .icache_bsize = 32, | 814 | .icache_bsize = 32, |
768 | .dcache_bsize = 32, | 815 | .dcache_bsize = 32, |
769 | .num_pmcs = 4, | 816 | .num_pmcs = 4, |
@@ -779,6 +826,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
779 | .cpu_features = CPU_FTRS_7400, | 826 | .cpu_features = CPU_FTRS_7400, |
780 | .cpu_user_features = COMMON_USER | | 827 | .cpu_user_features = COMMON_USER | |
781 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 828 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
829 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
782 | .icache_bsize = 32, | 830 | .icache_bsize = 32, |
783 | .dcache_bsize = 32, | 831 | .dcache_bsize = 32, |
784 | .num_pmcs = 4, | 832 | .num_pmcs = 4, |
@@ -794,6 +842,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
794 | .cpu_features = CPU_FTRS_7450_20, | 842 | .cpu_features = CPU_FTRS_7450_20, |
795 | .cpu_user_features = COMMON_USER | | 843 | .cpu_user_features = COMMON_USER | |
796 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 844 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
845 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
797 | .icache_bsize = 32, | 846 | .icache_bsize = 32, |
798 | .dcache_bsize = 32, | 847 | .dcache_bsize = 32, |
799 | .num_pmcs = 6, | 848 | .num_pmcs = 6, |
@@ -811,6 +860,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
811 | .cpu_features = CPU_FTRS_7450_21, | 860 | .cpu_features = CPU_FTRS_7450_21, |
812 | .cpu_user_features = COMMON_USER | | 861 | .cpu_user_features = COMMON_USER | |
813 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 862 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
863 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
814 | .icache_bsize = 32, | 864 | .icache_bsize = 32, |
815 | .dcache_bsize = 32, | 865 | .dcache_bsize = 32, |
816 | .num_pmcs = 6, | 866 | .num_pmcs = 6, |
@@ -828,6 +878,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
828 | .cpu_features = CPU_FTRS_7450_23, | 878 | .cpu_features = CPU_FTRS_7450_23, |
829 | .cpu_user_features = COMMON_USER | | 879 | .cpu_user_features = COMMON_USER | |
830 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 880 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
881 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
831 | .icache_bsize = 32, | 882 | .icache_bsize = 32, |
832 | .dcache_bsize = 32, | 883 | .dcache_bsize = 32, |
833 | .num_pmcs = 6, | 884 | .num_pmcs = 6, |
@@ -845,6 +896,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
845 | .cpu_features = CPU_FTRS_7455_1, | 896 | .cpu_features = CPU_FTRS_7455_1, |
846 | .cpu_user_features = COMMON_USER | | 897 | .cpu_user_features = COMMON_USER | |
847 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 898 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
899 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
848 | .icache_bsize = 32, | 900 | .icache_bsize = 32, |
849 | .dcache_bsize = 32, | 901 | .dcache_bsize = 32, |
850 | .num_pmcs = 6, | 902 | .num_pmcs = 6, |
@@ -862,6 +914,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
862 | .cpu_features = CPU_FTRS_7455_20, | 914 | .cpu_features = CPU_FTRS_7455_20, |
863 | .cpu_user_features = COMMON_USER | | 915 | .cpu_user_features = COMMON_USER | |
864 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 916 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
917 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
865 | .icache_bsize = 32, | 918 | .icache_bsize = 32, |
866 | .dcache_bsize = 32, | 919 | .dcache_bsize = 32, |
867 | .num_pmcs = 6, | 920 | .num_pmcs = 6, |
@@ -879,6 +932,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
879 | .cpu_features = CPU_FTRS_7455, | 932 | .cpu_features = CPU_FTRS_7455, |
880 | .cpu_user_features = COMMON_USER | | 933 | .cpu_user_features = COMMON_USER | |
881 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 934 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
935 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
882 | .icache_bsize = 32, | 936 | .icache_bsize = 32, |
883 | .dcache_bsize = 32, | 937 | .dcache_bsize = 32, |
884 | .num_pmcs = 6, | 938 | .num_pmcs = 6, |
@@ -896,6 +950,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
896 | .cpu_features = CPU_FTRS_7447_10, | 950 | .cpu_features = CPU_FTRS_7447_10, |
897 | .cpu_user_features = COMMON_USER | | 951 | .cpu_user_features = COMMON_USER | |
898 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 952 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
953 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
899 | .icache_bsize = 32, | 954 | .icache_bsize = 32, |
900 | .dcache_bsize = 32, | 955 | .dcache_bsize = 32, |
901 | .num_pmcs = 6, | 956 | .num_pmcs = 6, |
@@ -913,6 +968,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
913 | .cpu_features = CPU_FTRS_7447_10, | 968 | .cpu_features = CPU_FTRS_7447_10, |
914 | .cpu_user_features = COMMON_USER | | 969 | .cpu_user_features = COMMON_USER | |
915 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 970 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
971 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
916 | .icache_bsize = 32, | 972 | .icache_bsize = 32, |
917 | .dcache_bsize = 32, | 973 | .dcache_bsize = 32, |
918 | .num_pmcs = 6, | 974 | .num_pmcs = 6, |
@@ -929,6 +985,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
929 | .cpu_name = "7447/7457", | 985 | .cpu_name = "7447/7457", |
930 | .cpu_features = CPU_FTRS_7447, | 986 | .cpu_features = CPU_FTRS_7447, |
931 | .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 987 | .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
988 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
932 | .icache_bsize = 32, | 989 | .icache_bsize = 32, |
933 | .dcache_bsize = 32, | 990 | .dcache_bsize = 32, |
934 | .num_pmcs = 6, | 991 | .num_pmcs = 6, |
@@ -946,6 +1003,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
946 | .cpu_features = CPU_FTRS_7447A, | 1003 | .cpu_features = CPU_FTRS_7447A, |
947 | .cpu_user_features = COMMON_USER | | 1004 | .cpu_user_features = COMMON_USER | |
948 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 1005 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
1006 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
949 | .icache_bsize = 32, | 1007 | .icache_bsize = 32, |
950 | .dcache_bsize = 32, | 1008 | .dcache_bsize = 32, |
951 | .num_pmcs = 6, | 1009 | .num_pmcs = 6, |
@@ -963,6 +1021,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
963 | .cpu_features = CPU_FTRS_7448, | 1021 | .cpu_features = CPU_FTRS_7448, |
964 | .cpu_user_features = COMMON_USER | | 1022 | .cpu_user_features = COMMON_USER | |
965 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, | 1023 | PPC_FEATURE_HAS_ALTIVEC_COMP | PPC_FEATURE_PPC_LE, |
1024 | .mmu_features = MMU_FTR_HPTE_TABLE | MMU_FTR_USE_HIGH_BATS, | ||
966 | .icache_bsize = 32, | 1025 | .icache_bsize = 32, |
967 | .dcache_bsize = 32, | 1026 | .dcache_bsize = 32, |
968 | .num_pmcs = 6, | 1027 | .num_pmcs = 6, |
@@ -979,6 +1038,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
979 | .cpu_name = "82xx", | 1038 | .cpu_name = "82xx", |
980 | .cpu_features = CPU_FTRS_82XX, | 1039 | .cpu_features = CPU_FTRS_82XX, |
981 | .cpu_user_features = COMMON_USER, | 1040 | .cpu_user_features = COMMON_USER, |
1041 | .mmu_features = 0, | ||
982 | .icache_bsize = 32, | 1042 | .icache_bsize = 32, |
983 | .dcache_bsize = 32, | 1043 | .dcache_bsize = 32, |
984 | .cpu_setup = __setup_cpu_603, | 1044 | .cpu_setup = __setup_cpu_603, |
@@ -991,6 +1051,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
991 | .cpu_name = "G2_LE", | 1051 | .cpu_name = "G2_LE", |
992 | .cpu_features = CPU_FTRS_G2_LE, | 1052 | .cpu_features = CPU_FTRS_G2_LE, |
993 | .cpu_user_features = COMMON_USER, | 1053 | .cpu_user_features = COMMON_USER, |
1054 | .mmu_features = MMU_FTR_USE_HIGH_BATS, | ||
994 | .icache_bsize = 32, | 1055 | .icache_bsize = 32, |
995 | .dcache_bsize = 32, | 1056 | .dcache_bsize = 32, |
996 | .cpu_setup = __setup_cpu_603, | 1057 | .cpu_setup = __setup_cpu_603, |
@@ -1003,6 +1064,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1003 | .cpu_name = "e300c1", | 1064 | .cpu_name = "e300c1", |
1004 | .cpu_features = CPU_FTRS_E300, | 1065 | .cpu_features = CPU_FTRS_E300, |
1005 | .cpu_user_features = COMMON_USER, | 1066 | .cpu_user_features = COMMON_USER, |
1067 | .mmu_features = MMU_FTR_USE_HIGH_BATS, | ||
1006 | .icache_bsize = 32, | 1068 | .icache_bsize = 32, |
1007 | .dcache_bsize = 32, | 1069 | .dcache_bsize = 32, |
1008 | .cpu_setup = __setup_cpu_603, | 1070 | .cpu_setup = __setup_cpu_603, |
@@ -1015,6 +1077,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1015 | .cpu_name = "e300c2", | 1077 | .cpu_name = "e300c2", |
1016 | .cpu_features = CPU_FTRS_E300C2, | 1078 | .cpu_features = CPU_FTRS_E300C2, |
1017 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 1079 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, |
1080 | .mmu_features = MMU_FTR_USE_HIGH_BATS, | ||
1018 | .icache_bsize = 32, | 1081 | .icache_bsize = 32, |
1019 | .dcache_bsize = 32, | 1082 | .dcache_bsize = 32, |
1020 | .cpu_setup = __setup_cpu_603, | 1083 | .cpu_setup = __setup_cpu_603, |
@@ -1027,6 +1090,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1027 | .cpu_name = "e300c3", | 1090 | .cpu_name = "e300c3", |
1028 | .cpu_features = CPU_FTRS_E300, | 1091 | .cpu_features = CPU_FTRS_E300, |
1029 | .cpu_user_features = COMMON_USER, | 1092 | .cpu_user_features = COMMON_USER, |
1093 | .mmu_features = MMU_FTR_USE_HIGH_BATS, | ||
1030 | .icache_bsize = 32, | 1094 | .icache_bsize = 32, |
1031 | .dcache_bsize = 32, | 1095 | .dcache_bsize = 32, |
1032 | .cpu_setup = __setup_cpu_603, | 1096 | .cpu_setup = __setup_cpu_603, |
@@ -1041,6 +1105,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1041 | .cpu_name = "e300c4", | 1105 | .cpu_name = "e300c4", |
1042 | .cpu_features = CPU_FTRS_E300, | 1106 | .cpu_features = CPU_FTRS_E300, |
1043 | .cpu_user_features = COMMON_USER, | 1107 | .cpu_user_features = COMMON_USER, |
1108 | .mmu_features = MMU_FTR_USE_HIGH_BATS, | ||
1044 | .icache_bsize = 32, | 1109 | .icache_bsize = 32, |
1045 | .dcache_bsize = 32, | 1110 | .dcache_bsize = 32, |
1046 | .cpu_setup = __setup_cpu_603, | 1111 | .cpu_setup = __setup_cpu_603, |
@@ -1056,6 +1121,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1056 | .cpu_name = "(generic PPC)", | 1121 | .cpu_name = "(generic PPC)", |
1057 | .cpu_features = CPU_FTRS_CLASSIC32, | 1122 | .cpu_features = CPU_FTRS_CLASSIC32, |
1058 | .cpu_user_features = COMMON_USER, | 1123 | .cpu_user_features = COMMON_USER, |
1124 | .mmu_features = MMU_FTR_HPTE_TABLE, | ||
1059 | .icache_bsize = 32, | 1125 | .icache_bsize = 32, |
1060 | .dcache_bsize = 32, | 1126 | .dcache_bsize = 32, |
1061 | .machine_check = machine_check_generic, | 1127 | .machine_check = machine_check_generic, |
@@ -1071,6 +1137,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1071 | * if the 8xx code is there.... */ | 1137 | * if the 8xx code is there.... */ |
1072 | .cpu_features = CPU_FTRS_8XX, | 1138 | .cpu_features = CPU_FTRS_8XX, |
1073 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 1139 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, |
1140 | .mmu_features = MMU_FTR_TYPE_8xx, | ||
1074 | .icache_bsize = 16, | 1141 | .icache_bsize = 16, |
1075 | .dcache_bsize = 16, | 1142 | .dcache_bsize = 16, |
1076 | .platform = "ppc823", | 1143 | .platform = "ppc823", |
@@ -1083,6 +1150,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1083 | .cpu_name = "403GC", | 1150 | .cpu_name = "403GC", |
1084 | .cpu_features = CPU_FTRS_40X, | 1151 | .cpu_features = CPU_FTRS_40X, |
1085 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 1152 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, |
1153 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1086 | .icache_bsize = 16, | 1154 | .icache_bsize = 16, |
1087 | .dcache_bsize = 16, | 1155 | .dcache_bsize = 16, |
1088 | .machine_check = machine_check_4xx, | 1156 | .machine_check = machine_check_4xx, |
@@ -1095,6 +1163,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1095 | .cpu_features = CPU_FTRS_40X, | 1163 | .cpu_features = CPU_FTRS_40X, |
1096 | .cpu_user_features = PPC_FEATURE_32 | | 1164 | .cpu_user_features = PPC_FEATURE_32 | |
1097 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB, | 1165 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB, |
1166 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1098 | .icache_bsize = 16, | 1167 | .icache_bsize = 16, |
1099 | .dcache_bsize = 16, | 1168 | .dcache_bsize = 16, |
1100 | .machine_check = machine_check_4xx, | 1169 | .machine_check = machine_check_4xx, |
@@ -1106,6 +1175,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1106 | .cpu_name = "403G ??", | 1175 | .cpu_name = "403G ??", |
1107 | .cpu_features = CPU_FTRS_40X, | 1176 | .cpu_features = CPU_FTRS_40X, |
1108 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 1177 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, |
1178 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1109 | .icache_bsize = 16, | 1179 | .icache_bsize = 16, |
1110 | .dcache_bsize = 16, | 1180 | .dcache_bsize = 16, |
1111 | .machine_check = machine_check_4xx, | 1181 | .machine_check = machine_check_4xx, |
@@ -1118,6 +1188,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1118 | .cpu_features = CPU_FTRS_40X, | 1188 | .cpu_features = CPU_FTRS_40X, |
1119 | .cpu_user_features = PPC_FEATURE_32 | | 1189 | .cpu_user_features = PPC_FEATURE_32 | |
1120 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1190 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1191 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1121 | .icache_bsize = 32, | 1192 | .icache_bsize = 32, |
1122 | .dcache_bsize = 32, | 1193 | .dcache_bsize = 32, |
1123 | .machine_check = machine_check_4xx, | 1194 | .machine_check = machine_check_4xx, |
@@ -1130,6 +1201,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1130 | .cpu_features = CPU_FTRS_40X, | 1201 | .cpu_features = CPU_FTRS_40X, |
1131 | .cpu_user_features = PPC_FEATURE_32 | | 1202 | .cpu_user_features = PPC_FEATURE_32 | |
1132 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1203 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1204 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1133 | .icache_bsize = 32, | 1205 | .icache_bsize = 32, |
1134 | .dcache_bsize = 32, | 1206 | .dcache_bsize = 32, |
1135 | .machine_check = machine_check_4xx, | 1207 | .machine_check = machine_check_4xx, |
@@ -1142,6 +1214,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1142 | .cpu_features = CPU_FTRS_40X, | 1214 | .cpu_features = CPU_FTRS_40X, |
1143 | .cpu_user_features = PPC_FEATURE_32 | | 1215 | .cpu_user_features = PPC_FEATURE_32 | |
1144 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1216 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1217 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1145 | .icache_bsize = 32, | 1218 | .icache_bsize = 32, |
1146 | .dcache_bsize = 32, | 1219 | .dcache_bsize = 32, |
1147 | .machine_check = machine_check_4xx, | 1220 | .machine_check = machine_check_4xx, |
@@ -1154,6 +1227,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1154 | .cpu_features = CPU_FTRS_40X, | 1227 | .cpu_features = CPU_FTRS_40X, |
1155 | .cpu_user_features = PPC_FEATURE_32 | | 1228 | .cpu_user_features = PPC_FEATURE_32 | |
1156 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1229 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1230 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1157 | .icache_bsize = 32, | 1231 | .icache_bsize = 32, |
1158 | .dcache_bsize = 32, | 1232 | .dcache_bsize = 32, |
1159 | .machine_check = machine_check_4xx, | 1233 | .machine_check = machine_check_4xx, |
@@ -1166,6 +1240,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1166 | .cpu_features = CPU_FTRS_40X, | 1240 | .cpu_features = CPU_FTRS_40X, |
1167 | .cpu_user_features = PPC_FEATURE_32 | | 1241 | .cpu_user_features = PPC_FEATURE_32 | |
1168 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1242 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1243 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1169 | .icache_bsize = 32, | 1244 | .icache_bsize = 32, |
1170 | .dcache_bsize = 32, | 1245 | .dcache_bsize = 32, |
1171 | .machine_check = machine_check_4xx, | 1246 | .machine_check = machine_check_4xx, |
@@ -1178,6 +1253,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1178 | .cpu_features = CPU_FTRS_40X, | 1253 | .cpu_features = CPU_FTRS_40X, |
1179 | .cpu_user_features = PPC_FEATURE_32 | | 1254 | .cpu_user_features = PPC_FEATURE_32 | |
1180 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1255 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1256 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1181 | .icache_bsize = 32, | 1257 | .icache_bsize = 32, |
1182 | .dcache_bsize = 32, | 1258 | .dcache_bsize = 32, |
1183 | .machine_check = machine_check_4xx, | 1259 | .machine_check = machine_check_4xx, |
@@ -1190,6 +1266,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1190 | .cpu_features = CPU_FTRS_40X, | 1266 | .cpu_features = CPU_FTRS_40X, |
1191 | .cpu_user_features = PPC_FEATURE_32 | | 1267 | .cpu_user_features = PPC_FEATURE_32 | |
1192 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1268 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1269 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1193 | .icache_bsize = 32, | 1270 | .icache_bsize = 32, |
1194 | .dcache_bsize = 32, | 1271 | .dcache_bsize = 32, |
1195 | .machine_check = machine_check_4xx, | 1272 | .machine_check = machine_check_4xx, |
@@ -1202,6 +1279,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1202 | .cpu_features = CPU_FTRS_40X, | 1279 | .cpu_features = CPU_FTRS_40X, |
1203 | .cpu_user_features = PPC_FEATURE_32 | | 1280 | .cpu_user_features = PPC_FEATURE_32 | |
1204 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1281 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1282 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1205 | .icache_bsize = 32, | 1283 | .icache_bsize = 32, |
1206 | .dcache_bsize = 32, | 1284 | .dcache_bsize = 32, |
1207 | .machine_check = machine_check_4xx, | 1285 | .machine_check = machine_check_4xx, |
@@ -1213,6 +1291,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1213 | .cpu_name = "405LP", | 1291 | .cpu_name = "405LP", |
1214 | .cpu_features = CPU_FTRS_40X, | 1292 | .cpu_features = CPU_FTRS_40X, |
1215 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, | 1293 | .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, |
1294 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1216 | .icache_bsize = 32, | 1295 | .icache_bsize = 32, |
1217 | .dcache_bsize = 32, | 1296 | .dcache_bsize = 32, |
1218 | .machine_check = machine_check_4xx, | 1297 | .machine_check = machine_check_4xx, |
@@ -1225,6 +1304,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1225 | .cpu_features = CPU_FTRS_40X, | 1304 | .cpu_features = CPU_FTRS_40X, |
1226 | .cpu_user_features = PPC_FEATURE_32 | | 1305 | .cpu_user_features = PPC_FEATURE_32 | |
1227 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1306 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1307 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1228 | .icache_bsize = 32, | 1308 | .icache_bsize = 32, |
1229 | .dcache_bsize = 32, | 1309 | .dcache_bsize = 32, |
1230 | .machine_check = machine_check_4xx, | 1310 | .machine_check = machine_check_4xx, |
@@ -1237,6 +1317,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1237 | .cpu_features = CPU_FTRS_40X, | 1317 | .cpu_features = CPU_FTRS_40X, |
1238 | .cpu_user_features = PPC_FEATURE_32 | | 1318 | .cpu_user_features = PPC_FEATURE_32 | |
1239 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1319 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1320 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1240 | .icache_bsize = 32, | 1321 | .icache_bsize = 32, |
1241 | .dcache_bsize = 32, | 1322 | .dcache_bsize = 32, |
1242 | .machine_check = machine_check_4xx, | 1323 | .machine_check = machine_check_4xx, |
@@ -1249,6 +1330,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1249 | .cpu_features = CPU_FTRS_40X, | 1330 | .cpu_features = CPU_FTRS_40X, |
1250 | .cpu_user_features = PPC_FEATURE_32 | | 1331 | .cpu_user_features = PPC_FEATURE_32 | |
1251 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1332 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1333 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1252 | .icache_bsize = 32, | 1334 | .icache_bsize = 32, |
1253 | .dcache_bsize = 32, | 1335 | .dcache_bsize = 32, |
1254 | .machine_check = machine_check_4xx, | 1336 | .machine_check = machine_check_4xx, |
@@ -1261,6 +1343,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1261 | .cpu_features = CPU_FTRS_40X, | 1343 | .cpu_features = CPU_FTRS_40X, |
1262 | .cpu_user_features = PPC_FEATURE_32 | | 1344 | .cpu_user_features = PPC_FEATURE_32 | |
1263 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1345 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1346 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1264 | .icache_bsize = 32, | 1347 | .icache_bsize = 32, |
1265 | .dcache_bsize = 32, | 1348 | .dcache_bsize = 32, |
1266 | .machine_check = machine_check_4xx, | 1349 | .machine_check = machine_check_4xx, |
@@ -1273,6 +1356,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1273 | .cpu_features = CPU_FTRS_40X, | 1356 | .cpu_features = CPU_FTRS_40X, |
1274 | .cpu_user_features = PPC_FEATURE_32 | | 1357 | .cpu_user_features = PPC_FEATURE_32 | |
1275 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1358 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1359 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1276 | .icache_bsize = 32, | 1360 | .icache_bsize = 32, |
1277 | .dcache_bsize = 32, | 1361 | .dcache_bsize = 32, |
1278 | .machine_check = machine_check_4xx, | 1362 | .machine_check = machine_check_4xx, |
@@ -1286,6 +1370,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1286 | .cpu_features = CPU_FTRS_40X, | 1370 | .cpu_features = CPU_FTRS_40X, |
1287 | .cpu_user_features = PPC_FEATURE_32 | | 1371 | .cpu_user_features = PPC_FEATURE_32 | |
1288 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1372 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1373 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1289 | .icache_bsize = 32, | 1374 | .icache_bsize = 32, |
1290 | .dcache_bsize = 32, | 1375 | .dcache_bsize = 32, |
1291 | .machine_check = machine_check_4xx, | 1376 | .machine_check = machine_check_4xx, |
@@ -1298,6 +1383,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1298 | .cpu_features = CPU_FTRS_40X, | 1383 | .cpu_features = CPU_FTRS_40X, |
1299 | .cpu_user_features = PPC_FEATURE_32 | | 1384 | .cpu_user_features = PPC_FEATURE_32 | |
1300 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, | 1385 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, |
1386 | .mmu_features = MMU_FTR_TYPE_40x, | ||
1301 | .icache_bsize = 32, | 1387 | .icache_bsize = 32, |
1302 | .dcache_bsize = 32, | 1388 | .dcache_bsize = 32, |
1303 | .machine_check = machine_check_4xx, | 1389 | .machine_check = machine_check_4xx, |
@@ -1312,6 +1398,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1312 | .cpu_name = "440GR Rev. A", | 1398 | .cpu_name = "440GR Rev. A", |
1313 | .cpu_features = CPU_FTRS_44X, | 1399 | .cpu_features = CPU_FTRS_44X, |
1314 | .cpu_user_features = COMMON_USER_BOOKE, | 1400 | .cpu_user_features = COMMON_USER_BOOKE, |
1401 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1315 | .icache_bsize = 32, | 1402 | .icache_bsize = 32, |
1316 | .dcache_bsize = 32, | 1403 | .dcache_bsize = 32, |
1317 | .machine_check = machine_check_4xx, | 1404 | .machine_check = machine_check_4xx, |
@@ -1323,6 +1410,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1323 | .cpu_name = "440EP Rev. A", | 1410 | .cpu_name = "440EP Rev. A", |
1324 | .cpu_features = CPU_FTRS_44X, | 1411 | .cpu_features = CPU_FTRS_44X, |
1325 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, | 1412 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, |
1413 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1326 | .icache_bsize = 32, | 1414 | .icache_bsize = 32, |
1327 | .dcache_bsize = 32, | 1415 | .dcache_bsize = 32, |
1328 | .cpu_setup = __setup_cpu_440ep, | 1416 | .cpu_setup = __setup_cpu_440ep, |
@@ -1335,6 +1423,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1335 | .cpu_name = "440GR Rev. B", | 1423 | .cpu_name = "440GR Rev. B", |
1336 | .cpu_features = CPU_FTRS_44X, | 1424 | .cpu_features = CPU_FTRS_44X, |
1337 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, | 1425 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, |
1426 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1338 | .icache_bsize = 32, | 1427 | .icache_bsize = 32, |
1339 | .dcache_bsize = 32, | 1428 | .dcache_bsize = 32, |
1340 | .machine_check = machine_check_4xx, | 1429 | .machine_check = machine_check_4xx, |
@@ -1346,6 +1435,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1346 | .cpu_name = "440EP Rev. C", | 1435 | .cpu_name = "440EP Rev. C", |
1347 | .cpu_features = CPU_FTRS_44X, | 1436 | .cpu_features = CPU_FTRS_44X, |
1348 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, | 1437 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, |
1438 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1349 | .icache_bsize = 32, | 1439 | .icache_bsize = 32, |
1350 | .dcache_bsize = 32, | 1440 | .dcache_bsize = 32, |
1351 | .cpu_setup = __setup_cpu_440ep, | 1441 | .cpu_setup = __setup_cpu_440ep, |
@@ -1358,6 +1448,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1358 | .cpu_name = "440EP Rev. B", | 1448 | .cpu_name = "440EP Rev. B", |
1359 | .cpu_features = CPU_FTRS_44X, | 1449 | .cpu_features = CPU_FTRS_44X, |
1360 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, | 1450 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, |
1451 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1361 | .icache_bsize = 32, | 1452 | .icache_bsize = 32, |
1362 | .dcache_bsize = 32, | 1453 | .dcache_bsize = 32, |
1363 | .cpu_setup = __setup_cpu_440ep, | 1454 | .cpu_setup = __setup_cpu_440ep, |
@@ -1370,6 +1461,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1370 | .cpu_name = "440GRX", | 1461 | .cpu_name = "440GRX", |
1371 | .cpu_features = CPU_FTRS_44X, | 1462 | .cpu_features = CPU_FTRS_44X, |
1372 | .cpu_user_features = COMMON_USER_BOOKE, | 1463 | .cpu_user_features = COMMON_USER_BOOKE, |
1464 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1373 | .icache_bsize = 32, | 1465 | .icache_bsize = 32, |
1374 | .dcache_bsize = 32, | 1466 | .dcache_bsize = 32, |
1375 | .cpu_setup = __setup_cpu_440grx, | 1467 | .cpu_setup = __setup_cpu_440grx, |
@@ -1382,6 +1474,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1382 | .cpu_name = "440EPX", | 1474 | .cpu_name = "440EPX", |
1383 | .cpu_features = CPU_FTRS_44X, | 1475 | .cpu_features = CPU_FTRS_44X, |
1384 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, | 1476 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, |
1477 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1385 | .icache_bsize = 32, | 1478 | .icache_bsize = 32, |
1386 | .dcache_bsize = 32, | 1479 | .dcache_bsize = 32, |
1387 | .cpu_setup = __setup_cpu_440epx, | 1480 | .cpu_setup = __setup_cpu_440epx, |
@@ -1394,6 +1487,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1394 | .cpu_name = "440GP Rev. B", | 1487 | .cpu_name = "440GP Rev. B", |
1395 | .cpu_features = CPU_FTRS_44X, | 1488 | .cpu_features = CPU_FTRS_44X, |
1396 | .cpu_user_features = COMMON_USER_BOOKE, | 1489 | .cpu_user_features = COMMON_USER_BOOKE, |
1490 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1397 | .icache_bsize = 32, | 1491 | .icache_bsize = 32, |
1398 | .dcache_bsize = 32, | 1492 | .dcache_bsize = 32, |
1399 | .machine_check = machine_check_4xx, | 1493 | .machine_check = machine_check_4xx, |
@@ -1405,6 +1499,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1405 | .cpu_name = "440GP Rev. C", | 1499 | .cpu_name = "440GP Rev. C", |
1406 | .cpu_features = CPU_FTRS_44X, | 1500 | .cpu_features = CPU_FTRS_44X, |
1407 | .cpu_user_features = COMMON_USER_BOOKE, | 1501 | .cpu_user_features = COMMON_USER_BOOKE, |
1502 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1408 | .icache_bsize = 32, | 1503 | .icache_bsize = 32, |
1409 | .dcache_bsize = 32, | 1504 | .dcache_bsize = 32, |
1410 | .machine_check = machine_check_4xx, | 1505 | .machine_check = machine_check_4xx, |
@@ -1416,6 +1511,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1416 | .cpu_name = "440GX Rev. A", | 1511 | .cpu_name = "440GX Rev. A", |
1417 | .cpu_features = CPU_FTRS_44X, | 1512 | .cpu_features = CPU_FTRS_44X, |
1418 | .cpu_user_features = COMMON_USER_BOOKE, | 1513 | .cpu_user_features = COMMON_USER_BOOKE, |
1514 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1419 | .icache_bsize = 32, | 1515 | .icache_bsize = 32, |
1420 | .dcache_bsize = 32, | 1516 | .dcache_bsize = 32, |
1421 | .cpu_setup = __setup_cpu_440gx, | 1517 | .cpu_setup = __setup_cpu_440gx, |
@@ -1428,6 +1524,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1428 | .cpu_name = "440GX Rev. B", | 1524 | .cpu_name = "440GX Rev. B", |
1429 | .cpu_features = CPU_FTRS_44X, | 1525 | .cpu_features = CPU_FTRS_44X, |
1430 | .cpu_user_features = COMMON_USER_BOOKE, | 1526 | .cpu_user_features = COMMON_USER_BOOKE, |
1527 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1431 | .icache_bsize = 32, | 1528 | .icache_bsize = 32, |
1432 | .dcache_bsize = 32, | 1529 | .dcache_bsize = 32, |
1433 | .cpu_setup = __setup_cpu_440gx, | 1530 | .cpu_setup = __setup_cpu_440gx, |
@@ -1440,6 +1537,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1440 | .cpu_name = "440GX Rev. C", | 1537 | .cpu_name = "440GX Rev. C", |
1441 | .cpu_features = CPU_FTRS_44X, | 1538 | .cpu_features = CPU_FTRS_44X, |
1442 | .cpu_user_features = COMMON_USER_BOOKE, | 1539 | .cpu_user_features = COMMON_USER_BOOKE, |
1540 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1443 | .icache_bsize = 32, | 1541 | .icache_bsize = 32, |
1444 | .dcache_bsize = 32, | 1542 | .dcache_bsize = 32, |
1445 | .cpu_setup = __setup_cpu_440gx, | 1543 | .cpu_setup = __setup_cpu_440gx, |
@@ -1452,6 +1550,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1452 | .cpu_name = "440GX Rev. F", | 1550 | .cpu_name = "440GX Rev. F", |
1453 | .cpu_features = CPU_FTRS_44X, | 1551 | .cpu_features = CPU_FTRS_44X, |
1454 | .cpu_user_features = COMMON_USER_BOOKE, | 1552 | .cpu_user_features = COMMON_USER_BOOKE, |
1553 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1455 | .icache_bsize = 32, | 1554 | .icache_bsize = 32, |
1456 | .dcache_bsize = 32, | 1555 | .dcache_bsize = 32, |
1457 | .cpu_setup = __setup_cpu_440gx, | 1556 | .cpu_setup = __setup_cpu_440gx, |
@@ -1464,6 +1563,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1464 | .cpu_name = "440SP Rev. A", | 1563 | .cpu_name = "440SP Rev. A", |
1465 | .cpu_features = CPU_FTRS_44X, | 1564 | .cpu_features = CPU_FTRS_44X, |
1466 | .cpu_user_features = COMMON_USER_BOOKE, | 1565 | .cpu_user_features = COMMON_USER_BOOKE, |
1566 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1467 | .icache_bsize = 32, | 1567 | .icache_bsize = 32, |
1468 | .dcache_bsize = 32, | 1568 | .dcache_bsize = 32, |
1469 | .machine_check = machine_check_4xx, | 1569 | .machine_check = machine_check_4xx, |
@@ -1475,6 +1575,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1475 | .cpu_name = "440SPe Rev. A", | 1575 | .cpu_name = "440SPe Rev. A", |
1476 | .cpu_features = CPU_FTRS_44X, | 1576 | .cpu_features = CPU_FTRS_44X, |
1477 | .cpu_user_features = COMMON_USER_BOOKE, | 1577 | .cpu_user_features = COMMON_USER_BOOKE, |
1578 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1478 | .icache_bsize = 32, | 1579 | .icache_bsize = 32, |
1479 | .dcache_bsize = 32, | 1580 | .dcache_bsize = 32, |
1480 | .cpu_setup = __setup_cpu_440spe, | 1581 | .cpu_setup = __setup_cpu_440spe, |
@@ -1487,6 +1588,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1487 | .cpu_name = "440SPe Rev. B", | 1588 | .cpu_name = "440SPe Rev. B", |
1488 | .cpu_features = CPU_FTRS_44X, | 1589 | .cpu_features = CPU_FTRS_44X, |
1489 | .cpu_user_features = COMMON_USER_BOOKE, | 1590 | .cpu_user_features = COMMON_USER_BOOKE, |
1591 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1490 | .icache_bsize = 32, | 1592 | .icache_bsize = 32, |
1491 | .dcache_bsize = 32, | 1593 | .dcache_bsize = 32, |
1492 | .cpu_setup = __setup_cpu_440spe, | 1594 | .cpu_setup = __setup_cpu_440spe, |
@@ -1499,6 +1601,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1499 | .cpu_name = "440 in Virtex-5 FXT", | 1601 | .cpu_name = "440 in Virtex-5 FXT", |
1500 | .cpu_features = CPU_FTRS_44X, | 1602 | .cpu_features = CPU_FTRS_44X, |
1501 | .cpu_user_features = COMMON_USER_BOOKE, | 1603 | .cpu_user_features = COMMON_USER_BOOKE, |
1604 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1502 | .icache_bsize = 32, | 1605 | .icache_bsize = 32, |
1503 | .dcache_bsize = 32, | 1606 | .dcache_bsize = 32, |
1504 | .cpu_setup = __setup_cpu_440x5, | 1607 | .cpu_setup = __setup_cpu_440x5, |
@@ -1509,8 +1612,9 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1509 | .pvr_mask = 0xffff0002, | 1612 | .pvr_mask = 0xffff0002, |
1510 | .pvr_value = 0x13020002, | 1613 | .pvr_value = 0x13020002, |
1511 | .cpu_name = "460EX", | 1614 | .cpu_name = "460EX", |
1512 | .cpu_features = CPU_FTRS_44X, | 1615 | .cpu_features = CPU_FTRS_440x6, |
1513 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, | 1616 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, |
1617 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1514 | .icache_bsize = 32, | 1618 | .icache_bsize = 32, |
1515 | .dcache_bsize = 32, | 1619 | .dcache_bsize = 32, |
1516 | .cpu_setup = __setup_cpu_460ex, | 1620 | .cpu_setup = __setup_cpu_460ex, |
@@ -1521,8 +1625,9 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1521 | .pvr_mask = 0xffff0002, | 1625 | .pvr_mask = 0xffff0002, |
1522 | .pvr_value = 0x13020000, | 1626 | .pvr_value = 0x13020000, |
1523 | .cpu_name = "460GT", | 1627 | .cpu_name = "460GT", |
1524 | .cpu_features = CPU_FTRS_44X, | 1628 | .cpu_features = CPU_FTRS_440x6, |
1525 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, | 1629 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, |
1630 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1526 | .icache_bsize = 32, | 1631 | .icache_bsize = 32, |
1527 | .dcache_bsize = 32, | 1632 | .dcache_bsize = 32, |
1528 | .cpu_setup = __setup_cpu_460gt, | 1633 | .cpu_setup = __setup_cpu_460gt, |
@@ -1535,6 +1640,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1535 | .cpu_name = "(generic 44x PPC)", | 1640 | .cpu_name = "(generic 44x PPC)", |
1536 | .cpu_features = CPU_FTRS_44X, | 1641 | .cpu_features = CPU_FTRS_44X, |
1537 | .cpu_user_features = COMMON_USER_BOOKE, | 1642 | .cpu_user_features = COMMON_USER_BOOKE, |
1643 | .mmu_features = MMU_FTR_TYPE_44x, | ||
1538 | .icache_bsize = 32, | 1644 | .icache_bsize = 32, |
1539 | .dcache_bsize = 32, | 1645 | .dcache_bsize = 32, |
1540 | .machine_check = machine_check_4xx, | 1646 | .machine_check = machine_check_4xx, |
@@ -1551,6 +1657,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1551 | .cpu_user_features = COMMON_USER_BOOKE | | 1657 | .cpu_user_features = COMMON_USER_BOOKE | |
1552 | PPC_FEATURE_HAS_EFP_SINGLE | | 1658 | PPC_FEATURE_HAS_EFP_SINGLE | |
1553 | PPC_FEATURE_UNIFIED_CACHE, | 1659 | PPC_FEATURE_UNIFIED_CACHE, |
1660 | .mmu_features = MMU_FTR_TYPE_FSL_E, | ||
1554 | .dcache_bsize = 32, | 1661 | .dcache_bsize = 32, |
1555 | .machine_check = machine_check_e200, | 1662 | .machine_check = machine_check_e200, |
1556 | .platform = "ppc5554", | 1663 | .platform = "ppc5554", |
@@ -1565,6 +1672,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1565 | PPC_FEATURE_HAS_SPE_COMP | | 1672 | PPC_FEATURE_HAS_SPE_COMP | |
1566 | PPC_FEATURE_HAS_EFP_SINGLE_COMP | | 1673 | PPC_FEATURE_HAS_EFP_SINGLE_COMP | |
1567 | PPC_FEATURE_UNIFIED_CACHE, | 1674 | PPC_FEATURE_UNIFIED_CACHE, |
1675 | .mmu_features = MMU_FTR_TYPE_FSL_E, | ||
1568 | .dcache_bsize = 32, | 1676 | .dcache_bsize = 32, |
1569 | .machine_check = machine_check_e200, | 1677 | .machine_check = machine_check_e200, |
1570 | .platform = "ppc5554", | 1678 | .platform = "ppc5554", |
@@ -1577,6 +1685,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1577 | .cpu_user_features = COMMON_USER_BOOKE | | 1685 | .cpu_user_features = COMMON_USER_BOOKE | |
1578 | PPC_FEATURE_HAS_EFP_SINGLE | | 1686 | PPC_FEATURE_HAS_EFP_SINGLE | |
1579 | PPC_FEATURE_UNIFIED_CACHE, | 1687 | PPC_FEATURE_UNIFIED_CACHE, |
1688 | .mmu_features = MMU_FTR_TYPE_FSL_E, | ||
1580 | .dcache_bsize = 32, | 1689 | .dcache_bsize = 32, |
1581 | .machine_check = machine_check_e200, | 1690 | .machine_check = machine_check_e200, |
1582 | .platform = "ppc5554", | 1691 | .platform = "ppc5554", |
@@ -1591,6 +1700,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1591 | .cpu_user_features = COMMON_USER_BOOKE | | 1700 | .cpu_user_features = COMMON_USER_BOOKE | |
1592 | PPC_FEATURE_HAS_SPE_COMP | | 1701 | PPC_FEATURE_HAS_SPE_COMP | |
1593 | PPC_FEATURE_HAS_EFP_SINGLE_COMP, | 1702 | PPC_FEATURE_HAS_EFP_SINGLE_COMP, |
1703 | .mmu_features = MMU_FTR_TYPE_FSL_E, | ||
1594 | .icache_bsize = 32, | 1704 | .icache_bsize = 32, |
1595 | .dcache_bsize = 32, | 1705 | .dcache_bsize = 32, |
1596 | .num_pmcs = 4, | 1706 | .num_pmcs = 4, |
@@ -1608,6 +1718,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1608 | PPC_FEATURE_HAS_SPE_COMP | | 1718 | PPC_FEATURE_HAS_SPE_COMP | |
1609 | PPC_FEATURE_HAS_EFP_SINGLE_COMP | | 1719 | PPC_FEATURE_HAS_EFP_SINGLE_COMP | |
1610 | PPC_FEATURE_HAS_EFP_DOUBLE_COMP, | 1720 | PPC_FEATURE_HAS_EFP_DOUBLE_COMP, |
1721 | .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS, | ||
1611 | .icache_bsize = 32, | 1722 | .icache_bsize = 32, |
1612 | .dcache_bsize = 32, | 1723 | .dcache_bsize = 32, |
1613 | .num_pmcs = 4, | 1724 | .num_pmcs = 4, |
@@ -1622,6 +1733,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1622 | .cpu_name = "e500mc", | 1733 | .cpu_name = "e500mc", |
1623 | .cpu_features = CPU_FTRS_E500MC, | 1734 | .cpu_features = CPU_FTRS_E500MC, |
1624 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, | 1735 | .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, |
1736 | .mmu_features = MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS, | ||
1625 | .icache_bsize = 64, | 1737 | .icache_bsize = 64, |
1626 | .dcache_bsize = 64, | 1738 | .dcache_bsize = 64, |
1627 | .num_pmcs = 4, | 1739 | .num_pmcs = 4, |
@@ -1638,6 +1750,7 @@ static struct cpu_spec __initdata cpu_specs[] = { | |||
1638 | .cpu_user_features = COMMON_USER_BOOKE | | 1750 | .cpu_user_features = COMMON_USER_BOOKE | |
1639 | PPC_FEATURE_HAS_SPE_COMP | | 1751 | PPC_FEATURE_HAS_SPE_COMP | |
1640 | PPC_FEATURE_HAS_EFP_SINGLE_COMP, | 1752 | PPC_FEATURE_HAS_EFP_SINGLE_COMP, |
1753 | .mmu_features = MMU_FTR_TYPE_FSL_E, | ||
1641 | .icache_bsize = 32, | 1754 | .icache_bsize = 32, |
1642 | .dcache_bsize = 32, | 1755 | .dcache_bsize = 32, |
1643 | .machine_check = machine_check_e500, | 1756 | .machine_check = machine_check_e500, |
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c index 3a6eaa876ee1..1c5c8a6fc129 100644 --- a/arch/powerpc/kernel/dma.c +++ b/arch/powerpc/kernel/dma.c | |||
@@ -120,6 +120,26 @@ static inline void dma_direct_unmap_page(struct device *dev, | |||
120 | { | 120 | { |
121 | } | 121 | } |
122 | 122 | ||
123 | #ifdef CONFIG_NOT_COHERENT_CACHE | ||
124 | static inline void dma_direct_sync_sg(struct device *dev, | ||
125 | struct scatterlist *sgl, int nents, | ||
126 | enum dma_data_direction direction) | ||
127 | { | ||
128 | struct scatterlist *sg; | ||
129 | int i; | ||
130 | |||
131 | for_each_sg(sgl, sg, nents, i) | ||
132 | __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); | ||
133 | } | ||
134 | |||
135 | static inline void dma_direct_sync_single_range(struct device *dev, | ||
136 | dma_addr_t dma_handle, unsigned long offset, size_t size, | ||
137 | enum dma_data_direction direction) | ||
138 | { | ||
139 | __dma_sync(bus_to_virt(dma_handle+offset), size, direction); | ||
140 | } | ||
141 | #endif | ||
142 | |||
123 | struct dma_mapping_ops dma_direct_ops = { | 143 | struct dma_mapping_ops dma_direct_ops = { |
124 | .alloc_coherent = dma_direct_alloc_coherent, | 144 | .alloc_coherent = dma_direct_alloc_coherent, |
125 | .free_coherent = dma_direct_free_coherent, | 145 | .free_coherent = dma_direct_free_coherent, |
@@ -128,5 +148,11 @@ struct dma_mapping_ops dma_direct_ops = { | |||
128 | .dma_supported = dma_direct_dma_supported, | 148 | .dma_supported = dma_direct_dma_supported, |
129 | .map_page = dma_direct_map_page, | 149 | .map_page = dma_direct_map_page, |
130 | .unmap_page = dma_direct_unmap_page, | 150 | .unmap_page = dma_direct_unmap_page, |
151 | #ifdef CONFIG_NOT_COHERENT_CACHE | ||
152 | .sync_single_range_for_cpu = dma_direct_sync_single_range, | ||
153 | .sync_single_range_for_device = dma_direct_sync_single_range, | ||
154 | .sync_sg_for_cpu = dma_direct_sync_sg, | ||
155 | .sync_sg_for_device = dma_direct_sync_sg, | ||
156 | #endif | ||
131 | }; | 157 | }; |
132 | EXPORT_SYMBOL(dma_direct_ops); | 158 | EXPORT_SYMBOL(dma_direct_ops); |
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 0c326823c6d4..a1c4cfd25ded 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/ppc_asm.h> | 31 | #include <asm/ppc_asm.h> |
32 | #include <asm/asm-offsets.h> | 32 | #include <asm/asm-offsets.h> |
33 | #include <asm/ptrace.h> | 33 | #include <asm/ptrace.h> |
34 | #include <asm/bug.h> | ||
34 | 35 | ||
35 | /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ | 36 | /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */ |
36 | #define LOAD_BAT(n, reg, RA, RB) \ | 37 | #define LOAD_BAT(n, reg, RA, RB) \ |
@@ -182,7 +183,8 @@ __after_mmu_off: | |||
182 | bl reloc_offset | 183 | bl reloc_offset |
183 | mr r26,r3 | 184 | mr r26,r3 |
184 | addis r4,r3,KERNELBASE@h /* current address of _start */ | 185 | addis r4,r3,KERNELBASE@h /* current address of _start */ |
185 | cmpwi 0,r4,0 /* are we already running at 0? */ | 186 | lis r5,PHYSICAL_START@h |
187 | cmplw 0,r4,r5 /* already running at PHYSICAL_START? */ | ||
186 | bne relocate_kernel | 188 | bne relocate_kernel |
187 | /* | 189 | /* |
188 | * we now have the 1st 16M of ram mapped with the bats. | 190 | * we now have the 1st 16M of ram mapped with the bats. |
@@ -810,13 +812,13 @@ giveup_altivec: | |||
810 | 812 | ||
811 | /* | 813 | /* |
812 | * This code is jumped to from the startup code to copy | 814 | * This code is jumped to from the startup code to copy |
813 | * the kernel image to physical address 0. | 815 | * the kernel image to physical address PHYSICAL_START. |
814 | */ | 816 | */ |
815 | relocate_kernel: | 817 | relocate_kernel: |
816 | addis r9,r26,klimit@ha /* fetch klimit */ | 818 | addis r9,r26,klimit@ha /* fetch klimit */ |
817 | lwz r25,klimit@l(r9) | 819 | lwz r25,klimit@l(r9) |
818 | addis r25,r25,-KERNELBASE@h | 820 | addis r25,r25,-KERNELBASE@h |
819 | li r3,0 /* Destination base address */ | 821 | lis r3,PHYSICAL_START@h /* Destination base address */ |
820 | li r6,0 /* Destination offset */ | 822 | li r6,0 /* Destination offset */ |
821 | li r5,0x4000 /* # bytes of memory to copy */ | 823 | li r5,0x4000 /* # bytes of memory to copy */ |
822 | bl copy_and_flush /* copy the first 0x4000 bytes */ | 824 | bl copy_and_flush /* copy the first 0x4000 bytes */ |
@@ -989,12 +991,12 @@ load_up_mmu: | |||
989 | LOAD_BAT(1,r3,r4,r5) | 991 | LOAD_BAT(1,r3,r4,r5) |
990 | LOAD_BAT(2,r3,r4,r5) | 992 | LOAD_BAT(2,r3,r4,r5) |
991 | LOAD_BAT(3,r3,r4,r5) | 993 | LOAD_BAT(3,r3,r4,r5) |
992 | BEGIN_FTR_SECTION | 994 | BEGIN_MMU_FTR_SECTION |
993 | LOAD_BAT(4,r3,r4,r5) | 995 | LOAD_BAT(4,r3,r4,r5) |
994 | LOAD_BAT(5,r3,r4,r5) | 996 | LOAD_BAT(5,r3,r4,r5) |
995 | LOAD_BAT(6,r3,r4,r5) | 997 | LOAD_BAT(6,r3,r4,r5) |
996 | LOAD_BAT(7,r3,r4,r5) | 998 | LOAD_BAT(7,r3,r4,r5) |
997 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) | 999 | END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) |
998 | blr | 1000 | blr |
999 | 1001 | ||
1000 | /* | 1002 | /* |
@@ -1070,9 +1072,14 @@ start_here: | |||
1070 | RFI | 1072 | RFI |
1071 | 1073 | ||
1072 | /* | 1074 | /* |
1075 | * void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next); | ||
1076 | * | ||
1073 | * Set up the segment registers for a new context. | 1077 | * Set up the segment registers for a new context. |
1074 | */ | 1078 | */ |
1075 | _ENTRY(set_context) | 1079 | _ENTRY(switch_mmu_context) |
1080 | lwz r3,MMCONTEXTID(r4) | ||
1081 | cmpwi cr0,r3,0 | ||
1082 | blt- 4f | ||
1076 | mulli r3,r3,897 /* multiply context by skew factor */ | 1083 | mulli r3,r3,897 /* multiply context by skew factor */ |
1077 | rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */ | 1084 | rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */ |
1078 | addis r3,r3,0x6000 /* Set Ks, Ku bits */ | 1085 | addis r3,r3,0x6000 /* Set Ks, Ku bits */ |
@@ -1083,6 +1090,7 @@ _ENTRY(set_context) | |||
1083 | /* Context switch the PTE pointer for the Abatron BDI2000. | 1090 | /* Context switch the PTE pointer for the Abatron BDI2000. |
1084 | * The PGDIR is passed as second argument. | 1091 | * The PGDIR is passed as second argument. |
1085 | */ | 1092 | */ |
1093 | lwz r4,MM_PGD(r4) | ||
1086 | lis r5, KERNELBASE@h | 1094 | lis r5, KERNELBASE@h |
1087 | lwz r5, 0xf0(r5) | 1095 | lwz r5, 0xf0(r5) |
1088 | stw r4, 0x4(r5) | 1096 | stw r4, 0x4(r5) |
@@ -1098,6 +1106,9 @@ _ENTRY(set_context) | |||
1098 | sync | 1106 | sync |
1099 | isync | 1107 | isync |
1100 | blr | 1108 | blr |
1109 | 4: trap | ||
1110 | EMIT_BUG_ENTRY 4b,__FILE__,__LINE__,0 | ||
1111 | blr | ||
1101 | 1112 | ||
1102 | /* | 1113 | /* |
1103 | * An undocumented "feature" of 604e requires that the v bit | 1114 | * An undocumented "feature" of 604e requires that the v bit |
@@ -1131,7 +1142,7 @@ clear_bats: | |||
1131 | mtspr SPRN_IBAT2L,r10 | 1142 | mtspr SPRN_IBAT2L,r10 |
1132 | mtspr SPRN_IBAT3U,r10 | 1143 | mtspr SPRN_IBAT3U,r10 |
1133 | mtspr SPRN_IBAT3L,r10 | 1144 | mtspr SPRN_IBAT3L,r10 |
1134 | BEGIN_FTR_SECTION | 1145 | BEGIN_MMU_FTR_SECTION |
1135 | /* Here's a tweak: at this point, CPU setup have | 1146 | /* Here's a tweak: at this point, CPU setup have |
1136 | * not been called yet, so HIGH_BAT_EN may not be | 1147 | * not been called yet, so HIGH_BAT_EN may not be |
1137 | * set in HID0 for the 745x processors. However, it | 1148 | * set in HID0 for the 745x processors. However, it |
@@ -1154,7 +1165,7 @@ BEGIN_FTR_SECTION | |||
1154 | mtspr SPRN_IBAT6L,r10 | 1165 | mtspr SPRN_IBAT6L,r10 |
1155 | mtspr SPRN_IBAT7U,r10 | 1166 | mtspr SPRN_IBAT7U,r10 |
1156 | mtspr SPRN_IBAT7L,r10 | 1167 | mtspr SPRN_IBAT7L,r10 |
1157 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) | 1168 | END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) |
1158 | blr | 1169 | blr |
1159 | 1170 | ||
1160 | flush_tlbs: | 1171 | flush_tlbs: |
@@ -1178,11 +1189,11 @@ mmu_off: | |||
1178 | 1189 | ||
1179 | /* | 1190 | /* |
1180 | * Use the first pair of BAT registers to map the 1st 16MB | 1191 | * Use the first pair of BAT registers to map the 1st 16MB |
1181 | * of RAM to KERNELBASE. From this point on we can't safely | 1192 | * of RAM to PAGE_OFFSET. From this point on we can't safely |
1182 | * call OF any more. | 1193 | * call OF any more. |
1183 | */ | 1194 | */ |
1184 | initial_bats: | 1195 | initial_bats: |
1185 | lis r11,KERNELBASE@h | 1196 | lis r11,PAGE_OFFSET@h |
1186 | mfspr r9,SPRN_PVR | 1197 | mfspr r9,SPRN_PVR |
1187 | rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ | 1198 | rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ |
1188 | cmpwi 0,r9,1 | 1199 | cmpwi 0,r9,1 |
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index f3a1ea9d7fe4..b56fecc93a16 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S | |||
@@ -69,6 +69,17 @@ _ENTRY(_start); | |||
69 | li r24,0 /* CPU number */ | 69 | li r24,0 /* CPU number */ |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * In case the firmware didn't do it, we apply some workarounds | ||
73 | * that are good for all 440 core variants here | ||
74 | */ | ||
75 | mfspr r3,SPRN_CCR0 | ||
76 | rlwinm r3,r3,0,0,27 /* disable icache prefetch */ | ||
77 | isync | ||
78 | mtspr SPRN_CCR0,r3 | ||
79 | isync | ||
80 | sync | ||
81 | |||
82 | /* | ||
72 | * Set up the initial MMU state | 83 | * Set up the initial MMU state |
73 | * | 84 | * |
74 | * We are still executing code at the virtual address | 85 | * We are still executing code at the virtual address |
@@ -391,12 +402,14 @@ interrupt_base: | |||
391 | rlwimi r13,r12,10,30,30 | 402 | rlwimi r13,r12,10,30,30 |
392 | 403 | ||
393 | /* Load the PTE */ | 404 | /* Load the PTE */ |
394 | rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ | 405 | /* Compute pgdir/pmd offset */ |
406 | rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 | ||
395 | lwzx r11, r12, r11 /* Get pgd/pmd entry */ | 407 | lwzx r11, r12, r11 /* Get pgd/pmd entry */ |
396 | rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ | 408 | rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ |
397 | beq 2f /* Bail if no table */ | 409 | beq 2f /* Bail if no table */ |
398 | 410 | ||
399 | rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ | 411 | /* Compute pte address */ |
412 | rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 | ||
400 | lwz r11, 0(r12) /* Get high word of pte entry */ | 413 | lwz r11, 0(r12) /* Get high word of pte entry */ |
401 | lwz r12, 4(r12) /* Get low word of pte entry */ | 414 | lwz r12, 4(r12) /* Get low word of pte entry */ |
402 | 415 | ||
@@ -485,12 +498,14 @@ tlb_44x_patch_hwater_D: | |||
485 | /* Make up the required permissions */ | 498 | /* Make up the required permissions */ |
486 | li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC | 499 | li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC |
487 | 500 | ||
488 | rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ | 501 | /* Compute pgdir/pmd offset */ |
502 | rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 | ||
489 | lwzx r11, r12, r11 /* Get pgd/pmd entry */ | 503 | lwzx r11, r12, r11 /* Get pgd/pmd entry */ |
490 | rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ | 504 | rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ |
491 | beq 2f /* Bail if no table */ | 505 | beq 2f /* Bail if no table */ |
492 | 506 | ||
493 | rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ | 507 | /* Compute pte address */ |
508 | rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 | ||
494 | lwz r11, 0(r12) /* Get high word of pte entry */ | 509 | lwz r11, 0(r12) /* Get high word of pte entry */ |
495 | lwz r12, 4(r12) /* Get low word of pte entry */ | 510 | lwz r12, 4(r12) /* Get low word of pte entry */ |
496 | 511 | ||
@@ -554,15 +569,16 @@ tlb_44x_patch_hwater_I: | |||
554 | */ | 569 | */ |
555 | finish_tlb_load: | 570 | finish_tlb_load: |
556 | /* Combine RPN & ERPN an write WS 0 */ | 571 | /* Combine RPN & ERPN an write WS 0 */ |
557 | rlwimi r11,r12,0,0,19 | 572 | rlwimi r11,r12,0,0,31-PAGE_SHIFT |
558 | tlbwe r11,r13,PPC44x_TLB_XLAT | 573 | tlbwe r11,r13,PPC44x_TLB_XLAT |
559 | 574 | ||
560 | /* | 575 | /* |
561 | * Create WS1. This is the faulting address (EPN), | 576 | * Create WS1. This is the faulting address (EPN), |
562 | * page size, and valid flag. | 577 | * page size, and valid flag. |
563 | */ | 578 | */ |
564 | li r11,PPC44x_TLB_VALID | PPC44x_TLB_4K | 579 | li r11,PPC44x_TLB_VALID | PPC44x_TLBE_SIZE |
565 | rlwimi r10,r11,0,20,31 /* Insert valid and page size*/ | 580 | /* Insert valid and page size */ |
581 | rlwimi r10,r11,0,PPC44x_PTE_ADD_MASK_BIT,31 | ||
566 | tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ | 582 | tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ |
567 | 583 | ||
568 | /* And WS 2 */ | 584 | /* And WS 2 */ |
@@ -634,12 +650,12 @@ _GLOBAL(set_context) | |||
634 | * goes at the beginning of the data segment, which is page-aligned. | 650 | * goes at the beginning of the data segment, which is page-aligned. |
635 | */ | 651 | */ |
636 | .data | 652 | .data |
637 | .align 12 | 653 | .align PAGE_SHIFT |
638 | .globl sdata | 654 | .globl sdata |
639 | sdata: | 655 | sdata: |
640 | .globl empty_zero_page | 656 | .globl empty_zero_page |
641 | empty_zero_page: | 657 | empty_zero_page: |
642 | .space 4096 | 658 | .space PAGE_SIZE |
643 | 659 | ||
644 | /* | 660 | /* |
645 | * To support >32-bit physical addresses, we use an 8KB pgdir. | 661 | * To support >32-bit physical addresses, we use an 8KB pgdir. |
diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 590304c24dad..11b549acc034 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S | |||
@@ -92,6 +92,7 @@ _ENTRY(_start); | |||
92 | * if needed | 92 | * if needed |
93 | */ | 93 | */ |
94 | 94 | ||
95 | _ENTRY(__early_start) | ||
95 | /* 1. Find the index of the entry we're executing in */ | 96 | /* 1. Find the index of the entry we're executing in */ |
96 | bl invstr /* Find our address */ | 97 | bl invstr /* Find our address */ |
97 | invstr: mflr r6 /* Make it accessible */ | 98 | invstr: mflr r6 /* Make it accessible */ |
@@ -235,36 +236,40 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
235 | tlbivax 0,r9 | 236 | tlbivax 0,r9 |
236 | TLBSYNC | 237 | TLBSYNC |
237 | 238 | ||
239 | /* The mapping only needs to be cache-coherent on SMP */ | ||
240 | #ifdef CONFIG_SMP | ||
241 | #define M_IF_SMP MAS2_M | ||
242 | #else | ||
243 | #define M_IF_SMP 0 | ||
244 | #endif | ||
245 | |||
238 | /* 6. Setup KERNELBASE mapping in TLB1[0] */ | 246 | /* 6. Setup KERNELBASE mapping in TLB1[0] */ |
239 | lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ | 247 | lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ |
240 | mtspr SPRN_MAS0,r6 | 248 | mtspr SPRN_MAS0,r6 |
241 | lis r6,(MAS1_VALID|MAS1_IPROT)@h | 249 | lis r6,(MAS1_VALID|MAS1_IPROT)@h |
242 | ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l | 250 | ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l |
243 | mtspr SPRN_MAS1,r6 | 251 | mtspr SPRN_MAS1,r6 |
244 | li r7,0 | 252 | lis r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@h |
245 | lis r6,PAGE_OFFSET@h | 253 | ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOKE_PAGESZ_64M, M_IF_SMP)@l |
246 | ori r6,r6,PAGE_OFFSET@l | ||
247 | rlwimi r6,r7,0,20,31 | ||
248 | mtspr SPRN_MAS2,r6 | 254 | mtspr SPRN_MAS2,r6 |
249 | mtspr SPRN_MAS3,r8 | 255 | mtspr SPRN_MAS3,r8 |
250 | tlbwe | 256 | tlbwe |
251 | 257 | ||
252 | /* 7. Jump to KERNELBASE mapping */ | 258 | /* 7. Jump to KERNELBASE mapping */ |
253 | lis r6,KERNELBASE@h | 259 | lis r6,(KERNELBASE & ~0xfff)@h |
254 | ori r6,r6,KERNELBASE@l | 260 | ori r6,r6,(KERNELBASE & ~0xfff)@l |
255 | rlwimi r6,r7,0,20,31 | ||
256 | lis r7,MSR_KERNEL@h | 261 | lis r7,MSR_KERNEL@h |
257 | ori r7,r7,MSR_KERNEL@l | 262 | ori r7,r7,MSR_KERNEL@l |
258 | bl 1f /* Find our address */ | 263 | bl 1f /* Find our address */ |
259 | 1: mflr r9 | 264 | 1: mflr r9 |
260 | rlwimi r6,r9,0,20,31 | 265 | rlwimi r6,r9,0,20,31 |
261 | addi r6,r6,24 | 266 | addi r6,r6,(2f - 1b) |
262 | mtspr SPRN_SRR0,r6 | 267 | mtspr SPRN_SRR0,r6 |
263 | mtspr SPRN_SRR1,r7 | 268 | mtspr SPRN_SRR1,r7 |
264 | rfi /* start execution out of TLB1[0] entry */ | 269 | rfi /* start execution out of TLB1[0] entry */ |
265 | 270 | ||
266 | /* 8. Clear out the temp mapping */ | 271 | /* 8. Clear out the temp mapping */ |
267 | lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ | 272 | 2: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ |
268 | rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ | 273 | rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ |
269 | mtspr SPRN_MAS0,r7 | 274 | mtspr SPRN_MAS0,r7 |
270 | tlbre | 275 | tlbre |
@@ -344,6 +349,15 @@ skpinv: addi r6,r6,1 /* Increment */ | |||
344 | mtspr SPRN_DBSR,r2 | 349 | mtspr SPRN_DBSR,r2 |
345 | #endif | 350 | #endif |
346 | 351 | ||
352 | #ifdef CONFIG_SMP | ||
353 | /* Check to see if we're the second processor, and jump | ||
354 | * to the secondary_start code if so | ||
355 | */ | ||
356 | mfspr r24,SPRN_PIR | ||
357 | cmpwi r24,0 | ||
358 | bne __secondary_start | ||
359 | #endif | ||
360 | |||
347 | /* | 361 | /* |
348 | * This is where the main kernel code starts. | 362 | * This is where the main kernel code starts. |
349 | */ | 363 | */ |
@@ -685,12 +699,13 @@ interrupt_base: | |||
685 | /* SPE Floating Point Data */ | 699 | /* SPE Floating Point Data */ |
686 | #ifdef CONFIG_SPE | 700 | #ifdef CONFIG_SPE |
687 | EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE); | 701 | EXCEPTION(0x2030, SPEFloatingPointData, SPEFloatingPointException, EXC_XFER_EE); |
688 | #else | ||
689 | EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE) | ||
690 | #endif /* CONFIG_SPE */ | ||
691 | 702 | ||
692 | /* SPE Floating Point Round */ | 703 | /* SPE Floating Point Round */ |
704 | EXCEPTION(0x2050, SPEFloatingPointRound, SPEFloatingPointRoundException, EXC_XFER_EE) | ||
705 | #else | ||
706 | EXCEPTION(0x2040, SPEFloatingPointData, unknown_exception, EXC_XFER_EE) | ||
693 | EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE) | 707 | EXCEPTION(0x2050, SPEFloatingPointRound, unknown_exception, EXC_XFER_EE) |
708 | #endif /* CONFIG_SPE */ | ||
694 | 709 | ||
695 | /* Performance Monitor */ | 710 | /* Performance Monitor */ |
696 | EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD) | 711 | EXCEPTION(0x2060, PerformanceMonitor, performance_monitor_exception, EXC_XFER_STD) |
@@ -735,6 +750,9 @@ finish_tlb_load: | |||
735 | #else | 750 | #else |
736 | rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */ | 751 | rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */ |
737 | #endif | 752 | #endif |
753 | #ifdef CONFIG_SMP | ||
754 | ori r12, r12, MAS2_M | ||
755 | #endif | ||
738 | mtspr SPRN_MAS2, r12 | 756 | mtspr SPRN_MAS2, r12 |
739 | 757 | ||
740 | li r10, (_PAGE_HWEXEC | _PAGE_PRESENT) | 758 | li r10, (_PAGE_HWEXEC | _PAGE_PRESENT) |
@@ -746,15 +764,15 @@ finish_tlb_load: | |||
746 | iseleq r12, r12, r10 | 764 | iseleq r12, r12, r10 |
747 | 765 | ||
748 | #ifdef CONFIG_PTE_64BIT | 766 | #ifdef CONFIG_PTE_64BIT |
749 | 2: rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */ | 767 | rlwimi r12, r13, 24, 0, 7 /* grab RPN[32:39] */ |
750 | rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */ | 768 | rlwimi r12, r11, 24, 8, 19 /* grab RPN[40:51] */ |
751 | mtspr SPRN_MAS3, r12 | 769 | mtspr SPRN_MAS3, r12 |
752 | BEGIN_FTR_SECTION | 770 | BEGIN_MMU_FTR_SECTION |
753 | srwi r10, r13, 8 /* grab RPN[8:31] */ | 771 | srwi r10, r13, 8 /* grab RPN[8:31] */ |
754 | mtspr SPRN_MAS7, r10 | 772 | mtspr SPRN_MAS7, r10 |
755 | END_FTR_SECTION_IFSET(CPU_FTR_BIG_PHYS) | 773 | END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) |
756 | #else | 774 | #else |
757 | 2: rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ | 775 | rlwimi r11, r12, 0, 20, 31 /* Extract RPN from PTE and merge with perms */ |
758 | mtspr SPRN_MAS3, r11 | 776 | mtspr SPRN_MAS3, r11 |
759 | #endif | 777 | #endif |
760 | #ifdef CONFIG_E200 | 778 | #ifdef CONFIG_E200 |
@@ -1037,6 +1055,63 @@ _GLOBAL(flush_dcache_L1) | |||
1037 | 1055 | ||
1038 | blr | 1056 | blr |
1039 | 1057 | ||
1058 | #ifdef CONFIG_SMP | ||
1059 | /* When we get here, r24 needs to hold the CPU # */ | ||
1060 | .globl __secondary_start | ||
1061 | __secondary_start: | ||
1062 | lis r3,__secondary_hold_acknowledge@h | ||
1063 | ori r3,r3,__secondary_hold_acknowledge@l | ||
1064 | stw r24,0(r3) | ||
1065 | |||
1066 | li r3,0 | ||
1067 | mr r4,r24 /* Why? */ | ||
1068 | bl call_setup_cpu | ||
1069 | |||
1070 | lis r3,tlbcam_index@ha | ||
1071 | lwz r3,tlbcam_index@l(r3) | ||
1072 | mtctr r3 | ||
1073 | li r26,0 /* r26 safe? */ | ||
1074 | |||
1075 | /* Load each CAM entry */ | ||
1076 | 1: mr r3,r26 | ||
1077 | bl loadcam_entry | ||
1078 | addi r26,r26,1 | ||
1079 | bdnz 1b | ||
1080 | |||
1081 | /* get current_thread_info and current */ | ||
1082 | lis r1,secondary_ti@ha | ||
1083 | lwz r1,secondary_ti@l(r1) | ||
1084 | lwz r2,TI_TASK(r1) | ||
1085 | |||
1086 | /* stack */ | ||
1087 | addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD | ||
1088 | li r0,0 | ||
1089 | stw r0,0(r1) | ||
1090 | |||
1091 | /* ptr to current thread */ | ||
1092 | addi r4,r2,THREAD /* address of our thread_struct */ | ||
1093 | mtspr SPRN_SPRG3,r4 | ||
1094 | |||
1095 | /* Setup the defaults for TLB entries */ | ||
1096 | li r4,(MAS4_TSIZED(BOOKE_PAGESZ_4K))@l | ||
1097 | mtspr SPRN_MAS4,r4 | ||
1098 | |||
1099 | /* Jump to start_secondary */ | ||
1100 | lis r4,MSR_KERNEL@h | ||
1101 | ori r4,r4,MSR_KERNEL@l | ||
1102 | lis r3,start_secondary@h | ||
1103 | ori r3,r3,start_secondary@l | ||
1104 | mtspr SPRN_SRR0,r3 | ||
1105 | mtspr SPRN_SRR1,r4 | ||
1106 | sync | ||
1107 | rfi | ||
1108 | sync | ||
1109 | |||
1110 | .globl __secondary_hold_acknowledge | ||
1111 | __secondary_hold_acknowledge: | ||
1112 | .long -1 | ||
1113 | #endif | ||
1114 | |||
1040 | /* | 1115 | /* |
1041 | * We put a few things here that have to be page-aligned. This stuff | 1116 | * We put a few things here that have to be page-aligned. This stuff |
1042 | * goes at the beginning of the data segment, which is page-aligned. | 1117 | * goes at the beginning of the data segment, which is page-aligned. |
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index 64299d28f364..6e3f62493659 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <asm/abs_addr.h> | 47 | #include <asm/abs_addr.h> |
48 | 48 | ||
49 | static struct device ibmebus_bus_device = { /* fake "parent" device */ | 49 | static struct device ibmebus_bus_device = { /* fake "parent" device */ |
50 | .bus_id = "ibmebus", | 50 | .init_name = "ibmebus", |
51 | }; | 51 | }; |
52 | 52 | ||
53 | struct bus_type ibmebus_bus_type; | 53 | struct bus_type ibmebus_bus_type; |
@@ -231,6 +231,7 @@ void ibmebus_free_irq(u32 ist, void *dev_id) | |||
231 | unsigned int irq = irq_find_mapping(NULL, ist); | 231 | unsigned int irq = irq_find_mapping(NULL, ist); |
232 | 232 | ||
233 | free_irq(irq, dev_id); | 233 | free_irq(irq, dev_id); |
234 | irq_dispose_mapping(irq); | ||
234 | } | 235 | } |
235 | EXPORT_SYMBOL(ibmebus_free_irq); | 236 | EXPORT_SYMBOL(ibmebus_free_irq); |
236 | 237 | ||
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index ac2a21f45c75..b3abebb7ee64 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c | |||
@@ -13,13 +13,17 @@ | |||
13 | #include <linux/reboot.h> | 13 | #include <linux/reboot.h> |
14 | #include <linux/threads.h> | 14 | #include <linux/threads.h> |
15 | #include <linux/lmb.h> | 15 | #include <linux/lmb.h> |
16 | #include <linux/of.h> | ||
16 | #include <asm/machdep.h> | 17 | #include <asm/machdep.h> |
17 | #include <asm/prom.h> | 18 | #include <asm/prom.h> |
19 | #include <asm/sections.h> | ||
18 | 20 | ||
19 | void machine_crash_shutdown(struct pt_regs *regs) | 21 | void machine_crash_shutdown(struct pt_regs *regs) |
20 | { | 22 | { |
21 | if (ppc_md.machine_crash_shutdown) | 23 | if (ppc_md.machine_crash_shutdown) |
22 | ppc_md.machine_crash_shutdown(regs); | 24 | ppc_md.machine_crash_shutdown(regs); |
25 | else | ||
26 | default_machine_crash_shutdown(regs); | ||
23 | } | 27 | } |
24 | 28 | ||
25 | /* | 29 | /* |
@@ -31,11 +35,8 @@ int machine_kexec_prepare(struct kimage *image) | |||
31 | { | 35 | { |
32 | if (ppc_md.machine_kexec_prepare) | 36 | if (ppc_md.machine_kexec_prepare) |
33 | return ppc_md.machine_kexec_prepare(image); | 37 | return ppc_md.machine_kexec_prepare(image); |
34 | /* | 38 | else |
35 | * Fail if platform doesn't provide its own machine_kexec_prepare | 39 | return default_machine_kexec_prepare(image); |
36 | * implementation. | ||
37 | */ | ||
38 | return -ENOSYS; | ||
39 | } | 40 | } |
40 | 41 | ||
41 | void machine_kexec_cleanup(struct kimage *image) | 42 | void machine_kexec_cleanup(struct kimage *image) |
@@ -52,13 +53,11 @@ void machine_kexec(struct kimage *image) | |||
52 | { | 53 | { |
53 | if (ppc_md.machine_kexec) | 54 | if (ppc_md.machine_kexec) |
54 | ppc_md.machine_kexec(image); | 55 | ppc_md.machine_kexec(image); |
55 | else { | 56 | else |
56 | /* | 57 | default_machine_kexec(image); |
57 | * Fall back to normal restart if platform doesn't provide | 58 | |
58 | * its own kexec function, and user insist to kexec... | 59 | /* Fall back to normal restart if we're still alive. */ |
59 | */ | 60 | machine_restart(NULL); |
60 | machine_restart(NULL); | ||
61 | } | ||
62 | for(;;); | 61 | for(;;); |
63 | } | 62 | } |
64 | 63 | ||
@@ -118,3 +117,71 @@ int overlaps_crashkernel(unsigned long start, unsigned long size) | |||
118 | { | 117 | { |
119 | return (start + size) > crashk_res.start && start <= crashk_res.end; | 118 | return (start + size) > crashk_res.start && start <= crashk_res.end; |
120 | } | 119 | } |
120 | |||
121 | /* Values we need to export to the second kernel via the device tree. */ | ||
122 | static unsigned long kernel_end; | ||
123 | static unsigned long crashk_size; | ||
124 | |||
125 | static struct property kernel_end_prop = { | ||
126 | .name = "linux,kernel-end", | ||
127 | .length = sizeof(unsigned long), | ||
128 | .value = &kernel_end, | ||
129 | }; | ||
130 | |||
131 | static struct property crashk_base_prop = { | ||
132 | .name = "linux,crashkernel-base", | ||
133 | .length = sizeof(unsigned long), | ||
134 | .value = &crashk_res.start, | ||
135 | }; | ||
136 | |||
137 | static struct property crashk_size_prop = { | ||
138 | .name = "linux,crashkernel-size", | ||
139 | .length = sizeof(unsigned long), | ||
140 | .value = &crashk_size, | ||
141 | }; | ||
142 | |||
143 | static void __init export_crashk_values(struct device_node *node) | ||
144 | { | ||
145 | struct property *prop; | ||
146 | |||
147 | /* There might be existing crash kernel properties, but we can't | ||
148 | * be sure what's in them, so remove them. */ | ||
149 | prop = of_find_property(node, "linux,crashkernel-base", NULL); | ||
150 | if (prop) | ||
151 | prom_remove_property(node, prop); | ||
152 | |||
153 | prop = of_find_property(node, "linux,crashkernel-size", NULL); | ||
154 | if (prop) | ||
155 | prom_remove_property(node, prop); | ||
156 | |||
157 | if (crashk_res.start != 0) { | ||
158 | prom_add_property(node, &crashk_base_prop); | ||
159 | crashk_size = crashk_res.end - crashk_res.start + 1; | ||
160 | prom_add_property(node, &crashk_size_prop); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | static int __init kexec_setup(void) | ||
165 | { | ||
166 | struct device_node *node; | ||
167 | struct property *prop; | ||
168 | |||
169 | node = of_find_node_by_path("/chosen"); | ||
170 | if (!node) | ||
171 | return -ENOENT; | ||
172 | |||
173 | /* remove any stale properties so ours can be found */ | ||
174 | prop = of_find_property(node, kernel_end_prop.name, NULL); | ||
175 | if (prop) | ||
176 | prom_remove_property(node, prop); | ||
177 | |||
178 | /* information needed by userspace when using default_machine_kexec */ | ||
179 | kernel_end = __pa(_end); | ||
180 | prom_add_property(node, &kernel_end_prop); | ||
181 | |||
182 | export_crashk_values(node); | ||
183 | |||
184 | of_node_put(node); | ||
185 | return 0; | ||
186 | } | ||
187 | late_initcall(kexec_setup); | ||
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 3c4ca046e854..49e705fcee6d 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c | |||
@@ -289,7 +289,7 @@ void default_machine_kexec(struct kimage *image) | |||
289 | } | 289 | } |
290 | 290 | ||
291 | /* Values we need to export to the second kernel via the device tree. */ | 291 | /* Values we need to export to the second kernel via the device tree. */ |
292 | static unsigned long htab_base, kernel_end; | 292 | static unsigned long htab_base; |
293 | 293 | ||
294 | static struct property htab_base_prop = { | 294 | static struct property htab_base_prop = { |
295 | .name = "linux,htab-base", | 295 | .name = "linux,htab-base", |
@@ -303,25 +303,20 @@ static struct property htab_size_prop = { | |||
303 | .value = &htab_size_bytes, | 303 | .value = &htab_size_bytes, |
304 | }; | 304 | }; |
305 | 305 | ||
306 | static struct property kernel_end_prop = { | 306 | static int __init export_htab_values(void) |
307 | .name = "linux,kernel-end", | ||
308 | .length = sizeof(unsigned long), | ||
309 | .value = &kernel_end, | ||
310 | }; | ||
311 | |||
312 | static void __init export_htab_values(void) | ||
313 | { | 307 | { |
314 | struct device_node *node; | 308 | struct device_node *node; |
315 | struct property *prop; | 309 | struct property *prop; |
316 | 310 | ||
311 | /* On machines with no htab htab_address is NULL */ | ||
312 | if (!htab_address) | ||
313 | return -ENODEV; | ||
314 | |||
317 | node = of_find_node_by_path("/chosen"); | 315 | node = of_find_node_by_path("/chosen"); |
318 | if (!node) | 316 | if (!node) |
319 | return; | 317 | return -ENODEV; |
320 | 318 | ||
321 | /* remove any stale propertys so ours can be found */ | 319 | /* remove any stale propertys so ours can be found */ |
322 | prop = of_find_property(node, kernel_end_prop.name, NULL); | ||
323 | if (prop) | ||
324 | prom_remove_property(node, prop); | ||
325 | prop = of_find_property(node, htab_base_prop.name, NULL); | 320 | prop = of_find_property(node, htab_base_prop.name, NULL); |
326 | if (prop) | 321 | if (prop) |
327 | prom_remove_property(node, prop); | 322 | prom_remove_property(node, prop); |
@@ -329,68 +324,11 @@ static void __init export_htab_values(void) | |||
329 | if (prop) | 324 | if (prop) |
330 | prom_remove_property(node, prop); | 325 | prom_remove_property(node, prop); |
331 | 326 | ||
332 | /* information needed by userspace when using default_machine_kexec */ | ||
333 | kernel_end = __pa(_end); | ||
334 | prom_add_property(node, &kernel_end_prop); | ||
335 | |||
336 | /* On machines with no htab htab_address is NULL */ | ||
337 | if (NULL == htab_address) | ||
338 | goto out; | ||
339 | |||
340 | htab_base = __pa(htab_address); | 327 | htab_base = __pa(htab_address); |
341 | prom_add_property(node, &htab_base_prop); | 328 | prom_add_property(node, &htab_base_prop); |
342 | prom_add_property(node, &htab_size_prop); | 329 | prom_add_property(node, &htab_size_prop); |
343 | 330 | ||
344 | out: | ||
345 | of_node_put(node); | ||
346 | } | ||
347 | |||
348 | static struct property crashk_base_prop = { | ||
349 | .name = "linux,crashkernel-base", | ||
350 | .length = sizeof(unsigned long), | ||
351 | .value = &crashk_res.start, | ||
352 | }; | ||
353 | |||
354 | static unsigned long crashk_size; | ||
355 | |||
356 | static struct property crashk_size_prop = { | ||
357 | .name = "linux,crashkernel-size", | ||
358 | .length = sizeof(unsigned long), | ||
359 | .value = &crashk_size, | ||
360 | }; | ||
361 | |||
362 | static void __init export_crashk_values(void) | ||
363 | { | ||
364 | struct device_node *node; | ||
365 | struct property *prop; | ||
366 | |||
367 | node = of_find_node_by_path("/chosen"); | ||
368 | if (!node) | ||
369 | return; | ||
370 | |||
371 | /* There might be existing crash kernel properties, but we can't | ||
372 | * be sure what's in them, so remove them. */ | ||
373 | prop = of_find_property(node, "linux,crashkernel-base", NULL); | ||
374 | if (prop) | ||
375 | prom_remove_property(node, prop); | ||
376 | |||
377 | prop = of_find_property(node, "linux,crashkernel-size", NULL); | ||
378 | if (prop) | ||
379 | prom_remove_property(node, prop); | ||
380 | |||
381 | if (crashk_res.start != 0) { | ||
382 | prom_add_property(node, &crashk_base_prop); | ||
383 | crashk_size = crashk_res.end - crashk_res.start + 1; | ||
384 | prom_add_property(node, &crashk_size_prop); | ||
385 | } | ||
386 | |||
387 | of_node_put(node); | 331 | of_node_put(node); |
388 | } | ||
389 | |||
390 | static int __init kexec_setup(void) | ||
391 | { | ||
392 | export_htab_values(); | ||
393 | export_crashk_values(); | ||
394 | return 0; | 332 | return 0; |
395 | } | 333 | } |
396 | __initcall(kexec_setup); | 334 | late_initcall(export_htab_values); |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 5c33bc14bd9f..15f28e0de78d 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/asm-offsets.h> | 29 | #include <asm/asm-offsets.h> |
30 | #include <asm/processor.h> | 30 | #include <asm/processor.h> |
31 | #include <asm/kexec.h> | 31 | #include <asm/kexec.h> |
32 | #include <asm/bug.h> | ||
32 | 33 | ||
33 | .text | 34 | .text |
34 | 35 | ||
@@ -271,231 +272,6 @@ _GLOBAL(real_writeb) | |||
271 | 272 | ||
272 | #endif /* CONFIG_40x */ | 273 | #endif /* CONFIG_40x */ |
273 | 274 | ||
274 | /* | ||
275 | * Flush MMU TLB | ||
276 | */ | ||
277 | #ifndef CONFIG_FSL_BOOKE | ||
278 | _GLOBAL(_tlbil_all) | ||
279 | _GLOBAL(_tlbil_pid) | ||
280 | #endif | ||
281 | _GLOBAL(_tlbia) | ||
282 | #if defined(CONFIG_40x) | ||
283 | sync /* Flush to memory before changing mapping */ | ||
284 | tlbia | ||
285 | isync /* Flush shadow TLB */ | ||
286 | #elif defined(CONFIG_44x) | ||
287 | li r3,0 | ||
288 | sync | ||
289 | |||
290 | /* Load high watermark */ | ||
291 | lis r4,tlb_44x_hwater@ha | ||
292 | lwz r5,tlb_44x_hwater@l(r4) | ||
293 | |||
294 | 1: tlbwe r3,r3,PPC44x_TLB_PAGEID | ||
295 | addi r3,r3,1 | ||
296 | cmpw 0,r3,r5 | ||
297 | ble 1b | ||
298 | |||
299 | isync | ||
300 | #elif defined(CONFIG_FSL_BOOKE) | ||
301 | /* Invalidate all entries in TLB0 */ | ||
302 | li r3, 0x04 | ||
303 | tlbivax 0,3 | ||
304 | /* Invalidate all entries in TLB1 */ | ||
305 | li r3, 0x0c | ||
306 | tlbivax 0,3 | ||
307 | msync | ||
308 | #ifdef CONFIG_SMP | ||
309 | tlbsync | ||
310 | #endif /* CONFIG_SMP */ | ||
311 | #else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */ | ||
312 | #if defined(CONFIG_SMP) | ||
313 | rlwinm r8,r1,0,0,(31-THREAD_SHIFT) | ||
314 | lwz r8,TI_CPU(r8) | ||
315 | oris r8,r8,10 | ||
316 | mfmsr r10 | ||
317 | SYNC | ||
318 | rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ | ||
319 | rlwinm r0,r0,0,28,26 /* clear DR */ | ||
320 | mtmsr r0 | ||
321 | SYNC_601 | ||
322 | isync | ||
323 | lis r9,mmu_hash_lock@h | ||
324 | ori r9,r9,mmu_hash_lock@l | ||
325 | tophys(r9,r9) | ||
326 | 10: lwarx r7,0,r9 | ||
327 | cmpwi 0,r7,0 | ||
328 | bne- 10b | ||
329 | stwcx. r8,0,r9 | ||
330 | bne- 10b | ||
331 | sync | ||
332 | tlbia | ||
333 | sync | ||
334 | TLBSYNC | ||
335 | li r0,0 | ||
336 | stw r0,0(r9) /* clear mmu_hash_lock */ | ||
337 | mtmsr r10 | ||
338 | SYNC_601 | ||
339 | isync | ||
340 | #else /* CONFIG_SMP */ | ||
341 | sync | ||
342 | tlbia | ||
343 | sync | ||
344 | #endif /* CONFIG_SMP */ | ||
345 | #endif /* ! defined(CONFIG_40x) */ | ||
346 | blr | ||
347 | |||
348 | /* | ||
349 | * Flush MMU TLB for a particular address | ||
350 | */ | ||
351 | #ifndef CONFIG_FSL_BOOKE | ||
352 | _GLOBAL(_tlbil_va) | ||
353 | #endif | ||
354 | _GLOBAL(_tlbie) | ||
355 | #if defined(CONFIG_40x) | ||
356 | /* We run the search with interrupts disabled because we have to change | ||
357 | * the PID and I don't want to preempt when that happens. | ||
358 | */ | ||
359 | mfmsr r5 | ||
360 | mfspr r6,SPRN_PID | ||
361 | wrteei 0 | ||
362 | mtspr SPRN_PID,r4 | ||
363 | tlbsx. r3, 0, r3 | ||
364 | mtspr SPRN_PID,r6 | ||
365 | wrtee r5 | ||
366 | bne 10f | ||
367 | sync | ||
368 | /* There are only 64 TLB entries, so r3 < 64, which means bit 25 is clear. | ||
369 | * Since 25 is the V bit in the TLB_TAG, loading this value will invalidate | ||
370 | * the TLB entry. */ | ||
371 | tlbwe r3, r3, TLB_TAG | ||
372 | isync | ||
373 | 10: | ||
374 | |||
375 | #elif defined(CONFIG_44x) | ||
376 | mfspr r5,SPRN_MMUCR | ||
377 | rlwimi r5,r4,0,24,31 /* Set TID */ | ||
378 | |||
379 | /* We have to run the search with interrupts disabled, even critical | ||
380 | * and debug interrupts (in fact the only critical exceptions we have | ||
381 | * are debug and machine check). Otherwise an interrupt which causes | ||
382 | * a TLB miss can clobber the MMUCR between the mtspr and the tlbsx. */ | ||
383 | mfmsr r4 | ||
384 | lis r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@ha | ||
385 | addi r6,r6,(MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l | ||
386 | andc r6,r4,r6 | ||
387 | mtmsr r6 | ||
388 | mtspr SPRN_MMUCR,r5 | ||
389 | tlbsx. r3, 0, r3 | ||
390 | mtmsr r4 | ||
391 | bne 10f | ||
392 | sync | ||
393 | /* There are only 64 TLB entries, so r3 < 64, | ||
394 | * which means bit 22, is clear. Since 22 is | ||
395 | * the V bit in the TLB_PAGEID, loading this | ||
396 | * value will invalidate the TLB entry. | ||
397 | */ | ||
398 | tlbwe r3, r3, PPC44x_TLB_PAGEID | ||
399 | isync | ||
400 | 10: | ||
401 | #elif defined(CONFIG_FSL_BOOKE) | ||
402 | rlwinm r4, r3, 0, 0, 19 | ||
403 | ori r5, r4, 0x08 /* TLBSEL = 1 */ | ||
404 | tlbivax 0, r4 | ||
405 | tlbivax 0, r5 | ||
406 | msync | ||
407 | #if defined(CONFIG_SMP) | ||
408 | tlbsync | ||
409 | #endif /* CONFIG_SMP */ | ||
410 | #else /* !(CONFIG_40x || CONFIG_44x || CONFIG_FSL_BOOKE) */ | ||
411 | #if defined(CONFIG_SMP) | ||
412 | rlwinm r8,r1,0,0,(31-THREAD_SHIFT) | ||
413 | lwz r8,TI_CPU(r8) | ||
414 | oris r8,r8,11 | ||
415 | mfmsr r10 | ||
416 | SYNC | ||
417 | rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ | ||
418 | rlwinm r0,r0,0,28,26 /* clear DR */ | ||
419 | mtmsr r0 | ||
420 | SYNC_601 | ||
421 | isync | ||
422 | lis r9,mmu_hash_lock@h | ||
423 | ori r9,r9,mmu_hash_lock@l | ||
424 | tophys(r9,r9) | ||
425 | 10: lwarx r7,0,r9 | ||
426 | cmpwi 0,r7,0 | ||
427 | bne- 10b | ||
428 | stwcx. r8,0,r9 | ||
429 | bne- 10b | ||
430 | eieio | ||
431 | tlbie r3 | ||
432 | sync | ||
433 | TLBSYNC | ||
434 | li r0,0 | ||
435 | stw r0,0(r9) /* clear mmu_hash_lock */ | ||
436 | mtmsr r10 | ||
437 | SYNC_601 | ||
438 | isync | ||
439 | #else /* CONFIG_SMP */ | ||
440 | tlbie r3 | ||
441 | sync | ||
442 | #endif /* CONFIG_SMP */ | ||
443 | #endif /* ! CONFIG_40x */ | ||
444 | blr | ||
445 | |||
446 | #if defined(CONFIG_FSL_BOOKE) | ||
447 | /* | ||
448 | * Flush MMU TLB, but only on the local processor (no broadcast) | ||
449 | */ | ||
450 | _GLOBAL(_tlbil_all) | ||
451 | #define MMUCSR0_TLBFI (MMUCSR0_TLB0FI | MMUCSR0_TLB1FI | \ | ||
452 | MMUCSR0_TLB2FI | MMUCSR0_TLB3FI) | ||
453 | li r3,(MMUCSR0_TLBFI)@l | ||
454 | mtspr SPRN_MMUCSR0, r3 | ||
455 | 1: | ||
456 | mfspr r3,SPRN_MMUCSR0 | ||
457 | andi. r3,r3,MMUCSR0_TLBFI@l | ||
458 | bne 1b | ||
459 | blr | ||
460 | |||
461 | /* | ||
462 | * Flush MMU TLB for a particular process id, but only on the local processor | ||
463 | * (no broadcast) | ||
464 | */ | ||
465 | _GLOBAL(_tlbil_pid) | ||
466 | /* we currently do an invalidate all since we don't have per pid invalidate */ | ||
467 | li r3,(MMUCSR0_TLBFI)@l | ||
468 | mtspr SPRN_MMUCSR0, r3 | ||
469 | 1: | ||
470 | mfspr r3,SPRN_MMUCSR0 | ||
471 | andi. r3,r3,MMUCSR0_TLBFI@l | ||
472 | bne 1b | ||
473 | msync | ||
474 | isync | ||
475 | blr | ||
476 | |||
477 | /* | ||
478 | * Flush MMU TLB for a particular address, but only on the local processor | ||
479 | * (no broadcast) | ||
480 | */ | ||
481 | _GLOBAL(_tlbil_va) | ||
482 | mfmsr r10 | ||
483 | wrteei 0 | ||
484 | slwi r4,r4,16 | ||
485 | mtspr SPRN_MAS6,r4 /* assume AS=0 for now */ | ||
486 | tlbsx 0,r3 | ||
487 | mfspr r4,SPRN_MAS1 /* check valid */ | ||
488 | andis. r3,r4,MAS1_VALID@h | ||
489 | beq 1f | ||
490 | rlwinm r4,r4,0,1,31 | ||
491 | mtspr SPRN_MAS1,r4 | ||
492 | tlbwe | ||
493 | msync | ||
494 | isync | ||
495 | 1: wrtee r10 | ||
496 | blr | ||
497 | #endif /* CONFIG_FSL_BOOKE */ | ||
498 | |||
499 | 275 | ||
500 | /* | 276 | /* |
501 | * Flush instruction cache. | 277 | * Flush instruction cache. |
@@ -650,8 +426,8 @@ _GLOBAL(__flush_dcache_icache) | |||
650 | BEGIN_FTR_SECTION | 426 | BEGIN_FTR_SECTION |
651 | blr | 427 | blr |
652 | END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) | 428 | END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) |
653 | rlwinm r3,r3,0,0,19 /* Get page base address */ | 429 | rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ |
654 | li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ | 430 | li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ |
655 | mtctr r4 | 431 | mtctr r4 |
656 | mr r6,r3 | 432 | mr r6,r3 |
657 | 0: dcbst 0,r3 /* Write line to ram */ | 433 | 0: dcbst 0,r3 /* Write line to ram */ |
@@ -691,8 +467,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) | |||
691 | rlwinm r0,r10,0,28,26 /* clear DR */ | 467 | rlwinm r0,r10,0,28,26 /* clear DR */ |
692 | mtmsr r0 | 468 | mtmsr r0 |
693 | isync | 469 | isync |
694 | rlwinm r3,r3,0,0,19 /* Get page base address */ | 470 | rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ |
695 | li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ | 471 | li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ |
696 | mtctr r4 | 472 | mtctr r4 |
697 | mr r6,r3 | 473 | mr r6,r3 |
698 | 0: dcbst 0,r3 /* Write line to ram */ | 474 | 0: dcbst 0,r3 /* Write line to ram */ |
@@ -716,7 +492,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) | |||
716 | * void clear_pages(void *page, int order) ; | 492 | * void clear_pages(void *page, int order) ; |
717 | */ | 493 | */ |
718 | _GLOBAL(clear_pages) | 494 | _GLOBAL(clear_pages) |
719 | li r0,4096/L1_CACHE_BYTES | 495 | li r0,PAGE_SIZE/L1_CACHE_BYTES |
720 | slw r0,r0,r4 | 496 | slw r0,r0,r4 |
721 | mtctr r0 | 497 | mtctr r0 |
722 | #ifdef CONFIG_8xx | 498 | #ifdef CONFIG_8xx |
@@ -774,7 +550,7 @@ _GLOBAL(copy_page) | |||
774 | dcbt r5,r4 | 550 | dcbt r5,r4 |
775 | li r11,L1_CACHE_BYTES+4 | 551 | li r11,L1_CACHE_BYTES+4 |
776 | #endif /* MAX_COPY_PREFETCH */ | 552 | #endif /* MAX_COPY_PREFETCH */ |
777 | li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH | 553 | li r0,PAGE_SIZE/L1_CACHE_BYTES - MAX_COPY_PREFETCH |
778 | crclr 4*cr0+eq | 554 | crclr 4*cr0+eq |
779 | 2: | 555 | 2: |
780 | mtctr r0 | 556 | mtctr r0 |
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 7ff292475269..43e7e3a7f130 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c | |||
@@ -78,6 +78,12 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
78 | (void *)sect->sh_addr, | 78 | (void *)sect->sh_addr, |
79 | (void *)sect->sh_addr + sect->sh_size); | 79 | (void *)sect->sh_addr + sect->sh_size); |
80 | 80 | ||
81 | sect = find_section(hdr, sechdrs, "__mmu_ftr_fixup"); | ||
82 | if (sect != NULL) | ||
83 | do_feature_fixups(cur_cpu_spec->mmu_features, | ||
84 | (void *)sect->sh_addr, | ||
85 | (void *)sect->sh_addr + sect->sh_size); | ||
86 | |||
81 | #ifdef CONFIG_PPC64 | 87 | #ifdef CONFIG_PPC64 |
82 | sect = find_section(hdr, sechdrs, "__fw_ftr_fixup"); | 88 | sect = find_section(hdr, sechdrs, "__fw_ftr_fixup"); |
83 | if (sect != NULL) | 89 | if (sect != NULL) |
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index f3c9cae01dd5..fa983a59c4ce 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c | |||
@@ -14,7 +14,6 @@ static void of_device_make_bus_id(struct of_device *dev) | |||
14 | { | 14 | { |
15 | static atomic_t bus_no_reg_magic; | 15 | static atomic_t bus_no_reg_magic; |
16 | struct device_node *node = dev->node; | 16 | struct device_node *node = dev->node; |
17 | char *name = dev->dev.bus_id; | ||
18 | const u32 *reg; | 17 | const u32 *reg; |
19 | u64 addr; | 18 | u64 addr; |
20 | int magic; | 19 | int magic; |
@@ -27,14 +26,12 @@ static void of_device_make_bus_id(struct of_device *dev) | |||
27 | reg = of_get_property(node, "dcr-reg", NULL); | 26 | reg = of_get_property(node, "dcr-reg", NULL); |
28 | if (reg) { | 27 | if (reg) { |
29 | #ifdef CONFIG_PPC_DCR_NATIVE | 28 | #ifdef CONFIG_PPC_DCR_NATIVE |
30 | snprintf(name, BUS_ID_SIZE, "d%x.%s", | 29 | dev_set_name(&dev->dev, "d%x.%s", *reg, node->name); |
31 | *reg, node->name); | ||
32 | #else /* CONFIG_PPC_DCR_NATIVE */ | 30 | #else /* CONFIG_PPC_DCR_NATIVE */ |
33 | addr = of_translate_dcr_address(node, *reg, NULL); | 31 | addr = of_translate_dcr_address(node, *reg, NULL); |
34 | if (addr != OF_BAD_ADDR) { | 32 | if (addr != OF_BAD_ADDR) { |
35 | snprintf(name, BUS_ID_SIZE, | 33 | dev_set_name(&dev->dev, "D%llx.%s", |
36 | "D%llx.%s", (unsigned long long)addr, | 34 | (unsigned long long)addr, node->name); |
37 | node->name); | ||
38 | return; | 35 | return; |
39 | } | 36 | } |
40 | #endif /* !CONFIG_PPC_DCR_NATIVE */ | 37 | #endif /* !CONFIG_PPC_DCR_NATIVE */ |
@@ -48,9 +45,8 @@ static void of_device_make_bus_id(struct of_device *dev) | |||
48 | if (reg) { | 45 | if (reg) { |
49 | addr = of_translate_address(node, reg); | 46 | addr = of_translate_address(node, reg); |
50 | if (addr != OF_BAD_ADDR) { | 47 | if (addr != OF_BAD_ADDR) { |
51 | snprintf(name, BUS_ID_SIZE, | 48 | dev_set_name(&dev->dev, "%llx.%s", |
52 | "%llx.%s", (unsigned long long)addr, | 49 | (unsigned long long)addr, node->name); |
53 | node->name); | ||
54 | return; | 50 | return; |
55 | } | 51 | } |
56 | } | 52 | } |
@@ -60,7 +56,7 @@ static void of_device_make_bus_id(struct of_device *dev) | |||
60 | * counter (and pray...) | 56 | * counter (and pray...) |
61 | */ | 57 | */ |
62 | magic = atomic_add_return(1, &bus_no_reg_magic); | 58 | magic = atomic_add_return(1, &bus_no_reg_magic); |
63 | snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1); | 59 | dev_set_name(&dev->dev, "%s.%d", node->name, magic - 1); |
64 | } | 60 | } |
65 | 61 | ||
66 | struct of_device *of_device_alloc(struct device_node *np, | 62 | struct of_device *of_device_alloc(struct device_node *np, |
@@ -80,7 +76,7 @@ struct of_device *of_device_alloc(struct device_node *np, | |||
80 | dev->dev.archdata.of_node = np; | 76 | dev->dev.archdata.of_node = np; |
81 | 77 | ||
82 | if (bus_id) | 78 | if (bus_id) |
83 | strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE); | 79 | dev_set_name(&dev->dev, bus_id); |
84 | else | 80 | else |
85 | of_device_make_bus_id(dev); | 81 | of_device_make_bus_id(dev); |
86 | 82 | ||
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c index 48a347133f41..c744b327bcab 100644 --- a/arch/powerpc/kernel/paca.c +++ b/arch/powerpc/kernel/paca.c | |||
@@ -37,6 +37,7 @@ struct lppaca lppaca[] = { | |||
37 | .end_of_quantum = 0xfffffffffffffffful, | 37 | .end_of_quantum = 0xfffffffffffffffful, |
38 | .slb_count = 64, | 38 | .slb_count = 64, |
39 | .vmxregs_in_use = 0, | 39 | .vmxregs_in_use = 0, |
40 | .page_ins = 0, | ||
40 | }, | 41 | }, |
41 | }; | 42 | }; |
42 | 43 | ||
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f36936d9fda3..2538030954d8 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -37,13 +37,7 @@ | |||
37 | #include <asm/machdep.h> | 37 | #include <asm/machdep.h> |
38 | #include <asm/ppc-pci.h> | 38 | #include <asm/ppc-pci.h> |
39 | #include <asm/firmware.h> | 39 | #include <asm/firmware.h> |
40 | 40 | #include <asm/eeh.h> | |
41 | #ifdef DEBUG | ||
42 | #include <asm/udbg.h> | ||
43 | #define DBG(fmt...) printk(fmt) | ||
44 | #else | ||
45 | #define DBG(fmt...) | ||
46 | #endif | ||
47 | 41 | ||
48 | static DEFINE_SPINLOCK(hose_spinlock); | 42 | static DEFINE_SPINLOCK(hose_spinlock); |
49 | 43 | ||
@@ -53,8 +47,9 @@ static int global_phb_number; /* Global phb counter */ | |||
53 | /* ISA Memory physical address */ | 47 | /* ISA Memory physical address */ |
54 | resource_size_t isa_mem_base; | 48 | resource_size_t isa_mem_base; |
55 | 49 | ||
56 | /* Default PCI flags is 0 */ | 50 | /* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */ |
57 | unsigned int ppc_pci_flags; | 51 | unsigned int ppc_pci_flags = 0; |
52 | |||
58 | 53 | ||
59 | static struct dma_mapping_ops *pci_dma_ops; | 54 | static struct dma_mapping_ops *pci_dma_ops; |
60 | 55 | ||
@@ -165,8 +160,6 @@ EXPORT_SYMBOL(pci_domain_nr); | |||
165 | */ | 160 | */ |
166 | struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) | 161 | struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) |
167 | { | 162 | { |
168 | if (!have_of) | ||
169 | return NULL; | ||
170 | while(node) { | 163 | while(node) { |
171 | struct pci_controller *hose, *tmp; | 164 | struct pci_controller *hose, *tmp; |
172 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) | 165 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) |
@@ -208,26 +201,6 @@ char __devinit *pcibios_setup(char *str) | |||
208 | return str; | 201 | return str; |
209 | } | 202 | } |
210 | 203 | ||
211 | void __devinit pcibios_setup_new_device(struct pci_dev *dev) | ||
212 | { | ||
213 | struct dev_archdata *sd = &dev->dev.archdata; | ||
214 | |||
215 | sd->of_node = pci_device_to_OF_node(dev); | ||
216 | |||
217 | DBG("PCI: device %s OF node: %s\n", pci_name(dev), | ||
218 | sd->of_node ? sd->of_node->full_name : "<none>"); | ||
219 | |||
220 | sd->dma_ops = pci_dma_ops; | ||
221 | #ifdef CONFIG_PPC32 | ||
222 | sd->dma_data = (void *)PCI_DRAM_OFFSET; | ||
223 | #endif | ||
224 | set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); | ||
225 | |||
226 | if (ppc_md.pci_dma_dev_setup) | ||
227 | ppc_md.pci_dma_dev_setup(dev); | ||
228 | } | ||
229 | EXPORT_SYMBOL(pcibios_setup_new_device); | ||
230 | |||
231 | /* | 204 | /* |
232 | * Reads the interrupt pin to determine if interrupt is use by card. | 205 | * Reads the interrupt pin to determine if interrupt is use by card. |
233 | * If the interrupt is used, then gets the interrupt line from the | 206 | * If the interrupt is used, then gets the interrupt line from the |
@@ -252,7 +225,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
252 | return -1; | 225 | return -1; |
253 | #endif | 226 | #endif |
254 | 227 | ||
255 | DBG("Try to map irq for %s...\n", pci_name(pci_dev)); | 228 | pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); |
256 | 229 | ||
257 | #ifdef DEBUG | 230 | #ifdef DEBUG |
258 | memset(&oirq, 0xff, sizeof(oirq)); | 231 | memset(&oirq, 0xff, sizeof(oirq)); |
@@ -276,26 +249,26 @@ int pci_read_irq_line(struct pci_dev *pci_dev) | |||
276 | line == 0xff || line == 0) { | 249 | line == 0xff || line == 0) { |
277 | return -1; | 250 | return -1; |
278 | } | 251 | } |
279 | DBG(" -> no map ! Using line %d (pin %d) from PCI config\n", | 252 | pr_debug(" No map ! Using line %d (pin %d) from PCI config\n", |
280 | line, pin); | 253 | line, pin); |
281 | 254 | ||
282 | virq = irq_create_mapping(NULL, line); | 255 | virq = irq_create_mapping(NULL, line); |
283 | if (virq != NO_IRQ) | 256 | if (virq != NO_IRQ) |
284 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); | 257 | set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); |
285 | } else { | 258 | } else { |
286 | DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n", | 259 | pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", |
287 | oirq.size, oirq.specifier[0], oirq.specifier[1], | 260 | oirq.size, oirq.specifier[0], oirq.specifier[1], |
288 | oirq.controller->full_name); | 261 | oirq.controller->full_name); |
289 | 262 | ||
290 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, | 263 | virq = irq_create_of_mapping(oirq.controller, oirq.specifier, |
291 | oirq.size); | 264 | oirq.size); |
292 | } | 265 | } |
293 | if(virq == NO_IRQ) { | 266 | if(virq == NO_IRQ) { |
294 | DBG(" -> failed to map !\n"); | 267 | pr_debug(" Failed to map !\n"); |
295 | return -1; | 268 | return -1; |
296 | } | 269 | } |
297 | 270 | ||
298 | DBG(" -> mapped to linux irq %d\n", virq); | 271 | pr_debug(" Mapped to linux irq %d\n", virq); |
299 | 272 | ||
300 | pci_dev->irq = virq; | 273 | pci_dev->irq = virq; |
301 | 274 | ||
@@ -397,13 +370,10 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |||
397 | } | 370 | } |
398 | 371 | ||
399 | /* XXX would be nice to have a way to ask for write-through */ | 372 | /* XXX would be nice to have a way to ask for write-through */ |
400 | prot |= _PAGE_NO_CACHE; | ||
401 | if (write_combine) | 373 | if (write_combine) |
402 | prot &= ~_PAGE_GUARDED; | 374 | return pgprot_noncached_wc(prot); |
403 | else | 375 | else |
404 | prot |= _PAGE_GUARDED; | 376 | return pgprot_noncached(prot); |
405 | |||
406 | return __pgprot(prot); | ||
407 | } | 377 | } |
408 | 378 | ||
409 | /* | 379 | /* |
@@ -414,19 +384,17 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, | |||
414 | pgprot_t pci_phys_mem_access_prot(struct file *file, | 384 | pgprot_t pci_phys_mem_access_prot(struct file *file, |
415 | unsigned long pfn, | 385 | unsigned long pfn, |
416 | unsigned long size, | 386 | unsigned long size, |
417 | pgprot_t protection) | 387 | pgprot_t prot) |
418 | { | 388 | { |
419 | struct pci_dev *pdev = NULL; | 389 | struct pci_dev *pdev = NULL; |
420 | struct resource *found = NULL; | 390 | struct resource *found = NULL; |
421 | unsigned long prot = pgprot_val(protection); | ||
422 | resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT; | 391 | resource_size_t offset = ((resource_size_t)pfn) << PAGE_SHIFT; |
423 | int i; | 392 | int i; |
424 | 393 | ||
425 | if (page_is_ram(pfn)) | 394 | if (page_is_ram(pfn)) |
426 | return __pgprot(prot); | 395 | return prot; |
427 | |||
428 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; | ||
429 | 396 | ||
397 | prot = pgprot_noncached(prot); | ||
430 | for_each_pci_dev(pdev) { | 398 | for_each_pci_dev(pdev) { |
431 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { | 399 | for (i = 0; i <= PCI_ROM_RESOURCE; i++) { |
432 | struct resource *rp = &pdev->resource[i]; | 400 | struct resource *rp = &pdev->resource[i]; |
@@ -447,14 +415,14 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
447 | } | 415 | } |
448 | if (found) { | 416 | if (found) { |
449 | if (found->flags & IORESOURCE_PREFETCH) | 417 | if (found->flags & IORESOURCE_PREFETCH) |
450 | prot &= ~_PAGE_GUARDED; | 418 | prot = pgprot_noncached_wc(prot); |
451 | pci_dev_put(pdev); | 419 | pci_dev_put(pdev); |
452 | } | 420 | } |
453 | 421 | ||
454 | DBG("non-PCI map for %llx, prot: %lx\n", | 422 | pr_debug("PCI: Non-PCI map for %llx, prot: %lx\n", |
455 | (unsigned long long)offset, prot); | 423 | (unsigned long long)offset, pgprot_val(prot)); |
456 | 424 | ||
457 | return __pgprot(prot); | 425 | return prot; |
458 | } | 426 | } |
459 | 427 | ||
460 | 428 | ||
@@ -610,8 +578,7 @@ int pci_mmap_legacy_page_range(struct pci_bus *bus, | |||
610 | pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset); | 578 | pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset); |
611 | 579 | ||
612 | vma->vm_pgoff = offset >> PAGE_SHIFT; | 580 | vma->vm_pgoff = offset >> PAGE_SHIFT; |
613 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | 581 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
614 | | _PAGE_NO_CACHE | _PAGE_GUARDED); | ||
615 | return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, | 582 | return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, |
616 | vma->vm_end - vma->vm_start, | 583 | vma->vm_end - vma->vm_start, |
617 | vma->vm_page_prot); | 584 | vma->vm_page_prot); |
@@ -853,15 +820,12 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, | |||
853 | int pci_proc_domain(struct pci_bus *bus) | 820 | int pci_proc_domain(struct pci_bus *bus) |
854 | { | 821 | { |
855 | struct pci_controller *hose = pci_bus_to_host(bus); | 822 | struct pci_controller *hose = pci_bus_to_host(bus); |
856 | #ifdef CONFIG_PPC64 | 823 | |
857 | return hose->buid != 0; | ||
858 | #else | ||
859 | if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS)) | 824 | if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS)) |
860 | return 0; | 825 | return 0; |
861 | if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0) | 826 | if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0) |
862 | return hose->global_number != 0; | 827 | return hose->global_number != 0; |
863 | return 1; | 828 | return 1; |
864 | #endif | ||
865 | } | 829 | } |
866 | 830 | ||
867 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | 831 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, |
@@ -1083,27 +1047,50 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) | |||
1083 | } | 1047 | } |
1084 | } | 1048 | } |
1085 | 1049 | ||
1086 | static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) | 1050 | void __devinit pcibios_setup_bus_self(struct pci_bus *bus) |
1087 | { | 1051 | { |
1088 | struct pci_dev *dev = bus->self; | 1052 | /* Fix up the bus resources for P2P bridges */ |
1089 | 1053 | if (bus->self != NULL) | |
1090 | pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB"); | ||
1091 | |||
1092 | /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for | ||
1093 | * now differently between 32 and 64 bits. | ||
1094 | */ | ||
1095 | if (dev != NULL) | ||
1096 | pcibios_fixup_bridge(bus); | 1054 | pcibios_fixup_bridge(bus); |
1097 | 1055 | ||
1098 | /* Additional setup that is different between 32 and 64 bits for now */ | 1056 | /* Platform specific bus fixups. This is currently only used |
1099 | pcibios_do_bus_setup(bus); | 1057 | * by fsl_pci and I'm hoping to get rid of it at some point |
1100 | 1058 | */ | |
1101 | /* Platform specific bus fixups */ | ||
1102 | if (ppc_md.pcibios_fixup_bus) | 1059 | if (ppc_md.pcibios_fixup_bus) |
1103 | ppc_md.pcibios_fixup_bus(bus); | 1060 | ppc_md.pcibios_fixup_bus(bus); |
1104 | 1061 | ||
1105 | /* Read default IRQs and fixup if necessary */ | 1062 | /* Setup bus DMA mappings */ |
1063 | if (ppc_md.pci_dma_bus_setup) | ||
1064 | ppc_md.pci_dma_bus_setup(bus); | ||
1065 | } | ||
1066 | |||
1067 | void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) | ||
1068 | { | ||
1069 | struct pci_dev *dev; | ||
1070 | |||
1071 | pr_debug("PCI: Fixup bus devices %d (%s)\n", | ||
1072 | bus->number, bus->self ? pci_name(bus->self) : "PHB"); | ||
1073 | |||
1106 | list_for_each_entry(dev, &bus->devices, bus_list) { | 1074 | list_for_each_entry(dev, &bus->devices, bus_list) { |
1075 | struct dev_archdata *sd = &dev->dev.archdata; | ||
1076 | |||
1077 | /* Setup OF node pointer in archdata */ | ||
1078 | sd->of_node = pci_device_to_OF_node(dev); | ||
1079 | |||
1080 | /* Fixup NUMA node as it may not be setup yet by the generic | ||
1081 | * code and is needed by the DMA init | ||
1082 | */ | ||
1083 | set_dev_node(&dev->dev, pcibus_to_node(dev->bus)); | ||
1084 | |||
1085 | /* Hook up default DMA ops */ | ||
1086 | sd->dma_ops = pci_dma_ops; | ||
1087 | sd->dma_data = (void *)PCI_DRAM_OFFSET; | ||
1088 | |||
1089 | /* Additional platform DMA/iommu setup */ | ||
1090 | if (ppc_md.pci_dma_dev_setup) | ||
1091 | ppc_md.pci_dma_dev_setup(dev); | ||
1092 | |||
1093 | /* Read default IRQs and fixup if necessary */ | ||
1107 | pci_read_irq_line(dev); | 1094 | pci_read_irq_line(dev); |
1108 | if (ppc_md.pci_irq_fixup) | 1095 | if (ppc_md.pci_irq_fixup) |
1109 | ppc_md.pci_irq_fixup(dev); | 1096 | ppc_md.pci_irq_fixup(dev); |
@@ -1113,22 +1100,19 @@ static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) | |||
1113 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 1100 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
1114 | { | 1101 | { |
1115 | /* When called from the generic PCI probe, read PCI<->PCI bridge | 1102 | /* When called from the generic PCI probe, read PCI<->PCI bridge |
1116 | * bases before proceeding | 1103 | * bases. This is -not- called when generating the PCI tree from |
1104 | * the OF device-tree. | ||
1117 | */ | 1105 | */ |
1118 | if (bus->self != NULL) | 1106 | if (bus->self != NULL) |
1119 | pci_read_bridge_bases(bus); | 1107 | pci_read_bridge_bases(bus); |
1120 | __pcibios_fixup_bus(bus); | ||
1121 | } | ||
1122 | EXPORT_SYMBOL(pcibios_fixup_bus); | ||
1123 | 1108 | ||
1124 | /* When building a bus from the OF tree rather than probing, we need a | 1109 | /* Now fixup the bus bus */ |
1125 | * slightly different version of the fixup which doesn't read the | 1110 | pcibios_setup_bus_self(bus); |
1126 | * bridge bases using config space accesses | 1111 | |
1127 | */ | 1112 | /* Now fixup devices on that bus */ |
1128 | void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus) | 1113 | pcibios_setup_bus_devices(bus); |
1129 | { | ||
1130 | __pcibios_fixup_bus(bus); | ||
1131 | } | 1114 | } |
1115 | EXPORT_SYMBOL(pcibios_fixup_bus); | ||
1132 | 1116 | ||
1133 | static int skip_isa_ioresource_align(struct pci_dev *dev) | 1117 | static int skip_isa_ioresource_align(struct pci_dev *dev) |
1134 | { | 1118 | { |
@@ -1198,10 +1182,10 @@ static int __init reparent_resources(struct resource *parent, | |||
1198 | *pp = NULL; | 1182 | *pp = NULL; |
1199 | for (p = res->child; p != NULL; p = p->sibling) { | 1183 | for (p = res->child; p != NULL; p = p->sibling) { |
1200 | p->parent = res; | 1184 | p->parent = res; |
1201 | DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", | 1185 | pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n", |
1202 | p->name, | 1186 | p->name, |
1203 | (unsigned long long)p->start, | 1187 | (unsigned long long)p->start, |
1204 | (unsigned long long)p->end, res->name); | 1188 | (unsigned long long)p->end, res->name); |
1205 | } | 1189 | } |
1206 | return 0; | 1190 | return 0; |
1207 | } | 1191 | } |
@@ -1245,9 +1229,12 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1245 | int i; | 1229 | int i; |
1246 | struct resource *res, *pr; | 1230 | struct resource *res, *pr; |
1247 | 1231 | ||
1232 | pr_debug("PCI: Allocating bus resources for %04x:%02x...\n", | ||
1233 | pci_domain_nr(bus), bus->number); | ||
1234 | |||
1248 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { | 1235 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { |
1249 | if ((res = bus->resource[i]) == NULL || !res->flags | 1236 | if ((res = bus->resource[i]) == NULL || !res->flags |
1250 | || res->start > res->end) | 1237 | || res->start > res->end || res->parent) |
1251 | continue; | 1238 | continue; |
1252 | if (bus->parent == NULL) | 1239 | if (bus->parent == NULL) |
1253 | pr = (res->flags & IORESOURCE_IO) ? | 1240 | pr = (res->flags & IORESOURCE_IO) ? |
@@ -1271,14 +1258,14 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1271 | } | 1258 | } |
1272 | } | 1259 | } |
1273 | 1260 | ||
1274 | DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx " | 1261 | pr_debug("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx " |
1275 | "[0x%x], parent %p (%s)\n", | 1262 | "[0x%x], parent %p (%s)\n", |
1276 | bus->self ? pci_name(bus->self) : "PHB", | 1263 | bus->self ? pci_name(bus->self) : "PHB", |
1277 | bus->number, i, | 1264 | bus->number, i, |
1278 | (unsigned long long)res->start, | 1265 | (unsigned long long)res->start, |
1279 | (unsigned long long)res->end, | 1266 | (unsigned long long)res->end, |
1280 | (unsigned int)res->flags, | 1267 | (unsigned int)res->flags, |
1281 | pr, (pr && pr->name) ? pr->name : "nil"); | 1268 | pr, (pr && pr->name) ? pr->name : "nil"); |
1282 | 1269 | ||
1283 | if (pr && !(pr->flags & IORESOURCE_UNSET)) { | 1270 | if (pr && !(pr->flags & IORESOURCE_UNSET)) { |
1284 | if (request_resource(pr, res) == 0) | 1271 | if (request_resource(pr, res) == 0) |
@@ -1305,11 +1292,11 @@ static inline void __devinit alloc_resource(struct pci_dev *dev, int idx) | |||
1305 | { | 1292 | { |
1306 | struct resource *pr, *r = &dev->resource[idx]; | 1293 | struct resource *pr, *r = &dev->resource[idx]; |
1307 | 1294 | ||
1308 | DBG("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", | 1295 | pr_debug("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", |
1309 | pci_name(dev), idx, | 1296 | pci_name(dev), idx, |
1310 | (unsigned long long)r->start, | 1297 | (unsigned long long)r->start, |
1311 | (unsigned long long)r->end, | 1298 | (unsigned long long)r->end, |
1312 | (unsigned int)r->flags); | 1299 | (unsigned int)r->flags); |
1313 | 1300 | ||
1314 | pr = pci_find_parent_resource(dev, r); | 1301 | pr = pci_find_parent_resource(dev, r); |
1315 | if (!pr || (pr->flags & IORESOURCE_UNSET) || | 1302 | if (!pr || (pr->flags & IORESOURCE_UNSET) || |
@@ -1317,10 +1304,11 @@ static inline void __devinit alloc_resource(struct pci_dev *dev, int idx) | |||
1317 | printk(KERN_WARNING "PCI: Cannot allocate resource region %d" | 1304 | printk(KERN_WARNING "PCI: Cannot allocate resource region %d" |
1318 | " of device %s, will remap\n", idx, pci_name(dev)); | 1305 | " of device %s, will remap\n", idx, pci_name(dev)); |
1319 | if (pr) | 1306 | if (pr) |
1320 | DBG("PCI: parent is %p: %016llx-%016llx [%x]\n", pr, | 1307 | pr_debug("PCI: parent is %p: %016llx-%016llx [%x]\n", |
1321 | (unsigned long long)pr->start, | 1308 | pr, |
1322 | (unsigned long long)pr->end, | 1309 | (unsigned long long)pr->start, |
1323 | (unsigned int)pr->flags); | 1310 | (unsigned long long)pr->end, |
1311 | (unsigned int)pr->flags); | ||
1324 | /* We'll assign a new address later */ | 1312 | /* We'll assign a new address later */ |
1325 | r->flags |= IORESOURCE_UNSET; | 1313 | r->flags |= IORESOURCE_UNSET; |
1326 | r->end -= r->start; | 1314 | r->end -= r->start; |
@@ -1358,7 +1346,8 @@ static void __init pcibios_allocate_resources(int pass) | |||
1358 | * but keep it unregistered. | 1346 | * but keep it unregistered. |
1359 | */ | 1347 | */ |
1360 | u32 reg; | 1348 | u32 reg; |
1361 | DBG("PCI: Switching off ROM of %s\n", pci_name(dev)); | 1349 | pr_debug("PCI: Switching off ROM of %s\n", |
1350 | pci_name(dev)); | ||
1362 | r->flags &= ~IORESOURCE_ROM_ENABLE; | 1351 | r->flags &= ~IORESOURCE_ROM_ENABLE; |
1363 | pci_read_config_dword(dev, dev->rom_base_reg, ®); | 1352 | pci_read_config_dword(dev, dev->rom_base_reg, ®); |
1364 | pci_write_config_dword(dev, dev->rom_base_reg, | 1353 | pci_write_config_dword(dev, dev->rom_base_reg, |
@@ -1383,7 +1372,7 @@ void __init pcibios_resource_survey(void) | |||
1383 | } | 1372 | } |
1384 | 1373 | ||
1385 | if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { | 1374 | if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { |
1386 | DBG("PCI: Assigning unassigned resouces...\n"); | 1375 | pr_debug("PCI: Assigning unassigned resouces...\n"); |
1387 | pci_assign_unassigned_resources(); | 1376 | pci_assign_unassigned_resources(); |
1388 | } | 1377 | } |
1389 | 1378 | ||
@@ -1393,9 +1382,11 @@ void __init pcibios_resource_survey(void) | |||
1393 | } | 1382 | } |
1394 | 1383 | ||
1395 | #ifdef CONFIG_HOTPLUG | 1384 | #ifdef CONFIG_HOTPLUG |
1396 | /* This is used by the pSeries hotplug driver to allocate resource | 1385 | |
1386 | /* This is used by the PCI hotplug driver to allocate resource | ||
1397 | * of newly plugged busses. We can try to consolidate with the | 1387 | * of newly plugged busses. We can try to consolidate with the |
1398 | * rest of the code later, for now, keep it as-is | 1388 | * rest of the code later, for now, keep it as-is as our main |
1389 | * resource allocation function doesn't deal with sub-trees yet. | ||
1399 | */ | 1390 | */ |
1400 | void __devinit pcibios_claim_one_bus(struct pci_bus *bus) | 1391 | void __devinit pcibios_claim_one_bus(struct pci_bus *bus) |
1401 | { | 1392 | { |
@@ -1410,6 +1401,14 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus) | |||
1410 | 1401 | ||
1411 | if (r->parent || !r->start || !r->flags) | 1402 | if (r->parent || !r->start || !r->flags) |
1412 | continue; | 1403 | continue; |
1404 | |||
1405 | pr_debug("PCI: Claiming %s: " | ||
1406 | "Resource %d: %016llx..%016llx [%x]\n", | ||
1407 | pci_name(dev), i, | ||
1408 | (unsigned long long)r->start, | ||
1409 | (unsigned long long)r->end, | ||
1410 | (unsigned int)r->flags); | ||
1411 | |||
1413 | pci_claim_resource(dev, i); | 1412 | pci_claim_resource(dev, i); |
1414 | } | 1413 | } |
1415 | } | 1414 | } |
@@ -1418,6 +1417,31 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus) | |||
1418 | pcibios_claim_one_bus(child_bus); | 1417 | pcibios_claim_one_bus(child_bus); |
1419 | } | 1418 | } |
1420 | EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); | 1419 | EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); |
1420 | |||
1421 | |||
1422 | /* pcibios_finish_adding_to_bus | ||
1423 | * | ||
1424 | * This is to be called by the hotplug code after devices have been | ||
1425 | * added to a bus, this include calling it for a PHB that is just | ||
1426 | * being added | ||
1427 | */ | ||
1428 | void pcibios_finish_adding_to_bus(struct pci_bus *bus) | ||
1429 | { | ||
1430 | pr_debug("PCI: Finishing adding to hotplug bus %04x:%02x\n", | ||
1431 | pci_domain_nr(bus), bus->number); | ||
1432 | |||
1433 | /* Allocate bus and devices resources */ | ||
1434 | pcibios_allocate_bus_resources(bus); | ||
1435 | pcibios_claim_one_bus(bus); | ||
1436 | |||
1437 | /* Add new devices to global lists. Register in proc, sysfs. */ | ||
1438 | pci_bus_add_devices(bus); | ||
1439 | |||
1440 | /* Fixup EEH */ | ||
1441 | eeh_add_device_tree_late(bus); | ||
1442 | } | ||
1443 | EXPORT_SYMBOL_GPL(pcibios_finish_adding_to_bus); | ||
1444 | |||
1421 | #endif /* CONFIG_HOTPLUG */ | 1445 | #endif /* CONFIG_HOTPLUG */ |
1422 | 1446 | ||
1423 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 1447 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
@@ -1428,3 +1452,61 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
1428 | 1452 | ||
1429 | return pci_enable_resources(dev, mask); | 1453 | return pci_enable_resources(dev, mask); |
1430 | } | 1454 | } |
1455 | |||
1456 | void __devinit pcibios_setup_phb_resources(struct pci_controller *hose) | ||
1457 | { | ||
1458 | struct pci_bus *bus = hose->bus; | ||
1459 | struct resource *res; | ||
1460 | int i; | ||
1461 | |||
1462 | /* Hookup PHB IO resource */ | ||
1463 | bus->resource[0] = res = &hose->io_resource; | ||
1464 | |||
1465 | if (!res->flags) { | ||
1466 | printk(KERN_WARNING "PCI: I/O resource not set for host" | ||
1467 | " bridge %s (domain %d)\n", | ||
1468 | hose->dn->full_name, hose->global_number); | ||
1469 | #ifdef CONFIG_PPC32 | ||
1470 | /* Workaround for lack of IO resource only on 32-bit */ | ||
1471 | res->start = (unsigned long)hose->io_base_virt - isa_io_base; | ||
1472 | res->end = res->start + IO_SPACE_LIMIT; | ||
1473 | res->flags = IORESOURCE_IO; | ||
1474 | #endif /* CONFIG_PPC32 */ | ||
1475 | } | ||
1476 | |||
1477 | pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n", | ||
1478 | (unsigned long long)res->start, | ||
1479 | (unsigned long long)res->end, | ||
1480 | (unsigned long)res->flags); | ||
1481 | |||
1482 | /* Hookup PHB Memory resources */ | ||
1483 | for (i = 0; i < 3; ++i) { | ||
1484 | res = &hose->mem_resources[i]; | ||
1485 | if (!res->flags) { | ||
1486 | if (i > 0) | ||
1487 | continue; | ||
1488 | printk(KERN_ERR "PCI: Memory resource 0 not set for " | ||
1489 | "host bridge %s (domain %d)\n", | ||
1490 | hose->dn->full_name, hose->global_number); | ||
1491 | #ifdef CONFIG_PPC32 | ||
1492 | /* Workaround for lack of MEM resource only on 32-bit */ | ||
1493 | res->start = hose->pci_mem_offset; | ||
1494 | res->end = (resource_size_t)-1LL; | ||
1495 | res->flags = IORESOURCE_MEM; | ||
1496 | #endif /* CONFIG_PPC32 */ | ||
1497 | } | ||
1498 | bus->resource[i+1] = res; | ||
1499 | |||
1500 | pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", i, | ||
1501 | (unsigned long long)res->start, | ||
1502 | (unsigned long long)res->end, | ||
1503 | (unsigned long)res->flags); | ||
1504 | } | ||
1505 | |||
1506 | pr_debug("PCI: PHB MEM offset = %016llx\n", | ||
1507 | (unsigned long long)hose->pci_mem_offset); | ||
1508 | pr_debug("PCI: PHB IO offset = %08lx\n", | ||
1509 | (unsigned long)hose->io_base_virt - _IO_BASE); | ||
1510 | |||
1511 | } | ||
1512 | |||
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index 131b1dfa68c6..132cd80afa21 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
@@ -26,12 +26,6 @@ | |||
26 | 26 | ||
27 | #undef DEBUG | 27 | #undef DEBUG |
28 | 28 | ||
29 | #ifdef DEBUG | ||
30 | #define DBG(x...) printk(x) | ||
31 | #else | ||
32 | #define DBG(x...) | ||
33 | #endif | ||
34 | |||
35 | unsigned long isa_io_base = 0; | 29 | unsigned long isa_io_base = 0; |
36 | unsigned long pci_dram_offset = 0; | 30 | unsigned long pci_dram_offset = 0; |
37 | int pcibios_assign_bus_offset = 1; | 31 | int pcibios_assign_bus_offset = 1; |
@@ -272,17 +266,14 @@ pci_busdev_to_OF_node(struct pci_bus *bus, int devfn) | |||
272 | { | 266 | { |
273 | struct device_node *parent, *np; | 267 | struct device_node *parent, *np; |
274 | 268 | ||
275 | if (!have_of) | 269 | pr_debug("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn); |
276 | return NULL; | ||
277 | |||
278 | DBG("pci_busdev_to_OF_node(%d,0x%x)\n", bus->number, devfn); | ||
279 | parent = scan_OF_for_pci_bus(bus); | 270 | parent = scan_OF_for_pci_bus(bus); |
280 | if (parent == NULL) | 271 | if (parent == NULL) |
281 | return NULL; | 272 | return NULL; |
282 | DBG(" parent is %s\n", parent ? parent->full_name : "<NULL>"); | 273 | pr_debug(" parent is %s\n", parent ? parent->full_name : "<NULL>"); |
283 | np = scan_OF_for_pci_dev(parent, devfn); | 274 | np = scan_OF_for_pci_dev(parent, devfn); |
284 | of_node_put(parent); | 275 | of_node_put(parent); |
285 | DBG(" result is %s\n", np ? np->full_name : "<NULL>"); | 276 | pr_debug(" result is %s\n", np ? np->full_name : "<NULL>"); |
286 | 277 | ||
287 | /* XXX most callers don't release the returned node | 278 | /* XXX most callers don't release the returned node |
288 | * mostly because ppc64 doesn't increase the refcount, | 279 | * mostly because ppc64 doesn't increase the refcount, |
@@ -315,8 +306,6 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) | |||
315 | struct pci_controller* hose; | 306 | struct pci_controller* hose; |
316 | struct pci_dev* dev = NULL; | 307 | struct pci_dev* dev = NULL; |
317 | 308 | ||
318 | if (!have_of) | ||
319 | return -ENODEV; | ||
320 | /* Make sure it's really a PCI device */ | 309 | /* Make sure it's really a PCI device */ |
321 | hose = pci_find_hose_for_OF_device(node); | 310 | hose = pci_find_hose_for_OF_device(node); |
322 | if (!hose || !hose->dn) | 311 | if (!hose || !hose->dn) |
@@ -379,10 +368,41 @@ void pcibios_make_OF_bus_map(void) | |||
379 | } | 368 | } |
380 | #endif /* CONFIG_PPC_OF */ | 369 | #endif /* CONFIG_PPC_OF */ |
381 | 370 | ||
371 | static void __devinit pcibios_scan_phb(struct pci_controller *hose) | ||
372 | { | ||
373 | struct pci_bus *bus; | ||
374 | struct device_node *node = hose->dn; | ||
375 | unsigned long io_offset; | ||
376 | struct resource *res = &hose->io_resource; | ||
377 | |||
378 | pr_debug("PCI: Scanning PHB %s\n", | ||
379 | node ? node->full_name : "<NO NAME>"); | ||
380 | |||
381 | /* Create an empty bus for the toplevel */ | ||
382 | bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, hose); | ||
383 | if (bus == NULL) { | ||
384 | printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", | ||
385 | hose->global_number); | ||
386 | return; | ||
387 | } | ||
388 | bus->secondary = hose->first_busno; | ||
389 | hose->bus = bus; | ||
390 | |||
391 | /* Fixup IO space offset */ | ||
392 | io_offset = (unsigned long)hose->io_base_virt - isa_io_base; | ||
393 | res->start = (res->start + io_offset) & 0xffffffffu; | ||
394 | res->end = (res->end + io_offset) & 0xffffffffu; | ||
395 | |||
396 | /* Wire up PHB bus resources */ | ||
397 | pcibios_setup_phb_resources(hose); | ||
398 | |||
399 | /* Scan children */ | ||
400 | hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); | ||
401 | } | ||
402 | |||
382 | static int __init pcibios_init(void) | 403 | static int __init pcibios_init(void) |
383 | { | 404 | { |
384 | struct pci_controller *hose, *tmp; | 405 | struct pci_controller *hose, *tmp; |
385 | struct pci_bus *bus; | ||
386 | int next_busno = 0; | 406 | int next_busno = 0; |
387 | 407 | ||
388 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); | 408 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); |
@@ -395,12 +415,8 @@ static int __init pcibios_init(void) | |||
395 | if (pci_assign_all_buses) | 415 | if (pci_assign_all_buses) |
396 | hose->first_busno = next_busno; | 416 | hose->first_busno = next_busno; |
397 | hose->last_busno = 0xff; | 417 | hose->last_busno = 0xff; |
398 | bus = pci_scan_bus_parented(hose->parent, hose->first_busno, | 418 | pcibios_scan_phb(hose); |
399 | hose->ops, hose); | 419 | pci_bus_add_devices(hose->bus); |
400 | if (bus) { | ||
401 | pci_bus_add_devices(bus); | ||
402 | hose->last_busno = bus->subordinate; | ||
403 | } | ||
404 | if (pci_assign_all_buses || next_busno <= hose->last_busno) | 420 | if (pci_assign_all_buses || next_busno <= hose->last_busno) |
405 | next_busno = hose->last_busno + pcibios_assign_bus_offset; | 421 | next_busno = hose->last_busno + pcibios_assign_bus_offset; |
406 | } | 422 | } |
@@ -410,7 +426,7 @@ static int __init pcibios_init(void) | |||
410 | * numbers vs. kernel bus numbers since we may have to | 426 | * numbers vs. kernel bus numbers since we may have to |
411 | * remap them. | 427 | * remap them. |
412 | */ | 428 | */ |
413 | if (pci_assign_all_buses && have_of) | 429 | if (pci_assign_all_buses) |
414 | pcibios_make_OF_bus_map(); | 430 | pcibios_make_OF_bus_map(); |
415 | 431 | ||
416 | /* Call common code to handle resource allocation */ | 432 | /* Call common code to handle resource allocation */ |
@@ -425,54 +441,6 @@ static int __init pcibios_init(void) | |||
425 | 441 | ||
426 | subsys_initcall(pcibios_init); | 442 | subsys_initcall(pcibios_init); |
427 | 443 | ||
428 | void __devinit pcibios_do_bus_setup(struct pci_bus *bus) | ||
429 | { | ||
430 | struct pci_controller *hose = (struct pci_controller *) bus->sysdata; | ||
431 | unsigned long io_offset; | ||
432 | struct resource *res; | ||
433 | int i; | ||
434 | struct pci_dev *dev; | ||
435 | |||
436 | /* Hookup PHB resources */ | ||
437 | io_offset = (unsigned long)hose->io_base_virt - isa_io_base; | ||
438 | if (bus->parent == NULL) { | ||
439 | /* This is a host bridge - fill in its resources */ | ||
440 | hose->bus = bus; | ||
441 | |||
442 | bus->resource[0] = res = &hose->io_resource; | ||
443 | if (!res->flags) { | ||
444 | if (io_offset) | ||
445 | printk(KERN_ERR "I/O resource not set for host" | ||
446 | " bridge %d\n", hose->global_number); | ||
447 | res->start = 0; | ||
448 | res->end = IO_SPACE_LIMIT; | ||
449 | res->flags = IORESOURCE_IO; | ||
450 | } | ||
451 | res->start = (res->start + io_offset) & 0xffffffffu; | ||
452 | res->end = (res->end + io_offset) & 0xffffffffu; | ||
453 | |||
454 | for (i = 0; i < 3; ++i) { | ||
455 | res = &hose->mem_resources[i]; | ||
456 | if (!res->flags) { | ||
457 | if (i > 0) | ||
458 | continue; | ||
459 | printk(KERN_ERR "Memory resource not set for " | ||
460 | "host bridge %d\n", hose->global_number); | ||
461 | res->start = hose->pci_mem_offset; | ||
462 | res->end = ~0U; | ||
463 | res->flags = IORESOURCE_MEM; | ||
464 | } | ||
465 | bus->resource[i+1] = res; | ||
466 | } | ||
467 | } | ||
468 | |||
469 | if (ppc_md.pci_dma_bus_setup) | ||
470 | ppc_md.pci_dma_bus_setup(bus); | ||
471 | |||
472 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
473 | pcibios_setup_new_device(dev); | ||
474 | } | ||
475 | |||
476 | /* the next one is stolen from the alpha port... */ | 444 | /* the next one is stolen from the alpha port... */ |
477 | void __init | 445 | void __init |
478 | pcibios_update_irq(struct pci_dev *dev, int irq) | 446 | pcibios_update_irq(struct pci_dev *dev, int irq) |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 3502b9101e6b..39fadc6e1492 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -32,13 +32,6 @@ | |||
32 | #include <asm/machdep.h> | 32 | #include <asm/machdep.h> |
33 | #include <asm/ppc-pci.h> | 33 | #include <asm/ppc-pci.h> |
34 | 34 | ||
35 | #ifdef DEBUG | ||
36 | #include <asm/udbg.h> | ||
37 | #define DBG(fmt...) printk(fmt) | ||
38 | #else | ||
39 | #define DBG(fmt...) | ||
40 | #endif | ||
41 | |||
42 | unsigned long pci_probe_only = 1; | 35 | unsigned long pci_probe_only = 1; |
43 | 36 | ||
44 | /* pci_io_base -- the base address from which io bars are offsets. | 37 | /* pci_io_base -- the base address from which io bars are offsets. |
@@ -102,7 +95,7 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) | |||
102 | addrs = of_get_property(node, "assigned-addresses", &proplen); | 95 | addrs = of_get_property(node, "assigned-addresses", &proplen); |
103 | if (!addrs) | 96 | if (!addrs) |
104 | return; | 97 | return; |
105 | DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); | 98 | pr_debug(" parse addresses (%d bytes) @ %p\n", proplen, addrs); |
106 | for (; proplen >= 20; proplen -= 20, addrs += 5) { | 99 | for (; proplen >= 20; proplen -= 20, addrs += 5) { |
107 | flags = pci_parse_of_flags(addrs[0]); | 100 | flags = pci_parse_of_flags(addrs[0]); |
108 | if (!flags) | 101 | if (!flags) |
@@ -112,8 +105,9 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) | |||
112 | if (!size) | 105 | if (!size) |
113 | continue; | 106 | continue; |
114 | i = addrs[0] & 0xff; | 107 | i = addrs[0] & 0xff; |
115 | DBG(" base: %llx, size: %llx, i: %x\n", | 108 | pr_debug(" base: %llx, size: %llx, i: %x\n", |
116 | (unsigned long long)base, (unsigned long long)size, i); | 109 | (unsigned long long)base, |
110 | (unsigned long long)size, i); | ||
117 | 111 | ||
118 | if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { | 112 | if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { |
119 | res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; | 113 | res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; |
@@ -144,7 +138,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, | |||
144 | if (type == NULL) | 138 | if (type == NULL) |
145 | type = ""; | 139 | type = ""; |
146 | 140 | ||
147 | DBG(" create device, devfn: %x, type: %s\n", devfn, type); | 141 | pr_debug(" create device, devfn: %x, type: %s\n", devfn, type); |
148 | 142 | ||
149 | dev->bus = bus; | 143 | dev->bus = bus; |
150 | dev->sysdata = node; | 144 | dev->sysdata = node; |
@@ -165,8 +159,8 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, | |||
165 | dev->class = get_int_prop(node, "class-code", 0); | 159 | dev->class = get_int_prop(node, "class-code", 0); |
166 | dev->revision = get_int_prop(node, "revision-id", 0); | 160 | dev->revision = get_int_prop(node, "revision-id", 0); |
167 | 161 | ||
168 | DBG(" class: 0x%x\n", dev->class); | 162 | pr_debug(" class: 0x%x\n", dev->class); |
169 | DBG(" revision: 0x%x\n", dev->revision); | 163 | pr_debug(" revision: 0x%x\n", dev->revision); |
170 | 164 | ||
171 | dev->current_state = 4; /* unknown power state */ | 165 | dev->current_state = 4; /* unknown power state */ |
172 | dev->error_state = pci_channel_io_normal; | 166 | dev->error_state = pci_channel_io_normal; |
@@ -187,7 +181,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, | |||
187 | 181 | ||
188 | pci_parse_of_addrs(node, dev); | 182 | pci_parse_of_addrs(node, dev); |
189 | 183 | ||
190 | DBG(" adding to system ...\n"); | 184 | pr_debug(" adding to system ...\n"); |
191 | 185 | ||
192 | pci_device_add(dev, bus); | 186 | pci_device_add(dev, bus); |
193 | 187 | ||
@@ -195,19 +189,20 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, | |||
195 | } | 189 | } |
196 | EXPORT_SYMBOL(of_create_pci_dev); | 190 | EXPORT_SYMBOL(of_create_pci_dev); |
197 | 191 | ||
198 | void __devinit of_scan_bus(struct device_node *node, | 192 | static void __devinit __of_scan_bus(struct device_node *node, |
199 | struct pci_bus *bus) | 193 | struct pci_bus *bus, int rescan_existing) |
200 | { | 194 | { |
201 | struct device_node *child; | 195 | struct device_node *child; |
202 | const u32 *reg; | 196 | const u32 *reg; |
203 | int reglen, devfn; | 197 | int reglen, devfn; |
204 | struct pci_dev *dev; | 198 | struct pci_dev *dev; |
205 | 199 | ||
206 | DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number); | 200 | pr_debug("of_scan_bus(%s) bus no %d... \n", |
201 | node->full_name, bus->number); | ||
207 | 202 | ||
208 | /* Scan direct children */ | 203 | /* Scan direct children */ |
209 | for_each_child_of_node(node, child) { | 204 | for_each_child_of_node(node, child) { |
210 | DBG(" * %s\n", child->full_name); | 205 | pr_debug(" * %s\n", child->full_name); |
211 | reg = of_get_property(child, "reg", ®len); | 206 | reg = of_get_property(child, "reg", ®len); |
212 | if (reg == NULL || reglen < 20) | 207 | if (reg == NULL || reglen < 20) |
213 | continue; | 208 | continue; |
@@ -217,11 +212,15 @@ void __devinit of_scan_bus(struct device_node *node, | |||
217 | dev = of_create_pci_dev(child, bus, devfn); | 212 | dev = of_create_pci_dev(child, bus, devfn); |
218 | if (!dev) | 213 | if (!dev) |
219 | continue; | 214 | continue; |
220 | DBG(" dev header type: %x\n", dev->hdr_type); | 215 | pr_debug(" dev header type: %x\n", dev->hdr_type); |
221 | } | 216 | } |
222 | 217 | ||
223 | /* Ally all fixups */ | 218 | /* Apply all fixups necessary. We don't fixup the bus "self" |
224 | pcibios_fixup_of_probed_bus(bus); | 219 | * for an existing bridge that is being rescanned |
220 | */ | ||
221 | if (!rescan_existing) | ||
222 | pcibios_setup_bus_self(bus); | ||
223 | pcibios_setup_bus_devices(bus); | ||
225 | 224 | ||
226 | /* Now scan child busses */ | 225 | /* Now scan child busses */ |
227 | list_for_each_entry(dev, &bus->devices, bus_list) { | 226 | list_for_each_entry(dev, &bus->devices, bus_list) { |
@@ -233,7 +232,20 @@ void __devinit of_scan_bus(struct device_node *node, | |||
233 | } | 232 | } |
234 | } | 233 | } |
235 | } | 234 | } |
236 | EXPORT_SYMBOL(of_scan_bus); | 235 | |
236 | void __devinit of_scan_bus(struct device_node *node, | ||
237 | struct pci_bus *bus) | ||
238 | { | ||
239 | __of_scan_bus(node, bus, 0); | ||
240 | } | ||
241 | EXPORT_SYMBOL_GPL(of_scan_bus); | ||
242 | |||
243 | void __devinit of_rescan_bus(struct device_node *node, | ||
244 | struct pci_bus *bus) | ||
245 | { | ||
246 | __of_scan_bus(node, bus, 1); | ||
247 | } | ||
248 | EXPORT_SYMBOL_GPL(of_rescan_bus); | ||
237 | 249 | ||
238 | void __devinit of_scan_pci_bridge(struct device_node *node, | 250 | void __devinit of_scan_pci_bridge(struct device_node *node, |
239 | struct pci_dev *dev) | 251 | struct pci_dev *dev) |
@@ -245,7 +257,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node, | |||
245 | unsigned int flags; | 257 | unsigned int flags; |
246 | u64 size; | 258 | u64 size; |
247 | 259 | ||
248 | DBG("of_scan_pci_bridge(%s)\n", node->full_name); | 260 | pr_debug("of_scan_pci_bridge(%s)\n", node->full_name); |
249 | 261 | ||
250 | /* parse bus-range property */ | 262 | /* parse bus-range property */ |
251 | busrange = of_get_property(node, "bus-range", &len); | 263 | busrange = of_get_property(node, "bus-range", &len); |
@@ -309,12 +321,12 @@ void __devinit of_scan_pci_bridge(struct device_node *node, | |||
309 | } | 321 | } |
310 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), | 322 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), |
311 | bus->number); | 323 | bus->number); |
312 | DBG(" bus name: %s\n", bus->name); | 324 | pr_debug(" bus name: %s\n", bus->name); |
313 | 325 | ||
314 | mode = PCI_PROBE_NORMAL; | 326 | mode = PCI_PROBE_NORMAL; |
315 | if (ppc_md.pci_probe_mode) | 327 | if (ppc_md.pci_probe_mode) |
316 | mode = ppc_md.pci_probe_mode(bus); | 328 | mode = ppc_md.pci_probe_mode(bus); |
317 | DBG(" probe mode: %d\n", mode); | 329 | pr_debug(" probe mode: %d\n", mode); |
318 | 330 | ||
319 | if (mode == PCI_PROBE_DEVTREE) | 331 | if (mode == PCI_PROBE_DEVTREE) |
320 | of_scan_bus(node, bus); | 332 | of_scan_bus(node, bus); |
@@ -327,9 +339,10 @@ void __devinit scan_phb(struct pci_controller *hose) | |||
327 | { | 339 | { |
328 | struct pci_bus *bus; | 340 | struct pci_bus *bus; |
329 | struct device_node *node = hose->dn; | 341 | struct device_node *node = hose->dn; |
330 | int i, mode; | 342 | int mode; |
331 | 343 | ||
332 | DBG("PCI: Scanning PHB %s\n", node ? node->full_name : "<NO NAME>"); | 344 | pr_debug("PCI: Scanning PHB %s\n", |
345 | node ? node->full_name : "<NO NAME>"); | ||
333 | 346 | ||
334 | /* Create an empty bus for the toplevel */ | 347 | /* Create an empty bus for the toplevel */ |
335 | bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); | 348 | bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); |
@@ -345,26 +358,13 @@ void __devinit scan_phb(struct pci_controller *hose) | |||
345 | pcibios_map_io_space(bus); | 358 | pcibios_map_io_space(bus); |
346 | 359 | ||
347 | /* Wire up PHB bus resources */ | 360 | /* Wire up PHB bus resources */ |
348 | DBG("PCI: PHB IO resource = %016lx-%016lx [%lx]\n", | 361 | pcibios_setup_phb_resources(hose); |
349 | hose->io_resource.start, hose->io_resource.end, | ||
350 | hose->io_resource.flags); | ||
351 | bus->resource[0] = &hose->io_resource; | ||
352 | for (i = 0; i < 3; ++i) { | ||
353 | DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i, | ||
354 | hose->mem_resources[i].start, | ||
355 | hose->mem_resources[i].end, | ||
356 | hose->mem_resources[i].flags); | ||
357 | bus->resource[i+1] = &hose->mem_resources[i]; | ||
358 | } | ||
359 | DBG("PCI: PHB MEM offset = %016lx\n", hose->pci_mem_offset); | ||
360 | DBG("PCI: PHB IO offset = %08lx\n", | ||
361 | (unsigned long)hose->io_base_virt - _IO_BASE); | ||
362 | 362 | ||
363 | /* Get probe mode and perform scan */ | 363 | /* Get probe mode and perform scan */ |
364 | mode = PCI_PROBE_NORMAL; | 364 | mode = PCI_PROBE_NORMAL; |
365 | if (node && ppc_md.pci_probe_mode) | 365 | if (node && ppc_md.pci_probe_mode) |
366 | mode = ppc_md.pci_probe_mode(bus); | 366 | mode = ppc_md.pci_probe_mode(bus); |
367 | DBG(" probe mode: %d\n", mode); | 367 | pr_debug(" probe mode: %d\n", mode); |
368 | if (mode == PCI_PROBE_DEVTREE) { | 368 | if (mode == PCI_PROBE_DEVTREE) { |
369 | bus->subordinate = hose->last_busno; | 369 | bus->subordinate = hose->last_busno; |
370 | of_scan_bus(node, bus); | 370 | of_scan_bus(node, bus); |
@@ -380,7 +380,7 @@ static int __init pcibios_init(void) | |||
380 | 380 | ||
381 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); | 381 | printk(KERN_INFO "PCI: Probing PCI hardware\n"); |
382 | 382 | ||
383 | /* For now, override phys_mem_access_prot. If we need it, | 383 | /* For now, override phys_mem_access_prot. If we need it,g |
384 | * later, we may move that initialization to each ppc_md | 384 | * later, we may move that initialization to each ppc_md |
385 | */ | 385 | */ |
386 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | 386 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; |
@@ -388,6 +388,11 @@ static int __init pcibios_init(void) | |||
388 | if (pci_probe_only) | 388 | if (pci_probe_only) |
389 | ppc_pci_flags |= PPC_PCI_PROBE_ONLY; | 389 | ppc_pci_flags |= PPC_PCI_PROBE_ONLY; |
390 | 390 | ||
391 | /* On ppc64, we always enable PCI domains and we keep domain 0 | ||
392 | * backward compatible in /proc for video cards | ||
393 | */ | ||
394 | ppc_pci_flags |= PPC_PCI_ENABLE_PROC_DOMAINS | PPC_PCI_COMPAT_DOMAIN_0; | ||
395 | |||
391 | /* Scan all of the recorded PCI controllers. */ | 396 | /* Scan all of the recorded PCI controllers. */ |
392 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { | 397 | list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { |
393 | scan_phb(hose); | 398 | scan_phb(hose); |
@@ -422,8 +427,8 @@ int pcibios_unmap_io_space(struct pci_bus *bus) | |||
422 | if (bus->self) { | 427 | if (bus->self) { |
423 | struct resource *res = bus->resource[0]; | 428 | struct resource *res = bus->resource[0]; |
424 | 429 | ||
425 | DBG("IO unmapping for PCI-PCI bridge %s\n", | 430 | pr_debug("IO unmapping for PCI-PCI bridge %s\n", |
426 | pci_name(bus->self)); | 431 | pci_name(bus->self)); |
427 | 432 | ||
428 | __flush_hash_table_range(&init_mm, res->start + _IO_BASE, | 433 | __flush_hash_table_range(&init_mm, res->start + _IO_BASE, |
429 | res->end + _IO_BASE + 1); | 434 | res->end + _IO_BASE + 1); |
@@ -437,8 +442,8 @@ int pcibios_unmap_io_space(struct pci_bus *bus) | |||
437 | if (hose->io_base_alloc == 0) | 442 | if (hose->io_base_alloc == 0) |
438 | return 0; | 443 | return 0; |
439 | 444 | ||
440 | DBG("IO unmapping for PHB %s\n", hose->dn->full_name); | 445 | pr_debug("IO unmapping for PHB %s\n", hose->dn->full_name); |
441 | DBG(" alloc=0x%p\n", hose->io_base_alloc); | 446 | pr_debug(" alloc=0x%p\n", hose->io_base_alloc); |
442 | 447 | ||
443 | /* This is a PHB, we fully unmap the IO area */ | 448 | /* This is a PHB, we fully unmap the IO area */ |
444 | vunmap(hose->io_base_alloc); | 449 | vunmap(hose->io_base_alloc); |
@@ -463,11 +468,11 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) | |||
463 | * thus HPTEs will be faulted in when needed | 468 | * thus HPTEs will be faulted in when needed |
464 | */ | 469 | */ |
465 | if (bus->self) { | 470 | if (bus->self) { |
466 | DBG("IO mapping for PCI-PCI bridge %s\n", | 471 | pr_debug("IO mapping for PCI-PCI bridge %s\n", |
467 | pci_name(bus->self)); | 472 | pci_name(bus->self)); |
468 | DBG(" virt=0x%016lx...0x%016lx\n", | 473 | pr_debug(" virt=0x%016lx...0x%016lx\n", |
469 | bus->resource[0]->start + _IO_BASE, | 474 | bus->resource[0]->start + _IO_BASE, |
470 | bus->resource[0]->end + _IO_BASE); | 475 | bus->resource[0]->end + _IO_BASE); |
471 | return 0; | 476 | return 0; |
472 | } | 477 | } |
473 | 478 | ||
@@ -496,11 +501,11 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) | |||
496 | hose->io_base_virt = (void __iomem *)(area->addr + | 501 | hose->io_base_virt = (void __iomem *)(area->addr + |
497 | hose->io_base_phys - phys_page); | 502 | hose->io_base_phys - phys_page); |
498 | 503 | ||
499 | DBG("IO mapping for PHB %s\n", hose->dn->full_name); | 504 | pr_debug("IO mapping for PHB %s\n", hose->dn->full_name); |
500 | DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", | 505 | pr_debug(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", |
501 | hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); | 506 | hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); |
502 | DBG(" size=0x%016lx (alloc=0x%016lx)\n", | 507 | pr_debug(" size=0x%016lx (alloc=0x%016lx)\n", |
503 | hose->pci_io_size, size_page); | 508 | hose->pci_io_size, size_page); |
504 | 509 | ||
505 | /* Establish the mapping */ | 510 | /* Establish the mapping */ |
506 | if (__ioremap_at(phys_page, area->addr, size_page, | 511 | if (__ioremap_at(phys_page, area->addr, size_page, |
@@ -512,24 +517,13 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) | |||
512 | hose->io_resource.start += io_virt_offset; | 517 | hose->io_resource.start += io_virt_offset; |
513 | hose->io_resource.end += io_virt_offset; | 518 | hose->io_resource.end += io_virt_offset; |
514 | 519 | ||
515 | DBG(" hose->io_resource=0x%016lx...0x%016lx\n", | 520 | pr_debug(" hose->io_resource=0x%016lx...0x%016lx\n", |
516 | hose->io_resource.start, hose->io_resource.end); | 521 | hose->io_resource.start, hose->io_resource.end); |
517 | 522 | ||
518 | return 0; | 523 | return 0; |
519 | } | 524 | } |
520 | EXPORT_SYMBOL_GPL(pcibios_map_io_space); | 525 | EXPORT_SYMBOL_GPL(pcibios_map_io_space); |
521 | 526 | ||
522 | void __devinit pcibios_do_bus_setup(struct pci_bus *bus) | ||
523 | { | ||
524 | struct pci_dev *dev; | ||
525 | |||
526 | if (ppc_md.pci_dma_bus_setup) | ||
527 | ppc_md.pci_dma_bus_setup(bus); | ||
528 | |||
529 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
530 | pcibios_setup_new_device(dev); | ||
531 | } | ||
532 | |||
533 | unsigned long pci_address_to_pio(phys_addr_t address) | 527 | unsigned long pci_address_to_pio(phys_addr_t address) |
534 | { | 528 | { |
535 | struct pci_controller *hose, *tmp; | 529 | struct pci_controller *hose, *tmp; |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 260089dccfb0..dcec1325d340 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -116,12 +116,6 @@ EXPORT_SYMBOL(giveup_spe); | |||
116 | 116 | ||
117 | #ifndef CONFIG_PPC64 | 117 | #ifndef CONFIG_PPC64 |
118 | EXPORT_SYMBOL(flush_instruction_cache); | 118 | EXPORT_SYMBOL(flush_instruction_cache); |
119 | EXPORT_SYMBOL(flush_tlb_kernel_range); | ||
120 | EXPORT_SYMBOL(flush_tlb_page); | ||
121 | EXPORT_SYMBOL(_tlbie); | ||
122 | #if defined(CONFIG_4xx) || defined(CONFIG_8xx) || defined(CONFIG_FSL_BOOKE) | ||
123 | EXPORT_SYMBOL(_tlbil_va); | ||
124 | #endif | ||
125 | #endif | 119 | #endif |
126 | EXPORT_SYMBOL(__flush_icache_range); | 120 | EXPORT_SYMBOL(__flush_icache_range); |
127 | EXPORT_SYMBOL(flush_dcache_range); | 121 | EXPORT_SYMBOL(flush_dcache_range); |
@@ -174,8 +168,7 @@ EXPORT_SYMBOL(cacheable_memcpy); | |||
174 | #endif | 168 | #endif |
175 | 169 | ||
176 | #ifdef CONFIG_PPC32 | 170 | #ifdef CONFIG_PPC32 |
177 | EXPORT_SYMBOL(next_mmu_context); | 171 | EXPORT_SYMBOL(switch_mmu_context); |
178 | EXPORT_SYMBOL(set_context); | ||
179 | #endif | 172 | #endif |
180 | 173 | ||
181 | #ifdef CONFIG_PPC_STD_MMU_32 | 174 | #ifdef CONFIG_PPC_STD_MMU_32 |
diff --git a/arch/powerpc/kernel/ppc_save_regs.S b/arch/powerpc/kernel/ppc_save_regs.S new file mode 100644 index 000000000000..5113bd2285e1 --- /dev/null +++ b/arch/powerpc/kernel/ppc_save_regs.S | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1996 Paul Mackerras. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * NOTE: assert(sizeof(buf) > 23 * sizeof(long)) | ||
10 | */ | ||
11 | #include <asm/processor.h> | ||
12 | #include <asm/ppc_asm.h> | ||
13 | #include <asm/asm-offsets.h> | ||
14 | |||
15 | /* | ||
16 | * Grab the register values as they are now. | ||
17 | * This won't do a particularily good job because we really | ||
18 | * want our caller's caller's registers, and our caller has | ||
19 | * already executed its prologue. | ||
20 | * ToDo: We could reach back into the caller's save area to do | ||
21 | * a better job of representing the caller's state (note that | ||
22 | * that will be different for 32-bit and 64-bit, because of the | ||
23 | * different ABIs, though). | ||
24 | */ | ||
25 | _GLOBAL(ppc_save_regs) | ||
26 | PPC_STL r0,0*SZL(r3) | ||
27 | PPC_STL r2,2*SZL(r3) | ||
28 | PPC_STL r3,3*SZL(r3) | ||
29 | PPC_STL r4,4*SZL(r3) | ||
30 | PPC_STL r5,5*SZL(r3) | ||
31 | PPC_STL r6,6*SZL(r3) | ||
32 | PPC_STL r7,7*SZL(r3) | ||
33 | PPC_STL r8,8*SZL(r3) | ||
34 | PPC_STL r9,9*SZL(r3) | ||
35 | PPC_STL r10,10*SZL(r3) | ||
36 | PPC_STL r11,11*SZL(r3) | ||
37 | PPC_STL r12,12*SZL(r3) | ||
38 | PPC_STL r13,13*SZL(r3) | ||
39 | PPC_STL r14,14*SZL(r3) | ||
40 | PPC_STL r15,15*SZL(r3) | ||
41 | PPC_STL r16,16*SZL(r3) | ||
42 | PPC_STL r17,17*SZL(r3) | ||
43 | PPC_STL r18,18*SZL(r3) | ||
44 | PPC_STL r19,19*SZL(r3) | ||
45 | PPC_STL r20,20*SZL(r3) | ||
46 | PPC_STL r21,21*SZL(r3) | ||
47 | PPC_STL r22,22*SZL(r3) | ||
48 | PPC_STL r23,23*SZL(r3) | ||
49 | PPC_STL r24,24*SZL(r3) | ||
50 | PPC_STL r25,25*SZL(r3) | ||
51 | PPC_STL r26,26*SZL(r3) | ||
52 | PPC_STL r27,27*SZL(r3) | ||
53 | PPC_STL r28,28*SZL(r3) | ||
54 | PPC_STL r29,29*SZL(r3) | ||
55 | PPC_STL r30,30*SZL(r3) | ||
56 | PPC_STL r31,31*SZL(r3) | ||
57 | /* go up one stack frame for SP */ | ||
58 | PPC_LL r4,0(r1) | ||
59 | PPC_STL r4,1*SZL(r3) | ||
60 | /* get caller's LR */ | ||
61 | PPC_LL r0,LRSAVE(r4) | ||
62 | PPC_STL r0,_NIP-STACK_FRAME_OVERHEAD(r3) | ||
63 | PPC_STL r0,_LINK-STACK_FRAME_OVERHEAD(r3) | ||
64 | mfmsr r0 | ||
65 | PPC_STL r0,_MSR-STACK_FRAME_OVERHEAD(r3) | ||
66 | mfctr r0 | ||
67 | PPC_STL r0,_CTR-STACK_FRAME_OVERHEAD(r3) | ||
68 | mfxer r0 | ||
69 | PPC_STL r0,_XER-STACK_FRAME_OVERHEAD(r3) | ||
70 | mfcr r0 | ||
71 | PPC_STL r0,_CCR-STACK_FRAME_OVERHEAD(r3) | ||
72 | li r0,0 | ||
73 | PPC_STL r0,_TRAP-STACK_FRAME_OVERHEAD(r3) | ||
74 | blr | ||
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 957bded0020d..51b201ddf9a1 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -467,6 +467,8 @@ static struct regbit { | |||
467 | {MSR_VEC, "VEC"}, | 467 | {MSR_VEC, "VEC"}, |
468 | {MSR_VSX, "VSX"}, | 468 | {MSR_VSX, "VSX"}, |
469 | {MSR_ME, "ME"}, | 469 | {MSR_ME, "ME"}, |
470 | {MSR_CE, "CE"}, | ||
471 | {MSR_DE, "DE"}, | ||
470 | {MSR_IR, "IR"}, | 472 | {MSR_IR, "IR"}, |
471 | {MSR_DR, "DR"}, | 473 | {MSR_DR, "DR"}, |
472 | {0, NULL} | 474 | {0, NULL} |
@@ -998,7 +1000,7 @@ unsigned long get_wchan(struct task_struct *p) | |||
998 | return 0; | 1000 | return 0; |
999 | } | 1001 | } |
1000 | 1002 | ||
1001 | static int kstack_depth_to_print = 64; | 1003 | static int kstack_depth_to_print = CONFIG_PRINT_STACK_DEPTH; |
1002 | 1004 | ||
1003 | void show_stack(struct task_struct *tsk, unsigned long *stack) | 1005 | void show_stack(struct task_struct *tsk, unsigned long *stack) |
1004 | { | 1006 | { |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 3a2dc7e6586a..6f73c739f1e2 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -1160,6 +1160,8 @@ static inline void __init phyp_dump_reserve_mem(void) {} | |||
1160 | 1160 | ||
1161 | void __init early_init_devtree(void *params) | 1161 | void __init early_init_devtree(void *params) |
1162 | { | 1162 | { |
1163 | unsigned long limit; | ||
1164 | |||
1163 | DBG(" -> early_init_devtree(%p)\n", params); | 1165 | DBG(" -> early_init_devtree(%p)\n", params); |
1164 | 1166 | ||
1165 | /* Setup flat device-tree pointer */ | 1167 | /* Setup flat device-tree pointer */ |
@@ -1200,7 +1202,19 @@ void __init early_init_devtree(void *params) | |||
1200 | early_reserve_mem(); | 1202 | early_reserve_mem(); |
1201 | phyp_dump_reserve_mem(); | 1203 | phyp_dump_reserve_mem(); |
1202 | 1204 | ||
1203 | lmb_enforce_memory_limit(memory_limit); | 1205 | limit = memory_limit; |
1206 | if (! limit) { | ||
1207 | unsigned long memsize; | ||
1208 | |||
1209 | /* Ensure that total memory size is page-aligned, because | ||
1210 | * otherwise mark_bootmem() gets upset. */ | ||
1211 | lmb_analyze(); | ||
1212 | memsize = lmb_phys_mem_size(); | ||
1213 | if ((memsize & PAGE_MASK) != memsize) | ||
1214 | limit = memsize & PAGE_MASK; | ||
1215 | } | ||
1216 | lmb_enforce_memory_limit(limit); | ||
1217 | |||
1204 | lmb_analyze(); | 1218 | lmb_analyze(); |
1205 | 1219 | ||
1206 | DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); | 1220 | DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); |
@@ -1271,6 +1285,37 @@ struct device_node *of_find_node_by_phandle(phandle handle) | |||
1271 | EXPORT_SYMBOL(of_find_node_by_phandle); | 1285 | EXPORT_SYMBOL(of_find_node_by_phandle); |
1272 | 1286 | ||
1273 | /** | 1287 | /** |
1288 | * of_find_next_cache_node - Find a node's subsidiary cache | ||
1289 | * @np: node of type "cpu" or "cache" | ||
1290 | * | ||
1291 | * Returns a node pointer with refcount incremented, use | ||
1292 | * of_node_put() on it when done. Caller should hold a reference | ||
1293 | * to np. | ||
1294 | */ | ||
1295 | struct device_node *of_find_next_cache_node(struct device_node *np) | ||
1296 | { | ||
1297 | struct device_node *child; | ||
1298 | const phandle *handle; | ||
1299 | |||
1300 | handle = of_get_property(np, "l2-cache", NULL); | ||
1301 | if (!handle) | ||
1302 | handle = of_get_property(np, "next-level-cache", NULL); | ||
1303 | |||
1304 | if (handle) | ||
1305 | return of_find_node_by_phandle(*handle); | ||
1306 | |||
1307 | /* OF on pmac has nodes instead of properties named "l2-cache" | ||
1308 | * beneath CPU nodes. | ||
1309 | */ | ||
1310 | if (!strcmp(np->type, "cpu")) | ||
1311 | for_each_child_of_node(np, child) | ||
1312 | if (!strcmp(child->type, "cache")) | ||
1313 | return child; | ||
1314 | |||
1315 | return NULL; | ||
1316 | } | ||
1317 | |||
1318 | /** | ||
1274 | * of_find_all_nodes - Get next node in global list | 1319 | * of_find_all_nodes - Get next node in global list |
1275 | * @prev: Previous node or NULL to start iteration | 1320 | * @prev: Previous node or NULL to start iteration |
1276 | * of_node_put() will be called on it | 1321 | * of_node_put() will be called on it |
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index a11d68976dc8..8c1335566089 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c | |||
@@ -734,10 +734,7 @@ void of_irq_map_init(unsigned int flags) | |||
734 | if (flags & OF_IMAP_NO_PHANDLE) { | 734 | if (flags & OF_IMAP_NO_PHANDLE) { |
735 | struct device_node *np; | 735 | struct device_node *np; |
736 | 736 | ||
737 | for(np = NULL; (np = of_find_all_nodes(np)) != NULL;) { | 737 | for_each_node_with_property(np, "interrupt-controller") { |
738 | if (of_get_property(np, "interrupt-controller", NULL) | ||
739 | == NULL) | ||
740 | continue; | ||
741 | /* Skip /chosen/interrupt-controller */ | 738 | /* Skip /chosen/interrupt-controller */ |
742 | if (strcmp(np->name, "chosen") == 0) | 739 | if (strcmp(np->name, "chosen") == 0) |
743 | continue; | 740 | continue; |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 1f8505c23548..fdfe14c4bdef 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -566,6 +566,32 @@ int rtas_get_sensor(int sensor, int index, int *state) | |||
566 | } | 566 | } |
567 | EXPORT_SYMBOL(rtas_get_sensor); | 567 | EXPORT_SYMBOL(rtas_get_sensor); |
568 | 568 | ||
569 | bool rtas_indicator_present(int token, int *maxindex) | ||
570 | { | ||
571 | int proplen, count, i; | ||
572 | const struct indicator_elem { | ||
573 | u32 token; | ||
574 | u32 maxindex; | ||
575 | } *indicators; | ||
576 | |||
577 | indicators = of_get_property(rtas.dev, "rtas-indicators", &proplen); | ||
578 | if (!indicators) | ||
579 | return false; | ||
580 | |||
581 | count = proplen / sizeof(struct indicator_elem); | ||
582 | |||
583 | for (i = 0; i < count; i++) { | ||
584 | if (indicators[i].token != token) | ||
585 | continue; | ||
586 | if (maxindex) | ||
587 | *maxindex = indicators[i].maxindex; | ||
588 | return true; | ||
589 | } | ||
590 | |||
591 | return false; | ||
592 | } | ||
593 | EXPORT_SYMBOL(rtas_indicator_present); | ||
594 | |||
569 | int rtas_set_indicator(int indicator, int index, int new_value) | 595 | int rtas_set_indicator(int indicator, int index, int new_value) |
570 | { | 596 | { |
571 | int token = rtas_token("set-indicator"); | 597 | int token = rtas_token("set-indicator"); |
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 589a2797eac2..8869001ab5d7 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -301,51 +301,3 @@ void __init find_and_init_phbs(void) | |||
301 | #endif /* CONFIG_PPC32 */ | 301 | #endif /* CONFIG_PPC32 */ |
302 | } | 302 | } |
303 | } | 303 | } |
304 | |||
305 | /* RPA-specific bits for removing PHBs */ | ||
306 | int pcibios_remove_root_bus(struct pci_controller *phb) | ||
307 | { | ||
308 | struct pci_bus *b = phb->bus; | ||
309 | struct resource *res; | ||
310 | int rc, i; | ||
311 | |||
312 | res = b->resource[0]; | ||
313 | if (!res->flags) { | ||
314 | printk(KERN_ERR "%s: no IO resource for PHB %s\n", __func__, | ||
315 | b->name); | ||
316 | return 1; | ||
317 | } | ||
318 | |||
319 | rc = pcibios_unmap_io_space(b); | ||
320 | if (rc) { | ||
321 | printk(KERN_ERR "%s: failed to unmap IO on bus %s\n", | ||
322 | __func__, b->name); | ||
323 | return 1; | ||
324 | } | ||
325 | |||
326 | if (release_resource(res)) { | ||
327 | printk(KERN_ERR "%s: failed to release IO on bus %s\n", | ||
328 | __func__, b->name); | ||
329 | return 1; | ||
330 | } | ||
331 | |||
332 | for (i = 1; i < 3; ++i) { | ||
333 | res = b->resource[i]; | ||
334 | if (!res->flags && i == 0) { | ||
335 | printk(KERN_ERR "%s: no MEM resource for PHB %s\n", | ||
336 | __func__, b->name); | ||
337 | return 1; | ||
338 | } | ||
339 | if (res->flags && release_resource(res)) { | ||
340 | printk(KERN_ERR | ||
341 | "%s: failed to release IO %d on bus %s\n", | ||
342 | __func__, i, b->name); | ||
343 | return 1; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | pcibios_free_controller(phb); | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | EXPORT_SYMBOL(pcibios_remove_root_bus); | ||
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index c1a27626a940..9e1ca745d8f0 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <asm/time.h> | 38 | #include <asm/time.h> |
39 | #include <asm/serial.h> | 39 | #include <asm/serial.h> |
40 | #include <asm/udbg.h> | 40 | #include <asm/udbg.h> |
41 | #include <asm/mmu_context.h> | ||
41 | 42 | ||
42 | #include "setup.h" | 43 | #include "setup.h" |
43 | 44 | ||
@@ -49,12 +50,12 @@ int boot_cpuid; | |||
49 | EXPORT_SYMBOL_GPL(boot_cpuid); | 50 | EXPORT_SYMBOL_GPL(boot_cpuid); |
50 | int boot_cpuid_phys; | 51 | int boot_cpuid_phys; |
51 | 52 | ||
53 | int smp_hw_index[NR_CPUS]; | ||
54 | |||
52 | unsigned long ISA_DMA_THRESHOLD; | 55 | unsigned long ISA_DMA_THRESHOLD; |
53 | unsigned int DMA_MODE_READ; | 56 | unsigned int DMA_MODE_READ; |
54 | unsigned int DMA_MODE_WRITE; | 57 | unsigned int DMA_MODE_WRITE; |
55 | 58 | ||
56 | int have_of = 1; | ||
57 | |||
58 | #ifdef CONFIG_VGA_CONSOLE | 59 | #ifdef CONFIG_VGA_CONSOLE |
59 | unsigned long vgacon_remap_base; | 60 | unsigned long vgacon_remap_base; |
60 | EXPORT_SYMBOL(vgacon_remap_base); | 61 | EXPORT_SYMBOL(vgacon_remap_base); |
@@ -97,6 +98,10 @@ notrace unsigned long __init early_init(unsigned long dt_ptr) | |||
97 | PTRRELOC(&__start___ftr_fixup), | 98 | PTRRELOC(&__start___ftr_fixup), |
98 | PTRRELOC(&__stop___ftr_fixup)); | 99 | PTRRELOC(&__stop___ftr_fixup)); |
99 | 100 | ||
101 | do_feature_fixups(spec->mmu_features, | ||
102 | PTRRELOC(&__start___mmu_ftr_fixup), | ||
103 | PTRRELOC(&__stop___mmu_ftr_fixup)); | ||
104 | |||
100 | do_lwsync_fixups(spec->cpu_features, | 105 | do_lwsync_fixups(spec->cpu_features, |
101 | PTRRELOC(&__start___lwsync_fixup), | 106 | PTRRELOC(&__start___lwsync_fixup), |
102 | PTRRELOC(&__stop___lwsync_fixup)); | 107 | PTRRELOC(&__stop___lwsync_fixup)); |
@@ -121,6 +126,8 @@ notrace void __init machine_init(unsigned long dt_ptr) | |||
121 | 126 | ||
122 | probe_machine(); | 127 | probe_machine(); |
123 | 128 | ||
129 | setup_kdump_trampoline(); | ||
130 | |||
124 | #ifdef CONFIG_6xx | 131 | #ifdef CONFIG_6xx |
125 | if (cpu_has_feature(CPU_FTR_CAN_DOZE) || | 132 | if (cpu_has_feature(CPU_FTR_CAN_DOZE) || |
126 | cpu_has_feature(CPU_FTR_CAN_NAP)) | 133 | cpu_has_feature(CPU_FTR_CAN_NAP)) |
@@ -326,4 +333,8 @@ void __init setup_arch(char **cmdline_p) | |||
326 | if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); | 333 | if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); |
327 | 334 | ||
328 | paging_init(); | 335 | paging_init(); |
336 | |||
337 | /* Initialize the MMU context management stuff */ | ||
338 | mmu_context_init(); | ||
339 | |||
329 | } | 340 | } |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 169d74cef157..d8bd2161e738 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
@@ -70,7 +70,6 @@ | |||
70 | #define DBG(fmt...) | 70 | #define DBG(fmt...) |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | int have_of = 1; | ||
74 | int boot_cpuid = 0; | 73 | int boot_cpuid = 0; |
75 | u64 ppc64_pft_size; | 74 | u64 ppc64_pft_size; |
76 | 75 | ||
@@ -362,6 +361,8 @@ void __init setup_system(void) | |||
362 | */ | 361 | */ |
363 | do_feature_fixups(cur_cpu_spec->cpu_features, | 362 | do_feature_fixups(cur_cpu_spec->cpu_features, |
364 | &__start___ftr_fixup, &__stop___ftr_fixup); | 363 | &__start___ftr_fixup, &__stop___ftr_fixup); |
364 | do_feature_fixups(cur_cpu_spec->mmu_features, | ||
365 | &__start___mmu_ftr_fixup, &__stop___mmu_ftr_fixup); | ||
365 | do_feature_fixups(powerpc_firmware_features, | 366 | do_feature_fixups(powerpc_firmware_features, |
366 | &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); | 367 | &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup); |
367 | do_lwsync_fixups(cur_cpu_spec->cpu_features, | 368 | do_lwsync_fixups(cur_cpu_spec->cpu_features, |
@@ -606,8 +607,6 @@ void __init setup_per_cpu_areas(void) | |||
606 | 607 | ||
607 | for_each_possible_cpu(i) { | 608 | for_each_possible_cpu(i) { |
608 | ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); | 609 | ptr = alloc_bootmem_pages_node(NODE_DATA(cpu_to_node(i)), size); |
609 | if (!ptr) | ||
610 | panic("Cannot allocate cpu data for CPU %d\n", i); | ||
611 | 610 | ||
612 | paca[i].data_offset = ptr - __per_cpu_start; | 611 | paca[i].data_offset = ptr - __per_cpu_start; |
613 | memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); | 612 | memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); |
diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index bc892e69b4f7..a5e54526403d 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c | |||
@@ -113,7 +113,7 @@ void __devinit smp_generic_give_timebase(void) | |||
113 | { | 113 | { |
114 | int i, score, score2, old, min=0, max=5000, offset=1000; | 114 | int i, score, score2, old, min=0, max=5000, offset=1000; |
115 | 115 | ||
116 | printk("Synchronizing timebase\n"); | 116 | pr_debug("Software timebase sync\n"); |
117 | 117 | ||
118 | /* if this fails then this kernel won't work anyway... */ | 118 | /* if this fails then this kernel won't work anyway... */ |
119 | tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL ); | 119 | tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL ); |
@@ -123,13 +123,13 @@ void __devinit smp_generic_give_timebase(void) | |||
123 | while (!tbsync->ack) | 123 | while (!tbsync->ack) |
124 | barrier(); | 124 | barrier(); |
125 | 125 | ||
126 | printk("Got ack\n"); | 126 | pr_debug("Got ack\n"); |
127 | 127 | ||
128 | /* binary search */ | 128 | /* binary search */ |
129 | for (old = -1; old != offset ; offset = (min+max) / 2) { | 129 | for (old = -1; old != offset ; offset = (min+max) / 2) { |
130 | score = start_contest(kSetAndTest, offset, NUM_ITER); | 130 | score = start_contest(kSetAndTest, offset, NUM_ITER); |
131 | 131 | ||
132 | printk("score %d, offset %d\n", score, offset ); | 132 | pr_debug("score %d, offset %d\n", score, offset ); |
133 | 133 | ||
134 | if( score > 0 ) | 134 | if( score > 0 ) |
135 | max = offset; | 135 | max = offset; |
@@ -140,8 +140,8 @@ void __devinit smp_generic_give_timebase(void) | |||
140 | score = start_contest(kSetAndTest, min, NUM_ITER); | 140 | score = start_contest(kSetAndTest, min, NUM_ITER); |
141 | score2 = start_contest(kSetAndTest, max, NUM_ITER); | 141 | score2 = start_contest(kSetAndTest, max, NUM_ITER); |
142 | 142 | ||
143 | printk("Min %d (score %d), Max %d (score %d)\n", | 143 | pr_debug("Min %d (score %d), Max %d (score %d)\n", |
144 | min, score, max, score2); | 144 | min, score, max, score2); |
145 | score = abs(score); | 145 | score = abs(score); |
146 | score2 = abs(score2); | 146 | score2 = abs(score2); |
147 | offset = (score < score2) ? min : max; | 147 | offset = (score < score2) ? min : max; |
@@ -155,7 +155,7 @@ void __devinit smp_generic_give_timebase(void) | |||
155 | if (score2 <= score || score2 < 20) | 155 | if (score2 <= score || score2 < 20) |
156 | break; | 156 | break; |
157 | } | 157 | } |
158 | printk("Final offset: %d (%d/%d)\n", offset, score2, NUM_ITER ); | 158 | pr_debug("Final offset: %d (%d/%d)\n", offset, score2, NUM_ITER ); |
159 | 159 | ||
160 | /* exiting */ | 160 | /* exiting */ |
161 | tbsync->cmd = kExit; | 161 | tbsync->cmd = kExit; |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index ff9f7010097d..8ac3f721d235 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -57,7 +57,6 @@ | |||
57 | #define DBG(fmt...) | 57 | #define DBG(fmt...) |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | int smp_hw_index[NR_CPUS]; | ||
61 | struct thread_info *secondary_ti; | 60 | struct thread_info *secondary_ti; |
62 | 61 | ||
63 | cpumask_t cpu_possible_map = CPU_MASK_NONE; | 62 | cpumask_t cpu_possible_map = CPU_MASK_NONE; |
@@ -123,6 +122,65 @@ void smp_message_recv(int msg) | |||
123 | } | 122 | } |
124 | } | 123 | } |
125 | 124 | ||
125 | static irqreturn_t call_function_action(int irq, void *data) | ||
126 | { | ||
127 | generic_smp_call_function_interrupt(); | ||
128 | return IRQ_HANDLED; | ||
129 | } | ||
130 | |||
131 | static irqreturn_t reschedule_action(int irq, void *data) | ||
132 | { | ||
133 | /* we just need the return path side effect of checking need_resched */ | ||
134 | return IRQ_HANDLED; | ||
135 | } | ||
136 | |||
137 | static irqreturn_t call_function_single_action(int irq, void *data) | ||
138 | { | ||
139 | generic_smp_call_function_single_interrupt(); | ||
140 | return IRQ_HANDLED; | ||
141 | } | ||
142 | |||
143 | static irqreturn_t debug_ipi_action(int irq, void *data) | ||
144 | { | ||
145 | smp_message_recv(PPC_MSG_DEBUGGER_BREAK); | ||
146 | return IRQ_HANDLED; | ||
147 | } | ||
148 | |||
149 | static irq_handler_t smp_ipi_action[] = { | ||
150 | [PPC_MSG_CALL_FUNCTION] = call_function_action, | ||
151 | [PPC_MSG_RESCHEDULE] = reschedule_action, | ||
152 | [PPC_MSG_CALL_FUNC_SINGLE] = call_function_single_action, | ||
153 | [PPC_MSG_DEBUGGER_BREAK] = debug_ipi_action, | ||
154 | }; | ||
155 | |||
156 | const char *smp_ipi_name[] = { | ||
157 | [PPC_MSG_CALL_FUNCTION] = "ipi call function", | ||
158 | [PPC_MSG_RESCHEDULE] = "ipi reschedule", | ||
159 | [PPC_MSG_CALL_FUNC_SINGLE] = "ipi call function single", | ||
160 | [PPC_MSG_DEBUGGER_BREAK] = "ipi debugger", | ||
161 | }; | ||
162 | |||
163 | /* optional function to request ipi, for controllers with >= 4 ipis */ | ||
164 | int smp_request_message_ipi(int virq, int msg) | ||
165 | { | ||
166 | int err; | ||
167 | |||
168 | if (msg < 0 || msg > PPC_MSG_DEBUGGER_BREAK) { | ||
169 | return -EINVAL; | ||
170 | } | ||
171 | #if !defined(CONFIG_DEBUGGER) && !defined(CONFIG_KEXEC) | ||
172 | if (msg == PPC_MSG_DEBUGGER_BREAK) { | ||
173 | return 1; | ||
174 | } | ||
175 | #endif | ||
176 | err = request_irq(virq, smp_ipi_action[msg], IRQF_DISABLED|IRQF_PERCPU, | ||
177 | smp_ipi_name[msg], 0); | ||
178 | WARN(err < 0, "unable to request_irq %d for %s (rc %d)\n", | ||
179 | virq, smp_ipi_name[msg], err); | ||
180 | |||
181 | return err; | ||
182 | } | ||
183 | |||
126 | void smp_send_reschedule(int cpu) | 184 | void smp_send_reschedule(int cpu) |
127 | { | 185 | { |
128 | if (likely(smp_ops)) | 186 | if (likely(smp_ops)) |
@@ -408,8 +466,7 @@ out: | |||
408 | static struct device_node *cpu_to_l2cache(int cpu) | 466 | static struct device_node *cpu_to_l2cache(int cpu) |
409 | { | 467 | { |
410 | struct device_node *np; | 468 | struct device_node *np; |
411 | const phandle *php; | 469 | struct device_node *cache; |
412 | phandle ph; | ||
413 | 470 | ||
414 | if (!cpu_present(cpu)) | 471 | if (!cpu_present(cpu)) |
415 | return NULL; | 472 | return NULL; |
@@ -418,13 +475,11 @@ static struct device_node *cpu_to_l2cache(int cpu) | |||
418 | if (np == NULL) | 475 | if (np == NULL) |
419 | return NULL; | 476 | return NULL; |
420 | 477 | ||
421 | php = of_get_property(np, "l2-cache", NULL); | 478 | cache = of_find_next_cache_node(np); |
422 | if (php == NULL) | 479 | |
423 | return NULL; | ||
424 | ph = *php; | ||
425 | of_node_put(np); | 480 | of_node_put(np); |
426 | 481 | ||
427 | return of_find_node_by_phandle(ph); | 482 | return cache; |
428 | } | 483 | } |
429 | 484 | ||
430 | /* Activate a secondary processor. */ | 485 | /* Activate a secondary processor. */ |
diff --git a/arch/powerpc/kernel/swsusp.c b/arch/powerpc/kernel/swsusp.c index 77b7b34b5955..560c96119501 100644 --- a/arch/powerpc/kernel/swsusp.c +++ b/arch/powerpc/kernel/swsusp.c | |||
@@ -34,6 +34,6 @@ void save_processor_state(void) | |||
34 | void restore_processor_state(void) | 34 | void restore_processor_state(void) |
35 | { | 35 | { |
36 | #ifdef CONFIG_PPC32 | 36 | #ifdef CONFIG_PPC32 |
37 | set_context(current->active_mm->context.id, current->active_mm->pgd); | 37 | switch_mmu_context(NULL, current->active_mm); |
38 | #endif | 38 | #endif |
39 | } | 39 | } |
diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S index 77fc76607ab2..b47d8ceffb52 100644 --- a/arch/powerpc/kernel/swsusp_32.S +++ b/arch/powerpc/kernel/swsusp_32.S | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <asm/thread_info.h> | 5 | #include <asm/thread_info.h> |
6 | #include <asm/ppc_asm.h> | 6 | #include <asm/ppc_asm.h> |
7 | #include <asm/asm-offsets.h> | 7 | #include <asm/asm-offsets.h> |
8 | 8 | #include <asm/mmu.h> | |
9 | 9 | ||
10 | /* | 10 | /* |
11 | * Structure for storing CPU registers on the save area. | 11 | * Structure for storing CPU registers on the save area. |
@@ -279,7 +279,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | |||
279 | mtibatl 3,r4 | 279 | mtibatl 3,r4 |
280 | #endif | 280 | #endif |
281 | 281 | ||
282 | BEGIN_FTR_SECTION | 282 | BEGIN_MMU_FTR_SECTION |
283 | li r4,0 | 283 | li r4,0 |
284 | mtspr SPRN_DBAT4U,r4 | 284 | mtspr SPRN_DBAT4U,r4 |
285 | mtspr SPRN_DBAT4L,r4 | 285 | mtspr SPRN_DBAT4L,r4 |
@@ -297,7 +297,7 @@ BEGIN_FTR_SECTION | |||
297 | mtspr SPRN_IBAT6L,r4 | 297 | mtspr SPRN_IBAT6L,r4 |
298 | mtspr SPRN_IBAT7U,r4 | 298 | mtspr SPRN_IBAT7U,r4 |
299 | mtspr SPRN_IBAT7L,r4 | 299 | mtspr SPRN_IBAT7L,r4 |
300 | END_FTR_SECTION_IFSET(CPU_FTR_HAS_HIGH_BATS) | 300 | END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) |
301 | 301 | ||
302 | /* Flush all TLBs */ | 302 | /* Flush all TLBs */ |
303 | lis r4,0x1000 | 303 | lis r4,0x1000 |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 20885a38237a..0c64f10087b9 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -566,7 +566,6 @@ static bool cache_is_unified(struct device_node *np) | |||
566 | 566 | ||
567 | static struct cache_desc * __cpuinit create_cache_index_info(struct device_node *np, struct kobject *parent, int index, int level) | 567 | static struct cache_desc * __cpuinit create_cache_index_info(struct device_node *np, struct kobject *parent, int index, int level) |
568 | { | 568 | { |
569 | const phandle *next_cache_phandle; | ||
570 | struct device_node *next_cache; | 569 | struct device_node *next_cache; |
571 | struct cache_desc *new, **end; | 570 | struct cache_desc *new, **end; |
572 | 571 | ||
@@ -591,11 +590,7 @@ static struct cache_desc * __cpuinit create_cache_index_info(struct device_node | |||
591 | while (*end) | 590 | while (*end) |
592 | end = &(*end)->next; | 591 | end = &(*end)->next; |
593 | 592 | ||
594 | next_cache_phandle = of_get_property(np, "l2-cache", NULL); | 593 | next_cache = of_find_next_cache_node(np); |
595 | if (!next_cache_phandle) | ||
596 | goto out; | ||
597 | |||
598 | next_cache = of_find_node_by_phandle(*next_cache_phandle); | ||
599 | if (!next_cache) | 594 | if (!next_cache) |
600 | goto out; | 595 | goto out; |
601 | 596 | ||
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index e2ee66b5831d..e1f3a5140429 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -164,8 +164,6 @@ static u64 tb_to_ns_scale __read_mostly; | |||
164 | static unsigned tb_to_ns_shift __read_mostly; | 164 | static unsigned tb_to_ns_shift __read_mostly; |
165 | static unsigned long boot_tb __read_mostly; | 165 | static unsigned long boot_tb __read_mostly; |
166 | 166 | ||
167 | static struct gettimeofday_struct do_gtod; | ||
168 | |||
169 | extern struct timezone sys_tz; | 167 | extern struct timezone sys_tz; |
170 | static long timezone_offset; | 168 | static long timezone_offset; |
171 | 169 | ||
@@ -415,31 +413,9 @@ void udelay(unsigned long usecs) | |||
415 | } | 413 | } |
416 | EXPORT_SYMBOL(udelay); | 414 | EXPORT_SYMBOL(udelay); |
417 | 415 | ||
418 | |||
419 | /* | ||
420 | * There are two copies of tb_to_xs and stamp_xsec so that no | ||
421 | * lock is needed to access and use these values in | ||
422 | * do_gettimeofday. We alternate the copies and as long as a | ||
423 | * reasonable time elapses between changes, there will never | ||
424 | * be inconsistent values. ntpd has a minimum of one minute | ||
425 | * between updates. | ||
426 | */ | ||
427 | static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, | 416 | static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, |
428 | u64 new_tb_to_xs) | 417 | u64 new_tb_to_xs) |
429 | { | 418 | { |
430 | unsigned temp_idx; | ||
431 | struct gettimeofday_vars *temp_varp; | ||
432 | |||
433 | temp_idx = (do_gtod.var_idx == 0); | ||
434 | temp_varp = &do_gtod.vars[temp_idx]; | ||
435 | |||
436 | temp_varp->tb_to_xs = new_tb_to_xs; | ||
437 | temp_varp->tb_orig_stamp = new_tb_stamp; | ||
438 | temp_varp->stamp_xsec = new_stamp_xsec; | ||
439 | smp_mb(); | ||
440 | do_gtod.varp = temp_varp; | ||
441 | do_gtod.var_idx = temp_idx; | ||
442 | |||
443 | /* | 419 | /* |
444 | * tb_update_count is used to allow the userspace gettimeofday code | 420 | * tb_update_count is used to allow the userspace gettimeofday code |
445 | * to assure itself that it sees a consistent view of the tb_to_xs and | 421 | * to assure itself that it sees a consistent view of the tb_to_xs and |
@@ -456,6 +432,7 @@ static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec, | |||
456 | vdso_data->tb_to_xs = new_tb_to_xs; | 432 | vdso_data->tb_to_xs = new_tb_to_xs; |
457 | vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; | 433 | vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec; |
458 | vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; | 434 | vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec; |
435 | vdso_data->stamp_xtime = xtime; | ||
459 | smp_wmb(); | 436 | smp_wmb(); |
460 | ++(vdso_data->tb_update_count); | 437 | ++(vdso_data->tb_update_count); |
461 | } | 438 | } |
@@ -514,9 +491,7 @@ static int __init iSeries_tb_recal(void) | |||
514 | tb_ticks_per_sec = new_tb_ticks_per_sec; | 491 | tb_ticks_per_sec = new_tb_ticks_per_sec; |
515 | calc_cputime_factors(); | 492 | calc_cputime_factors(); |
516 | div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres ); | 493 | div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres ); |
517 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; | ||
518 | tb_to_xs = divres.result_low; | 494 | tb_to_xs = divres.result_low; |
519 | do_gtod.varp->tb_to_xs = tb_to_xs; | ||
520 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; | 495 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; |
521 | vdso_data->tb_to_xs = tb_to_xs; | 496 | vdso_data->tb_to_xs = tb_to_xs; |
522 | } | 497 | } |
@@ -988,15 +963,6 @@ void __init time_init(void) | |||
988 | sys_tz.tz_dsttime = 0; | 963 | sys_tz.tz_dsttime = 0; |
989 | } | 964 | } |
990 | 965 | ||
991 | do_gtod.varp = &do_gtod.vars[0]; | ||
992 | do_gtod.var_idx = 0; | ||
993 | do_gtod.varp->tb_orig_stamp = tb_last_jiffy; | ||
994 | __get_cpu_var(last_jiffy) = tb_last_jiffy; | ||
995 | do_gtod.varp->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC; | ||
996 | do_gtod.tb_ticks_per_sec = tb_ticks_per_sec; | ||
997 | do_gtod.varp->tb_to_xs = tb_to_xs; | ||
998 | do_gtod.tb_to_us = tb_to_us; | ||
999 | |||
1000 | vdso_data->tb_orig_stamp = tb_last_jiffy; | 966 | vdso_data->tb_orig_stamp = tb_last_jiffy; |
1001 | vdso_data->tb_update_count = 0; | 967 | vdso_data->tb_update_count = 0; |
1002 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; | 968 | vdso_data->tb_ticks_per_sec = tb_ticks_per_sec; |
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index f5def6cf5cd6..5457e9575685 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -1160,37 +1160,85 @@ void CacheLockingException(struct pt_regs *regs, unsigned long address, | |||
1160 | #ifdef CONFIG_SPE | 1160 | #ifdef CONFIG_SPE |
1161 | void SPEFloatingPointException(struct pt_regs *regs) | 1161 | void SPEFloatingPointException(struct pt_regs *regs) |
1162 | { | 1162 | { |
1163 | extern int do_spe_mathemu(struct pt_regs *regs); | ||
1163 | unsigned long spefscr; | 1164 | unsigned long spefscr; |
1164 | int fpexc_mode; | 1165 | int fpexc_mode; |
1165 | int code = 0; | 1166 | int code = 0; |
1167 | int err; | ||
1168 | |||
1169 | preempt_disable(); | ||
1170 | if (regs->msr & MSR_SPE) | ||
1171 | giveup_spe(current); | ||
1172 | preempt_enable(); | ||
1166 | 1173 | ||
1167 | spefscr = current->thread.spefscr; | 1174 | spefscr = current->thread.spefscr; |
1168 | fpexc_mode = current->thread.fpexc_mode; | 1175 | fpexc_mode = current->thread.fpexc_mode; |
1169 | 1176 | ||
1170 | /* Hardware does not neccessarily set sticky | ||
1171 | * underflow/overflow/invalid flags */ | ||
1172 | if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) { | 1177 | if ((spefscr & SPEFSCR_FOVF) && (fpexc_mode & PR_FP_EXC_OVF)) { |
1173 | code = FPE_FLTOVF; | 1178 | code = FPE_FLTOVF; |
1174 | spefscr |= SPEFSCR_FOVFS; | ||
1175 | } | 1179 | } |
1176 | else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) { | 1180 | else if ((spefscr & SPEFSCR_FUNF) && (fpexc_mode & PR_FP_EXC_UND)) { |
1177 | code = FPE_FLTUND; | 1181 | code = FPE_FLTUND; |
1178 | spefscr |= SPEFSCR_FUNFS; | ||
1179 | } | 1182 | } |
1180 | else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV)) | 1183 | else if ((spefscr & SPEFSCR_FDBZ) && (fpexc_mode & PR_FP_EXC_DIV)) |
1181 | code = FPE_FLTDIV; | 1184 | code = FPE_FLTDIV; |
1182 | else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) { | 1185 | else if ((spefscr & SPEFSCR_FINV) && (fpexc_mode & PR_FP_EXC_INV)) { |
1183 | code = FPE_FLTINV; | 1186 | code = FPE_FLTINV; |
1184 | spefscr |= SPEFSCR_FINVS; | ||
1185 | } | 1187 | } |
1186 | else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES)) | 1188 | else if ((spefscr & (SPEFSCR_FG | SPEFSCR_FX)) && (fpexc_mode & PR_FP_EXC_RES)) |
1187 | code = FPE_FLTRES; | 1189 | code = FPE_FLTRES; |
1188 | 1190 | ||
1189 | current->thread.spefscr = spefscr; | 1191 | err = do_spe_mathemu(regs); |
1192 | if (err == 0) { | ||
1193 | regs->nip += 4; /* skip emulated instruction */ | ||
1194 | emulate_single_step(regs); | ||
1195 | return; | ||
1196 | } | ||
1197 | |||
1198 | if (err == -EFAULT) { | ||
1199 | /* got an error reading the instruction */ | ||
1200 | _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip); | ||
1201 | } else if (err == -EINVAL) { | ||
1202 | /* didn't recognize the instruction */ | ||
1203 | printk(KERN_ERR "unrecognized spe instruction " | ||
1204 | "in %s at %lx\n", current->comm, regs->nip); | ||
1205 | } else { | ||
1206 | _exception(SIGFPE, regs, code, regs->nip); | ||
1207 | } | ||
1190 | 1208 | ||
1191 | _exception(SIGFPE, regs, code, regs->nip); | ||
1192 | return; | 1209 | return; |
1193 | } | 1210 | } |
1211 | |||
1212 | void SPEFloatingPointRoundException(struct pt_regs *regs) | ||
1213 | { | ||
1214 | extern int speround_handler(struct pt_regs *regs); | ||
1215 | int err; | ||
1216 | |||
1217 | preempt_disable(); | ||
1218 | if (regs->msr & MSR_SPE) | ||
1219 | giveup_spe(current); | ||
1220 | preempt_enable(); | ||
1221 | |||
1222 | regs->nip -= 4; | ||
1223 | err = speround_handler(regs); | ||
1224 | if (err == 0) { | ||
1225 | regs->nip += 4; /* skip emulated instruction */ | ||
1226 | emulate_single_step(regs); | ||
1227 | return; | ||
1228 | } | ||
1229 | |||
1230 | if (err == -EFAULT) { | ||
1231 | /* got an error reading the instruction */ | ||
1232 | _exception(SIGSEGV, regs, SEGV_ACCERR, regs->nip); | ||
1233 | } else if (err == -EINVAL) { | ||
1234 | /* didn't recognize the instruction */ | ||
1235 | printk(KERN_ERR "unrecognized spe instruction " | ||
1236 | "in %s at %lx\n", current->comm, regs->nip); | ||
1237 | } else { | ||
1238 | _exception(SIGFPE, regs, 0, regs->nip); | ||
1239 | return; | ||
1240 | } | ||
1241 | } | ||
1194 | #endif | 1242 | #endif |
1195 | 1243 | ||
1196 | /* | 1244 | /* |
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index f7ec7d0888fe..ad06d5c75b15 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c | |||
@@ -566,6 +566,11 @@ static __init int vdso_fixup_features(struct lib32_elfinfo *v32, | |||
566 | do_feature_fixups(cur_cpu_spec->cpu_features, | 566 | do_feature_fixups(cur_cpu_spec->cpu_features, |
567 | start64, start64 + size64); | 567 | start64, start64 + size64); |
568 | 568 | ||
569 | start64 = find_section64(v64->hdr, "__mmu_ftr_fixup", &size64); | ||
570 | if (start64) | ||
571 | do_feature_fixups(cur_cpu_spec->mmu_features, | ||
572 | start64, start64 + size64); | ||
573 | |||
569 | start64 = find_section64(v64->hdr, "__fw_ftr_fixup", &size64); | 574 | start64 = find_section64(v64->hdr, "__fw_ftr_fixup", &size64); |
570 | if (start64) | 575 | if (start64) |
571 | do_feature_fixups(powerpc_firmware_features, | 576 | do_feature_fixups(powerpc_firmware_features, |
@@ -582,6 +587,11 @@ static __init int vdso_fixup_features(struct lib32_elfinfo *v32, | |||
582 | do_feature_fixups(cur_cpu_spec->cpu_features, | 587 | do_feature_fixups(cur_cpu_spec->cpu_features, |
583 | start32, start32 + size32); | 588 | start32, start32 + size32); |
584 | 589 | ||
590 | start32 = find_section32(v32->hdr, "__mmu_ftr_fixup", &size32); | ||
591 | if (start32) | ||
592 | do_feature_fixups(cur_cpu_spec->mmu_features, | ||
593 | start32, start32 + size32); | ||
594 | |||
585 | #ifdef CONFIG_PPC64 | 595 | #ifdef CONFIG_PPC64 |
586 | start32 = find_section32(v32->hdr, "__fw_ftr_fixup", &size32); | 596 | start32 = find_section32(v32->hdr, "__fw_ftr_fixup", &size32); |
587 | if (start32) | 597 | if (start32) |
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S index 72ca26df457e..ee038d4bf252 100644 --- a/arch/powerpc/kernel/vdso32/gettimeofday.S +++ b/arch/powerpc/kernel/vdso32/gettimeofday.S | |||
@@ -16,6 +16,13 @@ | |||
16 | #include <asm/asm-offsets.h> | 16 | #include <asm/asm-offsets.h> |
17 | #include <asm/unistd.h> | 17 | #include <asm/unistd.h> |
18 | 18 | ||
19 | /* Offset for the low 32-bit part of a field of long type */ | ||
20 | #ifdef CONFIG_PPC64 | ||
21 | #define LOPART 4 | ||
22 | #else | ||
23 | #define LOPART 0 | ||
24 | #endif | ||
25 | |||
19 | .text | 26 | .text |
20 | /* | 27 | /* |
21 | * Exact prototype of gettimeofday | 28 | * Exact prototype of gettimeofday |
@@ -90,101 +97,53 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
90 | 97 | ||
91 | mflr r12 /* r12 saves lr */ | 98 | mflr r12 /* r12 saves lr */ |
92 | .cfi_register lr,r12 | 99 | .cfi_register lr,r12 |
93 | mr r10,r3 /* r10 saves id */ | ||
94 | mr r11,r4 /* r11 saves tp */ | 100 | mr r11,r4 /* r11 saves tp */ |
95 | bl __get_datapage@local /* get data page */ | 101 | bl __get_datapage@local /* get data page */ |
96 | mr r9,r3 /* datapage ptr in r9 */ | 102 | mr r9,r3 /* datapage ptr in r9 */ |
97 | beq cr1,50f /* if monotonic -> jump there */ | ||
98 | |||
99 | /* | ||
100 | * CLOCK_REALTIME | ||
101 | */ | ||
102 | |||
103 | bl __do_get_xsec@local /* get xsec from tb & kernel */ | ||
104 | bne- 98f /* out of line -> do syscall */ | ||
105 | |||
106 | /* seconds are xsec >> 20 */ | ||
107 | rlwinm r5,r4,12,20,31 | ||
108 | rlwimi r5,r3,12,0,19 | ||
109 | stw r5,TSPC32_TV_SEC(r11) | ||
110 | 103 | ||
111 | /* get remaining xsec and convert to nsec. we scale | 104 | 50: bl __do_get_tspec@local /* get sec/nsec from tb & kernel */ |
112 | * up remaining xsec by 12 bits and get the top 32 bits | 105 | bne cr1,80f /* not monotonic -> all done */ |
113 | * of the multiplication, then we multiply by 1000 | ||
114 | */ | ||
115 | rlwinm r5,r4,12,0,19 | ||
116 | lis r6,1000000@h | ||
117 | ori r6,r6,1000000@l | ||
118 | mulhwu r5,r5,r6 | ||
119 | mulli r5,r5,1000 | ||
120 | stw r5,TSPC32_TV_NSEC(r11) | ||
121 | mtlr r12 | ||
122 | crclr cr0*4+so | ||
123 | li r3,0 | ||
124 | blr | ||
125 | 106 | ||
126 | /* | 107 | /* |
127 | * CLOCK_MONOTONIC | 108 | * CLOCK_MONOTONIC |
128 | */ | 109 | */ |
129 | 110 | ||
130 | 50: bl __do_get_xsec@local /* get xsec from tb & kernel */ | ||
131 | bne- 98f /* out of line -> do syscall */ | ||
132 | |||
133 | /* seconds are xsec >> 20 */ | ||
134 | rlwinm r6,r4,12,20,31 | ||
135 | rlwimi r6,r3,12,0,19 | ||
136 | |||
137 | /* get remaining xsec and convert to nsec. we scale | ||
138 | * up remaining xsec by 12 bits and get the top 32 bits | ||
139 | * of the multiplication, then we multiply by 1000 | ||
140 | */ | ||
141 | rlwinm r7,r4,12,0,19 | ||
142 | lis r5,1000000@h | ||
143 | ori r5,r5,1000000@l | ||
144 | mulhwu r7,r7,r5 | ||
145 | mulli r7,r7,1000 | ||
146 | |||
147 | /* now we must fixup using wall to monotonic. We need to snapshot | 111 | /* now we must fixup using wall to monotonic. We need to snapshot |
148 | * that value and do the counter trick again. Fortunately, we still | 112 | * that value and do the counter trick again. Fortunately, we still |
149 | * have the counter value in r8 that was returned by __do_get_xsec. | 113 | * have the counter value in r8 that was returned by __do_get_xsec. |
150 | * At this point, r6,r7 contain our sec/nsec values, r3,r4 and r5 | 114 | * At this point, r3,r4 contain our sec/nsec values, r5 and r6 |
151 | * can be used | 115 | * can be used, r7 contains NSEC_PER_SEC. |
152 | */ | 116 | */ |
153 | 117 | ||
154 | lwz r3,WTOM_CLOCK_SEC(r9) | 118 | lwz r5,WTOM_CLOCK_SEC(r9) |
155 | lwz r4,WTOM_CLOCK_NSEC(r9) | 119 | lwz r6,WTOM_CLOCK_NSEC(r9) |
156 | 120 | ||
157 | /* We now have our result in r3,r4. We create a fake dependency | 121 | /* We now have our offset in r5,r6. We create a fake dependency |
158 | * on that result and re-check the counter | 122 | * on that value and re-check the counter |
159 | */ | 123 | */ |
160 | or r5,r4,r3 | 124 | or r0,r6,r5 |
161 | xor r0,r5,r5 | 125 | xor r0,r0,r0 |
162 | add r9,r9,r0 | 126 | add r9,r9,r0 |
163 | #ifdef CONFIG_PPC64 | 127 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) |
164 | lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9) | ||
165 | #else | ||
166 | lwz r0,(CFG_TB_UPDATE_COUNT)(r9) | ||
167 | #endif | ||
168 | cmpl cr0,r8,r0 /* check if updated */ | 128 | cmpl cr0,r8,r0 /* check if updated */ |
169 | bne- 50b | 129 | bne- 50b |
170 | 130 | ||
171 | /* Calculate and store result. Note that this mimmics the C code, | 131 | /* Calculate and store result. Note that this mimics the C code, |
172 | * which may cause funny results if nsec goes negative... is that | 132 | * which may cause funny results if nsec goes negative... is that |
173 | * possible at all ? | 133 | * possible at all ? |
174 | */ | 134 | */ |
175 | add r3,r3,r6 | 135 | add r3,r3,r5 |
176 | add r4,r4,r7 | 136 | add r4,r4,r6 |
177 | lis r5,NSEC_PER_SEC@h | 137 | cmpw cr0,r4,r7 |
178 | ori r5,r5,NSEC_PER_SEC@l | 138 | cmpwi cr1,r4,0 |
179 | cmpl cr0,r4,r5 | ||
180 | cmpli cr1,r4,0 | ||
181 | blt 1f | 139 | blt 1f |
182 | subf r4,r5,r4 | 140 | subf r4,r7,r4 |
183 | addi r3,r3,1 | 141 | addi r3,r3,1 |
184 | 1: bge cr1,1f | 142 | 1: bge cr1,80f |
185 | addi r3,r3,-1 | 143 | addi r3,r3,-1 |
186 | add r4,r4,r5 | 144 | add r4,r4,r7 |
187 | 1: stw r3,TSPC32_TV_SEC(r11) | 145 | |
146 | 80: stw r3,TSPC32_TV_SEC(r11) | ||
188 | stw r4,TSPC32_TV_NSEC(r11) | 147 | stw r4,TSPC32_TV_NSEC(r11) |
189 | 148 | ||
190 | mtlr r12 | 149 | mtlr r12 |
@@ -195,10 +154,6 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
195 | /* | 154 | /* |
196 | * syscall fallback | 155 | * syscall fallback |
197 | */ | 156 | */ |
198 | 98: | ||
199 | mtlr r12 | ||
200 | mr r3,r10 | ||
201 | mr r4,r11 | ||
202 | 99: | 157 | 99: |
203 | li r0,__NR_clock_gettime | 158 | li r0,__NR_clock_gettime |
204 | sc | 159 | sc |
@@ -254,11 +209,7 @@ __do_get_xsec: | |||
254 | /* Check for update count & load values. We use the low | 209 | /* Check for update count & load values. We use the low |
255 | * order 32 bits of the update count | 210 | * order 32 bits of the update count |
256 | */ | 211 | */ |
257 | #ifdef CONFIG_PPC64 | 212 | 1: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9) |
258 | 1: lwz r8,(CFG_TB_UPDATE_COUNT+4)(r9) | ||
259 | #else | ||
260 | 1: lwz r8,(CFG_TB_UPDATE_COUNT)(r9) | ||
261 | #endif | ||
262 | andi. r0,r8,1 /* pending update ? loop */ | 213 | andi. r0,r8,1 /* pending update ? loop */ |
263 | bne- 1b | 214 | bne- 1b |
264 | xor r0,r8,r8 /* create dependency */ | 215 | xor r0,r8,r8 /* create dependency */ |
@@ -305,11 +256,7 @@ __do_get_xsec: | |||
305 | or r6,r4,r3 | 256 | or r6,r4,r3 |
306 | xor r0,r6,r6 | 257 | xor r0,r6,r6 |
307 | add r9,r9,r0 | 258 | add r9,r9,r0 |
308 | #ifdef CONFIG_PPC64 | 259 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) |
309 | lwz r0,(CFG_TB_UPDATE_COUNT+4)(r9) | ||
310 | #else | ||
311 | lwz r0,(CFG_TB_UPDATE_COUNT)(r9) | ||
312 | #endif | ||
313 | cmpl cr0,r8,r0 /* check if updated */ | 260 | cmpl cr0,r8,r0 /* check if updated */ |
314 | bne- 1b | 261 | bne- 1b |
315 | 262 | ||
@@ -322,3 +269,98 @@ __do_get_xsec: | |||
322 | */ | 269 | */ |
323 | 3: blr | 270 | 3: blr |
324 | .cfi_endproc | 271 | .cfi_endproc |
272 | |||
273 | /* | ||
274 | * This is the core of clock_gettime(), it returns the current | ||
275 | * time in seconds and nanoseconds in r3 and r4. | ||
276 | * It expects the datapage ptr in r9 and doesn't clobber it. | ||
277 | * It clobbers r0, r5, r6, r10 and returns NSEC_PER_SEC in r7. | ||
278 | * On return, r8 contains the counter value that can be reused. | ||
279 | * This clobbers cr0 but not any other cr field. | ||
280 | */ | ||
281 | __do_get_tspec: | ||
282 | .cfi_startproc | ||
283 | /* Check for update count & load values. We use the low | ||
284 | * order 32 bits of the update count | ||
285 | */ | ||
286 | 1: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9) | ||
287 | andi. r0,r8,1 /* pending update ? loop */ | ||
288 | bne- 1b | ||
289 | xor r0,r8,r8 /* create dependency */ | ||
290 | add r9,r9,r0 | ||
291 | |||
292 | /* Load orig stamp (offset to TB) */ | ||
293 | lwz r5,CFG_TB_ORIG_STAMP(r9) | ||
294 | lwz r6,(CFG_TB_ORIG_STAMP+4)(r9) | ||
295 | |||
296 | /* Get a stable TB value */ | ||
297 | 2: mftbu r3 | ||
298 | mftbl r4 | ||
299 | mftbu r0 | ||
300 | cmpl cr0,r3,r0 | ||
301 | bne- 2b | ||
302 | |||
303 | /* Subtract tb orig stamp and shift left 12 bits. | ||
304 | */ | ||
305 | subfc r7,r6,r4 | ||
306 | subfe r0,r5,r3 | ||
307 | slwi r0,r0,12 | ||
308 | rlwimi. r0,r7,12,20,31 | ||
309 | slwi r7,r7,12 | ||
310 | |||
311 | /* Load scale factor & do multiplication */ | ||
312 | lwz r5,CFG_TB_TO_XS(r9) /* load values */ | ||
313 | lwz r6,(CFG_TB_TO_XS+4)(r9) | ||
314 | mulhwu r3,r7,r6 | ||
315 | mullw r10,r7,r5 | ||
316 | mulhwu r4,r7,r5 | ||
317 | addc r10,r3,r10 | ||
318 | li r3,0 | ||
319 | |||
320 | beq+ 4f /* skip high part computation if 0 */ | ||
321 | mulhwu r3,r0,r5 | ||
322 | mullw r7,r0,r5 | ||
323 | mulhwu r5,r0,r6 | ||
324 | mullw r6,r0,r6 | ||
325 | adde r4,r4,r7 | ||
326 | addze r3,r3 | ||
327 | addc r4,r4,r5 | ||
328 | addze r3,r3 | ||
329 | addc r10,r10,r6 | ||
330 | |||
331 | 4: addze r4,r4 /* add in carry */ | ||
332 | lis r7,NSEC_PER_SEC@h | ||
333 | ori r7,r7,NSEC_PER_SEC@l | ||
334 | mulhwu r4,r4,r7 /* convert to nanoseconds */ | ||
335 | |||
336 | /* At this point, we have seconds & nanoseconds since the xtime | ||
337 | * stamp in r3+CA and r4. Load & add the xtime stamp. | ||
338 | */ | ||
339 | #ifdef CONFIG_PPC64 | ||
340 | lwz r5,STAMP_XTIME+TSPC64_TV_SEC+LOPART(r9) | ||
341 | lwz r6,STAMP_XTIME+TSPC64_TV_NSEC+LOPART(r9) | ||
342 | #else | ||
343 | lwz r5,STAMP_XTIME+TSPC32_TV_SEC(r9) | ||
344 | lwz r6,STAMP_XTIME+TSPC32_TV_NSEC(r9) | ||
345 | #endif | ||
346 | add r4,r4,r6 | ||
347 | adde r3,r3,r5 | ||
348 | |||
349 | /* We now have our result in r3,r4. We create a fake dependency | ||
350 | * on that result and re-check the counter | ||
351 | */ | ||
352 | or r6,r4,r3 | ||
353 | xor r0,r6,r6 | ||
354 | add r9,r9,r0 | ||
355 | lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9) | ||
356 | cmpl cr0,r8,r0 /* check if updated */ | ||
357 | bne- 1b | ||
358 | |||
359 | /* check for nanosecond overflow and adjust if necessary */ | ||
360 | cmpw r4,r7 | ||
361 | bltlr /* all done if no overflow */ | ||
362 | subf r4,r7,r4 /* adjust if overflow */ | ||
363 | addi r3,r3,1 | ||
364 | |||
365 | blr | ||
366 | .cfi_endproc | ||
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S index be3b6a41dc09..904ef1360dd7 100644 --- a/arch/powerpc/kernel/vdso32/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S | |||
@@ -34,6 +34,9 @@ SECTIONS | |||
34 | __ftr_fixup : { *(__ftr_fixup) } | 34 | __ftr_fixup : { *(__ftr_fixup) } |
35 | 35 | ||
36 | . = ALIGN(8); | 36 | . = ALIGN(8); |
37 | __mmu_ftr_fixup : { *(__mmu_ftr_fixup) } | ||
38 | |||
39 | . = ALIGN(8); | ||
37 | __lwsync_fixup : { *(__lwsync_fixup) } | 40 | __lwsync_fixup : { *(__lwsync_fixup) } |
38 | 41 | ||
39 | #ifdef CONFIG_PPC64 | 42 | #ifdef CONFIG_PPC64 |
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S index c6401f9e37f1..262cd5857a56 100644 --- a/arch/powerpc/kernel/vdso64/gettimeofday.S +++ b/arch/powerpc/kernel/vdso64/gettimeofday.S | |||
@@ -75,90 +75,49 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
75 | 75 | ||
76 | mflr r12 /* r12 saves lr */ | 76 | mflr r12 /* r12 saves lr */ |
77 | .cfi_register lr,r12 | 77 | .cfi_register lr,r12 |
78 | mr r10,r3 /* r10 saves id */ | ||
79 | mr r11,r4 /* r11 saves tp */ | 78 | mr r11,r4 /* r11 saves tp */ |
80 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ | 79 | bl V_LOCAL_FUNC(__get_datapage) /* get data page */ |
81 | beq cr1,50f /* if monotonic -> jump there */ | 80 | 50: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */ |
82 | 81 | bne cr1,80f /* if not monotonic, all done */ | |
83 | /* | ||
84 | * CLOCK_REALTIME | ||
85 | */ | ||
86 | |||
87 | bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ | ||
88 | |||
89 | lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ | ||
90 | ori r7,r7,16960 | ||
91 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ | ||
92 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ | ||
93 | std r5,TSPC64_TV_SEC(r11) /* store sec in tv */ | ||
94 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ | ||
95 | mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / | ||
96 | * XSEC_PER_SEC | ||
97 | */ | ||
98 | rldicl r0,r0,44,20 | ||
99 | mulli r0,r0,1000 /* nsec = usec * 1000 */ | ||
100 | std r0,TSPC64_TV_NSEC(r11) /* store nsec in tp */ | ||
101 | |||
102 | mtlr r12 | ||
103 | crclr cr0*4+so | ||
104 | li r3,0 | ||
105 | blr | ||
106 | 82 | ||
107 | /* | 83 | /* |
108 | * CLOCK_MONOTONIC | 84 | * CLOCK_MONOTONIC |
109 | */ | 85 | */ |
110 | 86 | ||
111 | 50: bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */ | ||
112 | |||
113 | lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */ | ||
114 | ori r7,r7,16960 | ||
115 | rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */ | ||
116 | rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */ | ||
117 | subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */ | ||
118 | mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) / | ||
119 | * XSEC_PER_SEC | ||
120 | */ | ||
121 | rldicl r6,r0,44,20 | ||
122 | mulli r6,r6,1000 /* nsec = usec * 1000 */ | ||
123 | |||
124 | /* now we must fixup using wall to monotonic. We need to snapshot | 87 | /* now we must fixup using wall to monotonic. We need to snapshot |
125 | * that value and do the counter trick again. Fortunately, we still | 88 | * that value and do the counter trick again. Fortunately, we still |
126 | * have the counter value in r8 that was returned by __do_get_xsec. | 89 | * have the counter value in r8 that was returned by __do_get_tspec. |
127 | * At this point, r5,r6 contain our sec/nsec values. | 90 | * At this point, r4,r5 contain our sec/nsec values. |
128 | * can be used | ||
129 | */ | 91 | */ |
130 | 92 | ||
131 | lwa r4,WTOM_CLOCK_SEC(r3) | 93 | lwa r6,WTOM_CLOCK_SEC(r3) |
132 | lwa r7,WTOM_CLOCK_NSEC(r3) | 94 | lwa r9,WTOM_CLOCK_NSEC(r3) |
133 | 95 | ||
134 | /* We now have our result in r4,r7. We create a fake dependency | 96 | /* We now have our result in r6,r9. We create a fake dependency |
135 | * on that result and re-check the counter | 97 | * on that result and re-check the counter |
136 | */ | 98 | */ |
137 | or r9,r4,r7 | 99 | or r0,r6,r9 |
138 | xor r0,r9,r9 | 100 | xor r0,r0,r0 |
139 | add r3,r3,r0 | 101 | add r3,r3,r0 |
140 | ld r0,CFG_TB_UPDATE_COUNT(r3) | 102 | ld r0,CFG_TB_UPDATE_COUNT(r3) |
141 | cmpld cr0,r0,r8 /* check if updated */ | 103 | cmpld cr0,r0,r8 /* check if updated */ |
142 | bne- 50b | 104 | bne- 50b |
143 | 105 | ||
144 | /* Calculate and store result. Note that this mimmics the C code, | 106 | /* Add wall->monotonic offset and check for overflow or underflow. |
145 | * which may cause funny results if nsec goes negative... is that | ||
146 | * possible at all ? | ||
147 | */ | 107 | */ |
148 | add r4,r4,r5 | 108 | add r4,r4,r6 |
149 | add r7,r7,r6 | 109 | add r5,r5,r9 |
150 | lis r9,NSEC_PER_SEC@h | 110 | cmpd cr0,r5,r7 |
151 | ori r9,r9,NSEC_PER_SEC@l | 111 | cmpdi cr1,r5,0 |
152 | cmpl cr0,r7,r9 | ||
153 | cmpli cr1,r7,0 | ||
154 | blt 1f | 112 | blt 1f |
155 | subf r7,r9,r7 | 113 | subf r5,r7,r5 |
156 | addi r4,r4,1 | 114 | addi r4,r4,1 |
157 | 1: bge cr1,1f | 115 | 1: bge cr1,80f |
158 | addi r4,r4,-1 | 116 | addi r4,r4,-1 |
159 | add r7,r7,r9 | 117 | add r5,r5,r7 |
160 | 1: std r4,TSPC64_TV_SEC(r11) | 118 | |
161 | std r7,TSPC64_TV_NSEC(r11) | 119 | 80: std r4,TSPC64_TV_SEC(r11) |
120 | std r5,TSPC64_TV_NSEC(r11) | ||
162 | 121 | ||
163 | mtlr r12 | 122 | mtlr r12 |
164 | crclr cr0*4+so | 123 | crclr cr0*4+so |
@@ -168,10 +127,6 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime) | |||
168 | /* | 127 | /* |
169 | * syscall fallback | 128 | * syscall fallback |
170 | */ | 129 | */ |
171 | 98: | ||
172 | mtlr r12 | ||
173 | mr r3,r10 | ||
174 | mr r4,r11 | ||
175 | 99: | 130 | 99: |
176 | li r0,__NR_clock_gettime | 131 | li r0,__NR_clock_gettime |
177 | sc | 132 | sc |
@@ -253,3 +208,59 @@ V_FUNCTION_BEGIN(__do_get_xsec) | |||
253 | blr | 208 | blr |
254 | .cfi_endproc | 209 | .cfi_endproc |
255 | V_FUNCTION_END(__do_get_xsec) | 210 | V_FUNCTION_END(__do_get_xsec) |
211 | |||
212 | /* | ||
213 | * This is the core of clock_gettime(), it returns the current | ||
214 | * time in seconds and nanoseconds in r4 and r5. | ||
215 | * It expects the datapage ptr in r3 and doesn't clobber it. | ||
216 | * It clobbers r0 and r6 and returns NSEC_PER_SEC in r7. | ||
217 | * On return, r8 contains the counter value that can be reused. | ||
218 | * This clobbers cr0 but not any other cr field. | ||
219 | */ | ||
220 | V_FUNCTION_BEGIN(__do_get_tspec) | ||
221 | .cfi_startproc | ||
222 | /* check for update count & load values */ | ||
223 | 1: ld r8,CFG_TB_UPDATE_COUNT(r3) | ||
224 | andi. r0,r8,1 /* pending update ? loop */ | ||
225 | bne- 1b | ||
226 | xor r0,r8,r8 /* create dependency */ | ||
227 | add r3,r3,r0 | ||
228 | |||
229 | /* Get TB & offset it. We use the MFTB macro which will generate | ||
230 | * workaround code for Cell. | ||
231 | */ | ||
232 | MFTB(r7) | ||
233 | ld r9,CFG_TB_ORIG_STAMP(r3) | ||
234 | subf r7,r9,r7 | ||
235 | |||
236 | /* Scale result */ | ||
237 | ld r5,CFG_TB_TO_XS(r3) | ||
238 | sldi r7,r7,12 /* compute time since stamp_xtime */ | ||
239 | mulhdu r6,r7,r5 /* in units of 2^-32 seconds */ | ||
240 | |||
241 | /* Add stamp since epoch */ | ||
242 | ld r4,STAMP_XTIME+TSPC64_TV_SEC(r3) | ||
243 | ld r5,STAMP_XTIME+TSPC64_TV_NSEC(r3) | ||
244 | or r0,r4,r5 | ||
245 | or r0,r0,r6 | ||
246 | xor r0,r0,r0 | ||
247 | add r3,r3,r0 | ||
248 | ld r0,CFG_TB_UPDATE_COUNT(r3) | ||
249 | cmpld r0,r8 /* check if updated */ | ||
250 | bne- 1b /* reload if so */ | ||
251 | |||
252 | /* convert to seconds & nanoseconds and add to stamp */ | ||
253 | lis r7,NSEC_PER_SEC@h | ||
254 | ori r7,r7,NSEC_PER_SEC@l | ||
255 | mulhwu r0,r6,r7 /* compute nanoseconds and */ | ||
256 | srdi r6,r6,32 /* seconds since stamp_xtime */ | ||
257 | clrldi r0,r0,32 | ||
258 | add r5,r5,r0 /* add nanoseconds together */ | ||
259 | cmpd r5,r7 /* overflow? */ | ||
260 | add r4,r4,r6 | ||
261 | bltlr /* all done if no overflow */ | ||
262 | subf r5,r7,r5 /* if overflow, adjust */ | ||
263 | addi r4,r4,1 | ||
264 | blr | ||
265 | .cfi_endproc | ||
266 | V_FUNCTION_END(__do_get_tspec) | ||
diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S index d0b2526dd38d..0e615404e247 100644 --- a/arch/powerpc/kernel/vdso64/vdso64.lds.S +++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S | |||
@@ -35,6 +35,9 @@ SECTIONS | |||
35 | __ftr_fixup : { *(__ftr_fixup) } | 35 | __ftr_fixup : { *(__ftr_fixup) } |
36 | 36 | ||
37 | . = ALIGN(8); | 37 | . = ALIGN(8); |
38 | __mmu_ftr_fixup : { *(__mmu_ftr_fixup) } | ||
39 | |||
40 | . = ALIGN(8); | ||
38 | __lwsync_fixup : { *(__lwsync_fixup) } | 41 | __lwsync_fixup : { *(__lwsync_fixup) } |
39 | 42 | ||
40 | . = ALIGN(8); | 43 | . = ALIGN(8); |
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index a11e6bc59b30..94aa7b011b27 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -41,9 +41,9 @@ | |||
41 | static struct bus_type vio_bus_type; | 41 | static struct bus_type vio_bus_type; |
42 | 42 | ||
43 | static struct vio_dev vio_bus_device = { /* fake "parent" device */ | 43 | static struct vio_dev vio_bus_device = { /* fake "parent" device */ |
44 | .name = vio_bus_device.dev.bus_id, | 44 | .name = "vio", |
45 | .type = "", | 45 | .type = "", |
46 | .dev.bus_id = "vio", | 46 | .dev.init_name = "vio", |
47 | .dev.bus = &vio_bus_type, | 47 | .dev.bus = &vio_bus_type, |
48 | }; | 48 | }; |
49 | 49 | ||
@@ -1216,7 +1216,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) | |||
1216 | 1216 | ||
1217 | viodev->irq = irq_of_parse_and_map(of_node, 0); | 1217 | viodev->irq = irq_of_parse_and_map(of_node, 0); |
1218 | 1218 | ||
1219 | snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); | 1219 | dev_set_name(&viodev->dev, "%x", *unit_address); |
1220 | viodev->name = of_node->name; | 1220 | viodev->name = of_node->name; |
1221 | viodev->type = of_node->type; | 1221 | viodev->type = of_node->type; |
1222 | viodev->unit_address = *unit_address; | 1222 | viodev->unit_address = *unit_address; |
@@ -1243,7 +1243,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) | |||
1243 | /* register with generic device framework */ | 1243 | /* register with generic device framework */ |
1244 | if (device_register(&viodev->dev)) { | 1244 | if (device_register(&viodev->dev)) { |
1245 | printk(KERN_ERR "%s: failed to register device %s\n", | 1245 | printk(KERN_ERR "%s: failed to register device %s\n", |
1246 | __func__, viodev->dev.bus_id); | 1246 | __func__, dev_name(&viodev->dev)); |
1247 | /* XXX free TCE table */ | 1247 | /* XXX free TCE table */ |
1248 | kfree(viodev); | 1248 | kfree(viodev); |
1249 | return NULL; | 1249 | return NULL; |
@@ -1400,13 +1400,13 @@ static struct vio_dev *vio_find_name(const char *name) | |||
1400 | struct vio_dev *vio_find_node(struct device_node *vnode) | 1400 | struct vio_dev *vio_find_node(struct device_node *vnode) |
1401 | { | 1401 | { |
1402 | const uint32_t *unit_address; | 1402 | const uint32_t *unit_address; |
1403 | char kobj_name[BUS_ID_SIZE]; | 1403 | char kobj_name[20]; |
1404 | 1404 | ||
1405 | /* construct the kobject name from the device node */ | 1405 | /* construct the kobject name from the device node */ |
1406 | unit_address = of_get_property(vnode, "reg", NULL); | 1406 | unit_address = of_get_property(vnode, "reg", NULL); |
1407 | if (!unit_address) | 1407 | if (!unit_address) |
1408 | return NULL; | 1408 | return NULL; |
1409 | snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); | 1409 | snprintf(kobj_name, sizeof(kobj_name), "%x", *unit_address); |
1410 | 1410 | ||
1411 | return vio_find_name(kobj_name); | 1411 | return vio_find_name(kobj_name); |
1412 | } | 1412 | } |
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 2412c056baa4..47bf15cd2c9e 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S | |||
@@ -152,6 +152,12 @@ SECTIONS | |||
152 | __stop___ftr_fixup = .; | 152 | __stop___ftr_fixup = .; |
153 | } | 153 | } |
154 | . = ALIGN(8); | 154 | . = ALIGN(8); |
155 | __mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) { | ||
156 | __start___mmu_ftr_fixup = .; | ||
157 | *(__mmu_ftr_fixup) | ||
158 | __stop___mmu_ftr_fixup = .; | ||
159 | } | ||
160 | . = ALIGN(8); | ||
155 | __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) { | 161 | __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) { |
156 | __start___lwsync_fixup = .; | 162 | __start___lwsync_fixup = .; |
157 | *(__lwsync_fixup) | 163 | *(__lwsync_fixup) |