[PATCH] arch/powerpc: dtc is required to build dtb files
Fixes this following: $ make distclean; make corenet32_smp_defconfig; make p4080ds.dtb CLEAN arch/powerpc/boot CLEAN scripts/basic CLEAN scripts/dtc CLEAN scripts/genksyms CLEAN scripts/kconfig CLEAN scripts/mod CLEAN scripts CLEAN include/config include/generated CLEAN .config HOSTCC scripts/basic/fixdep HOSTCC scripts/kconfig/conf.o SHIPPED scripts/kconfig/zconf.tab.c SHIPPED scripts/kconfig/zconf.lex.c SHIPPED scripts/kconfig/zconf.hash.c HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/conf scripts/kconfig/conf --silentoldconfig Kconfig DTC arch/powerpc/boot/p4080ds.dtb /bin/sh: /local/home/mattsm/git/linux/scripts/dtc/dtc: No such file or directory make[1]: *** [arch/powerpc/boot/p4080ds.dtb] Error 1 make: *** [p4080ds.dtb] Error 2 Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/Makefile |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 159e94f..b639852 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -181,7 +181,7 @@ $(BOOT_TARGETS2): vmlinux bootwrapper_install: $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) -%.dtb: +%.dtb: scripts $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) define archhelp -- 1.7.9.7 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Fix build dependencies for c files requiring libfdt.h
Several files in obj-plat depend on libfdt header file. Sometimes when building one can see the following issue. This patch adds libfdt as dependency to those object files | In file included from arch/powerpc/boot/treeboot-iss4xx.c:33:0: | arch/powerpc/boot/libfdt.h:854:1: error: unterminated comment | In file included from arch/powerpc/boot/treeboot-iss4xx.c:33:0: | arch/powerpc/boot/libfdt.h:1:0: error: unterminated #ifndef | BOOTCC arch/powerpc/boot/inffast.o | make[1]: *** [arch/powerpc/boot/treeboot-iss4xx.o] Error 1 | make[1]: *** Waiting for unfinished jobs | BOOTCC arch/powerpc/boot/inflate.o | make: *** [uImage] Error 2 | ERROR: oe_runmake failed | ERROR: Function failed: do_compile (see /srv/home/pokybuild/yocto-autobuilder/yocto-slave/p1022ds/build/build/tmp/work/p1022ds-poky-linux-gnuspe/linux-qoriq-sdk-3.0.34-r5/temp/log.do_compile.2167 for further information) NOTE: recipe linux-qoriq-sdk-3.0.34-r5: task do_compile: Failed Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/boot/Makefile |1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index b7d8333..6a15c96 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -107,6 +107,7 @@ src-boot := $(addprefix $(obj)/, $(src-boot)) obj-boot := $(addsuffix .o, $(basename $(src-boot))) obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat +obj-plat: $(libfdt) quiet_cmd_copy_zlib = COPY$@ cmd_copy_zlib = sed s@__used@@;s@linux/\([^]*\).*@\\1\@ $ $@ -- 1.7.9.7 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/hugepage: Fix missing header file for parse_args
This seems to fix the following issue: arch/powerpc/mm/hugetlbpage.c: In function 'reserve_hugetlb_gpages': arch/powerpc/mm/hugetlbpage.c:313: error: passing argument 5 of 'parse_args' makes integer from pointer without a cast include/linux/moduleparam.h:317: note: expected 's16' but argument is of type 'int (*)(char *, char *)' arch/powerpc/mm/hugetlbpage.c:313: error: too few arguments to function 'parse_args' Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/mm/hugetlbpage.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 79c575d..a8b3cc7 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -15,6 +15,7 @@ #include linux/of_fdt.h #include linux/memblock.h #include linux/bootmem.h +#include linux/moduleparam.h #include asm/pgtable.h #include asm/pgalloc.h #include asm/tlb.h -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/mm: Fix parse_arg build error
This fixes this build issue: arch/powerpc/mm/hugetlbpage.c: In function 'reserve_hugetlb_gpages': arch/powerpc/mm/hugetlbpage.c:312:2: error: implicit declaration of function 'parse_args' make[1]: *** [arch/powerpc/mm/hugetlbpage.o] Error 1 Signed-off-by: Matthew McClintock m...@freescale.com --- This is for benh next tree arch/powerpc/mm/hugetlbpage.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 79c575d..a8b3cc7 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -15,6 +15,7 @@ #include linux/of_fdt.h #include linux/memblock.h #include linux/bootmem.h +#include linux/moduleparam.h #include asm/pgtable.h #include asm/pgalloc.h #include asm/tlb.h -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2] powerpc/setup_{32, 64}.c: remove unneeded boot_cpuid{, _phys}
boot_cpuid and init_thread_info.cpu are redundant, just use the var that stays around longer and add a define to make boot_cpuid point at the correct value boot_cpudid_phys is not needed and can completly go away from the SMP case, we leave it there for the non-SMP case since the paca struct is not around to store this info This patch also has the effect of having the logical cpu number of the boot cpu be updated correctly independently of the ordering of the cpu nodes in the device tree. Signed-off-by: Matthew McClintock m...@freescale.com --- v2: Fix compile issue for peries Remove '-1' initial value arch/powerpc/include/asm/smp.h |2 +- arch/powerpc/kernel/setup_32.c |5 +++-- arch/powerpc/kernel/setup_64.c |1 - arch/powerpc/sysdev/xics/xics-common.c |1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index adba970..f26c554 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -29,7 +29,7 @@ #endif #include asm/percpu.h -extern int boot_cpuid; +#define boot_cpuid (init_thread_info.cpu) extern int spinning_secondaries; extern void cpu_die(void); diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index ac76108..8d4df4c 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -46,10 +46,11 @@ extern void bootx_init(unsigned long r4, unsigned long phys); -int boot_cpuid = -1; -EXPORT_SYMBOL_GPL(boot_cpuid); +/* we need a place to store phys cpu for non-SMP case */ +#ifndef CONFIG_SMP int boot_cpuid_phys; EXPORT_SYMBOL_GPL(boot_cpuid_phys); +#endif int smp_hw_index[NR_CPUS]; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index fb9bb46..6d0f00f 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -73,7 +73,6 @@ #define DBG(fmt...) #endif -int boot_cpuid = 0; int __initdata spinning_secondaries; u64 ppc64_pft_size; diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c index d72eda6..8998b7a 100644 --- a/arch/powerpc/sysdev/xics/xics-common.c +++ b/arch/powerpc/sysdev/xics/xics-common.c @@ -20,6 +20,7 @@ #include linux/of.h #include linux/slab.h #include linux/spinlock.h +#include linux/sched.h #include asm/prom.h #include asm/io.h -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/5] powerpc/85xx: issue 15 EOI after core reset for FSL CoreNet devices
This is listed as a requirement for Freescale CoreNet based devices (e.g p4080ds with MPIC v4.x) after issuing a core reset to properly clear pending interrupts. Signed-off-by: Matthew McClintock m...@freescale.com --- v2: Updated commit message arch/powerpc/sysdev/mpic.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9678081..f5b83f0 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1748,6 +1748,7 @@ void mpic_reset_core(int cpu) struct mpic *mpic = mpic_primary; u32 pir; int cpuid = get_hard_smp_processor_id(cpu); + int i; /* Set target bit for core reset */ pir = mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); @@ -1759,6 +1760,12 @@ void mpic_reset_core(int cpu) pir = ~(1 cpuid); mpic_write(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); + + /* Perform 15 EOI on each reset core to clear pending interrupts */ + for (i = 0; i 15; i++) { + _mpic_write(mpic-reg_type, mpic-cpuregs[cpuid], + MPIC_CPU_EOI, 0); + } } #endif /* CONFIG_SMP */ -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 1/5] powerpc/85xx: issue 15 EOI after core reset for FSL CoreNet devices
This is listed as a requirement for Freescale CoreNet based devices (e.g p4080ds with MPIC v4.x) after issuing a core reset to properly clear pending interrupts. Signed-off-by: Matthew McClintock m...@freescale.com --- v2: Updated commit message v3: Added detail in code comment as well arch/powerpc/sysdev/mpic.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9678081..d641481 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1748,6 +1748,7 @@ void mpic_reset_core(int cpu) struct mpic *mpic = mpic_primary; u32 pir; int cpuid = get_hard_smp_processor_id(cpu); + int i; /* Set target bit for core reset */ pir = mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); @@ -1759,6 +1760,13 @@ void mpic_reset_core(int cpu) pir = ~(1 cpuid); mpic_write(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); + + /* Perform 15 EOI on each reset core to clear pending interrupts. +* This is required for FSL CoreNet based devices */ + for (i = 0; i 15; i++) { + _mpic_write(mpic-reg_type, mpic-cpuregs[cpuid], + MPIC_CPU_EOI, 0); + } } #endif /* CONFIG_SMP */ -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v4 1/5] powerpc/85xx: issue 15 EOI after core reset for FSL CoreNet devices
This is listed as a requirement for Freescale CoreNet based devices (e.g p4080ds with MPIC v4.x) after issuing a core reset to properly clear pending interrupts. Signed-off-by: Matthew McClintock m...@freescale.com --- v2: Updated commit message v3: Added detail in code comment as well v4: Check for MPIC_FSL in mpic-flags to determine if we need 15 EOIs arch/powerpc/sysdev/mpic.c | 10 ++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9678081..0842c6f 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1748,6 +1748,7 @@ void mpic_reset_core(int cpu) struct mpic *mpic = mpic_primary; u32 pir; int cpuid = get_hard_smp_processor_id(cpu); + int i; /* Set target bit for core reset */ pir = mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); @@ -1759,6 +1760,15 @@ void mpic_reset_core(int cpu) pir = ~(1 cpuid); mpic_write(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); + + /* Perform 15 EOI on each reset core to clear pending interrupts. +* This is required for FSL CoreNet based devices */ + if (mpic-flags MPIC_FSL) { + for (i = 0; i 15; i++) { + _mpic_write(mpic-reg_type, mpic-cpuregs[cpuid], + MPIC_CPU_EOI, 0); + } + } } #endif /* CONFIG_SMP */ -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/5] powerpc/fsl_booke: Fix comment in head_fsl_booke.S
Fix typo in comments introduced by: commit 6dece0eb69b2a28e18d104bc5d707f1cb673f5e0 Author: Scott Wood scottw...@freescale.com Date: Mon Jul 25 11:29:33 2011 + powerpc/32: Pass device tree address as u64 to machine_init Signed-off-by: Matthew McClintock m...@freescale.com cc: Scott Wood scottw...@freescale.com --- arch/powerpc/kernel/head_fsl_booke.S |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index e1c699f..9f5d210 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -80,8 +80,8 @@ _ENTRY(_start); slw r18,r18,r17 /* r18 = page size */ addir18,r18,-1 and r19,r3,r18 /* r19 = page offset */ - andcr31,r20,r18 /* r3 = page base */ - or r31,r31,r19 /* r3 = devtree phys addr */ + andcr31,r20,r18 /* r31 = page base */ + or r31,r31,r19 /* r31 = devtree phys addr */ mfspr r30,SPRN_MAS7 li r25,0 /* phys kernel start (low) */ -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/5] powerpc/85xx: issue 15 EOI after core reset
This is listed as a requirement after issuing a core reset to properly clear pending interrupts Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/sysdev/mpic.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9678081..f5b83f0 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1748,6 +1748,7 @@ void mpic_reset_core(int cpu) struct mpic *mpic = mpic_primary; u32 pir; int cpuid = get_hard_smp_processor_id(cpu); + int i; /* Set target bit for core reset */ pir = mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); @@ -1759,6 +1760,12 @@ void mpic_reset_core(int cpu) pir = ~(1 cpuid); mpic_write(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); + + /* Perform 15 EOI on each reset core to clear pending interrupts */ + for (i = 0; i 15; i++) { + _mpic_write(mpic-reg_type, mpic-cpuregs[cpuid], + MPIC_CPU_EOI, 0); + } } #endif /* CONFIG_SMP */ -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/5] powerpc/85xx: Make kexec to interate over online cpus
This is not strictly required, because this iterates over logical cpus and they are not (currently) discontigous. But, it's cleaner code and more obvious what is going on Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/platforms/85xx/smp.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 5b9b901..b830f8a 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -206,7 +206,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image) if ( !timeout ) printk(KERN_ERR Unable to bring down secondary cpu(s)); - for (i = 0; i num_cpus; i++) + for_each_online_cpu(i) { if ( i == smp_processor_id() ) continue; mpic_reset_core(i); -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 4/5] powerpc/85xx: use physical cpu from device tree
Currently, we assume the first CPU to come up is the boot cpu. Instead we can use the boot_cpu_phys from the device tree. Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/kernel/asm-offsets.c|4 arch/powerpc/kernel/head_fsl_booke.S |9 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 536ffa8..264f8ad 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -28,6 +28,7 @@ #include linux/hardirq.h #endif #include linux/kbuild.h +#include linux/of_fdt.h #include asm/io.h #include asm/page.h @@ -619,5 +620,8 @@ int main(void) DEFINE(PACA_OPAL_MC_EVT, offsetof(struct paca_struct, opal_mc_evt)); #endif + DEFINE(DT_BOOTCPU, offsetof(struct boot_param_header, + boot_cpuid_phys)); + return 0; } diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 9f5d210..eb28ade 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -87,6 +87,7 @@ _ENTRY(_start); li r25,0 /* phys kernel start (low) */ li r24,0 /* CPU number */ li r23,0 /* phys kernel start (high) */ + lwz r22,DT_BOOTCPU(r3) /* boot_cpuid_phys */ /* We try to not make any assumptions about how the boot loader * setup or used the TLBs. We invalidate all mappings from the @@ -166,11 +167,8 @@ _ENTRY(__early_start) /* Check to see if we're the second processor, and jump * to the secondary_start code if so */ - lis r24, boot_cpuid@h - ori r24, r24, boot_cpuid@l - lwz r24, 0(r24) - cmpwi r24, -1 mfspr r24,SPRN_PIR + cmpwr22,r24 bne __secondary_start #endif @@ -192,9 +190,6 @@ _ENTRY(__early_start) li r0,0 stwur0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) - rlwinm r22,r1,0,0,31-THREAD_SHIFT /* current thread_info */ - stw r24, TI_CPU(r22) - bl early_init #ifdef CONFIG_RELOCATABLE -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 5/5] powerpc/setup_{32, 64}.c: remove unneeded boot_cpuid{, _phys}
boot_cpuid and init_thread_info.cpu are redundant, just use the var that stays around longer and add a define to make boot_cpuid point at the correct value boot_cpudid_phys is not needed and can completely go away from the SMP case, we leave it there for the non-SMP case since the paca struct is not around to store this info This patch also has the effect of having the logical cpu number of the boot cpu be updated correctly independently of the ordering of the cpu nodes in the device tree. Signed-off-by: Matthew McClintock m...@freescale.com --- Could also just change boot_cpuid every to init_thread_info.cpu instead of using this define This is only tested on 32-bit parts, only compiled on 64-bit arch/powerpc/include/asm/smp.h |2 +- arch/powerpc/kernel/setup_32.c |7 --- arch/powerpc/kernel/setup_64.c |1 - 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h index adba970..f26c554 100644 --- a/arch/powerpc/include/asm/smp.h +++ b/arch/powerpc/include/asm/smp.h @@ -29,7 +29,7 @@ #endif #include asm/percpu.h -extern int boot_cpuid; +#define boot_cpuid (init_thread_info.cpu) extern int spinning_secondaries; extern void cpu_die(void); diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index c1ce863..f396847 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -46,10 +46,11 @@ extern void bootx_init(unsigned long r4, unsigned long phys); -int boot_cpuid = -1; -EXPORT_SYMBOL_GPL(boot_cpuid); -int boot_cpuid_phys; +/* we need a place to store phys cpu for non-SMP case */ +#ifndef CONFIG_SMP +int boot_cpuid_phys = -1; EXPORT_SYMBOL_GPL(boot_cpuid_phys); +#endif int smp_hw_index[NR_CPUS]; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index d4168c9..eacefba 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -73,7 +73,6 @@ #define DBG(fmt...) #endif -int boot_cpuid = 0; int __initdata spinning_secondaries; u64 ppc64_pft_size; -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/85xx: Fix doorbells
Commit 765342526246c97600e5344c0949824d94bb51c3 made some small changes to IPI, message_pass in smp_ops was initialized to NULL for other platforms but not for 85xx which causes us to always use the mpic for IPI's. This patch makes doorbells work again. Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/platforms/85xx/smp.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 5b9b901..d6e4746 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -243,6 +243,7 @@ void __init mpc85xx_smp_init(void) * If left NULL, .message_pass defaults to * smp_muxed_ipi_message_pass */ + smp_85xx_ops.message_pass = NULL; smp_85xx_ops.cause_ipi = doorbell_cause_ipi; } -- 1.7.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: Fix build dependencies for epapr.c which needs libfdt.h
Currently, the build can (very rarely) fail to build because libfdt.h has not been created or is in the process of being copied. Signed-off-by: Matthew McClintock m...@freescale.com --- I think this fixes this build error. Please comment as it's really hard to reproduce this build error. I've seen this happen a few times now on our automated build server. BOOTCC arch/powerpc/boot/ep8248e.o BOOTCC arch/powerpc/boot/cuboot-warp.o BOOTCC arch/powerpc/boot/cuboot-85xx-cpm2.o In file included from arch/powerpc/boot/epapr.c:20:0: arch/powerpc/boot/libfdt.h:382:1: error: unterminated comment arch/powerpc/boot/libfdt.h:1:0: error: unterminated #ifndef BOOTCC arch/powerpc/boot/cuboot-yosemite.o make[1]: *** [arch/powerpc/boot/epapr.o] Error 1 make[1]: *** Waiting for unfinished jobs BOOTCC arch/powerpc/boot/simpleboot.o make: *** [uImage] Error 2 Build step 'Execute shell' marked build as failure arch/powerpc/boot/Makefile |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index c26200b..ac6705e 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -58,7 +58,7 @@ $(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o prpmc2800.o): \ libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c libfdtheader := fdt.h libfdt.h libfdt_internal.h -$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o): \ +$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o): \ $(addprefix $(obj)/,$(libfdtheader)) src-wlib := string.S crt0.S crtsavres.S stdio.c main.c \ -- 1.7.5 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/module: Remove unused variable err
Commit 5336377d6225959624146629ce3fc88ee8ecda3d removed the need for err, remove the variable Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/kernel/module.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c index 4ef93ae..49cee9d 100644 --- a/arch/powerpc/kernel/module.c +++ b/arch/powerpc/kernel/module.c @@ -63,7 +63,6 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { const Elf_Shdr *sect; - int err; /* Apply feature fixups */ sect = find_section(hdr, sechdrs, __ftr_fixup); -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/4] powerpc/85xx: Remove call to mpic_teardown_this_cpu in kexec
We no longer need to call this explicitly as a generic version is called by default Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/platforms/85xx/smp.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index a6b1065..cb8ad3b 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -118,8 +118,6 @@ static int kexec_down_cpus = 0; void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) { - mpic_teardown_this_cpu(1); - /* When crashing, this gets called on all CPU's we only * take down the non-boot cpus */ if (smp_processor_id() != boot_cpuid) -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/4] powerpc/kexec: make masking/disabling interrupts generic
Right now just the kexec crash pathway turns turns off the interrupts. Pull that out and make a generic version for use elsewhere Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/include/asm/kexec.h |1 + arch/powerpc/kernel/crash.c| 13 + arch/powerpc/kernel/machine_kexec.c| 24 arch/powerpc/kernel/machine_kexec_32.c |4 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index 076327f..f54408d 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h @@ -91,6 +91,7 @@ extern void machine_kexec_simple(struct kimage *image); extern void crash_kexec_secondary(struct pt_regs *regs); extern int overlaps_crashkernel(unsigned long start, unsigned long size); extern void reserve_crashkernel(void); +extern void machine_kexec_mask_interrupts(void); #else /* !CONFIG_KEXEC */ static inline int kexec_sr_activated(int cpu) { return 0; } diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c index 4457382..832c8c4 100644 --- a/arch/powerpc/kernel/crash.c +++ b/arch/powerpc/kernel/crash.c @@ -414,18 +414,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs) crash_kexec_wait_realmode(crashing_cpu); #endif - for_each_irq(i) { - struct irq_desc *desc = irq_to_desc(i); - - if (!desc || !desc-chip || !desc-chip-eoi) - continue; - - if (desc-status IRQ_INPROGRESS) - desc-chip-eoi(i); - - if (!(desc-status IRQ_DISABLED)) - desc-chip-shutdown(i); - } + machine_kexec_mask_interrupts(); /* * Call registered shutdown routines savely. Swap out diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index dd6c141..df7e20c 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -14,10 +14,34 @@ #include linux/threads.h #include linux/memblock.h #include linux/of.h +#include linux/irq.h + #include asm/machdep.h #include asm/prom.h #include asm/sections.h +void machine_kexec_mask_interrupts(void) { + unsigned int i; + + for_each_irq(i) { + struct irq_desc *desc = irq_to_desc(i); + + if (!desc || !desc-chip) + continue; + + if (desc-chip-eoi + desc-status IRQ_INPROGRESS) + desc-chip-eoi(i); + + if (desc-chip-mask) + desc-chip-mask(i); + + if (desc-chip-disable + !(desc-status IRQ_DISABLED)) + desc-chip-disable(i); + } +} + void machine_crash_shutdown(struct pt_regs *regs) { if (ppc_md.machine_crash_shutdown) diff --git a/arch/powerpc/kernel/machine_kexec_32.c b/arch/powerpc/kernel/machine_kexec_32.c index ae63a96..e63f2e7 100644 --- a/arch/powerpc/kernel/machine_kexec_32.c +++ b/arch/powerpc/kernel/machine_kexec_32.c @@ -39,6 +39,10 @@ void default_machine_kexec(struct kimage *image) /* Interrupts aren't acceptable while we reboot */ local_irq_disable(); + /* mask each interrupt so we are in a more sane state for the +* kexec kernel */ + machine_kexec_mask_interrupts(); + page_list = image-head; /* we need both effective and real address here */ -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 4/4] powerpc/85xx: flush dcache before resetting cores
When we do an mpic_reset_core we need to make sure the dcache is flushed Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/platforms/85xx/smp.c | 50 + 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 29416a9..c89a370 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -16,6 +16,7 @@ #include linux/delay.h #include linux/of.h #include linux/kexec.h +#include linux/highmem.h #include asm/machdep.h #include asm/pgtable.h @@ -133,11 +134,60 @@ static void mpc85xx_smp_kexec_down(void *arg) ppc_md.kexec_cpu_down(0,1); } +static void map_and_flush(unsigned long paddr) +{ + struct page *page = pfn_to_page(paddr PAGE_SHIFT); + unsigned long kaddr = (unsigned long)kmap(page); + + flush_dcache_range(kaddr, kaddr + PAGE_SIZE); + kunmap(page); +} + +/** + * Before we reset the other cores, we need to flush relevant cache + * out to memory so we don't get anything corrupted, some of these flushes + * are performed out of an overabundance of caution as interrupts are not + * disabled yet and we can switch cores + */ +static void mpc85xx_smp_flush_dcache_kexec(struct kimage *image) +{ + kimage_entry_t *ptr, entry; + unsigned long paddr; + int i; + + if (image-type == KEXEC_TYPE_DEFAULT) { + /* normal kexec images are stored in temporary pages */ + for (ptr = image-head; (entry = *ptr) !(entry IND_DONE); +ptr = (entry IND_INDIRECTION) ? + phys_to_virt(entry PAGE_MASK) : ptr + 1) { + if (!(entry IND_DESTINATION)) { + map_and_flush(entry); + } + } + /* flush out last IND_DONE page */ + map_and_flush(entry); + } else { + /* crash type kexec images are copied to the crash region */ + for (i = 0; i image-nr_segments; i++) { + struct kexec_segment *seg = image-segment[i]; + for (paddr = seg-mem; paddr seg-mem + seg-memsz; +paddr += PAGE_SIZE) { + map_and_flush(paddr); + } + } + } + + /* also flush the kimage struct to be passed in as well */ + flush_dcache_range((unsigned long)image, + (unsigned long)image + sizeof(*image)); +} + static void mpc85xx_smp_machine_kexec(struct kimage *image) { int timeout = INT_MAX; int i, num_cpus = num_present_cpus(); + mpc85xx_smp_flush_dcache_kexec(image); if (image-type == KEXEC_TYPE_DEFAULT) smp_call_function(mpc85xx_smp_kexec_down, NULL, 0); -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/4] powerpc/85xx: Minor fixups for kexec on 85xx
Make kexec_down_cpus atmoic since it will be incremented by all cores as they are coming down Remove duplicate calls to mpc85xx_smp_kexec_down, now it's called by the crash and normal kexec pathway only once Increase the timeout to wait for other cores to shutdown Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/platforms/85xx/smp.c | 24 +++- 1 files changed, 11 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index cb8ad3b..29416a9 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -114,17 +114,15 @@ struct smp_ops_t smp_85xx_ops = { }; #ifdef CONFIG_KEXEC -static int kexec_down_cpus = 0; +atomic_t kexec_down_cpus = ATOMIC_INIT(0); void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) { - /* When crashing, this gets called on all CPU's we only -* take down the non-boot cpus */ - if (smp_processor_id() != boot_cpuid) - { - local_irq_disable(); - kexec_down_cpus++; + local_irq_disable(); + if (secondary) { + atomic_inc(kexec_down_cpus); + /* loop forever */ while (1); } } @@ -137,14 +135,14 @@ static void mpc85xx_smp_kexec_down(void *arg) static void mpc85xx_smp_machine_kexec(struct kimage *image) { - int timeout = 2000; - int i; + int timeout = INT_MAX; + int i, num_cpus = num_present_cpus(); - set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); - smp_call_function(mpc85xx_smp_kexec_down, NULL, 0); + if (image-type == KEXEC_TYPE_DEFAULT) + smp_call_function(mpc85xx_smp_kexec_down, NULL, 0); - while ( (kexec_down_cpus != (num_online_cpus() - 1)) + while ( (atomic_read(kexec_down_cpus) != (num_cpus - 1)) ( timeout 0 ) ) { timeout--; @@ -153,7 +151,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image) if ( !timeout ) printk(KERN_ERR Unable to bring down secondary cpu(s)); - for (i = 0; i num_present_cpus(); i++) + for (i = 0; i num_cpus; i++) { if ( i == smp_processor_id() ) continue; mpic_reset_core(i); -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
kexec on ppc64
All, I'm trying to determine how kexec'ing works on 64 bit powerpc. When allocating a region for the kexec'ed kernel is it ever the same as the currently running kernel or do you always boot the kexec'ed kernel from a different memory region? I understand that a crash kernel will be in a different region, however I was hoping to confirm the behavior for a normal kexec -e. Thanks, Matthew ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[RFC] arch/powerpc: Remove duplicate/redundant Altivec entries
In lieu of having multiple similiar lines, we can just have one generic cpu-as line for CONFIG_ALTIVEC --- Was hoping to get comments about this change and if anyone sees any potential problems? arch/powerpc/Makefile |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index e07d499..4e88b42 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -131,8 +131,7 @@ KBUILD_CFLAGS += -mno-sched-epilog endif cpu-as-$(CONFIG_4xx) += -Wa,-m405 -cpu-as-$(CONFIG_6xx) += -Wa,-maltivec -cpu-as-$(CONFIG_POWER4)+= -Wa,-maltivec +cpu-as-$(CONFIG_ALTIVEC) += -Wa,-maltivec cpu-as-$(CONFIG_E500) += -Wa,-me500 cpu-as-$(CONFIG_E200) += -Wa,-me200 -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/fsl_soc: Search all global-utilities nodes for rstccr
On Aug 28, 2010, at 5:34 PM, Timur Tabi wrote: m...@freescale.com wrote: + + for_each_node_by_name(np, global-utilities) { + if ((of_get_property(np, fsl,has-rstcr, NULL))) { + rstcr = of_iomap(np, 0) + 0xb0; + if (!rstcr) + printk (KERN_EMERG Error: reset control I'm not sure KERN_EMERG is warranted for this kind of error. I'm not sure either - I left it as it was before. + register not mapped!\n); + } So if a node has an fsl,rstcr property, but the of_iomap() fails, we jump to the next global-utilities node? Perhaps you need a 'break' after the printk()? Or potentially a continue to be more robust? Or would two (or more) has-rstcr nodes be wrong? + } + + if (!rstcr ppc_md.restart == fsl_rstcr_restart) Wouldn't it make more sense to assign fsl_rstcr_restart to ppc_md.restart only if we find a valid fsl,has-rstcr property? Again I'm not entirely sure, I left this as it was before. Is there another way to reset the board if the rstcr node was not found correctly? -M -- Timur Tabi Linux kernel developer at Freescale ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2] powerpc/fsl_soc: Search all global-utilities nodes for rstccr
The first global-utilities node might not contain the rstcr property, so we should search all the nodes Signed-off-by: Matthew McClintock m...@freescale.com --- -Changed KERN_EMERG to KERN_ERR -Break if we do not find rstcr mapped -Restore of_put_node that was dropped arch/powerpc/sysdev/fsl_soc.c | 20 +--- 1 files changed, 13 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index b91f7ac..6c67d9e 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -378,17 +378,23 @@ static __be32 __iomem *rstcr; static int __init setup_rstcr(void) { struct device_node *np; - np = of_find_node_by_name(NULL, global-utilities); - if ((np of_get_property(np, fsl,has-rstcr, NULL))) { - rstcr = of_iomap(np, 0) + 0xb0; - if (!rstcr) - printk (KERN_EMERG Error: reset control register - not mapped!\n); - } else if (ppc_md.restart == fsl_rstcr_restart) + + for_each_node_by_name(np, global-utilities) { + if ((of_get_property(np, fsl,has-rstcr, NULL))) { + rstcr = of_iomap(np, 0) + 0xb0; + if (!rstcr) + printk (KERN_ERR Error: reset control + register not mapped!\n); + break; + } + } + + if (!rstcr ppc_md.restart == fsl_rstcr_restart) printk(KERN_ERR No RSTCR register, warm reboot won't work\n); if (np) of_node_put(np); + return 0; } -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/2] powerpc/fsl_booke: Add support to boot from core other than 0
First we check to see if we are the first core booting up. This is accomplished by comparing the boot_cpuid with -1, if it is we assume this is the first core coming up. Secondly, we need to update the initial thread info structure to reflect the actual cpu we are running on otherwise smp_processor_id() and related functions will return the default initialization value of the struct or 0. Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/kernel/head_fsl_booke.S | 10 -- arch/powerpc/kernel/setup_32.c |2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 258315a..5bbf593 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -152,8 +152,11 @@ _ENTRY(__early_start) /* Check to see if we're the second processor, and jump * to the secondary_start code if so */ - mfspr r24,SPRN_PIR - cmpwi r24,0 + lis r24, boot_cp...@h + ori r24, r24, boot_cp...@l + lwz r24, 0(r24) + cmpwi r24, -1 + mfspr r24,SPRN_PIR bne __secondary_start #endif @@ -175,6 +178,9 @@ _ENTRY(__early_start) li r0,0 stwur0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) + rlwinm r22,r1,0,0,31-THREAD_SHIFT /* current thread_info */ + stw r24, TI_CPU(r22) + bl early_init #ifdef CONFIG_RELOCATABLE diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 8f58986..4be3ef4 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -46,7 +46,7 @@ extern void bootx_init(unsigned long r4, unsigned long phys); -int boot_cpuid; +int boot_cpuid = -1; EXPORT_SYMBOL_GPL(boot_cpuid); int boot_cpuid_phys; -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/2] powerpc/mm: Assume first cpu is boot_cpuid not 0
arch/powerpc/mm/mmu_context_nohash.c assumes the boot cpu will always have smp_processor_id() == 0. This patch fixes that assumption Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/mm/mmu_context_nohash.c |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index 1f2d9ff..cf98c1e 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c @@ -334,7 +334,7 @@ static int __cpuinit mmu_context_cpu_notify(struct notifier_block *self, /* We don't touch CPU 0 map, it's allocated at aboot and kept * around forever */ - if (cpu == 0) + if (cpu == boot_cpuid) return NOTIFY_OK; switch (action) { @@ -412,9 +412,11 @@ void __init mmu_context_init(void) */ context_map = alloc_bootmem(CTX_MAP_SIZE); context_mm = alloc_bootmem(sizeof(void *) * (last_context + 1)); +#ifndef CONFIG_SMP stale_map[0] = alloc_bootmem(CTX_MAP_SIZE); +#else + stale_map[boot_cpuid] = alloc_bootmem(CTX_MAP_SIZE); -#ifdef CONFIG_SMP register_cpu_notifier(mmu_context_cpu_nb); #endif -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/fsl_soc: Search all global-utilities nodes for rstccr
The first global-utilities node might not contain the rstcr property, so we should search all the nodes Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/sysdev/fsl_soc.c | 20 +++- 1 files changed, 11 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index b91f7ac..e2c8e47 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -378,17 +378,19 @@ static __be32 __iomem *rstcr; static int __init setup_rstcr(void) { struct device_node *np; - np = of_find_node_by_name(NULL, global-utilities); - if ((np of_get_property(np, fsl,has-rstcr, NULL))) { - rstcr = of_iomap(np, 0) + 0xb0; - if (!rstcr) - printk (KERN_EMERG Error: reset control register - not mapped!\n); - } else if (ppc_md.restart == fsl_rstcr_restart) + + for_each_node_by_name(np, global-utilities) { + if ((of_get_property(np, fsl,has-rstcr, NULL))) { + rstcr = of_iomap(np, 0) + 0xb0; + if (!rstcr) + printk (KERN_EMERG Error: reset control + register not mapped!\n); + } + } + + if (!rstcr ppc_md.restart == fsl_rstcr_restart) printk(KERN_ERR No RSTCR register, warm reboot won't work\n); - if (np) - of_node_put(np); return 0; } -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/kernel: Adds correct calling convention for kexec purgatory
Call kexec purgatory code correctly. We were getting lucky before. If you examine the powerpc 32bit kexec purgatory code you will see it expects the following: From kexec-tools: purgatory/arch/ppc/v2wrap_32.S - calling convention: - r3 = physical number of this cpu (all cpus) - r4 = address of this chunk (master only) As such, we need to set r3 to the current core, r4 happens to be unused by purgatory at the moment but we go ahead and set it here as well Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/kernel/misc_32.S |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index 99bc652..6d1151f 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -807,6 +807,9 @@ relocate_new_kernel: isync sync + mfspr r3, SPRN_PIR /* current core we are running on */ + mr r4, r5 /* load physical address of chunk called */ + /* jump to the entry point, usually the setup routine */ mtlrr5 blrl -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 1/3] Ramdisk address was not copied correctly on kexec'ed kernel
Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/fixup_dtb.c |2 +- kexec/arch/ppc/kexec-ppc.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kexec/arch/ppc/fixup_dtb.c b/kexec/arch/ppc/fixup_dtb.c index 26c23a3..09f9ac1 100644 --- a/kexec/arch/ppc/fixup_dtb.c +++ b/kexec/arch/ppc/fixup_dtb.c @@ -311,7 +311,7 @@ static void fixup_initrd(char *blob_buf) return; } - tmp = ramdisk_base + ramdisk_size + 1; + tmp = ramdisk_base + ramdisk_size; err = fdt_setprop(blob_buf, nodeoffset, linux,initrd-end, tmp, sizeof(tmp)); if (err 0) { diff --git a/kexec/arch/ppc/kexec-ppc.c b/kexec/arch/ppc/kexec-ppc.c index c36c7b3..ab76d6f 100644 --- a/kexec/arch/ppc/kexec-ppc.c +++ b/kexec/arch/ppc/kexec-ppc.c @@ -481,7 +481,7 @@ static int get_devtree_details(unsigned long kexec_flags) if ((initrd_end - initrd_start) != 0 ) { initrd_base = initrd_start; - initrd_size = initrd_end - initrd_start + 1; + initrd_size = initrd_end - initrd_start; } if (reuse_initrd) { -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 0/3] Misc. bug fixes for ppc32
This patch series fixes a few issues I have discovered with my previous patch series. Nothing new has been added. v2: Missed signoff, removed initializing variable twice Matthew McClintock (3): Ramdisk address was not copied correctly on kexec'ed kernel Prevent multiple reservations for cpu-release-addr Prevent initrd-start and initrd-end from appearing multiple times kexec/arch/ppc/fixup_dtb.c | 50 --- kexec/arch/ppc/kexec-ppc.c |2 +- 2 files changed, 29 insertions(+), 23 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 3/3] Prevent initrd-start and initrd-end from appearing multiple times
We always remove the old entry, and add it back if it is needed on for the kexec'ed kernel Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/fixup_dtb.c | 20 ++-- 1 files changed, 10 insertions(+), 10 deletions(-) diff --git a/kexec/arch/ppc/fixup_dtb.c b/kexec/arch/ppc/fixup_dtb.c index 910a3f0..205fd77 100644 --- a/kexec/arch/ppc/fixup_dtb.c +++ b/kexec/arch/ppc/fixup_dtb.c @@ -160,7 +160,7 @@ static void fixup_reserve_regions(struct kexec_info *info, char *blob_buf, off_t goto out; } } - } else { + } else if (ramdisk || reuse_initrd) { /* Otherwise we just add back the ramdisk and the device tree * is already in the list */ ret = fdt_add_mem_rsv(blob_buf, ramdisk_base, ramdisk_size); @@ -300,13 +300,16 @@ static void fixup_initrd(char *blob_buf) nodeoffset = fdt_path_offset(blob_buf, /chosen); - if ((reuse_initrd || ramdisk) - ((ramdisk_base != 0) (ramdisk_size != 0))) { - if (nodeoffset 0) { - printf(fdt_initrd: %s\n, fdt_strerror(nodeoffset)); - return; - } + if (nodeoffset 0) { + printf(fdt_initrd: %s\n, fdt_strerror(nodeoffset)); + return; + } + + fdt_delprop(blob_buf, nodeoffset, linux,initrd-start); + fdt_delprop(blob_buf, nodeoffset, linux,initrd-end); + if ((reuse_initrd || ramdisk) + ((ramdisk_base != 0) (ramdisk_size != 0))) { tmp = ramdisk_base; err = fdt_setprop(blob_buf, nodeoffset, linux,initrd-start, tmp, sizeof(tmp)); @@ -325,9 +328,6 @@ static void fixup_initrd(char *blob_buf) fdt_strerror(err)); return; } - } else { - fdt_delprop(blob_buf, nodeoffset, linux,initrd-start); - fdt_delprop(blob_buf, nodeoffset, linux,initrd-end); } } -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 2/3] Prevent multiple reservations for cpu-release-addr
Currently, we can add a lot of reservations over a small range, this does a simple check to verify the previous entry is not the same as the current one and skips it if so Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/fixup_dtb.c | 28 +--- 1 files changed, 17 insertions(+), 11 deletions(-) diff --git a/kexec/arch/ppc/fixup_dtb.c b/kexec/arch/ppc/fixup_dtb.c index 09f9ac1..910a3f0 100644 --- a/kexec/arch/ppc/fixup_dtb.c +++ b/kexec/arch/ppc/fixup_dtb.c @@ -139,6 +139,7 @@ static void fixup_reserve_regions(struct kexec_info *info, char *blob_buf, off_t { int ret, i; int nodeoffset; + u64 val = 0; /* If this is a KEXEC kernel we add all regions since they will * all need to be saved */ @@ -175,20 +176,25 @@ static void fixup_reserve_regions(struct kexec_info *info, char *blob_buf, off_t while (nodeoffset != -FDT_ERR_NOTFOUND) { const void *buf; int sz, ret; - u64 val = 0; + u64 tmp; buf = fdt_getprop(blob_buf, nodeoffset, cpu-release-addr, sz); - if (sz == 4) { - val = *(u32 *)buf; - } else if (sz == 8) { - val = *(u64 *)buf; - } - if (val) { - ret = fdt_add_mem_rsv(blob_buf, PAGE_ALIGN(val-PAGE_SIZE), PAGE_SIZE); - if (ret) - printf(%s: Unable to add reserve for cpu-release-addr!\n, - fdt_strerror(ret)); + if (buf) { + if (sz == 4) { + tmp = *(u32 *)buf; + } else if (sz == 8) { + tmp = *(u64 *)buf; + } + + /* crude check to see if last value is repeated */ + if (_ALIGN_DOWN(tmp, PAGE_SIZE) != _ALIGN_DOWN(val, PAGE_SIZE)) { + val = tmp; + ret = fdt_add_mem_rsv(blob_buf, _ALIGN_DOWN(val, PAGE_SIZE), PAGE_SIZE); + if (ret) + printf(%s: Unable to add reserve for cpu-release-addr!\n, + fdt_strerror(ret)); + } } nodeoffset = fdt_node_offset_by_prop_value(blob_buf, nodeoffset, -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2 5/7] Add support for ramdisk on ppc32 for uImage-ppc and Elf-ppc
On Jul 29, 2010, at 3:33 AM, Simon Horman wrote: On Tue, Jul 20, 2010 at 03:14:58PM -0500, Matthew McClintock wrote: This fixes --reuseinitrd and --ramdisk option for ppc32 on uImage-ppc and Elf. It works for normal kexec as well as for kdump. When using --reuseinitrd you need to specifify retain_initrd on the command line. Also, if you are doing kdump you need to make sure your initrd lives in the crashdump region otherwise the kdump kernel will not be able to access it. The --ramdisk option should always work. Thanks, I have applied this change. I had to do a minor merge on the Makefile, could you verify that the result is correct? Tested and looks good. -M ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 0/7] Fixup booting with device trees and uImage/elf on ppc32
On Jul 26, 2010, at 9:55 PM, Simon Horman wrote: [Cced linuxppc-dev] On Tue, Jul 20, 2010 at 11:42:57PM -0500, Matthew McClintock wrote: This patch series adds full support for booting with a flat device tree with either uImage or elf file formats. Kexec and Kdump should work, and you should also be able to use ramdisks or reuse your current ramdisk as well This patch series was tested on an mpc85xx system with a kernel version 2.6.35-rc3 v1: Initial version v2: Added support for fs2dt (file system to device tree) v3: Fix some misc. git problems I had and other code cleanups Hi Matthew, I'm a little concerned that these changes are non trivial and haven't had much review. But I am prepared to put them into my tree once 2.0.2 is released - perhaps that way they will get some test coverage. Does that work for you? Either way works for me. I know they could use more review, however as Maxim said the current tree does not work AFAIK. Either way, I'm willing to keeping addressing everyones concerns and wait or move forward and make some quick fixes as well. -M Matthew McClintock (7): Restore kexec uImage-ppc to working state Fix case where phys_addr_t != unsigned long when reading proc entries Update uImage to support crash kernel and misc fixes Update Elf-ppc to support crash kernel and misc fixes Add support for ramdisk on ppc32 for uImage-ppc and Elf-ppc Add support for reworking flat device tree support Add documentation/howto for mpc85xx systems doc/mpc85xx.txt | 190 + kexec/arch/ppc/Makefile |1 + kexec/arch/ppc/fixup_dtb.c| 298 - kexec/arch/ppc/fixup_dtb.h|6 +- kexec/arch/ppc/include/arch/options.h |3 + kexec/arch/ppc/kexec-elf-ppc.c| 186 + kexec/arch/ppc/kexec-ppc.c| 262 + kexec/arch/ppc/kexec-ppc.h|3 + kexec/arch/ppc/kexec-uImage-ppc.c | 136 --- kexec/arch/ppc/ops.h |1 - purgatory/arch/ppc/purgatory-ppc.c|5 + 11 files changed, 852 insertions(+), 239 deletions(-) create mode 100644 doc/mpc85xx.txt ___ kexec mailing list ke...@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 0/2] kexec/crash support on mpc85xx parts
The patch series is meant to fix a few issues with kexec/crash working on mpc85xx parts v1: initial version v2: Fix a typo when decremeting a wait condition twice leading to never showing when we fail waiting for extra cpus to shutdown Moved around code so the crash and kexec shutdown code paths both work correctly - this was exposed by the above fix Disable modifying the PAGE_OFFSET and PHYSICAL_START when we build a crash kernel w/ relocation enabled. We don't need to change these values as a default action. Matthew McClintock (2): powerpc/85xx: kexec for SMP 85xx BookE systems powerpc/crashdump: Fix issues with kexec and 36bit physical addr arch/powerpc/Kconfig| 10 +++--- arch/powerpc/kernel/crash_dump.c|4 +- arch/powerpc/kernel/machine_kexec.c | 10 +++--- arch/powerpc/platforms/85xx/smp.c | 63 +++ 4 files changed, 75 insertions(+), 12 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 1/2] powerpc/85xx: kexec for SMP 85xx BookE systems
Adds support for kexec on 85xx machines for the BookE platform. Including support for SMP machines Based off work from Maxim Uvarov muva...@mvista.com Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/Kconfig | 10 +++--- arch/powerpc/platforms/85xx/smp.c | 63 + 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 328774b..351ce4a 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -351,7 +351,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE config KEXEC bool kexec system call (EXPERIMENTAL) - depends on (PPC_BOOK3S || (FSL_BOOKE !SMP)) EXPERIMENTAL + depends on (PPC_BOOK3S || FSL_BOOKE) EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot @@ -368,8 +368,8 @@ config KEXEC config CRASH_DUMP bool Build a kdump crash kernel - depends on PPC64 || 6xx - select RELOCATABLE if PPC64 + depends on PPC64 || 6xx || FSL_BOOKE + select RELOCATABLE if PPC64 || FSL_BOOKE help Build a kernel suitable for use as a kdump capture kernel. The same kernel binary can be used as production kernel and dump @@ -897,7 +897,7 @@ config KERNEL_START_BOOL config KERNEL_START hex Virtual address of kernel base if KERNEL_START_BOOL default PAGE_OFFSET if PAGE_OFFSET_BOOL - default 0xc200 if CRASH_DUMP + default 0xc200 if CRASH_DUMP !RELOCATABLE default 0xc000 config PHYSICAL_START_BOOL @@ -910,7 +910,7 @@ config PHYSICAL_START_BOOL config PHYSICAL_START hex Physical address where the kernel is loaded if PHYSICAL_START_BOOL - default 0x0200 if PPC_STD_MMU CRASH_DUMP + default 0x0200 if PPC_STD_MMU CRASH_DUMP !RELOCATABLE default 0x config PHYSICAL_ALIGN diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index a15f582..036c33c 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -15,6 +15,7 @@ #include linux/init.h #include linux/delay.h #include linux/of.h +#include linux/kexec.h #include asm/machdep.h #include asm/pgtable.h @@ -24,6 +25,7 @@ #include asm/dbell.h #include sysdev/fsl_soc.h +#include sysdev/mpic.h extern void __early_start(void); @@ -103,8 +105,64 @@ smp_85xx_setup_cpu(int cpu_nr) struct smp_ops_t smp_85xx_ops = { .kick_cpu = smp_85xx_kick_cpu, +#ifdef CONFIG_KEXEC + .give_timebase = smp_generic_give_timebase, + .take_timebase = smp_generic_take_timebase, +#endif }; +#ifdef CONFIG_KEXEC +static int kexec_down_cpus = 0; + +void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) +{ + mpic_teardown_this_cpu(1); + + /* When crashing, this gets called on all CPU's we only +* take down the non-boot cpus */ + if (smp_processor_id() != boot_cpuid) + { + local_irq_disable(); + kexec_down_cpus++; + + while (1); + } +} + +static void mpc85xx_smp_kexec_down(void *arg) +{ + if (ppc_md.kexec_cpu_down) + ppc_md.kexec_cpu_down(0,1); +} + +static void mpc85xx_smp_machine_kexec(struct kimage *image) +{ + int timeout = 2000; + int i; + + set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); + + smp_call_function(mpc85xx_smp_kexec_down, NULL, 0); + + while ( (kexec_down_cpus != (num_online_cpus() - 1)) + ( timeout 0 ) ) + { + timeout--; + } + + if ( !timeout ) + printk(KERN_ERR Unable to bring down secondary cpu(s)); + + for (i = 0; i num_present_cpus(); i++) + { + if ( i == smp_processor_id() ) continue; + mpic_reset_core(i); + } + + default_machine_kexec(image); +} +#endif /* CONFIG_KEXEC */ + void __init mpc85xx_smp_init(void) { struct device_node *np; @@ -122,4 +180,9 @@ void __init mpc85xx_smp_init(void) BUG_ON(!smp_85xx_ops.message_pass); smp_ops = smp_85xx_ops; + +#ifdef CONFIG_KEXEC + ppc_md.kexec_cpu_down = mpc85xx_smp_kexec_cpu_down; + ppc_md.machine_kexec = mpc85xx_smp_machine_kexec; +#endif } -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 2/2] powerpc/crashdump: Fix issues with kexec and 36bit physical addr
Fix sizes of variables so correct values are exported via /proc. Cast variable in comparison to avoid compiler error. Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/kernel/crash_dump.c|4 ++-- arch/powerpc/kernel/machine_kexec.c | 10 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 5fb667a..d254132 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -128,9 +128,9 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, if (!csize) return 0; - csize = min(csize, PAGE_SIZE); + csize = min_t(size_t, csize, PAGE_SIZE); - if (pfn max_pfn) { + if ((min_low_pfn pfn) (pfn max_pfn)) { vaddr = __va(pfn PAGE_SHIFT); csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); } else { diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index bb3d893..6ff15f0 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -144,24 +144,24 @@ int overlaps_crashkernel(unsigned long start, unsigned long size) } /* Values we need to export to the second kernel via the device tree. */ -static unsigned long kernel_end; -static unsigned long crashk_size; +static phys_addr_t kernel_end; +static phys_addr_t crashk_size; static struct property kernel_end_prop = { .name = linux,kernel-end, - .length = sizeof(unsigned long), + .length = sizeof(phys_addr_t), .value = kernel_end, }; static struct property crashk_base_prop = { .name = linux,crashkernel-base, - .length = sizeof(unsigned long), + .length = sizeof(phys_addr_t), .value = crashk_res.start, }; static struct property crashk_size_prop = { .name = linux,crashkernel-size, - .length = sizeof(unsigned long), + .length = sizeof(phys_addr_t), .value = crashk_size, }; -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 4/7] Update Elf-ppc to support crash kernel and misc fixes
Use current command line if none given, specifically useful for when arguments are added causing the use of the current cmdline to not occur We also try to load the dtb above the kernel, this is useful for relocatable kernels where they device tree needs to reside just above the kernel base address Set the kernel entry address in the relocatable purgatory code so we jump to the correct start address if not the default. Useful for relocatable kernels Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/kexec-elf-ppc.c | 26 ++ kexec/arch/ppc/kexec-ppc.c |7 --- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/kexec/arch/ppc/kexec-elf-ppc.c b/kexec/arch/ppc/kexec-elf-ppc.c index ab2d343..87e6507 100644 --- a/kexec/arch/ppc/kexec-elf-ppc.c +++ b/kexec/arch/ppc/kexec-elf-ppc.c @@ -182,6 +182,7 @@ int elf_ppc_load(int argc, char **argv, const char *buf, off_t len, int target_is_gamecube = 0; unsigned int addr; unsigned long dtb_addr; + unsigned long kernel_addr; #endif #define FIXUP_ENTRYS (20) char *fixup_nodes[FIXUP_ENTRYS + 1]; @@ -228,6 +229,9 @@ int elf_ppc_load(int argc, char **argv, const char *buf, off_t len, command_line_len = 0; if (command_line) { command_line_len = strlen(command_line) + 1; + } else { + command_line = get_command_line(); + command_line_len = strlen(command_line) + 1; } fixup_nodes[cur_fixup] = NULL; @@ -264,11 +268,11 @@ int elf_ppc_load(int argc, char **argv, const char *buf, off_t len, if (size phdr-p_memsz) size = phdr-p_memsz; - hole_addr = locate_hole(info, size, 0, 0, max_addr, 1); + kernel_addr = locate_hole(info, size, 0, 0, max_addr, 1); #ifdef CONFIG_PPC64 - ehdr.e_phdr[0].p_paddr = (Elf64_Addr)hole_addr; + ehdr.e_phdr[0].p_paddr = (Elf64_Addr)kernel_addr; #else - ehdr.e_phdr[0].p_paddr = hole_addr; + ehdr.e_phdr[0].p_paddr = kernel_addr; #endif /* Load the Elf data */ @@ -343,10 +347,11 @@ int elf_ppc_load(int argc, char **argv, const char *buf, off_t len, blob_buf = slurp_file(dtb, blob_size); if (!blob_buf || !blob_size) die(Device tree seems to be an empty file.\n); + blob_buf = fixup_dtb_nodes(blob_buf, blob_size, fixup_nodes, cmdline_buf); - dtb_addr = add_buffer(info, blob_buf, blob_size, blob_size, 0, 0, - KERNEL_ACCESS_TOP, -1); + dtb_addr = add_buffer(info, blob_buf, blob_size, blob_size, 0, kernel_addr, + kernel_addr + KERNEL_ACCESS_TOP, -1); } else { /* create from fs2dt */ seg_buf = NULL; @@ -364,19 +369,16 @@ int elf_ppc_load(int argc, char **argv, const char *buf, off_t len, if (dtb) { - /* set various variables for the purgatory */ - addr = ehdr.e_entry; + /* set various variables for the purgatory ehdr.e_entry is a +* virtual address, we can use kernel_addr which +* should be the physical start address of the kernel */ + addr = kernel_addr; elf_rel_set_symbol(info-rhdr, kernel, addr, sizeof(addr)); addr = dtb_addr; elf_rel_set_symbol(info-rhdr, dt_offset, addr, sizeof(addr)); - addr = rmo_top; - - elf_rel_set_symbol(info-rhdr, mem_size, - addr, sizeof(addr)); - #define PUL_STACK_SIZE (16 * 1024) addr = locate_hole(info, PUL_STACK_SIZE, 0, 0, elf_max_addr(ehdr), 1); diff --git a/kexec/arch/ppc/kexec-ppc.c b/kexec/arch/ppc/kexec-ppc.c index d7afad6..d9f1d05 100644 --- a/kexec/arch/ppc/kexec-ppc.c +++ b/kexec/arch/ppc/kexec-ppc.c @@ -27,9 +27,10 @@ #include config.h uint64_t rmo_top; -unsigned long long crash_base, crash_size; -unsigned long long initrd_base, initrd_size; -unsigned long long devicetree_base, devicetree_size; +unsigned long long crash_base = 0, crash_size = 0; +unsigned long long initrd_base = 0, initrd_size = 0; +unsigned long long ramdisk_base = 0, ramdisk_size = 0; +unsigned long long devicetree_base = 0, devicetree_size = 0; unsigned int rtas_base, rtas_size; int max_memory_ranges; -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 3/7] Update uImage to support crash kernel and misc fixes
Use current command line if none given, specifically useful for when arguments are added causing the use of the current cmdline to not occur. We also try to load the dtb above the kernel, this is useful for relocatable kernels where they device tree needs to reside just above the kernel base address. Only allocate 1 MiB extra for bss space after kernel as it appears to be more than adequate. Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/kexec-uImage-ppc.c | 32 ++-- 1 files changed, 22 insertions(+), 10 deletions(-) diff --git a/kexec/arch/ppc/kexec-uImage-ppc.c b/kexec/arch/ppc/kexec-uImage-ppc.c index 4a8d28d..21a7c1b 100644 --- a/kexec/arch/ppc/kexec-uImage-ppc.c +++ b/kexec/arch/ppc/kexec-uImage-ppc.c @@ -10,6 +10,7 @@ #include getopt.h #include arch/options.h #include ../../kexec.h +#include ../../kexec-syscall.h #include kexec-ppc.h #include fixup_dtb.h #include kexec-uImage.h @@ -45,7 +46,7 @@ static int ppc_load_bare_bits(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info, unsigned int load_addr, unsigned int ep) { - char *command_line; + char *command_line, *cmdline_buf; int command_line_len; char *dtb; unsigned int addr; @@ -56,6 +57,7 @@ static int ppc_load_bare_bits(int argc, char **argv, const char *buf, int opt; int ret; + cmdline_buf = NULL; command_line = NULL; dtb = NULL; @@ -89,24 +91,34 @@ static int ppc_load_bare_bits(int argc, char **argv, const char *buf, } command_line_len = 0; - if (command_line) + if (command_line) { + command_line_len = strlen(command_line) + 1; + } else { + command_line = get_command_line(); command_line_len = strlen(command_line) + 1; + } fixup_nodes[cur_fixup] = NULL; /* * len contains the length of the whole kernel image except the bss -* section. The 3 MiB should cover it. The purgatory and the dtb are +* section. The 1 MiB should cover it. The purgatory and the dtb are * allocated from memtop down towards zero so we should never get too * close to the bss :) */ - ret = valid_memory_range(info, load_addr, len + 3 * 1024 * 1024); + ret = valid_memory_range(info, load_addr, load_addr + (len + (1 * 1024 * 1024))); if (!ret) { printf(Can't add kernel to addr 0x%08x len %ld\n, - load_addr, len + 3 * 1024 * 1024); + load_addr, len + (1 * 1024 * 1024)); return -1; } - add_segment(info, buf, len, load_addr, len + 3 * 1024 * 1024); + add_segment(info, buf, len, load_addr, len + (1 * 1024 * 1024)); + + cmdline_buf = xmalloc(COMMAND_LINE_SIZE); + memset((void *)cmdline_buf, 0, COMMAND_LINE_SIZE); + if (command_line) + strncat(cmdline_buf, command_line, command_line_len); + if (dtb) { char *blob_buf; off_t blob_size = 0; @@ -115,10 +127,9 @@ static int ppc_load_bare_bits(int argc, char **argv, const char *buf, blob_buf = slurp_file(dtb, blob_size); if (!blob_buf || !blob_size) die(Device tree seems to be an empty file.\n); - blob_buf = fixup_dtb_nodes(blob_buf, blob_size, fixup_nodes, command_line); - - dtb_addr = add_buffer(info, blob_buf, blob_size, blob_size, 0, 0, - KERNEL_ACCESS_TOP, -1); + blob_buf = fixup_dtb_nodes(blob_buf, blob_size, fixup_nodes, cmdline_buf); + dtb_addr = add_buffer(info, blob_buf, blob_size, blob_size, 0, load_addr, + load_addr + KERNEL_ACCESS_TOP, -1); } else { dtb_addr = 0; } @@ -142,6 +153,7 @@ static int ppc_load_bare_bits(int argc, char **argv, const char *buf, addr = elf_rel_get_addr(info-rhdr, purgatory_start); info-entry = (void *)addr; + return 0; } -- 1.6.0.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2 7/7] Add documentation/howto for mpc85xx systems
Signed-off-by: Matthew McClintock m...@freescale.com --- doc/mpc85xx.txt | 190 +++ 1 files changed, 190 insertions(+), 0 deletions(-) create mode 100644 doc/mpc85xx.txt diff --git a/doc/mpc85xx.txt b/doc/mpc85xx.txt new file mode 100644 index 000..af96841 --- /dev/null +++ b/doc/mpc85xx.txt @@ -0,0 +1,190 @@ + mpc85xx kexec howto + --- + + Matthew McClintock m...@freescale.com + Last Updated: 2010-07-20 + +There is some terminology that will be useful which will be described here. + +boot kernel - the first one that you start, from u-boot for instance +kexec kernel - the kernel that you reboot into when running kexec -e +kdump kernel - the kernel that you reboot into after the boot kernel crash +relocatable kernel - kernel that can boot from a 256MB alignment of physical +memory (for mpc85xx systems at least) + +Each of the above types of kernels have specific requirements, they can +all be different kernels or all the same kernel depending on your +particular requirements. + +1) Build kernel for kexec (i.e. running kexec -e to reboot) + +This case is the simplest. You need to enable CONFIG_KEXEC for kexec for the +boot kernel, the kexec kernel can be a any kernel that already boots on your +platform. However, if you want to be able run kexec again after rebooting once +you will need to have CONFIG_KEXEC enabled for the kexec kernel as well. + +2) Build for kdump (i.e. for rebooting when your main kernel crashes) + +In this situation, you need to be aware that the kdump kernel will boot from +a different physical address than your boot kernel (or even the kexec kernel). +There are two approaches to this. First, you can build a relocatable kernel +which will boot from a different physical address with no changes. This method +is ideal as it would even allow your boot kernel and kdump kernel to be the +same one. Optionally, you can build a kernel with custom physical address and +kernel base address according to where you will load the kdump kernel*, but +it's much easier to just use a relocatable kernel and let things work +themselves out at run time. + +You will need to enable CONFIG_CRASH_DUMP on the boot kernel. You can chose to +enable CONFIG_RELOCATABLE for the kdump kernel, and you will still want to +verify that CONFIG_KERNEL_START and CONFIG_PHYSICAL_START have sane defaults. +Most likely, you can leave these as 0xC000 and 0x000 respectively. +Finally, on the kdump kernel you will want to make sure CONFIG_PROC_VMCORE is +enabled as well so the core dump is exported via /proc/vmcore. You can just +enable all these options on the boot and kdump and use the same kernel for both +which is the simplest option. + +Summary of 1 2: + +Just enable kexec, crash support, and relocatable kernel and you should be good +to go for all of the above scenarios using the same kernel. + +3) Obtaining a device tree + +You best bet for getting a working device tree is to pull the one the current +kernel is using. The easiest way to do this is use the device tree compiler +to create one from the proc file system + + $ dtc -I fs -O dtb /proc/device-tree/ flat-device-tree + +Kexec should be able to take this flat device tree, and modifiy it/update it +as needed for your particular scenario. It will update memreserve regions, add +initrd/ramdisks, fixup the command line, etc. + +NOTE: If no device tree is given, kexec will do the above on it's own to + obtain a useable device tree. You can specify the device tree to use + with the --dtb=flat_device_tree_blob kexec argument. + +4) Kexec'ing a new kernel + +If you have followed the procedure above you need to do the following to reboot +into a new kexec kernel. + + $ kexec -l {uImage,vmlinux} + $ kexec -e + +These options will boot the new kernel, you should see some message as shown +below. NOTE: The old command line is used, so if you are booting from an NFS +mount it should work fine, however it you are using an initrd/ramdisk there are +caveats to consider (see #6 below). + + sd 2:0:0:0: [sda] Synchronizing SCSI cache + Starting new kernel + Bye! + Reserving 256MB of memory at 512MB for crashkernel (System RAM: 4096MB) + Using MPC8572 DS machine description + [snip] + +5) Setting for a kdump kernel + +For the boot kernel, you need to reserve a region of memory for the kdump kernel +to use when the system crashes. This region is removed for use from the boot +kernel and when the system crashes the kdump kernel will operate out of this +region exclusively. For mpc85xx, we need to pick a region aligned at 256MB if we +are using a relocatable kernel, other than that the size allocated needs to leave +enough memory for your kdump environment to function properly as well as store +the kdump kernel and any other
[PATCH v2 6/7] Add support for reworking flat device tree support
Currently, the device tree is passed as is. You can optionally update the command line and specifically listed nodes but nothing is updated automatically. This patch updates the memreserve regions, memory node, initrd nodes and attempts to make the device tree look as it should. Some code is borrowed from the u-boot routines which do similiar things Also, now if no flat device tree is passed to kexec it will attempt to rebuild one from the /proc/device-tree file system to use for the kexec'ed kernel for both uImage and elf formats Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/fixup_dtb.c| 314 - kexec/arch/ppc/fixup_dtb.h|6 +- kexec/arch/ppc/kexec-elf-ppc.c| 148 + kexec/arch/ppc/kexec-ppc.h|1 + kexec/arch/ppc/kexec-uImage-ppc.c | 54 +-- kexec/arch/ppc/ops.h |1 - 6 files changed, 400 insertions(+), 124 deletions(-) diff --git a/kexec/arch/ppc/fixup_dtb.c b/kexec/arch/ppc/fixup_dtb.c index 40e9350..0f9238b 100644 --- a/kexec/arch/ppc/fixup_dtb.c +++ b/kexec/arch/ppc/fixup_dtb.c @@ -8,13 +8,36 @@ #include sys/stat.h #include ../../kexec.h +#include ../../kexec-syscall.h #include libfdt.h #include ops.h #include page.h #include fixup_dtb.h +#include kexec-ppc.h const char proc_dts[] = /proc/device-tree; +#ifdef DEBUG +static void print_fdt_reserve_regions(char *blob_buf) +{ + int i, num; + + /* Print out a summary of the final reserve regions */ + num = fdt_num_mem_rsv(blob_buf); + printf (reserve regions: %d\n, num); + for (i = 0; i num; i++) + { + uint64_t offset, size; + + if (fdt_get_mem_rsv(blob_buf, i, offset, size) == 0) { + printf(%d: offset: %llx, size: %llx\n, i, offset, size); + } else { + printf(Error retreiving reserved region\n); + } + } +} +#endif + static void fixup_nodes(char *nodes[]) { int index = 0; @@ -92,14 +115,303 @@ static void fixup_cmdline(const char *cmdline) return; } -char *fixup_dtb_nodes(char *blob_buf, off_t *blob_size, char *nodes[], char *cmdline) +#define EXPAND_GRANULARITY 1024 + +static char *expand_buf(int minexpand, char *blob_buf, off_t *blob_size) +{ + int size = fdt_totalsize(blob_buf); + int rc; + + size = _ALIGN(size + minexpand, EXPAND_GRANULARITY); + blob_buf = realloc(blob_buf, size); + if (!blob_buf) + fatal(Couldn't find %d bytes to expand device tree\n\r, size); + rc = fdt_open_into(blob_buf, blob_buf, size); + if (rc != 0) + fatal(Couldn't expand fdt into new buffer: %s\n\r, + fdt_strerror(rc)); + + *blob_size = fdt_totalsize(blob_buf); + + return blob_buf; +} + +static void fixup_reserve_regions(struct kexec_info *info, char *blob_buf, off_t *blob_size) +{ + int ret, i; + int nodeoffset; + + /* If this is a KEXEC kernel we add all regions since they will +* all need to be saved */ + if (info-kexec_flags KEXEC_ON_CRASH) { + for (i = 0; i info-nr_segments; i++) + { + uint64_t address = (unsigned long)info-segment[i].mem; + uint64_t size = info-segment[i].memsz; + + /* We add all except the device tree because it's already added */ + if (address == devicetree_base) continue; + + while ((i+1) info-nr_segments + (address + size == (unsigned long)info-segment[i+1].mem)) + { + /* We add all except the device tree because it's already added */ + if ( (unsigned long)info-segment[i+1].mem == devicetree_base) +continue; + + size += info-segment[++i].memsz; + } + + ret = fdt_add_mem_rsv(blob_buf, address, size); + if (ret) { + printf(%s: Error adding memory range to memreserve!\n, + fdt_strerror(ret)); + goto out; + } + } + } else { + /* Otherwise we just add back the ramdisk and the device tree +* is already in the list */ + ret = fdt_add_mem_rsv(blob_buf, ramdisk_base, ramdisk_size); + if (ret) { + printf(%s: Unable to add new reserved memory for initrd flat device tree\n, + fdt_strerror(ret)); + goto out; + } + } + + /* Add reserve regions for cpu-release-addr */ + nodeoffset = fdt_node_offset_by_prop_value(blob_buf, -1
[PATCH v2 5/7] Add support for ramdisk on ppc32 for uImage-ppc and Elf-ppc
This fixes --reuseinitrd and --ramdisk option for ppc32 on uImage-ppc and Elf. It works for normal kexec as well as for kdump. When using --reuseinitrd you need to specifify retain_initrd on the command line. Also, if you are doing kdump you need to make sure your initrd lives in the crashdump region otherwise the kdump kernel will not be able to access it. The --ramdisk option should always work. Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/Makefile |1 + kexec/arch/ppc/include/arch/options.h |3 + kexec/arch/ppc/kexec-elf-ppc.c| 44 - kexec/arch/ppc/kexec-ppc.c|6 +++ kexec/arch/ppc/kexec-ppc.h|2 + kexec/arch/ppc/kexec-uImage-ppc.c | 68 +++- 6 files changed, 118 insertions(+), 6 deletions(-) diff --git a/kexec/arch/ppc/Makefile b/kexec/arch/ppc/Makefile index 5988213..c963175 100644 --- a/kexec/arch/ppc/Makefile +++ b/kexec/arch/ppc/Makefile @@ -21,6 +21,7 @@ libfdt_SRCS += $(LIBFDT_SRCS:%=kexec/arch/ppc/libfdt/%) CPPFLAGS+=-I$(srcdir)/kexec/arch/$(ARCH)/libfdt ppc_KEXEC_SRCS += $(libfdt_SRCS) +ppc_ARCH_REUSE_INITRD = dist += kexec/arch/ppc/Makefile $(ppc_KEXEC_SRCS) \ kexec/arch/ppc/kexec-ppc.h kexec/arch/ppc/ppc_asm.h \ diff --git a/kexec/arch/ppc/include/arch/options.h b/kexec/arch/ppc/include/arch/options.h index f646ccc..0c00ea7 100644 --- a/kexec/arch/ppc/include/arch/options.h +++ b/kexec/arch/ppc/include/arch/options.h @@ -8,6 +8,7 @@ #define OPT_GAMECUBE(OPT_ARCH_MAX+1) #define OPT_DTB (OPT_ARCH_MAX+2) #define OPT_NODES (OPT_ARCH_MAX+3) +#define OPT_RAMDISK(OPT_ARCH_MAX+4) /* Options relevant to the architecture (excluding loader-specific ones), * in this case none: @@ -35,6 +36,8 @@ KEXEC_ARCH_OPTIONS \ {command-line, 1, 0, OPT_APPEND},\ {append, 1, 0, OPT_APPEND},\ + {ramdisk, 1, 0, OPT_APPEND},\ + {initrd, 1, 0, OPT_APPEND},\ {gamecube, 1, 0, OPT_GAMECUBE},\ {dtb, 1, 0, OPT_DTB},\ {reuse-node, 1, 0, OPT_NODES},\ diff --git a/kexec/arch/ppc/kexec-elf-ppc.c b/kexec/arch/ppc/kexec-elf-ppc.c index 87e6507..58bba54 100644 --- a/kexec/arch/ppc/kexec-elf-ppc.c +++ b/kexec/arch/ppc/kexec-elf-ppc.c @@ -127,6 +127,8 @@ static const struct option options[] = { KEXEC_ARCH_OPTIONS {command-line, 1, 0, OPT_APPEND}, {append, 1, 0, OPT_APPEND}, + {ramdisk, 1, 0, OPT_RAMDISK}, + {initrd, 1, 0, OPT_RAMDISK}, {gamecube, 1, 0, OPT_GAMECUBE}, {dtb, 1, 0, OPT_DTB}, {reuse-node, 1, 0, OPT_NODES}, @@ -139,10 +141,12 @@ void elf_ppc_usage(void) printf( --command-line=STRING Set the kernel command line to STRING.\n --append=STRING Set the kernel command line to STRING.\n +--ramdisk=filename Initial RAM disk.\n +--initrd=filename same as --ramdisk\n --gamecube=1|0Enable/disable support for ELFs with changed\n addresses suitable for the GameCube.\n - --dtb=filename Specify device tree blob file.\n - --reuse-node=nodeSpecify nodes which should be taken from /proc/device-tree.\n +--dtb=filename Specify device tree blob file.\n +--reuse-node=nodeSpecify nodes which should be taken from /proc/device-tree.\n Can be set multiple times.\n ); } @@ -177,7 +181,7 @@ int elf_ppc_load(int argc, char **argv, const char *buf, off_t len, unsigned long my_kernel, my_dt_offset; unsigned long my_stack, my_backup_start; unsigned int slave_code[256 / sizeof(unsigned int)], master_entry; - unsigned char *seg_buf = NULL; + char *seg_buf = NULL; off_t seg_size = 0; int target_is_gamecube = 0; unsigned int addr; @@ -193,6 +197,8 @@ int elf_ppc_load(int argc, char **argv, const char *buf, off_t len, dtb = NULL; max_addr = LONG_MAX; hole_addr = 0; + kernel_addr = 0; + ramdisk = 0; while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch (opt) { @@ -207,6 +213,9 @@ int elf_ppc_load(int argc, char **argv, const char *buf, off_t len, case OPT_APPEND: command_line = optarg; break; + case OPT_RAMDISK: + ramdisk = optarg; + break; case OPT_GAMECUBE: target_is_gamecube = atoi(optarg); break; @@ -234,6 +243,9 @@ int elf_ppc_load(int argc, char **argv, const char *buf, off_t len, command_line_len
[PATCH v2 1/7] Restore kexec uImage-ppc to working state
Booting with uImage-ppc was broken by previous work, this patch should restore it to working order Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/kexec-ppc.c | 68 ++- kexec/arch/ppc/kexec-uImage-ppc.c |5 +-- purgatory/arch/ppc/purgatory-ppc.c |5 +++ 3 files changed, 49 insertions(+), 29 deletions(-) diff --git a/kexec/arch/ppc/kexec-ppc.c b/kexec/arch/ppc/kexec-ppc.c index 55cadd6..c073f56 100644 --- a/kexec/arch/ppc/kexec-ppc.c +++ b/kexec/arch/ppc/kexec-ppc.c @@ -261,11 +261,28 @@ static int get_base_ranges(void) break; } } - base_memory_range[local_memory_ranges].start = - ((uint32_t *)buf)[0]; - base_memory_range[local_memory_ranges].end = - base_memory_range[local_memory_ranges].start + - ((uint32_t *)buf)[1]; + + if (n == 8) + { + base_memory_range[local_memory_ranges].start = + ((uint32_t *)buf)[0]; + base_memory_range[local_memory_ranges].end = + base_memory_range[local_memory_ranges].start + + ((uint32_t *)buf)[1]; + } + else if (n == 16) + { + base_memory_range[local_memory_ranges].start = +((uint64_t *)buf)[0]; +base_memory_range[local_memory_ranges].end = + base_memory_range[local_memory_ranges].start + +((uint64_t *)buf)[1]; + } + else + { + fprintf(stderr, Mem node has invalid size: %d\n, n); + return -1; + } base_memory_range[local_memory_ranges].type = RANGE_RAM; local_memory_ranges++; dbgprintf(%016llx-%016llx : %x\n, @@ -327,27 +344,28 @@ static int get_devtree_details(unsigned long kexec_flags) } if (strncmp(dentry-d_name, chosen, 6) == 0) { - strcat(fname, /linux,kernel-end); - file = fopen(fname, r); - if (!file) { - perror(fname); - goto error_opencdir; - } - if (fread(tmp_long, sizeof(unsigned long), 1, file) - != 1) { - perror(fname); - goto error_openfile; - } - kernel_end = tmp_long; - fclose(file); - - /* Add kernel memory to exclude_range */ - exclude_range[i].start = 0x0UL; - exclude_range[i].end = kernel_end; - i++; - if (i = max_memory_ranges) - realloc_memory_ranges(); + /* only reserve kernel region if we are doing a crash kernel */ if (kexec_flags KEXEC_ON_CRASH) { + strcat(fname, /linux,kernel-end); + file = fopen(fname, r); + if (!file) { + perror(fname); + goto error_opencdir; + } + if (fread(tmp_long, sizeof(unsigned long), 1, file) + != 1) { + perror(fname); + goto error_openfile; + } + kernel_end = tmp_long; + fclose(file); + + /* Add kernel memory to exclude_range */ + exclude_range[i].start = 0x0UL; + exclude_range[i].end = kernel_end; + i++; + if (i = max_memory_ranges) + realloc_memory_ranges(); memset(fname, 0, sizeof(fname)); strcpy(fname, device_tree); strcat(fname, dentry-d_name); diff --git a/kexec/arch/ppc/kexec-uImage-ppc.c b/kexec/arch/ppc/kexec-uImage-ppc.c index 45cde2f..4a8d28d 100644 --- a/kexec/arch/ppc/kexec
[PATCH v2 2/7] Fix case where phys_addr_t != unsigned long when reading proc entries
On some actitectures the physical memory can be 64 bits, therefore the code that reads proc entries needs to take into account it could read either a 32 bit or 64bit value for the physical addresses. Signed-off-by: Matthew McClintock m...@freescale.com --- kexec/arch/ppc/kexec-elf-ppc.c |1 - kexec/arch/ppc/kexec-ppc.c | 210 kexec/arch/ppc/kexec-ppc.h |1 + 3 files changed, 148 insertions(+), 64 deletions(-) diff --git a/kexec/arch/ppc/kexec-elf-ppc.c b/kexec/arch/ppc/kexec-elf-ppc.c index d155bde..ab2d343 100644 --- a/kexec/arch/ppc/kexec-elf-ppc.c +++ b/kexec/arch/ppc/kexec-elf-ppc.c @@ -32,7 +32,6 @@ static const int probe_debug = 0; -unsigned long long initrd_base, initrd_size; unsigned char reuse_initrd; const char *ramdisk; int create_flatten_tree(struct kexec_info *, unsigned char **, unsigned long *, diff --git a/kexec/arch/ppc/kexec-ppc.c b/kexec/arch/ppc/kexec-ppc.c index c073f56..d7afad6 100644 --- a/kexec/arch/ppc/kexec-ppc.c +++ b/kexec/arch/ppc/kexec-ppc.c @@ -28,6 +28,8 @@ uint64_t rmo_top; unsigned long long crash_base, crash_size; +unsigned long long initrd_base, initrd_size; +unsigned long long devicetree_base, devicetree_size; unsigned int rtas_base, rtas_size; int max_memory_ranges; @@ -320,9 +322,7 @@ static int get_devtree_details(unsigned long kexec_flags) DIR *dir, *cdir; FILE *file; struct dirent *dentry; - struct stat fstat; int n, i = 0; - unsigned long tmp_long; if ((dir = opendir(device_tree)) == NULL) { perror(device_tree); @@ -352,12 +352,18 @@ static int get_devtree_details(unsigned long kexec_flags) perror(fname); goto error_opencdir; } - if (fread(tmp_long, sizeof(unsigned long), 1, file) - != 1) { + if ((n = fread(buf, 1, MAXBYTES, file)) 0) { perror(fname); goto error_openfile; } - kernel_end = tmp_long; + if (n == 4) { + kernel_end = ((uint32_t *)buf)[0]; + } else if (n == 8) { + kernel_end = ((uint64_t *)buf)[0]; + } else { + fprintf(stderr, %s node has invalid size: %d\n, fname, n); + goto error_openfile; + } fclose(file); /* Add kernel memory to exclude_range */ @@ -375,12 +381,18 @@ static int get_devtree_details(unsigned long kexec_flags) perror(fname); goto error_opencdir; } - if (fread(tmp_long, sizeof(unsigned long), 1, - file) != 1) { + if ((n = fread(buf, 1, MAXBYTES, file)) 0) { perror(fname); goto error_openfile; } - crash_base = tmp_long; + if (n == 4) { + crash_base = ((uint32_t *)buf)[0]; + } else if (n == 8) { + crash_base = ((uint64_t *)buf)[0]; + } else { + fprintf(stderr, %s node has invalid size: %d\n, fname, n); + goto error_openfile; + } fclose(file); memset(fname, 0, sizeof(fname)); @@ -392,12 +404,19 @@ static int get_devtree_details(unsigned long kexec_flags) perror(fname); goto error_opencdir; } - if (fread(tmp_long, sizeof(unsigned long), 1, - file) != 1) { + if ((n = fread(buf, 1, MAXBYTES, file)) 0) { perror(fname); goto error_openfile; } - crash_size = tmp_long; + if (n == 4) { + crash_size = ((uint32_t *)buf)[0]; + } else if (n == 8
Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
On Jul 17, 2010, at 11:41 AM, Segher Boessenkool wrote: Yes. Where would we get a list of memreserve sections? I would say the list of reserves that are not under the control of Linux should be explicitly described in the device tree proper. For instance, if you have a region that firmware depends on, then have a node for describing the firmware and a property stating the memory regions that it depends on. The memreserve regions can be generated from that. Ok, so we could traverse the tree node-by-bode for a persistent-memreserve property and add them to the /memreserve/ list in the kexec user space tools? I *think* that is okay, but I'd like to hear from Segher, Ben, Mitch, David Gibson, and other device tree experts on whether or not that exact property naming is a good one. Let's take a step back: what exactly _are_ memreserve sections, what are they used for, who (kernel, firmware, bootloader, etc.) holds what responsibility wrt them? On the platform I'm working on (mpc85xx) they can be the following: 1) Boot page (aka cpu-release-addr) - always present on MP 2) Flat Device Tree - always present 3) Initrd - optional When kexec'ing a kernel, we will provide new memory regions for the flat device tree and the initrd (if present). However, all others will not be replaced by kexec and should either be tossed or preserved. The question is how to decide what to do... save them all by default? Save none of them? If we save them all at a minimum we need to remove/replace the device tree and initrd regions as well. So we need a way to identify which regions correspond to these. Grant and I talked and though a property that lives in the device tree describing a persistant-memreseve might work. And Mitch talked about an available memory property to go along with the current one which could be used to determine which ranges were invalid and need a memreserve for... -Matthew Segher ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
On Jul 18, 2010, at 6:41 PM, Benjamin Herrenschmidt wrote: On Thu, 2010-07-15 at 00:21 -0600, Grant Likely wrote: On Wed, Jul 14, 2010 at 9:18 AM, Matthew McClintock m...@freescale.com wrote: To build a proper flat device tree for kexec we need to know which memreserve region was used for the device tree for the currently running kernel, so we can remove it and replace it with the new memreserve for the kexec'ed kernel Signed-off-by: Matthew McClintock m...@freescale.com Hi Matthew. I don't understand. Why does userspace need to know about the old memreserve sections? Doesn't kexec tear down all of the old allocations anyway? How are they relevant for constructing the dtb for the kexec kernel? I'll need a lot more details before I consider merging this. Also, please cc: me and Ben Herrenschmidt on powerpc related device tree changes. I admit to be the victim of a similar misunderstanding... Care to explain in more details ? (with examples) Upon first examining the details of getting kexec working on our platform I noticed our device tree passed from u-boot contained an additional memreserve section for the boot page. Subsequently, I've been trying to preserve the ones passed in for the kexec'ed kernel thinking anyone could add anything they wanted for their own particular needs and would quite possibly need those regions preserved across reboots. Recently, I've discovered the boot page address is given in the device tree as a property. So, for our platform (mpc85xx) in particular, I'm back to not needing the read the old memreserve sections... I can completely reconstruct the appropriate memreserve regions for kexec'ing from the information passed in the device tree. That isn't to say there might not be more memreserve regions that are not there for some valid reason. I'm not sure if we need to attempt to address another scenario where there are other memreserve regions. So this would be a good time to address this issue if anyone believes it is a worthwhile pursuit to have a mechanism to have memreserve regions persistent across kexec'ing - or any other reboot. -Matthew Cheers, Ben. Cheers, g. --- V4: Fixed misspelling V3: Remove unneeded cast, and fixed indentation screw up V2: messed up changes arch/powerpc/kernel/prom.c | 45 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index fd9359a..ff3e240 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -32,6 +32,7 @@ #include linux/debugfs.h #include linux/irq.h #include linux/lmb.h +#include linux/bootmem.h #include asm/prom.h #include asm/rtas.h @@ -911,3 +912,47 @@ static int __init export_flat_device_tree(void) } __initcall(export_flat_device_tree); #endif + +#ifdef CONFIG_KEXEC +static phys_addr_t flat_dt_start; +static phys_addr_t flat_dt_end; + +static struct property flat_dt_start_prop = { + .name = linux,devicetree-start, + .length = sizeof(phys_addr_t), + .value = flat_dt_start, +}; + +static struct property flat_dt_end_prop = { + .name = linux,devicetree-end, + .length = sizeof(phys_addr_t), + .value = flat_dt_end, +}; + +static int __init export_flat_device_tree_phys_addr(void) +{ + struct property *prop; + struct device_node *node; + + node = of_find_node_by_path(/chosen); + if (!node) + return -ENOENT; + + prop = of_find_property(node, linux,devicetree-start, NULL); + if (prop) + prom_remove_property(node, prop); + + prop = of_find_property(node, linux,devicetree-end, NULL); + if (prop) + prom_remove_property(node, prop); + + flat_dt_start = virt_to_phys(initial_boot_params); + flat_dt_end = virt_to_phys(initial_boot_params) + + initial_boot_params-totalsize; + prom_add_property(node, flat_dt_start_prop); + prom_add_property(node, flat_dt_end_prop); + + return 0; +} +__initcall(export_flat_device_tree_phys_addr); +#endif -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
On Jul 18, 2010, at 7:09 PM, Benjamin Herrenschmidt wrote: On Thu, 2010-07-15 at 10:22 -0600, Grant Likely wrote: What is your starting point? Where does the device tree (and memreserve list) come from that you're passing to kexec? My first impression is that if you have to scrub the memreserve list, then the source being used to obtain the memreserves is either faulty or unsuitable to the task. The kernel should ultimately pass the thing to userspace I reckon, with an appropriate hook for platform code to insert/recover reserved regions. Or possibly in the device tree itself? As I mentioned in my previous email - my particular case can already be handled by the information passed in the device tree (as I recently discovered), is this something we would want to make generic for the device tree or add platform code to expose these memreserve regions? -Matthew ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
On Wed, 2010-07-14 at 17:46 +0200, Segher Boessenkool wrote: What about just one node called flat-device-tree? But *what* flat device tree? It cannot be the flat device tree, or it would be useless information, since we are already reading it! I thought about it all day and did not come up with anything terribly insightful... boot-fdt-phys-addr fdt-phys-addr boot-fdt-phys-reg fdt-phys-addr-reg Thoughts? -M ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
On Thu, 2010-07-15 at 00:21 -0600, Grant Likely wrote: On Wed, Jul 14, 2010 at 9:18 AM, Matthew McClintock m...@freescale.com wrote: To build a proper flat device tree for kexec we need to know which memreserve region was used for the device tree for the currently running kernel, so we can remove it and replace it with the new memreserve for the kexec'ed kernel Signed-off-by: Matthew McClintock m...@freescale.com Hi Matthew. I don't understand. Why does userspace need to know about the old memreserve sections? Doesn't kexec tear down all of the old allocations anyway? How are they relevant for constructing the dtb for the kexec kernel? I'll need a lot more details before I consider merging this. Also, please cc: me and Ben Herrenschmidt on powerpc related device tree changes. Cheers, g. Grant, Thanks for taking a look. My first thought was to just blow away all the memreserve regions and start over. But, there are reserve regions for other things that I might not want to blow away. For example, on mpc85xx SMP systems we have an additional reserve region for our boot page. There is already precedence for exporting the initrd physical addresses in the same fashion, which is mostly why I took this route. So instead I just choose to find and replace the device tree and initrd reserve regions. I'm open to other ideas, just let me know. Regards, Matthew ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
On Thu, 2010-07-15 at 10:22 -0600, Grant Likely wrote: Thanks for taking a look. My first thought was to just blow away all the memreserve regions and start over. But, there are reserve regions for other things that I might not want to blow away. For example, on mpc85xx SMP systems we have an additional reserve region for our boot page. What is your starting point? Where does the device tree (and memreserve list) come from that you're passing to kexec? My first impression is that if you have to scrub the memreserve list, then the source being used to obtain the memreserves is either faulty or unsuitable to the task. I'm pulling the device tree passed in via u-boot and passing it to kexec. It is the most complete device tree and requires the least amount of fixup. I have to scrub two items, the ramdisk/initrd and the device tree because upon kexec'ing the kernel we have the ability to pass in new ramdisk/initrd and device tree. They can also live at different physical addresses for the second reboot. The initrd addresses are already exposed, so we can update/remove/reuse that entry, we just need a way for kexec to determine the current device tree address so it can replace the correct memreserve region for the kexec'ing kernels' device tree. The whole problem comes from repeatedly kexec'ing, we need to make sure we don't keep losing blobs of memory to reserve regions (so we can't just blindly add). We also need to make sure we don't lose other memreserve regions that might be important for other things (so we can't just blow them all away). -M ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
On Thu, 2010-07-15 at 10:57 -0600, Grant Likely wrote: On Thu, Jul 15, 2010 at 10:39 AM, Matthew McClintock m...@freescale.com wrote: On Thu, 2010-07-15 at 10:22 -0600, Grant Likely wrote: Thanks for taking a look. My first thought was to just blow away all the memreserve regions and start over. But, there are reserve regions for other things that I might not want to blow away. For example, on mpc85xx SMP systems we have an additional reserve region for our boot page. What is your starting point? Where does the device tree (and memreserve list) come from that you're passing to kexec? My first impression is that if you have to scrub the memreserve list, then the source being used to obtain the memreserves is either faulty or unsuitable to the task. I'm pulling the device tree passed in via u-boot and passing it to kexec. How? (what mechanism?) I hope you're not using the debugfs flat-device-tree file. That is one way to get a good working copy. What is wrong with this mechanism? Should we duplicate everything u-boot does in kexec to build up a flat device tree? Or is there another way to get a good tree? Ideally, we don't make the end user manually edit a device tree. It is the most complete device tree and requires the least amount of fixup. I have to scrub two items, the ramdisk/initrd and the device tree because upon kexec'ing the kernel we have the ability to pass in new ramdisk/initrd and device tree. They can also live at different physical addresses for the second reboot. This sounds like the model is backwards. Rather than scrubbing items, the memreserve list should be built up from a known good source. You can build one up yourself and it will still work out fine. Or you can pull one from debugfs to get yourself started. Or you can pull it every time. The initrd addresses are already exposed, so we can update/remove/reuse that entry, we just need a way for kexec to determine the current device tree address so it can replace the correct memreserve region for the kexec'ing kernels' device tree. The whole problem comes from repeatedly kexec'ing, we need to make sure we don't keep losing blobs of memory to reserve regions (so we can't just blindly add). We also need to make sure we don't lose other memreserve regions that might be important for other things (so we can't just blow them all away). Right, so you need to have a known-good list of reserve sections. Trying to go the other way sounds very fragile. Yes. Where would we get a list of memreserve sections? Should we export the reserve sections instead of the device tree location? We just need a way to preserve what was there at boot to pass to the new kernel. -M ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
On Thu, 2010-07-15 at 12:37 -0600, Grant Likely wrote: On Thu, Jul 15, 2010 at 12:03 PM, Matthew McClintock m...@freescale.com wrote: On Thu, 2010-07-15 at 10:57 -0600, Grant Likely wrote: On Thu, Jul 15, 2010 at 10:39 AM, Matthew McClintock m...@freescale.com wrote: On Thu, 2010-07-15 at 10:22 -0600, Grant Likely wrote: Thanks for taking a look. My first thought was to just blow away all the memreserve regions and start over. But, there are reserve regions for other things that I might not want to blow away. For example, on mpc85xx SMP systems we have an additional reserve region for our boot page. What is your starting point? Where does the device tree (and memreserve list) come from that you're passing to kexec? My first impression is that if you have to scrub the memreserve list, then the source being used to obtain the memreserves is either faulty or unsuitable to the task. I'm pulling the device tree passed in via u-boot and passing it to kexec. How? (what mechanism?) I hope you're not using the debugfs flat-device-tree file. That is one way to get a good working copy. What is wrong with this mechanism? It's unstable. It is in the debugfs, so there are no guarantees that the ABI will remain the same. Plus it doesn't reflect any changes that the kernel may make to the device tree. That interface is *debug only*. Do not use it. Ok. Should we duplicate everything u-boot does in kexec to build up a flat device tree? Or is there another way to get a good tree? That is one option. U-Boot really shouldn't be modifying the tree very much anyway (I know on some platforms U-Boot is almost creating a tree from scratch, but that is insane and an entirely different discussion). /proc/device-tree always gives the kernel's current view of the tree. You can use dtc to extract it and write it into a dtb. Ok wow, I've missed this completely. dtc to extract the device tree is a very good option. I will pursue that line of thinking. Ideally, we don't make the end user manually edit a device tree. Of course not, any device tree manipulation is the job of the kexec tools. None of this should be manual. However, the data source is a significant and important question. Ideally, we don't duplicate this in kexec and u-boot. Right now there is nothing specific for say mpc85xx in kexec it's just ppc32. I would prefer it stay this way. It is the most complete device tree and requires the least amount of fixup. I have to scrub two items, the ramdisk/initrd and the device tree because upon kexec'ing the kernel we have the ability to pass in new ramdisk/initrd and device tree. They can also live at different physical addresses for the second reboot. This sounds like the model is backwards. Rather than scrubbing items, the memreserve list should be built up from a known good source. You can build one up yourself and it will still work out fine. Or you can pull one from debugfs to get yourself started. Or you can pull it every time. What do you mean by pull it every time? Exactly what you are saying is bad to do ;-P. Pull it from debugfs. But the above dts -I fs solution practically fixes that issue. Out of curiosity, what is responsible for building up the memreserve list? The userspace portion, or the kernel portion of kexec? Or is it done by a totally separate program? Currently, neither. I have submitted patches for the user space tool to fixup the memreserve regions. The initrd addresses are already exposed, so we can update/remove/reuse that entry, we just need a way for kexec to determine the current device tree address so it can replace the correct memreserve region for the kexec'ing kernels' device tree. The whole problem comes from repeatedly kexec'ing, we need to make sure we don't keep losing blobs of memory to reserve regions (so we can't just blindly add). We also need to make sure we don't lose other memreserve regions that might be important for other things (so we can't just blow them all away). Right, so you need to have a known-good list of reserve sections. Trying to go the other way sounds very fragile. Yes. Where would we get a list of memreserve sections? I would say the list of reserves that are not under the control of Linux should be explicitly described in the device tree proper. For instance, if you have a region that firmware depends on, then have a node for describing the firmware and a property stating the memory regions that it depends on. The memreserve regions can be generated from that. Ok, so we could traverse the tree node-by-bode for a persistent-memreserve property and add them to the /memreserve/ list in the kexec user space tools? Should we export the reserve sections instead of the device tree location? It shouldn't really be something that the kernel
[PATCH V4] powerpc/prom: Export device tree physical address via proc
To build a proper flat device tree for kexec we need to know which memreserve region was used for the device tree for the currently running kernel, so we can remove it and replace it with the new memreserve for the kexec'ed kernel Signed-off-by: Matthew McClintock m...@freescale.com --- V4: Fixed misspelling V3: Remove unneeded cast, and fixed indentation screw up V2: messed up changes arch/powerpc/kernel/prom.c | 45 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index fd9359a..ff3e240 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -32,6 +32,7 @@ #include linux/debugfs.h #include linux/irq.h #include linux/lmb.h +#include linux/bootmem.h #include asm/prom.h #include asm/rtas.h @@ -911,3 +912,47 @@ static int __init export_flat_device_tree(void) } __initcall(export_flat_device_tree); #endif + +#ifdef CONFIG_KEXEC +static phys_addr_t flat_dt_start; +static phys_addr_t flat_dt_end; + +static struct property flat_dt_start_prop = { + .name = linux,devicetree-start, + .length = sizeof(phys_addr_t), + .value = flat_dt_start, +}; + +static struct property flat_dt_end_prop = { + .name = linux,devicetree-end, + .length = sizeof(phys_addr_t), + .value = flat_dt_end, +}; + +static int __init export_flat_device_tree_phys_addr(void) +{ + struct property *prop; + struct device_node *node; + + node = of_find_node_by_path(/chosen); + if (!node) + return -ENOENT; + + prop = of_find_property(node, linux,devicetree-start, NULL); + if (prop) + prom_remove_property(node, prop); + + prop = of_find_property(node, linux,devicetree-end, NULL); + if (prop) + prom_remove_property(node, prop); + + flat_dt_start = virt_to_phys(initial_boot_params); + flat_dt_end = virt_to_phys(initial_boot_params) + + initial_boot_params-totalsize; + prom_add_property(node, flat_dt_start_prop); + prom_add_property(node, flat_dt_end_prop); + + return 0; +} +__initcall(export_flat_device_tree_phys_addr); +#endif -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH V4] powerpc/prom: Export device tree physical address via proc
On Wed, 2010-07-14 at 17:35 +0200, Segher Boessenkool wrote: V4: Fixed misspelling Any particular reason you fixed only one of the two mispelings I pointed out? (device tree is two words, not one). Ahh, my fault. + prop = of_find_property(node, linux,devicetree-start, NULL); + if (prop) + prom_remove_property(node, prop); + + prop = of_find_property(node, linux,devicetree-end, NULL); + if (prop) + prom_remove_property(node, prop); + + flat_dt_start = virt_to_phys(initial_boot_params); + flat_dt_end = virt_to_phys(initial_boot_params) + + initial_boot_params-totalsize; + prom_add_property(node, flat_dt_start_prop); + prom_add_property(node, flat_dt_end_prop); You could use one property instead of two; use addr+len like every other property does. You also should use a better name for the property; is this the previous kernel's device tree? Just device-tree makes no sense, it is not pointing to the device tree for sure! What about just one node called flat-device-tree? -Matthew ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc:prom Export device tree physical address via proc
To build a proper flat device tree for kexec we need to know which memreserve region was used for the device tree for the currently running kernel, so we can remove it and replace it with the new memreserve for the kexec'ed kernel Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/kernel/prom.c | 44 1 files changed, 44 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index fd9359a..6a8400e 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -32,6 +32,7 @@ #include linux/debugfs.h #include linux/irq.h #include linux/lmb.h +#include linux/bootmem.h #include asm/prom.h #include asm/rtas.h @@ -911,3 +912,46 @@ static int __init export_flat_device_tree(void) } __initcall(export_flat_device_tree); #endif + +#ifdef CONFIG_KEXEC +static phys_addr_t flat_dt_start; +static phys_addr_t flat_dt_end; + +static struct property flat_dt_start_prop = { + .name = linux,devicetree-start, + .length = sizeof(phys_addr_t), + .value = flat_dt_start, +}; + +static struct property flat_dt_end_prop = { + .name = linux,devicetree-end, + .length = sizeof(phys_addr_t), + .value = flat_dt_end, +}; + +static int __init export_flat_device_tree_phys_addr(void) +{ + struct property *prop; + struct device_node *node; + + node = of_find_node_by_path(/chosen); + if (!node) + return -ENOENT; + + prop = of_find_property(node, linux,devicetree-start, NULL); + if (prop) + prom_remove_property(node, prop); + prop = of_find_property(node, linux,devietree-end, NULL); + if (prop) + prom_remove_property(node, prop); + + flat_dt_start = (unsigned long)virt_to_phys(initial_boot_params); + flat_dt_end = (unsigned long)virt_to_phys(initial_boot_params) + + initial_boot_params-totalsize; + prom_add_property(node, flat_dt_start_prop); + prom_add_property(node, flat_dt_end_prop); + + return 0; +} +__initcall(export_flat_device_tree_phys_addr); +#endif -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V2] powerpc:prom Export device tree physical address via proc
To build a proper flat device tree for kexec we need to know which memreserve region was used for the device tree for the currently running kernel, so we can remove it and replace it with the new memreserve for the kexec'ed kernel Signed-off-by: Matthew McClintock m...@freescale.com --- Removed unneeded cast, and fixed indentation screwup arch/powerpc/kernel/prom.c | 44 1 files changed, 44 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index fd9359a..6a8400e 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -32,6 +32,7 @@ #include linux/debugfs.h #include linux/irq.h #include linux/lmb.h +#include linux/bootmem.h #include asm/prom.h #include asm/rtas.h @@ -911,3 +912,46 @@ static int __init export_flat_device_tree(void) } __initcall(export_flat_device_tree); #endif + +#ifdef CONFIG_KEXEC +static phys_addr_t flat_dt_start; +static phys_addr_t flat_dt_end; + +static struct property flat_dt_start_prop = { + .name = linux,devicetree-start, + .length = sizeof(phys_addr_t), + .value = flat_dt_start, +}; + +static struct property flat_dt_end_prop = { + .name = linux,devicetree-end, + .length = sizeof(phys_addr_t), + .value = flat_dt_end, +}; + +static int __init export_flat_device_tree_phys_addr(void) +{ + struct property *prop; + struct device_node *node; + + node = of_find_node_by_path(/chosen); + if (!node) + return -ENOENT; + + prop = of_find_property(node, linux,devicetree-start, NULL); + if (prop) + prom_remove_property(node, prop); + prop = of_find_property(node, linux,devietree-end, NULL); + if (prop) + prom_remove_property(node, prop); + + flat_dt_start = (unsigned long)virt_to_phys(initial_boot_params); + flat_dt_end = (unsigned long)virt_to_phys(initial_boot_params) + + initial_boot_params-totalsize; + prom_add_property(node, flat_dt_start_prop); + prom_add_property(node, flat_dt_end_prop); + + return 0; +} +__initcall(export_flat_device_tree_phys_addr); +#endif -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V3] powerpc:prom Export device tree physical address via proc
To build a proper flat device tree for kexec we need to know which memreserve region was used for the device tree for the currently running kernel, so we can remove it and replace it with the new memreserve for the kexec'ed kernel Signed-off-by: Matthew McClintock m...@freescale.com --- V3: Remove unneeded cast, and fixed indentation screw up V2: messed up changes arch/powerpc/kernel/prom.c | 45 1 files changed, 45 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index fd9359a..79c1f35 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -32,6 +32,7 @@ #include linux/debugfs.h #include linux/irq.h #include linux/lmb.h +#include linux/bootmem.h #include asm/prom.h #include asm/rtas.h @@ -911,3 +912,47 @@ static int __init export_flat_device_tree(void) } __initcall(export_flat_device_tree); #endif + +#ifdef CONFIG_KEXEC +static phys_addr_t flat_dt_start; +static phys_addr_t flat_dt_end; + +static struct property flat_dt_start_prop = { + .name = linux,devicetree-start, + .length = sizeof(phys_addr_t), + .value = flat_dt_start, +}; + +static struct property flat_dt_end_prop = { + .name = linux,devicetree-end, + .length = sizeof(phys_addr_t), + .value = flat_dt_end, +}; + +static int __init export_flat_device_tree_phys_addr(void) +{ + struct property *prop; + struct device_node *node; + + node = of_find_node_by_path(/chosen); + if (!node) + return -ENOENT; + + prop = of_find_property(node, linux,devicetree-start, NULL); + if (prop) + prom_remove_property(node, prop); + + prop = of_find_property(node, linux,devietree-end, NULL); + if (prop) + prom_remove_property(node, prop); + + flat_dt_start = virt_to_phys(initial_boot_params); + flat_dt_end = virt_to_phys(initial_boot_params) + + initial_boot_params-totalsize; + prom_add_property(node, flat_dt_start_prop); + prom_add_property(node, flat_dt_end_prop); + + return 0; +} +__initcall(export_flat_device_tree_phys_addr); +#endif -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [1/2] powerpc/crashdump: Fix issues with kexec and 36bit physical addr
On Thu, 2010-07-08 at 04:07 -0500, Milton Miller wrote: On Wed, 07 Jul 2010 around 10:51:20 - Matthew McClintock wrote: Fix sizes of variables so correct values are exported via /proc. Cast variable in comparison to avoid compiler error. Signed-off-by: Matthew McClintock m...@freescale.com - csize = min(csize, PAGE_SIZE); + csize = min(csize, (size_t)PAGE_SIZE); no use min_t Ok - if (pfn max_pfn) { + if ((min_low_pfn pfn) (pfn max_pfn)) { vaddr = __va(pfn PAGE_SHIFT); csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); } else { diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index bb3d893..ec7f054 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -145,6 +145,7 @@ int overlaps_crashkernel(unsigned long start, unsigned long size) /* Values we need to export to the second kernel via the device tree. */ static unsigned long kernel_end; +static unsigned long crashk_start; static unsigned long crashk_size; static struct property kernel_end_prop = { @@ -156,7 +157,7 @@ static struct property kernel_end_prop = { static struct property crashk_base_prop = { .name = linux,crashkernel-base, .length = sizeof(unsigned long), - .value = crashk_res.start, + .value = crashk_start, }; This is wrong, its truncating the start and size. Change the variables to be physaddr_t and the length to be sizeof(physaddr_t). Since these properites only contain one variable, the number of cells can be inferred from the property size like we do for reading the initrd-size. Technically they should be an array of be32 but we can make that a comment. I don't disagree but this can break kexec if phys_addr_t != unsigned long. Also, doesn't the crash kernel have to live below 2GB so unsigned long is always fine? Will still change unless I hear otherwise. By the way, why does 32 bit care about the running kernel's size? aka linux,kernel-end? 64 bit book 3S needs it because we use mmu hooks to copy the pages to their destination, but I thought ppc32 was using a relocatable copy routine. Are we missing the code to create temp ref tlbs on the fly for book 3E? This is not really in this patch or did I miss something? Kexec uses kernel-end just to add as a invalid region. Not crucial though for 32 bit. static struct property crashk_size_prop = { @@ -180,6 +181,7 @@ static void __init export_crashk_values(struct device_node *node) prom_remove_property(node, prop); if (crashk_res.start != 0) { + crashk_start = crashk_res.start; prom_add_property(node, crashk_base_prop); crashk_size = crashk_res.end - crashk_res.start + 1; prom_add_property(node, crashk_size_prop); I guess we use the reuse of the resources varables, but such is common code vs userspace. milton ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [1/2] powerpc/crashdump: Fix issues with kexec and 36bit physical addr
On Fri, 2010-07-09 at 15:18 -0500, Milton Miller wrote: I don't disagree but this can break kexec if phys_addr_t != unsigned long. Also, doesn't the crash kernel have to live below 2GB so unsigned long is always fine? Its could only break kexec for the case of phys_addr_t != unsigned long which you are fixing, and its the right way to fix it. There is nothing inherent in linux requiring the crash kernel to be below 2G, although there may be limitations of the current kernel that require such a limit. Fair enough. This will be updated in the next patch. Will still change unless I hear otherwise. By the way, why does 32 bit care about the running kernel's size? aka linux,kernel-end? 64 bit book 3S needs it because we use mmu hooks to copy the pages to their destination, but I thought ppc32 was using a relocatable copy routine. Are we missing the code to create temp ref tlbs on the fly for book 3E? This is not really in this patch or did I miss something? Kexec uses kernel-end just to add as a invalid region. Not crucial though for 32 bit. No its not in this patch, hence By the way. I figured you might have some knowledge as you were working in this area. If there is no reason to have the kernel region blocked for 32 bit, then it should be removed. Obviously from kexec-tools first, and then after some time we could move its export to be only for 64-bit (or only 64 bit book-3S?) As far as I can tell it's just used as an exclusion range. It's only applicable for a crash kernel to make sure your crashkernel=...@xxm does not overlap with the current kernel. Seems like it might not be needed. It only causes additional time for traditional, and memory fragmentation for book 3E, if you disallow memory below the current kernel end. For that matter, on 3E, does this limit creep as you repeatedly reboot? For a crash kernel it does not matter as you stick with the reserved region. For kexec proper the current kexec HEAD disallows loading from 0x0-kernelend but I think that is wrong and needs to be modified for at least some platforms. So, basically you can't load too the currently running kernel address, and you can't even restart but I have not tried a different address. I submitted a patch a while back to change that behavior for kexec-uImage targets and have more working coming soon which will need to be reviewed as well for kexec-elf targets. -Matthew ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/2] powerpc/crashdump: Fix issues with kexec and 36bit physical addr
Fix sizes of variables so correct values are exported via /proc. Cast variable in comparison to avoid compiler error. Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/kernel/crash_dump.c|4 ++-- arch/powerpc/kernel/machine_kexec.c | 10 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 5fb667a..d254132 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -128,9 +128,9 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, if (!csize) return 0; - csize = min(csize, PAGE_SIZE); + csize = min_t(size_t, csize, PAGE_SIZE); - if (pfn max_pfn) { + if ((min_low_pfn pfn) (pfn max_pfn)) { vaddr = __va(pfn PAGE_SHIFT); csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); } else { diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index bb3d893..6ff15f0 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -144,24 +144,24 @@ int overlaps_crashkernel(unsigned long start, unsigned long size) } /* Values we need to export to the second kernel via the device tree. */ -static unsigned long kernel_end; -static unsigned long crashk_size; +static phys_addr_t kernel_end; +static phys_addr_t crashk_size; static struct property kernel_end_prop = { .name = linux,kernel-end, - .length = sizeof(unsigned long), + .length = sizeof(phys_addr_t), .value = kernel_end, }; static struct property crashk_base_prop = { .name = linux,crashkernel-base, - .length = sizeof(unsigned long), + .length = sizeof(phys_addr_t), .value = crashk_res.start, }; static struct property crashk_size_prop = { .name = linux,crashkernel-size, - .length = sizeof(unsigned long), + .length = sizeof(phys_addr_t), .value = crashk_size, }; -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/2] powerpc/booke: Enable building of a crash dump kernel
Enable building crash dump kernel as well as expose the flat device tree for kexec to update to boot the crash kernel --- arch/powerpc/Kconfig |2 +- arch/powerpc/kernel/prom.c |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 042f2f0..0b60c57 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -368,7 +368,7 @@ config KEXEC config CRASH_DUMP bool Build a kdump crash kernel - depends on PPC64 || 6xx + depends on PPC64 || 6xx || FSL_BOOKE select RELOCATABLE if PPC64 help Build a kernel suitable for use as a kdump capture kernel. diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 05131d6..fd9359a 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -892,7 +892,7 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) } EXPORT_SYMBOL(of_get_cpu_node); -#if defined(CONFIG_DEBUG_FS) defined(DEBUG) +#if defined(CONFIG_DEBUG_FS) (defined(DEBUG) || defined(CONFIG_KEXEC)) static struct debugfs_blob_wrapper flat_dt_blob; static int __init export_flat_device_tree(void) -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/2] powerpc/crashdump: Fix issues with kexec and 36bit physical addr
Fix sizes of variables so correct values are exported via /proc. Cast variable in comparison to avoid compiler error. Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/kernel/crash_dump.c|4 ++-- arch/powerpc/kernel/machine_kexec.c |4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 5fb667a..71cadde 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -128,9 +128,9 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, if (!csize) return 0; - csize = min(csize, PAGE_SIZE); + csize = min(csize, (size_t)PAGE_SIZE); - if (pfn max_pfn) { + if ((min_low_pfn pfn) (pfn max_pfn)) { vaddr = __va(pfn PAGE_SHIFT); csize = copy_oldmem_vaddr(vaddr, buf, csize, offset, userbuf); } else { diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c index bb3d893..ec7f054 100644 --- a/arch/powerpc/kernel/machine_kexec.c +++ b/arch/powerpc/kernel/machine_kexec.c @@ -145,6 +145,7 @@ int overlaps_crashkernel(unsigned long start, unsigned long size) /* Values we need to export to the second kernel via the device tree. */ static unsigned long kernel_end; +static unsigned long crashk_start; static unsigned long crashk_size; static struct property kernel_end_prop = { @@ -156,7 +157,7 @@ static struct property kernel_end_prop = { static struct property crashk_base_prop = { .name = linux,crashkernel-base, .length = sizeof(unsigned long), - .value = crashk_res.start, + .value = crashk_start, }; static struct property crashk_size_prop = { @@ -180,6 +181,7 @@ static void __init export_crashk_values(struct device_node *node) prom_remove_property(node, prop); if (crashk_res.start != 0) { + crashk_start = crashk_res.start; prom_add_property(node, crashk_base_prop); crashk_size = crashk_res.end - crashk_res.start + 1; prom_add_property(node, crashk_size_prop); -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/fsl-booke: Fix address issue when using relocatable kernels
When booting a relocatable kernel it needs to jump to the correct start address, which for BookE parts is usually unchanged regardless of the physical memory offset. Recent changes cause problems with how we calculate the start address, it was always adding the RMO into the start address which is incorrect. This patch only adds in the RMO offset if we are in the kexec code path, as it needs the RMO to work correctly. Instead of adding the RMO offset in in the common code path, we can just set r6 to the RMO offset in the kexec code path instead of to zero, and finally perform the masking in the common code path Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/kernel/fsl_booke_entry_mapping.S |4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S index beb4d78..a92c79b 100644 --- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S +++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S @@ -205,8 +205,7 @@ next_tlb_setup: bdnz+ next_tlb_setup /* 7. Jump to our 1:1 mapping */ - li r6, 0 - + mr r6, r25 #else #error You need to specify the mapping or not use this at all. #endif @@ -217,7 +216,6 @@ next_tlb_setup: 1: mflrr9 rlwimi r6,r9,0,20,31 addir6,r6,(2f - 1b) - add r6, r6, r25 mtspr SPRN_SRR0,r6 mtspr SPRN_SRR1,r7 rfi /* start execution out of TLB1[0] entry */ -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/2] powerpc/mpic: Add ability to reset a core via MPIC
We need the ability to reset cores for use with kexec/kdump for SMP systems. Calling this function with the specific core you want to reset will cause the CPU to spin in reset. Signed-off-by: Matthew McClintock m...@freescale.com --- arch/powerpc/sysdev/mpic.c | 18 ++ arch/powerpc/sysdev/mpic.h |1 + 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 20b73c0..7c13426 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1636,6 +1636,24 @@ void __devinit smp_mpic_setup_cpu(int cpu) { mpic_setup_this_cpu(); } + +void mpic_reset_core(int cpu) +{ + struct mpic *mpic = mpic_primary; + u32 pir; + int cpuid = get_hard_smp_processor_id(cpu); + + /* Set target bit for core reset */ + pir = mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); + pir |= (1 cpuid); + mpic_write(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); + mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); + + /* Restore target bit after reset complete */ + pir = ~(1 cpuid); + mpic_write(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir); + mpic_read(mpic-gregs, MPIC_INFO(GREG_PROCESSOR_INIT)); +} #endif /* CONFIG_SMP */ #ifdef CONFIG_PM diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h index eff433c..e4a6df7 100644 --- a/arch/powerpc/sysdev/mpic.h +++ b/arch/powerpc/sysdev/mpic.h @@ -37,5 +37,6 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic) extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type); extern void mpic_set_vector(unsigned int virq, unsigned int vector); extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask); +extern void mpic_reset_core(int cpu); #endif /* _POWERPC_SYSDEV_MPIC_H */ -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/2] powerpc/85xx platorms: kexec for SMP 85xx BookE systems
Adds support for kexec on 85xx machines for the BookE platform. Including support for SMP machines Based off work from Maxim Uvarov muva...@mvista.com Signed-off-by: Matthew McClintock m...@freescale.com --- To test/use you will need to fetch kexec from GIT and apply the following patch for kexec to work properply with uImages http://lists.infradead.org/pipermail/kexec/2010-June/004163.html arch/powerpc/Kconfig |2 +- arch/powerpc/platforms/85xx/smp.c | 57 + 2 files changed, 58 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 328774b..042f2f0 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -351,7 +351,7 @@ config ARCH_ENABLE_MEMORY_HOTREMOVE config KEXEC bool kexec system call (EXPERIMENTAL) - depends on (PPC_BOOK3S || (FSL_BOOKE !SMP)) EXPERIMENTAL + depends on (PPC_BOOK3S || FSL_BOOKE) EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index a15f582..35c3d95 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -15,6 +15,7 @@ #include linux/init.h #include linux/delay.h #include linux/of.h +#include linux/kexec.h #include asm/machdep.h #include asm/pgtable.h @@ -24,6 +25,7 @@ #include asm/dbell.h #include sysdev/fsl_soc.h +#include sysdev/mpic.h extern void __early_start(void); @@ -103,8 +105,58 @@ smp_85xx_setup_cpu(int cpu_nr) struct smp_ops_t smp_85xx_ops = { .kick_cpu = smp_85xx_kick_cpu, +#ifdef CONFIG_KEXEC + .give_timebase = smp_generic_give_timebase, + .take_timebase = smp_generic_take_timebase, +#endif }; +#ifdef CONFIG_KEXEC +void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary) +{ + mpic_teardown_this_cpu(1); +} + +static int kexec_down_cpus = 0; + +static void mpc85xx_smp_kexec_down(void *arg) +{ + if (ppc_md.kexec_cpu_down) + ppc_md.kexec_cpu_down(0,1); + + local_irq_disable(); + kexec_down_cpus++; + while (1) ; +} + +static void mpc85xx_smp_machine_kexec(struct kimage *image) +{ + int timeout = 1000; + int i; + + set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); + + smp_call_function(mpc85xx_smp_kexec_down, NULL, 0); + + while ( (kexec_down_cpus != (num_present_cpus() - 1)) + ( timeout-- 0 ) ) + { + timeout--; + } + + if ( !timeout ) + printk(KERN_ERR Unable to bring down secondary cpu(s)); + + for (i = 0; i num_present_cpus(); i++) + { + if ( i == smp_processor_id() ) continue; + mpic_reset_core(i); + } + + default_machine_kexec(image); +} +#endif /* CONFIG_KEXEC */ + void __init mpc85xx_smp_init(void) { struct device_node *np; @@ -122,4 +174,9 @@ void __init mpc85xx_smp_init(void) BUG_ON(!smp_85xx_ops.message_pass); smp_ops = smp_85xx_ops; + +#ifdef CONFIG_KEXEC + ppc_md.kexec_cpu_down = mpc85xx_smp_kexec_cpu_down; + ppc_md.machine_kexec = mpc85xx_smp_machine_kexec; +#endif } -- 1.6.6.1 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev