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

📄 locore.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 5 页
字号:
#ifdef KGDB	moveq	#T_TRACE,d0	movw	sp@(FR_HW),d1		| get SSW	andw	#PSL_S,d1		| from user mode?	jeq	fault			| no, regular fault	movl	d0,sp@-	jbsr	_kgdb_trap_glue		| returns if no debugger	addl	#4,sp#endif	moveq	#T_TRACE,d0	jra	fault/* * The sigreturn() syscall comes here.  It requires special handling * because we must open a hole in the stack to fill in the (possibly much * larger) original stack frame. */sigreturn:	lea	sp@(-84),sp		| leave enough space for largest frame	movl	sp@(84),sp@		| move up current 8 byte frame	movl	sp@(88),sp@(4)	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 IPL3 to IPL5.  Here are our assignments: * *	Level 0:	Spurious: ignored. *	Level 1:	HIL *	Level 2: *	Level 3:	Internal HP-IB, DCM *	Level 4:	"Fast" HP-IBs, SCSI *	Level 5:	DMA, Ethernet, Built-in RS232 (DCA) *	Level 6:	Clock *	Level 7:	Non-maskable: parity errors, RESET key */	.globl	_hilint, _intrhand, _hardclock, _nmihand, _dmaintr	.globl	_dcafastservice_spurintr:	addql	#1,_intrcnt+0	addql	#1,_cnt+V_INTR	jra	rei_lev1intr:	moveml	#0xC0C0,sp@-	jbsr	_hilint	moveml	sp@+,#0x0303	addql	#1,_intrcnt+4	addql	#1,_cnt+V_INTR	jra	rei/* * Check for unbuffered serial port (DCA) interrupts first in an attempt * to minimize received character lossage.  Then we check for DMA activity * to reduce overhead there. */_lev5intr:	moveml	#0xC0C0,sp@-	tstl	_dcafastservice		| unbuffered port active?	jeq	Ltrydma			| no, check DMA	clrl	sp@-			| yes, check DCA port 0	jbsr	_dcaintr		|    first to avoid overflow	addql	#4,sp	tstl	d0			| did it belong to DCA?	jeq	Ltrydma			| no, go try DMA	moveml	sp@+,#0x0303	addql	#1,_intrcnt+20	addql	#1,_cnt+V_INTR	jra	reiLtrydma:	jbsr	_dmaintr		| check DMA channels	tstl	d0 			| was it ours?	jeq	Lnotdma			| no, go poll other devices	moveml	sp@+,#0x0303	addql	#1,_intrcnt+24	addql	#1,_cnt+V_INTR	jra	rei_lev2intr:_lev3intr:_lev4intr:	moveml	#0xC0C0,sp@-Lnotdma:	lea	_intrcnt,a0	movw	sp@(22),d0		| use vector offset	andw	#0xfff,d0		|   sans frame type	addql	#1,a0@(-0x60,d0:w)	|     to increment apropos counter	movw	sr,sp@-			| push current SR value	clrw	sp@-			|    padded to longword	jbsr	_intrhand		| handle interrupt	addql	#4,sp			| pop SR	moveml	sp@+,#0x0303	addql	#1,_cnt+V_INTR	jra	rei_lev6intr:#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@-		| save scratch registers	CLKADDR(a0)	movb	a0@(CLKSR),d0		| read clock statusLclkagain:	btst	#0,d0			| clear timer1 int immediately to	jeq	Lnotim1			|  minimize chance of losing another	movpw	a0@(CLKMSB1),d1		|  due to statintr processing delayLnotim1:	btst	#2,d0			| timer3 interrupt?	jeq	Lnotim3			| no, skip statclock	movpw	a0@(CLKMSB3),d1		| clear timer3 interrupt	addql	#1,_intrcnt+32		| count clock interrupts	lea	sp@(16),a1		| a1 = &clockframe	movl	d0,sp@-			| save status	movl	a1,sp@-	jbsr	_statintr		| statintr(&frame)	addql	#4,sp	movl	sp@+,d0			| restore pre-statintr status	CLKADDR(a0)Lnotim3:	btst	#0,d0			| timer1 interrupt?	jeq	Lrecheck		| no, skip hardclock	addql	#1,_intrcnt+28		| count hardclock interrupts	lea	sp@(16),a1		| a1 = &clockframe	movl	a1,sp@-#ifdef USELEDS	.globl	_ledaddr, _inledcontrol, _ledcontrol, _hz	tstl	_ledaddr		| using LEDs?	jeq	Lnoled0			| no, skip this code	movl	heartbeat,d0		| get tick count	addql	#1,d0			|  increment	movl	_hz,d1	lsrl	#1,d1			| throb twice a second	cmpl	d0,d1			| are we there yet?	jne	Lnoled1			| no, nothing to do	tstl	_inledcontrol		| already updating LEDs?	jne	Lnoled2			| yes, skip it	movl	#LED_PULSE,sp@-	movl	#LED_DISK+LED_LANRCV+LED_LANXMT,sp@-	clrl	sp@-	jbsr	_ledcontrol		| toggle pulse, turn all others off	lea	sp@(12),spLnoled2:	movql	#0,d0Lnoled1:	movl	d0,heartbeatLnoled0:#endif	jbsr	_hardclock		| hardclock(&frame)	addql	#4,sp	CLKADDR(a0)Lrecheck:	addql	#1,_cnt+V_INTR		| chalk up another interrupt	movb	a0@(CLKSR),d0		| see if anything happened	jmi	Lclkagain		|  while we were in hardclock/statintr	moveml	sp@+,#0x0303		| restore scratch registers	jra	rei			| all done_lev7intr:	addql	#1,_intrcnt+36	clrl	sp@-	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 SP and stack adjust	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,USRSTACK	.set	_kstackatbase,USRSTACK+UPAGES*NBPG-4	.globl	_kstackatbase_Umap:	.long	0	.globl	_kstack, _Umap#define	RELOC(var, ar)	\	lea	var,ar;	\	addl	a5,ar/* * Initialization * * A5 contains physical load point from boot * 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	RELOC(tmpstk, a0)	movl	a0,sp			| give ourselves a temporary stack	RELOC(_lowram, a0)	movl	a5,a0@			| store start of physical memory	movl	#CACHE_OFF,d0	movc	d0,cacr			| clear and disable on-chip cache(s)/* determine our CPU/MMU combo - check for all regardless of kernel config */	movl	#INTIOBASE+MMUBASE,a1	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 68020/68040	RELOC(_mmutype, a0)		| no, we have 68030	movl	#-1,a0@			| set to reflect 68030 PMMU	RELOC(_machineid, a0)	movl	#0x80,a1@(MMUCMD)	| set magic cookie	movl	a1@(MMUCMD),d0		| read it back	btst	#7,d0			| cookie still on?	jeq	Lnot370			| no, 360 or 375	movl	#0,a1@(MMUCMD)		| clear magic cookie	movl	a1@(MMUCMD),d0		| read it back	btst	#7,d0			| still on?	jeq	Lisa370			| no, must be a 370	movl	#5,a0@			| yes, must be a 340	jra	Lstart1Lnot370:	movl	#3,a0@			| type is at least a 360	movl	#0,a1@(MMUCMD)		| clear magic cookie2	movl	a1@(MMUCMD),d0		| read it back	btst	#16,d0			| still on?	jeq	Lstart1			| no, must be a 360	movl	#6,a0@			| yes, must be a 345/375	jra	LhaspacLisa370:	movl	#4,a0@			| set to 370Lhaspac:	RELOC(_ectype, a0)	movl	#-1,a0@			| also has a physical address cache	jra	Lstart1Lnot68030:	bset	#31,d0			| data cache enable bit	movc	d0,cacr			|   only exists on 68040	movc	cacr,d0			| read it back	tstl	d0			| zero?	beq	Lis68020		| yes, we have 68020	moveq	#0,d0			| now turn it back off	movec	d0,cacr			|   before we access any data	RELOC(_mmutype, a0)	movl	#-2,a0@			| with a 68040 MMU	RELOC(_ectype, a0)	movl	#0,a0@			| and no cache (for now XXX)#ifdef HPFPLIB	RELOC(_processor, a0)	movl	#3,a0@			| HP-UX style processor id#endif	RELOC(_machineid, a0)	movl	a1@(MMUCMD),d0		| read MMU register	lsrl	#8,d0			| get apparent ID	cmpb	#6,d0			| id == 6?	jeq	Lis33mhz		| yes, we have a 433s	movl	#7,a0@			| no, we have a 380/425t	jra	Lstart1Lis33mhz:	movl	#8,a0@			| 433s (XXX 425s returns same ID, ugh!)	jra	Lstart1Lis68020:	movl	#1,a1@(MMUCMD)		| a 68020, write HP MMU location	movl	a1@(MMUCMD),d0		| read it back	btst	#0,d0			| non-zero?	jne	Lishpmmu		| yes, we have HP MMU	RELOC(_mmutype, a0)	movl	#1,a0@			| no, we have PMMU	RELOC(_machineid, a0)	movl	#1,a0@			| and 330 CPU	jra	Lstart1Lishpmmu:	RELOC(_ectype, a0)		| 320 or 350	movl	#1,a0@			| both have a virtual address cache	movl	#0x80,a1@(MMUCMD)	| set magic cookie	movl	a1@(MMUCMD),d0		| read it back	btst	#7,d0			| cookie still on?	jeq	Lstart1			| no, just a 320	RELOC(_machineid, a0)	movl	#2,a0@			| yes, a 350Lstart1:	movl	#0,a1@(MMUCMD)		| clear out MMU again/* 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/* initialize memory sizes (for pmap_bootstrap) */	movl	#MAXADDR,d1		| last page	moveq	#PGSHIFT,d2	lsrl	d2,d1			| convert to page (click) number	RELOC(_maxmem, a0)	movl	d1,a0@			| save as maxmem	movl	a5,d0			| lowram value from ROM via boot	lsrl	d2,d0			| convert to page number	subl	d0,d1			| compute amount of RAM present	RELOC(_physmem, a0)	movl	d1,a0@			| and physmem/* 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	addl	a5,a4			| convert to PA	pea	a5@			| firstpa	pea	a4@			| nextpa	RELOC(_pmap_bootstrap,a0)	jbsr	a0@			| pmap_bootstrap(firstpa, nextpa)	addql	#8,sp/* * Prepare to enable MMU. * Since the kernel is not mapped logical == physical we must insure

⌨️ 快捷键说明

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