|
|
1.1 root 1: /* locore.s 6.3 83/08/12 */
2:
3: #include "../machine/psl.h"
4: #include "../machine/pte.h"
5:
6: #include "../h/errno.h"
7:
8: #include "../vax/mtpr.h"
9: #include "../vax/trap.h"
10: #include "../vax/cpu.h"
11: #include "../vax/nexus.h"
12: #include "../vax/cons.h"
13: #include "../vax/clock.h"
14: #include "../vaxuba/ubareg.h"
15:
16: #include "dh.h"
17: #include "dz.h"
18: #include "uu.h"
19: #include "ps.h"
20: #include "mba.h"
21:
22: .set HIGH,0x1f # mask for total disable
23: .set MCKVEC,4 # offset into scb of machine check vector
24: .set NBPG,512
25: .set PGSHIFT,9
26:
27: .set NISP,3 # number of interrupt stack pages
28:
29: /*
30: * User structure is UPAGES at top of user space.
31: */
32: .globl _u
33: .set _u,0x80000000 - UPAGES*NBPG
34:
35: .globl _intstack
36: _intstack:
37: .space NISP*NBPG
38: eintstack:
39:
40: /*
41: * Do a dump.
42: * Called by auto-restart.
43: * May be called manually.
44: */
45: .align 2
46: .globl _doadump
47: _doadump:
48: nop; nop # .word 0x0101
49: #define _rpbmap _Sysmap # rpb, scb, UNI*vec, istack*4
50: bicl2 $PG_PROT,_rpbmap
51: bisl2 $PG_KW,_rpbmap
52: tstl _rpb+RP_FLAG # dump only once!
53: bneq 1f
54: incl _rpb+RP_FLAG
55: mtpr $0,$TBIA
56: movl sp,erpb
57: movab erpb,sp
58: mfpr $PCBB,-(sp)
59: mfpr $MAPEN,-(sp)
60: mfpr $IPL,-(sp)
61: mtpr $0,$MAPEN
62: mtpr $HIGH,$IPL
63: pushr $0x3fff
64: calls $0,_dumpsys
65: 1:
66: mfpr $TXCS,r0
67: bitl $TXCS_RDY,r0
68: beql 1b
69: mtpr $TXDB_BOOT,$TXDB
70: halt
71:
72: /*
73: * Interrupt vector routines
74: */
75: .globl _waittime
76:
77: #define SCBVEC(name) .align 2; .globl _X/**/name; _X/**/name
78: #define PANIC(msg) clrl _waittime; pushab 1f; \
79: calls $1,_panic; 1: .asciz msg
80: #define PRINTF(n,msg) pushab 1f; calls $n+1,_printf; MSG(msg)
81: #define MSG(msg) .data; 1: .asciz msg; .text
82: #define PUSHR pushr $0x3f
83: #define POPR popr $0x3f
84:
85: SCBVEC(machcheck):
86: PUSHR; pushab 6*4(sp); calls $1,_machinecheck; POPR;
87: addl2 (sp)+,sp; rei
88: SCBVEC(kspnotval):
89: PUSHR; PANIC("KSP not valid");
90: SCBVEC(powfail):
91: halt
92: SCBVEC(chme): SCBVEC(chms): SCBVEC(chmu):
93: PUSHR; PANIC("CHM? in kernel");
94: SCBVEC(stray):
95: PUSHR; PRINTF(0, "stray scb interrupt\n"); POPR;
96: rei
97: SCBVEC(nexzvec):
98: PUSHR; mfpr $IPL,-(sp); PRINTF(1, "nexus stray intr ipl%x\n"); POPR; rei
99: SCBVEC(cmrd):
100: PUSHR; calls $0,_memerr; POPR; rei
101: SCBVEC(wtime):
102: PUSHR; pushl 6*4(sp); PRINTF(1,"write timeout %x\n"); POPR;
103: PANIC("wtimo");
104:
105: #if NMBA > 0
106: SCBVEC(mba3int):
107: PUSHR; pushl $3; brb 1f
108: SCBVEC(mba2int):
109: PUSHR; pushl $2; brb 1f
110: SCBVEC(mba1int):
111: PUSHR; pushl $1; brb 1f
112: SCBVEC(mba0int):
113: PUSHR; pushl $0
114: 1: calls $1,_mbintr
115: POPR
116: incl _cnt+V_INTR
117: rei
118: #endif
119:
120: #if VAX780
121: /*
122: * Registers for the uba handling code
123: */
124: #define rUBANUM r0
125: #define rUBAHD r1
126: #define rUVEC r3
127: #define rUBA r4
128: /* r2,r5 are scratch */
129:
130: SCBVEC(ua3int):
131: PUSHR; movl $3,rUBANUM; moval _uba_hd+(3*UH_SIZE),rUBAHD; brb 1f
132: SCBVEC(ua2int):
133: PUSHR; movl $2,rUBANUM; moval _uba_hd+(2*UH_SIZE),rUBAHD; brb 1f
134: SCBVEC(ua1int):
135: PUSHR; movl $1,rUBANUM; moval _uba_hd+(1*UH_SIZE),rUBAHD; brb 1f
136: SCBVEC(ua0int):
137: PUSHR; movl $0,rUBANUM; moval _uba_hd+(0*UH_SIZE),rUBAHD;
138: 1:
139: incl _cnt+V_INTR
140: mfpr $IPL,r2 /* r2 = mfpr(IPL); */
141: movl UH_UBA(rUBAHD),rUBA /* uba = uhp->uh_uba; */
142: movl UBA_BRRVR-0x14*4(rUBA)[r2],rUVEC
143: /* uvec = uba->uba_brrvr[r2-0x14] */
144: ubanorm:
145: bleq ubaerror
146: addl2 UH_VEC(rUBAHD),rUVEC /* uvec += uh->uh_vec */
147: bicl3 $3,(rUVEC),r1
148: jmp 2(r1) /* 2 skips ``pushr $0x3f'' */
149: ubaerror:
150: PUSHR; calls $0,_ubaerror; POPR /* ubaerror r/w's r0-r5 */
151: tstl rUVEC; jneq ubanorm /* rUVEC contains result */
152: POPR
153: rei
154: #endif
155: SCBVEC(cnrint):
156: PUSHR; calls $0,_cnrint; POPR; incl _cnt+V_INTR; rei
157: SCBVEC(cnxint):
158: PUSHR; calls $0,_cnxint; POPR; incl _cnt+V_INTR; rei
159: SCBVEC(hardclock):
160: PUSHR
161: mtpr $ICCS_RUN|ICCS_IE|ICCS_INT|ICCS_ERR,$ICCS
162: pushl 4+6*4(sp); pushl 4+6*4(sp);
163: calls $2,_hardclock # hardclock(pc,psl)
164: #if NPS > 0
165: pushl 4+6*4(sp); pushl 4+6*4(sp);
166: calls $2,_psextsync
167: #endif
168: POPR;
169: incl _cnt+V_INTR ## temp so not to break vmstat -= HZ
170: rei
171: SCBVEC(softclock):
172: PUSHR
173: #if NDZ > 0
174: calls $0,_dztimer
175: #endif
176: #if NDH > 0
177: calls $0,_dhtimer
178: #endif
179: pushl 4+6*4(sp); pushl 4+6*4(sp);
180: calls $2,_softclock # softclock(pc,psl)
181: POPR;
182: rei
183: #include "../net/netisr.h"
184: .globl _netisr
185: SCBVEC(netintr):
186: PUSHR
187: bbcc $NETISR_RAW,_netisr,1f; calls $0,_rawintr; 1:
188: #ifdef INET
189: #include "../netinet/in_systm.h"
190: bbcc $NETISR_IP,_netisr,1f; calls $0,_ipintr; 1:
191: #endif
192: #ifdef NS
193: bbcc $NETISR_NS,_netisr,1f; calls $0,_nsintr; 1:
194: #endif
195: POPR
196: rei
197: #if defined(VAX750) || defined(VAX730)
198: SCBVEC(consdin):
199: PUSHR;
200: #if defined(VAX750) && !defined(VAX730) && !defined(MRSP)
201: jsb tudma
202: #endif
203: calls $0,_turintr;
204: POPR;
205: incl _cnt+V_INTR;
206: rei
207: SCBVEC(consdout):
208: PUSHR; calls $0,_tuxintr; POPR; incl _cnt+V_INTR; rei
209: #else
210: SCBVEC(consdin):
211: halt
212: SCBVEC(consdout):
213: halt
214: #endif
215:
216: #if NDZ > 0
217: /*
218: * DZ pseudo dma routine:
219: * r0 - controller number
220: */
221: .align 1
222: .globl dzdma
223: dzdma:
224: mull2 $8*20,r0
225: movab _dzpdma(r0),r3 # pdma structure base
226: # for this controller
227: dzploop:
228: movl r3,r0
229: movl (r0)+,r1 # device register address
230: movzbl 1(r1),r2 # get line number
231: bitb $0x80,r2 # TRDY on?
232: beql dzprei # no
233: bicb2 $0xf8,r2 # clear garbage bits
234: mull2 $20,r2
235: addl2 r2,r0 # point at line's pdma structure
236: movl (r0)+,r2 # p_mem
237: cmpl r2,(r0)+ # p_mem < p_end ?
238: bgequ dzpcall # no, go call dzxint
239: movb (r2)+,6(r1) # dztbuf = *p_mem++
240: movl r2,-8(r0)
241: brb dzploop # check for another line
242: dzprei:
243: POPR
244: incl _cnt+V_PDMA
245: rei
246:
247: dzpcall:
248: pushl r3
249: pushl (r0)+ # push tty address
250: calls $1,*(r0) # call interrupt rtn
251: movl (sp)+,r3
252: brb dzploop # check for another line
253: #endif
254:
255: #if NUU > 0 && defined(UUDMA)
256: /*
257: * Pseudo DMA routine for tu58 (on DL11)
258: * r0 - controller number
259: */
260: .align 1
261: .globl uudma
262: uudma:
263: movl _uudinfo[r0],r2
264: movl 16(r2),r2 # r2 = uuaddr
265: mull3 $48,r0,r3
266: movab _uu_softc(r3),r5 # r5 = uuc
267:
268: cvtwl 2(r2),r1 # c = uuaddr->rdb
269: bbc $15,r1,1f # if (c & UUDB_ERROR)
270: movl $13,16(r5) # uuc->tu_state = TUC_RCVERR;
271: rsb # let uurintr handle it
272: 1:
273: tstl 4(r5) # if (uuc->tu_rcnt) {
274: beql 1f
275: movb r1,*0(r5) # *uuc->tu_rbptr++ = r1
276: incl (r5)
277: decl 4(r5) # if (--uuc->tu_rcnt)
278: beql 2f # done
279: tstl (sp)+
280: POPR # registers saved in ubglue.s
281: rei # }
282: 2:
283: cmpl 16(r5),$8 # if (uuc->tu_state != TUS_GETH)
284: beql 2f # let uurintr handle it
285: 1:
286: rsb
287: 2:
288: mull2 $14,r0 # sizeof(uudata[ctlr]) = 14
289: movab _uudata(r0),r4 # data = &uudata[ctlr];
290: cmpb $1,(r4) # if (data->pk_flag != TUF_DATA)
291: bneq 1b
292: #ifdef notdef
293: /* this is for command packets */
294: beql 1f # r0 = uuc->tu_rbptr
295: movl (r5),r0
296: brb 2f
297: 1: # else
298: #endif
299: movl 24(r5),r0 # r0 = uuc->tu_addr
300: 2:
301: movzbl 1(r4),r3 # counter to r3 (data->pk_count)
302: movzwl (r4),r1 # first word of checksum (=header)
303: mfpr $IPL,-(sp) # s = spl5();
304: mtpr $0x15,$IPL # to keep disk interrupts out
305: clrw (r2) # disable receiver interrupts
306: 3: bbc $7,(r2),3b # while ((uuaddr->rcs & UUCS_READY)==0);
307: cvtwb 2(r2),(r0)+ # *buffer = uuaddr->rdb & 0xff
308: sobgtr r3,1f # continue with next byte ...
309: addw2 2(r2),r1 # unless this was the last (odd count)
310: brb 2f
311:
312: 1: bbc $7,(r2),1b # while ((uuaddr->rcs & UUCS_READY)==0);
313: cvtwb 2(r2),(r0)+ # *buffer = uuaddr->rdb & 0xff
314: addw2 -2(r0),r1 # add to checksum..
315: 2:
316: adwc $0,r1 # get the carry
317: sobgtr r3,3b # loop while r3 > 0
318: /*
319: * We're ready to get the checksum
320: */
321: 1: bbc $7,(r2),1b # while ((uuaddr->rcs & UUCS_READY)==0);
322: cvtwb 2(r2),12(r4) # get first (lower) byte
323: 1: bbc $7,(r2),1b
324: cvtwb 2(r2),13(r4) # ..and second
325: cmpw 12(r4),r1 # is checksum ok?
326: beql 1f
327: movl $14,16(r5) # uuc->tu_state = TUS_CHKERR
328: brb 2f # exit
329: 1:
330: movl $11,16(r5) # uuc->tu_state = TUS_GET (ok)
331: 2:
332: movw $0x40,(r2) # enable receiver interrupts
333: mtpr (sp)+,$IPL # splx(s);
334: rsb # continue processing in uurintr
335: #endif
336:
337: #if defined(VAX750) && !defined(VAX730) && !defined(MRSP)
338: /*
339: * Pseudo DMA routine for VAX-11/750 console tu58
340: * (without MRSP)
341: */
342: .align 1
343: .globl tudma
344: tudma:
345: movab _tu,r5 # r5 = tu
346: tstl 4(r5) # if (tu.tu_rcnt) {
347: beql 3f
348: mfpr $CSRD,r1 # get data from tu58
349: movb r1,*0(r5) # *tu.tu_rbptr++ = r1
350: incl (r5)
351: decl 4(r5) # if (--tu.tu_rcnt)
352: beql 1f # done
353: tstl (sp)+
354: POPR # registers saved in ubglue.s
355: rei # data handled, done
356: 1: # }
357: cmpl 16(r5),$8 # if (tu.tu_state != TUS_GETH)
358: beql 2f # let turintr handle it
359: 3:
360: rsb
361: 2:
362: movab _tudata,r4 # r4 = tudata
363: cmpb $1,(r4) # if (tudata.pk_flag != TUF_DATA)
364: bneq 3b # let turintr handle it
365: 1: # else
366: movl 24(r5),r1 # get buffer pointer to r1
367: movzbl 1(r4),r3 # counter to r3
368: movzwl (r4),r0 # first word of checksum (=header)
369: mtpr $0,$CSRS # disable receiver interrupts
370: 3:
371: bsbw 5f # wait for next byte
372: mfpr $CSRD,r5
373: movb r5,(r1)+ # *buffer = rdb
374: sobgtr r3,1f # continue with next byte ...
375: mfpr $CSRD,r2 # unless this was the last (odd count)
376: brb 2f
377:
378: 1: bsbw 5f # wait for next byte
379: mfpr $CSRD,r5
380: movb r5,(r1)+ # *buffer = rdb
381: movzwl -2(r1),r2 # get the last word back from memory
382: 2:
383: addw2 r2,r0 # add to checksum..
384: adwc $0,r0 # get the carry
385: sobgtr r3,3b # loop while r3 > 0
386: /*
387: * We're ready to get the checksum.
388: */
389: bsbw 5f
390: movab _tudata,r4
391: mfpr $CSRD,r5
392: movb r5,12(r4) # get first (lower) byte
393: bsbw 5f
394: mfpr $CSRD,r5
395: movb r5,13(r4) # ..and second
396: movab _tu,r5
397: cmpw 12(r4),r0 # is checksum ok?
398: beql 1f
399: movl $14,16(r5) # tu.tu_state = TUS_CHKERR
400: brb 2f # exit
401: 1:
402: movl $11,16(r5) # tu.tu_state = TUS_GET
403: 2:
404: mtpr $0x40,$CSRS # enable receiver interrupts
405: rsb # continue processing in turintr
406: /*
407: * Loop until a new byte is ready from
408: * the tu58, make sure we don't loop forever
409: */
410: 5:
411: movl $5000,r5 # loop max 5000 times
412: 1:
413: mfpr $CSRS,r2
414: bbs $7,r2,1f
415: sobgtr r5,1b
416: movab _tu,r5
417: movl $13,16(r5) # return TUS_RCVERR
418: tstl (sp)+ # and let turintr handle it
419: 1:
420: rsb
421: #endif
422:
423: /*
424: * Stray UNIBUS interrupt catch routines
425: */
426: .data
427: .align 2
428: #define PJ PUSHR;jsb _Xustray
429: .globl _catcher
430: _catcher:
431: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
432: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
433: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
434: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
435: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
436: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
437: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
438: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ
439:
440: .globl _cold
441: _cold: .long 1
442: .data
443:
444: .text
445: SCBVEC(ustray):
446: blbc _cold,1f
447: mfpr $IPL,r11
448: subl3 $_catcher+8,(sp)+,r10
449: ashl $-1,r10,r10
450: POPR
451: rei
452: 1:
453: subl3 $_catcher+8,(sp)+,r0
454: ashl $-1,r0,-(sp)
455: mfpr $IPL,-(sp)
456: PRINTF(2, "uba?: stray intr ipl %x vec %o\n")
457: POPR
458: rei
459:
460: /*
461: * Trap and fault vector routines
462: */
463: #define TRAP(a) pushl $T_/**/a; jbr alltraps
464:
465: /*
466: * Ast delivery (profiling and/or reschedule)
467: */
468: SCBVEC(astflt):
469: pushl $0; TRAP(ASTFLT)
470: SCBVEC(privinflt):
471: pushl $0; TRAP(PRIVINFLT)
472: SCBVEC(xfcflt):
473: pushl $0; TRAP(XFCFLT)
474: SCBVEC(resopflt):
475: pushl $0; TRAP(RESOPFLT)
476: SCBVEC(resadflt):
477: pushl $0; TRAP(RESADFLT)
478: SCBVEC(bptflt):
479: pushl $0; TRAP(BPTFLT)
480: SCBVEC(compatflt):
481: TRAP(COMPATFLT);
482: SCBVEC(tracep):
483: pushl $0; TRAP(TRCTRAP)
484: SCBVEC(arithtrap):
485: TRAP(ARITHTRAP)
486: SCBVEC(protflt):
487: blbs (sp)+,segflt
488: TRAP(PROTFLT)
489: segflt:
490: TRAP(SEGFLT)
491: SCBVEC(transflt):
492: bitl $2,(sp)+
493: bnequ tableflt
494: jsb Fastreclaim # try and avoid pagein
495: TRAP(PAGEFLT)
496: tableflt:
497: TRAP(TABLEFLT)
498:
499: alltraps:
500: mfpr $USP,-(sp); calls $0,_trap; mtpr (sp)+,$USP
501: incl _cnt+V_TRAP
502: addl2 $8,sp # pop type, code
503: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT)
504: rei
505:
506: SCBVEC(syscall):
507: pushl $T_SYSCALL
508: mfpr $USP,-(sp); calls $0,_syscall; mtpr (sp)+,$USP
509: incl _cnt+V_SYSCALL
510: addl2 $8,sp # pop type, code
511: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT)
512: rei
513:
514: /*
515: * System page table
516: */
517: #define vaddr(x) ((((x)-_Sysmap)/4)*NBPG+0x80000000)
518: #define SYSMAP(mname, vname, npte) \
519: _/**/mname: .globl _/**/mname; \
520: .space npte*4; \
521: .globl _/**/vname; \
522: .set _/**/vname,vaddr(_/**/mname)
523:
524: .data
525: .align 2
526: SYSMAP(Sysmap ,Sysbase ,SYSPTSIZE )
527: SYSMAP(UMBAbeg ,umbabeg ,0 )
528: SYSMAP(Nexmap ,nexus ,16*MAXNNEXUS )
529: SYSMAP(UMEMmap ,umem ,512*MAXNUBA )
530: SYSMAP(UMBAend ,umbaend ,0 )
531: SYSMAP(Usrptmap ,usrpt ,USRPTSIZE )
532: SYSMAP(Forkmap ,forkutl ,UPAGES )
533: SYSMAP(Xswapmap ,xswaputl ,UPAGES )
534: SYSMAP(Xswap2map,xswap2utl ,UPAGES )
535: SYSMAP(Swapmap ,swaputl ,UPAGES )
536: SYSMAP(Pushmap ,pushutl ,UPAGES )
537: SYSMAP(Vfmap ,vfutl ,UPAGES )
538: SYSMAP(CMAP1 ,CADDR1 ,1 )
539: SYSMAP(CMAP2 ,CADDR2 ,1 )
540: SYSMAP(mcrmap ,mcr ,1 )
541: SYSMAP(mmap ,vmmap ,1 )
542: SYSMAP(msgbufmap,msgbuf ,MSGBUFPTECNT )
543: SYSMAP(camap ,cabase ,16*CLSIZE )
544: SYSMAP(ecamap ,calimit ,0 )
545: SYSMAP(Mbmap ,mbutl ,NMBCLUSTERS*CLSIZE)
546:
547: eSysmap:
548: .globl _Syssize
549: .set _Syssize,(eSysmap-_Sysmap)/4
550: .text
551:
552: /*
553: * Initialization
554: *
555: * ipl 0x1f; mapen 0; scbb, pcbb, sbr, slr, isp, ksp not set
556: */
557: .data
558: .globl _cpu
559: _cpu: .long 0
560: .text
561: .globl start
562: start:
563: .word 0
564: /* set system control block base and system page table params */
565: mtpr $_scb-0x80000000,$SCBB
566: mtpr $_Sysmap-0x80000000,$SBR
567: mtpr $_Syssize,$SLR
568: /* double map the kernel into the virtual user addresses of phys mem */
569: mtpr $_Sysmap,$P0BR
570: mtpr $_Syssize,$P0LR
571: /* set ISP and get cpu type */
572: movl $_intstack+NISP*NBPG,sp
573: mfpr $SID,r0
574: movab _cpu,r1
575: extzv $24,$8,r0,(r1)
576: /* init RPB */
577: movab _rpb,r0
578: movl r0,(r0)+ # rp_selfref
579: movab _doadump,r1
580: movl r1,(r0)+ # rp_dumprout
581: movl $0x1f,r2
582: clrl r3
583: 1: addl2 (r1)+,r3; sobgtr r2,1b
584: movl r3,(r0)+ # rp_chksum
585: /* count up memory */
586: clrl r7
587: 1: pushl $4; pushl r7; calls $2,_badaddr; tstl r0; bneq 9f
588: acbl $8192*1024-1,$64*1024,r7,1b
589: 9:
590: /* clear memory from kernel bss and pages for proc 0 u. and page table */
591: movab _edata,r6
592: movab _end,r5
593: bbcc $31,r5,0f; 0:
594: addl2 $(UPAGES*NBPG)+NBPG+NBPG,r5
595: 1: clrq (r6); acbl r5,$8,r6,1b
596: /* trap() and syscall() save r0-r11 in the entry mask (per ../h/reg.h) */
597: bisw2 $0x0fff,_trap
598: bisw2 $0x0fff,_syscall
599: calls $0,_fixctlrmask
600: /* initialize system page table: scb and int stack writeable */
601: clrl r2
602: movab eintstack,r1; bbcc $31,r1,0f; 0: ashl $-PGSHIFT,r1,r1
603: 1: bisl3 $PG_V|PG_KW,r2,_Sysmap[r2]; aoblss r1,r2,1b
604: /* make rpb read-only as red zone for interrupt stack */
605: bicl2 $PG_PROT,_rpbmap
606: bisl2 $PG_KR,_rpbmap
607: /* make kernel text space read-only */
608: movab _etext+NBPG-1,r1; bbcc $31,r1,0f; 0: ashl $-PGSHIFT,r1,r1
609: 1: bisl3 $PG_V|PG_KR,r2,_Sysmap[r2]; aoblss r1,r2,1b
610: /* make kernel data, bss, read-write */
611: movab _end+NBPG-1,r1; bbcc $31,r1,0f; 0:; ashl $-PGSHIFT,r1,r1
612: 1: bisl3 $PG_V|PG_KW,r2,_Sysmap[r2]; aoblss r1,r2,1b
613: /* now go to mapped mode */
614: mtpr $1,$TBIA; mtpr $1,$MAPEN; jmp *$0f; 0:
615: /* init mem sizes */
616: ashl $-PGSHIFT,r7,_maxmem
617: movl _maxmem,_physmem
618: movl _maxmem,_freemem
619: /* setup context for proc[0] == Scheduler */
620: movab _end+NBPG-1,r6
621: bicl2 $NBPG-1,r6 # make page boundary
622: /* setup page table for proc[0] */
623: bbcc $31,r6,0f; 0:
624: ashl $-PGSHIFT,r6,r3 # r3 = btoc(r6)
625: bisl3 $PG_V|PG_KW,r3,_Usrptmap # init first upt entry
626: incl r3
627: movab _usrpt,r0
628: mtpr r0,$TBIS
629: /* init p0br, p0lr */
630: mtpr r0,$P0BR
631: mtpr $0,$P0LR
632: /* init p1br, p1lr */
633: movab NBPG(r0),r0
634: movl $0x200000-UPAGES,r1
635: mtpr r1,$P1LR
636: mnegl r1,r1
637: moval -4*UPAGES(r0)[r1],r2
638: mtpr r2,$P1BR
639: /* setup mapping for UPAGES of _u */
640: movl $UPAGES,r2; movab _u+NBPG*UPAGES,r1; addl2 $UPAGES,r3; jbr 2f
641: 1: decl r3
642: moval -NBPG(r1),r1;
643: bisl3 $PG_V|PG_URKW,r3,-(r0)
644: mtpr r1,$TBIS
645: 2: sobgeq r2,1b
646: /* initialize (slightly) the pcb */
647: movab UPAGES*NBPG(r1),PCB_KSP(r1)
648: mnegl $1,PCB_ESP(r1)
649: mnegl $1,PCB_SSP(r1)
650: movl r1,PCB_USP(r1)
651: mfpr $P0BR,PCB_P0BR(r1)
652: mfpr $P0LR,PCB_P0LR(r1)
653: movb $4,PCB_P0LR+3(r1) # disable ast
654: mfpr $P1BR,PCB_P1BR(r1)
655: mfpr $P1LR,PCB_P1LR(r1)
656: movl $CLSIZE,PCB_SZPT(r1) # init u.u_pcb.pcb_szpt
657: movl r11,PCB_R11(r1)
658: movab 1f,PCB_PC(r1) # initial pc
659: clrl PCB_PSL(r1) # mode(k,k), ipl=0
660: ashl $PGSHIFT,r3,r3
661: mtpr r3,$PCBB # first pcbb
662: /* set regs, p0br, p0lr, p1br, p1lr, astlvl, ksp and change to kernel mode */
663: ldpctx
664: rei
665: /* put signal trampoline code in u. area */
666: 1: movab _u,r0
667: movc3 $16,sigcode,PCB_SIGC(r0)
668: /* save reboot flags in global _boothowto */
669: movl r11,_boothowto
670: /* calculate firstaddr, and call main() */
671: movab _end+NBPG-1,r0; bbcc $31,r0,0f; 0:; ashl $-PGSHIFT,r0,-(sp)
672: addl2 $UPAGES+1,(sp); calls $1,_main
673: /* proc[1] == /etc/init now running here; run icode */
674: pushl $PSL_CURMOD|PSL_PRVMOD; pushl $0; rei
675:
676: /* signal trampoline code: it is known that this code takes exactly 16 bytes */
677: /* in ../vax/pcb.h and in the movc3 above */
678: sigcode:
679: calls $4,5(pc) # params pushed by sendsig
680: chmk $139 # cleanup mask and onsigstack
681: rei
682: .word 0x7f # registers 0-6 (6==sp/compat)
683: callg (ap),*16(ap)
684: ret
685:
686: /*
687: * Primitives
688: */
689:
690: /*
691: * badaddr(addr, len)
692: * see if access addr with a len type instruction causes a machine check
693: * len is length of access (1=byte, 2=short, 4=long)
694: */
695: .globl _badaddr
696: _badaddr:
697: .word 0
698: movl $1,r0
699: mfpr $IPL,r1
700: mtpr $HIGH,$IPL
701: movl _scb+MCKVEC,r2
702: movl 4(ap),r3
703: movl 8(ap),r4
704: movab 9f+INTSTK,_scb+MCKVEC
705: bbc $0,r4,1f; tstb (r3)
706: 1: bbc $1,r4,1f; tstw (r3)
707: 1: bbc $2,r4,1f; tstl (r3)
708: 1: clrl r0 # made it w/o machine checks
709: 2: movl r2,_scb+MCKVEC
710: mtpr r1,$IPL
711: ret
712: .align 2
713: 9:
714: casel _cpu,$1,$VAX_MAX
715: 0:
716: .word 8f-0b # 1 is 780
717: .word 5f-0b # 2 is 750
718: .word 5f-0b # 3 is 730
719: 5:
720: #if defined(VAX750) || defined(VAX730)
721: mtpr $0xf,$MCESR
722: #endif
723: brb 1f
724: 8:
725: #if VAX780
726: mtpr $0,$SBIFS
727: #endif
728: 1:
729: addl2 (sp)+,sp # discard mchchk trash
730: movab 2b,(sp)
731: rei
732:
733: _addupc: .globl _addupc
734: .word 0x0
735: movl 8(ap),r2 # &u.u_prof
736: subl3 8(r2),4(ap),r0 # corrected pc
737: blss 9f
738: extzv $1,$31,r0,r0 # logical right shift
739: extzv $1,$31,12(r2),r1 # ditto for scale
740: emul r1,r0,$0,r0
741: ashq $-14,r0,r0
742: tstl r1
743: bneq 9f
744: bicl2 $1,r0
745: cmpl r0,4(r2) # length
746: bgequ 9f
747: addl2 (r2),r0 # base
748: probew $3,$2,(r0)
749: beql 8f
750: addw2 12(ap),(r0)
751: 9:
752: ret
753: 8:
754: clrl 12(r2)
755: ret
756:
757: _Copyin: .globl _Copyin # <<<massaged for jsb by asm.sed>>>
758: movl 12(sp),r0 # copy length
759: blss ersb
760: movl 4(sp),r1 # copy user address
761: cmpl $NBPG,r0 # probing one page or less ?
762: bgeq cishort # yes
763: ciloop:
764: prober $3,$NBPG,(r1) # bytes accessible ?
765: beql ersb # no
766: addl2 $NBPG,r1 # incr user address ptr
767: acbl $NBPG+1,$-NBPG,r0,ciloop # reduce count and loop
768: cishort:
769: prober $3,r0,(r1) # bytes accessible ?
770: beql ersb # no
771: movl 4(sp),r1
772: movl 8(sp),r3
773: jbr 2f
774: 1:
775: subl2 r0,12(sp)
776: movc3 r0,(r1),(r3)
777: 2:
778: movzwl $65535,r0
779: cmpl 12(sp),r0
780: jgtr 1b
781: movc3 12(sp),(r1),(r3)
782: clrl r0 #redundant
783: rsb
784:
785: ersb:
786: movl $EFAULT,r0
787: rsb
788:
789: _Copyout: .globl _Copyout # <<<massaged for jsb by asm.sed >>>
790: movl 12(sp),r0 # get count
791: blss ersb
792: movl 8(sp),r1 # get user address
793: cmpl $NBPG,r0 # can do in one probew?
794: bgeq coshort # yes
795: coloop:
796: probew $3,$NBPG,(r1) # bytes accessible?
797: beql ersb # no
798: addl2 $NBPG,r1 # increment user address
799: acbl $NBPG+1,$-NBPG,r0,coloop # reduce count and loop
800: coshort:
801: probew $3,r0,(r1) # bytes accessible?
802: beql ersb # no
803: movl 4(sp),r1
804: movl 8(sp),r3
805: jbr 2f
806: 1:
807: subl2 r0,12(sp)
808: movc3 r0,(r1),(r3)
809: 2:
810: movzwl $65535,r0
811: cmpl 12(sp),r0
812: jgtr 1b
813: movc3 12(sp),(r1),(r3)
814: clrl r0 #redundant
815: rsb
816:
817: /*
818: * non-local goto's
819: */
820: .globl _Setjmp
821: _Setjmp:
822: movq r6,(r0)+
823: movq r8,(r0)+
824: movq r10,(r0)+
825: movq r12,(r0)+
826: addl3 $4,sp,(r0)+
827: movl (sp),(r0)
828: clrl r0
829: rsb
830:
831: .globl _Longjmp
832: _Longjmp:
833: movq (r0)+,r6
834: movq (r0)+,r8
835: movq (r0)+,r10
836: movq (r0)+,r12
837: movl (r0)+,r1
838: cmpl r1,sp # must be a pop
839: bgequ lj2
840: pushab lj1
841: calls $1,_panic
842: lj2:
843: movl r1,sp
844: jmp *(r0) # ``rsb''
845:
846: lj1: .asciz "longjmp"
847:
848: .globl _whichqs
849: .globl _qs
850: .globl _cnt
851:
852: .globl _noproc
853: .comm _noproc,4
854: .globl _runrun
855: .comm _runrun,4
856:
857: /*
858: * The following primitives use the fancy VAX instructions
859: * much like VMS does. _whichqs tells which of the 32 queues _qs
860: * have processes in them. Setrq puts processes into queues, Remrq
861: * removes them from queues. The running process is on no queue,
862: * other processes are on a queue related to p->p_pri, divided by 4
863: * actually to shrink the 0-127 range of priorities into the 32 available
864: * queues.
865: */
866:
867: /*
868: * Setrq(p), using fancy VAX instructions.
869: *
870: * Call should be made at spl6(), and p->p_stat should be SRUN
871: */
872: .globl _Setrq # <<<massaged to jsb by "asm.sed">>>
873: _Setrq:
874: tstl P_RLINK(r0) ## firewall: p->p_rlink must be 0
875: beql set1 ##
876: pushab set3 ##
877: calls $1,_panic ##
878: set1:
879: movzbl P_PRI(r0),r1 # put on queue which is p->p_pri / 4
880: ashl $-2,r1,r1
881: movaq _qs[r1],r2
882: insque (r0),*4(r2) # at end of queue
883: bbss r1,_whichqs,set2 # mark queue non-empty
884: set2:
885: rsb
886:
887: set3: .asciz "setrq"
888:
889: /*
890: * Remrq(p), using fancy VAX instructions
891: *
892: * Call should be made at spl6().
893: */
894: .globl _Remrq # <<<massaged to jsb by "asm.sed">>>
895: _Remrq:
896: movzbl P_PRI(r0),r1
897: ashl $-2,r1,r1
898: bbsc r1,_whichqs,rem1
899: pushab rem3 # it wasn't recorded to be on its q
900: calls $1,_panic
901: rem1:
902: remque (r0),r2
903: beql rem2
904: bbss r1,_whichqs,rem2
905: rem2:
906: clrl P_RLINK(r0) ## for firewall checking
907: rsb
908:
909: rem3: .asciz "remrq"
910:
911: /*
912: * Masterpaddr is the p->p_addr of the running process on the master
913: * processor. When a multiprocessor system, the slave processors will have
914: * an array of slavepaddr's.
915: */
916: .globl _masterpaddr
917: .data
918: _masterpaddr:
919: .long 0
920:
921: .text
922: sw0: .asciz "swtch"
923: /*
924: * Swtch(), using fancy VAX instructions
925: */
926: .globl _Swtch
927: _Swtch: # <<<massaged to jsb by "asm.sed">>>
928: movl $1,_noproc
929: clrl _runrun
930: sw1: ffs $0,$32,_whichqs,r0 # look for non-empty queue
931: bneq sw1a
932: mtpr $0,$IPL # must allow interrupts here
933: jbr sw1 # this is an idle loop!
934: sw1a: mtpr $0x18,$IPL # lock out all so _whichqs==_qs
935: bbcc r0,_whichqs,sw1 # proc moved via lbolt interrupt
936: movaq _qs[r0],r1
937: remque *(r1),r2 # r2 = p = highest pri process
938: bvc sw2 # make sure something was there
939: sw1b: pushab sw0
940: calls $1,_panic
941: sw2: beql sw3
942: insv $1,r0,$1,_whichqs # still more procs in this queue
943: sw3:
944: clrl _noproc
945: tstl P_WCHAN(r2) ## firewalls
946: bneq sw1b ##
947: movzbl P_STAT(r2),r3 ##
948: cmpl $SRUN,r3 ##
949: bneq sw1b ##
950: clrl P_RLINK(r2) ##
951: movl *P_ADDR(r2),r0
952: movl r0,_masterpaddr
953: ashl $PGSHIFT,r0,r0 # r0 = pcbb(p)
954: /* mfpr $PCBB,r1 # resume of current proc is easy
955: * cmpl r0,r1
956: */ beql res0
957: incl _cnt+V_SWTCH
958: /* fall into... */
959:
960: /*
961: * Resume(pf)
962: */
963: .globl _Resume # <<<massaged to jsb by "asm.sed">>>
964: _Resume:
965: mtpr $0x18,$IPL # no interrupts, please
966: movl _CMAP2,_u+PCB_CMAP2 # yech
967: svpctx
968: mtpr r0,$PCBB
969: ldpctx
970: movl _u+PCB_CMAP2,_CMAP2 # yech
971: mtpr $_CADDR2,$TBIS
972: res0:
973: tstl _u+PCB_SSWAP
974: beql res1
975: movl _u+PCB_SSWAP,r0
976: clrl _u+PCB_SSWAP
977: movab _Longjmp,(sp)
978: movl $PSL_PRVMOD,4(sp) # ``cheating'' (jfr)
979: res1:
980: rei
981:
982: /*
983: * {fu,su},{byte,word}, all massaged by asm.sed to jsb's
984: */
985: .globl _Fuword
986: _Fuword:
987: prober $3,$4,(r0)
988: beql fserr
989: movl (r0),r0
990: rsb
991: fserr:
992: mnegl $1,r0
993: rsb
994:
995: .globl _Fubyte
996: _Fubyte:
997: prober $3,$1,(r0)
998: beql fserr
999: movzbl (r0),r0
1000: rsb
1001:
1002: .globl _Suword
1003: _Suword:
1004: probew $3,$4,(r0)
1005: beql fserr
1006: movl r1,(r0)
1007: clrl r0
1008: rsb
1009:
1010: .globl _Subyte
1011: _Subyte:
1012: probew $3,$1,(r0)
1013: beql fserr
1014: movb r1,(r0)
1015: clrl r0
1016: rsb
1017:
1018: /*
1019: * Copy 1 relocation unit (NBPG bytes)
1020: * from user virtual address to physical address
1021: */
1022: _copyseg: .globl _copyseg
1023: .word 0x0
1024: bisl3 $PG_V|PG_KW,8(ap),_CMAP2
1025: mtpr $_CADDR2,$TBIS # invalidate entry for copy
1026: movc3 $NBPG,*4(ap),_CADDR2
1027: ret
1028:
1029: /*
1030: * zero out physical memory
1031: * specified in relocation units (NBPG bytes)
1032: */
1033: _clearseg: .globl _clearseg
1034: .word 0x0
1035: bisl3 $PG_V|PG_KW,4(ap),_CMAP1
1036: mtpr $_CADDR1,$TBIS
1037: movc5 $0,(sp),$0,$NBPG,_CADDR1
1038: ret
1039:
1040: /*
1041: * Check address.
1042: * Given virtual address, byte count, and rw flag
1043: * returns 0 on no access.
1044: */
1045: _useracc: .globl _useracc
1046: .word 0x0
1047: movl 4(ap),r0 # get va
1048: movl 8(ap),r1 # count
1049: tstl 12(ap) # test for read access ?
1050: bneq userar # yes
1051: cmpl $NBPG,r1 # can we do it in one probe ?
1052: bgeq uaw2 # yes
1053: uaw1:
1054: probew $3,$NBPG,(r0)
1055: beql uaerr # no access
1056: addl2 $NBPG,r0
1057: acbl $NBPG+1,$-NBPG,r1,uaw1
1058: uaw2:
1059: probew $3,r1,(r0)
1060: beql uaerr
1061: movl $1,r0
1062: ret
1063:
1064: userar:
1065: cmpl $NBPG,r1
1066: bgeq uar2
1067: uar1:
1068: prober $3,$NBPG,(r0)
1069: beql uaerr
1070: addl2 $NBPG,r0
1071: acbl $NBPG+1,$-NBPG,r1,uar1
1072: uar2:
1073: prober $3,r1,(r0)
1074: beql uaerr
1075: movl $1,r0
1076: ret
1077: uaerr:
1078: clrl r0
1079: ret
1080:
1081: /*
1082: * kernacc - check for kernel access privileges
1083: *
1084: * We can't use the probe instruction directly because
1085: * it ors together current and previous mode.
1086: */
1087: .globl _kernacc
1088: _kernacc:
1089: .word 0x0
1090: movl 4(ap),r0 # virtual address
1091: bbcc $31,r0,kacc1
1092: bbs $30,r0,kacerr
1093: mfpr $SBR,r2 # address and length of page table (system)
1094: bbss $31,r2,0f; 0:
1095: mfpr $SLR,r3
1096: brb kacc2
1097: kacc1:
1098: bbsc $30,r0,kacc3
1099: mfpr $P0BR,r2 # user P0
1100: mfpr $P0LR,r3
1101: brb kacc2
1102: kacc3:
1103: mfpr $P1BR,r2 # user P1 (stack)
1104: mfpr $P1LR,r3
1105: kacc2:
1106: addl3 8(ap),r0,r1 # ending virtual address
1107: addl2 $NBPG-1,r1
1108: ashl $-PGSHIFT,r0,r0
1109: ashl $-PGSHIFT,r1,r1
1110: bbs $31,4(ap),kacc6
1111: bbc $30,4(ap),kacc6
1112: cmpl r0,r3 # user stack
1113: blss kacerr # address too low
1114: brb kacc4
1115: kacc6:
1116: cmpl r1,r3 # compare last page to P0LR or SLR
1117: bgtr kacerr # address too high
1118: kacc4:
1119: movl (r2)[r0],r3
1120: bbc $31,4(ap),kacc4a
1121: bbc $31,r3,kacerr # valid bit is off
1122: kacc4a:
1123: cmpzv $27,$4,r3,$1 # check protection code
1124: bleq kacerr # no access allowed
1125: tstb 12(ap)
1126: bneq kacc5 # only check read access
1127: cmpzv $27,$2,r3,$3 # check low 2 bits of prot code
1128: beql kacerr # no write access
1129: kacc5:
1130: aoblss r1,r0,kacc4 # next page
1131: movl $1,r0 # no errors
1132: ret
1133: kacerr:
1134: clrl r0 # error
1135: ret
1136: /*
1137: * Extracted and unrolled most common case of pagein (hopefully):
1138: * resident and not on free list (reclaim of page is purely
1139: * for the purpose of simulating a reference bit)
1140: *
1141: * Built in constants:
1142: * CLSIZE of 2, USRSTACK of 0x7ffff000, any bit fields
1143: * in pte's or the core map
1144: */
1145: .text
1146: .globl Fastreclaim
1147: Fastreclaim:
1148: PUSHR
1149: extzv $9,$23,28(sp),r3 # virtual address
1150: bicl2 $1,r3 # v = clbase(btop(virtaddr));
1151: movl _u+U_PROCP,r5 # p = u.u_procp
1152: # from vtopte(p, v) ...
1153: cmpl r3,P_TSIZE(r5)
1154: jgequ 2f # if (isatsv(p, v)) {
1155: ashl $2,r3,r4
1156: addl2 P_P0BR(r5),r4 # tptopte(p, vtotp(p, v));
1157: movl $1,r2 # type = CTEXT;
1158: jbr 3f
1159: 2:
1160: subl3 P_SSIZE(r5),$0x3ffff8,r0
1161: cmpl r3,r0
1162: jgequ 2f # } else if (isadsv(p, v)) {
1163: ashl $2,r3,r4
1164: addl2 P_P0BR(r5),r4 # dptopte(p, vtodp(p, v));
1165: clrl r2 # type = !CTEXT;
1166: jbr 3f
1167: 2:
1168: cvtwl P_SZPT(r5),r4 # } else (isassv(p, v)) {
1169: ashl $7,r4,r4
1170: subl2 $(0x3ffff8+UPAGES),r4
1171: addl2 r3,r4
1172: ashl $2,r4,r4
1173: addl2 P_P0BR(r5),r4 # sptopte(p, vtosp(p, v));
1174: clrl r2 # type = !CTEXT;
1175: 3: # }
1176: bitb $0x82,3(r4)
1177: beql 2f # if (pte->pg_v || pte->pg_fod)
1178: POPR; rsb # let pagein handle it
1179: 2:
1180: bicl3 $0xffe00000,(r4),r0
1181: jneq 2f # if (pte->pg_pfnum == 0)
1182: POPR; rsb # let pagein handle it
1183: 2:
1184: subl2 _firstfree,r0
1185: ashl $-1,r0,r0
1186: incl r0 # pgtocm(pte->pg_pfnum)
1187: mull2 $12,r0
1188: addl2 _cmap,r0 # &cmap[pgtocm(pte->pg_pfnum)]
1189: tstl r2
1190: jeql 2f # if (type == CTEXT &&
1191: jbc $29,4(r0),2f # c_intrans)
1192: POPR; rsb # let pagein handle it
1193: 2:
1194: jbc $30,4(r0),2f # if (c_free)
1195: POPR; rsb # let pagein handle it
1196: 2:
1197: bisb2 $0x80,3(r4) # pte->pg_v = 1;
1198: jbc $26,4(r4),2f # if (anycl(pte, pg_m)
1199: bisb2 $0x04,3(r4) # pte->pg_m = 1;
1200: 2:
1201: bicw3 $0x7f,2(r4),r0
1202: bicw3 $0xff80,6(r4),r1
1203: bisw3 r0,r1,6(r4) # distcl(pte);
1204: ashl $PGSHIFT,r3,r0
1205: mtpr r0,$TBIS
1206: addl2 $NBPG,r0
1207: mtpr r0,$TBIS # tbiscl(v);
1208: tstl r2
1209: jeql 2f # if (type == CTEXT)
1210: movl P_TEXTP(r5),r0
1211: movl X_CADDR(r0),r5 # for (p = p->p_textp->x_caddr; p; ) {
1212: jeql 2f
1213: ashl $2,r3,r3
1214: 3:
1215: addl3 P_P0BR(r5),r3,r0 # tpte = tptopte(p, tp);
1216: bisb2 $1,P_FLAG+3(r5) # p->p_flag |= SPTECHG;
1217: movl (r4),(r0)+ # for (i = 0; i < CLSIZE; i++)
1218: movl 4(r4),(r0) # tpte[i] = pte[i];
1219: movl P_XLINK(r5),r5 # p = p->p_xlink;
1220: jneq 3b # }
1221: 2: # collect a few statistics...
1222: incl _u+U_RU+RU_MINFLT # u.u_ru.ru_minflt++;
1223: moval _cnt,r0
1224: incl V_FAULTS(r0) # cnt.v_faults++;
1225: incl V_PGREC(r0) # cnt.v_pgrec++;
1226: incl V_FASTPGREC(r0) # cnt.v_fastpgrec++;
1227: incl V_TRAP(r0) # cnt.v_trap++;
1228: POPR
1229: addl2 $8,sp # pop pc, code
1230: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT)
1231: rei
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.