2
#include "asm/asmdefs.h"
3
#include "asm/processor.h"
6
#ifdef CONFIG_PPC_64BITSUPPORT
9
#define STACKFRAME_MINSIZE 48
10
#define STKOFF STACKFRAME_MINSIZE
11
#define SAVE_SPACE 320
14
#define STACKFRAME_MINSIZE 16
16
#define SAVE_SPACE 144
20
/* According to IEEE 1275, PPC bindings:
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)
28
* Yaboot and Linux use r3 and r4 for initrd address and size
31
/* void call_elf( arg1, arg2, entry ) */
34
PPC_STLU r1, -STACKFRAME_MINSIZE(r1)
35
PPC_STL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
37
LOAD_REG_IMMEDIATE(r8, saved_stack) // save our stack pointer
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
51
LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
54
LOAD_REG_IMMEDIATE(r8, saved_stack) // restore stack pointer
56
PPC_LL r0, (STACKFRAME_MINSIZE + PPC_LR_STKOFF)(r1)
58
addi r1, r1, STACKFRAME_MINSIZE
59
// XXX: should restore r12-r31 etc..
60
// we should not really come here though
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.
73
_GLOBAL(__switch_context):
74
/* save internal stack pointer */
76
PPC_STL r1, -(SAVE_SPACE + 16) + STKOFF(r1)
78
PPC_STL r1, -SAVE_SPACE + STKOFF(r1)
82
PPC_STLU r1, -(SAVE_SPACE + 16)(r1)
84
PPC_STLU r1, -SAVE_SPACE(r1) /* fits within alignment */
88
PPC_STL r4, (STKOFF + 9 * ULONG_SIZE)(r1)
89
PPC_STL r5, (STKOFF + 10 * ULONG_SIZE)(r1)
93
PPC_STL r4, PPC_LR_STKOFF(r1)
94
PPC_STL r4, (STKOFF + ULONG_SIZE)(r1)
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)
100
/* ctr, cr and xer */
102
PPC_STL r4, (STKOFF + 6 * ULONG_SIZE)(r1)
104
PPC_STL r4, (STKOFF + 7 * ULONG_SIZE)(r1)
106
PPC_STL r4, (STKOFF + 8 * ULONG_SIZE)(r1)
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)
137
LOAD_REG_IMMEDIATE(r4, __context)
144
_GLOBAL(__switch_context_nosave):
145
LOAD_REG_IMMEDIATE(r4, __context)
150
PPC_LL r5, (STKOFF + ULONG_SIZE)(r4)
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)
157
/* ctr, cr and xer */
158
PPC_LL r5, (STKOFF + 6 * ULONG_SIZE)(r4)
160
PPC_LL r5, (STKOFF + 7 * ULONG_SIZE)(r4)
162
PPC_LL r5, (STKOFF + 8 * ULONG_SIZE)(r4)
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)
195
PPC_LL r1, STKOFF(r4)
196
PPC_LL r4, (STKOFF + 9 * ULONG_SIZE)(r4)
198
LOAD_REG_IMMEDIATE(r0, MSR_FP | MSR_ME | MSR_DR | MSR_IR)
205
LOAD_REG_IMMEDIATE(r0, MSR_SF | MSR_FP | MSR_ME | MSR_DR | MSR_IR)
209
_GLOBAL(__exit_context):
210
/* Get back to the original context */