diff options
author | Paul Mackerras <paulus@samba.org> | 2005-09-30 23:49:08 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-09-30 23:49:08 -0400 |
commit | c0c0d996d08e450164adedc249c1bbbca63524ce (patch) | |
tree | 15f297796a93568fd45756c72ca07e77756c8653 | |
parent | ab11d1ea281e85895369ef57c5259ad8a432fabb (diff) |
powerpc: Get merged kernel to compile and run on 32-bit SMP powermac.
This updates the powermac SMP code to use the mpic driver instead of
the openpic driver and fixes the SMP-dependent context switch code.
We had a subtle bug where we were using interrupt numbers 256-259 for
IPIs, but ppc32 had NR_IRQS = 256. Moved the IPIs down to use interrupt
numbers 252-255 instead.
Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r-- | arch/powerpc/kernel/ppc_ksyms.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/process.c | 17 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pmac_pic.c | 7 | ||||
-rw-r--r-- | arch/powerpc/platforms/powermac/pmac_smp.c | 10 | ||||
-rw-r--r-- | arch/powerpc/sysdev/mpic.c | 3 |
5 files changed, 24 insertions, 15 deletions
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 7bfa0f0121ff..e73b0699b5f0 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -182,11 +182,9 @@ EXPORT_SYMBOL(flush_tlb_kernel_range); | |||
182 | EXPORT_SYMBOL(flush_tlb_page); | 182 | EXPORT_SYMBOL(flush_tlb_page); |
183 | EXPORT_SYMBOL(_tlbie); | 183 | EXPORT_SYMBOL(_tlbie); |
184 | #ifdef CONFIG_ALTIVEC | 184 | #ifdef CONFIG_ALTIVEC |
185 | EXPORT_SYMBOL(last_task_used_altivec); | ||
186 | EXPORT_SYMBOL(giveup_altivec); | 185 | EXPORT_SYMBOL(giveup_altivec); |
187 | #endif /* CONFIG_ALTIVEC */ | 186 | #endif /* CONFIG_ALTIVEC */ |
188 | #ifdef CONFIG_SPE | 187 | #ifdef CONFIG_SPE |
189 | EXPORT_SYMBOL(last_task_used_spe); | ||
190 | EXPORT_SYMBOL(giveup_spe); | 188 | EXPORT_SYMBOL(giveup_spe); |
191 | #endif /* CONFIG_SPE */ | 189 | #endif /* CONFIG_SPE */ |
192 | #ifdef CONFIG_SMP | 190 | #ifdef CONFIG_SMP |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index e3946769dd8e..ae316e9ed581 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -272,11 +272,6 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
272 | */ | 272 | */ |
273 | if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) | 273 | if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) |
274 | giveup_altivec(prev); | 274 | giveup_altivec(prev); |
275 | /* Avoid the trap. On smp this this never happens since | ||
276 | * we don't set last_task_used_altivec -- Cort | ||
277 | */ | ||
278 | if (new->thread.regs && last_task_used_altivec == new) | ||
279 | new->thread.regs->msr |= MSR_VEC; | ||
280 | #endif /* CONFIG_ALTIVEC */ | 275 | #endif /* CONFIG_ALTIVEC */ |
281 | #ifdef CONFIG_SPE | 276 | #ifdef CONFIG_SPE |
282 | /* | 277 | /* |
@@ -288,12 +283,24 @@ struct task_struct *__switch_to(struct task_struct *prev, | |||
288 | */ | 283 | */ |
289 | if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE))) | 284 | if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE))) |
290 | giveup_spe(prev); | 285 | giveup_spe(prev); |
286 | #endif /* CONFIG_SPE */ | ||
287 | |||
288 | #else /* CONFIG_SMP */ | ||
289 | #ifdef CONFIG_ALTIVEC | ||
290 | /* Avoid the trap. On smp this this never happens since | ||
291 | * we don't set last_task_used_altivec -- Cort | ||
292 | */ | ||
293 | if (new->thread.regs && last_task_used_altivec == new) | ||
294 | new->thread.regs->msr |= MSR_VEC; | ||
295 | #endif /* CONFIG_ALTIVEC */ | ||
296 | #ifdef CONFIG_SPE | ||
291 | /* Avoid the trap. On smp this this never happens since | 297 | /* Avoid the trap. On smp this this never happens since |
292 | * we don't set last_task_used_spe | 298 | * we don't set last_task_used_spe |
293 | */ | 299 | */ |
294 | if (new->thread.regs && last_task_used_spe == new) | 300 | if (new->thread.regs && last_task_used_spe == new) |
295 | new->thread.regs->msr |= MSR_SPE; | 301 | new->thread.regs->msr |= MSR_SPE; |
296 | #endif /* CONFIG_SPE */ | 302 | #endif /* CONFIG_SPE */ |
303 | |||
297 | #endif /* CONFIG_SMP */ | 304 | #endif /* CONFIG_SMP */ |
298 | 305 | ||
299 | #ifdef CONFIG_PPC64 /* for now */ | 306 | #ifdef CONFIG_PPC64 /* for now */ |
diff --git a/arch/powerpc/platforms/powermac/pmac_pic.c b/arch/powerpc/platforms/powermac/pmac_pic.c index a6b1b577e19f..7ddd5264cc6e 100644 --- a/arch/powerpc/platforms/powermac/pmac_pic.c +++ b/arch/powerpc/platforms/powermac/pmac_pic.c | |||
@@ -430,7 +430,7 @@ void __init pmac_pic_init(void) | |||
430 | prom_get_irq_senses(senses, 0, 128); | 430 | prom_get_irq_senses(senses, 0, 128); |
431 | mpic1 = mpic_alloc(irqctrler->addrs[0].address, | 431 | mpic1 = mpic_alloc(irqctrler->addrs[0].address, |
432 | MPIC_PRIMARY | MPIC_WANTS_RESET, | 432 | MPIC_PRIMARY | MPIC_WANTS_RESET, |
433 | 0, 0, 128, 256, senses, 128, " K2-MPIC "); | 433 | 0, 0, 128, 252, senses, 128, " OpenPIC "); |
434 | BUG_ON(mpic1 == NULL); | 434 | BUG_ON(mpic1 == NULL); |
435 | mpic_init(mpic1); | 435 | mpic_init(mpic1); |
436 | 436 | ||
@@ -441,14 +441,15 @@ void __init pmac_pic_init(void) | |||
441 | irqctrler2->intrs[0].line); | 441 | irqctrler2->intrs[0].line); |
442 | 442 | ||
443 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0); | 443 | pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0); |
444 | prom_get_irq_senses(senses, 128, 128 + 128); | 444 | prom_get_irq_senses(senses, 128, 128 + 124); |
445 | 445 | ||
446 | /* We don't need to set MPIC_BROKEN_U3 here since we don't have | 446 | /* We don't need to set MPIC_BROKEN_U3 here since we don't have |
447 | * hypertransport interrupts routed to it | 447 | * hypertransport interrupts routed to it |
448 | */ | 448 | */ |
449 | mpic2 = mpic_alloc(irqctrler2->addrs[0].address, | 449 | mpic2 = mpic_alloc(irqctrler2->addrs[0].address, |
450 | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET, | 450 | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET, |
451 | 0, 128, 128, 0, senses, 128, " U3-MPIC "); | 451 | 0, 128, 124, 0, senses, 124, |
452 | " U3-MPIC "); | ||
452 | BUG_ON(mpic2 == NULL); | 453 | BUG_ON(mpic2 == NULL); |
453 | mpic_init(mpic2); | 454 | mpic_init(mpic2); |
454 | mpic_setup_cascade(irqctrler2->intrs[0].line, | 455 | mpic_setup_cascade(irqctrler2->intrs[0].line, |
diff --git a/arch/powerpc/platforms/powermac/pmac_smp.c b/arch/powerpc/platforms/powermac/pmac_smp.c index 995e9095d865..fb996336c58b 100644 --- a/arch/powerpc/platforms/powermac/pmac_smp.c +++ b/arch/powerpc/platforms/powermac/pmac_smp.c | |||
@@ -48,7 +48,7 @@ | |||
48 | #include <asm/machdep.h> | 48 | #include <asm/machdep.h> |
49 | #include <asm/pmac_feature.h> | 49 | #include <asm/pmac_feature.h> |
50 | #include <asm/time.h> | 50 | #include <asm/time.h> |
51 | #include <asm/open_pic.h> | 51 | #include <asm/mpic.h> |
52 | #include <asm/cacheflush.h> | 52 | #include <asm/cacheflush.h> |
53 | #include <asm/keylargo.h> | 53 | #include <asm/keylargo.h> |
54 | 54 | ||
@@ -638,14 +638,14 @@ void smp_core99_message_pass(int target, int msg, unsigned long data, int wait) | |||
638 | } | 638 | } |
639 | switch (target) { | 639 | switch (target) { |
640 | case MSG_ALL: | 640 | case MSG_ALL: |
641 | mpic_send_ipi(msg, mask); | 641 | mpic_send_ipi(msg, cpus_addr(mask)[0]); |
642 | break; | 642 | break; |
643 | case MSG_ALL_BUT_SELF: | 643 | case MSG_ALL_BUT_SELF: |
644 | cpu_clear(smp_processor_id(), mask); | 644 | cpu_clear(smp_processor_id(), mask); |
645 | mpic_send_ipi(msg, mask); | 645 | mpic_send_ipi(msg, cpus_addr(mask)[0]); |
646 | break; | 646 | break; |
647 | default: | 647 | default: |
648 | mpic_send_ipi(msg, cpumask_of_cpu(target)); | 648 | mpic_send_ipi(msg, 1 << target); |
649 | break; | 649 | break; |
650 | } | 650 | } |
651 | } | 651 | } |
@@ -678,7 +678,7 @@ int __cpu_disable(void) | |||
678 | cpu_clear(smp_processor_id(), cpu_online_map); | 678 | cpu_clear(smp_processor_id(), cpu_online_map); |
679 | 679 | ||
680 | /* XXX reset cpu affinity here */ | 680 | /* XXX reset cpu affinity here */ |
681 | openpic_set_priority(0xf); | 681 | mpic_cpu_set_priority(0xf); |
682 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); | 682 | asm volatile("mtdec %0" : : "r" (0x7fffffff)); |
683 | mb(); | 683 | mb(); |
684 | udelay(20); | 684 | udelay(20); |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index c660e7d7c643..02b4d2488bfd 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -44,6 +44,9 @@ static struct mpic *mpics; | |||
44 | static struct mpic *mpic_primary; | 44 | static struct mpic *mpic_primary; |
45 | static DEFINE_SPINLOCK(mpic_lock); | 45 | static DEFINE_SPINLOCK(mpic_lock); |
46 | 46 | ||
47 | #ifdef CONFIG_PPC32 /* XXX for now */ | ||
48 | #define distribute_irqs CONFIG_IRQ_ALL_CPUS | ||
49 | #endif | ||
47 | 50 | ||
48 | /* | 51 | /* |
49 | * Register accessor functions | 52 | * Register accessor functions |