Re: [RFC PATCH v1 1/1] powerpc/85xx: Wakeup kexec smp slave cpus in second kernel
On 08/31/2013 05:12 PM, Yu Chen wrote: >From 1ccf579b871dfd5938ce958f729361a203485c74 Mon Sep 17 00:00:00 2001 From: Yu Chen Date: Sat, 31 Aug 2013 23:52:31 +0800 Subject: [PATCH] powerpc/85xx: Wakeup kexec smp slave cpus in second kernel In current 85xx smp kexec implementation,master cpu reset slave cpus by mpic_reset_core, before jump to second kernel.In order to wake slave cpus up in second kernel,we debug this patch on p2041rdb. What problem causes that you do the modification? I am just curious as kexec feature always is fine on our P2041RDB board.:-) Wei The main principle of this patch,is to get slave cpus polling for flag to change, thus waiting for master cpu to set it with non-zero cpu number(see misc_32.S). This flag is placed in kexec control page,so it would not be overlapped when copying kimage. The master cpu put flag's physical address in r28 as a parameter passed to second kernel, so the latter knows how to wake slave cpus up in smp_85xx_kick_cpu. The pseudo-code may be like: void slave_cpu_spin(void) { int cpu = smp_processor_id(); while (*kexec_poll != cpu) ; /*slave wakeup and jump*/ jump(*(kexec_poll+1)); } void master_cpu_wakeup(unsigned long *kexec_poll, int cpu) { *(kexec_poll+1) = __early_start; mb(); *kexec_poll = cpu; } However,after applied this patch,we got some kernel exception during booting second kernel, I'm not sure if it's caused by improper treament of cache,or tlb,or other.So I put this patch here hoping someone can check and review it. Signed-off-by: Yu Chen --- arch/powerpc/kernel/head_fsl_booke.S |7 ++ arch/powerpc/kernel/misc_32.S| 66 +- arch/powerpc/platforms/85xx/smp.c| 166 ++ 3 files changed, 222 insertions(+), 17 deletions(-) mode change 100644 => 100755 arch/powerpc/kernel/head_fsl_booke.S mode change 100644 => 100755 arch/powerpc/kernel/misc_32.S mode change 100644 => 100755 arch/powerpc/platforms/85xx/smp.c diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S old mode 100644 new mode 100755 index d10a7ca..63c8392 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -178,6 +178,13 @@ _ENTRY(__early_start) * This is where the main kernel code starts. */ +#if defined(CONFIG_KEXEC) && defined(CONFIG_SMP) +/* r28 contain position where slave cpus spin*/ +lisr1,kexec_poll_phy@h +orir1,r1,kexec_poll_phy@l +stwr28,0(r1) +#endif + /* ptr to current */ lisr2,init_task@h orir2,r2,init_task@l diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S old mode 100644 new mode 100755 index e469f30..d9eefc2 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -120,7 +120,7 @@ _GLOBAL(reloc_got2) addir4,r4,1b@l subfr0,r4,r0 addr7,r0,r7 -2:lwzr0,0(r7) +2:lwzr0,0(r7) addr0,r0,r3 stwr0,0(r7) addir7,r7,4 @@ -692,6 +692,7 @@ _GLOBAL(__main) blr #ifdef CONFIG_KEXEC +#define KEXEC_MAGIC 0xdeadbeef /* * Must be relocatable PIC code callable as a C function. */ @@ -707,6 +708,16 @@ relocate_new_kernel: mrr30, r4 mrr31, r5 +#ifdef CONFIG_SMP +bl1f +1:mflrr8 +addir8,r8,kexec_flag-1b +lis r7,PAGE_OFFSET@h +ori r7,r7,PAGE_OFFSET@l +/*r28 contain slave cpu spin physical address */ +subfr28, r7, r8 +#endif + #define ENTRY_MAPPING_KEXEC_SETUP #include "fsl_booke_entry_mapping.S" #undef ENTRY_MAPPING_KEXEC_SETUP @@ -1172,4 +1183,57 @@ relocate_new_kernel_end: .globl relocate_new_kernel_size relocate_new_kernel_size: .long relocate_new_kernel_end - relocate_new_kernel +#ifdef CONFIG_FSL_BOOKE +/** +* Slave cpus wait for kexec_flag to change +*/ +.globl relocate_smp_cpu_offset +relocate_smp_cpu_offset: +.long relocate_smp_cpu_wait-relocate_new_kernel + +.globl relocate_smp_cpu_wait +relocate_smp_cpu_wait: + +bl1f +1:mflrr5 +addir5,r5,kexec_flag-1b +/*see if anyone calls me?*/ +mfspr r24,SPRN_PIR +99:lwzr4,4(r5) +cmpwr4,r24 +msync +bne99b + +msync +/*r4 contains jump address*/ +lwzr4,8(r5) +msync +lisr5,MSR_KERNEL@h +orir5,r5,MSR_KERNEL@l +msync +isync +mtsprSPRN_SRR1, r5 +mtsprSPRN_SRR0, r4 +msync +isync +rfi +isync +1:b1b + +/** +* kexec_flag indicates a kexec magic +* kexec_flag+4 bytes supposed to be set with cpu number +* kexec_flag+8 countain addr for slave cpu to jump into +*/ +.globl kexec_flag +kexec_flag: +.long KEXEC_MAGIC +.long0 +.long0 +relocate_smp_cpu_wait_end: +.globl relocate_smp_cpu_size
Re: [RFC PATCH v1 1/1] powerpc/85xx: Wakeup kexec smp slave cpus in second kernel
On 08/31/2013 05:12 PM, Yu Chen wrote: From 1ccf579b871dfd5938ce958f729361a203485c74 Mon Sep 17 00:00:00 2001 From: Yu Chen chenyu...@gmail.com Date: Sat, 31 Aug 2013 23:52:31 +0800 Subject: [PATCH] powerpc/85xx: Wakeup kexec smp slave cpus in second kernel In current 85xx smp kexec implementation,master cpu reset slave cpus by mpic_reset_core, before jump to second kernel.In order to wake slave cpus up in second kernel,we debug this patch on p2041rdb. What problem causes that you do the modification? I am just curious as kexec feature always is fine on our P2041RDB board.:-) Wei The main principle of this patch,is to get slave cpus polling for flag to change, thus waiting for master cpu to set it with non-zero cpu number(see misc_32.S). This flag is placed in kexec control page,so it would not be overlapped when copying kimage. The master cpu put flag's physical address in r28 as a parameter passed to second kernel, so the latter knows how to wake slave cpus up in smp_85xx_kick_cpu. The pseudo-code may be like: void slave_cpu_spin(void) { int cpu = smp_processor_id(); while (*kexec_poll != cpu) ; /*slave wakeup and jump*/ jump(*(kexec_poll+1)); } void master_cpu_wakeup(unsigned long *kexec_poll, int cpu) { *(kexec_poll+1) = __early_start; mb(); *kexec_poll = cpu; } However,after applied this patch,we got some kernel exception during booting second kernel, I'm not sure if it's caused by improper treament of cache,or tlb,or other.So I put this patch here hoping someone can check and review it. Signed-off-by: Yu Chen chenyu...@gmail.com --- arch/powerpc/kernel/head_fsl_booke.S |7 ++ arch/powerpc/kernel/misc_32.S| 66 +- arch/powerpc/platforms/85xx/smp.c| 166 ++ 3 files changed, 222 insertions(+), 17 deletions(-) mode change 100644 = 100755 arch/powerpc/kernel/head_fsl_booke.S mode change 100644 = 100755 arch/powerpc/kernel/misc_32.S mode change 100644 = 100755 arch/powerpc/platforms/85xx/smp.c diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S old mode 100644 new mode 100755 index d10a7ca..63c8392 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -178,6 +178,13 @@ _ENTRY(__early_start) * This is where the main kernel code starts. */ +#if defined(CONFIG_KEXEC) defined(CONFIG_SMP) +/* r28 contain position where slave cpus spin*/ +lisr1,kexec_poll_phy@h +orir1,r1,kexec_poll_phy@l +stwr28,0(r1) +#endif + /* ptr to current */ lisr2,init_task@h orir2,r2,init_task@l diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S old mode 100644 new mode 100755 index e469f30..d9eefc2 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -120,7 +120,7 @@ _GLOBAL(reloc_got2) addir4,r4,1b@l subfr0,r4,r0 addr7,r0,r7 -2:lwzr0,0(r7) +2:lwzr0,0(r7) addr0,r0,r3 stwr0,0(r7) addir7,r7,4 @@ -692,6 +692,7 @@ _GLOBAL(__main) blr #ifdef CONFIG_KEXEC +#define KEXEC_MAGIC 0xdeadbeef /* * Must be relocatable PIC code callable as a C function. */ @@ -707,6 +708,16 @@ relocate_new_kernel: mrr30, r4 mrr31, r5 +#ifdef CONFIG_SMP +bl1f +1:mflrr8 +addir8,r8,kexec_flag-1b +lis r7,PAGE_OFFSET@h +ori r7,r7,PAGE_OFFSET@l +/*r28 contain slave cpu spin physical address */ +subfr28, r7, r8 +#endif + #define ENTRY_MAPPING_KEXEC_SETUP #include fsl_booke_entry_mapping.S #undef ENTRY_MAPPING_KEXEC_SETUP @@ -1172,4 +1183,57 @@ relocate_new_kernel_end: .globl relocate_new_kernel_size relocate_new_kernel_size: .long relocate_new_kernel_end - relocate_new_kernel +#ifdef CONFIG_FSL_BOOKE +/** +* Slave cpus wait for kexec_flag to change +*/ +.globl relocate_smp_cpu_offset +relocate_smp_cpu_offset: +.long relocate_smp_cpu_wait-relocate_new_kernel + +.globl relocate_smp_cpu_wait +relocate_smp_cpu_wait: + +bl1f +1:mflrr5 +addir5,r5,kexec_flag-1b +/*see if anyone calls me?*/ +mfspr r24,SPRN_PIR +99:lwzr4,4(r5) +cmpwr4,r24 +msync +bne99b + +msync +/*r4 contains jump address*/ +lwzr4,8(r5) +msync +lisr5,MSR_KERNEL@h +orir5,r5,MSR_KERNEL@l +msync +isync +mtsprSPRN_SRR1, r5 +mtsprSPRN_SRR0, r4 +msync +isync +rfi +isync +1:b1b + +/** +* kexec_flag indicates a kexec magic +* kexec_flag+4 bytes supposed to be set with cpu number +* kexec_flag+8 countain addr for slave cpu to jump into +*/ +.globl kexec_flag +kexec_flag: +.long KEXEC_MAGIC +.long0 +.long0 +relocate_smp_cpu_wait_end: +.globl
[RFC PATCH v1 1/1] powerpc/85xx: Wakeup kexec smp slave cpus in second kernel
>From 1ccf579b871dfd5938ce958f729361a203485c74 Mon Sep 17 00:00:00 2001 From: Yu Chen Date: Sat, 31 Aug 2013 23:52:31 +0800 Subject: [PATCH] powerpc/85xx: Wakeup kexec smp slave cpus in second kernel In current 85xx smp kexec implementation,master cpu reset slave cpus by mpic_reset_core, before jump to second kernel.In order to wake slave cpus up in second kernel,we debug this patch on p2041rdb. The main principle of this patch,is to get slave cpus polling for flag to change, thus waiting for master cpu to set it with non-zero cpu number(see misc_32.S). This flag is placed in kexec control page,so it would not be overlapped when copying kimage. The master cpu put flag's physical address in r28 as a parameter passed to second kernel, so the latter knows how to wake slave cpus up in smp_85xx_kick_cpu. The pseudo-code may be like: void slave_cpu_spin(void) { int cpu = smp_processor_id(); while (*kexec_poll != cpu) ; /*slave wakeup and jump*/ jump(*(kexec_poll+1)); } void master_cpu_wakeup(unsigned long *kexec_poll, int cpu) { *(kexec_poll+1) = __early_start; mb(); *kexec_poll = cpu; } However,after applied this patch,we got some kernel exception during booting second kernel, I'm not sure if it's caused by improper treament of cache,or tlb,or other.So I put this patch here hoping someone can check and review it. Signed-off-by: Yu Chen --- arch/powerpc/kernel/head_fsl_booke.S |7 ++ arch/powerpc/kernel/misc_32.S| 66 +- arch/powerpc/platforms/85xx/smp.c| 166 ++ 3 files changed, 222 insertions(+), 17 deletions(-) mode change 100644 => 100755 arch/powerpc/kernel/head_fsl_booke.S mode change 100644 => 100755 arch/powerpc/kernel/misc_32.S mode change 100644 => 100755 arch/powerpc/platforms/85xx/smp.c diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S old mode 100644 new mode 100755 index d10a7ca..63c8392 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -178,6 +178,13 @@ _ENTRY(__early_start) * This is where the main kernel code starts. */ +#if defined(CONFIG_KEXEC) && defined(CONFIG_SMP) +/* r28 contain position where slave cpus spin*/ +lisr1,kexec_poll_phy@h +orir1,r1,kexec_poll_phy@l +stwr28,0(r1) +#endif + /* ptr to current */ lisr2,init_task@h orir2,r2,init_task@l diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S old mode 100644 new mode 100755 index e469f30..d9eefc2 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -120,7 +120,7 @@ _GLOBAL(reloc_got2) addir4,r4,1b@l subfr0,r4,r0 addr7,r0,r7 -2:lwzr0,0(r7) +2:lwzr0,0(r7) addr0,r0,r3 stwr0,0(r7) addir7,r7,4 @@ -692,6 +692,7 @@ _GLOBAL(__main) blr #ifdef CONFIG_KEXEC +#define KEXEC_MAGIC 0xdeadbeef /* * Must be relocatable PIC code callable as a C function. */ @@ -707,6 +708,16 @@ relocate_new_kernel: mrr30, r4 mrr31, r5 +#ifdef CONFIG_SMP +bl1f +1:mflrr8 +addir8,r8,kexec_flag-1b +lis r7,PAGE_OFFSET@h +ori r7,r7,PAGE_OFFSET@l +/*r28 contain slave cpu spin physical address */ +subfr28, r7, r8 +#endif + #define ENTRY_MAPPING_KEXEC_SETUP #include "fsl_booke_entry_mapping.S" #undef ENTRY_MAPPING_KEXEC_SETUP @@ -1172,4 +1183,57 @@ relocate_new_kernel_end: .globl relocate_new_kernel_size relocate_new_kernel_size: .long relocate_new_kernel_end - relocate_new_kernel +#ifdef CONFIG_FSL_BOOKE +/** +* Slave cpus wait for kexec_flag to change +*/ +.globl relocate_smp_cpu_offset +relocate_smp_cpu_offset: +.long relocate_smp_cpu_wait-relocate_new_kernel + +.globl relocate_smp_cpu_wait +relocate_smp_cpu_wait: + +bl1f +1:mflrr5 +addir5,r5,kexec_flag-1b +/*see if anyone calls me?*/ +mfspr r24,SPRN_PIR +99:lwzr4,4(r5) +cmpwr4,r24 +msync +bne99b + +msync +/*r4 contains jump address*/ +lwzr4,8(r5) +msync +lisr5,MSR_KERNEL@h +orir5,r5,MSR_KERNEL@l +msync +isync +mtsprSPRN_SRR1, r5 +mtsprSPRN_SRR0, r4 +msync +isync +rfi +isync +1:b1b + +/** +* kexec_flag indicates a kexec magic +* kexec_flag+4 bytes supposed to be set with cpu number +* kexec_flag+8 countain addr for slave cpu to jump into +*/ +.globl kexec_flag +kexec_flag: +.long KEXEC_MAGIC +.long0 +.long0 +relocate_smp_cpu_wait_end: +.globl relocate_smp_cpu_size +relocate_smp_cpu_size: +.long relocate_smp_cpu_wait_end-relocate_smp_cpu_wait +#endif + #endif diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c old mode 100644 new mode 100755 index 5ced4f5..c4f5c4c
[RFC PATCH v1 1/1] powerpc/85xx: Wakeup kexec smp slave cpus in second kernel
From 1ccf579b871dfd5938ce958f729361a203485c74 Mon Sep 17 00:00:00 2001 From: Yu Chen chenyu...@gmail.com Date: Sat, 31 Aug 2013 23:52:31 +0800 Subject: [PATCH] powerpc/85xx: Wakeup kexec smp slave cpus in second kernel In current 85xx smp kexec implementation,master cpu reset slave cpus by mpic_reset_core, before jump to second kernel.In order to wake slave cpus up in second kernel,we debug this patch on p2041rdb. The main principle of this patch,is to get slave cpus polling for flag to change, thus waiting for master cpu to set it with non-zero cpu number(see misc_32.S). This flag is placed in kexec control page,so it would not be overlapped when copying kimage. The master cpu put flag's physical address in r28 as a parameter passed to second kernel, so the latter knows how to wake slave cpus up in smp_85xx_kick_cpu. The pseudo-code may be like: void slave_cpu_spin(void) { int cpu = smp_processor_id(); while (*kexec_poll != cpu) ; /*slave wakeup and jump*/ jump(*(kexec_poll+1)); } void master_cpu_wakeup(unsigned long *kexec_poll, int cpu) { *(kexec_poll+1) = __early_start; mb(); *kexec_poll = cpu; } However,after applied this patch,we got some kernel exception during booting second kernel, I'm not sure if it's caused by improper treament of cache,or tlb,or other.So I put this patch here hoping someone can check and review it. Signed-off-by: Yu Chen chenyu...@gmail.com --- arch/powerpc/kernel/head_fsl_booke.S |7 ++ arch/powerpc/kernel/misc_32.S| 66 +- arch/powerpc/platforms/85xx/smp.c| 166 ++ 3 files changed, 222 insertions(+), 17 deletions(-) mode change 100644 = 100755 arch/powerpc/kernel/head_fsl_booke.S mode change 100644 = 100755 arch/powerpc/kernel/misc_32.S mode change 100644 = 100755 arch/powerpc/platforms/85xx/smp.c diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S old mode 100644 new mode 100755 index d10a7ca..63c8392 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -178,6 +178,13 @@ _ENTRY(__early_start) * This is where the main kernel code starts. */ +#if defined(CONFIG_KEXEC) defined(CONFIG_SMP) +/* r28 contain position where slave cpus spin*/ +lisr1,kexec_poll_phy@h +orir1,r1,kexec_poll_phy@l +stwr28,0(r1) +#endif + /* ptr to current */ lisr2,init_task@h orir2,r2,init_task@l diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S old mode 100644 new mode 100755 index e469f30..d9eefc2 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -120,7 +120,7 @@ _GLOBAL(reloc_got2) addir4,r4,1b@l subfr0,r4,r0 addr7,r0,r7 -2:lwzr0,0(r7) +2:lwzr0,0(r7) addr0,r0,r3 stwr0,0(r7) addir7,r7,4 @@ -692,6 +692,7 @@ _GLOBAL(__main) blr #ifdef CONFIG_KEXEC +#define KEXEC_MAGIC 0xdeadbeef /* * Must be relocatable PIC code callable as a C function. */ @@ -707,6 +708,16 @@ relocate_new_kernel: mrr30, r4 mrr31, r5 +#ifdef CONFIG_SMP +bl1f +1:mflrr8 +addir8,r8,kexec_flag-1b +lis r7,PAGE_OFFSET@h +ori r7,r7,PAGE_OFFSET@l +/*r28 contain slave cpu spin physical address */ +subfr28, r7, r8 +#endif + #define ENTRY_MAPPING_KEXEC_SETUP #include fsl_booke_entry_mapping.S #undef ENTRY_MAPPING_KEXEC_SETUP @@ -1172,4 +1183,57 @@ relocate_new_kernel_end: .globl relocate_new_kernel_size relocate_new_kernel_size: .long relocate_new_kernel_end - relocate_new_kernel +#ifdef CONFIG_FSL_BOOKE +/** +* Slave cpus wait for kexec_flag to change +*/ +.globl relocate_smp_cpu_offset +relocate_smp_cpu_offset: +.long relocate_smp_cpu_wait-relocate_new_kernel + +.globl relocate_smp_cpu_wait +relocate_smp_cpu_wait: + +bl1f +1:mflrr5 +addir5,r5,kexec_flag-1b +/*see if anyone calls me?*/ +mfspr r24,SPRN_PIR +99:lwzr4,4(r5) +cmpwr4,r24 +msync +bne99b + +msync +/*r4 contains jump address*/ +lwzr4,8(r5) +msync +lisr5,MSR_KERNEL@h +orir5,r5,MSR_KERNEL@l +msync +isync +mtsprSPRN_SRR1, r5 +mtsprSPRN_SRR0, r4 +msync +isync +rfi +isync +1:b1b + +/** +* kexec_flag indicates a kexec magic +* kexec_flag+4 bytes supposed to be set with cpu number +* kexec_flag+8 countain addr for slave cpu to jump into +*/ +.globl kexec_flag +kexec_flag: +.long KEXEC_MAGIC +.long0 +.long0 +relocate_smp_cpu_wait_end: +.globl relocate_smp_cpu_size +relocate_smp_cpu_size: +.long relocate_smp_cpu_wait_end-relocate_smp_cpu_wait +#endif + #endif diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c old mode 100644 new mode