~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/openbios/arch/ppc/qemu/switch.S

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "autoconf.h"
 
2
#include "asm/asmdefs.h"
 
3
#include "asm/processor.h"
 
4
 
 
5
 
 
6
#ifdef CONFIG_PPC_64BITSUPPORT
 
7
  #ifdef __powerpc64__
 
8
    #define ULONG_SIZE 8
 
9
    #define STACKFRAME_MINSIZE 48
 
10
    #define STKOFF STACKFRAME_MINSIZE
 
11
    #define SAVE_SPACE 320
 
12
  #else
 
13
    #define ULONG_SIZE 4
 
14
    #define STACKFRAME_MINSIZE 16
 
15
    #define STKOFF 8
 
16
    #define SAVE_SPACE 144
 
17
  #endif
 
18
#endif
 
19
 
 
20
        /* According to IEEE 1275, PPC bindings:
 
21
         *
 
22
         *      MSR = FP, ME + (DR|IR)
 
23
         *      r1 = stack (32 K + 32 bytes link area above)
 
24
         *      r5 = client interface handler
 
25
         *      r6 = address of client program arguments (unused)
 
26
         *      r7 = length of client program arguments (unused)
 
27
         *
 
28
         *      Yaboot and Linux use r3 and r4 for initrd address and size
 
29
         */
 
30
 
 
31
        /* void call_elf( arg1, arg2, entry ) */
 
32
_GLOBAL(call_elf):
 
33
        mflr    r0
 
34
        PPC_STLU r1, -STACKFRAME_MINSIZE(r1)
 
35
        PPC_STL  r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
 
36
        mtlr    r5
 
37
        LOAD_REG_IMMEDIATE(r8, saved_stack)             // save our stack pointer
 
38
        PPC_STL r1,0(r8)
 
39
        mfsdr1  r1
 
40
        addi    r1, r1, -32768          /* - 32 KiB exception stack */
 
41
        addis   r1, r1, -1                      /* - 64 KiB stack */
 
42
        LOAD_REG_IMMEDIATE(r5, of_client_callback)      // r5 = callback
 
43
        li      r6,0                    // r6 = address of client program arguments (unused)
 
44
        li      r7,0                    // r7 = length of client program arguments (unused)
 
45
        li      r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR
 
46
        MTMSRD(r0)
 
47
        blrl
 
48
 
 
49
#ifdef CONFIG_PPC64
 
50
    /* Restore SF bit */
 
51
    LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
 
52
    MTMSRD(r0)
 
53
#endif
 
54
        LOAD_REG_IMMEDIATE(r8, saved_stack)             // restore stack pointer
 
55
        mr      r1,r8
 
56
        PPC_LL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
 
57
        mtlr    r0
 
58
        addi    r1, r1, STACKFRAME_MINSIZE
 
59
        // XXX: should restore r12-r31 etc..
 
60
        // we should not really come here though
 
61
        blrl
 
62
 
 
63
/*
 
64
 * Switch execution context
 
65
 * This saves registers in the stack, then
 
66
 * switches the stack, and restores everything from the new stack.
 
67
 * This function takes no argument. New stack pointer is
 
68
 * taken from global variable __context, and old stack pointer
 
69
 * is also saved to __context. This way we can just jump to
 
70
 * this routine to get back to the original context.
 
71
 */
 
72
 
 
73
_GLOBAL(__switch_context):
 
74
        /* save internal stack pointer */
 
75
#ifdef CONFIG_PPC64
 
76
        PPC_STL  r1, -(SAVE_SPACE + 16) + STKOFF(r1)
 
77
#else
 
78
        PPC_STL  r1, -SAVE_SPACE + STKOFF(r1)
 
79
#endif
 
80
        
 
81
#ifdef CONFIG_PPC64
 
82
        PPC_STLU r1, -(SAVE_SPACE + 16)(r1)
 
83
#else
 
84
        PPC_STLU r1, -SAVE_SPACE(r1) /* fits within alignment */
 
85
#endif
 
86
        
 
87
        /* r4, r5 */
 
88
        PPC_STL r4, (STKOFF + 9 * ULONG_SIZE)(r1)
 
89
        PPC_STL r5, (STKOFF + 10 * ULONG_SIZE)(r1)
 
90
        
 
91
        /* link register */
 
92
        mflr    r4
 
93
        PPC_STL  r4, PPC_LR_STKOFF(r1)
 
94
        PPC_STL  r4,  (STKOFF + ULONG_SIZE)(r1)
 
95
        
 
96
        PPC_STL  r3,  (STKOFF + 5 * ULONG_SIZE)(r1)
 
97
        PPC_STL  r2,  (STKOFF + 4 * ULONG_SIZE)(r1)
 
98
        PPC_STL  r0,  (STKOFF + 3 * ULONG_SIZE)(r1)
 
99
        
 
100
        /* ctr, cr and xer */
 
101
        mfctr   r4
 
102
        PPC_STL  r4,  (STKOFF + 6 * ULONG_SIZE)(r1)
 
103
        mfcr    r4
 
104
        PPC_STL  r4,  (STKOFF + 7 * ULONG_SIZE)(r1)
 
105
        mfxer   r4
 
106
        PPC_STL  r4,  (STKOFF + 8 * ULONG_SIZE)(r1)
 
107
        
 
108
        /* r6-r31 */
 
109
        PPC_STL  r6,  (STKOFF + 11 * ULONG_SIZE)(r1)
 
110
        PPC_STL  r7,  (STKOFF + 12 * ULONG_SIZE)(r1)
 
111
        PPC_STL  r8,  (STKOFF + 13 * ULONG_SIZE)(r1)
 
112
        PPC_STL  r9,  (STKOFF + 14 * ULONG_SIZE)(r1)
 
113
        PPC_STL  r10,  (STKOFF + 15 * ULONG_SIZE)(r1)
 
114
        PPC_STL  r11,  (STKOFF + 16 * ULONG_SIZE)(r1)
 
115
        PPC_STL  r12,  (STKOFF + 17 * ULONG_SIZE)(r1)
 
116
        PPC_STL  r13,  (STKOFF + 18 * ULONG_SIZE)(r1)
 
117
        PPC_STL  r14,  (STKOFF + 19 * ULONG_SIZE)(r1)
 
118
        PPC_STL  r15,  (STKOFF + 20 * ULONG_SIZE)(r1)
 
119
        PPC_STL  r16,  (STKOFF + 21 * ULONG_SIZE)(r1)
 
120
        PPC_STL  r17,  (STKOFF + 22 * ULONG_SIZE)(r1)
 
121
        PPC_STL  r18,  (STKOFF + 23 * ULONG_SIZE)(r1)
 
122
        PPC_STL  r19,  (STKOFF + 24 * ULONG_SIZE)(r1)
 
123
        PPC_STL  r20,  (STKOFF + 25 * ULONG_SIZE)(r1)
 
124
        PPC_STL  r21,  (STKOFF + 26 * ULONG_SIZE)(r1)
 
125
        PPC_STL  r22,  (STKOFF + 27 * ULONG_SIZE)(r1)
 
126
        PPC_STL  r23,  (STKOFF + 28 * ULONG_SIZE)(r1)
 
127
        PPC_STL  r24,  (STKOFF + 29 * ULONG_SIZE)(r1)
 
128
        PPC_STL  r25,  (STKOFF + 30 * ULONG_SIZE)(r1)
 
129
        PPC_STL  r26,  (STKOFF + 31 * ULONG_SIZE)(r1)
 
130
        PPC_STL  r27,  (STKOFF + 32 * ULONG_SIZE)(r1)
 
131
        PPC_STL  r28,  (STKOFF + 33 * ULONG_SIZE)(r1)
 
132
        PPC_STL  r29,  (STKOFF + 34 * ULONG_SIZE)(r1)
 
133
        PPC_STL  r30,  (STKOFF + 35 * ULONG_SIZE)(r1)
 
134
        PPC_STL  r31,  (STKOFF + 36 * ULONG_SIZE)(r1)
 
135
        
 
136
        /* swap context */
 
137
        LOAD_REG_IMMEDIATE(r4, __context)
 
138
        PPC_LL   r5, 0(r4)
 
139
        PPC_STL  r1, 0(r4)
 
140
        mr      r4, r5
 
141
        
 
142
        b       __set_context
 
143
        
 
144
_GLOBAL(__switch_context_nosave):
 
145
        LOAD_REG_IMMEDIATE(r4, __context)
 
146
        PPC_LL  r4, 0(r4)
 
147
        
 
148
__set_context:
 
149
        /* link register */
 
150
        PPC_LL  r5, (STKOFF + ULONG_SIZE)(r4)
 
151
        mtlr    r5
 
152
        
 
153
        PPC_LL r3,  (STKOFF + 5 * ULONG_SIZE)(r4)
 
154
        PPC_LL r2,  (STKOFF + 4 * ULONG_SIZE)(r4)
 
155
        PPC_LL r0,  (STKOFF + 3 * ULONG_SIZE)(r4)
 
156
        
 
157
        /* ctr, cr and xer */
 
158
        PPC_LL r5,  (STKOFF + 6 * ULONG_SIZE)(r4)
 
159
        mtctr   r5
 
160
        PPC_LL r5,  (STKOFF + 7 * ULONG_SIZE)(r4)
 
161
        mtcr    r5
 
162
        PPC_LL r5,  (STKOFF + 8 * ULONG_SIZE)(r4)
 
163
        mtxer   r5
 
164
        
 
165
        /* r5-r31 */
 
166
        PPC_LL  r5,  (STKOFF + 10 * ULONG_SIZE)(r4)
 
167
        PPC_LL  r6,  (STKOFF + 11 * ULONG_SIZE)(r4)
 
168
        PPC_LL  r7,  (STKOFF + 12 * ULONG_SIZE)(r4)
 
169
        PPC_LL  r8,  (STKOFF + 13 * ULONG_SIZE)(r4)
 
170
        PPC_LL  r9,  (STKOFF + 14 * ULONG_SIZE)(r4)
 
171
        PPC_LL  r10,  (STKOFF + 15 * ULONG_SIZE)(r4)
 
172
        PPC_LL  r11,  (STKOFF + 16 * ULONG_SIZE)(r4)
 
173
        PPC_LL  r12,  (STKOFF + 17 * ULONG_SIZE)(r4)
 
174
        PPC_LL  r13,  (STKOFF + 18 * ULONG_SIZE)(r4)
 
175
        PPC_LL  r14,  (STKOFF + 19 * ULONG_SIZE)(r4)
 
176
        PPC_LL  r15,  (STKOFF + 20 * ULONG_SIZE)(r4)
 
177
        PPC_LL  r16,  (STKOFF + 21 * ULONG_SIZE)(r4)
 
178
        PPC_LL  r17,  (STKOFF + 22 * ULONG_SIZE)(r4)
 
179
        PPC_LL  r18,  (STKOFF + 23 * ULONG_SIZE)(r4)
 
180
        PPC_LL  r19,  (STKOFF + 24 * ULONG_SIZE)(r4)
 
181
        PPC_LL  r20,  (STKOFF + 25 * ULONG_SIZE)(r4)
 
182
        PPC_LL  r21,  (STKOFF + 26 * ULONG_SIZE)(r4)
 
183
        PPC_LL  r22,  (STKOFF + 27 * ULONG_SIZE)(r4)
 
184
        PPC_LL  r23,  (STKOFF + 28 * ULONG_SIZE)(r4)
 
185
        PPC_LL  r24,  (STKOFF + 29 * ULONG_SIZE)(r4)
 
186
        PPC_LL  r25,  (STKOFF + 30 * ULONG_SIZE)(r4)
 
187
        PPC_LL  r26,  (STKOFF + 31 * ULONG_SIZE)(r4)
 
188
        PPC_LL  r27,  (STKOFF + 32 * ULONG_SIZE)(r4)
 
189
        PPC_LL  r28,  (STKOFF + 33 * ULONG_SIZE)(r4)
 
190
        PPC_LL  r29,  (STKOFF + 34 * ULONG_SIZE)(r4)
 
191
        PPC_LL  r30,  (STKOFF + 35 * ULONG_SIZE)(r4)
 
192
        PPC_LL  r31,  (STKOFF + 36 * ULONG_SIZE)(r4)
 
193
        
 
194
        /* r4, r1 */
 
195
        PPC_LL  r1,  STKOFF(r4)
 
196
        PPC_LL  r4,  (STKOFF + 9 * ULONG_SIZE)(r4)
 
197
        
 
198
        LOAD_REG_IMMEDIATE(r0, MSR_FP | MSR_ME | MSR_DR | MSR_IR)
 
199
        MTMSRD(r0)
 
200
        
 
201
        blrl
 
202
        
 
203
#ifdef CONFIG_PPC64
 
204
        /* Restore SF bit */
 
205
        LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
 
206
        MTMSRD(r0)
 
207
#endif
 
208
        
 
209
_GLOBAL(__exit_context):
 
210
        /* Get back to the original context */
 
211
        b       __switch_context