plan 9 kernel history: overview | file list | diff list

2001/0822/bitsy/l.s (diff list | history)

2001/0822/sys/src/9/bitsy/l.s:1,7552002/0424/sys/src/9/bitsy/l.s:1,755 (short | long | prev | next)
2000/0831    
#include "mem.h" 
 
/* 
2000/0901    
 * Entered here from Compaq's bootldr with MMU disabled. 
2000/0831    
 */ 
2000/0901    
TEXT _start(SB), $-4 
	MOVW	$setR12(SB), R12		/* load the SB */ 
2000/0831    
_main: 
2000/0901    
	/* SVC mode, interrupts disabled */ 
	MOVW	$(PsrDirq|PsrDfiq|PsrMsvc), R1 
2000/0831    
	MOVW	R1, CPSR 
2000/0901    
 
2000/1007    
	/* 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 */ 
2000/0905    
	MOVW	R0,R0						 
	MOVW	R0,R0 
	MOVW	R0,R0 
	MOVW	R0,R0 
2000/0901    
 
2000/0905    
	/* drain write buffer */ 
2000/1007    
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 
2000/0905    
 
2000/1207    
	MOVW	$(MACHADDR+4*BY2PG), R13		/* stack */ 
2000/0831    
	SUB	$4, R13				/* link */ 
	BL	main(SB) 
2000/0901    
	BL	exit(SB) 
	/* we shouldn't get here */ 
2000/0831    
_mainloop: 
2000/0901    
	B	_mainloop 
2000/0904    
	BL	_div(SB)			/* hack to get _div etc loaded */ 
2000/0831    
 
2000/0901    
/* flush tlb's */ 
2000/1015    
TEXT mmuinvalidate(SB), $-4 
2000/1007    
	MCR	CpMMU, 0, R0, C(CpTLBFlush), C(0x7) 
2000/0831    
	RET 
 
2000/1018    
/* flush tlb's */ 
TEXT mmuinvalidateaddr(SB), $-4 
	MCR	CpMMU, 0, R0, C(CpTLBFlush), C(0x6), 1 
	RET 
 
2000/1015    
/* write back and invalidate i and d caches */ 
TEXT cacheflush(SB), $-4 
2000/1212    
	/* splhi */ 
	MOVW	CPSR, R3 
2001/0621    
	ORR		$(PsrDirq), R3, R1 
2000/1212    
	MOVW	R1, CPSR 
 
2000/1010    
	/* write back any dirty data */ 
	MOVW	$0xe0000000,R0 
2001/0621    
	ADD		$(8*1024),R0,R1 
2000/1018    
_cfloop: 
	MOVW.P	32(R0),R2 
2000/1106    
	CMP.S	R0,R1 
2000/1212    
	BGE	_cfloop 
2000/1010    
	 
2000/1207    
	/* drain write buffer and invalidate i cache contents */ 
2001/0621    
	MCR		CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 
	MCR		CpMMU, 0, R0, C(CpCacheFlush), C(0x5), 0 
2000/1010    
 
2000/0901    
	/* drain prefetch */ 
	MOVW	R0,R0						 
	MOVW	R0,R0 
	MOVW	R0,R0 
	MOVW	R0,R0 
2000/1212    
 
	/* splx */ 
	MOVW	R3, CPSR 
2000/1014    
	RET 
2000/0831    
 
2000/1102    
/* write back d cache */ 
2000/1018    
TEXT cachewb(SB), $-4 
	/* write back any dirty data */ 
2000/1106    
_cachewb: 
2000/1018    
	MOVW	$0xe0000000,R0 
2001/0621    
	ADD		$(8*1024),R0,R1 
2000/1018    
_cwbloop: 
	MOVW.P	32(R0),R2 
2000/1106    
	CMP.S	R0,R1 
2000/1212    
	BGE	_cwbloop 
2001/0621    
 
2000/1018    
	/* 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 
2000/1014    
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1 
2000/1018    
	B	_wbflush 
 
/* write back a region of cache lines */ 
TEXT cachewbregion(SB), $-4 
	MOVW	4(FP),R1 
2000/1106    
	CMP.S	$(4*1024),R1 
	BGT	_cachewb 
2000/1018    
	ADD	R0,R1 
2000/1106    
	BIC	$31,R0 
_cwbrloop: 
2000/1018    
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1 
	ADD	$32,R0 
	CMP.S	R0,R1 
2000/1106    
	BGT	_cwbrloop 
2000/1018    
	B	_wbflush 
 
/* invalidate the dcache */ 
TEXT dcacheinvalidate(SB), $-4 
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x6) 
2000/1014    
	RET 
 
2000/1018    
/* invalidate the icache */ 
TEXT icacheinvalidate(SB), $-4 
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0x9) 
	RET 
 
2000/0901    
/* drain write buffer */ 
2000/0929    
TEXT wbflush(SB), $-4 
2000/1018    
_wbflush: 
2000/1007    
	MCR	CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 
2000/0831    
	RET 
 
2000/0901    
/* return cpu id */ 
TEXT getcpuid(SB), $-4 
2000/0929    
	MRC	CpMMU, 0, R0, C(CpCPUID), C(0x0) 
2000/0831    
	RET 
 
2000/0901    
/* return fault status */ 
TEXT getfsr(SB), $-4 
	MRC	CpMMU, 0, R0, C(CpFSR), C(0x0) 
2000/0831    
	RET 
 
2001/0814    
/* return mmu control register */ 
TEXT getcontrol(SB), $-4 
	SUB R0, R0 
	MRC	CpMMU, 0, R0, C(CpControl), C(0x0) 
	RET 
 
/* return mmu dac register */ 
TEXT getdac(SB), $-4 
	SUB R0, R0 
	MRC	CpMMU, 0, R0, C(CpDAC), C(0x0) 
	RET 
 
/* return mmu ttb register */ 
TEXT getttb(SB), $-4 
	SUB R0, R0 
	MRC	CpMMU, 0, R0, C(CpTTB), C(0x0) 
	RET 
 
2000/0901    
/* return fault address */ 
TEXT getfar(SB), $-4 
	MRC	CpMMU, 0, R0, C(CpFAR), C(0x0) 
2000/0831    
	RET 
 
2000/0904    
/* set the translation table base */ 
2000/0906    
TEXT putttb(SB), $-4 
2000/0901    
	MCR	CpMMU, 0, R0, C(CpTTB), C(0x0) 
2000/0929    
	RET 
2000/0906    
 
2000/0929    
/* 
2000/1007    
 *  enable mmu, i and d caches 
2000/0929    
 */ 
TEXT mmuenable(SB), $-4 
	MRC	CpMMU, 0, R0, C(CpControl), C(0x0) 
2000/1101    
	ORR	$(CpCmmuena|CpCdcache|CpCicache|CpCwb), R0 
2000/0929    
	MCR     CpMMU, 0, R0, C(CpControl), C(0x0) 
2001/0814    
	MOVW R0, R0 
	MOVW R0, R0 
	MOVW R0, R0 
	MOVW R0, R0 
2000/0929    
	RET 
 
TEXT mmudisable(SB), $-4 
	MRC	CpMMU, 0, R0, C(CpControl), C(0x0) 
2000/1101    
	BIC	$(CpCmmuena|CpCdcache|CpCicache|CpCwb|CpCvivec), R0 
2000/0929    
	MCR     CpMMU, 0, R0, C(CpControl), C(0x0) 
	RET 
 
2000/1007    
/* 
 *  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) 
	RET 
TEXT mappedIvecDisable(SB), $-4 
	MRC	CpMMU, 0, R0, C(CpControl), C(0x0) 
	BIC	$(CpCvivec), R0 
	MCR     CpMMU, 0, R0, C(CpControl), C(0x0) 
	RET 
 
2000/0906    
/* set the translation table base */ 
TEXT putdac(SB), $-4 
	MCR	CpMMU, 0, R0, C(CpDAC), C(0x0) 
2000/0929    
	RET 
2000/0906    
 
2000/0929    
/* set address translation pid */ 
2000/0906    
TEXT putpid(SB), $-4 
	MCR	CpMMU, 0, R0, C(CpPID), C(0x0) 
2000/0929    
	RET 
2000/0831    
 
2000/0904    
/* 
 *  set the stack value for the mode passed in R0 
 */ 
2000/0831    
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 
 
2000/0904    
/* 
 *  exception vectors, copied by trapinit() to somewhere useful 
 */ 
2000/1007    
 
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 */ 
2000/1012    
	WORD	$_vpabt(SB)			/* prefetch abort, switch to svc mode */ 
	WORD	$_vdabt(SB)			/* data abort, switch to svc mode */ 
2000/1007    
	WORD	$_vsvc(SB)			/* reserved */ 
	WORD	$_virq(SB)			/* IRQ, switch to svc mode */ 
	WORD	$_vfiq(SB)			/* FIQ, switch to svc mode */ 
2000/0831    
 
2000/1001    
TEXT _vrst(SB), $-4 
2000/1205    
	BL	resettrap(SB) 
2000/1001    
 
TEXT _vsvc(SB), $-4			/* SWI */ 
2000/1014    
	MOVW.W	R14, -4(R13)		/* ureg->pc = interupted PC */ 
2000/0904    
	MOVW	SPSR, R14		/* ureg->psr = SPSR */ 
2000/1014    
	MOVW.W	R14, -4(R13)		/* ... */ 
2000/0904    
	MOVW	$PsrMsvc, R14		/* ureg->type = PsrMsvc */ 
2000/1014    
	MOVW.W	R14, -4(R13)		/* ... */ 
2000/0904    
	MOVM.DB.W.S [R0-R14], (R13)	/* save user level registers, at end r13 points to ureg */ 
2000/1002    
	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 */ 
2000/0831    
 
2000/1002    
	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] */ 
 
2000/0904    
TEXT _vund(SB), $-4			/* undefined */ 
2000/1002    
	MOVM.IA	[R0-R4], (R13)		/* free some working space */ 
2000/0831    
	MOVW	$PsrMund, R0 
	B	_vswitch 
 
2000/1012    
TEXT _vpabt(SB), $-4			/* prefetch abort */ 
2000/1002    
	MOVM.IA	[R0-R4], (R13)		/* free some working space */ 
2000/0904    
	MOVW	$PsrMabt, R0		/* r0 = type */ 
2000/0831    
	B	_vswitch 
 
2000/1012    
TEXT _vdabt(SB), $-4			/* prefetch abort */ 
	MOVM.IA	[R0-R4], (R13)		/* free some working space */ 
	MOVW	$(PsrMabt+1), R0		/* r0 = type */ 
	B	_vswitch 
 
2000/0904    
TEXT _virq(SB), $-4			/* IRQ */ 
2000/1002    
	MOVM.IA	[R0-R4], (R13)		/* free some working space */ 
2000/0904    
	MOVW	$PsrMirq, R0		/* r0 = type */ 
2000/0831    
	B	_vswitch 
 
2000/0903    
	/* 
2000/1002    
	 *  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. 
2000/0903    
	 */ 
2000/1002    
_vswitch: 
2000/0904    
	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 */ 
2000/0831    
 
2000/0904    
	/* switch to svc mode */ 
2000/0903    
	MOVW	CPSR, R14 
2000/0831    
	BIC	$PsrMask, R14 
	ORR	$(PsrDirq|PsrDfiq|PsrMsvc), R14 
	MOVW	R14, CPSR 
 
2000/1002    
	/* interupted code kernel or user? */ 
	AND.S	$0xf, R1, R4 
2000/1010    
	BEQ	_userexcep 
2000/1002    
 
	/* here for trap from SVC mode */ 
2000/1001    
	MOVM.DB.W [R0-R2], (R13)	/* set ureg->{type, psr, pc}; r13 points to ureg->type  */ 
2000/1002    
	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) */ 
2000/1028    
	MOVW	$0xdeaddead,R11		/* marker */ 
2000/0831    
 
2000/1002    
	BL	trap(SB) 
2000/0831    
 
2000/1002    
	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 */ 
2000/0904    
	MOVW	$setR12(SB), R12	/* Make sure we've got the kernel's SB loaded */ 
2000/0903    
	MOVW	R13, R0			/* first arg is pointer to ureg */ 
2000/1002    
	SUB	$8, R13			/* space for argument+link (for debugger) */ 
 
2000/0929    
	BL	trap(SB) 
2000/0831    
 
2000/0904    
	ADD	$(8+4*15), R13		/* make r13 point to ureg->type */ 
2000/0903    
	MOVW	8(R13), R14		/* restore link */ 
	MOVW	4(R13), R0		/* restore SPSR */ 
	MOVW	R0, SPSR		/* ... */ 
2000/1002    
	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 */ 
 
2000/1012    
/* 
 *  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 
 */ 
2000/1002    
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 */ 
2000/0904    
	ADD	$8, R13			/* pop past ureg->{type+psr} */ 
2000/0831    
	RFE				/* MOVM.IA.S.W (R13), [R15] */ 
 
TEXT splhi(SB), $-4 
2000/1101    
	/* save caller pc in Mach */ 
	MOVW	$(MACHADDR+0x04),R2 
	MOVW	R14,0(R2) 
	/* turn off interrupts */ 
2000/0831    
	MOVW	CPSR, R0 
2000/1207    
	ORR	$(PsrDirq), R0, R1 
2000/0831    
	MOVW	R1, CPSR 
	RET 
 
TEXT spllo(SB), $-4 
	MOVW	CPSR, R0 
2000/1207    
	BIC	$(PsrDirq), R0, R1 
2000/0831    
	MOVW	R1, CPSR 
	RET 
 
TEXT splx(SB), $-4 
2000/1101    
	/* save caller pc in Mach */ 
	MOVW	$(MACHADDR+0x04),R2 
	MOVW	R14,0(R2) 
	/* reset interrupt level */ 
2000/0902    
	MOVW	R0, R1 
	MOVW	CPSR, R0 
	MOVW	R1, CPSR 
	RET 
 
2000/0928    
TEXT splxpc(SB), $-4				/* for iunlock */ 
2000/0831    
	MOVW	R0, R1 
	MOVW	CPSR, R0 
	MOVW	R1, CPSR 
2000/1101    
	RET 
 
TEXT spldone(SB), $0 
2000/0831    
	RET 
 
TEXT islo(SB), $-4 
	MOVW	CPSR, R0 
2000/1207    
	AND	$(PsrDirq), R0 
	EOR	$(PsrDirq), R0 
2000/0831    
	RET 
 
TEXT cpsrr(SB), $-4 
	MOVW	CPSR, R0 
	RET 
 
TEXT spsrr(SB), $-4 
	MOVW	SPSR, R0 
	RET 
 
2001/0621    
TEXT getsp(SB), $-4 
	MOVW	R13, R0 
	RET 
 
TEXT getlink(SB), $-4 
	MOVW	R14, R0 
	RET 
 
2000/0831    
TEXT getcallerpc(SB), $-4 
	MOVW	0(R13), R0 
	RET 
 
TEXT tas(SB), $-4 
	MOVW	R0, R1 
2000/1208    
	MOVW	$0xDEADDEAD, R0 
	MOVW	R0, R3 
	SWPW	R0, (R1) 
2000/1207    
	CMP.S	R0, R3 
	BEQ	_tasout 
	EOR	R3, R3 
	CMP.S	R0, R3 
	BEQ	_tasout 
	MOVW	$1,R15 
_tasout: 
2000/0831    
	RET 
 
TEXT setlabel(SB), $-4 
	MOVW	R13, 0(R0)			/* sp */ 
	MOVW	R14, 4(R0)			/* pc */ 
	MOVW	$0, R0 
	RET 
 
TEXT gotolabel(SB), $-4 
	MOVW	0(R0), R13			/* sp */ 
	MOVW	4(R0), R14			/* pc */ 
	MOVW	$1, R0 
	RET 
2000/1130    
 
2001/0821    
/* save the state machine in power_state[] for an upcoming suspend 
2001/0618    
 */ 
TEXT setpowerlabel(SB), $-4 
2001/0821    
	MOVW	$power_state+0(SB), R0 
	/* svc */				/* power_state[]: what */ 
2001/0621    
	MOVW	R1, 0(R0) 
	MOVW	R2, 4(R0) 
	MOVW	R3, 8(R0) 
	MOVW	R4, 12(R0) 
	MOVW	R5, 16(R0) 
	MOVW	R6, 20(R0) 
	MOVW	R7, 24(R0) 
	MOVW	R8, 28(R0) 
	MOVW	R9, 32(R0) 
	MOVW	R10,36(R0) 
	MOVW	R11,40(R0) 
	MOVW	R12,44(R0) 
	MOVW	R13,48(R0) 
	MOVW	R14,52(R0) 
	MOVW	SPSR, R1 
	MOVW	R1, 56(R0) 
	MOVW	CPSR, R2 
	MOVW	R2, 60(R0) 
2001/0618    
	/* copro */ 
	MRC		CpMMU, 0, R3, C(CpDAC), C(0x0) 
2001/0621    
	MOVW	R3, 144(R0) 
2001/0618    
	MRC		CpMMU, 0, R3, C(CpTTB), C(0x0) 
2001/0621    
	MOVW	R3, 148(R0) 
2001/0618    
	MRC		CpMMU, 0, R3, C(CpControl), C(0x0) 
2001/0621    
	MOVW	R3, 152(R0) 
2001/0618    
	MRC		CpMMU, 0, R3, C(CpFSR), C(0x0) 
2001/0621    
	MOVW	R3, 156(R0) 
2001/0618    
	MRC		CpMMU, 0, R3, C(CpFAR), C(0x0) 
2001/0621    
	MOVW	R3, 160(R0) 
2001/0618    
	MRC		CpMMU, 0, R3, C(CpPID), C(0x0) 
2001/0621    
	MOVW	R3, 164(R0) 
2001/0618    
	/* irq */ 
	BIC		$(PsrMask), R2, R3 
	ORR		$(PsrDirq|PsrMirq), R3 
2001/0621    
	MOVW	R3, CPSR 
	MOVW	SPSR, R11 
	MOVW	R11, 64(R0) 
	MOVW	R12, 68(R0) 
	MOVW	R13, 72(R0) 
	MOVW	R14, 76(R0) 
2001/0618    
	/* und */ 
	BIC		$(PsrMask), R2, R3 
	ORR		$(PsrDirq|PsrMund), R3 
2001/0621    
	MOVW	R3, CPSR 
	MOVW	SPSR, R11 
	MOVW	R11, 80(R0) 
	MOVW	R12, 84(R0) 
	MOVW	R13, 88(R0) 
	MOVW	R14, 92(R0) 
2001/0618    
	/* abt */ 
	BIC		$(PsrMask), R2, R3 
	ORR		$(PsrDirq|PsrMabt), R3 
2001/0621    
	MOVW	R3, CPSR 
	MOVW	SPSR, R11 
	MOVW	R11, 96(R0) 
	MOVW	R12, 100(R0) 
	MOVW	R13, 104(R0) 
	MOVW	R14, 108(R0) 
2001/0618    
	/* fiq */ 
	BIC		$(PsrMask), R2, R3 
	ORR		$(PsrDirq|PsrMfiq), R3 
2001/0621    
	MOVW	R3, CPSR 
	MOVW	SPSR, R7 
	MOVW	R7, 112(R0) 
	MOVW	R8, 116(R0) 
	MOVW	R9, 120(R0) 
	MOVW	R10,124(R0) 
	MOVW	R11,128(R0) 
	MOVW	R12,132(R0) 
	MOVW	R13,136(R0) 
	MOVW	R14,140(R0) 
2001/0618    
	/* done */ 
2001/0621    
	MOVW	R2, CPSR 
	MOVW	R1, SPSR 
	MOVW	$0, R0 
2001/0618    
	RET 
 
/* Entered after a resume from suspend state. 
 * The bootldr jumps here after a processor reset. 
2001/0620    
 */ 
2001/0821    
TEXT power_resume(SB), $-4 
2001/0618    
	MOVW	$setR12(SB), R12		/* load the SB */ 
	/* SVC mode, interrupts disabled */ 
	MOVW	$(PsrDirq|PsrDfiq|PsrMsvc), R1 
	MOVW	R1, CPSR 
	/* gotopowerlabel() */ 
	/* svc */ 
2001/0811    
 
2001/0821    
	MOVW	$power_state+0(SB), R0 
2001/0618    
	MOVW	56(R0), R1		/* R1: SPSR, R2: CPSR */ 
	MOVW	60(R0), R2 
2001/0809    
	MOVW	R1, SPSR 
	MOVW	R2, CPSR 
2001/0618    
	/* copro */ 
2001/0815    
	/* 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 
	MCR		CpMMU, 0, R0, C(CpTLBFlush), C(0x7) 
2001/0621    
	MOVW	144(R0), R3 
2001/0618    
	MCR		CpMMU, 0, R3, C(CpDAC), C(0x0) 
2001/0815    
	MOVW	148(R0), R3 
	MCR		CpMMU, 0, R3, C(CpTTB), C(0x0) 
2001/0621    
	MOVW	156(R0), R3 
2001/0618    
	MCR		CpMMU, 0, R3, C(CpFSR), C(0x0) 
2001/0621    
	MOVW	160(R0), R3 
2001/0618    
	MCR		CpMMU, 0, R3, C(CpFAR), C(0x0) 
2001/0621    
	MOVW	164(R0), R3 
2001/0618    
	MCR		CpMMU, 0, R3, C(CpPID), C(0x0) 
2001/0815    
	MOVW	152(R0), R3 
	MCR		CpMMU, 0, R3, C(CpControl), C(0x0)	/* Enable cache */ 
	MOVW	R0,R0						 
	MOVW	R0,R0 
	MOVW	R0,R0 
	MOVW	R0,R0 
	/* flush i&d caches */ 
	MCR		CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0 
	/* flush tlb */ 
	MCR		CpMMU, 0, R0, C(CpTLBFlush), C(0x7), 0 
2001/0816    
	/* drain prefetch */ 
2001/0815    
	MOVW	R0,R0						 
	MOVW	R0,R0 
	MOVW	R0,R0 
	MOVW	R0,R0 
2001/0618    
	/* irq */ 
2001/0621    
	BIC		$(PsrMask), R2, R3 
	ORR		$(PsrDirq|PsrMirq), R3 
2001/0618    
	MOVW	R3, CPSR 
	MOVW	64(R0), R11 
	MOVW	68(R0), R12 
	MOVW	72(R0), R13 
	MOVW	76(R0), R14 
	MOVW	R11, SPSR 
	/* und */ 
2001/0621    
	BIC		$(PsrMask), R2, R3 
	ORR		$(PsrDirq|PsrMund), R3 
2001/0618    
	MOVW	R3, CPSR 
	MOVW	80(R0), R11 
	MOVW	84(R0), R12 
	MOVW	88(R0), R13 
	MOVW	92(R0), R14 
	MOVW	R11, SPSR 
	/* abt */ 
2001/0621    
	BIC		$(PsrMask), R2, R3 
	ORR		$(PsrDirq|PsrMabt), R3 
2001/0618    
	MOVW	R3, CPSR 
	MOVW	96(R0), R11 
	MOVW	100(R0), R12 
	MOVW	104(R0), R13 
	MOVW	108(R0), R14 
	MOVW	R11, SPSR 
	/* fiq */ 
2001/0621    
	BIC		$(PsrMask), R2, R3 
	ORR		$(PsrDirq|PsrMfiq), R3 
2001/0618    
	MOVW	R3, CPSR 
	MOVW	112(R0), R7 
	MOVW	116(R0), R8 
	MOVW	120(R0), R9 
	MOVW	124(R0), R10 
	MOVW	128(R0), R11 
	MOVW	132(R0), R12 
	MOVW	136(R0), R13 
	MOVW	140(R0), R14 
	MOVW	R7, SPSR 
	/* svc */ 
	MOVW	56(R0), R1 
	MOVW	60(R0), R2 
	MOVW	R1, SPSR 
	MOVW	R2, CPSR 
	MOVW	0(R0), R1 
	MOVW	4(R0), R2 
	MOVW	8(R0), R3 
	MOVW	12(R0),R4 
	MOVW	16(R0),R5 
	MOVW	20(R0),R6 
	MOVW	24(R0),R7 
	MOVW	28(R0),R8 
	MOVW	32(R0),R9 
	MOVW	36(R0),R10 
	MOVW	40(R0),R11 
	MOVW	44(R0),R12 
	MOVW	48(R0),R13 
	MOVW	52(R0),R14 
	RET 
loop: 
2001/0621    
	B		loop 
2001/0618    
 
2001/0818    
TEXT power_down(SB), $-4 
2001/0817    
 
2001/0820    
	TEXT	sa1100_power_off<>+0(SB),$8 
	MOVW	resetregs+0(SB),R7 
	MOVW	gpioregs+0(SB),R6 
	MOVW	memconfregs+0(SB),R5 
	MOVW	powerregs+0(SB),R3 
2001/0821    
	MOVW	0x1c(R5),R4 
	ORR		$0x30400000,R4 
	AND		$(~0xfff0),R4 
2001/0820    
	MOVW	$0x80000003,R2 
	MOVW	R2,0xc(R3) 
	MOVW	$15,R2 
	MOVW	R2,0x4(R7) 
	MOVW	$7,R2 
	MOVW	R2,0x10(R3) 
	MOVW	$0,R2 
	MOVW	R2,0x18(R3) 
2001/0822    
/*	MOVW	$power_resume+0(SB),R2	*/ 
	MOVW	$0,R2 
2002/0424    
	MOVW	$power_resume+0(SB),R2 
/*	MOVW	$0,R2	*/ 
2001/0820    
	MOVW	R2,0x8(R3) 
	MOVW	$0,R2 
	MOVW	R2,0x4(R6) 
	MOVW	0x1c(R5),R2 
	ORR		$0x400000,R2 
	MOVW	R2,0x1c(R5) 
2001/0818    
	MOVW	$(90*206),R0 
2001/0820    
l13:	SUB		$1,R0 
	BGT		l13 
	MOVW	powerregs+0(SB),R3 
	MOVW	$0,R2 
	MOVW	R2,20(R3) 
2001/0818    
	MOVW	$(90*206),R0 
2001/0820    
l14:	SUB		$1,R0 
	BGT		l14 
	MOVW	powerregs+0(SB),R5 
	ORR		$0x80000000,R4,R6 
	AND		$(~0x80100000),R6,R11 
2001/0818    
 
2001/0820    
	MOVW	memconfregs+0(SB),R3 
2001/0821    
	MOVW	0x0(R3),R12 
2001/0820    
	AND		$(~0x30003),R12 
2001/0818    
 
2001/0820    
	MOVW	0x10(R3),R2 
2001/0821    
	AND		$(~0x00030003),R2 
2001/0820    
	MOVW	R2,0x10(R3) 
	MOVW	0x14(R3),R2 
2001/0821    
	AND		$(~0x00030003),R2 
2001/0820    
	MOVW	R2,0x14(R3) 
	MOVW	0x2c(R3),R2 
2001/0821    
	AND		$(~0x00030003),R2 
2001/0820    
	MOVW	R2,0x2c(R3) 
2001/0821    
	MOVW	R0,R0			/* filler */ 
2001/0817    
 
2001/0820    
	MOVW	$1,R2 
	MOVW	R4,0x1c(R3) 
//	MOVW	R6,0x1c(R3) 
2002/0424    
	MOVW	R6,0x1c(R3) 
2001/0821    
	MOVW	R12,0x0(R3) 
2001/0820    
//	MOVW	R11,0x1c(R3) 
2002/0424    
	MOVW	R11,0x1c(R3) 
2001/0821    
	MOVW	R2,0x0(R5) 
2001/0817    
 
2001/0818    
slloop: 
	B		slloop			/* loop waiting for sleep */ 
2001/0817    
 
2000/1130    
/* 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 
2001/0621    
	MCR   	CpPWR, 0, R0, C(CpTest), C(0x2), 2 
2000/1130    
	MOVW	(R1), R0 
2001/0621    
	MCR  	CpPWR, 0, R0, C(CpTest), C(0x8), 2 
2000/1130    
	RET 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)