summaryrefslogtreecommitdiff
path: root/roms/openbios/arch/ppc/qemu/start.S
diff options
context:
space:
mode:
Diffstat (limited to 'roms/openbios/arch/ppc/qemu/start.S')
-rw-r--r--roms/openbios/arch/ppc/qemu/start.S244
1 files changed, 146 insertions, 98 deletions
diff --git a/roms/openbios/arch/ppc/qemu/start.S b/roms/openbios/arch/ppc/qemu/start.S
index 33ca1e03e..ae2fd53dc 100644
--- a/roms/openbios/arch/ppc/qemu/start.S
+++ b/roms/openbios/arch/ppc/qemu/start.S
@@ -482,15 +482,56 @@ real_entry:
#endif
bl BRANCH_LABEL(setup_mmu)
- bl BRANCH_LABEL(__switch_context_nosave)
+ bl BRANCH_LABEL(entry)
1: nop
b 1b
+
+ /* According to IEEE 1275, PPC bindings:
+ *
+ * MSR = FP, ME + (DR|IR)
+ * r1 = stack (32 K + 32 bytes link area above)
+ * r5 = client interface handler
+ * r6 = address of client program arguments (unused)
+ * r7 = length of client program arguments (unused)
+ *
+ * Yaboot and Linux use r3 and r4 for initrd address and size
+ */
.data
-_GLOBAL(saved_stack):
- DATA_LONG(0)
-
+saved_stack:
+ DATA_LONG(0)
.previous
+ /* void call_elf( arg1, arg2, entry ) */
+_GLOBAL(call_elf):
+ mflr r0
+ PPC_STLU r1, -STACKFRAME_MINSIZE(r1)
+ PPC_STL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
+ mtlr r5
+ LOAD_REG_IMMEDIATE(r8, saved_stack) // save our stack pointer
+ PPC_STL r1,0(r8)
+ mfsdr1 r1
+ addi r1, r1, -32768 /* - 32 KiB exception stack */
+ addis r1, r1, -1 /* - 64 KiB stack */
+ LOAD_REG_IMMEDIATE(r5, of_client_callback) // r5 = callback
+ li r6,0 // r6 = address of client program arguments (unused)
+ li r7,0 // r7 = length of client program arguments (unused)
+ li r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR
+ MTMSRD(r0)
+ blrl
+
+#ifdef CONFIG_PPC64
+ /* Restore SF bit */
+ LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
+ MTMSRD(r0)
+#endif
+ LOAD_REG_IMMEDIATE(r8, saved_stack) // restore stack pointer
+ mr r1,r8
+ PPC_LL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
+ mtlr r0
+ addi r1, r1, STACKFRAME_MINSIZE
+ // XXX: should restore r12-r31 etc..
+ // we should not really come here though
+ blr
#ifdef __powerpc64__
#define STKOFF STACKFRAME_MINSIZE
@@ -499,126 +540,133 @@ _GLOBAL(saved_stack):
#define STKOFF 8
#define SAVE_SPACE 144
#endif
-
GLOBL(of_client_callback):
+
#ifdef CONFIG_PPC64
- PPC_STLU r1, -(STACKFRAME_MINSIZE + 16)(r1)
+ PPC_STLU r1, -(STACKFRAME_MINSIZE + 16)(r1)
#else
- PPC_STLU r1, -STACKFRAME_MINSIZE(r1) /* fits within alignment */
+ PPC_STLU r1, -STACKFRAME_MINSIZE(r1) /* fits within alignment */
#endif
/* save r4 */
- PPC_STL r4, STKOFF(r1)
-
+
+ PPC_STL r4, STKOFF(r1)
+
/* save lr */
+
mflr r4
- PPC_STL r4, PPC_LR_STKOFF(r1)
-
+ PPC_STL r4, PPC_LR_STKOFF(r1)
+
/* restore OF stack */
+
LOAD_REG_IMMEDIATE(r4, saved_stack)
- PPC_LL r4, 0(r4)
-
- PPC_STLU r4, -SAVE_SPACE(r4)
- PPC_STL r1, (STKOFF)(r4) // save caller stack
+ PPC_LL r4, 0(r4)
+
+ PPC_STLU r4,-SAVE_SPACE(r4)
+ PPC_STL r1,(STKOFF)(r4) // save caller stack
mr r1,r4
-
- PPC_STL r3, (STKOFF + 5 * ULONG_SIZE)(r1)
- PPC_STL r2, (STKOFF + 4 * ULONG_SIZE)(r1)
- PPC_STL r0, (STKOFF + 3 * ULONG_SIZE)(r1)
-
+
+ PPC_STL r2, (STKOFF + 1 * ULONG_SIZE)(r1)
+ PPC_STL r0, (STKOFF + 2 * ULONG_SIZE)(r1)
+
/* save ctr, cr and xer */
+
mfctr r2
- PPC_STL r2, (STKOFF + 6 * ULONG_SIZE)(r1)
+ PPC_STL r2, (STKOFF + 3 * ULONG_SIZE)(r1)
mfcr r2
- PPC_STL r2, (STKOFF + 7 * ULONG_SIZE)(r1)
+ PPC_STL r2, (STKOFF + 4 * ULONG_SIZE)(r1)
mfxer r2
- PPC_STL r2, (STKOFF + 8 * ULONG_SIZE)(r1)
-
+ PPC_STL r2, (STKOFF + 5 * ULONG_SIZE)(r1)
+
/* save r5 - r31 */
- PPC_STL r5, (STKOFF + 10 * ULONG_SIZE)(r1)
- PPC_STL r6, (STKOFF + 11 * ULONG_SIZE)(r1)
- PPC_STL r7, (STKOFF + 12 * ULONG_SIZE)(r1)
- PPC_STL r8, (STKOFF + 13 * ULONG_SIZE)(r1)
- PPC_STL r9, (STKOFF + 14 * ULONG_SIZE)(r1)
- PPC_STL r10, (STKOFF + 15 * ULONG_SIZE)(r1)
- PPC_STL r11, (STKOFF + 16 * ULONG_SIZE)(r1)
- PPC_STL r12, (STKOFF + 17 * ULONG_SIZE)(r1)
- PPC_STL r13, (STKOFF + 18 * ULONG_SIZE)(r1)
- PPC_STL r14, (STKOFF + 19 * ULONG_SIZE)(r1)
- PPC_STL r15, (STKOFF + 20 * ULONG_SIZE)(r1)
- PPC_STL r16, (STKOFF + 21 * ULONG_SIZE)(r1)
- PPC_STL r17, (STKOFF + 22 * ULONG_SIZE)(r1)
- PPC_STL r18, (STKOFF + 23 * ULONG_SIZE)(r1)
- PPC_STL r19, (STKOFF + 24 * ULONG_SIZE)(r1)
- PPC_STL r20, (STKOFF + 25 * ULONG_SIZE)(r1)
- PPC_STL r21, (STKOFF + 26 * ULONG_SIZE)(r1)
- PPC_STL r22, (STKOFF + 27 * ULONG_SIZE)(r1)
- PPC_STL r23, (STKOFF + 28 * ULONG_SIZE)(r1)
- PPC_STL r24, (STKOFF + 29 * ULONG_SIZE)(r1)
- PPC_STL r25, (STKOFF + 30 * ULONG_SIZE)(r1)
- PPC_STL r26, (STKOFF + 31 * ULONG_SIZE)(r1)
- PPC_STL r27, (STKOFF + 32 * ULONG_SIZE)(r1)
- PPC_STL r28, (STKOFF + 33 * ULONG_SIZE)(r1)
- PPC_STL r29, (STKOFF + 34 * ULONG_SIZE)(r1)
- PPC_STL r30, (STKOFF + 35 * ULONG_SIZE)(r1)
- PPC_STL r31, (STKOFF + 36 * ULONG_SIZE)(r1)
-
+
+ PPC_STL r5, (STKOFF + 6 * ULONG_SIZE)(r1)
+ PPC_STL r6, (STKOFF + 7 * ULONG_SIZE)(r1)
+ PPC_STL r7, (STKOFF + 8 * ULONG_SIZE)(r1)
+ PPC_STL r8, (STKOFF + 9 * ULONG_SIZE)(r1)
+ PPC_STL r9, (STKOFF + 10 * ULONG_SIZE)(r1)
+ PPC_STL r10, (STKOFF + 11 * ULONG_SIZE)(r1)
+ PPC_STL r11, (STKOFF + 12 * ULONG_SIZE)(r1)
+ PPC_STL r12, (STKOFF + 13 * ULONG_SIZE)(r1)
+ PPC_STL r13, (STKOFF + 14 * ULONG_SIZE)(r1)
+ PPC_STL r14, (STKOFF + 15 * ULONG_SIZE)(r1)
+ PPC_STL r15, (STKOFF + 16 * ULONG_SIZE)(r1)
+ PPC_STL r16, (STKOFF + 17 * ULONG_SIZE)(r1)
+ PPC_STL r17, (STKOFF + 18 * ULONG_SIZE)(r1)
+ PPC_STL r18, (STKOFF + 19 * ULONG_SIZE)(r1)
+ PPC_STL r19, (STKOFF + 20 * ULONG_SIZE)(r1)
+ PPC_STL r20, (STKOFF + 21 * ULONG_SIZE)(r1)
+ PPC_STL r21, (STKOFF + 22 * ULONG_SIZE)(r1)
+ PPC_STL r22, (STKOFF + 23 * ULONG_SIZE)(r1)
+ PPC_STL r23, (STKOFF + 24 * ULONG_SIZE)(r1)
+ PPC_STL r24, (STKOFF + 25 * ULONG_SIZE)(r1)
+ PPC_STL r25, (STKOFF + 26 * ULONG_SIZE)(r1)
+ PPC_STL r26, (STKOFF + 27 * ULONG_SIZE)(r1)
+ PPC_STL r27, (STKOFF + 28 * ULONG_SIZE)(r1)
+ PPC_STL r28, (STKOFF + 29 * ULONG_SIZE)(r1)
+ PPC_STL r29, (STKOFF + 30 * ULONG_SIZE)(r1)
+ PPC_STL r30, (STKOFF + 31 * ULONG_SIZE)(r1)
+ PPC_STL r31, (STKOFF + 32 * ULONG_SIZE)(r1)
+
#ifdef CONFIG_PPC64
- LOAD_REG_IMMEDIATE(r2, of_client_interface)
- ld r2, 8(r2)
+ LOAD_REG_IMMEDIATE(r2, of_client_interface)
+ ld r2, 8(r2)
#endif
-
- bl BRANCH_LABEL(of_client_interface)
-
+ bl BRANCH_LABEL(of_client_interface)
+
/* restore r5 - r31 */
- PPC_LL r5, (STKOFF + 10 * ULONG_SIZE)(r1)
- PPC_LL r6, (STKOFF + 11 * ULONG_SIZE)(r1)
- PPC_LL r7, (STKOFF + 12 * ULONG_SIZE)(r1)
- PPC_LL r8, (STKOFF + 13 * ULONG_SIZE)(r1)
- PPC_LL r9, (STKOFF + 14 * ULONG_SIZE)(r1)
- PPC_LL r10, (STKOFF + 15 * ULONG_SIZE)(r1)
- PPC_LL r11, (STKOFF + 16 * ULONG_SIZE)(r1)
- PPC_LL r12, (STKOFF + 17 * ULONG_SIZE)(r1)
- PPC_LL r13, (STKOFF + 18 * ULONG_SIZE)(r1)
- PPC_LL r14, (STKOFF + 19 * ULONG_SIZE)(r1)
- PPC_LL r15, (STKOFF + 20 * ULONG_SIZE)(r1)
- PPC_LL r16, (STKOFF + 21 * ULONG_SIZE)(r1)
- PPC_LL r17, (STKOFF + 22 * ULONG_SIZE)(r1)
- PPC_LL r18, (STKOFF + 23 * ULONG_SIZE)(r1)
- PPC_LL r19, (STKOFF + 24 * ULONG_SIZE)(r1)
- PPC_LL r20, (STKOFF + 25 * ULONG_SIZE)(r1)
- PPC_LL r21, (STKOFF + 26 * ULONG_SIZE)(r1)
- PPC_LL r22, (STKOFF + 27 * ULONG_SIZE)(r1)
- PPC_LL r23, (STKOFF + 28 * ULONG_SIZE)(r1)
- PPC_LL r24, (STKOFF + 29 * ULONG_SIZE)(r1)
- PPC_LL r25, (STKOFF + 30 * ULONG_SIZE)(r1)
- PPC_LL r26, (STKOFF + 31 * ULONG_SIZE)(r1)
- PPC_LL r27, (STKOFF + 32 * ULONG_SIZE)(r1)
- PPC_LL r28, (STKOFF + 33 * ULONG_SIZE)(r1)
- PPC_LL r29, (STKOFF + 34 * ULONG_SIZE)(r1)
- PPC_LL r30, (STKOFF + 35 * ULONG_SIZE)(r1)
- PPC_LL r31, (STKOFF + 36 * ULONG_SIZE)(r1)
-
+
+ PPC_LL r5, (STKOFF + 6 * ULONG_SIZE)(r1)
+ PPC_LL r6, (STKOFF + 7 * ULONG_SIZE)(r1)
+ PPC_LL r7, (STKOFF + 8 * ULONG_SIZE)(r1)
+ PPC_LL r8, (STKOFF + 9 * ULONG_SIZE)(r1)
+ PPC_LL r9, (STKOFF + 10 * ULONG_SIZE)(r1)
+ PPC_LL r10, (STKOFF + 11 * ULONG_SIZE)(r1)
+ PPC_LL r11, (STKOFF + 12 * ULONG_SIZE)(r1)
+ PPC_LL r12, (STKOFF + 13 * ULONG_SIZE)(r1)
+ PPC_LL r13, (STKOFF + 14 * ULONG_SIZE)(r1)
+ PPC_LL r14, (STKOFF + 15 * ULONG_SIZE)(r1)
+ PPC_LL r15, (STKOFF + 16 * ULONG_SIZE)(r1)
+ PPC_LL r16, (STKOFF + 17 * ULONG_SIZE)(r1)
+ PPC_LL r17, (STKOFF + 18 * ULONG_SIZE)(r1)
+ PPC_LL r18, (STKOFF + 19 * ULONG_SIZE)(r1)
+ PPC_LL r19, (STKOFF + 20 * ULONG_SIZE)(r1)
+ PPC_LL r20, (STKOFF + 21 * ULONG_SIZE)(r1)
+ PPC_LL r21, (STKOFF + 22 * ULONG_SIZE)(r1)
+ PPC_LL r22, (STKOFF + 23 * ULONG_SIZE)(r1)
+ PPC_LL r23, (STKOFF + 24 * ULONG_SIZE)(r1)
+ PPC_LL r24, (STKOFF + 25 * ULONG_SIZE)(r1)
+ PPC_LL r25, (STKOFF + 26 * ULONG_SIZE)(r1)
+ PPC_LL r26, (STKOFF + 27 * ULONG_SIZE)(r1)
+ PPC_LL r27, (STKOFF + 28 * ULONG_SIZE)(r1)
+ PPC_LL r28, (STKOFF + 29 * ULONG_SIZE)(r1)
+ PPC_LL r29, (STKOFF + 30 * ULONG_SIZE)(r1)
+ PPC_LL r30, (STKOFF + 31 * ULONG_SIZE)(r1)
+ PPC_LL r31, (STKOFF + 32 * ULONG_SIZE)(r1)
+
/* restore ctr, cr and xer */
- PPC_LL r2, (STKOFF + 6 * ULONG_SIZE)(r1)
+
+ PPC_LL r2, (STKOFF + 3 * ULONG_SIZE)(r1)
mtctr r2
- PPC_LL r2, (STKOFF + 7 * ULONG_SIZE)(r1)
+ PPC_LL r2, (STKOFF + 4 * ULONG_SIZE)(r1)
mtcr r2
- PPC_LL r2, (STKOFF + 8 * ULONG_SIZE)(r1)
+ PPC_LL r2, (STKOFF + 5 * ULONG_SIZE)(r1)
mtxer r2
-
+
/* restore r0 and r2 */
- PPC_LL r2, (STKOFF + 4 * ULONG_SIZE)(r1)
- PPC_LL r0, (STKOFF + 3 * ULONG_SIZE)(r1)
-
+
+ PPC_LL r2, (STKOFF + 1 * ULONG_SIZE)(r1)
+ PPC_LL r0, (STKOFF + 2 * ULONG_SIZE)(r1)
+
/* restore caller stack */
- PPC_LL r1, (STKOFF)(r1)
-
- PPC_LL r4, PPC_LR_STKOFF(r1)
+
+ PPC_LL r1, (STKOFF)(r1)
+
+ PPC_LL r4, PPC_LR_STKOFF(r1)
mtlr r4
- PPC_LL r4, STKOFF(r1)
- PPC_LL r1, 0(r1)
-
+ PPC_LL r4, STKOFF(r1)
+ PPC_LL r1, 0(r1)
+
blr
/* rtas glue (must be reloctable) */