]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/kernel/machine_kexec_64.c
powerpc: Support for relocatable kdump kernel
[linux-2.6-omap-h63xx.git] / arch / powerpc / kernel / machine_kexec_64.c
index a24b09c27718b0f5ece5ae90ecc3ad0e059d49ed..e6efec788c4d0d98706c729666e1ab779feee6f9 100644 (file)
@@ -72,8 +72,8 @@ int default_machine_kexec_prepare(struct kimage *image)
        /* We also should not overwrite the tce tables */
        for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
                        node = of_find_node_by_type(node, "pci")) {
-               basep = get_property(node, "linux,tce-base", NULL);
-               sizep = get_property(node, "linux,tce-size", NULL);
+               basep = of_get_property(node, "linux,tce-base", NULL);
+               sizep = of_get_property(node, "linux,tce-size", NULL);
                if (basep == NULL || sizep == NULL)
                        continue;
 
@@ -158,7 +158,7 @@ void kexec_copy_flush(struct kimage *image)
  * on calling the interrupts, but we would like to call it off irq level
  * so that the interrupt controller is clean.
  */
-void kexec_smp_down(void *arg)
+static void kexec_smp_down(void *arg)
 {
        if (ppc_md.kexec_cpu_down)
                ppc_md.kexec_cpu_down(0, 1);
@@ -172,7 +172,7 @@ static void kexec_prepare_cpus(void)
 {
        int my_cpu, i, notified=-1;
 
-       smp_call_function(kexec_smp_down, NULL, 0, /* wait */0);
+       smp_call_function(kexec_smp_down, NULL, /* wait */0);
        my_cpu = get_cpu();
 
        /* check the others cpus are now down (via paca hw cpu id == -1) */
@@ -249,17 +249,20 @@ static void kexec_prepare_cpus(void)
  * We could use a smaller stack if we don't care about anything using
  * current, but that audit has not been performed.
  */
-union thread_union kexec_stack
+static union thread_union kexec_stack
        __attribute__((__section__(".data.init_task"))) = { };
 
 /* Our assembly helper, in kexec_stub.S */
 extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start,
                                        void *image, void *control,
-                                       void (*clear_all)(void)) ATTRIB_NORET;
+                                       void (*clear_all)(void),
+                                       unsigned long kdump_flag) ATTRIB_NORET;
 
 /* too late to fail here */
 void default_machine_kexec(struct kimage *image)
 {
+       unsigned long kdump_flag = 0;
+
        /* prepare control code if any */
 
        /*
@@ -270,8 +273,10 @@ void default_machine_kexec(struct kimage *image)
         * using debugger IPI.
         */
 
-       if (crashing_cpu == -1)
-               kexec_prepare_cpus();
+       if (crashing_cpu == -1)
+               kexec_prepare_cpus();
+       else
+               kdump_flag = KDUMP_SIGNATURE;
 
        /* switch to a staticly allocated stack.  Based on irq stack code.
         * XXX: the task struct will likely be invalid once we do the copy!
@@ -284,7 +289,7 @@ void default_machine_kexec(struct kimage *image)
         */
        kexec_sequence(&kexec_stack, image->start, image,
                        page_address(image->control_code_page),
-                       ppc_md.hpte_clear_all);
+                       ppc_md.hpte_clear_all, kdump_flag);
        /* NOTREACHED */
 }
 
@@ -294,29 +299,42 @@ static unsigned long htab_base, kernel_end;
 static struct property htab_base_prop = {
        .name = "linux,htab-base",
        .length = sizeof(unsigned long),
-       .value = (unsigned char *)&htab_base,
+       .value = &htab_base,
 };
 
 static struct property htab_size_prop = {
        .name = "linux,htab-size",
        .length = sizeof(unsigned long),
-       .value = (unsigned char *)&htab_size_bytes,
+       .value = &htab_size_bytes,
 };
 
 static struct property kernel_end_prop = {
        .name = "linux,kernel-end",
        .length = sizeof(unsigned long),
-       .value = (unsigned char *)&kernel_end,
+       .value = &kernel_end,
 };
 
 static void __init export_htab_values(void)
 {
        struct device_node *node;
+       struct property *prop;
 
        node = of_find_node_by_path("/chosen");
        if (!node)
                return;
 
+       /* remove any stale propertys so ours can be found */
+       prop = of_find_property(node, kernel_end_prop.name, NULL);
+       if (prop)
+               prom_remove_property(node, prop);
+       prop = of_find_property(node, htab_base_prop.name, NULL);
+       if (prop)
+               prom_remove_property(node, prop);
+       prop = of_find_property(node, htab_size_prop.name, NULL);
+       if (prop)
+               prom_remove_property(node, prop);
+
+       /* information needed by userspace when using default_machine_kexec */
        kernel_end = __pa(_end);
        prom_add_property(node, &kernel_end_prop);
 
@@ -335,7 +353,7 @@ static void __init export_htab_values(void)
 static struct property crashk_base_prop = {
        .name = "linux,crashkernel-base",
        .length = sizeof(unsigned long),
-       .value = (unsigned char *)&crashk_res.start,
+       .value = &crashk_res.start,
 };
 
 static unsigned long crashk_size;
@@ -343,7 +361,7 @@ static unsigned long crashk_size;
 static struct property crashk_size_prop = {
        .name = "linux,crashkernel-size",
        .length = sizeof(unsigned long),
-       .value = (unsigned char *)&crashk_size,
+       .value = &crashk_size,
 };
 
 static void __init export_crashk_values(void)