ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/ppc_asm.S
Revision: 1.3
Committed: 2005-06-23T16:23:31Z (19 years, 5 months ago) by gbeauche
Branch: MAIN
Changes since 1.2: +0 -55 lines
Log Message:
Don't fake the TVECT value on non-BeOS native systems. This is important
for systems that use a global r2 as the TLS register, e.g. Linux/ppc with
newer glibc. Also remove the syscall junk which were simply workarounds
for this bug. Remove a duplicate r2 restoration in EmulOp.

BTW, it's possible to get SheepShaver running on Linux/ppc systems with
NPTL rather than SheepThreads.

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 beq 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 blr
348
349
350 // Save address of EXEC_RETURN routine for 68k emulator patch
351 2: mflr r0
352 stw r0,XLM_EXEC_RETURN_PROC(0)
353
354 // Skip over EMUL_BREAK/EMUL_OP routine and get its address
355 bl 3f
356
357
358 /*
359 * EMUL_BREAK/EMUL_OP: Execute native routine, selector in r5 (my own private mode switch)
360 *
361 * 68k registers are stored in a M68kRegisters struct on the stack
362 * which the native routine may read and modify
363 */
364
365 // Save r25 (contains current 68k interrupt level)
366 stw r25,XLM_68K_R25(0)
367
368 // Entering EMUL_OP mode within 68k emulator
369 li r0,MODE_EMUL_OP
370 stw r0,XLM_RUN_MODE(0)
371
372 // Create PowerPC stack frame, reserve space for M68kRegisters
373 mr r3,r1
374 subi r1,r1,64 // Fake "caller" frame
375 rlwinm r1,r1,0,0,27 // Align stack
376
377 mfcr r0
378 rlwinm r0,r0,0,11,8
379 stw r0,4(r1)
380 mfxer r0
381 stw r0,16(r1)
382 stw r2,12(r1)
383 stwu r1,-(24+16*4+15*8)(r1)
384
385 // Save 68k registers (M68kRegisters)
386 stw r8,24+0*4(r1) // d[0]..d[7]
387 stw r9,24+1*4(r1)
388 stw r10,24+2*4(r1)
389 stw r11,24+3*4(r1)
390 stw r12,24+4*4(r1)
391 stw r13,24+5*4(r1)
392 stw r14,24+6*4(r1)
393 stw r15,24+7*4(r1)
394 stw r16,24+8*4(r1) // a[0]..a[7]
395 stw r17,24+9*4(r1)
396 stw r18,24+10*4(r1)
397 stw r19,24+11*4(r1)
398 stw r20,24+12*4(r1)
399 stw r21,24+13*4(r1)
400 stw r22,24+14*4(r1)
401 stw r3,24+15*4(r1)
402 stfd f0,24+16*4+0*8(r1)
403 stfd f1,24+16*4+1*8(r1)
404 stfd f2,24+16*4+2*8(r1)
405 stfd f3,24+16*4+3*8(r1)
406 stfd f4,24+16*4+4*8(r1)
407 stfd f5,24+16*4+5*8(r1)
408 stfd f6,24+16*4+6*8(r1)
409 stfd f7,24+16*4+7*8(r1)
410 mffs f0
411 stfd f8,24+16*4+8*8(r1)
412 stfd f9,24+16*4+9*8(r1)
413 stfd f10,24+16*4+10*8(r1)
414 stfd f11,24+16*4+11*8(r1)
415 stfd f12,24+16*4+12*8(r1)
416 stfd f13,24+16*4+13*8(r1)
417 stfd f0,24+16*4+14*8(r1)
418
419 // Execute native routine
420 RESTORE_SYSTEM_R2
421 RESTORE_SYSTEM_R13
422 addi r3,r1,24
423 mr r4,r24
424 bl C_SYMBOL_NAME(EmulOp)
425
426 // Restore 68k registers (M68kRegisters)
427 lwz r8,24+0*4(r1) // d[0]..d[7]
428 lwz r9,24+1*4(r1)
429 lwz r10,24+2*4(r1)
430 lwz r11,24+3*4(r1)
431 lwz r12,24+4*4(r1)
432 lwz r13,24+5*4(r1)
433 lwz r14,24+6*4(r1)
434 lwz r15,24+7*4(r1)
435 lwz r16,24+8*4(r1) // a[0]..a[7]
436 lwz r17,24+9*4(r1)
437 lwz r18,24+10*4(r1)
438 lwz r19,24+11*4(r1)
439 lwz r20,24+12*4(r1)
440 lwz r21,24+13*4(r1)
441 lwz r22,24+14*4(r1)
442 lwz r3,24+15*4(r1)
443 lfd f13,24+16*4+14*8(r1)
444 lfd f0,24+16*4+0*8(r1)
445 lfd f1,24+16*4+1*8(r1)
446 lfd f2,24+16*4+2*8(r1)
447 lfd f3,24+16*4+3*8(r1)
448 lfd f4,24+16*4+4*8(r1)
449 lfd f5,24+16*4+5*8(r1)
450 lfd f6,24+16*4+6*8(r1)
451 lfd f7,24+16*4+7*8(r1)
452 mtfsf 0xff,f13
453 lfd f8,24+16*4+8*8(r1)
454 lfd f9,24+16*4+9*8(r1)
455 lfd f10,24+16*4+10*8(r1)
456 lfd f11,24+16*4+11*8(r1)
457 lfd f12,24+16*4+12*8(r1)
458 lfd f13,24+16*4+13*8(r1)
459
460 // Delete PowerPC stack frame
461 lwz r2,24+16*4+15*8+12(r1)
462 lwz r0,24+16*4+15*8+16(r1)
463 mtxer r0
464 lwz r0,24+16*4+15*8+4(r1)
465 mtcrf 0xff,r0
466 mr r1,r3
467
468 // Reentering 68k emulator
469 li r0,MODE_68K
470 stw r0,XLM_RUN_MODE(0)
471
472 // Set r0 to 0 for 68k emulator
473 li r0,0
474
475 // Execute next 68k opcode
476 rlwimi r29,r27,3,13,28
477 lhau r27,2(r24)
478 mtlr r29
479 blr
480
481
482 // Save address of EMUL_BREAK/EMUL_OP routine for 68k emulator patch
483 3: mflr r0
484 stw r0,XLM_EMUL_OP_PROC(0)
485
486 // Save stack pointer for EMUL_RETURN
487 stw r1,XLM_EMUL_RETURN_STACK(0)
488
489 // Preset registers for ROM boot routine
490 lis r3,0x40b0 // Pointer to ROM boot structure
491 ori r3,r3,0xd000
492
493 // 68k emulator is now active
494 li r0,MODE_68K
495 stw r0,XLM_RUN_MODE(0)
496
497 // Jump to ROM
498 bctr
499
500
501 /*
502 * void execute_68k(uint32 pc {r3}, M68kRegisters *r {r4}) - Execute 68k routine
503 */
504
505 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(execute_68k)
506 C_SYMBOL_NAME(execute_68k):
507 // Create MacOS stack frame
508 mflr r0
509 stw r0,4(r1)
510 stwu r1,-(56+19*4+18*8)(r1)
511 mfcr r0
512 stw r4,48(r1) // save pointer to M68kRegisters for EXEC_RETURN
513 stw r0,52(r1) // save CR
514
515 // Save PowerPC registers
516 stmw r13,56(r1)
517 #if SAVE_FP_EXEC_68K
518 stfd f14,56+19*4+0*8(r1)
519 stfd f15,56+19*4+1*8(r1)
520 stfd f16,56+19*4+2*8(r1)
521 stfd f17,56+19*4+3*8(r1)
522 stfd f18,56+19*4+4*8(r1)
523 stfd f19,56+19*4+5*8(r1)
524 stfd f20,56+19*4+6*8(r1)
525 stfd f21,56+19*4+7*8(r1)
526 stfd f22,56+19*4+8*8(r1)
527 stfd f23,56+19*4+9*8(r1)
528 stfd f24,56+19*4+10*8(r1)
529 stfd f25,56+19*4+11*8(r1)
530 stfd f26,56+19*4+12*8(r1)
531 stfd f27,56+19*4+13*8(r1)
532 stfd f28,56+19*4+14*8(r1)
533 stfd f29,56+19*4+15*8(r1)
534 stfd f30,56+19*4+16*8(r1)
535 stfd f31,56+19*4+17*8(r1)
536 #endif
537
538 // Set up registers for 68k emulator
539 lwz r31,XLM_KERNEL_DATA(0) // Pointer to Kernel Data
540 addi r31,r31,0x1000
541 li r0,0
542 mtcrf 0xff,r0
543 creqv 11,11,11 // Supervisor mode
544 lwz r8,0*4(r4) // d[0]..d[7]
545 lwz r9,1*4(r4)
546 lwz r10,2*4(r4)
547 lwz r11,3*4(r4)
548 lwz r12,4*4(r4)
549 lwz r13,5*4(r4)
550 lwz r14,6*4(r4)
551 lwz r15,7*4(r4)
552 lwz r16,8*4(r4) // a[0]..a[6]
553 lwz r17,9*4(r4)
554 lwz r18,10*4(r4)
555 lwz r19,11*4(r4)
556 lwz r20,12*4(r4)
557 lwz r21,13*4(r4)
558 lwz r22,14*4(r4)
559 li r23,0
560 mr r24,r3
561 lwz r25,XLM_68K_R25(0) // MSB of SR
562 li r26,0
563 li r28,0 // VBR
564 lwz r29,0x74(r31) // Pointer to opcode table
565 lwz r30,0x78(r31) // Address of emulator
566
567 // Push return address (points to EXEC_RETURN opcode) on stack
568 li r0,XLM_EXEC_RETURN_OPCODE
569 stwu r0,-4(r1)
570
571 // Reentering 68k emulator
572 li r0,MODE_68K
573 stw r0,XLM_RUN_MODE(0)
574
575 // Set r0 to 0 for 68k emulator
576 li r0,0
577
578 // Execute 68k opcode
579 lha r27,0(r24)
580 rlwimi r29,r27,3,13,28
581 lhau r27,2(r24)
582 mtlr r29
583 blr
584
585
586 /*
587 * uint32 call_macos1(uint32 tvect{r3}, uint32 arg1{r4}) ... - Call MacOS routines
588 */
589
590 ASM_MACRO_START prolog
591 mflr r0
592 stw r0,4(r1)
593 stwu r1,-64(r1)
594 ASM_MACRO_END
595
596 ASM_MACRO_START epilog
597 RESTORE_SYSTEM_R2
598 RESTORE_SYSTEM_R13
599 lwz r0,64+4(r1)
600 mtlr r0
601 addi r1,r1,64
602 blr
603 ASM_MACRO_END
604
605 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos)
606 C_SYMBOL_NAME(call_macos):
607 prolog
608 lwz r0,0(r3) // Get routine address
609 lwz r2,4(r3) // Load TOC pointer
610 mtctr r0
611 bctrl
612 epilog
613
614 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos1)
615 C_SYMBOL_NAME(call_macos1):
616 prolog
617 lwz r0,0(r3) // Get routine address
618 lwz r2,4(r3) // Load TOC pointer
619 mtctr r0
620 mr r3,r4
621 bctrl
622 epilog
623
624 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos2)
625 C_SYMBOL_NAME(call_macos2):
626 prolog
627 lwz r0,0(r3) // Get routine address
628 lwz r2,4(r3) // Load TOC pointer
629 mtctr r0
630 mr r3,r4
631 mr r4,r5
632 bctrl
633 epilog
634
635 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos3)
636 C_SYMBOL_NAME(call_macos3):
637 prolog
638 lwz r0,0(r3) // Get routine address
639 lwz r2,4(r3) // Load TOC pointer
640 mtctr r0
641 mr r3,r4
642 mr r4,r5
643 mr r5,r6
644 bctrl
645 epilog
646
647 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos4)
648 C_SYMBOL_NAME(call_macos4):
649 prolog
650 lwz r0,0(r3) // Get routine address
651 lwz r2,4(r3) // Load TOC pointer
652 mtctr r0
653 mr r3,r4
654 mr r4,r5
655 mr r5,r6
656 mr r6,r7
657 bctrl
658 epilog
659
660 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos5)
661 C_SYMBOL_NAME(call_macos5):
662 prolog
663 lwz r0,0(r3) // Get routine address
664 lwz r2,4(r3) // Load TOC pointer
665 mtctr r0
666 mr r3,r4
667 mr r4,r5
668 mr r5,r6
669 mr r6,r7
670 mr r7,r8
671 bctrl
672 epilog
673
674 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos6)
675 C_SYMBOL_NAME(call_macos6):
676 prolog
677 lwz r0,0(r3) // Get routine address
678 lwz r2,4(r3) // Load TOC pointer
679 mtctr r0
680 mr r3,r4
681 mr r4,r5
682 mr r5,r6
683 mr r6,r7
684 mr r7,r8
685 mr r8,r9
686 bctrl
687 epilog
688
689 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos7)
690 C_SYMBOL_NAME(call_macos7):
691 prolog
692 lwz r0,0(r3) // Get routine address
693 lwz r2,4(r3) // Load TOC pointer
694 mtctr r0
695 mr r3,r4
696 mr r4,r5
697 mr r5,r6
698 mr r6,r7
699 mr r7,r8
700 mr r8,r9
701 mr r9,r10
702 bctrl
703 epilog
704
705
706 /*
707 * Native resource manager patches
708 */
709
710 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_resource)
711 C_SYMBOL_NAME(get_resource):
712 // Create stack frame
713 mflr r0
714 stw r0,8(r1)
715 stwu r1,-(56+12)(r1)
716
717 // Save type/ID
718 stw r3,56(r1)
719 stw r4,56+4(r1)
720
721 // Call old routine
722 lwz r0,XLM_GET_RESOURCE(0)
723 lwz r2,XLM_RES_LIB_TOC(0)
724 mtctr r0
725 bctrl
726 RESTORE_SYSTEM_R2
727 stw r3,56+8(r1) // Save handle
728
729 // Call CheckLoad
730 lwz r3,56(r1)
731 lha r4,56+6(r1)
732 lwz r5,56+8(r1)
733 bl C_SYMBOL_NAME(check_load_invoc)
734 lwz r3,56+8(r1) // Restore handle
735
736 // Return to caller
737 lwz r0,56+12+8(r1)
738 mtlr r0
739 addi r1,r1,56+12
740 blr
741
742 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_1_resource)
743 C_SYMBOL_NAME(get_1_resource):
744 // Create stack frame
745 mflr r0
746 stw r0,8(r1)
747 stwu r1,-(56+12)(r1)
748
749 // Save type/ID
750 stw r3,56(r1)
751 stw r4,56+4(r1)
752
753 // Call old routine
754 lwz r0,XLM_GET_1_RESOURCE(0)
755 lwz r2,XLM_RES_LIB_TOC(0)
756 mtctr r0
757 bctrl
758 RESTORE_SYSTEM_R2
759 stw r3,56+8(r1) // Save handle
760
761 // Call CheckLoad
762 lwz r3,56(r1)
763 lha r4,56+6(r1)
764 lwz r5,56+8(r1)
765 bl C_SYMBOL_NAME(check_load_invoc)
766 lwz r3,56+8(r1) // Restore handle
767
768 // Return to caller
769 lwz r0,56+12+8(r1)
770 mtlr r0
771 addi r1,r1,56+12
772 blr
773
774 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_ind_resource)
775 C_SYMBOL_NAME(get_ind_resource):
776 // Create stack frame
777 mflr r0
778 stw r0,8(r1)
779 stwu r1,-(56+12)(r1)
780
781 // Save type/index
782 stw r3,56(r1)
783 stw r4,56+4(r1)
784
785 // Call old routine
786 lwz r0,XLM_GET_IND_RESOURCE(0)
787 lwz r2,XLM_RES_LIB_TOC(0)
788 mtctr r0
789 bctrl
790 RESTORE_SYSTEM_R2
791 stw r3,56+8(r1) // Save handle
792
793 // Call CheckLoad
794 lwz r3,56(r1)
795 lha r4,56+6(r1)
796 lwz r5,56+8(r1)
797 bl C_SYMBOL_NAME(check_load_invoc)
798 lwz r3,56+8(r1) // Restore handle
799
800 // Return to caller
801 lwz r0,56+12+8(r1)
802 mtlr r0
803 addi r1,r1,56+12
804 blr
805
806 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_1_ind_resource)
807 C_SYMBOL_NAME(get_1_ind_resource):
808 // Create stack frame
809 mflr r0
810 stw r0,8(r1)
811 stwu r1,-(56+12)(r1)
812
813 // Save type/index
814 stw r3,56(r1)
815 stw r4,56+4(r1)
816
817 // Call old routine
818 lwz r0,XLM_GET_1_IND_RESOURCE(0)
819 lwz r2,XLM_RES_LIB_TOC(0)
820 mtctr r0
821 bctrl
822 RESTORE_SYSTEM_R2
823 stw r3,56+8(r1) // Save handle
824
825 // Call CheckLoad
826 lwz r3,56(r1)
827 lha r4,56+6(r1)
828 lwz r5,56+8(r1)
829 bl C_SYMBOL_NAME(check_load_invoc)
830 lwz r3,56+8(r1) // Restore handle
831
832 // Return to caller
833 lwz r0,56+12+8(r1)
834 mtlr r0
835 addi r1,r1,56+12
836 blr
837
838 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(r_get_resource)
839 C_SYMBOL_NAME(r_get_resource):
840 // Create stack frame
841 mflr r0
842 stw r0,8(r1)
843 stwu r1,-(56+12)(r1)
844
845 // Save type/ID
846 stw r3,56(r1)
847 stw r4,56+4(r1)
848
849 // Call old routine
850 lwz r0,XLM_R_GET_RESOURCE(0)
851 lwz r2,XLM_RES_LIB_TOC(0)
852 mtctr r0
853 bctrl
854 RESTORE_SYSTEM_R2
855 stw r3,56+8(r1) // Save handle
856
857 // Call CheckLoad
858 lwz r3,56(r1)
859 lha r4,56+6(r1)
860 lwz r5,56+8(r1)
861 bl C_SYMBOL_NAME(check_load_invoc)
862 lwz r3,56+8(r1) // Restore handle
863
864 // Return to caller
865 lwz r0,56+12+8(r1)
866 mtlr r0
867 addi r1,r1,56+12
868 blr
869
870
871 /*
872 * void ppc_interrupt(uint32 entry{r3}, uint32 kernel_data{r4}) - Execute PPC interrupt
873 */
874
875 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(ppc_interrupt)
876 C_SYMBOL_NAME(ppc_interrupt):
877 mflr r0
878 stw r0,4(r1)
879 stwu r1,-64(r1)
880
881 // Get address of return routine
882 bl 1f
883
884 // Return routine
885 lwz r0,64+4(r1)
886 mtlr r0
887 addi r1,r1,64
888 blr
889
890 // Prepare registers for nanokernel interrupt routine
891 1: mtctr r1
892 mr r1,r4
893 stw r6,0x018(r1)
894 mfctr r6
895 stw r6,0x004(r1)
896 lwz r6,0x65c(r1)
897 stw r7,0x13c(r6)
898 stw r8,0x144(r6)
899 stw r9,0x14c(r6)
900 stw r10,0x154(r6)
901 stw r11,0x15c(r6)
902 stw r12,0x164(r6)
903 stw r13,0x16c(r6)
904
905 mflr r10
906 mfcr r13
907 lwz r7,0x660(r1)
908 mflr r12
909 rlwimi. r7,r7,8,0,0
910 li r11,0
911 ori r11,r11,0xf072 // MSR (SRR1)
912 mtcrf 0x70,r11
913 li r8,0
914
915 // Enter nanokernel
916 mtlr r3
917 blr