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, 2 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

# 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 gbeauche 1.2 * void *get_sp(void) - Get stack pointer
29 gbeauche 1.1 */
30    
31 gbeauche 1.2 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_sp)
32     C_SYMBOL_NAME(get_sp):
33     mr r3,r1
34 gbeauche 1.1 blr
35    
36    
37     /*
38 gbeauche 1.2 * void *get_r2(void) - Get r2
39 gbeauche 1.1 */
40    
41 gbeauche 1.2 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_r2)
42     C_SYMBOL_NAME(get_r2):
43     mr r3,r2
44 gbeauche 1.1 blr
45    
46    
47     /*
48 gbeauche 1.2 * void set_r2(void *val {r3}) - Set r2
49 gbeauche 1.1 */
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 gbeauche 1.2 * 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 gbeauche 1.1 * 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 gbeauche 1.2 RESTORE_SYSTEM_R2
248 gbeauche 1.1 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 gbeauche 1.2 RESTORE_SYSTEM_R2
421     RESTORE_SYSTEM_R13
422 gbeauche 1.1 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 gbeauche 1.2 RESTORE_SYSTEM_R2
598     RESTORE_SYSTEM_R13
599 gbeauche 1.1 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 gbeauche 1.2 RESTORE_SYSTEM_R2
727 gbeauche 1.1 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 gbeauche 1.2 RESTORE_SYSTEM_R2
759 gbeauche 1.1 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 gbeauche 1.2 RESTORE_SYSTEM_R2
791 gbeauche 1.1 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 gbeauche 1.2 RESTORE_SYSTEM_R2
823 gbeauche 1.1 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 gbeauche 1.2 RESTORE_SYSTEM_R2
855 gbeauche 1.1 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