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