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

will schmidt will_schmidt at vnet.ibm.com
Fri Aug 26 23:53:59 EST 2005


Hi Michael,
      first question is inline, the other question..  when the 
KDUMP_CAPTURE_KERNEL is configured, is it only mapped into memory ahead 
of time, or would functions like this one (setup_kdump_trampoline) be 
run during normal system start?


Michael Ellerman wrote:
> 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));
> +	}


So here we're replacing the exception code in the first kernel, with 
pointers to the exception code in the second, right?  once this runs we 
end up with code something like...

c0000000 00000100:	60 00 00 00   nop
c0000000 00000108:      48 00 xx xx   b  (PHYSICAL_START -1)
c0000000 00000110:	60 00 00 00   nop
c0000000 00000118:      48 00 xx xx   b  (PHYSICAL_START -1)
c0000000 00000120:	60 00 00 00   nop
c0000000 00000128:      48 00 xx xx   b  (PHYSICAL_START -1)
...

Is this the intent, or should there be a +i somewhere in the branch 
instruction too?


> +}
> +#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);
> 
> _______________________________________________
> Linuxppc64-dev mailing list
> Linuxppc64-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc64-dev




More information about the Linuxppc64-dev mailing list