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

[XenPPC] [PATCH] Handshake with secondary processors (take 2)



Take two.

Note that the processors on a JS20 are noticably slower to handshake
than those on a JS21.  I had to rid of the hard-coded 1024 timebase
ticks and replace it with calculating five seconds from the timebase
frequency, as the timeout logic was firing on my JS20 blade.

Note that the SLOF image I have for JS20 blades seems to have a bug
wherein string passed to the last of_printf() call before quiescing is
never output to the serial port.  This will cause you to waste a lot of
time when debugging with printfs, not to mention that it appears to the
user that cpu #1 was never spun up.  So this patch makes us print one
extra line before quiescing OF.
 
Signed-off-by: Amos Waterland <apw@xxxxxxxxxx>

---

 boot_of.c              |   52 ++++++++++++++++++++++++++++++++++++++++++++++---
 powerpc64/exceptions.S |    8 +++++++
 2 files changed, 57 insertions(+), 3 deletions(-)

diff -r 058f2e27476d xen/arch/powerpc/boot_of.c
--- a/xen/arch/powerpc/boot_of.c        Mon Aug 07 17:49:16 2006 -0500
+++ b/xen/arch/powerpc/boot_of.c        Thu Aug 10 21:56:18 2006 -0400
@@ -30,6 +30,9 @@
 #include <asm/io.h>
 #include "exceptions.h"
 #include "of-devtree.h"
+
+/* Secondary processors use this for handshaking with main processor.  */
+volatile unsigned int __spin_ack;
 
 static ulong of_vec;
 static ulong of_msr;
@@ -928,7 +931,7 @@ static int __init boot_of_cpus(void)
 static int __init boot_of_cpus(void)
 {
     int cpus;
-    int cpu;
+    int cpu, bootcpu;
     int result;
     u32 cpu_clock[2];
 
@@ -953,10 +956,52 @@ static int __init boot_of_cpus(void)
     cpu_khz /= 1000;
     of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz);
 
-    /* FIXME: should not depend on the boot CPU bring the first child */
+    /* 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);
     while (cpu > 0) {
-        of_start_cpu(cpu, (ulong)spin_start, 0);
+        unsigned int cpuid, ping, pong;
+        unsigned long now, then, timeout;
+        unsigned int *ack = (unsigned int *)&__spin_ack;
+
+        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: ", cpuid);
+
+        *ack = ~0x0;
+        ping = *ack;
+        of_printf("ping = 0x%x: ", ping);
+
+        mb();
+        of_start_cpu(cpu, (ulong)spin_start, cpuid);
+
+        /* 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: ");
+                pong = 0x0;
+                break;
+            }
+
+            mb();
+            pong = *ack;
+        } while (pong == ping);
+        of_printf("pong = 0x%x\n", pong);
+
         cpu = of_getpeer(cpu);
     }
     return 1;
@@ -1004,6 +1049,7 @@ multiboot_info_t __init *boot_of_init(
     boot_of_rtas();
 
     /* end of OF */
+    of_printf("Quiescing Open Firmware ...\n");
     of_call("quiesce", 0, 0, NULL);
 
     return &mbi;
diff -r 058f2e27476d xen/arch/powerpc/powerpc64/exceptions.S
--- a/xen/arch/powerpc/powerpc64/exceptions.S   Mon Aug 07 17:49:16 2006 -0500
+++ b/xen/arch/powerpc/powerpc64/exceptions.S   Thu Aug 10 22:03:15 2006 -0400
@@ -514,6 +514,14 @@ _GLOBAL(sleep)
     mtmsrd r3
     blr
 
+/* Firmware is told to spin up secondary processors at this address.  We
+ * only need a function entry point instead of a descriptor since this is
+ * never called from C code.
+ */    
     .globl spin_start
 spin_start:
+    /* Our physical cpu number is passed in r3.  */
+    LOADADDR(r4, __spin_ack)
+    stw r3, 0(r4)
+    sync
     b .

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


 


Rackspace

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