ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/Linux/asm_linux.S
Revision: 1.8
Committed: 2005-02-20T18:25:45Z (19 years, 8 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.7: +0 -0 lines
State: FILE REMOVED
Log Message:
Move Linux/asm_linux.S to ppc_asm.S suitable for Linux, MacOS X and NetBSD

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * asm_linux.S - Assembly routines
3     *
4 gbeauche 1.7 * SheepShaver (C) 1997-2005 Christian Bauer and Marc Hellwig
5 cebix 1.1 *
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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_toc)
32     C_SYMBOL_NAME(get_toc):
33 cebix 1.1 mr r3,r13
34     blr
35    
36    
37     /*
38     * void *get_sp(void) - Get stack pointer
39     */
40    
41 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_sp)
42     C_SYMBOL_NAME(get_sp):
43 cebix 1.1 mr r3,r1
44     blr
45    
46    
47     /*
48     * void set_r2(uint32 val {r3}) - Set r2
49     */
50    
51 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(set_r2)
52     C_SYMBOL_NAME(set_r2):
53 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(flush_icache_range)
65     C_SYMBOL_NAME(flush_icache_range):
66 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(atomic_add)
95     C_SYMBOL_NAME(atomic_add):
96     0: dcbf 0,r3
97 cebix 1.1 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 gbeauche 1.5 lwarx r5,0,r3
106 cebix 1.1 add r0,r4,r5
107 gbeauche 1.5 stwcx. r0,0,r3
108     bne- 0b
109 cebix 1.1 mr r3,r5
110     isync
111     blr
112    
113 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(atomic_and)
114     C_SYMBOL_NAME(atomic_and):
115     0: dcbf 0,r3
116 cebix 1.1 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 gbeauche 1.5 lwarx r5,0,r3
125 cebix 1.1 and r0,r4,r5
126 gbeauche 1.5 stwcx. r0,0,r3
127     bne- 0b
128 cebix 1.1 mr r3,r5
129     isync
130     blr
131    
132 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(atomic_or)
133     C_SYMBOL_NAME(atomic_or):
134     0: dcbf 0,r3
135 cebix 1.1 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 gbeauche 1.5 lwarx r5,0,r3
144 cebix 1.1 or r0,r4,r5
145 gbeauche 1.5 stwcx. r0,0,r3
146     bne- 0b
147 cebix 1.1 mr r3,r5
148     isync
149     blr
150    
151 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(test_and_set)
152     C_SYMBOL_NAME(test_and_set):
153     0: dcbf 0,r3
154 cebix 1.1 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 gbeauche 1.5 lwarx r5,0,r3
163 cebix 1.1 cmpi 0,r5,0x0000
164     beq 1f
165 gbeauche 1.5 stwcx. r4,0,r3
166     bne- 0b
167 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(quit_emulator)
177     C_SYMBOL_NAME(quit_emulator):
178     lwz r0,XLM_EMUL_RETURN_PROC(0)
179 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(jump_to_rom)
188     C_SYMBOL_NAME(jump_to_rom):
189 cebix 1.1 // 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 gbeauche 1.5 lwz r1,XLM_EMUL_RETURN_STACK(0)
228 cebix 1.1 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 gbeauche 1.5 stw r0,XLM_IRQ_NEST(0)
251 cebix 1.1 li r0,MODE_NATIVE
252 gbeauche 1.5 stw r0,XLM_RUN_MODE(0)
253 cebix 1.1
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 gbeauche 1.5 stw r0,XLM_EMUL_RETURN_PROC(0)
264 cebix 1.1
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 gbeauche 1.5 stw r25,XLM_68K_R25(0)
275 cebix 1.1
276     // Reentering EMUL_OP mode
277     li r0,MODE_EMUL_OP
278 gbeauche 1.5 stw r0,XLM_RUN_MODE(0)
279 cebix 1.1
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 gbeauche 1.5 stw r0,XLM_EXEC_RETURN_PROC(0)
333 cebix 1.1
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 gbeauche 1.5 stw r25,XLM_68K_R25(0)
347 cebix 1.1
348     // Entering EMUL_OP mode within 68k emulator
349     li r0,MODE_EMUL_OP
350 gbeauche 1.5 stw r0,XLM_RUN_MODE(0)
351 cebix 1.1
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 gbeauche 1.5 stwu r1,-(24+16*4+15*8)(r1)
364 cebix 1.1
365     // Save 68k registers (M68kRegisters)
366 gbeauche 1.5 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 cebix 1.1 mffs f0
391 gbeauche 1.5 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 cebix 1.1
399     // Execute native routine
400 gbeauche 1.5 lwz r13,XLM_TOC(0)
401     addi r3,r1,24
402 cebix 1.1 mr r4,r24
403 gbeauche 1.5 bl C_SYMBOL_NAME(EmulOp)
404 cebix 1.1
405     // Restore 68k registers (M68kRegisters)
406 gbeauche 1.5 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 cebix 1.1 mtfsf 0xff,f13
432 gbeauche 1.5 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 cebix 1.1
439     // Delete PowerPC stack frame
440 gbeauche 1.5 lwz r2,24+16*4+15*8+12(r1)
441     lwz r0,24+16*4+15*8+16(r1)
442 cebix 1.1 mtxer r0
443 gbeauche 1.5 lwz r0,24+16*4+15*8+4(r1)
444 cebix 1.1 mtcrf 0xff,r0
445     mr r1,r3
446    
447     // Reentering 68k emulator
448     li r0,MODE_68K
449 gbeauche 1.5 stw r0,XLM_RUN_MODE(0)
450 cebix 1.1
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 gbeauche 1.5 stw r0,XLM_EMUL_OP_PROC(0)
464 cebix 1.1
465     // Save stack pointer for EMUL_RETURN
466 gbeauche 1.5 stw r1,XLM_EMUL_RETURN_STACK(0)
467 cebix 1.1
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 gbeauche 1.5 stw r0,XLM_RUN_MODE(0)
475 cebix 1.1
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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(execute_68k)
485     C_SYMBOL_NAME(execute_68k):
486 cebix 1.1 // 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 gbeauche 1.5 lwz r31,XLM_KERNEL_DATA(0) // Pointer to Kernel Data
519 cebix 1.1 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 gbeauche 1.5 lwz r25,XLM_68K_R25(0) // MSB of SR
541 cebix 1.1 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 gbeauche 1.5 stw r0,XLM_RUN_MODE(0)
553 cebix 1.1
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 gbeauche 1.6 ASM_MACRO_START prolog
570 gbeauche 1.5 mflr r0
571     stw r0,4(r1)
572 cebix 1.1 stwu r1,-64(r1)
573 gbeauche 1.6 ASM_MACRO_END
574 cebix 1.1
575 gbeauche 1.6 ASM_MACRO_START epilog
576 gbeauche 1.5 lwz r13,XLM_TOC(0)
577     lwz r0,64+4(r1)
578     mtlr r0
579     addi r1,r1,64
580 cebix 1.1 blr
581 gbeauche 1.6 ASM_MACRO_END
582 cebix 1.1
583 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos)
584     C_SYMBOL_NAME(call_macos):
585 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos1)
593     C_SYMBOL_NAME(call_macos1):
594 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos2)
603     C_SYMBOL_NAME(call_macos2):
604 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos3)
614     C_SYMBOL_NAME(call_macos3):
615 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos4)
626     C_SYMBOL_NAME(call_macos4):
627 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos5)
639     C_SYMBOL_NAME(call_macos5):
640 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos6)
653     C_SYMBOL_NAME(call_macos6):
654 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos7)
668     C_SYMBOL_NAME(call_macos7):
669 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_resource)
689     C_SYMBOL_NAME(get_resource):
690 cebix 1.1 // 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 gbeauche 1.5 lwz r0,XLM_GET_RESOURCE(0)
701     lwz r2,XLM_RES_LIB_TOC(0)
702 cebix 1.1 mtctr r0
703     bctrl
704     stw r3,56+8(r1) // Save handle
705    
706     // Call CheckLoad
707     lwz r3,56(r1)
708 gbeauche 1.3 lha r4,56+6(r1)
709 cebix 1.1 lwz r5,56+8(r1)
710 gbeauche 1.5 bl C_SYMBOL_NAME(check_load_invoc)
711 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_1_resource)
720     C_SYMBOL_NAME(get_1_resource):
721 cebix 1.1 // 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 gbeauche 1.5 lwz r0,XLM_GET_1_RESOURCE(0)
732     lwz r2,XLM_RES_LIB_TOC(0)
733 cebix 1.1 mtctr r0
734     bctrl
735     stw r3,56+8(r1) // Save handle
736    
737     // Call CheckLoad
738     lwz r3,56(r1)
739 gbeauche 1.3 lha r4,56+6(r1)
740 cebix 1.1 lwz r5,56+8(r1)
741 gbeauche 1.5 bl C_SYMBOL_NAME(check_load_invoc)
742 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_ind_resource)
751     C_SYMBOL_NAME(get_ind_resource):
752 cebix 1.1 // 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 gbeauche 1.5 lwz r0,XLM_GET_IND_RESOURCE(0)
763     lwz r2,XLM_RES_LIB_TOC(0)
764 cebix 1.1 mtctr r0
765     bctrl
766     stw r3,56+8(r1) // Save handle
767    
768     // Call CheckLoad
769     lwz r3,56(r1)
770 gbeauche 1.3 lha r4,56+6(r1)
771 cebix 1.1 lwz r5,56+8(r1)
772 gbeauche 1.5 bl C_SYMBOL_NAME(check_load_invoc)
773 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_1_ind_resource)
782     C_SYMBOL_NAME(get_1_ind_resource):
783 cebix 1.1 // 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 gbeauche 1.5 lwz r0,XLM_GET_1_IND_RESOURCE(0)
794     lwz r2,XLM_RES_LIB_TOC(0)
795 cebix 1.1 mtctr r0
796     bctrl
797     stw r3,56+8(r1) // Save handle
798    
799     // Call CheckLoad
800     lwz r3,56(r1)
801 gbeauche 1.3 lha r4,56+6(r1)
802 cebix 1.1 lwz r5,56+8(r1)
803 gbeauche 1.5 bl C_SYMBOL_NAME(check_load_invoc)
804 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(r_get_resource)
813     C_SYMBOL_NAME(r_get_resource):
814 cebix 1.1 // 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 gbeauche 1.5 lwz r0,XLM_R_GET_RESOURCE(0)
825     lwz r2,XLM_RES_LIB_TOC(0)
826 cebix 1.1 mtctr r0
827     bctrl
828     stw r3,56+8(r1) // Save handle
829    
830     // Call CheckLoad
831     lwz r3,56(r1)
832 gbeauche 1.3 lha r4,56+6(r1)
833 cebix 1.1 lwz r5,56+8(r1)
834 gbeauche 1.5 bl C_SYMBOL_NAME(check_load_invoc)
835 cebix 1.1 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 gbeauche 1.5 ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(ppc_interrupt)
849     C_SYMBOL_NAME(ppc_interrupt):
850 cebix 1.1 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