entry.h
7.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#ifndef __SK_ENTRY_CONSTANTS_HDR__
#define __SK_ENTRY_CONSTANTS_HDR__
/* define to enable stack checking via gaurdband */
#undef SK_STACK_CHECK
//#define SK_STACK_CHECK 1
#ifndef _LANGUAGE_C
#include <regdef.h>
#include <asm.h>
#include <PR/R4300.h>
#include <PR/bcp.h>
#define PTR .word
#define PTRSIZE 4
#define PTRLOG 2
/* macros for switching execution between cached and uncached */
#define CACHED_EXECUTION_USING_T0 \
la t0, 1f; \
and t0, ~K1BASE; \
or t0, K0BASE; \
jr t0; \
1:
#define UNCACHED_EXECUTION_USING_T0 \
la t0, 1f; \
or t0, K1BASE; \
jr t0; \
1:
#define REG_TO_K1(_r) or _r, K1BASE
#define REG_TO_K0(_r) and _r, ~K1BASE; or _r, K0BASE
/* hard-coded locations */
#define SK_STACK_SIZE 0x6000
#define SK_HEAP_SIZE 0x400
/* preserve space for initial C call from assembly. the
* compiler may use this space to store a0..a3 and ra.
* it is 8B aligned.
*/
#define SK_STACK_RESV_INIT_C 24
/* register saving for SK */
#define SK_SP_AT (SK_STACK_RESV_INIT_C + 0x00)
#define SK_SP_V0 (SK_STACK_RESV_INIT_C + 0x08)
#define SK_SP_V1 (SK_STACK_RESV_INIT_C + 0x10)
#define SK_SP_A0 (SK_STACK_RESV_INIT_C + 0x18)
#define SK_SP_A1 (SK_STACK_RESV_INIT_C + 0x20)
#define SK_SP_A2 (SK_STACK_RESV_INIT_C + 0x28)
#define SK_SP_A3 (SK_STACK_RESV_INIT_C + 0x30)
#define SK_SP_T0 (SK_STACK_RESV_INIT_C + 0x38)
#define SK_SP_T1 (SK_STACK_RESV_INIT_C + 0x40)
#define SK_SP_T2 (SK_STACK_RESV_INIT_C + 0x48)
#define SK_SP_T3 (SK_STACK_RESV_INIT_C + 0x50)
#define SK_SP_T4 (SK_STACK_RESV_INIT_C + 0x58)
#define SK_SP_T5 (SK_STACK_RESV_INIT_C + 0x60)
#define SK_SP_T6 (SK_STACK_RESV_INIT_C + 0x68)
#define SK_SP_T7 (SK_STACK_RESV_INIT_C + 0x70)
#define SK_SP_S0 (SK_STACK_RESV_INIT_C + 0x78)
#define SK_SP_S1 (SK_STACK_RESV_INIT_C + 0x80)
#define SK_SP_S2 (SK_STACK_RESV_INIT_C + 0x88)
#define SK_SP_S3 (SK_STACK_RESV_INIT_C + 0x90)
#define SK_SP_S4 (SK_STACK_RESV_INIT_C + 0x98)
#define SK_SP_S5 (SK_STACK_RESV_INIT_C + 0xa0)
#define SK_SP_S6 (SK_STACK_RESV_INIT_C + 0xa8)
#define SK_SP_S7 (SK_STACK_RESV_INIT_C + 0xb0)
#define SK_SP_T8 (SK_STACK_RESV_INIT_C + 0xb8)
#define SK_SP_T9 (SK_STACK_RESV_INIT_C + 0xc0)
#define SK_SP_K0 (SK_STACK_RESV_INIT_C + 0xc8)
#define SK_SP_K1 (SK_STACK_RESV_INIT_C + 0xd0)
#define SK_SP_GP (SK_STACK_RESV_INIT_C + 0xd8)
#define SK_SP_SP (SK_STACK_RESV_INIT_C + 0xe0)
#define SK_SP_S8 (SK_STACK_RESV_INIT_C + 0xe8)
#define SK_SP_RA (SK_STACK_RESV_INIT_C + 0xf0)
#define SK_SP_CP0_TAGLO (SK_STACK_RESV_INIT_C + 0x0f8)
#define SK_SP_CP0_TAGHI (SK_STACK_RESV_INIT_C + 0x100)
#define SK_SP_CP0_COUNT (SK_STACK_RESV_INIT_C + 0x108)
#define SK_SP_LO (SK_STACK_RESV_INIT_C + 0x110)
#define SK_SP_HI (SK_STACK_RESV_INIT_C + 0x118)
/* this number must include space for the total number of
* SK_SP_ vals above (*8), and the initial stack the compiler
* might use for the first "C" call.
*/
#define SK_CONTEXT_SIZE (0x118 + 8 + SK_STACK_RESV_INIT_C)
#define SK_STACK_SET \
la sp, __stack + SK_STACK_SIZE; \
subu sp, SK_CONTEXT_SIZE
#define SK_STACK_SET_KSEG1 \
la sp, (__stack + SK_STACK_SIZE) | K1BASE; \
subu sp, SK_CONTEXT_SIZE
#define SK_CONTEXT_SAVE_AT \
.set push; \
.set noat; \
sd AT, SK_SP_AT(sp); \
.set pop
#define SK_CONTEXT_REST_AT \
.set push; \
.set noat; \
ld AT, SK_SP_AT(sp); \
.set pop
#define SK_CONTEXT_SAVE_CP0_API(_r) \
mfc0 _r, C0_TAGLO; \
sd _r, SK_SP_CP0_TAGLO(sp); \
mfc0 _r, C0_TAGHI; \
sd _r, SK_SP_CP0_TAGHI(sp); \
mflo _r; \
sd _r, SK_SP_LO(sp); \
mfhi _r; \
sd _r, SK_SP_HI(sp)
#define SK_CONTEXT_SAVE_CP0(_r) \
SK_CONTEXT_SAVE_CP0_API(_r); \
mfc0 _r, C0_COUNT; \
sd _r, SK_SP_CP0_COUNT(sp)
#define SK_CONTEXT_REST_CP0_API(_r) \
ld _r, SK_SP_CP0_TAGLO(sp); \
mtc0 _r, C0_TAGLO; \
ld _r, SK_SP_CP0_TAGHI(sp); \
mtc0 _r, C0_TAGHI; \
ld _r, SK_SP_LO(sp); \
mtlo _r; \
ld _r, SK_SP_HI(sp); \
mthi _r
#define SK_CONTEXT_REST_CP0(_r) \
SK_CONTEXT_REST_CP0_API(_r); \
ld _r, SK_SP_CP0_COUNT(sp); \
mtc0 _r, C0_COUNT
#define SK_CONTEXT_SAVE_KX \
sw k1, SK_SP_K0(sp); \
dsrl32 k1, 0; \
sw k1, SK_SP_K1(sp)
#define SK_CONTEXT_SAVE_AX \
sd a0, SK_SP_A0(sp); \
sd a1, SK_SP_A1(sp); \
sd a2, SK_SP_A2(sp); \
sd a3, SK_SP_A3(sp)
#define SK_CONTEXT_REST_AX \
ld a0, SK_SP_A0(sp); \
ld a1, SK_SP_A1(sp); \
ld a2, SK_SP_A2(sp); \
ld a3, SK_SP_A3(sp)
#define SK_CONTEXT_SAVE_SX \
sd s0, SK_SP_S0(sp); \
sd s1, SK_SP_S1(sp); \
sd s2, SK_SP_S2(sp); \
sd s3, SK_SP_S3(sp); \
sd s4, SK_SP_S4(sp); \
sd s5, SK_SP_S5(sp); \
sd s6, SK_SP_S6(sp); \
sd s7, SK_SP_S7(sp); \
sd s8, SK_SP_S8(sp)
#define SK_CONTEXT_REST_SX \
ld s0, SK_SP_S0(sp); \
ld s1, SK_SP_S1(sp); \
ld s2, SK_SP_S2(sp); \
ld s3, SK_SP_S3(sp); \
ld s4, SK_SP_S4(sp); \
ld s5, SK_SP_S5(sp); \
ld s6, SK_SP_S6(sp); \
ld s7, SK_SP_S7(sp); \
ld s8, SK_SP_S8(sp)
#define SK_CONTEXT_SAVE_TX \
sd t0, SK_SP_T0(sp); \
sd t1, SK_SP_T1(sp); \
sd t2, SK_SP_T2(sp); \
sd t3, SK_SP_T3(sp); \
sd t4, SK_SP_T4(sp); \
sd t5, SK_SP_T5(sp); \
sd t6, SK_SP_T6(sp); \
sd t7, SK_SP_T7(sp); \
sd t8, SK_SP_T8(sp); \
sd t9, SK_SP_T9(sp)
#define SK_CONTEXT_REST_TX \
ld t0, SK_SP_T0(sp); \
ld t1, SK_SP_T1(sp); \
ld t2, SK_SP_T2(sp); \
ld t3, SK_SP_T3(sp); \
ld t4, SK_SP_T4(sp); \
ld t5, SK_SP_T5(sp); \
ld t6, SK_SP_T6(sp); \
ld t7, SK_SP_T7(sp); \
ld t8, SK_SP_T8(sp); \
ld t9, SK_SP_T9(sp)
/* NOTE: assuming k0 holds entry sp. */
#define SK_CONTEXT_SAVE_API \
SK_CONTEXT_SAVE_AT; \
SK_CONTEXT_SAVE_SX; \
sd gp, SK_SP_GP(sp); \
sw k0, SK_SP_SP(sp); \
sd ra, SK_SP_RA(sp)
/* DO NOT restore sp here */
#define SK_CONTEXT_REST_API \
SK_CONTEXT_REST_AT; \
SK_CONTEXT_REST_SX; \
ld gp, SK_SP_GP(sp); \
ld ra, SK_SP_RA(sp)
/* save all regs assuming k0 holds entry sp, and k1 holds both k0 and k1.
* doing CP0 as soon as possible to catch C0_COUNT early.
*/
#define SK_CONTEXT_SAVE_ALL \
SK_CONTEXT_SAVE_KX; \
SK_CONTEXT_SAVE_CP0(k1);\
SK_CONTEXT_SAVE_API; \
SK_CONTEXT_SAVE_TX; \
sd v0, SK_SP_V0(sp); \
sd v1, SK_SP_V1(sp); \
SK_CONTEXT_SAVE_AX
/* restore all except k0, k1, and sp. doing CP0 as late as possible
* so C0_COUNT changes as little as possible.
*/
#define SK_CONTEXT_REST_MOST \
SK_CONTEXT_REST_TX; \
SK_CONTEXT_REST_AX; \
ld v0, SK_SP_V0(sp); \
SK_CONTEXT_REST_API; \
SK_CONTEXT_REST_CP0(v1); \
ld v1, SK_SP_V1(sp); \
#endif
#endif