Annotation of sys/arch/mvmeppc/mvmeppc/locore.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: locore.S,v 1.12 2005/11/24 12:08:16 pedro Exp $ */
2: /* $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws Exp $ */
3:
4: /*
5: * Copyright (C) 1995, 1996 Wolfgang Solfrank.
6: * Copyright (C) 1995, 1996 TooLs GmbH.
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. All advertising materials mentioning features or use of this software
18: * must display the following acknowledgement:
19: * This product includes software developed by TooLs GmbH.
20: * 4. The name of TooLs GmbH may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26: * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33: */
34:
35: #include "assym.h"
36:
37: #include <sys/syscall.h>
38:
39: #include <machine/asm.h>
40: #include <machine/param.h>
41: #include <machine/pmap.h>
42: #include <machine/psl.h>
43: #include <machine/trap.h>
44:
45: /*
46: * Globals
47: */
48: .globl _C_LABEL(esym),_C_LABEL(proc0paddr)
49: .type _C_LABEL(esym),@object
50: .type _C_LABEL(proc0paddr),@object
51: .data
52: _C_LABEL(esym): .long 0 /* end of symbol table */
53: _C_LABEL(proc0paddr): .long 0 /* proc0 p_addr */
54: idle_u: .long 0 /* fake uarea during idle after exit */
55:
56: /*
57: * Startup entry
58: */
59: _ENTRY(_C_LABEL(kernel_text))
60: _ENTRY(_ASM_LABEL(start))
61: /*
62: * Arguments to start for mvmeppc
63: * r1 - stack provided by firmware/bootloader
64: * r3 - boot flags
65: * r4 - boot device
66: * r5 - firmware pointer (NULL for PPC1bug)
67: * r6 - arg list (NULL)
68: * r7 - length (0)
69: * r8 - end of symbol table
70: */
71: .globl start
72: .type start,@function
73: start:
74: li %r0,0
75: mtmsr %r0 /* Disable FPU/MMU/exceptions */
76: isync
77:
78: /* save boot device and flags */
79: lis %r9, _C_LABEL(boothowto)@ha
80: stw %r3, _C_LABEL(boothowto)@l(%r9)
81: lis %r9, _C_LABEL(bootdev)@ha
82: stw %r4, _C_LABEL(bootdev)@l(%r9)
83:
84: /* compute end of kernel memory */
85: #if defined(DDB)
86: lis %r9,_C_LABEL(esym)@ha
87: stw %r8,_C_LABEL(esym)@l(%r9) /* save for symbol handling */
88: #else
89: lis %r8,_end@ha
90: addi %r8,%r8,_end@l
91: #endif
92: li %r9,PGOFSET
93: add %r8,%r8,%r9
94: andc %r8,%r8,%r9
95: lis %r9,idle_u@ha
96: stw %r8,idle_u@l(%r9)
97: addi %r8,%r8,USPACE /* space for idle_u */
98: lis %r9,_C_LABEL(proc0paddr)@ha
99: stw %r8,_C_LABEL(proc0paddr)@l(%r9)
100: addi %r1,%r8,USPACE-FRAMELEN /* stackpointer for proc0 */
101: mr %r4,%r1 /* end of mem reserved for kernel */
102: li %r0,0
103: stwu %r0,-16(%r1) /* end of stack chain */
104:
105: lis %r3,start@ha
106: addi %r3,%r3,start@l
107: mr %r5,%r6 /* args string */
108: bl _C_LABEL(initppc)
109: bl _C_LABEL(main)
110: b _C_LABEL(PPC1_exit)
111:
112: /*
113: * No processes are runnable, so loop waiting for one.
114: * Separate label here for accounting purposes.
115: */
116: _C_LABEL(idle):
117: mfmsr %r3
118: /* disable interrupts while manipulating runque */
119: andi. %r3,%r3,~PSL_EE@l
120: mtmsr %r3
121:
122: lis %r8,_C_LABEL(whichqs)@ha
123: lwz %r9,_C_LABEL(whichqs)@l(%r8)
124:
125: or. %r9,%r9,%r9
126: bne- _C_LABEL(sw1) /* at least one queue non-empty */
127:
128: ori %r3,%r3,PSL_EE /* reenable ints again */
129: mtmsr %r3
130: isync
131: sync
132: /* low power mode */
133: mfmsr %r3
134: oris %r3, %r3, PSL_POW@h
135: mtmsr %r3
136: isync
137:
138: /* May do some power saving here? */
139:
140: b _C_LABEL(idle)
141:
142: /*
143: * switchexit gets called from cpu_exit to free the user structure
144: * and kernel stack of the current process.
145: */
146: _ENTRY(_C_LABEL(switchexit))
147: /* First switch to the idle pcb/kernel stack */
148: lis %r6,idle_u@ha
149: lwz %r6,idle_u@l(%r6)
150: lis %r7,_C_LABEL(curpcb)@ha
151: stw %r6,_C_LABEL(curpcb)@l(%r7)
152: addi %r1,%r6,USPACE-16 /* 16 bytes are reserved at stack top */
153: /*
154: * Schedule the vmspace and stack to be freed (the proc arg is
155: * already in r3).
156: */
157: bl _C_LABEL(exit2)
158:
159: /* Fall through to cpu_switch to actually select another proc */
160: li %r3,0 /* indicate exited process */
161:
162: /* Fall through to cpu_switch to actually select another proc */
163:
164: /*
165: * void cpu_switch(struct proc *p)
166: * Find a runnable process and switch to it.
167: */
168: _ENTRY(_C_LABEL(cpu_switch))
169: mflr %r0 /* save lr */
170: stw %r0,4(%r1)
171: stwu %r1,-16(%r1)
172: stw %r31,12(%r1)
173: stw %r30,8(%r1)
174:
175: mr %r30,%r3
176: lis %r3,_C_LABEL(curproc)@ha
177: li %r31,0
178: /* Zero to not accumulate cpu time */
179: stw %r31,_C_LABEL(curproc)@l(%r3)
180: lis %r3,_C_LABEL(curpcb)@ha
181: lwz %r31,_C_LABEL(curpcb)@l(%r3)
182:
183: li %r3,0
184: bl _C_LABEL(lcsplx)
185: stw %r3,PCB_SPL(%r31) /* save spl */
186:
187: /* Find a new process */
188: mfmsr %r3
189: andi. %r3,%r3,~PSL_EE@l /* disable interrupts while
190: manipulating runque */
191: mtmsr %r3
192: isync
193:
194: lis %r8,_C_LABEL(whichqs)@ha
195: lwz %r9,_C_LABEL(whichqs)@l(%r8)
196:
197: or. %r9,%r9,%r9
198: beq- _C_LABEL(idle) /* all queues empty */
199: _C_LABEL(sw1):
200: cntlzw %r10,%r9
201: lis %r4,_C_LABEL(qs)@ha
202: addi %r4,%r4,_C_LABEL(qs)@l
203: slwi %r3,%r10,3
204: add %r3,%r3,%r4 /* select queue */
205:
206: lwz %r31,P_FORW(%r3) /* unlink first proc from queue */
207: lwz %r4,P_FORW(%r31)
208: stw %r4,P_FORW(%r3)
209: stw %r3,P_BACK(%r4)
210:
211: cmpl 0,%r3,%r4 /* queue empty? */
212: bne 1f
213:
214: lis %r3,0x80000000@ha
215: srw %r3,%r3,%r10
216: andc %r9,%r9,%r3
217: stw %r9,_C_LABEL(whichqs)@l(%r8) /* mark it empty */
218:
219: 1:
220: /* just did this resched thing, clear resched */
221: li %r3,0
222: lis %r4,_C_LABEL(want_resched)@ha
223: stw %r3,_C_LABEL(want_resched)@l(%r4)
224:
225: stw %r3,P_BACK(%r31) /* probably superfluous */
226:
227: lis %r4,_C_LABEL(curproc)@ha
228: stw %r31,_C_LABEL(curproc)@l(%r4) /* record new process */
229:
230: li %r3,SONPROC
231: stb %r3,P_STAT(%r31)
232:
233: mfmsr %r3
234: ori %r3,%r3,PSL_EE /* Now we can interrupt again */
235: mtmsr %r3
236:
237: cmpl 0,%r31,%r30 /* is it the same process? */
238: beq switch_return
239:
240: or. %r30,%r30,%r30 /* old process was exiting? */
241: beq switch_exited
242:
243: mfsr %r10,PPC_USER_SR /* save PPC_USER_SR for copyin/copyout*/
244: mfcr %r11 /* save cr */
245: mr %r12,%r2 /* save r2 */
246: stwu %r1,-SFRAMELEN(%r1) /* still running on old stack */
247: stmw %r10,8(%r1)
248: lwz %r3,P_ADDR(%r30)
249: stw %r1,PCB_SP(%r3) /* save SP */
250:
251: switch_exited:
252: /* disable interrupts while actually switching */
253: mfmsr %r3
254: andi. %r3,%r3,~PSL_EE@l
255: mtmsr %r3
256:
257: lwz %r4,P_ADDR(%r31)
258: lis %r5,_C_LABEL(curpcb)@ha
259: stw %r4,_C_LABEL(curpcb)@l(%r5) /* indicate new pcb */
260:
261: lwz %r5,PCB_PMR(%r4)
262:
263: /* save real pmap pointer for spill fill */
264: lis %r6,_C_LABEL(curpm)@ha
265: stwu %r5,_C_LABEL(curpm)@l(%r6)
266: stwcx. %r5,%r0,%r6 /* clear possible reservation */
267:
268: addic. %r5,%r5,64
269: li %r6,0
270: mfsr %r8,PPC_KERNEL_SR /* save kernel SR */
271: 1:
272: addis %r6,%r6,-0x10000000@ha /* set new procs segment registers */
273: or. %r6,%r6,%r6 /* This is done from the real address pmap */
274: lwzu %r7,-4(%r5) /* so we don't have to worry */
275: mtsrin %r7,%r6 /* about accessibility */
276: bne 1b
277: mtsr PPC_KERNEL_SR,%r8 /* restore kernel SR */
278: isync
279:
280: lwz %r1,PCB_SP(%r4) /* get new procs SP */
281:
282: ori %r3,%r3,PSL_EE /* interrupts are okay again */
283: mtmsr %r3
284:
285: lmw %r10,8(%r1) /* get other regs */
286: lwz %r1,0(%r1) /* get saved SP */
287: mr %r2,%r12 /* get saved r2 */
288: mtcr %r11 /* get saved cr */
289: isync
290: mtsr PPC_USER_SR,%r10 /* get saved PPC_USER_SR */
291: isync
292:
293: switch_return:
294: mr %r30,%r7 /* save proc pointer */
295: lwz %r3,PCB_SPL(%r4)
296: bl _C_LABEL(lcsplx)
297:
298: mr %r3,%r30 /* curproc for special fork returns */
299:
300: lwz %r31,12(%r1)
301: lwz %r30,8(%r1)
302: addi %r1,%r1,16
303: lwz %r0,4(%r1)
304: mtlr %r0
305: blr
306:
307:
308: /*
309: * Data used during primary/secondary traps/interrupts
310: */
311: #define tempsave 0x2e0 /* primary save area for trap handling */
312: #define disisave 0x3e0 /* primary save area for dsi/isi traps */
313: #define INTSTK (8*1024) /* 8K interrupt stack */
314: .data
315: intstk: .space INTSTK /* interrupt stack */
316: .global _C_LABEL(intr_depth)
317: .type _C_LABEL(intr_depth),@object
318: _C_LABEL(intr_depth):
319: .long -1 /* in-use marker */
320: #define SPILLSTK 1024 /* 1K spill stack */
321: .lcomm spillstk,SPILLSTK,8
322:
323: /*
324: * This code gets copied to all the trap vectors
325: * except ISI/DSI, ALI, and the interrupts
326: */
327: .text
328: .globl _C_LABEL(trapcode),_C_LABEL(trapsize)
329: .type _C_LABEL(trapcode),@function
330: .type _C_LABEL(trapsize),@object
331: _C_LABEL(trapcode):
332: mtsprg 1,%r1 /* save SP */
333: stmw %r28,tempsave(%r0) /* free r28-r31 */
334: mflr %r28 /* save LR */
335: mfcr %r29 /* save CR */
336:
337: /* Test whether we already had PR set */
338: mfsrr1 %r31
339: mtcr %r31
340: bc 4,17,1f /* branch if PSL_PR is clear */
341: lis %r1,_C_LABEL(curpcb)@ha
342: lwz %r1,_C_LABEL(curpcb)@l(%r1)
343: addi %r1,%r1,USPACE /* stack is top of user struct */
344: 1:
345: bla s_trap
346: _C_LABEL(trapsize) = .-_C_LABEL(trapcode)
347:
348: /*
349: * For ALI: has to save DSISR and DAR
350: */
351: .globl _C_LABEL(alitrap),_C_LABEL(alisize)
352: _C_LABEL(alitrap):
353: mtsprg 1,%r1 /* save SP */
354: stmw %r28,tempsave(0) /* free r28-r31 */
355: mfdar %r30
356: mfdsisr %r31
357: stmw %r30,tempsave+16(0)
358: mflr %r28 /* save LR */
359: mfcr %r29 /* save CR */
360:
361: /* Test whether we already had PR set */
362: mfsrr1 %r31
363: mtcr %r31
364: bc 4,17,1f /* branch if PSL_PR is clear */
365: lis %r1,_C_LABEL(curpcb)@ha
366: lwz %r1,_C_LABEL(curpcb)@l(%r1)
367: addi %r1,%r1,USPACE /* stack is top of user struct */
368: 1:
369: bla s_trap
370: _C_LABEL(alisize) = .-_C_LABEL(alitrap)
371:
372: /*
373: * Similar to the above for DSI
374: * Has to handle BAT spills
375: * and standard pagetable spills
376: */
377: .globl _C_LABEL(dsitrap),_C_LABEL(dsisize)
378: .type _C_LABEL(dsitrap),@function
379: .type _C_LABEL(dsisize),@object
380: _C_LABEL(dsitrap):
381: stmw %r28,disisave(0) /* free r28-r31 */
382: mfcr %r29 /* save CR */
383: mfxer %r30 /* save XER */
384: mtsprg 2,%r30 /* in SPRG2 */
385: mfsrr1 %r31 /* test kernel mode */
386: #if 0
387: mtcr %r31
388: bc 12,17,1f /* branch if PSL_PR is set */
389: mfdar %r31 /* get fault address */
390: rlwinm %r31,%r31,7,25,28 /* get segment * 8 */
391: addis %r31,%r31,_C_LABEL(battable)@ha
392: lwz %r30,_C_LABEL(battable)@l(%r31) /* get batu */
393: mtcr %r30
394: bc 4,30,1f /* branch if supervisor valid is false */
395: lwz %r31,_C_LABEL(battable)+4@l(%r31) /* get batl */
396: /* We randomly use the highest two bat registers here */
397: mftb %r28
398: andi. %r28,%r28,1
399: bne 2f
400: mtdbatu 2,%r30
401: mtdbatl 2,%r31
402: b 3f
403: 2:
404: mtdbatu 3,%r30
405: mtdbatl 3,%r31
406: 3:
407: mfsprg %r30,2 /* restore XER */
408: mtxer %r30
409: mtcr %r29 /* restore CR */
410: lmw %r28,disisave(0) /* restore r28-r31 */
411: rfi /* return to trapped code */
412: 1:
413: #endif
414: mflr %r28 /* save LR */
415: bla s_dsitrap
416: _C_LABEL(dsisize) = .-_C_LABEL(dsitrap)
417:
418: /*
419: * Similar to the above for ISI
420: */
421: .globl _C_LABEL(isitrap),_C_LABEL(isisize)
422: .type _C_LABEL(isitrap),@function
423: .type _C_LABEL(isisize),@object
424: _C_LABEL(isitrap):
425: stmw %r28,disisave(0) /* free r28-r31 */
426: mflr %r28 /* save LR */
427: mfcr %r29 /* save CR */
428: mfsrr1 %r31 /* test kernel mode */
429: #if 0
430: mtcr %r31
431: bc 12,17,1f /* branch if PSL_PR is set */
432: mfsrr0 %r31 /* get fault address */
433: rlwinm %r31,%r31,7,25,28 /* get segment * 8 */
434: addis %r31,%r31,_C_LABEL(battable)@ha
435: lwz %r30,_C_LABEL(battable)@l(%r31) /* get batu */
436: mtcr %r30
437: bc 4,30,1f /* branch if supervisor valid is false */
438: mtibatu 3,%r30
439: lwz %r30,_C_LABEL(battable)+4@l(%r31) /* get batl */
440: mtibatl 3,%r30
441: mtcr %r29 /* restore CR */
442: lmw %r28,disisave(0) /* restore r28-r31 */
443: rfi /* return to trapped code */
444: 1:
445: #endif
446: bla s_isitrap
447: _C_LABEL(isisize) = .-_C_LABEL(isitrap)
448:
449: /*
450: * This one for the external interrupt handler.
451: */
452: .globl _C_LABEL(extint),_C_LABEL(extsize)
453: .type _C_LABEL(extint),@function
454: .type _C_LABEL(extsize),@object
455: _C_LABEL(extint):
456: mtsprg 1,%r1 /* save SP */
457: stmw %r28,tempsave(0) /* free r28-r31 */
458: mflr %r28 /* save LR */
459: mfcr %r29 /* save CR */
460: mfxer %r30 /* save XER */
461: lis %r1,intstk+INTSTK@ha /* get interrupt stack */
462: addi %r1,%r1,intstk+INTSTK@l
463: lwz %r31,0(%r1) /* were we already running on intstk? */
464: addic. %r31,%r31,%r1
465: stw %r31,0(%r1)
466: beq 1f
467: mfsprg %r1,1 /* yes, get old SP */
468: 1:
469: ba extintr
470: _C_LABEL(extsize) = .-_C_LABEL(extint)
471:
472: /*
473: * And this one for the decrementer interrupt handler.
474: */
475: .globl _C_LABEL(decrint),_C_LABEL(decrsize)
476: .type _C_LABEL(decrint),@function
477: .type _C_LABEL(decrsize),@object
478: _C_LABEL(decrint):
479: mtsprg 1,%r1 /* save SP */
480: stmw %r28,tempsave(0) /* free r28-r31 */
481: mflr %r28 /* save LR */
482: mfcr %r29 /* save CR */
483: mfxer %r30 /* save XER */
484: lis %r1,intstk+INTSTK@ha /* get interrupt stack */
485: addi %r1,%r1,intstk+INTSTK@l
486: lwz %r31,0(%r1) /* were we already running on intstk? */
487: addic. %r31,%r31,%r1
488: stw %r31,0(%r1)
489: beq 1f
490: mfsprg %r1,1 /* yes, get old SP */
491: 1:
492: ba decrintr
493: _C_LABEL(decrsize) = .-_C_LABEL(decrint)
494:
495: /*
496: * Now the tlb software load for 603 processors:
497: * (Code essentially from the 603e User Manual, Chapter 5)
498: */
499: #define DMISS 976
500: #define DCMP 977
501: #define HASH1 978
502: #define HASH2 979
503: #define IMISS 980
504: #define ICMP 981
505: #define RPA 982
506:
507: #define bdneq bdnzf 2,
508: #define tlbli .long 0x7c0007e4+0x800*
509: #define tlbld .long 0x7c0007a4+0x800*
510:
511: .globl _C_LABEL(tlbimiss),_C_LABEL(tlbimsize)
512: .type _C_LABEL(tlbimiss),@function
513: .type _C_LABEL(tlbimsize),@object
514: _C_LABEL(tlbimiss):
515: mfspr %r2,HASH1 /* get first pointer */
516: li %r1,8
517: mfctr %r0 /* save counter */
518: mfspr %r3,ICMP /* get first compare value */
519: addi %r2,%r2,-8 /* predec pointer */
520: 1:
521: mtctr %r1 /* load counter */
522: 2:
523: lwzu %r1,8(%r2) /* get next pte */
524: cmpl 0,%r1,%r3 /* see if found pte */
525: bdneq 2b /* loop if not eq */
526: bne 3f /* not found */
527: lwz %r1,4(%r2) /* load tlb entry lower word */
528: andi. %r3,%r1,8 /* check G-bit */
529: bne 4f /* if guarded, take ISI */
530: mtctr %r0 /* restore counter */
531: mfspr %r0,IMISS /* get the miss address for the tlbli */
532: mfsrr1 %r3 /* get the saved cr0 bits */
533: mtcrf 0x80,%r3 /* and restore */
534: ori %r1,%r1,0x100 /* set the reference bit */
535: mtspr RPA,%r1 /* set the pte */
536: srwi %r1,%r1,8 /* get byte 7 of pte */
537: tlbli 0 /* load the itlb */
538: stb %r1,6(%r2) /* update page table */
539: rfi
540:
541: 3: /* not found in pteg */
542: andi. %r1,%r3,0x40 /* have we already done second hash? */
543: bne 5f
544: mfspr %r2,HASH2 /* get the second pointer */
545: ori %r3,%r3,0x40 /* change the compare value */
546: li %r1,8
547: addi %r2,%r2,-8 /* predec pointer */
548: b 1b
549: 4: /* guarded */
550: mfsrr1 %r3
551: andi. %r2,%r3,0xffff /* clean upper srr1 */
552: addis %r2,%r2,0x800 /* set srr<4> to flag prot violation */
553: b 6f
554: 5: /* not found anywhere */
555: mfsrr1 %r3
556: andi. %r2,%r3,0xffff /* clean upper srr1 */
557: addis %r2,%r2,0x4000 /* set srr1<1> to flag pte not found */
558: 6:
559: mtctr %r0 /* restore counter */
560: mtsrr1 %r2
561: mfmsr %r0
562: xoris %r0,%r0,2 /* flip the msr<tgpr> bit */
563: mtcrf 0x80,%r3 /* restore cr0 */
564: mtmsr %r0 /* now with native gprs */
565: isync
566: ba EXC_ISI
567: _C_LABEL(tlbimsize) = .-_C_LABEL(tlbimiss)
568:
569: .globl _C_LABEL(tlbdlmiss),_C_LABEL(tlbdlmsize)
570: .type _C_LABEL(tlbdlmiss),@function
571: .type _C_LABEL(tlbdlmsize),@object
572: _C_LABEL(tlbdlmiss):
573: mfspr %r2,HASH1 /* get first pointer */
574: li %r1,8
575: mfctr %r0 /* save counter */
576: mfspr %r3,DCMP /* get first compare value */
577: addi %r2,%r2,-8 /* predec pointer */
578: 1:
579: mtctr %r1 /* load counter */
580: 2:
581: lwzu %r1,8(%r2) /* get next pte */
582: cmpl 0,%r1,%r3 /* see if found pte */
583: bdneq 2b /* loop if not eq */
584: bne 3f /* not found */
585: lwz %r1,4(%r2) /* load tlb entry lower word */
586: mtctr %r0 /* restore counter */
587: mfspr %r0,DMISS /* get the miss address for the tlbld */
588: mfsrr1 %r3 /* get the saved cr0 bits */
589: mtcrf 0x80,%r3 /* and restore */
590: ori %r1,%r1,0x100 /* set the reference bit */
591: mtspr RPA,%r1 /* set the pte */
592: srwi %r1,%r1,8 /* get byte 7 of pte */
593: tlbld 0 /* load the dtlb */
594: stb %r1,6(%r2) /* update page table */
595: rfi
596:
597: 3: /* not found in pteg */
598: andi. %r1,%r3,0x40 /* have we already done second hash? */
599: bne 5f
600: mfspr %r2,HASH2 /* get the second pointer */
601: ori %r3,%r3,0x40 /* change the compare value */
602: li %r1,8
603: addi %r2,%r2,-8 /* predec pointer */
604: b 1b
605: 5: /* not found anywhere */
606: mfsrr1 %r3
607: lis %r1,0x4000 /* set dsisr<1> to flag pte not found */
608: mtctr %r0 /* restore counter */
609: andi. %r2,%r3,0xffff /* clean upper srr1 */
610: mtsrr1 %r2
611: mtdsisr %r1 /* load the dsisr */
612: mfspr %r1,DMISS /* get the miss address */
613: mtdar %r1 /* put in dar */
614: mfmsr %r0
615: xoris %r0,%r0,2 /* flip the msr<tgpr> bit */
616: mtcrf 0x80,%r3 /* restore cr0 */
617: mtmsr %r0 /* now with native gprs */
618: isync
619: ba EXC_DSI
620: _C_LABEL(tlbdlmsize) = .-_C_LABEL(tlbdlmiss)
621:
622: .globl _C_LABEL(tlbdsmiss),_C_LABEL(tlbdsmsize)
623: .type _C_LABEL(tlbdsmiss),@function
624: .type _C_LABEL(tlbdsmsize),@object
625: _C_LABEL(tlbdsmiss):
626: mfspr %r2,HASH1 /* get first pointer */
627: li %r1,8
628: mfctr %r0 /* save counter */
629: mfspr %r3,DCMP /* get first compare value */
630: addi %r2,%r2,-8 /* predec pointer */
631: 1:
632: mtctr %r1 /* load counter */
633: 2:
634: lwzu %r1,8(%r2) /* get next pte */
635: cmpl 0,%r1,%r3 /* see if found pte */
636: bdneq 2b /* loop if not eq */
637: bne 3f /* not found */
638: lwz %r1,4(%r2) /* load tlb entry lower word */
639: andi. %r3,%r1,0x80 /* check the C-bit */
640: beq 4f
641: 5:
642: mtctr %r0 /* restore counter */
643: mfspr %r0,DMISS /* get the miss address for the tlbld */
644: mfsrr1 %r3 /* get the saved cr0 bits */
645: mtcrf 0x80,%r3 /* and restore */
646: mtspr RPA,%r1 /* set the pte */
647: tlbld 0 /* load the dtlb */
648: rfi
649:
650: 3: /* not found in pteg */
651: andi. %r1,%r3,0x40 /* have we already done second hash? */
652: bne 5f
653: mfspr %r2,HASH2 /* get the second pointer */
654: ori %r3,%r3,0x40 /* change the compare value */
655: li %r1,8
656: addi %r2,%r2,-8 /* predec pointer */
657: b 1b
658: 4: /* found, but C-bit = 0 */
659: rlwinm. %r3,%r1,30,0,1 /* test PP */
660: bge- 7f
661: andi. %r3,%r1,1
662: beq+ 8f
663: 9: /* found, but protection violation (PP==00)*/
664: mfsrr1 %r3
665: lis %r1,0xa00 /* indicate protection violation on store */
666: b 1f
667: 7: /* found, PP=1x */
668: mfspr %r3,DMISS /* get the miss address */
669: mfsrin %r1,%r3 /* get the segment register */
670: mfsrr1 %r3
671: rlwinm %r3,%r3,18,31,31 /* get PR-bit */
672: rlwnm. %r2,%r2,3,1,1 /* get the key */
673: bne- 9b /* protection violation */
674: 8: /* found, set reference/change bits */
675: lwz %r1,4(%r2) /* reload tlb entry */
676: ori %r1,%r1,0x180
677: sth %r1,6(%r2)
678: b 5b
679: 5: /* not found anywhere */
680: mfsrr1 %r3
681: lis %r1,0x4200 /* set dsisr<1> to flag pte not found */
682: /* dsisr<6> to flag store */
683: 1:
684: mtctr %r0 /* restore counter */
685: andi. %r2,%r3,0xffff /* clean upper srr1 */
686: mtsrr1 %r2
687: mtdsisr %r1 /* load the dsisr */
688: mfspr %r1,DMISS /* get the miss address */
689: mtdar %r1 /* put in dar */
690: mfmsr %r0
691: xoris %r0,%r0,2 /* flip the msr<tgpr> bit */
692: mtcrf 0x80,%r3 /* restore cr0 */
693: mtmsr %r0 /* now with native gprs */
694: isync
695: ba EXC_DSI
696: _C_LABEL(tlbdsmsize) = .-_C_LABEL(tlbdsmiss)
697:
698: #ifdef DDB
699: #define ddbsave 0xde0 /* primary save area for DDB */
700: /*
701: * In case of DDB we want a separate trap catcher for it
702: */
703: .local ddbstk
704: .comm ddbstk,INTSTK,8 /* ddb stack */
705:
706: .globl _C_LABEL(ddblow),_C_LABEL(ddbsize)
707: _C_LABEL(ddblow):
708: mtsprg 1,%r1 /* save SP */
709: stmw %r28,ddbsave(0) /* free r28-r31 */
710: mflr %r28 /* save LR */
711: mfcr %r29 /* save CR */
712: lis %r1,ddbstk+INTSTK@ha /* get new SP */
713: addi %r1,%r1,ddbstk+INTSTK@l
714: bla ddbtrap
715: _C_LABEL(ddbsize) = .-_C_LABEL(ddblow)
716: #endif /* DDB */
717:
718:
719: /*
720: * FRAME_SETUP assumes:
721: * SPRG1 SP (1)
722: * savearea r28-r31,DAR,DSISR (DAR & DSISR only for DSI traps)
723: * 28 LR
724: * 29 CR
725: * 1 kernel stack
726: * LR trap type
727: * SRR0/1 as at start of trap
728: */
729: #define FRAME_SETUP(savearea) \
730: /* Have to enable translation to allow access of kernel stack: */ \
731: mfsrr0 %r30; \
732: mfsrr1 %r31; \
733: stmw %r30,savearea+24(0); \
734: mfmsr %r30; \
735: ori %r30,%r30,(PSL_DR|PSL_IR); \
736: mtmsr %r30; \
737: isync; \
738: mfsprg %r31,1; \
739: stwu %r31,-FRAMELEN(%r1); \
740: stw %r0,FRAME_0+8(%r1); \
741: stw %r31,FRAME_1+8(%r1); \
742: stw %r28,FRAME_LR+8(%r1); \
743: stw %r29,FRAME_CR+8(%r1); \
744: lmw %r28,savearea(0); \
745: stmw %r2,FRAME_2+8(%r1); \
746: lmw %r28,savearea+16(0); \
747: mfxer %r3; \
748: mfctr %r4; \
749: mflr %r5; \
750: andi. %r5,%r5,0xff00; \
751: stw %r3,FRAME_XER+8(%r1); \
752: stw %r4,FRAME_CTR+8(%r1); \
753: stw %r5,FRAME_EXC+8(%r1); \
754: stw %r28,FRAME_DAR+8(%r1); \
755: stw %r29,FRAME_DSISR+8(%r1); \
756: stw %r30,FRAME_SRR0+8(%r1); \
757: stw %r31,FRAME_SRR1+8(%r1)
758:
759: #define FRAME_LEAVE(savearea) \
760: /* Now restore regs: */ \
761: lwz %r2,FRAME_SRR0+8(%r1); \
762: lwz %r3,FRAME_SRR1+8(%r1); \
763: lwz %r4,FRAME_CTR+8(%r1); \
764: lwz %r5,FRAME_XER+8(%r1); \
765: lwz %r6,FRAME_LR+8(%r1); \
766: lwz %r7,FRAME_CR+8(%r1); \
767: stw %r2,savearea(0); \
768: stw %r3,savearea+4(0); \
769: mtctr %r4; \
770: mtxer %r5; \
771: mtlr %r6; \
772: mtsprg 1,%r7; /* save cr */ \
773: lmw %r2,FRAME_2+8(%r1); \
774: lwz %r0,FRAME_0+8(%r1); \
775: lwz %r1,FRAME_1+8(%r1); \
776: mtsprg 2,%r2; /* save r2 & r3 */ \
777: mtsprg 3,%r3; \
778: /* Disable translation, machine check and recoverability: */ \
779: mfmsr %r2; \
780: lis %r3,(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@ha; \
781: addi %r3,%r3,(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \
782: andc %r2,%r2,%r3; \
783: mtmsr %r2; \
784: isync; \
785: /* Decide whether we return to user mode: */ \
786: lwz %r3,savearea+4(0); \
787: mtcr %r3; \
788: bc 4,17,1f; /* branch if PSL_PR is false */ \
789: /* Restore user & kernel access SR: */ \
790: lis %r2,_C_LABEL(curpm)@ha; /* get real address of pmap */ \
791: lwz %r2,_C_LABEL(curpm)@l(%r2); \
792: lwz %r3,PM_USRSR(%r2); \
793: mtsr PPC_USER_SR,%r3; \
794: lwz %r3,PM_KERNELSR(%r2); \
795: mtsr PPC_KERNEL_SR,%r3; \
796: 1: mfsprg %r2,1; /* restore cr */ \
797: mtcr %r2; \
798: lwz %r2,savearea(0); \
799: lwz %r3,savearea+4(0); \
800: mtsrr0 %r2; \
801: mtsrr1 %r3; \
802: mfsprg %r2,2; /* restore r2 & r3 */ \
803: mfsprg %r3,3
804:
805: /*
806: * Preamble code for DSI/ISI traps
807: */
808: disitrap:
809: lmw %r30,disisave(0)
810: stmw %r30,tempsave(0)
811: lmw %r30,disisave+8(0)
812: stmw %r30,tempsave+8(0)
813: mfdar %r30
814: mfdsisr %r31
815: stmw %r30,tempsave+16(0)
816: realtrap:
817: /* Test whether we already had PR set */
818: mfsrr1 %r1
819: mtcr %r1
820: /* restore SP (might have been overwritten) */
821: mfsprg %r1,1
822: bc 4,17,s_trap /* branch if PSL_PR is false */
823: lis %r1,_C_LABEL(curpcb)@ha
824: lwz %r1,_C_LABEL(curpcb)@l(%r1)
825: addi %r1,%r1,USPACE /* stack is top of user struct */
826: /*
827: * Now the common trap catching code.
828: */
829: s_trap:
830: /* First have to enable KERNEL mapping */
831: lis %r31,PPC_KERNEL_SEGMENT@ha
832: addi %r31,%r31,PPC_KERNEL_SEGMENT@l
833: mtsr PPC_KERNEL_SR,%r31
834: FRAME_SETUP(tempsave)
835: /* Now we can recover interrupts again: */
836: mfmsr %r7
837: mfsrr1 %r31
838: andi. %r31,%r31,PSL_EE /* restore EE from previous context */
839: or %r7,%r7,%r31
840: ori %r7,%r7,(PSL_ME|PSL_RI)
841: mtmsr %r7
842: isync
843: /* Call C trap code: */
844: trapagain:
845: addi %r3,%r1,8
846: bl _C_LABEL(trap)
847: trapexit:
848: /* Disable interrupts: */
849: mfmsr %r3
850: andi. %r3,%r3,~PSL_EE@l
851: mtmsr %r3
852: /* Test AST pending: */
853: lwz %r5,FRAME_SRR1+8(%r1)
854: mtcr %r5
855: bc 4,17,1f /* branch if PSL_PR is false */
856: lis %r3,_C_LABEL(astpending)@ha
857: lwz %r4,_C_LABEL(astpending)@l(%r3)
858: andi. %r4,%r4,1
859: beq 1f
860: li %r6,EXC_AST
861: stw %r6,FRAME_EXC+8(%r1)
862: b trapagain
863: 1:
864: FRAME_LEAVE(tempsave)
865: rfi
866:
867: /*
868: * Child comes here at the end of a fork.
869: * Mostly similar to the above.
870: */
871: .globl _C_LABEL(fork_trampoline)
872: .type _C_LABEL(fork_trampoline),@function
873: _C_LABEL(fork_trampoline):
874: li %r3,0
875: bl _C_LABEL(lcsplx)
876: mtlr %r31
877: mr %r3,%r30
878: blrl /* jump indirect to r31 */
879: b trapexit
880:
881: /*
882: * DSI second stage fault handler
883: */
884: s_dsitrap:
885: mfdsisr %r31 /* test if this is spill fault */
886: mtcr %r31
887: mtsprg 1,%r1 /* save SP */
888: bc 4,1,disitrap /* branch if table miss is false */
889: lis %r1,spillstk+SPILLSTK@ha
890: addi %r1,%r1,spillstk+SPILLSTK@l /* get spill stack */
891: stwu %r1,-52(%r1)
892: stw %r0,48(%r1) /* save non-volatile registers */
893: stw %r3,44(%r1)
894: stw %r4,40(%r1)
895: stw %r5,36(%r1)
896: stw %r6,32(%r1)
897: stw %r7,28(%r1)
898: stw %r8,24(%r1)
899: stw %r9,20(%r1)
900: stw %r10,16(%r1)
901: stw %r11,12(%r1)
902: stw %r12,8(%r1)
903: mfxer %r30 /* save XER */
904: mtsprg 2,%r30
905: mflr %r30 /* save trap type */
906: mfctr %r31 /* & CTR */
907: mfdar %r3
908: mfsrr1 %r4
909: mfdsisr %r5
910: li %r6, 0
911: s_pte_spill:
912: bl _C_LABEL(pte_spill_r) /* try a spill */
913: cmpwi 0,%r3,0
914: mtctr %r31 /* restore CTR */
915: mtlr %r30 /* and trap type */
916: mfsprg %r31,2 /* get saved XER */
917: mtxer %r31 /* restore XER */
918: lwz %r12,8(%r1) /* restore non-volatile registers */
919: lwz %r11,12(%r1)
920: lwz %r10,16(%r1)
921: lwz %r9,20(%r1)
922: lwz %r8,24(%r1)
923: lwz %r7,28(%r1)
924: lwz %r6,32(%r1)
925: lwz %r5,36(%r1)
926: lwz %r4,40(%r1)
927: lwz %r3,44(%r1)
928: lwz %r0,48(%r1)
929: beq disitrap
930: mfsprg %r1,1 /* restore SP */
931: mtcr %r29 /* restore CR */
932: mtlr %r28 /* restore LR */
933: lmw %r28,disisave(0) /* restore r28-r31 */
934: rfi /* return to trapped code */
935:
936: /*
937: * ISI second stage fault handler
938: */
939: s_isitrap:
940: mfsrr1 %r31 /* test if this may be a spill fault */
941: mtcr %r31
942: mtsprg 1,%r1 /* save SP */
943: bc 4,%r1,disitrap /* branch if table miss is false */
944: lis %r1,spillstk+SPILLSTK@ha
945: addi %r1,%r1,spillstk+SPILLSTK@l /* get spill stack */
946: stwu %r1,-52(%r1)
947: stw %r0,48(%r1) /* save non-volatile registers */
948: stw %r3,44(%r1)
949: stw %r4,40(%r1)
950: stw %r5,36(%r1)
951: stw %r6,32(%r1)
952: stw %r7,28(%r1)
953: stw %r8,24(%r1)
954: stw %r9,20(%r1)
955: stw %r10,16(%r1)
956: stw %r11,12(%r1)
957: stw %r12,8(%r1)
958: mfxer %r30 /* save XER */
959: mtsprg 2,%r30
960: mflr %r30 /* save trap type */
961: mfctr %r31 /* & ctr */
962: mfsrr0 %r3
963: mfsrr1 %r4
964: li %r5, 0
965: li %r6, 1
966: b s_pte_spill /* above */
967:
968: /*
969: * External interrupt second level handler
970: */
971: #define INTRENTER \
972: /* Save non-volatile registers: */ \
973: stwu %r1,-88(%r1); /* temporarily */ \
974: stw %r0,84(%r1); \
975: mfsprg %r0,1; /* get original SP */ \
976: stw %r0,0(%r1); /* and store it */ \
977: stw %r3,80(%r1); \
978: stw %r4,76(%r1); \
979: stw %r5,72(%r1); \
980: stw %r6,68(%r1); \
981: stw %r7,64(%r1); \
982: stw %r8,60(%r1); \
983: stw %r9,56(%r1); \
984: stw %r10,52(%r1); \
985: stw %r11,48(%r1); \
986: stw %r12,44(%r1); \
987: stw %r28,40(%r1); /* saved LR */ \
988: stw %r29,36(%r1); /* saved CR */ \
989: stw %r30,32(%r1); /* saved XER */ \
990: lmw %r28,tempsave(0); /* restore r28-r31 */ \
991: mfctr %r6; \
992: lis %r5,_C_LABEL(intr_depth)@ha; \
993: lwz %r5,_C_LABEL(intr_depth)@l(%r5); \
994: mfsrr0 %r4; \
995: mfsrr1 %r3; \
996: stw %r6,28(%r1); \
997: stw %r5,20(%r1); \
998: stw %r4,12(%r1); \
999: stw %r3,8(%r1); \
1000: /* interrupts are recoverable here, and enable translation */ \
1001: lis %r3,(PPC_KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY)@ha; \
1002: addi %r3,%r3,(PPC_KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY)@l; \
1003: mtsr PPC_KERNEL_SR,%r3; \
1004: mfmsr %r5; \
1005: ori %r5,%r5,(PSL_IR|PSL_DR|PSL_RI); \
1006: mtmsr %r5; \
1007: isync
1008:
1009: .globl _C_LABEL(extint_call)
1010: .type _C_LABEL(extint_call),@function
1011: extintr:
1012: INTRENTER
1013: _C_LABEL(extint_call):
1014: bl _C_LABEL(extint_call) /* to be filled in later */
1015: intr_exit:
1016: /* Disable interrupts (should already be disabled) and MMU here: */
1017: mfmsr %r3
1018: andi. %r3,%r3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l
1019: mtmsr %r3
1020: isync
1021: /* restore possibly overwritten registers: */
1022: lwz %r12,44(%r1)
1023: lwz %r11,48(%r1)
1024: lwz %r10,52(%r1)
1025: lwz %r9,56(%r1)
1026: lwz %r8,60(%r1)
1027: lwz %r7,64(%r1)
1028: lwz %r6,8(%r1)
1029: lwz %r5,12(%r1)
1030: lwz %r4,28(%r1)
1031: lwz %r3,32(%r1)
1032: mtsrr1 %r6
1033: mtsrr0 %r5
1034: mtctr %r4
1035: mtxer %r3
1036: /* Returning to user mode? */
1037: mtcr %r6 /* saved SRR1 */
1038: bc 4,17,1f /* branch if PSL_PR is false */
1039: lis %r3,_C_LABEL(curpm)@ha /* get current pmap real address */
1040: lwz %r3,_C_LABEL(curpm)@l(%r3)
1041: lwz %r3,PM_KERNELSR(%r3)
1042: mtsr PPC_KERNEL_SR,%r3 /* Restore kernel SR */
1043: lis %r3,_C_LABEL(astpending)@ha /* Test AST pending */
1044: lwz %r4,_C_LABEL(astpending)@l(%r3)
1045: andi. %r4,%r4,1
1046: beq 1f
1047: /* Setup for entry to realtrap: */
1048: lwz %r3,0(%r1) /* get saved SP */
1049: mtsprg %r1,3
1050: li %r6,EXC_AST
1051: stmw %r28,tempsave(0) /* establish tempsave again */
1052: mtlr %r6
1053: lwz %r28,40(%r1) /* saved LR */
1054: lwz %r29,36(%r1) /* saved CR */
1055: lwz %r6,68(%r1)
1056: lwz %r5,72(%r1)
1057: lwz %r4,76(%r1)
1058: lwz %r3,80(%r1)
1059: lwz %r0,84(%r1)
1060: lis %r30,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
1061: lwz %r31,_C_LABEL(intr_depth)@l(%r30)
1062: addi %r31,%r31,-1
1063: stw %r31,_C_LABEL(intr_depth)@l(%r30)
1064: b realtrap
1065: 1:
1066: /* Here is the normal exit of extintr: */
1067: lwz %r5,36(%r1)
1068: lwz %r6,40(%r1)
1069: mtcr %r5
1070: mtlr %r6
1071: lwz %r6,68(%r1)
1072: lwz %r5,72(%r1)
1073: lis %r3,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */
1074: lwz %r4,_C_LABEL(intr_depth)@l(%r3)
1075: addi %r4,%r4,-1
1076: stw %r4,_C_LABEL(intr_depth)@l(%r3)
1077: lwz %r4,76(%r1)
1078: lwz %r3,80(%r1)
1079: lwz %r0,84(%r1)
1080: lwz %r1,0(%r1)
1081: rfi
1082:
1083: /*
1084: * Decrementer interrupt second level handler
1085: */
1086: decrintr:
1087: INTRENTER
1088: addi %r3,%r1,8 /* intr frame */
1089: bl _C_LABEL(decr_intr)
1090: b intr_exit
1091:
1092:
1093: /*
1094: * int setfault()
1095: *
1096: * Similar to setjmp to setup for handling faults on accesses to user memory.
1097: * Any routine using this may only call bcopy, either the form below,
1098: * or the (currently used) C code optimized, so it doesn't use any non-volatile
1099: * registers.
1100: */
1101: .globl _C_LABEL(setfault)
1102: .type _C_LABEL(setfault),@function
1103: _C_LABEL(setfault):
1104: mflr %r0
1105: mfcr %r12
1106: mfmsr %r2
1107: lis %r4,_C_LABEL(curpcb)@ha
1108: lwz %r4,_C_LABEL(curpcb)@l(%r4)
1109: stw %r3,PCB_FAULT(%r4)
1110: stw %r0,0(%r3)
1111: stw %r2,4(%r3)
1112: stw %r1,8(%r3)
1113: stmw %r12,12(%r3)
1114: li %r3,0
1115: blr
1116:
1117: /*
1118: * The following code gets copied to the top of the user stack on process
1119: * execution. It does signal trampolining on signal delivery.
1120: *
1121: * On entry r1 points to a struct sigframe at bottom of current stack.
1122: * All other registers are unchanged.
1123: */
1124: .globl _C_LABEL(sigcode),_C_LABEL(esigcode)
1125: .type _C_LABEL(sigcode),@function
1126: .type _C_LABEL(esigcode),@function
1127: _C_LABEL(sigcode):
1128: addi %r1,%r1,-((16+FPSIG_SIZEOF+15)& ~0xf) /* reserved space for callee */
1129: addi %r6,%r1,8
1130: stfd %f0,0(%r6)
1131: stfd %f1,8(%r6)
1132: stfd %f2,16(%r6)
1133: stfd %f3,24(%r6)
1134: stfd %f4,32(%r6)
1135: stfd %f5,40(%r6)
1136: stfd %f6,48(%r6)
1137: stfd %f7,56(%r6)
1138: stfd %f8,64(%r6)
1139: stfd %f9,72(%r6)
1140: stfd %f10,80(%r6)
1141: stfd %f11,88(%r6)
1142: stfd %f12,96(%r6)
1143: stfd %f13,104(%r6)
1144: mffs %f0
1145: stfd %f0,112(%r6)
1146: lfd %f0,0(%r6) /* restore the clobbered register */
1147:
1148: blrl
1149: addi %r6,%r1,8
1150: lfd %f0,112(%r6)
1151: mtfsf 0xff,%f0
1152: lfd %f0,0(%r6)
1153: lfd %f1,8(%r6)
1154: lfd %f2,16(%r6)
1155: lfd %f3,24(%r6)
1156: lfd %f4,32(%r6)
1157: lfd %f5,40(%r6)
1158: lfd %f6,48(%r6)
1159: lfd %f7,56(%r6)
1160: lfd %f8,64(%r6)
1161: lfd %f9,72(%r6)
1162: lfd %f10,80(%r6)
1163: lfd %f11,88(%r6)
1164: lfd %f12,96(%r6)
1165: lfd %f13,104(%r6)
1166: addi %r3,%r1,((16+FPSIG_SIZEOF+15)&~0xf)+SF_SC /* compute &sf_sc */
1167: li %r0,SYS_sigreturn
1168: sc /* sigreturn(scp) */
1169: li %r0,SYS_exit
1170: sc /* exit(errno) */
1171: _C_LABEL(esigcode):
1172:
1173:
1174: #ifdef DDB
1175: /*
1176: * Deliberate entry to ddbtrap
1177: */
1178: .globl _C_LABEL(ddb_trap)
1179: _C_LABEL(ddb_trap):
1180: mtsprg %r1,1
1181: mfmsr %r3
1182: mtsrr1 %r3
1183: andi. %r3,%r3,~(PSL_EE|PSL_ME)@l
1184: mtmsr %r3 /* disable interrupts */
1185: isync
1186: stmw %r28,ddbsave(0)
1187: mflr %r28
1188: li %r29,EXC_BPT
1189: mtlr %r29
1190: mfcr %r29
1191: mtsrr0 %r28
1192:
1193: /*
1194: * Now the ddb trap catching code.
1195: */
1196: ddbtrap:
1197: FRAME_SETUP(ddbsave)
1198: /* Call C trap code: */
1199: addi %r3,%r1,8
1200: bl _C_LABEL(ddb_trap_glue)
1201: or. %r3,%r3,%r3
1202: bne ddbleave
1203: /* This wasn't for DDB, so switch to real trap: */
1204: lwz %r3,FRAME_EXC+8(%r1) /* save exception */
1205: stw %r3,ddbsave+8(0)
1206: FRAME_LEAVE(ddbsave)
1207: mtsprg %r1,1 /* prepare for entrance to realtrap */
1208: stmw %r28,tempsave(0)
1209: mflr %r28
1210: mfcr %r29
1211: lwz %r31,ddbsave+8(0)
1212: mtlr %r31
1213: b realtrap
1214: ddbleave:
1215: FRAME_LEAVE(ddbsave)
1216: rfi
1217: #endif /* DDB */
1218:
CVSweb