powerpc: enable relocatable support for 6xx
cover powerpc: enable relocatable support for 6xx
This patch series enables the relocatable support for 6xx boards. With these patches:
* the kernel can boot from any address between 0x10000 ~ 0x2000000
* kdump is workable
* a single kernel image can be used as boot or kdump kernel
Boot test on a mpc8260 board. Also passed the build test for the following configurations:
ppc40x_defconfig
ppc64e_defconfig
ppc64_defconfig
corenet32_smp_defconfig
corenet64_smp_defconfig
ppc44x_defconfig
pmac32_defconfig
pq2fads_defconfig
mpc5200_defconfig
pseries_defconfig---
Kevin Hao (4):
powerpc: enable relocatable support for 6xx
powerpc: move the exception trampoline helper functions to a separate
file
powerpc: s/kdump/exception/ for the exception trampoline functions
powerpc: make the kernel bootable from non 0 address for 6xx
arch/powerpc/Kconfig | 4 +- arch/powerpc/include/asm/exception_trampoline.h | 35 ++++++++ arch/powerpc/include/asm/kdump.h | 32 -------- arch/powerpc/include/asm/page.h | 2 +- arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/crash_dump.c | 41 ---------- arch/powerpc/kernel/exception_trampoline.c | 82 +++++++++++++++++++ arch/powerpc/kernel/head_32.S | 103 ++++++++++++++++++++++++ arch/powerpc/kernel/prom.c | 4 +- arch/powerpc/kernel/prom_init_check.sh | 2 +- arch/powerpc/kernel/setup_32.c | 3 +- arch/powerpc/kernel/setup_64.c | 4 +- arch/powerpc/mm/ppc_mmu_32.c | 7 +- 13 files changed, 232 insertions(+), 88 deletions(-) create mode 100644 arch/powerpc/include/asm/exception_trampoline.h create mode 100644 arch/powerpc/kernel/exception_trampoline.c
Signature · 5 lines
1.8.1.4 Thanks, Kevin
PATCH 1/4 powerpc: enable relocatable support for 6xx
This is based on the codes in head_44x.S. With this patch the kernel can only boot from 0 with CONFIG_RELOCATABLE enabled. We will add the support to boot from a non 0 address in the following patches.
--- arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/page.h | 2 +- arch/powerpc/kernel/head_32.S | 103 +++++++++++++++++++++++++++++++++ arch/powerpc/kernel/prom_init_check.sh | 2 +- 4 files changed, 106 insertions(+), 3 deletions(-)
arch/powerpc/Kconfig +1 -1
@@ -866,7 +866,7 @@ config DYNAMIC_MEMSTART config RELOCATABLE bool "Build a relocatable kernel" - depends on ADVANCED_OPTIONS && FLATMEM && 44x + depends on ADVANCED_OPTIONS && FLATMEM && (44x || 6xx) select NONSTATIC_KERNEL help This builds a kernel image that is capable of running at the
arch/powerpc/include/asm/page.h +1 -1
@@ -207,7 +207,7 @@ extern long long virt_phys_offset;* On non-Book-E PPC64 PAGE_OFFSET and MEMORY_START are constants so use * the other definitions for __va & __pa. */ -#ifdef CONFIG_BOOKE +#if defined(CONFIG_BOOKE ) || defined(CONFIG_6xx)#define __va (x) ((void *)(unsigned long)((phys_addr_t)(x) + VIRT_PHYS_OFFSET))#define __pa (x) ((unsigned long)(x) - VIRT_PHYS_OFFSET)#else
arch/powerpc/kernel/head_32.S +103 -0
133 lines not on this page · raw message
arch/powerpc/kernel/prom_init_check.sh +1 -1
@@ -22,7 +22,7 @@ __secondary_hold_acknowledge __secondary_hold_spinloop __start strcmp strcpy strlcpy strlen strncmp strstr logo_linux_clut224 reloc_got2 kernstart_addr memstart_addr linux_banner _stext opal_query_takeover opal_do_takeover opal_enter_rtas opal_secondary_entry -boot_command_line __prom_init_toc_start __prom_init_toc_end" +boot_command_line __prom_init_toc_start __prom_init_toc_end virt_phys_offset" NM="$1" OBJ="$2"
Signature · 1 line
1.8.1.4
PATCH 2/4 powerpc: move the exception trampoline helper functions to a separate file
In reply to Kevin HaoFor some platform such as 6xx we need to setup the exception trampoline for a relocatable kernel even through the CONFIG_CRASH_DUMP is disabled. So move these functions to a separate file so they can be used by non dump kernel. This patch doesn't introduce any function change.
--- arch/powerpc/include/asm/exception_trampoline.h | 35 +++++++++++++ arch/powerpc/include/asm/kdump.h | 32 ----------- arch/powerpc/kernel/Makefile | 2 +- arch/powerpc/kernel/crash_dump.c | 41 --------------- arch/powerpc/kernel/exception_trampoline.c | 70 +++++++++++++++++++++++++ arch/powerpc/kernel/prom.c | 2 +- arch/powerpc/kernel/setup_32.c | 1 + arch/powerpc/kernel/setup_64.c | 2 +- 8 files changed, 109 insertions(+), 76 deletions(-) create mode 100644 arch/powerpc/include/asm/exception_trampoline.h create mode 100644 arch/powerpc/kernel/exception_trampoline.c
arch/powerpc/include/asm/exception_trampoline.h new file +35 -0
@@ -0,0 +1,35 @@ +#ifndef _EXCEPTION_TRAMPOLINE_H +#define _EXCEPTION_TRAMPOLINE_H + +/* How many bytes to reserve at zero for kdump. The reserve limit should +* be greater or equal to the trampoline's end address. +* Reserve to the end of the FWNMI area, see head_64.S */ +#define KDUMP_RESERVE_LIMIT 0x10000/* 64K */ + +/* +* On PPC64 translation is disabled during trampoline setup, so we use +* physical addresses. Though on PPC32 translation is already enabled, +* so we can't do the same. Luckily create_trampoline() creates relative +* branches, so we can just add the PAGE_OFFSET and don't worry about it. +*/ +#ifdef __powerpc64__ +#define KDUMP_TRAMPOLINE_START 0x0100 +#define KDUMP_TRAMPOLINE_END 0x3000 +#else +#define KDUMP_TRAMPOLINE_START (0x0100 + PAGE_OFFSET) +#define KDUMP_TRAMPOLINE_END (0x3000 + PAGE_OFFSET) +#endif /* __powerpc64__ */ + +#ifndef __ASSEMBLY__ + +#if defined(CONFIG_CRASH_DUMP ) && !defined(CONFIG_NONSTATIC_KERNEL ) +extern void reserve_kdump_trampoline (void ); +extern void setup_kdump_trampoline (void ); +#else +/* !CRASH_DUMP || !NONSTATIC_KERNEL */ +static inline void reserve_kdump_trampoline (void ) { ; } +static inline void setup_kdump_trampoline (void ) { ; } +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* _EXCEPTION_TRAMPOLINE_H */
arch/powerpc/include/asm/kdump.h +0 -32
@@ -5,42 +5,10 @@#define KDUMP_KERNELBASE 0x2000000 -/* How many bytes to reserve at zero for kdump. The reserve limit should -* be greater or equal to the trampoline's end address. -* Reserve to the end of the FWNMI area, see head_64.S */ -#define KDUMP_RESERVE_LIMIT 0x10000/* 64K */ -#ifdef CONFIG_CRASH_DUMP -/* -* On PPC64 translation is disabled during trampoline setup, so we use -* physical addresses. Though on PPC32 translation is already enabled, -* so we can't do the same. Luckily create_trampoline() creates relative -* branches, so we can just add the PAGE_OFFSET and don't worry about it. -*/ -#ifdef __powerpc64__ -#define KDUMP_TRAMPOLINE_START 0x0100 -#define KDUMP_TRAMPOLINE_END 0x3000 -#else -#define KDUMP_TRAMPOLINE_START (0x0100 + PAGE_OFFSET) -#define KDUMP_TRAMPOLINE_END (0x3000 + PAGE_OFFSET) -#endif /* __powerpc64__ */ -#define KDUMP_MIN_TCE_ENTRIES 2048#endif /* CONFIG_CRASH_DUMP */ -#ifndef __ASSEMBLY__ - -#if defined(CONFIG_CRASH_DUMP ) && !defined(CONFIG_NONSTATIC_KERNEL ) -extern void reserve_kdump_trampoline (void ); -extern void setup_kdump_trampoline (void ); -#else -/* !CRASH_DUMP || !NONSTATIC_KERNEL */ -static inline void reserve_kdump_trampoline (void ) { ; } -static inline void setup_kdump_trampoline (void ) { ; } -#endif - -#endif /* __ASSEMBLY__ */ -#endif /* __PPC64_KDUMP_H */
arch/powerpc/kernel/Makefile +1 -1
@@ -59,7 +59,7 @@ obj-$(CONFIG_LPARCFG) += lparcfg.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_IBMEBUS) += ibmebus.o obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o -obj-$(CONFIG_CRASH_DUMP) += crash_dump.o +obj-$(CONFIG_CRASH_DUMP) += crash_dump.o exception_trampoline.o obj-$(CONFIG_FA_DUMP) += fadump.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_E500) += idle_e500.o
arch/powerpc/kernel/crash_dump.c +0 -41
47 lines not on this page · raw message
arch/powerpc/kernel/exception_trampoline.c new file +70 -0
70 lines not on this page · raw message
arch/powerpc/kernel/prom.c +1 -1
@@ -40,7 +40,7 @@#include <asm/processor.h> #include <asm/irq.h> #include <asm/io.h> -#include <asm/kdump.h> +#include <asm/exception_trampoline.h> #include <asm/smp.h> #include <asm/mmu.h> #include <asm/paca.h>
arch/powerpc/kernel/setup_32.c +1 -0
@@ -38,6 +38,7 @@#include <asm/serial.h> #include <asm/udbg.h> #include <asm/mmu_context.h> +#include <asm/exception_trampoline.h> #include "setup.h"
arch/powerpc/kernel/setup_64.c +1 -1
@@ -38,7 +38,7 @@#include <linux/hugetlb.h> #include <asm/io.h> -#include <asm/kdump.h> +#include <asm/exception_trampoline.h> #include <asm/prom.h> #include <asm/processor.h> #include <asm/pgtable.h>
Signature · 1 line
1.8.1.4
PATCH 3/4 powerpc: s/kdump/exception/ for the exception trampoline functions
In reply to Kevin HaoThese functions are not just kdump specific. Replace the 'kdump' with the 'exception' to make them more general.
--- arch/powerpc/include/asm/exception_trampoline.h | 20 ++++++++++---------- arch/powerpc/kernel/exception_trampoline.c | 14 +++++++------- arch/powerpc/kernel/prom.c | 2 +- arch/powerpc/kernel/setup_32.c | 2 +- arch/powerpc/kernel/setup_64.c | 2 +- 5 files changed, 20 insertions(+), 20 deletions(-)
arch/powerpc/include/asm/exception_trampoline.h +10 -10
@@ -1,10 +1,10 @@#ifndef _EXCEPTION_TRAMPOLINE_H#define _EXCEPTION_TRAMPOLINE_H -/* How many bytes to reserve at zero for kdump. The reserve limit should +/* How many bytes to reserve at zero for exception. The reserve limit should * be greater or equal to the trampoline's end address. * Reserve to the end of the FWNMI area, see head_64.S */ -#define KDUMP_RESERVE_LIMIT 0x10000/* 64K */ +#define EXCEPTION_RESERVE_LIMIT 0x10000/* 64K */ /* * On PPC64 translation is disabled during trampoline setup, so we use
@@ -13,22 +13,22 @@* branches, so we can just add the PAGE_OFFSET and don't worry about it. */ #ifdef __powerpc64__ -#define KDUMP_TRAMPOLINE_START 0x0100 -#define KDUMP_TRAMPOLINE_END 0x3000 +#define EXCEPTION_TRAMPOLINE_START 0x0100 +#define EXCEPTION_TRAMPOLINE_END 0x3000#else -#define KDUMP_TRAMPOLINE_START (0x0100 + PAGE_OFFSET) -#define KDUMP_TRAMPOLINE_END (0x3000 + PAGE_OFFSET) +#define EXCEPTION_TRAMPOLINE_START (0x0100 + PAGE_OFFSET) +#define EXCEPTION_TRAMPOLINE_END (0x3000 + PAGE_OFFSET)#endif /* __powerpc64__ */ #ifndef __ASSEMBLY__#if defined(CONFIG_CRASH_DUMP ) && !defined(CONFIG_NONSTATIC_KERNEL ) -extern void reserve_kdump_trampoline (void ); -extern void setup_kdump_trampoline (void ); +extern void reserve_exception_trampoline (void ); +extern void setup_exception_trampoline (void );#else /* !CRASH_DUMP || !NONSTATIC_KERNEL */ -static inline void reserve_kdump_trampoline (void ) { ; } -static inline void setup_kdump_trampoline (void ) { ; } +static inline void reserve_exception_trampoline (void ) { ; } +static inline void setup_exception_trampoline (void ) { ; }#endif #endif /* __ASSEMBLY__ */
arch/powerpc/kernel/exception_trampoline.c +7 -7
@@ -15,7 +15,7 @@#include <linux/bootmem.h> #include <linux/memblock.h> #include <asm/code-patching.h> -#include <asm/kdump.h> +#include <asm/exception_trampoline.h> #include <asm/prom.h> #include <asm/firmware.h> #include <asm/uaccess.h>
@@ -29,9 +29,9 @@#endif #ifndef CONFIG_NONSTATIC_KERNEL -void __init reserve_kdump_trampoline (void ) +void __init reserve_exception_trampoline (void ) { -memblock_reserve (0 ,KDUMP_RESERVE_LIMIT ); +memblock_reserve (0 ,EXCEPTION_RESERVE_LIMIT ); }static void __init create_trampoline (unsigned long addr)
@@ -50,13 +50,13 @@ static void __init create_trampoline(unsigned long addr)patch_branch (++p, addr +PHYSICAL_START ,0 ); } -void __init setup_kdump_trampoline (void ) +void __init setup_exception_trampoline (void ) {unsigned long i; -DBG (" -> setup_kdump_trampoline()\n" ); +DBG (" -> setup_exception_trampoline()\n" ); -for (i =KDUMP_TRAMPOLINE_START ; i <KDUMP_TRAMPOLINE_END ; i +=8 ) { +for (i =EXCEPTION_TRAMPOLINE_START ; i <EXCEPTION_TRAMPOLINE_END ; i +=8 ) {create_trampoline (i); }
@@ -65,6 +65,6 @@ void __init setup_kdump_trampoline(void)create_trampoline (__pa (machine_check_fwnmi) -PHYSICAL_START );#endif /* CONFIG_PPC_PSERIES */ - DBG(" <- setup_kdump_trampoline()\n"); + DBG(" <- setup_exception_trampoline()\n"); }#endif /* CONFIG_NONSTATIC_KERNEL */
arch/powerpc/kernel/prom.c +1 -1
@@ -669,7 +669,7 @@ void __init early_init_devtree(void *params)/* If relocatable, reserve first 32k for interrupt vectors etc. */ if (PHYSICAL_START >MEMORY_START )memblock_reserve (MEMORY_START ,0x8000 ); -reserve_kdump_trampoline (); +reserve_exception_trampoline ();#ifdef CONFIG_FA_DUMP /* * If we fail to reserve memory for firmware-assisted dump then
arch/powerpc/kernel/setup_32.c +1 -1
@@ -133,7 +133,7 @@ notrace void __init machine_init(u64 dt_ptr)probe_machine (); -setup_kdump_trampoline (); +setup_exception_trampoline ();#ifdef CONFIG_6xx if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
arch/powerpc/kernel/setup_64.c +1 -1
@@ -222,7 +222,7 @@ void __init early_setup(unsigned long dt_ptr)/* Probe the machine type */ probe_machine (); -setup_kdump_trampoline (); +setup_exception_trampoline ();DBG ("Found, Initializing memory management...\n" );
Signature · 1 line
1.8.1.4
PATCH 4/4 powerpc: make the kernel bootable from non 0 address for 6xx
In reply to Kevin HaoAdd the support to boot the kernel from a non 0 address for 6xx. Setup the exception trampoline if the physical start address is not 0.
For a kdump kernel, enable the relocatable support implicitly. Since the memstart_adddr of the kdump is not 0, we definitely should regard this when setting up the BAT map.
--- arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/exception_trampoline.h | 4 ++-- arch/powerpc/kernel/Makefile | 3 ++- arch/powerpc/kernel/exception_trampoline.c | 18 +++++++++++++++--- arch/powerpc/mm/ppc_mmu_32.c | 7 +------ 5 files changed, 21 insertions(+), 13 deletions(-)
arch/powerpc/Kconfig +1 -1
@@ -382,7 +382,7 @@ config KEXEC config CRASH_DUMP bool "Build a kdump crash kernel" depends on PPC64 || 6xx || FSL_BOOKE || (44x && !SMP) - select RELOCATABLE if PPC64 || 44x + select RELOCATABLE if PPC64 || 44x || 6xx select DYNAMIC_MEMSTART if FSL_BOOKE help Build a kernel suitable for use as a kdump capture kernel.
arch/powerpc/include/asm/exception_trampoline.h +2 -2
@@ -22,11 +22,11 @@#ifndef __ASSEMBLY__ -#if defined(CONFIG_CRASH_DUMP ) && !defined(CONFIG_NONSTATIC_KERNEL ) +#if defined(CONFIG_RELOCATABLE ) && defined(CONFIG_6xx)extern void reserve_exception_trampoline (void );extern void setup_exception_trampoline (void );#else -/* !CRASH_DUMP || !NONSTATIC_KERNEL */ +/* !CONFIG_RELOCATABLE || !CONFIG_6xx */ static inline void reserve_exception_trampoline (void ) { ; }static inline void setup_exception_trampoline (void ) { ; }#endif
arch/powerpc/kernel/Makefile +2 -1
@@ -59,7 +59,8 @@ obj-$(CONFIG_LPARCFG) += lparcfg.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_IBMEBUS) += ibmebus.o obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o -obj-$(CONFIG_CRASH_DUMP) += crash_dump.o exception_trampoline.o +obj-$(CONFIG_CRASH_DUMP) += crash_dump.o +obj-$(CONFIG_RELOCATABLE) += exception_trampoline.o obj-$(CONFIG_FA_DUMP) += fadump.o ifeq ($(CONFIG_PPC32),y) obj-$(CONFIG_E500) += idle_e500.o
arch/powerpc/kernel/exception_trampoline.c +15 -3
@@ -28,10 +28,16 @@ #define DBG(fmt...)#endif -#ifndef CONFIG_NONSTATIC_KERNEL +#ifdef CONFIG_6xxvoid __init reserve_exception_trampoline (void ) { -memblock_reserve (0 ,EXCEPTION_RESERVE_LIMIT ); +/* +* We don't need to reserve this memory region for a kdump kernel +* since this is not included in the memory regions of kdump kernel. +*/ + +if (!memstart_addr &&PHYSICAL_START ) +memblock_reserve (0 ,EXCEPTION_RESERVE_LIMIT ); }static void __init create_trampoline (unsigned long addr)
@@ -54,6 +60,12 @@ void __init setup_exception_trampoline(void) {unsigned long i; +if (!PHYSICAL_START ) +return ; + +if (PHYSICAL_START >0x2000000 ) +panic ("Don't support to load a kernel above 32M address" ); +DBG (" -> setup_exception_trampoline()\n" );for (i =EXCEPTION_TRAMPOLINE_START ; i <EXCEPTION_TRAMPOLINE_END ; i +=8 ) {
@@ -67,4 +79,4 @@ void __init setup_exception_trampoline(void) DBG(" <- setup_exception_trampoline()\n"); } -#endif /* CONFIG_NONSTATIC_KERNEL */ +#endif /* CONFIG_6xx */
arch/powerpc/mm/ppc_mmu_32.c +1 -6
@@ -86,7 +86,7 @@ unsigned long __init mmu_mapin_ram(unsigned long top)/* Make sure we don't map a block larger than the smallest alignment of the physical address. */ - tot = top; + tot = top + memstart_addr;for (bl =128 <<10 ; bl < max_size; bl <<=1 ) {if (bl *2 > tot)break ;
@@ -275,11 +275,6 @@ void __init MMU_init_hw(void)void setup_initial_memory_limit (phys_addr_t first_memblock_base,phys_addr_t first_memblock_size) { -/* We don't currently support the first MEMBLOCK not mapping 0 -* physical on those processors -*/ -BUG_ON (first_memblock_base !=0 ); -/* 601 can only access 16MB at the moment */ if (PVR_VER (mfspr (SPRN_PVR )) ==1 )memblock_set_current_limit (min_t (u64, first_memblock_size,0x01000000 ));
Signature · 1 line
1.8.1.4