aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powermac
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2005-12-05 16:49:00 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 22:52:25 -0500
commit758438a7b8da593c9116e95cc7fdff6e9e0b0c40 (patch)
tree5343d8ec40016294902278c27a9f5647bd061890 /arch/powerpc/platforms/powermac
parent0cc4746cadda16826a1b3214c042a2f75445b71c (diff)
[PATCH] powerpc: Fixups for kernel linked at 32 MB
There's a few places where we need to fix things up for the kernel to work if it's linked at 32MB: - platforms/powermac/smp.c To start secondary cpus on pmac we patch the reset vector, which is fine. Except if we're above 32MB we don't have enough bits for an absolute branch, it needs to relative. - kernel/head_64.s - A few branches in the cpu hold code need to load the full target address and do a bctr. - after_prom_start needs to load PHYSICAL_START as the dest address, not 0. - The exception prolog needs to load the low word of the target adddress, not just the low halfword. - Fixup handling of the initial stab address. - kernel/setup_64.c smp_release_cpus() needs to write 1 to the spinloop flag near 0, not 32 MB. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/powermac')
-rw-r--r--arch/powerpc/platforms/powermac/smp.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index fb2a7c798e82..862f1e985c19 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -753,14 +753,15 @@ static int __init smp_core99_probe(void)
753static void __devinit smp_core99_kick_cpu(int nr) 753static void __devinit smp_core99_kick_cpu(int nr)
754{ 754{
755 unsigned int save_vector; 755 unsigned int save_vector;
756 unsigned long new_vector; 756 unsigned long target, flags;
757 unsigned long flags;
758 volatile unsigned int *vector 757 volatile unsigned int *vector
759 = ((volatile unsigned int *)(KERNELBASE+0x100)); 758 = ((volatile unsigned int *)(KERNELBASE+0x100));
760 759
761 if (nr < 0 || nr > 3) 760 if (nr < 0 || nr > 3)
762 return; 761 return;
763 if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); 762
763 if (ppc_md.progress)
764 ppc_md.progress("smp_core99_kick_cpu", 0x346);
764 765
765 local_irq_save(flags); 766 local_irq_save(flags);
766 local_irq_disable(); 767 local_irq_disable();
@@ -768,14 +769,11 @@ static void __devinit smp_core99_kick_cpu(int nr)
768 /* Save reset vector */ 769 /* Save reset vector */
769 save_vector = *vector; 770 save_vector = *vector;
770 771
771 /* Setup fake reset vector that does 772 /* Setup fake reset vector that does
772 * b __secondary_start_pmac_0 + nr*8 - KERNELBASE 773 * b __secondary_start_pmac_0 + nr*8 - KERNELBASE
773 */ 774 */
774 new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8; 775 target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
775 *vector = 0x48000002 + new_vector - KERNELBASE; 776 create_branch((unsigned long)vector, target, BRANCH_SET_LINK);
776
777 /* flush data cache and inval instruction cache */
778 flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
779 777
780 /* Put some life in our friend */ 778 /* Put some life in our friend */
781 pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); 779 pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);