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