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

📄 locore.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 5 页
字号:
	pflusha				| flush entire TLB#if defined(HP360) || defined(HP370)	jpl	Lmc68851a		| 68851 implies no d-cache	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip d-cacheLmc68851a:#endif	rtsLhpmmu6:#endif#if defined(HP320) || defined(HP350)	MMUADDR(a0)	movl	a0@(MMUTBINVAL),sp@-	| do not ask me, this	addql	#4,sp			|   is how hpux does it#ifdef DEBUG	tstl	fullcflush	jne	__DCIA			| XXX: invalidate entire cache#endif#endif	rts/* * Invalidate any TLB entry for given VA (TB Invalidate Single) */ENTRY(TBIS)#ifdef DEBUG	tstl	fulltflush		| being conservative?	jne	__TBIA			| yes, flush entire TLB#endif#if defined(HP380)	cmpl	#-2,_mmutype		| 68040?	jne	Lmotommu4		| no, skip	movl	sp@(4),a0	movc	dfc,d1	moveq	#1,d0			| user space	movc	d0,dfc	.word	0xf508			| pflush a0@	moveq	#5,d0			| super space	movc	d0,dfc	.word	0xf508			| pflush a0@	movc	d1,dfc	rtsLmotommu4:#endif#if defined(HP330) || defined(HP360) || defined(HP370)	tstl	_mmutype		| HP MMU?	jeq	Lhpmmu5			| yes, skip	movl	sp@(4),a0		| get addr to flush#if defined(HP360) || defined(HP370)	jpl	Lmc68851b		| is 68851?	pflush	#0,#0,a0@		| flush address from both sides	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip data cache	rtsLmc68851b:#endif	pflushs	#0,#0,a0@		| flush address from both sides	rtsLhpmmu5:#endif#if defined(HP320) || defined(HP350)	movl	sp@(4),d0		| VA to invalidate	bclr	#0,d0			| ensure even	movl	d0,a0	movw	sr,d1			| go critical	movw	#PSL_HIGHIPL,sr		|   while in purge space	moveq	#FC_PURGE,d0		| change address space	movc	d0,dfc			|   for destination	moveq	#0,d0			| zero to invalidate?	movsl	d0,a0@			| hit it	moveq	#FC_USERD,d0		| back to old	movc	d0,dfc			|   address space	movw	d1,sr			| restore IPL#endif	rts/* * Invalidate supervisor side of TLB */ENTRY(TBIAS)#ifdef DEBUG	tstl	fulltflush		| being conservative?	jne	__TBIA			| yes, flush everything#endif#if defined(HP380)	cmpl	#-2,_mmutype		| 68040?	jne	Lmotommu5		| no, skip	.word	0xf518			| yes, pflusha (for now) XXX	rtsLmotommu5:#endif#if defined(HP330) || defined(HP360) || defined(HP370)	tstl	_mmutype		| HP MMU?	jeq	Lhpmmu7			| yes, skip#if defined(HP360) || defined(HP370)	jpl	Lmc68851c		| 68851?	pflush #4,#4			| flush supervisor TLB entries	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip d-cache	rtsLmc68851c:#endif	pflushs #4,#4			| flush supervisor TLB entries	rtsLhpmmu7:#endif#if defined(HP320) || defined(HP350)	MMUADDR(a0)	movl	#0x8000,d0		| more	movl	d0,a0@(MMUTBINVAL)	|   HP magic#ifdef DEBUG	tstl	fullcflush	jne	__DCIS			| XXX: invalidate entire sup. cache#endif#endif	rts/* * Invalidate user side of TLB */ENTRY(TBIAU)#ifdef DEBUG	tstl	fulltflush		| being conservative?	jne	__TBIA			| yes, flush everything#endif#if defined(HP380)	cmpl	#-2,_mmutype		| 68040?	jne	Lmotommu6		| no, skip	.word	0xf518			| yes, pflusha (for now) XXX	rtsLmotommu6:#endif#if defined(HP330) || defined(HP360) || defined(HP370)	tstl	_mmutype		| HP MMU?	jeq	Lhpmmu8			| yes, skip#if defined(HP360) || defined(HP370)	jpl	Lmc68851d		| 68851?	pflush	#0,#4			| flush user TLB entries	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip d-cache	rtsLmc68851d:#endif	pflushs	#0,#4			| flush user TLB entries	rtsLhpmmu8:#endif#if defined(HP320) || defined(HP350)	MMUADDR(a0)	moveq	#0,d0			| more	movl	d0,a0@(MMUTBINVAL)	|   HP magic#ifdef DEBUG	tstl	fullcflush	jne	__DCIU			| XXX: invalidate entire user cache#endif#endif	rts/* * Invalidate instruction cache */ENTRY(ICIA)#if defined(HP380)ENTRY(ICPA)	cmpl	#-2,_mmutype		| 68040	jne	Lmotommu7		| no, skip	.word	0xf498			| cinva ic	rtsLmotommu7:#endif	movl	#IC_CLEAR,d0	movc	d0,cacr			| invalidate i-cache	rts/* * Invalidate data cache. * HP external cache allows for invalidation of user/supervisor portions. * NOTE: we do not flush 68030 on-chip cache as there are no aliasing * problems with DC_WA.  The only cases we have to worry about are context * switch and TLB changes, both of which are handled "in-line" in resume * and TBI*. */ENTRY(DCIA)__DCIA:#if defined(HP380)	cmpl	#-2,_mmutype		| 68040	jne	Lmotommu8		| no, skip	/* XXX implement */	rtsLmotommu8:#endif#if defined(HP320) || defined(HP350)	tstl	_ectype			| got external VAC?	jle	Lnocache2		| no, all done	MMUADDR(a0)	andl	#~MMU_CEN,a0@(MMUCMD)	| disable cache in MMU control reg	orl	#MMU_CEN,a0@(MMUCMD)	| reenable cache in MMU control regLnocache2:#endif	rtsENTRY(DCIS)__DCIS:#if defined(HP380)	cmpl	#-2,_mmutype		| 68040	jne	Lmotommu9		| no, skip	/* XXX implement */	rtsLmotommu9:#endif#if defined(HP320) || defined(HP350)	tstl	_ectype			| got external VAC?	jle	Lnocache3		| no, all done	MMUADDR(a0)	movl	a0@(MMUSSTP),d0		| read the supervisor STP	movl	d0,a0@(MMUSSTP)		| write it backLnocache3:#endif	rtsENTRY(DCIU)__DCIU:#if defined(HP380)	cmpl	#-2,_mmutype		| 68040	jne	LmotommuA		| no, skip	/* XXX implement */	rtsLmotommuA:#endif#if defined(HP320) || defined(HP350)	tstl	_ectype			| got external VAC?	jle	Lnocache4		| no, all done	MMUADDR(a0)	movl	a0@(MMUUSTP),d0		| read the user STP	movl	d0,a0@(MMUUSTP)		| write it backLnocache4:#endif	rts#if defined(HP380)ENTRY(ICPL)	movl	sp@(4),a0		| address	.word	0xf488			| cinvl ic,a0@	rtsENTRY(ICPP)	movl	sp@(4),a0		| address	.word	0xf490			| cinvp ic,a0@	rtsENTRY(DCPL)	movl	sp@(4),a0		| address	.word	0xf448			| cinvl dc,a0@	rtsENTRY(DCPP)	movl	sp@(4),a0		| address	.word	0xf450			| cinvp dc,a0@	rtsENTRY(DCPA)	.word	0xf458			| cinva dc	rtsENTRY(DCFL)	movl	sp@(4),a0		| address	.word	0xf468			| cpushl dc,a0@	rtsENTRY(DCFP)	movl	sp@(4),a0		| address	.word	0xf470			| cpushp dc,a0@	rts#endifENTRY(PCIA)#if defined(HP380)ENTRY(DCFA)	cmpl	#-2,_mmutype		| 68040	jne	LmotommuB		| no, skip	.word	0xf478			| cpusha dc	rtsLmotommuB:#endif#if defined(HP360) || defined(HP370)	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip d-cache	tstl	_ectype			| got external PAC?	jge	Lnocache6		| no, all done	MMUADDR(a0)	andl	#~MMU_CEN,a0@(MMUCMD)	| disable cache in MMU control reg	orl	#MMU_CEN,a0@(MMUCMD)	| reenable cache in MMU control regLnocache6:#endif	rtsENTRY(ecacheon)	tstl	_ectype	jeq	Lnocache7	MMUADDR(a0)	orl	#MMU_CEN,a0@(MMUCMD)Lnocache7:	rtsENTRY(ecacheoff)	tstl	_ectype	jeq	Lnocache8	MMUADDR(a0)	andl	#~MMU_CEN,a0@(MMUCMD)Lnocache8:	rts/* * Get callers current SP value. * Note that simply taking the address of a local variable in a C function * doesn't work because callee saved registers may be outside the stack frame * defined by A6 (e.g. GCC generated code). */	.globl	_getsp_getsp:	movl	sp,d0			| get current SP	addql	#4,d0			| compensate for return address	rts	.globl	_getsfc, _getdfc_getsfc:	movc	sfc,d0	rts_getdfc:	movc	dfc,d0	rts/* * Load a new user segment table pointer. */ENTRY(loadustp)#if defined(HP330) || defined(HP360) || defined(HP370) || defined(HP380)	tstl	_mmutype		| HP MMU?	jeq	Lhpmmu9			| yes, skip	movl	sp@(4),d0		| new USTP	moveq	#PGSHIFT,d1	lsll	d1,d0			| convert to addr#if defined(HP380)	cmpl	#-2,_mmutype		| 68040?	jne	LmotommuC		| no, skip	.long	0x4e7b0806		| movc d0,urp	rtsLmotommuC:#endif	lea	_protorp,a0		| CRP prototype	movl	d0,a0@(4)		| stash USTP	pmove	a0@,crp			| load root pointer	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip d-cache	rts				|   since pmove flushes TLBLhpmmu9:#endif#if defined(HP320) || defined(HP350)	MMUADDR(a0)	movl	sp@(4),a0@(MMUUSTP)	| load a new USTP#endif	rtsENTRY(ploadw)#if defined(HP330) || defined(HP360) || defined(HP370)	movl	sp@(4),a0		| address to load	ploadw	#1,a0@			| pre-load translation#endif	rts/* * Set processor priority level calls.  Most are implemented with * inline asm expansions.  However, spl0 requires special handling * as we need to check for our emulated software interrupts. */ENTRY(spl0)	moveq	#0,d0	movw	sr,d0			| get old SR for return	movw	#PSL_LOWIPL,sr		| restore new SR	tstb	_ssir			| software interrupt pending?	jeq	Lspldone		| no, all done	subql	#4,sp			| make room for RTE frame	movl	sp@(4),sp@(2)		| position return address	clrw	sp@(6)			| set frame type 0	movw	#PSL_LOWIPL,sp@		| and new SR	jra	Lgotsir			| go handle itLspldone:	rtsENTRY(_insque)	movw	sr,d0	movw	#PSL_HIGHIPL,sr		| atomic	movl	sp@(8),a0		| where to insert (after)	movl	sp@(4),a1		| element to insert (e)	movl	a0@,a1@			| e->next = after->next	movl	a0,a1@(4)		| e->prev = after	movl	a1,a0@			| after->next = e	movl	a1@,a0	movl	a1,a0@(4)		| e->next->prev = e	movw	d0,sr	rtsENTRY(_remque)	movw	sr,d0	movw	#PSL_HIGHIPL,sr		| atomic	movl	sp@(4),a0		| element to remove (e)	movl	a0@,a1	movl	a0@(4),a0	movl	a0,a1@(4)		| e->next->prev = e->prev	movl	a1,a0@			| e->prev->next = e->next	movw	d0,sr	rts/* * bzero(addr, count) */ALTENTRY(blkclr, _bzero)ENTRY(bzero)	movl	sp@(4),a0	| address	movl	sp@(8),d0	| count	jeq	Lbzdone		| if zero, nothing to do	movl	a0,d1	btst	#0,d1		| address odd?	jeq	Lbzeven		| no, can copy words	clrb	a0@+		| yes, zero byte to get to even boundary	subql	#1,d0		| decrement count	jeq	Lbzdone		| none left, all doneLbzeven:	movl	d0,d1	andl	#31,d0	lsrl	#5,d1		| convert count to 8*longword count	jeq	Lbzbyte		| no such blocks, zero byte at a timeLbzloop:	clrl	a0@+; clrl	a0@+; clrl	a0@+; clrl	a0@+;	clrl	a0@+; clrl	a0@+; clrl	a0@+; clrl	a0@+;	subql	#1,d1		| one more block zeroed	jne	Lbzloop		| more to go, do it	tstl	d0		| partial block left?	jeq	Lbzdone		| no, all doneLbzbyte:	clrb	a0@+	subql	#1,d0		| one more byte cleared	jne	Lbzbyte		| more to go, do itLbzdone:	rts/* * strlen(str) */ENTRY(strlen)	moveq	#-1,d0	movl	sp@(4),a0	| stringLslloop:	addql	#1,d0		| increment count	tstb	a0@+		| null?	jne	Lslloop		| no, keep going	rts/* * bcmp(s1, s2, len) * * WARNING!  This guy only works with counts up to 64K */ENTRY(bcmp)	movl	sp@(4),a0		| string 1	movl	sp@(8),a1		| string 2	moveq	#0,d0	movw	sp@(14),d0		| length	jeq	Lcmpdone		| if zero, nothing to do	subqw	#1,d0			| set up for DBcc loopLcmploop:	cmpmb	a0@+,a1@+		| equal?	dbne	d0,Lcmploop		| yes, keep going	addqw	#1,d0			| +1 gives zero on matchLcmpdone:	rts	/* * {ov}bcopy(from, to, len) * * Works for counts up to 128K. */ALTENTRY(ovbcopy, _bcopy)ENTRY(bcopy)	movl	sp@(12),d0		| get count	jeq	Lcpyexit		| if zero, return	movl	sp@(4),a0		| src address	movl	sp@(8),a1		| dest address	cmpl	a1,a0			| src before dest?	jlt	Lcpyback		| yes, copy backwards (avoids overlap)	movl	a0,d1	btst	#0,d1			| src address odd?	jeq	Lcfeven			| no, go check dest	movb	a0@+,a1@+		| yes, copy a byte	subql	#1,d0			| update count	jeq	Lcpyexit		| exit if doneLcfeven:	movl	a1,d1	btst	#0,d1			| dest address odd?	jne	Lcfbyte			| yes, must copy by bytes	movl	d0,d1			| no, get count	l

⌨️ 快捷键说明

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