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