summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/setup_64.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2008-08-30 11:40:24 +1000
committerPaul Mackerras <paulus@samba.org>2008-09-15 11:08:08 -0700
commit1f6a93e4c35e75d547b51f56ba8139ab1a91628c (patch)
treec755528c7f299fa407b3eda77a3e08af78b0b25c /arch/powerpc/kernel/setup_64.c
parent9a95516740c924675d52c472d7d170c62eab176c (diff)
downloadtalos-op-linux-1f6a93e4c35e75d547b51f56ba8139ab1a91628c.tar.gz
talos-op-linux-1f6a93e4c35e75d547b51f56ba8139ab1a91628c.zip
powerpc: Make it possible to move the interrupt handlers away from the kernel
This changes the way that the exception prologs transfer control to the handlers in 64-bit kernels with the aim of making it possible to have the prologs separate from the main body of the kernel. Now, instead of computing the address of the handler by taking the top 32 bits of the paca address (to get the 0xc0000000........ part) and ORing in something in the bottom 16 bits, we get the base address of the kernel by doing a load from the paca and add an offset. This also replaces an mfmsr and an ori to compute the MSR value for the handler with a load from the paca. That makes it unnecessary to have a separate version of EXCEPTION_PROLOG_PSERIES that forces 64-bit mode. We can no longer use a direct branches in the exception prolog code, which means that the SLB miss handlers can't branch directly to .slb_miss_realmode any more. Instead we have to compute the address and do an indirect branch. This is conditional on CONFIG_RELOCATABLE; for non-relocatable kernels we use a direct branch as before. (A later change will allow CONFIG_RELOCATABLE to be set on 64-bit powerpc.) Since the secondary CPUs on pSeries start execution in the first 0x100 bytes of real memory and then have to get to wherever the kernel is, we can't use a direct branch to get there. Instead this changes __secondary_hold_spinloop from a flag to a function pointer. When it is set to a non-NULL value, the secondary CPUs jump to the function pointed to by that value. Finally this eliminates one code difference between 32-bit and 64-bit by making __secondary_hold be the text address of the secondary CPU spinloop rather than a function descriptor for it. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/setup_64.c')
-rw-r--r--arch/powerpc/kernel/setup_64.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 8b25f51f03bf..843c0af210d0 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -255,9 +255,11 @@ void early_setup_secondary(void)
#endif /* CONFIG_SMP */
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
+extern unsigned long __secondary_hold_spinloop;
+extern void generic_secondary_smp_init(void);
+
void smp_release_cpus(void)
{
- extern unsigned long __secondary_hold_spinloop;
unsigned long *ptr;
DBG(" -> smp_release_cpus()\n");
@@ -266,12 +268,11 @@ void smp_release_cpus(void)
* all now so they can start to spin on their individual paca
* spinloops. For non SMP kernels, the secondary cpus never get out
* of the common spinloop.
- * This is useless but harmless on iSeries, secondaries are already
- * waiting on their paca spinloops. */
+ */
ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop
- PHYSICAL_START);
- *ptr = 1;
+ *ptr = __pa(generic_secondary_smp_init);
mb();
DBG(" <- smp_release_cpus()\n");
OpenPOWER on IntegriCloud