ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/ppc_asm.S
Revision: 1.1
Committed: 2005-02-20T18:25:45Z (19 years, 8 months ago) by gbeauche
Branch: MAIN
Log Message:
Move Linux/asm_linux.S to ppc_asm.S suitable for Linux, MacOS X and NetBSD

File Contents

# User Rev Content
1 gbeauche 1.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_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     ASM_MACRO_START prolog
570     mflr r0
571     stw r0,4(r1)
572     stwu r1,-64(r1)
573     ASM_MACRO_END
574    
575     ASM_MACRO_START epilog
576     lwz r13,XLM_TOC(0)
577     lwz r0,64+4(r1)
578     mtlr r0
579     addi r1,r1,64
580     blr
581     ASM_MACRO_END
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