ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/ppc_asm.S
Revision: 1.8
Committed: 2005-06-28T16:50:30Z (19 years ago) by gbeauche
Branch: MAIN
Changes since 1.7: +0 -1 lines
Log Message:
Clean-ups: comments, ticks per sec output, don't restore r13 twice.

File Contents

# Content
1 /*
2 * asm_linux.S - Assembly routines
3 *
4 * SheepShaver (C) 1997-2005 Christian Bauer and Marc Hellwig
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <ppc_asm.tmpl>
22 #include <xlowmem.h>
23
24 #define SAVE_FP_EXEC_68K 1
25
26
27 /*
28 * void *get_sp(void) - Get stack pointer
29 */
30
31 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_sp)
32 C_SYMBOL_NAME(get_sp):
33 mr r3,r1
34 blr
35
36
37 /*
38 * void *get_r2(void) - Get r2
39 */
40
41 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_r2)
42 C_SYMBOL_NAME(get_r2):
43 mr r3,r2
44 blr
45
46
47 /*
48 * void set_r2(void *val {r3}) - Set r2
49 */
50
51 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(set_r2)
52 C_SYMBOL_NAME(set_r2):
53 mr r2,r3
54 blr
55
56
57 /*
58 * void *get_r13(void) - Get r13 (small data pointer under Linux)
59 */
60
61 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_r13)
62 C_SYMBOL_NAME(get_r13):
63 mr r3,r13
64 blr
65
66 /*
67 * void set_r13(void *val {r3}) - Set r13 (small data pointer under Linux)
68 */
69
70 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(set_r13)
71 C_SYMBOL_NAME(set_r13):
72 mr r13,r3
73 blr
74
75
76 /*
77 * void flush_icache_range(void *start {r3}, void *end {r3}) - Flush D and I cache
78 */
79
80 CACHE_LINE_SIZE = 32
81 LG_CACHE_LINE_SIZE = 5
82
83 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(flush_icache_range)
84 C_SYMBOL_NAME(flush_icache_range):
85 li r5,CACHE_LINE_SIZE-1
86 andc r3,r3,r5
87 subf r4,r3,r4
88 add r4,r4,r5
89 srwi. r4,r4,LG_CACHE_LINE_SIZE
90 beqlr
91 mtctr r4
92 mr r6,r3
93 1: dcbst 0,r3
94 addi r3,r3,CACHE_LINE_SIZE
95 bdnz 1b
96 sync /* wait for dcbst's to get to ram */
97 mtctr r4
98 2: icbi 0,r6
99 addi r6,r6,CACHE_LINE_SIZE
100 bdnz 2b
101 sync
102 isync
103 blr
104
105
106 /*
107 * long atomic_add(long *var{r3}, long add{r4}) - Atomic add operation
108 * long atomic_and(long *var{r3}, long and{r4}) - Atomic and operation
109 * long atomic_or(long *var{r3}, long or{r4}) - Atomic or operation
110 * int test_and_set(int *var{r3}, int val{r4}) - Atomic test-and-set
111 */
112
113 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(atomic_add)
114 C_SYMBOL_NAME(atomic_add):
115 0: dcbf 0,r3
116 sync
117 ori r0,r0,1
118 ori r0,r0,1
119 ori r0,r0,1
120 ori r0,r0,1
121 ori r0,r0,1
122 ori r0,r0,1
123 isync
124 lwarx r5,0,r3
125 add r0,r4,r5
126 stwcx. r0,0,r3
127 bne- 0b
128 mr r3,r5
129 isync
130 blr
131
132 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(atomic_and)
133 C_SYMBOL_NAME(atomic_and):
134 0: dcbf 0,r3
135 sync
136 ori r0,r0,1
137 ori r0,r0,1
138 ori r0,r0,1
139 ori r0,r0,1
140 ori r0,r0,1
141 ori r0,r0,1
142 isync
143 lwarx r5,0,r3
144 and r0,r4,r5
145 stwcx. r0,0,r3
146 bne- 0b
147 mr r3,r5
148 isync
149 blr
150
151 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(atomic_or)
152 C_SYMBOL_NAME(atomic_or):
153 0: dcbf 0,r3
154 sync
155 ori r0,r0,1
156 ori r0,r0,1
157 ori r0,r0,1
158 ori r0,r0,1
159 ori r0,r0,1
160 ori r0,r0,1
161 isync
162 lwarx r5,0,r3
163 or r0,r4,r5
164 stwcx. r0,0,r3
165 bne- 0b
166 mr r3,r5
167 isync
168 blr
169
170 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(test_and_set)
171 C_SYMBOL_NAME(test_and_set):
172 0: dcbf 0,r3
173 sync
174 ori r0,r0,1
175 ori r0,r0,1
176 ori r0,r0,1
177 ori r0,r0,1
178 ori r0,r0,1
179 ori r0,r0,1
180 isync
181 lwarx r5,0,r3
182 cmpi 0,r5,0x0000
183 bne 1f
184 stwcx. r4,0,r3
185 bne- 0b
186 1: isync
187 mr r3,r5
188 blr
189
190
191 /*
192 * void quit_emulator(void) - Jump to XLM_EMUL_RETURN_PROC
193 */
194
195 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(quit_emulator)
196 C_SYMBOL_NAME(quit_emulator):
197 lwz r0,XLM_EMUL_RETURN_PROC(0)
198 mtlr r0
199 blr
200
201
202 /*
203 * void jump_to_rom(uint32 entry {r3}, uint32 emulator_data {r4}) - Jump to Mac ROM
204 */
205
206 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(jump_to_rom)
207 C_SYMBOL_NAME(jump_to_rom):
208 // Create stack frame
209 mflr r0
210 stw r0,4(r1)
211 stwu r1,-(20+19*4+18*8)(r1) // maintain 16 byte alignment
212
213 // Save PowerPC registers
214 stmw r13,20(r1)
215 stfd f14,20+19*4+0*8(r1)
216 stfd f15,20+19*4+1*8(r1)
217 stfd f16,20+19*4+2*8(r1)
218 stfd f17,20+19*4+3*8(r1)
219 stfd f18,20+19*4+4*8(r1)
220 stfd f19,20+19*4+5*8(r1)
221 stfd f20,20+19*4+6*8(r1)
222 stfd f21,20+19*4+7*8(r1)
223 stfd f22,20+19*4+8*8(r1)
224 stfd f23,20+19*4+9*8(r1)
225 stfd f24,20+19*4+10*8(r1)
226 stfd f25,20+19*4+11*8(r1)
227 stfd f26,20+19*4+12*8(r1)
228 stfd f27,20+19*4+13*8(r1)
229 stfd f28,20+19*4+14*8(r1)
230 stfd f29,20+19*4+15*8(r1)
231 stfd f30,20+19*4+16*8(r1)
232 stfd f31,20+19*4+17*8(r1)
233
234 // Move entry address to ctr
235 mtctr r3
236
237 // Skip over EMUL_RETURN routine and get its address
238 bl 1f
239
240
241 /*
242 * EMUL_RETURN: Returned from emulator
243 */
244
245 // Restore PowerPC registers
246 lwz r1,XLM_EMUL_RETURN_STACK(0)
247 RESTORE_SYSTEM_R2
248 lmw r13,20(r1)
249 lfd f14,20+19*4+0*8(r1)
250 lfd f15,20+19*4+1*8(r1)
251 lfd f16,20+19*4+2*8(r1)
252 lfd f17,20+19*4+3*8(r1)
253 lfd f18,20+19*4+4*8(r1)
254 lfd f19,20+19*4+5*8(r1)
255 lfd f20,20+19*4+6*8(r1)
256 lfd f21,20+19*4+7*8(r1)
257 lfd f22,20+19*4+8*8(r1)
258 lfd f23,20+19*4+9*8(r1)
259 lfd f24,20+19*4+10*8(r1)
260 lfd f25,20+19*4+11*8(r1)
261 lfd f26,20+19*4+12*8(r1)
262 lfd f27,20+19*4+13*8(r1)
263 lfd f28,20+19*4+14*8(r1)
264 lfd f29,20+19*4+15*8(r1)
265 lfd f30,20+19*4+16*8(r1)
266 lfd f31,20+19*4+17*8(r1)
267
268 // Exiting from 68k emulator
269 li r0,1
270 stw r0,XLM_IRQ_NEST(0)
271 li r0,MODE_NATIVE
272 stw r0,XLM_RUN_MODE(0)
273
274 // Return to caller of jump_to_rom()
275 lwz r0,20+19*4+18*8+4(r1)
276 mtlr r0
277 addi r1,r1,20+19*4+18*8
278 blr
279
280
281 // Save address of EMUL_RETURN routine for 68k emulator patch
282 1: mflr r0
283 stw r0,XLM_EMUL_RETURN_PROC(0)
284
285 // Skip over EXEC_RETURN routine and get its address
286 bl 2f
287
288
289 /*
290 * EXEC_RETURN: Returned from 68k routine executed with Execute68k()
291 */
292
293 // Save r25 (contains current 68k interrupt level)
294 stw r25,XLM_68K_R25(0)
295
296 // Reentering EMUL_OP mode
297 li r0,MODE_EMUL_OP
298 stw r0,XLM_RUN_MODE(0)
299
300 // Save 68k registers
301 lwz r4,48(r1) // Pointer to M68kRegisters
302 stw r8,0*4(r4) // d[0]...d[7]
303 stw r9,1*4(r4)
304 stw r10,2*4(r4)
305 stw r11,3*4(r4)
306 stw r12,4*4(r4)
307 stw r13,5*4(r4)
308 stw r14,6*4(r4)
309 stw r15,7*4(r4)
310 stw r16,8*4(r4) // a[0]..a[6]
311 stw r17,9*4(r4)
312 stw r18,10*4(r4)
313 stw r19,11*4(r4)
314 stw r20,12*4(r4)
315 stw r21,13*4(r4)
316 stw r22,14*4(r4)
317
318 // Restore PowerPC registers
319 lmw r13,56(r1)
320 #if SAVE_FP_EXEC_68K
321 lfd f14,56+19*4+0*8(r1)
322 lfd f15,56+19*4+1*8(r1)
323 lfd f16,56+19*4+2*8(r1)
324 lfd f17,56+19*4+3*8(r1)
325 lfd f18,56+19*4+4*8(r1)
326 lfd f19,56+19*4+5*8(r1)
327 lfd f20,56+19*4+6*8(r1)
328 lfd f21,56+19*4+7*8(r1)
329 lfd f22,56+19*4+8*8(r1)
330 lfd f23,56+19*4+9*8(r1)
331 lfd f24,56+19*4+10*8(r1)
332 lfd f25,56+19*4+11*8(r1)
333 lfd f26,56+19*4+12*8(r1)
334 lfd f27,56+19*4+13*8(r1)
335 lfd f28,56+19*4+14*8(r1)
336 lfd f29,56+19*4+15*8(r1)
337 lfd f30,56+19*4+16*8(r1)
338 lfd f31,56+19*4+17*8(r1)
339 #endif
340
341 // Return to caller
342 lwz r0,52(r1)
343 mtcrf 0xff,r0
344 lwz r0,56+19*4+18*8+4(r1)
345 mtlr r0
346 addi r1,r1,56+19*4+18*8
347 RESTORE_SYSTEM_R2
348 RESTORE_SYSTEM_R13
349 blr
350
351
352 // Save address of EXEC_RETURN routine for 68k emulator patch
353 2: mflr r0
354 stw r0,XLM_EXEC_RETURN_PROC(0)
355
356 // Skip over EMUL_BREAK/EMUL_OP routine and get its address
357 bl 3f
358
359
360 /*
361 * EMUL_BREAK/EMUL_OP: Execute native routine, selector in r5 (my own private mode switch)
362 *
363 * 68k registers are stored in a M68kRegisters struct on the stack
364 * which the native routine may read and modify
365 */
366
367 // Save r25 (contains current 68k interrupt level)
368 stw r25,XLM_68K_R25(0)
369
370 // Entering EMUL_OP mode within 68k emulator
371 li r0,MODE_EMUL_OP
372 stw r0,XLM_RUN_MODE(0)
373
374 // Create PowerPC stack frame, reserve space for M68kRegisters
375 mr r3,r1
376 subi r1,r1,64 // Fake "caller" frame
377 rlwinm r1,r1,0,0,27 // Align stack
378
379 mfcr r0
380 rlwinm r0,r0,0,11,8
381 stw r0,4(r1)
382 mfxer r0
383 stw r0,16(r1)
384 stw r2,12(r1)
385 stwu r1,-(56+16*4+15*8)(r1)
386
387 // Save 68k registers (M68kRegisters)
388 stw r8,56+0*4(r1) // d[0]..d[7]
389 stw r9,56+1*4(r1)
390 stw r10,56+2*4(r1)
391 stw r11,56+3*4(r1)
392 stw r12,56+4*4(r1)
393 stw r13,56+5*4(r1)
394 stw r14,56+6*4(r1)
395 stw r15,56+7*4(r1)
396 stw r16,56+8*4(r1) // a[0]..a[7]
397 stw r17,56+9*4(r1)
398 stw r18,56+10*4(r1)
399 stw r19,56+11*4(r1)
400 stw r20,56+12*4(r1)
401 stw r21,56+13*4(r1)
402 stw r22,56+14*4(r1)
403 stw r3,56+15*4(r1)
404 stfd f0,56+16*4+0*8(r1)
405 stfd f1,56+16*4+1*8(r1)
406 stfd f2,56+16*4+2*8(r1)
407 stfd f3,56+16*4+3*8(r1)
408 stfd f4,56+16*4+4*8(r1)
409 stfd f5,56+16*4+5*8(r1)
410 stfd f6,56+16*4+6*8(r1)
411 stfd f7,56+16*4+7*8(r1)
412 mffs f0
413 stfd f8,56+16*4+8*8(r1)
414 stfd f9,56+16*4+9*8(r1)
415 stfd f10,56+16*4+10*8(r1)
416 stfd f11,56+16*4+11*8(r1)
417 stfd f12,56+16*4+12*8(r1)
418 stfd f13,56+16*4+13*8(r1)
419 stfd f0,56+16*4+14*8(r1)
420
421 // Execute native routine
422 RESTORE_SYSTEM_R2
423 RESTORE_SYSTEM_R13
424 addi r3,r1,56
425 mr r4,r24
426 bl C_SYMBOL_NAME(EmulOp)
427
428 // Restore 68k registers (M68kRegisters)
429 lwz r8,56+0*4(r1) // d[0]..d[7]
430 lwz r9,56+1*4(r1)
431 lwz r10,56+2*4(r1)
432 lwz r11,56+3*4(r1)
433 lwz r12,56+4*4(r1)
434 lwz r13,56+5*4(r1)
435 lwz r14,56+6*4(r1)
436 lwz r15,56+7*4(r1)
437 lwz r16,56+8*4(r1) // a[0]..a[7]
438 lwz r17,56+9*4(r1)
439 lwz r18,56+10*4(r1)
440 lwz r19,56+11*4(r1)
441 lwz r20,56+12*4(r1)
442 lwz r21,56+13*4(r1)
443 lwz r22,56+14*4(r1)
444 lwz r3,56+15*4(r1)
445 lfd f13,56+16*4+14*8(r1)
446 lfd f0,56+16*4+0*8(r1)
447 lfd f1,56+16*4+1*8(r1)
448 lfd f2,56+16*4+2*8(r1)
449 lfd f3,56+16*4+3*8(r1)
450 lfd f4,56+16*4+4*8(r1)
451 lfd f5,56+16*4+5*8(r1)
452 lfd f6,56+16*4+6*8(r1)
453 lfd f7,56+16*4+7*8(r1)
454 mtfsf 0xff,f13
455 lfd f8,56+16*4+8*8(r1)
456 lfd f9,56+16*4+9*8(r1)
457 lfd f10,56+16*4+10*8(r1)
458 lfd f11,56+16*4+11*8(r1)
459 lfd f12,56+16*4+12*8(r1)
460 lfd f13,56+16*4+13*8(r1)
461
462 // Delete PowerPC stack frame
463 lwz r2,56+16*4+15*8+12(r1)
464 lwz r0,56+16*4+15*8+16(r1)
465 mtxer r0
466 lwz r0,56+16*4+15*8+4(r1)
467 mtcrf 0xff,r0
468 mr r1,r3
469
470 // Reentering 68k emulator
471 li r0,MODE_68K
472 stw r0,XLM_RUN_MODE(0)
473
474 // Set r0 to 0 for 68k emulator
475 li r0,0
476
477 // Execute next 68k opcode
478 rlwimi r29,r27,3,13,28
479 lhau r27,2(r24)
480 mtlr r29
481 blr
482
483
484 // Save address of EMUL_BREAK/EMUL_OP routine for 68k emulator patch
485 3: mflr r0
486 stw r0,XLM_EMUL_OP_PROC(0)
487
488 // Save stack pointer for EMUL_RETURN
489 stw r1,XLM_EMUL_RETURN_STACK(0)
490
491 // Preset registers for ROM boot routine
492 lis r3,0x40b0 // Pointer to ROM boot structure
493 ori r3,r3,0xd000
494
495 // 68k emulator is now active
496 li r0,MODE_68K
497 stw r0,XLM_RUN_MODE(0)
498
499 // Jump to ROM
500 bctr
501
502
503 /*
504 * void execute_68k(uint32 pc {r3}, M68kRegisters *r {r4}) - Execute 68k routine
505 */
506
507 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(execute_68k)
508 C_SYMBOL_NAME(execute_68k):
509 // Create MacOS stack frame
510 mflr r0
511 stw r0,4(r1)
512 stwu r1,-(56+19*4+18*8)(r1)
513 mfcr r0
514 stw r4,48(r1) // save pointer to M68kRegisters for EXEC_RETURN
515 stw r0,52(r1) // save CR
516
517 // Save PowerPC registers
518 stmw r13,56(r1)
519 #if SAVE_FP_EXEC_68K
520 stfd f14,56+19*4+0*8(r1)
521 stfd f15,56+19*4+1*8(r1)
522 stfd f16,56+19*4+2*8(r1)
523 stfd f17,56+19*4+3*8(r1)
524 stfd f18,56+19*4+4*8(r1)
525 stfd f19,56+19*4+5*8(r1)
526 stfd f20,56+19*4+6*8(r1)
527 stfd f21,56+19*4+7*8(r1)
528 stfd f22,56+19*4+8*8(r1)
529 stfd f23,56+19*4+9*8(r1)
530 stfd f24,56+19*4+10*8(r1)
531 stfd f25,56+19*4+11*8(r1)
532 stfd f26,56+19*4+12*8(r1)
533 stfd f27,56+19*4+13*8(r1)
534 stfd f28,56+19*4+14*8(r1)
535 stfd f29,56+19*4+15*8(r1)
536 stfd f30,56+19*4+16*8(r1)
537 stfd f31,56+19*4+17*8(r1)
538 #endif
539
540 // Set up registers for 68k emulator
541 lwz r31,XLM_KERNEL_DATA(0) // Pointer to Kernel Data
542 addi r31,r31,0x1000
543 li r0,0
544 mtcrf 0xff,r0
545 creqv 11,11,11 // Supervisor mode
546 lwz r8,0*4(r4) // d[0]..d[7]
547 lwz r9,1*4(r4)
548 lwz r10,2*4(r4)
549 lwz r11,3*4(r4)
550 lwz r12,4*4(r4)
551 lwz r13,5*4(r4)
552 lwz r14,6*4(r4)
553 lwz r15,7*4(r4)
554 lwz r16,8*4(r4) // a[0]..a[6]
555 lwz r17,9*4(r4)
556 lwz r18,10*4(r4)
557 lwz r19,11*4(r4)
558 lwz r20,12*4(r4)
559 lwz r21,13*4(r4)
560 lwz r22,14*4(r4)
561 li r23,0
562 mr r24,r3
563 lwz r25,XLM_68K_R25(0) // MSB of SR
564 li r26,0
565 li r28,0 // VBR
566 lwz r29,0x74(r31) // Pointer to opcode table
567 lwz r30,0x78(r31) // Address of emulator
568
569 // Push return address (points to EXEC_RETURN opcode) on stack
570 li r0,XLM_EXEC_RETURN_OPCODE
571 stwu r0,-4(r1)
572
573 // Reentering 68k emulator
574 li r0,MODE_68K
575 stw r0,XLM_RUN_MODE(0)
576
577 // Set r0 to 0 for 68k emulator
578 li r0,0
579
580 // Execute 68k opcode
581 lha r27,0(r24)
582 rlwimi r29,r27,3,13,28
583 lhau r27,2(r24)
584 mtlr r29
585 blr
586
587
588 /*
589 * uint32 call_macos1(uint32 tvect{r3}, uint32 arg1{r4}) ... - Call MacOS routines
590 */
591
592 ASM_MACRO_START prolog
593 mflr r0
594 stw r0,4(r1)
595 stwu r1,-64(r1)
596 ASM_MACRO_END
597
598 ASM_MACRO_START epilog
599 lwz r0,64+4(r1)
600 mtlr r0
601 addi r1,r1,64
602 RESTORE_SYSTEM_R2
603 RESTORE_SYSTEM_R13
604 blr
605 ASM_MACRO_END
606
607 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos)
608 C_SYMBOL_NAME(call_macos):
609 prolog
610 lwz r0,0(r3) // Get routine address
611 lwz r2,4(r3) // Load TOC pointer
612 mtctr r0
613 bctrl
614 epilog
615
616 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos1)
617 C_SYMBOL_NAME(call_macos1):
618 prolog
619 lwz r0,0(r3) // Get routine address
620 lwz r2,4(r3) // Load TOC pointer
621 mtctr r0
622 mr r3,r4
623 bctrl
624 epilog
625
626 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos2)
627 C_SYMBOL_NAME(call_macos2):
628 prolog
629 lwz r0,0(r3) // Get routine address
630 lwz r2,4(r3) // Load TOC pointer
631 mtctr r0
632 mr r3,r4
633 mr r4,r5
634 bctrl
635 epilog
636
637 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos3)
638 C_SYMBOL_NAME(call_macos3):
639 prolog
640 lwz r0,0(r3) // Get routine address
641 lwz r2,4(r3) // Load TOC pointer
642 mtctr r0
643 mr r3,r4
644 mr r4,r5
645 mr r5,r6
646 bctrl
647 epilog
648
649 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos4)
650 C_SYMBOL_NAME(call_macos4):
651 prolog
652 lwz r0,0(r3) // Get routine address
653 lwz r2,4(r3) // Load TOC pointer
654 mtctr r0
655 mr r3,r4
656 mr r4,r5
657 mr r5,r6
658 mr r6,r7
659 bctrl
660 epilog
661
662 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos5)
663 C_SYMBOL_NAME(call_macos5):
664 prolog
665 lwz r0,0(r3) // Get routine address
666 lwz r2,4(r3) // Load TOC pointer
667 mtctr r0
668 mr r3,r4
669 mr r4,r5
670 mr r5,r6
671 mr r6,r7
672 mr r7,r8
673 bctrl
674 epilog
675
676 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos6)
677 C_SYMBOL_NAME(call_macos6):
678 prolog
679 lwz r0,0(r3) // Get routine address
680 lwz r2,4(r3) // Load TOC pointer
681 mtctr r0
682 mr r3,r4
683 mr r4,r5
684 mr r5,r6
685 mr r6,r7
686 mr r7,r8
687 mr r8,r9
688 bctrl
689 epilog
690
691 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos7)
692 C_SYMBOL_NAME(call_macos7):
693 prolog
694 lwz r0,0(r3) // Get routine address
695 lwz r2,4(r3) // Load TOC pointer
696 mtctr r0
697 mr r3,r4
698 mr r4,r5
699 mr r5,r6
700 mr r6,r7
701 mr r7,r8
702 mr r8,r9
703 mr r9,r10
704 bctrl
705 epilog
706
707
708 /*
709 * Native resource manager patches
710 */
711
712 ASM_MACRO_START do_get_resource ASM_MACRO_ARG0_DEF
713 // Create stack frame
714 mflr r0
715 stw r0,8(r1)
716 stwu r1,-(56+12)(r1)
717
718 // Save type/ID
719 stw r3,56(r1)
720 stw r4,56+4(r1)
721
722 // Call old routine
723 lwz r0,ASM_MACRO_ARG0(0)
724 lwz r2,XLM_RES_LIB_TOC(0)
725 mtctr r0
726 bctrl
727 stw r3,56+8(r1) // Save handle
728
729 // Call CheckLoad
730 RESTORE_SYSTEM_R2
731 RESTORE_SYSTEM_R13
732 lwz r3,56(r1)
733 lha r4,56+6(r1)
734 lwz r5,56+8(r1)
735 bl C_SYMBOL_NAME(check_load_invoc)
736 lwz r3,56+8(r1) // Restore handle
737
738 // Return to caller
739 lwz r0,56+12+8(r1)
740 mtlr r0
741 addi r1,r1,56+12
742 blr
743 ASM_MACRO_END
744
745 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_resource)
746 C_SYMBOL_NAME(get_resource):
747 do_get_resource XLM_GET_RESOURCE
748
749 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_1_resource)
750 C_SYMBOL_NAME(get_1_resource):
751 do_get_resource XLM_GET_1_RESOURCE
752
753 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_ind_resource)
754 C_SYMBOL_NAME(get_ind_resource):
755 do_get_resource XLM_GET_IND_RESOURCE
756
757 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_1_ind_resource)
758 C_SYMBOL_NAME(get_1_ind_resource):
759 do_get_resource XLM_GET_1_IND_RESOURCE
760
761 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(r_get_resource)
762 C_SYMBOL_NAME(r_get_resource):
763 do_get_resource XLM_R_GET_RESOURCE
764
765
766 /*
767 * void ppc_interrupt(uint32 entry{r3}, uint32 kernel_data{r4}) - Execute PPC interrupt
768 */
769
770 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(ppc_interrupt)
771 C_SYMBOL_NAME(ppc_interrupt):
772 mflr r0
773 stw r0,4(r1)
774 stwu r1,-64(r1)
775
776 // Get address of return routine
777 bl 1f
778
779 // Return routine
780 lwz r0,64+4(r1)
781 mtlr r0
782 addi r1,r1,64
783 blr
784
785 // Prepare registers for nanokernel interrupt routine
786 1: mtctr r1
787 mr r1,r4
788 stw r6,0x018(r1)
789 mfctr r6
790 stw r6,0x004(r1)
791 lwz r6,0x65c(r1)
792 stw r7,0x13c(r6)
793 stw r8,0x144(r6)
794 stw r9,0x14c(r6)
795 stw r10,0x154(r6)
796 stw r11,0x15c(r6)
797 stw r12,0x164(r6)
798 stw r13,0x16c(r6)
799
800 mflr r10
801 mfcr r13
802 lwz r7,0x660(r1)
803 mflr r12
804 rlwimi. r7,r7,8,0,0
805 li r11,0
806 ori r11,r11,0xf072 // MSR (SRR1)
807 mtcrf 0x70,r11
808 li r8,0
809
810 // Enter nanokernel
811 mtlr r3
812 blr
813
814
815 /*
816 * Define signal handlers with alternate stack initialization magic
817 */
818
819 #define SIG_STACK_SIZE 0x10000
820
821 ASM_MACRO_START do_define_signal_handler \
822 ASM_MACRO_ARG0_DEF /* name */ \
823 ASM_MACRO_ARG1_DEF /* stack */ \
824 ASM_MACRO_ARG2_DEF /* stack id */ \
825 ASM_MACRO_ARG3_DEF /* signal handler */
826
827 // Alternate stack lower base for this signal handler
828 .lcomm ASM_MACRO_ARG1,SIG_STACK_SIZE,ASM_ALIGN_2(4)
829 ASM_TYPE(ASM_MACRO_ARG1,@object)
830
831 // Represents the current nest level for this signal handler
832 // Note that in SheepShaver, SIGUSR2 signals are blocked while
833 // handling other signals so, it's unlikely we ever get a nest
834 // level greater than 1
835 .lcomm ASM_MACRO_ARG2,4,ASM_ALIGN_2(2)
836 ASM_TYPE(ASM_MACRO_ARG2,@object)
837
838 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(ASM_MACRO_ARG0)
839 C_SYMBOL_NAME(ASM_MACRO_ARG0):
840 // Preserve args in scratch registers
841 mflr r14
842 mr r15,r3
843 mr r16,r4
844 mr r17,r5
845 mr r18,r1
846
847 // Atomically increase stack_id
848 lis r19,ASM_HA16(ASM_MACRO_ARG2)
849 la r19,ASM_LO16(ASM_MACRO_ARG2,r19)
850 li r4,1
851 mr r3,r19
852 bl C_SYMBOL_NAME(atomic_add)
853 cmpwi r3,0
854 bne- 1f
855
856 // ID was 0, we can use the local stack
857 lis r9,ASM_HA16(ASM_MACRO_ARG1)
858 lis r3,(SIG_STACK_SIZE>>16)
859 la r9,ASM_LO16(ASM_MACRO_ARG1,r9)
860 addi r3,r3,((SIG_STACK_SIZE&0xffff)-64)
861 add r1,r9,r3
862
863 1: // Invoke signal handler
864 stwu r1,-16(r1)
865 mr r3,r15
866 mr r4,r16
867 mr r5,r17
868 bl C_SYMBOL_NAME(ASM_MACRO_ARG3)
869 addi r1,r1,16
870
871 // Atomically decrease stack id
872 mr r3,r19
873 li r4,-1
874 bl C_SYMBOL_NAME(atomic_add)
875
876 // Restore kernel stack and return
877 mtlr r14
878 mr r1,r18
879 blr
880 ASM_MACRO_END
881
882 #define DEFINE_SIGNAL_HANDLER(NAME) \
883 do_define_signal_handler \
884 NAME##_handler_init ASM_MACRO_ARG_SEP \
885 NAME##_stack ASM_MACRO_ARG_SEP \
886 NAME##_stack_id ASM_MACRO_ARG_SEP \
887 NAME##_handler
888
889 DEFINE_SIGNAL_HANDLER(sigusr2)