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>
This commit is contained in:
Родитель
ab11d1ea28
Коммит
c0c0d996d0
|
@ -182,11 +182,9 @@ EXPORT_SYMBOL(flush_tlb_kernel_range);
|
||||||
EXPORT_SYMBOL(flush_tlb_page);
|
EXPORT_SYMBOL(flush_tlb_page);
|
||||||
EXPORT_SYMBOL(_tlbie);
|
EXPORT_SYMBOL(_tlbie);
|
||||||
#ifdef CONFIG_ALTIVEC
|
#ifdef CONFIG_ALTIVEC
|
||||||
EXPORT_SYMBOL(last_task_used_altivec);
|
|
||||||
EXPORT_SYMBOL(giveup_altivec);
|
EXPORT_SYMBOL(giveup_altivec);
|
||||||
#endif /* CONFIG_ALTIVEC */
|
#endif /* CONFIG_ALTIVEC */
|
||||||
#ifdef CONFIG_SPE
|
#ifdef CONFIG_SPE
|
||||||
EXPORT_SYMBOL(last_task_used_spe);
|
|
||||||
EXPORT_SYMBOL(giveup_spe);
|
EXPORT_SYMBOL(giveup_spe);
|
||||||
#endif /* CONFIG_SPE */
|
#endif /* CONFIG_SPE */
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
|
|
|
@ -272,11 +272,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
||||||
*/
|
*/
|
||||||
if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))
|
if (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))
|
||||||
giveup_altivec(prev);
|
giveup_altivec(prev);
|
||||||
/* Avoid the trap. On smp this this never happens since
|
|
||||||
* we don't set last_task_used_altivec -- Cort
|
|
||||||
*/
|
|
||||||
if (new->thread.regs && last_task_used_altivec == new)
|
|
||||||
new->thread.regs->msr |= MSR_VEC;
|
|
||||||
#endif /* CONFIG_ALTIVEC */
|
#endif /* CONFIG_ALTIVEC */
|
||||||
#ifdef CONFIG_SPE
|
#ifdef CONFIG_SPE
|
||||||
/*
|
/*
|
||||||
|
@ -288,12 +283,24 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
||||||
*/
|
*/
|
||||||
if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
|
if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
|
||||||
giveup_spe(prev);
|
giveup_spe(prev);
|
||||||
|
#endif /* CONFIG_SPE */
|
||||||
|
|
||||||
|
#else /* CONFIG_SMP */
|
||||||
|
#ifdef CONFIG_ALTIVEC
|
||||||
|
/* Avoid the trap. On smp this this never happens since
|
||||||
|
* we don't set last_task_used_altivec -- Cort
|
||||||
|
*/
|
||||||
|
if (new->thread.regs && last_task_used_altivec == new)
|
||||||
|
new->thread.regs->msr |= MSR_VEC;
|
||||||
|
#endif /* CONFIG_ALTIVEC */
|
||||||
|
#ifdef CONFIG_SPE
|
||||||
/* Avoid the trap. On smp this this never happens since
|
/* Avoid the trap. On smp this this never happens since
|
||||||
* we don't set last_task_used_spe
|
* we don't set last_task_used_spe
|
||||||
*/
|
*/
|
||||||
if (new->thread.regs && last_task_used_spe == new)
|
if (new->thread.regs && last_task_used_spe == new)
|
||||||
new->thread.regs->msr |= MSR_SPE;
|
new->thread.regs->msr |= MSR_SPE;
|
||||||
#endif /* CONFIG_SPE */
|
#endif /* CONFIG_SPE */
|
||||||
|
|
||||||
#endif /* CONFIG_SMP */
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64 /* for now */
|
#ifdef CONFIG_PPC64 /* for now */
|
||||||
|
|
|
@ -430,7 +430,7 @@ void __init pmac_pic_init(void)
|
||||||
prom_get_irq_senses(senses, 0, 128);
|
prom_get_irq_senses(senses, 0, 128);
|
||||||
mpic1 = mpic_alloc(irqctrler->addrs[0].address,
|
mpic1 = mpic_alloc(irqctrler->addrs[0].address,
|
||||||
MPIC_PRIMARY | MPIC_WANTS_RESET,
|
MPIC_PRIMARY | MPIC_WANTS_RESET,
|
||||||
0, 0, 128, 256, senses, 128, " K2-MPIC ");
|
0, 0, 128, 252, senses, 128, " OpenPIC ");
|
||||||
BUG_ON(mpic1 == NULL);
|
BUG_ON(mpic1 == NULL);
|
||||||
mpic_init(mpic1);
|
mpic_init(mpic1);
|
||||||
|
|
||||||
|
@ -441,14 +441,15 @@ void __init pmac_pic_init(void)
|
||||||
irqctrler2->intrs[0].line);
|
irqctrler2->intrs[0].line);
|
||||||
|
|
||||||
pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
|
pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0);
|
||||||
prom_get_irq_senses(senses, 128, 128 + 128);
|
prom_get_irq_senses(senses, 128, 128 + 124);
|
||||||
|
|
||||||
/* We don't need to set MPIC_BROKEN_U3 here since we don't have
|
/* We don't need to set MPIC_BROKEN_U3 here since we don't have
|
||||||
* hypertransport interrupts routed to it
|
* hypertransport interrupts routed to it
|
||||||
*/
|
*/
|
||||||
mpic2 = mpic_alloc(irqctrler2->addrs[0].address,
|
mpic2 = mpic_alloc(irqctrler2->addrs[0].address,
|
||||||
MPIC_BIG_ENDIAN | MPIC_WANTS_RESET,
|
MPIC_BIG_ENDIAN | MPIC_WANTS_RESET,
|
||||||
0, 128, 128, 0, senses, 128, " U3-MPIC ");
|
0, 128, 124, 0, senses, 124,
|
||||||
|
" U3-MPIC ");
|
||||||
BUG_ON(mpic2 == NULL);
|
BUG_ON(mpic2 == NULL);
|
||||||
mpic_init(mpic2);
|
mpic_init(mpic2);
|
||||||
mpic_setup_cascade(irqctrler2->intrs[0].line,
|
mpic_setup_cascade(irqctrler2->intrs[0].line,
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/pmac_feature.h>
|
#include <asm/pmac_feature.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
#include <asm/open_pic.h>
|
#include <asm/mpic.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/keylargo.h>
|
#include <asm/keylargo.h>
|
||||||
|
|
||||||
|
@ -638,14 +638,14 @@ void smp_core99_message_pass(int target, int msg, unsigned long data, int wait)
|
||||||
}
|
}
|
||||||
switch (target) {
|
switch (target) {
|
||||||
case MSG_ALL:
|
case MSG_ALL:
|
||||||
mpic_send_ipi(msg, mask);
|
mpic_send_ipi(msg, cpus_addr(mask)[0]);
|
||||||
break;
|
break;
|
||||||
case MSG_ALL_BUT_SELF:
|
case MSG_ALL_BUT_SELF:
|
||||||
cpu_clear(smp_processor_id(), mask);
|
cpu_clear(smp_processor_id(), mask);
|
||||||
mpic_send_ipi(msg, mask);
|
mpic_send_ipi(msg, cpus_addr(mask)[0]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mpic_send_ipi(msg, cpumask_of_cpu(target));
|
mpic_send_ipi(msg, 1 << target);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -678,7 +678,7 @@ int __cpu_disable(void)
|
||||||
cpu_clear(smp_processor_id(), cpu_online_map);
|
cpu_clear(smp_processor_id(), cpu_online_map);
|
||||||
|
|
||||||
/* XXX reset cpu affinity here */
|
/* XXX reset cpu affinity here */
|
||||||
openpic_set_priority(0xf);
|
mpic_cpu_set_priority(0xf);
|
||||||
asm volatile("mtdec %0" : : "r" (0x7fffffff));
|
asm volatile("mtdec %0" : : "r" (0x7fffffff));
|
||||||
mb();
|
mb();
|
||||||
udelay(20);
|
udelay(20);
|
||||||
|
|
|
@ -44,6 +44,9 @@ static struct mpic *mpics;
|
||||||
static struct mpic *mpic_primary;
|
static struct mpic *mpic_primary;
|
||||||
static DEFINE_SPINLOCK(mpic_lock);
|
static DEFINE_SPINLOCK(mpic_lock);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC32 /* XXX for now */
|
||||||
|
#define distribute_irqs CONFIG_IRQ_ALL_CPUS
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register accessor functions
|
* Register accessor functions
|
||||||
|
|
Загрузка…
Ссылка в новой задаче