ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/Linux/asm_linux.S
Revision: 1.1.1.1 (vendor branch)
Committed: 2002-02-04T16:58:13Z (22 years, 5 months ago) by cebix
Branch: cebix
CVS Tags: start
Changes since 1.1: +0 -0 lines
Log Message:
Imported sources

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * asm_linux.S - Assembly routines
3     *
4     * SheepShaver (C) 1997-2002 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     .globl get_toc
32     get_toc:
33     mr r3,r13
34     blr
35    
36    
37     /*
38     * void *get_sp(void) - Get stack pointer
39     */
40    
41     .globl get_sp
42     get_sp:
43     mr r3,r1
44     blr
45    
46    
47     /*
48     * void set_r2(uint32 val {r3}) - Set r2
49     */
50    
51     .globl set_r2
52     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     .globl flush_icache_range
65     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     .globl atomic_add
95     atomic_add:
96     10: dcbf r0,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,r0,r3
106     add r0,r4,r5
107     stwcx. r0,r0,r3
108     bne- 10b
109     mr r3,r5
110     isync
111     blr
112    
113     .globl atomic_and
114     atomic_and:
115     10: dcbf r0,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,r0,r3
125     and r0,r4,r5
126     stwcx. r0,r0,r3
127     bne- 10b
128     mr r3,r5
129     isync
130     blr
131    
132     .globl atomic_or
133     atomic_or:
134     10: dcbf r0,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,r0,r3
144     or r0,r4,r5
145     stwcx. r0,r0,r3
146     bne- 10b
147     mr r3,r5
148     isync
149     blr
150    
151     .globl test_and_set
152     test_and_set:
153     10: dcbf r0,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,r0,r3
163     cmpi 0,r5,0x0000
164     beq 1f
165     stwcx. r4,r0,r3
166     bne- 10b
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     .globl quit_emulator
177     quit_emulator:
178     lwz r0,XLM_EMUL_RETURN_PROC(r0)
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     .globl jump_to_rom
188     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(r0)
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(r0)
251     li r0,MODE_NATIVE
252     stw r0,XLM_RUN_MODE(r0)
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(r0)
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(r0)
275    
276     // Reentering EMUL_OP mode
277     li r0,MODE_EMUL_OP
278     stw r0,XLM_RUN_MODE(r0)
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(r0)
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(r0)
347    
348     // Entering EMUL_OP mode within 68k emulator
349     li r0,MODE_EMUL_OP
350     stw r0,XLM_RUN_MODE(r0)
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,-(8+16*4+15*8)(r1)
364    
365     // Save 68k registers (M68kRegisters)
366     stw r8,8+0*4(r1) // d[0]..d[7]
367     stw r9,8+1*4(r1)
368     stw r10,8+2*4(r1)
369     stw r11,8+3*4(r1)
370     stw r12,8+4*4(r1)
371     stw r13,8+5*4(r1)
372     stw r14,8+6*4(r1)
373     stw r15,8+7*4(r1)
374     stw r16,8+8*4(r1) // a[0]..a[7]
375     stw r17,8+9*4(r1)
376     stw r18,8+10*4(r1)
377     stw r19,8+11*4(r1)
378     stw r20,8+12*4(r1)
379     stw r21,8+13*4(r1)
380     stw r22,8+14*4(r1)
381     stw r3,8+15*4(r1)
382     stfd f0,8+16*4+0*8(r1)
383     stfd f1,8+16*4+1*8(r1)
384     stfd f2,8+16*4+2*8(r1)
385     stfd f3,8+16*4+3*8(r1)
386     stfd f4,8+16*4+4*8(r1)
387     stfd f5,8+16*4+5*8(r1)
388     stfd f6,8+16*4+6*8(r1)
389     stfd f7,8+16*4+7*8(r1)
390     mffs f0
391     stfd f8,8+16*4+8*8(r1)
392     stfd f9,8+16*4+9*8(r1)
393     stfd f10,8+16*4+10*8(r1)
394     stfd f11,8+16*4+11*8(r1)
395     stfd f12,8+16*4+12*8(r1)
396     stfd f13,8+16*4+13*8(r1)
397     stfd f0,8+16*4+14*8(r1)
398    
399     // Execute native routine
400     lwz r13,XLM_TOC(r0)
401     addi r3,r1,8
402     mr r4,r24
403     bl EmulOp__FP13M68kRegistersUii
404    
405     // Restore 68k registers (M68kRegisters)
406     lwz r8,8+0*4(r1) // d[0]..d[7]
407     lwz r9,8+1*4(r1)
408     lwz r10,8+2*4(r1)
409     lwz r11,8+3*4(r1)
410     lwz r12,8+4*4(r1)
411     lwz r13,8+5*4(r1)
412     lwz r14,8+6*4(r1)
413     lwz r15,8+7*4(r1)
414     lwz r16,8+8*4(r1) // a[0]..a[7]
415     lwz r17,8+9*4(r1)
416     lwz r18,8+10*4(r1)
417     lwz r19,8+11*4(r1)
418     lwz r20,8+12*4(r1)
419     lwz r21,8+13*4(r1)
420     lwz r22,8+14*4(r1)
421     lwz r3,8+15*4(r1)
422     lfd f13,8+16*4+14*8(r1)
423     lfd f0,8+16*4+0*8(r1)
424     lfd f1,8+16*4+1*8(r1)
425     lfd f2,8+16*4+2*8(r1)
426     lfd f3,8+16*4+3*8(r1)
427     lfd f4,8+16*4+4*8(r1)
428     lfd f5,8+16*4+5*8(r1)
429     lfd f6,8+16*4+6*8(r1)
430     lfd f7,8+16*4+7*8(r1)
431     mtfsf 0xff,f13
432     lfd f8,8+16*4+8*8(r1)
433     lfd f9,8+16*4+9*8(r1)
434     lfd f10,8+16*4+10*8(r1)
435     lfd f11,8+16*4+11*8(r1)
436     lfd f12,8+16*4+12*8(r1)
437     lfd f13,8+16*4+13*8(r1)
438    
439     // Delete PowerPC stack frame
440     lwz r2,8+16*4+15*8+12(r1)
441     lwz r0,8+16*4+15*8+16(r1)
442     mtxer r0
443     lwz r0,8+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(r0)
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(r0)
464    
465     // Save stack pointer for EMUL_RETURN
466     stw r1,XLM_EMUL_RETURN_STACK(r0)
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(r0)
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     .globl execute_68k
485     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(r0) // 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(r0) // 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(r0)
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     #define prolog \
570     mflr r0; \
571     stw r0,4(r1); \
572     stwu r1,-64(r1)
573    
574     #define epilog \
575     lwz r13,XLM_TOC(r0);\
576     lwz r0,64+4(r1); \
577     mtlr r0; \
578     addi r1,r1,64; \
579     blr
580    
581     .globl call_macos
582     call_macos:
583     prolog
584     lwz r0,0(r3) // Get routine address
585     lwz r2,4(r3) // Load TOC pointer
586     mtctr r0
587     bctrl
588     epilog
589    
590     .globl call_macos1
591     call_macos1:
592     prolog
593     lwz r0,0(r3) // Get routine address
594     lwz r2,4(r3) // Load TOC pointer
595     mtctr r0
596     mr r3,r4
597     bctrl
598     epilog
599    
600     .globl call_macos2
601     call_macos2:
602     prolog
603     lwz r0,0(r3) // Get routine address
604     lwz r2,4(r3) // Load TOC pointer
605     mtctr r0
606     mr r3,r4
607     mr r4,r5
608     bctrl
609     epilog
610    
611     .globl call_macos3
612     call_macos3:
613     prolog
614     lwz r0,0(r3) // Get routine address
615     lwz r2,4(r3) // Load TOC pointer
616     mtctr r0
617     mr r3,r4
618     mr r4,r5
619     mr r5,r6
620     bctrl
621     epilog
622    
623     .globl call_macos4
624     call_macos4:
625     prolog
626     lwz r0,0(r3) // Get routine address
627     lwz r2,4(r3) // Load TOC pointer
628     mtctr r0
629     mr r3,r4
630     mr r4,r5
631     mr r5,r6
632     mr r6,r7
633     bctrl
634     epilog
635    
636     .globl call_macos5
637     call_macos5:
638     prolog
639     lwz r0,0(r3) // Get routine address
640     lwz r2,4(r3) // Load TOC pointer
641     mtctr r0
642     mr r3,r4
643     mr r4,r5
644     mr r5,r6
645     mr r6,r7
646     mr r7,r8
647     bctrl
648     epilog
649    
650     .globl call_macos6
651     call_macos6:
652     prolog
653     lwz r0,0(r3) // Get routine address
654     lwz r2,4(r3) // Load TOC pointer
655     mtctr r0
656     mr r3,r4
657     mr r4,r5
658     mr r5,r6
659     mr r6,r7
660     mr r7,r8
661     mr r8,r9
662     bctrl
663     epilog
664    
665     .globl call_macos7
666     call_macos7:
667     prolog
668     lwz r0,0(r3) // Get routine address
669     lwz r2,4(r3) // Load TOC pointer
670     mtctr r0
671     mr r3,r4
672     mr r4,r5
673     mr r5,r6
674     mr r6,r7
675     mr r7,r8
676     mr r8,r9
677     mr r9,r10
678     bctrl
679     epilog
680    
681    
682     /*
683     * Native resource manager patches
684     */
685    
686     .globl get_resource
687     get_resource:
688     // Create stack frame
689     mflr r0
690     stw r0,8(r1)
691     stwu r1,-(56+12)(r1)
692    
693     // Save type/ID
694     stw r3,56(r1)
695     stw r4,56+4(r1)
696    
697     // Call old routine
698     lwz r0,XLM_GET_RESOURCE(r0)
699     lwz r2,XLM_RES_LIB_TOC(r0)
700     mtctr r0
701     bctrl
702     stw r3,56+8(r1) // Save handle
703    
704     // Call CheckLoad
705     lwz r3,56(r1)
706     lwz r4,56+4(r1)
707     lwz r5,56+8(r1)
708     bl check_load_invoc__FUisPPUs
709     lwz r3,56+8(r1) // Restore handle
710    
711     // Return to caller
712     lwz r0,56+12+8(r1)
713     mtlr r0
714     addi r1,r1,56+12
715     blr
716    
717     .globl get_1_resource
718     get_1_resource:
719     // Create stack frame
720     mflr r0
721     stw r0,8(r1)
722     stwu r1,-(56+12)(r1)
723    
724     // Save type/ID
725     stw r3,56(r1)
726     stw r4,56+4(r1)
727    
728     // Call old routine
729     lwz r0,XLM_GET_1_RESOURCE(r0)
730     lwz r2,XLM_RES_LIB_TOC(r0)
731     mtctr r0
732     bctrl
733     stw r3,56+8(r1) // Save handle
734    
735     // Call CheckLoad
736     lwz r3,56(r1)
737     lwz r4,56+4(r1)
738     lwz r5,56+8(r1)
739     bl check_load_invoc__FUisPPUs
740     lwz r3,56+8(r1) // Restore handle
741    
742     // Return to caller
743     lwz r0,56+12+8(r1)
744     mtlr r0
745     addi r1,r1,56+12
746     blr
747    
748     .globl get_ind_resource
749     get_ind_resource:
750     // Create stack frame
751     mflr r0
752     stw r0,8(r1)
753     stwu r1,-(56+12)(r1)
754    
755     // Save type/index
756     stw r3,56(r1)
757     stw r4,56+4(r1)
758    
759     // Call old routine
760     lwz r0,XLM_GET_IND_RESOURCE(r0)
761     lwz r2,XLM_RES_LIB_TOC(r0)
762     mtctr r0
763     bctrl
764     stw r3,56+8(r1) // Save handle
765    
766     // Call CheckLoad
767     lwz r3,56(r1)
768     lwz r4,56+4(r1)
769     lwz r5,56+8(r1)
770     bl check_load_invoc__FUisPPUs
771     lwz r3,56+8(r1) // Restore handle
772    
773     // Return to caller
774     lwz r0,56+12+8(r1)
775     mtlr r0
776     addi r1,r1,56+12
777     blr
778    
779     .globl get_1_ind_resource
780     get_1_ind_resource:
781     // Create stack frame
782     mflr r0
783     stw r0,8(r1)
784     stwu r1,-(56+12)(r1)
785    
786     // Save type/index
787     stw r3,56(r1)
788     stw r4,56+4(r1)
789    
790     // Call old routine
791     lwz r0,XLM_GET_1_IND_RESOURCE(r0)
792     lwz r2,XLM_RES_LIB_TOC(r0)
793     mtctr r0
794     bctrl
795     stw r3,56+8(r1) // Save handle
796    
797     // Call CheckLoad
798     lwz r3,56(r1)
799     lwz r4,56+4(r1)
800     lwz r5,56+8(r1)
801     bl check_load_invoc__FUisPPUs
802     lwz r3,56+8(r1) // Restore handle
803    
804     // Return to caller
805     lwz r0,56+12+8(r1)
806     mtlr r0
807     addi r1,r1,56+12
808     blr
809    
810     .globl r_get_resource
811     r_get_resource:
812     // Create stack frame
813     mflr r0
814     stw r0,8(r1)
815     stwu r1,-(56+12)(r1)
816    
817     // Save type/ID
818     stw r3,56(r1)
819     stw r4,56+4(r1)
820    
821     // Call old routine
822     lwz r0,XLM_R_GET_RESOURCE(r0)
823     lwz r2,XLM_RES_LIB_TOC(r0)
824     mtctr r0
825     bctrl
826     stw r3,56+8(r1) // Save handle
827    
828     // Call CheckLoad
829     lwz r3,56(r1)
830     lwz r4,56+4(r1)
831     lwz r5,56+8(r1)
832     bl check_load_invoc__FUisPPUs
833     lwz r3,56+8(r1) // Restore handle
834    
835     // Return to caller
836     lwz r0,56+12+8(r1)
837     mtlr r0
838     addi r1,r1,56+12
839     blr
840    
841    
842     /*
843     * void ppc_interrupt(uint32 entry{r3}, uint32 kernel_data{r4}) - Execute PPC interrupt
844     */
845    
846     .globl ppc_interrupt
847     ppc_interrupt:
848     mflr r0
849     stw r0,4(r1)
850     stwu r1,-64(r1)
851    
852     // Get address of return routine
853     bl 1f
854    
855     // Return routine
856     lwz r0,64+4(r1)
857     mtlr r0
858     addi r1,r1,64
859     blr
860    
861     // Prepare registers for nanokernel interrupt routine
862     1: mtctr r1
863     mr r1,r4
864     stw r6,0x018(r1)
865     mfctr r6
866     stw r6,0x004(r1)
867     lwz r6,0x65c(r1)
868     stw r7,0x13c(r6)
869     stw r8,0x144(r6)
870     stw r9,0x14c(r6)
871     stw r10,0x154(r6)
872     stw r11,0x15c(r6)
873     stw r12,0x164(r6)
874     stw r13,0x16c(r6)
875    
876     mflr r10
877     mfcr r13
878     lwz r7,0x660(r1)
879     mflr r12
880     rlwimi. r7,r7,8,0,0
881     li r11,0
882     ori r11,r11,0xf072 // MSR (SRR1)
883     mtcrf 0x70,r11
884     li r8,0
885    
886     // Enter nanokernel
887     mtlr r3
888     blr