Merge branch 'upstream-fixes'
[powerpc.git] / arch / powerpc / kernel / setup_64.c
index 0fc442a..a717dff 100644 (file)
@@ -33,7 +33,9 @@
 #include <linux/unistd.h>
 #include <linux/serial.h>
 #include <linux/serial_8250.h>
+#include <linux/bootmem.h>
 #include <asm/io.h>
+#include <asm/kdump.h>
 #include <asm/prom.h>
 #include <asm/processor.h>
 #include <asm/pgtable.h>
 #define DBG(fmt...)
 #endif
 
-/*
- * Here are some early debugging facilities. You can enable one
- * but your kernel will not boot on anything else if you do so
- */
-
-/* This one is for use on LPAR machines that support an HVC console
- * on vterm 0
- */
-extern void udbg_init_debug_lpar(void);
-/* This one is for use on Apple G5 machines
- */
-extern void udbg_init_pmac_realmode(void);
-/* That's RTAS panel debug */
-extern void call_rtas_display_status_delay(unsigned char c);
-/* Here's maple real mode debug */
-extern void udbg_init_maple_realmode(void);
-
-#define EARLY_DEBUG_INIT() do {} while(0)
-
-#if 0
-#define EARLY_DEBUG_INIT() udbg_init_debug_lpar()
-#define EARLY_DEBUG_INIT() udbg_init_maple_realmode()
-#define EARLY_DEBUG_INIT() udbg_init_pmac_realmode()
-#define EARLY_DEBUG_INIT()                                             \
-       do { udbg_putc = call_rtas_display_status_delay; } while(0)
-#endif
-
 int have_of = 1;
 int boot_cpuid = 0;
 int boot_cpuid_phys = 0;
@@ -236,11 +211,8 @@ void __init early_setup(unsigned long dt_ptr)
        struct paca_struct *lpaca = get_paca();
        static struct machdep_calls **mach;
 
-       /*
-        * Enable early debugging if any specified (see top of
-        * this file)
-        */
-       EARLY_DEBUG_INIT();
+       /* Enable early debugging if any specified (see udbg.h) */
+       udbg_early_init();
 
        DBG(" -> early_setup()\n");
 
@@ -268,6 +240,10 @@ void __init early_setup(unsigned long dt_ptr)
        }
        ppc_md = **mach;
 
+#ifdef CONFIG_CRASH_DUMP
+       kdump_setup();
+#endif
+
        DBG("Found, Initializing memory management...\n");
 
        /*
@@ -317,6 +293,7 @@ void early_setup_secondary(void)
 void smp_release_cpus(void)
 {
        extern unsigned long __secondary_hold_spinloop;
+       unsigned long *ptr;
 
        DBG(" -> smp_release_cpus()\n");
 
@@ -327,7 +304,9 @@ void smp_release_cpus(void)
         * This is useless but harmless on iSeries, secondaries are already
         * waiting on their paca spinloops. */
 
-       __secondary_hold_spinloop = 1;
+       ptr  = (unsigned long *)((unsigned long)&__secondary_hold_spinloop
+                       - PHYSICAL_START);
+       *ptr = 1;
        mb();
 
        DBG(" <- smp_release_cpus()\n");
@@ -419,6 +398,9 @@ void __init setup_system(void)
 {
        DBG(" -> setup_system()\n");
 
+#ifdef CONFIG_KEXEC
+       kdump_move_device_tree();
+#endif
        /*
         * Unflatten the device-tree passed by prom_init or kexec
         */
@@ -430,7 +412,7 @@ void __init setup_system(void)
 
        /*
         * Fill the ppc64_caches & systemcfg structures with informations
-        * retreived from the device-tree. Need to be called before
+        * retrieved from the device-tree. Need to be called before
         * finish_device_tree() since the later requires some of the
         * informations filled up here to properly parse the interrupt
         * tree.
@@ -464,9 +446,7 @@ void __init setup_system(void)
         * hash table management for us, thus ioremap works. We do that early
         * so that further code can be debugged
         */
-#ifdef CONFIG_PPC_MULTIPLATFORM
        find_legacy_serial_ports();
-#endif
 
        /*
         * "Finish" the device-tree, that is do the actual parsing of
@@ -474,10 +454,6 @@ void __init setup_system(void)
         */
        finish_device_tree();
 
-#ifdef CONFIG_BOOTX_TEXT
-       init_boot_display();
-#endif
-
        /*
         * Initialize xmon
         */
@@ -516,6 +492,9 @@ void __init setup_system(void)
               ppc64_caches.iline_size);
        printk("htab_address                  = 0x%p\n", htab_address);
        printk("htab_hash_mask                = 0x%lx\n", htab_hash_mask);
+#if PHYSICAL_START > 0
+       printk("physical_start                = 0x%x\n", PHYSICAL_START);
+#endif
        printk("-----------------------------------------------------\n");
 
        mm_init_ppc64();
@@ -679,3 +658,28 @@ void cpu_die(void)
        if (ppc_md.cpu_die)
                ppc_md.cpu_die();
 }
+
+#ifdef CONFIG_SMP
+void __init setup_per_cpu_areas(void)
+{
+       int i;
+       unsigned long size;
+       char *ptr;
+
+       /* Copy section for each CPU (we discard the original) */
+       size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
+#ifdef CONFIG_MODULES
+       if (size < PERCPU_ENOUGH_ROOM)
+               size = PERCPU_ENOUGH_ROOM;
+#endif
+
+       for_each_cpu(i) {
+               ptr = alloc_bootmem_node(NODE_DATA(cpu_to_node(i)), size);
+               if (!ptr)
+                       panic("Cannot allocate cpu data for CPU %d\n", i);
+
+               paca[i].data_offset = ptr - __per_cpu_start;
+               memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+       }
+}
+#endif