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

📄 locore.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 5 页
字号:
	movl	a1@(P_FORW),a0		| p = q->p_forw	movl	a0@(P_FORW),a1@(P_FORW)	| q->p_forw = p->p_forw	movl	a0@(P_FORW),a1		| q = p->p_forw	movl	a0@(P_BACK),a1@(P_BACK)	| q->p_back = p->p_back	cmpl	a0@(P_FORW),d1		| anyone left on queue?	jeq	Lsw2			| no, skip	movl	_whichqs,d1	bset	d0,d1			| yes, reset bit	movl	d1,_whichqsLsw2:	movl	a0,_curproc	clrl	_want_resched#ifdef notyet	movl	sp@+,a1	cmpl	a0,a1			| switching to same proc?	jeq	Lswdone			| yes, skip save and restore#endif	/*	 * Save state of previous process in its pcb.	 */	movl	_curpcb,a1	moveml	#0xFCFC,a1@(PCB_REGS)	| save non-scratch registers	movl	usp,a2			| grab USP (a2 has been saved)	movl	a2,a1@(PCB_USP)		| and save it#ifdef FPCOPROC	lea	a1@(PCB_FPCTX),a2	| pointer to FP save area	fsave	a2@			| save FP state	tstb	a2@			| null state frame?	jeq	Lswnofpsave		| yes, all done	fmovem	fp0-fp7,a2@(216)	| save FP general registers	fmovem	fpcr/fpsr/fpi,a2@(312)	| save FP control registersLswnofpsave:#endif#ifdef DIAGNOSTIC	tstl	a0@(P_WCHAN)	jne	Lbadsw	cmpb	#SRUN,a0@(P_STAT)	jne	Lbadsw#endif	clrl	a0@(P_BACK)		| clear back link	movb	a0@(P_MDFLAG+3),mdpflag	| low byte of p_md.md_flags	movl	a0@(P_ADDR),a1		| get p_addr	movl	a1,_curpcb	/* see if pmap_activate needs to be called; should remove this */	movl	a0@(P_VMSPACE),a0	| vmspace = p->p_vmspace#ifdef DIAGNOSTIC	tstl	a0			| map == VM_MAP_NULL?	jeq	Lbadsw			| panic#endif	lea	a0@(VM_PMAP),a0		| pmap = &vmspace.vm_pmap	tstl	a0@(PM_STCHG)		| pmap->st_changed?	jeq	Lswnochg		| no, skip	pea	a1@			| push pcb (at p_addr)	pea	a0@			| push pmap	jbsr	_pmap_activate		| pmap_activate(pmap, pcb)	addql	#8,sp	movl	_curpcb,a1		| restore p_addrLswnochg:	movl	#PGSHIFT,d1	movl	a1,d0	lsrl	d1,d0			| convert p_addr to page number	lsll	#2,d0			| and now to Sysmap offset	addl	_Sysmap,d0		| add Sysmap base to get PTE addr#ifdef notdef	movw	#PSL_HIGHIPL,sr		| go crit while changing PTEs#endif	lea	tmpstk,sp		| now goto a tmp stack for NMI	movl	d0,a0			| address of new context	movl	_Umap,a2		| address of PTEs for kstack	moveq	#UPAGES-1,d0		| sizeof kstackLres1:	movl	a0@+,d1			| get PTE	andl	#~PG_PROT,d1		| mask out old protection	orl	#PG_RW+PG_V,d1		| ensure valid and writable	movl	d1,a2@+			| load it up	dbf	d0,Lres1		| til done#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040?	jne	Lres1a			| no, skip	.word	0xf518			| yes, pflusha	movl	a1@(PCB_USTP),d0	| get USTP	moveq	#PGSHIFT,d1	lsll	d1,d0			| convert to addr	.long	0x4e7b0806		| movc d0,urp	jra	LcxswdoneLres1a:#endif	movl	#CACHE_CLR,d0	movc	d0,cacr			| invalidate cache(s)	pflusha				| flush entire TLB	movl	a1@(PCB_USTP),d0	| get USTP	moveq	#PGSHIFT,d1	lsll	d1,d0			| convert to addr	lea	_protorp,a0		| CRP prototype	movl	d0,a0@(4)		| stash USTP	pmove	a0@,crp			| load new user root pointerLcxswdone:	moveml	a1@(PCB_REGS),#0xFCFC	| and registers	movl	a1@(PCB_USP),a0	movl	a0,usp			| and USP#ifdef FPCOPROC	lea	a1@(PCB_FPCTX),a0	| pointer to FP save area	tstb	a0@			| null state frame?	jeq	Lresfprest		| yes, easy#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040?	jne	Lresnot040		| no, skip	clrl	sp@-			| yes...	frestore sp@+			| ...magic!Lresnot040:#endif	fmovem	a0@(312),fpcr/fpsr/fpi	| restore FP control registers	fmovem	a0@(216),fp0-fp7	| restore FP general registersLresfprest:	frestore a0@			| restore state#endif	movw	a1@(PCB_PS),sr		| no, restore PS	moveq	#1,d0			| return 1 (for alternate returns)	rts/* * savectx(pcb, altreturn) * Update pcb, saving current processor state and arranging * for alternate return ala longjmp in switch if altreturn is true. */ENTRY(savectx)	movl	sp@(4),a1	movw	sr,a1@(PCB_PS)	movl	usp,a0			| grab USP	movl	a0,a1@(PCB_USP)		| and save it	moveml	#0xFCFC,a1@(PCB_REGS)	| save non-scratch registers#ifdef FPCOPROC	lea	a1@(PCB_FPCTX),a0	| pointer to FP save area	fsave	a0@			| save FP state	tstb	a0@			| null state frame?	jeq	Lsvnofpsave		| yes, all done	fmovem	fp0-fp7,a0@(216)	| save FP general registers	fmovem	fpcr/fpsr/fpi,a0@(312)	| save FP control registersLsvnofpsave:#endif	tstl	sp@(8)			| altreturn?	jeq	Lsavedone	movl	sp,d0			| relocate current sp relative to a1	subl	#_kstack,d0		|   (sp is relative to kstack):	addl	d0,a1			|   a1 += sp - kstack;	movl	sp@,a1@			| write return pc at (relocated) sp@Lsavedone:	moveq	#0,d0			| return 0	rts/* * {fu,su},{byte,sword,word} */ALTENTRY(fuiword, _fuword)ENTRY(fuword)	movl	sp@(4),a0		| address to read	movl	_curpcb,a1		| current pcb	movl	#Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault	movsl	a0@,d0			| do read from user space	nop	jra	LfsdoneENTRY(fusword)	movl	sp@(4),a0	movl	_curpcb,a1		| current pcb	movl	#Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault	moveq	#0,d0	movsw	a0@,d0			| do read from user space	nop	jra	Lfsdone/* Just like fusword, but tells trap code not to page in. */ENTRY(fuswintr)	movl	sp@(4),a0	movl	_curpcb,a1	movl	#_fswintr,a1@(PCB_ONFAULT)	moveq	#0,d0	movsw	a0@,d0	nop	jra	LfsdoneALTENTRY(fuibyte, _fubyte)ENTRY(fubyte)	movl	sp@(4),a0		| address to read	movl	_curpcb,a1		| current pcb	movl	#Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault	moveq	#0,d0	movsb	a0@,d0			| do read from user space	nop	jra	LfsdoneLfserr:	moveq	#-1,d0			| error indicatorLfsdone:	clrl	a1@(PCB_ONFAULT) 	| clear fault address	rts/* Just like Lfserr, but the address is different (& exported). */	.globl	_fswintr_fswintr:	moveq	#-1,d0	jra	Lfsdone/* * Write a longword in user instruction space. * Largely the same as suword but with a final i-cache purge on those * machines with split caches. */ENTRY(suiword)	movl	sp@(4),a0		| address to write	movl	sp@(8),d0		| value to put there	movl	_curpcb,a1		| current pcb	movl	#Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault	movsl	d0,a0@			| do write to user space	nop	moveq	#0,d0			| indicate no fault#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040?	jne	Lsuicpurge		| no, skip	.word	0xf498			| cinva ic (XXX overkill)	jra	LfsdoneLsuicpurge:#endif	movl	#IC_CLEAR,d1	movc	d1,cacr			| invalidate i-cache	jra	LfsdoneENTRY(suword)	movl	sp@(4),a0		| address to write	movl	sp@(8),d0		| value to put there	movl	_curpcb,a1		| current pcb	movl	#Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault	movsl	d0,a0@			| do write to user space	nop	moveq	#0,d0			| indicate no fault	jra	LfsdoneENTRY(susword)	movl	sp@(4),a0		| address to write	movw	sp@(10),d0		| value to put there	movl	_curpcb,a1		| current pcb	movl	#Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault	movsw	d0,a0@			| do write to user space	nop	moveq	#0,d0			| indicate no fault	jra	LfsdoneENTRY(suswintr)	movl	sp@(4),a0	movw	sp@(10),d0	movl	_curpcb,a1	movl	#_fswintr,a1@(PCB_ONFAULT)	movsw	d0,a0@	nop	moveq	#0,d0	jra	LfsdoneALTENTRY(suibyte, _subyte)ENTRY(subyte)	movl	sp@(4),a0		| address to write	movb	sp@(11),d0		| value to put there	movl	_curpcb,a1		| current pcb	movl	#Lfserr,a1@(PCB_ONFAULT) | where to return to on a fault	movsb	d0,a0@			| do write to user space	nop	moveq	#0,d0			| indicate no fault	jra	Lfsdone#if defined(LUNA2)ENTRY(suline)	movl	sp@(4),a0		| address to write	movl	_curpcb,a1		| current pcb	movl	#Lslerr,a1@(PCB_ONFAULT) | where to return to on a fault	movl	sp@(8),a1		| address of line	movl	a1@+,d0			| get lword	movsl	d0,a0@+			| put lword	nop				| sync	movl	a1@+,d0			| get lword	movsl	d0,a0@+			| put lword	nop				| sync	movl	a1@+,d0			| get lword	movsl	d0,a0@+			| put lword	nop				| sync	movl	a1@+,d0			| get lword	movsl	d0,a0@+			| put lword	nop				| sync	moveq	#0,d0			| indicate no fault	jra	LsldoneLslerr:	moveq	#-1,d0Lsldone:	movl	_curpcb,a1		| current pcb	clrl	a1@(PCB_ONFAULT) 	| clear fault address	rts#endif/* * Invalidate entire TLB. */ENTRY(TBIA)__TBIA:#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040?	jne	Lmotommu3		| no, skip	.word	0xf518			| yes, pflusha	rtsLmotommu3:#endif	pflusha				| flush entire TLB	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip d-cache	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(LUNA2)	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	movl	sp@(4),a0		| get addr to flush	pflush	#0,#0,a0@		| flush address from both sides	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip data cache	rts/* * Invalidate supervisor side of TLB */ENTRY(TBIAS)#ifdef DEBUG	tstl	fulltflush		| being conservative?	jne	__TBIA			| yes, flush everything#endif#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040?	jne	Lmotommu5		| no, skip	.word	0xf518			| yes, pflusha (for now) XXX	rtsLmotommu5:#endif	pflush #4,#4			| flush supervisor TLB entries	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip d-cache	rts/* * Invalidate user side of TLB */ENTRY(TBIAU)#ifdef DEBUG	tstl	fulltflush		| being conservative?	jne	__TBIA			| yes, flush everything#endif#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040?	jne	Lmotommu6		| no, skip	.word	0xf518			| yes, pflusha (for now) XXX	rtsLmotommu6:#endif	pflush	#0,#4			| flush user TLB entries	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip d-cache	rts/* * Invalidate instruction cache */ENTRY(ICIA)#if defined(LUNA2)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. * 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(LUNA2)	cmpl	#-2,_mmutype		| 68040	jne	Lmotommu8		| no, skip	/* XXX implement */	rtsLmotommu8:#endif	rtsENTRY(DCIS)__DCIS:#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040	jne	Lmotommu9		| no, skip	/* XXX implement */	rtsLmotommu9:#endif	rtsENTRY(DCIU)__DCIU:#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040	jne	LmotommuA		| no, skip	/* XXX implement */	rtsLmotommuA:#endif	rts#if defined(LUNA2)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(LUNA2)ENTRY(DCFA)	cmpl	#-2,_mmutype		| 68040	jne	LmotommuB		| no, skip	.word	0xf478			| cpusha dc	rtsLmotommuB:#endif	movl	#DC_CLEAR,d0	movc	d0,cacr			| invalidate on-chip d-cache	rts#if 0 /****************************************************************//* external cache control */ENTRY(ecacheon)	rtsENTRY(ecacheoff)	rts#endif /****************************************************************//* * 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

⌨️ 快捷键说明

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