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

📄 locore.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 5 页
字号:
 * 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)	movl	sp@(4),d0		| new USTP	moveq	#PGSHIFT,d1	lsll	d1,d0			| convert to addr#if defined(LUNA2)	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	rtsENTRY(ploadw)	movl	sp@(4),a0		| address to load	ploadw	#1,a0@			| pre-load translation	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	lsrl	#2,d1			| convert to longwords	jeq	Lcfbyte			| no longwords, copy bytes	subql	#1,d1			| set up for dbfLcflloop:	movl	a0@+,a1@+		| copy longwords	dbf	d1,Lcflloop		| til done	andl	#3,d0			| get remaining count	jeq	Lcpyexit		| done if noneLcfbyte:	subql	#1,d0			| set up for dbfLcfbloop:	movb	a0@+,a1@+		| copy bytes	dbf	d0,Lcfbloop		| til doneLcpyexit:	rtsLcpyback:	addl	d0,a0			| add count to src	addl	d0,a1			| add count to dest	movl	a0,d1	btst	#0,d1			| src address odd?	jeq	Lcbeven			| no, go check dest	movb	a0@-,a1@-		| yes, copy a byte	subql	#1,d0			| update count	jeq	Lcpyexit		| exit if doneLcbeven:	movl	a1,d1	btst	#0,d1			| dest address odd?	jne	Lcbbyte			| yes, must copy by bytes	movl	d0,d1			| no, get count	lsrl	#2,d1			| convert to longwords	jeq	Lcbbyte			| no longwords, copy bytes	subql	#1,d1			| set up for dbfLcblloop:	movl	a0@-,a1@-		| copy longwords	dbf	d1,Lcblloop		| til done	andl	#3,d0			| get remaining count	jeq	Lcpyexit		| done if noneLcbbyte:	subql	#1,d0			| set up for dbfLcbbloop:	movb	a0@-,a1@-		| copy bytes	dbf	d0,Lcbbloop		| til done	rts/* * Emulate fancy VAX string operations: *	scanc(count, startc, table, mask) *	skpc(mask, count, startc) *	locc(mask, count, startc) */ENTRY(scanc)	movl	sp@(4),d0	| get length	jeq	Lscdone		| nothing to do, return	movl	sp@(8),a0	| start of scan	movl	sp@(12),a1	| table to compare with	movb	sp@(19),d1	| and mask to use	movw	d2,sp@-		| need a scratch register	clrw	d2		| clear it out	subqw	#1,d0		| adjust for dbraLscloop:	movb	a0@+,d2		| get character	movb	a1@(0,d2:w),d2	| get table entry	andb	d1,d2		| mask it	dbne	d0,Lscloop	| keep going til no more or non-zero	addqw	#1,d0		| overshot by one	movw	sp@+,d2		| restore scratchLscdone:	rtsENTRY(skpc)	movl	sp@(8),d0	| get length	jeq	Lskdone		| nothing to do, return	movb	sp@(7),d1	| mask to use	movl	sp@(12),a0	| where to start	subqw	#1,d0		| adjust for dbccLskloop:	cmpb	a0@+,d1		| compate with mask	dbne	d0,Lskloop	| keep going til no more or zero	addqw	#1,d0		| overshot by oneLskdone:	rtsENTRY(locc)	movl	sp@(8),d0	| get length	jeq	Llcdone		| nothing to do, return	movb	sp@(7),d1	| mask to use	movl	sp@(12),a0	| where to start	subqw	#1,d0		| adjust for dbccLlcloop:	cmpb	a0@+,d1		| compate with mask	dbeq	d0,Llcloop	| keep going til no more or non-zero	addqw	#1,d0		| overshot by oneLlcdone:	rts/* * Emulate VAX FFS (find first set) instruction. */ENTRY(ffs)	moveq	#-1,d0	movl	sp@(4),d1	jeq	LffsdoneLffsloop:	addql	#1,d0	btst	d0,d1	jeq	LffsloopLffsdone:	addql	#1,d0	rts#ifdef FPCOPROC/* * Save and restore 68881 state. * Pretty awful looking since our assembler does not * recognize FP mnemonics. */ENTRY(m68881_save)	movl	sp@(4),a0		| save area pointer	fsave	a0@			| save state	tstb	a0@			| null state frame?	jeq	Lm68881sdone		| yes, all done	fmovem fp0-fp7,a0@(216)		| save FP general registers	fmovem fpcr/fpsr/fpi,a0@(312)	| save FP control registersLm68881sdone:	rtsENTRY(m68881_restore)	movl	sp@(4),a0		| save area pointer	tstb	a0@			| null state frame?	jeq	Lm68881rdone		| yes, easy	fmovem	a0@(312),fpcr/fpsr/fpi	| restore FP control registers	fmovem	a0@(216),fp0-fp7	| restore FP general registersLm68881rdone:	frestore a0@			| restore state	rts/* LUNA */	.globl	_fpp_svarea/* Fpp is MC68882 ? */ENTRY(is_68882)	frestore _fppnull	| initialize fpp	movl	#2,d0	fmovecr	#0,fp1	fsinx	fp1,fp2	lea	_fpp_svarea,a0	| save area	movw	sr,d1		| save status reg.	movw	#0x2700,sr	| mask intrrupt	fsave	a0@		| save fpp context	movw	d1,sr		| restore status reg.	movl	a0@,d1	andl	#0x00ff0000,d1  | check status field	cmpl	#0x00180000,d1  | 68881(idle)?	beq	_is81			cmpl	#0x00b40000,d1	| 68881(busy)?	beq	_is81	cmpl	#0x00380000,d1	| 68882(idle)?		beq	_is82	cmpl	#0x00d40000,d1	| 68882(busy)?	beq	_is82	bra	_is82out	| default 68881_is81:	clrl	d0	bra	_is82out_is82:	movl	#1,d0_is82out:	frestore a0@	rts#ifdef	OLD_LUNA/* We have fpp ? */ENTRY(havefpp)	movl	a2,sp@-	clrl	d0	movl	vb,a2	movl	a2@(FLINE_VEC),a0	| save vectors	movl	a2@(COPRO_VEC),a1	movl	sp,d1	movl	#_fpvec,a2@(FLINE_VEC)	| change vectors	movl	#_fpvec,a2@(COPRO_VEC)	fnop				| cause exception ?	movl	#1,d0_fpvec:	movl	a0,a2@(FLINE_VEC)	| restore vectors	movl	a1,a2@(COPRO_VEC)	movl	d1,sp	movl	sp@+,a2	rts#endif#endif/* * Handle the nitty-gritty of rebooting the machine. * Basically we just turn off the MMU and jump to the appropriate ROM routine. * Note that we must be running in an address range that is mapped one-to-one * logical to physical so that the PC is still valid immediately after the MMU * is turned off.  We have conveniently mapped the last page of physical * memory this way. */	.globl	_doboot_doboot:	movl	#0x41000004,a0	movl	a0@,a1			| get PROM restart entry address#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040?	jne	LmotommuF		| no, skip	movw	#PSL_HIGHIPL,sr		| no interrupts	movl	#0x41000000,a0	movl	a0@,d0	movc	d0,isp			| set ISP	.word	0xf4f8			| cpusha bc	movl	#0,d0	movc	d0,cacr			| caches off	movql	#0,d0	.long	0x4e7b0004		| movc d0,itt0	.long	0x4e7b0005		| movc d0,itt1	.long	0x4e7b0006		| movc d0,dtt0	.long	0x4e7b0007		| movc d0,dtt1	.long	0x4e7b0003		| movc d0,tc	jmp	a1@			| goto REBOOTLmotommuF:#endif	movl	#CACHE_OFF,d0	movc	d0,cacr			| disable on-chip cache(s)	movl	#_tcroff,a0		| value for pmove to TC (turn off MMU)	pmove	a0@,tc			| disable MMU	jmp	a1@			| goto REBOOT	.data	.globl	_machineid,_mmutype_machineid:	.long	1		| default to LUNA-I_mmutype:	.long	-1		| default to 68030 PMMU	.globl	_protorp,_protott0,_protott1_protorp:	.long	0,0		| prototype root pointer_protott0:	.long	0x403f8543	| tt0 (for LUNA1 kernel 0x40000000-0x7fffffff)_protott1:	.long	0x807F8543	| tt1 (for LUNA1 kernel 0x80000000-0xffffffff)_mapping_tc:	.long	0	.globl	_cold_cold:	.long	1		| cold start flag	.globl	_want_resched_want_resched:	.long	0	.globl	_proc0paddr_proc0paddr:	.long	0		| KVA of proc0 u-area	.globl	_tcroff_tcroff:	.long	0		| TC reg. reset flag#ifdef FPCOPROC	.globl	_fppnull_fppnull:	.long	0#endif	.globl	_clock_on_clock_on:	.long	0		| clock is enable ?	.globl	_dipswitch_dipswitch:	.word	0		| dipsw(front panel) value	.globl	_KernInter_KernInter:			| Kernel InterFace Field	.space	KIFF_SIZE#ifdef DEBUG	.globl	fulltflush, fullcflushfulltflush:	.long	0fullcflush:	.long	0#endif#ifdef HPFPLIB/* * Undefined symbols from hpux_float.o: * * kdb_printf:	A kernel debugger print routine, we just use printf instead. * processor:	HP-UX equiv. of machineid, set to 3 if it is a 68040. * u:		Ye ole u-area.  The code wants to grab the first longword *		indirect off of that and clear the 0x40000 bit there. *		Oddly enough this was incorrect even in HP-UX! * runrun:	Old name for want_resched. */	.globl	_kdb_printf,_processor,_u,_runrun_kdb_printf:	.long	_printf_processor:	.long	0_u:	.long	.+4	.long	0	.set	_runrun,_want_resched#endif/* interrupt counters */	.globl	_intrcnt,_eintrcnt,_intrnames,_eintrnames_intrnames:	.asciz	"spur"	.asciz	"lev1"	.asciz	"lev2"	.asciz	"lev3"	.asciz	"lev4"	.asciz	"clock"	.asciz	"lev7"	.asciz	"nmi"_eintrnames:	.even_intrcnt:	.long	0,0,0,0,0,0,0,0,0_eintrcnt:

⌨️ 快捷键说明

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