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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
|
#include "mem.h"
#include "osf1pal.h"
#define SP R30
#define HI_IPL 6 /* use 7 to disable mchecks */
TEXT _main(SB), $-8
MOVQ $setSB(SB), R29
MOVQ R29, R16
CALL_PAL $PALwrkgp
MOVQ $mach0(SB), R(MACH)
MOVQ $(BY2PG-8)(R(MACH)), R30
MOVQ R31, R(USER)
MOVQ R31, 0(R(MACH))
MOVQ $edata(SB), R1
MOVQ $end(SB), R2
clrbss:
MOVQ R31, (R1)
ADDQ $8, R1
CMPUGT R1, R2, R3
BEQ R3, clrbss
MOVL R0, bootconf(SB) /* passed in from boot loader */
_fpinit:
MOVQ $1, R16
CALL_PAL $PALwrfen
MOVQ initfpcr(SB), R1 /* MOVQ $0x2800800000000000, R1 */
MOVQ R1, (R30)
MOVT (R30), F1
MOVT F1, FPCR
MOVT $0.5, F28
ADDT F28, F28, F29
ADDT F29, F29, F30
MOVT F31, F1
MOVT F31, F2
MOVT F31, F3
MOVT F31, F4
MOVT F31, F5
MOVT F31, F6
MOVT F31, F7
MOVT F31, F8
MOVT F31, F9
MOVT F31, F10
MOVT F31, F11
MOVT F31, F12
MOVT F31, F13
MOVT F31, F14
MOVT F31, F15
MOVT F31, F16
MOVT F31, F17
MOVT F31, F18
MOVT F31, F19
MOVT F31, F20
MOVT F31, F21
MOVT F31, F22
MOVT F31, F23
MOVT F31, F24
MOVT F31, F25
MOVT F31, F26
MOVT F31, F27
JSR main(SB)
MOVQ $_divq(SB), R31 /* touch _divq etc.; doesn't need to execute */
MOVQ $_divl(SB), R31 /* touch _divl etc.; doesn't need to execute */
RET
TEXT setpcb(SB), $-8
MOVQ R30, (R0)
AND $0x7FFFFFFF, R0, R16 /* make address physical */
CALL_PAL $PALswpctx
RET
GLOBL mach0(SB), $(MAXMACH*BY2PG)
GLOBL init_ptbr(SB), $8
TEXT firmware(SB), $-8
CALL_PAL $PALhalt
TEXT xxfirmware(SB), $-8
CALL_PAL $PALhalt
TEXT splhi(SB), $0
MOVL R26, 4(R(MACH)) /* save PC in m->splpc */
MOVQ $HI_IPL, R16
CALL_PAL $PALswpipl
RET
TEXT spllo(SB), $0
MOVQ R31, R16
CALL_PAL $PALswpipl
RET
TEXT splx(SB), $0
MOVL R26, 4(R(MACH)) /* save PC in m->splpc */
TEXT splxpc(SB), $0 /* for iunlock */
MOVQ R0, R16
CALL_PAL $PALswpipl
RET
TEXT spldone(SB), $0
RET
TEXT islo(SB), $0
CALL_PAL $PALrdps
AND $IPL, R0
XOR $HI_IPL, R0
RET
TEXT mb(SB), $-8
MB
RET
TEXT icflush(SB), $-8
CALL_PAL $PALimb
RET
TEXT tlbflush(SB), $-8
MOVQ R0, R16
MOVL 4(FP), R17
CALL_PAL $PALtbi
RET
TEXT swpctx(SB), $-8
MOVQ R0, R16
AND $0x7FFFFFFF, R16 /* make address physical */
CALL_PAL $PALswpctx
RET
TEXT wrent(SB), $-8
MOVQ R0, R17
MOVL 4(FP), R16
CALL_PAL $PALwrent
RET
TEXT wrvptptr(SB), $-8
MOVQ R0, R16
CALL_PAL $PALwrvptptr
RET
TEXT cserve(SB), $-8
MOVQ R0, R16
MOVL 4(FP), R17
CALL_PAL $PALcserve
RET
TEXT setlabel(SB), $-8
MOVL R30, 0(R0)
MOVL R26, 4(R0)
MOVQ $0, R0
RET
TEXT gotolabel(SB), $-8
MOVL 0(R0), R30
MOVL 4(R0), R26
MOVQ $1, R0
RET
TEXT tas(SB), $-8
MOVQ R0, R1 /* l */
tas1:
MOVLL (R1), R0 /* l->key */
BNE R0, tas2
MOVQ $1, R2
MOVLC R2, (R1) /* l->key = 1 */
BEQ R2, tas1 /* write failed, try again? */
tas2:
RET
TEXT _xdec(SB), $-8
MOVQ R0, R1 /* p */
dec1:
MOVLL (R1), R0 /* *p */
SUBL $1, R0
MOVQ R0, R2
MOVLC R2, (R1) /* --(*p) */
BEQ R2, dec1 /* write failed, retry */
RET
TEXT _xinc(SB), $-8
MOVQ R0, R1 /* p */
inc1:
MOVLL (R1), R0 /* *p */
ADDL $1, R0
MOVLC R0, (R1) /* (*p)++ */
BEQ R0, inc1 /* write failed, retry */
RET
TEXT cmpswap(SB), $-8
MOVQ R0, R1 /* p */
MOVL old+4(FP), R2
MOVL new+8(FP), R3
MOVLL (R1), R0
CMPEQ R0, R2, R4
BEQ R4, fail /* if R0 != [sic] R2, goto fail */
MOVQ R3, R0
MOVLC R0, (R1)
RET
fail:
MOVL $0, R0
RET
TEXT fpenab(SB), $-8
MOVQ R0, R16
CALL_PAL $PALwrfen
RET
TEXT rpcc(SB), $0
MOVL R0, R1
MOVL $0, R0
WORD $0x6000C000 /* RPCC R0 */
BEQ R1, _ret
MOVQ R0, (R1)
_ret:
RET
/*
* Exception handlers. The stack frame looks like this:
*
* R30+0: (unused) link reg storage (R26) (32 bits)
* R30+4: padding for alignment (32 bits)
* R30+8: trap()'s first arg storage (R0) (32 bits -- type Ureg*)
* R30+12: padding for alignment (32 bits)
* R30+16: first 31 fields of Ureg, saved here (31*64 bits)
* R30+264: other 6 fields of Ureg, saved by PALcode (6*64 bits)
* R30+312: previous value of KSP before trap
*/
TEXT arith(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30)
MOVQ $1, R0
JMP trapcommon
TEXT illegal0(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30)
MOVQ $2, R0
JMP trapcommon
TEXT fault0(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30)
MOVQ $4, R0
JMP trapcommon
TEXT unaligned(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30)
MOVQ $6, R0
JMP trapcommon
TEXT intr0(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30)
MOVQ $3, R0
trapcommon:
MOVQ R0, (4*BY2WD+0*BY2V)(R30)
MOVQ R16, (4*BY2WD+1*BY2V)(R30)
MOVQ R17, (4*BY2WD+2*BY2V)(R30)
MOVQ R18, (4*BY2WD+3*BY2V)(R30)
/* R0 already saved, (4*BY2WD+4*BY2V)(R30) */
MOVQ R1, (4*BY2WD+5*BY2V)(R30)
MOVQ R2, (4*BY2WD+6*BY2V)(R30)
MOVQ R3, (4*BY2WD+7*BY2V)(R30)
MOVQ R4, (4*BY2WD+8*BY2V)(R30)
MOVQ R5, (4*BY2WD+9*BY2V)(R30)
MOVQ R6, (4*BY2WD+10*BY2V)(R30)
MOVQ R7, (4*BY2WD+11*BY2V)(R30)
MOVQ R8, (4*BY2WD+12*BY2V)(R30)
MOVQ R9, (4*BY2WD+13*BY2V)(R30)
MOVQ R10, (4*BY2WD+14*BY2V)(R30)
MOVQ R11, (4*BY2WD+15*BY2V)(R30)
MOVQ R12, (4*BY2WD+16*BY2V)(R30)
MOVQ R13, (4*BY2WD+17*BY2V)(R30)
MOVQ R14, (4*BY2WD+18*BY2V)(R30)
MOVQ R15, (4*BY2WD+19*BY2V)(R30)
MOVQ R19, (4*BY2WD+20*BY2V)(R30)
MOVQ R20, (4*BY2WD+21*BY2V)(R30)
MOVQ R21, (4*BY2WD+22*BY2V)(R30)
MOVQ R22, (4*BY2WD+23*BY2V)(R30)
MOVQ R23, (4*BY2WD+24*BY2V)(R30)
MOVQ R24, (4*BY2WD+25*BY2V)(R30)
MOVQ R25, (4*BY2WD+26*BY2V)(R30)
MOVQ R26, (4*BY2WD+27*BY2V)(R30)
MOVQ R27, (4*BY2WD+28*BY2V)(R30)
MOVQ R28, (4*BY2WD+29*BY2V)(R30)
MOVQ $HI_IPL, R16
CALL_PAL $PALswpipl
CALL_PAL $PALrdusp
MOVQ R0, (4*BY2WD+30*BY2V)(R30) /* save USP */
MOVQ $mach0(SB), R(MACH)
MOVQ $(4*BY2WD)(R30), R0
JSR trap(SB)
trapret:
MOVQ (4*BY2WD+30*BY2V)(R30), R16 /* USP */
CALL_PAL $PALwrusp /* ... */
MOVQ (4*BY2WD+4*BY2V)(R30), R0
MOVQ (4*BY2WD+5*BY2V)(R30), R1
MOVQ (4*BY2WD+6*BY2V)(R30), R2
MOVQ (4*BY2WD+7*BY2V)(R30), R3
MOVQ (4*BY2WD+8*BY2V)(R30), R4
MOVQ (4*BY2WD+9*BY2V)(R30), R5
MOVQ (4*BY2WD+10*BY2V)(R30), R6
MOVQ (4*BY2WD+11*BY2V)(R30), R7
MOVQ (4*BY2WD+12*BY2V)(R30), R8
MOVQ (4*BY2WD+13*BY2V)(R30), R9
MOVQ (4*BY2WD+14*BY2V)(R30), R10
MOVQ (4*BY2WD+15*BY2V)(R30), R11
MOVQ (4*BY2WD+16*BY2V)(R30), R12
MOVQ (4*BY2WD+17*BY2V)(R30), R13
MOVQ (4*BY2WD+18*BY2V)(R30), R14
MOVQ (4*BY2WD+19*BY2V)(R30), R15
MOVQ (4*BY2WD+20*BY2V)(R30), R19
MOVQ (4*BY2WD+21*BY2V)(R30), R20
MOVQ (4*BY2WD+22*BY2V)(R30), R21
MOVQ (4*BY2WD+23*BY2V)(R30), R22
MOVQ (4*BY2WD+24*BY2V)(R30), R23
MOVQ (4*BY2WD+25*BY2V)(R30), R24
MOVQ (4*BY2WD+26*BY2V)(R30), R25
MOVQ (4*BY2WD+27*BY2V)(R30), R26
MOVQ (4*BY2WD+28*BY2V)(R30), R27
MOVQ (4*BY2WD+29*BY2V)(R30), R28
/* USP already restored from (4*BY2WD+30*BY2V)(R30) */
ADDQ $(4*BY2WD+31*BY2V), R30
CALL_PAL $PALrti
TEXT forkret(SB), $0
MOVQ R31, R0 /* Fake out system call return */
JMP systrapret
TEXT syscall0(SB), $-8
SUBQ $(4*BY2WD+31*BY2V), R30
MOVQ R0, (4*BY2WD+4*BY2V)(R30) /* save scallnr in R0 */
MOVQ $HI_IPL, R16
CALL_PAL $PALswpipl
MOVQ $mach0(SB), R(MACH)
CALL_PAL $PALrdusp
MOVQ R0, (4*BY2WD+30*BY2V)(R30) /* save USP */
MOVQ R26, (4*BY2WD+27*BY2V)(R30) /* save last return address */
MOVQ $(4*BY2WD)(R30), R0 /* pass address of Ureg */
JSR syscall(SB)
systrapret:
MOVQ (4*BY2WD+30*BY2V)(R30), R16 /* USP */
CALL_PAL $PALwrusp /* consider doing this in execregs... */
MOVQ (4*BY2WD+27*BY2V)(R30), R26 /* restore last return address */
ADDQ $(4*BY2WD+31*BY2V), R30
CALL_PAL $PALretsys
/*
* Take first processor into user mode
* - argument is stack pointer to user
*/
TEXT touser(SB), $-8
MOVQ R0, R16
CALL_PAL $PALwrusp /* set USP to value passed */
SUBQ $(6*BY2V), R30 /* create frame for retsys */
MOVQ $(UTZERO+32), R26 /* header appears in text */
MOVQ R26, (1*BY2V)(R30) /* PC -- only reg that matters */
CALL_PAL $PALretsys
TEXT rfnote(SB), $0
SUBL $(2*BY2WD), R0, SP
JMP trapret
TEXT savefpregs(SB), $-8
MOVT F0, 0x00(R0)
MOVT F1, 0x08(R0)
MOVT F2, 0x10(R0)
MOVT F3, 0x18(R0)
MOVT F4, 0x20(R0)
MOVT F5, 0x28(R0)
MOVT F6, 0x30(R0)
MOVT F7, 0x38(R0)
MOVT F8, 0x40(R0)
MOVT F9, 0x48(R0)
MOVT F10, 0x50(R0)
MOVT F11, 0x58(R0)
MOVT F12, 0x60(R0)
MOVT F13, 0x68(R0)
MOVT F14, 0x70(R0)
MOVT F15, 0x78(R0)
MOVT F16, 0x80(R0)
MOVT F17, 0x88(R0)
MOVT F18, 0x90(R0)
MOVT F19, 0x98(R0)
MOVT F20, 0xA0(R0)
MOVT F21, 0xA8(R0)
MOVT F22, 0xB0(R0)
MOVT F23, 0xB8(R0)
MOVT F24, 0xC0(R0)
MOVT F25, 0xC8(R0)
MOVT F26, 0xD0(R0)
MOVT F27, 0xD8(R0)
MOVT F28, 0xE0(R0)
MOVT F29, 0xE8(R0)
MOVT F30, 0xF0(R0)
MOVT F31, 0xF8(R0)
MOVT FPCR, F0
MOVT F0, 0x100(R0)
MOVQ $0, R16
CALL_PAL $PALwrfen /* disable */
RET
TEXT restfpregs(SB), $-8
MOVQ $1, R16
CALL_PAL $PALwrfen /* enable */
MOVT 0x100(R0), F0
MOVT F0, FPCR
MOVT 0x00(R0), F0
MOVT 0x08(R0), F1
MOVT 0x10(R0), F2
MOVT 0x18(R0), F3
MOVT 0x20(R0), F4
MOVT 0x28(R0), F5
MOVT 0x30(R0), F6
MOVT 0x38(R0), F7
MOVT 0x40(R0), F8
MOVT 0x48(R0), F9
MOVT 0x50(R0), F10
MOVT 0x58(R0), F11
MOVT 0x60(R0), F12
MOVT 0x68(R0), F13
MOVT 0x70(R0), F14
MOVT 0x78(R0), F15
MOVT 0x80(R0), F16
MOVT 0x88(R0), F17
MOVT 0x90(R0), F18
MOVT 0x98(R0), F19
MOVT 0xA0(R0), F20
MOVT 0xA8(R0), F21
MOVT 0xB0(R0), F22
MOVT 0xB8(R0), F23
MOVT 0xC0(R0), F24
MOVT 0xC8(R0), F25
MOVT 0xD0(R0), F26
MOVT 0xD8(R0), F27
MOVT 0xE0(R0), F28
MOVT 0xE8(R0), F29
MOVT 0xF0(R0), F30
MOVT 0xF8(R0), F31
RET
|