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