[PATCH 10/12] ppc64: Reroute interrupts from zero + offset to KERNELBASE + offset

Milton D. Miller II miltonm at realtime.net
Tue Aug 30 15:41:20 EST 2005


> From michael at ellerman.id.au  Fri Aug 26 12:53:31 2005
> From: michael at ellerman.id.au (Michael Ellerman)
> Date: Fri Aug 26 12:53:42 2005
> Subject: [PATCH 10/12] ppc64: Reroute interrupts from zero + offset to
> 	KERNELBASE + offset
> In-Reply-To: <1125024799.128302.675577398916.qpatch at concordia>
>
> 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.


Actually we should reserve 0 to __pa(KERNELBASE) for testing kdump
environment...

Do we work if the reserve of low memory is not part of the mem= ?
In kdump, this memory will not be part of the "mem=" line passed to
the capture kernel.

Why is it 0x8000 for the reserve and 0x3000 for the trampoline?
Do we know what we expect the trampoline will save?

page 9  is the initial stab (for RS64 and POWER3), or are you using
the new rearranged low memory patch?



>
> 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 */

how about an #error ?

> +
> +	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));

every 8 bytes is a bit overkill, but ok.   The -1 should be -4, its the
instruction target..  

Others have commented on the comments for the patching.   The
trick of doing a nop to extend the range to 32k should be
explicitly stated.


Another approach is to copy pages 0-3 down to pages 0-3 and execute the
copy there.  It does mean that we can't use relative branchs from there
to the "main" kernel.

> +	}
> +}
> +#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);
>  
>

milton



More information about the Linuxppc64-dev mailing list