|
|
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.