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

📄 locore.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 5 页
字号:
	movl	#84,sp@-		| default: adjust by 84 bytes	moveml	#0xFFFF,sp@-		| save user registers	movl	usp,a0			| save the user SP	movl	a0,sp@(FR_SP)		|   in the savearea	movl	#SYS_sigreturn,sp@-	| push syscall number	jbsr	_syscall		| handle it	addql	#4,sp			| pop syscall#	movl	sp@(FR_SP),a0		| grab and restore	movl	a0,usp			|   user SP	lea	sp@(FR_HW),a1		| pointer to HW frame	movw	sp@(FR_ADJ),d0		| do we need to adjust the stack?	jeq	Lsigr1			| no, just continue	moveq	#92,d1			| total size	subw	d0,d1			|  - hole size = frame size	lea	a1@(92),a0		| destination	addw	d1,a1			| source	lsrw	#1,d1			| convert to word count	subqw	#1,d1			| minus 1 for dbfLsigrlp:	movw	a1@-,a0@-		| copy a word	dbf	d1,Lsigrlp		| continue	movl	a0,a1			| new HW frame baseLsigr1:	movl	a1,sp@(FR_SP)		| new SP value	moveml	sp@+,#0x7FFF		| restore user registers	movl	sp@,sp			| and our SP	jra	rei			| all done/* * Interrupt handlers. * All DIO device interrupts are auto-vectored.  Most can be configured * to interrupt in the range IPL2 to IPL5.  Here are our assignments: * *	Level 0:	Spurious: ignored. *	Level 1:	(low XP) *	Level 2:	SCSI *	Level 3:	LANCE *	Level 4:	[PC98] *	Level 5:	Clock *	Level 6:	RS232C *	Level 7:	Non-maskable: parity errors, Abort SW */	.globl	_hardclock, _nmihand_spurintr:	addql	#1,_intrcnt+0	addql	#1,_cnt+V_INTR	jra	rei_lev1intr:	addql	#1,_intrcnt+4	addql	#1,_cnt+V_INTR	jra	rei			| XP not surpported yet	XXXX_lev2intr:	addql	#1,_intrcnt+8	moveml	#0xC0C0,sp@-	jbsr	__scintr		moveml	sp@+,#0x0303	addql	#1,_cnt+V_INTR	jra	rei_lev3intr:	addql	#1,_intrcnt+12	moveml	#0xC0C0,sp@-	jbsr	__leintr	moveml	sp@+,#0x0303	addql	#1,_cnt+V_INTR	jra	rei_lev4intr:	addql	#1,_intrcnt+16	addql	#1,_cnt+V_INTR	jra	rei			| EX-PC not surpported yet XXXX_lev6intr:	addql	#1,_intrcnt+24	moveml	#0xC0C0,sp@-	jbsr	__siointr	moveml	sp@+,#0x0303	addql	#1,_cnt+V_INTR	jra	rei_lev5intr:#ifdef STACKCHECK	.globl	_panicstr,_badkstack	cmpl	#_kstack+NBPG,sp	| are we still in stack page?	jcc	Lstackok		| yes, continue normally	tstl	_curproc		| if !curproc could have switch_exited,	jeq	Lstackok		|     might be on tmpstk	tstl	_panicstr		| have we paniced?	jne	Lstackok		| yes, do not re-panic	movl	sp@(4),tmpstk-4		| no, copy common	movl	sp@,tmpstk-8		|  frame info	movl	sp,tmpstk-16		| no, save original SP	lea	tmpstk-16,sp		| switch to tmpstk	moveml	#0xFFFE,sp@-		| push remaining registers	movl	#1,sp@-			| is an overflow	jbsr	_badkstack		| badkstack(1, frame)	addql	#4,sp	moveml	sp@+,#0x7FFF		| restore most registers	movl	sp@,sp			| and SPLstackok:#endif	moveml	#0xC0C0,sp@-	lea	sp@(16),a1		| a1 = &clockframe	btst	#CLK_INT,CLOCK_REG 	| system-clock intrrupt?	jeq	Lnottimer		| no, skip hardclock	movb	#CLK_CLR,CLOCK_REG	| clear system-clock interrupt        tstl	_clock_on		| system-clock started?        jeq	Lnottimer		| no, skip hardclock	addql	#1,_intrcnt+28		| count hardclock interrupt	movl	a1,sp@-	jbsr	_hardclock		| hardclock(&frame)	addql	#4,spLnottimer:	moveml	sp@+,#0x0303		| restore scratch regs	addql	#1,_cnt+V_INTR		| chalk up another interrupt	jra	rei			| all done_lev7intr:	addql	#1,_intrcnt+36	clrl	sp@-			| pad SR to longword	moveml	#0xFFFF,sp@-		| save registers	movl	usp,a0			| and save	movl	a0,sp@(FR_SP)		|   the user stack pointer	jbsr	_nmihand		| call handler	movl	sp@(FR_SP),a0		| restore	movl	a0,usp			|   user SP	moveml	sp@+,#0x7FFF		| and remaining registers	addql	#8,sp			| pop SSP and align word	jra	rei			| all done/* * Emulation of VAX REI instruction. * * This code deals with checking for and servicing ASTs * (profiling, scheduling) and software interrupts (network, softclock). * We check for ASTs first, just like the VAX.  To avoid excess overhead * the T_ASTFLT handling code will also check for software interrupts so we * do not have to do it here.  After identifing that we need an AST we * drop the IPL to allow device interrupts. * * This code is complicated by the fact that sendsig may have been called * necessitating a stack cleanup. */	.comm	_ssir,1	.globl	_astpendingrei:#ifdef STACKCHECK	tstl	_panicstr		| have we paniced?	jne	Ldorte1			| yes, do not make matters worse#endif	tstl	_astpending		| AST pending?	jeq	Lchksir			| no, go check for SIRLrei1:	btst	#5,sp@			| yes, are we returning to user mode?	jne	Lchksir			| no, go check for SIR	movw	#PSL_LOWIPL,sr		| lower SPL	clrl	sp@-			| stack adjust	moveml	#0xFFFF,sp@-		| save all registers	movl	usp,a1			| including	movl	a1,sp@(FR_SP)		|    the users SP	clrl	sp@-			| VA == none	clrl	sp@-			| code == none	movl	#T_ASTFLT,sp@-		| type == async system trap	jbsr	_trap			| go handle it	lea	sp@(12),sp		| pop value args	movl	sp@(FR_SP),a0		| restore user SP	movl	a0,usp			|   from save area	movw	sp@(FR_ADJ),d0		| need to adjust stack?	jne	Laststkadj		| yes, go to it	moveml	sp@+,#0x7FFF		| no, restore most user regs	addql	#8,sp			| toss SP and stack adjust#ifdef STACKCHECK	jra	Ldorte#else	rte				| and do real RTE#endifLaststkadj:	lea	sp@(FR_HW),a1		| pointer to HW frame	addql	#8,a1			| source pointer	movl	a1,a0			| source	addw	d0,a0			|  + hole size = dest pointer	movl	a1@-,a0@-		| copy	movl	a1@-,a0@-		|  8 bytes	movl	a0,sp@(FR_SP)		| new SSP	moveml	sp@+,#0x7FFF		| restore user registers	movl	sp@,sp			| and our SP#ifdef STACKCHECK	jra	Ldorte#else	rte				| and do real RTE#endifLchksir:	tstb	_ssir			| SIR pending?	jeq	Ldorte			| no, all done	movl	d0,sp@-			| need a scratch register	movw	sp@(4),d0		| get SR	andw	#PSL_IPL7,d0		| mask all but IPL	jne	Lnosir			| came from interrupt, no can do	movl	sp@+,d0			| restore scratch registerLgotsir:	movw	#SPL1,sr		| prevent others from servicing int	tstb	_ssir			| too late?	jeq	Ldorte			| yes, oh well...	clrl	sp@-			| stack adjust	moveml	#0xFFFF,sp@-		| save all registers	movl	usp,a1			| including	movl	a1,sp@(FR_SP)		|    the users SP	clrl	sp@-			| VA == none	clrl	sp@-			| code == none	movl	#T_SSIR,sp@-		| type == software interrupt	jbsr	_trap			| go handle it	lea	sp@(12),sp		| pop value args	movl	sp@(FR_SP),a0		| restore	movl	a0,usp			|   user SP	moveml	sp@+,#0x7FFF		| and all remaining registers	addql	#8,sp			| pop SP and stack adjust#ifdef STACKCHECK	jra	Ldorte#else	rte#endifLnosir:	movl	sp@+,d0			| restore scratch registerLdorte:#ifdef STACKCHECK	movw	#SPL6,sr		| avoid trouble	btst	#5,sp@			| are we returning to user mode?	jne	Ldorte1			| no, skip it	movl	a6,tmpstk-20	movl	d0,tmpstk-76	moveq	#0,d0	movb	sp@(6),d0		| get format/vector	lsrl	#3,d0			| convert to index	lea	_exframesize,a6		|  into exframesize	addl	d0,a6			|  to get pointer to correct entry	movw	a6@,d0			| get size for this frame	addql	#8,d0			| adjust for unaccounted for bytes	lea	_kstackatbase,a6	| desired stack base	subl	d0,a6			|   - frame size == our stack	cmpl	a6,sp			| are we where we think?	jeq	Ldorte2			| yes, skip it	lea	tmpstk,a6		| will be using tmpstk	movl	sp@(4),a6@-		| copy common	movl	sp@,a6@-		|   frame info	clrl	a6@-	movl	sp,a6@-			| save sp	subql	#4,a6			| skip over already saved a6	moveml	#0x7FFC,a6@-		| push remaining regs (d0/a6/a7 done)	lea	a6@(-4),sp		| switch to tmpstk (skip saved d0)	clrl	sp@-			| is an underflow	jbsr	_badkstack		| badkstack(0, frame)	addql	#4,sp	moveml	sp@+,#0x7FFF		| restore most registers	movl	sp@,sp			| and SP	rteLdorte2:	movl	tmpstk-76,d0	movl	tmpstk-20,a6Ldorte1:#endif	rte				| real return/* * Kernel access to the current processes kernel stack is via a fixed * virtual address.  It is at the same address as in the users VA space. * Umap contains the KVA of the first of UPAGES PTEs mapping VA _kstack. */	.data	.set	_kstack,KERNELSTACK	| KERNELSTACK(0x3ff00000) != USRSTACK_Umap:	.long	0	.globl	_kstack, _Umap/* * Initialization * * Kernel is loaded at 0. * VBR contains zero from ROM.  Exceptions will continue to vector * through ROM until MMU is turned on at which time they will vector * through our table (vectors.s). */	.comm	_lowram,4	.text	.globl	_edata	.globl	_etext,_end	.globl	startstart:	movw	#PSL_HIGHIPL,sr		| no interrupts	lea	tmpstk,sp		| give ourselves a temporary stack 	clrl	d0			| XXXX if loader set vbr = 0 	movc	d0,vbr			| XXXX please remove these 2 lines/*  * a5 contains parameters address from booter. * First, we copy whole parameters to Kernel InterFace Field */	movl	#KIFF_SIZE,sp@-		| KIFF size	pea	_KernInter		| KIFF address	pea	a5@			| bootor's KIFF address	jbsr	_bcopy	lea	sp@(12),sp		| pop value args	movl	a5@(KI_MAXADDR),d0	| maxaddr	moveq	#PGSHIFT,d1	lsrl	d1,d0			| convert to page (click) number	movl	d0,_maxmem		| argument saved in maxmem	movl	d0,_physmem		| physmem = maxmem	clrl	_lowram			| lowram = 0	movl	#0,a5			| kernel is loaded at 0	movl	#CACHE_OFF,d0	movc	d0,cacr			| clear and disable on-chip cache(s)#if defined(LUNA2)/* determine our CPU/MMU combo - check for all regardless of kernel config */	movl	#0x200,d0		| data freeze bit	movc	d0,cacr			|   only exists on 68030	movc	cacr,d0			| read it back	tstl	d0			| zero?	jeq	Lnot68030		| yes, we have 68040(LUNA2)	movl	#1,_machineid		| no, must be a LUNA-I	movl	#-1,_mmutype		| set to reflect 68030 PMMU	jra	Lstart1Lnot68030:	movl	#2,_machineid		| must be a LUNA-II	movl	#-2,_mmutype		| set to reflect 68040 MMU#ifdef HPFPLIB	movl	#3,_processor		| HP-UX style processor id#endifLstart1:#endif/* set 60 to hz, when running LUNA-I */	.globl	_modify_clock_param	jbsr	_modify_clock_param/* initialize source/destination control registers for movs */	moveq	#FC_USERD,d0		| user space	movc	d0,sfc			|   as source	movc	d0,dfc			|   and destination of transfers	/* * LUNA  PIO initialization. */	movw	PIO0_A,d0		| dipsw-1,2 (from port A&B)	movw	d0,_dipswitch/* configure kernel and proc0 VA space so we can get going */	.globl	_Sysseg, _pmap_bootstrap, _avail_start	movl	#_end,d5		| end of static kernel text/data	addl	#NBPG-1,d5	andl	#PG_FRAME,d5		| round to a page	movl	d5,a4			| PA=VA	pea	a5@			| firstpa	pea	a4@			| nextpa	jbsr	_pmap_bootstrap		| bootstrap(firstpa, nextpa)	addql	#8,sp/* * Prepare to enable MMU. */	movl	_Sysseg,d1		| system segment table addr read value (a KVA)#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040?	jne	Lmotommu1		| no, skip		.long	0x4e7b1807		| movc d1,srp/* we must set tt-registers here */	movl	#0x403FA040,d0		| tt0 for LUNA2 0x40000000-0x7fffffff	.long	0x4e7b0004		| movc d0,itt0	.long	0x4e7b0006		| movc d0,dtt0	movl	#0x807FA040,d0		| tt1 for LUNA2 0x80000000-0xffffffff	.long	0x4e7b0005		| movc d0,itt1	.long	0x4e7b0007		| movc d0,dtt1	.word	0xf4d8			| cinva bc	.word	0xf518			| pflusha	movl	#0x8000,d0	.long	0x4e7b0003		| movc d0,tc	movl	#0x80008000,d0	movc	d0,cacr			| turn on both caches	jmp	Lenab1Lmotommu1:#endif	lea	_protorp,a0	movl	#0x80000202,a0@		| nolimit + share global + 4 byte PTEs	movl	d1,a0@(4)		| + segtable address	pmove	a0@,srp			| load the supervisor root pointer	movl	#0x80000002,a0@		| reinit upper half for CRP loads/* we must set tt-registers here */	lea	_protott0,a0		| tt0 for LUNA1 0x40000000-0x7fffffff	.word	0xf010			| pmove	a0@,mmutt0	.word	0x0800	lea	_protott1,a0		| tt1 for LUNA1 0x80000000-0xffffffff	.word	0xf010			| pmove	a0@,mmutt1	.word	0x0c00	lea	_mapping_tc,a2	movl	#0x82c0aa00,a2@		| value to load TC with	pmove	a2@,tc			| load it/* * Should be running mapped from this point on */Lenab1:#ifdef FPCOPROC/* fpp check */	movl	a1,sp@-	jbsr	_checkfpp		| check fpp	frestore _fppnull		| reset	movl	sp@+,a1#endif/* select the software page size now */	lea	tmpstk,sp		| temporary stack	jbsr	_vm_set_page_size	| select software page size/* set kernel stack, user SP, and initial pcb */	lea	_kstack,a1		| proc0 kernel stack	lea	a1@(UPAGES*NBPG-4),sp	| set kernel stack to end of area	movl	#USRSTACK-4,a2	movl	a2,usp			| init user SP	movl	_proc0paddr,a1		| get proc0 pcb addr	movl	a1,_curpcb		| proc0 is running#ifdef FPCOPROC	clrl	a1@(PCB_FPCTX)		| ensure null FP context	movl	a1,sp@-	jbsr	_m68881_restore		| restore it (does not kill a1)	addql	#4,sp#endif/* flush TLB and turn on caches */	jbsr	_TBIA			| invalidate TLB#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040?	jeq	Lnocache0		| yes, cache already on#endif	movl	#CACHE_ON,d0	movc	d0,cacr			| clear cache(s)Lnocache0:/* final setup for C code */	movw	#PSL_LOWIPL,sr		| lower SPL	movl	d7,_boothowto		| save reboot flags	movl	d6,_bootdev		|   and boot device/* * Create a fake exception frame that returns to user mode, * make space for the rest of a fake saved register set, and * pass the first available RAM and a pointer to the register * set to "main()".  "main()" will call "icode()", which fakes * an "execve()" system call, which is why we need to do that * ("main()" sets "u.u_ar0" to point to the register set). * When "main()" returns, we're running in process 1 and have * successfully faked the "execve()".  We load up the registers from * that set; the "rte" loads the PC and PSR, which jumps to "init". */  	clrw	sp@-			| vector offset/frame type	clrl	sp@-			| PC - filled in by "execve"  	movw	#PSL_USER,sp@-		| in user mode	clrw	sp@-			| pad SR to longword	lea	sp@(-64),sp		| construct space for D0-D7/A0-A7	pea	sp@			| addr of space for D0	jbsr	_main			| main(firstaddr, r0)	addql	#4,sp			| pop args#if defined(LUNA2)	cmpl	#-2,_mmutype		| 68040?	jne	Lnoflush		| no, skip	.word	0xf478			| cpusha dc	.word	0xf498			| cinva icLnoflush:#endif	movl	sp@(60),a0		| grab and load	movl	a0,usp			|   user SP	moveml	sp@+,#0x7FFF		| load most registers (all but SSP)	addql	#6,sp			| pop SSP and align word  	rte/* * Signal "trampoline" code (18 bytes).  Invoked from RTE setup by sendsig(). *  * Stack looks like: * *	sp+0 ->	signal number *	sp+4	signal specific code *	sp+8	pointer to signal context frame (scp) *	sp+12	address of handler *	sp+16	saved hardware state *			. *			. *	scp+0->	beginning of signal context frame */	.globl	_sigcode, _esigcode, _sigcodetrap	.data_sigcode:	movl	sp@(12),a0		| signal handler addr	(4 bytes)	jsr	a0@			| call signal handler	(2 bytes)	addql	#4,sp			| pop signo		(2 bytes)_sigcodetrap:	trap	#1			| special syscall entry	(2 bytes)	movl	d0,sp@(4)		| save errno		(4 bytes)	moveq	#1,d0			| syscall == exit	(2 bytes)	trap	#0			| exit(errno)		(2 bytes)	.align	2

⌨️ 快捷键说明

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