⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locore.s

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 S
📖 第 1 页 / 共 5 页
字号:
	.set reorder	END(clear_bev)/* * setsoftnet() - make software network interrupt request */EXPORT(setsoftnet)	li	a0, CAUSE_SW2	j	siron/* * acksoftnet() - acknowledge software network interrupt */EXPORT(acksoftnet)	li	a0, CAUSE_SW2	j	siroff/* * setsoftclock() - make software clock interrupt request */EXPORT(setsoftclock)	li	a0, CAUSE_SW1	j	siron/* * acksoftclock() - acknowledge software clock interrupt */EXPORT(acksoftclock)	li	a0, CAUSE_SW1	j	siroff/* * siron(level) -- make software interrupt request */LEAF(siron)	.set	noreorder	mfc0	v0,C0_SR	mtc0	zero,C0_SR		# disable all interrupts	mfc0	v1,C0_CAUSE	nop	or	v1,a0	mtc0	v1,C0_CAUSE	mtc0	v0,C0_SR		# PE BIT	j	ra		nop	.set	reorder	END(siron)/* * siroff(level) -- acknowledge software interrupt request */LEAF(siroff)	.set	noreorder	mfc0	v0,C0_SR	mtc0	zero,C0_SR		# disable all interrupts	mfc0	v1,C0_CAUSE	not	a0	and	v1,a0	mtc0	v1,C0_CAUSE	mtc0	v0,C0_SR		# PE BIT	j	ra	nop	.set	reorder	END(siroff)/* * bbadaddr(addr, len) *	check for bus error on read access to addr *	len is length of access (1=byte, 2=short, 4=long) */BADADDRFRM=	(4*4)+4		# 4 arg saves plus a raNESTED(bbadaddr, BADADDRFRM, zero)	.set noreorder	nop	mfc0	t0,C0_SR	nop	mtc0	zero,C0_SR	nop	.set reorder	subu	sp,BADADDRFRM	sw	ra,BADADDRFRM-4(sp)#ifdef ASSERTIONS	lw	v0,u+PCB_CPUPTR	lw	v0,CPU_NOFAULT(v0)	beq	v0,zero,8f	PANIC("recursive nofault")8:#endif ASSERTIONS	.set	noreorder	lw	t1,u+PCB_CPUPTR	li	v0,NF_BADADDR	bne	a1,1,1f	sw	v0,CPU_NOFAULT(t1)	lb	v0,0(a0)	b	4f	nop1:	bne	a1,2,2f	nop	lh	v0,0(a0)	b	4f	nop2:	bne	a1,4,3f	nop	lw	v0,0(a0)	b	4f	nop	.set	reorder3:	PANIC("bbaddaddr")	.set	noreorder4:	lw	t1,u+PCB_CPUPTR	nop	sw	zero,CPU_NOFAULT(t1)	lw	ra,BADADDRFRM-4(sp)	addu	sp,BADADDRFRM	mtc0	t0,C0_SR		# PE BIT	move	v0,zero	j	ra	nop	.set	reorder	END(bbadaddr)/* * wbadaddr(addr, len) *	check for bus error on write access to addr *	len is length of access (1=byte, 2=short, 4=long) */NESTED(wbadaddr, BADADDRFRM, zero)	subu	sp,BADADDRFRM	sw	ra,BADADDRFRM-4(sp)	.set noreorder	nop	mfc0	t0,C0_SR	nop	mtc0	zero,C0_SR	nop	.set reorder#ifndef SABLE	lw	zero,SBE_ADDR|K1BASE#endif#ifdef ASSERTIONS	lw	v0,u+PCB_CPUPTR	lw	v0,CPU_NOFAULT(v0)	beq	v0,zero,8f	PANIC("recursive nofault")8:#endif ASSERTIONS	.set	noreorder	bne	a1,1,1f	lw	t1,u+PCB_CPUPTR	li	v0,NF_BADADDR		#LDSLOT	sw	v0,CPU_NOFAULT(t1)	sb	zero,0(a0)	b	4f	nop1:	bne	a1,2,2f	nop	b	4f	sh	zero,0(a0)2:	bne	a1,4,3f	nop	b	4f	sw	zero,0(a0)	.set	reorder3:	PANIC("wbaddaddr")	.set	noreorder4:	bc0f	4b			# wait for write buffer empty	nop	lw	v0,K1BASE	mfc0	t1,C0_CAUSE	nop	and	t1,CAUSE_IP7		# Memory line error	bne	t1,zero,baerror	nop	lw	t1,u+PCB_CPUPTR	nop	sw	zero,CPU_NOFAULT(t1)	mtc0	t0,C0_SR		# PE BIT	lw	ra,BADADDRFRM-4(sp)	addu	sp,BADADDRFRM	j	ra	move	v0,zero	.set	reorder	END(wbadaddr)/* * wbadmemaddr(addr) *	check for address error on word access to addr *	Assumes addr points to RAM since trap is generated by read-back */ NESTED(wbadmemaddr, BADADDRFRM, zero)	.set noreorder	nop	mfc0	t0,C0_SR	nop	mtc0	zero,C0_SR	nop	.set reorder 	subu	sp,BADADDRFRM 	sw	ra,BADADDRFRM-4(sp)#ifdef ASSERTIONS	lw	v0,u+PCB_CPUPTR	lw	v0,CPU_NOFAULT(v0)	beq	v0,zero,8f	PANIC("recursive nofault")8:#endif ASSERTIONS 	.set	noreorder	lw	t1,u+PCB_CPUPTR 	li	v0,NF_BADADDR		# LDSLOT	sw	v0,CPU_NOFAULT(t1) 	sw	zero,0(a0)		# store first to generate ECC 	lw	v0,0(a0)		# load can cause sync DBE	sw	zero,CPU_NOFAULT(t1) 	lw	ra,BADADDRFRM-4(sp) 	addu	sp,BADADDRFRM	mtc0	t0,C0_SR		# PE BIT 	j	ra 	move	v0,zero 	.set	reorder	END(wbadmemaddr)/* * trap() nofault code comes here on bus errors when nofault == NF_BADADDR */NESTED(baerror, BADADDRFRM, zero)#ifndef SABLE	lw	v0, cpu			# get cpu	bne	v0, DS_3100, 1f		# only PMAX has SBE	lw	zero,SBE_ADDR|K1BASE1:#endif	.set noreorder	nop	mtc0	t0,C0_SR		# PE BIT	nop	.set reorder	li	v0,1	lw	ra,BADADDRFRM-4(sp)	addu	sp,BADADDRFRM	j	ra	END(baerror)/* * ffs(word) * BEWARE: that C version of this routine that is distributed with 4.2 * is incorrect! * * find first bit set in word (a la VAX instruction) * looks at low order bits first, lowest order bit is 1, highest bit is 32 * no bits returns 0 */LEAF(ffs)	.set	noreorder	move	v0,zero	beq	a0,zero,2f		# no bits set, return zero1:	and	v1,a0,1	addu	v0,1	beq	v1,zero,1b	srl	a0,1			# BDSLOT: shift right to next bit2:	j	ra	nop	.set	reorder	END(ffs)#ifdef notdefLEAF(ffs)	move	v1,zero			# initial table offset	and	v0,a0,0xffff		# check lower halfword	bne	v0,zero,1f		# bits in lower halfword	addu	v1,64			# table offset for halfword	srl	a0,16			# check upper halfword1:	and	v0,a0,0xff		# check lower byte of halfword	bne	v0,zero,2f		# bits in lower byte	addu	v1,32			# table offset for byte	srl	a0,8			# check upper byte of halfword2:	and	v0,a0,0xf		# check lower nibble	bne	v0,zero,3f		# bits in lower nibble	addu	v1,16			# table offset for nibble	srl	v0,a0,4			# check upper nibble	and	v0,0xf			# isolate lower nibble3:	addu	v1,v0			# total table offset	lbu	v0,ffstbl(v1)		# load bit number from table	j	ra	END(ffs)	.data#define NIBBLE(x) \	.byte	0,       1+(x)*4, 2+(x)*4, 1+(x)*4; \	.byte	3+(x)*4, 1+(x)*4, 2+(x)*4, 1+(x)*4; \	.byte	4+(x)*4, 1+(x)*4, 2+(x)*4, 1+(x)*4; \	.byte	3+(x)*4, 1+(x)*4, 2+(x)*4, 1+(x)*4ffstbl:	NIBBLE(0)	NIBBLE(1)	NIBBLE(2)	NIBBLE(3)	NIBBLE(4)	NIBBLE(5)	NIBBLE(6)	NIBBLE(7)	.text#endif notdef/* * ffintr(cause_register) -- find first bit set in interrupt pending byte * bits are numbered as 8 most significant to 1 least significant, * search starts from most significant end, returns 0 in no bits set */LEAF(ffintr)	and	v0,a0,CAUSE_IPMASK	srl	a0,v0,CAUSE_IPSHIFT+4	# shift to high nibble of IPEND bits	bne	a0,zero,1f		# bits set in high nibble	srl	a0,v0,CAUSE_IPSHIFT	# get 2nd nibble right	add	a0,16			# to get to 2nd half of table1:	lbu	v0,ffitbl(a0)		# get value from table	j	ra	END(ffintr)	.dataffitbl:	.byte 0,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8	.byte 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4	.text/* * scanc(count, cp, table, mask) * Like VAX instruction */LEAF(scanc)	move	v0,a0	b	2f1:	subu	v0,1		# decr count2:	beq	v0,zero,3f	# count exhausted	lbu	v1,0(a1)	# get char at cp	addu	a1,1		# incr cp	addu	t8,a2,v1	# offset into table	lbu	t9,0(t8)	# load table entry	and	t9,a3		# mask table entry	beq	t9,zero,1b	# masked bit set3:	j	ra	END(scanc)/* * in_checksum(addr, len, prevcksum) * * Calculates a 16 bit ones-complement checksum. * Note that for a big-endian machine, this routine always adds even * address bytes to the high order 8 bits of the 16 bit checksum and * odd address bytes are added to the low order 8 bits of the 16 bit checksum. * For little-endian machines, this routine always adds even address bytes * to the low order 8 bits of the 16 bit checksum and the odd address bytes * to the high order 8 bits of the 16 bit checksum. */LEAF(in_checksum)	move	v0,a2		# copy previous checksum	beq	a1,zero,4f	# count exhausted	and	v1,a0,1	beq	v1,zero,2f	# already on a halfword boundry	lbu	t8,0(a0)	addu	a0,1#ifdef MIPSEL	sll	t8,8#endif MIPSEL	addu	v0,t8	subu	a1,1	b	2f1:	lhu	t8,0(a0)	addu	a0,2	addu	v0,t8	subu	a1,22:	bge	a1,2,1b	beq	a1,zero,3f	# no trailing byte	lbu	t8,0(a0)#ifdef MIPSEB	sll	t8,8#endif MIPSEB	addu	v0,t83:	srl	v1,v0,16	# add in all previous wrap around carries	and	v0,0xffff	addu	v0,v1	srl	v1,v0,16	# wrap-arounds could cause carry, also	addu	v0,v1	and	v0,0xffff4:	j	ra	END(in_checksum)/* *	The XNS checksummer does an add-and-cycle checksum.  Odd byte *	lengths are dealt with by postpending a garbage byte, which is *	carried with the packet forever, and is not assumed to be *	zero.  Thus, the algorithm is load a half-word, and add it to *	the current checksum.  Then, shift the whole mess left one bit, *	and iterate.  All math is ones-complement on  16 bits, so when *	we are done, we must  fold back all the carry bits that are in *	the high 16 bits of our register.  The caller is required to *	half-word align the packet, since we can't easily, and to *	postpend the garbage byte if necessary. */LEAF(ns_checksum)	move	v0,a2		# copy previous checksum	move	t0, a1		# save count	beq	a1,zero,3f	# count exhausted	and	v1,a0,1	beq	v1,zero,2f	# already on a halfword boundry	li	v0, 0177777	# error code	b	3f1:	lhu	t8,0(a0)	addu	a0,2	addu	v0,t8	subu	a1,22:	bge	a1,2,1b	srl	v1,v0,16	# add in all previous wrap around carries	and	v0,0xffff	addu	v0,v1	srl	v1,v0,16	# wrap-arounds could cause carry, also	addu	v0,v1	and	v0,0xffff	sll	t0, 1		# divide count by two it - is round	rol	v0, t0		# now do 32 bit rotate...	and	v1, v0, 0xffff	# and fold it back down to 16 bits	and	v0, 0xffff0000	or	v0, v1		# done, now have 16 bit checksum3:	j	ra	END(ns_checksum)/* * nuxi_s and nuxi_l -- byte swap short and long */LEAF(nuxi_s)			# a0 = ??ab	srl	v0,a0,8		# v0 = 0??a	and	v0,0xff		# v0 = 000a	sll	v1,a0,8		# v1 = ?ab0	or	v0,v1		# v0 = ?aba	and	v0,0xffff	# v0 = 00ba	j	ra	END(nuxi_s)LEAF(nuxi_l)			# a0 = abcd	sll	v0,a0,24	# v0 = d000	srl	v1,a0,24	# v1 = 000a	or	v0,v0,v1	# v0 = d00a	and	v1,a0,0xff00	# v1 = 00c0	sll	v1,v1,8		# v1 = 0c00	or	v0,v0,v1	# v0 = dc0a	srl	v1,a0,8		# v1 = 0abc	and	v1,v1,0xff00	# v1 = 00b0	or	v0,v0,v1	# v0 = dcba	j	ra	END(nuxi_l)/* * Write buffer flush routine.  Routine waits until * the write buffer is empty before returning. */LEAF(kn01wbflush)		/* WB flush routine for PMAX (R2000a) */1:	 	bc0f	1b 	j	ra	END(kn01wbflush)LEAF(kn210wbflush)		/* WB flush routine for R3000	*/	.set noreorder	mfc0	v0,C0_SR	/* v0 = status register */	li	t0,0x80000000	/* set CU3 bit */	or	v1,v0,t0	/* v1 = v0 | 0x80000000 */	nop	mtc0	v1,C0_SR	/* status register = v1 */	nop			/* both these nops are needed */	nop			/* both these nops are needed */1:	 	bc3f	1b		/* wait till write buffer empty */	nop			/* this no op too		*/	mtc0	v0,C0_SR	/* restore old status register */	nop 	j	ra	nop	.set reorder	END(kn210wbflush)#ifdef DS5000_100LEAF(kn02ba_wbflush)			/* WB flush routine for 5000_100 */	lw	v0, KN02BA_SIRM_K1ADDR	/* a read will flush all writes	 */	j	ra	END(kn02ba_wbflush)#endifLEAF(kn220wbflush)		/* WB flush routine for R3000	*/	.set noreorder	la	t0,kn220wbflush_loc	li	t1, 0xa0000000  /* Make kseg1 address   */	or      t0,t1	sw	t1,0(t0)	lw	t1,0(t0)	nop 	j	ra	nop	.set reorder	END(kn210wbflush)NESTED(smp_lock_retry,24,zero)	.set	noreorder#ifndef SMP	lw	t5,(a0)		lw	t1,u+PCB_CPUPTR	 /* get cpudata pointer */	bltz	t5,3f	lw	t2,CPU_HLOCK(t1) /* save off lock list head */	sw	a0,CPU_HLOCK(t1) /* put new lock at head */	sw	ra,L_PC(a0)	/* store off PC lock asserted at */		lui	t3,0x8000	lw	t4,L_WON(a0)	/* get lock won */	or	t6,t3,t5	/* set lock bit */	addiu	t4,t4,1		/* increment lock won */	sw	t6,(a0)	sw	t4,L_WON(a0)	j	ra	sw	t2,L_PLOCK(a0)  /* chain old list off new lock */3:	addiu	sp,sp,-24	/* save stack space */	b 	1f	sw	ra,20(sp)	/* save off return */#else			2:		lw	t6,smp_debug	/* read up smp_debug*/	addiu	sp,sp,-24	/* save stack space */	bne	t6,zero,1f	/* branch if debug enabled */	sw	ra,20(sp)	/* save off return */	jal	setlock	sw	a0,24(sp)	/* save off lock pointer */	beq 	v0,zero,1f	/* branch if we failed to get lock */	lw	a0,24(sp)	/* restore lock pointer */	lw	t1,u+PCB_CPUPTR	 /* get cpudata pointer */	lw	ra,20(sp)		/* restore return address */	lw	t2,CPU_HLOCK(t1) /* save off lock list head */	sw	a0,CPU_HLOCK(t1)	/* put new lock at head */	lw	t4,L_WON(a0)	/* get lock won */	sw	ra,L_PC(a0)			addiu	t4,t4,1		/* increment lock won */	addiu	sp,sp,24		/* give back stack space */	sw	t4,L_WON(a0)	j	ra	sw	t2,L_PLOCK(a0);		/* chain old list off new lock */#endif1:	li	a1,LK_RETRY	jal	smp_lock_long		/*  smp_lock_long(lk,L

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -