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, 9 months ago) by cebix
Branch: cebix
CVS Tags: start
Changes since 1.1: +0 -0 lines
Error occurred while calculating annotation data.
Log Message:
Imported sources

File Contents

# Content
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