|
|
1.1 ! root 1: /* locore.s 4.50 81/05/18 */ ! 2: # ------------------- ! 3: ! 4: #include "../machine/mtpr.h" ! 5: #include "../machine/trap.h" ! 6: #include "../machine/psl.h" ! 7: #include "../machine/pte.h" ! 8: #include "../machine/cp.h" ! 9: #include "../machine/mem.h" ! 10: ! 11: #include "../h/errno.h" ! 12: ! 13: .set HIGH,0x1f # mask for total disable ! 14: .set BERVEC,0x80 # offset into scb of the bus error vector ! 15: .set RESTVEC,0x8 # offset into scb of the restart vector ! 16: .set MAXPHYSMEM,8*1024*1024-1 # max physical memory ! 17: # while we work on CMD/32M ! ! 18: # look at vmsched.c to see why. ! 19: .set MEMUNIT,64*1024 # minimum memory increment ! 20: ! 21: .set NISP,3 # number of interrupt stack pages ! 22: .set SYSTEM,0xC0000000 # virtual address of system start ! 23: .set PPAGES,0x100000 # Number of possible pages in P0,P1, etc. ! 24: ! 25: /* ACBL for non-negative '_add' */ ! 26: #define ACBL(_limit,_add,_index,_displ) \ ! 27: addl2 _add,_index; \ ! 28: cmpl _index,_limit; \ ! 29: bleq _displ ! 30: ! 31: /* _ACBL for negative '_add' */ ! 32: #define _ACBL(_limit,_add,_index,_displ) \ ! 33: addl2 _add,_index; \ ! 34: cmpl _index,_limit; \ ! 35: bgeq _displ ! 36: ! 37: #define MOVC3(_len,_srcaddr,_dstaddr) \ ! 38: movl _srcaddr,r0; \ ! 39: movl _dstaddr,r1; \ ! 40: movl _len,r2; \ ! 41: movblk ! 42: ! 43: /* Keep address of psl if coming from user mode */ ! 44: #define CHECK_SFE(_delta) \ ! 45: bitl $PSL_CURMOD,_delta(sp); \ ! 46: jeql 1f; \ ! 47: moval _delta(sp),_user_psl; \ ! 48: 1: ! 49: ! 50: /* ! 51: * User structure is UPAGES at top of user space. ! 52: */ ! 53: .globl _u ! 54: .set _u,SYSTEM - UPAGES*NBPG ! 55: ! 56: /* ! 57: * Restart stack. Used on power recovery or panic. ! 58: * Takes a core-dump and then halts. ! 59: */ ! 60: .globl _rsstk ! 61: ! 62: _rsstk: .space 1024-8 ! 63: .globl pwfl_stk ! 64: pwfl_stk: .space 4 ! 65: dumpflag: .space 4 ! 66: ! 67: .globl _intstack ! 68: _intstack: ! 69: .space NISP*NBPG ! 70: eintstack: ! 71: ! 72: .data ! 73: .globl pwfl_r0 ! 74: pwfl_r0: .space 14*4 # Enough for r0 - r13 ! 75: .globl pwfl_sp ! 76: pwfl_sp: .long 0x12345678 # r14 ! 77: .globl pwfl_SCBB ! 78: pwfl_SCBB: .long 0x12345678 ! 79: .globl pwfl_SBR ! 80: pwfl_SBR: .long 0x12345678 ! 81: .globl pwfl_SLR ! 82: pwfl_SLR: .long 0x12345678 ! 83: .globl pwfl_P0BR ! 84: pwfl_P0BR: .long 0x12345678 ! 85: .globl pwfl_P0LR ! 86: pwfl_P0LR: .long 0x12345678 ! 87: .globl pwfl_P1BR ! 88: pwfl_P1BR: .long 0x12345678 ! 89: .globl pwfl_P1LR ! 90: pwfl_P1LR: .long 0x12345678 ! 91: .globl pwfl_P2BR ! 92: pwfl_P2BR: .long 0x12345678 ! 93: .globl pwfl_P2LR ! 94: pwfl_P2LR: .long 0x12345678 ! 95: .globl pwfl_IPL ! 96: pwfl_IPL: .long 0x12345678 ! 97: .globl pwfl_DCK ! 98: pwfl_DCK: .long 0x12345678 ! 99: .globl pwfl_CCK ! 100: pwfl_CCK: .long 0x12345678 ! 101: .globl pwfl_PCBB ! 102: pwfl_PCBB: .long 0x12345678 ! 103: .globl pwfl_ISP ! 104: pwfl_ISP: .long 0x12345678 ! 105: .globl pwfl_KSP ! 106: pwfl_KSP: .long 0x12345678 ! 107: .globl pwfl_USP ! 108: pwfl_USP: .long 0x12345678 ! 109: .globl pwfl_MME ! 110: pwfl_MME: .long 0x12345678 ! 111: .globl pwfl_PSL ! 112: pwfl_PSL: .long 0x12345678 ! 113: ! 114: /* ! 115: * Do a dump. ! 116: * Called by auto-restart. ! 117: * May be called manually. ! 118: */ ! 119: .align 2 ! 120: .text ! 121: .globl _Xdoadump ! 122: .globl _doadump ! 123: _Xdoadump: # CP brings Tahoe here on power recovery ! 124: loadr $0x3fff,pwfl_r0 # Restore r0 - r13 ! 125: movl pwfl_sp,sp # Restore sp ( = r14 ) ! 126: mtpr pwfl_SCBB,$SCBB ! 127: mtpr pwfl_SBR,$SBR # Restore all re_loadable registers ! 128: mtpr pwfl_SLR,$SLR ! 129: mtpr pwfl_P0BR,$P0BR ! 130: mtpr pwfl_P0LR,$P0LR ! 131: mtpr pwfl_P1BR,$P1BR ! 132: mtpr pwfl_P1LR,$P1LR ! 133: mtpr pwfl_P2BR,$P2BR ! 134: mtpr pwfl_P2LR,$P2LR ! 135: mtpr pwfl_IPL,$IPL ! 136: mtpr pwfl_DCK,$DCK ! 137: mtpr pwfl_CCK,$CCK ! 138: mtpr pwfl_PCBB,$PCBB ! 139: mtpr pwfl_ISP,$ISP ! 140: mtpr pwfl_KSP,$KSP ! 141: mtpr pwfl_USP,$USP ! 142: ! 143: /* now go to mapped mode */ ! 144: /* Have to change PC to system addresses */ ! 145: mtpr $1,$PACC # Thoroughly clean up caches. ! 146: mtpr $1,$PADC ! 147: mtpr $1,$TBIA ! 148: mtpr pwfl_MME,$MME ! 149: # Restore PSW. Last thing to be done. ! 150: bicpsw $0xff ! 151: bispsw pwfl_PSL+2 # Set original bits back (just in case..) ! 152: jmp *$0f ! 153: _doadump: ! 154: .word 0 ! 155: #define _rsstkmap _Sysmap+12 ! 156: # Tahoe storage, scb, rsstk, interrupt stack ! 157: 0: ! 158: mtpr $HIGH,$IPL ! 159: andl2 $0!PG_PROT,_rsstkmap ! 160: orl2 $PG_KW,_rsstkmap # Make dump stack r/w ! 161: tstl dumpflag # dump only once! ! 162: bneq 1f ! 163: movl $1,dumpflag ! 164: mtpr $0,$TBIA ! 165: movab dumpflag,sp ! 166: callf $4,_dumpsys ! 167: 1: ! 168: halt ! 169: ! 170: /* ! 171: * Interrupt vector routines ! 172: */ ! 173: .globl _waittime ! 174: ! 175: #define SCBVEC(name) \ ! 176: .align 2; \ ! 177: .globl _X/**/name; \ ! 178: _X/**/name ! 179: #define PANIC(msg) clrl _waittime; pushab 1f; \ ! 180: callf $8,_panic; 1: .asciz msg ! 181: #define PRINTF(n,msg) pushab 1f; callf $(n+2)*4,_printf; MSG(msg) ! 182: #define MSG(msg) .data; 1: .asciz msg; .text ! 183: ! 184: # these registers are not restored by the C-compiler. ! 185: #define PUSHR pushl r0; pushl r1; ! 186: #define POPR movl (sp)+, r1; movl (sp)+, r0; ! 187: # mask for error code on stack. ! 188: ! 189: SCBVEC(buserr): ! 190: CHECK_SFE(12) ! 191: PUSHR ! 192: andl3 12(sp),$ERRCD,r0 ! 193: jeql go_on ! 194: cmpl r0,$APE ! 195: jneq 1f ! 196: halt # Address parity error !!! ! 197: 1: cmpl r0,$VBE ! 198: jneq go_on ! 199: halt # Versabus error !!! ! 200: go_on: ! 201: pushab 2*4(sp) # Pointer to parameters ! 202: callf $8,_buserror ! 203: POPR ! 204: movab 8(sp),sp # Remove hardware parameters ! 205: rei ! 206: ! 207: SCBVEC(powfail): # We should be on interrupt stack now. ! 208: movpsl pwfl_PSL # Keeps all flags, etc. ! 209: storer $0x3fff,pwfl_r0 # Saves r0 - r13 ! 210: moval 0(sp),pwfl_sp # Saves sp ( = r14 ) ! 211: mfpr $SBR,pwfl_SBR # Save all re_loadable registers ! 212: mfpr $SLR,pwfl_SLR ! 213: mfpr $P0BR,pwfl_P0BR ! 214: mfpr $P0LR,pwfl_P0LR ! 215: mfpr $P1BR,pwfl_P1BR ! 216: mfpr $P1LR,pwfl_P1LR ! 217: mfpr $P2BR,pwfl_P2BR ! 218: mfpr $P2LR,pwfl_P2LR ! 219: mfpr $IPL,pwfl_IPL ! 220: mfpr $MME,pwfl_MME ! 221: mfpr $DCK,pwfl_DCK ! 222: mfpr $CCK,pwfl_CCK ! 223: mfpr $PCBB,pwfl_PCBB ! 224: mfpr $ISP,pwfl_ISP ! 225: mfpr $SCBB,pwfl_SCBB ! 226: mfpr $KSP,pwfl_KSP ! 227: mfpr $USP,pwfl_USP ! 228: moval _Xdoadump-SYSTEM,_scb+RESTVEC ! 229: halt ! 230: ! 231: SCBVEC(stray): ! 232: PUSHR; PRINTF(0, "******* Undefined interrupt *******\n"); POPR; ! 233: rei ! 234: SCBVEC(soft15): ! 235: SCBVEC(soft14): ! 236: SCBVEC(soft13): ! 237: SCBVEC(soft12): ! 238: SCBVEC(soft11): ! 239: SCBVEC(soft10): ! 240: #ifndef SIMIO ! 241: SCBVEC(soft9): ! 242: #endif ! 243: SCBVEC(soft7): ! 244: SCBVEC(soft6): ! 245: SCBVEC(soft5): ! 246: SCBVEC(soft4): ! 247: #ifndef SIMIO ! 248: SCBVEC(soft3): ! 249: SCBVEC(soft2): ! 250: SCBVEC(soft1): ! 251: #endif ! 252: PUSHR ! 253: PRINTF(0, "******* Undefined software interrupt *******\n") ! 254: POPR; ! 255: rei ! 256: ! 257: #ifdef SIMIO ! 258: SCBVEC(soft2): ! 259: #endif ! 260: SCBVEC(cnrint): ! 261: CHECK_SFE(4) ! 262: PUSHR; pushl $CPCONS; callf $8,_cnrint; POPR; incl _cnt+V_INTR; rei ! 263: #ifdef SIMIO ! 264: SCBVEC(soft3): ! 265: #endif ! 266: SCBVEC(cnxint): ! 267: CHECK_SFE(4) ! 268: PUSHR; pushl $CPCONS; callf $8,_cnxint; POPR; incl _cnt+V_INTR; rei ! 269: SCBVEC(rmtrint): ! 270: CHECK_SFE(4) ! 271: PUSHR; pushl $CPREMOT; callf $8,_cnrint; POPR; incl _cnt+V_INTR; rei ! 272: SCBVEC(rmtxint): ! 273: CHECK_SFE(4) ! 274: PUSHR; pushl $CPREMOT; callf $8,_cnxint; POPR; incl _cnt+V_INTR; rei ! 275: #ifdef SIMIO ! 276: SCBVEC(soft9): ! 277: #endif ! 278: SCBVEC(hardclock): ! 279: CHECK_SFE(4) ! 280: PUSHR ! 281: pushl 4+2*4(sp); pushl 4+2*4(sp); ! 282: callf $12,_hardclock # hardclock(pc,psl) ! 283: POPR; ! 284: incl _cnt+V_INTR ## temp so not to break vmstat -= HZ ! 285: rei ! 286: SCBVEC(softclock): ! 287: CHECK_SFE(4) ! 288: PUSHR ! 289: pushl 4+2*4(sp); pushl 4+2*4(sp); ! 290: callf $12,_softclock # softclock(pc,psl) ! 291: POPR; ! 292: rei ! 293: ! 294: /* ! 295: * Trap and fault vector routines ! 296: */ ! 297: #define TRAP(a) pushl $T_/**/a; jbr alltraps ! 298: ! 299: /* ! 300: * Ast delivery (profiling and/or reschedule) ! 301: */ ! 302: /* ! 303: * When we want to reschedule we will force a memory fault by setting the m.s.b ! 304: * of P0LR. Then , on memory fault if m.s.b of P0LR is on we will clear it and ! 305: * TRAP(astflt). ! 306: * ! 307: */ ! 308: ! 309: # if this bit is on it is an ast. ! 310: #define ASTBIT 0x00100000 ! 311: #define P0MASK 0xc0000000 ! 312: ! 313: SCBVEC(kspnotval): ! 314: CHECK_SFE(4) ! 315: pushl $0; TRAP(KSPNOTVAL) ! 316: SCBVEC(privinflt): ! 317: CHECK_SFE(4) ! 318: pushl $0; TRAP(PRIVINFLT) ! 319: SCBVEC(resopflt): ! 320: CHECK_SFE(4) ! 321: pushl $0; TRAP(RESOPFLT) ! 322: SCBVEC(resadflt): ! 323: CHECK_SFE(4) ! 324: pushl $0; TRAP(RESADFLT) ! 325: SCBVEC(bptflt): ! 326: CHECK_SFE(4) ! 327: pushl $0; TRAP(BPTFLT) ! 328: SCBVEC(tracep): ! 329: CHECK_SFE(4) ! 330: pushl $0; TRAP(TRCTRAP) ! 331: SCBVEC(alignflt): ! 332: CHECK_SFE(4) ! 333: pushl $0; TRAP(ALIGNFLT) ! 334: SCBVEC(arithtrap): ! 335: CHECK_SFE(8) ! 336: TRAP(ARITHTRAP) ! 337: ! 338: SCBVEC(protflt): ! 339: CHECK_SFE(12) ! 340: bitl $1,(sp)+ ! 341: jneq segflt ! 342: TRAP(PROTFLT) ! 343: segflt: ! 344: TRAP(SEGFLT) ! 345: ! 346: SCBVEC(fpm): # Floating Point eMulation ! 347: .globl _fpemulate ! 348: CHECK_SFE(24) ! 349: callf $24,_fpemulate # We want psl, pc and opcode ! 350: # not to be removed by the ret. ! 351: ! 352: # Don't modify registers now !! ! 353: tstl (sp) # Stack= PSL, PC, return_code ! 354: jneq _Xarithtrap # If not OK, emulate F.P. exception ! 355: movab 4(sp),sp # Else remove return_code and ! 356: rei ! 357: ! 358: SCBVEC(sfexcep): ! 359: CHECK_SFE(4) ! 360: pushl $0 ! 361: TRAP(ASTFLT) ! 362: ! 363: SCBVEC(transflt): ! 364: CHECK_SFE(12) ! 365: bitl $1,(sp)+ ! 366: bneq tableflt ! 367: pageflt: ! 368: TRAP(PAGEFLT) ! 369: tableflt: ! 370: TRAP(TABLEFLT) ! 371: ! 372: alltraps: ! 373: mfpr $USP,-(sp); callf $4,_trap; mtpr (sp)+,$USP ! 374: incl _cnt+V_TRAP ! 375: movab 8(sp),sp # pop type, code ! 376: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT) ! 377: rei ! 378: ! 379: SCBVEC(syscall): ! 380: CHECK_SFE(8) ! 381: pushl $T_SYSCALL ! 382: mfpr $USP,-(sp); callf $4,_syscall; mtpr (sp)+,$USP ! 383: incl _cnt+V_SYSCALL ! 384: movab 8(sp),sp # pop type, code ! 385: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT) ! 386: rei ! 387: ! 388: /* ! 389: * System page table ! 390: */ ! 391: #define vaddr(x) ((((x)-_Sysmap)/4)*NBPG+SYSTEM) ! 392: #define SYSMAP(mname, vname, npte) \ ! 393: _/**/mname: .globl _/**/mname; \ ! 394: .space npte*4; \ ! 395: .globl _/**/vname; \ ! 396: .set _/**/vname,vaddr(_/**/mname) ! 397: ! 398: .data ! 399: .align 2 ! 400: SYSMAP(Sysmap ,Sysbase ,SYSPTSIZE ) ! 401: SYSMAP(VMEMbeg ,vmembeg ,0 ) ! 402: SYSMAP(VMEMmap ,vmem ,IOSIZE ) ! 403: SYSMAP(VMEMend ,vmemend ,0 ) ! 404: SYSMAP(Usrptmap ,usrpt ,USRPTSIZE ) ! 405: SYSMAP(Forkmap ,forkutl ,UPAGES ) ! 406: SYSMAP(Xswapmap ,xswaputl ,UPAGES ) ! 407: SYSMAP(Xswap2map,xswap2utl ,UPAGES ) ! 408: SYSMAP(Swapmap ,swaputl ,UPAGES ) ! 409: SYSMAP(Pushmap ,pushutl ,UPAGES ) ! 410: SYSMAP(Vfmap ,vfutl ,UPAGES ) ! 411: /* ! 412: SYSMAP(IOmap ,ioutl ,(MAXBPTE+1) ) ! 413: */ ! 414: SYSMAP(VDmap ,vdutl ,(MAXBPTE+1) ) ! 415: SYSMAP(CYmap ,cyutl ,(TBUFSIZ+1) ) ! 416: SYSMAP(CMAP1 ,CADDR1 ,1 ) ! 417: SYSMAP(CMAP2 ,CADDR2 ,1 ) ! 418: SYSMAP(mmap ,vmmap ,1 ) ! 419: SYSMAP(msgbufmap,msgbuf ,MSGBUFPTECNT ) ! 420: SYSMAP(camap ,cabase ,16*CLSIZE ) ! 421: SYSMAP(ecamap ,calimit ,0 ) ! 422: SYSMAP(Mbmap ,mbutl ,NMBCLUSTERS*CLSIZE) ! 423: eSysmap: ! 424: .globl _Syssize ! 425: .set _Syssize,(eSysmap-_Sysmap)/4 ! 426: ! 427: .text ! 428: /* ! 429: * Initialization ! 430: * ! 431: * IPL 0x1f; MME 0; scbb, pcbb, sbr, slr, isp, ksp not set ! 432: * ! 433: */ ! 434: ! 435: .align 2 ! 436: .globl start ! 437: start: ! 438: .word 0 ! 439: ! 440: /* set system control block base and system page table params */ ! 441: ! 442: mtpr $_scb-SYSTEM,$SCBB ! 443: mtpr $_Sysmap-SYSTEM,$SBR ! 444: mtpr $_Syssize,$SLR ! 445: ! 446: /* double map the kernel into the virtual user addresses of phys mem */ ! 447: /* (to be on the safe side.This is supposed to run in system sace. ) */ ! 448: mtpr $_Sysmap,$P0BR ! 449: mtpr $_Syssize,$P0LR ! 450: ! 451: mtpr $_Sysmap,$P1BR # Against Murphy ! 452: mtpr $_Syssize,$P1LR ! 453: ! 454: /* set ISP */ ! 455: movl $_intstack-SYSTEM+NISP*NBPG,sp # Still physical ! ! 456: mtpr $_intstack+NISP*NBPG,$ISP ! 457: ! 458: /* count up memory */ ! 459: ! 460: clrl r7 ! 461: 1: pushl $1; pushl r7; callf $12,_badaddr; tstl r0; bneq 9f ! 462: addl2 $MEMUNIT,r7 ! 463: cmpl r7,$MAXPHYSMEM ! 464: bleq 1b ! 465: 9: ! 466: /* clear memory from kernel bss and pages for proc 0 u. and page table */ ! 467: movab _edata,r6 ! 468: movab _end,r5 ! 469: andl2 $0!SYSTEM,r6 ! 470: andl2 $0!SYSTEM,r5 ! 471: addl2 $(UPAGES*NBPG)+NBPG+NBPG,r5 ! 472: 1: clrl (r6); ACBL( r5,$4,r6,1b) ! 473: ! 474: /* trap() and syscall() save r0-r13 in the entry mask (per ../h/reg.h) */ ! 475: /* For floating point emulation, we do same for 'fpemulate' */ ! 476: orw2 $0x01fff,_trap ! 477: orw2 $0x01fff,_syscall ! 478: orw2 $0x01fff,_fpemulate ! 479: ! 480: /* initialize system page table: scb and int stack writeable */ ! 481: clrl r2 ! 482: movab eintstack,r1 ! 483: andl2 $0!SYSTEM,r1 ! 484: shrl $PGSHIFT,r1,r1 # r1-page number of eintstack. ! 485: ! 486: /* Start by making the processor storage read/only */ ! 487: ! 488: orl3 $PG_V|PG_KR,r2,_Sysmap[r2]; incl r2; ! 489: orl3 $PG_V|PG_KR,r2,_Sysmap[r2]; incl r2; ! 490: ! 491: /* Other parts of the system are read/write for kernel */ ! 492: ! 493: 1: orl3 $PG_V|PG_KW,r2,_Sysmap[r2]; # data:kernel write + phys=virtual ! 494: aoblss r1,r2,1b ! 495: ! 496: /* make rsstk read-only as red zone for interrupt stack */ ! 497: andl2 $0!PG_PROT,_rsstkmap ! 498: orl2 $PG_V|PG_KR,_rsstkmap # Make dump stack r/w ! 499: ! 500: /* make kernel text space read-only */ ! 501: /* ! 502: * HAVE TO CHECK ALL THE MAGIC CONSTANTS USED HERE : $xxxxxx */ ! 503: ! 504: movab _etext+NBPG-1,r1 ! 505: andl2 $0!SYSTEM,r1 ! 506: shrl $PGSHIFT,r1,r1 ! 507: 1: orl3 $PG_V|PG_KR,r2,_Sysmap[r2] ! 508: aoblss r1,r2,1b ! 509: ! 510: /* make kernel data, bss, read-write */ ! 511: movab _end+NBPG-1,r1 ! 512: andl2 $0!SYSTEM,r1 ! 513: shrl $PGSHIFT,r1,r1 ! 514: 1: orl3 $PG_V|PG_KW,r2,_Sysmap[r2] ! 515: aoblss r1,r2,1b ! 516: ! 517: /* now go to mapped mode */ ! 518: /* Have to change both PC and SP to system addresses */ ! 519: mtpr $1,$TBIA ! 520: mtpr $1,$PADC /* needed by HW parity & ECC logic */ ! 521: mtpr $1,$PACC /* just in case */ ! 522: mtpr $1,$MME ! 523: movab SYSTEM(sp),sp ! 524: .globl go_virt ! 525: go_virt: ! 526: jmp *$0f ! 527: 0: ! 528: ! 529: /* disable any interrupts */ ! 530: movl $0,_intenable ! 531: /* init mem sizes */ ! 532: shrl $PGSHIFT,r7,_maxmem ! 533: movl _maxmem,_physmem ! 534: movl _maxmem,_freemem ! 535: ! 536: /* setup context for proc[0] == Scheduler */ ! 537: movab _end-SYSTEM+NBPG-1,r6 ! 538: andl2 $0!(NBPG-1),r6 # make page boundary ! 539: ! 540: /* setup page table for proc[0] */ ! 541: shrl $PGSHIFT,r6,r3 # r3 = btoc(r6) ! 542: orl3 $PG_V|PG_KW,r3,_Usrptmap # init first upt entry ! 543: incl r3 # r3 - next page ! 544: movab _usrpt,r0 # r0 - first user page ! 545: mtpr r0,$TBIS ! 546: ! 547: /* init p0br, p0lr */ ! 548: mtpr r0,$P0BR # No P0 for proc[0] ! 549: mtpr $0,$P0LR ! 550: ! 551: mtpr r0,$P1BR # No P1 either ! 552: mtpr $0,$P1LR ! 553: ! 554: ! 555: /* init p2br, p2lr */ ! 556: movab NBPG(r0),r0 ! 557: movl $PPAGES-UPAGES,r1 ! 558: mtpr r1,$P2LR ! 559: moval -4*PPAGES(r0),r2 ! 560: mtpr r2,$P2BR ! 561: ! 562: /* setup mapping for UPAGES of _u */ ! 563: clrl r2; ! 564: movl $SYSTEM,r1 ! 565: addl2 $UPAGES,r3 ! 566: jbr 2f ! 567: 1: decl r3 ! 568: moval -NBPG(r1),r1; # r1 = virtual add of next (downward) _u page ! 569: subl2 $4,r0 # r0 = pte address ! 570: orl3 $PG_V|PG_URKW,r3,(r0) ! 571: mtpr r1,$TBIS ! 572: 2: aobleq $UPAGES,r2,1b ! 573: ! 574: /* initialize (slightly) the pcb */ ! 575: movab UPAGES*NBPG(r1),PCB_KSP(r1) # KSP starts at end of _u ! 576: movl r1,PCB_USP(r1) # USP starts just below _u ! 577: mfpr $P0BR,PCB_P0BR(r1) ! 578: mfpr $P0LR,PCB_P0LR(r1) ! 579: mfpr $P1BR,PCB_P1BR(r1) ! 580: mfpr $P1LR,PCB_P1LR(r1) ! 581: mfpr $P2BR,PCB_P2BR(r1) ! 582: mfpr $P2LR,PCB_P2LR(r1) ! 583: movl $CLSIZE,PCB_SZPT(r1) # init u.u_pcb.pcb_szpt ! 584: movl r11,PCB_R11(r1) # r11 obtained from CP on boot ! 585: movab 1f,PCB_PC(r1) # initial pc ! 586: clrl PCB_PSL(r1) # kernel mode, ipl=0 ! 587: movw $0xff,PCB_CKEY(r1) # give him a code key ! 588: movw $0xff,PCB_DKEY(r1) # give him a data key ! 589: shll $PGSHIFT,r3,r3 ! 590: mtpr r3,$PCBB # first pcbb (physical ! ) ! 591: ! 592: /* Go to a 'normal' process mode (kernel) */ ! 593: ! 594: ldpctx ! 595: rei # Actually 'returns' to the next instruction: ! 596: ! 597: /* put signal trampoline code in u. area */ ! 598: 1: movab _u,r0 ! 599: movl sigcode+0,PCB_SIGC+0(r0) ! 600: movl sigcode+4,PCB_SIGC+4(r0) ! 601: movl sigcode+8,PCB_SIGC+8(r0) ! 602: movl sigcode+12,PCB_SIGC+12(r0) ! 603: ! 604: /* save reboot flags in global _boothowto */ ! 605: movl r11,_boothowto ! 606: ! 607: /* calculate firstaddr, and call main() */ ! 608: movab _end-SYSTEM+NBPG-1,r0 ! 609: shrl $PGSHIFT,r0,-(sp) ! 610: addl2 $UPAGES+1,(sp) # First physical unused page number ! 611: callf $8,_main ! 612: ! 613: /* proc[1] == /etc/init now running here in kernel mode; run icode */ ! 614: pushl $PSL_CURMOD # User mode PSL ! 615: pushl $0 # PC = 0 (virtual now) ! 616: rei ! 617: ! 618: /* signal trampoline code: it is known that this code takes up to 16 */ ! 619: /* bytes in pcb.h and in the code above */ ! 620: /* The following user stack layout was set up by machdep.c/sendsig */ ! 621: /* routine: */ ! 622: /* */ ! 623: /* +---------------+ */ ! 624: /* | Last PSL |\ */ ! 625: /* +---------------+ > for rei */ ! 626: /* :-->| Last PC |/ */ ! 627: /* | +---------------+ */ ! 628: /* :___|__* SP |\ */ ! 629: /* +---------------+ | */ ! 630: /* | sigmask | | */ ! 631: /* +---------------+ > cleaned by kcall $139 (sigcleanup) */ ! 632: /* :-->| u.u_onstack | | */ ! 633: /* | +---------------+ | */ ! 634: /* :___|_* copy of SCP |/ */ ! 635: /* | +---------------+ */ ! 636: /* | | Process' r0 | */ ! 637: /* | +---------------+ */ ! 638: /* | | Process' r1 | */ ! 639: /* | +---------------+ */ ! 640: /* | | Handler addr. |\ */ ! 641: /* | +---------------+ | */ ! 642: /* :___|_* SCP | | */ ! 643: /* +---------------+ > cleaned by ret from calls */ ! 644: /* | u.u_code | | */ ! 645: /* +---------------+ | */ ! 646: /* | signal number|/ */ ! 647: /* +---------------+ */ ! 648: /* */ ! 649: /* * Stack when entering sigcode; setup by sendsig(); */ ! 650: /* */ ! 651: .align 2 ! 652: sigcode: # When the process executes this code ! 653: # (located in its u. structure), it ! 654: # is in user mode ! ! 655: calls $4*4+4,*12(sp) # 4 words popped from stack when this call returns ! 656: movl (sp)+,r1 ! 657: movl (sp)+,r0 ! 658: kcall $139 # Signal cleanup ! 659: rei # From user mode to user mode ! ! 660: ! 661: /* ! 662: * Primitives ! 663: */ ! 664: ! 665: /* ! 666: * badaddr(addr, len) ! 667: * see if access addr with a len type instruction causes a machine check ! 668: * len is length of access (1=byte, 2=short, 4=long) ! 669: * r0 = 0 means good(exists); r0 =1 means does not exist. ! 670: */ ! 671: .globl _badaddr ! 672: _badaddr: ! 673: .word 0x1c # Keep r4,r3,r2 ! 674: mfpr $IPL,r1 ! 675: mtpr $HIGH,$IPL ! 676: movl _scb+BERVEC,r2 ! 677: movl 4(fp),r3 ! 678: movl 8(fp),r4 ! 679: movab 9f,_scb+BERVEC ! 680: bbc $0,r4,1f; tstb (r3) ! 681: 1: bbc $1,r4,1f; tstw (r3) ! 682: 1: bbc $2,r4,1f; tstl (r3) ! 683: 1: clrl r0 # made it w/o machine checks ! 684: 2: movl r2,_scb+BERVEC ! 685: mtpr r1,$IPL ! 686: ret ! 687: ! 688: .align 2 ! 689: 9: # Here we catch buss error (if it comes) ! 690: andl3 4(sp),$ERRCD,r0 ! 691: cmpl r0,$APE ! 692: jneq 1f ! 693: halt # Address parity error !!! ! 694: 1: cmpl r0,$VBE ! 695: jneq 1f ! 696: halt # Versabus error ! 697: 1: ! 698: movl $1,r0 # Anything else = bad address ! 699: movab 8(sp),sp # discard buss error trash ! 700: movab 2b,(sp) # new program counter on stack. ! 701: rei ! 702: ! 703: ! 704: /* ! 705: * badcyaddr(addr) ! 706: * see if access tape master controller addr causes a bus error ! 707: * r0 = 0: no error; r0 = 1: timeout error. ! 708: */ ! 709: .globl _badcyaddr ! 710: _badcyaddr: ! 711: .word 0x0c # Keep r3,r2 ! 712: mfpr $IPL,r1 ! 713: mtpr $HIGH,$IPL ! 714: movl _scb+BERVEC,r2 ! 715: clrl r3 ! 716: movab 9f,_scb+BERVEC ! 717: movob $-1, *4(fp) ! 718: 1: aobleq $1000, r3, 1b ! 719: clrl r0 # made it w/o machine checks ! 720: 2: movl r2,_scb+BERVEC ! 721: mtpr r1,$IPL ! 722: ret ! 723: ! 724: .align 2 ! 725: 9: # Here we catch buss error (if it comes) ! 726: andl3 4(sp),$ERRCD,r0 ! 727: cmpl r0,$APE ! 728: jneq 1f ! 729: halt # Address parity error !!! ! 730: 1: cmpl r0,$VBE ! 731: jneq 1f ! 732: halt # Versabus error ! 733: 1: ! 734: movl $1,r0 # Anything else = timeout ! 735: movab 8(sp),sp # discard buss error trash ! 736: movab 2b,(sp) # new program counter on stack. ! 737: rei ! 738: ! 739: _bcopy: .globl _bcopy ! 740: .word 0x4 # save r2 ! 741: # Called by ovbcopy(from,dst,len) ! 742: movl 4(fp),r0 ! 743: movl 8(fp),r1 ! 744: movl 12(fp),r2 ! 745: movblk ! 746: ret ! 747: ! 748: _ovbcopy: .globl _ovbcopy ! 749: .word 0x001c ! 750: movl 4(fp),r0 ! 751: movl 8(fp),r1 ! 752: movl 12(fp),r2 ! 753: cmpl r0,r1 ! 754: bgtru 1f # normal forward case ! 755: beql 2f # equal, nothing to do ! 756: addl2 r2,r0 # may be overlapping ! 757: cmpl r0,r1 ! 758: bgtru 3f ! 759: subl2 r2,r0 # normal forward case ! 760: 1: ! 761: movblk ! 762: 2: ! 763: ret ! 764: 3: ! 765: addl2 r2,r1 # overlapping, must do backwards ! 766: subl3 r0,r1,r3 ! 767: movl r2,r4 ! 768: jbr 5f ! 769: 4: ! 770: subl2 r3,r0 ! 771: subl2 r3,r1 ! 772: movl r3,r2 ! 773: movblk ! 774: subl2 r3,r0 ! 775: subl2 r3,r1 ! 776: subl2 r3,r4 ! 777: 5: ! 778: cmpl r4,r3 ! 779: jgtr 4b ! 780: movl r4,r2 ! 781: subl2 r2,r0 ! 782: subl2 r2,r1 ! 783: movblk ! 784: ret ! 785: ! 786: /* ! 787: * bzero (base, count) ! 788: * zero out a block starting at 'base', size 'count'. ! 789: */ ! 790: _bzero: ! 791: .globl _bzero ! 792: .word 0x4 ! 793: movl $1f,r0 # r0 = null source string ! 794: movl 4(fp),r1 # r1 = destination address ! 795: movl 8(fp),r2 # r2 = count ! 796: movs3 ! 797: ret ! 798: 1: ! 799: .byte 0 ! 800: ! 801: ! 802: _copyin: .globl _copyin # the _Copyin subroutine in VAX ! 803: # became _copyin procedure for TAHOE ! 804: .word 0x0004 ! 805: movl 12(fp),r0 # copy length ! 806: blss ersb ! 807: movl 4(fp),r1 # copy user address ! 808: cmpl $NBPG,r0 # probing one page or less ? ! 809: bgeq cishort # yes ! 810: ciloop: ! 811: prober $1,(r1),$NBPG # bytes accessible ? ! 812: beql ersb # no ! 813: addl2 $NBPG,r1 # incr user address ptr ! 814: _ACBL ($NBPG+1,$-NBPG,r0,ciloop) # reduce count and loop ! 815: cishort: ! 816: prober $1,(r1),r0 # bytes accessible ? ! 817: beql ersb # no ! 818: MOVC3 (12(fp),4(fp),8(fp)) ! 819: clrl r0 ! 820: ret ! 821: ! 822: ersb: ! 823: movl $EFAULT,r0 ! 824: ret ! 825: ! 826: _copyout: .globl _copyout # the _Copyout subroutine in VAX ! 827: # became _copyout procedure for TAHOE ! 828: .word 0x04 ! 829: movl 12(fp),r0 # get count ! 830: blss ersb ! 831: movl 8(fp),r1 # get user address ! 832: cmpl $NBPG,r0 # can do in one probew? ! 833: bgeq coshort # yes ! 834: coloop: ! 835: probew $1,(r1),$NBPG # bytes accessible? ! 836: beql ersb # no ! 837: addl2 $NBPG,r1 # increment user address ! 838: _ACBL ($NBPG+1,$-NBPG,r0,coloop) # reduce count and loop ! 839: coshort: ! 840: probew $1,(r1),r0 # bytes accessible? ! 841: beql ersb # no ! 842: MOVC3 (12(fp),4(fp),8(fp)) ! 843: clrl r0 ! 844: ret ! 845: ! 846: /* ! 847: * non-local goto's ! 848: */ ! 849: .globl _setjmp # the _Setjmp subroutine in VAX ! 850: # became _setjmp procedure for TAHOE ! 851: _setjmp: ! 852: .word 0x0 ! 853: movl 4(fp),r2 ! 854: storer $0x1ff8,(r2) ! 855: addl2 $40,r2 ! 856: movl (fp),(r2) ! 857: addl2 $4,r2 ! 858: movab 8(fp),(r2) ! 859: addl2 $4,r2 ! 860: movl -8(fp),(r2) ! 861: clrl r0 ! 862: ret ! 863: ! 864: .globl _longjmp # the _Longjmp subroutine in VAX ! 865: # became _longjmp procedure for TAHOE ! 866: _longjmp: ! 867: .word 0x0000 ! 868: movl 4(fp),r2 ! 869: _Longjmp: # called from swtch ! 870: loadr $0x3ff8,(r2) ! 871: addl2 $44,r2 ! 872: movl (r2),r1 ! 873: addl2 $4,r2 ! 874: movab (sp),r0 ! 875: cmpl r1,r0 # must be a pop ! 876: bgequ lj2 ! 877: pushab lj1 ! 878: callf $8,_panic ! 879: lj2: ! 880: movl r1,sp ! 881: jmp *(r2) ! 882: ! 883: lj1: .asciz "longjmp" ! 884: ! 885: ! 886: .globl _whichqs ! 887: .globl _qs ! 888: .globl _cnt ! 889: ! 890: .globl _noproc ! 891: .comm _noproc,4 ! 892: .globl _runrun ! 893: .comm _runrun,4 ! 894: ! 895: /* ! 896: * The following primitives use the fancy TAHOE instructions. ! 897: * _whichqs tells which of the 32 queues _qs ! 898: * have processes in them. setrq puts processes into queues, remrq ! 899: * removes them from queues. The running process is on no queue, ! 900: * other processes are on a queue related to p->p_pri, divided by 4 ! 901: * actually to shrink the 0-127 range of priorities into the 32 available ! 902: * queues. ! 903: */ ! 904: ! 905: /* ! 906: * setrq(p), using fancy TAHOE instructions. ! 907: * ! 908: * Call should be made at spl8(), and p->p_stat should be SRUN ! 909: */ ! 910: .globl _setrq ! 911: _setrq: ! 912: .word 0x4 ! 913: movl 4(fp),r0 ! 914: tstl P_RLINK(r0) ## firewall: p->p_rlink must be 0 ! 915: beql set1 ## ! 916: pushab set3 ## ! 917: callf $8,_panic ## ! 918: set1: ! 919: movzbl P_PRI(r0),r1 # put on queue which is p->p_pri / 4 ! 920: shar $2,r1,r1 ! 921: shal $1,r1,r2 ! 922: moval _qs[r2],r2 ! 923: insque (r0),*4(r2) # at end of queue ! 924: shal r1,$1,r1 ! 925: orl2 r1,_whichqs # mark queue non-empty ! 926: ret ! 927: ! 928: set3: .asciz "setrq" ! 929: ! 930: /* ! 931: * remrq(p), using fancy TAHOE instructions ! 932: * ! 933: * Call should be made at spl8(). ! 934: */ ! 935: .globl _remrq ! 936: _remrq: ! 937: .word 0x0 ! 938: movl 4(fp),r0 ! 939: movzbl P_PRI(r0),r1 ! 940: shar $2,r1,r1 ! 941: bbs r1,_whichqs,rem1 ! 942: pushab rem3 # it wasn't recorded to be on its q ! 943: callf $8,_panic ! 944: rem1: ! 945: remque (r0) ! 946: bneq rem2 # q not empty yet ! 947: shal r1,$1,r1 ! 948: mcoml r1,r1 ! 949: andl2 r1,_whichqs # mark queue empty ! 950: rem2: ! 951: clrl P_RLINK(r0) ## for firewall checking ! 952: ret ! 953: ! 954: rem3: .asciz "remrq" ! 955: ! 956: .globl __insque ! 957: __insque: ! 958: .word 0 ! 959: insque *4(fp), *8(fp) ! 960: ret ! 961: ! 962: ! 963: .globl __remque ! 964: __remque: ! 965: .word 0 ! 966: remque *4(fp) ! 967: ret ! 968: ! 969: /* ! 970: * Masterpaddr is the p->p_addr of the running process on the master ! 971: * processor. When a multiprocessor system, the slave processors will have ! 972: * an array of slavepaddr's. ! 973: */ ! 974: .globl _masterpaddr ! 975: .data ! 976: _masterpaddr: ! 977: .long 0 ! 978: ! 979: .text ! 980: sw0: .asciz "swtch" ! 981: /* ! 982: * swtch(), using fancy TAHOE instructions ! 983: */ ! 984: .globl _swtch ! 985: _swtch: ! 986: .word 0x0 ! 987: movl (fp),fp # prepare for rei ! 988: movl (sp),4(sp) # saved pc ! 989: tstl (sp)+ ! 990: movpsl 4(sp) ! 991: movl $1,_noproc ! 992: clrl _runrun ! 993: mtpr0: mtpr $0,$IPL # must allow interrupts here ! 994: sw1: ffs _whichqs,r0 # look for non-empty queue ! 995: bgeq sw1a ! 996: brb sw1 # this is an idle loop! ! 997: sw1a: mtpr $0x18,$IPL # lock out all so _whichqs==_qs ! 998: bbc r0,_whichqs,mtpr0 # proc moved via lbolt interrupt ! 999: shal $1,r0,r1 ! 1000: moval _qs[r1],r1 ! 1001: movl (r1),r2 # r2 = p = highest pri process ! 1002: remque *(r1) ! 1003: bvc sw2 # make sure something was there ! 1004: sw1b: pushab sw0 ! 1005: callf $8,_panic ! 1006: sw2: bneq sw3 ! 1007: shal r0,$1,r1 ! 1008: mcoml r1,r1 ! 1009: andl2 r1,_whichqs # no more procs in this queue ! 1010: sw3: ! 1011: clrl _noproc ! 1012: tstl P_WCHAN(r2) ## firewalls ! 1013: bneq sw1b ## ! 1014: movzbl P_STAT(r2),r3 ## ! 1015: cmpl $SRUN,r3 ## ! 1016: bneq sw1b ## ! 1017: clrl P_RLINK(r2) ## ! 1018: movl *P_ADDR(r2),r0 ! 1019: movl r0,_masterpaddr ! 1020: shal $PGSHIFT,r0,r0 # r0 = pcbb(p) ! 1021: /* mfpr $PCBB,r1 # resume of current proc is easy ! 1022: * cmpl r0,r1 ! 1023: */ beql res0 ! 1024: incl _cnt+V_SWTCH ! 1025: brb swresume ! 1026: /* fall into... */ ! 1027: ! 1028: /* ! 1029: * global cache key used if cant use proc index as key ! 1030: * (e.g. NPROC>=255) ! 1031: * otherwise used for temporary storage of key ! 1032: */ ! 1033: .data ! 1034: _globkey: ! 1035: .long 0 ! 1036: .text ! 1037: /* ! 1038: * resume(pf) ! 1039: */ ! 1040: .globl _resume ! 1041: _resume: ! 1042: .word 0x0 ! 1043: shal $PGSHIFT,4(fp),r0 # r0 = pcbb(p) ! 1044: movl (fp),fp # prepare for rei ! 1045: movl (sp)+,4(sp) # saved pc ! 1046: tstl (sp)+ ! 1047: movpsl 4(sp) ! 1048: swresume: ! 1049: mtpr $0x18,$IPL # no interrupts, please ! 1050: movl _CMAP2,_u+PCB_CMAP2 # yech ! 1051: svpctx ! 1052: mtpr r0,$PCBB ! 1053: ldpctx ! 1054: movl _u+PCB_CMAP2,_CMAP2 # yech ! 1055: mtpr $_CADDR2,$TBIS ! 1056: res0: ! 1057: tstl _u+PCB_SSWAP ! 1058: beql res1 ! 1059: movl _u+PCB_SSWAP,r2 ! 1060: clrl _u+PCB_SSWAP ! 1061: movab _Longjmp,(sp) ! 1062: clrl 4(sp) # PSL = kernel mode, IPL=0 ! 1063: res1: ! 1064: #ifdef GLOBKEY ! 1065: aoblss $256,_globkey,res2 # define new cache key ! 1066: mtpr $0,$PACC # out of keys, purge all ! 1067: mtpr $0,$PADC ! 1068: movl $1,_globkey ! 1069: res2: ! 1070: mtpr _globkey,$CCK ! 1071: #else ! 1072: res3: ! 1073: movzwl _u+PCB_CKEY,_globkey ! 1074: mtpr _globkey,$CCK ! 1075: res4: ! 1076: movzwl _u+PCB_DKEY,_globkey ! 1077: #endif ! 1078: mtpr _globkey,$DCK ! 1079: rei ! 1080: ! 1081: /* ! 1082: * {fu,su},{byte,word} ! 1083: */ ! 1084: .globl _fuiword ! 1085: .globl _fuword ! 1086: _fuiword: ! 1087: _fuword: ! 1088: .word 0x0 ! 1089: prober $1,*4(fp),$4 ! 1090: beql fserr ! 1091: movl *4(fp),r0 ! 1092: ret ! 1093: fserr: ! 1094: mnegl $1,r0 ! 1095: ret ! 1096: ! 1097: .globl _fuibyte ! 1098: .globl _fubyte ! 1099: _fuibyte: ! 1100: _fubyte: ! 1101: .word 0x0 ! 1102: prober $1,*4(fp),$1 ! 1103: beql fserr ! 1104: movzbl *4(fp),r0 ! 1105: ret ! 1106: ! 1107: .globl _suiword ! 1108: .globl _suword ! 1109: _suiword: ! 1110: _suword: ! 1111: .word 0x0 ! 1112: probew $1,*4(fp),$4 ! 1113: beql fserr ! 1114: movl 8(fp),*4(fp) ! 1115: clrl r0 ! 1116: ret ! 1117: ! 1118: .globl _suibyte ! 1119: .globl _subyte ! 1120: _suibyte: ! 1121: _subyte: ! 1122: .word 0x0 ! 1123: probew $1,*4(fp),$1 ! 1124: beql fserr ! 1125: movb 11(fp),*4(fp) ! 1126: clrl r0 ! 1127: ret ! 1128: ! 1129: /* ! 1130: * Copy 1 relocation unit (NBPG bytes) ! 1131: * from user virtual address to physical address ! 1132: */ ! 1133: _copyseg: .globl _copyseg ! 1134: .word 0x0 ! 1135: orl3 $PG_V|PG_KW,8(fp),_CMAP2 ! 1136: mtpr $_CADDR2,$TBIS # invalidate entry for copy ! 1137: MOVC3 ($NBPG,4(fp),$_CADDR2) ! 1138: ret ! 1139: ! 1140: /* ! 1141: * clearseg(physical_page_number); ! 1142: * ! 1143: * zero out physical memory ! 1144: * specified in relocation units (NBPG bytes) ! 1145: * This routine was optimized for speed on Tahoe. ! 1146: */ ! 1147: _clearseg: .globl _clearseg ! 1148: .word 0 ! 1149: orl3 $PG_V|PG_KW,4(fp),_CMAP1 # Maps to virtual addr CADDR1 ! 1150: mtpr $_CADDR1,$TBIS ! 1151: movl $255,r0 # r0 = limit ! 1152: clrl r1 # r1 = index of cleared long ! 1153: 1: ! 1154: clrl _CADDR1[r1] ! 1155: aobleq r0,r1,1b ! 1156: ret ! 1157: ! 1158: /* ! 1159: * if ( useracc(address, count, mode) ) .... ! 1160: * Check address. ! 1161: * Given virtual address, byte count, and rw flag ! 1162: * returns 0 on no access. ! 1163: * Note : it is assumed that on all calls to this routine, ! 1164: * mode=0 means write access, mode=1 means read access. ! 1165: */ ! 1166: _useracc: .globl _useracc ! 1167: .word 0x4 ! 1168: movl $1,r2 # r2 = 'user mode' for probew/probew ! 1169: probes: ! 1170: movl 4(fp),r0 # get va ! 1171: movl 8(fp),r1 # count ! 1172: tstl 12(fp) # test for read access ? ! 1173: bneq userar # yes ! 1174: cmpl $NBPG,r1 # can we do it in one probe ? ! 1175: bgeq uaw2 # yes ! 1176: uaw1: ! 1177: probew r2,(r0),$NBPG ! 1178: beql uaerr # no access ! 1179: addl2 $NBPG,r0 ! 1180: _ACBL($NBPG+1,$-NBPG,r1,uaw1) ! 1181: uaw2: ! 1182: probew r2,(r0),r1 ! 1183: beql uaerr ! 1184: movl $1,r0 ! 1185: ret ! 1186: ! 1187: userar: ! 1188: cmpl $NBPG,r1 ! 1189: bgeq uar2 ! 1190: uar1: ! 1191: prober r2,(r0),$NBPG ! 1192: beql uaerr ! 1193: addl2 $NBPG,r0 ! 1194: _ACBL($NBPG+1,$-NBPG,r1,uar1) ! 1195: uar2: ! 1196: prober r2,(r0),r1 ! 1197: beql uaerr ! 1198: movl $1,r0 ! 1199: ret ! 1200: uaerr: ! 1201: clrl r0 ! 1202: ret ! 1203: ! 1204: /* ! 1205: * if ( kernacc(address, count, mode) ) .... ! 1206: * Check address. ! 1207: * Given virtual address, byte count, and rw flag ! 1208: * returns 0 on no access. ! 1209: * Same as useracc routine but checks for kernel access rights. ! 1210: */ ! 1211: ! 1212: _kernacc: .globl _kernacc ! 1213: .word 0x4 ! 1214: clrl r2 # r2 = 0 means kernel mode probe. ! 1215: jbr probes # Dijkstra would get gastric distress here. ! 1216: ! 1217: /* ! 1218: * addupc - increment some histogram counter ! 1219: * in the profiling buffer ! 1220: * ! 1221: * addupc(pc, prof, counts) ! 1222: * long pc , counts; Only least significant word of 'counts' is added. ! 1223: * struct uprof *prof; ! 1224: * ! 1225: * struct uprof { # profile arguments ! 1226: * short *r_base; # buffer base ! 1227: * unsigned pr_size; # buffer size ! 1228: * unsigned pr_off; # pc offset ! 1229: * unsigned pr_scale; # pc scaling ! 1230: * } ! 1231: */ ! 1232: .globl _addupc ! 1233: _addupc: ! 1234: .word 4 ! 1235: movl 8(fp),r2 # r2 points to structure ! 1236: subl3 8(r2),4(fp),r0 # r0 = PC - lowpc ! 1237: jlss 9f # PC < lowpc , out of range ! ! 1238: shrl $1,r0,r0 # the unit is words ! 1239: shrl $1,12(r2),r1 # ditto for scale ! 1240: emul r1,r0,$0,r0 ! 1241: shrq $14,r0,r0 ! 1242: tstl r0 # too big ! 1243: jneq 9f ! 1244: cmpl r1,4(r2) # Check buffer overflow ! 1245: jgequ 9f ! 1246: probew $1,*0(r2)[r1],$2 # counter accessible? ! 1247: jeql 9f ! 1248: shrl $1,r1,r1 # make r1 word index ! 1249: addw2 14(fp),*0(r2)[r1] ! 1250: 9: ret ! 1251: SCBVEC(udintr0): ! 1252: SCBVEC(xpintr0): ! 1253: jbr _Xstray
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.