[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [POWERPC][XEN] Track the Hard CPUID as configured by the FW



# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID ce9c34c049c541446d291b6839a83563a9f78a3d
# Parent  a3762039dc23f731977befa7a00710c7584d41f0
[POWERPC][XEN] Track the Hard CPUID as configured by the FW

This patch correctly implements and supports hard_smp_processor_id().

Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx>
---
 xen/arch/powerpc/boot_of.c                   |  146 +++++++++++++++------------
 xen/arch/powerpc/powerpc64/ppc970.c          |    2 
 xen/arch/powerpc/setup.c                     |    2 
 xen/include/asm-powerpc/powerpc64/procarea.h |    1 
 xen/include/asm-powerpc/processor.h          |    2 
 xen/include/asm-powerpc/smp.h                |    4 
 6 files changed, 90 insertions(+), 67 deletions(-)

diff -r a3762039dc23 -r ce9c34c049c5 xen/arch/powerpc/boot_of.c
--- a/xen/arch/powerpc/boot_of.c        Mon Sep 18 08:14:46 2006 -0400
+++ b/xen/arch/powerpc/boot_of.c        Mon Sep 18 09:23:51 2006 -0400
@@ -957,21 +957,31 @@ static void boot_of_module(ulong r3, ulo
 
 static int __init boot_of_cpus(void)
 {
-    int cpus;
-    int cpu, bootcpu, logical;
+    int cpus_node;
+    int cpu_node, bootcpu_node, logical;
     int result;
+    s32 cpuid;
     u32 cpu_clock[2];
-
-    cpus = of_finddevice("/cpus");
-    cpu = of_getchild(cpus);
-    result = of_getprop(cpu, "timebase-frequency", &timebase_freq,
+    extern uint cpu_hard_id[NR_CPUS];
+
+    /* Look up which CPU we are running on right now and get all info
+     * from there */
+    result = of_getprop(bof_chosen, "cpu",
+                        &bootcpu_node, sizeof (bootcpu_node));
+    if (result == OF_FAILURE)
+        of_panic("Failed to look up boot cpu\n");
+
+    cpu_node = bootcpu_node;
+
+    result = of_getprop(cpu_node, "timebase-frequency", &timebase_freq,
             sizeof(timebase_freq));
     if (result == OF_FAILURE) {
         of_panic("Couldn't get timebase frequency!\n");
     }
     of_printf("OF: timebase-frequency = %d Hz\n", timebase_freq);
 
-    result = of_getprop(cpu, "clock-frequency", &cpu_clock, sizeof(cpu_clock));
+    result = of_getprop(cpu_node, "clock-frequency",
+                        &cpu_clock, sizeof(cpu_clock));
     if (result == OF_FAILURE || (result !=4 && result != 8)) {
         of_panic("Couldn't get clock frequency!\n");
     }
@@ -983,69 +993,79 @@ static int __init boot_of_cpus(void)
     cpu_khz /= 1000;
     of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz);
 
-    /* Look up which CPU we are running on right now.  */
-    result = of_getprop(bof_chosen, "cpu", &bootcpu, sizeof (bootcpu));
-    if (result == OF_FAILURE)
-        of_panic("Failed to look up boot cpu\n");
-
-    cpu = of_getpeer(cpu);
-
-    /* We want a continuous logical cpu number space.  */
+    /* We want a continuous logical cpu number space and we'll make
+     * the booting CPU logical 0.  */
     cpu_set(0, cpu_present_map);
     cpu_set(0, cpu_online_map);
     cpu_set(0, cpu_possible_map);
 
-    /* Spin up all CPUS, even if there are more than NR_CPUS, because
-     * Open Firmware has them spinning on cache lines which will
-     * eventually be scrubbed, which could lead to random CPU activation.
+    result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid));
+    cpu_hard_id[0] = cpuid;
+
+    /* Spin up all CPUS, even if there are more than NR_CPUS or we are
+     * runnign nosmp, because Open Firmware has them spinning on cache
+     * lines which will eventually be scrubbed, which could lead to
+     * random CPU activation.
      */
-    for (logical = 1; cpu > 0; logical++) {
-        unsigned int cpuid, ping, pong;
+
+    /* Find the base of the multi-CPU package node */
+    cpus_node = of_finddevice("/cpus");
+    if (cpus_node <= 0) {
+        of_printf("Single Processor System\n");
+        return 1;
+    }
+    /* Start with the first child */
+    cpu_node = of_getchild(cpus_node);
+
+    for (logical = 1; cpu_node > 0; logical++) {
+        unsigned int ping, pong;
         unsigned long now, then, timeout;
-
-        if (cpu == bootcpu) {
-            of_printf("skipping boot cpu!\n");
-            continue;
-        }
-
-        result = of_getprop(cpu, "reg", &cpuid, sizeof(cpuid));
-        if (result == OF_FAILURE)
-            of_panic("cpuid lookup failed\n");
-
-        of_printf("spinning up secondary processor #%d: ", logical);
-
-        __spin_ack = ~0x0;
-        ping = __spin_ack;
-        pong = __spin_ack;
-        of_printf("ping = 0x%x: ", ping);
-
-        mb();
-        result = of_start_cpu(cpu, (ulong)spin_start, logical);
-        if (result == OF_FAILURE)
-            of_panic("start cpu failed\n");
-
-        /* We will give the secondary processor five seconds to reply.  */
-        then = mftb();
-        timeout = then + (5 * timebase_freq);
-
-        do {
-            now = mftb();
-            if (now >= timeout) {
-                of_printf("BROKEN: ");
-                break;
+        
+        if (cpu_node == bootcpu_node) {
+            /* same CPU as boot CPU shich we have already made 0 so
+             * reduce the logical count */
+            --logical;
+        } else {
+            result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid));
+            if (result == OF_FAILURE)
+                of_panic("cpuid lookup failed\n");
+
+            cpu_hard_id[logical] = cpuid;
+
+            of_printf("spinning up secondary processor #%d: ", logical);
+
+            __spin_ack = ~0x0;
+            ping = __spin_ack;
+            pong = __spin_ack;
+            of_printf("ping = 0x%x: ", ping);
+
+            mb();
+            result = of_start_cpu(cpu_node, (ulong)spin_start, logical);
+            if (result == OF_FAILURE)
+                of_panic("start cpu failed\n");
+
+            /* We will give the secondary processor five seconds to reply.  */
+            then = mftb();
+            timeout = then + (5 * timebase_freq);
+
+            do {
+                now = mftb();
+                if (now >= timeout) {
+                    of_printf("BROKEN: ");
+                    break;
+                }
+
+                mb();
+                pong = __spin_ack;
+            } while (pong == ping);
+            of_printf("pong = 0x%x\n", pong);
+
+            if (pong != ping) {
+                cpu_set(logical, cpu_present_map);
+                cpu_set(logical, cpu_possible_map);
             }
-
-            mb();
-            pong = __spin_ack;
-        } while (pong == ping);
-        of_printf("pong = 0x%x\n", pong);
-
-        if (pong != ping) {
-            cpu_set(logical, cpu_present_map);
-            cpu_set(logical, cpu_possible_map);
-        }
-
-        cpu = of_getpeer(cpu);
+        }
+        cpu_node = of_getpeer(cpu_node);
     }
     return 1;
 }
diff -r a3762039dc23 -r ce9c34c049c5 xen/arch/powerpc/powerpc64/ppc970.c
--- a/xen/arch/powerpc/powerpc64/ppc970.c       Mon Sep 18 08:14:46 2006 -0400
+++ b/xen/arch/powerpc/powerpc64/ppc970.c       Mon Sep 18 09:23:51 2006 -0400
@@ -145,7 +145,7 @@ void cpu_initialize(int cpuid)
     mthsprg0((ulong)parea); /* now ready for exceptions */
 
     printk("CPU[PIR:%u IPI:%u Logical:%u] Hello World!\n",
-           mfpir(), raw_smp_processor_id(), smp_processor_id());
+           mfpir(), hard_smp_processor_id(), smp_processor_id());
 
 #ifdef DEBUG
     {
diff -r a3762039dc23 -r ce9c34c049c5 xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Mon Sep 18 08:14:46 2006 -0400
+++ b/xen/arch/powerpc/setup.c  Mon Sep 18 09:23:51 2006 -0400
@@ -74,6 +74,7 @@ ulong oftree_len;
 ulong oftree_len;
 ulong oftree_end;
 
+uint cpu_hard_id[NR_CPUS] __initdata;
 cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
 cpumask_t cpu_online_map; /* missing ifdef in schedule.c */
 cpumask_t cpu_present_map;
@@ -227,6 +228,7 @@ static void init_parea(int cpuid)
               __func__, STACK_ORDER, cpuid);
 
     pa->whoami = cpuid;
+    pa->hard_id = cpu_hard_id[cpuid];
     pa->hyp_stack_base = (void *)((ulong)stack + STACK_SIZE);
 
     /* This store has the effect of invoking secondary_cpu_init.  */
diff -r a3762039dc23 -r ce9c34c049c5 
xen/include/asm-powerpc/powerpc64/procarea.h
--- a/xen/include/asm-powerpc/powerpc64/procarea.h      Mon Sep 18 08:14:46 
2006 -0400
+++ b/xen/include/asm-powerpc/powerpc64/procarea.h      Mon Sep 18 09:23:51 
2006 -0400
@@ -29,6 +29,7 @@ struct processor_area
 struct processor_area
 {
     unsigned int whoami;
+    unsigned int hard_id;
     struct vcpu *cur_vcpu;
     void *hyp_stack_base;
     ulong saved_regs[2];
diff -r a3762039dc23 -r ce9c34c049c5 xen/include/asm-powerpc/processor.h
--- a/xen/include/asm-powerpc/processor.h       Mon Sep 18 08:14:46 2006 -0400
+++ b/xen/include/asm-powerpc/processor.h       Mon Sep 18 09:23:51 2006 -0400
@@ -38,7 +38,7 @@ struct vcpu;
 struct vcpu;
 struct cpu_user_regs;
 extern int cpu_machinecheck(struct cpu_user_regs *);
-extern int cpu_scom_init(void);
+extern void cpu_scom_init(void);
 extern void show_registers(struct cpu_user_regs *);
 extern void show_execution_state(struct cpu_user_regs *);
 extern void show_backtrace(ulong sp, ulong lr, ulong pc);
diff -r a3762039dc23 -r ce9c34c049c5 xen/include/asm-powerpc/smp.h
--- a/xen/include/asm-powerpc/smp.h     Mon Sep 18 08:14:46 2006 -0400
+++ b/xen/include/asm-powerpc/smp.h     Mon Sep 18 09:23:51 2006 -0400
@@ -28,9 +28,9 @@ extern int smp_num_siblings;
 extern int smp_num_siblings;
 
 /* revisit when we support SMP */
-#define get_hard_smp_processor_id(i) (global_cpu_table[i]->whoami)
 #define raw_smp_processor_id() (parea->whoami)
-#define hard_smp_processor_id() raw_smp_processor_id()
+#define get_hard_smp_processor_id(i) (global_cpu_table[i]->hard_id)
+#define hard_smp_processor_id() (parea->hard_id)
 extern cpumask_t cpu_sibling_map[];
 extern cpumask_t cpu_core_map[];
 extern void __devinit smp_generic_take_timebase(void);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.