|
|
1.1 root 1: /*
2: * Copyright (c) 1980, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)locore.s 7.12 (Berkeley) 5/27/88
7: */
8:
9: #include "psl.h"
10: #include "pte.h"
11:
12: #include "errno.h"
13: #include "cmap.h"
14:
15: #include "mtpr.h"
16: #include "trap.h"
17: #include "cpu.h"
18: #include "nexus.h"
19: #include "cons.h"
20: #include "clock.h"
21: #include "ioa.h"
22: #include "ka630.h"
23: #include "ka820.h"
24: #include "../vaxuba/ubareg.h"
25:
26: #include "dz.h"
27: #include "uu.h"
28: #include "ps.h"
29: #include "mba.h"
30: #include "uba.h"
31:
32: .set HIGH,0x1f # mask for total disable
33: .set MCKVEC,4 # offset into scb of machine check vector
34: .set NBPG,512
35: .set PGSHIFT,9
36: .set SYSTEM,0x80000000 # virtual address of system start
37:
38: .set NISP,3 # number of interrupt stack pages
39:
40: /*
41: * User structure is UPAGES at top of user space.
42: */
43: .globl _u
44: .set _u,0x80000000 - UPAGES*NBPG
45:
46: .globl _intstack
47: _intstack:
48: .space NISP*NBPG
49: eintstack:
50:
51: /*
52: * Do a dump.
53: * Called by auto-restart.
54: * May be called manually.
55: */
56: .align 2
57: .globl _doadump
58: .globl _msgbufmapped
59: _doadump:
60: nop; nop # .word 0x0101
61: #define _rpbmap _Sysmap # rpb, scb, UNIvec[], istack*4
62: bicl2 $PG_PROT,_rpbmap
63: bisl2 $PG_KW,_rpbmap
64: mtpr $0,$TBIA
65: tstl _rpb+RP_FLAG # dump only once!
66: bneq 1f
67: incl _rpb+RP_FLAG
68: movl sp,erpb
69: movab erpb,sp
70: mfpr $PCBB,-(sp)
71: mfpr $MAPEN,-(sp)
72: mfpr $IPL,-(sp)
73: clrl _msgbufmapped
74: mtpr $0,$MAPEN
75: mtpr $HIGH,$IPL
76: pushr $0x3fff
77: calls $0,_dumpsys
78: 1:
79: clrl r11 # boot flags
80: calls $0,_vaxboot
81: halt
82:
83: /*
84: * Interrupt vector routines
85: */
86: .globl _waittime
87:
88: #define SCBVEC(name) .align 2; .globl _X/**/name; _X/**/name
89: #define PANIC(msg) clrl _waittime; pushab 1f; \
90: calls $1,_panic; 1: .asciz msg
91: #define PRINTF(n,msg) pushab 1f; calls $n+1,_printf; MSG(msg)
92: #define MSG(msg) .data; 1: .asciz msg; .text
93: #define PUSHR pushr $0x3f
94: #define POPR popr $0x3f
95:
96: .data
97: nofault: .long 0 # where to go on predicted machcheck
98: .text
99: SCBVEC(machcheck):
100: tstl nofault
101: bneq 1f
102: PUSHR; pushab 6*4(sp); calls $1,_machinecheck; POPR;
103: addl2 (sp)+,sp; rei
104: .align 2
105: 1:
106: casel _cpu,$1,$VAX_MAX
107: 0:
108: .word 8f-0b # 1 is 780
109: .word 5f-0b # 2 is 750
110: .word 5f-0b # 3 is 730
111: .word 7f-0b # 4 is 8600
112: .word 5f-0b # 5 is 8200
113: .word 1f-0b # 6 is 8800 (unsupported)
114: .word 1f-0b # 7 is 610 (unsupported)
115: .word 1f-0b # 8 is 630
116: 5:
117: #if defined(VAX8200) || defined(VAX750) || defined(VAX730)
118: mtpr $0xf,$MCESR
119: #endif
120: brb 1f
121: 7:
122: #if VAX8600
123: mtpr $0,$EHSR
124: #endif
125: brb 1f
126: 8:
127: #if VAX780
128: mtpr $0,$SBIFS
129: #endif
130: 1:
131: addl2 (sp)+,sp # discard mchchk trash
132: movl nofault,(sp)
133: rei
134: SCBVEC(kspnotval):
135: PANIC("KSP not valid");
136: SCBVEC(powfail):
137: halt
138: SCBVEC(chme): SCBVEC(chms): SCBVEC(chmu):
139: PANIC("CHM? in kernel");
140:
141: SCBVEC(nex0zvec):
142: PUSHR
143: clrl r0
144: brb 1f
145: SCBVEC(nex1zvec):
146: PUSHR
147: movl $1,r0
148: 1:
149: cmpl _cpu,$VAX_8600 # this is a frill
150: beql 2f
151: mfpr $IPL,-(sp)
152: PRINTF(1, "nexus stray intr ipl%x\n")
153: POPR
154: rei
155: 2:
156: pushl r0
157: mfpr $IPL,-(sp)
158: PRINTF(2, "nexus stray intr ipl%x sbia%d\n")
159: POPR
160: rei
161:
162: SCBVEC(cmrd):
163: PUSHR; calls $0,_memerr; POPR; rei
164:
165: SCBVEC(wtime): /* sbi0err on 8600 */
166: #if VAX8600
167: cmpl _cpu,$VAX_8600
168: bneq wtimo
169: PANIC("sbia0 error")
170: wtimo:
171: #endif
172: PUSHR; pushl 6*4(sp); PRINTF(1, "write timeout %x\n"); POPR
173: PANIC("wtimo")
174:
175: SCBVEC(sbi0fail):
176: PANIC("sbia0 fail")
177: SCBVEC(sbi0alert):
178: #if VAX8200
179: cmpl _cpu,$VAX_8200
180: bneq alert
181: PUSHR; calls $0,_rxcdintr; POPR; rei
182: alert:
183: #endif
184: PANIC("sbia0 alert")
185: SCBVEC(sbi0fault):
186: PANIC("sbia0 fault")
187:
188: #ifdef notyet
189: #if VAX8600
190: SCBVEC(sbi1fail):
191: PANIC("sbia1 fail")
192: SCBVEC(sbi1alert):
193: PANIC("sbia1 alert")
194: SCBVEC(sbi1fault):
195: PANIC("sbia1 fault")
196: SCBVEC(sbi1err):
197: PANIC("sbia1 error")
198: #endif
199: #endif
200:
201: /*
202: * BI 0 bus error (8200), or SBI silo compare error (others)
203: * VMS boot leaves us 1 BI error to ignore.
204: */
205: #if VAX8200 && 0
206: .data
207: .align 2
208: _ignorebi: .globl _ignorebi
209: .long 1
210: .text
211: #endif VAX8200
212:
213: SCBVEC(sbisilo):
214: #if VAX8200
215: cmpl _cpu,$VAX_8200
216: bneq sbisilo
217: #if 0
218: blbs _ignorebi,1f
219: #else
220: blbs _cold,1f
221: #endif
222: PUSHR; pushl $0; calls $1,_bi_buserr; POPR
223: 1:
224: rei
225: #endif
226: sbisilo:
227: PANIC("sbi silo compare error")
228:
229: /*
230: * SCB stray interrupt catcher. Compute and print the actual
231: * SCB vector (for fault diagnosis).
232: */
233: .align 2
234: _scbstray: .globl _scbstray
235: #define PJ PUSHR;jsb 1f
236: /* 128 of 'em */
237: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
238: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
239: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
240: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
241: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
242: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
243: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
244: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
245: #if VAX8600
246: /* and another 128, for the second SBIA's scb */
247: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
248: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
249: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
250: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
251: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
252: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
253: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
254: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
255: #endif
256: #undef PJ
257: 1:
258: subl3 $_scbstray+8,(sp)+,r0
259: mfpr $IPL,-(sp)
260: ashl $-1,r0,-(sp)
261: /* call a C handler instead? perhaps later */
262: PRINTF(2, "stray scb intr vec 0x%x ipl%x\n")
263: POPR
264: rei
265:
266: #if NMBA > 0
267: SCBVEC(mba3int):
268: PUSHR; incl _intrcnt+I_MBA3; pushl $3; brb 1f
269: SCBVEC(mba2int):
270: PUSHR; incl _intrcnt+I_MBA2; pushl $2; brb 1f
271: SCBVEC(mba1int):
272: PUSHR; incl _intrcnt+I_MBA1; pushl $1; brb 1f
273: SCBVEC(mba0int):
274: PUSHR; incl _intrcnt+I_MBA0; pushl $0
275: 1: calls $1,_mbintr
276: POPR
277: incl _cnt+V_INTR
278: rei
279: #endif
280:
281: #ifdef DW780
282: /*
283: * Registers for the uba handling code
284: */
285: #define rUBANUM r0
286: #define rUBAHD r1
287: #define rUVEC r3
288: #define rUBA r4
289: /* r2,r5 are scratch */
290:
291: #define I_UBA I_UBA0 /* base of UBA interrupt counters */
292:
293: #if NUBA > 4
294: SCBVEC(ua7int):
295: PUSHR; movl $7,rUBANUM; moval _uba_hd+(7*UH_SIZE),rUBAHD; brb 1f
296: SCBVEC(ua6int):
297: PUSHR; movl $6,rUBANUM; moval _uba_hd+(6*UH_SIZE),rUBAHD; brb 1f
298: SCBVEC(ua5int):
299: PUSHR; movl $5,rUBANUM; moval _uba_hd+(5*UH_SIZE),rUBAHD; brb 1f
300: SCBVEC(ua4int):
301: PUSHR; movl $4,rUBANUM; moval _uba_hd+(4*UH_SIZE),rUBAHD; brb 1f
302: #endif
303: SCBVEC(ua3int):
304: PUSHR; movl $3,rUBANUM; moval _uba_hd+(3*UH_SIZE),rUBAHD; brb 1f
305: SCBVEC(ua2int):
306: PUSHR; movl $2,rUBANUM; moval _uba_hd+(2*UH_SIZE),rUBAHD; brb 1f
307: SCBVEC(ua1int):
308: PUSHR; movl $1,rUBANUM; moval _uba_hd+(1*UH_SIZE),rUBAHD; brb 1f
309: SCBVEC(ua0int):
310: PUSHR; movl $0,rUBANUM; moval _uba_hd+(0*UH_SIZE),rUBAHD;
311: 1:
312: mfpr $IPL,r2 /* r2 = mfpr(IPL); */
313: movl UH_UBA(rUBAHD),rUBA /* uba = uhp->uh_uba; */
314: movl UBA_BRRVR-0x14*4(rUBA)[r2],rUVEC
315: /* uvec = uba->uba_brrvr[r2-0x14] */
316: ubanorm:
317: bleq ubaerror
318: addl2 UH_VEC(rUBAHD),rUVEC /* uvec += uh->uh_vec */
319: bicl3 $3,(rUVEC),r1
320: jmp 2(r1) /* 2 skips ``pushr $0x3f'' */
321: ubaerror:
322: PUSHR; calls $0,_ubaerror; POPR /* ubaerror r/w's r0-r5 */
323: tstl rUVEC; jneq ubanorm /* rUVEC contains result */
324: incl _intrcnt+I_UBA[rUBANUM]
325: incl _cnt+V_INTR
326: POPR
327: rei
328: #endif
329: SCBVEC(cnrint):
330: PUSHR; calls $0,_cnrint; POPR
331: incl _cnt+V_INTR
332: incl _intrcnt+I_CNR
333: rei
334: SCBVEC(cnxint):
335: PUSHR; calls $0,_cnxint; POPR
336: incl _cnt+V_INTR
337: incl _intrcnt+I_CNX
338: rei
339: SCBVEC(hardclock):
340: PUSHR
341: mtpr $ICCS_RUN|ICCS_IE|ICCS_INT|ICCS_ERR,$ICCS
342: #if NPS > 0
343: pushl 4+6*4(sp); pushl 4+6*4(sp);
344: calls $2,_psextsync
345: #endif
346: pushl 4+6*4(sp); pushl 4+6*4(sp);
347: calls $2,_hardclock # hardclock(pc,psl)
348: POPR;
349: incl _cnt+V_INTR
350: incl _intrcnt+I_CLOCK
351: rei
352: SCBVEC(softclock):
353: PUSHR
354: pushl 4+6*4(sp); pushl 4+6*4(sp);
355: calls $2,_softclock # softclock(pc,psl)
356: POPR;
357: incl _cnt+V_SOFT
358: rei
359:
360: #include "../net/netisr.h"
361: .globl _netisr
362: SCBVEC(netintr):
363: PUSHR
364: #include "imp.h"
365: #if NIMP > 0
366: bbcc $NETISR_IMP,_netisr,1f; calls $0,_impintr; 1:
367: #endif
368: #ifdef INET
369: bbcc $NETISR_IP,_netisr,1f; calls $0,_ipintr; 1:
370: #endif
371: #ifdef NS
372: bbcc $NETISR_NS,_netisr,1f; calls $0,_nsintr; 1:
373: #endif
374: bbcc $NETISR_RAW,_netisr,1f; calls $0,_rawintr; 1:
375: POPR
376: incl _cnt+V_SOFT
377: rei
378:
379: SCBVEC(consdin):
380: PUSHR;
381: incl _intrcnt+I_TUR
382: casel _cpu,$VAX_750,$VAX_8200
383: 0:
384: .word 5f-0b # 2 is VAX_750
385: .word 3f-0b # 3 is VAX_730
386: .word 6f-0b # 4 is VAX_8600
387: .word 7f-0b # 5 is VAX_8200
388: halt
389: 5:
390: #if defined(VAX750) && !defined(MRSP)
391: jsb tudma
392: #endif
393: 3:
394: #if defined(VAX750) || defined(VAX730)
395: calls $0,_turintr
396: brb 2f
397: #else
398: halt
399: #endif
400: 7:
401: #if VAX8200
402: calls $0,_rx50intr
403: brb 2f
404: #else
405: halt
406: #endif
407: 6:
408: #if VAX8600
409: calls $0,_crlintr
410: #else
411: halt
412: #endif
413: 2:
414: POPR
415: incl _cnt+V_INTR
416: rei
417:
418: #if defined(VAX750) || defined(VAX730)
419: SCBVEC(consdout):
420: PUSHR; calls $0,_tuxintr; POPR
421: incl _cnt+V_INTR
422: incl _intrcnt+I_TUX
423: rei
424: #else
425: SCBVEC(consdout):
426: halt
427: #endif
428:
429: #if NDZ > 0
430: /*
431: * DZ pseudo dma routine:
432: * r0 - controller number
433: */
434: .align 1
435: .globl dzdma
436: dzdma:
437: mull2 $8*20,r0
438: movab _dzpdma(r0),r3 # pdma structure base
439: # for this controller
440: dzploop:
441: movl r3,r0
442: movl (r0)+,r1 # device register address
443: movzbl 1(r1),r2 # get line number
444: bitb $0x80,r2 # TRDY on?
445: beql dzprei # no
446: bicb2 $0xf8,r2 # clear garbage bits
447: mull2 $20,r2
448: addl2 r2,r0 # point at line's pdma structure
449: movl (r0)+,r2 # p_mem
450: cmpl r2,(r0)+ # p_mem < p_end ?
451: bgequ dzpcall # no, go call dzxint
452: movb (r2)+,6(r1) # dztbuf = *p_mem++
453: movl r2,-8(r0)
454: brb dzploop # check for another line
455: dzprei:
456: POPR
457: incl _cnt+V_PDMA
458: rei
459:
460: dzpcall:
461: pushl r3
462: pushl (r0)+ # push tty address
463: calls $1,*(r0) # call interrupt rtn
464: movl (sp)+,r3
465: brb dzploop # check for another line
466: #endif
467:
468: #if NUU > 0 && defined(UUDMA)
469: /*
470: * Pseudo DMA routine for tu58 (on DL11)
471: * r0 - controller number
472: */
473: .align 1
474: .globl uudma
475: uudma:
476: movl _uudinfo[r0],r2
477: movl 16(r2),r2 # r2 = uuaddr
478: mull3 $48,r0,r3
479: movab _uu_softc(r3),r5 # r5 = uuc
480:
481: cvtwl 2(r2),r1 # c = uuaddr->rdb
482: bbc $15,r1,1f # if (c & UUDB_ERROR)
483: movl $13,16(r5) # uuc->tu_state = TUC_RCVERR;
484: rsb # let uurintr handle it
485: 1:
486: tstl 4(r5) # if (uuc->tu_rcnt) {
487: beql 1f
488: movb r1,*0(r5) # *uuc->tu_rbptr++ = r1
489: incl (r5)
490: decl 4(r5) # if (--uuc->tu_rcnt)
491: beql 2f # done
492: tstl (sp)+
493: POPR # registers saved in ubglue.s
494: rei # }
495: 2:
496: cmpl 16(r5),$8 # if (uuc->tu_state != TUS_GETH)
497: beql 2f # let uurintr handle it
498: 1:
499: rsb
500: 2:
501: mull2 $14,r0 # sizeof(uudata[ctlr]) = 14
502: movab _uudata(r0),r4 # data = &uudata[ctlr];
503: cmpb $1,(r4) # if (data->pk_flag != TUF_DATA)
504: bneq 1b
505: #ifdef notdef
506: /* this is for command packets */
507: beql 1f # r0 = uuc->tu_rbptr
508: movl (r5),r0
509: brb 2f
510: 1: # else
511: #endif
512: movl 24(r5),r0 # r0 = uuc->tu_addr
513: 2:
514: movzbl 1(r4),r3 # counter to r3 (data->pk_count)
515: movzwl (r4),r1 # first word of checksum (=header)
516: mfpr $IPL,-(sp) # s = spl5();
517: mtpr $0x15,$IPL # to keep disk interrupts out
518: clrw (r2) # disable receiver interrupts
519: 3: bbc $7,(r2),3b # while ((uuaddr->rcs & UUCS_READY)==0);
520: cvtwb 2(r2),(r0)+ # *buffer = uuaddr->rdb & 0xff
521: sobgtr r3,1f # continue with next byte ...
522: addw2 2(r2),r1 # unless this was the last (odd count)
523: brb 2f
524:
525: 1: bbc $7,(r2),1b # while ((uuaddr->rcs & UUCS_READY)==0);
526: cvtwb 2(r2),(r0)+ # *buffer = uuaddr->rdb & 0xff
527: addw2 -2(r0),r1 # add to checksum..
528: 2:
529: adwc $0,r1 # get the carry
530: sobgtr r3,3b # loop while r3 > 0
531: /*
532: * We're ready to get the checksum
533: */
534: 1: bbc $7,(r2),1b # while ((uuaddr->rcs & UUCS_READY)==0);
535: cvtwb 2(r2),12(r4) # get first (lower) byte
536: 1: bbc $7,(r2),1b
537: cvtwb 2(r2),13(r4) # ..and second
538: cmpw 12(r4),r1 # is checksum ok?
539: beql 1f
540: movl $14,16(r5) # uuc->tu_state = TUS_CHKERR
541: brb 2f # exit
542: 1:
543: movl $11,16(r5) # uuc->tu_state = TUS_GET (ok)
544: 2:
545: movw $0x40,(r2) # enable receiver interrupts
546: mtpr (sp)+,$IPL # splx(s);
547: rsb # continue processing in uurintr
548: #endif
549:
550: #if defined(VAX750) && !defined(MRSP)
551: /*
552: * Pseudo DMA routine for VAX-11/750 console tu58
553: * (without MRSP)
554: */
555: .align 1
556: .globl tudma
557: tudma:
558: movab _tu,r5 # r5 = tu
559: tstl 4(r5) # if (tu.tu_rcnt) {
560: beql 3f
561: mfpr $CSRD,r1 # get data from tu58
562: movb r1,*0(r5) # *tu.tu_rbptr++ = r1
563: incl (r5)
564: decl 4(r5) # if (--tu.tu_rcnt)
565: beql 1f # done
566: tstl (sp)+
567: POPR # registers saved in ubglue.s
568: rei # data handled, done
569: 1: # }
570: cmpl 16(r5),$8 # if (tu.tu_state != TUS_GETH)
571: beql 2f # let turintr handle it
572: 3:
573: rsb
574: 2:
575: movab _tudata,r4 # r4 = tudata
576: cmpb $1,(r4) # if (tudata.pk_flag != TUF_DATA)
577: bneq 3b # let turintr handle it
578: 1: # else
579: movl 24(r5),r1 # get buffer pointer to r1
580: movzbl 1(r4),r3 # counter to r3
581: movzwl (r4),r0 # first word of checksum (=header)
582: mtpr $0,$CSRS # disable receiver interrupts
583: 3:
584: bsbw 5f # wait for next byte
585: mfpr $CSRD,r5
586: movb r5,(r1)+ # *buffer = rdb
587: sobgtr r3,1f # continue with next byte ...
588: mfpr $CSRD,r2 # unless this was the last (odd count)
589: brb 2f
590:
591: 1: bsbw 5f # wait for next byte
592: mfpr $CSRD,r5
593: movb r5,(r1)+ # *buffer = rdb
594: movzwl -2(r1),r2 # get the last word back from memory
595: 2:
596: addw2 r2,r0 # add to checksum..
597: adwc $0,r0 # get the carry
598: sobgtr r3,3b # loop while r3 > 0
599: /*
600: * We're ready to get the checksum.
601: */
602: bsbw 5f
603: movab _tudata,r4
604: mfpr $CSRD,r5
605: movb r5,12(r4) # get first (lower) byte
606: bsbw 5f
607: mfpr $CSRD,r5
608: movb r5,13(r4) # ..and second
609: movab _tu,r5
610: cmpw 12(r4),r0 # is checksum ok?
611: beql 1f
612: movl $14,16(r5) # tu.tu_state = TUS_CHKERR
613: brb 2f # exit
614: 1:
615: movl $11,16(r5) # tu.tu_state = TUS_GET
616: 2:
617: mtpr $0x40,$CSRS # enable receiver interrupts
618: rsb # continue processing in turintr
619: /*
620: * Loop until a new byte is ready from
621: * the tu58, make sure we don't loop forever
622: */
623: 5:
624: movl $5000,r5 # loop max 5000 times
625: 1:
626: mfpr $CSRS,r2
627: bbs $7,r2,1f
628: sobgtr r5,1b
629: movab _tu,r5
630: movl $13,16(r5) # return TUS_RCVERR
631: tstl (sp)+ # and let turintr handle it
632: 1:
633: rsb
634: #endif
635:
636: /*
637: * BI passive release things.
638: */
639: SCBVEC(passiverel):
640: rei # well that was useless
641:
642: /*
643: * Stray UNIBUS interrupt catch routines
644: */
645: .data
646: .align 2
647: #define PJ PUSHR;jsb _Xustray
648: .globl _catcher
649: _catcher:
650: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
651: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
652: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
653: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
654: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
655: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
656: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
657: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
658:
659: .globl _cold
660: _cold: .long 1
661: .data
662:
663: .text
664: SCBVEC(ustray):
665: blbc _cold,1f
666: mfpr $IPL,r11
667: subl3 $_catcher+8,(sp)+,r10
668: ashl $-1,r10,r10
669: POPR
670: rei
671: 1:
672: subl3 $_catcher+8,(sp)+,r0
673: ashl $-1,r0,-(sp)
674: mfpr $IPL,-(sp)
675: PRINTF(2, "uba?: stray intr ipl %x vec %o\n")
676: POPR
677: rei
678:
679: #ifdef VAX630
680: /*
681: * Emulation OpCode jump table:
682: * ONLY GOES FROM 0xf8 (-8) TO 0x3B (59)
683: */
684: #define EMUTABLE 0x43
685: #define NOEMULATE .long noemulate
686: #define EMULATE(a) .long _EM/**/a
687: .globl _emJUMPtable
688: _emJUMPtable:
689: /* f8 */ EMULATE(ashp); EMULATE(cvtlp); NOEMULATE; NOEMULATE
690: /* fc */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
691: /* 00 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
692: /* 04 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
693: /* 08 */ EMULATE(cvtps); EMULATE(cvtsp); NOEMULATE; EMULATE(crc)
694: /* 0c */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
695: /* 10 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
696: /* 14 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
697: /* 18 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
698: /* 1c */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
699: /* 20 */ EMULATE(addp4); EMULATE(addp6); EMULATE(subp4); EMULATE(subp6)
700: /* 24 */ EMULATE(cvtpt); EMULATE(mulp); EMULATE(cvttp); EMULATE(divp)
701: /* 28 */ NOEMULATE; EMULATE(cmpc3); EMULATE(scanc); EMULATE(spanc)
702: /* 2c */ NOEMULATE; EMULATE(cmpc5); EMULATE(movtc); EMULATE(movtuc)
703: /* 30 */ NOEMULATE; NOEMULATE; NOEMULATE; NOEMULATE
704: /* 34 */ EMULATE(movp); EMULATE(cmpp3); EMULATE(cvtpl); EMULATE(cmpp4)
705: /* 38 */ EMULATE(editpc); EMULATE(matchc); EMULATE(locc); EMULATE(skpc)
706: #endif
707:
708: /*
709: * Trap and fault vector routines
710: */
711: #define TRAP(a) pushl $T_/**/a; jbr alltraps
712:
713: /*
714: * Ast delivery (profiling and/or reschedule)
715: */
716: SCBVEC(astflt):
717: pushl $0; TRAP(ASTFLT)
718: SCBVEC(privinflt):
719: pushl $0; TRAP(PRIVINFLT)
720: SCBVEC(xfcflt):
721: pushl $0; TRAP(XFCFLT)
722: SCBVEC(resopflt):
723: pushl $0; TRAP(RESOPFLT)
724: SCBVEC(resadflt):
725: pushl $0; TRAP(RESADFLT)
726: SCBVEC(bptflt):
727: pushl $0; TRAP(BPTFLT)
728: SCBVEC(compatflt):
729: TRAP(COMPATFLT);
730: SCBVEC(kdbintr):
731: pushl $0; TRAP(KDBTRAP)
732: SCBVEC(tracep):
733: pushl $0; TRAP(TRCTRAP)
734: SCBVEC(arithtrap):
735: TRAP(ARITHTRAP)
736: SCBVEC(protflt):
737: blbs (sp)+,segflt
738: TRAP(PROTFLT)
739: segflt:
740: TRAP(SEGFLT)
741:
742: /*
743: * The following is called with the stack set up as follows:
744: *
745: * (sp): Opcode
746: * 4(sp): Instruction PC
747: * 8(sp): Operand 1
748: * 12(sp): Operand 2
749: * 16(sp): Operand 3
750: * 20(sp): Operand 4
751: * 24(sp): Operand 5
752: * 28(sp): Operand 6
753: * 32(sp): Operand 7 (unused)
754: * 36(sp): Operand 8 (unused)
755: * 40(sp): Return PC
756: * 44(sp): Return PSL
757: * 48(sp): TOS before instruction
758: *
759: * Each individual routine is called with the stack set up as follows:
760: *
761: * (sp): Return address of trap handler
762: * 4(sp): Opcode (will get return PSL)
763: * 8(sp): Instruction PC
764: * 12(sp): Operand 1
765: * 16(sp): Operand 2
766: * 20(sp): Operand 3
767: * 24(sp): Operand 4
768: * 28(sp): Operand 5
769: * 32(sp): Operand 6
770: * 36(sp): saved register 11
771: * 40(sp): saved register 10
772: * 44(sp): Return PC
773: * 48(sp): Return PSL
774: * 52(sp): TOS before instruction
775: */
776:
777: SCBVEC(emulate):
778: #ifdef VAX630
779: movl r11,32(sp) # save register r11 in unused operand
780: movl r10,36(sp) # save register r10 in unused operand
781: cvtbl (sp),r10 # get opcode
782: addl2 $8,r10 # shift negative opcodes
783: subl3 r10,$EMUTABLE,r11 # forget it if opcode is out of range
784: bcs noemulate
785: movl _emJUMPtable[r10],r10 # call appropriate emulation routine
786: jsb (r10) # routines put return values into regs 0-5
787: movl 32(sp),r11 # restore register r11
788: movl 36(sp),r10 # restore register r10
789: insv (sp),$0,$4,44(sp) # and condition codes in Opcode spot
790: addl2 $40,sp # adjust stack for return
791: rei
792: noemulate:
793: addl2 $48,sp # adjust stack for
794: #endif VAX630
795: .word 0xffff # "reserved instruction fault"
796: SCBVEC(emulateFPD):
797: .word 0xffff # "reserved instruction fault"
798: SCBVEC(transflt):
799: bitl $2,(sp)+
800: bnequ tableflt
801: jsb Fastreclaim # try and avoid pagein
802: TRAP(PAGEFLT)
803: tableflt:
804: TRAP(TABLEFLT)
805:
806: alltraps:
807: mfpr $USP,-(sp); calls $0,_trap; mtpr (sp)+,$USP
808: incl _cnt+V_TRAP
809: addl2 $8,sp # pop type, code
810: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT)
811: rei
812:
813: SCBVEC(syscall):
814: pushl $T_SYSCALL
815: mfpr $USP,-(sp); calls $0,_syscall; mtpr (sp)+,$USP
816: incl _cnt+V_SYSCALL
817: addl2 $8,sp # pop type, code
818: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT)
819: rei
820:
821: /*
822: * System page table
823: * Mbmap and Usrptmap are enlarged by CLSIZE entries
824: * as they are managed by resource maps starting with index 1 or CLSIZE.
825: */
826: #define vaddr(x) ((((x)-_Sysmap)/4)*NBPG+0x80000000)
827: #define SYSMAP(mname, vname, npte) \
828: _/**/mname: .globl _/**/mname; \
829: .space (npte)*4; \
830: .globl _/**/vname; \
831: .set _/**/vname,vaddr(_/**/mname)
832:
833: .data
834: .align 2
835: SYSMAP(Sysmap ,Sysbase ,SYSPTSIZE )
836: SYSMAP(Forkmap ,forkutl ,UPAGES )
837: SYSMAP(Xswapmap ,xswaputl ,UPAGES )
838: SYSMAP(Xswap2map,xswap2utl ,UPAGES )
839: SYSMAP(Swapmap ,swaputl ,UPAGES )
840: SYSMAP(Pushmap ,pushutl ,UPAGES )
841: SYSMAP(Vfmap ,vfutl ,UPAGES )
842: SYSMAP(CMAP1 ,CADDR1 ,1 )
843: SYSMAP(CMAP2 ,CADDR2 ,1 )
844: SYSMAP(mmap ,vmmap ,1 )
845: SYSMAP(alignmap ,alignutl ,1 ) /* XXX */
846: SYSMAP(msgbufmap,msgbuf ,MSGBUFPTECNT )
847: SYSMAP(Mbmap ,mbutl ,NMBCLUSTERS*CLSIZE+CLSIZE )
848: SYSMAP(kmempt ,kmembase ,200*CLSIZE )
849: #ifdef GPROF
850: SYSMAP(profmap ,profbase ,600*CLSIZE )
851: #endif
852: SYSMAP(ekmempt ,kmemlimit ,0 )
853:
854: SYSMAP(UMBAbeg ,umbabeg ,0 )
855: SYSMAP(Nexmap ,nexus ,16*MAXNNEXUS )
856: SYSMAP(UMEMmap ,umem ,(UBAPAGES+UBAIOPAGES)*NUBA )
857: #if VAX8600
858: SYSMAP(Ioamap ,ioa ,MAXNIOA*IOAMAPSIZ/NBPG )
859: #endif
860: #if VAX8200 || VAX630
861: SYSMAP(Clockmap ,ka630clock ,1 )
862: #endif
863: #if VAX8200
864: /* alas, the clocks on the 8200 and 630 are not quite identical */
865: /* they could be shared for now, but this seemed cleaner */
866: .globl _ka820clock; .set _ka820clock,_ka630clock
867: SYSMAP(Ka820map ,ka820port ,1 )
868: SYSMAP(RX50map ,rx50device ,1 )
869: #ifdef notyet
870: SYSMAP(BRAMmap ,ka820bootram ,KA820_BRPAGES )
871: SYSMAP(EEPROMmap,ka820eeprom ,KA820_EEPAGES )
872: #endif
873: #endif
874: #if VAX630
875: SYSMAP(Ka630map ,ka630cpu ,1 )
876: /*
877: * qvss and qdss can't coexist - one map will suffice
878: * for either. qvss is 256K each and qdss is 64K each.
879: */
880: #include "qv.h"
881: #include "qd.h"
882: #if NQV > 0 || NQD > 0
883: SYSMAP(QVmap ,qvmem ,((512*NQV)+(128*NQD)))
884: #endif /* NQV || NQD */
885: #endif /* VAX630 */
886: SYSMAP(UMBAend ,umbaend ,0 )
887:
888: SYSMAP(Usrptmap ,usrpt ,USRPTSIZE+CLSIZE )
889:
890: eSysmap:
891: .globl _Syssize
892: .set _Syssize,(eSysmap-_Sysmap)/4
893: .text
894:
895: /*
896: * Initialization
897: *
898: * ipl 0x1f; mapen 0; scbb, pcbb, sbr, slr, isp, ksp not set
899: */
900: .data
901: .globl _cpu
902: _cpu: .long 0
903: .text
904: .globl start
905: start:
906: .word 0
907: mtpr $0,$ICCS
908: /* set system control block base and system page table params */
909: mtpr $_scb-0x80000000,$SCBB
910: mtpr $_Sysmap-0x80000000,$SBR
911: mtpr $_Syssize,$SLR
912: /* double map the kernel into the virtual user addresses of phys mem */
913: mtpr $_Sysmap,$P0BR
914: mtpr $_Syssize,$P0LR
915: /* set ISP and get cpu type */
916: movl $_intstack+NISP*NBPG,sp
917: mfpr $SID,r0
918: movab _cpu,r1
919: extzv $24,$8,r0,(r1)
920: /* init RPB */
921: movab _rpb,r0
922: movl r0,(r0)+ # rp_selfref
923: movab _doadump,r1
924: movl r1,(r0)+ # rp_dumprout
925: movl $0x1f,r2
926: clrl r3
927: 1: addl2 (r1)+,r3; sobgtr r2,1b
928: movl r3,(r0)+ # rp_chksum
929: /* count up memory */
930: clrl r7
931: 1: pushl $4; pushl r7; calls $2,_badaddr; tstl r0; bneq 9f
932: acbl $MAXMEM*1024-1,$64*1024,r7,1b
933: 9:
934: #ifdef VAX630
935: /* leave an area for uVAX II console scratch pad at the top */
936: cmpb _cpu,$VAX_630
937: bneq 1f
938: subl2 $4096,r7
939: 1:
940: #endif
941: /* clear memory from kernel bss and pages for proc 0 u. and page table */
942: movab _edata,r6; bicl2 $SYSTEM,r6
943: movab _end,r5; bicl2 $SYSTEM,r5
944: #ifdef KADB
945: subl2 $4,r5
946: 1: clrl (r6); acbl r5,$4,r6,1b # clear just bss
947: addl2 $4,r5
948: bbc $6,r11,0f # check RB_KDB
949: bicl3 $SYSTEM,r9,r5 # skip symbol & string tables
950: bicl3 $SYSTEM,r9,r6 # r9 obtained from boot
951: #endif
952: 0: bisl3 $SYSTEM,r5,r9 # convert to virtual address
953: addl2 $NBPG-1,r9 # roundup to next page
954: addl2 $(UPAGES*NBPG)+NBPG+NBPG,r5
955: 1: clrq (r6); acbl r5,$8,r6,1b
956: /* trap() and syscall() save r0-r11 in the entry mask (per ../h/reg.h) */
957: /* panic() is convenient place to save all for debugging */
958: bisw2 $0x0fff,_trap
959: bisw2 $0x0fff,_syscall
960: bisw2 $0x0fff,_panic
961: calls $0,_fixctlrmask
962: /* initialize system page table: uba vectors and int stack writeable */
963: clrl r2
964: movab eintstack,r1; bbcc $31,r1,0f; 0: ashl $-PGSHIFT,r1,r1
965: 1: bisl3 $PG_V|PG_KW,r2,_Sysmap[r2]; aoblss r1,r2,1b
966: /*
967: * make rpb read-only as red zone for interrupt stack
968: * (scb(s) and UNIvec are write-protected later)
969: */
970: bicl2 $PG_PROT,_rpbmap
971: bisl2 $PG_KR,_rpbmap
972: /* make kernel text space read-only */
973: movab _etext+NBPG-1,r1; bbcc $31,r1,0f; 0: ashl $-PGSHIFT,r1,r1
974: 1: bisl3 $PG_V|PG_URKR,r2,_Sysmap[r2]; aoblss r1,r2,1b
975: /* make kernel data, bss, read-write */
976: bicl3 $SYSTEM,r9,r1; ashl $-PGSHIFT,r1,r1
977: 1: bisl3 $PG_V|PG_KW,r2,_Sysmap[r2]; aoblss r1,r2,1b
978: /* now go to mapped mode */
979: mtpr $0,$TBIA; mtpr $1,$MAPEN; jmp *$0f; 0:
980: /* init mem sizes */
981: ashl $-PGSHIFT,r7,_maxmem
982: movl _maxmem,_physmem
983: movl _maxmem,_freemem
984: /* setup context for proc[0] == Scheduler */
985: bicl3 $SYSTEM|(NBPG-1),r9,r6 # make phys, page boundary
986: /* setup page table for proc[0] */
987: ashl $-PGSHIFT,r6,r3 # r3 = btoc(r6)
988: bisl3 $PG_V|PG_KW,r3,_Usrptmap # init first upt entry
989: incl r3
990: movab _usrpt,r0
991: mtpr r0,$TBIS
992: /* init p0br, p0lr */
993: mtpr r0,$P0BR
994: mtpr $0,$P0LR
995: /* init p1br, p1lr */
996: movab NBPG(r0),r0
997: movl $0x200000-UPAGES,r1
998: mtpr r1,$P1LR
999: mnegl r1,r1
1000: moval -4*UPAGES(r0)[r1],r2
1001: mtpr r2,$P1BR
1002: /* setup mapping for UPAGES of _u */
1003: movl $UPAGES,r2; movab _u+NBPG*UPAGES,r1; addl2 $UPAGES,r3; jbr 2f
1004: 1: decl r3
1005: moval -NBPG(r1),r1;
1006: bisl3 $PG_V|PG_URKW,r3,-(r0)
1007: mtpr r1,$TBIS
1008: 2: sobgeq r2,1b
1009: /* initialize (slightly) the pcb */
1010: movab UPAGES*NBPG(r1),PCB_KSP(r1)
1011: mnegl $1,PCB_ESP(r1)
1012: mnegl $1,PCB_SSP(r1)
1013: movl r1,PCB_USP(r1)
1014: mfpr $P0BR,PCB_P0BR(r1)
1015: mfpr $P0LR,PCB_P0LR(r1)
1016: movb $4,PCB_P0LR+3(r1) # disable ast
1017: mfpr $P1BR,PCB_P1BR(r1)
1018: mfpr $P1LR,PCB_P1LR(r1)
1019: movl $CLSIZE,PCB_SZPT(r1) # init u.u_pcb.pcb_szpt
1020: movl r9,PCB_R9(r1)
1021: movl r10,PCB_R10(r1)
1022: movl r11,PCB_R11(r1)
1023: movab 1f,PCB_PC(r1) # initial pc
1024: clrl PCB_PSL(r1) # mode(k,k), ipl=0
1025: ashl $PGSHIFT,r3,r3
1026: mtpr r3,$PCBB # first pcbb
1027: /* set regs, p0br, p0lr, p1br, p1lr, astlvl, ksp and change to kernel mode */
1028: ldpctx
1029: rei
1030: /* put signal trampoline code in u. area */
1031: 1: movab _u,r0
1032: movc3 $19,sigcode,PCB_SIGC(r0)
1033: /* save boot device in global _bootdev */
1034: movl r10,_bootdev
1035: /* save reboot flags in global _boothowto */
1036: movl r11,_boothowto
1037: #ifdef KADB
1038: /* save end of symbol & string table in global _bootesym */
1039: subl3 $NBPG-1,r9,_bootesym
1040: #endif
1041: /* calculate firstaddr, and call main() */
1042: bicl3 $SYSTEM,r9,r0; ashl $-PGSHIFT,r0,-(sp)
1043: addl2 $UPAGES+1,(sp); calls $1,_main
1044: /* proc[1] == /etc/init now running here; run icode */
1045: pushl $PSL_CURMOD|PSL_PRVMOD; pushl $0; rei
1046:
1047: /* signal trampoline code: it is known that this code takes exactly 19 bytes */
1048: /* in ../vax/pcb.h and in the movc3 above */
1049: sigcode:
1050: calls $4,8(pc) # params pushed by sendsig
1051: movl sp,ap # calls frame built by sendsig
1052: chmk $103 # cleanup mask and onsigstack
1053: halt # sigreturn() does not return!
1054: .word 0x3f # registers 0-5
1055: callg (ap),*16(ap) # call the signal handler
1056: ret # return to code above
1057:
1058: .set exec,11
1059: .set exit,1
1060: .globl _icode
1061: .globl _initflags
1062: .globl _szicode
1063: /*
1064: * Icode is copied out to process 1 to exec /etc/init.
1065: * If the exec fails, process 1 exits.
1066: */
1067: _icode:
1068: pushab b`argv-l0(pc)
1069: l0: pushab b`init-l1(pc)
1070: l1: pushl $2
1071: movl sp,ap
1072: chmk $exec
1073: pushl r0
1074: chmk $exit
1075:
1076: init: .asciz "/etc/init"
1077: .align 2
1078: _initflags:
1079: .long 0
1080: argv: .long init+5-_icode
1081: .long _initflags-_icode
1082: .long 0
1083: _szicode:
1084: .long _szicode-_icode
1085:
1086: /*
1087: * Primitives
1088: */
1089:
1090: #ifdef GPROF
1091: #define ENTRY(name, regs) \
1092: .globl _/**/name; .align 1; _/**/name: .word regs; jsb mcount
1093: #define JSBENTRY(name, regs) \
1094: .globl _/**/name; _/**/name: \
1095: movl fp,-(sp); movab -12(sp),fp; pushr $(regs); jsb mcount; \
1096: popr $(regs); movl (sp)+,fp
1097: #else
1098: #define ENTRY(name, regs) \
1099: .globl _/**/name; .align 1; _/**/name: .word regs
1100: #define JSBENTRY(name, regs) \
1101: .globl _/**/name; _/**/name:
1102: #endif GPROF
1103: #define R0 0x01
1104: #define R1 0x02
1105: #define R2 0x04
1106: #define R3 0x08
1107: #define R4 0x10
1108: #define R5 0x20
1109: #define R6 0x40
1110:
1111: /*
1112: * badaddr(addr, len)
1113: * see if access addr with a len type instruction causes a machine check
1114: * len is length of access (1=byte, 2=short, 4=long)
1115: */
1116: .globl _badaddr
1117: _badaddr:
1118: .word 0
1119: movl $1,r0
1120: mfpr $IPL,r1
1121: mtpr $HIGH,$IPL
1122: movl 4(ap),r3
1123: movl 8(ap),r4
1124: movab 2f,nofault # jump to 2f on machcheck
1125: bbc $0,r4,1f; tstb (r3)
1126: 1: bbc $1,r4,1f; tstw (r3)
1127: 1: bbc $2,r4,1f; tstl (r3)
1128: 1: clrl r0 # made it w/o machine checks
1129: 2: clrl nofault
1130: mtpr r1,$IPL
1131: ret
1132:
1133: /*
1134: * update profiling information for the user
1135: * addupc(pc, &u.u_prof, ticks)
1136: */
1137: ENTRY(addupc, 0)
1138: movl 8(ap),r2 # &u.u_prof
1139: subl3 8(r2),4(ap),r0 # corrected pc
1140: blss 9f
1141: extzv $1,$31,r0,r0 # logical right shift
1142: extzv $1,$31,12(r2),r1 # ditto for scale
1143: emul r1,r0,$0,r0
1144: ashq $-14,r0,r0
1145: tstl r1
1146: bneq 9f
1147: bicl2 $1,r0
1148: cmpl r0,4(r2) # length
1149: bgequ 9f
1150: addl2 (r2),r0 # base
1151: probew $3,$2,(r0)
1152: beql 8f
1153: addw2 12(ap),(r0)
1154: 9:
1155: ret
1156: 8:
1157: clrl 12(r2)
1158: ret
1159:
1160: /*
1161: * Copy a null terminated string from the user address space into
1162: * the kernel address space.
1163: *
1164: * copyinstr(fromaddr, toaddr, maxlength, &lencopied)
1165: */
1166: ENTRY(copyinstr, R6)
1167: movl 12(ap),r6 # r6 = max length
1168: jlss 8f
1169: movl 4(ap),r1 # r1 = user address
1170: bicl3 $~(NBPG*CLSIZE-1),r1,r2 # r2 = bytes on first page
1171: subl3 r2,$NBPG*CLSIZE,r2
1172: movl 8(ap),r3 # r3 = kernel address
1173: 1:
1174: cmpl r6,r2 # r2 = min(bytes on page, length left);
1175: jgeq 2f
1176: movl r6,r2
1177: 2:
1178: prober $3,r2,(r1) # bytes accessible?
1179: jeql 8f
1180: subl2 r2,r6 # update bytes left count
1181: #ifdef NOSUBSINST
1182: # fake the locc instr. for processors that don't have it
1183: movl r2,r0
1184: 6:
1185: tstb (r1)+
1186: jeql 5f
1187: sobgtr r0,6b
1188: jbr 7f
1189: 5:
1190: decl r1
1191: jbr 3f
1192: 7:
1193: #else
1194: locc $0,r2,(r1) # null byte found?
1195: jneq 3f
1196: #endif
1197: subl2 r2,r1 # back up pointer updated by `locc'
1198: movc3 r2,(r1),(r3) # copy in next piece
1199: movl $(NBPG*CLSIZE),r2 # check next page
1200: tstl r6 # run out of space?
1201: jneq 1b
1202: movl $ENOENT,r0 # set error code and return
1203: jbr 9f
1204: 3:
1205: tstl 16(ap) # return length?
1206: beql 4f
1207: subl3 r6,12(ap),r6 # actual len = maxlen - unused pages
1208: subl2 r0,r6 # - unused on this page
1209: addl3 $1,r6,*16(ap) # + the null byte
1210: 4:
1211: subl2 r0,r2 # r2 = number of bytes to move
1212: subl2 r2,r1 # back up pointer updated by `locc'
1213: incl r2 # copy null byte as well
1214: movc3 r2,(r1),(r3) # copy in last piece
1215: clrl r0 # redundant
1216: ret
1217: 8:
1218: movl $EFAULT,r0
1219: 9:
1220: tstl 16(ap)
1221: beql 1f
1222: subl3 r6,12(ap),*16(ap)
1223: 1:
1224: ret
1225:
1226: /*
1227: * Copy a null terminated string from the kernel
1228: * address space to the user address space.
1229: *
1230: * copyoutstr(fromaddr, toaddr, maxlength, &lencopied)
1231: */
1232: ENTRY(copyoutstr, R6)
1233: movl 12(ap),r6 # r6 = max length
1234: jlss 8b
1235: movl 4(ap),r1 # r1 = kernel address
1236: movl 8(ap),r3 # r3 = user address
1237: bicl3 $~(NBPG*CLSIZE-1),r3,r2 # r2 = bytes on first page
1238: subl3 r2,$NBPG*CLSIZE,r2
1239: 1:
1240: cmpl r6,r2 # r2 = min(bytes on page, length left);
1241: jgeq 2f
1242: movl r6,r2
1243: 2:
1244: probew $3,r2,(r3) # bytes accessible?
1245: jeql 8b
1246: subl2 r2,r6 # update bytes left count
1247: #ifdef NOSUBSINST
1248: # fake the locc instr. for processors that don't have it
1249: movl r2,r0
1250: 6:
1251: tstb (r1)+
1252: jeql 5f
1253: sobgtr r0,6b
1254: jbr 7f
1255: 5:
1256: decl r1
1257: jbr 3b
1258: 7:
1259: #else
1260: locc $0,r2,(r1) # null byte found?
1261: jneq 3b
1262: #endif
1263: subl2 r2,r1 # back up pointer updated by `locc'
1264: movc3 r2,(r1),(r3) # copy in next piece
1265: movl $(NBPG*CLSIZE),r2 # check next page
1266: tstl r6 # run out of space?
1267: jneq 1b
1268: movl $ENOENT,r0 # set error code and return
1269: jbr 9b
1270:
1271: /*
1272: * Copy a null terminated string from one point to another in
1273: * the kernel address space.
1274: *
1275: * copystr(fromaddr, toaddr, maxlength, &lencopied)
1276: */
1277: ENTRY(copystr, R6)
1278: movl 12(ap),r6 # r6 = max length
1279: jlss 8b
1280: movl 4(ap),r1 # r1 = src address
1281: movl 8(ap),r3 # r3 = dest address
1282: 1:
1283: movzwl $65535,r2 # r2 = bytes in first chunk
1284: cmpl r6,r2 # r2 = min(bytes in chunk, length left);
1285: jgeq 2f
1286: movl r6,r2
1287: 2:
1288: subl2 r2,r6 # update bytes left count
1289: #ifdef NOSUBSINST
1290: # fake the locc instr. for processors that don't have it
1291: movl r2,r0
1292: 6:
1293: tstb (r1)+
1294: jeql 5f
1295: sobgtr r0,6b
1296: jbr 7f
1297: 5:
1298: decl r1
1299: jbr 3b
1300: 7:
1301: #else
1302: locc $0,r2,(r1) # null byte found?
1303: jneq 3b
1304: #endif
1305: subl2 r2,r1 # back up pointer updated by `locc'
1306: movc3 r2,(r1),(r3) # copy in next piece
1307: tstl r6 # run out of space?
1308: jneq 1b
1309: movl $ENOENT,r0 # set error code and return
1310: jbr 9b
1311:
1312: /*
1313: * Copy specified amount of data from user space into the kernel
1314: * Copyin(from, to, len)
1315: * r1 == from (user source address)
1316: * r3 == to (kernel destination address)
1317: * r5 == length
1318: */
1319: .align 1
1320: JSBENTRY(Copyin, R1|R3|R5)
1321: cmpl r5,$(NBPG*CLSIZE) # probing one page or less ?
1322: bgtru 1f # no
1323: prober $3,r5,(r1) # bytes accessible ?
1324: beql ersb # no
1325: movc3 r5,(r1),(r3)
1326: /* clrl r0 # redundant */
1327: rsb
1328: 1:
1329: blss ersb # negative length?
1330: pushl r6 # r6 = length
1331: movl r5,r6
1332: bicl3 $~(NBPG*CLSIZE-1),r1,r0 # r0 = bytes on first page
1333: subl3 r0,$(NBPG*CLSIZE),r0
1334: addl2 $(NBPG*CLSIZE),r0 # plus one additional full page
1335: jbr 2f
1336:
1337: ciloop:
1338: movc3 r0,(r1),(r3)
1339: movl $(2*NBPG*CLSIZE),r0 # next amount to move
1340: 2:
1341: cmpl r0,r6
1342: bleq 3f
1343: movl r6,r0
1344: 3:
1345: prober $3,r0,(r1) # bytes accessible ?
1346: beql ersb1 # no
1347: subl2 r0,r6 # last move?
1348: bneq ciloop # no
1349:
1350: movc3 r0,(r1),(r3)
1351: /* clrl r0 # redundant */
1352: movl (sp)+,r6 # restore r6
1353: rsb
1354:
1355: ersb1:
1356: movl (sp)+,r6 # restore r6
1357: ersb:
1358: movl $EFAULT,r0
1359: rsb
1360:
1361: /*
1362: * Copy specified amount of data from kernel to the user space
1363: * Copyout(from, to, len)
1364: * r1 == from (kernel source address)
1365: * r3 == to (user destination address)
1366: * r5 == length
1367: */
1368: .align 1
1369: JSBENTRY(Copyout, R1|R3|R5)
1370: cmpl r5,$(NBPG*CLSIZE) # moving one page or less ?
1371: bgtru 1f # no
1372: probew $3,r5,(r3) # bytes writeable?
1373: beql ersb # no
1374: movc3 r5,(r1),(r3)
1375: /* clrl r0 # redundant */
1376: rsb
1377: 1:
1378: blss ersb # negative length?
1379: pushl r6 # r6 = length
1380: movl r5,r6
1381: bicl3 $~(NBPG*CLSIZE-1),r3,r0 # r0 = bytes on first page
1382: subl3 r0,$(NBPG*CLSIZE),r0
1383: addl2 $(NBPG*CLSIZE),r0 # plus one additional full page
1384: jbr 2f
1385:
1386: coloop:
1387: movc3 r0,(r1),(r3)
1388: movl $(2*NBPG*CLSIZE),r0 # next amount to move
1389: 2:
1390: cmpl r0,r6
1391: bleq 3f
1392: movl r6,r0
1393: 3:
1394: probew $3,r0,(r3) # bytes writeable?
1395: beql ersb1 # no
1396: subl2 r0,r6 # last move?
1397: bneq coloop # no
1398:
1399: movc3 r0,(r1),(r3)
1400: /* clrl r0 # redundant */
1401: movl (sp)+,r6 # restore r6
1402: rsb
1403:
1404: /*
1405: * non-local goto's
1406: */
1407: #ifdef notdef /* this is now expanded completely inline */
1408: .align 1
1409: JSBENTRY(Setjmp, R0)
1410: movl fp,(r0)+ # current stack frame
1411: movl (sp),(r0) # resuming pc
1412: clrl r0
1413: rsb
1414: #endif
1415:
1416: #define PCLOC 16 /* location of pc in calls frame */
1417: #define APLOC 8 /* location of ap,fp in calls frame */
1418: .align 1
1419: JSBENTRY(Longjmp, R0)
1420: movl (r0)+,newfp # must save parameters in memory as all
1421: movl (r0),newpc # registers may be clobbered.
1422: 1:
1423: cmpl fp,newfp # are we there yet?
1424: bgequ 2f # yes
1425: moval 1b,PCLOC(fp) # redirect return pc to us!
1426: ret # pop next frame
1427: 2:
1428: beql 3f # did we miss our frame?
1429: pushab 4f # yep ?!?
1430: calls $1,_panic
1431: 3:
1432: movl newpc,r0 # all done, just return to the `setjmp'
1433: jmp (r0) # ``rsb''
1434:
1435: .data
1436: newpc: .space 4
1437: newfp: .space 4
1438: 4: .asciz "longjmp"
1439: .text
1440: /*
1441: * setjmp that saves all registers as the call frame may not
1442: * be available to recover them in the usual mannor by longjmp.
1443: * Called before swapping out the u. area, restored by resume()
1444: * below.
1445: */
1446: ENTRY(savectx, 0)
1447: movl 4(ap),r0
1448: movq r6,(r0)+
1449: movq r8,(r0)+
1450: movq r10,(r0)+
1451: movq APLOC(fp),(r0)+ # save ap, fp
1452: addl3 $8,ap,(r0)+ # save sp
1453: movl PCLOC(fp),(r0) # save pc
1454: clrl r0
1455: ret
1456:
1457: #ifdef KADB
1458: /*
1459: * C library -- reset, setexit
1460: *
1461: * reset(x)
1462: * will generate a "return" from
1463: * the last call to
1464: * setexit()
1465: * by restoring r6 - r12, ap, fp
1466: * and doing a return.
1467: * The returned value is x; on the original
1468: * call the returned value is 0.
1469: */
1470: ENTRY(setexit, 0)
1471: movab setsav,r0
1472: movq r6,(r0)+
1473: movq r8,(r0)+
1474: movq r10,(r0)+
1475: movq 8(fp),(r0)+ # ap, fp
1476: movab 4(ap),(r0)+ # sp
1477: movl 16(fp),(r0) # pc
1478: clrl r0
1479: ret
1480:
1481: ENTRY(reset, 0)
1482: movl 4(ap),r0 # returned value
1483: movab setsav,r1
1484: movq (r1)+,r6
1485: movq (r1)+,r8
1486: movq (r1)+,r10
1487: movq (r1)+,r12
1488: movl (r1)+,sp
1489: jmp *(r1)
1490:
1491: .data
1492: .align 2
1493: setsav: .space 10*4
1494: .text
1495: #endif
1496:
1497: .globl _whichqs
1498: .globl _qs
1499: .globl _cnt
1500:
1501: .globl _noproc
1502: .comm _noproc,4
1503: .globl _runrun
1504: .comm _runrun,4
1505:
1506: /*
1507: * The following primitives use the fancy VAX instructions
1508: * much like VMS does. _whichqs tells which of the 32 queues _qs
1509: * have processes in them. Setrq puts processes into queues, Remrq
1510: * removes them from queues. The running process is on no queue,
1511: * other processes are on a queue related to p->p_pri, divided by 4
1512: * actually to shrink the 0-127 range of priorities into the 32 available
1513: * queues.
1514: */
1515:
1516: /*
1517: * Setrq(p), using fancy VAX instructions.
1518: *
1519: * Call should be made at splclock(), and p->p_stat should be SRUN
1520: */
1521: .align 1
1522: JSBENTRY(Setrq, R0)
1523: tstl P_RLINK(r0) ## firewall: p->p_rlink must be 0
1524: beql set1 ##
1525: pushab set3 ##
1526: calls $1,_panic ##
1527: set1:
1528: movzbl P_PRI(r0),r1 # put on queue which is p->p_pri / 4
1529: ashl $-2,r1,r1
1530: movaq _qs[r1],r2
1531: insque (r0),*4(r2) # at end of queue
1532: bbss r1,_whichqs,set2 # mark queue non-empty
1533: set2:
1534: rsb
1535:
1536: set3: .asciz "setrq"
1537:
1538: /*
1539: * Remrq(p), using fancy VAX instructions
1540: *
1541: * Call should be made at splclock().
1542: */
1543: .align 1
1544: JSBENTRY(Remrq, R0)
1545: movzbl P_PRI(r0),r1
1546: ashl $-2,r1,r1
1547: bbsc r1,_whichqs,rem1
1548: pushab rem3 # it wasn't recorded to be on its q
1549: calls $1,_panic
1550: rem1:
1551: remque (r0),r2
1552: beql rem2
1553: bbss r1,_whichqs,rem2
1554: rem2:
1555: clrl P_RLINK(r0) ## for firewall checking
1556: rsb
1557:
1558: rem3: .asciz "remrq"
1559:
1560: /*
1561: * Masterpaddr is the p->p_addr of the running process on the master
1562: * processor. When a multiprocessor system, the slave processors will have
1563: * an array of slavepaddr's.
1564: */
1565: .globl _masterpaddr
1566: .data
1567: _masterpaddr:
1568: .long 0
1569:
1570: .text
1571: sw0: .asciz "swtch"
1572:
1573: /*
1574: * When no processes are on the runq, Swtch branches to idle
1575: * to wait for something to come ready.
1576: */
1577: .globl Idle
1578: Idle: idle:
1579: movl $1,_noproc
1580: mtpr $0,$IPL # must allow interrupts here
1581: 1:
1582: tstl _whichqs # look for non-empty queue
1583: bneq sw1
1584: brb 1b
1585:
1586: badsw: pushab sw0
1587: calls $1,_panic
1588: /*NOTREACHED*/
1589:
1590: /*
1591: * Swtch(), using fancy VAX instructions
1592: */
1593: .align 1
1594: JSBENTRY(Swtch, 0)
1595: incl _cnt+V_SWTCH
1596: sw1: ffs $0,$32,_whichqs,r0 # look for non-empty queue
1597: beql idle # if none, idle
1598: mtpr $0x18,$IPL # lock out all so _whichqs==_qs
1599: bbcc r0,_whichqs,sw1 # proc moved via interrupt
1600: movaq _qs[r0],r1
1601: remque *(r1),r2 # r2 = p = highest pri process
1602: bvs badsw # make sure something was there
1603: beql sw2
1604: insv $1,r0,$1,_whichqs # still more procs in this queue
1605: sw2:
1606: clrl _noproc
1607: clrl _runrun
1608: #ifdef notdef
1609: tstl P_WCHAN(r2) ## firewalls
1610: bneq badsw ##
1611: cmpb P_STAT(r2),$SRUN ##
1612: bneq badsw ##
1613: #endif
1614: clrl P_RLINK(r2) ##
1615: movl *P_ADDR(r2),r0
1616: #ifdef notdef
1617: cmpl r0,_masterpaddr # resume of current proc is easy
1618: beql res0
1619: #endif
1620: movl r0,_masterpaddr
1621: ashl $PGSHIFT,r0,r0 # r0 = pcbb(p)
1622: /* fall into... */
1623:
1624: /*
1625: * Resume(pf)
1626: */
1627: JSBENTRY(Resume, R0)
1628: mtpr $HIGH,$IPL # no interrupts, please
1629: movl _CMAP2,_u+PCB_CMAP2 # yech
1630: svpctx
1631: mtpr r0,$PCBB
1632: ldpctx
1633: movl _u+PCB_CMAP2,_CMAP2 # yech
1634: mtpr $_CADDR2,$TBIS
1635: res0:
1636: tstl _u+PCB_SSWAP
1637: bneq res1
1638: rei
1639: res1:
1640: movl _u+PCB_SSWAP,r0 # longjmp to saved context
1641: clrl _u+PCB_SSWAP
1642: movq (r0)+,r6 # restore r6, r7
1643: movq (r0)+,r8 # restore r8, r9
1644: movq (r0)+,r10 # restore r10, r11
1645: movq (r0)+,r12 # restore ap, fp
1646: movl (r0)+,r1 # saved sp
1647: cmpl r1,sp # must be a pop
1648: bgequ 1f
1649: pushab 2f
1650: calls $1,_panic
1651: /* NOTREACHED */
1652: 1:
1653: movl r1,sp # restore sp
1654: pushl $PSL_PRVMOD # return psl
1655: pushl (r0) # address to return to
1656: rei
1657:
1658: 2: .asciz "ldctx"
1659:
1660: /*
1661: * {fu,su},{byte,word}, all massaged by asm.sed to jsb's
1662: */
1663: .align 1
1664: JSBENTRY(Fuword, R0)
1665: prober $3,$4,(r0)
1666: beql fserr
1667: movl (r0),r0
1668: rsb
1669: fserr:
1670: mnegl $1,r0
1671: rsb
1672:
1673: .align 1
1674: JSBENTRY(Fubyte, R0)
1675: prober $3,$1,(r0)
1676: beql fserr
1677: movzbl (r0),r0
1678: rsb
1679:
1680: .align 1
1681: JSBENTRY(Suword, R0|R1)
1682: probew $3,$4,(r0)
1683: beql fserr
1684: movl r1,(r0)
1685: clrl r0
1686: rsb
1687:
1688: .align 1
1689: JSBENTRY(Subyte, R0|R1)
1690: probew $3,$1,(r0)
1691: beql fserr
1692: movb r1,(r0)
1693: clrl r0
1694: rsb
1695:
1696: /*
1697: * Copy 1 relocation unit (NBPG bytes)
1698: * from user virtual address to physical address
1699: */
1700: ENTRY(copyseg, 0)
1701: bisl3 $PG_V|PG_KW,8(ap),_CMAP2
1702: mtpr $_CADDR2,$TBIS # invalidate entry for copy
1703: movc3 $NBPG,*4(ap),_CADDR2
1704: ret
1705:
1706: /*
1707: * zero out physical memory
1708: * specified in relocation units (NBPG bytes)
1709: */
1710: ENTRY(clearseg, 0)
1711: bisl3 $PG_V|PG_KW,4(ap),_CMAP1
1712: mtpr $_CADDR1,$TBIS
1713: movc5 $0,(sp),$0,$NBPG,_CADDR1
1714: ret
1715:
1716: /*
1717: * Check address.
1718: * Given virtual address, byte count, and rw flag
1719: * returns 0 on no access.
1720: */
1721: ENTRY(useracc, 0)
1722: movl 4(ap),r0 # get va
1723: movl 8(ap),r1 # count
1724: tstl 12(ap) # test for read access ?
1725: bneq userar # yes
1726: cmpl $NBPG,r1 # can we do it in one probe ?
1727: bgeq uaw2 # yes
1728: uaw1:
1729: probew $3,$NBPG,(r0)
1730: beql uaerr # no access
1731: addl2 $NBPG,r0
1732: acbl $NBPG+1,$-NBPG,r1,uaw1
1733: uaw2:
1734: probew $3,r1,(r0)
1735: beql uaerr
1736: movl $1,r0
1737: ret
1738:
1739: userar:
1740: cmpl $NBPG,r1
1741: bgeq uar2
1742: uar1:
1743: prober $3,$NBPG,(r0)
1744: beql uaerr
1745: addl2 $NBPG,r0
1746: acbl $NBPG+1,$-NBPG,r1,uar1
1747: uar2:
1748: prober $3,r1,(r0)
1749: beql uaerr
1750: movl $1,r0
1751: ret
1752: uaerr:
1753: clrl r0
1754: ret
1755:
1756: /*
1757: * kernacc - check for kernel access privileges
1758: *
1759: * We can't use the probe instruction directly because
1760: * it ors together current and previous mode.
1761: */
1762: ENTRY(kernacc, 0)
1763: movl 4(ap),r0 # virtual address
1764: bbcc $31,r0,kacc1
1765: bbs $30,r0,kacerr
1766: mfpr $SBR,r2 # address and length of page table (system)
1767: bbss $31,r2,0f; 0:
1768: mfpr $SLR,r3
1769: brb kacc2
1770: kacc1:
1771: bbsc $30,r0,kacc3
1772: mfpr $P0BR,r2 # user P0
1773: mfpr $P0LR,r3
1774: brb kacc2
1775: kacc3:
1776: mfpr $P1BR,r2 # user P1 (stack)
1777: mfpr $P1LR,r3
1778: kacc2:
1779: addl3 8(ap),r0,r1 # ending virtual address
1780: addl2 $NBPG-1,r1
1781: ashl $-PGSHIFT,r0,r0
1782: ashl $-PGSHIFT,r1,r1
1783: bbs $31,4(ap),kacc6
1784: bbc $30,4(ap),kacc6
1785: cmpl r0,r3 # user stack
1786: blss kacerr # address too low
1787: brb kacc4
1788: kacc6:
1789: cmpl r1,r3 # compare last page to P0LR or SLR
1790: bgtr kacerr # address too high
1791: kacc4:
1792: movl (r2)[r0],r3
1793: bbc $31,4(ap),kacc4a
1794: bbc $31,r3,kacerr # valid bit is off
1795: kacc4a:
1796: cmpzv $27,$4,r3,$1 # check protection code
1797: bleq kacerr # no access allowed
1798: tstb 12(ap)
1799: bneq kacc5 # only check read access
1800: cmpzv $27,$2,r3,$3 # check low 2 bits of prot code
1801: beql kacerr # no write access
1802: kacc5:
1803: aoblss r1,r0,kacc4 # next page
1804: movl $1,r0 # no errors
1805: ret
1806: kacerr:
1807: clrl r0 # error
1808: ret
1809: /*
1810: * Extracted and unrolled most common case of pagein (hopefully):
1811: * resident and not on free list (reclaim of page is purely
1812: * for the purpose of simulating a reference bit)
1813: *
1814: * Built in constants:
1815: * CLSIZE of 2, any bit fields in pte's
1816: */
1817: .text
1818: .globl Fastreclaim
1819: Fastreclaim:
1820: PUSHR
1821: #ifdef GPROF
1822: movl fp,-(sp)
1823: movab 12(sp),fp
1824: jsb mcount
1825: movl (sp)+,fp
1826: #endif GPROF
1827: extzv $9,$23,28(sp),r3 # virtual address
1828: bicl2 $1,r3 # v = clbase(btop(virtaddr));
1829: movl _u+U_PROCP,r5 # p = u.u_procp
1830: # from vtopte(p, v) ...
1831: movl $1,r2 # type = CTEXT;
1832: cmpl r3,P_TSIZE(r5)
1833: jlssu 1f # if (isatsv(p, v)) {
1834: addl3 P_TSIZE(r5),P_DSIZE(r5),r0
1835: cmpl r3,r0
1836: jgequ 2f
1837: clrl r2 # type = !CTEXT;
1838: 1:
1839: ashl $2,r3,r4
1840: addl2 P_P0BR(r5),r4 # tptopte(p, vtotp(p, v));
1841: jbr 3f
1842: 2:
1843: cvtwl P_SZPT(r5),r4 # } else (isassv(p, v)) {
1844: ashl $7,r4,r4
1845: subl2 $0x400000,r4
1846: addl2 r3,r4
1847: ashl $2,r4,r4
1848: addl2 P_P0BR(r5),r4 # sptopte(p, vtosp(p, v));
1849: clrl r2 # type = !CTEXT;
1850: 3: # }
1851: bitb $0x82,3(r4)
1852: beql 2f # if (pte->pg_v || pte->pg_fod)
1853: POPR; rsb # let pagein handle it
1854: 2:
1855: bicl3 $0xffe00000,(r4),r0
1856: jneq 2f # if (pte->pg_pfnum == 0)
1857: POPR; rsb # let pagein handle it
1858: 2:
1859: subl2 _firstfree,r0
1860: ashl $-1,r0,r0
1861: incl r0 # pgtocm(pte->pg_pfnum)
1862: mull2 $SZ_CMAP,r0
1863: addl2 _cmap,r0 # &cmap[pgtocm(pte->pg_pfnum)]
1864: tstl r2
1865: jeql 2f # if (type == CTEXT &&
1866: jbc $C_INTRANS,(r0),2f # c_intrans)
1867: POPR; rsb # let pagein handle it
1868: 2:
1869: jbc $C_FREE,(r0),2f # if (c_free)
1870: POPR; rsb # let pagein handle it
1871: 2:
1872: bisb2 $0x80,3(r4) # pte->pg_v = 1;
1873: jbc $26,4(r4),2f # if (anycl(pte, pg_m)
1874: bisb2 $0x04,3(r4) # pte->pg_m = 1;
1875: 2:
1876: bicw3 $0x7f,2(r4),r0
1877: bicw3 $0xff80,6(r4),r1
1878: bisw3 r0,r1,6(r4) # distcl(pte);
1879: ashl $PGSHIFT,r3,r0
1880: mtpr r0,$TBIS
1881: addl2 $NBPG,r0
1882: mtpr r0,$TBIS # tbiscl(v);
1883: tstl r2
1884: jeql 2f # if (type == CTEXT)
1885: movl P_TEXTP(r5),r0
1886: movl X_CADDR(r0),r5 # for (p = p->p_textp->x_caddr; p; ) {
1887: jeql 2f
1888: ashl $2,r3,r3
1889: 3:
1890: addl3 P_P0BR(r5),r3,r0 # tpte = tptopte(p, tp);
1891: bisb2 $1,P_FLAG+3(r5) # p->p_flag |= SPTECHG;
1892: movl (r4),(r0)+ # for (i = 0; i < CLSIZE; i++)
1893: movl 4(r4),(r0) # tpte[i] = pte[i];
1894: movl P_XLINK(r5),r5 # p = p->p_xlink;
1895: jneq 3b # }
1896: 2: # collect a few statistics...
1897: incl _u+U_RU+RU_MINFLT # u.u_ru.ru_minflt++;
1898: moval _cnt,r0
1899: incl V_FAULTS(r0) # cnt.v_faults++;
1900: incl V_PGREC(r0) # cnt.v_pgrec++;
1901: incl V_FASTPGREC(r0) # cnt.v_fastpgrec++;
1902: incl V_TRAP(r0) # cnt.v_trap++;
1903: POPR
1904: addl2 $8,sp # pop pc, code
1905: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT)
1906: rei
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.