208 lines · 4.6 KB · Assembly
RawDownload
/* * arm v7 reboot code * * must fit in 11K to avoid stepping on PTEs; see mem.h. * cache parameters are at CACHECONF. */#include "arm.s" /* * All caches but L1 should be off before calling this. * Turn off MMU, then copy the new kernel to its correct location * in physical memory.  Then jump to the start of the kernel. */ /* main(PADDR(entry), PADDR(code), size); */TEXT	main(SB), 1, $-4	MOVW	$setR12(SB), R12	MOVW	R0, p1+0(FP)		/* destination, passed in R0 */	CPSID				/* splhi */ PUTC('R')	BL	cachesoff(SB)	/* now back in 29- or 26-bit addressing, mainly for SB */	/* double mapping of PHYSDRAM & KZERO now in effect */ PUTC('e')	/* before turning MMU off, switch to PHYSDRAM-based addresses */	DMB 	MOVW	$KSEGM, R7		/* clear segment bits */	MOVW	$PHYSDRAM, R0		/* set dram base bits */	BIC	R7, R12			/* adjust SB */	ORR	R0, R12 	BL	_r15warp(SB)	/* don't care about saving R14; we're not returning */ 	/*	 * now running in PHYSDRAM segment, not KZERO.	 */ PUTC('b')	/* invalidate mmu mappings */	MOVW	$KZERO, R0			/* some valid virtual address */	MTCP	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv	BARRIERS PUTC('o')	/*	 * turn the MMU off	 */	MFCP	CpSC, 0, R0, C(CpCONTROL), C(0)	BIC	$CpCmmu, R0	MTCP	CpSC, 0, R0, C(CpCONTROL), C(0)	BARRIERS PUTC('o')	/* copy in arguments from stack frame before moving stack */	MOVW	p2+4(FP), R4		/* phys source */	MOVW	n+8(FP), R5		/* byte count */	MOVW	p1+0(FP), R6		/* phys destination */ 	/* set up a new stack for local vars and memmove args */	MOVW	R6, SP			/* tiny trampoline stack */	SUB	$(0x20 + 4), SP		/* back up before a.out header */ //	MOVW	R14, -48(SP)		/* store return addr */	SUB	$48, SP			/* allocate stack frame */ 	MOVW	R5, 40(SP)		/* save count */	MOVW	R6, 44(SP)		/* save dest/entry */ 	/* copy the new kernel into place */	DELAY(printloop2, 2)PUTC('t')	MOVW	40(SP), R5		/* restore count */	MOVW	44(SP), R6		/* restore dest/entry */	MOVW	R6, 0(SP)		/* normally saved LR goes here */	MOVW	R6, 4(SP)		/* push dest */	MOVW	R6, R0	MOVW	R4, 8(SP)		/* push src */	MOVW	R5, 12(SP)		/* push size */	BL	memmove(SB) PUTC('-')PUTC('>')	DELAY(printloopret, 1)PUTC('\r')	DELAY(printloopnl, 1)PUTC('\n')/* * jump to kernel entry point.  Note the true kernel entry point is * the virtual address KZERO|R6, but this must wait until * the MMU is enabled by the kernel in l.s */	MOVW	44(SP), R6		/* restore R6 (dest/entry) */	ORR	R6, R6			/* NOP: avoid link bug */	B	(R6)PUTC('?')PUTC('?')	B	0(PC) /* * turn the caches off, double map PHYSDRAM & KZERO, invalidate TLBs, revert * to tiny addresses.  upon return, it will be safe to turn off the mmu. */TEXT cachesoff(SB), 1, $-4	MOVM.DB.W [R14,R1-R10], (R13)		/* save regs on stack */	CPSID	BARRIERS 	SUB	$12, SP				/* paranoia */	BL	cacheuwbinv(SB)	ADD	$12, SP				/* paranoia */ 	MFCP	CpSC, 0, R0, C(CpCONTROL), C(0)	BIC	$(CpCicache|CpCdcache), R0	MTCP	CpSC, 0, R0, C(CpCONTROL), C(0)	/* caches off */	BARRIERS 	/*	 * caches are off	 */ 	/* invalidate stale TLBs before changing them */	MOVW	$KZERO, R0			/* some valid virtual address */	MTCP	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv	BARRIERS 	/* redo double map of PHYSDRAM, KZERO */	MOVW	$PHYSDRAM, R3	CMP	$KZERO, R3	BEQ	noun2map	MOVW	$(L1+L1X(PHYSDRAM)), R4		/* address of PHYSDRAM's PTE */	MOVW	$PTEDRAM, R2			/* PTE bits */	MOVW	$DOUBLEMAPMBS, R5_ptrdbl:	ORR	R3, R2, R1		/* first identity-map 0 to 0, etc. */	MOVW	R1, (R4)	ADD	$4, R4				/* bump PTE address */	ADD	$MiB, R3			/* bump pa */	SUB.S	$1, R5	BNE	_ptrdblnoun2map: 	/*	 * flush stale TLB entries	 */ 	BARRIERS	MOVW	$KZERO, R0			/* some valid virtual address */	MTCP	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv	BARRIERS 	/* switch back to PHYSDRAM addressing, mainly for SB */	MOVW	$KSEGM, R7		/* clear segment bits */	MOVW	$PHYSDRAM, R0		/* set dram base bits */	BIC	R7, R12			/* adjust SB */	ORR	R0, R12	BIC	R7, SP	ORR	R0, SP 	MOVM.IA.W (R13), [R14,R1-R10]		/* restore regs from stack */ 	MOVW	$KSEGM, R0		/* clear segment bits */	BIC	R0, R14			/* adjust link */	MOVW	$PHYSDRAM, R0		/* set dram base bits */	ORR	R0, R14 	RET TEXT _r15warp(SB), 1, $-4	BIC	R7, R14			/* link */	ORR	R0, R14 	BIC	R7, R13			/* SP */	ORR	R0, R13	RET TEXT panic(SB), 1, $-4		/* stub */PUTC('?')PUTC('!')	RETTEXT pczeroseg(SB), 1, $-4	/* stub */	RET #include "cache.v7.s" /* modifies R0, R3—R6 */TEXT printhex(SB), 1, $-4	MOVW	R0, R3	MOVW	$(32-4), R5	/* bits to shift right */nextdig:	SRA	R5, R3, R4	AND	$0xf, R4	ADD	$'0', R4	CMP.S	$'9', R4	BLE	nothex		/* if R4 <= 9, jump */	ADD	$('a'-('9'+1)), R4nothex:	PUTC(R4)	SUB.S	$4, R5	BGE	nextdig 	PUTC('\r')	PUTC('\n')	DELAY(proct, 50)	RET