[Top][All Lists]
[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
- Re: [Qemu-devel] [PATCH 14/23] PPC: KVM: Add generic function to read host clockfreq, (continued)
[Qemu-devel] [PATCH 16/23] PPC: E500: Remove mpc8544_copy_soc_cell, Alexander Graf, 2011/07/20
[Qemu-devel] [PATCH 06/23] PPC: Fix IPI support in MPIC, Alexander Graf, 2011/07/20
[Qemu-devel] [PATCH 21/23] PPC: E500: Remove unneeded CPU nodes, Alexander Graf, 2011/07/20
[Qemu-devel] [PATCH 22/23] PPC: E500: Update cpu-release-addr property in cpu nodes, Alexander Graf, 2011/07/20
[Qemu-devel] [PATCH 19/23] PPC: KVM: Add stubs for kvm helper functions, Alexander Graf, 2011/07/20
[Qemu-devel] [PATCH 01/23] PPC: Add secondary CPU spinning code,
Alexander Graf <=
[Qemu-devel] [PATCH 04/23] PPC: Add CPU local MMIO regions to MPIC, Alexander Graf, 2011/07/20
[Qemu-devel] [PATCH 03/23] PPC: Add CPU definitions for up to 32 guest CPUs, Alexander Graf, 2011/07/20
[Qemu-devel] [PATCH 18/23] PPC: KVM: Remove kvmppc_read_host_property, Alexander Graf, 2011/07/20
[Qemu-devel] [PATCH 08/23] PPC: Bump MPIC up to 32 supported CPUs, Alexander Graf, 2011/07/20