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

📄 locore.s

📁 早期freebsd实现
💻 S
📖 第 1 页 / 共 5 页
字号:
 * that when the MMU is turned on, all prefetched addresses (including * the PC) are valid.  In order guarentee that, we use the last physical * page (which is conveniently mapped == VA) and load it up with enough * code to defeat the prefetch, then we execute the jump back to here. * * Is this all really necessary, or am I paranoid?? */	RELOC(_Sysseg, a0)		| system segment table addr	movl	a0@,d1			| read value (a KVA)	addl	a5,d1			| convert to PA	RELOC(_mmutype, a0)	tstl	a0@			| HP MMU?	jeq	Lhpmmu2			| yes, skip	cmpl	#-2,a0@			| 68040?	jne	Lmotommu1		| no, skip	.long	0x4e7b1807		| movc d1,srp	jra	LstploaddoneLmotommu1:	RELOC(_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	jra	Lstploaddone		| doneLhpmmu2:	moveq	#PGSHIFT,d2	lsrl	d2,d1			| convert to page frame	movl	d1,INTIOBASE+MMUBASE+MMUSSTP | load in sysseg table registerLstploaddone:	lea	MAXADDR,a2		| PA of last RAM page	RELOC(Lhighcode, a1)		| addr of high code	RELOC(Lehighcode, a3)		| end addrLcodecopy:	movw	a1@+,a2@+		| copy a word	cmpl	a3,a1			| done yet?	jcs	Lcodecopy		| no, keep going	jmp	MAXADDR			| go for it!Lhighcode:	RELOC(_mmutype, a0)	tstl	a0@			| HP MMU?	jeq	Lhpmmu3			| yes, skip	cmpl	#-2,a0@			| 68040?	jne	Lmotommu2		| no, skip	movw	#0,INTIOBASE+MMUBASE+MMUCMD+2	movw	#MMU_IEN+MMU_CEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD+2					| enable FPU and caches	moveq	#0,d0			| ensure TT regs are disabled	.long	0x4e7b0004		| movc d0,itt0	.long	0x4e7b0005		| movc d0,itt1	.long	0x4e7b0006		| movc d0,dtt0	.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	Lenab1Lmotommu2:	movl	#MMU_IEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD					| enable 68881 and i-cache	movl	#0x82c0aa00,a2@		| value to load TC with	pmove	a2@,tc			| load it	jmp	Lenab1Lhpmmu3:	movl	#0,INTIOBASE+MMUBASE+MMUCMD	| clear external cache	movl	#MMU_ENAB,INTIOBASE+MMUBASE+MMUCMD | turn on MMU	jmp	Lenab1				| jmp to mapped codeLehighcode:/* * Should be running mapped from this point on */Lenab1:/* check for internal HP-IB in SYSFLAG */	btst	#5,0xfffffed2		| internal HP-IB?	jeq	Lfinish			| yes, have HP-IB just continue	clrl	_internalhpib		| no, clear associated addressLfinish:/* 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	cmpl	#-2,_mmutype		| 68040?	jeq	Lnocache0		| yes, cache already on	movl	#CACHE_ON,d0	movc	d0,cacr			| clear cache(s)	tstl	_ectype	jeq	Lnocache0	MMUADDR(a0)	orl	#MMU_CEN,a0@(MMUCMD)	| turn on external cacheLnocache0:/* final setup for C code */	jbsr	_isrinit		| be ready for stray ints	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	cmpl	#-2,_mmutype		| 68040?	jne	Lnoflush		| no, skip	.word	0xf478			| cpusha dc	.word	0xf498			| cinva icLnoflush:	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_esigcode:/* * Primitives */ #ifdef __STDC__#define EXPORT(name)		.globl _ ## name; _ ## name:#else#define EXPORT(name)		.globl _/**/name; _/**/name:#endif#ifdef GPROF#if __GNUC__ >= 2#define	ENTRY(name)		EXPORT(name) link a6,\#0; jbsr mcount; unlk a6#else#define	ENTRY(name)		EXPORT(name) link a6,#0; jbsr mcount; unlk a6#endif#define ALTENTRY(name, rname)	ENTRY(name); jra rname+12#else#define	ENTRY(name)		EXPORT(name)#define ALTENTRY(name, rname) 	ENTRY(name)#endif/* * For gcc2 */ENTRY(__main)	rts/* * copypage(fromaddr, toaddr) * * Optimized version of bcopy for a single page-aligned NBPG byte copy. */ENTRY(copypage)	movl	sp@(4),a0		| source address	movl	sp@(8),a1		| destination address	movl	#NBPG/32,d0		| number of 32 byte chunks#if defined(HP380)	cmpl	#-2,_mmutype		| 68040?	jne	Lmlloop			| no, use movlLm16loop:	.long	0xf6209000		| move16 a0@+,a1@+	.long	0xf6209000		| move16 a0@+,a1@+	subql	#1,d0	jne	Lm16loop	rts#endifLmlloop:	movl	a0@+,a1@+	movl	a0@+,a1@+	movl	a0@+,a1@+	movl	a0@+,a1@+	movl	a0@+,a1@+	movl	a0@+,a1@+	movl	a0@+,a1@+	movl	a0@+,a1@+	subql	#1,d0	jne	Lmlloop	rts/* * copyinstr(fromaddr, toaddr, maxlength, &lencopied) * * Copy a null terminated string from the user address space into * the kernel address space. * * NOTE: maxlength must be < 64K (due to use of DBcc) */ENTRY(copyinstr)	movl	_curpcb,a0		| current pcb	movl	#Lcisflt1,a0@(PCB_ONFAULT) | set up to catch faults	movl	sp@(4),a0		| a0 = fromaddr	movl	sp@(8),a1		| a1 = toaddr	moveq	#0,d0	movw	sp@(14),d0		| d0 = maxlength	jlt	Lcisflt1		| negative count, error	jeq	Lcisdone		| zero count, all done	subql	#1,d0			| set up for dbeqLcisloop:	movsb	a0@+,d1			| grab a byte	nop	movb	d1,a1@+			| copy it	dbeq	d0,Lcisloop		| if !null and more, continue	jne	Lcisflt2		| ran out of room, error	moveq	#0,d0			| got a null, all doneLcisdone:	tstl	sp@(16)			| return length desired?	jeq	Lcisret			| no, just return	subl	sp@(4),a0		| determine how much was copied	movl	sp@(16),a1		| return location	movl	a0,a1@			| stash itLcisret:	movl	_curpcb,a0		| current pcb	clrl	a0@(PCB_ONFAULT) 	| clear fault addr	rtsLcisflt1:	moveq	#EFAULT,d0		| copy fault	jra	LcisdoneLcisflt2:	moveq	#ENAMETOOLONG,d0	| ran out of space	jra	Lcisdone	/* * copyoutstr(fromaddr, toaddr, maxlength, &lencopied) * * Copy a null terminated string from the kernel * address space to the user address space. * * NOTE: maxlength must be < 64K (due to use of DBcc) */ENTRY(copyoutstr)	movl	_curpcb,a0		| current pcb	movl	#Lcosflt1,a0@(PCB_ONFAULT) | set up to catch faults	movl	sp@(4),a0		| a0 = fromaddr	movl	sp@(8),a1		| a1 = toaddr	moveq	#0,d0	movw	sp@(14),d0		| d0 = maxlength	jlt	Lcosflt1		| negative count, error	jeq	Lcosdone		| zero count, all done	subql	#1,d0			| set up for dbeqLcosloop:	movb	a0@+,d1			| grab a byte	movsb	d1,a1@+			| copy it	nop	dbeq	d0,Lcosloop		| if !null and more, continue	jne	Lcosflt2		| ran out of room, error	moveq	#0,d0			| got a null, all doneLcosdone:	tstl	sp@(16)			| return length desired?	jeq	Lcosret			| no, just return	subl	sp@(4),a0		| determine how much was copied	movl	sp@(16),a1		| return location	movl	a0,a1@			| stash itLcosret:	movl	_curpcb,a0		| current pcb	clrl	a0@(PCB_ONFAULT) 	| clear fault addr	rtsLcosflt1:	moveq	#EFAULT,d0		| copy fault	jra	LcosdoneLcosflt2:	moveq	#ENAMETOOLONG,d0	| ran out of space	jra	Lcosdone	/* * copystr(fromaddr, toaddr, maxlength, &lencopied) * * Copy a null terminated string from one point to another in * the kernel address space. * * NOTE: maxlength must be < 64K (due to use of DBcc) */ENTRY(copystr)	movl	sp@(4),a0		| a0 = fromaddr	movl	sp@(8),a1		| a1 = toaddr	moveq	#0,d0	movw	sp@(14),d0		| d0 = maxlength	jlt	Lcsflt1			| negative count, error	jeq	Lcsdone			| zero count, all done	subql	#1,d0			| set up for dbeqLcsloop:	movb	a0@+,a1@+		| copy a byte	dbeq	d0,Lcsloop		| if !null and more, continue	jne	Lcsflt2			| ran out of room, error	moveq	#0,d0			| got a null, all doneLcsdone:	tstl	sp@(16)			| return length desired?	jeq	Lcsret			| no, just return	subl	sp@(4),a0		| determine how much was copied	movl	sp@(16),a1		| return location	movl	a0,a1@			| stash itLcsret:	rtsLcsflt1:	moveq	#EFAULT,d0		| copy fault	jra	LcsdoneLcsflt2:	moveq	#ENAMETOOLONG,d0	| ran out of space	jra	Lcsdone	/*  * Copyin(from_user, to_kernel, len) * Copyout(from_kernel, to_user, len) * * Copy specified amount of data between kernel and user space. * * XXX both use the DBcc instruction which has 16-bit limitation so only * 64k units can be copied, where "unit" is either a byte or a longword * depending on alignment.  To be safe, assume it can copy at most * 64k bytes.  Don't make MAXBSIZE or MAXPHYS larger than 64k without * fixing this code! */ENTRY(copyin)	movl	sp@(12),d0		| get size#ifdef MAPPEDCOPY	.globl	_mappedcopysize,_mappedcopyin	cmpl	_mappedcopysize,d0	| size >= mappedcopysize	jcc	_mappedcopyin		| yes, go do it the new way#endif	movl	d2,sp@-			| scratch register	movl	_curpcb,a0		| current pcb	movl	#Lciflt,a0@(PCB_ONFAULT) | set up to catch faults	tstl	d0			| check count	jlt	Lciflt			| negative, error	jeq	Lcidone			| zero, done	movl	sp@(8),a0		| src address	movl	sp@(12),a1		| dest address	movl	a0,d2	btst	#0,d2			| src address odd?	jeq	Lcieven			| no, go check dest	movsb	a0@+,d1			| yes, get a byte	nop	movb	d1,a1@+			| put a byte	subql	#1,d0			| adjust count	jeq	Lcidone			| exit if doneLcieven:	movl	a1,d2	btst	#0,d2			| dest address odd?	jne	Lcibloop		| yes, must copy by bytes	movl	d0,d2			| no, get count	lsrl	#2,d2			| convert to longwords	jeq	Lcibloop		| no longwords, copy bytesLcilloop:	movsl	a0@+,d1			| get a long	nop	movl	d1,a1@+			| put a long	subql	#1,d2	jne	Lcilloop		| til done	andl	#3,d0			| what remains	jeq	Lcidone			| all doneLcibloop:	movsb	a0@+,d1			| get a byte	nop	movb	d1,a1@+			| put a byte	subql	#1,d0	jne	Lcibloop		| til doneLcidone:	movl	_curpcb,a0		| current pcb	clrl	a0@(PCB_ONFAULT) 	| clear fault catcher	movl	sp@+,d2			| restore scratch reg	rtsLciflt:	moveq	#EFAULT,d0		| got a fault	jra	LcidoneENTRY(copyout)	movl	sp@(12),d0		| get size#ifdef MAPPEDCOPY	.globl	_mappedcopysize,_mappedcopyout	cmpl	_mappedcopysize,d0	| size >= mappedcopysize	jcc	_mappedcopyout		| yes, go do it the new way#endif	movl	d2,sp@-			| scratch register	movl	_curpcb,a0		| current pcb	movl	#Lcoflt,a0@(PCB_ONFAULT) | catch faults	tstl	d0			| check count	jlt	Lcoflt			| negative, error	jeq	Lcodone			| zero, done	movl	sp@(8),a0		| src address	movl	sp@(12),a1		| dest address	movl	a0,d2	btst	#0,d2			| src address odd?	jeq	Lcoeven			| no, go check dest	movb	a0@+,d1			| yes, get a byte	movsb	d1,a1@+			| put a byte	nop	subql	#1,d0			| adjust count	jeq	Lcodone			| exit if doneLcoeven:	movl	a1,d2	btst	#0,d2			| dest address odd?	jne	Lcobloop		| yes, must copy by bytes	movl	d0,d2			| no, get count	lsrl	#2,d2			| convert to longwords	jeq	Lcobloop		| no longwords, copy bytesLcolloop:	movl	a0@+,d1			| get a long	movsl	d1,a1@+			| put a long	nop	subql	#1,d2	jne	Lcolloop		| til done	andl	#3,d0			| what remains	jeq	Lcodone			| all doneLcobloop:	movb	a0@+,d1			| get a byte	movsb	d1,a1@+			| put a byte	nop	subql	#1,d0	jne	Lcobloop		| til doneLcodone:	movl	_curpcb,a0		| current pcb	clrl	a0@(PCB_ONFAULT) 	| clear fault catcher	movl	sp@+,d2			| restore scratch reg	rtsLcoflt:	moveq	#EFAULT,d0		| got a fault	jra	Lcodone/* * non-local gotos */ENTRY(setjmp)	movl	sp@(4),a0	| savearea pointer	moveml	#0xFCFC,a0@	| save d2-d7/a2-a7	movl	sp@,a0@(48)	| and return address	moveq	#0,d0		| return 0	rtsENTRY(longjmp)	movl	sp@(4),a0	moveml	a0@+,#0xFCFC	movl	a0@,sp@	moveq	#1,d0	rts/* * The following primitives manipulate the run queues.  _whichqs tells which * of the 32 queues _qs have processes in them.  Setrunqueue puts processes * into queues, Remrq removes them from queues.  The running process is on * no queue, other processes are on a queue related to p->p_priority, divided * by 4 actually to shrink the 0-127 range of priorities into the 32 available * queues. */	.globl	_whichqs,_qs,_cnt,_panic	.globl	_curproc,_want_resched/* * Setrunqueue(p) *

⌨️ 快捷键说明

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