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