* Re: [PATCH] MIPS: kexec mips64 XLR 732 support
[not found] <e997b7420912290702g31b69dd0l1b3c68b10fc3aacc@mail.gmail.com>
@ 2009-12-29 15:13 ` Florian Fainelli
0 siblings, 0 replies; 2+ messages in thread
From: Florian Fainelli @ 2009-12-29 15:13 UTC (permalink / raw)
To: kexec; +Cc: wilbur.chan, linux-mips
Hi,
On Tuesday 29 December 2009 16:02:38 wilbur.chan wrote:
> This patch works on mips64 xlr732 , which has 8 cores up to 32 threads.
> derived from Maxim Syrchin's patch at
> http://lists.infradead.org/pipermail/kexec/2008-June/001909.html
It would help if you cross-posted to linux-mips so that more people can review
your patch.
I do not see the point in adding support to kexec for a SoC which is not
supported by mainline linux-mips kernel.
Please make sure that support for mips64 in kexec and linux-mips hits
mainline, then add your XLR specific to the existing mips64 kexec
infrastructure as I am sure some code can be easily shared.
Thank you.
>
> Notice:
> (I)
> In my code,xlr kernel needs to call functions in bootloader when booting,
> so xlr bootloader is supposed to determin whether in first booting or
> second. (II)
> As xlr kernel choosed CPU0 for special purpose when booting,I simply
> bind kexec on CPU0.
> (III)
> Becasue non-zero CPUs have different kernel entry with respect to
> CPU0,they wait util CPU0 set flags at 0xa6000000.
>
>
> Signed-off-by: wilbur <chen.yu10 at zte.com.cn>
>
> --- machine_kexec.c 2007-08-05 00:11:13.000000000 +0800
> +++ patch.machine_kexec.c 2009-12-29 14:31:32.000000000 +0800
> @@ -13,12 +13,28 @@
> #include <asm/cacheflush.h>
> #include <asm/page.h>
>
> +#ifdef CONFIG_RMI_PHOENIX
> +#define KEXEC_FLAG_VAL 184790
> +#define KEXEC_FLAG_POS 0xa6000000
> +#define KEXEC_SECONDFUNC_POS 0xa6000004
> +#define V_CPUS 31
> +#endif
> extern const unsigned char relocate_new_kernel[];
> +#ifdef CONFIG_RMI_PHOENIX
> +extern const unsigned char kexec_smp_wait[];
> +#endif
> extern const unsigned int relocate_new_kernel_size;
>
> extern unsigned long kexec_start_address;
> extern unsigned long kexec_indirection_page;
>
> +#ifdef CONFIG_RMI_PHOENIX
> +extern unsigned long kexec_fw_arg0;
> +extern unsigned long kexec_fw_arg1;
> +extern unsigned long kexec_fw_arg2;
> +extern unsigned long kexec_fw_arg3;
> +extern unsigned long fw_arg0,fw_arg1,fw_arg2,fw_arg3;
> +#endif
> int
> machine_kexec_prepare(struct kimage *kimage)
> {
> @@ -33,7 +49,70 @@
> void
> machine_shutdown(void)
> {
> + #ifdef CONFIG_RMI_PHOENIX
> + default_machine_kexec_shutdown();
> + #endif
> }
> +#ifdef CONFIG_RMI_PHOENIX
> +unsigned long relocated_kexec_smp_wait;
> +atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
> +int main_cpu = -1;
> +static cpumask_t cpus_in_kexec = CPU_MASK_NONE;
> +void machine_shutdown_secondary(void *ignore)
> +{
> + int cpu = smp_processor_id();
> +
> + if (!cpu_online(cpu))
> + return;
> +
> + local_irq_disable();
> + uint64_t eimr=0;
> + write_64bit_cp0_eimr(eimr);
> +
> +
> +
> + /*
> + * clear flags and secondary funtion before wait
> + */
> + *(unsigned long*)KEXEC_FLAG_POS =0;
> + *(unsigned long*)KEXEC_SECONDFUNC_POS =0;
> +
> + cpu_set(cpu, cpus_in_kexec);
> +
> + while(!atomic_read(&kexec_ready_to_reboot)) {
> + cpu_relax();
> + }
> +
> + ((void (*)(void)) relocated_kexec_smp_wait)();
> + /* NOTREACHED */
> +}
> +static void machine_kexec_prepare_cpus(void)
> +{
> +
> + unsigned int msecs;
> + smp_call_function (machine_shutdown_secondary, NULL, 0, 0);
> + smp_wmb();
> + /*
> + * FIXME: Until we will have the way to stop other CPUSs reliabally,
> + * the crash CPU will send an IPI and wait for other CPUs to
> + * respond.
> + * Delay of at least 10 seconds.
> + */
> +
> + msecs = 10000;
> + while ((cpus_weight(cpus_in_kexec) < V_CPUS) && (--msecs > 0)) {
> + cpu_relax();
> + mdelay(1);
> + }
> +
> +}
> +void default_machine_kexec_shutdown()
> +{
> + machine_kexec_prepare_cpus();
> +}
> +
> +#endif
>
> void
> machine_crash_shutdown(struct pt_regs *regs)
> @@ -50,7 +129,13 @@
> reboot_code_buffer =
> (unsigned long)page_address(image->control_code_page);
>
> - kexec_start_address = image->start;
> + kexec_start_address = (unsigned long) phys_to_virt(image->start);
> + #ifdef CONFIG_RMI_PHOENIX
> + kexec_fw_arg0 = fw_arg0;
> + kexec_fw_arg1 = fw_arg1;
> + kexec_fw_arg2 = fw_arg2;
> + kexec_fw_arg3 = fw_arg3;
> + #endif
> kexec_indirection_page = phys_to_virt(image->head & PAGE_MASK);
>
> memcpy((void*)reboot_code_buffer, relocate_new_kernel,
> @@ -75,10 +160,23 @@
> */
> local_irq_disable();
>
> - flush_icache_range(reboot_code_buffer,
> - reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
>
> - printk("Will call new kernel at %08x\n", image->start);
> +
> + #ifdef CONFIG_RMI_PHOENIX
> + pic_and_control(0xfffffbff);
> + /* All secondary cpus now may jump to kexec_wait cycle */
> + relocated_kexec_smp_wait = reboot_code_buffer +
> + (kexec_smp_wait - relocate_new_kernel);
> + smp_wmb();
> + atomic_set(&kexec_ready_to_reboot,1);
> + pic_irt_timer_maskall();
> + pic_irt_uart0_0_and(0x0);
> + pic_irt_uart0_1_and(0x0);
> + uart_int_and(0x0);
> + uint64_t eimr=0;
> + write_64bit_cp0_eimr(eimr);
> + #endif
> + printk("Will call new kernel at %08x\n", kexec_start_address);
> printk("Bye ...\n");
> flush_cache_all();
> ((void (*)(void))reboot_code_buffer)();
>
> --- relocate_kernel.S 2007-08-05 00:11:13.000000000 +0800
> +++ patch.relocate_kernel.S 2009-12-29 14:25:27.873991800 +0800
> @@ -14,12 +14,21 @@
> #include <asm/stackframe.h>
> #include <asm/addrspace.h>
>
> +#ifdef CONFIG_RMI_PHOENIX
> +#define KEXEC_FLAG_POS 0xa6000000
> +#define KEXEC_SECONDFUNC_POS 0xa6000004
> +#endif
> .globl relocate_new_kernel
> relocate_new_kernel:
>
> PTR_L s0, kexec_indirection_page
> PTR_L s1, kexec_start_address
> -
> +#ifdef CONFIG_RMI_PHOENIX
> + PTR_L t0, kexec_fw_arg0
> + PTR_L t1, kexec_fw_arg1
> + PTR_L t2, kexec_fw_arg2
> + PTR_L t3, kexec_fw_arg3
> +#endif
> process_entry:
> PTR_L s2, (s0)
> PTR_ADD s0, s0, SZREG
> @@ -62,9 +71,39 @@
> b process_entry
>
> done:
> +#ifdef CONFIG_RMI_PHOENIX
> + move a0, t0
> + move a1, t1
> + move a2, t2
> + move a3, t3
> /* jump to kexec_start_address */
> - j s1
> + jr s1
> +#endif
> +
> +
>
> +#ifdef CONFIG_RMI_PHOENIX
> + .globl kexec_smp_wait
> +kexec_smp_wait:
> + /*
> + * wait util CPU0 set flag at 0xa6000000, then jump to
> secondary_function stored in 0xa6000004
> + *
> + */
> +
> + /*
> + * FIXME
> + */
> +20: li s2,KEXEC_FLAG_POS
> + REG_L s5, (s2)
> + beqz s5, 20b
> +
> + /*
> + * ok , we can jump to second kernel
> + */
> + li s2,KEXEC_SECONDFUNC_POS
> + REG_L s6, (s2)
> + jr s6
> +#endif
> .globl kexec_start_address
> kexec_start_address:
> .long 0x0
> @@ -73,6 +112,25 @@
> kexec_indirection_page:
> .long 0x0
>
> +#ifdef CONFIG_RMI_PHOENIX
> + .globl kexec_fw_arg0
> +kexec_fw_arg0:
> + .long 0x0
> +
> +
> + .globl kexec_fw_arg1
> +kexec_fw_arg1:
> + .long 0x0
> +
> + .globl kexec_fw_arg2
> +kexec_fw_arg2:
> + .long 0x0
> +
> + .globl kexec_fw_arg3
> +kexec_fw_arg3:
> + .long 0x0
> +
> +#endif
> relocate_new_kernel_end:
>
> .globl relocate_new_kernel_size
>
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec
>
--
Regards, Florian
^ permalink raw reply [flat|nested] 2+ messages in thread
* [PATCH] MIPS: kexec mips64 XLR 732 support
@ 2009-12-30 12:31 wilbur.chan
0 siblings, 0 replies; 2+ messages in thread
From: wilbur.chan @ 2009-12-30 12:31 UTC (permalink / raw)
To: Linux MIPS Mailing List
Though xlr family is not supported in kernel tree, this patch is
released in the hope that it might be help for some people using xlr.
This patch works on mips64 xlr732 , which has 8 cores up to 32 threads.
derived from Maxim Syrchin's patch at
http://lists.infradead.org/pipermail/kexec/2008-June/001909.html
Notice:
(I)
In my code,xlr kernel needs to call functions in bootloader when booting,
so xlr bootloader is supposed to determin whether in first booting or second.
(II)
As xlr kernel choosed CPU0 for special purpose when booting,I simply
bind kexec on CPU0.
(III)
Becasue non-zero CPUs have different kernel entry with respect to
CPU0,they wait util CPU0 set flags at 0xa6000000.
Signed-off-by: wilbur <chen.yu10 at zte.com.cn>
--- machine_kexec.c 2007-08-05 00:11:13.000000000 +0800
+++ patch.machine_kexec.c 2009-12-29 14:31:32.000000000 +0800
@@ -13,12 +13,28 @@
#include <asm/cacheflush.h>
#include <asm/page.h>
+#ifdef CONFIG_RMI_PHOENIX
+#define KEXEC_FLAG_VAL 184790
+#define KEXEC_FLAG_POS 0xa6000000
+#define KEXEC_SECONDFUNC_POS 0xa6000004
+#define V_CPUS 31
+#endif
extern const unsigned char relocate_new_kernel[];
+#ifdef CONFIG_RMI_PHOENIX
+extern const unsigned char kexec_smp_wait[];
+#endif
extern const unsigned int relocate_new_kernel_size;
extern unsigned long kexec_start_address;
extern unsigned long kexec_indirection_page;
+#ifdef CONFIG_RMI_PHOENIX
+extern unsigned long kexec_fw_arg0;
+extern unsigned long kexec_fw_arg1;
+extern unsigned long kexec_fw_arg2;
+extern unsigned long kexec_fw_arg3;
+extern unsigned long fw_arg0,fw_arg1,fw_arg2,fw_arg3;
+#endif
int
machine_kexec_prepare(struct kimage *kimage)
{
@@ -33,7 +49,70 @@
void
machine_shutdown(void)
{
+ #ifdef CONFIG_RMI_PHOENIX
+ default_machine_kexec_shutdown();
+ #endif
}
+#ifdef CONFIG_RMI_PHOENIX
+unsigned long relocated_kexec_smp_wait;
+atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
+int main_cpu = -1;
+static cpumask_t cpus_in_kexec = CPU_MASK_NONE;
+void machine_shutdown_secondary(void *ignore)
+{
+ int cpu = smp_processor_id();
+
+ if (!cpu_online(cpu))
+ return;
+
+ local_irq_disable();
+ uint64_t eimr=0;
+ write_64bit_cp0_eimr(eimr);
+
+
+
+ /*
+ * clear flags and secondary funtion before wait
+ */
+ *(unsigned long*)KEXEC_FLAG_POS =0;
+ *(unsigned long*)KEXEC_SECONDFUNC_POS =0;
+
+ cpu_set(cpu, cpus_in_kexec);
+
+ while(!atomic_read(&kexec_ready_to_reboot)) {
+ cpu_relax();
+ }
+
+ ((void (*)(void)) relocated_kexec_smp_wait)();
+ /* NOTREACHED */
+}
+static void machine_kexec_prepare_cpus(void)
+{
+
+ unsigned int msecs;
+ smp_call_function (machine_shutdown_secondary, NULL, 0, 0);
+ smp_wmb();
+ /*
+ * FIXME: Until we will have the way to stop other CPUSs reliabally,
+ * the crash CPU will send an IPI and wait for other CPUs to
+ * respond.
+ * Delay of at least 10 seconds.
+ */
+
+ msecs = 10000;
+ while ((cpus_weight(cpus_in_kexec) < V_CPUS) && (--msecs > 0)) {
+ cpu_relax();
+ mdelay(1);
+ }
+
+}
+void default_machine_kexec_shutdown()
+{
+ machine_kexec_prepare_cpus();
+}
+
+#endif
void
machine_crash_shutdown(struct pt_regs *regs)
@@ -50,7 +129,13 @@
reboot_code_buffer =
(unsigned long)page_address(image->control_code_page);
- kexec_start_address = image->start;
+ kexec_start_address = (unsigned long) phys_to_virt(image->start);
+ #ifdef CONFIG_RMI_PHOENIX
+ kexec_fw_arg0 = fw_arg0;
+ kexec_fw_arg1 = fw_arg1;
+ kexec_fw_arg2 = fw_arg2;
+ kexec_fw_arg3 = fw_arg3;
+ #endif
kexec_indirection_page = phys_to_virt(image->head & PAGE_MASK);
memcpy((void*)reboot_code_buffer, relocate_new_kernel,
@@ -75,10 +160,23 @@
*/
local_irq_disable();
- flush_icache_range(reboot_code_buffer,
- reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
- printk("Will call new kernel at %08x\n", image->start);
+
+ #ifdef CONFIG_RMI_PHOENIX
+ pic_and_control(0xfffffbff);
+ /* All secondary cpus now may jump to kexec_wait cycle */
+ relocated_kexec_smp_wait = reboot_code_buffer +
+ (kexec_smp_wait - relocate_new_kernel);
+ smp_wmb();
+ atomic_set(&kexec_ready_to_reboot,1);
+ pic_irt_timer_maskall();
+ pic_irt_uart0_0_and(0x0);
+ pic_irt_uart0_1_and(0x0);
+ uart_int_and(0x0);
+ uint64_t eimr=0;
+ write_64bit_cp0_eimr(eimr);
+ #endif
+ printk("Will call new kernel at %08x\n", kexec_start_address);
printk("Bye ...\n");
flush_cache_all();
((void (*)(void))reboot_code_buffer)();
--- relocate_kernel.S 2007-08-05 00:11:13.000000000 +0800
+++ patch.relocate_kernel.S 2009-12-29 14:25:27.873991800 +0800
@@ -14,12 +14,21 @@
#include <asm/stackframe.h>
#include <asm/addrspace.h>
+#ifdef CONFIG_RMI_PHOENIX
+#define KEXEC_FLAG_POS 0xa6000000
+#define KEXEC_SECONDFUNC_POS 0xa6000004
+#endif
.globl relocate_new_kernel
relocate_new_kernel:
PTR_L s0, kexec_indirection_page
PTR_L s1, kexec_start_address
-
+#ifdef CONFIG_RMI_PHOENIX
+ PTR_L t0, kexec_fw_arg0
+ PTR_L t1, kexec_fw_arg1
+ PTR_L t2, kexec_fw_arg2
+ PTR_L t3, kexec_fw_arg3
+#endif
process_entry:
PTR_L s2, (s0)
PTR_ADD s0, s0, SZREG
@@ -62,9 +71,39 @@
b process_entry
done:
+#ifdef CONFIG_RMI_PHOENIX
+ move a0, t0
+ move a1, t1
+ move a2, t2
+ move a3, t3
/* jump to kexec_start_address */
- j s1
+ jr s1
+#endif
+
+
+#ifdef CONFIG_RMI_PHOENIX
+ .globl kexec_smp_wait
+kexec_smp_wait:
+ /*
+ * wait util CPU0 set flag at 0xa6000000, then jump to
secondary_function stored in 0xa6000004
+ *
+ */
+
+ /*
+ * FIXME
+ */
+20: li s2,KEXEC_FLAG_POS
+ REG_L s5, (s2)
+ beqz s5, 20b
+
+ /*
+ * ok , we can jump to second kernel
+ */
+ li s2,KEXEC_SECONDFUNC_POS
+ REG_L s6, (s2)
+ jr s6
+#endif
.globl kexec_start_address
kexec_start_address:
.long 0x0
@@ -73,6 +112,25 @@
kexec_indirection_page:
.long 0x0
+#ifdef CONFIG_RMI_PHOENIX
+ .globl kexec_fw_arg0
+kexec_fw_arg0:
+ .long 0x0
+
+
+ .globl kexec_fw_arg1
+kexec_fw_arg1:
+ .long 0x0
+
+ .globl kexec_fw_arg2
+kexec_fw_arg2:
+ .long 0x0
+
+ .globl kexec_fw_arg3
+kexec_fw_arg3:
+ .long 0x0
+
+#endif
relocate_new_kernel_end:
.globl relocate_new_kernel_size
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-12-30 12:32 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <e997b7420912290702g31b69dd0l1b3c68b10fc3aacc@mail.gmail.com>
2009-12-29 15:13 ` [PATCH] MIPS: kexec mips64 XLR 732 support Florian Fainelli
2009-12-30 12:31 wilbur.chan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).