#ifdef LOCORE #define P_LINK 0 #define P_RLINK 4 #define P_ADDR 8 #define P_PRI 13 #define P_STAT 15 #define P_WCHAN 76 #define SSLEEP 1 #define SRUN 3 #define UBA_BRRVR 48 #define UH_UBA 0 #define UH_VEC 8 #define UH_SIZE 44 #define RP_FLAG 12 #define V_SWTCH 0 #define V_TRAP 4 #define V_SYSCALL 8 #define V_INTR 12 #define V_PDMA 16 #define UPAGES 8 #define CLSIZE 2 #define SYSPTSIZE 1536 #define USRPTSIZE 1024 #define NNETPAGES 256 #else asm(".set U_ARG,120"); asm(".set U_QSAV,140"); #endif /* scb.s 4.9 81/05/13 */ /* * System control block */ .set INTSTK,1 # handle this interrupt on the interrupt stack .set HALT,3 # halt if this interrupt occurs _scb: .globl _scb #define STRAY .long _Xstray+INTSTK #define STRAY8 STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY #define STRAY15 STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY;STRAY8 #define KS(a) .long _X/**/a #define IS(a) .long _X/**/a+INTSTK #define STOP(a) .long _X/**/a+HALT /* 000 */ STRAY; IS(machcheck); IS(kspnotval); STOP(powfail); /* 010 */ KS(privinflt); KS(xfcflt); KS(resopflt); KS(resadflt); /* 020 */ KS(protflt); KS(transflt); KS(tracep); KS(bptflt); /* 030 */ KS(compatflt); KS(arithtrap); STRAY; STRAY; /* 040 */ KS(syscall); KS(chme); KS(chms); KS(chmu); /* 050 */ STRAY; IS(cmrd); STRAY; STRAY; /* 060 */ IS(wtime); STRAY; STRAY; STRAY; /* 070 */ STRAY; STRAY; STRAY; STRAY; /* 080 */ STRAY; STRAY; KS(astflt); STRAY; /* 090 */ STRAY; STRAY; STRAY; STRAY; /* 0a0 */ IS(softclock); STRAY; STRAY; STRAY; /* 0b0 */ STRAY; STRAY; STRAY; STRAY; /* 0c0 */ IS(hardclock); STRAY; STRAY; STRAY; /* 0d0 */ STRAY; STRAY; STRAY; STRAY; /* 0e0 */ STRAY; STRAY; STRAY; STRAY; /* 0f0 */ IS(consdin); IS(consdout); IS(cnrint); IS(cnxint); /* 100 */ IS(nexzvec); STRAY15; /* ipl 0x14, nexus 0-15 */ /* 140 */ IS(nexzvec); STRAY15; /* ipl 0x15, nexus 0-15 */ /* 180 */ IS(nexzvec); STRAY15; /* ipl 0x16, nexus 0-15 */ /* 1c0 */ IS(nexzvec); STRAY15; /* ipl 0x17, nexus 0-15 */ .globl _UNIvec _UNIvec: .space 512 # 750 unibus intr vector # 1st UBA jump table on 780's /* locore.s 4.50 81/05/18 */ #include "../h/mtpr.h" #include "../h/trap.h" #include "../h/psl.h" #include "../h/pte.h" #include "../h/cpu.h" #include "../h/nexus.h" #include "../h/ubareg.h" #include "dz.h" #include "mba.h" .set HIGH,0x1f # mask for total disable .set MCKVEC,4 # offset into scb of machine check vector .set NBPG,512 .set PGSHIFT,9 .set NISP,3 # number of interrupt stack pages /* * User structure is UPAGES at top of user space. */ .globl _u .set _u,0x80000000 - UPAGES*NBPG /* * Restart parameter block * This is filled in in machdep.c in startup(). * It MUST be page aligned. * When auto-restart occurs, we run restart() in machdep.c, which * takes a core-dump and then cold-starts. */ .globl _rpb _rpb: .space 508 erpb: .space 4 .globl _intstack _intstack: .space NISP*NBPG eintstack: /* * Do a dump. * Called by auto-restart. * May be called manually. */ .align 2 .globl _doadump _doadump: nop; nop # .word 0x0101 #define _rpbmap _Sysmap+8 # scb, UNIvec, rpb, istack*4 bicl2 $PG_PROT,_rpbmap bisl2 $PG_KW,_rpbmap tstl _rpb+RP_FLAG # dump only once! bneq 1f incl _rpb+RP_FLAG mtpr $0,$TBIA movl sp,erpb movab erpb,sp mfpr $PCBB,-(sp) mfpr $MAPEN,-(sp) mfpr $IPL,-(sp) mtpr $0,$MAPEN mtpr $HIGH,$IPL pushr $0x3fff calls $0,_dumpsys 1: halt /* * Interrupt vector routines */ .globl _waittime #define SCBVEC(name) .align 2; .globl _X/**/name; _X/**/name #define PANIC(msg) clrl _waittime; pushab 1f; \ calls $1,_panic; 1: .asciz msg #define PRINTF(n,msg) pushab 1f; calls $n+1,_printf; MSG(msg) #define MSG(msg) .data; 1: .asciz msg; .text #define PUSHR pushr $0x3f #define POPR popr $0x3f SCBVEC(machcheck): PUSHR; pushab 6*4(sp); calls $1,_machinecheck; POPR; addl2 (sp)+,sp; rei SCBVEC(kspnotval): PUSHR; PANIC("KSP not valid"); SCBVEC(powfail): halt SCBVEC(chme): SCBVEC(chms): SCBVEC(chmu): PUSHR; PANIC("CHM? in kernel"); SCBVEC(stray): PUSHR; PRINTF(0, "stray scb interrupt\n"); POPR; rei SCBVEC(nexzvec): PUSHR; mfpr $IPL,-(sp); PRINTF(1, "nexus stray intr ipl%x\n"); POPR; rei SCBVEC(cmrd): PUSHR; calls $0,_memerr; POPR; rei SCBVEC(wtime): PUSHR; pushl 6*4(sp); PRINTF(1,"write timeout %x\n"); POPR; PANIC("wtimo"); #if NMBA > 0 SCBVEC(mba3int): PUSHR; pushl $3; brb 1f SCBVEC(mba2int): PUSHR; pushl $2; brb 1f SCBVEC(mba1int): PUSHR; pushl $1; brb 1f SCBVEC(mba0int): PUSHR; pushl $0 1: calls $1,_mbintr POPR incl _cnt+V_INTR rei #endif #if VAX780 /* * Registers for the uba handling code */ #define rUBANUM r0 #define rUBAHD r1 #define rUVEC r3 #define rUBA r4 /* r2,r5 are scratch */ SCBVEC(ua3int): PUSHR; movl $3,rUBANUM; moval _uba_hd+(3*UH_SIZE),rUBAHD; brb 1f SCBVEC(ua2int): PUSHR; movl $2,rUBANUM; moval _uba_hd+(2*UH_SIZE),rUBAHD; brb 1f SCBVEC(ua1int): PUSHR; movl $1,rUBANUM; moval _uba_hd+(1*UH_SIZE),rUBAHD; brb 1f SCBVEC(ua0int): PUSHR; movl $0,rUBANUM; moval _uba_hd+(0*UH_SIZE),rUBAHD; 1: incl _cnt+V_INTR mfpr $IPL,r2 /* r2 = mfpr(IPL); */ movl UH_UBA(rUBAHD),rUBA /* uba = uhp->uh_uba; */ movl UBA_BRRVR-0x14*4(rUBA)[r2],rUVEC /* uvec = uba->uba_brrvr[r2-0x14] */ ubanorm: bleq ubaerror addl2 UH_VEC(rUBAHD),rUVEC /* uvec += uh->uh_vec */ bicl3 $3,(rUVEC),r1 jmp 2(r1) /* 2 skips ``pushr $0x3f'' */ ubaerror: PUSHR; calls $0,_ubaerror; POPR /* ubaerror r/w's r0-r5 */ tstl rUVEC; jneq ubanorm /* rUVEC contains result */ POPR rei #endif SCBVEC(cnrint): PUSHR; calls $0,_cnrint; POPR; incl _cnt+V_INTR; rei SCBVEC(cnxint): PUSHR; calls $0,_cnxint; POPR; incl _cnt+V_INTR; rei SCBVEC(hardclock): PUSHR pushl 4+6*4(sp); pushl 4+6*4(sp); calls $2,_hardclock # hardclock(pc,psl) POPR; incl _cnt+V_INTR ## temp so not to break vmstat -= HZ rei SCBVEC(softclock): PUSHR pushl 4+6*4(sp); pushl 4+6*4(sp); calls $2,_softclock # softclock(pc,psl) POPR; rei SCBVEC(consdin): halt SCBVEC(consdout): halt #if NDZ > 0 /* * DZ pseudo dma routine: * r0 - controller number */ .align 1 .globl _dzdma _dzdma: mull2 $8*20,r0 movab _dzpdma(r0),r3 # pdma structure base # for this controller dzploop: movl r3,r0 movl (r0)+,r1 # device register address movzbl 1(r1),r2 # get line number bitb $0x80,r2 # TRDY on? beql dzprei # no bicb2 $0xf8,r2 # clear garbage bits mull2 $20,r2 addl2 r2,r0 # point at line's pdma structure movl (r0)+,r2 # p_mem cmpl r2,(r0)+ # p_mem < p_end ? bgequ dzpcall # no, go call dzxint movb (r2)+,6(r1) # dztbuf = *p_mem++ movl r2,-8(r0) brb dzploop # check for another line dzprei: POPR incl _cnt+V_PDMA rei dzpcall: pushl r3 pushl (r0)+ # push tty address calls $1,*(r0) # call interrupt rtn movl (sp)+,r3 brb dzploop # check for another line #endif /* * Stray UNIBUS interrupt catch routines */ .data .align 2 #define PJ PUSHR;jsb _Xustray .globl _catcher _catcher: PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ;PJ .globl _cold _cold: .long 1 .data .text SCBVEC(ustray): blbc _cold,1f mfpr $IPL,r11 subl3 $_catcher+8,(sp)+,r10 ashl $-1,r10,r10 POPR rei 1: subl3 $_catcher+8,(sp)+,r0 ashl $-1,r0,-(sp) mfpr $IPL,-(sp) PRINTF(2, "uba?: stray intr ipl %x vec %o\n") POPR rei /* * Trap and fault vector routines */ #define TRAP(a) pushl $a; brw alltraps /* * Ast delivery (profiling and/or reschedule) */ SCBVEC(astflt): pushl $0; TRAP(ASTFLT) SCBVEC(privinflt): pushl $0; TRAP(PRIVINFLT) SCBVEC(xfcflt): pushl $0; TRAP(XFCFLT) SCBVEC(resopflt): pushl $0; TRAP(RESOPFLT) SCBVEC(resadflt): pushl $0; TRAP(RESADFLT) SCBVEC(bptflt): pushl $0; TRAP(BPTFLT) SCBVEC(compatflt): TRAP(COMPATFLT); SCBVEC(tracep): pushl $0; TRAP(TRCTRAP) SCBVEC(arithtrap): TRAP(ARITHTRAP) SCBVEC(protflt): blbs (sp)+,segflt TRAP(PROTFLT) segflt: TRAP(SEGFLT) SCBVEC(transflt): bitl $1,(sp)+ bnequ tableflt TRAP(PAGEFLT) tableflt: TRAP(TABLEFLT) alltraps: mfpr $USP,-(sp); calls $0,_trap; mtpr (sp)+,$USP incl _cnt+V_TRAP addl2 $8,sp # pop type, code mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT) rei SCBVEC(syscall): pushl $SYSCALL mfpr $USP,-(sp); calls $0,_syscall; mtpr (sp)+,$USP incl _cnt+V_SYSCALL addl2 $8,sp # pop type, code mtpr $HIGH,$IPL ## dont go to a higher IPL (GROT) rei /* * System page table */ #define vaddr(x) ((((x)-_Sysmap)/4)*NBPG+0x80000000) #define SYSMAP(mname, vname, npte) \ _/**/mname: .globl _/**/mname; \ .space npte*4; \ .globl _/**/vname; \ .set _/**/vname,vaddr(_/**/mname) .data .align 2 SYSMAP(Sysmap ,Sysbase ,SYSPTSIZE ) SYSMAP(UMBAbeg ,umbabeg ,0 ) SYSMAP(Nexmap ,nexus ,16*MAXNNEXUS ) SYSMAP(UMEMmap ,umem ,16*MAXNUBA ) SYSMAP(UMBAend ,umbaend ,0 ) SYSMAP(Usrptmap ,usrpt ,USRPTSIZE ) SYSMAP(Forkmap ,forkutl ,UPAGES ) SYSMAP(Xswapmap ,xswaputl ,UPAGES ) SYSMAP(Xswap2map,xswap2utl ,UPAGES ) SYSMAP(Swapmap ,swaputl ,UPAGES ) SYSMAP(Pushmap ,pushutl ,UPAGES ) SYSMAP(Vfmap ,vfutl ,UPAGES ) SYSMAP(CMAP1 ,CADDR1 ,1 ) SYSMAP(CMAP2 ,CADDR2 ,1 ) SYSMAP(mcrmap ,mcr ,1 ) SYSMAP(mmap ,vmmap ,1 ) SYSMAP(msgbufmap,msgbuf ,CLSIZE ) SYSMAP(camap ,cabase ,16*CLSIZE ) SYSMAP(ecamap ,calimit ,0 ) #ifdef BBNNET SYSMAP(Netmap ,netutl ,NNETPAGES*CLSIZE) #endif eSysmap: .globl _Syssize .set _Syssize,(eSysmap-_Sysmap)/4 .text /* * Initialization * * ipl 0x1f; mapen 0; scbb, pcbb, sbr, slr, isp, ksp not set */ .data .globl _cpu _cpu: .long 0 .text .globl start start: .word 0 /* set system control block base and system page table params */ mtpr $_scb-0x80000000,$SCBB mtpr $_Sysmap-0x80000000,$SBR mtpr $_Syssize,$SLR /* double map the kernel into the virtual user addresses of phys mem */ mtpr $_Sysmap,$P0BR mtpr $_Syssize,$P0LR /* set ISP and get cpu type */ movl $_intstack+NISP*NBPG,sp mfpr $SID,r0 movab _cpu,r1 extzv $24,$8,r0,(r1) /* init RPB */ movab _rpb,r0 movl r0,(r0)+ # rp_selfref movab _doadump,r1 movl r1,(r0)+ # rp_dumprout movl $0x1f,r2 clrl r3 1: addl2 (r1)+,r3; sobgtr r2,1b movl r3,(r0)+ # rp_chksum /* count up memory */ clrl r7 1: pushl $4; pushl r7; calls $2,_badaddr; tstl r0; bneq 9f acbl $8096*1024-1,$64*1024,r7,1b 9: /* clear memory from kernel bss and pages for proc 0 u. and page table */ movab _edata,r6 movab _end,r5 bbcc $31,r5,0f; 0: addl2 $(UPAGES*NBPG)+NBPG+NBPG,r5 1: clrq (r6); acbl r5,$8,r6,1b /* trap() and syscall() save r0-r11 in the entry mask (per ../h/reg.h) */ bisw2 $0x0fff,_trap bisw2 $0x0fff,_syscall calls $0,_fixctlrmask /* initialize system page table: scb and int stack writeable */ clrl r2 movab eintstack,r1; bbcc $31,r1,0f; 0: ashl $-PGSHIFT,r1,r1 1: bisl3 $PG_V|PG_KW,r2,_Sysmap[r2]; aoblss r1,r2,1b /* make rpb read-only as red zone for interrupt stack */ bicl2 $PG_PROT,_rpbmap bisl2 $PG_KR,_rpbmap /* make kernel text space read-only */ movab _etext+NBPG-1,r1; bbcc $31,r1,0f; 0: ashl $-PGSHIFT,r1,r1 1: bisl3 $PG_V|PG_KR,r2,_Sysmap[r2]; aoblss r1,r2,1b /* make kernel data, bss, read-write */ movab _end+NBPG-1,r1; bbcc $31,r1,0f; 0:; ashl $-PGSHIFT,r1,r1 1: bisl3 $PG_V|PG_KW,r2,_Sysmap[r2]; aoblss r1,r2,1b /* now go to mapped mode */ mtpr $1,$TBIA; mtpr $1,$MAPEN; jmp *$0f; 0: /* init mem sizes */ ashl $-PGSHIFT,r7,_maxmem movl _maxmem,_physmem movl _maxmem,_freemem /* setup context for proc[0] == Scheduler */ movab _end+NBPG-1,r6 bicl2 $NBPG-1,r6 # make page boundary /* setup page table for proc[0] */ bbcc $31,r6,0f; 0: ashl $-PGSHIFT,r6,r3 # r3 = btoc(r6) bisl3 $PG_V|PG_KW,r3,_Usrptmap # init first upt entry incl r3 movab _usrpt,r0 mtpr r0,$TBIS /* init p0br, p0lr */ mtpr r0,$P0BR mtpr $0,$P0LR /* init p1br, p1lr */ movab NBPG(r0),r0 movl $0x200000-UPAGES,r1 mtpr r1,$P1LR mnegl r1,r1 moval -4*UPAGES(r0)[r1],r2 mtpr r2,$P1BR /* setup mapping for UPAGES of _u */ movl $UPAGES,r2; movab _u+NBPG*UPAGES,r1; addl2 $UPAGES,r3; jbr 2f 1: decl r3 moval -NBPG(r1),r1; bisl3 $PG_V|PG_URKW,r3,-(r0) mtpr r1,$TBIS 2: sobgeq r2,1b /* initialize (slightly) the pcb */ movab UPAGES*NBPG(r1),PCB_KSP(r1) mnegl $1,PCB_ESP(r1) mnegl $1,PCB_SSP(r1) movl r1,PCB_USP(r1) mfpr $P0BR,PCB_P0BR(r1) mfpr $P0LR,PCB_P0LR(r1) movb $4,PCB_P0LR+3(r1) # disable ast mfpr $P1BR,PCB_P1BR(r1) mfpr $P1LR,PCB_P1LR(r1) movl $CLSIZE,PCB_SZPT(r1) # init u.u_pcb.pcb_szpt movl r11,PCB_R11(r1) movab 1f,PCB_PC(r1) # initial pc clrl PCB_PSL(r1) # mode(k,k), ipl=0 ashl $PGSHIFT,r3,r3 mtpr r3,$PCBB # first pcbb /* set regs, p0br, p0lr, p1br, p1lr, astlvl, ksp and change to kernel mode */ ldpctx rei /* put signal trampoline code in u. area */ 1: movab _u,r0 movc3 $12,sigcode,PCB_SIGC(r0) /* save reboot flags in global _boothowto */ movl r11,_boothowto /* calculate firstaddr, and call main() */ movab _end+NBPG-1,r0; bbcc $31,r0,0f; 0:; ashl $-PGSHIFT,r0,-(sp) addl2 $UPAGES+1,(sp); calls $1,_main /* proc[1] == /etc/init now running here; run icode */ pushl $PSL_CURMOD|PSL_PRVMOD; pushl $0; rei /* signal trampoline code: it is known that this code takes exactly 12 bytes */ /* in ../h/pcb.h and in the movc3 above */ sigcode: calls $3,1(pc) rei .word 0x7f # registers 0-6 (6==sp/compat) callg (ap),*12(ap) ret /* * Primitives */ /* * badaddr(addr, len) * see if access addr with a len type instruction causes a machine check * len is length of access (1=byte, 2=short, 4=long) */ .globl _badaddr _badaddr: .word 0 movl $1,r0 mfpr $IPL,r1 mtpr $HIGH,$IPL movl _scb+MCKVEC,r2 movl 4(ap),r3 movl 8(ap),r4 movab 9f+INTSTK,_scb+MCKVEC bbc $0,r4,1f; tstb (r3) 1: bbc $1,r4,1f; tstw (r3) 1: bbc $2,r4,1f; tstl (r3) 1: clrl r0 # made it w/o machine checks 2: movl r2,_scb+MCKVEC mtpr r1,$IPL ret .align 2 9: casel _cpu,$1,$VAX_MAX 0: .word 8f-0b # 1 is 780 .word 5f-0b # 2 is 750 .word 5f-0b # 3 is 7ZZ 5: #if defined(VAX750) || defined(VAX7ZZ) mtpr $0xf,$MCESR #endif brb 1f 8: #if VAX780 mtpr $0,$SBIFS #endif 1: addl2 (sp)+,sp # discard mchchk trash movab 2b,(sp) rei _addupc: .globl _addupc .word 0x0 movl 8(ap),r2 # &u.u_prof subl3 8(r2),4(ap),r0 # corrected pc blss 9f extzv $1,$31,r0,r0 # logical right shift extzv $1,$31,12(r2),r1 # ditto for scale emul r1,r0,$0,r0 ashq $-14,r0,r0 tstl r1 bneq 9f incl r0 bicl2 $1,r0 cmpl r0,4(r2) # length bgequ 9f addl2 (r2),r0 # base probew $3,$2,(r0) beql 8f addw2 12(ap),(r0) 9: ret 8: clrl 12(r2) ret _Copyin: .globl _Copyin # <<<massaged for jsb by asm.sed>>> movl 12(sp),r0 # copy length blss ersb movl 4(sp),r1 # copy user address cmpl $NBPG,r0 # probing one page or less ? bgeq cishort # yes ciloop: prober $3,$NBPG,(r1) # bytes accessible ? beql ersb # no addl2 $NBPG,r1 # incr user address ptr acbl $NBPG+1,$-NBPG,r0,ciloop # reduce count and loop cishort: prober $3,r0,(r1) # bytes accessible ? beql ersb # no movc3 12(sp),*4(sp),*8(sp) clrl r0 rsb ersb: mnegl $1,r0 rsb _Copyout: .globl _Copyout # <<<massaged for jsb by asm.sed >>> movl 12(sp),r0 # get count blss ersb movl 8(sp),r1 # get user address cmpl $NBPG,r0 # can do in one probew? bgeq coshort # yes coloop: probew $3,$NBPG,(r1) # bytes accessible? beql ersb # no addl2 $NBPG,r1 # increment user address acbl $NBPG+1,$-NBPG,r0,coloop # reduce count and loop coshort: probew $3,r0,(r1) # bytes accessible? beql ersb # no movc3 12(sp),*4(sp),*8(sp) clrl r0 rsb /* * non-local goto's */ .globl _Setjmp _Setjmp: movq r6,(r0)+ movq r8,(r0)+ movq r10,(r0)+ movq r12,(r0)+ addl3 $4,sp,(r0)+ movl (sp),(r0) clrl r0 rsb .globl _Longjmp _Longjmp: movq (r0)+,r6 movq (r0)+,r8 movq (r0)+,r10 movq (r0)+,r12 movl (r0)+,r1 cmpl r1,sp # must be a pop bgequ lj2 pushab lj1 calls $1,_panic lj2: movl r1,sp jmp *(r0) # ``rsb'' lj1: .asciz "longjmp" .globl _whichqs .globl _qs .globl _cnt .globl _noproc .comm _noproc,4 .globl _runrun .comm _runrun,4 /* * The following primitives use the fancy VAX instructions * much like VMS does. _whichqs tells which of the 32 queues _qs * have processes in them. Setrq puts processes into queues, Remrq * removes them from queues. The running process is on no queue, * other processes are on a queue related to p->p_pri, divided by 4 * actually to shrink the 0-127 range of priorities into the 32 available * queues. */ /* * Setrq(p), using fancy VAX instructions. * * Call should be made at spl6(), and p->p_stat should be SRUN */ .globl _Setrq # <<<massaged to jsb by "asm.sed">>> _Setrq: tstl P_RLINK(r0) ## firewall: p->p_rlink must be 0 beql set1 ## pushab set3 ## calls $1,_panic ## set1: movzbl P_PRI(r0),r1 # put on queue which is p->p_pri / 4 ashl $-2,r1,r1 movaq _qs[r1],r2 insque (r0),*4(r2) # at end of queue bbss r1,_whichqs,set2 # mark queue non-empty set2: rsb set3: .asciz "setrq" /* * Remrq(p), using fancy VAX instructions * * Call should be made at spl6(). */ .globl _Remrq # <<<massaged to jsb by "asm.sed">>> _Remrq: movzbl P_PRI(r0),r1 ashl $-2,r1,r1 bbsc r1,_whichqs,rem1 pushab rem3 # it wasn't recorded to be on its q calls $1,_panic rem1: remque (r0),r2 beql rem2 bbss r1,_whichqs,rem2 rem2: clrl P_RLINK(r0) ## for firewall checking rsb rem3: .asciz "remrq" /* * Masterpaddr is the p->p_addr of the running process on the master * processor. When a multiprocessor system, the slave processors will have * an array of slavepaddr's. */ .globl _masterpaddr .data _masterpaddr: .long 0 .text sw0: .asciz "swtch" /* * Swtch(), using fancy VAX instructions */ .globl _Swtch _Swtch: # <<<massaged to jsb by "asm.sed">>> movl $1,_noproc clrl _runrun sw1: ffs $0,$32,_whichqs,r0 # look for non-empty queue bneq sw1a mtpr $0,$IPL # must allow interrupts here brw sw1 # this is an idle loop! sw1a: mtpr $0x18,$IPL # lock out all so _whichqs==_qs bbcc r0,_whichqs,sw1 # proc moved via lbolt interrupt movaq _qs[r0],r1 remque *(r1),r2 # r2 = p = highest pri process bvc sw2 # make sure something was there sw1b: pushab sw0 calls $1,_panic sw2: beql sw3 insv $1,r0,$1,_whichqs # still more procs in this queue sw3: clrl _noproc tstl P_WCHAN(r2) ## firewalls bneq sw1b ## movzbl P_STAT(r2),r3 ## cmpl $SRUN,r3 ## bneq sw1b ## clrl P_RLINK(r2) ## movl *P_ADDR(r2),r0 movl r0,_masterpaddr ashl $PGSHIFT,r0,r0 # r0 = pcbb(p) /* mfpr $PCBB,r1 # resume of current proc is easy * cmpl r0,r1 */ beql res0 incl _cnt+V_SWTCH /* fall into... */ /* * Resume(pf) */ .globl _Resume # <<<massaged to jsb by "asm.sed">>> _Resume: mtpr $0x18,$IPL # no interrupts, please movl _CMAP2,_u+PCB_CMAP2 # yech svpctx mtpr r0,$PCBB ldpctx movl _u+PCB_CMAP2,_CMAP2 # yech res0: tstl _u+PCB_SSWAP beql res1 movl _u+PCB_SSWAP,r0 clrl _u+PCB_SSWAP movab _Longjmp,(sp) movl $PSL_PRVMOD,4(sp) # ``cheating'' (jfr) res1: rei /* * {fu,su},{byte,word}, all massaged by asm.sed to jsb's */ .globl _Fuword _Fuword: prober $3,$4,(r0) beql fserr movl (r0),r0 rsb fserr: mnegl $1,r0 rsb .globl _Fubyte _Fubyte: prober $3,$1,(r0) beql fserr movzbl (r0),r0 rsb .globl _Suword _Suword: probew $3,$4,(r0) beql fserr movl r1,(r0) clrl r0 rsb .globl _Subyte _Subyte: probew $3,$1,(r0) beql fserr movb r1,(r0) clrl r0 rsb /* * Copy 1 relocation unit (NBPG bytes) * from user virtual address to physical address */ _copyseg: .globl _copyseg .word 0x0 bisl3 $PG_V|PG_KW,8(ap),_CMAP2 mtpr $_CADDR2,$TBIS # invalidate entry for copy movc3 $NBPG,*4(ap),_CADDR2 ret /* * zero out physical memory * specified in relocation units (NBPG bytes) */ _clearseg: .globl _clearseg .word 0x0 bisl3 $PG_V|PG_KW,4(ap),_CMAP1 mtpr $_CADDR1,$TBIS movc5 $0,(sp),$0,$NBPG,_CADDR1 ret /* * Check address. * Given virtual address, byte count, and rw flag * returns 0 on no access. */ _useracc: .globl _useracc .word 0x0 movl 4(ap),r0 # get va movl 8(ap),r1 # count tstl 12(ap) # test for read access ? bneq userar # yes cmpl $NBPG,r1 # can we do it in one probe ? bgeq uaw2 # yes uaw1: probew $3,$NBPG,(r0) beql uaerr # no access addl2 $NBPG,r0 acbl $NBPG+1,$-NBPG,r1,uaw1 uaw2: probew $3,r1,(r0) beql uaerr movl $1,r0 ret userar: cmpl $NBPG,r1 bgeq uar2 uar1: prober $3,$NBPG,(r0) beql uaerr addl2 $NBPG,r0 acbl $NBPG+1,$-NBPG,r1,uar1 uar2: prober $3,r1,(r0) beql uaerr movl $1,r0 ret uaerr: clrl r0 ret /* * kernacc - check for kernel access privileges * * We can't use the probe instruction directly because * it ors together current and previous mode. */ .globl _kernacc _kernacc: .word 0x0 movl 4(ap),r0 # virtual address bbcc $31,r0,kacc1 bbs $30,r0,kacerr mfpr $SBR,r2 # address and length of page table (system) bbss $31,r2,0f; 0: mfpr $SLR,r3 brb kacc2 kacc1: bbsc $30,r0,kacc3 mfpr $P0BR,r2 # user P0 mfpr $P0LR,r3 brb kacc2 kacc3: mfpr $P1BR,r2 # user P1 (stack) mfpr $P1LR,r3 kacc2: addl3 8(ap),r0,r1 # ending virtual address addl2 $NBPG-1,r1 ashl $-PGSHIFT,r0,r0 ashl $-PGSHIFT,r1,r1 bbs $31,4(ap),kacc6 bbc $30,4(ap),kacc6 cmpl r0,r3 # user stack blss kacerr # address too low brb kacc4 kacc6: cmpl r1,r3 # compare last page to P0LR or SLR bgtr kacerr # address too high kacc4: movl (r2)[r0],r3 bbc $31,4(ap),kacc4a bbc $31,r3,kacerr # valid bit is off kacc4a: cmpzv $27,$4,r3,$1 # check protection code bleq kacerr # no access allowed tstb 12(ap) bneq kacc5 # only check read access cmpzv $27,$2,r3,$3 # check low 2 bits of prot code beql kacerr # no write access kacc5: aoblss r1,r0,kacc4 # next page movl $1,r0 # no errors ret kacerr: clrl r0 # error ret .globl _Xdhrint0 .align 2 _Xdhrint0: pushr $0x3f pushl $0 calls $1,_dhrint popr $0x3f rei .globl _Xdhxint0 .align 2 _Xdhxint0: pushr $0x3f pushl $0 calls $1,_dhxint popr $0x3f rei .globl _Xdzrint0 .align 2 _Xdzrint0: pushr $0x3f pushl $0 calls $1,_dzrint popr $0x3f rei .globl _Xdzxint0 .align 2 _Xdzxint0: pushr $0x3f movl $0,r0 jbr _dzdma .globl _Xdzrint1 .align 2 _Xdzrint1: pushr $0x3f pushl $1 calls $1,_dzrint popr $0x3f rei .globl _Xdzxint1 .align 2 _Xdzxint1: pushr $0x3f movl $1,r0 jbr _dzdma .globl _Xdzrint2 .align 2 _Xdzrint2: pushr $0x3f pushl $2 calls $1,_dzrint popr $0x3f rei .globl _Xdzxint2 .align 2 _Xdzxint2: pushr $0x3f movl $2,r0 jbr _dzdma .globl _Xacc_iint0 .align 2 _Xacc_iint0: pushr $0x3f pushl $0 calls $1,_acc_iint popr $0x3f rei .globl _Xacc_oint0 .align 2 _Xacc_oint0: pushr $0x3f pushl $0 calls $1,_acc_oint popr $0x3f rei .globl _Xacc_iint1 .align 2 _Xacc_iint1: pushr $0x3f pushl $1 calls $1,_acc_iint popr $0x3f rei .globl _Xacc_oint1 .align 2 _Xacc_oint1: pushr $0x3f pushl $1 calls $1,_acc_oint popr $0x3f rei