|
|
1.1 ! root 1: #ifdef LOCORE ! 2: #define U_PROCP 144 ! 3: #define U_EOSYS 273 ! 4: #define P_LINK 0 ! 5: #define P_RLINK 4 ! 6: #define P_XLINK 108 ! 7: #define P_ADDR 16 ! 8: #define P_PRI 21 ! 9: #define P_STAT 23 ! 10: #define P_WCHAN 96 ! 11: #define P_TSIZE 68 ! 12: #define P_SSIZE 76 ! 13: #define P_P0BR 104 ! 14: #define P_SZPT 66 ! 15: #define P_TEXTP 100 ! 16: #define P_FLAG 44 ! 17: #define P_DKEY 164 ! 18: #define P_CKEY 160 ! 19: #define SSLEEP 1 ! 20: #define SRUN 3 ! 21: #define V_SWTCH 0 ! 22: #define V_TRAP 4 ! 23: #define V_SYSCALL 8 ! 24: #define V_INTR 12 ! 25: #define V_SOFT 16 ! 26: #define V_FPE 116 ! 27: #define V_ALIGN 120 ! 28: #define MCLBYTES 1024 ! 29: #define NBPG 1024 ! 30: #define PGSHIFT 10 ! 31: #define UPAGES 6 ! 32: #define CLSIZE 1 ! 33: #define MAXPHYS 65536 ! 34: #define SYSPTSIZE 9216 ! 35: #define USRPTSIZE 1024 ! 36: #define VBIOSIZE 1020 ! 37: #define MSGBUFPTECNT 4 ! 38: #define NMBCLUSTERS 256 ! 39: #define PCB_KSP 0 ! 40: #define PCB_USP 4 ! 41: #define PCB_R0 8 ! 42: #define PCB_R1 12 ! 43: #define PCB_R2 16 ! 44: #define PCB_R3 20 ! 45: #define PCB_R4 24 ! 46: #define PCB_R5 28 ! 47: #define PCB_R6 32 ! 48: #define PCB_R7 36 ! 49: #define PCB_R8 40 ! 50: #define PCB_R9 44 ! 51: #define PCB_R10 48 ! 52: #define PCB_R11 52 ! 53: #define PCB_R12 56 ! 54: #define PCB_R13 60 ! 55: #define PCB_FP 60 ! 56: #define PCB_PC 64 ! 57: #define PCB_PSL 68 ! 58: #define PCB_P0BR 72 ! 59: #define PCB_P0LR 76 ! 60: #define PCB_P1BR 80 ! 61: #define PCB_P1LR 84 ! 62: #define PCB_P2BR 88 ! 63: #define PCB_P2LR 92 ! 64: #define PCB_ACH 96 ! 65: #define PCB_ACL 100 ! 66: #define PCB_HFS 104 ! 67: #define PCB_SAVACC 108 ! 68: #define PCB_SZPT 112 ! 69: #define PCB_CMAP2 116 ! 70: #define PCB_SSWAP 120 ! 71: #define PCB_SIGC 124 ! 72: #define SCB_DOADUMP 8 ! 73: #define SCB_BUSERR 128 ! 74: #define SCB_DEVBASE 64 ! 75: #endif ! 76: /* ! 77: * @(#)scb.s 7.1 (Berkeley) 5/21/88 ! 78: */ ! 79: ! 80: /* ! 81: * System control block ! 82: */ ! 83: #define STRAY .long _Xstray ! 84: #define STRAY8 STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY ! 85: #define KS(a) .long _X/**/a ! 86: #define IS(a) .long _X/**/a ! 87: ! 88: _scb: .globl _scb ! 89: /* 000 */ STRAY; IS(powfail); IS(doadump); STRAY; ! 90: /* 004 */ STRAY; STRAY; STRAY; IS(hardclock); ! 91: /* 008 */ STRAY; STRAY; IS(cnrint); IS(cnxint); ! 92: /* 00c */ IS(rmtrint); IS(rmtxint); STRAY; STRAY; ! 93: /* 010 */ IS(kdbintr); STRAY; STRAY; IS(netintr); ! 94: /* 014 */ STRAY; STRAY; STRAY; IS(softclock); ! 95: /* 018 */ STRAY; STRAY; STRAY; STRAY; ! 96: /* 01c */ STRAY; STRAY; STRAY; STRAY; ! 97: /* 020 */ IS(buserr); STRAY; STRAY; STRAY; ! 98: /* 024 */ STRAY; STRAY; STRAY; STRAY; ! 99: /* 028 */ STRAY; STRAY; STRAY; KS(syscall); ! 100: /* 02c */ KS(privinflt); KS(resopflt); KS(resadflt); KS(protflt); ! 101: /* 030 */ KS(transflt); IS(kspnotval); KS(tracep); KS(bptflt); ! 102: /* 034 */ KS(arithtrap); KS(alignflt); KS(sfexcep); KS(fpm); ! 103: /* 038 */ STRAY; STRAY; STRAY; STRAY; ! 104: /* 03c */ STRAY; STRAY; STRAY; STRAY; ! 105: /* device interrupt vectors */ ! 106: /* 040 */ STRAY8; STRAY8; STRAY8; STRAY8; ! 107: /* 060 */ STRAY8; STRAY8; STRAY8; STRAY8; ! 108: /* 080 */ STRAY8; STRAY8; STRAY8; STRAY8; ! 109: /* 0a0 */ STRAY8; STRAY8; STRAY8; STRAY8; ! 110: /* 0c0 */ STRAY8; STRAY8; STRAY8; STRAY8; ! 111: /* 0e0 */ STRAY8; STRAY8; STRAY8; STRAY8; ! 112: #define I_CLOCK 0 ! 113: #define I_CNR 4 ! 114: #define I_CNX 8 ! 115: #define I_RMTR 12 ! 116: #define I_RMTX 16 ! 117: #define I_BUSERR 20 ! 118: /* ! 119: * Copyright (c) 1988 Regents of the University of California. ! 120: * All rights reserved. The Berkeley software License Agreement ! 121: * specifies the terms and conditions for redistribution. ! 122: * ! 123: * @(#)locore.s 7.6 (Berkeley) 5/1/89 ! 124: * 9/8/89 (bostic) -- added delay in wbadaddr from 7.10 ! 125: * This had already been patched, but I have no idea by whom; the ! 126: * following lines had been added: ! 127: * ! 128: * #if NVX > 0 ! 129: * ADDMAP( NVX * 16384/NBPG ) ! 130: * #endif ! 131: */ ! 132: ! 133: #include "../tahoe/mtpr.h" ! 134: #include "../tahoe/trap.h" ! 135: #include "../tahoe/psl.h" ! 136: #include "../tahoe/pte.h" ! 137: #include "../tahoe/cp.h" ! 138: #include "../tahoe/mem.h" ! 139: #include "../tahoe/SYS.h" ! 140: ! 141: #include "../tahoemath/fp.h" ! 142: ! 143: #include "errno.h" ! 144: #include "syscall.h" ! 145: #include "cmap.h" ! 146: ! 147: .set HIGH,0x1f # mask for total disable ! 148: .set NISP,3 # number of interrupt stack pages ! 149: .set SYSTEM,0xC0000000 # virtual address of system start ! 150: .set PPAGES,0x100000 # possible pages in P0,P1, etc. ! 151: ! 152: /* ACBL for non-negative '_add' */ ! 153: #define ACBL(_limit,_add,_index,_displ) \ ! 154: addl2 _add,_index; \ ! 155: cmpl _index,_limit; \ ! 156: bleq _displ ! 157: ! 158: /* _ACBL for negative '_add' */ ! 159: #define _ACBL(_limit,_add,_index,_displ) \ ! 160: addl2 _add,_index; \ ! 161: cmpl _index,_limit; \ ! 162: bgeq _displ ! 163: ! 164: #define MOVC3(_srcaddr,_dstaddr,_len) \ ! 165: movl _srcaddr,r0; \ ! 166: movl _dstaddr,r1; \ ! 167: movl _len,r2; \ ! 168: movblk ! 169: ! 170: /* keep address of psl if coming from user mode */ ! 171: #define CHECK_SFE(_delta) \ ! 172: bitl $PSL_CURMOD,_delta(sp); \ ! 173: jeql 1f; \ ! 174: moval _delta(sp),_user_psl; \ ! 175: 1: ! 176: ! 177: /* ! 178: * User structure is UPAGES at top of user space. ! 179: */ ! 180: .globl _u ! 181: .set _u,SYSTEM - UPAGES*NBPG ! 182: ! 183: /* ! 184: * Restart stack. Used on power recovery or panic. ! 185: * Takes a core-dump and then halts. ! 186: */ ! 187: .globl _rsstk ! 188: .globl pwfl_stk ! 189: _rsstk: ! 190: .space 1024-8 ! 191: pwfl_stk: ! 192: .space 4 ! 193: dumpflag: ! 194: .space 4 ! 195: ! 196: .globl _intstack ! 197: _intstack: ! 198: .space NISP*NBPG ! 199: eintstack: ! 200: ! 201: /* ! 202: * Power failure storage block and ! 203: * macros for saving and restoring. ! 204: */ ! 205: #define POWERFAIL(id,longs) \ ! 206: .globl pwfl_/**/id \ ! 207: pwfl_/**/id: .space longs*4 ! 208: .data ! 209: POWERFAIL(r0, 14) # r0-r13 ! 210: POWERFAIL(sp, 1) # r14 ! 211: POWERFAIL(SCBB, 1) # system control block base ! 212: POWERFAIL(SBR, 1) # system pte base ! 213: POWERFAIL(SLR, 1) # system pte length ! 214: POWERFAIL(P0BR, 1) # p0 pte base ! 215: POWERFAIL(P0LR, 1) # p0 pte length ! 216: POWERFAIL(P1BR, 1) # p1 pte base ! 217: POWERFAIL(P1LR, 1) # p1 pte length ! 218: POWERFAIL(P2BR, 1) # p2 pte base ! 219: POWERFAIL(P2LR, 1) # p2 pte length ! 220: POWERFAIL(IPL, 1) # interrupt priority level ! 221: POWERFAIL(DCK, 1) # data cache key ! 222: POWERFAIL(CCK, 1) # code cache key ! 223: POWERFAIL(PCBB, 1) # process control block base ! 224: POWERFAIL(ISP, 1) # interrupt stack pointer ! 225: POWERFAIL(KSP, 1) # kernel mode stack pointer ! 226: POWERFAIL(USP, 1) # user mode stack pointer ! 227: POWERFAIL(MME, 1) # memory management enable ! 228: POWERFAIL(PSL, 1) # processor status longword ! 229: ! 230: /* ! 231: * Save current state in power fail storage block. ! 232: */ ! 233: #define SAVEpwfl() \ ! 234: movpsl pwfl_PSL # Keeps all flags, etc. \ ! 235: storer $0x3fff,pwfl_r0 # Saves r0-r13 \ ! 236: moval 0(sp),pwfl_sp # Saves sp (=r14) \ ! 237: mfpr $SBR,pwfl_SBR # Save all re_loadable registers \ ! 238: mfpr $SLR,pwfl_SLR \ ! 239: mfpr $P0BR,pwfl_P0BR \ ! 240: mfpr $P0LR,pwfl_P0LR \ ! 241: mfpr $P1BR,pwfl_P1BR \ ! 242: mfpr $P1LR,pwfl_P1LR \ ! 243: mfpr $P2BR,pwfl_P2BR \ ! 244: mfpr $P2LR,pwfl_P2LR \ ! 245: mfpr $IPL,pwfl_IPL \ ! 246: mfpr $MME,pwfl_MME \ ! 247: mfpr $DCK,pwfl_DCK \ ! 248: mfpr $CCK,pwfl_CCK \ ! 249: mfpr $PCBB,pwfl_PCBB \ ! 250: mfpr $ISP,pwfl_ISP \ ! 251: mfpr $SCBB,pwfl_SCBB \ ! 252: mfpr $KSP,pwfl_KSP \ ! 253: mfpr $USP,pwfl_USP ! 254: ! 255: /* ! 256: * Restore state saved in power fail block and ! 257: * jmp to location specified after (possibly) ! 258: * enabling memory management. ! 259: */ ! 260: #define RESTOREpwfl(loc) \ ! 261: loadr $0x3fff,pwfl_r0 # Restore r0-r13 \ ! 262: movl pwfl_sp,sp # Restore sp (=r14) \ ! 263: mtpr pwfl_SCBB,$SCBB \ ! 264: mtpr pwfl_SBR,$SBR # Restore all re_loadable registers \ ! 265: mtpr pwfl_SLR,$SLR \ ! 266: mtpr pwfl_P0BR,$P0BR \ ! 267: mtpr pwfl_P0LR,$P0LR \ ! 268: mtpr pwfl_P1BR,$P1BR \ ! 269: mtpr pwfl_P1LR,$P1LR \ ! 270: mtpr pwfl_P2BR,$P2BR \ ! 271: mtpr pwfl_P2LR,$P2LR \ ! 272: mtpr pwfl_IPL,$IPL \ ! 273: mtpr pwfl_DCK,$DCK \ ! 274: mtpr pwfl_CCK,$CCK \ ! 275: mtpr pwfl_PCBB,$PCBB \ ! 276: mtpr pwfl_ISP,$ISP \ ! 277: mtpr pwfl_KSP,$KSP \ ! 278: mtpr pwfl_USP,$USP \ ! 279: \ ! 280: bicpsw $0xff # Restore PSW. \ ! 281: bispsw pwfl_PSL+2 # Set original bits back (just in case..) \ ! 282: # now go to mapped mode \ ! 283: # Have to change PC to system addresses \ ! 284: mtpr $1,$PACC # Thoroughly clean up caches. \ ! 285: mtpr $1,$PADC \ ! 286: mtpr $1,$TBIA \ ! 287: mtpr pwfl_MME,$MME # Restore MME. Last thing to be done. \ ! 288: jmp loc ! 289: ! 290: /* ! 291: * Do a dump. ! 292: * Called by auto-restart. ! 293: * May be called manually. ! 294: */ ! 295: .align 2 ! 296: .text ! 297: .globl _Xdoadump ! 298: .globl _doadump ! 299: _Xdoadump: # CP comes here after power fail ! 300: RESTOREpwfl(*0f) # restore state ! 301: _doadump: ! 302: .word 0 ! 303: 0: mtpr $HIGH,$IPL ! 304: #define _rsstkmap _Sysmap+12 # powerfail storage, scb, rsstk, int stack ! 305: tstl dumpflag # dump only once! ! 306: bneq 1f ! 307: andl2 $~PG_PROT,_rsstkmap ! 308: orl2 $PG_KW,_rsstkmap # Make dump stack r/w ! 309: mtpr $0,$TBIA ! 310: movl $1,dumpflag ! 311: movab dumpflag,sp ! 312: callf $4,_dumpsys ! 313: 1: ! 314: halt ! 315: ! 316: /* ! 317: * Interrupt vector routines ! 318: */ ! 319: .globl _waittime ! 320: #define SCBVEC(name) \ ! 321: .align 2; \ ! 322: .globl _X/**/name; \ ! 323: _X/**/name ! 324: #define PANIC(msg) \ ! 325: clrl _waittime; pushab 1f; callf $8,_panic; 1: .asciz msg ! 326: #define PRINTF(n,msg) \ ! 327: pushab 1f; callf $(n+2)*4,_printf; MSG(msg) ! 328: #define MSG(msg) .data; 1: .asciz msg; .text ! 329: /* ! 330: * r0-r5 are saved across all faults and interrupts. ! 331: * Routines below and those hidden in vbglue.s (device ! 332: * interrupts) invoke the PUSHR/POPR macros to execute ! 333: * this. Also, certain stack frame offset calculations ! 334: * use this, using the REGSPC definition (and FPSPC defined below). ! 335: */ ! 336: #define REGSPC 6*4 ! 337: #define PUSHR movab -REGSPC(sp),sp; storer $0x3f,(sp) ! 338: #define POPR loadr $0x3f,(sp); movab REGSPC(sp),sp ! 339: ! 340: /* ! 341: * Floating point state is saved across faults and ! 342: * interrupts. The state occupies 4 longwords on ! 343: * the stack: ! 344: * precision indicator (single = 0/double = 1) ! 345: * double representation of accumulator ! 346: * save accumulator status flag (pcb_savacc) ! 347: */ ! 348: #define FPSPC (4*4) ! 349: ! 350: #define SAVE_FPSTAT(_delta) \ ! 351: bitl $PSL_DBL,_delta(sp); \ ! 352: beql 1f; \ ! 353: pushl $1; \ ! 354: pushd; \ ! 355: jmp 2f; \ ! 356: 1: pushl $0; \ ! 357: pushl $0; \ ! 358: stf -(sp); \ ! 359: 2: tstl _u+PCB_SAVACC; \ ! 360: bneq 3f; \ ! 361: moval 0(sp),_u+PCB_SAVACC; \ ! 362: orl2 $2,8(sp);\ ! 363: 3: pushl $0; ! 364: ! 365: #define REST_FPSTAT \ ! 366: tstl (sp)+; \ ! 367: bitl $2,8(sp);\ ! 368: beql 1f;\ ! 369: movl $0,_u+PCB_SAVACC; \ ! 370: 1: bitl $1,8(sp); \ ! 371: beql 2f; \ ! 372: ldd (sp); \ ! 373: jmp 3f; \ ! 374: 2: ldf (sp); \ ! 375: 3: moval 12(sp),sp; ! 376: ! 377: #define REST_ACC \ ! 378: tstl _u+PCB_SAVACC; \ ! 379: beql 2f; \ ! 380: movl _u+PCB_SAVACC,r1; \ ! 381: andl3 $(EXPMASK|SIGNBIT),(r1),-(sp); \ ! 382: cmpl $0x80000000,(sp)+; \ ! 383: bneq 3f; \ ! 384: clrl (r1); \ ! 385: 3: bitl $1,8(r1); \ ! 386: beql 1f; \ ! 387: ldd (r1); \ ! 388: jmp 2f; \ ! 389: 1: ldf (r1); \ ! 390: 2: ; ! 391: ! 392: .data ! 393: nofault: .space 4 # bus error non-local goto label ! 394: ! 395: .text ! 396: SCBVEC(buserr): ! 397: CHECK_SFE(12) ! 398: SAVE_FPSTAT(12) ! 399: incl _intrcnt+I_BUSERR # keep stats... ! 400: pushl r0 # must save ! 401: andl3 24(sp),$ERRCD,r0 # grab pushed MER value ! 402: cmpl r0,$APE # address parity error? ! 403: jneq 1f ! 404: halt ! 405: 1: cmpl r0,$VBE # versabus error? ! 406: jneq 2f ! 407: halt ! 408: 2: ! 409: movl (sp)+,r0 # restore r0 and... ! 410: bitl $PSL_CURMOD,4*4+3*4(sp) # check if happened in user mode? ! 411: jeql 3f # yes, then shift stack up for trap... ! 412: movl 12(sp),16(sp) # sorry, no space for which-buss... ! 413: movl 8(sp),12(sp) ! 414: movl 4(sp),8(sp) ! 415: movl 0(sp),4(sp) ! 416: movl $T_BUSERR,0(sp) # push trap type code and... ! 417: jbr alltraps # ...merge with all other traps ! 418: 3: # kernel mode, check to see if... ! 419: tstl nofault # ...doing peek/poke? ! 420: jeql 4f # nofault set? if so, jump to it... ! 421: movl nofault,4*4+2*4(sp) # ...setup for non-local goto ! 422: clrl nofault ! 423: jbr 5f ! 424: 4: ! 425: PUSHR ! 426: pushab 4*4+REGSPC(sp) # address of bus error parameters ! 427: callf $8,_buserror ! 428: POPR ! 429: 5: ! 430: REST_FPSTAT ! 431: movab 8(sp),sp # remove bus error parameters ! 432: rei ! 433: ! 434: SCBVEC(powfail): # We should be on interrupt stack now. ! 435: SAVEpwfl() # save machine state ! 436: moval _Xdoadump-SYSTEM,_scb+SCB_DOADUMP ! 437: halt ! 438: ! 439: SCBVEC(stray): ! 440: incl _cnt+V_INTR # add to statistics ! 441: rei ! 442: ! 443: #include "../net/netisr.h" ! 444: .globl _netisr ! 445: SCBVEC(netintr): ! 446: CHECK_SFE(4) ! 447: SAVE_FPSTAT(4); PUSHR ! 448: #include "imp.h" ! 449: #if NIMP > 0 ! 450: bbc $NETISR_IMP,_netisr,1f; ! 451: andl2 $~(1<<NETISR_IMP),_netisr ! 452: callf $4,_impintr; ! 453: 1: ! 454: #endif ! 455: #ifdef INET ! 456: bbc $NETISR_IP,_netisr,1f ! 457: andl2 $~(1<<NETISR_IP),_netisr ! 458: callf $4,_ipintr ! 459: 1: ! 460: #endif ! 461: #ifdef NS ! 462: bbc $NETISR_NS,_netisr,1f ! 463: andl2 $~(1<<NETISR_NS),_netisr ! 464: callf $4,_nsintr ! 465: 1: ! 466: #endif ! 467: bbc $NETISR_RAW,_netisr,1f ! 468: andl2 $~(1<<NETISR_RAW),_netisr ! 469: callf $4,_rawintr ! 470: 1: ! 471: incl _cnt+V_SOFT ! 472: POPR; REST_FPSTAT ! 473: rei ! 474: ! 475: SCBVEC(cnrint): ! 476: CHECK_SFE(4) ! 477: SAVE_FPSTAT(4); PUSHR; ! 478: pushl $CPCONS; callf $8,_cnrint; ! 479: incl _intrcnt+I_CNR ! 480: incl _cnt+V_INTR ! 481: POPR; REST_FPSTAT; ! 482: rei ! 483: SCBVEC(cnxint): ! 484: CHECK_SFE(4) ! 485: SAVE_FPSTAT(4); PUSHR; ! 486: pushl $CPCONS; callf $8,_cnxint; ! 487: incl _intrcnt+I_CNX ! 488: incl _cnt+V_INTR ! 489: POPR; REST_FPSTAT; ! 490: rei ! 491: SCBVEC(rmtrint): ! 492: CHECK_SFE(4) ! 493: SAVE_FPSTAT(4); PUSHR; ! 494: pushl $CPREMOT; callf $8,_cnrint; ! 495: incl _intrcnt+I_RMTR ! 496: incl _cnt+V_INTR ! 497: POPR; REST_FPSTAT; ! 498: rei ! 499: SCBVEC(rmtxint): ! 500: CHECK_SFE(4) ! 501: SAVE_FPSTAT(4); PUSHR; ! 502: pushl $CPREMOT; callf $8,_cnxint; ! 503: incl _intrcnt+I_RMTX ! 504: incl _cnt+V_INTR ! 505: POPR; REST_FPSTAT; ! 506: rei ! 507: ! 508: #define PUSHPCPSL pushl 4+FPSPC+REGSPC(sp); pushl 4+FPSPC+REGSPC(sp); ! 509: ! 510: SCBVEC(hardclock): ! 511: tstl _clk_enable ! 512: bneq 1f ! 513: rei ! 514: 1: ! 515: CHECK_SFE(4) ! 516: SAVE_FPSTAT(4); PUSHR ! 517: PUSHPCPSL # push pc and psl ! 518: callf $12,_hardclock # hardclock(pc,psl) ! 519: incl _intrcnt+I_CLOCK ! 520: incl _cnt+V_INTR ## temp so not to break vmstat -= HZ ! 521: POPR; REST_FPSTAT ! 522: rei ! 523: SCBVEC(softclock): ! 524: CHECK_SFE(4) ! 525: SAVE_FPSTAT(4); PUSHR; ! 526: PUSHPCPSL # push pc and psl ! 527: callf $12,_softclock # softclock(pc,psl) ! 528: incl _cnt+V_SOFT ! 529: POPR; REST_FPSTAT ! 530: rei ! 531: ! 532: /* ! 533: * Stray VERSAbus interrupt catch routines ! 534: */ ! 535: .data ! 536: #define PJ .align 2; callf $4,_Xvstray ! 537: .globl _catcher ! 538: _catcher: ! 539: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 540: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 541: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 542: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 543: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 544: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 545: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 546: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 547: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 548: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 549: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 550: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ ! 551: ! 552: .align 2 ! 553: .globl _cold ! 554: _cold: .long 0x3 ! 555: ! 556: .text ! 557: SCBVEC(vstray): ! 558: .word 0 ! 559: bbc $0,_cold,2f # system running? ! 560: bbc $1,_cold,1f # doing autoconfig? ! 561: jbr 3f # random interrupt, ignore ! 562: 1: ! 563: mfpr $IPL,r12 # ...setup br and cvec ! 564: subl3 $_catcher+7,-8(fp),r11; shar $3,r11,r11 ! 565: addl2 $SCB_DEVBASE,r11 ! 566: jbr 3f ! 567: 2: ! 568: PUSHR ! 569: subl3 $_catcher+7,-8(fp),r0; shar $3,r0,r0 ! 570: addl3 $SCB_DEVBASE,r0,-(sp); ! 571: mfpr $IPL,-(sp) ! 572: PRINTF(2, "stray intr ipl %x vec %x\n") ! 573: POPR ! 574: 3: moval 0f,-8(fp); ret # pop callf frame... ! 575: 0: rei # ...and return ! 576: ! 577: /* ! 578: * Trap and fault vector routines ! 579: */ ! 580: #define TRAP(a) pushl $T_/**/a; jbr alltraps ! 581: ! 582: /* ! 583: * Ast delivery (profiling and/or reschedule) ! 584: */ ! 585: ! 586: SCBVEC(kspnotval): ! 587: CHECK_SFE(4) ! 588: pushl $0; ! 589: SAVE_FPSTAT(8) ! 590: TRAP(KSPNOTVAL) ! 591: SCBVEC(privinflt): ! 592: CHECK_SFE(4) ! 593: pushl $0; ! 594: SAVE_FPSTAT(8) ! 595: TRAP(PRIVINFLT) ! 596: SCBVEC(resopflt): ! 597: CHECK_SFE(4) ! 598: pushl $0; ! 599: SAVE_FPSTAT(8) ! 600: TRAP(RESOPFLT) ! 601: SCBVEC(resadflt): ! 602: CHECK_SFE(4) ! 603: pushl $0; ! 604: SAVE_FPSTAT(8) ! 605: TRAP(RESADFLT) ! 606: SCBVEC(bptflt): ! 607: CHECK_SFE(4) ! 608: pushl $0; ! 609: SAVE_FPSTAT(8) ! 610: TRAP(BPTFLT) ! 611: SCBVEC(kdbintr): ! 612: CHECK_SFE(4); ! 613: pushl $0; ! 614: SAVE_FPSTAT(8); ! 615: TRAP(KDBTRAP); ! 616: SCBVEC(tracep): ! 617: CHECK_SFE(4) ! 618: pushl $0; ! 619: SAVE_FPSTAT(8) ! 620: TRAP(TRCTRAP) ! 621: SCBVEC(alignflt): ! 622: #ifdef ALIGN ! 623: bitl $PSL_CURMOD,4(sp) ! 624: jeql align_excp # Can't emulate for kernel mode ! ! 625: jbr non_aligned # Only emulated for user mode. ! 626: align_excp: ! 627: #else ! 628: CHECK_SFE(4) ! 629: #endif ! 630: pushl $0; ! 631: SAVE_FPSTAT(8) ! 632: TRAP(ALIGNFLT) ! 633: SCBVEC(arithtrap): ! 634: CHECK_SFE(8) ! 635: SAVE_FPSTAT(8) ! 636: TRAP(ARITHTRAP) ! 637: ! 638: SCBVEC(protflt): ! 639: CHECK_SFE(12) ! 640: bitl $1,(sp)+ ! 641: jneq segflt ! 642: SAVE_FPSTAT(8) ! 643: TRAP(PROTFLT) ! 644: segflt: ! 645: SAVE_FPSTAT(8) ! 646: TRAP(SEGFLT) ! 647: ! 648: SCBVEC(fpm): # Floating Point Emulation ! 649: #ifdef FPE ! 650: CHECK_SFE(16) ! 651: SAVE_FPSTAT(16) ! 652: incl _cnt+V_FPE # count emulation traps ! 653: callf $4,_fpemulate ! 654: REST_FPSTAT ! 655: #endif ! 656: moval 8(sp),sp # Pop operand ! 657: tstl (sp) # Stack= PSL, PC, return_code ! 658: jneq _Xarithtrap # If not OK, emulate F.P. exception ! 659: movab 4(sp),sp # Else remove return_code and ! 660: rei ! 661: ! 662: SCBVEC(sfexcep): ! 663: CHECK_SFE(4) ! 664: pushl $0 ! 665: SAVE_FPSTAT(8) ! 666: TRAP(ASTFLT) ! 667: ! 668: SCBVEC(transflt): ! 669: CHECK_SFE(12) ! 670: bitl $2,(sp)+ ! 671: bneq tableflt ! 672: pageflt: ! 673: SAVE_FPSTAT(8) ! 674: TRAP(PAGEFLT) ! 675: tableflt: ! 676: SAVE_FPSTAT(8) ! 677: TRAP(TABLEFLT) ! 678: ! 679: #define REST_STACK movab 4(sp), sp; REST_FPSTAT; movab 4(sp), sp ! 680: ! 681: alltraps: ! 682: mfpr $USP,-(sp); ! 683: callf $4,_trap; ! 684: mtpr (sp)+,$USP ! 685: incl _cnt+V_TRAP ! 686: REST_STACK # pop type, code, and fp stuff ! 687: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT) ! 688: rei ! 689: ! 690: SCBVEC(syscall): ! 691: CHECK_SFE(8) ! 692: SAVE_FPSTAT(8) ! 693: pushl $T_SYSCALL ! 694: mfpr $USP,-(sp); ! 695: callf $4,_syscall; ! 696: mtpr (sp)+,$USP ! 697: incl _cnt+V_SYSCALL ! 698: REST_STACK # pop type, code, and fp stuff ! 699: mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT) ! 700: rei ! 701: ! 702: /* ! 703: * System page table. ! 704: * ! 705: * Mbmap and Usrptmap are enlarged by CLSIZE entries ! 706: * as they are managed by resource maps starting with index 1 or CLSIZE. ! 707: */ ! 708: #define vaddr(x) ((((x)-_Sysmap)/4)*NBPG+SYSTEM) ! 709: #define SYSMAP(mname, vname, npte) \ ! 710: _/**/mname: .globl _/**/mname; \ ! 711: .space (npte)*4; \ ! 712: .globl _/**/vname; \ ! 713: .set _/**/vname,vaddr(_/**/mname) ! 714: #define ADDMAP(npte) .space (npte)*4 ! 715: ! 716: .data ! 717: .align 2 ! 718: SYSMAP(Sysmap ,Sysbase ,SYSPTSIZE ) ! 719: SYSMAP(Forkmap ,forkutl ,UPAGES ) ! 720: SYSMAP(Xswapmap ,xswaputl ,UPAGES ) ! 721: SYSMAP(Xswap2map,xswap2utl ,UPAGES ) ! 722: SYSMAP(Swapmap ,swaputl ,UPAGES ) ! 723: SYSMAP(Pushmap ,pushutl ,UPAGES ) ! 724: SYSMAP(Vfmap ,vfutl ,UPAGES ) ! 725: SYSMAP(CMAP1 ,CADDR1 ,1 ) ! 726: SYSMAP(CMAP2 ,CADDR2 ,1 ) ! 727: SYSMAP(mmap ,vmmap ,1 ) ! 728: SYSMAP(alignmap ,alignutl ,1 ) /* XXX */ ! 729: SYSMAP(msgbufmap,msgbuf ,MSGBUFPTECNT ) ! 730: SYSMAP(Mbmap ,mbutl ,NMBCLUSTERS*MCLBYTES/NBPG+CLSIZE ) ! 731: SYSMAP(kmempt ,kmembase ,300*CLSIZE ) ! 732: #ifdef GPROF ! 733: SYSMAP(profmap ,profbase ,600*CLSIZE ) ! 734: #endif ! 735: /* ! 736: * Enlarge kmempt as needed for bounce buffers allocated ! 737: * by tahoe controllers. ! 738: */ ! 739: #include "hd.h" ! 740: #if NHD > 0 ! 741: ADDMAP( NHDC*(MAXPHYS/NBPG+CLSIZE) ) ! 742: #endif ! 743: #include "dk.h" ! 744: #if NDK > 0 ! 745: ADDMAP( NVD*(MAXPHYS/NBPG+CLSIZE) ) ! 746: #endif ! 747: #include "yc.h" ! 748: #if NYC > 0 ! 749: ADDMAP( NCY*(MAXPHYS/NBPG+CLSIZE) ) ! 750: #endif ! 751: #include "mp.h" ! 752: ADDMAP( NMP*14 ) ! 753: SYSMAP(ekmempt ,kmemlimit ,0 ) ! 754: ! 755: SYSMAP(VMEMbeg ,vmembeg ,0 ) ! 756: SYSMAP(VMEMmap ,vmem ,VBIOSIZE ) ! 757: SYSMAP(VMEMmap1 ,vmem1 ,0 ) ! 758: #include "ace.h" ! 759: #if NACE > 0 ! 760: ADDMAP( NACE*32 ) ! 761: #endif ! 762: #if NHD > 0 ! 763: ADDMAP( NHDC ) ! 764: #endif ! 765: #include "vx.h" ! 766: #if NVX > 0 ! 767: ADDMAP( NVX * 16384/NBPG ) ! 768: #endif ! 769: SYSMAP(VMEMend ,vmemend ,0 ) ! 770: ! 771: SYSMAP(VBmap ,vbbase ,CLSIZE ) ! 772: #if NHD > 0 ! 773: ADDMAP( NHDC*(MAXPHYS/NBPG+CLSIZE) ) ! 774: #endif ! 775: #if NDK > 0 ! 776: ADDMAP( NVD*(MAXPHYS/NBPG+CLSIZE) ) ! 777: #endif ! 778: #if NYC > 0 ! 779: ADDMAP( NCY*(MAXPHYS/NBPG+CLSIZE) ) ! 780: #endif ! 781: ADDMAP( NMP*14 ) ! 782: SYSMAP(eVBmap ,vbend ,0 ) ! 783: ! 784: SYSMAP(Usrptmap ,usrpt ,USRPTSIZE+CLSIZE ) ! 785: eSysmap: ! 786: .globl _Syssize ! 787: .set _Syssize,(eSysmap-_Sysmap)/4 ! 788: ! 789: .text ! 790: /* ! 791: * Initialization ! 792: * ! 793: * IPL 0x1f; MME 0; scbb, pcbb, sbr, slr, isp, ksp not set ! 794: */ ! 795: .align 2 ! 796: .globl start ! 797: start: ! 798: .word 0 ! 799: /* set system control block base and system page table params */ ! 800: mtpr $_scb-SYSTEM,$SCBB ! 801: mtpr $_Sysmap-SYSTEM,$SBR ! 802: mtpr $_Syssize,$SLR ! 803: /* double map the kernel into the virtual user addresses of phys mem */ ! 804: mtpr $_Sysmap,$P0BR ! 805: mtpr $_Syssize,$P0LR ! 806: mtpr $_Sysmap,$P1BR # against Murphy ! 807: mtpr $_Syssize,$P1LR ! 808: /* set ISP */ ! 809: movl $_intstack-SYSTEM+NISP*NBPG,sp # still physical ! 810: mtpr $_intstack+NISP*NBPG,$ISP ! 811: /* count up memory */ ! 812: clrl r7 ! 813: 1: pushl $1; pushl r7; callf $12,_badaddr; tstl r0; bneq 9f ! 814: ACBL($MAXMEM*1024-1,$64*1024,r7,1b) ! 815: 9: ! 816: /* clear memory from kernel bss and pages for proc 0 u. and page table */ ! 817: movab _edata,r6; andl2 $~SYSTEM,r6 ! 818: movab _end,r5; andl2 $~SYSTEM,r5 ! 819: #ifdef KADB ! 820: subl2 $4,r5 ! 821: 1: clrl (r6); ACBL(r5,$4,r6,1b) # clear just bss ! 822: addl2 $4,r5 ! 823: bbc $6,r11,0f # check RB_KDB ! 824: andl3 $~SYSTEM,r9,r5 # skip symbol & string tables ! 825: andl3 $~SYSTEM,r9,r6 ! 826: #endif ! 827: 0: orl3 $SYSTEM,r5,r9 # convert to virtual address ! 828: addl2 $NBPG-1,r9 # roundup to next page ! 829: addl2 $(UPAGES*NBPG)+NBPG+NBPG,r5 ! 830: 1: clrl (r6); ACBL(r5,$4,r6,1b) ! 831: /* trap(), syscall(), and fpemulate() save r0-r12 in the entry mask */ ! 832: orw2 $0x01fff,_trap ! 833: orw2 $0x01fff,_syscall ! 834: #ifdef FPE ! 835: orw2 $0x01fff,_fpemulate ! 836: #endif ! 837: orw2 $0x01ffc,_panic # for debugging (no r0|r1) ! 838: callf $4,_fixctlrmask # setup for autoconfig ! 839: /* initialize system page table: scb and int stack writeable */ ! 840: clrl r2 ! 841: movab eintstack,r1 ! 842: andl2 $~SYSTEM,r1 ! 843: shrl $PGSHIFT,r1,r1 # r1-page number of eintstack ! 844: /* make 1st page processor storage read/only, 2nd read/write */ ! 845: orl3 $PG_V|PG_KR,r2,_Sysmap[r2]; incl r2; ! 846: orl3 $PG_V|PG_KW,r2,_Sysmap[r2]; incl r2; ! 847: /* other parts of the system are read/write for kernel */ ! 848: 1: orl3 $PG_V|PG_KW,r2,_Sysmap[r2]; # data:kernel write+phys=virtual ! 849: aoblss r1,r2,1b ! 850: /* make rsstk read-only as red zone for interrupt stack */ ! 851: andl2 $~PG_PROT,_rsstkmap ! 852: orl2 $PG_V|PG_KR,_rsstkmap ! 853: /* make kernel text space read-only */ ! 854: movab _etext+NBPG-1,r1 ! 855: andl2 $~SYSTEM,r1 ! 856: shrl $PGSHIFT,r1,r1 ! 857: 1: orl3 $PG_V|PG_KR,r2,_Sysmap[r2] ! 858: aoblss r1,r2,1b ! 859: /* make kernel data, bss, read-write */ ! 860: andl3 $~SYSTEM,r9,r1 ! 861: shrl $PGSHIFT,r1,r1 ! 862: 1: orl3 $PG_V|PG_KW,r2,_Sysmap[r2] ! 863: aoblss r1,r2,1b ! 864: /* go to mapped mode, have to change both pc and sp to system addresses */ ! 865: mtpr $1,$TBIA ! 866: mtpr $1,$PADC # needed by HW parity&ECC logic ! 867: mtpr $1,$PACC # just in case ! 868: mtpr $1,$MME ! 869: movab SYSTEM(sp),sp ! 870: jmp *$0f ! 871: 0: ! 872: /* disable any interrupts */ ! 873: movl $0,_intenable ! 874: /* init mem sizes */ ! 875: shrl $PGSHIFT,r7,_maxmem ! 876: movl _maxmem,_physmem ! 877: movl _maxmem,_freemem ! 878: /* setup context for proc[0] == scheduler */ ! 879: andl3 $~SYSTEM,r9,r6 # convert to physical ! 880: andl2 $~(NBPG-1),r6 # make page boundary ! 881: /* setup page table for proc[0] */ ! 882: shrl $PGSHIFT,r6,r3 # r3 = btoc(r6) ! 883: orl3 $PG_V|PG_KW,r3,_Usrptmap # init first upt entry ! 884: incl r3 # r3 - next page ! 885: movab _usrpt,r0 # r0 - first user page ! 886: mtpr r0,$TBIS ! 887: /* init p0br, p0lr */ ! 888: mtpr r0,$P0BR # no p0 for proc[0] ! 889: mtpr $0,$P0LR ! 890: mtpr r0,$P1BR # no p1 either ! 891: mtpr $0,$P1LR ! 892: /* init p2br, p2lr */ ! 893: movab NBPG(r0),r0 ! 894: movl $PPAGES-UPAGES,r1 ! 895: mtpr r1,$P2LR ! 896: moval -4*PPAGES(r0),r2 ! 897: mtpr r2,$P2BR ! 898: /* setup mapping for UPAGES of _u */ ! 899: clrl r2 ! 900: movl $SYSTEM,r1 ! 901: addl2 $UPAGES,r3 ! 902: jbr 2f ! 903: 1: decl r3 ! 904: moval -NBPG(r1),r1 # r1 = virtual add of next (downward) _u page ! 905: subl2 $4,r0 # r0 = pte address ! 906: orl3 $PG_V|PG_URKW,r3,(r0) ! 907: mtpr r1,$TBIS ! 908: 2: aobleq $UPAGES,r2,1b ! 909: /* initialize (slightly) the pcb */ ! 910: movab UPAGES*NBPG(r1),PCB_KSP(r1) # KSP starts at end of _u ! 911: movl r1,PCB_USP(r1) # USP starts just below _u ! 912: mfpr $P0BR,PCB_P0BR(r1) ! 913: mfpr $P0LR,PCB_P0LR(r1) ! 914: mfpr $P1BR,PCB_P1BR(r1) ! 915: mfpr $P1LR,PCB_P1LR(r1) ! 916: mfpr $P2BR,PCB_P2BR(r1) ! 917: mfpr $P2LR,PCB_P2LR(r1) ! 918: movl $CLSIZE,PCB_SZPT(r1) # init u.u_pcb.pcb_szpt ! 919: movl r9,PCB_R9(r1) # r9 obtained from boot ! 920: movl r10,PCB_R10(r1) # r10 obtained from boot ! 921: movl r11,PCB_R11(r1) # r11 obtained from CP on boot ! 922: movab 1f,PCB_PC(r1) # initial pc ! 923: clrl PCB_PSL(r1) # kernel mode, ipl=0 ! 924: shll $PGSHIFT,r3,r3 ! 925: mtpr r3,$PCBB # first pcbb (physical) ! 926: /* go to kernel mode */ ! 927: ldpctx ! 928: rei # Actually next instruction: ! 929: /* put signal trampoline code in u. area */ ! 930: 1: movab sigcode,r0 ! 931: movab _u+PCB_SIGC,r1 ! 932: movl $19,r2 ! 933: movblk ! 934: /* save boot device in global _bootdev */ ! 935: movl r10,_bootdev ! 936: /* save reboot flags in global _boothowto */ ! 937: movl r11,_boothowto ! 938: #ifdef KADB ! 939: /* save end of symbol & string table in global _bootesym */ ! 940: subl3 $NBPG-1,r9,_bootesym ! 941: #endif ! 942: /* calculate firstaddr, and call main() */ ! 943: andl3 $~SYSTEM,r9,r0 ! 944: shrl $PGSHIFT,r0,-(sp) ! 945: addl2 $UPAGES+1,(sp) # first physical unused page ! 946: callf $8,_main ! 947: /* proc[1] == /etc/init now running here in kernel mode; run icode */ ! 948: pushl $PSL_CURMOD # User mode PSL ! 949: pushl $0 # PC = 0 (virtual now) ! 950: rei ! 951: ! 952: /* ! 953: * Mask for saving/restoring registers on entry to ! 954: * a user signal handler. Space for the registers ! 955: * is reserved in sendsig, so beware if you want ! 956: * to change the mask. ! 957: */ ! 958: #define SIGREGS (R0|R1|R2|R3|R4|R5) ! 959: .align 2 ! 960: .globl sigcode ! 961: sigcode: ! 962: storer $SIGREGS,16(sp) # save volatile registers ! 963: calls $4*3+4,*12(sp) # params pushed by sendsig for handler ! 964: loadr $SIGREGS,4(sp) # restore volatile registers ! 965: movab 24(sp),fp # use parameter list set up in sendsig ! 966: kcall $SYS_sigreturn # cleanup mask and onsigstack ! 967: halt # sigreturn does not return! ! 968: ! 969: .globl _icode ! 970: .globl _initflags ! 971: .globl _szicode ! 972: /* ! 973: * Icode is copied out to process 1 to exec /etc/init. ! 974: * If the exec fails, process 1 exits. ! 975: */ ! 976: .align 2 ! 977: _icode: ! 978: /* try /sbin/init */ ! 979: pushab b`argv1-l0(pc) ! 980: l0: pushab b`init1-l1(pc) ! 981: l1: pushl $2 ! 982: movab (sp),fp ! 983: kcall $SYS_execv ! 984: /* try /etc/init */ ! 985: pushab b`argv2-l2(pc) ! 986: l2: pushab b`init2-l3(pc) ! 987: l3: pushl $2 ! 988: movab (sp),fp ! 989: kcall $SYS_execv ! 990: /* give up */ ! 991: pushl r0 ! 992: pushl $1 ! 993: movab (sp),fp ! 994: kcall $SYS_exit ! 995: ! 996: init1: .asciz "/sbin/init" ! 997: init2: .asciz "/etc/init" ! 998: .align 2 ! 999: _initflags: ! 1000: .long 0 ! 1001: argv1: .long init1+6-_icode ! 1002: .long _initflags-_icode ! 1003: .long 0 ! 1004: argv2: .long init2+5-_icode ! 1005: .long _initflags-_icode ! 1006: .long 0 ! 1007: _szicode: ! 1008: .long _szicode-_icode ! 1009: ! 1010: /* ! 1011: * Primitives ! 1012: */ ! 1013: ! 1014: /* ! 1015: * badaddr(addr, len) ! 1016: * see if access addr with a len type instruction causes a machine check ! 1017: * len is length of access (1=byte, 2=short, 4=long) ! 1018: * r0 = 0 means good(exists); r0 =1 means does not exist. ! 1019: */ ! 1020: ENTRY(badaddr, R3|R4) ! 1021: mfpr $IPL,r1 ! 1022: mtpr $HIGH,$IPL ! 1023: movl _scb+SCB_BUSERR,r2 ! 1024: movl 4(fp),r3 ! 1025: movl 8(fp),r4 ! 1026: movab 9f,_scb+SCB_BUSERR ! 1027: bbc $0,r4,1f; tstb (r3) ! 1028: 1: bbc $1,r4,1f; tstw (r3) ! 1029: 1: bbc $2,r4,1f; tstl (r3) ! 1030: 1: clrl r0 ! 1031: 2: movl r2,_scb+SCB_BUSERR ! 1032: mtpr r1,$IPL ! 1033: ret ! 1034: ! 1035: /* ! 1036: * wbadaddr(addr, len, value) ! 1037: * see if write of value to addr with a len type instruction causes ! 1038: * a machine check ! 1039: * len is length of access (1=byte, 2=short, 4=long) ! 1040: * r0 = 0 means good(exists); r0 =1 means does not exist. ! 1041: */ ! 1042: ENTRY(wbadaddr, R3|R4) ! 1043: mfpr $IPL,r1 ! 1044: mtpr $HIGH,$IPL ! 1045: movl _scb+SCB_BUSERR,r2 ! 1046: movl 4(fp),r3 ! 1047: movl 8(fp),r4 ! 1048: movab 9f,_scb+SCB_BUSERR ! 1049: bbc $0,r4,1f; movb 15(fp), (r3) ! 1050: 1: bbc $1,r4,1f; movw 14(fp), (r3) ! 1051: 1: bbc $2,r4,1f; movl 12(fp), (r3) ! 1052: 1: movl $30000,r0 # delay for error interrupt ! 1053: 1: decl r0 ! 1054: jneq 1b ! 1055: 2: movl r2,_scb+SCB_BUSERR # made it w/o machine checks; r0 is 0 ! 1056: mtpr r1,$IPL ! 1057: ret ! 1058: ! 1059: .align 2 ! 1060: 9: # catch buss error (if it comes) ! 1061: andl3 4(sp),$ERRCD,r0 ! 1062: cmpl r0,$APE ! 1063: jneq 1f ! 1064: halt # address parity error ! 1065: 1: cmpl r0,$VBE ! 1066: jneq 1f ! 1067: halt # Versabus error ! 1068: 1: ! 1069: movl $1,r0 # Anything else = bad address ! 1070: movab 8(sp),sp # discard buss error trash ! 1071: movab 2b,(sp) # new program counter on stack. ! 1072: rei ! 1073: ! 1074: /* ! 1075: * badcyaddr(addr) ! 1076: * see if access tape master controller addr causes a bus error ! 1077: * r0 = 0: no error; r0 = 1: timeout error. ! 1078: */ ! 1079: ENTRY(badcyaddr, 0) ! 1080: mfpr $IPL,r1 ! 1081: mtpr $HIGH,$IPL ! 1082: clrl r2 ! 1083: movab 2f,nofault ! 1084: movob $-1, *4(fp) ! 1085: 1: aobleq $1000, r2, 1b ! 1086: clrl nofault # made it w/o bus error ! 1087: clrl r0 ! 1088: jbr 3f ! 1089: 2: movl $1,r0 ! 1090: 3: mtpr r1,$IPL ! 1091: ret ! 1092: ! 1093: /* ! 1094: * peek(addr) ! 1095: * fetch word and catch any bus error ! 1096: */ ! 1097: ENTRY(peek, 0) ! 1098: mfpr $IPL,r1 ! 1099: mtpr $0x18,$IPL # not reentrant ! 1100: movl 4(fp),r2 ! 1101: movab 1f,nofault ! 1102: movw (r2),r0 ! 1103: clrl nofault ! 1104: andl2 $0xffff,r0 ! 1105: jbr 2f ! 1106: 1: movl $-1,r0 # bus error ! 1107: 2: mtpr r1,$IPL ! 1108: ret ! 1109: ! 1110: /* ! 1111: * poke(addr, val) ! 1112: * write word and catch any bus error ! 1113: */ ! 1114: ENTRY(poke, R3) ! 1115: mfpr $IPL,r1 ! 1116: mtpr $0x18,$IPL # not reentrant ! 1117: movl 4(fp),r2 ! 1118: movl 8(fp),r3 ! 1119: clrl r0 ! 1120: movab 1f,nofault ! 1121: movw r3,(r2) ! 1122: clrl nofault ! 1123: jbr 2f ! 1124: 1: movl $-1,r0 # bus error ! 1125: 2: mtpr r1,$IPL ! 1126: ret ! 1127: ! 1128: /* ! 1129: * Copy a potentially overlapping block of memory. ! 1130: * ! 1131: * ovbcopy(src, dst, count) ! 1132: * caddr_t src, dst; unsigned count; ! 1133: */ ! 1134: ENTRY(ovbcopy, R3|R4) ! 1135: movl 4(fp),r0 ! 1136: movl 8(fp),r1 ! 1137: movl 12(fp),r2 ! 1138: cmpl r0,r1 ! 1139: bgtru 1f # normal forward case ! 1140: beql 2f # equal, nothing to do ! 1141: addl2 r2,r0 # may be overlapping ! 1142: cmpl r0,r1 ! 1143: bgtru 3f ! 1144: subl2 r2,r0 # normal forward case ! 1145: 1: ! 1146: movblk ! 1147: 2: ! 1148: ret ! 1149: 3: ! 1150: addl2 r2,r1 # overlapping, must do backwards ! 1151: subl3 r0,r1,r3 ! 1152: movl r2,r4 ! 1153: jbr 5f ! 1154: 4: ! 1155: subl2 r3,r0 ! 1156: subl2 r3,r1 ! 1157: movl r3,r2 ! 1158: movblk ! 1159: subl2 r3,r0 ! 1160: subl2 r3,r1 ! 1161: subl2 r3,r4 ! 1162: 5: ! 1163: cmpl r4,r3 ! 1164: jgtr 4b ! 1165: movl r4,r2 ! 1166: subl2 r2,r0 ! 1167: subl2 r2,r1 ! 1168: movblk ! 1169: ret ! 1170: ! 1171: /* ! 1172: * Copy a null terminated string from the user address space into ! 1173: * the kernel address space. ! 1174: * ! 1175: * copyinstr(fromaddr, toaddr, maxlength, &lencopied) ! 1176: */ ! 1177: ENTRY(copyinstr, 0) ! 1178: movl 12(fp),r5 # r5 = max length ! 1179: jlss 5f ! 1180: movl 8(fp),r4 # r4 = kernel address ! 1181: movl 4(fp),r0 # r0 = user address ! 1182: andl3 $(NBPG*CLSIZE-1),r0,r2 # r2 = bytes on first page ! 1183: subl3 r2,$(NBPG*CLSIZE),r2 ! 1184: 1: ! 1185: cmpl r5,r2 # r2 = min(bytes on page, length left); ! 1186: jgeq 2f ! 1187: movl r5,r2 ! 1188: 2: ! 1189: prober $1,(r0),r2 # bytes accessible? ! 1190: jeql 5f ! 1191: subl2 r2,r5 # update bytes left count ! 1192: movl r2,r3 # r3 = saved count ! 1193: movl r0,r1 ! 1194: cmps3 # check for null ! 1195: tstl r2 ! 1196: jneq 3f ! 1197: subl2 r3,r0 # back up r0 ! 1198: movl r4,r1 ! 1199: movl r3,r2 ! 1200: movblk # copy in next piece ! 1201: movl r1,r4 ! 1202: movl $(NBPG*CLSIZE),r2 # check next page ! 1203: tstl r5 # run out of space? ! 1204: jneq 1b ! 1205: movl $ENOENT,r0 # set error code and return ! 1206: jbr 6f ! 1207: 3: ! 1208: tstl 16(fp) # return length? ! 1209: beql 4f ! 1210: subl3 r5,12(fp),r5 # actual len = maxlen - unused pages ! 1211: subl2 r2,r5 # - unused on this page ! 1212: addl3 $1,r5,*16(fp) # + the null byte ! 1213: 4: ! 1214: movl r4,r1 ! 1215: subl3 r2,r3,r2 # calc char cnt ! 1216: subl2 r2,r0 # back up r0 ! 1217: incl r2 # add on null byte ! 1218: movblk # copy last piece ! 1219: clrl r0 ! 1220: ret ! 1221: 5: ! 1222: movl $EFAULT,r0 ! 1223: 6: ! 1224: tstl 16(fp) ! 1225: beql 7f ! 1226: subl3 r5,12(fp),*16(fp) ! 1227: 7: ! 1228: ret ! 1229: ! 1230: /* ! 1231: * Copy a null terminated string from the kernel ! 1232: * address space to the user address space. ! 1233: * ! 1234: * copyoutstr(fromaddr, toaddr, maxlength, &lencopied) ! 1235: */ ! 1236: ENTRY(copyoutstr, 0) ! 1237: movl 12(fp),r5 # r5 = max length ! 1238: jlss 5f ! 1239: movl 4(fp),r0 # r0 = kernel address ! 1240: movl 8(fp),r4 # r4 = user address ! 1241: andl3 $(NBPG*CLSIZE-1),r4,r2 # r2 = bytes on first page ! 1242: subl3 r2,$(NBPG*CLSIZE),r2 ! 1243: 1: ! 1244: cmpl r5,r2 # r2 = min(bytes on page, length left); ! 1245: jgeq 2f ! 1246: movl r5,r2 ! 1247: 2: ! 1248: probew $1,(r4),r2 # bytes accessible? ! 1249: jeql 5f ! 1250: subl2 r2,r5 # update bytes left count ! 1251: movl r2,r3 # r3 = saved count ! 1252: movl r0,r1 ! 1253: /* ! 1254: * This is a workaround for a microcode bug that causes ! 1255: * a trap type 9 when cmps3/movs3 touches the last byte ! 1256: * on a valid page immediately followed by an invalid page. ! 1257: */ ! 1258: #ifdef good_cmps3 ! 1259: cmps3 # check for null ! 1260: tstl r2 ! 1261: jneq 3b ! 1262: #else ! 1263: decl r2 ! 1264: beql 9f # cannot handle case of r2 == 0! ! 1265: cmps3 # check for null up to last byte ! 1266: 9: ! 1267: incl r2 ! 1268: cmpl $1,r2 # get to last byte on page? ! 1269: bneq 3b ! 1270: tstb (r0) # last byte on page null? ! 1271: beql 3b ! 1272: incl r0 # not null, so bump pointer ! 1273: #endif not good_cmps3 ! 1274: subl2 r3,r0 # back up r0 ! 1275: movl r4,r1 ! 1276: movl r3,r2 ! 1277: movblk # copy out next piece ! 1278: movl r1,r4 ! 1279: movl $(NBPG*CLSIZE),r2 # check next page ! 1280: tstl r5 # run out of space? ! 1281: jneq 1b ! 1282: movl $ENOENT,r0 # set error code and return ! 1283: jbr 6b ! 1284: 5: ! 1285: clrl *$0 # this should never execute, if it does ! 1286: movl $EFAULT,r0 # save me a core dump (mkm - 9/87) ! 1287: 6: ! 1288: tstl 16(fp) ! 1289: beql 7f ! 1290: subl3 r5,12(fp),*16(fp) ! 1291: 7: ! 1292: ret ! 1293: ! 1294: ! 1295: /* ! 1296: * Copy a null terminated string from one point to another in ! 1297: * the kernel address space. ! 1298: * ! 1299: * copystr(fromaddr, toaddr, maxlength, &lencopied) ! 1300: */ ! 1301: ENTRY(copystr, 0) ! 1302: movl 12(fp),r3 # r3 = max length ! 1303: jlss 5b ! 1304: movl 4(fp),r0 # r0 = src address ! 1305: movl 8(fp),r4 # r4 = dest address ! 1306: clrl r5 # r5 = bytes left ! 1307: movl r3,r2 # r2 = max bytes to copy ! 1308: movl r0,r1 ! 1309: cmps3 # check for null ! 1310: tstl r2 ! 1311: jneq 3b ! 1312: subl2 r3,r0 # back up r0 ! 1313: movl r4,r1 ! 1314: movl r3,r2 ! 1315: movblk # copy next piece ! 1316: movl $ENOENT,r0 # set error code and return ! 1317: jbr 6b ! 1318: ! 1319: /* ! 1320: * Copy a block of data from the user address space into ! 1321: * the kernel address space. ! 1322: * ! 1323: * copyin(fromaddr, toaddr, count) ! 1324: */ ! 1325: ENTRY(copyin, 0) ! 1326: movl 12(fp),r0 # copy length ! 1327: blss 9f ! 1328: movl 4(fp),r1 # copy user address ! 1329: cmpl $(CLSIZE*NBPG),r0 # probing one page or less ? ! 1330: bgeq 2f # yes ! 1331: 1: ! 1332: prober $1,(r1),$(CLSIZE*NBPG) # bytes accessible ? ! 1333: beql 9f # no ! 1334: addl2 $(CLSIZE*NBPG),r1 # incr user address ptr ! 1335: _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r0,1b) # reduce count and loop ! 1336: 2: ! 1337: prober $1,(r1),r0 # bytes accessible ? ! 1338: beql 9f # no ! 1339: MOVC3(4(fp),8(fp),12(fp)) ! 1340: clrl r0 ! 1341: ret ! 1342: 9: ! 1343: movl $EFAULT,r0 ! 1344: ret ! 1345: ! 1346: /* ! 1347: * Copy a block of data from the kernel ! 1348: * address space to the user address space. ! 1349: * ! 1350: * copyout(fromaddr, toaddr, count) ! 1351: */ ! 1352: ENTRY(copyout, 0) ! 1353: movl 12(fp),r0 # get count ! 1354: blss 9b ! 1355: movl 8(fp),r1 # get user address ! 1356: cmpl $(CLSIZE*NBPG),r0 # can do in one probew? ! 1357: bgeq 2f # yes ! 1358: 1: ! 1359: probew $1,(r1),$(CLSIZE*NBPG) # bytes accessible? ! 1360: beql 9b # no ! 1361: addl2 $(CLSIZE*NBPG),r1 # increment user address ! 1362: _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r0,1b) # reduce count and loop ! 1363: 2: ! 1364: probew $1,(r1),r0 # bytes accessible? ! 1365: beql 9b # no ! 1366: MOVC3(4(fp),8(fp),12(fp)) ! 1367: clrl r0 ! 1368: ret ! 1369: ! 1370: /* ! 1371: * non-local goto's ! 1372: */ ! 1373: #ifdef notdef ! 1374: ENTRY(setjmp, 0) ! 1375: movl 4(fp),r0 ! 1376: movl (fp),(r0); addl2 $4,r0 # save fp ! 1377: movl -8(fp),(r0) # save pc ! 1378: clrl r0 ! 1379: ret ! 1380: #endif ! 1381: ! 1382: ENTRY(longjmp, 0) ! 1383: movl 4(fp),r0 ! 1384: movl (r0),newfp; addl2 $4,r0 # must save parameters in memory ! 1385: movl (r0),newpc # as all regs may be clobbered. ! 1386: 1: ! 1387: cmpl fp,newfp # are we there yet? ! 1388: bgequ 2f # yes ! 1389: moval 1b,-8(fp) # redirect return pc to us! ! 1390: ret # pop next frame ! 1391: 2: ! 1392: beql 3f # did we miss our frame? ! 1393: pushab 4f # yep ?!? ! 1394: callf $8,_panic ! 1395: 3: ! 1396: movl newpc,r0 # all done, just return ! 1397: jmp (r0) # to setjmp `ret' ! 1398: ! 1399: .data ! 1400: newpc: .space 4 ! 1401: newfp: .space 4 ! 1402: 4: .asciz "longjmp" ! 1403: .text ! 1404: ! 1405: /* ! 1406: * setjmp that saves all registers as the call frame may not ! 1407: * be available to recover them in the usual manner by longjmp. ! 1408: * Called before swapping out the u. area, restored by resume() ! 1409: * below. ! 1410: */ ! 1411: ENTRY(savectx, 0) ! 1412: movl 4(fp),r2 ! 1413: storer $0x1ff8,(r2); addl2 $40,r2 # r3-r12 ! 1414: movl (fp),(r2); addl2 $4,r2 # fp ! 1415: movab 8(fp),(r2); addl2 $4,r2 # sp ! 1416: movl -8(fp),(r2) # pc ! 1417: clrl r0 ! 1418: ret ! 1419: ! 1420: #ifdef KADB ! 1421: /* ! 1422: * C library -- reset, setexit ! 1423: * ! 1424: * reset(x) ! 1425: * will generate a "return" from ! 1426: * the last call to ! 1427: * setexit() ! 1428: * by restoring r2 - r12, fp ! 1429: * and doing a return. ! 1430: * The returned value is x; on the original ! 1431: * call the returned value is 0. ! 1432: */ ! 1433: ENTRY(setexit, 0) ! 1434: movab setsav,r0 ! 1435: storer $0x1ffc, (r0) ! 1436: movl (fp),44(r0) # fp ! 1437: moval 4(fp),48(r0) # sp ! 1438: movl -8(fp),52(r0) # pc ! 1439: clrl r0 ! 1440: ret ! 1441: ! 1442: ENTRY(reset, 0) ! 1443: movl 4(fp),r0 # returned value ! 1444: movab setsav,r1 ! 1445: loadr $0x1ffc,(r1) ! 1446: movl 44(r1),fp ! 1447: movl 48(r1),sp ! 1448: jmp *52(r1) ! 1449: ! 1450: .data ! 1451: .align 2 ! 1452: setsav: .space 14*4 ! 1453: .text ! 1454: #endif ! 1455: ! 1456: .globl _whichqs ! 1457: .globl _qs ! 1458: .globl _cnt ! 1459: ! 1460: .globl _noproc ! 1461: .comm _noproc,4 ! 1462: .globl _runrun ! 1463: .comm _runrun,4 ! 1464: /* ! 1465: * The following primitives use the fancy TAHOE instructions. ! 1466: * _whichqs tells which of the 32 queues _qs ! 1467: * have processes in them. setrq puts processes into queues, remrq ! 1468: * removes them from queues. The running process is on no queue, ! 1469: * other processes are on a queue related to p->p_pri, divided by 4 ! 1470: * actually to shrink the 0-127 range of priorities into the 32 available ! 1471: * queues. ! 1472: */ ! 1473: ! 1474: /* ! 1475: * setrq(p), using fancy TAHOE instructions. ! 1476: * ! 1477: * Call should be made at spl8(), and p->p_stat should be SRUN ! 1478: */ ! 1479: ENTRY(setrq, 0) ! 1480: movl 4(fp),r0 ! 1481: tstl P_RLINK(r0) ## firewall: p->p_rlink must be 0 ! 1482: beql set1 ## ! 1483: pushab set3 ## ! 1484: callf $8,_panic ## ! 1485: set1: ! 1486: movzbl P_PRI(r0),r1 # put on queue which is p->p_pri / 4 ! 1487: shar $2,r1,r1 ! 1488: shal $1,r1,r2 ! 1489: moval _qs[r2],r2 ! 1490: insque (r0),*4(r2) # at end of queue ! 1491: shal r1,$1,r1 ! 1492: orl2 r1,_whichqs # mark queue non-empty ! 1493: ret ! 1494: ! 1495: set3: .asciz "setrq" ! 1496: ! 1497: /* ! 1498: * remrq(p), using fancy TAHOE instructions ! 1499: * ! 1500: * Call should be made at spl8(). ! 1501: */ ! 1502: ENTRY(remrq, 0) ! 1503: movl 4(fp),r0 ! 1504: movzbl P_PRI(r0),r1 ! 1505: shar $2,r1,r1 ! 1506: bbs r1,_whichqs,rem1 ! 1507: pushab rem3 # it wasn't recorded to be on its q ! 1508: callf $8,_panic ! 1509: rem1: ! 1510: remque (r0) ! 1511: bneq rem2 # q not empty yet ! 1512: shal r1,$1,r1 ! 1513: mcoml r1,r1 ! 1514: andl2 r1,_whichqs # mark queue empty ! 1515: rem2: ! 1516: clrl P_RLINK(r0) ## for firewall checking ! 1517: ret ! 1518: ! 1519: rem3: .asciz "remrq" ! 1520: ! 1521: /* ! 1522: * Masterpaddr is the p->p_addr of the running process on the master ! 1523: * processor. When a multiprocessor system, the slave processors will have ! 1524: * an array of slavepaddr's. ! 1525: */ ! 1526: .globl _masterpaddr ! 1527: .data ! 1528: .align 2 ! 1529: _masterpaddr: .long 0 ! 1530: ! 1531: .text ! 1532: sw0: .asciz "swtch" ! 1533: ! 1534: /* ! 1535: * When no processes are on the runq, swtch branches to idle ! 1536: * to wait for something to come ready. ! 1537: */ ! 1538: .globl Idle ! 1539: Idle: idle: ! 1540: movl $1,_noproc ! 1541: mtpr $0,$IPL # must allow interrupts here ! 1542: 1: ! 1543: tstl _whichqs # look for non-empty queue ! 1544: bneq sw1 ! 1545: brb 1b ! 1546: ! 1547: badsw: pushab sw0 ! 1548: callf $8,_panic ! 1549: /* NOTREACHED */ ! 1550: ! 1551: .align 2 ! 1552: /* ! 1553: * swtch(), using fancy tahoe instructions ! 1554: */ ! 1555: ENTRY(swtch, 0) ! 1556: movl (fp),fp # prepare for rei ! 1557: movl (sp),4(sp) # saved pc ! 1558: tstl (sp)+ ! 1559: movpsl 4(sp) ! 1560: incl _cnt+V_SWTCH ! 1561: sw1: ffs _whichqs,r0 # look for non-empty queue ! 1562: blss idle # if none, idle ! 1563: mtpr $0x18,$IPL # lock out all so _whichqs==_qs ! 1564: bbc r0,_whichqs,sw1 # proc moved via interrupt ! 1565: shal $1,r0,r1 ! 1566: moval _qs[r1],r1 ! 1567: movl (r1),r2 # r2 = p = highest pri process ! 1568: remque *(r1) ! 1569: bvs badsw # make sure something was there ! 1570: bneq sw2 ! 1571: shal r0,$1,r1 ! 1572: mcoml r1,r1 ! 1573: andl2 r1,_whichqs # no more procs in this queue ! 1574: sw2: ! 1575: clrl _noproc ! 1576: clrl _runrun ! 1577: #ifdef notdef ! 1578: tstl P_WCHAN(r2) ## firewalls ! 1579: bneq badsw ## ! 1580: cmpb P_STAT(r2),$SRUN ## ! 1581: bneq badsw ## ! 1582: #endif ! 1583: clrl P_RLINK(r2) ## ! 1584: movl *P_ADDR(r2),r0 ! 1585: #ifdef notdef ! 1586: cmpl r0,_masterpaddr # resume of current proc is easy ! 1587: beql res0 ! 1588: #endif ! 1589: movl r0,_masterpaddr ! 1590: shal $PGSHIFT,r0,r0 # r0 = pcbb(p) ! 1591: brb swresume ! 1592: ! 1593: /* ! 1594: * resume(pf) ! 1595: */ ! 1596: ENTRY(resume, 0) ! 1597: shal $PGSHIFT,4(fp),r0 # r0 = pcbb(pf) ! 1598: movl (fp),fp # prepare for rei ! 1599: movl (sp)+,4(sp) # saved pc ! 1600: tstl (sp)+ ! 1601: movpsl 4(sp) ! 1602: swresume: ! 1603: mtpr $0x18,$IPL # no interrupts, please ! 1604: movl _CMAP2,_u+PCB_CMAP2 # yech ! 1605: REST_ACC # restore original accumulator ! 1606: svpctx ! 1607: mtpr r0,$PCBB ! 1608: ldpctx ! 1609: movl _u+PCB_CMAP2,_CMAP2 # yech ! 1610: mtpr $_CADDR2,$TBIS ! 1611: res0: ! 1612: movl _u+U_PROCP,r2 # r2 = u.u_procp ! 1613: tstl P_CKEY(r2) # does proc have code key? ! 1614: bneq 1f ! 1615: callf $4,_getcodekey # no, give him one ! 1616: movl _u+U_PROCP,r2 # r2 = u.u_procp ! 1617: movl r0,P_CKEY(r2) ! 1618: 1: ! 1619: tstl P_DKEY(r2) # does proc have data key? ! 1620: bneq 1f ! 1621: callf $4,_getdatakey # no, give him one ! 1622: movl _u+U_PROCP,r2 # r2 = u.u_procp ! 1623: movl r0,P_DKEY(r2) ! 1624: 1: ! 1625: mtpr P_CKEY(r2),$CCK # set code cache key ! 1626: mtpr P_DKEY(r2),$DCK # set data cache key ! 1627: tstl _u+PCB_SSWAP ! 1628: bneq res1 ! 1629: rei ! 1630: res1: # longjmp to saved context ! 1631: movl _u+PCB_SSWAP,r2 ! 1632: clrl _u+PCB_SSWAP ! 1633: loadr $0x3ff8,(r2); addl2 $44,r2 # restore r3-r13 (r13=fp) ! 1634: movl (r2),r1; addl2 $4,r2 # fetch previous sp ... ! 1635: movab (sp),r0 # ... and current sp and ! 1636: cmpl r1,r0 # check for credibility, ! 1637: bgequ 1f # if further up stack ... ! 1638: pushab 2f; callf $8,_panic # ... panic ! 1639: /*NOTREACHED*/ ! 1640: 1: # sp ok, complete return ! 1641: movl r1,sp # restore sp ! 1642: pushl $PSL_PRVMOD # kernel mode, ipl 0 ! 1643: pushl (r2) # return address ! 1644: rei ! 1645: 2: .asciz "ldctx" ! 1646: ! 1647: /* ! 1648: * {fu,su},{byte,word} ! 1649: */ ! 1650: ENTRY(fuword, 0) ! 1651: movl 4(fp), r1 ! 1652: prober $1,(r1),$4 # check access ! 1653: beql fserr # page unreadable ! 1654: bitl $1,r1 # check byte alignment ! 1655: bneq 2f # odd, do byte-word-byte ! 1656: bitl $2,r1 # check word alignment ! 1657: bneq 1f # odd, do in 2 words ! 1658: movl (r1),r0 # move longword ! 1659: ret ! 1660: 1: ! 1661: movw (r1),r0 # move two words ! 1662: shal $16,r0,r0 ! 1663: movzwl 2(r1),r1 # orw2 sign extends ! 1664: orl2 r1,r0 ! 1665: ret ! 1666: 2: ! 1667: movb (r1),r0 # move byte-word-byte ! 1668: shal $24,r0,r0 ! 1669: movzwl 1(r1),r2 # orw2 sign extends ! 1670: shal $8,r2,r2 ! 1671: movzbl 3(r1),r1 # orb2 sign extends ! 1672: orl2 r2,r1 ! 1673: orl2 r1,r0 ! 1674: ret ! 1675: fserr: ! 1676: mnegl $1,r0 ! 1677: ret ! 1678: ! 1679: ENTRY(fubyte, 0) ! 1680: prober $1,*4(fp),$1 ! 1681: beql fserr ! 1682: movzbl *4(fp),r0 ! 1683: ret ! 1684: ! 1685: ENTRY(suword, 0) ! 1686: movl 4(fp), r0 ! 1687: probew $1,(r0),$4 # check access ! 1688: beql fserr # page unwritable ! 1689: bitl $1,r0 # check byte alignment ! 1690: bneq 1f # odd byte boundary ! 1691: bitl $2,r0 # check word alignment ! 1692: beql 2f # longword aligned ! 1693: movw 8(fp),(r0) # move two words ! 1694: movw 10(fp),2(r0) ! 1695: jbr 3f ! 1696: 1: ! 1697: movb 8(fp),(r0) ! 1698: movb 9(fp),1(r0) ! 1699: movb 10(fp),2(r0) ! 1700: movb 11(fp),3(r0) ! 1701: jbr 3f ! 1702: 2: ! 1703: movl 8(fp),(r0) ! 1704: 3: ! 1705: clrl r0 ! 1706: ret ! 1707: ! 1708: ENTRY(subyte, 0) ! 1709: probew $1,*4(fp),$1 ! 1710: beql fserr ! 1711: movb 11(fp),*4(fp) ! 1712: clrl r0 ! 1713: ret ! 1714: ! 1715: /* ! 1716: * Copy 1 relocation unit (NBPG bytes) ! 1717: * from user virtual address to physical address ! 1718: */ ! 1719: ENTRY(copyseg, 0) ! 1720: orl3 $PG_V|PG_KW,8(fp),_CMAP2 ! 1721: mtpr $_CADDR2,$TBIS # invalidate entry for copy ! 1722: MOVC3(4(fp),$_CADDR2,$NBPG) ! 1723: ret ! 1724: ! 1725: /* ! 1726: * Clear a page of memory. The page frame is specified. ! 1727: * ! 1728: * clearseg(pf); ! 1729: */ ! 1730: ENTRY(clearseg, 0) ! 1731: orl3 $PG_V|PG_KW,4(fp),_CMAP1 # Maps to virtual addr CADDR1 ! 1732: mtpr $_CADDR1,$TBIS ! 1733: movl $255,r0 # r0 = limit ! 1734: clrl r1 # r1 = index of cleared long ! 1735: 1: ! 1736: clrl _CADDR1[r1] ! 1737: aobleq r0,r1,1b ! 1738: ret ! 1739: ! 1740: /* ! 1741: * Check user mode read/write access. ! 1742: * ! 1743: * useracc(addr, count, mode) ! 1744: * caddr_t addr; int count, mode; ! 1745: * mode = 0 write access ! 1746: * mode = 1 read access ! 1747: */ ! 1748: ENTRY(useracc, 0) ! 1749: movl $1,r2 # r2 = 'user mode' for probew/probew ! 1750: probes: ! 1751: movl 4(fp),r0 # get va ! 1752: movl 8(fp),r1 # count ! 1753: tstl 12(fp) # test for read access ? ! 1754: bneq userar # yes ! 1755: cmpl $(CLSIZE*NBPG),r1 # can we do it in one probe ? ! 1756: bgeq uaw2 # yes ! 1757: uaw1: ! 1758: probew r2,(r0),$(CLSIZE*NBPG) ! 1759: beql uaerr # no access ! 1760: addl2 $(CLSIZE*NBPG),r0 ! 1761: _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r1,uaw1) ! 1762: uaw2: ! 1763: probew r2,(r0),r1 ! 1764: beql uaerr ! 1765: movl $1,r0 ! 1766: ret ! 1767: userar: ! 1768: cmpl $(CLSIZE*NBPG),r1 ! 1769: bgeq uar2 ! 1770: uar1: ! 1771: prober r2,(r0),$(CLSIZE*NBPG) ! 1772: beql uaerr ! 1773: addl2 $(CLSIZE*NBPG),r0 ! 1774: _ACBL($(CLSIZE*NBPG+1),$(-CLSIZE*NBPG),r1,uar1) ! 1775: uar2: ! 1776: prober r2,(r0),r1 ! 1777: beql uaerr ! 1778: movl $1,r0 ! 1779: ret ! 1780: uaerr: ! 1781: clrl r0 ! 1782: ret ! 1783: ! 1784: /* ! 1785: * Check kernel mode read/write access. ! 1786: * ! 1787: * kernacc(addr, count, mode) ! 1788: * caddr_t addr; int count, mode; ! 1789: * mode = 0 write access ! 1790: * mode = 1 read access ! 1791: */ ! 1792: ENTRY(kernacc, 0) ! 1793: clrl r2 # r2 = 0 means kernel mode probe. ! 1794: jbr probes # Dijkstra would get gastric distress here. ! 1795: ! 1796: /* ! 1797: * addupc - increment some histogram counter ! 1798: * in the profiling buffer ! 1799: * ! 1800: * addupc(pc, prof, delta) ! 1801: * long pc; short delta; struct uprof *prof; ! 1802: * ! 1803: * struct uprof { # profile arguments ! 1804: * short *r_base; # buffer base ! 1805: * unsigned pr_size; # buffer size ! 1806: * unsigned pr_off; # pc offset ! 1807: * unsigned pr_scale; # pc scaling ! 1808: * } ! 1809: */ ! 1810: ENTRY(addupc, 0) ! 1811: movl 8(fp),r2 # r2 points to structure ! 1812: subl3 8(r2),4(fp),r0 # r0 = PC - lowpc ! 1813: jlss 9f # PC < lowpc , out of range ! ! 1814: shrl $1,r0,r0 # the unit is words ! 1815: shrl $1,12(r2),r1 # ditto for scale ! 1816: emul r1,r0,$0,r0 ! 1817: shrq $14,r0,r0 ! 1818: tstl r0 # too big ! 1819: jneq 9f ! 1820: cmpl r1,4(r2) # Check buffer overflow ! 1821: jgequ 9f ! 1822: probew $1,*0(r2)[r1],$2 # counter accessible? ! 1823: jeql 9f ! 1824: shrl $1,r1,r1 # make r1 word index ! 1825: addw2 14(fp),*0(r2)[r1] ! 1826: 9: ret ! 1827: ! 1828: /* ! 1829: * scanc(size, cp, table, mask) ! 1830: */ ! 1831: ENTRY(scanc, R3|R4) ! 1832: movl 8(fp),r0 # r0 = cp ! 1833: addl3 4(fp),r0,r2 # end = &cp[size] ! 1834: movl 12(fp),r1 # r1 = table ! 1835: movb 19(fp),r4 # r4 = mask ! 1836: decl r0 # --cp ! 1837: jbr 0f # just like Fortran... ! 1838: 1: # do { ! 1839: movzbl (r0),r3 ! 1840: bitb r4,(r1)[r3] # if (table[*cp] & mask) ! 1841: jneq 2f # break; ! 1842: 0: aoblss r2,r0,1b # } while (++cp < end); ! 1843: 2: ! 1844: subl3 r0,r2,r0; ret # return (end - cp); ! 1845: ! 1846: /* ! 1847: * skpc(mask, size, cp) ! 1848: */ ! 1849: ENTRY(skpc, 0) ! 1850: movl 12(fp),r0 # r0 = cp ! 1851: addl3 8(fp),r0,r1 # r1 = end = &cp[size]; ! 1852: movb 7(fp),r2 # r2 = mask ! 1853: decl r0 # --cp; ! 1854: jbr 0f ! 1855: 1: # do ! 1856: cmpb (r0),r2 # if (*cp != mask) ! 1857: jneq 2f # break; ! 1858: 0: aoblss r1,r0,1b # while (++cp < end); ! 1859: 2: ! 1860: subl3 r0,r1,r0; ret # return (end - cp); ! 1861: ! 1862: /* ! 1863: * locc(mask, size, cp) ! 1864: */ ! 1865: ENTRY(locc, 0) ! 1866: movl 12(fp),r0 # r0 = cp ! 1867: addl3 8(fp),r0,r1 # r1 = end = &cp[size] ! 1868: movb 7(fp),r2 # r2 = mask ! 1869: decl r0 # --cp; ! 1870: jbr 0f ! 1871: 1: # do ! 1872: cmpb (r0),r2 # if (*cp == mask) ! 1873: jeql 2f # break; ! 1874: 0: aoblss r1,r0,1b # while (++cp < end); ! 1875: 2: ! 1876: subl3 r0,r1,r0; ret # return (end - cp); ! 1877: ! 1878: #ifdef ALIGN ! 1879: #include "../tahoealign/align.h" ! 1880: ! 1881: .globl _alignment ! 1882: /* ! 1883: * There's an intimate relationship between this piece of code ! 1884: * and the alignment emulation code (especially the layout ! 1885: * of local variables in alignment.c! Don't change unless ! 1886: * you update both this, alignment.h and alignment.c !! ! 1887: */ ! 1888: non_aligned: ! 1889: orb2 $EMULATEALIGN,_u+U_EOSYS ! 1890: incl _cnt+V_TRAP ! 1891: incl _cnt+V_ALIGN # count emulated alignment traps ! 1892: moval 4(sp),_user_psl ! 1893: SAVE_FPSTAT(4) # Also zeroes out ret_exception ! ! 1894: pushl $0 # ret_addr ! 1895: pushl $0 # ret_code ! 1896: mfpr $USP,-(sp) # user sp ! 1897: callf $4,_alignment # call w/o parms so regs may be modified ! 1898: /* ! 1899: * We return here after a successful emulation or an exception. ! 1900: * The registers have been restored and we must not alter them ! 1901: * before returning to the user. ! 1902: */ ! 1903: 2: mtpr (sp)+,$USP # restore user sp ! 1904: tstl 8(sp) # Any exception ? ! 1905: bneq got_excp # Yes, reflect it back to user. ! 1906: moval 8(sp),sp # pop 2 zeroes pushed above ! 1907: REST_FPSTAT ! 1908: xorb2 $EMULATEALIGN,_u+U_EOSYS ! 1909: ! 1910: bitl $PSL_T,4(sp) # check for trace bit set ! 1911: beql 9f ! 1912: CHECK_SFE(4) ! 1913: pushl $0 ! 1914: SAVE_FPSTAT(8) ! 1915: TRAP(TRCTRAP) ! 1916: 9: rei ! 1917: ! 1918: got_excp: # decode exception ! 1919: casel 8(sp),$ILL_ADDRMOD,$ALIGNMENT ! 1920: .align 1 ! 1921: L1: ! 1922: .word ill_addrmod-L1 ! 1923: .word ill_access-L1 ! 1924: .word ill_oprnd-L1 ! 1925: .word arithmetic-L1 ! 1926: .word alignment-L1 ! 1927: brw alignment # default - shouldn't come here at all ! ! 1928: ! 1929: ill_addrmod: # No other parameters. Set up stack as ! 1930: moval 8(sp),sp # the HW would do it in a real case. ! 1931: REST_FPSTAT ! 1932: jbr _Xresadflt ! 1933: ill_oprnd: ! 1934: moval 8(sp),sp ! 1935: REST_FPSTAT ! 1936: jbr _Xresopflt ! 1937: alignment: ! 1938: moval 8(sp),sp ! 1939: REST_FPSTAT ! 1940: jbr align_excp # NB: going to _Xalignflt would cause loop ! 1941: ill_access: ! 1942: /* ! 1943: * Must restore accumulator w/o modifying sp and w/o using ! 1944: * registers. Solution: copy things needed by REST_FPSTAT. ! 1945: */ ! 1946: pushl 20(sp) # The flags longword ! 1947: pushl 20(sp) # acc_low ! 1948: pushl 20(sp) # acc_high ! 1949: pushl 20(sp) # ret_exception ignored by REST_FPSTAT ! 1950: REST_FPSTAT # Back where we were with the sp ! ! 1951: movl (sp),16(sp) # code for illegal access ! 1952: movl 4(sp),20(sp) # original virtual address ! 1953: moval 16(sp),sp # Just like the HW would set it up ! 1954: jbr _Xprotflt ! 1955: arithmetic: # same trickery as above ! 1956: pushl 20(sp) # The flags longword ! 1957: pushl 20(sp) # acc_low ! 1958: pushl 20(sp) # acc_high ! 1959: pushl 20(sp) # ret_exception ignored by REST_FPSTAT ! 1960: REST_FPSTAT # Back where we were with the sp ! ! 1961: movl (sp),20(sp) # code for arithmetic exception ! 1962: moval 20(sp),sp # Just like the HW would set it up ! 1963: jbr _Xarithtrap ! 1964: #endif ! 1965: SCBVEC(hdintr0): ! 1966: CHECK_SFE(4) ! 1967: SAVE_FPSTAT(4) ! 1968: PUSHR ! 1969: incl _fltintrcnt+(4*0) ! 1970: pushl $0 ! 1971: callf $8,_hdintr ! 1972: incl _cnt+V_INTR ! 1973: POPR ! 1974: REST_FPSTAT ! 1975: rei ! 1976: ! 1977: SCBVEC(hdintr1): ! 1978: CHECK_SFE(4) ! 1979: SAVE_FPSTAT(4) ! 1980: PUSHR ! 1981: incl _fltintrcnt+(4*1) ! 1982: pushl $1 ! 1983: callf $8,_hdintr ! 1984: incl _cnt+V_INTR ! 1985: POPR ! 1986: REST_FPSTAT ! 1987: rei ! 1988: ! 1989: SCBVEC(vdintr0): ! 1990: CHECK_SFE(4) ! 1991: SAVE_FPSTAT(4) ! 1992: PUSHR ! 1993: incl _fltintrcnt+(4*2) ! 1994: pushl $0 ! 1995: callf $8,_vdintr ! 1996: incl _cnt+V_INTR ! 1997: POPR ! 1998: REST_FPSTAT ! 1999: rei ! 2000: ! 2001: SCBVEC(vdintr1): ! 2002: CHECK_SFE(4) ! 2003: SAVE_FPSTAT(4) ! 2004: PUSHR ! 2005: incl _fltintrcnt+(4*3) ! 2006: pushl $1 ! 2007: callf $8,_vdintr ! 2008: incl _cnt+V_INTR ! 2009: POPR ! 2010: REST_FPSTAT ! 2011: rei ! 2012: ! 2013: SCBVEC(vdintr2): ! 2014: CHECK_SFE(4) ! 2015: SAVE_FPSTAT(4) ! 2016: PUSHR ! 2017: incl _fltintrcnt+(4*4) ! 2018: pushl $2 ! 2019: callf $8,_vdintr ! 2020: incl _cnt+V_INTR ! 2021: POPR ! 2022: REST_FPSTAT ! 2023: rei ! 2024: ! 2025: SCBVEC(vackint0): ! 2026: CHECK_SFE(4) ! 2027: SAVE_FPSTAT(4) ! 2028: PUSHR ! 2029: incl _fltintrcnt+(4*5) ! 2030: pushl $0 ! 2031: callf $8,_vackint ! 2032: incl _cnt+V_INTR ! 2033: POPR ! 2034: REST_FPSTAT ! 2035: rei ! 2036: ! 2037: SCBVEC(vcmdrsp0): ! 2038: CHECK_SFE(4) ! 2039: SAVE_FPSTAT(4) ! 2040: PUSHR ! 2041: incl _fltintrcnt+(4*6) ! 2042: pushl $0 ! 2043: callf $8,_vcmdrsp ! 2044: incl _cnt+V_INTR ! 2045: POPR ! 2046: REST_FPSTAT ! 2047: rei ! 2048: ! 2049: SCBVEC(vunsol0): ! 2050: CHECK_SFE(4) ! 2051: SAVE_FPSTAT(4) ! 2052: PUSHR ! 2053: incl _fltintrcnt+(4*7) ! 2054: pushl $0 ! 2055: callf $8,_vunsol ! 2056: incl _cnt+V_INTR ! 2057: POPR ! 2058: REST_FPSTAT ! 2059: rei ! 2060: ! 2061: SCBVEC(vackint1): ! 2062: CHECK_SFE(4) ! 2063: SAVE_FPSTAT(4) ! 2064: PUSHR ! 2065: incl _fltintrcnt+(4*8) ! 2066: pushl $1 ! 2067: callf $8,_vackint ! 2068: incl _cnt+V_INTR ! 2069: POPR ! 2070: REST_FPSTAT ! 2071: rei ! 2072: ! 2073: SCBVEC(vcmdrsp1): ! 2074: CHECK_SFE(4) ! 2075: SAVE_FPSTAT(4) ! 2076: PUSHR ! 2077: incl _fltintrcnt+(4*9) ! 2078: pushl $1 ! 2079: callf $8,_vcmdrsp ! 2080: incl _cnt+V_INTR ! 2081: POPR ! 2082: REST_FPSTAT ! 2083: rei ! 2084: ! 2085: SCBVEC(vunsol1): ! 2086: CHECK_SFE(4) ! 2087: SAVE_FPSTAT(4) ! 2088: PUSHR ! 2089: incl _fltintrcnt+(4*10) ! 2090: pushl $1 ! 2091: callf $8,_vunsol ! 2092: incl _cnt+V_INTR ! 2093: POPR ! 2094: REST_FPSTAT ! 2095: rei ! 2096: ! 2097: SCBVEC(exintr0): ! 2098: CHECK_SFE(4) ! 2099: SAVE_FPSTAT(4) ! 2100: PUSHR ! 2101: incl _fltintrcnt+(4*11) ! 2102: pushl $0 ! 2103: callf $8,_exintr ! 2104: incl _cnt+V_INTR ! 2105: POPR ! 2106: REST_FPSTAT ! 2107: rei ! 2108: ! 2109: ! 2110: .globl _intrnames ! 2111: ! 2112: .globl _eintrnames ! 2113: .data ! 2114: _intrnames: ! 2115: .asciz "clock" ! 2116: .asciz "cnr" ! 2117: .asciz "cnx" ! 2118: .asciz "rmtr" ! 2119: .asciz "rmtx" ! 2120: .asciz "buserr" ! 2121: .asciz "hd0" ! 2122: .asciz "hd1" ! 2123: .asciz "vd0" ! 2124: .asciz "vd1" ! 2125: .asciz "vd2" ! 2126: .asciz "vack0" ! 2127: .asciz "vcmdrsp0" ! 2128: .asciz "vunsol0" ! 2129: .asciz "vack1" ! 2130: .asciz "vcmdrsp1" ! 2131: .asciz "vunsol1" ! 2132: .asciz "ex0" ! 2133: _eintrnames: ! 2134: ! 2135: .globl _intrcnt ! 2136: ! 2137: .globl _eintrcnt ! 2138: .align 2 ! 2139: _intrcnt: ! 2140: .space 4 * 6 ! 2141: _fltintrcnt: ! 2142: .space 4 * 12 ! 2143: _eintrcnt: ! 2144: ! 2145: .text
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.