[PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset
Michael Ellerman
michael at ellerman.id.au
Fri Aug 26 12:53:31 EST 2005
Regardless of where the kernel's linked we always get interrupts at low
addresses. This patch creates a trampoline in the first 3 pages of memory,
where interrupts land, and patches those addresses to jump into the real
kernel code at KERNELBASE.
We also need to reserve the low pages of memory in prom.c, as well as
__pa(KERNELBASE) to __pa(klimit).
FIXME, 0x8000 should be a #define.
Signed-off-by: Michael Ellerman <michael at ellerman.id.au>
---
arch/ppc64/kernel/prom.c | 5 ++++-
arch/ppc64/kernel/setup.c | 22 ++++++++++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
Index: work/arch/ppc64/kernel/setup.c
===================================================================
--- work.orig/arch/ppc64/kernel/setup.c
+++ work/arch/ppc64/kernel/setup.c
@@ -362,6 +362,26 @@ static struct machdep_calls __initdata *
NULL
};
+#ifdef CONFIG_KDUMP_CAPTURE_KERNEL
+static void setup_kdump_trampoline(void)
+{
+ unsigned long i;
+ unsigned int *addr;
+
+ /* XXX this only works if PHYSICAL_START <= 32 MB */
+
+ for (i = 0x100; i < 0x3000; i += 8) {
+ addr = (unsigned int *)i;
+ *addr++ = 0x60000000; /* nop */
+ *addr = 0x48000000 | ((PHYSICAL_START - 1) & 0x03fffffc);
+
+ asm ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (addr));
+ }
+}
+#else
+static inline void setup_kdump_trampoline(void) { }
+#endif
+
/*
* Early initialization entry point. This is called by head.S
* with MMU translation disabled. We rely on the "feature" of
@@ -394,6 +414,8 @@ void __init early_setup(unsigned long dt
DBG(" -> early_setup()\n");
+ setup_kdump_trampoline();
+
/*
* Fill the default DBG level (do we want to keep
* that old mecanism around forever ?)
Index: work/arch/ppc64/kernel/prom.c
===================================================================
--- work.orig/arch/ppc64/kernel/prom.c
+++ work/arch/ppc64/kernel/prom.c
@@ -1241,7 +1241,10 @@ void __init early_init_devtree(void *par
lmb_enforce_memory_limit();
lmb_analyze();
systemcfg->physicalMemorySize = lmb_phys_mem_size();
- lmb_reserve(0, __pa(klimit));
+ lmb_reserve(__pa(KERNELBASE), __pa(klimit));
+#ifdef CONFIG_KDUMP_CAPTURE_KERNEL
+ lmb_reserve(0, 0x8000); /* Reserve the trampoline */
+#endif
DBG("Phys. mem: %lx\n", systemcfg->physicalMemorySize);
More information about the Linuxppc64-dev
mailing list