qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 01/23] PPC: Add secondary CPU spinning code


From: Alexander Graf
Subject: [Qemu-devel] [PATCH 01/23] PPC: Add secondary CPU spinning code
Date: Thu, 21 Jul 2011 03:27:12 +0200

When directly starting an SMP system with -kernel on PPC e500, we need to
simulate the spin table code from u-boot. This code adds a small c file
plus generated .elf file that enable secondary CPUs to spin just like they
would with u-boot.

Signed-off-by: Alexander Graf <address@hidden>
---
 pc-bios/ppc_spin.c   |   97 ++++++++++++++++++++++++++++++++++++++++++++++++++
 pc-bios/ppc_spin.elf |  Bin 0 -> 66553 bytes
 2 files changed, 97 insertions(+), 0 deletions(-)
 create mode 100644 pc-bios/ppc_spin.c
 create mode 100755 pc-bios/ppc_spin.elf

diff --git a/pc-bios/ppc_spin.c b/pc-bios/ppc_spin.c
new file mode 100644
index 0000000..e46a6a7
--- /dev/null
+++ b/pc-bios/ppc_spin.c
@@ -0,0 +1,97 @@
+#include <stdio.h>
+#include <stdint.h>
+
+/*
+ * Secondary CPU spin code
+ *
+ * Compile using: gcc -m32 -nostdlib ppc_spin.c -o ppc_spin.elf -Os \
+ *                    -fno-stack-protector -Wl,-Ttext,0x7700000
+ */
+
+/* Initialize stack pointer */
+asm (
+"    .global _start             \n"
+"    _start:                    \n"
+"    addis   1, 3, address@hidden    \n"
+"    b       spin               \n");
+
+typedef struct spin_info {
+    uint32_t addr_hi;
+    uint32_t addr;
+    uint32_t r3_hi;
+    uint32_t r3;
+    uint32_t resv;
+    uint32_t pir;
+    uint32_t r6_hi;
+    uint32_t r6;
+} SpinInfo;
+
+#define __stringify_1(x...)     #x
+#define __stringify(x...)       __stringify_1(x)
+
+#define mfspr(rn)       ({unsigned long rval; \
+                        asm volatile("mfspr %0," __stringify(rn) \
+                                : "=r" (rval)); rval;})
+#define mtspr(rn, v)    asm volatile("mtspr " __stringify(rn) ",%0" : : "r" 
(v)\
+                                     : "memory")
+static inline void mtdec(unsigned long v)
+{
+    asm volatile("mtdec %0" : : "r" (v));
+}
+
+static inline void mtmsr(unsigned long msr)
+{
+    asm("mtmsr %0" : : "r"(msr));
+}
+
+#define __MASK(X)        (1UL<<(X))
+#define MSR_WE_LG        18              /* Wait State Enable */
+#define MSR_EE_LG        15              /* External Interrupt Enable */
+#define MSR_WE           __MASK(MSR_WE_LG)       /* Wait State Enable */
+#define MSR_EE           __MASK(MSR_EE_LG)       /* External Interrupt Enable 
*/
+#define SPR_PIR          0x11E
+#define SPR_HID0         (0x3F0)
+#define SPR_BOOKE_IVOR10 (0x19A)
+#define SPR_BOOKE_IVPR   (0x03F)
+
+void loop(void);
+
+__attribute__((noreturn)) void spin(unsigned long ptr)
+{
+    volatile SpinInfo *info = (void*)ptr;
+    uint32_t pir = mfspr(SPR_PIR);
+    __attribute__((noreturn)) void (*entry)(
+        unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6,
+        unsigned long r7, unsigned long r8, unsigned long r9);
+    unsigned long dec_p = (unsigned long)loop;
+
+    info->pir = pir;
+    info->r3 = pir;
+    info->addr = 1;
+    info->r6 = 0;
+
+    /* we don't want to keep the other CPUs from running, so set the IVOR for
+       DEC to our loop and only check for info->addr every other cycle */
+
+    mtspr(SPR_HID0, 0x00E00000);
+    mtspr(SPR_BOOKE_IVOR10, dec_p & 0xfff);
+    mtspr(SPR_BOOKE_IVPR, dec_p & ~0xfff);
+loop:
+    asm volatile (".global loop\n"
+        "   loop:" : : : "memory", "cc");
+
+    if (info->addr & 1) {
+        /* wait until addr is valid */
+        mtdec(0x100000);
+        mtmsr(MSR_WE|MSR_EE);
+        /* should never reach here */
+        while(1) { }
+    }
+
+    asm volatile ("");
+
+    mtspr(SPR_HID0, 0);
+    info->pir = pir;
+    entry = (void*)(unsigned long)info->addr;
+    entry(info->r3, 0, 0, info->r6, 64 * 1024 * 1024, 0, 0);
+}
diff --git a/pc-bios/ppc_spin.elf b/pc-bios/ppc_spin.elf
new file mode 100755
index 
0000000000000000000000000000000000000000..71c872b2d4685100b0050d549735662d7d763e08
GIT binary patch
literal 66553
zcmeIvJ#14~6u|Lw?Uy)KGdMIt2pAq}1Q;n#1dNoR(27QsO65DrK&xW>rNk<+U+tGR
zRgG$Ot}0q}>d-PEFED0dXJcVxWa(Zcm>A4Cetr(1EQs}gt>address@hidden>iU_`;=}
zj7CbPHFueCP$`IWzYQ~AJUJ>^8MnTE#MTVgJ<yuPnALSye>*2}=zL}v-mq`a-TNY5
zHTv(W9kR=?yS-iNln_7w0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{
z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL
zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~
z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**
z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0
z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{
z1Q0*~0R#|0009ILKmY**K2Tus6LDXPcz+%0|KIuUz*c7>)w|<l`u2^_d-Edhk0qJb
zm^|ZW!aHg4v?dFAS<(F9qR6vO?p1HqAN#bkztUUH%i-Ifebnpfx-cv5?5~40xz65n
address@hidden;EUK9-HJ?hAIrf`Hr>0_^$uw(8J;H7
z8tL<wR^{WrpXY!7`r7>?53le4_n)tpfA0TzU(PQro%W9|uP&eSFVq{GTY0|_oD5F*
z->g+CvxVZx*>bDYsI2>~+7I=1z1i^R3UenG=DwA)dhFC%V^f?aS<g+l%gf=9Ya&7W
zr;Vso)@Rg;pX*5$)wUuD8qKH{=+2<LS-(}Ctyd+eG&eSC4eeRE6h*Cic{8fDM~%RK
address@hidden&~l63_w*m?1A@>G-4
address@hidden>ti<address@hidden<=lCFxzpQ65rIC(HR&mGl`{roAbFZyU
address@hidden;address@hidden&Q
zY_NY!AESFb=|9)address@hidden|e9`M%8e@&A{L*UxC*-tC^^+WP!E{o`-V!?03p
khxJBKkz37XD8+VEYDH2kmfP)NZfz;ns->u;k49Bq1C*tqEC2ui

literal 0
HcmV?d00001

-- 
1.6.0.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]