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

📄 l.s

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 S
字号:
#include "mem.h"/* * Entered here from Compaq's bootldr with MMU disabled. */TEXT _start(SB), $-4	MOVW	$setR12(SB), R12		/* load the SB */_main:	/* SVC mode, interrupts disabled */	MOVW	$(PsrDirq|PsrDfiq|PsrMsvc), R1	MOVW	R1, CPSR	/* disable the MMU */	MOVW	$0x130, R1	MCR     CpMMU, 0, R1, C(CpControl), C(0x0)	/* flush caches */	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0	/* drain prefetch */	MOVW	R0,R0							MOVW	R0,R0	MOVW	R0,R0	MOVW	R0,R0	/* drain write buffer */	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4	MOVW	$(MACHADDR+BY2PG), R13		/* stack */	SUB	$4, R13				/* link */	BL	main(SB)	BL	exit(SB)	/* we shouldn't get here */_mainloop:	B	_mainloop	BL	_div(SB)			/* hack to get _div etc loaded *//* flush tlb's */TEXT mmuinvalidate(SB), $-4	MCR	CpMMU, 0, R0, C(CpTLBFlush), C(0x7)	RET/* flush tlb's */TEXT mmuinvalidateaddr(SB), $-4	MCR	CpMMU, 0, R0, C(CpTLBFlush), C(0x6), 1	RET/* write back and invalidate i and d caches */TEXT cacheflush(SB), $-4	/* write back any dirty data */	MOVW	$0xe0000000,R0	ADD	$(8*1024),R0,R1_cfloop:	MOVW.P	32(R0),R2	CMP.S	R0,R1	BNE	_cfloop		/* drain write buffer and invalidate i&d cache contents */	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0	/* drain prefetch */	MOVW	R0,R0							MOVW	R0,R0	MOVW	R0,R0	MOVW	R0,R0	RET/* write back d cache */TEXT cachewb(SB), $-4	/* write back any dirty data */_cachewb:	MOVW	$0xe0000000,R0	ADD	$(8*1024),R0,R1_cwbloop:	MOVW.P	32(R0),R2	CMP.S	R0,R1	BNE	_cwbloop		/* drain write buffer */	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4	RET/* write back a single cache line */TEXT cachewbaddr(SB), $-4	BIC	$31,R0	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1	B	_wbflush/* write back a region of cache lines */TEXT cachewbregion(SB), $-4	MOVW	4(FP),R1	CMP.S	$(4*1024),R1	BGT	_cachewb	ADD	R0,R1	BIC	$31,R0_cwbrloop:	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1	ADD	$32,R0	CMP.S	R0,R1	BGT	_cwbrloop	B	_wbflush/* invalidate the dcache */TEXT dcacheinvalidate(SB), $-4	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x6)	RET/* invalidate the icache */TEXT icacheinvalidate(SB), $-4	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x9)	RET/* drain write buffer */TEXT wbflush(SB), $-4_wbflush:	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4	RET/* return cpu id */TEXT getcpuid(SB), $-4	MRC	CpMMU, 0, R0, C(CpCPUID), C(0x0)	RET/* return fault status */TEXT getfsr(SB), $-4	MRC	CpMMU, 0, R0, C(CpFSR), C(0x0)	RET/* return fault address */TEXT getfar(SB), $-4	MRC	CpMMU, 0, R0, C(CpFAR), C(0x0)	RET/* return fault address */TEXT putfar(SB), $-4	MRC	CpMMU, 0, R0, C(CpFAR), C(0x0)	RET/* set the translation table base */TEXT putttb(SB), $-4	MCR	CpMMU, 0, R0, C(CpTTB), C(0x0)	RET/* *  enable mmu, i and d caches */TEXT mmuenable(SB), $-4	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)	ORR	$(CpCmmuena|CpCdcache|CpCicache|CpCwb), R0	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)	RETTEXT mmudisable(SB), $-4	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)	BIC	$(CpCmmuena|CpCdcache|CpCicache|CpCwb|CpCvivec), R0	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)	RET/* *  use exception vectors at 0xffff0000 */TEXT mappedIvecEnable(SB), $-4	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)	ORR	$(CpCvivec), R0	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)	RETTEXT mappedIvecDisable(SB), $-4	MRC	CpMMU, 0, R0, C(CpControl), C(0x0)	BIC	$(CpCvivec), R0	MCR     CpMMU, 0, R0, C(CpControl), C(0x0)	RET/* set the translation table base */TEXT putdac(SB), $-4	MCR	CpMMU, 0, R0, C(CpDAC), C(0x0)	RET/* set address translation pid */TEXT putpid(SB), $-4	MCR	CpMMU, 0, R0, C(CpPID), C(0x0)	RET/* *  set the stack value for the mode passed in R0 */TEXT setr13(SB), $-4	MOVW	4(FP), R1	MOVW	CPSR, R2	BIC	$PsrMask, R2, R3	ORR	R0, R3	MOVW	R3, CPSR	MOVW	R13, R0	MOVW	R1, R13	MOVW	R2, CPSR	RET/* *  exception vectors, copied by trapinit() to somewhere useful */TEXT vectors(SB), $-4	MOVW	0x18(R15), R15			/* reset */	MOVW	0x18(R15), R15			/* undefined */	MOVW	0x18(R15), R15			/* SWI */	MOVW	0x18(R15), R15			/* prefetch abort */	MOVW	0x18(R15), R15			/* data abort */	MOVW	0x18(R15), R15			/* reserved */	MOVW	0x18(R15), R15			/* IRQ */	MOVW	0x18(R15), R15			/* FIQ */TEXT vtable(SB), $-4	WORD	$_vsvc(SB)			/* reset, in svc mode already */	WORD	$_vund(SB)			/* undefined, switch to svc mode */	WORD	$_vsvc(SB)			/* swi, in svc mode already */	WORD	$_vpabt(SB)			/* prefetch abort, switch to svc mode */	WORD	$_vdabt(SB)			/* data abort, switch to svc mode */	WORD	$_vsvc(SB)			/* reserved */	WORD	$_virq(SB)			/* IRQ, switch to svc mode */	WORD	$_vfiq(SB)			/* FIQ, switch to svc mode */TEXT _vrst(SB), $-4	BL	resettrap(SB)TEXT _vsvc(SB), $-4			/* SWI */	MOVW.W	R14, -4(R13)		/* ureg->pc = interupted PC */	MOVW	SPSR, R14		/* ureg->psr = SPSR */	MOVW.W	R14, -4(R13)		/* ... */	MOVW	$PsrMsvc, R14		/* ureg->type = PsrMsvc */	MOVW.W	R14, -4(R13)		/* ... */	MOVM.DB.W.S [R0-R14], (R13)	/* save user level registers, at end r13 points to ureg */	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */	MOVW	R13, R0			/* first arg is pointer to ureg */	SUB	$8, R13			/* space for argument+link */	BL	syscall(SB)	ADD	$(8+4*15), R13		/* make r13 point to ureg->type */	MOVW	8(R13), R14		/* restore link */	MOVW	4(R13), R0		/* restore SPSR */	MOVW	R0, SPSR		/* ... */	MOVM.DB.S (R13), [R0-R14]	/* restore registers */	ADD	$8, R13			/* pop past ureg->{type+psr} */	RFE				/* MOVM.IA.S.W (R13), [R15] */TEXT _vund(SB), $-4			/* undefined */	MOVM.IA	[R0-R4], (R13)		/* free some working space */	MOVW	$PsrMund, R0	B	_vswitchTEXT _vpabt(SB), $-4			/* prefetch abort */	MOVM.IA	[R0-R4], (R13)		/* free some working space */	MOVW	$PsrMabt, R0		/* r0 = type */	B	_vswitchTEXT _vdabt(SB), $-4			/* prefetch abort */	MOVM.IA	[R0-R4], (R13)		/* free some working space */	MOVW	$(PsrMabt+1), R0		/* r0 = type */	B	_vswitchTEXT _virq(SB), $-4			/* IRQ */	MOVM.IA	[R0-R4], (R13)		/* free some working space */	MOVW	$PsrMirq, R0		/* r0 = type */	B	_vswitch	/*	 *  come here with type in R0 and R13 pointing above saved [r0-r4]	 *  and type in r0.  we'll switch to SVC mode and then call trap.	 */_vswitch:	MOVW	SPSR, R1		/* save SPSR for ureg */	MOVW	R14, R2			/* save interrupted pc for ureg */	MOVW	R13, R3			/* save pointer to where the original [R0-R3] are */	/* switch to svc mode */	MOVW	CPSR, R14	BIC	$PsrMask, R14	ORR	$(PsrDirq|PsrDfiq|PsrMsvc), R14	MOVW	R14, CPSR	/* interupted code kernel or user? */	AND.S	$0xf, R1, R4	BEQ	_userexcep	/* here for trap from SVC mode */	MOVM.DB.W [R0-R2], (R13)	/* set ureg->{type, psr, pc}; r13 points to ureg->type  */	MOVM.IA	  (R3), [R0-R4]		/* restore [R0-R4] from previous mode's stack */	MOVM.DB.W [R0-R14], (R13)	/* save kernel level registers, at end r13 points to ureg */	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */	MOVW	R13, R0			/* first arg is pointer to ureg */	SUB	$8, R13			/* space for argument+link (for debugger) */	MOVW	$0xdeaddead,R11		/* marker */	BL	trap(SB)	ADD	$(8+4*15), R13		/* make r13 point to ureg->type */	MOVW	8(R13), R14		/* restore link */	MOVW	4(R13), R0		/* restore SPSR */	MOVW	R0, SPSR		/* ... */	MOVM.DB (R13), [R0-R14]	/* restore registers */	ADD	$8, R13			/* pop past ureg->{type+psr} */	RFE				/* MOVM.IA.S.W (R13), [R15] */	/* here for trap from USER mode */_userexcep:	MOVM.DB.W [R0-R2], (R13)	/* set ureg->{type, psr, pc}; r13 points to ureg->type  */	MOVM.IA	  (R3), [R0-R4]		/* restore [R0-R4] from previous mode's stack */	MOVM.DB.W.S [R0-R14], (R13)	/* save kernel level registers, at end r13 points to ureg */	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */	MOVW	R13, R0			/* first arg is pointer to ureg */	SUB	$8, R13			/* space for argument+link (for debugger) */	BL	trap(SB)	ADD	$(8+4*15), R13		/* make r13 point to ureg->type */	MOVW	8(R13), R14		/* restore link */	MOVW	4(R13), R0		/* restore SPSR */	MOVW	R0, SPSR		/* ... */	MOVM.DB.S (R13), [R0-R14]	/* restore registers */	ADD	$8, R13			/* pop past ureg->{type+psr} */	RFE				/* MOVM.IA.S.W (R13), [R15] */TEXT _vfiq(SB), $-4			/* FIQ */	RFE				/* FIQ is special, ignore it for now *//* *  This is the first jump from kernel to user mode. *  Fake a return from interrupt. * *  Enter with R0 containing the user stack pointer. *  UTZERO + 0x20 is always the entry point. *   */TEXT touser(SB),$-4	/* store the user stack pointer into the USR_r13 */	MOVM.DB.W [R0], (R13)	MOVM.S.IA.W (R13),[R13]	/* set up a PSR for user level */	MOVW	$(PsrMusr), R0	MOVW	R0,SPSR	/* save the PC on the stack */	MOVW	$(UTZERO+0x20), R0	MOVM.DB.W [R0],(R13)	/* return from interrupt */	RFE				/* MOVM.IA.S.W (R13), [R15] */	/* *  here to jump to a newly forked process */TEXT forkret(SB),$-4	ADD	$(4*15), R13		/* make r13 point to ureg->type */	MOVW	8(R13), R14		/* restore link */	MOVW	4(R13), R0		/* restore SPSR */	MOVW	R0, SPSR		/* ... */	MOVM.DB.S (R13), [R0-R14]	/* restore registers */	ADD	$8, R13			/* pop past ureg->{type+psr} */	RFE				/* MOVM.IA.S.W (R13), [R15] */TEXT splhi(SB), $-4	/* save caller pc in Mach */	MOVW	$(MACHADDR+0x04),R2	MOVW	R14,0(R2)	/* turn off interrupts */	MOVW	CPSR, R0	ORR	$(PsrDfiq|PsrDirq), R0, R1	MOVW	R1, CPSR	RETTEXT spllo(SB), $-4	MOVW	CPSR, R0	BIC	$(PsrDfiq|PsrDirq), R0, R1	MOVW	R1, CPSR	RETTEXT splx(SB), $-4	/* save caller pc in Mach */	MOVW	$(MACHADDR+0x04),R2	MOVW	R14,0(R2)	/* reset interrupt level */	MOVW	R0, R1	MOVW	CPSR, R0	MOVW	R1, CPSR	RETTEXT splxpc(SB), $-4				/* for iunlock */	MOVW	R0, R1	MOVW	CPSR, R0	MOVW	R1, CPSR	RETTEXT spldone(SB), $0	RETTEXT islo(SB), $-4	MOVW	CPSR, R0	AND	$(PsrDfiq|PsrDirq), R0	EOR	$(PsrDfiq|PsrDirq), R0	RETTEXT cpsrr(SB), $-4	MOVW	CPSR, R0	RETTEXT spsrr(SB), $-4	MOVW	SPSR, R0	RETTEXT getcallerpc(SB), $-4	MOVW	0(R13), R0	RETTEXT tas(SB), $-4	MOVW	R0, R1	MOVW	$0xDEADDEAD, R2	SWPW	R2, (R1), R0	RETTEXT setlabel(SB), $-4	MOVW	R13, 0(R0)			/* sp */	MOVW	R14, 4(R0)			/* pc */	MOVW	$0, R0	RETTEXT gotolabel(SB), $-4	MOVW	0(R0), R13			/* sp */	MOVW	4(R0), R14			/* pc */	MOVW	$1, R0	RET/* The first MCR instruction of this function needs to be on a cache-line * boundary; to make this happen, it will be copied (in trap.c). * * Doze puts the machine into idle mode.  Any interrupt will get it out * at the next instruction (the RET, to be precise). */TEXT _doze(SB), $-4	MOVW	$UCDRAMZERO, R1	MOVW	R0,R0	MOVW	R0,R0	MOVW	R0,R0	MOVW	R0,R0	MOVW	R0,R0	MOVW	R0,R0	MOVW	R0,R0	MCR     CpPWR, 0, R0, C(CpTest), C(0x2), 2	MOVW	(R1), R0	MCR     CpPWR, 0, R0, C(CpTest), C(0x8), 2	RET

⌨️ 快捷键说明

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