Annotation of src/sys/arch/macppc/macppc/locore.S, Revision 1.16.2.2
1.16.2.2! bouyer 1: /* $NetBSD$ */
1.1 tsubai 2:
3: /*
4: * Copyright (C) 1995, 1996 Wolfgang Solfrank.
5: * Copyright (C) 1995, 1996 TooLs GmbH.
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by TooLs GmbH.
19: * 4. The name of TooLs GmbH may not be used to endorse or promote products
20: * derived from this software without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
23: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25: * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32: */
33:
1.4 jonathan 34: #include "opt_ddb.h"
1.16.2.1 bouyer 35: #include "opt_ipkdb.h"
36: #include "opt_lockdebug.h"
37: #include "opt_multiprocessor.h"
1.1 tsubai 38: #include "assym.h"
39:
40: #include <sys/syscall.h>
41:
42: #include <machine/param.h>
43: #include <machine/pmap.h>
44: #include <machine/psl.h>
45: #include <machine/trap.h>
46: #include <machine/asm.h>
47:
48: /*
49: * Some instructions gas doesn't understand (yet?)
50: */
51: #define bdneq bdnzf 2,
52:
1.16.2.1 bouyer 53: #if defined(MULTIPROCESSOR)
54: /*
55: * Get varios per-cpu values.
56: */
57: #define GET_CPUINFO(r) \
58: mfspr r,1023; /* r = cpu_number() */ \
59: mulli r,r,CI_SIZE; \
60: addis r,r,_C_LABEL(cpu_info)@ha; \
61: addi r,r,_C_LABEL(cpu_info)@l;
62: #endif
63:
1.1 tsubai 64: /*
65: * Globals
66: */
67: .data
68: GLOBAL(esym)
69: .long 0 /* end of symbol table */
70: GLOBAL(proc0paddr)
71: .long 0 /* proc0 p_addr */
72:
73: GLOBAL(intrnames)
74: .asciz "irq0", "irq1", "irq2", "irq3"
75: .asciz "irq4", "irq5", "irq6", "irq7"
76: .asciz "irq8", "irq9", "irq10", "irq11"
77: .asciz "irq12", "irq13", "irq14", "irq15"
78: .asciz "irq16", "irq17", "irq18", "irq19"
79: .asciz "irq20", "irq21", "irq22", "irq23"
80: .asciz "irq24", "irq25", "irq26", "irq27"
81: .asciz "irq28", "irq29", "irq30", "irq31"
1.9 tsubai 82: .asciz "irq32", "irq33", "irq34", "irq35"
83: .asciz "irq36", "irq37", "irq38", "irq39"
84: .asciz "irq40", "irq41", "irq42", "irq43"
85: .asciz "irq44", "irq45", "irq46", "irq47"
86: .asciz "irq48", "irq49", "irq50", "irq51"
87: .asciz "irq52", "irq53", "irq54", "irq55"
88: .asciz "irq56", "irq57", "irq58", "irq59"
89: .asciz "irq60", "irq61", "irq62", "irq63"
90: .asciz "clock", "softclock", "softnet", "softserial"
1.1 tsubai 91: GLOBAL(eintrnames)
92: .align 4
93: GLOBAL(intrcnt)
94: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
95: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1.9 tsubai 96: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
97: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
98: .long 0,0,0,0
1.1 tsubai 99: GLOBAL(eintrcnt)
100:
1.10 tsubai 101: GLOBAL(ofmsr)
102: .long 0 /* msr used in Open Firmware */
1.8 tsubai 103:
1.16.2.1 bouyer 104: GLOBAL(powersave)
105: .long 0
106:
1.1 tsubai 107: /*
108: * File-scope for locore.S
109: */
1.16.2.1 bouyer 110: #if !defined(MULTIPROCESSOR)
1.1 tsubai 111: idle_u:
112: .long 0 /* fake uarea during idle after exit */
1.16.2.1 bouyer 113: #endif
1.1 tsubai 114: openfirmware_entry:
115: .long 0 /* openfirmware entry point */
1.11 tsubai 116: srsave:
117: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
1.1 tsubai 118:
119: /*
120: * This symbol is here for the benefit of kvm_mkdb, and is supposed to
121: * mark the start of kernel text.
122: */
123: .text
124: .globl _C_LABEL(kernel_text)
125: _C_LABEL(kernel_text):
126:
127: /*
128: * Startup entry. Note, this must be the first thing in the text
129: * segment!
130: */
131: .text
132: .globl __start
133: __start:
134: #ifdef FIRMWORKSBUGS
135: mfmsr 0
136: andi. 0,0,PSL_IR|PSL_DR
137: beq 1f
138:
139: bl _C_LABEL(ofwr_init)
140: 1:
141: #endif
1.5 tsubai 142: mfmsr 0
1.8 tsubai 143: lis 9,ofmsr@ha
144: stw 0,ofmsr@l(9)
1.5 tsubai 145:
1.1 tsubai 146: li 0,0
147: mtmsr 0 /* Disable FPU/MMU/exceptions */
148: isync
149:
150: /* compute end of kernel memory */
151: lis 8,_C_LABEL(end)@ha
152: addi 8,8,_C_LABEL(end)@l
153: #ifdef DDB
1.14 tsubai 154: /* skip symbol table */
1.15 tsubai 155: cmpwi 6,0
156: beq 1f
1.14 tsubai 157: add 9,6,7 /* r9 = args + l */
158: lwz 9,-8(9) /* esym */
159: cmpwi 9,0
160: beq 1f
161: mr 8,9
162: 1:
1.1 tsubai 163: #endif
164: li 9,PGOFSET
165: add 8,8,9
166: andc 8,8,9
167: lis 9,_C_LABEL(OF_buf)@ha
168: stw 8,_C_LABEL(OF_buf)@l(9)
169: addi 8,8,NBPG
1.16.2.1 bouyer 170: #if defined(MULTIPROCESSOR)
171: lis 9,_C_LABEL(cpu_info)@ha
172: addi 9,9,_C_LABEL(cpu_info)@l
173: stw 8,CI_IDLE_PCB(9)
174: #else
1.1 tsubai 175: lis 9,idle_u@ha
176: stw 8,idle_u@l(9)
1.16.2.1 bouyer 177: #endif
1.1 tsubai 178: addi 8,8,USPACE /* space for idle_u */
179: lis 9,_C_LABEL(proc0paddr)@ha
180: stw 8,_C_LABEL(proc0paddr)@l(9)
181: addi 1,8,USPACE-FRAMELEN /* stackpointer for proc0 */
182: mr 4,1 /* end of mem reserved for kernel */
183: xor 0,0,0
184: stwu 0,-16(1) /* end of stack chain */
185:
186: lis 8,openfirmware_entry@ha
187: stw 5,openfirmware_entry@l(8) /* save client interface handler */
188: lis 3,__start@ha
189: addi 3,3,__start@l
190: mr 5,6 /* args string */
191: bl _C_LABEL(initppc)
192: bl _C_LABEL(main)
193: b _C_LABEL(OF_exit)
194:
195: /*
196: * OpenFirmware entry point
197: */
198: ENTRY(openfirmware)
199: mflr 0 /* save return address */
200: stw 0,4(1)
201: stwu 1,-16(1) /* setup stack frame */
202:
203: mfmsr 4 /* save msr */
204: stw 4,8(1)
205:
206: lis 4,openfirmware_entry@ha /* get firmware entry point */
207: lwz 4,openfirmware_entry@l(4)
208: mtlr 4
1.16 tsubai 209:
210: li 0,0 /* clear battable translations */
211: mtdbatu 2,0
212: mtdbatu 3,0
213: mtibatu 2,0
214: mtibatu 3,0
1.1 tsubai 215:
1.8 tsubai 216: lis 4,ofmsr@ha /* Open Firmware msr */
217: lwz 4,ofmsr@l(4)
1.5 tsubai 218: mtmsr 4
1.1 tsubai 219: isync
220:
1.11 tsubai 221: lis 4,srsave@ha /* save old SR */
222: addi 4,4,srsave@l
223: li 5,0
224: 1: mfsrin 0,5
225: stw 0,0(4)
226: addi 4,4,4
227: addis 5,5,0x10000000@h
228: cmpwi 5,0
229: bne 1b
230:
231: lis 4,_C_LABEL(ofw_pmap)@ha /* load OFW SR */
232: addi 4,4,_C_LABEL(ofw_pmap)@l
233: lwz 0,PM_KERNELSR(4)
234: cmpwi 0,0 /* pm_sr[KERNEL_SR] == 0? */
235: beq 2f /* then skip (not initialized yet) */
236: li 5,0
237: 1: lwz 0,0(4)
238: mtsrin 0,5
239: addi 4,4,4
240: addis 5,5,0x10000000@h
241: cmpwi 5,0
242: bne 1b
243: 2:
1.8 tsubai 244: blrl /* call Open Firmware */
1.11 tsubai 245:
246: lis 4,srsave@ha /* restore saved SR */
247: addi 4,4,srsave@l
248: li 5,0
1.12 tsubai 249: 1: lwz 0,0(4)
250: mtsrin 0,5
1.11 tsubai 251: addi 4,4,4
252: addis 5,5,0x10000000@h
253: cmpwi 5,0
254: bne 1b
1.1 tsubai 255:
256: lwz 4,8(1) /* restore msr */
257: mtmsr 4
258: isync
259:
260: lwz 1,0(1) /* and return */
261: lwz 0,4(1)
262: mtlr 0
263: blr
264:
265: /*
266: * Switch to/from OpenFirmware real mode stack
267: *
268: * Note: has to be called as the very first thing in OpenFirmware interface
269: * routines.
270: * E.g.:
271: * int
272: * OF_xxx(arg1, arg2)
273: * type arg1, arg2;
274: * {
275: * static struct {
276: * char *name;
277: * int nargs;
278: * int nreturns;
279: * char *method;
280: * int arg1;
281: * int arg2;
282: * int ret;
283: * } args = {
284: * "xxx",
285: * 2,
286: * 1,
287: * };
288: *
289: * ofw_stack();
290: * args.arg1 = arg1;
291: * args.arg2 = arg2;
292: * if (openfirmware(&args) < 0)
293: * return -1;
294: * return args.ret;
295: * }
296: */
297:
298: .local firmstk
299: .comm firmstk,NBPG,8
300:
301: ENTRY(ofw_stack)
302: mfmsr 8 /* turn off interrupts */
303: andi. 0,8,~(PSL_EE|PSL_RI)@l
304: mtmsr 0
305: stw 8,4(1) /* abuse return address slot */
306:
307: lwz 5,0(1) /* get length of stack frame */
308: subf 5,1,5
309:
310: lis 7,firmstk+NBPG-8@ha
311: addi 7,7,firmstk+NBPG-8@l
312: lis 6,ofw_back@ha
313: addi 6,6,ofw_back@l
314: subf 4,5,7 /* make room for stack frame on
315: new stack */
316: stw 6,-4(7) /* setup return pointer */
317: stwu 1,-8(7)
318:
319: stw 7,-8(4)
320:
321: addi 3,1,8
322: addi 1,4,-8
323: subi 5,5,8
324:
325: b _C_LABEL(ofbcopy) /* and copy it */
326:
327: ofw_back:
328: lwz 1,0(1) /* get callers original stack pointer */
329:
330: lwz 0,4(1) /* get saved msr from abused slot */
331: mtmsr 0
332:
333: lwz 1,0(1) /* return */
334: lwz 0,4(1)
335: mtlr 0
336: blr
337:
338:
339: /*
340: * No processes are runnable, so loop waiting for one.
341: * Separate label here for accounting purposes.
1.16.2.1 bouyer 342: * When we get here, interrupts are off (MSR[EE]=0) and sched_lock is held.
1.1 tsubai 343: */
344: ASENTRY(Idle)
1.16.2.1 bouyer 345: lis 8,_C_LABEL(sched_whichqs)@ha
346: lwz 9,_C_LABEL(sched_whichqs)@l(8)
1.1 tsubai 347:
348: or. 9,9,9
349: bne- .Lsw1 /* at least one queue non-empty */
350:
1.16.2.1 bouyer 351: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
352: bl _C_LABEL(sched_unlock_idle)
353: #endif
354:
355: mfmsr 3
1.1 tsubai 356: ori 3,3,PSL_EE@l /* reenable ints again */
357: mtmsr 3
358: isync
359:
1.16.2.1 bouyer 360: /* Check if we can use power saving mode */
361: lis 8,_C_LABEL(powersave)@ha
362: lwz 9,_C_LABEL(powersave)@l(8)
363:
364: or. 9,9,9
365: beq 1f
366:
367: sync
368: oris 3,3,PSL_POW@h /* enter power saving mode */
369: mtmsr 3
370: isync
371: 1:
372: andi. 3,3,~PSL_EE@l /* disable interrupts while
373: manipulating runque */
374: mtmsr 3
375:
376: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
377: bl _C_LABEL(sched_lock_idle)
378: #endif
1.1 tsubai 379: b _ASM_LABEL(Idle)
380:
381: /*
1.6 thorpej 382: * switchexit gets called from cpu_exit to complete the exit procedure.
1.1 tsubai 383: */
384: ENTRY(switchexit)
385: /* First switch to the idle pcb/kernel stack */
1.16.2.1 bouyer 386: #if defined(MULTIPROCESSOR)
387: GET_CPUINFO(7)
388: lwz 6,CI_IDLE_PCB(7)
389: stw 6,CI_CURPCB(7)
390: #else
1.1 tsubai 391: lis 6,idle_u@ha
392: lwz 6,idle_u@l(6)
393: lis 7,_C_LABEL(curpcb)@ha
394: stw 6,_C_LABEL(curpcb)@l(7)
1.16.2.1 bouyer 395: #endif
1.1 tsubai 396: addi 1,6,USPACE-16 /* 16 bytes are reserved at stack top */
1.6 thorpej 397: /*
398: * Schedule the vmspace and stack to be freed (the proc arg is
399: * already in r3).
400: */
401: bl _C_LABEL(exit2)
402:
1.16.2.1 bouyer 403: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
404: bl _C_LABEL(sched_lock_idle)
405: #endif
406:
1.1 tsubai 407: /* Fall through to cpu_switch to actually select another proc */
408: li 3,0 /* indicate exited process */
409:
410: /*
411: * void cpu_switch(struct proc *p)
412: * Find a runnable process and switch to it.
413: */
414: /* XXX noprofile? --thorpej@netbsd.org */
415: ENTRY(cpu_switch)
416: mflr 0 /* save lr */
417: stw 0,4(1)
418: stwu 1,-16(1)
419: stw 31,12(1)
420: stw 30,8(1)
421:
422: mr 30,3
1.16.2.1 bouyer 423: #if defined(MULTIPROCESSOR)
424: GET_CPUINFO(3)
425: xor 31,31,31
426: stw 31,CI_CURPROC(3) /* Zero to not accumulate cpu time */
427: lwz 31,CI_CURPCB(3)
428: #else
1.1 tsubai 429: lis 3,_C_LABEL(curproc)@ha
430: xor 31,31,31
431: stw 31,_C_LABEL(curproc)@l(3) /* Zero to not accumulate cpu time */
432: lis 3,_C_LABEL(curpcb)@ha
433: lwz 31,_C_LABEL(curpcb)@l(3)
1.16.2.1 bouyer 434: #endif
435:
436: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
437: /* Release the sched_lock before processing interrupts. */
438: bl _C_LABEL(sched_unlock_idle)
439: #endif
1.1 tsubai 440:
441: xor 3,3,3
442: bl _C_LABEL(lcsplx)
443: stw 3,PCB_SPL(31) /* save spl */
444:
1.16.2.1 bouyer 445: /* Lock the scheduler. */
1.1 tsubai 446: mfmsr 3
447: andi. 3,3,~PSL_EE@l /* disable interrupts while
448: manipulating runque */
449: mtmsr 3
450: isync
1.16.2.1 bouyer 451: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
452: bl _C_LABEL(sched_lock_idle)
453: #endif
1.1 tsubai 454:
1.16.2.1 bouyer 455: /* Find a new process */
456: lis 8,_C_LABEL(sched_whichqs)@ha
457: lwz 9,_C_LABEL(sched_whichqs)@l(8)
1.1 tsubai 458:
459: or. 9,9,9
460: beq- _ASM_LABEL(Idle) /* all queues empty */
461: .Lsw1:
462: cntlzw 10,9
1.16.2.1 bouyer 463: lis 4,_C_LABEL(sched_qs)@ha
464: addi 4,4,_C_LABEL(sched_qs)@l
1.1 tsubai 465: slwi 3,10,3
466: add 3,3,4 /* select queue */
467:
468: lwz 31,P_FORW(3) /* unlink first proc from queue */
469: lwz 4,P_FORW(31)
470: stw 4,P_FORW(3)
471: stw 3,P_BACK(4)
472:
473: cmpl 0,3,4 /* queue empty? */
474: bne 1f
475:
476: lis 3,0x80000000@h
477: srw 3,3,10
478: andc 9,9,3
1.16.2.1 bouyer 479: stw 9,_C_LABEL(sched_whichqs)@l(8) /* mark it empty */
1.1 tsubai 480:
481: 1:
482: /* just did this resched thing */
483: xor 3,3,3
484: lis 4,_C_LABEL(want_resched)@ha
485: stw 3,_C_LABEL(want_resched)@l(4)
486:
487: stw 3,P_BACK(31) /* probably superfluous */
488:
1.16.2.1 bouyer 489: #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
490: /* Unlock the sched_lock, but leave interrupts off, for now. */
491: bl _C_LABEL(sched_unlock_idle)
492: #endif
493:
494: #if defined(MULTIPROCESSOR)
495: GET_CPUINFO(4)
496: stw 4,P_CPU(31) /* p->p_cpu = curcpu() */
497: #endif
498:
499: /* Process now running on a processor. */
500: li 3,SONPROC /* p->p_stat = SONPROC */
501: stb 3,P_STAT(31)
502:
1.1 tsubai 503: /* record new process */
1.16.2.1 bouyer 504: #if defined(MULTIPROCESSOR)
505: stw 31,CI_CURPROC(4)
506: #else
1.1 tsubai 507: lis 4,_C_LABEL(curproc)@ha
508: stw 31,_C_LABEL(curproc)@l(4)
1.16.2.1 bouyer 509: #endif
1.1 tsubai 510:
511: mfmsr 3
512: ori 3,3,PSL_EE@l /* Now we can interrupt again */
513: mtmsr 3
514:
515: cmpl 0,31,30 /* is it the same process? */
516: beq switch_return
517:
518: or. 30,30,30 /* old process was exiting? */
519: beq switch_exited
520:
521: mfsr 10,USER_SR /* save USER_SR for copyin/copyout */
522: mfcr 11 /* save cr */
523: mr 12,2 /* save r2 */
524: stwu 1,-SFRAMELEN(1) /* still running on old stack */
525: stmw 10,8(1)
526: lwz 3,P_ADDR(30)
527: stw 1,PCB_SP(3) /* save SP */
528:
529: switch_exited:
530: mfmsr 3
531: andi. 3,3,~PSL_EE@l /* disable interrupts while
532: actually switching */
533: mtmsr 3
534:
535: /* indicate new pcb */
536: lwz 4,P_ADDR(31)
1.16.2.1 bouyer 537: #if defined(MULTIPROCESSOR)
538: GET_CPUINFO(6)
539: stw 4,CI_CURPCB(6)
540: #else
1.1 tsubai 541: lis 5,_C_LABEL(curpcb)@ha
542: stw 4,_C_LABEL(curpcb)@l(5)
1.16.2.1 bouyer 543: #endif
1.1 tsubai 544:
545: /* save real pmap pointer for spill fill */
546: lwz 5,PCB_PMR(4)
1.16.2.1 bouyer 547: #if defined(MULTIPROCESSOR)
548: stwu 5,CI_CURPM(6)
549: #else
1.1 tsubai 550: lis 6,_C_LABEL(curpm)@ha
551: stwu 5,_C_LABEL(curpm)@l(6)
1.16.2.1 bouyer 552: #endif
1.1 tsubai 553: stwcx. 5,0,6 /* clear possible reservation */
554:
555: addic. 5,5,64
556: li 6,0
557: mfsr 8,KERNEL_SR /* save kernel SR */
558: 1:
559: addis 6,6,-0x10000000@ha /* set new procs segment registers */
560: or. 6,6,6 /* This is done from the real
561: address pmap */
562: lwzu 7,-4(5) /* so we don't have to worry */
563: mtsrin 7,6 /* about accessibility */
564: bne 1b
565: mtsr KERNEL_SR,8 /* restore kernel SR */
566: isync
567:
568: lwz 1,PCB_SP(4) /* get new procs SP */
569:
570: ori 3,3,PSL_EE@l /* interrupts are okay again */
571: mtmsr 3
572:
573: lmw 10,8(1) /* get other regs */
574: lwz 1,0(1) /* get saved SP */
575: mr 2,12 /* get saved r2 */
576: mtcr 11 /* get saved cr */
577: isync
578: mtsr USER_SR,10 /* get saved USER_SR */
579: isync
580:
581: switch_return:
582: mr 30,7 /* save proc pointer */
583: lwz 3,PCB_SPL(4)
584: bl _C_LABEL(lcsplx)
585:
586: mr 3,30 /* get curproc for special fork
587: returns */
588:
589: lwz 31,12(1)
590: lwz 30,8(1)
591: addi 1,1,16
592: lwz 0,4(1)
593: mtlr 0
594: blr
595:
596: /*
597: * Child comes here at the end of a fork.
1.16.2.2! bouyer 598: * Return to userspace via the trap return path.
1.1 tsubai 599: */
600: .globl _C_LABEL(fork_trampoline)
601: _C_LABEL(fork_trampoline):
602: xor 3,3,3
603: bl _C_LABEL(lcsplx)
604: mtlr 31
605: mr 3,30
606: blrl /* jump indirect to r31 */
607: b trapexit
608:
609: /*
1.16.2.2! bouyer 610: * Pull in common trap vector code.
1.1 tsubai 611: */
1.16.2.2! bouyer 612: #include <powerpc/powerpc/trap_subr.S>
1.1 tsubai 613:
614: /*
615: * int ipkdbsbyte(unsigned char *p, int c)
616: */
617: .globl _C_LABEL(ipkdbsbyte)
618: _C_LABEL(ipkdbsbyte):
619: li 9,EXC_DSI /* establish new fault routine */
620: lwz 5,0(9)
621: lis 6,ipkdbfault@ha
622: lwz 6,ipkdbfault@l(6)
623: stw 6,0(9)
624: #ifdef IPKDBUSERHACK
625: lis 8,_C_LABEL(ipkdbsr)@ha
626: lwz 8,_C_LABEL(ipkdbsr)@l(8)
627: mtsr USER_SR,8
628: isync
629: #endif
630: dcbst 0,9 /* flush data... */
631: sync
632: icbi 0,9 /* and instruction caches */
633: mr 6,3
634: xor 3,3,3
635: stb 4,0(6)
636: dcbst 0,6 /* Now do appropriate flushes
637: to data... */
638: sync
639: icbi 0,6 /* and instruction caches */
640: stw 5,0(9) /* restore previous fault handler */
641: dcbst 0,9 /* and flush data... */
642: sync
643: icbi 0,9 /* and instruction caches */
644: blr
1.16.2.1 bouyer 645: #endif /* IPKDB */
1.1 tsubai 646:
647: /*
648: * int setfault()
649: *
650: * Similar to setjmp to setup for handling faults on accesses to user memory.
651: * Any routine using this may only call bcopy, either the form below,
652: * or the (currently used) C code optimized, so it doesn't use any non-volatile
653: * registers.
654: */
655: .globl _C_LABEL(setfault)
656: _C_LABEL(setfault):
657: mflr 0
658: mfcr 12
1.16.2.1 bouyer 659: #if defined(MULTIPROCESSOR)
660: GET_CPUINFO(4)
661: lwz 4,CI_CURPCB(4)
662: #else
1.1 tsubai 663: lis 4,_C_LABEL(curpcb)@ha
664: lwz 4,_C_LABEL(curpcb)@l(4)
1.16.2.1 bouyer 665: #endif
1.1 tsubai 666: stw 3,PCB_FAULT(4)
667: stw 0,0(3)
668: stw 1,4(3)
669: stw 2,8(3)
670: stmw 12,12(3)
671: xor 3,3,3
672: blr
673:
1.16.2.1 bouyer 674: #if defined(MULTIPROCESSOR)
675: .globl _C_LABEL(cpu_spinup_trampoline)
676: _C_LABEL(cpu_spinup_trampoline):
677: li 0,0
678: mtmsr 0
679: isync
680:
681: lis 3,cpu_hatchstack@ha
682: lwz 1,cpu_hatchstack@l(3)
683:
684: bl _C_LABEL(cpu_hatch)
685:
686: /* Loop forever. */
687: 1:
688: sync
689: mfmsr 3
690: oris 3,3,PSL_POW@h
691: mtmsr 3
692: isync
693: b 1b
694:
695: #endif
CVSweb <webmaster@jp.NetBSD.org>