ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/Linux/asm_linux.S
Revision: 1.5
Committed: 2004-01-18T22:08:39Z (20 years, 5 months ago) by gbeauche
Branch: MAIN
Changes since 1.4: +177 -175 lines
Log Message:
Handle (broken) Apple assembler. Make prologue/epilogue as macros as ';'
is the comment delimiter for Darwin assembler. Increase stack pad by
16 bytes in EMUL_OP_PROC to accomodate LR saves in Darwin EmulOp

File Contents

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