|
|
1.1 root 1: #ifdef LOCORE
2: #define U_PROCP 144
3: #define U_EOSYS 273
4: #define P_LINK 0
5: #define P_RLINK 4
6: #define P_XLINK 108
7: #define P_ADDR 16
8: #define P_PRI 21
9: #define P_STAT 23
10: #define P_WCHAN 96
11: #define P_TSIZE 68
12: #define P_SSIZE 76
13: #define P_P0BR 104
14: #define P_SZPT 66
15: #define P_TEXTP 100
16: #define P_FLAG 44
17: #define P_DKEY 164
18: #define P_CKEY 160
19: #define SSLEEP 1
20: #define SRUN 3
21: #define V_SWTCH 0
22: #define V_TRAP 4
23: #define V_SYSCALL 8
24: #define V_INTR 12
25: #define V_SOFT 16
26: #define V_FPE 116
27: #define V_ALIGN 120
28: #define MCLBYTES 1024
29: #define NBPG 1024
30: #define PGSHIFT 10
31: #define UPAGES 6
32: #define CLSIZE 1
33: #define MAXPHYS 65536
34: #define SYSPTSIZE 9216
35: #define USRPTSIZE 1024
36: #define VBIOSIZE 1020
37: #define MSGBUFPTECNT 4
38: #define NMBCLUSTERS 256
39: #define PCB_KSP 0
40: #define PCB_USP 4
41: #define PCB_R0 8
42: #define PCB_R1 12
43: #define PCB_R2 16
44: #define PCB_R3 20
45: #define PCB_R4 24
46: #define PCB_R5 28
47: #define PCB_R6 32
48: #define PCB_R7 36
49: #define PCB_R8 40
50: #define PCB_R9 44
51: #define PCB_R10 48
52: #define PCB_R11 52
53: #define PCB_R12 56
54: #define PCB_R13 60
55: #define PCB_FP 60
56: #define PCB_PC 64
57: #define PCB_PSL 68
58: #define PCB_P0BR 72
59: #define PCB_P0LR 76
60: #define PCB_P1BR 80
61: #define PCB_P1LR 84
62: #define PCB_P2BR 88
63: #define PCB_P2LR 92
64: #define PCB_ACH 96
65: #define PCB_ACL 100
66: #define PCB_HFS 104
67: #define PCB_SAVACC 108
68: #define PCB_SZPT 112
69: #define PCB_CMAP2 116
70: #define PCB_SSWAP 120
71: #define PCB_SIGC 124
72: #define SCB_DOADUMP 8
73: #define SCB_BUSERR 128
74: #define SCB_DEVBASE 64
75: #endif
76: /*
77: * @(#)scb.s 7.1 (Berkeley) 5/21/88
78: */
79:
80: /*
81: * System control block
82: */
83: #define STRAY .long _Xstray
84: #define STRAY8 STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY
85: #define KS(a) .long _X/**/a
86: #define IS(a) .long _X/**/a
87:
88: _scb: .globl _scb
89: /* 000 */ STRAY; IS(powfail); IS(doadump); STRAY;
90: /* 004 */ STRAY; STRAY; STRAY; IS(hardclock);
91: /* 008 */ STRAY; STRAY; IS(cnrint); IS(cnxint);
92: /* 00c */ IS(rmtrint); IS(rmtxint); STRAY; STRAY;
93: /* 010 */ IS(kdbintr); STRAY; STRAY; IS(netintr);
94: /* 014 */ STRAY; STRAY; STRAY; IS(softclock);
95: /* 018 */ STRAY; STRAY; STRAY; STRAY;
96: /* 01c */ STRAY; STRAY; STRAY; STRAY;
97: /* 020 */ IS(buserr); STRAY; STRAY; STRAY;
98: /* 024 */ STRAY; STRAY; STRAY; STRAY;
99: /* 028 */ STRAY; STRAY; STRAY; KS(syscall);
100: /* 02c */ KS(privinflt); KS(resopflt); KS(resadflt); KS(protflt);
101: /* 030 */ KS(transflt); IS(kspnotval); KS(tracep); KS(bptflt);
102: /* 034 */ KS(arithtrap); KS(alignflt); KS(sfexcep); KS(fpm);
103: /* 038 */ STRAY; STRAY; STRAY; STRAY;
104: /* 03c */ STRAY; STRAY; STRAY; STRAY;
105: /* device interrupt vectors */
106: /* 040 */ STRAY8; STRAY8; STRAY8; STRAY8;
107: /* 060 */ STRAY8; STRAY8; STRAY8; STRAY8;
108: /* 080 */ STRAY8; STRAY8; STRAY8; STRAY8;
109: /* 0a0 */ STRAY8; STRAY8; STRAY8; STRAY8;
110: /* 0c0 */ STRAY8; STRAY8; STRAY8; STRAY8;
111: /* 0e0 */ STRAY8; STRAY8; STRAY8; STRAY8;
112: #define I_CLOCK 0
113: #define I_CNR 4
114: #define I_CNX 8
115: #define I_RMTR 12
116: #define I_RMTX 16
117: #define I_BUSERR 20
118: /*
119: * Copyright (c) 1988 Regents of the University of California.
120: * All rights reserved. The Berkeley software License Agreement
121: * specifies the terms and conditions for redistribution.
122: *
123: * @(#)locore.s 7.6 (Berkeley) 5/1/89
124: * 9/8/89 (bostic) -- added delay in wbadaddr from 7.10
125: * This had already been patched, but I have no idea by whom; the
126: * following lines had been added:
127: *
128: * #if NVX > 0
129: * ADDMAP( NVX * 16384/NBPG )
130: * #endif
131: */
132:
133: #include "../tahoe/mtpr.h"
134: #include "../tahoe/trap.h"
135: #include "../tahoe/psl.h"
136: #include "../tahoe/pte.h"
137: #include "../tahoe/cp.h"
138: #include "../tahoe/mem.h"
139: #include "../tahoe/SYS.h"
140:
141: #include "../tahoemath/fp.h"
142:
143: #include "errno.h"
144: #include "syscall.h"
145: #include "cmap.h"
146:
147: .set HIGH,0x1f # mask for total disable
148: .set NISP,3 # number of interrupt stack pages
149: .set SYSTEM,0xC0000000 # virtual address of system start
150: .set PPAGES,0x100000 # possible pages in P0,P1, etc.
151:
152: /* ACBL for non-negative '_add' */
153: #define ACBL(_limit,_add,_index,_displ) \
154: addl2 _add,_index; \
155: cmpl _index,_limit; \
156: bleq _displ
157:
158: /* _ACBL for negative '_add' */
159: #define _ACBL(_limit,_add,_index,_displ) \
160: addl2 _add,_index; \
161: cmpl _index,_limit; \
162: bgeq _displ
163:
164: #define MOVC3(_srcaddr,_dstaddr,_len) \
165: movl _srcaddr,r0; \
166: movl _dstaddr,r1; \
167: movl _len,r2; \
168: movblk
169:
170: /* keep address of psl if coming from user mode */
171: #define CHECK_SFE(_delta) \
172: bitl $PSL_CURMOD,_delta(sp); \
173: jeql 1f; \
174: moval _delta(sp),_user_psl; \
175: 1:
176:
177: /*
178: * User structure is UPAGES at top of user space.
179: */
180: .globl _u
181: .set _u,SYSTEM - UPAGES*NBPG
182:
183: /*
184: * Restart stack. Used on power recovery or panic.
185: * Takes a core-dump and then halts.
186: */
187: .globl _rsstk
188: .globl pwfl_stk
189: _rsstk:
190: .space 1024-8
191: pwfl_stk:
192: .space 4
193: dumpflag:
194: .space 4
195:
196: .globl _intstack
197: _intstack:
198: .space NISP*NBPG
199: eintstack:
200:
201: /*
202: * Power failure storage block and
203: * macros for saving and restoring.
204: */
205: #define POWERFAIL(id,longs) \
206: .globl pwfl_/**/id \
207: pwfl_/**/id: .space longs*4
208: .data
209: POWERFAIL(r0, 14) # r0-r13
210: POWERFAIL(sp, 1) # r14
211: POWERFAIL(SCBB, 1) # system control block base
212: POWERFAIL(SBR, 1) # system pte base
213: POWERFAIL(SLR, 1) # system pte length
214: POWERFAIL(P0BR, 1) # p0 pte base
215: POWERFAIL(P0LR, 1) # p0 pte length
216: POWERFAIL(P1BR, 1) # p1 pte base
217: POWERFAIL(P1LR, 1) # p1 pte length
218: POWERFAIL(P2BR, 1) # p2 pte base
219: POWERFAIL(P2LR, 1) # p2 pte length
220: POWERFAIL(IPL, 1) # interrupt priority level
221: POWERFAIL(DCK, 1) # data cache key
222: POWERFAIL(CCK, 1) # code cache key
223: POWERFAIL(PCBB, 1) # process control block base
224: POWERFAIL(ISP, 1) # interrupt stack pointer
225: POWERFAIL(KSP, 1) # kernel mode stack pointer
226: POWERFAIL(USP, 1) # user mode stack pointer
227: POWERFAIL(MME, 1) # memory management enable
228: POWERFAIL(PSL, 1) # processor status longword
229:
230: /*
231: * Save current state in power fail storage block.
232: */
233: #define SAVEpwfl() \
234: movpsl pwfl_PSL # Keeps all flags, etc. \
235: storer $0x3fff,pwfl_r0 # Saves r0-r13 \
236: moval 0(sp),pwfl_sp # Saves sp (=r14) \
237: mfpr $SBR,pwfl_SBR # Save all re_loadable registers \
238: mfpr $SLR,pwfl_SLR \
239: mfpr $P0BR,pwfl_P0BR \
240: mfpr $P0LR,pwfl_P0LR \
241: mfpr $P1BR,pwfl_P1BR \
242: mfpr $P1LR,pwfl_P1LR \
243: mfpr $P2BR,pwfl_P2BR \
244: mfpr $P2LR,pwfl_P2LR \
245: mfpr $IPL,pwfl_IPL \
246: mfpr $MME,pwfl_MME \
247: mfpr $DCK,pwfl_DCK \
248: mfpr $CCK,pwfl_CCK \
249: mfpr $PCBB,pwfl_PCBB \
250: mfpr $ISP,pwfl_ISP \
251: mfpr $SCBB,pwfl_SCBB \
252: mfpr $KSP,pwfl_KSP \
253: mfpr $USP,pwfl_USP
254:
255: /*
256: * Restore state saved in power fail block and
257: * jmp to location specified after (possibly)
258: * enabling memory management.
259: */
260: #define RESTOREpwfl(loc) \
261: loadr $0x3fff,pwfl_r0 # Restore r0-r13 \
262: movl pwfl_sp,sp # Restore sp (=r14) \
263: mtpr pwfl_SCBB,$SCBB \
264: mtpr pwfl_SBR,$SBR # Restore all re_loadable registers \
265: mtpr pwfl_SLR,$SLR \
266: mtpr pwfl_P0BR,$P0BR \
267: mtpr pwfl_P0LR,$P0LR \
268: mtpr pwfl_P1BR,$P1BR \
269: mtpr pwfl_P1LR,$P1LR \
270: mtpr pwfl_P2BR,$P2BR \
271: mtpr pwfl_P2LR,$P2LR \
272: mtpr pwfl_IPL,$IPL \
273: mtpr pwfl_DCK,$DCK \
274: mtpr pwfl_CCK,$CCK \
275: mtpr pwfl_PCBB,$PCBB \
276: mtpr pwfl_ISP,$ISP \
277: mtpr pwfl_KSP,$KSP \
278: mtpr pwfl_USP,$USP \
279: \
280: bicpsw $0xff # Restore PSW. \
281: bispsw pwfl_PSL+2 # Set original bits back (just in case..) \
282: # now go to mapped mode \
283: # Have to change PC to system addresses \
284: mtpr $1,$PACC # Thoroughly clean up caches. \
285: mtpr $1,$PADC \
286: mtpr $1,$TBIA \
287: mtpr pwfl_MME,$MME # Restore MME. Last thing to be done. \
288: jmp loc
289:
290: /*
291: * Do a dump.
292: * Called by auto-restart.
293: * May be called manually.
294: */
295: .align 2
296: .text
297: .globl _Xdoadump
298: .globl _doadump
299: _Xdoadump: # CP comes here after power fail
300: RESTOREpwfl(*0f) # restore state
301: _doadump:
302: .word 0
303: 0: mtpr $HIGH,$IPL
304: #define _rsstkmap _Sysmap+12 # powerfail storage, scb, rsstk, int stack
305: tstl dumpflag # dump only once!
306: bneq 1f
307: andl2 $~PG_PROT,_rsstkmap
308: orl2 $PG_KW,_rsstkmap # Make dump stack r/w
309: mtpr $0,$TBIA
310: movl $1,dumpflag
311: movab dumpflag,sp
312: callf $4,_dumpsys
313: 1:
314: halt
315:
316: /*
317: * Interrupt vector routines
318: */
319: .globl _waittime
320: #define SCBVEC(name) \
321: .align 2; \
322: .globl _X/**/name; \
323: _X/**/name
324: #define PANIC(msg) \
325: clrl _waittime; pushab 1f; callf $8,_panic; 1: .asciz msg
326: #define PRINTF(n,msg) \
327: pushab 1f; callf $(n+2)*4,_printf; MSG(msg)
328: #define MSG(msg) .data; 1: .asciz msg; .text
329: /*
330: * r0-r5 are saved across all faults and interrupts.
331: * Routines below and those hidden in vbglue.s (device
332: * interrupts) invoke the PUSHR/POPR macros to execute
333: * this. Also, certain stack frame offset calculations
334: * use this, using the REGSPC definition (and FPSPC defined below).
335: */
336: #define REGSPC 6*4
337: #define PUSHR movab -REGSPC(sp),sp; storer $0x3f,(sp)
338: #define POPR loadr $0x3f,(sp); movab REGSPC(sp),sp
339:
340: /*
341: * Floating point state is saved across faults and
342: * interrupts. The state occupies 4 longwords on
343: * the stack:
344: * precision indicator (single = 0/double = 1)
345: * double representation of accumulator
346: * save accumulator status flag (pcb_savacc)
347: */
348: #define FPSPC (4*4)
349:
350: #define SAVE_FPSTAT(_delta) \
351: bitl $PSL_DBL,_delta(sp); \
352: beql 1f; \
353: pushl $1; \
354: pushd; \
355: jmp 2f; \
356: 1: pushl $0; \
357: pushl $0; \
358: stf -(sp); \
359: 2: tstl _u+PCB_SAVACC; \
360: bneq 3f; \
361: moval 0(sp),_u+PCB_SAVACC; \
362: orl2 $2,8(sp);\
363: 3: pushl $0;
364:
365: #define REST_FPSTAT \
366: tstl (sp)+; \
367: bitl $2,8(sp);\
368: beql 1f;\
369: movl $0,_u+PCB_SAVACC; \
370: 1: bitl $1,8(sp); \
371: beql 2f; \
372: ldd (sp); \
373: jmp 3f; \
374: 2: ldf (sp); \
375: 3: moval 12(sp),sp;
376:
377: #define REST_ACC \
378: tstl _u+PCB_SAVACC; \
379: beql 2f; \
380: movl _u+PCB_SAVACC,r1; \
381: andl3 $(EXPMASK|SIGNBIT),(r1),-(sp); \
382: cmpl $0x80000000,(sp)+; \
383: bneq 3f; \
384: clrl (r1); \
385: 3: bitl $1,8(r1); \
386: beql 1f; \
387: ldd (r1); \
388: jmp 2f; \
389: 1: ldf (r1); \
390: 2: ;
391:
392: .data
393: nofault: .space 4 # bus error non-local goto label
394:
395: .text
396: SCBVEC(buserr):
397: CHECK_SFE(12)
398: SAVE_FPSTAT(12)
399: incl _intrcnt+I_BUSERR # keep stats...
400: pushl r0 # must save
401: andl3 24(sp),$ERRCD,r0 # grab pushed MER value
402: cmpl r0,$APE # address parity error?
403: jneq 1f
404: halt
405: 1: cmpl r0,$VBE # versabus error?
406: jneq 2f
407: halt
408: 2:
409: movl (sp)+,r0 # restore r0 and...
410: bitl $PSL_CURMOD,4*4+3*4(sp) # check if happened in user mode?
411: jeql 3f # yes, then shift stack up for trap...
412: movl 12(sp),16(sp) # sorry, no space for which-buss...
413: movl 8(sp),12(sp)
414: movl 4(sp),8(sp)
415: movl 0(sp),4(sp)
416: movl $T_BUSERR,0(sp) # push trap type code and...
417: jbr alltraps # ...merge with all other traps
418: 3: # kernel mode, check to see if...
419: tstl nofault # ...doing peek/poke?
420: jeql 4f # nofault set? if so, jump to it...
421: movl nofault,4*4+2*4(sp) # ...setup for non-local goto
422: clrl nofault
423: jbr 5f
424: 4:
425: PUSHR
426: pushab 4*4+REGSPC(sp) # address of bus error parameters
427: callf $8,_buserror
428: POPR
429: 5:
430: REST_FPSTAT
431: movab 8(sp),sp # remove bus error parameters
432: rei
433:
434: SCBVEC(powfail): # We should be on interrupt stack now.
435: SAVEpwfl() # save machine state
436: moval _Xdoadump-SYSTEM,_scb+SCB_DOADUMP
437: halt
438:
439: SCBVEC(stray):
440: incl _cnt+V_INTR # add to statistics
441: rei
442:
443: #include "../net/netisr.h"
444: .globl _netisr
445: SCBVEC(netintr):
446: CHECK_SFE(4)
447: SAVE_FPSTAT(4); PUSHR
448: #include "imp.h"
449: #if NIMP > 0
450: bbc $NETISR_IMP,_netisr,1f;
451: andl2 $~(1<<NETISR_IMP),_netisr
452: callf $4,_impintr;
453: 1:
454: #endif
455: #ifdef INET
456: bbc $NETISR_IP,_netisr,1f
457: andl2 $~(1<<NETISR_IP),_netisr
458: callf $4,_ipintr
459: 1:
460: #endif
461: #ifdef NS
462: bbc $NETISR_NS,_netisr,1f
463: andl2 $~(1<<NETISR_NS),_netisr
464: callf $4,_nsintr
465: 1:
466: #endif
467: bbc $NETISR_RAW,_netisr,1f
468: andl2 $~(1<<NETISR_RAW),_netisr
469: callf $4,_rawintr
470: 1:
471: incl _cnt+V_SOFT
472: POPR; REST_FPSTAT
473: rei
474:
475: SCBVEC(cnrint):
476: CHECK_SFE(4)
477: SAVE_FPSTAT(4); PUSHR;
478: pushl $CPCONS; callf $8,_cnrint;
479: incl _intrcnt+I_CNR
480: incl _cnt+V_INTR
481: POPR; REST_FPSTAT;
482: rei
483: SCBVEC(cnxint):
484: CHECK_SFE(4)
485: SAVE_FPSTAT(4); PUSHR;
486: pushl $CPCONS; callf $8,_cnxint;
487: incl _intrcnt+I_CNX
488: incl _cnt+V_INTR
489: POPR; REST_FPSTAT;
490: rei
491: SCBVEC(rmtrint):
492: CHECK_SFE(4)
493: SAVE_FPSTAT(4); PUSHR;
494: pushl $CPREMOT; callf $8,_cnrint;
495: incl _intrcnt+I_RMTR
496: incl _cnt+V_INTR
497: POPR; REST_FPSTAT;
498: rei
499: SCBVEC(rmtxint):
500: CHECK_SFE(4)
501: SAVE_FPSTAT(4); PUSHR;
502: pushl $CPREMOT; callf $8,_cnxint;
503: incl _intrcnt+I_RMTX
504: incl _cnt+V_INTR
505: POPR; REST_FPSTAT;
506: rei
507:
508: #define PUSHPCPSL pushl 4+FPSPC+REGSPC(sp); pushl 4+FPSPC+REGSPC(sp);
509:
510: SCBVEC(hardclock):
511: tstl _clk_enable
512: bneq 1f
513: rei
514: 1:
515: CHECK_SFE(4)
516: SAVE_FPSTAT(4); PUSHR
517: PUSHPCPSL # push pc and psl
518: callf $12,_hardclock # hardclock(pc,psl)
519: incl _intrcnt+I_CLOCK
520: incl _cnt+V_INTR ## temp so not to break vmstat -= HZ
521: POPR; REST_FPSTAT
522: rei
523: SCBVEC(softclock):
524: CHECK_SFE(4)
525: SAVE_FPSTAT(4); PUSHR;
526: PUSHPCPSL # push pc and psl
527: callf $12,_softclock # softclock(pc,psl)
528: incl _cnt+V_SOFT
529: POPR; REST_FPSTAT
530: rei
531:
532: /*
533: * Stray VERSAbus interrupt catch routines
534: */
535: .data
536: #define PJ .align 2; callf $4,_Xvstray
537: .globl _catcher
538: _catcher:
539: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
540: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
541: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
542: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
543: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
544: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
545: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
546: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
547: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
548: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
549: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
550: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
551:
552: .align 2
553: .globl _cold
554: _cold: .long 0x3
555:
556: .text
557: SCBVEC(vstray):
558: .word 0
559: bbc $0,_cold,2f # system running?
560: bbc $1,_cold,1f # doing autoconfig?
561: jbr 3f # random interrupt, ignore
562: 1:
563: mfpr $IPL,r12 # ...setup br and cvec
564: subl3 $_catcher+7,-8(fp),r11; shar $3,r11,r11
565: addl2 $SCB_DEVBASE,r11
566: jbr 3f
567: 2:
568: PUSHR
569: subl3 $_catcher+7,-8(fp),r0; shar $3,r0,r0
570: addl3 $SCB_DEVBASE,r0,-(sp);
571: mfpr $IPL,-(sp)
572: PRINTF(2, "stray intr ipl %x vec %x\n")
573: POPR
574: 3: moval 0f,-8(fp); ret # pop callf frame...
575: 0: rei # ...and return
576:
577: /*
578: * Trap and fault vector routines
579: */
580: #define TRAP(a) pushl $T_/**/a; jbr alltraps
581:
582: /*
583: * Ast delivery (profiling and/or reschedule)
584: */
585:
586: SCBVEC(kspnotval):
587: CHECK_SFE(4)
588: pushl $0;
589: SAVE_FPSTAT(8)
590: TRAP(KSPNOTVAL)
591: SCBVEC(privinflt):
592: CHECK_SFE(4)
593: pushl $0;
594: SAVE_FPSTAT(8)
595: TRAP(PRIVINFLT)
596: SCBVEC(resopflt):
597: CHECK_SFE(4)
598: pushl $0;
599: SAVE_FPSTAT(8)
600: TRAP(RESOPFLT)
601: SCBVEC(resadflt):
602: CHECK_SFE(4)
603: pushl $0;
604: SAVE_FPSTAT(8)
605: TRAP(RESADFLT)
606: SCBVEC(bptflt):
607: CHECK_SFE(4)
608: pushl $0;
609: SAVE_FPSTAT(8)
610: TRAP(BPTFLT)
611: SCBVEC(kdbintr):
612: CHECK_SFE(4);
613: pushl $0;
614: SAVE_FPSTAT(8);
615: TRAP(KDBTRAP);
616: SCBVEC(tracep):
617: CHECK_SFE(4)
618: pushl $0;
619: SAVE_FPSTAT(8)
620: TRAP(TRCTRAP)
621: SCBVEC(alignflt):
622: #ifdef ALIGN
623: bitl $PSL_CURMOD,4(sp)
624: jeql align_excp # Can't emulate for kernel mode !
625: jbr non_aligned # Only emulated for user mode.
626: align_excp:
627: #else
628: CHECK_SFE(4)
629: #endif
630: pushl $0;
631: SAVE_FPSTAT(8)
632: TRAP(ALIGNFLT)
633: SCBVEC(arithtrap):
634: CHECK_SFE(8)
635: SAVE_FPSTAT(8)
636: TRAP(ARITHTRAP)
637:
638: SCBVEC(protflt):
639: CHECK_SFE(12)
640: bitl $1,(sp)+
641: jneq segflt
642: SAVE_FPSTAT(8)
643: TRAP(PROTFLT)
644: segflt:
645: SAVE_FPSTAT(8)
646: TRAP(SEGFLT)
647:
648: SCBVEC(fpm): # Floating Point Emulation
649: #ifdef FPE
650: CHECK_SFE(16)
651: SAVE_FPSTAT(16)
652: incl _cnt+V_FPE # count emulation traps
653: callf $4,_fpemulate
654: REST_FPSTAT
655: #endif
656: moval 8(sp),sp # Pop operand
657: tstl (sp) # Stack= PSL, PC, return_code
658: jneq _Xarithtrap # If not OK, emulate F.P. exception
659: movab 4(sp),sp # Else remove return_code and
660: rei
661:
662: SCBVEC(sfexcep):
663: CHECK_SFE(4)
664: pushl $0
665: SAVE_FPSTAT(8)
666: TRAP(ASTFLT)
667:
668: SCBVEC(transflt):
669: CHECK_SFE(12)
670: bitl $2,(sp)+
671: bneq tableflt
672: pageflt:
673: SAVE_FPSTAT(8)
674: TRAP(PAGEFLT)
675: tableflt:
676: SAVE_FPSTAT(8)
677: TRAP(TABLEFLT)
678:
679: #define REST_STACK movab 4(sp), sp; REST_FPSTAT; movab 4(sp), sp
680:
681: alltraps:
682: mfpr $USP,-(sp);
683: callf $4,_trap;
684: mtpr (sp)+,$USP
685: incl _cnt+V_TRAP
686: REST_STACK # pop type, code, and fp stuff
687: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT)
688: rei
689:
690: SCBVEC(syscall):
691: CHECK_SFE(8)
692: SAVE_FPSTAT(8)
693: pushl $T_SYSCALL
694: mfpr $USP,-(sp);
695: callf $4,_syscall;
696: mtpr (sp)+,$USP
697: incl _cnt+V_SYSCALL
698: REST_STACK # pop type, code, and fp stuff
699: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT)
700: rei
701:
702: /*
703: * System page table.
704: *
705: * Mbmap and Usrptmap are enlarged by CLSIZE entries
706: * as they are managed by resource maps starting with index 1 or CLSIZE.
707: */
708: #define vaddr(x) ((((x)-_Sysmap)/4)*NBPG+SYSTEM)
709: #define SYSMAP(mname, vname, npte) \
710: _/**/mname: .globl _/**/mname; \
711: .space (npte)*4; \
712: .globl _/**/vname; \
713: .set _/**/vname,vaddr(_/**/mname)
714: #define ADDMAP(npte) .space (npte)*4
715:
716: .data
717: .align 2
718: SYSMAP(Sysmap ,Sysbase ,SYSPTSIZE )
719: SYSMAP(Forkmap ,forkutl ,UPAGES )
720: SYSMAP(Xswapmap ,xswaputl ,UPAGES )
721: SYSMAP(Xswap2map,xswap2utl ,UPAGES )
722: SYSMAP(Swapmap ,swaputl ,UPAGES )
723: SYSMAP(Pushmap ,pushutl ,UPAGES )
724: SYSMAP(Vfmap ,vfutl ,UPAGES )
725: SYSMAP(CMAP1 ,CADDR1 ,1 )
726: SYSMAP(CMAP2 ,CADDR2 ,1 )
727: SYSMAP(mmap ,vmmap ,1 )
728: SYSMAP(alignmap ,alignutl ,1 ) /* XXX */
729: SYSMAP(msgbufmap,msgbuf ,MSGBUFPTECNT )
730: SYSMAP(Mbmap ,mbutl ,NMBCLUSTERS*MCLBYTES/NBPG+CLSIZE )
731: SYSMAP(kmempt ,kmembase ,300*CLSIZE )
732: #ifdef GPROF
733: SYSMAP(profmap ,profbase ,600*CLSIZE )
734: #endif
735: /*
736: * Enlarge kmempt as needed for bounce buffers allocated
737: * by tahoe controllers.
738: */
739: #include "hd.h"
740: #if NHD > 0
741: ADDMAP( NHDC*(MAXPHYS/NBPG+CLSIZE) )
742: #endif
743: #include "dk.h"
744: #if NDK > 0
745: ADDMAP( NVD*(MAXPHYS/NBPG+CLSIZE) )
746: #endif
747: #include "yc.h"
748: #if NYC > 0
749: ADDMAP( NCY*(MAXPHYS/NBPG+CLSIZE) )
750: #endif
751: #include "mp.h"
752: ADDMAP( NMP*14 )
753: SYSMAP(ekmempt ,kmemlimit ,0 )
754:
755: SYSMAP(VMEMbeg ,vmembeg ,0 )
756: SYSMAP(VMEMmap ,vmem ,VBIOSIZE )
757: SYSMAP(VMEMmap1 ,vmem1 ,0 )
758: #include "ace.h"
759: #if NACE > 0
760: ADDMAP( NACE*32 )
761: #endif
762: #if NHD > 0
763: ADDMAP( NHDC )
764: #endif
765: #include "vx.h"
766: #if NVX > 0
767: ADDMAP( NVX * 16384/NBPG )
768: #endif
769: SYSMAP(VMEMend ,vmemend ,0 )
770:
771: SYSMAP(VBmap ,vbbase ,CLSIZE )
772: #if NHD > 0
773: ADDMAP( NHDC*(MAXPHYS/NBPG+CLSIZE) )
774: #endif
775: #if NDK > 0
776: ADDMAP( NVD*(MAXPHYS/NBPG+CLSIZE) )
777: #endif
778: #if NYC > 0
779: ADDMAP( NCY*(MAXPHYS/NBPG+CLSIZE) )
780: #endif
781: ADDMAP( NMP*14 )
782: SYSMAP(eVBmap ,vbend ,0 )
783:
784: SYSMAP(Usrptmap ,usrpt ,USRPTSIZE+CLSIZE )
785: eSysmap:
786: .globl _Syssize
787: .set _Syssize,(eSysmap-_Sysmap)/4
788:
789: .text
790: /*
791: * Initialization
792: *
793: * IPL 0x1f; MME 0; scbb, pcbb, sbr, slr, isp, ksp not set
794: */
795: .align 2
796: .globl start
797: start:
798: .word 0
799: /* set system control block base and system page table params */
800: mtpr $_scb-SYSTEM,$SCBB
801: mtpr $_Sysmap-SYSTEM,$SBR
802: mtpr $_Syssize,$SLR
803: /* double map the kernel into the virtual user addresses of phys mem */
804: mtpr $_Sysmap,$P0BR
805: mtpr $_Syssize,$P0LR
806: mtpr $_Sysmap,$P1BR # against Murphy
807: mtpr $_Syssize,$P1LR
808: /* set ISP */
809: movl $_intstack-SYSTEM+NISP*NBPG,sp # still physical
810: mtpr $_intstack+NISP*NBPG,$ISP
811: /* count up memory */
812: clrl r7
813: 1: pushl $1; pushl r7; callf $12,_badaddr; tstl r0; bneq 9f
814: ACBL($MAXMEM*1024-1,$64*1024,r7,1b)
815: 9:
816: /* clear memory from kernel bss and pages for proc 0 u. and page table */
817: movab _edata,r6; andl2 $~SYSTEM,r6
818: movab _end,r5; andl2 $~SYSTEM,r5
819: #ifdef KADB
820: subl2 $4,r5
821: 1: clrl (r6); ACBL(r5,$4,r6,1b) # clear just bss
822: addl2 $4,r5
823: bbc $6,r11,0f # check RB_KDB
824: andl3 $~SYSTEM,r9,r5 # skip symbol & string tables
825: andl3 $~SYSTEM,r9,r6
826: #endif
827: 0: orl3 $SYSTEM,r5,r9 # convert to virtual address
828: addl2 $NBPG-1,r9 # roundup to next page
829: addl2 $(UPAGES*NBPG)+NBPG+NBPG,r5
830: 1: clrl (r6); ACBL(r5,$4,r6,1b)
831: /* trap(), syscall(), and fpemulate() save r0-r12 in the entry mask */
832: orw2 $0x01fff,_trap
833: orw2 $0x01fff,_syscall
834: #ifdef FPE
835: orw2 $0x01fff,_fpemulate
836: #endif
837: orw2 $0x01ffc,_panic # for debugging (no r0|r1)
838: callf $4,_fixctlrmask # setup for autoconfig
839: /* initialize system page table: scb and int stack writeable */
840: clrl r2
841: movab eintstack,r1
842: andl2 $~SYSTEM,r1
843: shrl $PGSHIFT,r1,r1 # r1-page number of eintstack
844: /* make 1st page processor storage read/only, 2nd read/write */
845: orl3 $PG_V|PG_KR,r2,_Sysmap[r2]; incl r2;
846: orl3 $PG_V|PG_KW,r2,_Sysmap[r2]; incl r2;
847: /* other parts of the system are read/write for kernel */
848: 1: orl3 $PG_V|PG_KW,r2,_Sysmap[r2]; # data:kernel write+phys=virtual
849: aoblss r1,r2,1b
850: /* make rsstk read-only as red zone for interrupt stack */
851: andl2 $~PG_PROT,_rsstkmap
852: orl2 $PG_V|PG_KR,_rsstkmap
853: /* make kernel text space read-only */
854: movab _etext+NBPG-1,r1
855: andl2 $~SYSTEM,r1
856: shrl $PGSHIFT,r1,r1
857: 1: orl3 $PG_V|PG_KR,r2,_Sysmap[r2]
858: aoblss r1,r2,1b
859: /* make kernel data, bss, read-write */
860: andl3 $~SYSTEM,r9,r1
861: shrl $PGSHIFT,r1,r1
862: 1: orl3 $PG_V|PG_KW,r2,_Sysmap[r2]
863: aoblss r1,r2,1b
864: /* go to mapped mode, have to change both pc and sp to system addresses */
865: mtpr $1,$TBIA
866: mtpr $1,$PADC # needed by HW parity&ECC logic
867: mtpr $1,$PACC # just in case
868: mtpr $1,$MME
869: movab SYSTEM(sp),sp
870: jmp *$0f
871: 0:
872: /* disable any interrupts */
873: movl $0,_intenable
874: /* init mem sizes */
875: shrl $PGSHIFT,r7,_maxmem
876: movl _maxmem,_physmem
877: movl _maxmem,_freemem
878: /* setup context for proc[0] == scheduler */
879: andl3 $~SYSTEM,r9,r6 # convert to physical
880: andl2 $~(NBPG-1),r6 # make page boundary
881: /* setup page table for proc[0] */
882: shrl $PGSHIFT,r6,r3 # r3 = btoc(r6)
883: orl3 $PG_V|PG_KW,r3,_Usrptmap # init first upt entry
884: incl r3 # r3 - next page
885: movab _usrpt,r0 # r0 - first user page
886: mtpr r0,$TBIS
887: /* init p0br, p0lr */
888: mtpr r0,$P0BR # no p0 for proc[0]
889: mtpr $0,$P0LR
890: mtpr r0,$P1BR # no p1 either
891: mtpr $0,$P1LR
892: /* init p2br, p2lr */
893: movab NBPG(r0),r0
894: movl $PPAGES-UPAGES,r1
895: mtpr r1,$P2LR
896: moval -4*PPAGES(r0),r2
897: mtpr r2,$P2BR
898: /* setup mapping for UPAGES of _u */
899: clrl r2
900: movl $SYSTEM,r1
901: addl2 $UPAGES,r3
902: jbr 2f
903: 1: decl r3
904: moval -NBPG(r1),r1 # r1 = virtual add of next (downward) _u page
905: subl2 $4,r0 # r0 = pte address
906: orl3 $PG_V|PG_URKW,r3,(r0)
907: mtpr r1,$TBIS
908: 2: aobleq $UPAGES,r2,1b
909: /* initialize (slightly) the pcb */
910: movab UPAGES*NBPG(r1),PCB_KSP(r1) # KSP starts at end of _u
911: movl r1,PCB_USP(r1) # USP starts just below _u
912: mfpr $P0BR,PCB_P0BR(r1)
913: mfpr $P0LR,PCB_P0LR(r1)
914: mfpr $P1BR,PCB_P1BR(r1)
915: mfpr $P1LR,PCB_P1LR(r1)
916: mfpr $P2BR,PCB_P2BR(r1)
917: mfpr $P2LR,PCB_P2LR(r1)
918: movl $CLSIZE,PCB_SZPT(r1) # init u.u_pcb.pcb_szpt
919: movl r9,PCB_R9(r1) # r9 obtained from boot
920: movl r10,PCB_R10(r1) # r10 obtained from boot
921: movl r11,PCB_R11(r1) # r11 obtained from CP on boot
922: movab 1f,PCB_PC(r1) # initial pc
923: clrl PCB_PSL(r1) # kernel mode, ipl=0
924: shll $PGSHIFT,r3,r3
925: mtpr r3,$PCBB # first pcbb (physical)
926: /* go to kernel mode */
927: ldpctx
928: rei # Actually next instruction:
929: /* put signal trampoline code in u. area */
930: 1: movab sigcode,r0
931: movab _u+PCB_SIGC,r1
932: movl $19,r2
933: movblk
934: /* save boot device in global _bootdev */
935: movl r10,_bootdev
936: /* save reboot flags in global _boothowto */
937: movl r11,_boothowto
938: #ifdef KADB
939: /* save end of symbol & string table in global _bootesym */
940: subl3 $NBPG-1,r9,_bootesym
941: #endif
942: /* calculate firstaddr, and call main() */
943: andl3 $~SYSTEM,r9,r0
944: shrl $PGSHIFT,r0,-(sp)
945: addl2 $UPAGES+1,(sp) # first physical unused page
946: callf $8,_main
947: /* proc[1] == /etc/init now running here in kernel mode; run icode */
948: pushl $PSL_CURMOD # User mode PSL
949: pushl $0 # PC = 0 (virtual now)
950: rei
951:
952: /*
953: * Mask for saving/restoring registers on entry to
954: * a user signal handler. Space for the registers
955: * is reserved in sendsig, so beware if you want
956: * to change the mask.
957: */
958: #define SIGREGS (R0|R1|R2|R3|R4|R5)
959: .align 2
960: .globl sigcode
961: sigcode:
962: storer $SIGREGS,16(sp) # save volatile registers
963: calls $4*3+4,*12(sp) # params pushed by sendsig for handler
964: loadr $SIGREGS,4(sp) # restore volatile registers
965: movab 24(sp),fp # use parameter list set up in sendsig
966: kcall $SYS_sigreturn # cleanup mask and onsigstack
967: halt # sigreturn does not return!
968:
969: .globl _icode
970: .globl _initflags
971: .globl _szicode
972: /*
973: * Icode is copied out to process 1 to exec /etc/init.
974: * If the exec fails, process 1 exits.
975: */
976: .align 2
977: _icode:
978: /* try /sbin/init */
979: pushab b`argv1-l0(pc)
980: l0: pushab b`init1-l1(pc)
981: l1: pushl $2
982: movab (sp),fp
983: kcall $SYS_execv
984: /* try /etc/init */
985: pushab b`argv2-l2(pc)
986: l2: pushab b`init2-l3(pc)
987: l3: pushl $2
988: movab (sp),fp
989: kcall $SYS_execv
990: /* give up */
991: pushl r0
992: pushl $1
993: movab (sp),fp
994: kcall $SYS_exit
995:
996: init1: .asciz "/sbin/init"
997: init2: .asciz "/etc/init"
998: .align 2
999: _initflags:
1000: .long 0
1001: argv1: .long init1+6-_icode
1002: .long _initflags-_icode
1003: .long 0
1004: argv2: .long init2+5-_icode
1005: .long _initflags-_icode
1006: .long 0
1007: _szicode:
1008: .long _szicode-_icode
1009:
1010: /*
1011: * Primitives
1012: */
1013:
1014: /*
1015: * badaddr(addr, len)
1016: * see if access addr with a len type instruction causes a machine check
1017: * len is length of access (1=byte, 2=short, 4=long)
1018: * r0 = 0 means good(exists); r0 =1 means does not exist.
1019: */
1020: ENTRY(badaddr, R3|R4)
1021: mfpr $IPL,r1
1022: mtpr $HIGH,$IPL
1023: movl _scb+SCB_BUSERR,r2
1024: movl 4(fp),r3
1025: movl 8(fp),r4
1026: movab 9f,_scb+SCB_BUSERR
1027: bbc $0,r4,1f; tstb (r3)
1028: 1: bbc $1,r4,1f; tstw (r3)
1029: 1: bbc $2,r4,1f; tstl (r3)
1030: 1: clrl r0
1031: 2: movl r2,_scb+SCB_BUSERR
1032: mtpr r1,$IPL
1033: ret
1034:
1035: /*
1036: * wbadaddr(addr, len, value)
1037: * see if write of value to addr with a len type instruction causes
1038: * a machine check
1039: * len is length of access (1=byte, 2=short, 4=long)
1040: * r0 = 0 means good(exists); r0 =1 means does not exist.
1041: */
1042: ENTRY(wbadaddr, R3|R4)
1043: mfpr $IPL,r1
1044: mtpr $HIGH,$IPL
1045: movl _scb+SCB_BUSERR,r2
1046: movl 4(fp),r3
1047: movl 8(fp),r4
1048: movab 9f,_scb+SCB_BUSERR
1049: bbc $0,r4,1f; movb 15(fp), (r3)
1050: 1: bbc $1,r4,1f; movw 14(fp), (r3)
1051: 1: bbc $2,r4,1f; movl 12(fp), (r3)
1052: 1: movl $30000,r0 # delay for error interrupt
1053: 1: decl r0
1054: jneq 1b
1055: 2: movl r2,_scb+SCB_BUSERR # made it w/o machine checks; r0 is 0
1056: mtpr r1,$IPL
1057: ret
1058:
1059: .align 2
1060: 9: # catch buss error (if it comes)
1061: andl3 4(sp),$ERRCD,r0
1062: cmpl r0,$APE
1063: jneq 1f
1064: halt # address parity error
1065: 1: cmpl r0,$VBE
1066: jneq 1f
1067: halt # Versabus error
1068: 1:
1069: movl $1,r0 # Anything else = bad address
1070: movab 8(sp),sp # discard buss error trash
1071: movab 2b,(sp) # new program counter on stack.
1072: rei
1073:
1074: /*
1075: * badcyaddr(addr)
1076: * see if access tape master controller addr causes a bus error
1077: * r0 = 0: no error; r0 = 1: timeout error.
1078: */
1079: ENTRY(badcyaddr, 0)
1080: mfpr $IPL,r1
1081: mtpr $HIGH,$IPL
1082: clrl r2
1083: movab 2f,nofault
1084: movob $-1, *4(fp)
1085: 1: aobleq $1000, r2, 1b
1086: clrl nofault # made it w/o bus error
1087: clrl r0
1088: jbr 3f
1089: 2: movl $1,r0
1090: 3: mtpr r1,$IPL
1091: ret
1092:
1093: /*
1094: * peek(addr)
1095: * fetch word and catch any bus error
1096: */
1097: ENTRY(peek, 0)
1098: mfpr $IPL,r1
1099: mtpr $0x18,$IPL # not reentrant
1100: movl 4(fp),r2
1101: movab 1f,nofault
1102: movw (r2),r0
1103: clrl nofault
1104: andl2 $0xffff,r0
1105: jbr 2f
1106: 1: movl $-1,r0 # bus error
1107: 2: mtpr r1,$IPL
1108: ret
1109:
1110: /*
1111: * poke(addr, val)
1112: * write word and catch any bus error
1113: */
1114: ENTRY(poke, R3)
1115: mfpr $IPL,r1
1116: mtpr $0x18,$IPL # not reentrant
1117: movl 4(fp),r2
1118: movl 8(fp),r3
1119: clrl r0
1120: movab 1f,nofault
1121: movw r3,(r2)
1122: clrl nofault
1123: jbr 2f
1124: 1: movl $-1,r0 # bus error
1125: 2: mtpr r1,$IPL
1126: ret
1127:
1128: /*
1129: * Copy a potentially overlapping block of memory.
1130: *
1131: * ovbcopy(src, dst, count)
1132: * caddr_t src, dst; unsigned count;
1133: */
1134: ENTRY(ovbcopy, R3|R4)
1135: movl 4(fp),r0
1136: movl 8(fp),r1
1137: movl 12(fp),r2
1138: cmpl r0,r1
1139: bgtru 1f # normal forward case
1140: beql 2f # equal, nothing to do
1141: addl2 r2,r0 # may be overlapping
1142: cmpl r0,r1
1143: bgtru 3f
1144: subl2 r2,r0 # normal forward case
1145: 1:
1146: movblk
1147: 2:
1148: ret
1149: 3:
1150: addl2 r2,r1 # overlapping, must do backwards
1151: subl3 r0,r1,r3
1152: movl r2,r4
1153: jbr 5f
1154: 4:
1155: subl2 r3,r0
1156: subl2 r3,r1
1157: movl r3,r2
1158: movblk
1159: subl2 r3,r0
1160: subl2 r3,r1
1161: subl2 r3,r4
1162: 5:
1163: cmpl r4,r3
1164: jgtr 4b
1165: movl r4,r2
1166: subl2 r2,r0
1167: subl2 r2,r1
1168: movblk
1169: ret
1170:
1171: /*
1172: * Copy a null terminated string from the user address space into
1173: * the kernel address space.
1174: *
1175: * copyinstr(fromaddr, toaddr, maxlength, &lencopied)
1176: */
1177: ENTRY(copyinstr, 0)
1178: movl 12(fp),r5 # r5 = max length
1179: jlss 5f
1180: movl 8(fp),r4 # r4 = kernel address
1181: movl 4(fp),r0 # r0 = user address
1182: andl3 $(NBPG*CLSIZE-1),r0,r2 # r2 = bytes on first page
1183: subl3 r2,$(NBPG*CLSIZE),r2
1184: 1:
1185: cmpl r5,r2 # r2 = min(bytes on page, length left);
1186: jgeq 2f
1187: movl r5,r2
1188: 2:
1189: prober $1,(r0),r2 # bytes accessible?
1190: jeql 5f
1191: subl2 r2,r5 # update bytes left count
1192: movl r2,r3 # r3 = saved count
1193: movl r0,r1
1194: cmps3 # check for null
1195: tstl r2
1196: jneq 3f
1197: subl2 r3,r0 # back up r0
1198: movl r4,r1
1199: movl r3,r2
1200: movblk # copy in next piece
1201: movl r1,r4
1202: movl $(NBPG*CLSIZE),r2 # check next page
1203: tstl r5 # run out of space?
1204: jneq 1b
1205: movl $ENOENT,r0 # set error code and return
1206: jbr 6f
1207: 3:
1208: tstl 16(fp) # return length?
1209: beql 4f
1210: subl3 r5,12(fp),r5 # actual len = maxlen - unused pages
1211: subl2 r2,r5 # - unused on this page
1212: addl3 $1,r5,*16(fp) # + the null byte
1213: 4:
1214: movl r4,r1
1215: subl3 r2,r3,r2 # calc char cnt
1216: subl2 r2,r0 # back up r0
1217: incl r2 # add on null byte
1218: movblk # copy last piece
1219: clrl r0
1220: ret
1221: 5:
1222: movl $EFAULT,r0
1223: 6:
1224: tstl 16(fp)
1225: beql 7f
1226: subl3 r5,12(fp),*16(fp)
1227: 7:
1228: ret
1229:
1230: /*
1231: * Copy a null terminated string from the kernel
1232: * address space to the user address space.
1233: *
1234: * copyoutstr(fromaddr, toaddr, maxlength, &lencopied)
1235: */
1236: ENTRY(copyoutstr, 0)
1237: movl 12(fp),r5 # r5 = max length
1238: jlss 5f
1239: movl 4(fp),r0 # r0 = kernel address
1240: movl 8(fp),r4 # r4 = user address
1241: andl3 $(NBPG*CLSIZE-1),r4,r2 # r2 = bytes on first page
1242: subl3 r2,$(NBPG*CLSIZE),r2
1243: 1:
1244: cmpl r5,r2 # r2 = min(bytes on page, length left);
1245: jgeq 2f
1246: movl r5,r2
1247: 2:
1248: probew $1,(r4),r2 # bytes accessible?
1249: jeql 5f
1250: subl2 r2,r5 # update bytes left count
1251: movl r2,r3 # r3 = saved count
1252: movl r0,r1
1253: /*
1254: * This is a workaround for a microcode bug that causes
1255: * a trap type 9 when cmps3/movs3 touches the last byte
1256: * on a valid page immediately followed by an invalid page.
1257: */
1258: #ifdef good_cmps3
1259: cmps3 # check for null
1260: tstl r2
1261: jneq 3b
1262: #else
1263: decl r2
1264: beql 9f # cannot handle case of r2 == 0!
1265: cmps3 # check for null up to last byte
1266: 9:
1267: incl r2
1268: cmpl $1,r2 # get to last byte on page?
1269: bneq 3b
1270: tstb (r0) # last byte on page null?
1271: beql 3b
1272: incl r0 # not null, so bump pointer
1273: #endif not good_cmps3
1274: subl2 r3,r0 # back up r0
1275: movl r4,r1
1276: movl r3,r2
1277: movblk # copy out next piece
1278: movl r1,r4
1279: movl $(NBPG*CLSIZE),r2 # check next page
1280: tstl r5 # run out of space?
1281: jneq 1b
1282: movl $ENOENT,r0 # set error code and return
1283: jbr 6b
1284: 5:
1285: clrl *$0 # this should never execute, if it does
1286: movl $EFAULT,r0 # save me a core dump (mkm - 9/87)
1287: 6:
1288: tstl 16(fp)
1289: beql 7f
1290: subl3 r5,12(fp),*16(fp)
1291: 7:
1292: ret
1293:
1294:
1295: /*
1296: * Copy a null terminated string from one point to another in
1297: * the kernel address space.
1298: *
1299: * copystr(fromaddr, toaddr, maxlength, &lencopied)
1300: */
1301: ENTRY(copystr, 0)
1302: movl 12(fp),r3 # r3 = max length
1303: jlss 5b
1304: movl 4(fp),r0 # r0 = src address
1305: movl 8(fp),r4 # r4 = dest address
1306: clrl r5 # r5 = bytes left
1307: movl r3,r2 # r2 = max bytes to copy
1308: movl r0,r1
1309: cmps3 # check for null
1310: tstl r2
1311: jneq 3b
1312: subl2 r3,r0 # back up r0
1313: movl r4,r1
1314: movl r3,r2
1315: movblk # copy next piece
1316: movl $ENOENT,r0 # set error code and return
1317: jbr 6b
1318:
1319: /*
1320: * Copy a block of data from the user address space into
1321: * the kernel address space.
1322: *
1323: * copyin(fromaddr, toaddr, count)
1324: */
1325: ENTRY(copyin, 0)
1326: movl 12(fp),r0 # copy length
1327: blss 9f
1328: movl 4(fp),r1 # copy user address
1329: cmpl $(CLSIZE*NBPG),r0 # probing one page or less ?
1330: bgeq 2f # yes
1331: 1:
1332: prober $1,(r1),$(CLSIZE*NBPG) # bytes accessible ?
1333: beql 9f # no
1334: addl2 $(CLSIZE*NBPG),r1 # incr user address ptr
1335: _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r0,1b) # reduce count and loop
1336: 2:
1337: prober $1,(r1),r0 # bytes accessible ?
1338: beql 9f # no
1339: MOVC3(4(fp),8(fp),12(fp))
1340: clrl r0
1341: ret
1342: 9:
1343: movl $EFAULT,r0
1344: ret
1345:
1346: /*
1347: * Copy a block of data from the kernel
1348: * address space to the user address space.
1349: *
1350: * copyout(fromaddr, toaddr, count)
1351: */
1352: ENTRY(copyout, 0)
1353: movl 12(fp),r0 # get count
1354: blss 9b
1355: movl 8(fp),r1 # get user address
1356: cmpl $(CLSIZE*NBPG),r0 # can do in one probew?
1357: bgeq 2f # yes
1358: 1:
1359: probew $1,(r1),$(CLSIZE*NBPG) # bytes accessible?
1360: beql 9b # no
1361: addl2 $(CLSIZE*NBPG),r1 # increment user address
1362: _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r0,1b) # reduce count and loop
1363: 2:
1364: probew $1,(r1),r0 # bytes accessible?
1365: beql 9b # no
1366: MOVC3(4(fp),8(fp),12(fp))
1367: clrl r0
1368: ret
1369:
1370: /*
1371: * non-local goto's
1372: */
1373: #ifdef notdef
1374: ENTRY(setjmp, 0)
1375: movl 4(fp),r0
1376: movl (fp),(r0); addl2 $4,r0 # save fp
1377: movl -8(fp),(r0) # save pc
1378: clrl r0
1379: ret
1380: #endif
1381:
1382: ENTRY(longjmp, 0)
1383: movl 4(fp),r0
1384: movl (r0),newfp; addl2 $4,r0 # must save parameters in memory
1385: movl (r0),newpc # as all regs may be clobbered.
1386: 1:
1387: cmpl fp,newfp # are we there yet?
1388: bgequ 2f # yes
1389: moval 1b,-8(fp) # redirect return pc to us!
1390: ret # pop next frame
1391: 2:
1392: beql 3f # did we miss our frame?
1393: pushab 4f # yep ?!?
1394: callf $8,_panic
1395: 3:
1396: movl newpc,r0 # all done, just return
1397: jmp (r0) # to setjmp `ret'
1398:
1399: .data
1400: newpc: .space 4
1401: newfp: .space 4
1402: 4: .asciz "longjmp"
1403: .text
1404:
1405: /*
1406: * setjmp that saves all registers as the call frame may not
1407: * be available to recover them in the usual manner by longjmp.
1408: * Called before swapping out the u. area, restored by resume()
1409: * below.
1410: */
1411: ENTRY(savectx, 0)
1412: movl 4(fp),r2
1413: storer $0x1ff8,(r2); addl2 $40,r2 # r3-r12
1414: movl (fp),(r2); addl2 $4,r2 # fp
1415: movab 8(fp),(r2); addl2 $4,r2 # sp
1416: movl -8(fp),(r2) # pc
1417: clrl r0
1418: ret
1419:
1420: #ifdef KADB
1421: /*
1422: * C library -- reset, setexit
1423: *
1424: * reset(x)
1425: * will generate a "return" from
1426: * the last call to
1427: * setexit()
1428: * by restoring r2 - r12, fp
1429: * and doing a return.
1430: * The returned value is x; on the original
1431: * call the returned value is 0.
1432: */
1433: ENTRY(setexit, 0)
1434: movab setsav,r0
1435: storer $0x1ffc, (r0)
1436: movl (fp),44(r0) # fp
1437: moval 4(fp),48(r0) # sp
1438: movl -8(fp),52(r0) # pc
1439: clrl r0
1440: ret
1441:
1442: ENTRY(reset, 0)
1443: movl 4(fp),r0 # returned value
1444: movab setsav,r1
1445: loadr $0x1ffc,(r1)
1446: movl 44(r1),fp
1447: movl 48(r1),sp
1448: jmp *52(r1)
1449:
1450: .data
1451: .align 2
1452: setsav: .space 14*4
1453: .text
1454: #endif
1455:
1456: .globl _whichqs
1457: .globl _qs
1458: .globl _cnt
1459:
1460: .globl _noproc
1461: .comm _noproc,4
1462: .globl _runrun
1463: .comm _runrun,4
1464: /*
1465: * The following primitives use the fancy TAHOE instructions.
1466: * _whichqs tells which of the 32 queues _qs
1467: * have processes in them. setrq puts processes into queues, remrq
1468: * removes them from queues. The running process is on no queue,
1469: * other processes are on a queue related to p->p_pri, divided by 4
1470: * actually to shrink the 0-127 range of priorities into the 32 available
1471: * queues.
1472: */
1473:
1474: /*
1475: * setrq(p), using fancy TAHOE instructions.
1476: *
1477: * Call should be made at spl8(), and p->p_stat should be SRUN
1478: */
1479: ENTRY(setrq, 0)
1480: movl 4(fp),r0
1481: tstl P_RLINK(r0) ## firewall: p->p_rlink must be 0
1482: beql set1 ##
1483: pushab set3 ##
1484: callf $8,_panic ##
1485: set1:
1486: movzbl P_PRI(r0),r1 # put on queue which is p->p_pri / 4
1487: shar $2,r1,r1
1488: shal $1,r1,r2
1489: moval _qs[r2],r2
1490: insque (r0),*4(r2) # at end of queue
1491: shal r1,$1,r1
1492: orl2 r1,_whichqs # mark queue non-empty
1493: ret
1494:
1495: set3: .asciz "setrq"
1496:
1497: /*
1498: * remrq(p), using fancy TAHOE instructions
1499: *
1500: * Call should be made at spl8().
1501: */
1502: ENTRY(remrq, 0)
1503: movl 4(fp),r0
1504: movzbl P_PRI(r0),r1
1505: shar $2,r1,r1
1506: bbs r1,_whichqs,rem1
1507: pushab rem3 # it wasn't recorded to be on its q
1508: callf $8,_panic
1509: rem1:
1510: remque (r0)
1511: bneq rem2 # q not empty yet
1512: shal r1,$1,r1
1513: mcoml r1,r1
1514: andl2 r1,_whichqs # mark queue empty
1515: rem2:
1516: clrl P_RLINK(r0) ## for firewall checking
1517: ret
1518:
1519: rem3: .asciz "remrq"
1520:
1521: /*
1522: * Masterpaddr is the p->p_addr of the running process on the master
1523: * processor. When a multiprocessor system, the slave processors will have
1524: * an array of slavepaddr's.
1525: */
1526: .globl _masterpaddr
1527: .data
1528: .align 2
1529: _masterpaddr: .long 0
1530:
1531: .text
1532: sw0: .asciz "swtch"
1533:
1534: /*
1535: * When no processes are on the runq, swtch branches to idle
1536: * to wait for something to come ready.
1537: */
1538: .globl Idle
1539: Idle: idle:
1540: movl $1,_noproc
1541: mtpr $0,$IPL # must allow interrupts here
1542: 1:
1543: tstl _whichqs # look for non-empty queue
1544: bneq sw1
1545: brb 1b
1546:
1547: badsw: pushab sw0
1548: callf $8,_panic
1549: /* NOTREACHED */
1550:
1551: .align 2
1552: /*
1553: * swtch(), using fancy tahoe instructions
1554: */
1555: ENTRY(swtch, 0)
1556: movl (fp),fp # prepare for rei
1557: movl (sp),4(sp) # saved pc
1558: tstl (sp)+
1559: movpsl 4(sp)
1560: incl _cnt+V_SWTCH
1561: sw1: ffs _whichqs,r0 # look for non-empty queue
1562: blss idle # if none, idle
1563: mtpr $0x18,$IPL # lock out all so _whichqs==_qs
1564: bbc r0,_whichqs,sw1 # proc moved via interrupt
1565: shal $1,r0,r1
1566: moval _qs[r1],r1
1567: movl (r1),r2 # r2 = p = highest pri process
1568: remque *(r1)
1569: bvs badsw # make sure something was there
1570: bneq sw2
1571: shal r0,$1,r1
1572: mcoml r1,r1
1573: andl2 r1,_whichqs # no more procs in this queue
1574: sw2:
1575: clrl _noproc
1576: clrl _runrun
1577: #ifdef notdef
1578: tstl P_WCHAN(r2) ## firewalls
1579: bneq badsw ##
1580: cmpb P_STAT(r2),$SRUN ##
1581: bneq badsw ##
1582: #endif
1583: clrl P_RLINK(r2) ##
1584: movl *P_ADDR(r2),r0
1585: #ifdef notdef
1586: cmpl r0,_masterpaddr # resume of current proc is easy
1587: beql res0
1588: #endif
1589: movl r0,_masterpaddr
1590: shal $PGSHIFT,r0,r0 # r0 = pcbb(p)
1591: brb swresume
1592:
1593: /*
1594: * resume(pf)
1595: */
1596: ENTRY(resume, 0)
1597: shal $PGSHIFT,4(fp),r0 # r0 = pcbb(pf)
1598: movl (fp),fp # prepare for rei
1599: movl (sp)+,4(sp) # saved pc
1600: tstl (sp)+
1601: movpsl 4(sp)
1602: swresume:
1603: mtpr $0x18,$IPL # no interrupts, please
1604: movl _CMAP2,_u+PCB_CMAP2 # yech
1605: REST_ACC # restore original accumulator
1606: svpctx
1607: mtpr r0,$PCBB
1608: ldpctx
1609: movl _u+PCB_CMAP2,_CMAP2 # yech
1610: mtpr $_CADDR2,$TBIS
1611: res0:
1612: movl _u+U_PROCP,r2 # r2 = u.u_procp
1613: tstl P_CKEY(r2) # does proc have code key?
1614: bneq 1f
1615: callf $4,_getcodekey # no, give him one
1616: movl _u+U_PROCP,r2 # r2 = u.u_procp
1617: movl r0,P_CKEY(r2)
1618: 1:
1619: tstl P_DKEY(r2) # does proc have data key?
1620: bneq 1f
1621: callf $4,_getdatakey # no, give him one
1622: movl _u+U_PROCP,r2 # r2 = u.u_procp
1623: movl r0,P_DKEY(r2)
1624: 1:
1625: mtpr P_CKEY(r2),$CCK # set code cache key
1626: mtpr P_DKEY(r2),$DCK # set data cache key
1627: tstl _u+PCB_SSWAP
1628: bneq res1
1629: rei
1630: res1: # longjmp to saved context
1631: movl _u+PCB_SSWAP,r2
1632: clrl _u+PCB_SSWAP
1633: loadr $0x3ff8,(r2); addl2 $44,r2 # restore r3-r13 (r13=fp)
1634: movl (r2),r1; addl2 $4,r2 # fetch previous sp ...
1635: movab (sp),r0 # ... and current sp and
1636: cmpl r1,r0 # check for credibility,
1637: bgequ 1f # if further up stack ...
1638: pushab 2f; callf $8,_panic # ... panic
1639: /*NOTREACHED*/
1640: 1: # sp ok, complete return
1641: movl r1,sp # restore sp
1642: pushl $PSL_PRVMOD # kernel mode, ipl 0
1643: pushl (r2) # return address
1644: rei
1645: 2: .asciz "ldctx"
1646:
1647: /*
1648: * {fu,su},{byte,word}
1649: */
1650: ENTRY(fuword, 0)
1651: movl 4(fp), r1
1652: prober $1,(r1),$4 # check access
1653: beql fserr # page unreadable
1654: bitl $1,r1 # check byte alignment
1655: bneq 2f # odd, do byte-word-byte
1656: bitl $2,r1 # check word alignment
1657: bneq 1f # odd, do in 2 words
1658: movl (r1),r0 # move longword
1659: ret
1660: 1:
1661: movw (r1),r0 # move two words
1662: shal $16,r0,r0
1663: movzwl 2(r1),r1 # orw2 sign extends
1664: orl2 r1,r0
1665: ret
1666: 2:
1667: movb (r1),r0 # move byte-word-byte
1668: shal $24,r0,r0
1669: movzwl 1(r1),r2 # orw2 sign extends
1670: shal $8,r2,r2
1671: movzbl 3(r1),r1 # orb2 sign extends
1672: orl2 r2,r1
1673: orl2 r1,r0
1674: ret
1675: fserr:
1676: mnegl $1,r0
1677: ret
1678:
1679: ENTRY(fubyte, 0)
1680: prober $1,*4(fp),$1
1681: beql fserr
1682: movzbl *4(fp),r0
1683: ret
1684:
1685: ENTRY(suword, 0)
1686: movl 4(fp), r0
1687: probew $1,(r0),$4 # check access
1688: beql fserr # page unwritable
1689: bitl $1,r0 # check byte alignment
1690: bneq 1f # odd byte boundary
1691: bitl $2,r0 # check word alignment
1692: beql 2f # longword aligned
1693: movw 8(fp),(r0) # move two words
1694: movw 10(fp),2(r0)
1695: jbr 3f
1696: 1:
1697: movb 8(fp),(r0)
1698: movb 9(fp),1(r0)
1699: movb 10(fp),2(r0)
1700: movb 11(fp),3(r0)
1701: jbr 3f
1702: 2:
1703: movl 8(fp),(r0)
1704: 3:
1705: clrl r0
1706: ret
1707:
1708: ENTRY(subyte, 0)
1709: probew $1,*4(fp),$1
1710: beql fserr
1711: movb 11(fp),*4(fp)
1712: clrl r0
1713: ret
1714:
1715: /*
1716: * Copy 1 relocation unit (NBPG bytes)
1717: * from user virtual address to physical address
1718: */
1719: ENTRY(copyseg, 0)
1720: orl3 $PG_V|PG_KW,8(fp),_CMAP2
1721: mtpr $_CADDR2,$TBIS # invalidate entry for copy
1722: MOVC3(4(fp),$_CADDR2,$NBPG)
1723: ret
1724:
1725: /*
1726: * Clear a page of memory. The page frame is specified.
1727: *
1728: * clearseg(pf);
1729: */
1730: ENTRY(clearseg, 0)
1731: orl3 $PG_V|PG_KW,4(fp),_CMAP1 # Maps to virtual addr CADDR1
1732: mtpr $_CADDR1,$TBIS
1733: movl $255,r0 # r0 = limit
1734: clrl r1 # r1 = index of cleared long
1735: 1:
1736: clrl _CADDR1[r1]
1737: aobleq r0,r1,1b
1738: ret
1739:
1740: /*
1741: * Check user mode read/write access.
1742: *
1743: * useracc(addr, count, mode)
1744: * caddr_t addr; int count, mode;
1745: * mode = 0 write access
1746: * mode = 1 read access
1747: */
1748: ENTRY(useracc, 0)
1749: movl $1,r2 # r2 = 'user mode' for probew/probew
1750: probes:
1751: movl 4(fp),r0 # get va
1752: movl 8(fp),r1 # count
1753: tstl 12(fp) # test for read access ?
1754: bneq userar # yes
1755: cmpl $(CLSIZE*NBPG),r1 # can we do it in one probe ?
1756: bgeq uaw2 # yes
1757: uaw1:
1758: probew r2,(r0),$(CLSIZE*NBPG)
1759: beql uaerr # no access
1760: addl2 $(CLSIZE*NBPG),r0
1761: _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r1,uaw1)
1762: uaw2:
1763: probew r2,(r0),r1
1764: beql uaerr
1765: movl $1,r0
1766: ret
1767: userar:
1768: cmpl $(CLSIZE*NBPG),r1
1769: bgeq uar2
1770: uar1:
1771: prober r2,(r0),$(CLSIZE*NBPG)
1772: beql uaerr
1773: addl2 $(CLSIZE*NBPG),r0
1774: _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r1,uar1)
1775: uar2:
1776: prober r2,(r0),r1
1777: beql uaerr
1778: movl $1,r0
1779: ret
1780: uaerr:
1781: clrl r0
1782: ret
1783:
1784: /*
1785: * Check kernel mode read/write access.
1786: *
1787: * kernacc(addr, count, mode)
1788: * caddr_t addr; int count, mode;
1789: * mode = 0 write access
1790: * mode = 1 read access
1791: */
1792: ENTRY(kernacc, 0)
1793: clrl r2 # r2 = 0 means kernel mode probe.
1794: jbr probes # Dijkstra would get gastric distress here.
1795:
1796: /*
1797: * addupc - increment some histogram counter
1798: * in the profiling buffer
1799: *
1800: * addupc(pc, prof, delta)
1801: * long pc; short delta; struct uprof *prof;
1802: *
1803: * struct uprof { # profile arguments
1804: * short *r_base; # buffer base
1805: * unsigned pr_size; # buffer size
1806: * unsigned pr_off; # pc offset
1807: * unsigned pr_scale; # pc scaling
1808: * }
1809: */
1810: ENTRY(addupc, 0)
1811: movl 8(fp),r2 # r2 points to structure
1812: subl3 8(r2),4(fp),r0 # r0 = PC - lowpc
1813: jlss 9f # PC < lowpc , out of range !
1814: shrl $1,r0,r0 # the unit is words
1815: shrl $1,12(r2),r1 # ditto for scale
1816: emul r1,r0,$0,r0
1817: shrq $14,r0,r0
1818: tstl r0 # too big
1819: jneq 9f
1820: cmpl r1,4(r2) # Check buffer overflow
1821: jgequ 9f
1822: probew $1,*0(r2)[r1],$2 # counter accessible?
1823: jeql 9f
1824: shrl $1,r1,r1 # make r1 word index
1825: addw2 14(fp),*0(r2)[r1]
1826: 9: ret
1827:
1828: /*
1829: * scanc(size, cp, table, mask)
1830: */
1831: ENTRY(scanc, R3|R4)
1832: movl 8(fp),r0 # r0 = cp
1833: addl3 4(fp),r0,r2 # end = &cp[size]
1834: movl 12(fp),r1 # r1 = table
1835: movb 19(fp),r4 # r4 = mask
1836: decl r0 # --cp
1837: jbr 0f # just like Fortran...
1838: 1: # do {
1839: movzbl (r0),r3
1840: bitb r4,(r1)[r3] # if (table[*cp] & mask)
1841: jneq 2f # break;
1842: 0: aoblss r2,r0,1b # } while (++cp < end);
1843: 2:
1844: subl3 r0,r2,r0; ret # return (end - cp);
1845:
1846: /*
1847: * skpc(mask, size, cp)
1848: */
1849: ENTRY(skpc, 0)
1850: movl 12(fp),r0 # r0 = cp
1851: addl3 8(fp),r0,r1 # r1 = end = &cp[size];
1852: movb 7(fp),r2 # r2 = mask
1853: decl r0 # --cp;
1854: jbr 0f
1855: 1: # do
1856: cmpb (r0),r2 # if (*cp != mask)
1857: jneq 2f # break;
1858: 0: aoblss r1,r0,1b # while (++cp < end);
1859: 2:
1860: subl3 r0,r1,r0; ret # return (end - cp);
1861:
1862: /*
1863: * locc(mask, size, cp)
1864: */
1865: ENTRY(locc, 0)
1866: movl 12(fp),r0 # r0 = cp
1867: addl3 8(fp),r0,r1 # r1 = end = &cp[size]
1868: movb 7(fp),r2 # r2 = mask
1869: decl r0 # --cp;
1870: jbr 0f
1871: 1: # do
1872: cmpb (r0),r2 # if (*cp == mask)
1873: jeql 2f # break;
1874: 0: aoblss r1,r0,1b # while (++cp < end);
1875: 2:
1876: subl3 r0,r1,r0; ret # return (end - cp);
1877:
1878: #ifdef ALIGN
1879: #include "../tahoealign/align.h"
1880:
1881: .globl _alignment
1882: /*
1883: * There's an intimate relationship between this piece of code
1884: * and the alignment emulation code (especially the layout
1885: * of local variables in alignment.c! Don't change unless
1886: * you update both this, alignment.h and alignment.c !!
1887: */
1888: non_aligned:
1889: orb2 $EMULATEALIGN,_u+U_EOSYS
1890: incl _cnt+V_TRAP
1891: incl _cnt+V_ALIGN # count emulated alignment traps
1892: moval 4(sp),_user_psl
1893: SAVE_FPSTAT(4) # Also zeroes out ret_exception !
1894: pushl $0 # ret_addr
1895: pushl $0 # ret_code
1896: mfpr $USP,-(sp) # user sp
1897: callf $4,_alignment # call w/o parms so regs may be modified
1898: /*
1899: * We return here after a successful emulation or an exception.
1900: * The registers have been restored and we must not alter them
1901: * before returning to the user.
1902: */
1903: 2: mtpr (sp)+,$USP # restore user sp
1904: tstl 8(sp) # Any exception ?
1905: bneq got_excp # Yes, reflect it back to user.
1906: moval 8(sp),sp # pop 2 zeroes pushed above
1907: REST_FPSTAT
1908: xorb2 $EMULATEALIGN,_u+U_EOSYS
1909:
1910: bitl $PSL_T,4(sp) # check for trace bit set
1911: beql 9f
1912: CHECK_SFE(4)
1913: pushl $0
1914: SAVE_FPSTAT(8)
1915: TRAP(TRCTRAP)
1916: 9: rei
1917:
1918: got_excp: # decode exception
1919: casel 8(sp),$ILL_ADDRMOD,$ALIGNMENT
1920: .align 1
1921: L1:
1922: .word ill_addrmod-L1
1923: .word ill_access-L1
1924: .word ill_oprnd-L1
1925: .word arithmetic-L1
1926: .word alignment-L1
1927: brw alignment # default - shouldn't come here at all !
1928:
1929: ill_addrmod: # No other parameters. Set up stack as
1930: moval 8(sp),sp # the HW would do it in a real case.
1931: REST_FPSTAT
1932: jbr _Xresadflt
1933: ill_oprnd:
1934: moval 8(sp),sp
1935: REST_FPSTAT
1936: jbr _Xresopflt
1937: alignment:
1938: moval 8(sp),sp
1939: REST_FPSTAT
1940: jbr align_excp # NB: going to _Xalignflt would cause loop
1941: ill_access:
1942: /*
1943: * Must restore accumulator w/o modifying sp and w/o using
1944: * registers. Solution: copy things needed by REST_FPSTAT.
1945: */
1946: pushl 20(sp) # The flags longword
1947: pushl 20(sp) # acc_low
1948: pushl 20(sp) # acc_high
1949: pushl 20(sp) # ret_exception ignored by REST_FPSTAT
1950: REST_FPSTAT # Back where we were with the sp !
1951: movl (sp),16(sp) # code for illegal access
1952: movl 4(sp),20(sp) # original virtual address
1953: moval 16(sp),sp # Just like the HW would set it up
1954: jbr _Xprotflt
1955: arithmetic: # same trickery as above
1956: pushl 20(sp) # The flags longword
1957: pushl 20(sp) # acc_low
1958: pushl 20(sp) # acc_high
1959: pushl 20(sp) # ret_exception ignored by REST_FPSTAT
1960: REST_FPSTAT # Back where we were with the sp !
1961: movl (sp),20(sp) # code for arithmetic exception
1962: moval 20(sp),sp # Just like the HW would set it up
1963: jbr _Xarithtrap
1964: #endif
1965: SCBVEC(hdintr0):
1966: CHECK_SFE(4)
1967: SAVE_FPSTAT(4)
1968: PUSHR
1969: incl _fltintrcnt+(4*0)
1970: pushl $0
1971: callf $8,_hdintr
1972: incl _cnt+V_INTR
1973: POPR
1974: REST_FPSTAT
1975: rei
1976:
1977: SCBVEC(hdintr1):
1978: CHECK_SFE(4)
1979: SAVE_FPSTAT(4)
1980: PUSHR
1981: incl _fltintrcnt+(4*1)
1982: pushl $1
1983: callf $8,_hdintr
1984: incl _cnt+V_INTR
1985: POPR
1986: REST_FPSTAT
1987: rei
1988:
1989: SCBVEC(vdintr0):
1990: CHECK_SFE(4)
1991: SAVE_FPSTAT(4)
1992: PUSHR
1993: incl _fltintrcnt+(4*2)
1994: pushl $0
1995: callf $8,_vdintr
1996: incl _cnt+V_INTR
1997: POPR
1998: REST_FPSTAT
1999: rei
2000:
2001: SCBVEC(vdintr1):
2002: CHECK_SFE(4)
2003: SAVE_FPSTAT(4)
2004: PUSHR
2005: incl _fltintrcnt+(4*3)
2006: pushl $1
2007: callf $8,_vdintr
2008: incl _cnt+V_INTR
2009: POPR
2010: REST_FPSTAT
2011: rei
2012:
2013: SCBVEC(vdintr2):
2014: CHECK_SFE(4)
2015: SAVE_FPSTAT(4)
2016: PUSHR
2017: incl _fltintrcnt+(4*4)
2018: pushl $2
2019: callf $8,_vdintr
2020: incl _cnt+V_INTR
2021: POPR
2022: REST_FPSTAT
2023: rei
2024:
2025: SCBVEC(vackint0):
2026: CHECK_SFE(4)
2027: SAVE_FPSTAT(4)
2028: PUSHR
2029: incl _fltintrcnt+(4*5)
2030: pushl $0
2031: callf $8,_vackint
2032: incl _cnt+V_INTR
2033: POPR
2034: REST_FPSTAT
2035: rei
2036:
2037: SCBVEC(vcmdrsp0):
2038: CHECK_SFE(4)
2039: SAVE_FPSTAT(4)
2040: PUSHR
2041: incl _fltintrcnt+(4*6)
2042: pushl $0
2043: callf $8,_vcmdrsp
2044: incl _cnt+V_INTR
2045: POPR
2046: REST_FPSTAT
2047: rei
2048:
2049: SCBVEC(vunsol0):
2050: CHECK_SFE(4)
2051: SAVE_FPSTAT(4)
2052: PUSHR
2053: incl _fltintrcnt+(4*7)
2054: pushl $0
2055: callf $8,_vunsol
2056: incl _cnt+V_INTR
2057: POPR
2058: REST_FPSTAT
2059: rei
2060:
2061: SCBVEC(vackint1):
2062: CHECK_SFE(4)
2063: SAVE_FPSTAT(4)
2064: PUSHR
2065: incl _fltintrcnt+(4*8)
2066: pushl $1
2067: callf $8,_vackint
2068: incl _cnt+V_INTR
2069: POPR
2070: REST_FPSTAT
2071: rei
2072:
2073: SCBVEC(vcmdrsp1):
2074: CHECK_SFE(4)
2075: SAVE_FPSTAT(4)
2076: PUSHR
2077: incl _fltintrcnt+(4*9)
2078: pushl $1
2079: callf $8,_vcmdrsp
2080: incl _cnt+V_INTR
2081: POPR
2082: REST_FPSTAT
2083: rei
2084:
2085: SCBVEC(vunsol1):
2086: CHECK_SFE(4)
2087: SAVE_FPSTAT(4)
2088: PUSHR
2089: incl _fltintrcnt+(4*10)
2090: pushl $1
2091: callf $8,_vunsol
2092: incl _cnt+V_INTR
2093: POPR
2094: REST_FPSTAT
2095: rei
2096:
2097: SCBVEC(exintr0):
2098: CHECK_SFE(4)
2099: SAVE_FPSTAT(4)
2100: PUSHR
2101: incl _fltintrcnt+(4*11)
2102: pushl $0
2103: callf $8,_exintr
2104: incl _cnt+V_INTR
2105: POPR
2106: REST_FPSTAT
2107: rei
2108:
2109:
2110: .globl _intrnames
2111:
2112: .globl _eintrnames
2113: .data
2114: _intrnames:
2115: .asciz "clock"
2116: .asciz "cnr"
2117: .asciz "cnx"
2118: .asciz "rmtr"
2119: .asciz "rmtx"
2120: .asciz "buserr"
2121: .asciz "hd0"
2122: .asciz "hd1"
2123: .asciz "vd0"
2124: .asciz "vd1"
2125: .asciz "vd2"
2126: .asciz "vack0"
2127: .asciz "vcmdrsp0"
2128: .asciz "vunsol0"
2129: .asciz "vack1"
2130: .asciz "vcmdrsp1"
2131: .asciz "vunsol1"
2132: .asciz "ex0"
2133: _eintrnames:
2134:
2135: .globl _intrcnt
2136:
2137: .globl _eintrcnt
2138: .align 2
2139: _intrcnt:
2140: .space 4 * 6
2141: _fltintrcnt:
2142: .space 4 * 12
2143: _eintrcnt:
2144:
2145: .text
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.