ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/ppc_asm.S
Revision: 1.7
Committed: 2005-06-28T16:47:32Z (19 years, 4 months ago) by gbeauche
Branch: MAIN
Changes since 1.6: +77 -0 lines
Log Message:
The alternate stack trick never worked as you can't modify an active stack.
i.e. it returned EPERM and ran into stack corruption to eventually crash the
emulator. This is noticeable in !hw_mac_cursor_accl mode (e.g. fullscreen DGA).

In order to the sigalstack() to be effective, we must kludge the kernel to
think it's running on another stack. In practise, we provide another stack
for the SIGUSR2 handler. sigusr2_handler_init() fulfills that purpose.

I hope this fixes remaining issues forever. At some point, I had multiple
*_init() handlers in case this is necessary.

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 gbeauche 1.6 bne 1f
184 gbeauche 1.1 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.4 RESTORE_SYSTEM_R13
249 gbeauche 1.1 lmw r13,20(r1)
250     lfd f14,20+19*4+0*8(r1)
251     lfd f15,20+19*4+1*8(r1)
252     lfd f16,20+19*4+2*8(r1)
253     lfd f17,20+19*4+3*8(r1)
254     lfd f18,20+19*4+4*8(r1)
255     lfd f19,20+19*4+5*8(r1)
256     lfd f20,20+19*4+6*8(r1)
257     lfd f21,20+19*4+7*8(r1)
258     lfd f22,20+19*4+8*8(r1)
259     lfd f23,20+19*4+9*8(r1)
260     lfd f24,20+19*4+10*8(r1)
261     lfd f25,20+19*4+11*8(r1)
262     lfd f26,20+19*4+12*8(r1)
263     lfd f27,20+19*4+13*8(r1)
264     lfd f28,20+19*4+14*8(r1)
265     lfd f29,20+19*4+15*8(r1)
266     lfd f30,20+19*4+16*8(r1)
267     lfd f31,20+19*4+17*8(r1)
268    
269     // Exiting from 68k emulator
270     li r0,1
271     stw r0,XLM_IRQ_NEST(0)
272     li r0,MODE_NATIVE
273     stw r0,XLM_RUN_MODE(0)
274    
275     // Return to caller of jump_to_rom()
276     lwz r0,20+19*4+18*8+4(r1)
277     mtlr r0
278     addi r1,r1,20+19*4+18*8
279     blr
280    
281    
282     // Save address of EMUL_RETURN routine for 68k emulator patch
283     1: mflr r0
284     stw r0,XLM_EMUL_RETURN_PROC(0)
285    
286     // Skip over EXEC_RETURN routine and get its address
287     bl 2f
288    
289    
290     /*
291     * EXEC_RETURN: Returned from 68k routine executed with Execute68k()
292     */
293    
294     // Save r25 (contains current 68k interrupt level)
295     stw r25,XLM_68K_R25(0)
296    
297     // Reentering EMUL_OP mode
298     li r0,MODE_EMUL_OP
299     stw r0,XLM_RUN_MODE(0)
300    
301     // Save 68k registers
302     lwz r4,48(r1) // Pointer to M68kRegisters
303     stw r8,0*4(r4) // d[0]...d[7]
304     stw r9,1*4(r4)
305     stw r10,2*4(r4)
306     stw r11,3*4(r4)
307     stw r12,4*4(r4)
308     stw r13,5*4(r4)
309     stw r14,6*4(r4)
310     stw r15,7*4(r4)
311     stw r16,8*4(r4) // a[0]..a[6]
312     stw r17,9*4(r4)
313     stw r18,10*4(r4)
314     stw r19,11*4(r4)
315     stw r20,12*4(r4)
316     stw r21,13*4(r4)
317     stw r22,14*4(r4)
318    
319     // Restore PowerPC registers
320     lmw r13,56(r1)
321     #if SAVE_FP_EXEC_68K
322     lfd f14,56+19*4+0*8(r1)
323     lfd f15,56+19*4+1*8(r1)
324     lfd f16,56+19*4+2*8(r1)
325     lfd f17,56+19*4+3*8(r1)
326     lfd f18,56+19*4+4*8(r1)
327     lfd f19,56+19*4+5*8(r1)
328     lfd f20,56+19*4+6*8(r1)
329     lfd f21,56+19*4+7*8(r1)
330     lfd f22,56+19*4+8*8(r1)
331     lfd f23,56+19*4+9*8(r1)
332     lfd f24,56+19*4+10*8(r1)
333     lfd f25,56+19*4+11*8(r1)
334     lfd f26,56+19*4+12*8(r1)
335     lfd f27,56+19*4+13*8(r1)
336     lfd f28,56+19*4+14*8(r1)
337     lfd f29,56+19*4+15*8(r1)
338     lfd f30,56+19*4+16*8(r1)
339     lfd f31,56+19*4+17*8(r1)
340     #endif
341    
342     // Return to caller
343     lwz r0,52(r1)
344     mtcrf 0xff,r0
345     lwz r0,56+19*4+18*8+4(r1)
346     mtlr r0
347     addi r1,r1,56+19*4+18*8
348 gbeauche 1.4 RESTORE_SYSTEM_R2
349     RESTORE_SYSTEM_R13
350 gbeauche 1.1 blr
351    
352    
353     // Save address of EXEC_RETURN routine for 68k emulator patch
354     2: mflr r0
355     stw r0,XLM_EXEC_RETURN_PROC(0)
356    
357     // Skip over EMUL_BREAK/EMUL_OP routine and get its address
358     bl 3f
359    
360    
361     /*
362     * EMUL_BREAK/EMUL_OP: Execute native routine, selector in r5 (my own private mode switch)
363     *
364     * 68k registers are stored in a M68kRegisters struct on the stack
365     * which the native routine may read and modify
366     */
367    
368     // Save r25 (contains current 68k interrupt level)
369     stw r25,XLM_68K_R25(0)
370    
371     // Entering EMUL_OP mode within 68k emulator
372     li r0,MODE_EMUL_OP
373     stw r0,XLM_RUN_MODE(0)
374    
375     // Create PowerPC stack frame, reserve space for M68kRegisters
376     mr r3,r1
377     subi r1,r1,64 // Fake "caller" frame
378     rlwinm r1,r1,0,0,27 // Align stack
379    
380     mfcr r0
381     rlwinm r0,r0,0,11,8
382     stw r0,4(r1)
383     mfxer r0
384     stw r0,16(r1)
385     stw r2,12(r1)
386 gbeauche 1.4 stwu r1,-(56+16*4+15*8)(r1)
387 gbeauche 1.1
388     // Save 68k registers (M68kRegisters)
389 gbeauche 1.4 stw r8,56+0*4(r1) // d[0]..d[7]
390     stw r9,56+1*4(r1)
391     stw r10,56+2*4(r1)
392     stw r11,56+3*4(r1)
393     stw r12,56+4*4(r1)
394     stw r13,56+5*4(r1)
395     stw r14,56+6*4(r1)
396     stw r15,56+7*4(r1)
397     stw r16,56+8*4(r1) // a[0]..a[7]
398     stw r17,56+9*4(r1)
399     stw r18,56+10*4(r1)
400     stw r19,56+11*4(r1)
401     stw r20,56+12*4(r1)
402     stw r21,56+13*4(r1)
403     stw r22,56+14*4(r1)
404     stw r3,56+15*4(r1)
405     stfd f0,56+16*4+0*8(r1)
406     stfd f1,56+16*4+1*8(r1)
407     stfd f2,56+16*4+2*8(r1)
408     stfd f3,56+16*4+3*8(r1)
409     stfd f4,56+16*4+4*8(r1)
410     stfd f5,56+16*4+5*8(r1)
411     stfd f6,56+16*4+6*8(r1)
412     stfd f7,56+16*4+7*8(r1)
413 gbeauche 1.1 mffs f0
414 gbeauche 1.4 stfd f8,56+16*4+8*8(r1)
415     stfd f9,56+16*4+9*8(r1)
416     stfd f10,56+16*4+10*8(r1)
417     stfd f11,56+16*4+11*8(r1)
418     stfd f12,56+16*4+12*8(r1)
419     stfd f13,56+16*4+13*8(r1)
420     stfd f0,56+16*4+14*8(r1)
421 gbeauche 1.1
422     // Execute native routine
423 gbeauche 1.2 RESTORE_SYSTEM_R2
424     RESTORE_SYSTEM_R13
425 gbeauche 1.4 addi r3,r1,56
426 gbeauche 1.1 mr r4,r24
427     bl C_SYMBOL_NAME(EmulOp)
428    
429     // Restore 68k registers (M68kRegisters)
430 gbeauche 1.4 lwz r8,56+0*4(r1) // d[0]..d[7]
431     lwz r9,56+1*4(r1)
432     lwz r10,56+2*4(r1)
433     lwz r11,56+3*4(r1)
434     lwz r12,56+4*4(r1)
435     lwz r13,56+5*4(r1)
436     lwz r14,56+6*4(r1)
437     lwz r15,56+7*4(r1)
438     lwz r16,56+8*4(r1) // a[0]..a[7]
439     lwz r17,56+9*4(r1)
440     lwz r18,56+10*4(r1)
441     lwz r19,56+11*4(r1)
442     lwz r20,56+12*4(r1)
443     lwz r21,56+13*4(r1)
444     lwz r22,56+14*4(r1)
445     lwz r3,56+15*4(r1)
446     lfd f13,56+16*4+14*8(r1)
447     lfd f0,56+16*4+0*8(r1)
448     lfd f1,56+16*4+1*8(r1)
449     lfd f2,56+16*4+2*8(r1)
450     lfd f3,56+16*4+3*8(r1)
451     lfd f4,56+16*4+4*8(r1)
452     lfd f5,56+16*4+5*8(r1)
453     lfd f6,56+16*4+6*8(r1)
454     lfd f7,56+16*4+7*8(r1)
455 gbeauche 1.1 mtfsf 0xff,f13
456 gbeauche 1.4 lfd f8,56+16*4+8*8(r1)
457     lfd f9,56+16*4+9*8(r1)
458     lfd f10,56+16*4+10*8(r1)
459     lfd f11,56+16*4+11*8(r1)
460     lfd f12,56+16*4+12*8(r1)
461     lfd f13,56+16*4+13*8(r1)
462 gbeauche 1.1
463     // Delete PowerPC stack frame
464 gbeauche 1.4 lwz r2,56+16*4+15*8+12(r1)
465     lwz r0,56+16*4+15*8+16(r1)
466 gbeauche 1.1 mtxer r0
467 gbeauche 1.4 lwz r0,56+16*4+15*8+4(r1)
468 gbeauche 1.1 mtcrf 0xff,r0
469     mr r1,r3
470    
471     // Reentering 68k emulator
472     li r0,MODE_68K
473     stw r0,XLM_RUN_MODE(0)
474    
475     // Set r0 to 0 for 68k emulator
476     li r0,0
477    
478     // Execute next 68k opcode
479     rlwimi r29,r27,3,13,28
480     lhau r27,2(r24)
481     mtlr r29
482     blr
483    
484    
485     // Save address of EMUL_BREAK/EMUL_OP routine for 68k emulator patch
486     3: mflr r0
487     stw r0,XLM_EMUL_OP_PROC(0)
488    
489     // Save stack pointer for EMUL_RETURN
490     stw r1,XLM_EMUL_RETURN_STACK(0)
491    
492     // Preset registers for ROM boot routine
493     lis r3,0x40b0 // Pointer to ROM boot structure
494     ori r3,r3,0xd000
495    
496     // 68k emulator is now active
497     li r0,MODE_68K
498     stw r0,XLM_RUN_MODE(0)
499    
500     // Jump to ROM
501     bctr
502    
503    
504     /*
505     * void execute_68k(uint32 pc {r3}, M68kRegisters *r {r4}) - Execute 68k routine
506     */
507    
508     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(execute_68k)
509     C_SYMBOL_NAME(execute_68k):
510     // Create MacOS stack frame
511     mflr r0
512     stw r0,4(r1)
513     stwu r1,-(56+19*4+18*8)(r1)
514     mfcr r0
515     stw r4,48(r1) // save pointer to M68kRegisters for EXEC_RETURN
516     stw r0,52(r1) // save CR
517    
518     // Save PowerPC registers
519     stmw r13,56(r1)
520     #if SAVE_FP_EXEC_68K
521     stfd f14,56+19*4+0*8(r1)
522     stfd f15,56+19*4+1*8(r1)
523     stfd f16,56+19*4+2*8(r1)
524     stfd f17,56+19*4+3*8(r1)
525     stfd f18,56+19*4+4*8(r1)
526     stfd f19,56+19*4+5*8(r1)
527     stfd f20,56+19*4+6*8(r1)
528     stfd f21,56+19*4+7*8(r1)
529     stfd f22,56+19*4+8*8(r1)
530     stfd f23,56+19*4+9*8(r1)
531     stfd f24,56+19*4+10*8(r1)
532     stfd f25,56+19*4+11*8(r1)
533     stfd f26,56+19*4+12*8(r1)
534     stfd f27,56+19*4+13*8(r1)
535     stfd f28,56+19*4+14*8(r1)
536     stfd f29,56+19*4+15*8(r1)
537     stfd f30,56+19*4+16*8(r1)
538     stfd f31,56+19*4+17*8(r1)
539     #endif
540    
541     // Set up registers for 68k emulator
542     lwz r31,XLM_KERNEL_DATA(0) // Pointer to Kernel Data
543     addi r31,r31,0x1000
544     li r0,0
545     mtcrf 0xff,r0
546     creqv 11,11,11 // Supervisor mode
547     lwz r8,0*4(r4) // d[0]..d[7]
548     lwz r9,1*4(r4)
549     lwz r10,2*4(r4)
550     lwz r11,3*4(r4)
551     lwz r12,4*4(r4)
552     lwz r13,5*4(r4)
553     lwz r14,6*4(r4)
554     lwz r15,7*4(r4)
555     lwz r16,8*4(r4) // a[0]..a[6]
556     lwz r17,9*4(r4)
557     lwz r18,10*4(r4)
558     lwz r19,11*4(r4)
559     lwz r20,12*4(r4)
560     lwz r21,13*4(r4)
561     lwz r22,14*4(r4)
562     li r23,0
563     mr r24,r3
564     lwz r25,XLM_68K_R25(0) // MSB of SR
565     li r26,0
566     li r28,0 // VBR
567     lwz r29,0x74(r31) // Pointer to opcode table
568     lwz r30,0x78(r31) // Address of emulator
569    
570     // Push return address (points to EXEC_RETURN opcode) on stack
571     li r0,XLM_EXEC_RETURN_OPCODE
572     stwu r0,-4(r1)
573    
574     // Reentering 68k emulator
575     li r0,MODE_68K
576     stw r0,XLM_RUN_MODE(0)
577    
578     // Set r0 to 0 for 68k emulator
579     li r0,0
580    
581     // Execute 68k opcode
582     lha r27,0(r24)
583     rlwimi r29,r27,3,13,28
584     lhau r27,2(r24)
585     mtlr r29
586     blr
587    
588    
589     /*
590     * uint32 call_macos1(uint32 tvect{r3}, uint32 arg1{r4}) ... - Call MacOS routines
591     */
592    
593     ASM_MACRO_START prolog
594     mflr r0
595     stw r0,4(r1)
596     stwu r1,-64(r1)
597     ASM_MACRO_END
598    
599     ASM_MACRO_START epilog
600     lwz r0,64+4(r1)
601     mtlr r0
602     addi r1,r1,64
603 gbeauche 1.4 RESTORE_SYSTEM_R2
604     RESTORE_SYSTEM_R13
605 gbeauche 1.1 blr
606     ASM_MACRO_END
607    
608     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos)
609     C_SYMBOL_NAME(call_macos):
610     prolog
611     lwz r0,0(r3) // Get routine address
612     lwz r2,4(r3) // Load TOC pointer
613     mtctr r0
614     bctrl
615     epilog
616    
617     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos1)
618     C_SYMBOL_NAME(call_macos1):
619     prolog
620     lwz r0,0(r3) // Get routine address
621     lwz r2,4(r3) // Load TOC pointer
622     mtctr r0
623     mr r3,r4
624     bctrl
625     epilog
626    
627     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos2)
628     C_SYMBOL_NAME(call_macos2):
629     prolog
630     lwz r0,0(r3) // Get routine address
631     lwz r2,4(r3) // Load TOC pointer
632     mtctr r0
633     mr r3,r4
634     mr r4,r5
635     bctrl
636     epilog
637    
638     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos3)
639     C_SYMBOL_NAME(call_macos3):
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     bctrl
648     epilog
649    
650     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos4)
651     C_SYMBOL_NAME(call_macos4):
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     bctrl
661     epilog
662    
663     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos5)
664     C_SYMBOL_NAME(call_macos5):
665     prolog
666     lwz r0,0(r3) // Get routine address
667     lwz r2,4(r3) // Load TOC pointer
668     mtctr r0
669     mr r3,r4
670     mr r4,r5
671     mr r5,r6
672     mr r6,r7
673     mr r7,r8
674     bctrl
675     epilog
676    
677     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos6)
678     C_SYMBOL_NAME(call_macos6):
679     prolog
680     lwz r0,0(r3) // Get routine address
681     lwz r2,4(r3) // Load TOC pointer
682     mtctr r0
683     mr r3,r4
684     mr r4,r5
685     mr r5,r6
686     mr r6,r7
687     mr r7,r8
688     mr r8,r9
689     bctrl
690     epilog
691    
692     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(call_macos7)
693     C_SYMBOL_NAME(call_macos7):
694     prolog
695     lwz r0,0(r3) // Get routine address
696     lwz r2,4(r3) // Load TOC pointer
697     mtctr r0
698     mr r3,r4
699     mr r4,r5
700     mr r5,r6
701     mr r6,r7
702     mr r7,r8
703     mr r8,r9
704     mr r9,r10
705     bctrl
706     epilog
707    
708    
709     /*
710     * Native resource manager patches
711     */
712    
713 gbeauche 1.5 ASM_MACRO_START do_get_resource ASM_MACRO_ARG0_DEF
714 gbeauche 1.1 // Create stack frame
715     mflr r0
716     stw r0,8(r1)
717     stwu r1,-(56+12)(r1)
718    
719     // Save type/ID
720     stw r3,56(r1)
721     stw r4,56+4(r1)
722    
723     // Call old routine
724 gbeauche 1.5 lwz r0,ASM_MACRO_ARG0(0)
725 gbeauche 1.1 lwz r2,XLM_RES_LIB_TOC(0)
726     mtctr r0
727     bctrl
728     stw r3,56+8(r1) // Save handle
729    
730     // Call CheckLoad
731 gbeauche 1.4 RESTORE_SYSTEM_R2
732     RESTORE_SYSTEM_R13
733 gbeauche 1.1 lwz r3,56(r1)
734     lha r4,56+6(r1)
735     lwz r5,56+8(r1)
736     bl C_SYMBOL_NAME(check_load_invoc)
737     lwz r3,56+8(r1) // Restore handle
738    
739     // Return to caller
740     lwz r0,56+12+8(r1)
741     mtlr r0
742     addi r1,r1,56+12
743     blr
744 gbeauche 1.4 ASM_MACRO_END
745    
746     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_resource)
747     C_SYMBOL_NAME(get_resource):
748     do_get_resource XLM_GET_RESOURCE
749 gbeauche 1.1
750     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_1_resource)
751     C_SYMBOL_NAME(get_1_resource):
752 gbeauche 1.4 do_get_resource XLM_GET_1_RESOURCE
753 gbeauche 1.1
754     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_ind_resource)
755     C_SYMBOL_NAME(get_ind_resource):
756 gbeauche 1.4 do_get_resource XLM_GET_IND_RESOURCE
757 gbeauche 1.1
758     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(get_1_ind_resource)
759     C_SYMBOL_NAME(get_1_ind_resource):
760 gbeauche 1.4 do_get_resource XLM_GET_1_IND_RESOURCE
761 gbeauche 1.1
762     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(r_get_resource)
763     C_SYMBOL_NAME(r_get_resource):
764 gbeauche 1.4 do_get_resource XLM_R_GET_RESOURCE
765 gbeauche 1.1
766    
767     /*
768     * void ppc_interrupt(uint32 entry{r3}, uint32 kernel_data{r4}) - Execute PPC interrupt
769     */
770    
771     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(ppc_interrupt)
772     C_SYMBOL_NAME(ppc_interrupt):
773     mflr r0
774     stw r0,4(r1)
775     stwu r1,-64(r1)
776    
777     // Get address of return routine
778     bl 1f
779    
780     // Return routine
781     lwz r0,64+4(r1)
782     mtlr r0
783     addi r1,r1,64
784     blr
785    
786     // Prepare registers for nanokernel interrupt routine
787     1: mtctr r1
788     mr r1,r4
789     stw r6,0x018(r1)
790     mfctr r6
791     stw r6,0x004(r1)
792     lwz r6,0x65c(r1)
793     stw r7,0x13c(r6)
794     stw r8,0x144(r6)
795     stw r9,0x14c(r6)
796     stw r10,0x154(r6)
797     stw r11,0x15c(r6)
798     stw r12,0x164(r6)
799     stw r13,0x16c(r6)
800    
801     mflr r10
802     mfcr r13
803     lwz r7,0x660(r1)
804     mflr r12
805     rlwimi. r7,r7,8,0,0
806     li r11,0
807     ori r11,r11,0xf072 // MSR (SRR1)
808     mtcrf 0x70,r11
809     li r8,0
810    
811     // Enter nanokernel
812     mtlr r3
813     blr
814 gbeauche 1.7
815    
816     /*
817     * Define signal handlers with alternate stack initialization magic
818     */
819    
820     #define SIG_STACK_SIZE 0x10000
821    
822     ASM_MACRO_START do_define_signal_handler \
823     ASM_MACRO_ARG0_DEF /* name */ \
824     ASM_MACRO_ARG1_DEF /* stack */ \
825     ASM_MACRO_ARG2_DEF /* stack id */ \
826     ASM_MACRO_ARG3_DEF /* signal handler */
827    
828     // Alternate stack lower base for this signal handler
829     .lcomm ASM_MACRO_ARG1,SIG_STACK_SIZE,ASM_ALIGN_2(4)
830     ASM_TYPE(ASM_MACRO_ARG1,@object)
831    
832     // Represents the current nest level for this signal handler
833     // Note that in SheepShaver, SIGUSR2 signals are blocked while
834     // handling other signals so, it's unlikely we ever get a nest
835     // level greater than 1
836     .lcomm ASM_MACRO_ARG2,4,ASM_ALIGN_2(2)
837     ASM_TYPE(ASM_MACRO_ARG2,@object)
838    
839     ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(ASM_MACRO_ARG0)
840     C_SYMBOL_NAME(ASM_MACRO_ARG0):
841     // Preserve args in scratch registers
842     mflr r14
843     mr r15,r3
844     mr r16,r4
845     mr r17,r5
846     mr r18,r1
847    
848     // Atomically increase stack_id
849     lis r19,ASM_HA16(ASM_MACRO_ARG2)
850     la r19,ASM_LO16(ASM_MACRO_ARG2,r19)
851     li r4,1
852     mr r3,r19
853     bl C_SYMBOL_NAME(atomic_add)
854     cmpwi r3,0
855     bne- 1f
856    
857     // ID was 0, we can use the local stack
858     lis r9,ASM_HA16(ASM_MACRO_ARG1)
859     lis r3,(SIG_STACK_SIZE>>16)
860     la r9,ASM_LO16(ASM_MACRO_ARG1,r9)
861     addi r3,r3,((SIG_STACK_SIZE&0xffff)-64)
862     add r1,r9,r3
863    
864     1: // Invoke signal handler
865     stwu r1,-16(r1)
866     mr r3,r15
867     mr r4,r16
868     mr r5,r17
869     bl C_SYMBOL_NAME(ASM_MACRO_ARG3)
870     addi r1,r1,16
871    
872     // Atomically decrease stack id
873     mr r3,r19
874     li r4,-1
875     bl C_SYMBOL_NAME(atomic_add)
876    
877     // Restore kernel stack and return
878     mtlr r14
879     mr r1,r18
880     blr
881     ASM_MACRO_END
882    
883     #define DEFINE_SIGNAL_HANDLER(NAME) \
884     do_define_signal_handler \
885     NAME##_handler_init ASM_MACRO_ARG_SEP \
886     NAME##_stack ASM_MACRO_ARG_SEP \
887     NAME##_stack_id ASM_MACRO_ARG_SEP \
888     NAME##_handler
889    
890     DEFINE_SIGNAL_HANDLER(sigusr2)